master
c 305 lines 7.16 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #define UNICODE
4 #define _UNICODE
5 #include <windows.h>
6 #include <shellapi.h>
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <string.h>
10 #include <signal.h>
11
12 #include "main.h"
13
14 LPWSTR token = NULL;
15 LPWSTR room = NULL;
16 LPWSTR proxy = NULL;
17 LPWSTR url = NULL;
18 LPWSTR extPath = NULL;
19 LPWSTR *argv = NULL;
20
21 char *aToken = NULL;
22 char *aRoom = NULL;
23 char *aProxy = NULL;
24 char *aURL = NULL;
25 int insecure = 0;
26
27 LPWSTR netdata_claim_get_formatted_message(LPWSTR pMessage, ...)
28 {
29 LPWSTR pBuffer = NULL;
30
31 va_list args = NULL;
32 va_start(args, pMessage);
33
34 FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, pMessage, 0, 0, (LPWSTR)&pBuffer,
35 0, &args);
36 va_end(args);
37
38 return pBuffer;
39 }
40
41 // Common Functions
42 void netdata_claim_error_exit(wchar_t *function)
43 {
44 DWORD error = GetLastError();
45 LPWSTR pMessage = L"The function %1 failed with error %2.";
46 LPWSTR pBuffer = netdata_claim_get_formatted_message(pMessage, function, error);
47
48 if (pBuffer) {
49 MessageBoxW(NULL, pBuffer, L"Error", MB_OK|MB_ICONERROR);
50 LocalFree(pBuffer);
51 }
52
53 ExitProcess(error);
54 }
55
56 /**
57 * Parse Args
58 *
59 * Parse arguments identifying necessity to make a window
60 *
61 * @param argc number of arguments
62 * @param argv A pointer for all arguments given
63 *
64 * @return it return the number of arguments parsed.
65 */
66 int nd_claim_parse_args(int argc, LPWSTR *argv)
67 {
68 int i;
69 for (i = 1 ; i < argc; i++) {
70 // We are working with Microsoft, thus it does not make sense wait for only smallcase
71 if(wcscasecmp(L"/T", argv[i]) == 0) {
72 if (argc <= i + 1)
73 continue;
74 i++;
75 token = argv[i];
76 }
77
78 if(wcscasecmp(L"/R", argv[i]) == 0) {
79 if (argc <= i + 1)
80 continue;
81 i++;
82 room = argv[i];
83 }
84
85 if(wcscasecmp(L"/P", argv[i]) == 0) {
86 if (argc <= i + 1)
87 continue;
88 i++;
89 // Minimum IPV4
90 if(wcslen(argv[i]) >= 8) {
91 proxy = argv[i];
92 }
93 }
94
95 if(wcscasecmp(L"/F", argv[i]) == 0) {
96 if (argc <= i + 1)
97 continue;
98 i++;
99 extPath = argv[i];
100 }
101
102 if(wcscasecmp(L"/U", argv[i]) == 0) {
103 if (argc <= i + 1)
104 continue;
105 i++;
106 url = argv[i];
107 }
108
109 if(wcscasecmp(L"/I", argv[i]) == 0) {
110 if (argc <= i + 1)
111 continue;
112
113 i++;
114 size_t length = wcslen(argv[i]);
115 char *tmp = calloc(sizeof(char), length);
116 if (!tmp)
117 ExitProcess(1);
118
119 netdata_claim_convert_str(tmp, argv[i], length - 1);
120 if (i < argc)
121 insecure = atoi(tmp);
122 else
123 insecure = 1;
124
125 free(tmp);
126 }
127 }
128
129 if (!token || !room)
130 return 0;
131
132 return argc;
133 }
134
135 static int netdata_claim_prepare_strings()
136 {
137 if (!token || !room)
138 return -1;
139
140 size_t length = wcslen(token) + 1;
141 aToken = calloc(sizeof(char), length);
142 if (!aToken)
143 return -1;
144
145 netdata_claim_convert_str(aToken, token, length - 1);
146
147 length = wcslen(room) + 1;
148 aRoom = calloc(sizeof(char), length - 1);
149 if (!aRoom)
150 return -1;
151
152 netdata_claim_convert_str(aRoom, room, length - 1);
153
154 if (proxy) {
155 length = wcslen(proxy) + 1;
156 aProxy = calloc(sizeof(char), length - 1);
157 if (!aProxy)
158 return -1;
159
160 netdata_claim_convert_str(aProxy, proxy, length - 1);
161 }
162
163 if (url) {
164 length = wcslen(url) + 1;
165 aURL = calloc(sizeof(char), length - 1);
166 if (!aURL)
167 return -1;
168
169 netdata_claim_convert_str(aURL, url, length - 1);
170 }
171 return 0;
172 }
173
174 static void netdata_claim_exit_callback(int signal)
175 {
176 (void)signal;
177 if (aToken)
178 free(aToken);
179
180 if (aRoom)
181 free(aRoom);
182
183 if (aProxy)
184 free(aProxy);
185
186 if (aURL)
187 free(aURL);
188
189 if (argv)
190 LocalFree(argv);
191
192 if (extPath)
193 LocalFree(extPath);
194 }
195
196 static inline int netdata_claim_prepare_data(char *out, size_t length)
197 {
198 char *proxyLabel = (aProxy) ? "proxy = " : "# proxy = ";
199 char *proxyValue = (aProxy) ? aProxy : "";
200
201 char *urlValue = (aURL) ? aURL : "https://app.netdata.cloud";
202 return snprintf(out,
203 length,
204 "[global]\n url = %s\n token = %s\n rooms = %s\n %s%s\n insecure = %s",
205 urlValue,
206 aToken,
207 aRoom,
208 proxyLabel,
209 proxyValue,
210 (insecure) ? "yes" : "no"
211 );
212 }
213
214 static int netdata_claim_get_path(char *path)
215 {
216 if (extPath) {
217 size_t length = wcslen(extPath) + 1;
218 if (length >= WINDOWS_MAX_PATH)
219 return -1;
220
221 netdata_claim_convert_str(path, extPath, length - 1);
222 return 0;
223 }
224
225 char *usrPath = { "\\usr\\bin" };
226 DWORD length = GetCurrentDirectoryA(WINDOWS_MAX_PATH, path);
227 if (!length) {
228 return -1;
229 }
230
231 if (strstr(path, usrPath)) {
232 length -= 7;
233 path[length] = '\0';
234 }
235
236 return 0;
237 }
238
239 static void netdata_claim_write_config(char *path)
240 {
241 #define NETDATA_MIN_CLOUD_LENGTH 135
242 #define NETDATA_MIN_ROOM_LENGTH 36
243 if (strlen(aToken) != NETDATA_MIN_CLOUD_LENGTH || strlen(aRoom) < NETDATA_MIN_ROOM_LENGTH)
244 return;
245
246 char configPath[WINDOWS_MAX_PATH + 1];
247 char data[WINDOWS_MAX_PATH + 1];
248 char *filename;
249 if (!extPath) {
250 snprintf(configPath, WINDOWS_MAX_PATH - 1, "%s\\etc\\netdata\\claim.conf", path);
251 filename = configPath;
252 } else {
253 filename = path;
254 }
255
256 HANDLE hf = CreateFileA(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
257 if (hf == INVALID_HANDLE_VALUE)
258 netdata_claim_error_exit(L"CreateFileA");
259
260 DWORD length = netdata_claim_prepare_data(data, WINDOWS_MAX_PATH);
261 DWORD written = 0;
262
263 BOOL ret = WriteFile(hf, data, length, &written, NULL);
264 if (!ret) {
265 CloseHandle(hf);
266 netdata_claim_error_exit(L"WriteFileA");
267 }
268
269 if (length != written)
270 MessageBoxW(NULL, L"Cannot write claim.conf.", L"Error", MB_OK|MB_ICONERROR);
271
272 CloseHandle(hf);
273 }
274
275 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
276 {
277 signal(SIGABRT, netdata_claim_exit_callback);
278 signal(SIGINT, netdata_claim_exit_callback);
279 signal(SIGTERM, netdata_claim_exit_callback);
280
281 int argc;
282 LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc);
283 if (argc)
284 argc = nd_claim_parse_args(argc, argv);
285
286 // When no data is given, user must to use graphic mode
287 int ret = 0;
288 if (!argc) {
289 ret = netdata_claim_window_loop(hInstance, nCmdShow);
290 } else {
291 if (netdata_claim_prepare_strings()) {
292 goto exit_claim;
293 }
294
295 char basePath[WINDOWS_MAX_PATH];
296 if (!netdata_claim_get_path(basePath)) {
297 netdata_claim_write_config(basePath);
298 }
299 }
300
301 exit_claim:
302 netdata_claim_exit_callback(0);
303
304 return ret;
305 }