📄 xmlconfig.cpp
字号:
} return CfgVarString;}voidXMLConfig::StuffRegistry(XMLConfigList* list){ CHXSimpleList::Iterator i; char* regname = list->m_parentnode->get_registry_name(); if(m_pRegistry->GetTypeByName(regname) == PT_UNKNOWN) { m_pRegistry->AddComp(regname); } delete [] regname; for(i = list->Begin(); i != list->End(); ++i) { XMLConfigListNode* node = (XMLConfigListNode*)(*i); switch(node->m_type) { case CfgVar: regname = node->get_registry_name(); switch(GetVarType(node)) { case CfgVarInt: // printf("%s = %ld\n", regname, node->m_int); if(m_pRegistry->GetTypeByName(regname) == PT_UNKNOWN) { m_pRegistry->AddInt(regname, node->m_int); } else { m_pRegistry->SetIntByName(regname, node->m_int); } break; case CfgVarString: { CHXBuffer* pBuffer = new CHXBuffer; pBuffer->AddRef(); pBuffer->Set((UINT8*)node->m_value, strlen(node->m_value) + 1); // printf("%s = %s\n", regname, (const char *)pBuffer->GetBuffer()); if(m_pRegistry->GetTypeByName(regname) == PT_UNKNOWN) { m_pRegistry->AddStr(regname, pBuffer); } else { m_pRegistry->SetStrByName(regname, pBuffer); } pBuffer->Release(); break; } case CfgVarBool: // printf("%s = %ld\n", regname, node->m_bool); if(m_pRegistry->GetTypeByName(regname) == PT_UNKNOWN) { m_pRegistry->AddInt(regname, node->m_bool); } else { m_pRegistry->SetIntByName(regname, node->m_bool); } break; } delete [] regname; break; case CfgList: StuffRegistry(node->m_pList); break; } }}// // Method: Read//// Parameters://// filename: The file to be read.// pWinRegKey: The Windows registry key to be filled in (can be// NULL if no registry writing is needed).// pServRegKey: The Server registry key to be filled in.// // Notes: the bIncludedFile is for internal recursive use only. Do not // set it when calling from outside this object.HX_RESULTXMLConfig::Read(char* filename, char* pServRegKey, BOOL bIncludedFile){ HX_RESULT hResult = HXR_OK; FILE* fp=0; XMLParser parser; XMLTag* tag = 0; CBigByteQueue queue(MAX_TAG_SIZE); int l=0; BOOL filedone = FALSE; UINT32 indent = 0; HX_ASSERT(filename && strlen(filename)); HX_VECTOR_DELETE(m_filename); m_filename = new_string(filename); fp = fopen(filename, "r"); if (!fp) { ERRMSG(m_pMessages, "%s: file not found", filename); return HXR_FILE_NOT_FOUND; } if(!m_pList) { m_pList = new XMLConfigList; m_pList->m_parentnode = new XMLConfigListNode; m_pList->m_parentnode->m_name = new_string(pServRegKey); m_pList->m_parentnode->m_parent = NULL; } // read the config file into the byte queue INT32 nBufSize = 16384; BYTE* pBuf = new BYTE[nBufSize]; while (!filedone && hResult == HXR_OK) { l = fread(pBuf, 1, nBufSize, fp); if (l > 0) { if (!queue.EnQueue(pBuf, l)) { if (!queue.Grow(l)) { ERRMSG(m_pMessages, "error expanding data structure while parsing %s", filename); hResult = HXR_FAIL; } if (!queue.EnQueue(pBuf, l)) { ERRMSG(m_pMessages, "unknown error while parsing %s", filename); hResult = HXR_FAIL; } } } else { filedone = TRUE; } } UINT32 bytesUsed=0; UINT32 bytesAvail=0; BYTE* p=0; while (hResult == HXR_OK && (bytesAvail = queue.GetQueuedItemCount()) > 0) { if (bytesAvail > nBufSize) { HX_VECTOR_DELETE(pBuf); pBuf = new BYTE[bytesAvail]; nBufSize = bytesAvail; } p = pBuf; queue.DeQueue(pBuf, bytesAvail); bytesUsed = bytesAvail; HX_DELETE(tag); XMLParseResult res = parser.Parse((const char*&)p, bytesAvail, tag); queue.EnQueue(p, bytesAvail - (p - pBuf)); switch(res) { case XMLPNoClose: // A tag opener was found, but no closer yet. if (filedone) { pBuf[bytesAvail - 1] = '\0'; if (bytesAvail > MAX_ERROR_CHARS) { pBuf[MAX_ERROR_CHARS - 1] = '\0'; } ERRMSG(m_pMessages, "%s: Missing close for tag '%s'...", m_filename, pBuf); hResult = HXR_FAIL; } break; case XMLPNoTagType: *p = 0; ERRMSG(m_pMessages, "%s: Badly formed tag '%s'", m_filename, pBuf); break; case XMLPBadAttribute: *p = 0; ERRMSG(m_pMessages, "%s: Badly formed attribute in '%s'", m_filename, pBuf); break; case XMLPPlainText: //Some text. What do we care? break; case XMLPBadEndTag: *p = 0; ERRMSG(m_pMessages, "%s: Unexpected end tag '</%s>'", m_filename, tag->m_name); hResult = HXR_FAIL; break; case XMLPComment: // A comment, fine. if(tag != NULL) { //Some kind of comment directive XMLAttribute* pAttr = tag->attribute(0); if(pAttr && pAttr->name) { if(strcasecmp(pAttr->name, "include") == 0) { char* path; char* newfile = new char[1024]; if(!strchr(tag->attribute(0)->value, OS_SEPARATOR_CHAR) && ((path = strrchr(m_filename, OS_SEPARATOR_CHAR)) != NULL)) { path++; if (path - m_filename < 1024) { strncpy(newfile, m_filename, path - m_filename); newfile[path - m_filename] = '\0'; } SafeStrCat(newfile, tag->attribute(0)->value, 1024); } else { SafeStrCpy(newfile, tag->attribute(0)->value, 1024); } char* filename = m_filename; m_filename = NULL; Read(newfile, pServRegKey, TRUE); delete[] m_filename; m_filename = filename; delete[] newfile; } } } break; case XMLPDirective: // A directive. We don't handle any yet. break; case XMLPProcInst: // A processing Instruction, whee! break; case XMLPTag: { if(Expand(tag, &queue)) break; XMLConfigListNode* node = new XMLConfigListNode; node->m_parent = m_pList->m_parentnode; node->m_vserver = m_vserver; if(tag->m_need_close) { if(strcasecmp(tag->m_name, "list") == 0) { const char* name = tag->get_attribute("name"); if(!name) { ERRMSG(m_pMessages, "%s: List tag requires a name attribute", m_filename); // Process anyway, give it a dummy name name = "XXXBADLIST"; } node->m_type = CfgList; node->m_name = new_string(name); node->m_num = tag->elem; m_pList->AddTail(node); m_pListStack.Push(m_pList); node->m_pList = new XMLConfigList; m_pList = node->m_pList; m_pList->m_parentnode = node; } else if(strcasecmp(tag->m_name, "server") == 0) { const char* server = tag->get_attribute("number"); if(!server) { ERRMSG(m_pMessages, "%s: Server tag requires a number, defaulting to 0", m_filename); m_vserver = 0; } else { char vserver_str[64]; /* Flawfinder: ignore */ m_vserver = atol(server); sprintf(vserver_str, "server%ld", m_vserver); /* Flawfinder: ignore */ if(m_pRegistry->GetTypeByName(vserver_str) == PT_UNKNOWN) { m_pRegistry->AddComp(vserver_str); sprintf(vserver_str, "server%ld.config", /* Flawfinder: ignore */ m_vserver); m_pRegistry->AddComp(vserver_str); } } } } else if(tag->m_type != XMLEndTag) { const char* name = tag->get_attribute("name"); const char* value = tag->get_attribute("value"); if(name && value) { node->m_type = CfgVar; node->m_name = new_string(name); node->m_value = new_string(value); node->m_num = tag->elem; m_pList->AddTail(node); } } else { // An End Tag if(strcasecmp(tag->m_name, "list") == 0) { m_pList = (XMLConfigList*)m_pListStack.Pop(); } else if(strcasecmp(tag->m_name, "server") == 0) { if(m_vserver < 0) { ERRMSG(m_pMessages, "%s: </Server> Tag with no matching <Server>", m_filename); } else { m_vserver = -1; } } } break; } } } if(hResult == HXR_OK && !bIncludedFile) { StuffRegistry(m_pList); delete m_pList->m_parentnode; } if (hResult == HXR_OK && !m_pListStack.IsEmpty()) { ERRMSG(m_pMessages, "%s: <List> tag with no matching </List>", m_filename); hResult = HXR_FAIL; } // cleanup if (fp) fclose(fp); HX_VECTOR_DELETE(pBuf); HX_DELETE(tag); return hResult;}char*XMLConfig::XMLConfigListNode::get_registry_name(INT32 vserver){ char* name; if(m_parent) { char* parentname = m_parent->get_registry_name( vserver < 0 ? m_vserver : vserver); name = new char[strlen(parentname) + strlen(m_name) + 2]; sprintf(name, "%s.%s", parentname, m_name); /* Flawfinder: ignore */ delete [] parentname; return name; } else { if(vserver >= 0) { name = new char[26 + strlen(m_name) + 2]; sprintf(name, "server%ld.%s", vserver, m_name); /* Flawfinder: ignore */ } else { name = new_string(m_name); } return name; }}///XXXPM This func does not correctly handle the original file not///being there.HX_RESULTXMLConfig::WriteToFile(const char* pKeyName, const char* pFileName){ UINT32 ulListsToIgnore = 0; /* * Make sure we have a valid file name to use. */ if (!pFileName) { return HXR_FAIL; } /* * Copy filename to filename.bak. */ char *pNewFileName = new char[strlen(pFileName) + strlen(".bak") + 1]; sprintf(pNewFileName, "%s.bak", pFileName); /* Flawfinder: ignore */ FILE* fpOld = fopen(pFileName, "r"); FILE* fpNew = fopen(pNewFileName, "w"); if (!fpNew || !fpOld) { HX_VECTOR_DELETE(pNewFileName); if (fpNew) fclose(fpNew); if (fpOld) fclose(fpOld); return HXR_FAIL; } INT32 nBufSize=16384; BYTE* pBuf = new BYTE[nBufSize]; int iGot = 0; while (!feof(fpOld)) { iGot = fread(pBuf, sizeof(char), nBufSize, fpOld); if (iGot) { fwrite(pBuf, sizeof(char), iGot, fpNew); } } fclose(fpNew); fclose(fpOld);#ifdef _UNIX chmod(pNewFileName, 0700);#endif //UNIX fpNew = fopen(pFileName, "w"); fpOld = fopen(pNewFileName, "r"); HX_VECTOR_DELETE(pNewFileName); if (!fpNew || !fpOld) { if (fpNew) fclose(fpNew); if (fpOld) fclose(fpOld); return HXR_FAIL; } int l; BOOL filedone = 0; XMLTag* tag = 0; XMLTag* wspacetag = 0; CBigByteQueue queue(MAX_TAG_SIZE); XMLParser parser; HX_RESULT hResult = HXR_OK; /* * Files are all aready. Now we need to build our config levels list. */ CHXSimpleList levlist; /* * Add for level 0. */ CHXSimpleList* pNewList = new CHXSimpleList; IHXValues* pValues = 0; _AddPropsToList(pNewList, pKeyName, m_pRegistry); XMLConfigString curr_level; curr_level.AddLevel(pKeyName); while (!filedone && hResult == HXR_OK) { l = fread(pBuf, 1, nBufSize, fpOld); if (l > 0) { if (!queue.EnQueue(pBuf, l)) { if (!queue.Grow(l)) { ERRMSG(m_pMessages, "error expanding data structure while parsing"); hResult = HXR_FAIL; } if (!queue.EnQueue(pBuf, l)) { ERRMSG(m_pMessages, "unknown error while parsing"); hResult = HXR_FAIL; } } } else { filedone = TRUE; } } UINT32 bytesUsed=0; UINT32 bytesAvail=0; BYTE* p=0; while (hResult == HXR_OK && (bytesAvail = queue.GetQueuedItemCount()) > 0) { if (bytesAvail > nBufSize) { HX_VECTOR_DELETE(pBuf); pBuf = new BYTE[bytesAvail]; nBufSize = bytesAvail; } p = pBuf; queue.DeQueue(pBuf, bytesAvail); bytesUsed = bytesAvail; HX_DELETE(tag); XMLParseResult res = parser.Parse((const char*&)p, bytesAvail, tag); queue.EnQueue(p, bytesAvail - (p - pBuf)); switch(res) { case XMLPNoClose: // A tag opener was found, but no closer yet. if (filedone) { pBuf[bytesAvail - 1] = '\0'; if (bytesAvail > MAX_ERROR_CHARS) { pBuf[MAX_ERROR_CHARS - 1] = '\0'; } ERRMSG(m_pMessages, "%s: Missing close for tag %s...", m_filename, pBuf); hResult = HXR_FAIL; } break; case XMLPNoTagType: *p = 0; ERRMSG(m_pMessages, "%s: Badly formed tag %s", m_filename, pBuf); break; case XMLPBadAttribute: *p = 0; ERRMSG(m_pMessages, "%s: Badly formed attribute in %s", m_filename, pBuf); break; case XMLPPlainText: /* * Just plaintext. Dump this out directly. */ if (wspacetag) { delete wspacetag; } wspacetag = tag; tag = 0; /* fwrite(tag->m_cur_attribute->value, sizeof(char), strlen(tag->m_cur_attribute->value), fpNew); */ break; case XMLPBadEndTag: *p = 0; ERRMSG(m_pMessages, "%s: Unexpected tag %s", m_filename, pBuf); break; case XMLPComment: /* * Just a comment. Dump it out. Comment lives from * p to pBuf. */ if (wspacetag) { fwrite(wspacetag->m_cur_attribute->value, sizeof(char), strlen(wspacetag->m_cur_attribute->value), fpNew); delete wspacetag; wspacetag = 0; } fwrite(pBuf, sizeof(char), p - pBuf, fpNew); break; case XMLPDirective: // A directive. We don't handle any yet. break; case XMLPProcInst: /* * Just dump processing instructions as we read them. */ if (wspacetag) { fwrite(wspacetag->m_cur_attribute->value, sizeof(char), strlen(wspacetag->m_cur_attribute->value), fpNew); delete wspacetag; wspacetag = 0; } fwrite(pBuf, sizeof(char), p - pBuf, fpNew); break; case XMLPTag: { if(Expand(tag, &queue)) break; if(tag->m_need_close) { if(strcasecmp(tag->m_name, "list") == 0) { if (ulListsToIgnore) { ulListsToIgnore++; } else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -