Logo Search packages:      
Sourcecode: jabberd14 version File versions  Download package

int main ( int  argc,
const char **  argv 
)

the entry point to jabberd

Parameters:
argc the number of arguments on the command line used to start jabberd
argv array of the arguments
Returns:
0 on successfull shutdown, 1 else

Definition at line 95 of file jabberd.cc.

References _jabberd_atexit(), _jabberd_signal(), base_init(), jabberd_struct::cfgfile, jabberd_struct::cmd_line, configo(), configurate(), debug__zones, deliver(), deliver__flag, deliver_init(), do_include(), heartbeat_birth(), jabberd_signal_handler(), log_notice(), mio_init(), mio_tls_early_init(), pool_stat(), pstrdup(), register_beat(), jabberd_struct::runtime_pool, set_cmdline_debug_flag(), xhash_new(), and xhash_put().

                                       {
    char *c = NULL;
    char *cmd = NULL;
    char *home = NULL;
    char *zones = NULL;       /* debugging zones */
    char *host = NULL;        /* domain/hostname to run as */
    char *spool = NULL;       /* spool directory for xdb_file */
    char *import_spool = NULL;      /* spool base dir for import */
    char *do_include = NULL;  /* include files in configuration */
    float avload;
    int do_debug = 0;           /* Debug output option, default no */
    int do_background = 0;      /* Daemonize option, default no */
    int do_version = 0;       /* print version information */
    char *run_as_user = NULL; /* user to run jabberd as */
    poptContext pCtx = NULL;
    int pReturn = 0;          /* return code of popt */

    /*
     * command line options for jabberd14
     */
    struct poptOption options[] = {
      { "config", 'c', POPT_ARG_STRING, &(jabberd.cfgfile), 0, "configuration file to use", "path and filename"},
      { "include", 'i', POPT_ARG_STRING, &do_include, 0, "include configuration files", "comma separated list"},
      { "debugmask", 'd', POPT_ARG_INT, &do_debug, 0, "enable debugging (by type)", "debugging mask"},
      { "debug", 'D', POPT_ARG_NONE, NULL, 1, "enable debugging (all types)", NULL},
      { "zones", 'Z', POPT_ARG_STRING, &zones, 0, "debugging zones (file names without extension)", "comma separated list"},
      { "user", 'U', POPT_ARG_STRING, &run_as_user, 0, "run " PACKAGE " as another user", "user to run as"},
      { "home", 'H', POPT_ARG_STRING, &home, 0, "what to use as home directory", "directory path"},
      { "define", 'x', POPT_ARG_STRING, NULL, 2, "define a replacement string for configuration", "key:value"},
      { "background", 'B', POPT_ARG_NONE, &do_background, 0, "background the server process", NULL},
      { "host", 'h', POPT_ARG_STRING, &host, 0, "hostname that should be served by " PACKAGE, "domain (FQDN)"},
      { "spooldir", 's', POPT_ARG_STRING, &spool, 0, "directory where to place the file spool of xdb_file", "directory path"},
      { "import", 'I', POPT_ARG_STRING, &import_spool, 0, "import data to the server from a filespool", "basedir of file-spool"},
      { "version", 'V', POPT_ARG_NONE, &do_version, 0, "print server version", NULL},
      { NULL, 'v', POPT_ARG_NONE|POPT_ARGFLAG_DOC_HIDDEN, &do_version, 0, "print server version", NULL},
      POPT_AUTOHELP
      POPT_TABLEEND
    };

    if (!mio_tls_early_init()) {
      return 2;
    }

    /* create hash for command line options */
    jabberd.cmd_line = xhash_new(11);
    
    /* parse command line options */
    pCtx = poptGetContext(NULL, argc, argv, options, 0);
    while ((pReturn = poptGetNextOpt(pCtx)) >= 0) {
      switch (pReturn) {
          case 1:
            do_debug = -1;
            break;
          case 2:
            cmd = pstrdup(jabberd.cmd_line->p, poptGetOptArg(pCtx));
            c = strchr(cmd, ':');
            if (c == NULL) {
                fprintf(stderr, "Invalid definition for config file replacement: %s\nNeeds to be of key:value\n", cmd);
                return 1;
            }
            c[0] = 0;
            c++;
            xhash_put(jabberd.cmd_line, cmd, c);
            cmd = c = NULL;
            break;
      }
    }

    /* error? */
    if (pReturn < -1) {
      fprintf(stderr, "%s: %s\n", poptBadOption(pCtx, POPT_BADOPTION_NOALIAS), poptStrerror(pReturn));
      return 1;
    }

    /* anything left? */
    if (poptPeekArg(pCtx) != NULL) {
      fprintf(stderr, "invalid argument: %s\n", poptGetArg(pCtx));
      return 1;
    }

    /* printing version information desired? */
    if (do_version != 0) {
      printf("%s version %s\n", PACKAGE, VERSION);
      printf("\nThe following optional features have been enabled:\n");
#ifdef WITH_IPV6
      printf("- support for IPv6.\n");
#endif
      printf("- support for TLS");
      printf(" using GNU TLS");
      printf("\n");
#ifdef HAVE_MYSQL
      printf("- support for MySQL\n");
#endif
#ifdef HAVE_POSTGRESQL
      printf("- support for PostgreSQL\n");
#endif
#ifdef HAVE_SYSLOG
      printf("- logging to syslog\n");
#endif
      printf("\nDefault config file is: %s\n", CONFIG_DIR "/jabber.xml");
      printf("Locales are in: %s\n", LOCALEDIR);
      printf("\nFor more information please visit http://jabberd.org/\n");
      printf("If you need support, check out http://jabberd.org/gettingSupport\n");
      printf("\nNOTICE: With the next release of this software, this package\n");
      printf("        will get renamed to 'xmppd'. (http://xmppd.org/)\n");
      return 0;
    }

    /* generate a memory pool that is available for the whole livetime of jabberd */
    jabberd.runtime_pool = pool_new();

    /* register this handler to remove our pidfile at exit */
    atexit(_jabberd_atexit);

    /* putting h and s to the cmd_line hash */
    if (host != NULL) {
      xhash_put(jabberd.cmd_line, "h", host);
    }
    if (spool != NULL) {
      xhash_put(jabberd.cmd_line, "s", spool);
    }
    if (do_include != NULL) {
      xhash_put(jabberd.cmd_line, "i", do_include);
    }
    if (import_spool != NULL) {
      xhash_put(jabberd.cmd_line, "I", import_spool);
    }

    /* the special -Z flag provides a list of zones to filter debug output for, flagged w/ a simple hash */
    if (zones != NULL) {
      debug__zones = xhash_new(11);
      cmd = pstrdup(debug__zones->p, zones);
        while(cmd != NULL) {
            c = strchr(cmd, ',');
            if (c != NULL) {
                *c = '\0';
                c++;
            }
            xhash_put(debug__zones, cmd, cmd);
            cmd = c;
        }
    } else {
        debug__zones = NULL;
    }

    if (do_debug && do_background) {
      printf(PACKAGE " will not background with debugging enabled.\n");
      do_background=0;
    }

#ifdef HAVE_SYSLOG
    openlog(PACKAGE, LOG_PID, LOG_DAEMON);
#endif

    /* set to debug mode if we have it */
    set_cmdline_debug_flag(do_debug);

    /* Switch to the specified user */
    if (run_as_user != NULL) {
        struct passwd* user = NULL;

        user = getpwnam(run_as_user);
        if (user == NULL) {
            fprintf(stderr, "Unable to lookup user %s.\n", cmd);
            exit(1);
        }
        
        if (setgid(user->pw_gid) < 0) {
            fprintf(stderr, "Unable to set group permissions.\n");
            exit(1);
        }
        if (setuid(user->pw_uid) < 0) {
            fprintf(stderr, "Unable to set user permissions.\n");
            exit(1);
        }
    }

    /* change the current working directory so everything is "local" */
    if(home != NULL && chdir(home))
        fprintf(stderr, "Unable to access home folder %s: %s\n", home, strerror(errno));

    /* background ourselves if we have been flagged to do so */
    if (do_background != 0) {
        if (fork() != 0) {
            exit(0);
        }
    }

    /* load the config passing the file if it was manually set */
    if(configurate(jabberd.cfgfile, jabberd.cmd_line, 0))
        exit(1);

    /* EPIPE is easier to handle than a signal */
    signal(SIGPIPE, SIG_IGN);

    /* handle signals */
    signal(SIGHUP,_jabberd_signal);
    signal(SIGINT,_jabberd_signal);
    signal(SIGTERM,_jabberd_signal);

    /* init pth */
    pth_init();

#ifdef LIBIDN
    /* init the stringprep caches for jid manipulation */
    jid_init_cache();
#endif

    /* fire em up baby! */
    heartbeat_birth();

    /* register a function that regularily checks the signal flag */
    register_beat(1, jabberd_signal_handler, &jabberd);

    /* init MIO */
    mio_init();

    base_init(jabberd.runtime_pool);
    deliver_init(jabberd.runtime_pool);

    /* everything should be registered for the config pass, validate */
    deliver__flag = 0; /* pause deliver() while starting up */
    if (configo(0))
        exit(1);

    log_notice(NULL, "initializing server");

    /* karma granted, rock on */
    if(configo(1))
        exit(1);

    /* begin delivery of queued msgs */
    deliver__flag=1;
    deliver(NULL,NULL);

    /* was there a request to import an existing filespool? */
    if (import_spool != NULL) {
    }

    while (1) {
        pth_ctrl(PTH_CTRL_GETAVLOAD, &avload);
        log_debug2(ZONE, LOGT_STATUS, "main load check of %.2f with %ld total threads", avload, pth_ctrl(PTH_CTRL_GETTHREADS));
#ifdef POOL_DEBUG
      pool_stat(0);
      xmlnode_stat();
      deliver_pool_debug();
#endif
#ifdef LIBIDN
      jid_clean_cache();
#endif
        pth_sleep(60);
    };

    /* we never get here */
    return 0;
}


Generated by  Doxygen 1.6.0   Back to index