/[hydra]/hydra/src/cgi.c
ViewVC logotype

Diff of /hydra/src/cgi.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.6 by nmav, Wed Sep 25 19:55:53 2002 UTC revision 1.7 by nmav, Wed Sep 25 22:10:03 2002 UTC
# Line 40  static char *common_cgi_env[COMMON_CGI_C Line 40  static char *common_cgi_env[COMMON_CGI_C
40    
41  void create_common_env()  void create_common_env()
42  {  {
43      int index = 0, i;     int index = 0, i;
44    
45    
46      /* NOTE NOTE NOTE:     /* NOTE NOTE NOTE:
47         If you (the reader) someday modify this chunk of code to        If you (the reader) someday modify this chunk of code to
48         handle more "common" CGI environment variables, then bump the        handle more "common" CGI environment variables, then bump the
49         value COMMON_CGI_COUNT in defines.h UP        value COMMON_CGI_COUNT in defines.h UP
50    
51         Also, in the case of document_root and server_admin, two variables        Also, in the case of document_root and server_admin, two variables
52         that may or may not be defined depending on the way the server        that may or may not be defined depending on the way the server
53         is configured, we check for null values and use an empty        is configured, we check for null values and use an empty
54         string to denote a NULL value to the environment, as per the        string to denote a NULL value to the environment, as per the
55         specification. The quote for which follows:        specification. The quote for which follows:
56    
57         "In all cases, a missing environment variable is        "In all cases, a missing environment variable is
58         equivalent to a zero-length (NULL) value, and vice versa."        equivalent to a zero-length (NULL) value, and vice versa."
59       */      */
60      common_cgi_env[index++] = env_gen_extra("PATH",     common_cgi_env[index++] = env_gen_extra("PATH",
61                                              ((cgi_path != NULL) ? cgi_path : DEFAULT_PATH), 0);                                             ((cgi_path !=
62      common_cgi_env[index++] = env_gen_extra("SERVER_SOFTWARE", SERVER_NAME"/"SERVER_VERSION, 0);                                               NULL) ? cgi_path :
63      common_cgi_env[index++] = env_gen_extra("GATEWAY_INTERFACE", CGI_VERSION, 0);                                              DEFAULT_PATH), 0);
64       common_cgi_env[index++] =
65      /* removed the SERVER_PORT which may change due to SSL support         env_gen_extra("SERVER_SOFTWARE", SERVER_NAME "/" SERVER_VERSION, 0);
66       * Also removed the DOCUMENT_ROOT, SERVER_NAME, which are now per request.     common_cgi_env[index++] =
67       */         env_gen_extra("GATEWAY_INTERFACE", CGI_VERSION, 0);
68    
69       /* removed the SERVER_PORT which may change due to SSL support
70      /* NCSA added */      * Also removed the DOCUMENT_ROOT, SERVER_NAME, which are now per request.
71      /* common_cgi_env[index++] = env_gen_extra("SERVER_ROOT", server_root); */      */
72    
73      /* APACHE added */  
74      common_cgi_env[index++] = env_gen_extra("SERVER_ADMIN", server_admin, 0);     /* NCSA added */
75      common_cgi_env[index] = NULL;     /* common_cgi_env[index++] = env_gen_extra("SERVER_ROOT", server_root); */
76    
77      /* Sanity checking -- make *sure* the memory got allocated */     /* APACHE added */
78      if (index > COMMON_CGI_COUNT) {     common_cgi_env[index++] =
79          log_error_time();         env_gen_extra("SERVER_ADMIN", server_admin, 0);
80          fprintf(stderr, "COMMON_CGI_COUNT not high enough.\n");     common_cgi_env[index] = NULL;
81          exit(1);  
82      }     /* Sanity checking -- make *sure* the memory got allocated */
83       if (index > COMMON_CGI_COUNT) {
84      for(i = 0;i < index;++i) {        log_error_time();
85          if (common_cgi_env[i] == NULL) {        fprintf(stderr, "COMMON_CGI_COUNT not high enough.\n");
86              log_error_time();        exit(1);
87              fprintf(stderr, "Unable to allocate a component of common_cgi_env - out of memory.\n");     }
88              exit(1);  
89          }     for (i = 0; i < index; ++i) {
90      }        if (common_cgi_env[i] == NULL) {
91             log_error_time();
92             fprintf(stderr,
93                     "Unable to allocate a component of common_cgi_env - out of memory.\n");
94             exit(1);
95          }
96       }
97  }  }
98    
99  void clear_common_env(void)  void clear_common_env(void)
100  {  {
101      int i;     int i;
102    
103      for(i = 0;i <= COMMON_CGI_COUNT;++i) {     for (i = 0; i <= COMMON_CGI_COUNT; ++i) {
104          if (common_cgi_env[i] != NULL) {        if (common_cgi_env[i] != NULL) {
105              free(common_cgi_env[i]);           free(common_cgi_env[i]);
106              common_cgi_env[i] = NULL;           common_cgi_env[i] = NULL;
107          }        }
108      }     }
109  }  }
110    
111  /*  /*
# Line 109  void clear_common_env(void) Line 115  void clear_common_env(void)
115   */   */
116  static char *env_gen_extra(const char *key, const char *value, int extra)  static char *env_gen_extra(const char *key, const char *value, int extra)
117  {  {
118      char *result;     char *result;
119      int key_len, value_len;     int key_len, value_len;
120    
121      if (value == NULL)          /* ServerAdmin may not be defined, eg */     if (value == NULL)           /* ServerAdmin may not be defined, eg */
122          value = "";        value = "";
123      key_len = strlen(key);     key_len = strlen(key);
124      value_len = strlen(value);     value_len = strlen(value);
125      /* leave room for '=' sign and null terminator */     /* leave room for '=' sign and null terminator */
126      result = malloc(extra + key_len + value_len + 2);     result = malloc(extra + key_len + value_len + 2);
127      if (result) {     if (result) {
128          memcpy(result + extra, key, key_len);        memcpy(result + extra, key, key_len);
129          *(result + extra + key_len) = '=';        *(result + extra + key_len) = '=';
130          memcpy(result + extra + key_len + 1, value, value_len);        memcpy(result + extra + key_len + 1, value, value_len);
131          *(result + extra + key_len + value_len + 1) = '\0';        *(result + extra + key_len + value_len + 1) = '\0';
132      } else {     } else {
133          log_error_time();        log_error_time();
134          perror("malloc");        perror("malloc");
135          log_error_time();        log_error_time();
136          fprintf(stderr,        fprintf(stderr,
137                  "tried to allocate (key=value) extra=%d: %s=%s\n",                "tried to allocate (key=value) extra=%d: %s=%s\n",
138                  extra, key, value);                extra, key, value);
139      }     }
140      return result;     return result;
141  }  }
142    
143  /*  /*
# Line 143  static char *env_gen_extra(const char *k Line 149  static char *env_gen_extra(const char *k
149    
150  int add_cgi_env(request * req, char *key, char *value, int http_prefix)  int add_cgi_env(request * req, char *key, char *value, int http_prefix)
151  {  {
152      char *p;     char *p;
153      int prefix_len;     int prefix_len;
154    
155      if (http_prefix) {     if (http_prefix) {
156          prefix_len = 5;        prefix_len = 5;
157      } else {     } else {
158          prefix_len = 0;        prefix_len = 0;
159      }     }
160    
161      if (req->cgi_env_index < CGI_ENV_MAX) {     if (req->cgi_env_index < CGI_ENV_MAX) {
162          p = env_gen_extra(key, value, prefix_len);        p = env_gen_extra(key, value, prefix_len);
163          if (!p) {        if (!p) {
164              log_error_time();           log_error_time();
165              fprintf(stderr, "Unable to generate additional CGI Environment"           fprintf(stderr, "Unable to generate additional CGI Environment"
166                      "variable -- ran out of memory!\n");                   "variable -- ran out of memory!\n");
167          }        }
168          if (prefix_len)        if (prefix_len)
169              memcpy(p, "HTTP_", 5);           memcpy(p, "HTTP_", 5);
170          req->cgi_env[req->cgi_env_index++] = p;        req->cgi_env[req->cgi_env_index++] = p;
171          return 1;        return 1;
172      } else {     } else {
173          log_error_time();        log_error_time();
174          fprintf(stderr, "Unable to generate additional CGI Environment"        fprintf(stderr, "Unable to generate additional CGI Environment"
175                  "variable -- not enough space!\n");                "variable -- not enough space!\n");
176      }     }
177      return 0;     return 0;
178  }  }
179    
180  #define my_add_cgi_env(req, key, value) { \  #define my_add_cgi_env(req, key, value) { \
# Line 185  int add_cgi_env(request * req, char *key Line 191  int add_cgi_env(request * req, char *key
191    
192  int complete_env(request * req)  int complete_env(request * req)
193  {  {
194      int i;     int i;
195      char buf[22];     char buf[22];
       
     for (i = 0; common_cgi_env[i]; i++)  
         req->cgi_env[i] = common_cgi_env[i];  
   
     {  
         char *w;  
         switch (req->method) {  
         case M_POST:  
             w = "POST";  
             break;  
         case M_HEAD:  
             w = "HEAD";  
             break;  
         case M_GET:  
             w = "GET";  
             break;  
         default:  
             w = "UNKNOWN";  
             break;  
         }  
         my_add_cgi_env(req, "REQUEST_METHOD", w);  
     }  
   
     if (req->secure) {  
        simple_itoa(ssl_port, buf);  
     } else {  
        simple_itoa(server_port, buf);  
     }  
     my_add_cgi_env( req, "SERVER_PORT", buf);  
     my_add_cgi_env( req, "SERVER_NAME", req->hostname);  
196    
197      /* NCSA and APACHE added -- not in CGI spec */     for (i = 0; common_cgi_env[i]; i++)
198      /* my_add_cgi_env( req, "DOCUMENT_ROOT", req->document_root); */        req->cgi_env[i] = common_cgi_env[i];
199    
200      my_add_cgi_env(req, "SERVER_ADDR", req->local_ip_addr);     {
201      my_add_cgi_env(req, "SERVER_PROTOCOL", req->http_version);        char *w;
202      my_add_cgi_env(req, "REQUEST_URI", req->request_uri);        switch (req->method) {
203          case M_POST:
204      if (req->path_info)           w = "POST";
205          my_add_cgi_env(req, "PATH_INFO", req->path_info);           break;
206          case M_HEAD:
207      if (req->path_translated)           w = "HEAD";
208          /* while path_translated depends on path_info,           break;
209           * there are cases when path_translated might        case M_GET:
210           * not exist when path_info does           w = "GET";
211           */           break;
212          my_add_cgi_env(req, "PATH_TRANSLATED", req->path_translated);        default:
213             w = "UNKNOWN";
214      my_add_cgi_env(req, "SCRIPT_NAME", req->script_name);           break;
215          }
216      if (req->query_string)        my_add_cgi_env(req, "REQUEST_METHOD", w);
217          my_add_cgi_env(req, "QUERY_STRING", req->query_string);     }
218      my_add_cgi_env(req, "REMOTE_ADDR", req->remote_ip_addr);  
219           if (req->secure) {
220      simple_itoa(req->remote_port, buf);        simple_itoa(ssl_port, buf);
221      my_add_cgi_env(req, "REMOTE_PORT", buf);     } else {
222          simple_itoa(server_port, buf);
223      if (req->method == M_POST) {     }
224              if (req->content_type) {     my_add_cgi_env(req, "SERVER_PORT", buf);
225                  my_add_cgi_env(req, "CONTENT_TYPE", req->content_type);     my_add_cgi_env(req, "SERVER_NAME", req->hostname);
226              } else {  
227                  my_add_cgi_env(req, "CONTENT_TYPE", default_type);     /* NCSA and APACHE added -- not in CGI spec */
228              }     /* my_add_cgi_env( req, "DOCUMENT_ROOT", req->document_root); */
229              if (req->content_length) {  
230                  my_add_cgi_env(req, "CONTENT_LENGTH", req->content_length);     my_add_cgi_env(req, "SERVER_ADDR", req->local_ip_addr);
231              }     my_add_cgi_env(req, "SERVER_PROTOCOL", req->http_version);
232          }     my_add_cgi_env(req, "REQUEST_URI", req->request_uri);
233    
234       if (req->path_info)
235          my_add_cgi_env(req, "PATH_INFO", req->path_info);
236    
237       if (req->path_translated)
238          /* while path_translated depends on path_info,
239           * there are cases when path_translated might
240           * not exist when path_info does
241           */
242          my_add_cgi_env(req, "PATH_TRANSLATED", req->path_translated);
243    
244       my_add_cgi_env(req, "SCRIPT_NAME", req->script_name);
245    
246       if (req->query_string)
247          my_add_cgi_env(req, "QUERY_STRING", req->query_string);
248       my_add_cgi_env(req, "REMOTE_ADDR", req->remote_ip_addr);
249    
250       simple_itoa(req->remote_port, buf);
251       my_add_cgi_env(req, "REMOTE_PORT", buf);
252    
253       if (req->method == M_POST) {
254          if (req->content_type) {
255             my_add_cgi_env(req, "CONTENT_TYPE", req->content_type);
256          } else {
257             my_add_cgi_env(req, "CONTENT_TYPE", default_type);
258          }
259          if (req->content_length) {
260             my_add_cgi_env(req, "CONTENT_LENGTH", req->content_length);
261          }
262       }
263  #ifdef ACCEPT_ON  #ifdef ACCEPT_ON
264      if (req->accept[0])     if (req->accept[0])
265          my_add_cgi_env(req, "HTTP_ACCEPT", req->accept);        my_add_cgi_env(req, "HTTP_ACCEPT", req->accept);
266  #endif  #endif
267    
268      if (req->cgi_env_index < CGI_ENV_MAX + 1) {     if (req->cgi_env_index < CGI_ENV_MAX + 1) {
269          req->cgi_env[req->cgi_env_index] = NULL; /* terminate */        req->cgi_env[req->cgi_env_index] = NULL;  /* terminate */
270          return 1;        return 1;
271      }     }
272      log_error_time();     log_error_time();
273      fprintf(stderr, "Not enough space in CGI environment for remainder"\     fprintf(stderr, "Not enough space in CGI environment for remainder"
274              " of variables.\n");             " of variables.\n");
275      return 0;     return 0;
276  }  }
277    
278  /*  /*
# Line 278  int complete_env(request * req) Line 284  int complete_env(request * req)
284    
285  void create_argv(request * req, char **aargv)  void create_argv(request * req, char **aargv)
286  {  {
287      char *p, *q, *r;     char *p, *q, *r;
288      int aargc;     int aargc;
289    
290      q = req->query_string;     q = req->query_string;
291      aargv[0] = req->pathname;     aargv[0] = req->pathname;
292    
293      /* here, we handle a special "indexed" query string.     /* here, we handle a special "indexed" query string.
294       * Taken from the CGI/1.1 SPEC:      * Taken from the CGI/1.1 SPEC:
295       * This is identified by a GET or HEAD request with a query string      * This is identified by a GET or HEAD request with a query string
296       * with no *unencoded* '=' in it.      * with no *unencoded* '=' in it.
297       * For such a request, I'm supposed to parse the search string      * For such a request, I'm supposed to parse the search string
298       * into words, according to the following rules:      * into words, according to the following rules:
299    
300         search-string = search-word *( "+" search-word )      search-string = search-word *( "+" search-word )
301         search-word   = 1*schar      search-word   = 1*schar
302         schar         = xunreserved | escaped | xreserved      schar         = xunreserved | escaped | xreserved
303         xunreserved   = alpha | digit | xsafe | extra      xunreserved   = alpha | digit | xsafe | extra
304         xsafe         = "$" | "-" | "_" | "."      xsafe         = "$" | "-" | "_" | "."
305         xreserved     = ";" | "/" | "?" | ":" | "@" | "&"      xreserved     = ";" | "/" | "?" | ":" | "@" | "&"
306    
307         After parsing, each word is URL-decoded, optionally encoded in a system      After parsing, each word is URL-decoded, optionally encoded in a system
308         defined manner, and then the argument list      defined manner, and then the argument list
309         is set to the list of words.      is set to the list of words.
310    
311    
312        Thus, schar is alpha|digit|"$"|"-"|"_"|"."|";"|"/"|"?"|":"|"@"|"&"      Thus, schar is alpha|digit|"$"|"-"|"_"|"."|";"|"/"|"?"|":"|"@"|"&"
313    
314        As of this writing, escape.pl escapes the following chars:      As of this writing, escape.pl escapes the following chars:
315    
316         "-", "_", ".", "!", "~", "*", "'", "(", ")",      "-", "_", ".", "!", "~", "*", "'", "(", ")",
317         "0".."9", "A".."Z", "a".."z",      "0".."9", "A".."Z", "a".."z",
318         ";", "/", "?", ":", "@", "&", "=", "+", "\$", ","      ";", "/", "?", ":", "@", "&", "=", "+", "\$", ","
319    
320        Which therefore means      Which therefore means
321         "=", "+", "~", "!", "*", "'", "(", ")", ","      "=", "+", "~", "!", "*", "'", "(", ")", ","
322         are *not* escaped and should be?      are *not* escaped and should be?
323        Wait, we don't do any escaping, and nor should we.      Wait, we don't do any escaping, and nor should we.
324        According to the RFC draft, we unescape and then re-escape      According to the RFC draft, we unescape and then re-escape
325        in a "system defined manner" (here: none).      in a "system defined manner" (here: none).
326    
327        The CGI/1.1 draft (03, latest is 1999???) is very unclear here.      The CGI/1.1 draft (03, latest is 1999???) is very unclear here.
328    
329        I am using the latest published RFC, 2396, for what does and does      I am using the latest published RFC, 2396, for what does and does
330        not need escaping.      not need escaping.
331    
332        Since boa builds the argument list and does not call /bin/sh,      Since boa builds the argument list and does not call /bin/sh,
333        (boa uses execve for CGI)      (boa uses execve for CGI)
334       */      */
335    
336      if (q && !strchr(q, '=')) {     if (q && !strchr(q, '=')) {
337          /* we have an 'index' style */        /* we have an 'index' style */
338          q = strdup(q);        q = strdup(q);
339          if (!q) {        if (!q) {
340              WARN("unable to strdup 'q' in create_argv!");           WARN("unable to strdup 'q' in create_argv!");
341          }        }
342          for (aargc = 1; q && (aargc < CGI_ARGC_MAX);) {        for (aargc = 1; q && (aargc < CGI_ARGC_MAX);) {
343              r = q;           r = q;
344              /* for an index-style CGI, + is used to seperate arguments           /* for an index-style CGI, + is used to seperate arguments
345               * an escaped '+' is of no concern to us            * an escaped '+' is of no concern to us
346               */            */
347              if ((p = strchr(q, '+'))) {           if ((p = strchr(q, '+'))) {
348                  *p = '\0';              *p = '\0';
349                  q = p + 1;              q = p + 1;
350              } else {           } else {
351                  q = NULL;              q = NULL;
352              }           }
353              if (unescape_uri(r, NULL)) {           if (unescape_uri(r, NULL)) {
354                  /* printf("parameter %d: %s\n",aargc,r); */              /* printf("parameter %d: %s\n",aargc,r); */
355                  aargv[aargc++] = r;              aargv[aargc++] = r;
356              }           }
357          }        }
358          aargv[aargc] = NULL;        aargv[aargc] = NULL;
359      } else {     } else {
360          aargv[1] = NULL;        aargv[1] = NULL;
361      }     }
362  }  }
363    
364  /*  /*
365   * Name: init_cgi   * Name: init_cgi
366   *   *
367   * Description: Called for GET/POST requests that refer to ScriptAlias   * Description: Called for GET/POST requests that refer to ScriptAlias
368   * directories or application/x-httpd-cgi files.  Ties stdout to socket,   * directories or application/x-httpd-cgi files.  Pipes are used for the
369   * stdin to data if POST, and execs CGI.   * communication with the child.
370   * stderr remains tied to our log file; is this good?   * stderr remains tied to our log file; is this good?
371   *   *
372   * Returns:   * Returns:
# Line 370  void create_argv(request * req, char **a Line 376  void create_argv(request * req, char **a
376    
377  int init_cgi(request * req)  int init_cgi(request * req)
378  {  {
379      int child_pid;     int child_pid;
380      int pipes[2];     int pipes[2];
381      int use_pipes = 0;  
382       SQUASH_KA(req);
383      SQUASH_KA(req);  
384       if (req->is_cgi == NPH || req->is_cgi == CGI) {
385      if (req->is_cgi==NPH || req->is_cgi==CGI) {        if (complete_env(req) == 0) {
386          if (complete_env(req) == 0) {           return 0;
387              return 0;        }
388          }     }
     }  
389  #ifdef FASCIST_LOGGING  #ifdef FASCIST_LOGGING
390      {     {
391          int i;        int i;
392          for (i = 0; i < req->cgi_env_index; ++i)        for (i = 0; i < req->cgi_env_index; ++i)
393              fprintf(stderr, "%s - environment variable for cgi: \"%s\"\n",           fprintf(stderr, "%s - environment variable for cgi: \"%s\"\n",
394                      __FILE__, req->cgi_env[i]);                   __FILE__, req->cgi_env[i]);
395      }     }
396  #endif  #endif
397    
398      if (req->is_cgi) {     if (req->is_cgi) {
399          use_pipes = 1;        if (pipe(pipes) == -1) {
400          if (pipe(pipes) == -1) {           log_error_time();
401              log_error_time();           perror("pipe");
402              perror("pipe");           return 0;
403              return 0;        }
404          }  
405          /* set the read end of the socket to non-blocking */
406          /* set the read end of the socket to non-blocking */        if (set_nonblock_fd(pipes[0]) == -1) {
407          if (set_nonblock_fd(pipes[0]) == -1) {           log_error_time();
408              log_error_time();           perror("cgi-fcntl");
409              perror("cgi-fcntl");           close(pipes[0]);
410              close(pipes[0]);           close(pipes[1]);
411              close(pipes[1]);           return 0;
412              return 0;        }
413          }     } else {
414      } else {        log_error_time();
415          log_error_time();        fprintf(stderr, "Non CGI in init_cgi()!\n");
416          fprintf(stderr, "Non CGI in init_cgi()!\n");        return 0;
417          return 0;     }
418      }  
419       child_pid = fork();
420      child_pid = fork();     switch (child_pid) {
421      switch(child_pid) {     case -1:
422      case -1:        /* fork unsuccessful */
423          /* fork unsuccessful */        log_error_time();
424          log_error_time();        perror("fork");
425          perror("fork");  
426          close(pipes[0]);
427          if (use_pipes) {        close(pipes[1]);
428              close(pipes[0]);  
429              close(pipes[1]);        send_r_error(req);
430          }        /* FIXME: There is aproblem here. send_r_error would work
431          send_r_error(req);           for NPH and CGI, but not for GUNZIP.  Fix that. */
432          /* FIXME: There is aproblem here. send_r_error would work        /* i'd like to send_r_error, but.... */
433             for NPH and CGI, but not for GUNZIP.  Fix that. */        return 0;
434          /* i'd like to send_r_error, but.... */        break;
435          return 0;     case 0:
436          break;        /* child */
437      case 0:        if (req->is_cgi == CGI || req->is_cgi == NPH) {
438          /* child */           char *foo = strdup(req->pathname);
439          if (req->is_cgi == CGI || req->is_cgi == NPH) {           char *c;
440              char *foo = strdup(req->pathname);  
441              char *c;           if (!foo) {
442                WARN("unable to strdup pathname for req->pathname");
443              if (!foo) {              _exit(1);
444                  WARN("unable to strdup pathname for req->pathname");           }
445                  _exit(1);           c = strrchr(foo, '/');
446              }           if (c) {
447              c = strrchr(foo, '/');              ++c;
448              if (c) {              *c = '\0';
449                  ++c;           } else {
450                  *c = '\0';              /* we have a serious problem */
451              } else {              log_error_time();
452                  /* we have a serious problem */              perror("chdir");
453                  log_error_time();              close(pipes[1]);
454                  perror("chdir");              _exit(1);
455                  if (use_pipes)           }
456                      close(pipes[1]);           if (chdir(foo) != 0) {
457                  _exit(1);              log_error_time();
458              }              perror("chdir");
459              if (chdir(foo) != 0) {              close(pipes[1]);
460                  log_error_time();              _exit(1);
461                  perror("chdir");           }
462                  if (use_pipes)        }
463                      close(pipes[1]);        close(pipes[0]);
464                  _exit(1);        /* tie cgi's STDOUT to it's write end of pipe */
465              }        if (dup2(pipes[1], STDOUT_FILENO) == -1) {
466          }           log_error_time();
467          if (use_pipes) {           perror("dup2 - pipes");
468              close(pipes[0]);           close(pipes[1]);
469              /* tie cgi's STDOUT to it's write end of pipe */           _exit(1);
470              if (dup2(pipes[1], STDOUT_FILENO) == -1) {        }
471                  log_error_time();        close(pipes[1]);
472                  perror("dup2 - pipes");        if (set_block_fd(STDOUT_FILENO) == -1) {
473                  close(pipes[1]);           log_error_time();
474                  _exit(1);           perror("cgi-fcntl");
475              }           _exit(1);
476              close(pipes[1]);        }
477              if (set_block_fd(STDOUT_FILENO) == -1) {  
478                  log_error_time();        /* tie post_data_fd to POST stdin */
479                  perror("cgi-fcntl");        if (req->method == M_POST) {      /* tie stdin to file */
480                  _exit(1);           lseek(req->post_data_fd, SEEK_SET, 0);
481              }           dup2(req->post_data_fd, STDIN_FILENO);
482          } else {           close(req->post_data_fd);
483              /* tie stdout to socket */        }
484              if (dup2(req->fd, STDOUT_FILENO) == -1) {        /* Close access log, so CGI program can't scribble
485                  log_error_time();         * where it shouldn't
486                  perror("dup2 - fd");         */
487                  _exit(1);        close_access_log();
488              }  
489              /* Switch socket flags back to blocking */        /*
490              if (set_block_fd(req->fd) == -1) {         * tie STDERR to cgi_log_fd
491                  log_error_time();         * cgi_log_fd will automatically close, close-on-exec rocks!
492                  perror("cgi-fcntl");         * if we don't tied STDERR (current log_error) to cgi_log_fd,
493                  _exit(1);         *  then we ought to close it.
494              }         */
495          }        if (!cgi_log_fd)
496          /* tie post_data_fd to POST stdin */           dup2(devnullfd, STDERR_FILENO);
497          if (req->method == M_POST) { /* tie stdin to file */        else
498              lseek(req->post_data_fd, SEEK_SET, 0);           dup2(cgi_log_fd, STDERR_FILENO);
499              dup2(req->post_data_fd, STDIN_FILENO);  
500              close(req->post_data_fd);        if (req->is_cgi == NPH || req->is_cgi == CGI) {
501          }           char *aargv[CGI_ARGC_MAX + 1];
502          /* Close access log, so CGI program can't scribble           create_argv(req, aargv);
503           * where it shouldn't           execve(req->pathname, aargv, req->cgi_env);
504           */        } else {
505          close_access_log();           if (req->is_cgi == INDEXER_CGI)
506                execl(dirmaker, dirmaker, req->pathname, req->request_uri,
507          /*                    NULL);
508           * tie STDERR to cgi_log_fd        }
509           * cgi_log_fd will automatically close, close-on-exec rocks!        /* execve failed */
510           * if we don't tied STDERR (current log_error) to cgi_log_fd,        WARN(req->pathname);
511           *  then we ought to close it.        _exit(1);
512           */        break;
513          if (!cgi_log_fd)  
514              dup2(devnullfd, STDERR_FILENO);     default:
515          else        /* parent */
516              dup2(cgi_log_fd, STDERR_FILENO);        /* if here, fork was successful */
517          if (verbose_cgi_logs) {
518          if (req->is_cgi==NPH || req->is_cgi==CGI) {           log_error_time();
519              char *aargv[CGI_ARGC_MAX + 1];           fprintf(stderr, "Forked child \"%s\" pid %d\n",
520              create_argv(req, aargv);                   req->pathname, child_pid);
521              execve(req->pathname, aargv, req->cgi_env);        }
522          } else {  
523              if (req->is_cgi==INDEXER_CGI)        if (req->method == M_POST) {
524                  execl(dirmaker, dirmaker, req->pathname, req->request_uri,           close(req->post_data_fd);      /* child closed it too */
525                        NULL);           req->post_data_fd = 0;
526          }        }
527          /* execve failed */  
528          WARN(req->pathname);        /* NPH, etc... all go straight to the fd */
529          _exit(1);  
530          break;        close(pipes[1]);
531          req->data_fd = pipes[0];
532      default:  
533          /* parent */        req->status = PIPE_READ;
534          /* if here, fork was successful */        if (req->is_cgi == CGI) {
535          if (verbose_cgi_logs) {           req->cgi_status = CGI_PARSE;   /* got to parse cgi header */
536              log_error_time();           /* for cgi_header... I get half the buffer! */
537              fprintf(stderr, "Forked child \"%s\" pid %d\n",           req->header_line = req->header_end =
538                      req->pathname, child_pid);               (req->buffer + BUFFER_SIZE / 2);
539          }        } else {
540             req->cgi_status = CGI_BUFFER;
541          if (req->method == M_POST) {           /* I get all the buffer! */
542              close(req->post_data_fd); /* child closed it too */           req->header_line = req->header_end = req->buffer;
543              req->post_data_fd = 0;        }
544          }  
545          /* reset req->filepos for logging (it's used in pipe.c) */
546          /* NPH, GUNZIP, etc... all go straight to the fd */        /* still don't know why req->filesize might be reset though */
547          if (!use_pipes)        req->filepos = 0;
548              return 0;        break;
549       }
         close(pipes[1]);  
         req->data_fd = pipes[0];  
   
         req->status = PIPE_READ;  
         if (req->is_cgi == CGI) {  
             req->cgi_status = CGI_PARSE; /* got to parse cgi header */  
             /* for cgi_header... I get half the buffer! */  
             req->header_line = req->header_end =  
                 (req->buffer + BUFFER_SIZE / 2);  
         } else {  
             req->cgi_status = CGI_BUFFER;  
             /* I get all the buffer! */  
             req->header_line = req->header_end = req->buffer;  
         }  
   
         /* reset req->filepos for logging (it's used in pipe.c) */  
         /* still don't know why req->filesize might be reset though */  
         req->filepos = 0;  
         break;  
     }  
550    
551      return 1;     return 1;
552  }  }

Legend:
Removed from v.1.6  
changed lines
  Added in v.1.7

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26