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