]> code.citadel.org Git - citadel.git/blobdiff - citadel/sysdep.c
* Finished removing all the "dynamic session data" stuff in order to
[citadel.git] / citadel / sysdep.c
index e100ec67cdb4ff5ee30beec665e1a85a74400bd6..b571b8b478674dbc558c7c41d32f78a997f4d56e 100644 (file)
@@ -103,9 +103,6 @@ int syslog_facility = (-1);
 
 /*
  * lprintf()  ...   Write logging information
- * 
- * Note: the variable "buf" below needs to be large enough to handle any
- * log data sent through this function.  BE CAREFUL!
  */
 extern int running_as_daemon;
 static int enable_syslog = 1;
@@ -118,15 +115,7 @@ void lprintf(enum LogLevel loglevel, const char *format, ...) {
                va_end(arg_ptr);
        }
 
-       if (enable_syslog && LogHookTable == 0) return;
-
-       /* legacy output code; hooks get processed first */
-       char buf[SIZ];
-       va_start(arg_ptr, format);   
-               vsnprintf(buf, sizeof(buf), format, arg_ptr);   
-       va_end(arg_ptr);   
-       PerformLogHooks(loglevel, buf);
-
+       /* stderr output code */
        if (enable_syslog || running_as_daemon) return;
 
        /* if we run in forground and syslog is disabled, log to terminal */
@@ -141,18 +130,21 @@ void lprintf(enum LogLevel loglevel, const char *format, ...) {
                localtime_r(&unixtime, &tim);
                if (CC->cs_pid != 0) {
                        fprintf(stderr,
-                               "%04d/%02d/%02d %2d:%02d:%02d.%06ld [%3d] %s",
+                               "%04d/%02d/%02d %2d:%02d:%02d.%06ld [%3d] ",
                                tim.tm_year + 1900, tim.tm_mon + 1,
                                tim.tm_mday, tim.tm_hour, tim.tm_min,
                                tim.tm_sec, (long)tv.tv_usec,
-                               CC->cs_pid, buf);
+                               CC->cs_pid);
                } else {
                        fprintf(stderr,
-                               "%04d/%02d/%02d %2d:%02d:%02d.%06ld %s",
+                               "%04d/%02d/%02d %2d:%02d:%02d.%06ld ",
                                tim.tm_year + 1900, tim.tm_mon + 1,
                                tim.tm_mday, tim.tm_hour, tim.tm_min,
-                               tim.tm_sec, (long)tv.tv_usec, buf);
+                               tim.tm_sec, (long)tv.tv_usec);
                }
+               va_start(arg_ptr, format);   
+                       vfprintf(stderr, format, arg_ptr);   
+               va_end(arg_ptr);   
                fflush(stderr);
        }
 }   
@@ -160,20 +152,15 @@ void lprintf(enum LogLevel loglevel, const char *format, ...) {
 
 
 /*
- * We used to use master_cleanup() as a signal handler to shut down the server.
- * however, master_cleanup() and the functions it calls do some things that
- * aren't such a good idea to do from a signal handler: acquiring mutexes,
- * playing with signal masks on BSDI systems, etc. so instead we install the
- * following signal handler to set a global variable to inform the main loop
- * that it's time to call master_cleanup() and exit.
+ * Signal handler to shut down the server.
  */
 
 volatile int time_to_die = 0;
 
 static RETSIGTYPE signal_cleanup(int signum) {
-       lprintf(CTDL_DEBUG, "Signal %d received.\n", signum);
+       lprintf(CTDL_DEBUG, "Caught signal %d; shutting down.\n", signum);
        time_to_die = 1;
-       master_cleanup();       /* will this work? */
+       master_cleanup(signum);
 }
 
 
@@ -182,6 +169,7 @@ static RETSIGTYPE signal_cleanup(int signum) {
  */
 void init_sysdep(void) {
        int i;
+       sigset_t set;
 
        /* Avoid vulnerabilities related to FD_SETSIZE if we can. */
 #ifdef FD_SETSIZE
@@ -218,10 +206,23 @@ void init_sysdep(void) {
         * The action for unexpected signals and exceptions should be to
         * call signal_cleanup() to gracefully shut down the server.
         */
+       sigemptyset(&set);
+       sigaddset(&set, SIGINT);
+       sigaddset(&set, SIGQUIT);
+       sigaddset(&set, SIGHUP);
+       sigaddset(&set, SIGTERM);
+       // sigaddset(&set, SIGSEGV);    commented out because
+       // sigaddset(&set, SIGILL);     we want core dumps
+       // sigaddset(&set, SIGBUS);
+       sigprocmask(SIG_UNBLOCK, &set, NULL);
+
        signal(SIGINT, signal_cleanup);
        signal(SIGQUIT, signal_cleanup);
        signal(SIGHUP, signal_cleanup);
        signal(SIGTERM, signal_cleanup);
+       // signal(SIGSEGV, signal_cleanup);     commented out because
+       // signal(SIGILL, signal_cleanup);      we want core dumps
+       // signal(SIGBUS, signal_cleanup);
 
        /*
         * Do not shut down the server on broken pipe signals, otherwise the
@@ -309,6 +310,14 @@ int ig_tcp_server(char *ip_addr, int port_number, int queue_len)
                return(-1);
        }
 
+       /* set to nonblock - we need this for some obscure situations */
+       if (fcntl(s, F_SETFL, O_NONBLOCK) < 0) {
+               lprintf(CTDL_EMERG, "citserver: Can't set socket to non-blocking: %s\n",
+                       strerror(errno));
+               close(s);
+               return(-1);
+       }
+
        if (listen(s, actual_queue_len) < 0) {
                lprintf(CTDL_EMERG, "citserver: Can't listen: %s\n", strerror(errno));
                close(s);
@@ -357,6 +366,14 @@ int ig_uds_server(char *sockpath, int queue_len)
                return(-1);
        }
 
+       /* set to nonblock - we need this for some obscure situations */
+       if (fcntl(s, F_SETFL, O_NONBLOCK) < 0) {
+               lprintf(CTDL_EMERG, "citserver: Can't set socket to non-blocking: %s\n",
+                       strerror(errno));
+               close(s);
+               return(-1);
+       }
+
        if (listen(s, actual_queue_len) < 0) {
                lprintf(CTDL_EMERG, "citserver: Can't listen: %s\n", strerror(errno));
                return(-1);
@@ -393,7 +410,8 @@ struct CitContext *MyContext(void) {
  * sessions terminate.
  */
 struct CitContext *CreateNewContext(void) {
-       struct CitContext *me, *ptr;
+       struct CitContext *me;
+       static int next_pid = 0;
 
        me = (struct CitContext *) malloc(sizeof(struct CitContext));
        if (me == NULL) {
@@ -414,42 +432,14 @@ struct CitContext *CreateNewContext(void) {
         * the list.
         */
        begin_critical_section(S_SESSION_TABLE);
-
-       if (ContextList == NULL) {
-               ContextList = me;
-               me->cs_pid = 1;
-               me->prev = NULL;
-               me->next = NULL;
-       }
-
-       else if (ContextList->cs_pid > 1) {
-               me->prev = NULL;
-               me->next = ContextList;
-               ContextList = me;
-               me->cs_pid = 1;
-       }
-
-       else {
-               for (ptr = ContextList; ptr != NULL; ptr = ptr->next) {
-                       if (ptr->next == NULL) {
-                               ptr->next = me;
-                               me->cs_pid = ptr->cs_pid + 1;
-                               me->prev = ptr;
-                               me->next = NULL;
-                               goto DONE;
-                       }
-                       else if (ptr->next->cs_pid > (ptr->cs_pid+1)) {
-                               me->prev = ptr;
-                               me->next = ptr->next;
-                               ptr->next->prev = me;
-                               ptr->next = me;
-                               me->cs_pid = ptr->cs_pid + 1;
-                               goto DONE;
-                       }
-               }
+       me->cs_pid = ++next_pid;
+       me->prev = NULL;
+       me->next = ContextList;
+       ContextList = me;
+       if (me->next != NULL) {
+               me->next->prev = me;
        }
-
-DONE:  ++num_sessions;
+       ++num_sessions;
        end_critical_section(S_SESSION_TABLE);
        return(me);
 }
@@ -526,21 +516,25 @@ void client_write(char *buf, int nbytes)
 {
        int bytes_written = 0;
        int retval;
-       int sock;
 #ifndef HAVE_TCP_BUFFERING
        int old_buffer_len = 0;
 #endif
 
-       if (CC->redirect_fp != NULL) {
-               fwrite(buf, (size_t)nbytes, (size_t)1, CC->redirect_fp);
+       if (CC->redirect_buffer != NULL) {
+               if ((CC->redirect_len + nbytes + 2) >= CC->redirect_alloc) {
+                       CC->redirect_alloc = (CC->redirect_alloc * 2) + nbytes;
+                       CC->redirect_buffer = realloc(CC->redirect_buffer,
+                                               CC->redirect_alloc);
+               }
+               memcpy(&CC->redirect_buffer[CC->redirect_len], buf, nbytes);
+               CC->redirect_len += nbytes;
+               CC->redirect_buffer[CC->redirect_len] = 0;
                return;
        }
 
-       if (CC->redirect_sock > 0) {
-               sock = CC->redirect_sock;       /* and continue below... */
-       }
-       else {
-               sock = CC->client_socket;
+       if (CC->redirect_fp != NULL) {
+               fwrite(buf, (size_t)nbytes, (size_t)1, CC->redirect_fp);
+               return;
        }
 
 #ifndef HAVE_TCP_BUFFERING
@@ -564,12 +558,12 @@ void client_write(char *buf, int nbytes)
 #endif
 
        while (bytes_written < nbytes) {
-               retval = write(sock, &buf[bytes_written],
+               retval = write(CC->client_socket, &buf[bytes_written],
                        nbytes - bytes_written);
                if (retval < 1) {
                        lprintf(CTDL_ERR, "client_write() failed: %s\n",
                                strerror(errno));
-                       if (sock == CC->client_socket) CC->kill_me = 1;
+                       CC->kill_me = 1;
                        return;
                }
                bytes_written = bytes_written + retval;
@@ -876,18 +870,14 @@ void dead_session_purge(int force) {
 
 
 /*
- * Redirect a session's output to a file or socket.
- * This function may be called with a file handle *or* a socket (but not
- * both).  Call with neither to return output to its normal client socket.
+ * Redirect a session's output to a file.
+ * This function may be called with a file handle.
+ * Call with NULL to return output to its normal client socket.
  */
-void CtdlRedirectOutput(FILE *fp, int sock) {
-
+void CtdlRedirectOutput(FILE *fp)
+{
        if (fp != NULL) CC->redirect_fp = fp;
        else CC->redirect_fp = NULL;
-
-       if (sock > 0) CC->redirect_sock = sock;
-       else CC->redirect_sock = (-1);
-
 }
 
 
@@ -963,7 +953,9 @@ do_select:  force_purge = 0;
                }
                end_critical_section(S_SESSION_TABLE);
 
-               if (bind_me) goto SKIP_SELECT;
+               if (bind_me) {
+                       goto SKIP_SELECT;
+               }
 
                /* If we got this far, it means that there are no sessions
                 * which a previous thread marked for attention, so we go
@@ -1012,12 +1004,7 @@ do_select:       force_purge = 0;
 
                        if (FD_ISSET(serviceptr->msock, &readfds)) {
                                ssock = accept(serviceptr->msock, NULL, 0);
-                               if (ssock < 0) {
-                                       lprintf(CTDL_CRIT,
-                                               "citserver: accept(): %s\n",
-                                               strerror(errno));
-                               }
-                               else {
+                               if (ssock >= 0) {
                                        lprintf(CTDL_DEBUG,
                                                "New client socket %d\n",
                                                ssock);