]> code.citadel.org Git - citadel.git/blobdiff - citadel/sysdep.c
* added message subject to all those tiny messages
[citadel.git] / citadel / sysdep.c
index 4022555a4ca72d43218cdffeea5e68655d57c7e2..f4e20d72ebb3c6bda71acff9ecad6fce5d95f1e9 100644 (file)
@@ -154,6 +154,7 @@ void lprintf(enum LogLevel loglevel, const char *format, ...) {
  */
 
 volatile int time_to_die = 0;
+volatile int shutdown_and_halt = 0;
 
 static RETSIGTYPE signal_cleanup(int signum) {
        lprintf(CTDL_DEBUG, "Caught signal %d; shutting down.\n", signum);
@@ -247,6 +248,7 @@ void begin_critical_section(int which_one)
 #ifdef DEBUG_MEMORY_LEAKS
                && (which_one != S_DEBUGMEMLEAKS)
 #endif
+               && (which_one != S_RPLIST)
        ) {
                cdb_check_handles();
        }
@@ -268,7 +270,7 @@ void end_critical_section(int which_one)
  * a TCP port.  The server shuts down if the bind fails.
  *
  */
-int ig_tcp_server(char *ip_addr, int port_number, int queue_len)
+int ig_tcp_server(char *ip_addr, int port_number, int queue_len, char **errormessage)
 {
        struct sockaddr_in sin;
        int s, i;
@@ -294,8 +296,11 @@ int ig_tcp_server(char *ip_addr, int port_number, int queue_len)
        s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
 
        if (s < 0) {
-               lprintf(CTDL_EMERG, "citserver: Can't create a socket: %s\n",
-                       strerror(errno));
+               *errormessage = (char*) malloc(SIZ + 1);
+               snprintf(*errormessage, SIZ, 
+                                "citserver: Can't create a socket: %s",
+                                strerror(errno));
+               lprintf(CTDL_EMERG, "%s\n", *errormessage);
                return(-1);
        }
 
@@ -303,24 +308,32 @@ int ig_tcp_server(char *ip_addr, int port_number, int queue_len)
        setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
 
        if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
-               lprintf(CTDL_EMERG, "citserver: Can't bind: %s\n",
-                       strerror(errno));
+               *errormessage = (char*) malloc(SIZ + 1);
+               snprintf(*errormessage, SIZ, 
+                                "citserver: Can't bind: %s",
+                                strerror(errno));
+               lprintf(CTDL_EMERG, "%s\n", *errormessage);
                close(s);
                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));
+               *errormessage = (char*) malloc(SIZ + 1);
+               snprintf(*errormessage, SIZ, 
+                                "citserver: Can't set socket to non-blocking: %s",
+                                strerror(errno));
+               lprintf(CTDL_EMERG, "%s\n", *errormessage);
                close(s);
                return(-1);
        }
 
        if (listen(s, actual_queue_len) < 0) {
-               lprintf(CTDL_EMERG, "citserver: Can't listen: %s\n",
-                       strerror(errno));
+               *errormessage = (char*) malloc(SIZ + 1);
+               snprintf(*errormessage, SIZ, 
+                                "citserver: Can't listen: %s",
+                                strerror(errno));
+               lprintf(CTDL_EMERG, "%s\n", *errormessage);
                close(s);
                return(-1);
        }
@@ -333,7 +346,7 @@ int ig_tcp_server(char *ip_addr, int port_number, int queue_len)
 /*
  * Create a Unix domain socket and listen on it
  */
-int ig_uds_server(char *sockpath, int queue_len)
+int ig_uds_server(char *sockpath, int queue_len, char **errormessage)
 {
        struct sockaddr_un addr;
        int s;
@@ -345,8 +358,10 @@ int ig_uds_server(char *sockpath, int queue_len)
 
        i = unlink(sockpath);
        if (i != 0) if (errno != ENOENT) {
-               lprintf(CTDL_EMERG, "citserver: can't unlink %s: %s\n",
+               *errormessage = (char*) malloc(SIZ + 1);
+               snprintf(*errormessage, SIZ, "citserver: can't unlink %s: %s",
                        sockpath, strerror(errno));
+               lprintf(CTDL_EMERG, "%s\n", *errormessage);
                return(-1);
        }
 
@@ -356,29 +371,40 @@ int ig_uds_server(char *sockpath, int queue_len)
 
        s = socket(AF_UNIX, SOCK_STREAM, 0);
        if (s < 0) {
-               lprintf(CTDL_EMERG, "citserver: Can't create a socket: %s\n",
-                       strerror(errno));
+               *errormessage = (char*) malloc(SIZ + 1);
+               snprintf(*errormessage, SIZ, 
+                        "citserver: Can't create a socket: %s",
+                        strerror(errno));
+               lprintf(CTDL_EMERG, "%s\n", *errormessage);
                return(-1);
        }
 
        if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
-               lprintf(CTDL_EMERG, "citserver: Can't bind: %s\n",
-                       strerror(errno));
+               *errormessage = (char*) malloc(SIZ + 1);
+               snprintf(*errormessage, SIZ, 
+                        "citserver: Can't bind: %s",
+                        strerror(errno));
+               lprintf(CTDL_EMERG, "%s\n", *errormessage);
                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));
+               *errormessage = (char*) malloc(SIZ + 1);
+               snprintf(*errormessage, SIZ, 
+                        "citserver: Can't set socket to non-blocking: %s",
+                        strerror(errno));
+               lprintf(CTDL_EMERG, "%s\n", *errormessage);
                close(s);
                return(-1);
        }
 
        if (listen(s, actual_queue_len) < 0) {
-               lprintf(CTDL_EMERG, "citserver: Can't listen: %s\n",
-                       strerror(errno));
+               *errormessage = (char*) malloc(SIZ + 1);
+               snprintf(*errormessage, SIZ, 
+                        "citserver: Can't listen: %s",
+                        strerror(errno));
+               lprintf(CTDL_EMERG, "%s\n", *errormessage);
                return(-1);
        }
 
@@ -1051,19 +1077,29 @@ do_select:      force_purge = 0;
                                                "New client socket %d\n",
                                                ssock);
 
+                                       /* The master socket is non-blocking but the client
+                                        * sockets need to be blocking, otherwise certain
+                                        * operations barf on FreeBSD.  Not a fatal error.
+                                        */
+                                       if (fcntl(ssock, F_SETFL, 0) < 0) {
+                                               lprintf(CTDL_EMERG,
+                                                       "citserver: Can't set socket to blocking: %s\n",
+                                                       strerror(errno));
+                                       }
+
                                        /* New context will be created already
-                                       * set up in the CON_EXECUTING state.
-                                       */
+                                        * set up in the CON_EXECUTING state.
+                                        */
                                        con = CreateNewContext();
 
-                                       /* Assign new socket number to it. */
+                                       /* Assign our new socket number to it. */
                                        con->client_socket = ssock;
                                        con->h_command_function =
                                                serviceptr->h_command_function;
                                        con->h_async_function =
                                                serviceptr->h_async_function;
 
-                                       /* Determine whether local socket */
+                                       /* Determine whether it's a local socket */
                                        if (serviceptr->sockpath != NULL)
                                                con->is_local_socket = 1;