fixed bug caused by nxmibc refactoring
[public/netxms.git] / src / snmp / nxmibc / nxmibc.cpp
1 /*
2 ** NetXMS - Network Management System
3 ** NetXMS MIB compiler
4 ** Copyright (C) 2005-2012 Victor Kirhenshtein
5 **
6 ** This program is free software; you can redistribute it and/or modify
7 ** it under the terms of the GNU General Public License as published by
8 ** the Free Software Foundation; either version 2 of the License, or
9 ** (at your option) any later version.
10 **
11 ** This program is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ** GNU General Public License for more details.
15 **
16 ** You should have received a copy of the GNU General Public License
17 ** along with this program; if not, write to the Free Software
18 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 **
20 ** File: nxmibc.cpp
21 **
22 **/
23
24 #include "nxmibc.h"
25
26 #ifdef _WIN32
27 #include <conio.h>
28 #endif
29
30 /**
31 * Severity codes
32 */
33 #define MIBC_INFO 0
34 #define MIBC_WARNING 1
35 #define MIBC_ERROR 2
36
37 /**
38 * Externals
39 */
40 int ParseMIBFiles(StringList *fileList, SNMP_MIBObject **ppRoot);
41
42 /**
43 * Static data
44 */
45 static char m_szOutFile[MAX_PATH] = "netxms.mib";
46 static StringList s_fileList;
47 static bool s_pauseBeforeExit = false;
48
49 /**
50 * Errors
51 */
52 static struct
53 {
54 int nSeverity;
55 const TCHAR *pszText;
56 } m_errorList[] =
57 {
58 { MIBC_INFO, _T("Operation completed successfully") },
59 { MIBC_ERROR, _T("Import symbol \"%hs\" unresolved") },
60 { MIBC_ERROR, _T("Import module \"%hs\" unresolved") },
61 { MIBC_ERROR, _T("Parser error - %hs in line %d") },
62 { MIBC_ERROR, _T("Cannot open input file (%hs)") },
63 { MIBC_ERROR, _T("Cannot resolve symbol %hs") },
64 { MIBC_WARNING, _T("Cannot resolve data type \"%hs\" for object \"%hs\"") }
65 };
66
67 /**
68 * Pause if needed
69 */
70 static void Pause()
71 {
72 if (s_pauseBeforeExit)
73 {
74 #ifdef _WIN32
75 _tprintf(_T("Press any key to continue...\n"));
76 _getch();
77 #else
78 _tprintf(_T("Press ENTER to continue...\n"));
79 char temp[256];
80 fgets(temp, 255, stdin);
81 #endif
82 }
83 }
84
85 /**
86 * Display error text and abort compilation
87 */
88 extern "C" void Error(int nError, char *pszModule, ...)
89 {
90 va_list args;
91 static const TCHAR *severityText[] = { _T("INFO"), _T("WARNING"), _T("ERROR") };
92
93 _tprintf(_T("%hs: %s %03d: "), pszModule, severityText[m_errorList[nError].nSeverity], nError);
94 va_start(args, pszModule);
95 _vtprintf(m_errorList[nError].pszText, args);
96 va_end(args);
97 _tprintf(_T("\n"));
98 if (m_errorList[nError].nSeverity == MIBC_ERROR)
99 {
100 Pause();
101 exit(1);
102 }
103 }
104
105 /**
106 * Display help and exit
107 */
108 static void Help()
109 {
110 _tprintf(_T("Usage:\n\n")
111 _T("nxmibc [options] source1 ... sourceN\n\n")
112 _T("Valid options:\n")
113 _T(" -d <dir> : Include all MIB files from given directory to compilation\n")
114 _T(" -r : Scan sub-directories \n")
115 _T(" -e <ext> : Specify file extensions (default extension: \"txt\") \n")
116 _T(" -o <file> : Set output file name (default is netxms.mib)\n")
117 _T(" -P : Pause before exit\n")
118 _T(" -s : Strip descriptions from MIB objects\n")
119 _T(" -z : Compress output file\n")
120 _T("\n"));
121 exit(0);
122 }
123
124 /**
125 * Scan directory for MIB files
126 */
127 static void ScanDirectory(const TCHAR *path, const StringSet *extensions, bool recursive)
128 {
129 _TDIR *pDir = _topendir(path);
130 if (pDir != NULL)
131 {
132 while(true)
133 {
134 struct _tdirent *pFile = _treaddir(pDir);
135 if (pFile == NULL)
136 break;
137 if (_tcscmp(pFile->d_name, _T(".")) && _tcscmp(pFile->d_name, _T("..")))
138 {
139 TCHAR szBuffer[MAX_PATH];
140 _sntprintf(szBuffer, MAX_PATH, _T("%s") FS_PATH_SEPARATOR _T("%s"), path, pFile->d_name);
141 if (recursive && (pFile->d_type == DT_DIR))
142 {
143 ScanDirectory(szBuffer, extensions, recursive);
144 }
145 else
146 {
147 TCHAR *extension = _tcsrchr(pFile->d_name, _T('.'));
148 #ifdef _WIN32
149 _tcslwr(extension);
150 #endif
151 if ((extension != NULL) && extensions->contains(extension + 1))
152 s_fileList.add(szBuffer);
153 }
154 }
155 }
156 _tclosedir(pDir);
157 }
158 }
159
160 /**
161 * Entry point
162 */
163 int main(int argc, char *argv[])
164 {
165 bool recursive = false;
166 bool scanDir = false;
167 SNMP_MIBObject *pRoot;
168 DWORD dwFlags = 0, dwRet;
169 int i, ch, rc = 0;
170
171 InitNetXMSProcess(true);
172
173 _tprintf(_T("NetXMS MIB Compiler Version ") NETXMS_VERSION_STRING _T(" (") NETXMS_BUILD_TAG _T(")\n")
174 _T("Copyright (c) 2005-2017 Raden Solutions\n\n"));
175
176 StringList paths;
177 StringSet extensions;
178 extensions.add(_T("txt"));
179
180 // Parse command line
181 opterr = 1;
182 while((ch = getopt(argc, argv, "rd:ho:e:Psz")) != -1)
183 {
184 switch(ch)
185 {
186 case 'e':
187 #ifdef _WIN32
188 #ifdef UNICODE
189 extensions.addPreallocated(_wcslwr(WideStringFromMBStringSysLocale(optarg)));
190 #else
191 extensions.add(strlwr(optarg));
192 #endif
193 #else
194 #ifdef UNICODE
195 extensions.addPreallocated(WideStringFromMBStringSysLocale(optarg));
196 #else
197 extensions.add(optarg);
198 #endif
199 #endif
200 break;
201 case 'h': // Display help and exit
202 Help();
203 break;
204 case 'd':
205 #ifdef UNICODE
206 paths.addPreallocated(WideStringFromMBStringSysLocale(optarg));
207 #else
208 paths.add(optarg);
209 #endif
210 scanDir = true;
211 break;
212 case 'o':
213 strncpy(m_szOutFile, optarg, MAX_PATH);
214 m_szOutFile[MAX_PATH - 1] = 0;
215 break;
216 case 'P':
217 s_pauseBeforeExit = true;
218 break;
219 case 'r':
220 recursive = true;
221 break;
222 case 's':
223 dwFlags |= SMT_SKIP_DESCRIPTIONS;
224 break;
225 case 'z':
226 dwFlags |= SMT_COMPRESS_DATA;
227 break;
228 case '?':
229 return 255;
230 default:
231 break;
232 }
233 }
234
235 if (scanDir)
236 {
237 for(int i = 0; i < paths.size(); i++)
238 {
239 ScanDirectory(paths.get(i), &extensions, recursive);
240 }
241 }
242
243 for(i = optind; i < argc; i++)
244 {
245 #ifdef UNICODE
246 s_fileList.addPreallocated(WideStringFromMBStringSysLocale(argv[i]));
247 #else
248 s_fileList.add(argv[i]);
249 #endif
250 }
251
252 if (s_fileList.size() > 0)
253 {
254 ParseMIBFiles(&s_fileList, &pRoot);
255
256 if (pRoot != NULL)
257 {
258 #ifdef UNICODE
259 WCHAR *wname = WideStringFromMBString(m_szOutFile);
260 dwRet = SNMPSaveMIBTree(wname, pRoot, dwFlags);
261 free(wname);
262 #else
263 dwRet = SNMPSaveMIBTree(m_szOutFile, pRoot, dwFlags);
264 #endif
265 delete pRoot;
266 if (dwRet != SNMP_ERR_SUCCESS)
267 {
268 _tprintf(_T("ERROR: Cannot save output file %hs (%s)\n"), m_szOutFile, SNMPGetErrorText(dwRet));
269 rc = 1;
270 }
271 }
272 }
273 else
274 {
275 _tprintf(_T("ERROR: No source files given\n"));
276 rc = 1;
277 }
278
279 Pause();
280 return rc;
281 }