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 + -
显示快捷键?