--- /tmp/jabberd-2.2.13/router/main.c 2011-02-23 08:24:35.000000000 -0800 +++ ./jabberd2/router/main.c 2011-04-05 20:29:43.000000000 -0700 @@ -38,6 +38,10 @@ static void _router_pidfile(router_t r) 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(r->config, "pidfile", 0); if(pidfile == NULL) @@ -45,6 +49,39 @@ static void _router_pidfile(router_t r) 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(r->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(r->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(r->log, LOG_ERR, "couldn't open %s for writing: %s", pidfile, strerror(errno)); return; @@ -66,7 +103,7 @@ static void _router_config_expand(router { char *str, *ip, *mask, *name, *target; config_elem_t elem; - int i; + int i, len; alias_t alias; r->id = config_get_one(r->config, "id", 0); @@ -101,6 +138,8 @@ static void _router_config_expand(router r->local_pemfile = config_get_one(r->config, "local.pemfile", 0); + r->local_private_key_password = config_get_one(r->config, "local.private_key_password", 0); + r->io_max_fds = j_atoi(config_get_one(r->config, "io.max_fds", 0), 1024); elem = config_get(r->config, "io.limits.bytes"); @@ -186,6 +225,23 @@ static void _router_config_expand(router r->aliases = alias; } + /* message logging to flat file */ + r->message_logging_enabled = j_atoi(config_get_one(r->config, "message_logging_enabled", 0), 1); + r->message_logging_dir = config_get_one(r->config, "message_logging_dir", 0); + r->message_logging_file = config_get_one(r->config, "message_logging_file", 0); + len = strlen(r->message_logging_dir) + strlen(r->message_logging_file); + if (len < (PATH_MAX-13)) { // room for a full path plus .xxxx.gz appended (necessary for log rolling) + r->message_logging_fullpath = (char *)malloc(len+2); + snprintf(r->message_logging_fullpath, len+2, "%s/%s", r->message_logging_dir, r->message_logging_file); + } else { + log_debug(ZONE, "ERROR: message logging directory and filename exceed file system limits, %d bytes.\n Disabling message logging.", len); + r->message_logging_fullpath = NULL; + r->message_logging_enabled = 0; + } + r->message_logging_roll_days = j_atoi(config_get_one(r->config, "message_logging_roll_days", 0), 30); + r->message_logging_roll_megs = j_atoi(config_get_one(r->config, "message_logging_roll_megs", 0), 500); + r->filter_muc_messages_from = config_get_one(r->config, "filter_muc_messages_from", 0); + r->check_interval = j_atoi(config_get_one(r->config, "check.interval", 0), 60); r->check_keepalive = j_atoi(config_get_one(r->config, "check.keepalive", 0), 0); } @@ -282,6 +338,7 @@ JABBER_MAIN("jabberd2router", "Jabber 2 rate_t rt; component_t comp; union xhashv xhv; + int close_wait_max; #ifdef POOL_DEBUG time_t pool_time = 0; @@ -394,7 +451,7 @@ JABBER_MAIN("jabberd2router", "Jabber 2 #ifdef HAVE_SSL if(r->local_pemfile != NULL) { - r->sx_ssl = sx_env_plugin(r->sx_env, sx_ssl_init, NULL, r->local_pemfile, NULL, NULL); + r->sx_ssl = sx_env_plugin(r->sx_env, sx_ssl_init, NULL, r->local_pemfile, NULL, NULL, r->local_private_key_password); if(r->sx_ssl == NULL) log_write(r->log, LOG_ERR, "failed to load SSL pemfile, SSL disabled"); } @@ -457,6 +514,12 @@ JABBER_MAIN("jabberd2router", "Jabber 2 _router_time_checks(r); + if (r->message_logging_enabled) + { + // Roll message logs if necessary + roll_message_log(r); + } + r->next_check = time(NULL) + r->check_interval; log_debug(ZONE, "next time check at %d", r->next_check); } @@ -485,6 +548,8 @@ JABBER_MAIN("jabberd2router", "Jabber 2 * their destinations */ + close_wait_max = 30; /* time limit for component shutdown */ + /* close connections to components */ xhv.comp_val = ∁ if(xhash_iter_first(r->components)) @@ -493,9 +558,11 @@ JABBER_MAIN("jabberd2router", "Jabber 2 log_debug(ZONE, "close component %p", comp); if (comp) sx_close(comp->s); mio_run(r->mio, 5000); + if (1 > close_wait_max--) break; + sleep(1); while(jqueue_size(r->closefd) > 0) mio_close(r->mio, (mio_fd_t) jqueue_pull(r->closefd)); - } while(xhash_count(r->components) > 0); + } while (xhash_iter_next(r->components)); xhash_free(r->components); @@ -540,6 +607,10 @@ JABBER_MAIN("jabberd2router", "Jabber 2 /* unload acls */ aci_unload(r->aci); + /* free message logging variables */ + if (r->message_logging_fullpath != NULL) + free(r->message_logging_fullpath); + /* unload filter */ filter_unload(r);