handlr.c (4898B)
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 21 #include "ind.h" 22 #include "arg.h" 23 24 void 25 handledir(int sock, char *path, char *port, char *base, char *args, 26 char *sear, char *ohost, char *chost, char *bhost, int istls) 27 { 28 char *pa, *file, *e, *par, *b; 29 struct dirent **dirent; 30 int ndir, i, ret = 0; 31 struct stat st; 32 filetype *type; 33 34 USED(args); 35 USED(sear); 36 USED(bhost); 37 38 pa = xstrdup(path); 39 e = pa + strlen(pa) - 1; 40 if (e[0] == '/') 41 *e = '\0'; 42 43 par = xstrdup(pa); 44 b = strrchr(par + strlen(base), '/'); 45 if (b != NULL) { 46 *b = '\0'; 47 dprintf(sock, "1..\t%s\t%s\t%s\r\n", 48 par + strlen(base), ohost, port); 49 } 50 free(par); 51 52 ndir = scandir(pa[0] ? pa : ".", &dirent, 0, alphasort); 53 if (ndir < 0) { 54 perror("scandir"); 55 free(pa); 56 return; 57 } else { 58 for (i = 0; i < ndir && ret >= 0; i++) { 59 if (dirent[i]->d_name[0] == '.') { 60 free(dirent[i]); 61 continue; 62 } 63 64 type = gettype(dirent[i]->d_name); 65 file = smprintf("%s/%s", pa, 66 dirent[i]->d_name); 67 if (stat(file, &st) >= 0 && S_ISDIR(st.st_mode)) 68 type = gettype("index.gph"); 69 e = file + strlen(base); 70 ret = dprintf(sock, 71 "%c%-50.50s %10s %16s\t%s\t%s\t%s\r\n", 72 *type->type, 73 dirent[i]->d_name, 74 humansize(st.st_size), 75 humantime(&(st.st_mtime)), 76 e, ohost, port); 77 free(file); 78 free(dirent[i]); 79 } 80 free(dirent); 81 } 82 dprintf(sock, ".\r\n"); 83 84 free(pa); 85 } 86 87 void 88 handlegph(int sock, char *file, char *port, char *base, char *args, 89 char *sear, char *ohost, char *chost, char *bhost, int istls) 90 { 91 Indexs *act; 92 int i, ret = 0; 93 94 USED(args); 95 USED(sear); 96 USED(bhost); 97 98 act = scanfile(file); 99 if (act != NULL) { 100 for (i = 0; i < act->num && ret >= 0; i++) { 101 ret = printelem(sock, act->n[i], file, base, ohost, port); 102 freeelem(act->n[i]); 103 act->n[i] = NULL; 104 } 105 dprintf(sock, ".\r\n"); 106 107 freeindex(act); 108 } 109 } 110 111 void 112 handlebin(int sock, char *file, char *port, char *base, char *args, 113 char *sear, char *ohost, char *chost, char *bhost, int istls) 114 { 115 int fd; 116 117 USED(port); 118 USED(base); 119 USED(args); 120 USED(sear); 121 USED(ohost); 122 USED(bhost); 123 124 fd = open(file, O_RDONLY); 125 if (fd >= 0) { 126 if (xsendfile(fd, sock) < 0) 127 perror("sendfile"); 128 close(fd); 129 } 130 } 131 132 void 133 handlecgi(int sock, char *file, char *port, char *base, char *args, 134 char *sear, char *ohost, char *chost, char *bhost, int istls) 135 { 136 char *p, *path; 137 138 USED(base); 139 USED(port); 140 141 path = xstrdup(file); 142 p = strrchr(path, '/'); 143 if (p != NULL) 144 p[1] = '\0'; 145 else { 146 free(path); 147 path = NULL; 148 } 149 150 p = strrchr(file, '/'); 151 if (p == NULL) 152 p = file; 153 154 if (sear == NULL) 155 sear = ""; 156 if (args == NULL) 157 args = ""; 158 159 dup2(sock, 0); 160 dup2(sock, 1); 161 dup2(sock, 2); 162 switch (fork()) { 163 case 0: 164 if (path != NULL) { 165 if (chdir(path) < 0) 166 break; 167 } 168 169 setcgienviron(p, file, port, base, args, sear, ohost, chost, 170 bhost, istls); 171 172 if (execl(file, p, sear, args, ohost, port, 173 (char *)NULL) == -1) { 174 perror("execl"); 175 _exit(1); 176 } 177 case -1: 178 perror("fork"); 179 break; 180 default: 181 wait(NULL); 182 free(path); 183 break; 184 } 185 } 186 187 void 188 handledcgi(int sock, char *file, char *port, char *base, char *args, 189 char *sear, char *ohost, char *chost, char *bhost, int istls) 190 { 191 FILE *fp; 192 char *p, *path, *ln = NULL; 193 size_t linesiz = 0; 194 ssize_t n; 195 int outpipe[2], ret = 0; 196 Elems *el; 197 198 if (pipe(outpipe) < 0) 199 return; 200 201 path = xstrdup(file); 202 p = strrchr(path, '/'); 203 if (p != NULL) 204 p[1] = '\0'; 205 else { 206 free(path); 207 path = NULL; 208 } 209 210 p = strrchr(file, '/'); 211 if (p == NULL) 212 p = file; 213 214 if (sear == NULL) 215 sear = ""; 216 if (args == NULL) 217 args = ""; 218 219 while (dup2(sock, 0) < 0 && errno == EINTR); 220 while (dup2(sock, 2) < 0 && errno == EINTR); 221 switch (fork()) { 222 case 0: 223 while(dup2(outpipe[1], 1) < 0 && errno == EINTR); 224 close(outpipe[0]); 225 if (path != NULL) { 226 if (chdir(path) < 0) 227 break; 228 } 229 230 setcgienviron(p, file, port, base, args, sear, ohost, chost, 231 bhost, istls); 232 233 if (execl(file, p, sear, args, ohost, port, 234 (char *)NULL) == -1) { 235 perror("execl"); 236 _exit(1); 237 } 238 break; 239 case -1: 240 perror("fork"); 241 break; 242 default: 243 while(dup2(sock, 1) < 0 && errno == EINTR); 244 close(outpipe[1]); 245 246 if (!(fp = fdopen(outpipe[0], "r"))) { 247 perror("fdopen"); 248 close(outpipe[0]); 249 break; 250 } 251 252 while ((n = getline(&ln, &linesiz, fp)) > 0 && ret >= 0) { 253 if (ln[n - 1] == '\n') 254 ln[--n] = '\0'; 255 256 el = getadv(ln); 257 if (el == NULL) 258 continue; 259 260 ret = printelem(sock, el, file, base, ohost, port); 261 freeelem(el); 262 } 263 if (ferror(fp)) 264 perror("getline"); 265 dprintf(sock, ".\r\n"); 266 267 free(ln); 268 free(path); 269 fclose(fp); 270 wait(NULL); 271 break; 272 } 273 } 274