⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 这是一个完全开放的
💻 C
字号:
/* * 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 "router.h"static sig_atomic_t router_shutdown = 0;static sig_atomic_t router_logrotate = 0;void router_signal(int signum){    router_shutdown = 1;}void router_signal_hup(int signum){    router_logrotate = 1;}/** store the process id */static void _router_pidfile(router_t r) {    char *pidfile;    FILE *f;    pid_t pid;    pidfile = config_get_one(r->config, "pidfile", 0);    if(pidfile == NULL)        return;    pid = getpid();    if((f = fopen(pidfile, "w+")) == NULL) {        log_write(r->log, LOG_ERR, "couldn't open %s for writing: %s", pidfile, strerror(errno));        return;    }    if(fprintf(f, "%d", pid) < 0) {        log_write(r->log, LOG_ERR, "couldn't write to %s: %s", pidfile, strerror(errno));        return;    }    fclose(f);    log_write(r->log, LOG_INFO, "process id is %d, written to %s", pid, pidfile);}/** pull values out of the config file */static void _router_config_expand(router_t r){    char *str, *ip, *mask, *name, *target;    config_elem_t elem;    int i;    alias_t alias;    r->id = config_get_one(r->config, "id", 0);    if(r->id == NULL)        r->id = "router";    r->log_type = log_STDOUT;    if(config_get(r->config, "log") != NULL) {        if((str = config_get_attr(r->config, "log", 0, "type")) != NULL) {            if(strcmp(str, "file") == 0)                r->log_type = log_FILE;            else if(strcmp(str, "syslog") == 0)                r->log_type = log_SYSLOG;        }    }    if(r->log_type == log_SYSLOG) {        r->log_facility = config_get_one(r->config, "log.facility", 0);        r->log_ident = config_get_one(r->config, "log.ident", 0);        if(r->log_ident == NULL)            r->log_ident = "jabberd/router";    } else if(r->log_type == log_FILE)        r->log_ident = config_get_one(r->config, "log.file", 0);    r->local_ip = config_get_one(r->config, "local.ip", 0);    if(r->local_ip == NULL)        r->local_ip = "0.0.0.0";    r->local_port = j_atoi(config_get_one(r->config, "local.port", 0), 5347);    r->local_secret = config_get_one(r->config, "local.secret", 0);    r->local_pemfile = config_get_one(r->config, "local.pemfile", 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");    if(elem != NULL)    {        r->byte_rate_total = j_atoi(elem->values[0], 0);        if(r->byte_rate_total != 0)        {            r->byte_rate_seconds = j_atoi(j_attr((const char **) elem->attrs[0], "seconds"), 5);            r->byte_rate_wait = j_atoi(j_attr((const char **) elem->attrs[0], "throttle"), 5);        }    }    elem = config_get(r->config, "io.limits.connects");    if(elem != NULL)    {        r->conn_rate_total = j_atoi(elem->values[0], 0);        if(r->conn_rate_total != 0)        {            r->conn_rate_seconds = j_atoi(j_attr((const char **) elem->attrs[0], "seconds"), 5);            r->conn_rate_wait = j_atoi(j_attr((const char **) elem->attrs[0], "throttle"), 5);        }    }    str = config_get_one(r->config, "io.access.order", 0);    if(str == NULL || strcmp(str, "deny,allow") != 0)        r->access = access_new(0);    else        r->access = access_new(1);    elem = config_get(r->config, "io.access.allow");    if(elem != NULL)    {        for(i = 0; i < elem->nvalues; i++)        {            ip = j_attr((const char **) elem->attrs[i], "ip");            mask = j_attr((const char **) elem->attrs[i], "mask");            if(ip == NULL)                continue;            if(mask == NULL)                mask = "255.255.255.255";            access_allow(r->access, ip, mask);        }    }    elem = config_get(r->config, "io.access.deny");    if(elem != NULL)    {        for(i = 0; i < elem->nvalues; i++)        {            ip = j_attr((const char **) elem->attrs[i], "ip");            mask = j_attr((const char **) elem->attrs[i], "mask");            if(ip == NULL)                continue;            if(mask == NULL)                mask = "255.255.255.255";            access_deny(r->access, ip, mask);        }    }    /* aliases */    elem = config_get(r->config, "aliases.alias");    if(elem != NULL)        for(i = 0; i < elem->nvalues; i++) {            name = j_attr((const char **) elem->attrs[i], "name");            target = j_attr((const char **) elem->attrs[i], "target");            if(name == NULL || target == NULL)                continue;            alias = (alias_t) malloc(sizeof(struct alias_st));            memset(alias, 0, sizeof(struct alias_st));            alias->name = name;            alias->target = target;            alias->next = r->aliases;            r->aliases = alias;        }}static int _router_sx_sasl_callback(int cb, void *arg, void **res, scod_t sd, void *cbarg) {    router_t r = (router_t) cbarg;    sx_t s;    scod_cb_creds_t creds;    char *pass;    switch(cb) {        case sx_sasl_cb_GET_REALM:            s = (sx_t) arg;            strcpy((char *) res, "jabberd-router");            break;        case sx_sasl_cb_GET_PASS:            creds = (scod_cb_creds_t) arg;            log_debug(ZONE, "sx sasl callback: get pass (authnid=%s, realm=%s)", creds->authnid, creds->realm);            *res = xhash_get(r->users, creds->authnid);            if(*res == NULL)                return 1;            return 0;        case sx_sasl_cb_CHECK_PASS:            creds = (scod_cb_creds_t) arg;            log_debug(ZONE, "sx sasl callback: check pass (authnid=%s, realm=%s)", creds->authnid, creds->realm);            pass = xhash_get(r->users, creds->authnid);            if(pass == NULL || strcmp(creds->pass, pass) != 0)                return 1;            return 0;        case sx_sasl_cb_CHECK_AUTHZID:            creds = (scod_cb_creds_t) arg;            if(creds->authzid[0] == '\0')                strcpy(creds->authzid, creds->authnid);            if(strcmp(creds->authnid, creds->authzid) != 0) {                log_debug(ZONE, "authnid '%s' doesn't match authzid '%s'", creds->authnid, creds->authzid);                return 1;            }            return 0;        default:            break;    }    return 0;}int main(int argc, char **argv){    router_t r;    char *config_file;    int optchar;#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, router_signal);    jabber_signal(SIGTERM, router_signal);#ifdef SIGHUP    jabber_signal(SIGHUP, router_signal_hup);#endif#ifdef SIGPIPE    jabber_signal(SIGPIPE, SIG_IGN);#endif    r = (router_t) malloc(sizeof(struct router_st));    memset(r, 0, sizeof(struct router_st));    /* load our config */    r->config = config_new();    config_file = CONFIG_DIR "/router.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(                    "router - jabberd router (" VERSION ")\n"                    "Usage: router <options>\n"                    "Options are:\n"                    "   -c <config>     config file to use [default: " CONFIG_DIR "/router.xml]\n"#ifdef DEBUG                    "   -D              Show debug output\n"#endif                    ,                    stdout);                config_free(r->config);                free(r);                return 1;        }    }    if(config_load(r->config, config_file) != 0)    {        fputs("router: couldn't load config, aborting\n", stderr);        config_free(r->config);        free(r);        return 2;    }    _router_config_expand(r);    r->log = log_new(r->log_type, r->log_ident, r->log_facility);    log_write(r->log, LOG_NOTICE, "starting up");    _router_pidfile(r);    user_table_load(r);    r->aci = aci_load(r);    r->conn_rates = xhash_new(101);    r->pc = prep_cache_new();    r->components = xhash_new(101);    r->routes = xhash_new(101);    r->log_sinks = xhash_new(101);    r->dead = jqueue_new();    r->sx_env = sx_env_new();#ifdef HAVE_SSL    if(r->local_pemfile != NULL) {        r->sx_ssl = sx_env_plugin(r->sx_env, sx_ssl_init, r->local_pemfile, NULL);        if(r->sx_ssl == NULL)            log_write(r->log, LOG_ERR, "failed to load SSL pemfile, SSL disabled");    }#endif    /* get sasl online */    r->sx_sasl = sx_env_plugin(r->sx_env, sx_sasl_init, _router_sx_sasl_callback, (void *) r, sd_flag_GET_PASS);    if(r->sx_sasl == NULL) {        log_write(r->log, LOG_ERR, "failed to initialise SASL context, aborting");        exit(1);    }    r->mio = mio_new(r->io_max_fds);    r->fd = mio_listen(r->mio, r->local_port, r->local_ip, router_mio_callback, (void *) r);    if(r->fd < 0) {        log_write(r->log, LOG_ERR, "[%s, port=%d] unable to listen (%s)", r->local_ip, r->local_port, strerror(errno));        exit(1);    }    log_write(r->log, LOG_NOTICE, "[%s, port=%d] listening for incoming connections", r->local_ip, r->local_port, strerror(errno));    while(!router_shutdown)    {        mio_run(r->mio, 5);        if(router_logrotate)        {            log_write(r->log, LOG_NOTICE, "reopening log ...");            log_free(r->log);            r->log = log_new(r->log_type, r->log_ident, r->log_facility);            log_write(r->log, LOG_NOTICE, "log started");            router_logrotate = 0;        }        /* cleanup dead sx_ts */        while(jqueue_size(r->dead) > 0)            sx_free((sx_t) jqueue_pull(r->dead));#ifdef POOL_DEBUG        if(time(NULL) > pool_time + 60) {            pool_stat(1);            pool_time = time(NULL);        }#endif    }    log_write(r->log, LOG_NOTICE, "shutting down");    /*     * !!! issue remote shutdowns to each service, so they can clean up.     *     we'll need to mio_run() until they all disconnect, so that     *     the the last packets (eg sm presence unavailables) can get to     *     their destinations     */    /* !!! walk r->services and free contents */    /* !!! walk r->servers and close conns */    /* !!! walk r->conn_rates and free */    prep_cache_free(r->pc);    mio_free(r->mio);    access_free(r->access);    log_free(r->log);    config_free(r->config);    free(r);#ifdef POOL_DEBUG    pool_stat(1);#endif#ifdef HAVE_WINSOCK2_H    WSACleanup();#endif    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -