main.c.patch   [plain text]


--- /tmp/jabberd-2.2.14/sm/main.c	2011-05-31 15:11:37.000000000 -0700
+++ ./jabberd2/sm/main.c	2011-06-22 20:13:00.000000000 -0700
@@ -30,6 +30,7 @@
 
 static sig_atomic_t sm_shutdown = 0;
 static sig_atomic_t sm_logrotate = 0;
+static sig_atomic_t sm_sighup = 0;
 static sm_t sm = NULL;
 static char* config_file;
 
@@ -41,24 +42,7 @@ static void _sm_signal(int signum)
 
 static void _sm_signal_hup(int signum)
 {
-    config_t conf;
-
-    log_write(sm->log, LOG_NOTICE, "HUP handled. reloading modules...");
-
-    sm_logrotate = 1;
-
-    /* reload dynamic modules */
-    conf = config_new();
-    if (conf && config_load(conf, config_file) == 0) {
-        config_free(sm->config);
-        sm->config = conf;
-        /*_sm_config_expand(sm);*/ /* we want to reload modules only */
-    } else {
-        log_write(sm->log, LOG_WARNING, "couldn't reload config (%s)", config_file);
-        if (conf) config_free(conf);
-    }
-    mm_free(sm->mm);
-    sm->mm = mm_new(sm);
+    sm_sighup = 1;
 }
 
 /** store the process id */
@@ -66,6 +50,10 @@ static void _sm_pidfile(sm_t sm) {
     char *pidfile;
     FILE *f;
     pid_t pid;
+    char piddir[PATH_MAX] = "";
+    struct stat statbuf;
+    int i, last;
+    int i_slash = 0;
 
     pidfile = config_get_one(sm->config, "pidfile", 0);
     if(pidfile == NULL)
@@ -73,6 +61,39 @@ static void _sm_pidfile(sm_t sm) {
 
     pid = getpid();
 
+    // Get the pid directory from the full file path
+    for (i = 0; pidfile[i] != '\0'; i++) {
+        if (pidfile[i] == '/')
+            i_slash = i;
+    }
+    do { // not a loop
+        if (i_slash == 0) {
+            // no directory provided in pidfile preference, or only one slash found in path... skip creation attempt
+            break;
+        } else {
+            last = i_slash+1;
+        }
+        if (i_slash > sizeof(piddir)) {
+            log_write(sm->log, LOG_ERR, "specified PID path exceeds the maximum allowed length");
+            return;
+        }
+        strlcpy(piddir, pidfile, last);
+
+        // Create the pid directory if it does not exist (don't attempt to create intermediate directories)
+        if (stat(piddir, &statbuf)) {
+            log_debug(ZONE, "pid directory appears to not exist, trying to create it...");
+            if (mkdir(piddir, 0755)) {
+                if ((errno == EEXIST) && (! stat(piddir, &statbuf))) {
+                    log_debug(ZONE, "working around probable race condition, pid directory now exists");
+                    break;
+                }
+                log_write(sm->log, LOG_ERR, "couldn't create pid directory %s: %s", piddir, strerror(errno));
+                return;
+            }
+            log_debug(ZONE, "created pid directory: %s", piddir);
+        }
+    } while(0); // not a loop
+
     if((f = fopen(pidfile, "w+")) == NULL) {
         log_write(sm->log, LOG_ERR, "couldn't open %s for writing: %s", pidfile, strerror(errno));
         return;
@@ -93,6 +114,7 @@ static void _sm_pidfile(sm_t sm) {
 static void _sm_config_expand(sm_t sm)
 {
     char *str;
+    config_elem_t elem;
 
     sm->id = config_get_one(sm->config, "id", 0);
     if(sm->id == NULL)
@@ -113,6 +135,8 @@ static void _sm_config_expand(sm_t sm)
 
     sm->router_pemfile = config_get_one(sm->config, "router.pemfile", 0);
 
+    sm->router_private_key_password = config_get_one(sm->config, "router.private_key_password", 0);
+
     sm->retry_init = j_atoi(config_get_one(sm->config, "router.retry.init", 0), 3);
     sm->retry_lost = j_atoi(config_get_one(sm->config, "router.retry.lost", 0), 3);
     if((sm->retry_sleep = j_atoi(config_get_one(sm->config, "router.retry.sleep", 0), 2)) < 1)
@@ -135,6 +159,19 @@ static void _sm_config_expand(sm_t sm)
             sm->log_ident = "jabberd/sm";
     } else if(sm->log_type == log_FILE)
         sm->log_ident = config_get_one(sm->config, "log.file", 0);
+        
+    elem = config_get(sm->config, "storage.limits.queries");
+    if(elem != NULL)
+    {
+        sm->query_rate_total = j_atoi(elem->values[0], 0);
+        if(sm->query_rate_total != 0)
+        {
+            sm->query_rate_seconds = j_atoi(j_attr((const char **) elem->attrs[0], "seconds"), 5);
+            sm->query_rate_wait = j_atoi(j_attr((const char **) elem->attrs[0], "throttle"), 60);
+        }
+    }
+    sm->masq_sender_replacement = config_get_one(sm->config, "aci.masq_sender_replacement", 0);
+    sm->apple_notification_component_addr = config_get_one(sm->config, "apple_notification_component_addr", 0);
 }
 
 static void _sm_hosts_expand(sm_t sm)
@@ -332,11 +369,13 @@ JABBER_MAIN("jabberd2sm", "Jabber 2 Sess
 
     sm->users = xhash_new(401);
 
+    sm->query_rates = xhash_new(101);
+
     sm->sx_env = sx_env_new();
 
 #ifdef HAVE_SSL
     if(sm->router_pemfile != NULL) {
-        sm->sx_ssl = sx_env_plugin(sm->sx_env, sx_ssl_init, NULL, sm->router_pemfile, NULL, NULL);
+        sm->sx_ssl = sx_env_plugin(sm->sx_env, sx_ssl_init, NULL, sm->router_pemfile, NULL, NULL, sm->router_private_key_password);
         if(sm->sx_ssl == NULL) {
             log_write(sm->log, LOG_ERR, "failed to load SSL pemfile, SSL disabled");
             sm->router_pemfile = NULL;
@@ -363,6 +402,31 @@ JABBER_MAIN("jabberd2sm", "Jabber 2 Sess
     while(!sm_shutdown) {
         mio_run(sm->mio, 5);
 
+        if (sm_sighup) {
+            config_t conf;
+            log_write(sm->log, LOG_NOTICE, "HUP handled. reloading modules...");
+
+            sm_logrotate = 1;
+
+            // Reload any selected config items
+            conf = config_new();
+            if (conf && config_load(conf, config_file) == 0) {
+                // Apple FIXME: config_free here results in memory corruption and causes the logging of arbitrary
+                //     data.  Disabling module reloading until we can fix this.
+                //config_free(sm->config);
+                //sm->config = conf;
+                sm->apple_notification_component_addr = config_get_one(conf, "apple_notification_component_addr", 0);
+                config_free(conf);
+            } else {
+                log_write(sm->log, LOG_WARNING, "couldn't reload config (%s)", config_file);
+                if (conf) config_free(conf);
+            }
+            //mm_free(sm->mm);
+            //sm->mm = mm_new(sm);
+
+            sm_sighup = 0;
+        }
+
         if(sm_logrotate) {
             log_write(sm->log, LOG_NOTICE, "reopening log ...");
             log_free(sm->log);
@@ -411,7 +475,7 @@ JABBER_MAIN("jabberd2sm", "Jabber 2 Sess
             xhash_iter_get(sm->sessions, NULL, NULL, (void *) &sess);
             sm_c2s_action(sess, "ended", NULL);
             sess_end(sess);
-        } while(xhash_count(sm->sessions) > 0);
+        } while (xhash_iter_next(sm->sessions));
 
     xhash_free(sm->sessions);
 
@@ -428,6 +492,7 @@ JABBER_MAIN("jabberd2sm", "Jabber 2 Sess
     xhash_free(sm->xmlns_refcount);
     xhash_free(sm->users);
     xhash_free(sm->hosts);
+    xhash_free(sm->query_rates);
 
     sx_free(sm->router);