SMOLNET PORTAL home about changes
handlr.c - geomyidae - A small C-based gopherd.
(URL) git clone git://bitreich.org/geomyidae/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/geomyidae/ (git://bitreich.org)
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Tags
(DIR) README
(DIR) LICENSE
---
handlr.c (5384B)
---
1 /*
2 * Copy me if you can.
3 * by 20h
4 */
5
6 #include <unistd.h>
7 #include <memory.h>
8 #include <netdb.h>
9 #include <netinet/in.h>
10 #include <fcntl.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <sys/socket.h>
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <dirent.h>
18 #include <sys/wait.h>
19 #include <errno.h>
20 #include <libgen.h>
21
22 #include "ind.h"
23 #include "arg.h"
24
25 void
26 handledir(int sock, char *path, char *port, char *base, char *args,
27 char *sear, char *ohost, char *chost, char *bhost, int istls,
28 char *sel, char *traverse)
29 {
30 char *pa, *file, *e, *par;
31 struct dirent **dirent;
32 int ndir, i, ret = 0;
33 struct stat st;
34 filetype *type;
35
36 USED(args);
37 USED(sear);
38 USED(bhost);
39 USED(sel);
40 USED(traverse);
41
42 pa = xstrdup(path);
43
44 /* Is there any directory below the request? */
45 if (strlen(pa+strlen(base)) > 1) {
46 par = xstrdup(pa+strlen(base));
47 e = strrchr(par, '/');
48 *e = '\0';
49 dprintf(sock, "1..\t%s\t%s\t%s\r\n",
50 par, ohost, port);
51 free(par);
52 }
53
54 ndir = scandir(pa, &dirent, 0, alphasort);
55 if (ndir < 0) {
56 perror("scandir");
57 free(pa);
58 return;
59 } else {
60 for (i = 0; i < ndir && ret >= 0; i++) {
61 if (dirent[i]->d_name[0] == '.')
62 continue;
63
64 type = gettype(dirent[i]->d_name);
65
66 file = smprintf("%s%s%s",
67 pa,
68 pa[strlen(pa)-1] == '/'? "" : "/",
69 dirent[i]->d_name);
70 if (stat(file, &st) >= 0 && S_ISDIR(st.st_mode))
71 type = gettype("index.gph");
72 ret = dprintf(sock,
73 "%c%-50.50s %10s %16s\t%s\t%s\t%s\r\n",
74 *type->type,
75 dirent[i]->d_name,
76 humansize(st.st_size),
77 humantime(&(st.st_mtime)),
78 file + strlen(base), ohost, port);
79 free(file);
80 }
81 for (i = 0; i < ndir; i++)
82 free(dirent[i]);
83 free(dirent);
84 }
85 dprintf(sock, ".\r\n");
86
87 free(pa);
88 }
89
90 void
91 handlegph(int sock, char *file, char *port, char *base, char *args,
92 char *sear, char *ohost, char *chost, char *bhost, int istls,
93 char *sel, char *traverse)
94 {
95 gphindex *act;
96 int i, ret = 0;
97
98 USED(args);
99 USED(sear);
100 USED(bhost);
101 USED(sel);
102 USED(traverse);
103
104 act = gph_scanfile(file);
105 if (act != NULL) {
106 for (i = 0; i < act->num && ret >= 0; i++)
107 ret = gph_printelem(sock, act->n[i], file, base, ohost, port);
108 dprintf(sock, ".\r\n");
109
110 for (i = 0; i < act->num; i++) {
111 gph_freeelem(act->n[i]);
112 act->n[i] = NULL;
113 }
114 gph_freeindex(act);
115 }
116 }
117
118 void
119 handlebin(int sock, char *file, char *port, char *base, char *args,
120 char *sear, char *ohost, char *chost, char *bhost, int istls,
121 char *sel, char *traverse)
122 {
123 int fd;
124
125 USED(port);
126 USED(base);
127 USED(args);
128 USED(sear);
129 USED(ohost);
130 USED(bhost);
131 USED(sel);
132 USED(traverse);
133
134 fd = open(file, O_RDONLY);
135 if (fd >= 0) {
136 if (xsendfile(fd, sock) < 0)
137 perror("sendfile");
138 close(fd);
139 }
140 }
141
142 void
143 handlecgi(int sock, char *file, char *port, char *base, char *args,
144 char *sear, char *ohost, char *chost, char *bhost, int istls,
145 char *sel, char *traverse)
146 {
147 char *script, *path, *filec, *scriptc;
148
149 USED(base);
150 USED(port);
151
152 filec = xstrdup(file);
153 scriptc = xstrdup(file);
154 path = dirname(filec);
155 script = basename(scriptc);
156
157 if (sear == NULL)
158 sear = "";
159 if (args == NULL)
160 args = "";
161
162 while (dup2(sock, 0) < 0 && errno == EINTR);
163 while (dup2(sock, 1) < 0 && errno == EINTR);
164 while (dup2(sock, 2) < 0 && errno == EINTR);
165 switch (fork()) {
166 case 0:
167 if (path != NULL) {
168 if (chdir(path) < 0)
169 break;
170 }
171
172 setcgienviron(script, file, port, base, args, sear, ohost, chost,
173 bhost, istls, sel, traverse);
174
175 if (execl(file, script, sear, args, ohost, port, traverse, sel,
176 (char *)NULL) == -1) {
177 perror("execl");
178 _exit(1);
179 }
180 case -1:
181 perror("fork");
182 break;
183 default:
184 wait(NULL);
185 free(filec);
186 free(scriptc);
187 break;
188 }
189 }
190
191 void
192 handledcgi(int sock, char *file, char *port, char *base, char *args,
193 char *sear, char *ohost, char *chost, char *bhost, int istls,
194 char *sel, char *traverse)
195 {
196 FILE *fp;
197 char *script, *path, *filec, *scriptc, *ln = NULL;
198 size_t linesiz = 0;
199 ssize_t n;
200 int outsocks[2], ret = 0;
201 gphelem *el;
202
203 if (socketpair(AF_LOCAL, SOCK_STREAM, 0, outsocks) < 0)
204 return;
205
206 filec = xstrdup(file);
207 scriptc = xstrdup(file);
208 path = dirname(filec);
209 script = basename(scriptc);
210
211 if (sear == NULL)
212 sear = "";
213 if (args == NULL)
214 args = "";
215
216 while (dup2(sock, 0) < 0 && errno == EINTR);
217 while (dup2(sock, 2) < 0 && errno == EINTR);
218 switch (fork()) {
219 case 0:
220 while (dup2(outsocks[1], 1) < 0 && errno == EINTR);
221 close(outsocks[0]);
222 if (path != NULL) {
223 if (chdir(path) < 0)
224 break;
225 }
226
227 setcgienviron(script, file, port, base, args, sear, ohost, chost,
228 bhost, istls, sel, traverse);
229
230 if (execl(file, script, sear, args, ohost, port, traverse, sel,
231 (char *)NULL) == -1) {
232 perror("execl");
233 _exit(1);
234 }
235 break;
236 case -1:
237 perror("fork");
238 break;
239 default:
240 while (dup2(sock, 1) < 0 && errno == EINTR);
241 close(outsocks[1]);
242
243 if (!(fp = fdopen(outsocks[0], "r"))) {
244 perror("fdopen");
245 close(outsocks[0]);
246 break;
247 }
248
249 while ((n = getline(&ln, &linesiz, fp)) > 0 && ret >= 0) {
250 if (ln[n - 1] == '\n')
251 ln[--n] = '\0';
252
253 el = gph_getadv(ln);
254 if (el == NULL)
255 continue;
256
257 ret = gph_printelem(sock, el, file, base, ohost, port);
258 gph_freeelem(el);
259 }
260 if (ferror(fp))
261 perror("getline");
262 dprintf(sock, ".\r\n");
263
264 free(ln);
265 fclose(fp);
266 wait(NULL);
267 free(filec);
268 free(scriptc);
269 break;
270 }
271 }
272
Response: application/gopher-menu
Original URLgopher://bitreich.org/1/scm/geomyidae/file/handlr.c.gph
Content-Typeapplication/gopher-menu; charset=utf-8