Various fixes
[public/netxms.git] / src / agent / core / sysinfo.cpp
CommitLineData
39cc66bb 1/* $Id: sysinfo.cpp,v 1.23 2007-05-26 10:42:19 victor Exp $ */
e7474978
VK
2/*
3** NetXMS multiplatform core agent
4** Copyright (C) 2003, 2004 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**
c044c29c 20** File: sysinfo.cpp
e7474978
VK
21**/
22
23#include "nxagentd.h"
24
19acf449
VK
25#if HAVE_SYS_UTSNAME_H
26#include <sys/utsname.h>
27#endif
28
c044c29c
VK
29#ifndef S_ISDIR
30#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
31#endif
32
e7474978
VK
33
34//
35// Handler for Agent.Uptime parameter
36//
37
38LONG H_AgentUptime(char *cmd, char *arg, char *value)
39{
1da9d674 40 ret_uint(value, (DWORD)(time(NULL) - g_tmAgentStartTime));
e7474978
VK
41 return SYSINFO_RC_SUCCESS;
42}
43
44
45//
c044c29c
VK
46// Helper function to GetDirInfo
47//
e7474978 48
c044c29c
VK
49LONG GetDirInfo(char *szPath, char *szPattern, bool bRecursive,
50 unsigned int &uFileCount, QWORD &llFileSize)
e7474978 51{
c044c29c
VK
52 DIR *pDir = NULL;
53 struct dirent *pFile = NULL;
e7474978 54 struct stat fileInfo;
c044c29c
VK
55 char szFileName[MAX_PATH];
56 LONG nRet = SYSINFO_RC_SUCCESS;
e7474978 57
c044c29c
VK
58 if (stat(szPath, &fileInfo) == -1)
59 return SYSINFO_RC_ERROR;
e7474978 60
c044c29c
VK
61 // if this is just a file than simply return statistics
62 if (!S_ISDIR(fileInfo.st_mode))
63 {
64 if (MatchString(szPattern, szPath, FALSE))
65 {
66 llFileSize += (QWORD)fileInfo.st_size;
67 uFileCount++;
68 }
e7474978 69
c044c29c
VK
70 return nRet;
71 }
e7474978 72
c044c29c
VK
73 // this is a dir
74 pDir = opendir(szPath);
75 if (pDir != NULL)
76 {
77 while(1)
78 {
79 pFile = readdir(pDir);
80 if (pFile == NULL)
81 break;
e7474978 82
c044c29c
VK
83 if (!strcmp(pFile->d_name, ".") || !strcmp(pFile->d_name, ".."))
84 continue;
85
86 strcpy(szFileName, szPath);
87 strcat(szFileName, "/" );
88 strcat(szFileName, pFile->d_name);
89
90 // skip unaccessible entries
91 if (stat( szFileName, &fileInfo ) == -1)
92 continue;
93
94 if (S_ISDIR(fileInfo.st_mode) && bRecursive)
95 {
96 nRet = GetDirInfo(szFileName, szPattern, bRecursive, uFileCount, llFileSize);
97
98 if (nRet != SYSINFO_RC_SUCCESS)
99 break;
100 }
101
102 if (!S_ISDIR(fileInfo.st_mode) && MatchString(szPattern, pFile->d_name, FALSE))
103 {
104 llFileSize += (QWORD)fileInfo.st_size;
105 uFileCount++;
106 }
107 }
108 closedir(pDir);
109 }
110
111 return nRet;
e7474978
VK
112}
113
114
bb722c91 115//
c044c29c 116// Handler for File.Size(*) and File.Count(*)
bb722c91
VK
117//
118
c044c29c 119LONG H_DirInfo(char *cmd, char *arg, char *value)
bb722c91 120{
c044c29c
VK
121 char szPath[MAX_PATH], szPattern[MAX_PATH], szRecursive[10];
122 bool bRecursive = false;
bb722c91 123
c044c29c
VK
124 unsigned int uFileCount = 0;
125 QWORD llFileSize = 0;
126 LONG nRet;
bb722c91 127
c044c29c 128 if (!NxGetParameterArg(cmd, 1, szPath, MAX_PATH))
bb722c91 129 return SYSINFO_RC_UNSUPPORTED;
c044c29c
VK
130 if (!NxGetParameterArg(cmd, 2, szPattern, MAX_PATH))
131 return SYSINFO_RC_UNSUPPORTED;
132 if (!NxGetParameterArg(cmd, 3, szRecursive, 10))
133 return SYSINFO_RC_UNSUPPORTED;
134
135 // Recursion flag
c85a7173 136 bRecursive = ((atoi(szRecursive) != 0) || !_tcsicmp(szRecursive, _T("TRUE")));
bb722c91
VK
137
138 // If pattern is omited use asterisk
139 if (szPattern[0] == 0)
140 strcpy(szPattern, "*");
141
c044c29c
VK
142 nRet = GetDirInfo(szPath, szPattern, bRecursive, uFileCount, llFileSize);
143
8e0f62e5 144 switch(CAST_FROM_POINTER(arg, int))
bb722c91 145 {
c044c29c
VK
146 case DIRINFO_FILE_SIZE:
147 ret_uint64(value, llFileSize);
148 break;
149 case DIRINFO_FILE_COUNT:
150 ret_uint(value, uFileCount);
151 break;
152 default:
153 nRet = SYSINFO_RC_UNSUPPORTED;
154 break;
bb722c91
VK
155 }
156
c044c29c 157 return nRet;
bb722c91
VK
158}
159
160
e7474978
VK
161//
162// Calculate MD5 hash for file
163//
164
165LONG H_MD5Hash(char *cmd, char *arg, char *value)
166{
167 char szFileName[MAX_PATH], szHashText[MD5_DIGEST_SIZE * 2 + 1];
168 BYTE hash[MD5_DIGEST_SIZE];
169 DWORD i;
170
bb722c91 171 if (!NxGetParameterArg(cmd, 1, szFileName, MAX_PATH))
e7474978
VK
172 return SYSINFO_RC_UNSUPPORTED;
173
174 if (!CalculateFileMD5Hash(szFileName, hash))
175 return SYSINFO_RC_UNSUPPORTED;
176
177 // Convert MD5 hash to text form
178 for(i = 0; i < MD5_DIGEST_SIZE; i++)
179 sprintf(&szHashText[i << 1], "%02x", hash[i]);
180
181 ret_string(value, szHashText);
182 return SYSINFO_RC_SUCCESS;
183}
184
185
186//
187// Calculate SHA1 hash for file
188//
189
190LONG H_SHA1Hash(char *cmd, char *arg, char *value)
191{
901c96c7
VK
192 char szFileName[MAX_PATH], szHashText[SHA1_DIGEST_SIZE * 2 + 1];
193 BYTE hash[SHA1_DIGEST_SIZE];
194 DWORD i;
195
bb722c91 196 if (!NxGetParameterArg(cmd, 1, szFileName, MAX_PATH))
901c96c7
VK
197 return SYSINFO_RC_UNSUPPORTED;
198
199 if (!CalculateFileSHA1Hash(szFileName, hash))
200 return SYSINFO_RC_UNSUPPORTED;
201
6120112b 202 // Convert SHA1 hash to text form
901c96c7
VK
203 for(i = 0; i < SHA1_DIGEST_SIZE; i++)
204 sprintf(&szHashText[i << 1], "%02x", hash[i]);
205
206 ret_string(value, szHashText);
207 return SYSINFO_RC_SUCCESS;
e7474978
VK
208}
209
210
211//
212// Calculate CRC32 for file
213//
214
215LONG H_CRC32(char *cmd, char *arg, char *value)
216{
e3846581 217 char szFileName[MAX_PATH];
21d60842 218 DWORD dwCRC32;
6120112b
AK
219
220 if (!NxGetParameterArg(cmd, 1, szFileName, MAX_PATH))
221 return SYSINFO_RC_UNSUPPORTED;
222
223 if (!CalculateFileCRC32(szFileName, &dwCRC32))
224 return SYSINFO_RC_UNSUPPORTED;
225
e3846581 226 ret_uint(value, dwCRC32);
6120112b 227 return SYSINFO_RC_SUCCESS;
e7474978 228}
19acf449
VK
229
230
231//
232// Handler for System.PlatformName
233//
234
235LONG H_PlatformName(char *cmd, char *arg, char *value)
236{
237 LONG nResult = SYSINFO_RC_SUCCESS;
238
239#if defined(_WIN32)
240
241 SYSTEM_INFO sysInfo;
242
243 GetSystemInfo(&sysInfo);
244 switch(sysInfo.wProcessorArchitecture)
245 {
246 case PROCESSOR_ARCHITECTURE_INTEL:
247 strcpy(value, "windows-i386");
248 break;
249 case PROCESSOR_ARCHITECTURE_MIPS:
250 strcpy(value, "windows-mips");
251 break;
252 case PROCESSOR_ARCHITECTURE_ALPHA:
253 strcpy(value, "windows-alpha");
254 break;
255 case PROCESSOR_ARCHITECTURE_PPC:
256 strcpy(value, "windows-ppc");
257 break;
258 case PROCESSOR_ARCHITECTURE_IA64:
259 strcpy(value, "windows-ia64");
260 break;
261 case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
262 strcpy(value, "windows-i386");
263 break;
264 case PROCESSOR_ARCHITECTURE_AMD64:
6e2424fa 265 strcpy(value, "windows-x64");
19acf449
VK
266 break;
267 default:
268 strcpy(value, "windows-unknown");
269 break;
270 }
271
272#elif defined(_NETWARE)
273
274 // NetWare only exists on Intel x86 CPU,
275 // so there are nothing to detect
276 strcpy(value, "netware-i386");
277
278#elif HAVE_UNAME
279
280 struct utsname info;
281
8b85bd5a
VK
282 if (uname(&info) != -1)
283 {
39cc66bb
VK
284#ifdef _AIX
285 // Assume that we are running on PowerPC
286 sprintf(value, "%s-powerpc", info.sysname);
287#else
19acf449 288 sprintf(value, "%s-%s", info.sysname, info.machine);
39cc66bb 289#endif
19acf449
VK
290 }
291 else
292 {
2affecd6 293 DebugPrintf(INVALID_INDEX, "uname() failed: %s", strerror(errno));
19acf449
VK
294 nResult = SYSINFO_RC_ERROR;
295 }
296
297#else
298
299 // Finally, we don't know a way to detect platform
300 strcpy(value, "unknown");
301
302#endif
303
304 // Add user-configurable platform name suffix
305 if ((nResult == SYSINFO_RC_SUCCESS) && (g_szPlatformSuffix[0] != 0))
306 {
307 if (g_szPlatformSuffix[0] != '-')
308 strcat(value, "-");
309 strcat(value, g_szPlatformSuffix);
310 }
311
312 return nResult;
313}
0d2a47d9
VK
314
315
316//
317// Handler for File.Time.* parameters
318//
319
320LONG H_FileTime(char *cmd, char *arg, char *value)
321{
322 char szFilePath[MAX_PATH];
323 LONG nRet = SYSINFO_RC_SUCCESS;
324 struct stat fileInfo;
325
326 if (!NxGetParameterArg(cmd, 1, szFilePath, MAX_PATH))
327 return SYSINFO_RC_UNSUPPORTED;
328
329 if (stat(szFilePath, &fileInfo) == -1)
330 return SYSINFO_RC_ERROR;
331
8e0f62e5 332 switch(CAST_FROM_POINTER(arg, int))
0d2a47d9
VK
333 {
334 case FILETIME_ATIME:
77305d21
VK
335#ifdef _NETWARE
336 ret_uint64(value, fileInfo.st_atime.tv_sec);
337#else
0d2a47d9 338 ret_uint64(value, fileInfo.st_atime);
77305d21 339#endif
0d2a47d9
VK
340 break;
341 case FILETIME_MTIME:
77305d21
VK
342#ifdef _NETWARE
343 ret_uint64(value, fileInfo.st_mtime.tv_sec);
344#else
b0946f97 345 ret_uint64(value, fileInfo.st_mtime);
77305d21 346#endif
0d2a47d9
VK
347 break;
348 case FILETIME_CTIME:
77305d21
VK
349#ifdef _NETWARE
350 ret_uint64(value, fileInfo.st_ctime.tv_sec);
351#else
b0946f97 352 ret_uint64(value, fileInfo.st_ctime);
77305d21 353#endif
0d2a47d9
VK
354 break;
355 default:
356 nRet = SYSINFO_RC_UNSUPPORTED;
357 break;
358 }
359
360 return nRet;
361}