|
|
handlr.c - geomyidae - A small C-based gopherd. |
|
|
 |
git clone git://bitreich.org/geomyidae/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/geomyidae/ (git://bitreich.org) |
|
|
 |
Log |
|
|
 |
Files |
|
|
 |
Refs |
|
|
 |
Tags |
|
|
 |
README |
|
|
 |
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 |
|