-const char jcc_rcs[] = "$Id: jcc.c,v 1.92.2.4 2003/03/07 03:41:04 david__schmidt Exp $";
+const char jcc_rcs[] = "$Id: jcc.c,v 1.92.2.11 2003/05/14 12:32:02 oes Exp $";
/*********************************************************************
*
* File : $Source: /cvsroot/ijbswa/current/Attic/jcc.c,v $
*
* Revisions :
* $Log: jcc.c,v $
+ * Revision 1.92.2.11 2003/05/14 12:32:02 oes
+ * Close jarfile on graceful exit, remove stray line
+ *
+ * Revision 1.92.2.10 2003/05/08 15:13:46 oes
+ * Cosmetics: Killed a warning, a typo and an allocation left at exit
+ *
+ * Revision 1.92.2.9 2003/04/03 15:08:42 oes
+ * No longer rely on non-POSIX.1 extensions of getcwd().
+ * Fixes bug #711001
+ *
+ * Revision 1.92.2.8 2003/03/31 13:12:32 oes
+ * Replaced setenv() by posix-compliant putenv()
+ * Thanks to Neil McCalden (nmcc AT users.sf.net).
+ *
+ * Revision 1.92.2.7 2003/03/17 16:48:59 oes
+ * Added chroot ability, thanks to patch by Sviatoslav Sviridov
+ *
+ * Revision 1.92.2.6 2003/03/11 11:55:00 oes
+ * Clean-up and extension of improvements for forked mode:
+ * - Child's return code now consists of flags RC_FLAG_*
+ * - Reporting toggle to parent now properly #ifdef'ed
+ * - Children now report blocking to parent. This enables
+ * statistics in forked mode
+ *
+ * Revision 1.92.2.5 2003/03/10 23:45:32 oes
+ * Fixed bug #700381: Non-Threaded version now capable of being toggled.
+ * Children now report having been toggled through _exit(17), parents
+ * watch for that code and toggle themselves if found.
+ *
* Revision 1.92.2.4 2003/03/07 03:41:04 david__schmidt
* Wrapping all *_r functions (the non-_r versions of them) with mutex semaphores for OSX. Hopefully this will take care of all of those pesky crash reports.
*
#endif /* def OSX_DARWIN */
#if defined(unix) || defined(__EMX__)
-const char *basedir;
+const char *basedir = NULL;
const char *pidfile = NULL;
int received_hup_signal = 0;
#endif /* defined unix */
if (write_socket(csp->cfd, hdr, hdrlen)
|| ((flushed = flush_socket(csp->cfd, csp)) < 0)
- || (write_socket(csp->cfd, buf, len)))
+ || (write_socket(csp->cfd, buf, (size_t) len)))
{
log_error(LOG_LEVEL_CONNECT, "Flush header and buffers to client failed: %E");
struct passwd *pw = NULL;
struct group *grp = NULL;
char *p;
+ int do_chroot = 0;
#endif
Argc = argc;
if (p != NULL) *--p = '\0';
}
+
+ else if (strcmp(argv[argc_pos], "--chroot" ) == 0)
+ {
+ do_chroot = 1;
+ }
#endif /* defined(unix) */
else
#endif /* defined(_WIN32) && !defined(_WIN_CONSOLE) */
#if defined(unix)
if ( *configfile != '/' )
{
- char *abs_file;
+ char *abs_file, cwd[1024];
/* make config-filename absolute here */
- if ( !(basedir = getcwd( NULL, 1024 )))
+ if ( !(getcwd(cwd, sizeof(cwd))))
{
perror("get working dir failed");
exit( 1 );
}
- if ( !(abs_file = malloc( strlen( basedir ) + strlen( configfile ) + 5 )))
+ if (!(basedir = strdup(cwd))
+ || (!(abs_file = malloc( strlen( basedir ) + strlen( configfile ) + 5 ))))
{
perror("malloc failed");
exit( 1 );
*
* Catch the abort, interrupt and terminate signals for a graceful exit
* Catch the hangup signal so the errlog can be reopened.
- * Ignore the broken pipe and child signals
- * FIXME: Isn't ignoring the default for SIGCHLD anyway and why ignore SIGPIPE?
+ * Ignore the broken pipe signals (FIXME: Why?)
*/
#if !defined(_WIN32) && !defined(__OS2__) && !defined(AMIGA)
{
int idx;
const int catched_signals[] = { SIGABRT, SIGTERM, SIGINT, SIGHUP, 0 };
- const int ignored_signals[] = { SIGPIPE, SIGCHLD, 0 };
+ const int ignored_signals[] = { SIGPIPE, 0 };
for (idx = 0; catched_signals[idx] != 0; idx++)
{
{
log_error(LOG_LEVEL_FATAL, "Cannot setgid(): Insufficient permissions.");
}
+ if (do_chroot)
+ {
+ if (!pw->pw_dir)
+ {
+ log_error(LOG_LEVEL_FATAL, "Home directory for %s undefined", pw->pw_name);
+ }
+ if (chroot(pw->pw_dir) < 0)
+ {
+ log_error(LOG_LEVEL_FATAL, "Cannot chroot to %s", pw->pw_dir);
+ }
+ if (chdir ("/"))
+ {
+ log_error(LOG_LEVEL_FATAL, "Cannot chdir /");
+ }
+ }
if (setuid(pw->pw_uid))
{
log_error(LOG_LEVEL_FATAL, "Cannot setuid(): Insufficient permissions.");
}
+ if (do_chroot)
+ {
+ char putenv_dummy[64];
+
+ strcpy(putenv_dummy, "HOME=/");
+ if (putenv(putenv_dummy) != 0)
+ {
+ log_error(LOG_LEVEL_FATAL, "Cannot putenv(): HOME");
+ }
+
+ snprintf(putenv_dummy, 64, "USER=%s", pw->pw_name);
+ if (putenv(putenv_dummy) != 0)
+ {
+ log_error(LOG_LEVEL_FATAL, "Cannot putenv(): USER");
+ }
+ }
+ }
+ else if (do_chroot)
+ {
+ log_error(LOG_LEVEL_FATAL, "Cannot chroot without --user argument.");
}
}
#endif /* defined unix */
}
#ifdef FEATURE_TOGGLE
- if (g_bToggleIJB)
+ if (global_toggle_state)
{
csp->flags |= CSP_FLAG_TOGGLED_ON;
}
#if defined(AMIGA) && !defined(SELECTED_ONE_OPTION)
#define SELECTED_ONE_OPTION
csp->cfd = ReleaseSocket(csp->cfd, -1);
+
if((child_id = (int)CreateNewProcTags(
NP_Entry, (ULONG)server_thread,
NP_Output, Output(),
*/
if (child_id == 0) /* child */
{
- int inherited_toggle_state = g_bToggleIJB;
+ int rc = 0;
+#ifdef FEATURE_TOGGLE
+ int inherited_toggle_state = global_toggle_state;
+#endif /* def FEATURE_TOGGLE */
serve(csp);
+
/*
- * If we've been toggled, tell Mom
+ * If we've been toggled or we've blocked the request, tell Mom
*/
- if (inherited_toggle_state != g_bToggleIJB)
+
+#ifdef FEATURE_TOGGLE
+ if (inherited_toggle_state != global_toggle_state)
{
- _exit(17);
+ rc |= RC_FLAG_TOGGLED;
}
- else
+#endif /* def FEATURE_TOGGLE */
+
+#ifdef FEATURE_STATISTICS
+ if (csp->flags & CSP_FLAG_REJECTED)
{
- _exit(0);
+ rc |= RC_FLAG_BLOCKED;
}
+#endif /* ndef FEATURE_STATISTICS */
+
+ _exit(rc);
}
else if (child_id > 0) /* parent */
{
*/
int child_status;
#if !defined(_WIN32) && !defined(__CYGWIN__)
+
wait( &child_status );
+
/*
- * If the child has been toggled (return code 17), toggle ourselves
+ * Evaluate child's return code: If the child has
+ * - been toggled, toggle ourselves
+ * - blocked its request, bump up the stats counter
*/
- if (WIFEXITED(child_status) && (WEXITSTATUS(child_status) == 17))
+
+#ifdef FEATURE_TOGGLE
+ if (WIFEXITED(child_status) && (WEXITSTATUS(child_status) & RC_FLAG_TOGGLED))
{
- g_bToggleIJB = !g_bToggleIJB;
+ global_toggle_state = !global_toggle_state;
}
+#endif /* def FEATURE_TOGGLE */
+
+#ifdef FEATURE_STATISTICS
+ urls_read++;
+ if (WIFEXITED(child_status) && (WEXITSTATUS(child_status) & RC_FLAG_BLOCKED))
+ {
+ urls_rejected++;
+ }
+#endif /* def FEATURE_STATISTICS */
+
#endif /* !defined(_WIN32) && defined(__CYGWIN__) */
close_socket(csp->cfd);
csp->flags &= ~CSP_FLAG_ACTIVE;
sweep();
#if defined(unix)
- free(basedir);
+ freez(basedir);
#endif
+ freez(configfile);
+
+#ifdef FEATURE_COOKIE_JAR
+ if (NULL != config->jar)
+ {
+ fclose(config->jar);
+ }
+#endif
+
#if defined(_WIN32) && !defined(_WIN_CONSOLE)
/* Cleanup - remove taskbar icon etc. */
TermLogWindow();