#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "Debug.hpp" #include "Oid.hpp" #include "OidToF.hpp" #include "Configs.hpp" extern Configs theConfigs; OidToFile::OidToFile() { m_hMibFile = NULL; m_pszMibFilename = NULL; } // DESCRIPTION: // wrapper for the base class Scan(); // it find first the sizes of subtrees (subtree's root node included) // RETURN VALUE: // 0 on success // -1 on failure; int OidToFile::Scan() { SIMCOidTreeNode *pOidNode; SIMCNodeList recursionTrace; // get the root node from the oid tree, // return "error" if no tree or no root _VERIFY(m_pOidTree != NULL, -1); pOidNode = (SIMCOidTreeNode *)m_pOidTree->GetRoot(); _VERIFY(pOidNode != NULL, -1); // node hasn't been scanned; _lParam=number of dependencies pOidNode->_lParam = (DWORD)pOidNode->GetListOfChildNodes()->GetCount(); // initialize the recursionTree with the root node _VERIFY(recursionTrace.AddHead(pOidNode)!=NULL, -1); // start to scan the tree while (!recursionTrace.IsEmpty()) { const SIMCNodeList *pLstChildren; // allways pick up the node in the head of the list pOidNode = recursionTrace.GetHead(); // get the dependencies list pLstChildren = pOidNode->GetListOfChildNodes(); // if there are no more dependencies to process // sum the children values and add to its own if (pOidNode->_lParam == 0) { SIMCOidTreeNode *pParent; const char * cszSymbol = NULL; _VERIFY(GetNodeSymbol(pOidNode, cszSymbol)==0, -1); pOidNode->_lParam = sizeof(T_FILE_NODE_EX) + (cszSymbol != NULL ? strlen(cszSymbol) : 0); // compute the cumulated size of the subtree for (POSITION p = pLstChildren->GetHeadPosition(); p != NULL;) { const SIMCOidTreeNode *pChild; pChild = pLstChildren->GetNext(p); _VERIFY(pChild!=NULL, -1); // Modify here!!!! pOidNode->_lParam += pChild->_lParam; } // decrease the number of dependencies from the parent node pParent = m_pOidTree->GetParentOf(pOidNode); if ( pParent != NULL) { pParent->_lParam--; } // delete the node from the list recursionTrace.RemoveHead(); } else { // add the children list to the front of the recursionTrace for (POSITION p = pLstChildren->GetHeadPosition(); p != NULL;) { SIMCOidTreeNode *pChild; pChild = pLstChildren->GetNext(p); _VERIFY(pChild!=NULL, -1); pChild->_lParam = (DWORD)pChild->GetListOfChildNodes()->GetCount(); _VERIFY(recursionTrace.AddHead(pChild)!=NULL, -1); } } } return OidTreeScanner::Scan(); } // DESCRIPTION: // Creates the output file, containing the OID encoding // PARAMETERS: // (in) pointer to the output file name // RETURN VALUE: // 0 on success, -1 on failure int OidToFile::SetMibFilename(const char * pszMibFilename) { if (m_pszMibFilename != NULL) { delete (void *)m_pszMibFilename; m_pszMibFilename = NULL; } if (pszMibFilename != NULL) { _VERIFY(strlen(pszMibFilename) != 0, -1); m_pszMibFilename = new char [strlen(pszMibFilename) + 1]; _VERIFY(m_pszMibFilename != NULL, -1); strcpy((char *)m_pszMibFilename, pszMibFilename); } return 0; } // DESCRIPTION: // "callback" function, called each time a // tree node passes through the scan. // in pOidNode->_lParam there is the cumulated size // of the hole subtree, root included. // size = sizeof(T_FILE_NODE_EX) + strlen(node symbol) // PARAMETERS: // (in) Pointer to the current node in the tree. // Nodes are supplied in lexicographic order. // RETURN VALUE: // 0 - the scanner should continue // -1 - the scanner should abort. int OidToFile::OnScanNode(const SIMCOidTreeNode *pOidNode) { T_FILE_NODE_EX fileNode; char *nodeSymbol = NULL; // skip the '0' root of the OID tree if (m_pOidTree->GetParentOf(pOidNode) == NULL) return 0; if (theConfigs.m_dwFlags & CFG_PRINT_TREE) { Oid oid; _VERIFY(GetNodeOid(pOidNode, oid)==0, -1); cout << oid << "\n"; } if (theConfigs.m_dwFlags & CFG_PRINT_NODE) { cout << "."; cout.flush(); } // if no need to write output file, return success if (m_pszMibFilename == NULL) return 0; _VERIFY(GetNodeSymbol(pOidNode, nodeSymbol) == 0, -1); // build the T_FILE_NODE_EX structure fileNode.uNumChildren = (UINT)pOidNode->GetListOfChildNodes()->GetCount(); fileNode.uReserved = 0; fileNode.uNumSubID = pOidNode->GetValue(); if (nodeSymbol == NULL) { fileNode.lNextOffset = pOidNode->_lParam - sizeof(T_FILE_NODE_EX); fileNode.uStrLen = 0; } else { fileNode.uStrLen = strlen(nodeSymbol); fileNode.lNextOffset = pOidNode->_lParam - fileNode.uStrLen - sizeof(T_FILE_NODE_EX); } // create / write_open file if not already created if (m_hMibFile == NULL) { OFSTRUCT of; _VERIFY(m_pszMibFilename != NULL, -1); m_hMibFile = OpenFile(m_pszMibFilename, &of, OF_CREATE|OF_WRITE|OF_SHARE_EXCLUSIVE); _VERIFY(m_hMibFile != -1, -1); } // write fileNode to file _VERIFY(_lwrite(m_hMibFile, (LPSTR)&fileNode, sizeof(T_FILE_NODE_EX)) == sizeof(T_FILE_NODE_EX), -1); // write node's symbol if exists if (fileNode.uStrLen != 0) { _VERIFY(_lwrite(m_hMibFile, nodeSymbol, fileNode.uStrLen) == fileNode.uStrLen, -1); } return 0; } OidToFile::~OidToFile() { if (m_pszMibFilename != NULL) delete (void *)m_pszMibFilename; if (m_hMibFile != NULL) _lclose(m_hMibFile); }