1 /*
2 ** Zabbix
3 ** Copyright (C) 2001-2021 Zabbix SIA
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 **/
19
20 #include "common.h"
21 #include "sysinfo.h"
22 #include "zbxjson.h"
23
vfs_fs_size(AGENT_REQUEST * request,AGENT_RESULT * result)24 static int vfs_fs_size(AGENT_REQUEST *request, AGENT_RESULT *result)
25 {
26 char *path, *mode;
27 wchar_t *wpath;
28 ULARGE_INTEGER freeBytes, totalBytes;
29
30 if (2 < request->nparam)
31 {
32 SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
33 return SYSINFO_RET_FAIL;
34 }
35
36 path = get_rparam(request, 0);
37 mode = get_rparam(request, 1);
38
39 if (NULL == path || '\0' == *path)
40 {
41 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
42 return SYSINFO_RET_FAIL;
43 }
44
45 wpath = zbx_utf8_to_unicode(path);
46 if (0 == GetDiskFreeSpaceEx(wpath, &freeBytes, &totalBytes, NULL))
47 {
48 zbx_free(wpath);
49 SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain filesystem information."));
50 return SYSINFO_RET_FAIL;
51 }
52 zbx_free(wpath);
53
54 if (NULL == mode || '\0' == *mode || 0 == strcmp(mode, "total"))
55 SET_UI64_RESULT(result, totalBytes.QuadPart);
56 else if (0 == strcmp(mode, "free"))
57 SET_UI64_RESULT(result, freeBytes.QuadPart);
58 else if (0 == strcmp(mode, "used"))
59 SET_UI64_RESULT(result, totalBytes.QuadPart - freeBytes.QuadPart);
60 else if (0 == strcmp(mode, "pfree"))
61 SET_DBL_RESULT(result, (double)(__int64)freeBytes.QuadPart * 100. / (double)(__int64)totalBytes.QuadPart);
62 else if (0 == strcmp(mode, "pused"))
63 SET_DBL_RESULT(result, (double)((__int64)totalBytes.QuadPart - (__int64)freeBytes.QuadPart) * 100. /
64 (double)(__int64)totalBytes.QuadPart);
65 else
66 {
67 SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
68 return SYSINFO_RET_FAIL;
69 }
70
71 return SYSINFO_RET_OK;
72 }
73
VFS_FS_SIZE(AGENT_REQUEST * request,AGENT_RESULT * result)74 int VFS_FS_SIZE(AGENT_REQUEST *request, AGENT_RESULT *result)
75 {
76 return zbx_execute_threaded_metric(vfs_fs_size, request, result);
77 }
78
get_drive_type_string(UINT type)79 static const char *get_drive_type_string(UINT type)
80 {
81 switch (type)
82 {
83 case DRIVE_UNKNOWN:
84 return "unknown";
85 case DRIVE_NO_ROOT_DIR:
86 return "norootdir";
87 case DRIVE_REMOVABLE:
88 return "removable";
89 case DRIVE_FIXED:
90 return "fixed";
91 case DRIVE_REMOTE:
92 return "remote";
93 case DRIVE_CDROM:
94 return "cdrom";
95 case DRIVE_RAMDISK:
96 return "ramdisk";
97 default:
98 THIS_SHOULD_NEVER_HAPPEN;
99 return "unknown";
100 }
101 }
102
VFS_FS_DISCOVERY(AGENT_REQUEST * request,AGENT_RESULT * result)103 int VFS_FS_DISCOVERY(AGENT_REQUEST *request, AGENT_RESULT *result)
104 {
105 wchar_t fsName[MAX_PATH + 1];
106 wchar_t *buffer = NULL, *p;
107 char *utf8;
108 DWORD dwSize;
109 size_t sz;
110 struct zbx_json j;
111
112 /* Make an initial call to GetLogicalDriveStrings to
113 get the necessary size into the dwSize variable */
114 if (0 == (dwSize = GetLogicalDriveStrings(0, buffer)))
115 {
116 SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain necessary buffer size from system."));
117 return SYSINFO_RET_FAIL;
118 }
119
120 buffer = (wchar_t *)zbx_malloc(buffer, (dwSize + 1) * sizeof(wchar_t));
121
122 /* Make a second call to GetLogicalDriveStrings to get
123 the actual data we require */
124 if (0 == (dwSize = GetLogicalDriveStrings(dwSize, buffer)))
125 {
126 zbx_free(buffer);
127 SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain a list of filesystems."));
128 return SYSINFO_RET_FAIL;
129 }
130
131 zbx_json_init(&j, ZBX_JSON_STAT_BUF_LEN);
132
133 zbx_json_addarray(&j, ZBX_PROTO_TAG_DATA);
134
135 for (p = buffer, sz = wcslen(p); sz > 0; p += sz + 1, sz = wcslen(p))
136 {
137 zbx_json_addobject(&j, NULL);
138
139 utf8 = zbx_unicode_to_utf8(p);
140
141 /* remove trailing backslash */
142 if ('A' <= utf8[0] && utf8[0] <= 'Z' && ':' == utf8[1] && '\\' == utf8[2] && '\0' == utf8[3])
143 utf8[2] = '\0';
144
145 zbx_json_addstring(&j, "{#FSNAME}", utf8, ZBX_JSON_TYPE_STRING);
146 zbx_free(utf8);
147
148 if (TRUE == GetVolumeInformation(p, NULL, 0, NULL, NULL, NULL, fsName, ARRSIZE(fsName)))
149 {
150 utf8 = zbx_unicode_to_utf8(fsName);
151 zbx_json_addstring(&j, "{#FSTYPE}", utf8, ZBX_JSON_TYPE_STRING);
152 zbx_free(utf8);
153 }
154 else
155 zbx_json_addstring(&j, "{#FSTYPE}", "UNKNOWN", ZBX_JSON_TYPE_STRING);
156
157 zbx_json_addstring(&j, "{#FSDRIVETYPE}", get_drive_type_string(GetDriveType(p)), ZBX_JSON_TYPE_STRING);
158
159 zbx_json_close(&j);
160 }
161
162 zbx_free(buffer);
163
164 zbx_json_close(&j);
165
166 SET_STR_RESULT(result, zbx_strdup(NULL, j.buffer));
167
168 zbx_json_free(&j);
169
170 return SYSINFO_RET_OK;
171 }
172