Back to index

im-sdk  12.3.91
IMSvrXMLConf.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
00002 #ifdef HAVE_CONFIG_H
00003 #include <config.h>
00004 #endif
00005 #include <libgen.h>
00006 #include <libxml/parser.h>
00007 #include <libxml/tree.h>
00008 #include "IMAuth.hh"
00009 #include "IMLog.hh"
00010 #ifdef HAVE_TLS
00011 #include "IMTLS.hh"
00012 #endif
00013 #include "IMSvrXMLConf.hh"
00014 
00015 #define       EMPTY_NODE_ERROR(n)         LOG_ERROR("<%s> is an empty node.", n)
00016 #define       DUPLICATED_NODE_ERROR(n, p) LOG_ERROR("<%s> had the duplicated node `<%s>'", p, n)
00017 #define       UNKNOWN_NODE_ERROR(n, p)    LOG_WARNING("<%s> had an unknown node `<%s>'", p, n)
00018 #define       INVALID_NODE_ERROR(n, v)    LOG_ERROR("<%s> is an invalid node. [%s]", n, v)
00019 #define       MISSING_NODE_ERROR(n, p)    LOG_ERROR("<%s> is missing in <%s>", n, p)
00020 
00021 
00022 IMAuth::access_type
00023 IMSvrXMLConf::get_access_type(xmlChar *key)
00024 {
00025     if (key == NULL) {
00026        return IMAuth::UNKNOWN;
00027     } else if (xmlStrcasecmp(key, (xmlChar *)"permit") == 0) {
00028        return IMAuth::PERMIT;
00029     } else if (xmlStrcasecmp(key, (xmlChar *)"checkuser") == 0) {
00030        return IMAuth::CHECKUSER;
00031     } else if (xmlStrcasecmp(key, (xmlChar *)"password") == 0) {
00032        return IMAuth::PASSWORD;
00033     } else if (xmlStrcasecmp(key, (xmlChar *)"deny") == 0) {
00034        return IMAuth::DENY;
00035     }
00036 
00037     return IMAuth::UNKNOWN;
00038 }
00039 
00040 string
00041 IMSvrXMLConf::parse_text_node(xmlNodePtr &node)
00042 {
00043     string retval;
00044 
00045     while (node != NULL) {
00046        if (xmlStrcmp(node->name, (xmlChar *)"text") == 0) {
00047            retval = (const char *)node->content;
00048            node = node->next;
00049        } else if (xmlStrcmp(node->name, (xmlChar *)"comment") == 0) {
00050            /* ignore comment node */
00051            node = node->next;
00052        } else {
00053            UNKNOWN_NODE_ERROR(node->name, "text");
00054            node = node->next;
00055        }
00056     }
00057 
00058     return retval;
00059 }
00060 
00061 string
00062 IMSvrXMLConf::parse_hostname_node(xmlNodePtr &node)
00063 {
00064     string retval;
00065 
00066     if (node->name == NULL || xmlStrlen(node->name) == 0) {
00067        EMPTY_NODE_ERROR("hostname");
00068        return retval;
00069     } else {
00070        retval = parse_text_node(node);
00071     }
00072 
00073     return retval;
00074 }
00075 
00076 string
00077 IMSvrXMLConf::parse_port_node(xmlNodePtr &node)
00078 {
00079     string retval;
00080 
00081     if (node->name == NULL || xmlStrlen(node->name) == 0) {
00082        EMPTY_NODE_ERROR("port");
00083        return retval;
00084     } else {
00085        retval = parse_text_node(node);
00086     }
00087 
00088 #if 0
00089     if (retval.size() > 0) {
00090        for (int i = 0; i < retval.size(); i++) {
00091            if (!(retval.c_str()[i] >= '0' && retval.c_str()[i] <= '9')) {
00092               INVALID_NODE_ERROR("port", retval.c_str());
00093               retval = "";
00094               break;
00095            }
00096        }
00097     }
00098 #endif
00099 
00100     return retval;
00101 }
00102 
00103 string
00104 IMSvrXMLConf::parse_file_node(xmlNodePtr &node)
00105 {
00106     string retval;
00107 
00108     if (node->name == NULL || xmlStrlen(node->name) == 0) {
00109        EMPTY_NODE_ERROR("file");
00110        return retval;
00111     } else {
00112        retval = parse_text_node(node);
00113     }
00114 
00115     return retval;
00116 }
00117 
00118 void
00119 IMSvrXMLConf::parse_listen_tcp_node(xmlNodePtr &node, bool ssl)
00120 {
00121     string hostname;
00122     string port;
00123 
00124 #if defined(HAVE_UNIX_SOCKET)
00125     if (string(get_strval(IMSvrCfg::UDSFILE)).size() != 0) return;
00126 #endif /* HAVE_UNIX_SOCKET */
00127 
00128     while (node != NULL) {
00129        if (xmlStrcmp(node->name, (xmlChar *)"hostname") == 0) {
00130            if (hostname.size() > 0) {
00131               DUPLICATED_NODE_ERROR("hostname", "listen");
00132            } else {
00133               hostname = parse_hostname_node(node->xmlChildrenNode);
00134            }
00135            node = node->next;
00136        } else if (xmlStrcmp(node->name, (xmlChar *)"port") == 0) {
00137            if (port.size() > 0) {
00138               DUPLICATED_NODE_ERROR("port", "listen");
00139            } else {
00140               port = parse_port_node(node->xmlChildrenNode);
00141            }
00142            node = node->next;
00143        } else if (xmlStrcmp(node->name, (xmlChar *)"text") == 0
00144                  || xmlStrcmp(node->name, (xmlChar *)"comment") == 0) {
00145            /* ignore text and comment node */
00146            node = node->next;
00147        } else {
00148            /* ignore the unknown nodes */
00149            UNKNOWN_NODE_ERROR(node->name, "listen");
00150            node = node->next;
00151        }
00152     }
00153 
00154     /* validate the given directives */
00155     if (hostname.size() == 0)
00156        MISSING_NODE_ERROR("hostname", "listen");
00157     if (port.size() == 0)
00158        MISSING_NODE_ERROR("port", "listen");
00159     if (hostname.size() > 0 && port.size() > 0) {
00160        if (!get_boolval(USER)) {
00161            if (ssl) {
00162 #ifdef HAVE_TLS
00163               listenaddrvec.push_back(IMSocketAddress(IMSocketAddress::INET, IMSocketAddress::TLS,
00164                                                  hostname, port));
00165               LOG_DEBUG("<ssl><listen type=\"tcp\"><hostname>%s</hostname><port>%s</port></listen></ssl>",
00166                        hostname.c_str(), port.c_str());
00167 #else
00168               LOG_WARNING("it was compiled without SSL support.");
00169 #endif /* HAVE_TLS */
00170            } else {
00171               listenaddrvec.push_back(IMSocketAddress(IMSocketAddress::INET, hostname, port));
00172               LOG_DEBUG("<listen type=\"tcp\"><hostname>%s</hostname><port>%s</port></listen>",
00173                        hostname.c_str(), port.c_str());
00174            }
00175        }
00176     }
00177 }
00178 
00179 void
00180 IMSvrXMLConf::parse_listen_unix_node(xmlNodePtr &node, bool ssl)
00181 {
00182 #ifdef HAVE_UNIX_SOCKET
00183     string file;
00184     string prefix = SOCKETDIR "/.iiimp-unix";
00185     char *p;
00186 
00187     if (string(get_strval(IMSvrCfg::UDSFILE)).size() != 0) return;
00188 
00189     while (node != NULL) {
00190        if (xmlStrcmp(node->name, (xmlChar *)"file") == 0) {
00191            if (file.size() > 0) {
00192               DUPLICATED_NODE_ERROR("file", "listen");
00193            } else {
00194               file = parse_file_node(node->xmlChildrenNode);
00195            }
00196            node = node->next;
00197        } else if (xmlStrcmp(node->name, (xmlChar *)"text") == 0
00198                  || xmlStrcmp(node->name, (xmlChar *)"comment") == 0) {
00199            /* ignore text and comment node */
00200            node = node->next;
00201        } else {
00202            /* ignore the unknown nodes */
00203            UNKNOWN_NODE_ERROR(node->name, "listen");
00204            node = node->next;
00205        }
00206     }
00207 
00208     /* drop path in order to not allow ../path/to say */
00209     p = new char[file.size() + 1];
00210     strncpy(p, file.c_str(), file.size());
00211     p[file.size()] = 0;
00212     file = basename(p);
00213     delete[] p;
00214 
00215     /* validate the given directives */
00216     if (file.size() == 0) {
00217        MISSING_NODE_ERROR("file", "listen");
00218     } else {
00219        if (get_boolval(IMSvrCfg::USER)) {
00220            string user_name;
00221 
00222            if (get_process_user(user_name)) {
00223               if (ssl) {
00224 #ifdef HAVE_TLS
00225                   listenaddrvec.push_back(IMSocketAddress(IMSocketAddress::UNIX_DOMAIN_PER_USER,
00226                                                      IMSocketAddress::TLS,
00227                                                      prefix + string("-") + user_name,
00228                                                      file));
00229 #else
00230                   LOG_WARNING("it was compiled without SSL support.");
00231 #endif /* HAVE_TLS */
00232               } else {
00233                   listenaddrvec.push_back(IMSocketAddress(IMSocketAddress::UNIX_DOMAIN_PER_USER,
00234                                                      prefix + string("-") + user_name,
00235                                                      file));
00236               }
00237            }
00238        } else {
00239            if (ssl) {
00240 #ifdef HAVE_TLS
00241               listenaddrvec.push_back(IMSocketAddress(IMSocketAddress::UNIX_DOMAIN,
00242                                                  IMSocketAddress::TLS,
00243                                                  prefix, file));
00244 #else
00245               LOG_WARNING("it was compiled without SSL support.");
00246 #endif /* HAVE_TLS */
00247            } else {
00248               listenaddrvec.push_back(IMSocketAddress(IMSocketAddress::UNIX_DOMAIN,
00249                                                  prefix, file));
00250            }
00251        }
00252        if (ssl) {
00253 #ifdef HAVE_TLS
00254            LOG_DEBUG("<ssl><listen type=\"unix\"><file>%s</file></listen></ssl>", file.c_str());
00255 #else
00256            /* not supported */
00257 #endif /* HAVE_TLS */
00258        } else {
00259            LOG_DEBUG("<listen type=\"unix\"><file>%s</file></listen>", file.c_str());
00260        }
00261     }
00262 #else
00263     LOG_WARNING("it was compiled without Unix domain socket support.")
00264 #endif /* HAVE_UNIX_SOCKET */
00265 }
00266 
00267 void
00268 IMSvrXMLConf::parse_acl_node(xmlNodePtr &node)
00269 {
00270     xmlChar *type = NULL;
00271     IMAuth::access_type at;
00272     string hostname;
00273 
00274     type = xmlGetProp(node, (xmlChar *)"type");
00275     at = get_access_type(type);
00276     node = node->xmlChildrenNode;
00277 
00278     while (node != NULL) {
00279        if (xmlStrcmp(node->name, (xmlChar *)"hostname") == 0) {
00280            if (hostname.size() > 0) {
00281               DUPLICATED_NODE_ERROR("hostname", "acl");
00282            } else {
00283               hostname = parse_hostname_node(node->xmlChildrenNode);
00284            }
00285            node = node->next;
00286        } else if (xmlStrcmp(node->name, (xmlChar *)"text") == 0
00287                  || xmlStrcmp(node->name, (xmlChar *)"comment") == 0) {
00288            /* ignore text and comment node */
00289            node = node->next;
00290        } else {
00291            /* ignore the unknown nodes */
00292            UNKNOWN_NODE_ERROR(node->name, "acl");
00293            node = node->next;
00294        }
00295     }
00296 
00297     /* validate the given directives */
00298     if (hostname.size() == 0) {
00299        MISSING_NODE_ERROR("hostname", "acl");
00300     } else if (at != IMAuth::UNKNOWN) {
00301        get_usermgr(ptarget)->set_entry(hostname.c_str(), at);
00302        LOG_DEBUG("<acl type=\"%s\"><hostname>%s</hostname></acl>", type, hostname.c_str());
00303     } else {
00304        LOG_ERROR("<acl> needs `type' attribute.");
00305     }
00306 
00307     if (type != NULL)
00308        xmlFree(type);
00309 }
00310 
00311 void
00312 IMSvrXMLConf::parse_acls_node(xmlNodePtr &node)
00313 {
00314     xmlNodePtr topnode = NULL;
00315     xmlChar *type = NULL;
00316     IMAuth::access_type at;
00317 
00318     type = xmlGetProp(node, (xmlChar *)"default");
00319     at = get_access_type(type);
00320     if (at != IMAuth::UNKNOWN) {
00321        get_usermgr(ptarget)->set_default_entry(at);
00322        LOG_DEBUG("<acls default=\"%s\">", type);
00323     } else {
00324        LOG_WARNING("no default permission.");
00325     }
00326     if (type != NULL)
00327        xmlFree(type);
00328 
00329     node = node->xmlChildrenNode;
00330 
00331     while (node != NULL) {
00332        if (xmlStrcmp(node->name, (xmlChar *)"acl") == 0) {
00333            topnode = node;
00334            parse_acl_node(node);
00335            node = topnode->next;
00336            topnode = NULL;
00337        } else if (xmlStrcmp(node->name, (xmlChar *)"text") == 0
00338                  || xmlStrcmp(node->name, (xmlChar *)"comment") == 0) {
00339            /* ignore text and comment node */
00340            node = node->next;
00341        } else {
00342            /* ignore the unknown nodes */
00343            UNKNOWN_NODE_ERROR(node->name, "acls");
00344            node = node->next;
00345        }
00346     }
00347 }
00348 
00349 void
00350 IMSvrXMLConf::parse_system_node(xmlNodePtr &node)
00351 {
00352     xmlChar *type = NULL;
00353     IMAuth::access_type at;
00354 
00355     type = xmlGetProp(node, (xmlChar *)"type");
00356     at = get_access_type(type);
00357     if (at != IMAuth::UNKNOWN) {
00358        get_usermgr(ptarget)->set_systemuser_permission(at);
00359        LOG_DEBUG("<system type=\"%s\"/>", type);
00360     } else {
00361        LOG_ERROR("no permission or unknown permission `%s' on <system>.", type);
00362     }
00363     if (type != NULL)
00364        xmlFree(type);
00365 }
00366 
00367 void
00368 IMSvrXMLConf::parse_user_node(xmlNodePtr &node)
00369 {
00370     xmlChar *type = NULL, *name = NULL;
00371     IMAuth::access_type at;
00372     string password;
00373 
00374     type = xmlGetProp(node, (xmlChar *)"type");
00375     name = xmlGetProp(node, (xmlChar *)"name");
00376 
00377     at = get_access_type(type);
00378     if (at != IMAuth::UNKNOWN) {
00379        if (at == IMAuth::PASSWORD
00380            && node->xmlChildrenNode != NULL
00381            && node->xmlChildrenNode->name != NULL) {
00382            password += parse_text_node(node->xmlChildrenNode);
00383            get_usermgr(ptarget)->add_user((const char *)name, password.c_str(), at);
00384        } else {
00385            get_usermgr(ptarget)->add_user((const char *)name, NULL, at);
00386        }
00387        LOG_DEBUG("<user type=\"%s\" name=\"%s\">%s</user>", type, name, password.c_str());
00388     } else {
00389        LOG_ERROR("no permission or unknown permission `%s' on <user>.", type);
00390     }
00391 
00392     if (type != NULL)
00393        xmlFree(type);
00394     if (name != NULL)
00395        xmlFree(name);
00396 }
00397 
00398 void
00399 IMSvrXMLConf::parse_auth_node(xmlNodePtr &node)
00400 {
00401     xmlNodePtr topnode = NULL;
00402 
00403     while (node != NULL) {
00404        if (xmlStrcmp(node->name, (xmlChar *)"system") == 0) {
00405            topnode = node;
00406            parse_system_node(node);
00407            node = topnode->next;
00408            topnode = NULL;
00409        } else if (xmlStrcmp(node->name, (xmlChar *)"user") == 0) {
00410            topnode = node;
00411            parse_user_node(node);
00412            node = topnode->next;
00413            topnode = NULL;
00414        } else if (xmlStrcmp(node->name, (xmlChar *)"text") == 0
00415                  || xmlStrcmp(node->name, (xmlChar *)"comment") == 0) {
00416            /* ignore text and comment node */
00417            node = node->next;
00418        } else {
00419            /* ignore the unknown nodes */
00420            UNKNOWN_NODE_ERROR(node->name, "auth");
00421            node = node->next;
00422        }
00423     }
00424 }
00425 
00426 void
00427 IMSvrXMLConf::parse_ssl_node(xmlNodePtr &node)
00428 {
00429 #ifdef HAVE_TLS
00430     xmlNodePtr topnode = NULL;
00431     xmlChar *verify, *depth;
00432     string v;
00433 
00434     verify = xmlGetProp(node, (xmlChar *)"verify");
00435     depth = xmlGetProp(node, (xmlChar *)"depth");
00436     if (verify != NULL) {
00437        v = (const char *)verify;
00438        IMTLS::get_instance()->set_verify_client(v);
00439     }
00440     if (depth != NULL) {
00441        v = (const char *)depth;
00442        IMTLS::get_instance()->set_verify_depth(v);
00443     }
00444     LOG_DEBUG("<ssl verify=\"%s\" depth=\"%s\">", verify, depth);
00445 
00446     node = node->xmlChildrenNode;
00447 
00448     while (node != NULL) {
00449        if (xmlStrcmp(node->name, (xmlChar *)"listen") == 0) {
00450            xmlChar *type = NULL;
00451 
00452            type = xmlGetProp(node, (xmlChar *)"type");
00453            if (xmlStrcmp(type, (xmlChar *)"tcp") == 0) {
00454               topnode = node;
00455               node = node->xmlChildrenNode;
00456               parse_listen_tcp_node(node, true);
00457               node = topnode->next;
00458               topnode = NULL;
00459            } else if (xmlStrcmp(type, (xmlChar *)"unix") == 0) {
00460               topnode = node;
00461               node = node->xmlChildrenNode;
00462               parse_listen_unix_node(node, true);
00463               node = topnode->next;
00464               topnode = NULL;
00465            } else {
00466               /* ignore the unknown nodes */
00467               LOG_WARNING("unknown listen type `%s'. ignoring...", type);
00468               node = node->next;
00469            }
00470            if (type != NULL)
00471               xmlFree(type);
00472        } else if (xmlStrcmp(node->name, (xmlChar *)"CACertificate") == 0) {
00473            xmlChar *path, *file;
00474            string v;
00475 
00476            path = xmlGetProp(node, (xmlChar *)"path");
00477            file = xmlGetProp(node, (xmlChar *)"file");
00478 
00479            if (path != NULL) {
00480               v = (const char *)path;
00481               IMTLS::get_instance()->set_cacertificate_path(v);
00482            }
00483            if (file != NULL) {
00484               v = (const char *)file;
00485               IMTLS::get_instance()->set_cacertificate_file(v);
00486            }
00487            LOG_DEBUG("<CACertificate path=\"%s\" file=\"%s\"/>", path, file);
00488            if (path != NULL)
00489               xmlFree(path);
00490            if (file != NULL)
00491               xmlFree(file);
00492            node = node->next;
00493        } else if (xmlStrcmp(node->name, (xmlChar *)"Certificate") == 0) {
00494            xmlChar *file, *key;
00495            string v;
00496 
00497            file = xmlGetProp(node, (xmlChar *)"file");
00498            key = xmlGetProp(node, (xmlChar *)"key");
00499 
00500            if (file != NULL) {
00501               v = (const char *)file;
00502               IMTLS::get_instance()->set_certificate_file(v);
00503            }
00504            if (key != NULL) {
00505               v = (const char *)key;
00506               IMTLS::get_instance()->set_certificate_key_file(v);
00507            }
00508            LOG_DEBUG("<Certificate key=\"%s\" file=\"%s\"/>", key, file);
00509            if (file != NULL)
00510               xmlFree(file);
00511            if (key != NULL)
00512               xmlFree(key);
00513            node = node->next;
00514        } else if (xmlStrcmp(node->name, (xmlChar *)"text") == 0
00515                  || xmlStrcmp(node->name, (xmlChar *)"comment") == 0) {
00516            /* ignore text and comment node */
00517            node = node->next;
00518        } else {
00519            /* ignore the unknown nodes */
00520            UNKNOWN_NODE_ERROR(node->name, "ssl");
00521            node = node->next;
00522        }
00523     }
00524     LOG_DEBUG("</ssl>");
00525 
00526     if (verify != NULL)
00527        xmlFree(verify);
00528     if (depth != NULL)
00529        xmlFree(depth);
00530 #else
00531     LOG_WARNING("it was compiled without SSL support.");
00532 #endif
00533 }
00534 
00535 void
00536 IMSvrXMLConf::parse_server_node(xmlNodePtr &node)
00537 {
00538     xmlNodePtr topnode = NULL;
00539 
00540     while (node != NULL) {
00541        if (xmlStrcmp(node->name, (xmlChar *)"listen") == 0) {
00542            xmlChar *type = NULL;
00543 
00544            type = xmlGetProp(node, (xmlChar *)"type");
00545            if (xmlStrcmp(type, (xmlChar *)"tcp") == 0) {
00546               topnode = node;
00547               node = node->xmlChildrenNode;
00548               parse_listen_tcp_node(node, false);
00549               node = topnode->next;
00550               topnode = NULL;
00551            } else if (xmlStrcmp(type, (xmlChar *)"unix") == 0) {
00552               topnode = node;
00553               node = node->xmlChildrenNode;
00554               parse_listen_unix_node(node, false);
00555               node = topnode->next;
00556               topnode = NULL;
00557            } else {
00558               /* ignore the unknown nodes */
00559               LOG_WARNING("unknown listen type `%s'. ignoring...", type);
00560               node = node->next;
00561            }
00562            if (type != NULL)
00563               xmlFree(type);
00564        } else if (xmlStrcmp(node->name, (xmlChar *)"acls") == 0) {
00565            topnode = node;
00566            parse_acls_node(node);
00567            node = topnode->next;
00568            topnode = NULL;
00569        } else if (xmlStrcmp(node->name, (xmlChar *)"auth") == 0) {
00570            topnode = node;
00571            node = node->xmlChildrenNode;
00572            parse_auth_node(node);
00573            node = topnode->next;
00574            topnode = NULL;
00575        } else if (xmlStrcmp(node->name, (xmlChar *)"ssl") == 0) {
00576            topnode = node;
00577            parse_ssl_node(node);
00578            node = topnode->next;
00579            topnode = NULL;
00580        } else if (xmlStrcmp(node->name, (xmlChar *)"text") == 0
00581                  || xmlStrcmp(node->name, (xmlChar *)"comment") == 0) {
00582            /* ignore text and comment node */
00583            node = node->next;
00584        } else {
00585            /* ignore the unknown nodes */
00586            UNKNOWN_NODE_ERROR(node->name, "server");
00587            node = node->next;
00588        }
00589     }
00590 }
00591 
00592 bool
00593 IMSvrXMLConf::load(void)
00594 {
00595 #ifdef HAVE_XMLCTXTREAD
00596     xmlParserCtxtPtr parser = NULL;
00597 #endif
00598     xmlDocPtr doc = NULL;
00599     xmlNodePtr root = NULL, node, topnode = NULL;
00600     bool retval = false;
00601 
00602     if (filename.size() == 0)
00603        return false;
00604 
00605 #ifdef HAVE_XMLCTXTREAD
00606     parser = xmlNewParserCtxt();
00607     if ((doc = xmlCtxtReadFile(parser, filename.c_str(), "UTF-8", 0)) == NULL) {
00608 #else
00609     if ((doc = xmlParseFile(filename.c_str())) == NULL) {
00610 #endif
00611        goto ensure;
00612 #ifdef HAVE_XMLCTXTREAD
00613     }
00614 #else
00615     }
00616 #endif
00617     if ((root = xmlDocGetRootElement(doc)) == NULL)
00618        goto ensure;
00619     if (xmlStrcmp(root->name, (xmlChar *)"iiimf") != 0) {
00620        LOG_ERROR("invalid configuration file `%s'", filename.c_str());
00621        goto ensure;
00622     }
00623 
00624     node = root->xmlChildrenNode;
00625     while (node != NULL) {
00626        if (xmlStrcmp(node->name, (xmlChar *)"server") == 0) {
00627            topnode = node;
00628            node = node->xmlChildrenNode;
00629            parse_server_node(node);
00630            node = topnode->next;
00631            topnode = NULL;
00632        } else if (xmlStrcmp(node->name, (xmlChar *)"text") == 0
00633                  || xmlStrcmp(node->name, (xmlChar *)"comment") == 0) {
00634            /* ignore text and comment node */
00635            node = node->next;
00636        } else {
00637            /* ignore the unknown nodes */
00638            UNKNOWN_NODE_ERROR(node->name, "iiimf");
00639            node = node->next;
00640        }
00641     }
00642     retval = true;
00643 
00644   ensure:
00645     if (doc != NULL)
00646        xmlFreeDoc(doc);
00647 #ifdef HAVE_XMLCTXTREAD
00648     if (parser != NULL)
00649        xmlFreeParserCtxt(parser);
00650 #endif
00651 
00652     return retval;
00653 }
00654 
00655 bool
00656 IMSvrXMLConf::configure(IMSvr *pimsvr)
00657 {
00658     string prefix = SOCKETDIR "/.iiimp-unix";
00659 
00660     ptarget = pimsvr;
00661     if (!load())
00662        return false;
00663 
00664 #ifdef HAVE_TLS
00665     IMTLS::get_instance()->setup();
00666 #endif
00667     /* config listen address if it has not been configured yet. */
00668     if (listenaddrvec.empty()) {
00669         if (get_boolval(USER)) {
00670             // when iiimd run as a per-user daemon.
00671             // listens to /tmp/.iiimp-unix-${USER}/${PORT}
00672             string user_name;
00673             if (get_process_user(user_name)) {
00674               string sf;
00675               IM_unix_domain_socket_file_dir(user_name, sf);
00676               if (0 < sf.size()) {
00677                   listenaddrvec.push_back(IMSocketAddress(IMSocketAddress::UNIX_DOMAIN_PER_USER,
00678                                                      sf,
00679                                                      get_strval(IMSvrCfg::PORT)));
00680               }
00681 #if 0
00682                 listenaddrvec.push_back(IMSocketAddress(IMSocketAddress::UNIX_DOMAIN_PER_USER,
00683                                                  string("/tmp/.iiimp-unix-") + user_name,
00684                                                  get_strval(IMSvrCfg::PORT)));
00685 #endif
00686            }
00687        } else if (string(get_strval(IMSvrCfg::UDSFILE)).size() != 0) {
00688            listenaddrvec.push_back(IMSocketAddress(IMSocketAddress::UNIX_DOMAIN,
00689                                               get_strval(IMSvrCfg::UDSFILE), ""));
00690         } else {
00691             // by default, iiimd listens to
00692             // localhost:9010, /var/run/iiim/.iiimp-unix/${PORT}
00693            /* disable tcp listening by default */
00694 #if 0
00695            listenaddrvec.push_back(IMSocketAddress(IMSocketAddress::INET,
00696                                               get_strval(IMSvrCfg::HOSTNAME),
00697                                          get_strval(IMSvrCfg::PORT)));
00698 #endif
00699             listenaddrvec.push_back(IMSocketAddress(IMSocketAddress::UNIX_DOMAIN,
00700                                          prefix,
00701                                               get_strval(IMSvrCfg::PORT)));
00702         }
00703     }
00704     config_listenaddress(pimsvr, listenaddrvec);
00705 
00706     return true;
00707 }
00708 
00709 IMSvrXMLConf::IMSvrXMLConf(IMSvrCfg *pbase,
00710                         const char *conffile) : IMSvrCfg(*pbase), filename(conffile)
00711 {
00712 }
00713 
00714 IMSvrXMLConf::~IMSvrXMLConf()
00715 {
00716 }