main.c
来自「这是一个完全开放的」· C语言 代码 · 共 393 行
C
393 行
/* * jabberd - Jabber Open Source Server * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney, * Ryan Eatmon, Robert Norris * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA */#include "sm.h"/** @file sm/main.c * @brief initialisation * @author Robert Norris * $Date: 2004/11/13 16:14:26 $ * $Revision: 1.46.2.11 $ */static sig_atomic_t sm_shutdown = 0;sig_atomic_t sm_lost_router = 0;static sig_atomic_t sm_logrotate = 0;static void _sm_signal(int signum){ sm_shutdown = 1; sm_lost_router = 0;}static void _sm_signal_hup(int signum){ sm_logrotate = 1;}/** store the process id */static void _sm_pidfile(sm_t sm) { char *pidfile; FILE *f; pid_t pid; pidfile = config_get_one(sm->config, "pidfile", 0); if(pidfile == NULL) return; pid = getpid(); if((f = fopen(pidfile, "w+")) == NULL) { log_write(sm->log, LOG_ERR, "couldn't open %s for writing: %s", pidfile, strerror(errno)); return; } if(fprintf(f, "%d", pid) < 0) { log_write(sm->log, LOG_ERR, "couldn't write to %s: %s", pidfile, strerror(errno)); return; } fclose(f); log_write(sm->log, LOG_INFO, "process id is %d, written to %s", pid, pidfile);}/** pull values out of the config file */static void _sm_config_expand(sm_t sm){ char *str; sm->id = config_get_one(sm->config, "id", 0); if(sm->id == NULL) sm->id = "localhost"; sm->router_ip = config_get_one(sm->config, "router.ip", 0); if(sm->router_ip == NULL) sm->router_ip = "127.0.0.1"; sm->router_port = j_atoi(config_get_one(sm->config, "router.port", 0), 5347); sm->router_user = config_get_one(sm->config, "router.user", 0); if(sm->router_user == NULL) sm->router_user = "jabberd"; sm->router_pass = config_get_one(sm->config, "router.pass", 0); if(sm->router_pass == NULL) sm->router_pass = "secret"; sm->router_pemfile = config_get_one(sm->config, "router.pemfile", 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) sm->retry_sleep = 1; sm->log_type = log_STDOUT; if(config_get(sm->config, "log") != NULL) { if((str = config_get_attr(sm->config, "log", 0, "type")) != NULL) { if(strcmp(str, "file") == 0) sm->log_type = log_FILE; else if(strcmp(str, "syslog") == 0) sm->log_type = log_SYSLOG; } } if(sm->log_type == log_SYSLOG) { sm->log_facility = config_get_one(sm->config, "log.facility", 0); sm->log_ident = config_get_one(sm->config, "log.ident", 0); if(sm->log_ident == NULL) sm->log_ident = "jabberd/sm"; } else if(sm->log_type == log_FILE) sm->log_ident = config_get_one(sm->config, "log.file", 0);}static int _sm_router_connect(sm_t sm) { log_write(sm->log, LOG_NOTICE, "attempting connection to router at %s, port=%d", sm->router_ip, sm->router_port); sm->fd = mio_connect(sm->mio, sm->router_port, sm->router_ip, sm_mio_callback, (void *) sm); if(sm->fd < 0) { if(errno == ECONNREFUSED) sm_lost_router = 1; log_write(sm->log, LOG_NOTICE, "connection attempt to router failed: %s (%d)", strerror(errno), errno); return 1; } sm->router = sx_new(sm->sx_env, sm->fd, sm_sx_callback, (void *) sm); sx_client_init(sm->router, 0, NULL, NULL, NULL, "1.0"); return 0;}int main(int argc, char **argv) { sm_t sm; char *config_file; int optchar; sess_t sess;#ifdef POOL_DEBUG time_t pool_time = 0;#endif#ifdef HAVE_UMASK umask((mode_t) 0027);#endif srand(time(NULL));#ifdef HAVE_WINSOCK2_H/* get winsock running */ { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { /* !!! tell user that we couldn't find a usable winsock dll */ return 0; } }#endif jabber_signal(SIGINT, _sm_signal); jabber_signal(SIGTERM, _sm_signal);#ifdef SIGHUP jabber_signal(SIGHUP, _sm_signal_hup);#endif#ifdef SIGPIPE jabber_signal(SIGPIPE, SIG_IGN);#endif sm = (sm_t) malloc(sizeof(struct sm_st)); memset(sm, 0, sizeof(struct sm_st)); /* load our config */ sm->config = config_new(); config_file = CONFIG_DIR "/sm.xml"; /* cmdline parsing */ while((optchar = getopt(argc, argv, "Dc:h?")) >= 0) { switch(optchar) { case 'c': config_file = optarg; break; case 'D':#ifdef DEBUG set_debug_flag(1);#else printf("WARN: Debugging not enabled. Ignoring -D.\n");#endif break; case 'h': case '?': default: fputs( "sm - jabberd session manager (" VERSION ")\n" "Usage: sm <options>\n" "Options are:\n" " -c <config> config file to use [default: " CONFIG_DIR "/sm.xml]\n"#ifdef DEBUG " -D Show debug output\n"#endif , stdout); config_free(sm->config); free(sm); return 1; } } if(config_load(sm->config, config_file) != 0) { fputs("sm: couldn't load config, aborting\n", stderr); config_free(sm->config); free(sm); return 2; } _sm_config_expand(sm); sm->log = log_new(sm->log_type, sm->log_ident, sm->log_facility); log_write(sm->log, LOG_NOTICE, "starting up"); _sm_pidfile(sm); sm_signature(sm, "jabberd sm " VERSION); sm->pc = prep_cache_new(); /* start storage */ sm->st = storage_new(sm); if (sm->st == NULL) { log_write(sm->log, LOG_ERR, "failed to initialise one or more storage drivers, aborting"); exit(1); } /* pre-index known namespaces */ sm->xmlns = xhash_new(101); xhash_put(sm->xmlns, uri_AUTH, (void *) ns_AUTH); xhash_put(sm->xmlns, uri_REGISTER, (void *) ns_REGISTER); xhash_put(sm->xmlns, uri_ROSTER, (void *) ns_ROSTER); xhash_put(sm->xmlns, uri_AGENTS, (void *) ns_AGENTS); xhash_put(sm->xmlns, uri_DELAY, (void *) ns_DELAY); xhash_put(sm->xmlns, uri_VERSION, (void *) ns_VERSION); xhash_put(sm->xmlns, uri_TIME, (void *) ns_TIME); xhash_put(sm->xmlns, uri_VCARD, (void *) ns_VCARD); xhash_put(sm->xmlns, uri_PRIVATE, (void *) ns_PRIVATE); xhash_put(sm->xmlns, uri_BROWSE, (void *) ns_BROWSE); xhash_put(sm->xmlns, uri_EVENT, (void *) ns_EVENT); xhash_put(sm->xmlns, uri_GATEWAY, (void *) ns_GATEWAY); xhash_put(sm->xmlns, uri_LAST, (void *) ns_LAST); xhash_put(sm->xmlns, uri_EXPIRE, (void *) ns_EXPIRE); xhash_put(sm->xmlns, uri_PRIVACY, (void *) ns_PRIVACY); xhash_put(sm->xmlns, uri_SEARCH, (void *) ns_SEARCH); xhash_put(sm->xmlns, uri_DISCO, (void *) ns_DISCO); xhash_put(sm->xmlns, uri_DISCO_ITEMS, (void *) ns_DISCO_ITEMS); xhash_put(sm->xmlns, uri_DISCO_INFO, (void *) ns_DISCO_INFO); xhash_put(sm->xmlns, uri_VACATION, (void *) ns_VACATION); /* supported features */ sm->features = xhash_new(101); /* load acls */ sm->acls = aci_load(sm); /* the core supports iq, everything else is handled by the modules */ feature_register(sm, "iq"); /* startup the modules */ sm->mm = mm_new(sm); log_write(sm->log, LOG_NOTICE, "version: %s", sm->signature); sm->sessions = xhash_new(401); sm->users = xhash_new(401); 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, sm->router_pemfile, NULL); if(sm->sx_ssl == NULL) { log_write(sm->log, LOG_ERR, "failed to load SSL pemfile, SSL disabled"); sm->router_pemfile = NULL; } }#endif /* get sasl online */ sm->sx_sasl = sx_env_plugin(sm->sx_env, sx_sasl_init, NULL, NULL, 0); if(sm->sx_sasl == NULL) { log_write(sm->log, LOG_ERR, "failed to initialise SASL context, aborting"); exit(1); } sm->mio = mio_new(1024); sm->retry_left = sm->retry_init; _sm_router_connect(sm); while(!sm_shutdown) { mio_run(sm->mio, 5); if(sm_logrotate) { log_write(sm->log, LOG_NOTICE, "reopening log ..."); log_free(sm->log); sm->log = log_new(sm->log_type, sm->log_ident, sm->log_facility); log_write(sm->log, LOG_NOTICE, "log started"); sm_logrotate = 0; } if(sm_lost_router) { if(sm->retry_left < 0) { log_write(sm->log, LOG_NOTICE, "attempting reconnect"); sleep(sm->retry_sleep); sm_lost_router = 0; _sm_router_connect(sm); } else if(sm->retry_left == 0) { sm_shutdown = 1; } else { log_write(sm->log, LOG_NOTICE, "attempting reconnect (%d left)", sm->retry_left); sm->retry_left--; sleep(sm->retry_sleep); sm_lost_router = 0; _sm_router_connect(sm); } }#ifdef POOL_DEBUG if(time(NULL) > pool_time + 60) { pool_stat(1); pool_time = time(NULL); }#endif } log_write(sm->log, LOG_NOTICE, "shutting down"); /* shut down sessions */ if(xhash_iter_first(sm->sessions)) do { xhash_iter_get(sm->sessions, NULL, (void *) &sess); sm_c2s_action(sess, "ended", NULL); sess_end(sess); } while(xhash_iter_next(sm->sessions)); xhash_free(sm->sessions); mio_free(sm->mio); xhash_free(sm->acls); xhash_free(sm->features); xhash_free(sm->xmlns); xhash_free(sm->users); mm_free(sm->mm); storage_free(sm->st); sx_free(sm->router); sx_env_free(sm->sx_env); prep_cache_free(sm->pc); log_free(sm->log); config_free(sm->config); free(sm);#ifdef POOL_DEBUG pool_stat(1);#endif#ifdef HAVE_WINSOCK2_H WSACleanup();#endif return 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?