Index: cgi.c =================================================================== RCS file: /cvs/roxen_src/extern/cgi.c,v retrieving revision 1.16 diff -C3 -r1.16 cgi.c *** cgi.c 1997/10/06 18:06:52 1.16 --- cgi.c 1998/05/08 17:29:12 *************** *** 1,9 **** #include #include #include #include #include - #include "../pike/src/machine.h" /* for MAX_OPEN_FILEDESCRIPTORS */ #ifdef HAVE_CONFIG_H #include "config.h" --- 1,29 ---- + /* + * $Id: cgi.c,v 1.28 1998/05/08 14:29:31 grubba Exp $ + * + * CGI-wrapper for Roxen. + * + * David Hedbor + * Per Hedbor + * Henrik Grubbström + * and others. + */ + + #ifdef HAVE_CONFIG_H + #include + #endif /* HAVE_CONFIG_H */ + #include + #ifdef HAVE_STRINGS_H + #include + #endif /* HAVE_STRINGS_H */ #include #include + #ifdef HAVE_SIGNAL_H + #include + #endif /* HAVE_SIGNAL_H */ #include #include #ifdef HAVE_CONFIG_H #include "config.h" *************** *** 42,49 **** #ifndef MAXPATHLEN # define MAXPATHLEN 2048 #endif ! #undef DEBUG #include --- 62,76 ---- #ifndef MAXPATHLEN # define MAXPATHLEN 2048 #endif + + #ifndef MAXHEADERLEN + /* maximum size of the header before sending and error message and + * killing the script. + */ + # define MAXHEADERLEN 32769 + #endif ! #define DEBUG #include *************** *** 70,76 **** --- 97,114 ---- fd_set writefd[1]; #endif + #define LONGHEADER "HTTP/1.0 500 Buggy CGI Script\r\n\ + Content-Type: text/html\r\n\r\n\ + CGI-script error \n\ +

CGI-script error

\n\ + The CGI script you accessed is not working correctly. It tried \n\ + to send too much header data (probably due to incorrect separation between \n\ + the headers and the body. Please notify the author of the script of this\n\ + problem.\n" + + + /* This is stdout from the CGI script */ int script; *************** *** 236,260 **** } #endif - int is_end_of_headers(char *s, int len) - { - if(!headers) - { - hsize = (len/1024+1)*1024; - headers = malloc(hsize); - hpointer = 0; - } else if(hsize <= hpointer+len) { - headers = my_realloc(headers, hsize*2, hsize); - hsize *= 2; - } - - movemem(headers+hpointer, s, len); - hpointer += len; - headers[hpointer] = 0; - - return (strstr(headers, "\n\n")||strstr(headers, "\r\n\r\n")||strstr(headers, "\n\r\n\r")); - } - void reaper(int i) { int status; --- 274,279 ---- *************** *** 283,295 **** close(script); signal(SIGCHLD, reaper); kill(pid, 1); /* HUP */ ! sleep(10); kill(pid, 13); /* PIPE */ ! sleep(10); kill(pid, 2); /* INT */ ! sleep(10); kill(pid, 15); /* TERM */ ! sleep(10); kill(pid, 9); /* KILL */ exit(0); } --- 302,314 ---- close(script); signal(SIGCHLD, reaper); kill(pid, 1); /* HUP */ ! sleep(3); kill(pid, 13); /* PIPE */ ! sleep(3); kill(pid, 2); /* INT */ ! sleep(3); kill(pid, 15); /* TERM */ ! sleep(3); kill(pid, 9); /* KILL */ exit(0); } *************** *** 320,329 **** } } while(re); } ! int parse_and_send_headers(void) { ! char *error, *pointer; if(headers) { if(((error=strstr(headers, "status:")) || --- 339,390 ---- } } while(re); } + + + char *is_end_of_headers(char *s, int len) + { + char *end_of_header; + + if(!headers) + { + hpointer = 0; + hsize = (len/1024+1)*1024; + headers = malloc(hsize); + if ((s[0] == '\r') || (s[0] == '\n')) { + /* No headers. */ + movemem(headers, s, len); + hpointer = len; + headers[hpointer] = 0; + return(headers); + } + } else if(hsize <= hpointer+len) { + headers = my_realloc(headers, (hpointer+len)*2+1, hsize); + hsize = (hpointer+len)*2; + } + if(hsize > MAXHEADERLEN) { + send_data(LONGHEADER, strlen(LONGHEADER)); + kill_kill_kill(); + } + + + movemem(headers + hpointer, s, len); + hpointer += len; + headers[hpointer] = 0; + + end_of_header = strstr(headers, "\r\n\r\n"); + if (!end_of_header) { + end_of_header = strstr(headers, "\n\n"); + } + if (!end_of_header) { + end_of_header = strstr(headers, "\n\r\n\r"); + } + return(end_of_header); + } ! ! void parse_and_send_headers(char *header_end) { ! char *error, *pointer = NULL; if(headers) { if(((error=strstr(headers, "status:")) || *************** *** 331,355 **** && error==headers) { char *tmp; pointer = error; ! while(*error!=' ') error++; ! while(*error==' ') error++; tmp=error; ! while(*tmp!='\n') tmp++; send_data("HTTP/1.0 ", 9); ! send_data(error, tmp-error+1); ! /* send_data(headers, pointer-headers);*/ ! send_data(tmp+1, hpointer-(tmp-headers)); free(headers); ! return 1; } ! if(strstr(headers, "Location:") || strstr(headers, "location:")) ! error = "HTTP/1.0 302 Document Found\n"; ! else ! error = "HTTP/1.0 200 Ok\n"; } else ! error = "HTTP/1.0 200 Ok\n"; send_data(error, strlen(error)); if(headers) --- 392,432 ---- && error==headers) { char *tmp; + int skip; pointer = error; ! while(*error!=' ' && *error != ':') error++; ! while(*error==' ' || *error == ':') error++; tmp=error; ! while(*tmp!='\n' && *tmp!='\r') tmp++; ! if ((*tmp == '\n' && tmp[1] == '\r') || ! (*tmp == '\r' && tmp[1] == '\n')) ! skip = 2; ! else ! skip = 1; send_data("HTTP/1.0 ", 9); ! send_data(error, tmp - error); ! send_data("\r\n", 2); ! /* send_data(headers, hpointer-headers);*/ ! send_data(tmp+skip, hpointer-(tmp+skip-headers)); free(headers); ! return; } ! if(((pointer = strstr(headers, "Location:")) && ! (!header_end || (pointer < header_end))) || ! ((pointer = strstr(headers, "location:")) && ! (!header_end || (pointer < header_end)))) { ! #ifdef DEBUG ! fprintf(stderr, "Redirect: pointer:%p, header_end:%p, headers:%p\n", ! pointer, header_end, headers); ! #endif /* DEBUG */ ! ! error = "HTTP/1.0 302 Redirect\r\n"; ! } else { ! error = "HTTP/1.0 200 Ok\r\n"; ! } } else ! error = "HTTP/1.0 200 Ok\r\n"; send_data(error, strlen(error)); if(headers) *************** *** 358,364 **** free(headers); } /* send_data("\n", 1);*/ ! return 1; } --- 435,441 ---- free(headers); } /* send_data("\n", 1);*/ ! return; } *************** *** 377,383 **** return !(strncmp(foo+len, "nph", 3)); } ! void main(int argc, char **argv) { int i; /* Insure that all filedecriptors except stdin, stdout and stderr are closed --- 454,460 ---- return !(strncmp(foo+len, "nph", 3)); } ! int main(int argc, char **argv) { int i; /* Insure that all filedecriptors except stdin, stdout and stderr are closed *************** *** 401,407 **** if(!getuid()) { int euid = geteuid(); int egid = getegid(); ! #ifdef HAVE_SETRESUID setresgid(egid, egid, -1); setresuid(euid, euid, -1); #else --- 478,484 ---- if(!getuid()) { int euid = geteuid(); int egid = getegid(); ! #if defined(HAVE_SETRESUID) && !defined(HAVE_SETEUID) setresgid(egid, egid, -1); setresuid(euid, euid, -1); #else *************** *** 442,468 **** char foo[2049], *bar; re = read(script, foo, 2048); - #ifdef DEBUG - foo[re]=0; - fprintf(stderr, "read %s\n", foo); - #endif if(re <= 0) { #ifdef DEBUG perror("read failed"); #endif ! if(!raw) parse_and_send_headers(); kill(pid, 9); close(0); close(1); close(2); exit(0); } bar=foo; if(!raw) { ! if(is_end_of_headers(foo, re)) ! raw = parse_and_send_headers(); } else send_data(bar, re); } --- 519,548 ---- char foo[2049], *bar; re = read(script, foo, 2048); if(re <= 0) { #ifdef DEBUG perror("read failed"); #endif ! if(!raw) parse_and_send_headers(NULL); kill(pid, 9); close(0); close(1); close(2); exit(0); } + foo[re]=0; + #ifdef DEBUG + fprintf(stderr, "read %s\n", foo); + #endif bar=foo; if(!raw) { ! char *header_end; ! if((header_end = is_end_of_headers(foo, re))) { ! parse_and_send_headers(header_end); ! raw = 1; ! } } else send_data(bar, re); }