|
@@ -0,0 +1,250 @@
|
|
|
+// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
+
|
|
|
+#define UNICODE
|
|
|
+#define _UNICODE
|
|
|
+#include <windows.h>
|
|
|
+#include <shellapi.h>
|
|
|
+#include <stdlib.h>
|
|
|
+#include <stdio.h>
|
|
|
+#include <string.h>
|
|
|
+#include <signal.h>
|
|
|
+
|
|
|
+#include "netdata_claim.h"
|
|
|
+
|
|
|
+LPWSTR token = NULL;
|
|
|
+LPWSTR room = NULL;
|
|
|
+LPWSTR proxy = NULL;
|
|
|
+LPWSTR *argv = NULL;
|
|
|
+
|
|
|
+char *aToken = NULL;
|
|
|
+char *aRoom = NULL;
|
|
|
+char *aProxy = NULL;
|
|
|
+int insecure = 0;
|
|
|
+
|
|
|
+LPWSTR netdata_claim_get_formatted_message(LPWSTR pMessage, ...)
|
|
|
+{
|
|
|
+ LPWSTR pBuffer = NULL;
|
|
|
+
|
|
|
+ va_list args = NULL;
|
|
|
+ va_start(args, pMessage);
|
|
|
+
|
|
|
+ FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, pMessage, 0, 0, (LPWSTR)&pBuffer,
|
|
|
+ 0, &args);
|
|
|
+ va_end(args);
|
|
|
+
|
|
|
+ return pBuffer;
|
|
|
+}
|
|
|
+
|
|
|
+// Common Functions
|
|
|
+void netdata_claim_error_exit(wchar_t *function)
|
|
|
+{
|
|
|
+ DWORD error = GetLastError();
|
|
|
+ LPWSTR pMessage = L"The function %1 failed with error %2.";
|
|
|
+ LPWSTR pBuffer = netdata_claim_get_formatted_message(pMessage, function, error);
|
|
|
+
|
|
|
+ if (pBuffer) {
|
|
|
+ MessageBoxW(NULL, pBuffer, L"Error", MB_OK|MB_ICONERROR);
|
|
|
+ LocalFree(pBuffer);
|
|
|
+ }
|
|
|
+
|
|
|
+ ExitProcess(error);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Parse Args
|
|
|
+ *
|
|
|
+ * Parse arguments identifying necessity to make a window
|
|
|
+ *
|
|
|
+ * @param argc number of arguments
|
|
|
+ * @param argv A pointer for all arguments given
|
|
|
+ *
|
|
|
+ * @return it return the number of arguments parsed.
|
|
|
+ */
|
|
|
+int nd_claim_parse_args(int argc, LPWSTR *argv)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+ for (i = 1 ; i < argc; i++) {
|
|
|
+ // We are working with Microsoft, thus it does not make sense wait for only smallcase
|
|
|
+ if(wcscasecmp(L"/T", argv[i]) == 0) {
|
|
|
+ if (argc <= i + 1)
|
|
|
+ continue;
|
|
|
+ i++;
|
|
|
+ token = argv[i];
|
|
|
+ }
|
|
|
+
|
|
|
+ if(wcscasecmp(L"/R", argv[i]) == 0) {
|
|
|
+ if (argc <= i + 1)
|
|
|
+ continue;
|
|
|
+ i++;
|
|
|
+ room = argv[i];
|
|
|
+ }
|
|
|
+
|
|
|
+ if(wcscasecmp(L"/P", argv[i]) == 0) {
|
|
|
+ if (argc <= i + 1)
|
|
|
+ continue;
|
|
|
+ i++;
|
|
|
+ // Minimum IPV4
|
|
|
+ if(wcslen(argv[i]) >= 8) {
|
|
|
+ proxy = argv[i];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(wcscasecmp(L"/I", argv[i]) == 0) {
|
|
|
+ if (argc <= i + 1)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ i++;
|
|
|
+ size_t length = wcslen(argv[i]);
|
|
|
+ char *tmp = calloc(sizeof(char), length);
|
|
|
+ if (!tmp)
|
|
|
+ ExitProcess(1);
|
|
|
+
|
|
|
+ netdata_claim_convert_str(tmp, argv[i], length - 1);
|
|
|
+ if (i < argc)
|
|
|
+ insecure = atoi(tmp);
|
|
|
+ else
|
|
|
+ insecure = 1;
|
|
|
+
|
|
|
+ free(tmp);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!token || !room)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ return argc;
|
|
|
+}
|
|
|
+
|
|
|
+static int netdata_claim_prepare_strings()
|
|
|
+{
|
|
|
+ if (!token || !room)
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ size_t length = wcslen(token) + 1;
|
|
|
+ aToken = calloc(sizeof(char), length);
|
|
|
+ if (!aToken)
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ netdata_claim_convert_str(aToken, token, length - 1);
|
|
|
+
|
|
|
+ length = wcslen(room) + 1;
|
|
|
+ aRoom = calloc(sizeof(char), length - 1);
|
|
|
+ if (!aRoom)
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ netdata_claim_convert_str(aRoom, room, length - 1);
|
|
|
+
|
|
|
+ if (proxy) {
|
|
|
+ length = wcslen(proxy) + 1;
|
|
|
+ aProxy = calloc(sizeof(char), length - 1);
|
|
|
+ if (!aProxy)
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ netdata_claim_convert_str(aProxy, proxy, length - 1);
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static void netdata_claim_exit_callback(int signal)
|
|
|
+{
|
|
|
+ (void)signal;
|
|
|
+ if (aToken)
|
|
|
+ free(aToken);
|
|
|
+
|
|
|
+ if (aRoom)
|
|
|
+ free(aRoom);
|
|
|
+
|
|
|
+ if (aProxy)
|
|
|
+ free(aProxy);
|
|
|
+
|
|
|
+ if (argv)
|
|
|
+ LocalFree(argv);
|
|
|
+}
|
|
|
+
|
|
|
+static inline int netdata_claim_prepare_data(char *out, size_t length)
|
|
|
+{
|
|
|
+ char *proxyLabel = (aProxy) ? "proxy = " : "# proxy = ";
|
|
|
+ char *proxyValue = (aProxy) ? aProxy : "";
|
|
|
+ return snprintf(out,
|
|
|
+ length,
|
|
|
+ "[global]\n url = https://app.netdata.cloud\n token = %s\n rooms = %s\n %s%s\n insecure = %s",
|
|
|
+ aToken,
|
|
|
+ aRoom,
|
|
|
+ proxyLabel,
|
|
|
+ proxyValue,
|
|
|
+ (insecure) ? "YES" : "NO"
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+static int netdata_claim_get_path(char *path)
|
|
|
+{
|
|
|
+ char *usrPath = { "\\usr\\bin" };
|
|
|
+ DWORD length = GetCurrentDirectoryA(WINDOWS_MAX_PATH, path);
|
|
|
+ if (!length) {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (strstr(path, usrPath)) {
|
|
|
+ length -= 7;
|
|
|
+ path[length] = '\0';
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static void netdata_claim_write_config(char *path)
|
|
|
+{
|
|
|
+ char configPath[WINDOWS_MAX_PATH + 1];
|
|
|
+ char data[WINDOWS_MAX_PATH + 1];
|
|
|
+ snprintf(configPath, WINDOWS_MAX_PATH - 1, "%s\\etc\\netdata\\claim.conf", path);
|
|
|
+
|
|
|
+ HANDLE hf = CreateFileA(configPath, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
+ if (hf == INVALID_HANDLE_VALUE)
|
|
|
+ netdata_claim_error_exit(L"CreateFileA");
|
|
|
+
|
|
|
+ DWORD length = netdata_claim_prepare_data(data, WINDOWS_MAX_PATH);
|
|
|
+ DWORD written = 0;
|
|
|
+
|
|
|
+ BOOL ret = WriteFile(hf, data, length, &written, NULL);
|
|
|
+ if (!ret) {
|
|
|
+ CloseHandle(hf);
|
|
|
+ netdata_claim_error_exit(L"WriteFileA");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (length != written)
|
|
|
+ MessageBoxW(NULL, L"Cannot write claim.conf.", L"Error", MB_OK|MB_ICONERROR);
|
|
|
+
|
|
|
+ CloseHandle(hf);
|
|
|
+}
|
|
|
+
|
|
|
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
|
|
+{
|
|
|
+ signal(SIGABRT, netdata_claim_exit_callback);
|
|
|
+ signal(SIGINT, netdata_claim_exit_callback);
|
|
|
+ signal(SIGTERM, netdata_claim_exit_callback);
|
|
|
+
|
|
|
+ int argc;
|
|
|
+ LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
|
|
+ if (argc)
|
|
|
+ argc = nd_claim_parse_args(argc, argv);
|
|
|
+
|
|
|
+ // When no data is given, user must to use graphic mode
|
|
|
+ int ret = 0;
|
|
|
+ if (!argc) {
|
|
|
+ ret = netdata_claim_window_loop(hInstance, nCmdShow);
|
|
|
+ } else {
|
|
|
+ if (netdata_claim_prepare_strings()) {
|
|
|
+ goto exit_claim;
|
|
|
+ }
|
|
|
+
|
|
|
+ char basePath[WINDOWS_MAX_PATH];
|
|
|
+ if (!netdata_claim_get_path(basePath)) {
|
|
|
+ netdata_claim_write_config(basePath);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+exit_claim:
|
|
|
+ netdata_claim_exit_callback(0);
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|