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.4.6 by root, Sun Jul 8 08:22:33 2001 UTC vs.
Revision 1.4 by root, Sun Jul 8 08:21:57 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 ); 160static void cgi_child( httpd_conn* hc, char* exefilename );
161static off_t cgi( httpd_conn* hc ); 161static off_t cgi( httpd_conn* hc, char* exefilename );
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 );
243 if ( hs->cgi_pattern != (char*) 0 ) 245 if ( hs->cgi_pattern != (char*) 0 )
244 free( (void*) hs->cgi_pattern ); 246 free( (void*) hs->cgi_pattern );
245 if ( hs->charset != (char*) 0 ) 247 if ( hs->charset != (char*) 0 )
246 free( (void*) hs->charset ); 248 free( (void*) hs->charset );
247 if ( hs->url_pattern != (char*) 0 ) 249 if ( hs->url_pattern != (char*) 0 )
255httpd_server* 257httpd_server*
256httpd_initialize( 258httpd_initialize(
257 char* hostname, httpd_sockaddr* sa4P, httpd_sockaddr* sa6P, int port, 259 char* hostname, httpd_sockaddr* sa4P, httpd_sockaddr* sa6P, int port,
258 char* cgi_pattern, char* charset, char* cwd, int no_log, FILE* logfp, 260 char* cgi_pattern, char* charset, char* cwd, int no_log, FILE* logfp,
259 int no_symlink, int vhost, int global_passwd, char* url_pattern, 261 int no_symlink, int vhost, int global_passwd, char* url_pattern,
260 char* local_pattern, int no_empty_referers ) 262 char* local_pattern, int no_empty_referers,
263 char* autoindex_prog)
261 { 264 {
262 httpd_server* hs; 265 httpd_server* hs;
263 static char ghnbuf[256]; 266 static char ghnbuf[256];
264 char* cp; 267 char* cp;
265 268
327 } 330 }
328 /* Nuke any leading slashes in the cgi pattern. */ 331 /* Nuke any leading slashes in the cgi pattern. */
329 while ( ( cp = strstr( hs->cgi_pattern, "|/" ) ) != (char*) 0 ) 332 while ( ( cp = strstr( hs->cgi_pattern, "|/" ) ) != (char*) 0 )
330 (void) strcpy( cp + 1, cp + 2 ); 333 (void) strcpy( cp + 1, cp + 2 );
331 } 334 }
335 hs->autoindex_prog = autoindex_prog ? strdup( autoindex_prog ) : 0;
332 hs->charset = strdup( charset ); 336 hs->charset = strdup( charset );
333 hs->cwd = strdup( cwd ); 337 hs->cwd = strdup( cwd );
334 if ( hs->cwd == (char*) 0 ) 338 if ( hs->cwd == (char*) 0 )
335 { 339 {
336 syslog( LOG_CRIT, "out of memory copying cwd" ); 340 syslog( LOG_CRIT, "out of memory copying cwd" );
1471 checked[0] = '\0'; 1475 checked[0] = '\0';
1472 checkedlen = 0; 1476 checkedlen = 0;
1473 restlen = strlen( path ); 1477 restlen = strlen( path );
1474 httpd_realloc_str( &rest, &maxrest, restlen ); 1478 httpd_realloc_str( &rest, &maxrest, restlen );
1475 (void) strcpy( rest, path ); 1479 (void) strcpy( rest, path );
1476 if ( rest[restlen - 1] == '/' )
1477 rest[--restlen] = '\0'; /* trim trailing slash */
1478 if ( ! tildemapped ) 1480 if ( ! tildemapped )
1479 /* Remove any leading slashes. */ 1481 /* Remove any leading slashes. */
1480 while ( rest[0] == '/' ) 1482 while ( rest[0] == '/' )
1481 { 1483 {
1482 (void) strcpy( rest, &(rest[1]) ); 1484 (void) strcpy( rest, &(rest[1]) );
1738 hc->init_byte_loc = 0; 1740 hc->init_byte_loc = 0;
1739 hc->end_byte_loc = -1; 1741 hc->end_byte_loc = -1;
1740 hc->keep_alive = 0; 1742 hc->keep_alive = 0;
1741 hc->should_linger = 0; 1743 hc->should_linger = 0;
1742 hc->file_address = (char*) 0; 1744 hc->file_address = (char*) 0;
1745#ifdef MMAP_MAX
1746 hc->file_fd = -1;
1747 hc->write_buf = (char*) 0;
1748#endif
1743 return GC_OK; 1749 return GC_OK;
1744 } 1750 }
1745 1751
1746 1752
1747/* Checks hc->read_buf to see whether a complete request has been read so far; 1753/* Checks hc->read_buf to see whether a complete request has been read so far;
2388void 2394void
2389httpd_close_conn( httpd_conn* hc, struct timeval* nowP ) 2395httpd_close_conn( httpd_conn* hc, struct timeval* nowP )
2390 { 2396 {
2391 make_log_entry( hc, nowP ); 2397 make_log_entry( hc, nowP );
2392 2398
2399#ifdef MMAP_MAX
2400 if ( hc->file_fd >= 0)
2401 {
2402 (void) close( hc->file_fd );
2403 hc->file_fd = -1;
2404 }
2405 if ( hc->write_buf )
2406 {
2407 (void) free (hc->write_buf);
2408 hc->write_buf = 0;
2409 }
2410#endif
2393 if ( hc->file_address != (char*) 0 ) 2411 if ( hc->file_address != (char*) 0 )
2394 { 2412 {
2395 mmc_unmap( hc->file_address, &(hc->sb), nowP ); 2413 mmc_unmap( hc->file_address, &(hc->sb), nowP );
2396 hc->file_address = (char*) 0; 2414 hc->file_address = (char*) 0;
2397 } 2415 }
2796 exit( 0 ); 2814 exit( 0 );
2797 } 2815 }
2798 2816
2799 /* Parent process. */ 2817 /* Parent process. */
2800 closedir( dirp ); 2818 closedir( dirp );
2801 syslog( LOG_INFO, "spawned indexing process %d for directory '%.200s'", r, hc->expnfilename ); 2819 /*syslog( LOG_INFO, "spawned indexing process %d for directory '%.200s'", r, hc->expnfilename );*/
2802#ifdef CGI_TIMELIMIT 2820#ifdef CGI_TIMELIMIT
2803 /* Schedule a kill for the child process, in case it runs too long */ 2821 /* Schedule a kill for the child process, in case it runs too long */
2804 client_data.i = r; 2822 client_data.i = r;
2805 if ( tmr_create( (struct timeval*) 0, cgi_kill, client_data, CGI_TIMELIMIT * 1000L, 0 ) == (Timer*) 0 ) 2823 if ( tmr_create( (struct timeval*) 0, cgi_kill, client_data, CGI_TIMELIMIT * 1000L, 0 ) == (Timer*) 0 )
2806 { 2824 {
3162 } 3180 }
3163 3181
3164 3182
3165/* CGI child process. */ 3183/* CGI child process. */
3166static void 3184static void
3167cgi_child( httpd_conn* hc ) 3185cgi_child( httpd_conn* hc, char* exefilename )
3168 { 3186 {
3169 int r; 3187 int r;
3170 char** argp; 3188 char** argp;
3171 char** envp; 3189 char** envp;
3172 char* binary; 3190 char* binary;
3314 3332
3315 /* Split the program into directory and binary, so we can chdir() 3333 /* Split the program into directory and binary, so we can chdir()
3316 ** to the program's own directory. This isn't in the CGI 1.1 3334 ** to the program's own directory. This isn't in the CGI 1.1
3317 ** spec, but it's what other HTTP servers do. 3335 ** spec, but it's what other HTTP servers do.
3318 */ 3336 */
3319 directory = strdup( hc->expnfilename ); 3337 if (exefilename)
3320 if ( directory == (char*) 0 ) 3338 binary = exefilename;
3321 binary = hc->expnfilename; /* ignore errors */
3322 else 3339 else
3323 { 3340 {
3341 directory = strdup( exefilename ? exefilename : hc->expnfilename );
3342 if ( directory == (char*) 0 )
3343 binary = exefilename; /* ignore errors */
3344 else
3345 {
3324 binary = strrchr( directory, '/' ); 3346 binary = strrchr( directory, '/' );
3325 if ( binary == (char*) 0 ) 3347 if ( binary == (char*) 0 )
3326 binary = hc->expnfilename; 3348 binary = exefilename;
3327 else 3349 else
3328 { 3350 {
3329 *binary++ = '\0'; 3351 *binary++ = '\0';
3330 (void) chdir( directory ); /* ignore errors */ 3352 (void) chdir( directory ); /* ignore errors */
3353 }
3354 }
3331 } 3355 }
3332 }
3333 3356
3334 /* Default behavior for SIGPIPE. */ 3357 /* Default behavior for SIGPIPE. */
3335 (void) signal( SIGPIPE, SIG_DFL ); 3358 (void) signal( SIGPIPE, SIG_DFL );
3336 3359
3337 /* Run the program. */ 3360 /* Run the program. */
3343 exit( 1 ); 3366 exit( 1 );
3344 } 3367 }
3345 3368
3346 3369
3347static off_t 3370static off_t
3348cgi( httpd_conn* hc ) 3371cgi( httpd_conn* hc, char* exefilename )
3349 { 3372 {
3350 int r; 3373 int r;
3351 ClientData client_data; 3374 ClientData client_data;
3352 3375
3353 if ( hc->method == METHOD_GET || hc->method == METHOD_POST ) 3376 if ( hc->method == METHOD_GET || hc->method == METHOD_POST )
3361 return -1; 3384 return -1;
3362 } 3385 }
3363 if ( r == 0 ) 3386 if ( r == 0 )
3364 { 3387 {
3365 unlisten( hc->hs ); 3388 unlisten( hc->hs );
3366 cgi_child( hc ); 3389 cgi_child( hc, exefilename );
3367 } 3390 }
3368 3391
3369 /* Parent process. */ 3392 /* Parent process. */
3370 syslog( LOG_INFO, "spawned CGI process %d for file '%.200s'", r, hc->expnfilename ); 3393 /*syslog( LOG_INFO, "spawned CGI process %d for file '%.200s'", r, hc->expnfilename );*/
3371#ifdef CGI_TIMELIMIT 3394#ifdef CGI_TIMELIMIT
3372 /* Schedule a kill for the child process, in case it runs too long */ 3395 /* Schedule a kill for the child process, in case it runs too long */
3373 client_data.i = r; 3396 client_data.i = r;
3374 if ( tmr_create( (struct timeval*) 0, cgi_kill, client_data, CGI_TIMELIMIT * 1000L, 0 ) == (Timer*) 0 ) 3397 if ( tmr_create( (struct timeval*) 0, cgi_kill, client_data, CGI_TIMELIMIT * 1000L, 0 ) == (Timer*) 0 )
3375 { 3398 {
3501#endif /* AUTH_FILE */ 3524#endif /* AUTH_FILE */
3502 /* Referer check. */ 3525 /* Referer check. */
3503 if ( ! check_referer( hc ) ) 3526 if ( ! check_referer( hc ) )
3504 return -1; 3527 return -1;
3505 /* Ok, generate an index. */ 3528 /* Ok, generate an index. */
3506 return ls( hc ); 3529 return hc->hs->autoindex_prog ? cgi( hc, hc->hs->autoindex_prog) : ls( hc );
3507#else /* GENERATE_INDEXES */ 3530#else /* GENERATE_INDEXES */
3508 syslog( 3531 syslog(
3509 LOG_INFO, "%.80s URL \"%.80s\" tried to index a directory", 3532 LOG_INFO, "%.80s URL \"%.80s\" tried to index a directory",
3510 httpd_ntoa( &hc->client_addr ), hc->encodedurl ); 3533 httpd_ntoa( &hc->client_addr ), hc->encodedurl );
3511 httpd_send_err( 3534 httpd_send_err(
3594 3617
3595 /* Is it world-executable and in the CGI area? */ 3618 /* Is it world-executable and in the CGI area? */
3596 if ( hc->hs->cgi_pattern != (char*) 0 && 3619 if ( hc->hs->cgi_pattern != (char*) 0 &&
3597 ( hc->sb.st_mode & S_IXOTH ) && 3620 ( hc->sb.st_mode & S_IXOTH ) &&
3598 match( hc->hs->cgi_pattern, hc->expnfilename ) ) 3621 match( hc->hs->cgi_pattern, hc->expnfilename ) )
3599 return cgi( hc ); 3622 return cgi( hc, 0 );
3600 3623
3601 /* It's not CGI. If it's executable or there's pathinfo, someone's 3624 /* It's not CGI. If it's executable or there's pathinfo, someone's
3602 ** trying to either serve or run a non-CGI file as CGI. Either case 3625 ** trying to either serve or run a non-CGI file as CGI. Either case
3603 ** is prohibited. 3626 ** is prohibited.
3604 */ 3627 */
3646 hc, 304, err304title, hc->encodings, "", hc->type, hc->sb.st_size, 3669 hc, 304, err304title, hc->encodings, "", hc->type, hc->sb.st_size,
3647 hc->sb.st_mtime ); 3670 hc->sb.st_mtime );
3648 } 3671 }
3649 else 3672 else
3650 { 3673 {
3674#ifdef MMAP_MAX
3675 if ( hc->sb.st_size < MMAP_MAX)
3676#endif
3651 hc->file_address = mmc_map( hc->expnfilename, &(hc->sb), nowP ); 3677 hc->file_address = mmc_map( hc->expnfilename, &(hc->sb), nowP );
3652 if ( hc->file_address == (char*) 0 ) 3678 if ( hc->file_address == (char*) 0 )
3653 { 3679 {
3680#ifdef MMAP_MAX
3681 hc->file_fd = open ( hc->expnfilename, O_RDONLY);
3682 hc->write_buf = malloc (WRITE_BUFFER);
3683 hc->write_ofs = WRITE_BUFFER;
3684 if ( hc->file_fd < 0 || !hc->write_buf )
3685#endif
3686 {
3654 httpd_send_err( hc, 500, err500title, "", err500form, hc->encodedurl ); 3687 httpd_send_err( hc, 500, err500title, "", err500form, hc->encodedurl );
3655 return -1; 3688 return -1;
3689 }
3656 } 3690 }
3657 send_mime( 3691 send_mime(
3658 hc, 200, ok200title, hc->encodings, "", hc->type, hc->sb.st_size, 3692 hc, 200, ok200title, hc->encodings, "", hc->type, hc->sb.st_size,
3659 hc->sb.st_mtime ); 3693 hc->sb.st_mtime );
3660 } 3694 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines