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