source: nscp/trunk/modules/CheckDisk/CheckDisk.cpp @ e93e741

Last change on this file since e93e741 was e93e741, checked in by Michael Medin <michael@…>, 8 years ago
  • Fixed PROCSTATE and SERVICESTATE return state. + Added support for individual size in CheckDriveSize and CheckFileSize (size has to be specified before a drive/path)
  • Fixed performance data for drives (and possibly other places)
  • Property mode set to 100644
File size: 12.5 KB
Line 
1// CheckEventLog.cpp : Defines the entry point for the DLL application.
2//
3
4#include "stdafx.h"
5#include "CheckDisk.h"
6#include <strEx.h>
7#include <time.h>
8#include <utils.h>
9
10CheckDisk gCheckDisk;
11
12BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
13{
14        NSCModuleWrapper::wrapDllMain(hModule, ul_reason_for_call);
15        return TRUE;
16}
17
18CheckDisk::CheckDisk() {
19}
20CheckDisk::~CheckDisk() {
21}
22
23
24bool CheckDisk::loadModule() {
25        return true;
26}
27bool CheckDisk::unloadModule() {
28        return true;
29}
30
31std::string CheckDisk::getModuleName() {
32        return "CheckDisk Various Disk related checks.";
33}
34NSCModuleWrapper::module_version CheckDisk::getModuleVersion() {
35        NSCModuleWrapper::module_version version = {0, 0, 1 };
36        return version;
37}
38
39bool CheckDisk::hasCommandHandler() {
40        return true;
41}
42bool CheckDisk::hasMessageHandler() {
43        return false;
44}
45
46typedef std::unary_function<const WIN32_FIND_DATA&, bool> baseClass;
47struct GetSize : public baseClass
48{
49        GetSize() : size(0) { }
50        result_type operator()(argument_type wfd) {
51                if (!(wfd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)) {
52                        size += (wfd.nFileSizeHigh * ((long long)MAXDWORD+1)) + (long long)wfd.nFileSizeLow;
53                }
54                return true;
55        }
56        inline long long getSize() {
57                return size;
58        }
59private: 
60        long long size;
61};
62
63void RecursiveScanDirectory(std::string dir, GetSize & f) {
64        std::string baseDir;
65        std::string::size_type pos = dir.find_last_of('\\');
66        if (pos == std::string::npos)
67                return;
68        baseDir = dir.substr(0, pos);
69
70        WIN32_FIND_DATA wfd;
71        HANDLE hFind = FindFirstFile(dir.c_str(), &wfd);
72        if (hFind != INVALID_HANDLE_VALUE) {
73                do {
74                        if (!f(wfd))
75                                break;
76                        if ((wfd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) {
77                                if ( (strcmp(wfd.cFileName, ".") != 0) && (strcmp(wfd.cFileName, "..") != 0) )
78                                        RecursiveScanDirectory(baseDir + "\\" + wfd.cFileName + "\\*.*", f);
79                        }
80                } while (FindNextFile(hFind, &wfd));
81        }
82        FindClose(hFind);
83}
84
85struct DriveConatiner {
86        checkHolders::SizeMaxMinPercentage<> warn_;
87        checkHolders::SizeMaxMinPercentage<> crit_;
88        std::string drive_;
89        DriveConatiner(std::string drive, checkHolders::SizeMaxMinPercentage<> warn, checkHolders::SizeMaxMinPercentage<> crit)
90                : drive_(drive), warn_(warn), crit_(crit)
91        {}
92};
93
94NSCAPI::nagiosReturn CheckDisk::CheckDriveSize(const unsigned int argLen, char **char_args, std::string &message, std::string &perf) {
95        NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK;
96        std::list<std::string> args = arrayBuffer::arrayBuffer2list(argLen, char_args);
97        if (args.empty()) {
98                message = "Missing argument(s).";
99                return NSCAPI::returnCRIT;
100        }
101
102        checkHolders::SizeMaxMinPercentage<> warn;
103        checkHolders::SizeMaxMinPercentage<> crit;
104        bool bShowAll = false;
105        bool bNSClient = false;
106        bool bCheckAll = false;
107
108        bool bFilter = false;
109        bool bFilterRemote = false;
110        bool bFilterRemovable = false;
111        bool bFilterFixed = false;
112        bool bFilterCDROM = false;
113        std::list<DriveConatiner> drives;
114
115        std::list<std::string>::const_iterator cit;
116        for (cit=args.begin();cit!=args.end();++cit) {
117                std::string arg = *cit;
118                std::pair<std::string,std::string> p = strEx::split(arg,"=");
119                if (p.first == "Drive") {
120                        drives.push_back(DriveConatiner(p.second, warn, crit));
121                } else if (p.first == "MaxWarn") {
122                        warn.max.set(p.second);
123                } else if (p.first == "MinWarn") {
124                        warn.min.set(p.second);
125                } else if (p.first == "MaxCrit") {
126                        crit.max.set(p.second);
127                } else if (p.first == "MinCrit") {
128                        crit.min.set(p.second);
129                } else if (p.first == SHOW_ALL) {
130                        bShowAll = true;
131                } else if (p.first == "nsclient") {
132                        bNSClient = true;
133                } else if (p.first == "FilterType") {
134                        bFilter = true;
135                        if (p.second == "FIXED") {
136                                bFilterFixed = true;
137                        } else if (p.second == "CDROM") {
138                                bFilterCDROM= true;
139                        } else if (p.second == "REMOVABLE") {
140                                bFilterRemovable = true;
141                        } else if (p.second == "REMOTE") {
142                                bFilterRemote= true;
143                        }
144                } else if (p.first == "CheckAll") {
145                        bCheckAll = true;
146                } else {
147                        drives.push_back(DriveConatiner(p.first, warn, crit));
148                }
149        }
150
151        if (bCheckAll) {
152                DWORD dwDrives = GetLogicalDrives();
153                int idx = 0;
154                while (dwDrives != 0) {
155                        if (dwDrives & 0x1) {
156                                std::string drv;
157                                drv += static_cast<char>('A' + idx); drv += ":\\";
158                                UINT drvType = GetDriveType(drv.c_str());
159                                if ((!bFilter)&&(drvType == DRIVE_FIXED)) {
160                                        drives.push_back(DriveConatiner(drv, warn, crit));
161                                } else if ((bFilter)&&(bFilterFixed)&&(drvType==DRIVE_FIXED)) {
162                                        drives.push_back(DriveConatiner(drv, warn, crit));
163                                } else if ((bFilter)&&(bFilterCDROM)&&(drvType==DRIVE_CDROM)) {
164                                        drives.push_back(DriveConatiner(drv, warn, crit));
165                                } else if ((bFilter)&&(bFilterRemote)&&(drvType==DRIVE_REMOTE)) {
166                                        drives.push_back(DriveConatiner(drv, warn, crit));
167                                } else if ((bFilter)&&(bFilterRemovable)&&(drvType==DRIVE_REMOVABLE)) {
168                                        drives.push_back(DriveConatiner(drv, warn, crit));
169                                }
170                        }
171                        idx++;
172                        dwDrives >>= 1;
173                }
174        }
175
176        for (std::list<DriveConatiner>::iterator it = drives.begin();it!=drives.end();it++) {
177                DriveConatiner drive = (*it);
178                if (drive.drive_.length() == 1)
179                        drive.drive_ += ":";
180                UINT drvType = GetDriveType(drive.drive_.c_str());
181
182                if ((!bFilter)&&(drvType != DRIVE_FIXED)) {
183                        message = "UNKNOWN: Drive is not a fixed drive: " + drive.drive_ + " (it is a: " + strEx::itos(drvType) + ")";
184                        return NSCAPI::returnUNKNOWN;
185                } else if ((bFilter)&&(!bFilterFixed)&&(drvType==DRIVE_FIXED)) {
186                        message = "UNKNOWN: Drive does not match the current filter: " + drive.drive_ + " (it is a: " + strEx::itos(drvType) + ")";
187                        return NSCAPI::returnUNKNOWN;
188                } else if ((bFilter)&&(!bFilterCDROM)&&(drvType==DRIVE_CDROM)) {
189                        message = "UNKNOWN: Drive does not match the current filter: " + drive.drive_ + " (it is a: " + strEx::itos(drvType) + ")";
190                        return NSCAPI::returnUNKNOWN;
191                } else if ((bFilter)&&(!bFilterRemote)&&(drvType==DRIVE_REMOTE)) {
192                        message = "UNKNOWN: Drive does not match the current filter: " + drive.drive_ + " (it is a: " + strEx::itos(drvType) + ")";
193                        return NSCAPI::returnUNKNOWN;
194                } else if ((bFilter)&&(!bFilterRemovable)&&(drvType==DRIVE_REMOVABLE)) {
195                        message = "UNKNOWN: Drive does not match the current filter: " + drive.drive_ + " (it is a: " + strEx::itos(drvType) + ")";
196                        return NSCAPI::returnUNKNOWN;
197                }
198
199                ULARGE_INTEGER freeBytesAvailableToCaller;
200                ULARGE_INTEGER totalNumberOfBytes;
201                ULARGE_INTEGER totalNumberOfFreeBytes;
202                if (!GetDiskFreeSpaceEx(drive.drive_.c_str(), &freeBytesAvailableToCaller, &totalNumberOfBytes, &totalNumberOfFreeBytes)) {
203                        message = "UNKNOWN: Could not get free space for: " + drive.drive_;
204                        return NSCAPI::returnUNKNOWN;
205                }
206                //10597515264&80015491072
207
208                if (bNSClient) {
209                        if (!message.empty())
210                                message += "&";
211                        message += strEx::itos(totalNumberOfFreeBytes.QuadPart);
212                        message += "&";
213                        message += strEx::itos(totalNumberOfBytes.QuadPart);
214                } else {
215                        std::string tStr;
216                        checkHolders::drive_size usedSpace = totalNumberOfBytes.QuadPart-totalNumberOfFreeBytes.QuadPart;
217                        checkHolders::drive_size totalSpace = totalNumberOfBytes.QuadPart;
218                        if (drive.crit_.max.hasBounds() && drive.crit_.max.checkMAX(usedSpace, totalSpace)) {
219                                tStr += drive.crit_.max.prettyPrint(drive.drive_, usedSpace, totalSpace) + " > critical";
220                                NSCHelper::escalteReturnCodeToCRIT(returnCode);
221                        } else if (drive.crit_.min.hasBounds() && drive.crit_.min.checkMIN(usedSpace, totalSpace)) {
222                                tStr = drive.crit_.min.prettyPrint(drive.drive_, usedSpace, totalSpace) + " < critical";
223                                NSCHelper::escalteReturnCodeToCRIT(returnCode);
224                        } else if (drive.warn_.max.hasBounds() && drive.warn_.max.checkMAX(usedSpace, totalSpace)) {
225                                tStr = drive.warn_.max.prettyPrint(drive.drive_, usedSpace, totalSpace) + " > warning";
226                                NSCHelper::escalteReturnCodeToWARN(returnCode);
227                        } else if (drive.warn_.min.hasBounds() && drive.warn_.min.checkMIN(usedSpace, totalSpace)) {
228                                tStr = drive.warn_.min.prettyPrint(drive.drive_, usedSpace, totalSpace) + " < warning";
229                                NSCHelper::escalteReturnCodeToWARN(returnCode);
230                        } else if (bShowAll) {
231                                tStr = drive.drive_ + ": " + strEx::itos_as_BKMG(usedSpace);
232                        }
233                        perf += checkHolders::SizeMaxMinPercentage<>::printPerf(drive.drive_, usedSpace, totalSpace, drive.warn_, drive.crit_);
234                        if (!message.empty() && !tStr.empty())
235                                message += ", ";
236                        if (!tStr.empty())
237                                message += tStr;
238                }
239        }
240        if (message.empty())
241                message = "All drive sizes are within bounds.";
242        else if (!bNSClient)
243                message = NSCHelper::translateReturn(returnCode) + ": " + message;
244        return returnCode;
245}
246
247struct PathConatiner {
248        checkHolders::SizeMaxMin<> warn_;
249        checkHolders::SizeMaxMin<> crit_;
250        std::string drive_;
251        std::string alias_;
252        PathConatiner(std::string drive, checkHolders::SizeMaxMin<> warn, checkHolders::SizeMaxMin<> crit)
253                : drive_(drive), warn_(warn), crit_(crit)
254        {}
255        PathConatiner(std::string drive, std::string alias, checkHolders::SizeMaxMin<> warn, checkHolders::SizeMaxMin<> crit)
256                : drive_(drive), alias_(alias), warn_(warn), crit_(crit)
257        {}
258        std::string getPath() {
259                return drive_;
260        }
261        std::string getName() {
262                if (alias_.empty())
263                        return drive_;
264                return alias_;
265        }
266};
267
268NSCAPI::nagiosReturn CheckDisk::CheckFileSize(const unsigned int argLen, char **char_args, std::string &message, std::string &perf) {
269        NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK;
270        std::list<std::string> args = arrayBuffer::arrayBuffer2list(argLen, char_args);
271        if (args.empty()) {
272                message = "Missing argument(s).";
273                return NSCAPI::returnCRIT;
274        }
275        checkHolders::SizeMaxMin<> crit;
276        checkHolders::SizeMaxMin<> warn;
277        bool bShowAll = false;
278        std::list<PathConatiner> paths;
279
280        std::list<std::string>::const_iterator cit;
281        for (cit=args.begin();cit!=args.end();++cit) {
282                std::string arg = *cit;
283                std::pair<std::string,std::string> p = strEx::split(arg,"=");
284                if (p.first == "File") {
285                        paths.push_back(PathConatiner(p.second, warn, crit));
286                } else if (p.first == "MaxWarn") {
287                        warn.max.set(p.second);
288                } else if (p.first == "MinWarn") {
289                        warn.min.set(p.second);
290                } else if (p.first == "MaxCrit") {
291                        crit.max.set(p.second);
292                } else if (p.first == "MinCrit") {
293                        crit.min.set(p.second);
294                } else if (p.first == SHOW_ALL) {
295                        bShowAll = true;
296                } else if (p.first.find(":") != std::string::npos) {
297                        std::pair<std::string,std::string> p2 = strEx::split(p.first,":");
298                        if (p2.first == "File") {
299                                paths.push_back(PathConatiner(p.second, p2.second, warn, crit));
300                        } else {
301                                message = "Unknown command: " + p.first;
302                                return NSCAPI::returnCRIT;
303                        }
304                } else {
305                        message = "Unknown command: " + p.first;
306                        return NSCAPI::returnCRIT;
307                }
308        }
309
310        std::list<PathConatiner>::const_iterator pit;
311        for (pit = paths.begin(); pit != paths.end(); ++pit) {
312                PathConatiner path = (*pit);
313                std::string tstr;
314                GetSize sizeFinder;
315                std::string sName = path.getName();
316                RecursiveScanDirectory(path.getPath(), sizeFinder);
317
318                if (path.crit_.max.hasBounds() && path.crit_.max.checkMAX(sizeFinder.getSize())) {
319                        tstr += path.crit_.max.prettyPrint(sName, sizeFinder.getSize()) + " > critical";
320                        NSCHelper::escalteReturnCodeToCRIT(returnCode);
321                } else if (path.crit_.min.hasBounds() && path.crit_.min.checkMIN(sizeFinder.getSize())) {
322                        tstr += path.crit_.min.prettyPrint(sName, sizeFinder.getSize()) + " < critical";
323                        NSCHelper::escalteReturnCodeToCRIT(returnCode);
324                } else if (path.warn_.max.hasBounds() && path.warn_.max.checkMAX(sizeFinder.getSize())) {
325                        tstr += path.warn_.max.prettyPrint(sName, sizeFinder.getSize()) + " > warning";
326                        NSCHelper::escalteReturnCodeToWARN(returnCode);
327                } else if (path.warn_.min.hasBounds() && path.warn_.min.checkMIN(sizeFinder.getSize())) {
328                        tstr += path.warn_.min.prettyPrint(sName, sizeFinder.getSize()) + " < warning";
329                        NSCHelper::escalteReturnCodeToWARN(returnCode);
330                } else if (bShowAll) {
331                        tstr = sName +  ": " + strEx::itos_as_BKMG(sizeFinder.getSize());
332                }
333                perf += checkHolders::SizeMaxMin<>::printPerf(sName, sizeFinder.getSize(), path.warn_, path.crit_);
334                if (!message.empty() && !tstr.empty())
335                        message += ", ";
336                if (!tstr.empty())
337                        message = tstr;
338        }
339        if (message.empty())
340                message = "OK all file sizes are within bounds.";
341        else
342                message = NSCHelper::translateReturn(returnCode) + ": " + message;
343        return returnCode;
344}
345
346NSCAPI::nagiosReturn CheckDisk::handleCommand(const strEx::blindstr command, const unsigned int argLen, char **char_args, std::string &msg, std::string &perf) {
347        if (command == "CheckFileSize") {
348                return CheckFileSize(argLen, char_args, msg, perf);
349        } else if (command == "CheckDriveSize") {
350                return CheckDriveSize(argLen, char_args, msg, perf);
351
352//      } else if (command == "CheckFileDate") {
353        }       
354        return NSCAPI::returnIgnored;
355}
356
357
358NSC_WRAPPERS_MAIN_DEF(gCheckDisk);
359NSC_WRAPPERS_IGNORE_MSG_DEF();
360NSC_WRAPPERS_HANDLE_CMD_DEF(gCheckDisk);
Note: See TracBrowser for help on using the repository browser.