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.6.2 by root, Mon Jun 25 02:23:00 2001 UTC vs.
Revision 1.3 by root, Mon Jul 2 18:38:31 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" );
820 send_response( hc, status, title, extraheads, form, arg ); 824 send_response( hc, status, title, extraheads, form, arg );
821 825
822#endif /* ERR_DIR */ 826#endif /* ERR_DIR */
823 } 827 }
824 828
829void
830httpd_send_err_blocked( httpd_conn* hc )
831 {
832#ifdef ERR_DIR
833
834 char filename[1000];
835
836 /* Try virtual host error page. */
837 if ( hc->hs->vhost && hc->hostdir[0] != '\0' )
838 {
839 (void) my_snprintf( filename, sizeof(filename),
840 "%s/%s/err403blocked.html", hc->hostdir, ERR_DIR );
841 if ( send_err_file( hc, 403, err403title, "", filename ) )
842 return;
843 }
844
845 /* Try server-wide error page. */
846 (void) my_snprintf( filename, sizeof(filename),
847 "%s/err403blocked.html", ERR_DIR );
848 if ( send_err_file( hc, 403, err403title, "", filename ) )
849 return;
850
851 /* Fall back on built-in error page. */
852 send_response( hc, 403, err403title, "", err403form, "" );
853
854#else /* ERR_DIR */
855
856 send_response( hc, 403, err403title, "", err403form, "" );
857
858#endif /* ERR_DIR */
859 }
825 860
826#ifdef ERR_DIR 861#ifdef ERR_DIR
827static int 862static int
828send_err_file( httpd_conn* hc, int status, char* title, char* extraheads, char* filename ) 863send_err_file( httpd_conn* hc, int status, char* title, char* extraheads, char* filename )
829 { 864 {
1434 checked[0] = '\0'; 1469 checked[0] = '\0';
1435 checkedlen = 0; 1470 checkedlen = 0;
1436 restlen = strlen( path ); 1471 restlen = strlen( path );
1437 httpd_realloc_str( &rest, &maxrest, restlen ); 1472 httpd_realloc_str( &rest, &maxrest, restlen );
1438 (void) strcpy( rest, path ); 1473 (void) strcpy( rest, path );
1439 if ( rest[restlen - 1] == '/' )
1440 rest[--restlen] = '\0'; /* trim trailing slash */
1441 if ( ! tildemapped ) 1474 if ( ! tildemapped )
1442 /* Remove any leading slashes. */ 1475 /* Remove any leading slashes. */
1443 while ( rest[0] == '/' ) 1476 while ( rest[0] == '/' )
1444 { 1477 {
1445 (void) strcpy( rest, &(rest[1]) ); 1478 (void) strcpy( rest, &(rest[1]) );
2362 { 2395 {
2363 (void) close( hc->file_fd ); 2396 (void) close( hc->file_fd );
2364 hc->file_fd = -1; 2397 hc->file_fd = -1;
2365 } 2398 }
2366 if ( hc->write_buf ) 2399 if ( hc->write_buf )
2400 {
2367 (void) free (hc->write_buf); 2401 (void) free (hc->write_buf);
2402 hc->write_buf = 0;
2403 }
2368#endif 2404#endif
2369 if ( hc->file_address != (char*) 0 ) 2405 if ( hc->file_address != (char*) 0 )
2370 { 2406 {
2371 mmc_unmap( hc->file_address, &(hc->sb), nowP ); 2407 mmc_unmap( hc->file_address, &(hc->sb), nowP );
2372 hc->file_address = (char*) 0; 2408 hc->file_address = (char*) 0;
3138 } 3174 }
3139 3175
3140 3176
3141/* CGI child process. */ 3177/* CGI child process. */
3142static void 3178static void
3143cgi_child( httpd_conn* hc ) 3179cgi_child( httpd_conn* hc, char* exefilename )
3144 { 3180 {
3145 int r; 3181 int r;
3146 char** argp; 3182 char** argp;
3147 char** envp; 3183 char** envp;
3148 char* binary; 3184 char* binary;
3290 3326
3291 /* Split the program into directory and binary, so we can chdir() 3327 /* Split the program into directory and binary, so we can chdir()
3292 ** to the program's own directory. This isn't in the CGI 1.1 3328 ** to the program's own directory. This isn't in the CGI 1.1
3293 ** spec, but it's what other HTTP servers do. 3329 ** spec, but it's what other HTTP servers do.
3294 */ 3330 */
3295 directory = strdup( hc->expnfilename ); 3331 if (exefilename)
3296 if ( directory == (char*) 0 ) 3332 binary = exefilename;
3297 binary = hc->expnfilename; /* ignore errors */
3298 else 3333 else
3299 { 3334 {
3335 directory = strdup( exefilename ? exefilename : hc->expnfilename );
3336 if ( directory == (char*) 0 )
3337 binary = exefilename; /* ignore errors */
3338 else
3339 {
3300 binary = strrchr( directory, '/' ); 3340 binary = strrchr( directory, '/' );
3301 if ( binary == (char*) 0 ) 3341 if ( binary == (char*) 0 )
3302 binary = hc->expnfilename; 3342 binary = exefilename;
3303 else 3343 else
3304 { 3344 {
3305 *binary++ = '\0'; 3345 *binary++ = '\0';
3306 (void) chdir( directory ); /* ignore errors */ 3346 (void) chdir( directory ); /* ignore errors */
3347 }
3348 }
3307 } 3349 }
3308 }
3309 3350
3310 /* Default behavior for SIGPIPE. */ 3351 /* Default behavior for SIGPIPE. */
3311 (void) signal( SIGPIPE, SIG_DFL ); 3352 (void) signal( SIGPIPE, SIG_DFL );
3312 3353
3313 /* Run the program. */ 3354 /* Run the program. */
3319 exit( 1 ); 3360 exit( 1 );
3320 } 3361 }
3321 3362
3322 3363
3323static off_t 3364static off_t
3324cgi( httpd_conn* hc ) 3365cgi( httpd_conn* hc, char* exefilename )
3325 { 3366 {
3326 int r; 3367 int r;
3327 ClientData client_data; 3368 ClientData client_data;
3328 3369
3329 if ( hc->method == METHOD_GET || hc->method == METHOD_POST ) 3370 if ( hc->method == METHOD_GET || hc->method == METHOD_POST )
3337 return -1; 3378 return -1;
3338 } 3379 }
3339 if ( r == 0 ) 3380 if ( r == 0 )
3340 { 3381 {
3341 unlisten( hc->hs ); 3382 unlisten( hc->hs );
3342 cgi_child( hc ); 3383 cgi_child( hc, exefilename );
3343 } 3384 }
3344 3385
3345 /* Parent process. */ 3386 /* Parent process. */
3346 syslog( LOG_INFO, "spawned CGI process %d for file '%.200s'", r, hc->expnfilename ); 3387 syslog( LOG_INFO, "spawned CGI process %d for file '%.200s'", r, hc->expnfilename );
3347#ifdef CGI_TIMELIMIT 3388#ifdef CGI_TIMELIMIT
3477#endif /* AUTH_FILE */ 3518#endif /* AUTH_FILE */
3478 /* Referer check. */ 3519 /* Referer check. */
3479 if ( ! check_referer( hc ) ) 3520 if ( ! check_referer( hc ) )
3480 return -1; 3521 return -1;
3481 /* Ok, generate an index. */ 3522 /* Ok, generate an index. */
3482 return ls( hc ); 3523 return hc->hs->autoindex_prog ? cgi( hc, hc->hs->autoindex_prog) : ls( hc );
3483#else /* GENERATE_INDEXES */ 3524#else /* GENERATE_INDEXES */
3484 syslog( 3525 syslog(
3485 LOG_INFO, "%.80s URL \"%.80s\" tried to index a directory", 3526 LOG_INFO, "%.80s URL \"%.80s\" tried to index a directory",
3486 httpd_ntoa( &hc->client_addr ), hc->encodedurl ); 3527 httpd_ntoa( &hc->client_addr ), hc->encodedurl );
3487 httpd_send_err( 3528 httpd_send_err(
3570 3611
3571 /* Is it world-executable and in the CGI area? */ 3612 /* Is it world-executable and in the CGI area? */
3572 if ( hc->hs->cgi_pattern != (char*) 0 && 3613 if ( hc->hs->cgi_pattern != (char*) 0 &&
3573 ( hc->sb.st_mode & S_IXOTH ) && 3614 ( hc->sb.st_mode & S_IXOTH ) &&
3574 match( hc->hs->cgi_pattern, hc->expnfilename ) ) 3615 match( hc->hs->cgi_pattern, hc->expnfilename ) )
3575 return cgi( hc ); 3616 return cgi( hc, 0 );
3576 3617
3577 /* It's not CGI. If it's executable or there's pathinfo, someone's 3618 /* It's not CGI. If it's executable or there's pathinfo, someone's
3578 ** trying to either serve or run a non-CGI file as CGI. Either case 3619 ** trying to either serve or run a non-CGI file as CGI. Either case
3579 ** is prohibited. 3620 ** is prohibited.
3580 */ 3621 */
3670 char url[305]; 3711 char url[305];
3671 char bytes[40]; 3712 char bytes[40];
3672 3713
3673 if ( hc->hs->no_log ) 3714 if ( hc->hs->no_log )
3674 return; 3715 return;
3716
3717 /* don't log UNKNOWN protocol requests (blocks etc..) */
3718 if ( !strcmp (hc->protocol, "UNKNOWN") )
3719 return;
3675 3720
3676 /* This is straight CERN Combined Log Format - the only tweak 3721 /* This is straight CERN Combined Log Format - the only tweak
3677 ** being that if we're using syslog() we leave out the date, because 3722 ** being that if we're using syslog() we leave out the date, because
3678 ** syslogd puts it in. The included syslogtocern script turns the 3723 ** syslogd puts it in. The included syslogtocern script turns the
3679 ** results into true CERN format. 3724 ** results into true CERN format.

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines