Introduction
Introduction Statistics Contact Development Disclaimer Help
handlr.c - geomyidae - a small C-based gopherd (mirror)
git clone git://git.codemadness.org/geomyidae
Log
Files
Refs
README
LICENSE
---
handlr.c (5663B)
---
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 i…
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%…
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 i…
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,…
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 i…
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 /*
143 * See RFC3875 5 NPH Scripts
144 *
145 * In gopher, with no header parsing, this allows bi-directional
146 * long-running communications. One example would be raw HTTP emulation.
147 */
148 void
149 handlecgi(int sock, char *file, char *port, char *base, char *args,
150 char *sear, char *ohost, char *chost, char *bhost, int i…
151 char *sel, char *traverse)
152 {
153 char *script, *path, *filec, *scriptc;
154
155 USED(base);
156 USED(port);
157
158 filec = xstrdup(file);
159 scriptc = xstrdup(file);
160 path = dirname(filec);
161 script = basename(scriptc);
162
163 if (sear == NULL)
164 sear = "";
165 if (args == NULL)
166 args = "";
167
168 while (dup2(sock, 0) < 0 && errno == EINTR);
169 while (dup2(sock, 1) < 0 && errno == EINTR);
170 while (dup2(sock, 2) < 0 && errno == EINTR);
171 switch (fork()) {
172 case 0:
173 if (path != NULL) {
174 if (chdir(path) < 0)
175 break;
176 }
177
178 setcgienviron(script, file, port, base, args, sear, ohos…
179 bhost, istls, sel, traverse);
180
181 if (execl(file, script, sear, args, ohost, port, travers…
182 (char *)NULL) == -1) {
183 perror("execl");
184 _exit(1);
185 }
186 case -1:
187 perror("fork");
188 break;
189 default:
190 wait(NULL);
191 free(filec);
192 free(scriptc);
193 break;
194 }
195 }
196
197 /*
198 * This is RFC3875 NPH Scripts
199 * plus parsing of GPH syntax for easier gophermap portability.
200 */
201 void
202 handledcgi(int sock, char *file, char *port, char *base, char *args,
203 char *sear, char *ohost, char *chost, char *bhost, int i…
204 char *sel, char *traverse)
205 {
206 FILE *fp;
207 char *script, *path, *filec, *scriptc, *ln = NULL;
208 size_t linesiz = 0;
209 ssize_t n;
210 int outsocks[2], ret = 0;
211 gphelem *el;
212
213 if (socketpair(AF_LOCAL, SOCK_STREAM, 0, outsocks) < 0)
214 return;
215
216 filec = xstrdup(file);
217 scriptc = xstrdup(file);
218 path = dirname(filec);
219 script = basename(scriptc);
220
221 if (sear == NULL)
222 sear = "";
223 if (args == NULL)
224 args = "";
225
226 while (dup2(sock, 0) < 0 && errno == EINTR);
227 while (dup2(sock, 2) < 0 && errno == EINTR);
228 switch (fork()) {
229 case 0:
230 while (dup2(outsocks[1], 1) < 0 && errno == EINTR);
231 close(outsocks[0]);
232 if (path != NULL) {
233 if (chdir(path) < 0)
234 break;
235 }
236
237 setcgienviron(script, file, port, base, args, sear, ohos…
238 bhost, istls, sel, traverse);
239
240 if (execl(file, script, sear, args, ohost, port, travers…
241 (char *)NULL) == -1) {
242 perror("execl");
243 _exit(1);
244 }
245 break;
246 case -1:
247 perror("fork");
248 break;
249 default:
250 while (dup2(sock, 1) < 0 && errno == EINTR);
251 close(outsocks[1]);
252
253 if (!(fp = fdopen(outsocks[0], "r"))) {
254 perror("fdopen");
255 close(outsocks[0]);
256 break;
257 }
258
259 while ((n = getline(&ln, &linesiz, fp)) > 0 && ret >= 0)…
260 if (ln[n - 1] == '\n')
261 ln[--n] = '\0';
262
263 el = gph_getadv(ln);
264 if (el == NULL)
265 continue;
266
267 ret = gph_printelem(sock, el, file, base, ohost,…
268 gph_freeelem(el);
269 }
270 if (ferror(fp))
271 perror("getline");
272 dprintf(sock, ".\r\n");
273
274 free(ln);
275 fclose(fp);
276 wait(NULL);
277 free(filec);
278 free(scriptc);
279 break;
280 }
281 }
282
You are viewing proxied material from codemadness.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.