Jabberd14-1.6.0/jabberd/jabberd.cc/main

Last-modified: 2007-03-18 (日) 18:07:01

このページを編集する際は,編集に関する方針に従ってください.

概要

引数

 * @param argc the number of arguments on the command line used to start jabberd
 * @param argv array of the arguments
 * @return 0 on successfull shutdown, 1 else

実装

int main (int argc, const char** argv) {
    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
    };
  • jabberdに渡された引数を保存しておく。この引数は後でcmdline_replaceで利用する。
    /* create hash for command line options */
    jabberd.cmd_line = xhash_new(11);
  • libpoptを見ないとなんともいえない。pReturnが2の場合は、引数をハッシュにいれている。
  • pReturnが2の場合って、-x(define)の時だけっぽい。1の場合は-Dだし。struct poptOptionの第五要素がpReturnの値っぽいね。
    /* 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
#ifdef SUPPORT_TLS
	 printf("- support for TLS");
#ifdef HAVE_GNUTLS
	 printf(" using GNU TLS");
#endif
#ifdef HAVE_SSL
	 printf(" using OpenSSL");
#endif
	 printf("\n");
#endif
#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);
  • struct poptOptionの第四要素に渡したポインタに入っている値を保存している
    /* 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);
    }
  • -Zはデバック関連らしい。zoneの考え方がわからない。調べなければ。FIXME
    /* 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);
  • ユーザの切替え。中身はユーザを検索してgidとuidを設定しなおしているだけだね。
    /* 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) {
  • pidが0以外の場合。親には子プロセスのpidが帰ってくるから、親が終わるってことだ。失敗したときの返り値は-1だし。
	 if (fork() != 0) {
	     exit(0);
	 }
    }
  • 設定ファイル名とコマンドラインオプションを渡してjabberdの設定を行う。
    /* 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
  • なんかJOJOの用な暑さ熱さを感じる。
    /* fire em up baby! */
    heartbeat_birth();
  • beatってシグナルのこと?コメントでは「シグナルフラグを定期的にチェックする関数を登録する。」ってことになっている。
    /* 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);
#endif
#ifdef LIBIDN
	 jid_clean_cache();
#endif
	 pth_sleep(60);
    };
    /* we never get here */
    return 0;
}

実装の説明を書いてください

呼出元

#related: relatedプラグインは廃止されました。