Back to index

im-sdk  12.3.91
IMSvrArg.cpp
Go to the documentation of this file.
00001 #include <config.h>
00002 #include <stdio.h>
00003 #include <sys/stat.h>
00004 #include "IMSvrArg.hh"
00005 #include "IMUtil.hh"
00006 #include "IMLog.hh"
00007 
00008 void
00009 IMSvrArg::show_usage()
00010 {
00011     fprintf(stderr,
00012            "iiimd [-d] [-lc_basiclocale localename] \n"
00013            "      [-ifpath_name ifpath] [-if ifname] \n"
00014            "      [-port portnumber] [-hostname hostname] \n"
00015            "      [-conversionkeys keys] \n"
00016            "      [-ns_map filename ] \n"
00017            "      [-preferredload] \n" );
00018 }
00019 
00020 void
00021 IMSvrArg::initialize()
00022 {
00023     addopt(IMDIR, "imdir");
00024     addopt(BASICLOCALE, "lc_basiclocale");
00025     addopt(IFPATHNAME, "ifpath_name");
00026     addopt(IFNAME, "if");
00027     addopt(PORT, "port");
00028     addopt(HOSTNAME, "hostname");
00029     addopt(NSMAP_CFG_FILE, "ns_map");
00030     addopt(CONFIGFILE, "cf");
00031     addopt(CONVERSIONKEYS, "conversionkeys");
00032     addopt(LABEL, "label");
00033     addopt(SETTRIGGEROFFKEYS, "setTriggerOffKeys");
00034     // addopt(IMCONFIG, "imconfig");
00035     // addopt(DIRECT_XSUNIM, "direct_xsunim");
00036     // addopt(SYSLOG, "syslog");
00037     addopt(MESSAGE_LOCALE, "message_locale");
00038     addopt(LOOKUPROW, "lookupRow");
00039     addopt(LOOKUPCOL, "lookupRow");
00040     addopt(NODAEMON, "nodaemon");
00041     addopt(DEBUGFLAG, "d");
00042     addopt(USER, "user");
00043     addopt(VARDIR, "vardir");
00044 #if defined(HAVE_UNIX_SOCKET)
00045     addopt(UDSFILE, "udsfile");
00046 #endif /* HAVE_UNIX_SOCKET */
00047     addopt(DESKTOP, "desktop");
00048     addopt(PREFERRED_LOADING, "preferredload");
00049 }
00050 
00051 static enum IMLog::LOG_LEVEL
00052 convert_log_level_string(
00053     const char* str
00054 )
00055 {
00056     if (!strcmp(str, "QUIET")) {
00057        return IMLog::QUIET;
00058     } else if (!strcmp(str, "ERROR")) {
00059        return IMLog::ERROR;
00060     } else if (!strcmp(str, "WARNING")) {
00061        return IMLog::WARNING;
00062     } else if (!strcmp(str, "NORMAL")) {
00063        return IMLog::NORMAL;
00064     } else if (!strcmp(str, "INFO")) {
00065        return IMLog::INFO;
00066     } else if (!strcmp(str, "VERBOSE")) {
00067        return IMLog::VERBOSE;
00068     } else if (!strcmp(str, "DEBUG")) {
00069        return IMLog::DEBUGLOG;
00070     }
00071     return IMLog::INVALID;
00072 }
00073 
00074 static enum IMLog::LOG_DESTINATION
00075 convert_log_facility_string(
00076     const char* str
00077 )
00078 {
00079     if (!strcmp(str, "AUTH")) {
00080        return IMLog::SYSLOG_AUTHPRIV;
00081     } else if (!strcmp(str, "USER")) {
00082        return IMLog::SYSLOG_USER;
00083     } else if (!strcmp(str, "LOCAL0")) {
00084        return IMLog::SYSLOG_LOCAL0;
00085     } else if (!strcmp(str, "LOCAL1")) {
00086        return IMLog::SYSLOG_LOCAL1;
00087     } else if (!strcmp(str, "LOCAL2")) {
00088        return IMLog::SYSLOG_LOCAL2;
00089     } else if (!strcmp(str, "LOCAL3")) {
00090        return IMLog::SYSLOG_LOCAL3;
00091     } else if (!strcmp(str, "LOCAL4")) {
00092        return IMLog::SYSLOG_LOCAL4;
00093     } else if (!strcmp(str, "LOCAL5")) {
00094        return IMLog::SYSLOG_LOCAL5;
00095     } else if (!strcmp(str, "LOCAL6")) {
00096        return IMLog::SYSLOG_LOCAL6;
00097     } else if (!strcmp(str, "LOCAL7")) {
00098        return IMLog::SYSLOG_LOCAL7;
00099     } else if (!strcmp(str, "STDOUT")) {
00100        return IMLog::IMLOG_STDOUT;
00101     } else if (!strcmp(str, "STDERR")) {
00102        return IMLog::IMLOG_STDERR;
00103     }
00104     return IMLog::IMLOG_DEFAULT;
00105 }
00106 
00107 bool
00108 IMSvrArg::set_argopt()
00109 {
00110     IMSvrArgMap::iterator it;
00111     enum IMSvrCfgOpt opt;
00112 
00113     for (it = optmap.begin(); it != optmap.end(); it++) {
00114        ArgVal &val = it->second;
00115        if (val.specified) {
00116            opt = val.opt;
00117            switch (get_type(opt)) {
00118              case IMSvrCfg::ARG_BOOL:
00119               setbool(opt, val.arg.b);
00120               break;
00121              case IMSvrCfg::ARG_NUMBER:
00122               setnum(opt, val.arg.n);
00123               break;
00124              case IMSvrCfg::ARG_STRING:
00125               setstr(opt, val.arg.s.c_str());
00126               break;
00127              default:
00128               ERROR_INTERNAL("Argument type is invalid.  That must not happen...");
00129            }
00130        }
00131     }
00132 
00133     return true;
00134 }
00135 
00136 bool
00137 IMSvrArg::configure(
00138     IMSvr *pimsvr
00139 )
00140 {
00141     if (!valid_flag) return false;
00142 
00143     if (!set_argopt()) return false;
00144 
00145     if (!pxmlsvrcfg) {
00146         if (get_boolval(USER)) {
00147            struct stat st;
00148             string home_dir, conffile;
00149 
00150             // iiimd run as per-user daemon.
00151             // use ~/.iiim/iiimd.conf as a default configuration file.
00152             if (!get_home_dir(home_dir)) return false;
00153 
00154            conffile = home_dir + string("/.iiim/iiimd.xml.conf");
00155            if (stat(conffile.c_str(), &st) == -1) {
00156               /* it was failed to stat. use the system-wide config */
00157               conffile = string(get_strval(IMSvrCfg::CONFIGFILE));
00158            }
00159            pxmlsvrcfg = new IMSvrXMLConf(this, conffile.c_str());
00160         } else {
00161            pxmlsvrcfg = new IMSvrXMLConf(this, get_strval(IMSvrCfg::CONFIGFILE));
00162         }
00163     }
00164     if (!pxmllecfg) {
00165        if (get_boolval(USER)) {
00166            /*
00167             * iiimd run as per-user daemon.
00168             * use ~/.iiim/le.xml.conf as a default configuration file.
00169             */
00170            string home_dir;
00171            if (!get_home_dir(home_dir))
00172               return false;
00173            pxmllecfg = iiim_le_xmlconf_new((home_dir + string("/.iiim/le.xml.conf")).c_str());
00174        } else {
00175            pxmllecfg = iiim_le_xmlconf_new(get_strval(IMSvrCfg::LECONFFILE));
00176        }
00177     }
00178 
00179     /* turn on debug mode. */
00180     if (get_boolval(DEBUGFLAG)) {
00181        // output full debug info to stderr.
00182        IMLog::get_instance()->set_log_level(IMLog::DEBUGLOG);
00183        IMLog::get_instance()->set_default_destination(IMLog::IMLOG_STDERR);
00184        LOG_DEBUG("Turn on debug mode.");
00185     } else if (!get_boolval(NODAEMON)) {
00186        // make the program daemon.
00187        IMDaemon::get_instance()->setup(get_strval(IMSvrCfg::IMDIR));
00188     }
00189     /* ... actual configuration ... */
00190     // file base configuration.
00191     if (pxmlsvrcfg) {
00192        if (!pxmlsvrcfg->configure(pimsvr))
00193            return false;
00194     }
00195     if (pxmllecfg) {
00196        /* don't bother the return value to allow to run without xml conf */
00197        iiim_le_xmlconf_load_file(pxmllecfg);
00198     }
00199     if (!set_argopt()) return false;
00200 
00201     get_usermgr(pimsvr)->set_command_name(get_command_name());
00202 
00203 #if 0
00204     /* LE path */
00205     config_lepath(pimsvr, get_strval(IMSvrCfg::IFPATHNAME));
00206 #else
00207     config_le(pimsvr,
00208              get_strval(IMSvrCfg::IFPATHNAME),
00209              *pxmllecfg,
00210              get_boolval(IMSvrCfg::PREFERRED_LOADING));
00211 #endif
00212 
00213     /* IMLog */
00214     if (!get_boolval(DEBUGFLAG)) {
00215        enum IMLog::LOG_LEVEL lv;
00216        lv = convert_log_level_string(get_strval(IMSvrCfg::LOG_LEVEL));
00217        if (lv == IMLog::INVALID) {
00218            LOG_ERROR("Invalid log level %s.", get_strval(IMSvrCfg::LOG_LEVEL));
00219            return false;
00220        }
00221 
00222        enum IMLog::LOG_DESTINATION dest;
00223        dest = convert_log_facility_string(get_strval(IMSvrCfg::LOG_FACILITY));
00224        if (lv == IMLog::INVALID) {
00225            LOG_ERROR("Invalid log facility %s.", get_strval(IMSvrCfg::LOG_FACILITY));
00226            return false;
00227        }
00228 
00229        IMLog::get_instance()->set_log_level(lv);
00230        IMLog::get_instance()->set_default_destination(dest);
00231        LOG_INFO("Set log facility to %s, log level to %s.",
00232                get_strval(IMSvrCfg::LOG_FACILITY),              
00233                get_strval(IMSvrCfg::LOG_LEVEL));
00234     }
00235 
00236 
00237     /* By default, allow the connection from localhost. */
00238     get_usermgr(pimsvr)->set_entry("localhost", IMAuth::PERMIT);
00239     get_usermgr(pimsvr)->set_entry("localhost.localdomain", IMAuth::PERMIT);
00240 
00241     if (!pnsmapcfg) {
00242       pnsmapcfg = new IMNSMapConf(get_strval(IMSvrCfg::NSMAP_CFG_FILE));
00243     }
00244 
00245     if (pnsmapcfg) {
00246        pnsmapcfg->load();
00247     }
00248 
00249     int count;
00250     IMNsMapStruct *nsmp = pnsmapcfg->get_nsmap_info(&count);
00251     set_nsmap_config(pimsvr, nsmp, count);
00252 
00253     LOG_NORMAL("started.");
00254 
00255     return true;
00256 }
00257 
00258 bool
00259 IMSvrArg::parse_arguments(
00260     int argc,
00261     char **argv
00262 )
00263 {
00264     int i;
00265     char *key;
00266     IMSvrArgMap::iterator it;
00267     enum IMSvrCfgOpt opt;
00268 
00269     for (i = 1; i < argc;) {
00270        key = argv[i];
00271        if (*key != '-') {
00272            show_usage();
00273            return false;
00274        }
00275        key++;
00276        it = optmap.find(key);
00277        if (optmap.end() == it) {
00278            show_usage();
00279            return false;
00280        }
00281        ArgVal &val = it->second;
00282        opt = val.opt;
00283        if (val.specified) {
00284            fprintf(stderr, "Duplicated option:%s\n", key);
00285            show_usage();
00286            return false;
00287        }
00288 
00289        if (get_type(opt) == IMSvrCfg::ARG_BOOL) {
00290            val.arg.b = true;
00291            val.specified = true;
00292        } else {
00293            i++;
00294            if (i >= argc) {
00295               show_usage();
00296               return false;
00297            }
00298            if (get_type(opt) == IMSvrCfg::ARG_NUMBER) {
00299               char *ptr;
00300               long num;
00301               num = strtol(argv[i], &ptr, 10);
00302               if (*ptr != '\0') {
00303                   show_usage();
00304                   return false;
00305               }
00306               val.arg.n = num;
00307               val.specified = true;
00308            } else if (get_type(opt) == IMSvrCfg::ARG_STRING) {
00309               val.arg.s = argv[i];
00310               val.specified = true;
00311            } else {
00312               ERROR_INTERNAL("Argument type is invalid.");
00313            }
00314        }
00315        i++;
00316     }
00317     return true;
00318 }
00319 
00320 void
00321 IMSvrArg::addopt(
00322     enum IMSvrCfg::IMSvrCfgOpt opt,
00323     const char* option
00324 )
00325 {
00326     optmap.insert(IMSvrArgMap::value_type(option, ArgVal(opt)));
00327 }
00328 
00329 IMSvrArg::IMSvrArg(
00330     int argc,
00331     char **argv
00332 ) :
00333     IMSvrCfg(argv[0])
00334 {
00335     pxmlsvrcfg = NULL;
00336     pxmllecfg = NULL;
00337     pnsmapcfg = NULL;
00338     initialize();
00339     valid_flag = parse_arguments(argc, argv);
00340 }
00341 
00342 IMSvrArg::~IMSvrArg()
00343 {
00344     if (pxmlsvrcfg)
00345        delete pxmlsvrcfg;
00346     if (pxmllecfg)
00347        iiim_le_xmlconf_free(pxmllecfg);
00348     if (pnsmapcfg)
00349        delete pnsmapcfg;
00350 }
00351 
00352 /* Local Variables: */
00353 /* c-file-style: "iiim-project" */
00354 /* End: */