Ejemplo n.º 1
0
void plainconf::loadDirectory(const char *pPath, const char *pPattern)
{
    DIR *pDir = opendir(pPath);

    if (!pDir)
    {
        logToMem(LOG_LEVEL_ERR, "Failed to open directory [%s].", pPath);
        return ;
    }

    struct dirent *dir_ent;

    char str[4096] = {0};
    strcpy(str, pPath);
    strcatchr(str, '/', 4096);
    int offset = strlen(str);
    StringList AllEntries;

    while ((dir_ent = readdir(pDir)))
    {
        const char *pName = dir_ent->d_name;

        if ((strcmp(pName, ".") == 0) ||
            (strcmp(pName, "..") == 0) ||
            (*(pName + strlen(pName) - 1) == '~'))
            continue;

        if (pPattern)
        {
            //Beside the unmatch, also must exclude *,v which was created by rcs
            if(fnmatch(pPattern, pName, FNM_PATHNAME) != 0
                || fnmatch("*,v", pName, FNM_PATHNAME) == 0)
                continue;
        }

        strcpy(str + offset, pName);
        struct stat st;
        if (stat(str, &st) == 0)
        {
            if (S_ISDIR(st.st_mode)
                || pPattern
                || fnmatch("*.conf", pName, FNM_PATHNAME) == 0)
                AllEntries.add(str);
        }
    }
    closedir(pDir);
    AllEntries.sort();

    StringList::iterator iter;
    for (iter = AllEntries.begin(); iter != AllEntries.end(); ++iter)
    {
        const char *pName = (*iter)->c_str();
        logToMem(LOG_LEVEL_INFO, "Processing config file: %s", pName);
        loadConfFile(pName);
    }
}
Ejemplo n.º 2
0
void plainconf::loadDirectory(const char *pPath, const char *pPattern)
{
    DIR *pDir = opendir(pPath);

    if (!pDir)
    {
        logToMem(LOG_LEVEL_ERR, "Failed to open directory [%s].", pPath);
        return ;
    }

    struct dirent *dir_ent;

    StringList AllEntries;

    while ((dir_ent = readdir(pDir)))
    {
        const char *pName = dir_ent->d_name;

        if ((strcmp(pName, ".") == 0) ||
            (strcmp(pName, "..") == 0) ||
            (*(pName + strlen(pName) - 1) == '~'))
            continue;

        if (pPattern)
        {
            if (fnmatch(pPattern, pName, FNM_PATHNAME))
                continue;
        }

        char str[4096] = {0};
        strcpy(str, pPath);
        strcatchr(str, '/', 4096);
        strcat(str, pName);
        AllEntries.add(str);
    }

    closedir(pDir);

    //Sort the filename order
    AllEntries.sort();
    StringList::iterator iter;

    for (iter = AllEntries.begin(); iter != AllEntries.end(); ++iter)
    {
        const char *p = (*iter)->c_str();
        logToMem(LOG_LEVEL_INFO, "Processing config file: %s", p);
        loadConfFile(p);
    }
}
Ejemplo n.º 3
0
void plainconf::addModuleWithParam(XmlNode *pCurNode,
                                   const char *moduleName, const char *param)
{
    XmlNode *pModuleNode = NULL;
    XmlNodeList::const_iterator iter;
    const XmlNodeList *pModuleList = pCurNode->getChildren("module");

    if (pModuleList)
    {
        for (iter = pModuleList->begin(); iter != pModuleList->end(); ++iter)
        {
            if (strcasecmp((*iter)->getChildValue("name", 1), moduleName) == 0)
            {
                pModuleNode = (*iter);
                break;
            }
        }
    }

    if (!pModuleNode)
    {
        pModuleNode = new XmlNode;
        //XmlNode *pParamNode = new XmlNode;
        const char *attr = NULL;
        pModuleNode->init("module", &attr);
        pModuleNode->setValue(moduleName, strlen(moduleName));
        pCurNode->addChild(pModuleNode->getName(), pModuleNode);
        logToMem(LOG_LEVEL_INFO, "[%s:%s]addModuleWithParam ADD module %s",
                 pCurNode->getName(), pCurNode->getValue(), moduleName);
    }

    appendModuleParam(pModuleNode, param);
}
Ejemplo n.º 4
0
void plainconf::appendModuleParam(XmlNode *pModuleNode, const char *param)
{
    XmlNode *pParamNode = pModuleNode->getChild("param");

    if (pParamNode == NULL)
    {
        pParamNode = new XmlNode;
        const char *attr = NULL;
        pParamNode->init("param", &attr);
        pParamNode->setValue(param, strlen(param));
        pModuleNode->addChild(pParamNode->getName(), pParamNode);
    }
    else
    {
        AutoStr2 totalValue = pParamNode->getValue();
        totalValue.append("\n", 1);
        totalValue.append(param, strlen(param));
        pParamNode->setValue(totalValue.c_str(), totalValue.len());
    }

    logToMem(LOG_LEVEL_INFO, "[%s:%s] module [%s] add param [%s]",
             pModuleNode->getParent()->getName(),
             ((pModuleNode->getParent()->getValue()) ?
              pModuleNode->getParent()->getValue() : ""),
             pModuleNode->getValue(), param);
}
Ejemplo n.º 5
0
//return the root node of the tree
XmlNode *plainconf::parseFile(const char *configFilePath,
                              const char *rootTag)
{
#ifdef TEST_OUTPUT_PLAIN_CONF
    char *tmp = (char *)new char[5 * 1024 * 1024];

    if (tmp)
        delete []tmp;

#endif
    XmlNode *rootNode = new XmlNode;
    const char *attr = NULL;
    rootNode->init(rootTag, &attr);
    gModuleList.push_back(rootNode);

    loadConfFile(configFilePath);

    if (gModuleList.size() != 1)
        logToMem(LOG_LEVEL_ERR,
                 "parseFile find '{' and '}' do not match in the end of file %s, rootTag %s.",
                 configFilePath, rootTag);

    gModuleList.clear();

    handleSpecialCaseLoop(rootNode);


#ifdef TEST_OUTPUT_PLAIN_CONF
    char sPlainFile[512] = {0};
    strcpy(sPlainFile, configFilePath);
    strcat(sPlainFile, ".txt");
    plainconf::testOutputConfigFile(rootNode, sPlainFile);
#endif
    return rootNode;
}
Ejemplo n.º 6
0
void plainconf::getIncludeFile(const char *orgFile, char *targetFile)
{
    int len = strlen(orgFile);

    if (len == 0)
        return;

    //Absolute path
    if (orgFile[0] == '/')
        strcpy(targetFile, orgFile);

    else if (orgFile[0] == '$')
    {
        if (strncasecmp(orgFile, "$server_root/", 13) == 0)
        {
            strcpy(targetFile, rootPath.c_str());
            strcat(targetFile, orgFile + 13);
        }
        else
        {
            logToMem(LOG_LEVEL_ERR, "Can't resolve include file %s", orgFile);
            return ;
        }
    }

    else
    {
        strcpy(targetFile, rootPath.c_str());
        strcat(targetFile, orgFile);
    }
}
Ejemplo n.º 7
0
//When checking we use lock for may need to update the conf file later
//If user RCS checkout a revision, a unlock should be used for next time checkin.
//Example: co -u1.1 httpd_config.conf
void plainconf::checkInFile(const char *path)
{
    if (access(path, 0) == -1)
        return ;

    //Backup file abd checkin and out
    char new_path[4096];
    strcpy(new_path, path);
    strcat(new_path, "0");

    AutoStr2 buf;
    buf.setStr("cp \"");
    buf.append(path, strlen(path));
    buf.append("\" \"", 3);
    buf.append(new_path, strlen(new_path));
    buf.append("\"", 1);
    int ret = system(buf.c_str());

    if (ret != 0)
    {
        logToMem(LOG_LEVEL_INFO, "Failed to backup the conf file %s, ret %d.",
                 path, ret);
        return ;
    }

    buf.setStr("ci -l -q -t-\"");
    buf.append(new_path, strlen(new_path));
    buf.append("\" -mUpdate \"", 12);
    buf.append(new_path, strlen(new_path));
    buf.append("\" >/dev/null 2>&1", 17);
    ret = system(buf.c_str());

    if (ret == 0)
        logToMem(LOG_LEVEL_INFO, "RCS checkin config file %s OK.", new_path);
    else
        logToMem(LOG_LEVEL_INFO,
                 "Failed to RCS checkin conf file %s, ret %d, error(%s). "
                 "Org command is %s.", new_path, ret, strerror(errno), buf.c_str());

    unlink(new_path);
}
Ejemplo n.º 8
0
void plainconf::saveUnknownItems(const char *fileName, int lineNumber,
                                 XmlNode *pCurNode, const char *name, const char *value)
{
    //if not inside a "module" and without a "::", treated as error
    if (strcasecmp(pCurNode->getName(), "module") != 0 &&
        strstr(name, "::") == NULL)
    {
        logToMem(LOG_LEVEL_ERR, "Not support [%s %s] in file %s:%d", name, value,
                 fileName, lineNumber);
        return ;
    }

    char newvalue[4096] = {0};
    XmlNode *pParamNode = new XmlNode;
    const char *attr = NULL;
    pParamNode->init(UNKNOWN_KEYWORDS, &attr);
    strcpy(newvalue, name);
    strcat(newvalue, " ");
    strcat(newvalue, value);
    pParamNode->setValue(newvalue, strlen(newvalue));
    pCurNode->addChild(pParamNode->getName(), pParamNode);
}
Ejemplo n.º 9
0
void plainconf::parseLine(const char *fileName, int lineNumber,
                          const char *sLine)
{
    const int MAX_NAME_LENGTH = 4096;
    char name[MAX_NAME_LENGTH] = {0};
    char value[MAX_NAME_LENGTH] = {0};
    const char *attr = NULL;

    XmlNode *pNode = NULL;
    XmlNode *pCurNode = (XmlNode *)gModuleList.back();
    const char *p = sLine;
    const char *pEnd = sLine + strlen(sLine);

    bool bNameSet = false;

    for (; p < pEnd; ++p)
    {
        //"{" is a beginning of a block only if it is the last char of a line
        if (*p == '{' && pEnd - p == 1)
        {
            if (strlen(name) > 0)
            {
                const char *pRealname = getRealName(name);

                if (pRealname)
                {
                    pNode = new XmlNode;
                    pNode->init(pRealname, &attr);

                    //Remove space in the end of the value such as "module cache  {", value will be "cache"
                    removeSpace(value, 1);

                    if (strlen(value) > 0)
                        pNode->setValue(value, strlen(value));

                    pCurNode->addChild(pNode->getName(), pNode);
                    gModuleList.push_back(pNode);
                    pCurNode = pNode;
                    clearNameAndValue(name, value);
                    break;
                }
                else
                {
                    logToMem(LOG_LEVEL_ERR,
                             "parseline find block name [%s] is NOT keyword in %s:%d", name, fileName,
                             lineNumber);
                    break;
                }
            }
            else
            {
                logToMem(LOG_LEVEL_ERR,
                         "parseline found '{' without a block name in %s:%d", fileName, lineNumber);
                break;
            }
        }

        else if (*p == '}' && p == sLine)
        {
            if (gModuleList.size() > 1)
            {
                gModuleList.pop_back();
                clearNameAndValue(name, value);

                if (*(p + 1))
                {
                    ++p;
                    trimWhiteSpace(&p);
                    parseLine(fileName, lineNumber, p);
                    break;
                }
            }
            else
            {
                logToMem(LOG_LEVEL_ERR, "parseline found more '}' in %s:%d", fileName,
                         lineNumber);
                clearNameAndValue(name, value);
                break;
            }
        }
        else if ((*p == ' ' || *p == '\t') && value[0] == 0)
        {
            bNameSet = true;
            continue;
        }
        else
        {
            if (!bNameSet)
                strcatchr(name, *p, MAX_NAME_LENGTH);
            else
                strcatchr(value, *p, MAX_NAME_LENGTH);
        }
    }

    if (name[0] != 0)
    {
        const char *pRealname = getRealName(name);

        if (pRealname)
        {
            assert(pNode == NULL);
            pNode = new XmlNode;
            pNode->init(pRealname, &attr);

            if (strlen(value) > 0)
                pNode->setValue(value, strlen(value));

            pCurNode->addChild(pNode->getName(), pNode);
        }
        else
        {
            //There is no special case in server level
            //if (memcmp(pCurNode->getName(), SERVER_ROOT_XML_NAME, sizeof(SERVER_ROOT_XML_NAME) - 1) != 0)
            saveUnknownItems(fileName, lineNumber, pCurNode, name, value);
            //else
            //    logToMem(LOG_LEVEL_ERR, "%s Server level find unknown keyword [%s], ignored.", SERVER_ROOT_XML_NAME, name );
        }
    }
}
Ejemplo n.º 10
0
void plainconf::handleSpecialCase(XmlNode *pNode)
{
    const XmlNodeList *pUnknownList = pNode->getChildren(UNKNOWN_KEYWORDS);

    if (!pUnknownList)
        return ;

    int bModuleNode = (strcasecmp(pNode->getName(), "module") == 0);
    XmlNodeList::const_iterator iter;

    for (iter = pUnknownList->begin(); iter != pUnknownList->end(); ++iter)
    {
        const char *value = (*iter)->getValue();

        if (bModuleNode)
            appendModuleParam(pNode, value);
        else
        {
            const char *p = strstr(value, "::");

            //Only hanlde has :: case
            if (p)
            {
                /**
                 * CASE such as cache::enablecache 1, will be treated as
                 * module chace {
                 * param enablecache 1
                 * }
                 */
                char newname[1024] = {0};
                char newvalue[4096] = {0};
                strncpy(newname, value, p - value);
                strcpy(newvalue, p + 2);

                XmlNode *pRootNode = pNode;

                while (pRootNode->getParent())
                    pRootNode = pRootNode->getParent();

                const XmlNodeList *pModuleList = pRootNode->getChildren("module");

                if (pModuleList)
                {
                    XmlNodeList::const_iterator iter2;

                    for (iter2 = pModuleList->begin(); iter2 != pModuleList->end(); ++iter2)
                    {
                        if (strcasecmp((*iter2)->getValue(), newname) == 0)
                        {
                            addModuleWithParam(pNode, newname, newvalue);
                            break;
                        }
                    }

                    if (iter2 == pModuleList->end())
                        logToMem(LOG_LEVEL_ERR,
                                 "Module[%s] not defined in server leve while checking [%s].", newname,
                                 value);

                }
                else
                    logToMem(LOG_LEVEL_ERR,
                             "No module defined in server leve while checking [%s].", value);
            }
        }
    }
}
Ejemplo n.º 11
0
//This function may be recruse called
void plainconf::loadConfFile(const char *path)
{
    logToMem(LOG_LEVEL_INFO, "start parsing file %s", path);

    int type = checkFiletype(path);

    if (type == 0)
        return;

    else if (type == 2)
        loadDirectory(path, NULL);

    else if (type == 3)
    {
        AutoStr2 prefixPath = path;
        const char *p = strrchr(path, '/');

        if (p)
            prefixPath.setStr(path, p - path);

        struct stat sb;

        //removed the wildchar filename, should be a directory if exist
        if (stat(prefixPath.c_str(), &sb) == -1)
        {
            logToMem(LOG_LEVEL_ERR, "LoadConfFile error 1, path:%s directory:%s",
                     path, prefixPath.c_str());
            return ;
        }

        if ((sb.st_mode & S_IFMT) != S_IFDIR)
        {
            logToMem(LOG_LEVEL_ERR, "LoadConfFile error 2, path:%s directory:%s",
                     path, prefixPath.c_str());
            return ;
        }

        loadDirectory(prefixPath.c_str(), p + 1);
    }

    else //existed file
    {
        //gModuleList.push_back();
        //XmlNode *xmlNode = new XmlNode;
        FILE *fp = fopen(path, "r");

        if (fp == NULL)
        {
            logToMem(LOG_LEVEL_ERR, "Cannot open configuration file: %s", path);
            return;
        }


        const int MAX_LINE_LENGTH = 8192;
        char sLine[MAX_LINE_LENGTH];
        char *p;
        char sLines[MAX_LINE_LENGTH] = {0};
        int lineNumber = 0;
        const int MAX_MULLINE_SIGN_LENGTH = 128;
        char sMultiLineModeSign[MAX_MULLINE_SIGN_LENGTH] = {0};
        size_t  nMultiLineModeSignLen = 0;  //>0 is mulline mode

        while (fgets(sLine, MAX_LINE_LENGTH, fp), !feof(fp))
        {
            ++lineNumber;
            p = sLine;

            if (nMultiLineModeSignLen)
            {
                //Check if reach the END of the milline mode
                size_t len = 0;
                const char *pLineStart = getStrNoSpace(p, len);

                if (len == nMultiLineModeSignLen &&
                    strncasecmp(pLineStart, sMultiLineModeSign, nMultiLineModeSignLen) == 0)
                {
                    nMultiLineModeSignLen = 0;
                    removeSpace(sLines,
                                1);   //Remove the last \r\n so that if it is one line, it will still be one line
                    parseLine(path, lineNumber, sLines);
                    sLines[0] = 0x00;
                }
                else
                    strcat(sLines, p);

                continue;
            }

            removeSpace(p, 0);
            removeSpace(p, 1);

            if (!isValidline(p))
                continue;

            AutoStr2 pathInclude;

            if (isInclude(p, pathInclude))
            {
                char achBuf[512] = {0};
                getIncludeFile(pathInclude.c_str(), achBuf);
                loadConfFile(achBuf);
            }
            else
            {
                nMultiLineModeSignLen = checkMultiLineMode(p, sMultiLineModeSign,
                                        MAX_MULLINE_SIGN_LENGTH);

                if (nMultiLineModeSignLen > 0)
                    strncat(sLines, p, strlen(p) - (3 + nMultiLineModeSignLen));
                //need to continue
                else if (isChunkedLine(p))
                {
                    strncat(sLines, p, strlen(p) - 1);
                    //strcatchr(sLines, ' ', MAX_LINE_LENGTH); //add a space at the end of the line which has a '\\'
                }

                else
                {
                    strcat(sLines, p);
                    parseLine(path, lineNumber, sLines);
                    sLines[0] = 0x00;
                }
            }
        }

        fclose(fp);

        //Parsed, check in it
        checkInFile(path);
    }
}