1 /*
2  * $Id: fcgi.h,v 1.48 2008/09/22 10:36:06 robs Exp $
3  */
4 
5 #ifndef FCGI_H
6 #define FCGI_H
7 
8 #if defined(DEBUG) && ! defined(NDEBUG)
9 #define ASSERT(a) ap_assert(a)
10 #else
11 #define ASSERT(a) ((void) 0)
12 #endif
13 
14 #ifdef WIN32
15 /* warning C4115: named type definition in parentheses */
16 #pragma warning(disable : 4115)
17 /* warning C4514: unreferenced inline function has been removed */
18 #pragma warning(disable:4514)
19 #endif
20 
21 /* Apache header files */
22 #include "httpd.h"
23 #include "http_config.h"
24 #include "http_request.h"
25 #include "http_core.h"
26 #include "http_protocol.h"
27 #include "http_main.h"
28 #include "http_log.h"
29 #include "util_script.h"
30 #include "util_md5.h"
31 
32 /* AP2TODO there's probably a better way */
33 #ifdef STANDARD20_MODULE_STUFF
34 #define APACHE2
35 #endif
36 
37 #ifdef APACHE2
38 
39 #include <sys/stat.h>
40 #include "ap_compat.h"
41 #include "apr_strings.h"
42 
43 #ifdef WIN32
44 #if MODULE_MAGIC_NUMBER < 20020903
45 #error "mod_fastcgi is incompatible with Apache versions older than 2.0.41 under WIN"
46 #endif
47 #endif
48 
49 typedef struct apr_array_header_t array_header;
50 typedef struct apr_table_t table;
51 typedef struct apr_pool_t pool;
52 #define NET_SIZE_T apr_socklen_t
53 
54 typedef apr_status_t apcb_t;
55 #define APCB_OK APR_SUCCESS
56 
57 #define XtOffsetOf APR_OFFSETOF
58 #define ap_select select
59 
60 #if MODULE_MAGIC_NUMBER < 20081212
61 #define ap_unixd_config unixd_config
62 #endif
63 
64 #define ap_user_id        ap_unixd_config.user_id
65 #define ap_group_id       ap_unixd_config.group_id
66 #define ap_user_name      ap_unixd_config.user_name
67 #define ap_suexec_enabled ap_unixd_config.suexec_enabled
68 
69 #ifndef S_ISDIR
70 #define S_ISDIR(m)      (((m)&(S_IFMT)) == (S_IFDIR))
71 #endif
72 
73 /* obsolete fns */
74 #define ap_hard_timeout(a,b)
75 #define ap_kill_timeout(a)
76 #define ap_block_alarms()
77 #define ap_reset_timeout(a)
78 #define ap_unblock_alarms()
79 
80 /* starting with apache 2.2 the backward-compatibility defines for
81  * 1.3 APIs are not available anymore. Define them ourselves here.
82  */
83 #ifndef ap_copy_table
84 
85 #define ap_copy_table apr_table_copy
86 #define ap_cpystrn apr_cpystrn
87 #define ap_destroy_pool apr_pool_destroy
88 #define ap_isalnum apr_isalnum
89 #define ap_isspace apr_isspace
90 #define ap_make_array apr_array_make
91 #define ap_make_table apr_table_make
92 #define ap_null_cleanup apr_pool_cleanup_null
93 #define ap_palloc apr_palloc
94 #define ap_pcalloc apr_pcalloc
95 #define ap_psprintf apr_psprintf
96 #define ap_pstrcat apr_pstrcat
97 #define ap_pstrdup apr_pstrdup
98 #define ap_pstrndup apr_pstrndup
99 #define ap_push_array apr_array_push
100 #define ap_register_cleanup apr_pool_cleanup_register
101 #define ap_snprintf apr_snprintf
102 #define ap_table_add apr_table_add
103 #define ap_table_do apr_table_do
104 #define ap_table_get apr_table_get
105 #define ap_table_set apr_table_set
106 #define ap_table_setn apr_table_setn
107 #define ap_table_unset apr_table_unset
108 #define ap_toupper apr_toupper
109 
110 #endif /* defined(ap_copy_table) */
111 
112 #if (defined(HAVE_WRITEV) && !HAVE_WRITEV && !defined(NO_WRITEV)) || defined WIN32
113 #define NO_WRITEV
114 #endif
115 
116 #else /* !APACHE2 */
117 
118 #include "http_conf_globals.h"
119 typedef void apcb_t;
120 #define APCB_OK
121 
122 #if MODULE_MAGIC_NUMBER < 19990320
123 #error "This version of mod_fastcgi is incompatible with Apache versions older than 1.3.6."
124 #endif
125 
126 #endif /* !APACHE2 */
127 
128 #ifndef NO_WRITEV
129 #include <sys/uio.h>
130 #endif
131 
132 #ifdef WIN32
133 #ifndef APACHE2
134 #include "multithread.h"
135 #endif
136 #pragma warning(default : 4115)
137 #else
138 #include <sys/un.h>
139 #endif
140 
141 /* FastCGI header files */
142 #include "mod_fastcgi.h"
143 /* @@@ This should go away when fcgi_protocol is re-written */
144 #include "fcgi_protocol.h"
145 
146 typedef struct {
147     int size;               /* size of entire buffer */
148     int length;             /* number of bytes in current buffer */
149     char *begin;            /* begining of valid data */
150     char *end;              /* end of valid data */
151     char data[1];           /* buffer data */
152 } Buffer;
153 
154 #ifdef WIN32
155 #define READER 0
156 #define WRITER 1
157 
158 #define MBOX_EVENT 0   /* mboc is ready to be read */
159 #define TERM_EVENT 1   /* termination event */
160 #define WAKE_EVENT 2   /* notification of child Fserver dieing */
161 
162 typedef struct _fcgi_pm_job {
163     char id;
164     char *fs_path;
165     char *user;
166     char * group;
167     unsigned long qsec;
168     unsigned long start_time;
169     struct _fcgi_pm_job *next;
170 } fcgi_pm_job;
171 #endif
172 
173 enum process_state {
174     FCGI_RUNNING_STATE,             /* currently running */
175     FCGI_START_STATE,               /* needs to be started by PM */
176     FCGI_VICTIM_STATE,              /* SIGTERM was sent by PM */
177     FCGI_KILLED_STATE,              /* a wait() collected VICTIM */
178     FCGI_READY_STATE                /* empty cell, init state */
179 };
180 
181 /*
182  * ServerProcess holds data for each process associated with
183  * a class.  It is embedded in fcgi_server below.
184  */
185 typedef struct _FcgiProcessInfo {
186 #ifdef WIN32
187     HANDLE handle;                   /* process handle */
188     HANDLE terminationEvent;         /* Event used to signal process termination */
189 #endif
190     pid_t pid;                       /* pid of associated process */
191     enum process_state state;        /* state of the process */
192     time_t start_time;               /* time the process was started */
193 } ServerProcess;
194 
195 /*
196  * fcgi_server holds info for each AppClass specified in this
197  * Web server's configuration.
198  */
199 typedef struct _FastCgiServerInfo {
200     int flush;
201     char *fs_path;                  /* pathname of executable */
202     array_header *pass_headers;     /* names of headers to pass in the env */
203     u_int idle_timeout;             /* fs idle secs allowed before aborting */
204     char **envp;                    /* if NOT NULL, this is the env to send
205                                      * to the fcgi app when starting a server
206                                      * managed app. */
207     u_int listenQueueDepth;         /* size of listen queue for IPC */
208     u_int appConnectTimeout;        /* timeout (sec) for connect() requests */
209     u_int numProcesses;             /* max allowed processes of this class,
210                                      * or for dynamic apps, the number of
211                                      * processes actually running */
212     time_t startTime;               /* the time the application was started */
213     time_t restartTime;             /* most recent time when the process
214                                      * manager started a process in this
215                                      * class. */
216     int initStartDelay;             /* min number of seconds to wait between
217                                      * starting of AppClass processes at init */
218     u_int restartDelay;             /* number of seconds to wait between
219                                      * restarts after failure.  Can be zero. */
220     u_int minServerLife;            /* minimum number of seconds a server must
221                                      * live before it's considered borked. */
222     int restartOnExit;              /* = TRUE = restart. else terminate/free */
223     u_int numFailures;              /* num restarts due to exit failure */
224     int bad;                        /* is [not] having start problems */
225     struct sockaddr *socket_addr;   /* Socket Address of FCGI app server class */
226 #ifdef WIN32
227     struct sockaddr *dest_addr;     /* for local apps on NT need socket address */
228                                     /* bound to localhost */
229     const char *mutex_env_string;   /* string holding the accept mutex handle */
230 #endif
231     int socket_addr_len;            /* Length of socket */
232     enum {APP_CLASS_UNKNOWN,
233           APP_CLASS_STANDARD,
234           APP_CLASS_EXTERNAL,
235           APP_CLASS_DYNAMIC}
236          directive;                 /* AppClass or ExternalAppClass */
237     const char *socket_path;        /* Name used to create a socket */
238     const char *host;               /* Hostname for externally managed
239                                      * FastCGI application processes */
240     unsigned short port;            /* Port number either for externally
241                                      * managed FastCGI applications or for
242                                      * server managed FastCGI applications,
243                                      * where server became application mngr. */
244     int listenFd;                   /* Listener socket of FCGI app server
245                                      * class.  Passed to app server process
246                                      * at process creation. */
247     u_int processPriority;          /* If locally server managed process,
248                                      * this is the priority to run the
249                                      * processes in this class at. */
250     struct _FcgiProcessInfo *procs; /* Pointer to array of
251                                      * processes belonging to this class. */
252     int keepConnection;             /* = 1 = maintain connection to app. */
253     uid_t uid;                      /* uid this app should run as (suexec) */
254     gid_t gid;                      /* gid this app should run as (suexec) */
255     const char *username;           /* suexec user arg */
256     const char *group;              /* suexec group arg, AND used in comm
257                                      * between RH and PM */
258     const char *user;               /* used in comm between RH and PM */
259     /* Dynamic FastCGI apps configuration parameters */
260     u_long totalConnTime;           /* microseconds spent by the web server
261                                      * waiting while fastcgi app performs
262                                      * request processing since the last
263                                      * dynamicUpdateInterval */
264     u_long smoothConnTime;          /* exponentially decayed values of the
265                                      * connection times. */
266     u_long totalQueueTime;          /* microseconds spent by the web server
267                                      * waiting to connect to the fastcgi app
268                                      * since the last dynamicUpdateInterval. */
269     int nph;
270     struct _FastCgiServerInfo *next;
271 } fcgi_server;
272 
273 
274 /*
275  * fcgi_request holds the state of a particular FastCGI request.
276  */
277 typedef struct {
278 #ifdef WIN32
279     SOCKET fd;
280 #else
281     int fd;                         /* connection to FastCGI server */
282 #endif
283     int gotHeader;                  /* TRUE if reading content bytes */
284     unsigned char packetType;       /* type of packet */
285     int dataLen;                    /* length of data bytes */
286     int paddingLen;                 /* record padding after content */
287     fcgi_server *fs;                /* FastCGI server info */
288     const char *fs_path;         /* fcgi_server path */
289     Buffer *serverInputBuffer;   /* input buffer from FastCgi server */
290     Buffer *serverOutputBuffer;  /* output buffer to FastCgi server */
291     Buffer *clientInputBuffer;   /* client input buffer */
292     Buffer *clientOutputBuffer;  /* client output buffer */
293     table *authHeaders;          /* headers received from an auth fs */
294     int auth_compat;             /* whether the auth request is spec compat */
295     table *saved_subprocess_env; /* subprocess_env before auth handling */
296     int expectingClientContent;     /* >0 => more content, <=0 => no more */
297     array_header *header;
298     char *fs_stderr;
299     int fs_stderr_len;
300     int parseHeader;                /* TRUE iff parsing response headers */
301     request_rec *r;
302     int readingEndRequestBody;
303     FCGI_EndRequestBody endRequestBody;
304     Buffer *erBufPtr;
305     int exitStatus;
306     int exitStatusSet;
307     unsigned int requestId;
308     int eofSent;
309     int role;                       /* FastCGI Role: Authorizer or Responder */
310     int dynamic;                    /* whether or not this is a dynamic app */
311     struct timeval startTime;       /* dynamic app's connect() attempt start time */
312     struct timeval queueTime;       /* dynamic app's connect() complete time */
313     struct timeval completeTime;    /* dynamic app's connection close() time */
314     int keepReadingFromFcgiApp;     /* still more to read from fcgi app? */
315     const char *user;               /* user used to invoke app (suexec) */
316     const char *group;              /* group used to invoke app (suexec) */
317 #ifdef WIN32
318     BOOL using_npipe_io;             /* named pipe io */
319 #endif
320     int nph;
321 } fcgi_request;
322 
323 /* Values of parseHeader field */
324 #define SCAN_CGI_READING_HEADERS 1
325 #define SCAN_CGI_FINISHED        0
326 #define SCAN_CGI_BAD_HEADER     -1
327 #define SCAN_CGI_INT_REDIRECT   -2
328 #define SCAN_CGI_SRV_REDIRECT   -3
329 
330 /* Opcodes for Server->ProcMgr communication */
331 #define FCGI_SERVER_START_JOB     83        /* 'S' - start */
332 #define FCGI_SERVER_RESTART_JOB   82        /* 'R' - restart */
333 #define FCGI_REQUEST_TIMEOUT_JOB  84        /* 'T' - timeout */
334 #define FCGI_REQUEST_COMPLETE_JOB 67        /* 'C' - complete */
335 
336 /* Authorizer types, for auth directives handling */
337 #define FCGI_AUTH_TYPE_AUTHENTICATOR  0
338 #define FCGI_AUTH_TYPE_AUTHORIZER     1
339 #define FCGI_AUTH_TYPE_ACCESS_CHECKER 2
340 
341 /* Bits for auth_options */
342 #define FCGI_AUTHORITATIVE 1
343 #define FCGI_COMPAT 2
344 
345 typedef struct
346 {
347     const char *authorizer;
348     u_char authorizer_options;
349     const char *authenticator;
350     u_char authenticator_options;
351     const char *access_checker;
352     u_char access_checker_options;
353 } fcgi_dir_config;
354 
355 #define FCGI_OK     0
356 #define FCGI_FAILED 1
357 
358 #ifdef APACHE2
359 
360 #ifdef WIN32
361 #define FCGI_LOG_EMERG          APLOG_MARK,APLOG_EMERG,APR_FROM_OS_ERROR(GetLastError())
362 #define FCGI_LOG_ALERT          APLOG_MARK,APLOG_ALERT,APR_FROM_OS_ERROR(GetLastError())
363 #define FCGI_LOG_CRIT           APLOG_MARK,APLOG_CRIT,APR_FROM_OS_ERROR(GetLastError())
364 #define FCGI_LOG_ERR            APLOG_MARK,APLOG_ERR,APR_FROM_OS_ERROR(GetLastError())
365 #define FCGI_LOG_WARN           APLOG_MARK,APLOG_WARNING,APR_FROM_OS_ERROR(GetLastError())
366 #define FCGI_LOG_NOTICE         APLOG_MARK,APLOG_NOTICE,APR_FROM_OS_ERROR(GetLastError())
367 #define FCGI_LOG_INFO           APLOG_MARK,APLOG_INFO,APR_FROM_OS_ERROR(GetLastError())
368 #define FCGI_LOG_DEBUG          APLOG_MARK,APLOG_DEBUG,APR_FROM_OS_ERROR(GetLastError())
369 #else /* !WIN32 */
370 #define FCGI_LOG_EMERG          APLOG_MARK,APLOG_EMERG,APR_FROM_OS_ERROR(errno)
371 #define FCGI_LOG_ALERT          APLOG_MARK,APLOG_ALERT,APR_FROM_OS_ERROR(errno)
372 #define FCGI_LOG_CRIT           APLOG_MARK,APLOG_CRIT,APR_FROM_OS_ERROR(errno)
373 #define FCGI_LOG_ERR            APLOG_MARK,APLOG_ERR,APR_FROM_OS_ERROR(errno)
374 #define FCGI_LOG_WARN           APLOG_MARK,APLOG_WARNING,APR_FROM_OS_ERROR(errno)
375 #define FCGI_LOG_NOTICE         APLOG_MARK,APLOG_NOTICE,APR_FROM_OS_ERROR(errno)
376 #define FCGI_LOG_INFO           APLOG_MARK,APLOG_INFO,APR_FROM_OS_ERROR(errno)
377 #define FCGI_LOG_DEBUG          APLOG_MARK,APLOG_DEBUG,APR_FROM_OS_ERROR(errno)
378 #endif
379 
380 #define FCGI_LOG_EMERG_ERRNO    APLOG_MARK,APLOG_EMERG,APR_FROM_OS_ERROR(errno)
381 #define FCGI_LOG_ALERT_ERRNO    APLOG_MARK,APLOG_ALERT,APR_FROM_OS_ERROR(errno)
382 #define FCGI_LOG_CRIT_ERRNO     APLOG_MARK,APLOG_CRIT,APR_FROM_OS_ERROR(errno)
383 #define FCGI_LOG_ERR_ERRNO      APLOG_MARK,APLOG_ERR,APR_FROM_OS_ERROR(errno)
384 #define FCGI_LOG_WARN_ERRNO     APLOG_MARK,APLOG_WARNING,APR_FROM_OS_ERROR(errno)
385 #define FCGI_LOG_NOTICE_ERRNO   APLOG_MARK,APLOG_NOTICE,APR_FROM_OS_ERROR(errno)
386 #define FCGI_LOG_INFO_ERRNO     APLOG_MARK,APLOG_INFO,APR_FROM_OS_ERROR(errno)
387 #define FCGI_LOG_DEBUG_ERRNO    APLOG_MARK,APLOG_DEBUG,APR_FROM_OS_ERROR(errno)
388 
389 #define FCGI_LOG_EMERG_NOERRNO    APLOG_MARK,APLOG_EMERG,0
390 #define FCGI_LOG_ALERT_NOERRNO    APLOG_MARK,APLOG_ALERT,0
391 #define FCGI_LOG_CRIT_NOERRNO     APLOG_MARK,APLOG_CRIT,0
392 #define FCGI_LOG_ERR_NOERRNO      APLOG_MARK,APLOG_ERR,0
393 #define FCGI_LOG_WARN_NOERRNO     APLOG_MARK,APLOG_WARNING,0
394 #define FCGI_LOG_NOTICE_NOERRNO   APLOG_MARK,APLOG_NOTICE,0
395 #define FCGI_LOG_INFO_NOERRNO     APLOG_MARK,APLOG_INFO,0
396 #define FCGI_LOG_DEBUG_NOERRNO    APLOG_MARK,APLOG_DEBUG,0
397 
398 #else /* !APACHE2 */
399 
400 #ifdef WIN32
401 #define FCGI_LOG_EMERG          __FILE__,__LINE__,APLOG_EMERG|APLOG_WIN32ERROR
402 #define FCGI_LOG_ALERT          __FILE__,__LINE__,APLOG_ALERT|APLOG_WIN32ERROR
403 #define FCGI_LOG_CRIT           __FILE__,__LINE__,APLOG_CRIT|APLOG_WIN32ERROR
404 #define FCGI_LOG_ERR            __FILE__,__LINE__,APLOG_ERR|APLOG_WIN32ERROR
405 #define FCGI_LOG_WARN           __FILE__,__LINE__,APLOG_WARNING|APLOG_WIN32ERROR
406 #define FCGI_LOG_NOTICE         __FILE__,__LINE__,APLOG_NOTICE|APLOG_WIN32ERROR
407 #define FCGI_LOG_INFO           __FILE__,__LINE__,APLOG_INFO|APLOG_WIN32ERROR
408 #define FCGI_LOG_DEBUG          __FILE__,__LINE__,APLOG_DEBUG|APLOG_WIN32ERROR
409 #else /* !WIN32 */
410 #define FCGI_LOG_EMERG          __FILE__,__LINE__,APLOG_EMERG
411 #define FCGI_LOG_ALERT          __FILE__,__LINE__,APLOG_ALERT
412 #define FCGI_LOG_CRIT           __FILE__,__LINE__,APLOG_CRIT
413 #define FCGI_LOG_ERR            __FILE__,__LINE__,APLOG_ERR
414 #define FCGI_LOG_WARN           __FILE__,__LINE__,APLOG_WARNING
415 #define FCGI_LOG_NOTICE         __FILE__,__LINE__,APLOG_NOTICE
416 #define FCGI_LOG_INFO           __FILE__,__LINE__,APLOG_INFO
417 #define FCGI_LOG_DEBUG          __FILE__,__LINE__,APLOG_DEBUG
418 #endif
419 
420 #define FCGI_LOG_EMERG_ERRNO    __FILE__,__LINE__,APLOG_EMERG     /* system is unusable */
421 #define FCGI_LOG_ALERT_ERRNO    __FILE__,__LINE__,APLOG_ALERT     /* action must be taken immediately */
422 #define FCGI_LOG_CRIT_ERRNO     __FILE__,__LINE__,APLOG_CRIT      /* critical conditions */
423 #define FCGI_LOG_ERR_ERRNO      __FILE__,__LINE__,APLOG_ERR       /* error conditions */
424 #define FCGI_LOG_WARN_ERRNO     __FILE__,__LINE__,APLOG_WARNING   /* warning conditions */
425 #define FCGI_LOG_NOTICE_ERRNO   __FILE__,__LINE__,APLOG_NOTICE    /* normal but significant condition */
426 #define FCGI_LOG_INFO_ERRNO     __FILE__,__LINE__,APLOG_INFO      /* informational */
427 #define FCGI_LOG_DEBUG_ERRNO    __FILE__,__LINE__,APLOG_DEBUG     /* debug-level messages */
428 
429 #define FCGI_LOG_EMERG_NOERRNO    __FILE__,__LINE__,APLOG_EMERG|APLOG_NOERRNO
430 #define FCGI_LOG_ALERT_NOERRNO    __FILE__,__LINE__,APLOG_ALERT|APLOG_NOERRNO
431 #define FCGI_LOG_CRIT_NOERRNO     __FILE__,__LINE__,APLOG_CRIT|APLOG_NOERRNO
432 #define FCGI_LOG_ERR_NOERRNO      __FILE__,__LINE__,APLOG_ERR|APLOG_NOERRNO
433 #define FCGI_LOG_WARN_NOERRNO     __FILE__,__LINE__,APLOG_WARNING|APLOG_NOERRNO
434 #define FCGI_LOG_NOTICE_NOERRNO   __FILE__,__LINE__,APLOG_NOTICE|APLOG_NOERRNO
435 #define FCGI_LOG_INFO_NOERRNO     __FILE__,__LINE__,APLOG_INFO|APLOG_NOERRNO
436 #define FCGI_LOG_DEBUG_NOERRNO    __FILE__,__LINE__,APLOG_DEBUG|APLOG_NOERRNO
437 
438 #endif /* !APACHE2 */
439 
440 #ifdef FCGI_DEBUG
441 #define FCGIDBG1(a)              ap_log_error(FCGI_LOG_DEBUG,fcgi_apache_main_server,a);
442 #define FCGIDBG2(a,b)            ap_log_error(FCGI_LOG_DEBUG,fcgi_apache_main_server,a,b);
443 #define FCGIDBG3(a,b,c)          ap_log_error(FCGI_LOG_DEBUG,fcgi_apache_main_server,a,b,c);
444 #define FCGIDBG4(a,b,c,d)        ap_log_error(FCGI_LOG_DEBUG,fcgi_apache_main_server,a,b,c,d);
445 #define FCGIDBG5(a,b,c,d,e)      ap_log_error(FCGI_LOG_DEBUG,fcgi_apache_main_server,a,b,c,d,e);
446 #define FCGIDBG6(a,b,c,d,e,f)    ap_log_error(FCGI_LOG_DEBUG,fcgi_apache_main_server,a,b,c,d,e,f);
447 #define FCGIDBG7(a,b,c,d,e,f,g)  ap_log_error(FCGI_LOG_DEBUG,fcgi_apache_main_server,a,b,c,d,e,f,g);
448 #else
449 #define FCGIDBG1(a)
450 #define FCGIDBG2(a,b)
451 #define FCGIDBG3(a,b,c)
452 #define FCGIDBG4(a,b,c,d)
453 #define FCGIDBG5(a,b,c,d,e)
454 #define FCGIDBG6(a,b,c,d,e,f)
455 #define FCGIDBG7(a,b,c,d,e,f,g)
456 #endif
457 
458 /*
459  * Holds the status of the sending of the environment.
460  * A quick hack to dump the static vars for the NT port.
461  */
462 typedef struct {
463     enum { PREP, HEADER, NAME, VALUE } pass;
464     char **envp;
465     int headerLen, nameLen, valueLen, totalLen;
466     char *equalPtr;
467     unsigned char headerBuff[8];
468 } env_status;
469 
470 /*
471  * fcgi_config.c
472  */
473 void *fcgi_config_create_dir_config(pool *p, char *dummy);
474 const char *fcgi_config_make_dir(pool *tp, char *path);
475 const char *fcgi_config_make_dynamic_dir(pool *p, const int wax);
476 const char *fcgi_config_new_static_server(cmd_parms *cmd, void *dummy, const char *arg);
477 const char *fcgi_config_new_external_server(cmd_parms *cmd, void *dummy, const char *arg);
478 const char *fcgi_config_set_config(cmd_parms *cmd, void *dummy, const char *arg);
479 const char *fcgi_config_set_fcgi_uid_n_gid(int set);
480 
481 const char *fcgi_config_new_auth_server(cmd_parms * cmd,
482     void *dir_config, const char *fs_path, const char * compat);
483 
484 const char *fcgi_config_set_authoritative_slot(cmd_parms * cmd,
485     void * dir_config, int arg);
486 const char *fcgi_config_set_socket_dir(cmd_parms *cmd, void *dummy, const char *arg);
487 const char *fcgi_config_set_wrapper(cmd_parms *cmd, void *dummy, const char *arg);
488 apcb_t fcgi_config_reset_globals(void * dummy);
489 const char *fcgi_config_set_env_var(pool *p, char **envp, unsigned int *envc, char * var);
490 
491 /*
492  * fcgi_pm.c
493  */
494 #if defined(WIN32) || defined(APACHE2)
495 void fcgi_pm_main(void *dummy);
496 #else
497 int fcgi_pm_main(void *dummy, child_info *info);
498 #endif
499 
500 /*
501  * fcgi_protocol.c
502  */
503 void fcgi_protocol_queue_begin_request(fcgi_request *fr);
504 void fcgi_protocol_queue_client_buffer(fcgi_request *fr);
505 int fcgi_protocol_queue_env(request_rec *r, fcgi_request *fr, env_status *env);
506 int fcgi_protocol_dequeue(pool *p, fcgi_request *fr);
507 
508 /*
509  * fcgi_buf.c
510  */
511 #define BufferLength(b)     ((b)->length)
512 #define BufferFree(b)       ((b)->size - (b)->length)
513 
514 void fcgi_buf_reset(Buffer *bufPtr);
515 Buffer *fcgi_buf_new(pool *p, int size);
516 
517 #ifndef WIN32
518 typedef int SOCKET;
519 #endif
520 
521 int fcgi_buf_socket_recv(Buffer *b, SOCKET socket);
522 int fcgi_buf_socket_send(Buffer *b, SOCKET socket);
523 
524 void fcgi_buf_added(Buffer * const b, const unsigned int len);
525 void fcgi_buf_removed(Buffer * const b, unsigned int len);
526 void fcgi_buf_get_block_info(Buffer *bufPtr, char **beginPtr, int *countPtr);
527 void fcgi_buf_toss(Buffer *bufPtr, int count);
528 void fcgi_buf_get_free_block_info(Buffer *bufPtr, char **endPtr, int *countPtr);
529 void fcgi_buf_add_update(Buffer *bufPtr, int count);
530 int fcgi_buf_add_block(Buffer *bufPtr, char *data, int datalen);
531 int fcgi_buf_add_string(Buffer *bufPtr, char *str);
532 int fcgi_buf_get_to_block(Buffer *bufPtr, char *data, int datalen);
533 void fcgi_buf_get_to_buf(Buffer *toPtr, Buffer *fromPtr, int len);
534 void fcgi_buf_get_to_array(Buffer *buf, array_header *arr, int len);
535 
536 /*
537  * fcgi_util.c
538  */
539 
540 char *fcgi_util_socket_hash_filename(pool *p, const char *path,
541     const char *user, const char *group);
542 const char *fcgi_util_socket_make_path_absolute(pool * const p,
543     const char *const file, const int dynamic);
544 #ifndef WIN32
545 const char *fcgi_util_socket_make_domain_addr(pool *p, struct sockaddr_un **socket_addr,
546     int *socket_addr_len, const char *socket_path);
547 #endif
548 const char *fcgi_util_socket_make_inet_addr(pool *p, struct sockaddr_in **socket_addr,
549     int *socket_addr_len, const char *host, unsigned short port);
550 const char *fcgi_util_check_access(pool *tp,
551     const char * const path, const struct stat *statBuf,
552     const int mode, const uid_t uid, const gid_t gid);
553 fcgi_server *fcgi_util_fs_get_by_id(const char *ePath, uid_t uid, gid_t gid);
554 fcgi_server *fcgi_util_fs_get(const char *ePath, const char *user, const char *group);
555 const char *fcgi_util_fs_is_path_ok(pool * const p, const char * const fs_path, struct stat *finfo);
556 fcgi_server *fcgi_util_fs_new(pool *p);
557 void fcgi_util_fs_add(fcgi_server *s);
558 const char *fcgi_util_fs_set_uid_n_gid(pool *p, fcgi_server *s, uid_t uid, gid_t gid);
559 ServerProcess *fcgi_util_fs_create_procs(pool *p, int num);
560 
561 int fcgi_util_ticks(struct timeval *);
562 
563 #ifdef WIN32
564 int fcgi_pm_add_job(fcgi_pm_job *new_job);
565 #endif
566 
567 uid_t fcgi_util_get_server_uid(const server_rec * const s);
568 gid_t fcgi_util_get_server_gid(const server_rec * const s);
569 
570 /*
571  * Globals
572  */
573 
574 extern pool *fcgi_config_pool;
575 
576 extern server_rec *fcgi_apache_main_server;
577 
578 extern const char *fcgi_wrapper;                 /* wrapper path */
579 extern uid_t fcgi_user_id;                       /* the run uid of Apache & PM */
580 extern gid_t fcgi_group_id;                      /* the run gid of Apache & PM */
581 
582 extern fcgi_server *fcgi_servers;
583 
584 extern char *fcgi_socket_dir;             /* default FastCgiIpcDir */
585 
586 /* pipe used for comm between the request handlers and the PM */
587 extern int fcgi_pm_pipe[];
588 
589 extern pid_t fcgi_pm_pid;
590 
591 extern char *fcgi_dynamic_dir;            /* directory for the dynamic
592                                            * fastcgi apps' sockets */
593 
594 extern char *fcgi_empty_env;
595 
596 extern int fcgi_dynamic_total_proc_count;
597 extern time_t fcgi_dynamic_epoch;
598 extern time_t fcgi_dynamic_last_analyzed;
599 
600 #ifdef WIN32
601 extern HANDLE *fcgi_dynamic_mbox_mutex;
602 extern HANDLE fcgi_event_handles[3];
603 extern fcgi_pm_job *fcgi_dynamic_mbox;
604 #endif
605 
606 extern u_int dynamicMaxProcs;
607 extern int dynamicMinProcs;
608 extern int dynamicMaxClassProcs;
609 extern u_int dynamicKillInterval;
610 extern u_int dynamicUpdateInterval;
611 extern float dynamicGain;
612 extern int dynamicThreshold1;
613 extern int dynamicThresholdN;
614 extern u_int dynamicPleaseStartDelay;
615 extern u_int dynamicAppConnectTimeout;
616 extern char **dynamicEnvp;
617 extern u_int dynamicProcessSlack;
618 extern int dynamicAutoRestart;
619 extern int dynamicAutoUpdate;
620 extern u_int dynamicListenQueueDepth;
621 extern u_int dynamicInitStartDelay;
622 extern u_int dynamicRestartDelay;
623 extern array_header *dynamic_pass_headers;
624 extern u_int dynamic_idle_timeout;
625 extern int dynamicMinServerLife;
626 extern int dynamicFlush;
627 
628 
629 extern module MODULE_VAR_EXPORT fastcgi_module;
630 
631 #endif  /* FCGI_H */
632 
633