ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/thttpd/libhttpd.c
(Generate patch)

Comparing thttpd/libhttpd.c (file contents):
Revision 1.1.2.1 by root, Mon Jun 18 21:19:51 2001 UTC vs.
Revision 1.1.4.6 by root, Sun Jul 8 08:22:33 2001 UTC

155static char** make_envp( httpd_conn* hc ); 155static char** make_envp( httpd_conn* hc );
156static char** make_argp( httpd_conn* hc ); 156static char** make_argp( httpd_conn* hc );
157static void cgi_interpose_input( httpd_conn* hc, int wfd ); 157static void cgi_interpose_input( httpd_conn* hc, int wfd );
158static void post_post_garbage_hack( httpd_conn* hc ); 158static void post_post_garbage_hack( httpd_conn* hc );
159static void cgi_interpose_output( httpd_conn* hc, int rfd ); 159static void cgi_interpose_output( httpd_conn* hc, int rfd );
160static void cgi_child( httpd_conn* hc, char* exefilename ); 160static void cgi_child( httpd_conn* hc );
161static off_t cgi( httpd_conn* hc, char* exefilename ); 161static off_t cgi( httpd_conn* hc );
162static int really_start_request( httpd_conn* hc, struct timeval* nowP ); 162static int really_start_request( httpd_conn* hc, struct timeval* nowP );
163static void make_log_entry( httpd_conn* hc, struct timeval* nowP ); 163static void make_log_entry( httpd_conn* hc, struct timeval* nowP );
164static int check_referer( httpd_conn* hc ); 164static int check_referer( httpd_conn* hc );
165static int really_check_referer( httpd_conn* hc ); 165static int really_check_referer( httpd_conn* hc );
166static int sockaddr_check( httpd_sockaddr* saP ); 166static int sockaddr_check( httpd_sockaddr* saP );
238 { 238 {
239 if ( hs->binding_hostname != (char*) 0 ) 239 if ( hs->binding_hostname != (char*) 0 )
240 free( (void*) hs->binding_hostname ); 240 free( (void*) hs->binding_hostname );
241 if ( hs->cwd != (char*) 0 ) 241 if ( hs->cwd != (char*) 0 )
242 free( (void*) hs->cwd ); 242 free( (void*) hs->cwd );
243 if ( hs->autoindex_prog != (char*) 0 )
244 free( (void*) hs->autoindex_prog );
245 if ( hs->cgi_pattern != (char*) 0 ) 243 if ( hs->cgi_pattern != (char*) 0 )
246 free( (void*) hs->cgi_pattern ); 244 free( (void*) hs->cgi_pattern );
247 if ( hs->charset != (char*) 0 ) 245 if ( hs->charset != (char*) 0 )
248 free( (void*) hs->charset ); 246 free( (void*) hs->charset );
249 if ( hs->url_pattern != (char*) 0 ) 247 if ( hs->url_pattern != (char*) 0 )
257httpd_server* 255httpd_server*
258httpd_initialize( 256httpd_initialize(
259 char* hostname, httpd_sockaddr* sa4P, httpd_sockaddr* sa6P, int port, 257 char* hostname, httpd_sockaddr* sa4P, httpd_sockaddr* sa6P, int port,
260 char* cgi_pattern, char* charset, char* cwd, int no_log, FILE* logfp, 258 char* cgi_pattern, char* charset, char* cwd, int no_log, FILE* logfp,
261 int no_symlink, int vhost, int global_passwd, char* url_pattern, 259 int no_symlink, int vhost, int global_passwd, char* url_pattern,
262 char* local_pattern, int no_empty_referers, 260 char* local_pattern, int no_empty_referers )
263 char* autoindex_prog)
264 { 261 {
265 httpd_server* hs; 262 httpd_server* hs;
266 static char ghnbuf[256]; 263 static char ghnbuf[256];
267 char* cp; 264 char* cp;
268 265
330 } 327 }
331 /* Nuke any leading slashes in the cgi pattern. */ 328 /* Nuke any leading slashes in the cgi pattern. */
332 while ( ( cp = strstr( hs->cgi_pattern, "|/" ) ) != (char*) 0 ) 329 while ( ( cp = strstr( hs->cgi_pattern, "|/" ) ) != (char*) 0 )
333 (void) strcpy( cp + 1, cp + 2 ); 330 (void) strcpy( cp + 1, cp + 2 );
334 } 331 }
335 hs->autoindex_prog = autoindex_prog ? strdup( autoindex_prog ) : 0;
336 hs->charset = strdup( charset ); 332 hs->charset = strdup( charset );
337 hs->cwd = strdup( cwd ); 333 hs->cwd = strdup( cwd );
338 if ( hs->cwd == (char*) 0 ) 334 if ( hs->cwd == (char*) 0 )
339 { 335 {
340 syslog( LOG_CRIT, "out of memory copying cwd" ); 336 syslog( LOG_CRIT, "out of memory copying cwd" );
824 send_response( hc, status, title, extraheads, form, arg ); 820 send_response( hc, status, title, extraheads, form, arg );
825 821
826#endif /* ERR_DIR */ 822#endif /* ERR_DIR */
827 } 823 }
828 824
825void
826httpd_send_err_blocked( httpd_conn* hc )
827 {
828 char *protocol = hc->protocol;
829
830#ifdef ERR_DIR
831 char filename[1000];
832#endif
833
834 hc->protocol = "HTTP/1.0";
835
836#ifdef ERR_DIR
837 /* Try virtual host error page. */
838 if ( hc->hs->vhost && hc->hostdir[0] != '\0' )
839 {
840 (void) my_snprintf( filename, sizeof(filename),
841 "%s/%s/err403blocked.html", hc->hostdir, ERR_DIR );
842 if ( send_err_file( hc, 403, err403title, "", filename ) )
843 return;
844 }
845
846 /* Try server-wide error page. */
847 (void) my_snprintf( filename, sizeof(filename),
848 "%s/err403blocked.html", ERR_DIR );
849 if ( send_err_file( hc, 403, err403title, "", filename ) )
850 return;
851
852 /* Fall back on built-in error page. */
853 send_response( hc, 403, err403title, "", err403form, "" );
854
855#else /* ERR_DIR */
856
857 send_response( hc, 403, err403title, "", err403form, "" );
858
859#endif /* ERR_DIR */
860 hc->protocol = protocol;
861 }
829 862
830#ifdef ERR_DIR 863#ifdef ERR_DIR
831static int 864static int
832send_err_file( httpd_conn* hc, int status, char* title, char* extraheads, char* filename ) 865send_err_file( httpd_conn* hc, int status, char* title, char* extraheads, char* filename )
833 { 866 {
1438 checked[0] = '\0'; 1471 checked[0] = '\0';
1439 checkedlen = 0; 1472 checkedlen = 0;
1440 restlen = strlen( path ); 1473 restlen = strlen( path );
1441 httpd_realloc_str( &rest, &maxrest, restlen ); 1474 httpd_realloc_str( &rest, &maxrest, restlen );
1442 (void) strcpy( rest, path ); 1475 (void) strcpy( rest, path );
1476 if ( rest[restlen - 1] == '/' )
1477 rest[--restlen] = '\0'; /* trim trailing slash */
1443 if ( ! tildemapped ) 1478 if ( ! tildemapped )
1444 /* Remove any leading slashes. */ 1479 /* Remove any leading slashes. */
1445 while ( rest[0] == '/' ) 1480 while ( rest[0] == '/' )
1446 { 1481 {
1447 (void) strcpy( rest, &(rest[1]) ); 1482 (void) strcpy( rest, &(rest[1]) );
3127 } 3162 }
3128 3163
3129 3164
3130/* CGI child process. */ 3165/* CGI child process. */
3131static void 3166static void
3132cgi_child( httpd_conn* hc, char* exefilename ) 3167cgi_child( httpd_conn* hc )
3133 { 3168 {
3134 int r; 3169 int r;
3135 char** argp; 3170 char** argp;
3136 char** envp; 3171 char** envp;
3137 char* binary; 3172 char* binary;
3279 3314
3280 /* Split the program into directory and binary, so we can chdir() 3315 /* Split the program into directory and binary, so we can chdir()
3281 ** to the program's own directory. This isn't in the CGI 1.1 3316 ** to the program's own directory. This isn't in the CGI 1.1
3282 ** spec, but it's what other HTTP servers do. 3317 ** spec, but it's what other HTTP servers do.
3283 */ 3318 */
3284 if (exefilename) 3319 directory = strdup( hc->expnfilename );
3285 binary = exefilename; 3320 if ( directory == (char*) 0 )
3321 binary = hc->expnfilename; /* ignore errors */
3286 else 3322 else
3287 { 3323 {
3288 directory = strdup( exefilename ? exefilename : hc->expnfilename );
3289 if ( directory == (char*) 0 )
3290 binary = exefilename; /* ignore errors */
3291 else
3292 {
3293 binary = strrchr( directory, '/' ); 3324 binary = strrchr( directory, '/' );
3294 if ( binary == (char*) 0 ) 3325 if ( binary == (char*) 0 )
3295 binary = exefilename; 3326 binary = hc->expnfilename;
3296 else 3327 else
3297 { 3328 {
3298 *binary++ = '\0'; 3329 *binary++ = '\0';
3299 (void) chdir( directory ); /* ignore errors */ 3330 (void) chdir( directory ); /* ignore errors */
3300 }
3301 }
3302 } 3331 }
3332 }
3303 3333
3304 /* Default behavior for SIGPIPE. */ 3334 /* Default behavior for SIGPIPE. */
3305 (void) signal( SIGPIPE, SIG_DFL ); 3335 (void) signal( SIGPIPE, SIG_DFL );
3306 3336
3307 /* Run the program. */ 3337 /* Run the program. */
3313 exit( 1 ); 3343 exit( 1 );
3314 } 3344 }
3315 3345
3316 3346
3317static off_t 3347static off_t
3318cgi( httpd_conn* hc, char* exefilename ) 3348cgi( httpd_conn* hc )
3319 { 3349 {
3320 int r; 3350 int r;
3321 ClientData client_data; 3351 ClientData client_data;
3322 3352
3323 if ( hc->method == METHOD_GET || hc->method == METHOD_POST ) 3353 if ( hc->method == METHOD_GET || hc->method == METHOD_POST )
3331 return -1; 3361 return -1;
3332 } 3362 }
3333 if ( r == 0 ) 3363 if ( r == 0 )
3334 { 3364 {
3335 unlisten( hc->hs ); 3365 unlisten( hc->hs );
3336 cgi_child( hc, exefilename ); 3366 cgi_child( hc );
3337 } 3367 }
3338 3368
3339 /* Parent process. */ 3369 /* Parent process. */
3340 syslog( LOG_INFO, "spawned CGI process %d for file '%.200s'", r, hc->expnfilename ); 3370 syslog( LOG_INFO, "spawned CGI process %d for file '%.200s'", r, hc->expnfilename );
3341#ifdef CGI_TIMELIMIT 3371#ifdef CGI_TIMELIMIT
3471#endif /* AUTH_FILE */ 3501#endif /* AUTH_FILE */
3472 /* Referer check. */ 3502 /* Referer check. */
3473 if ( ! check_referer( hc ) ) 3503 if ( ! check_referer( hc ) )
3474 return -1; 3504 return -1;
3475 /* Ok, generate an index. */ 3505 /* Ok, generate an index. */
3476 return hc->hs->autoindex_prog ? cgi( hc, hc->hs->autoindex_prog) : ls( hc ); 3506 return ls( hc );
3477#else /* GENERATE_INDEXES */ 3507#else /* GENERATE_INDEXES */
3478 syslog( 3508 syslog(
3479 LOG_INFO, "%.80s URL \"%.80s\" tried to index a directory", 3509 LOG_INFO, "%.80s URL \"%.80s\" tried to index a directory",
3480 httpd_ntoa( &hc->client_addr ), hc->encodedurl ); 3510 httpd_ntoa( &hc->client_addr ), hc->encodedurl );
3481 httpd_send_err( 3511 httpd_send_err(
3564 3594
3565 /* Is it world-executable and in the CGI area? */ 3595 /* Is it world-executable and in the CGI area? */
3566 if ( hc->hs->cgi_pattern != (char*) 0 && 3596 if ( hc->hs->cgi_pattern != (char*) 0 &&
3567 ( hc->sb.st_mode & S_IXOTH ) && 3597 ( hc->sb.st_mode & S_IXOTH ) &&
3568 match( hc->hs->cgi_pattern, hc->expnfilename ) ) 3598 match( hc->hs->cgi_pattern, hc->expnfilename ) )
3569 return cgi( hc, 0 ); 3599 return cgi( hc );
3570 3600
3571 /* It's not CGI. If it's executable or there's pathinfo, someone's 3601 /* It's not CGI. If it's executable or there's pathinfo, someone's
3572 ** trying to either serve or run a non-CGI file as CGI. Either case 3602 ** trying to either serve or run a non-CGI file as CGI. Either case
3573 ** is prohibited. 3603 ** is prohibited.
3574 */ 3604 */
3653 char url[305]; 3683 char url[305];
3654 char bytes[40]; 3684 char bytes[40];
3655 3685
3656 if ( hc->hs->no_log ) 3686 if ( hc->hs->no_log )
3657 return; 3687 return;
3688
3689 /* don't log UNKNOWN protocol requests (blocks etc..) */
3690 if ( hc->method == METHOD_UNKNOWN )
3691 return;
3658 3692
3659 /* This is straight CERN Combined Log Format - the only tweak 3693 /* This is straight CERN Combined Log Format - the only tweak
3660 ** being that if we're using syslog() we leave out the date, because 3694 ** being that if we're using syslog() we leave out the date, because
3661 ** syslogd puts it in. The included syslogtocern script turns the 3695 ** syslogd puts it in. The included syslogtocern script turns the
3662 ** results into true CERN format. 3696 ** results into true CERN format.

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines