main.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. #define UNICODE
  3. #define _UNICODE
  4. #include <windows.h>
  5. #include <shellapi.h>
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <signal.h>
  10. #include "main.h"
  11. LPWSTR token = NULL;
  12. LPWSTR room = NULL;
  13. LPWSTR proxy = NULL;
  14. LPWSTR *argv = NULL;
  15. char *aToken = NULL;
  16. char *aRoom = NULL;
  17. char *aProxy = NULL;
  18. int insecure = 0;
  19. LPWSTR netdata_claim_get_formatted_message(LPWSTR pMessage, ...)
  20. {
  21. LPWSTR pBuffer = NULL;
  22. va_list args = NULL;
  23. va_start(args, pMessage);
  24. FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, pMessage, 0, 0, (LPWSTR)&pBuffer,
  25. 0, &args);
  26. va_end(args);
  27. return pBuffer;
  28. }
  29. // Common Functions
  30. void netdata_claim_error_exit(wchar_t *function)
  31. {
  32. DWORD error = GetLastError();
  33. LPWSTR pMessage = L"The function %1 failed with error %2.";
  34. LPWSTR pBuffer = netdata_claim_get_formatted_message(pMessage, function, error);
  35. if (pBuffer) {
  36. MessageBoxW(NULL, pBuffer, L"Error", MB_OK|MB_ICONERROR);
  37. LocalFree(pBuffer);
  38. }
  39. ExitProcess(error);
  40. }
  41. /**
  42. * Parse Args
  43. *
  44. * Parse arguments identifying necessity to make a window
  45. *
  46. * @param argc number of arguments
  47. * @param argv A pointer for all arguments given
  48. *
  49. * @return it return the number of arguments parsed.
  50. */
  51. int nd_claim_parse_args(int argc, LPWSTR *argv)
  52. {
  53. int i;
  54. for (i = 1 ; i < argc; i++) {
  55. // We are working with Microsoft, thus it does not make sense wait for only smallcase
  56. if(wcscasecmp(L"/T", argv[i]) == 0) {
  57. if (argc <= i + 1)
  58. continue;
  59. i++;
  60. token = argv[i];
  61. }
  62. if(wcscasecmp(L"/R", argv[i]) == 0) {
  63. if (argc <= i + 1)
  64. continue;
  65. i++;
  66. room = argv[i];
  67. }
  68. if(wcscasecmp(L"/P", argv[i]) == 0) {
  69. if (argc <= i + 1)
  70. continue;
  71. i++;
  72. // Minimum IPV4
  73. if(wcslen(argv[i]) >= 8) {
  74. proxy = argv[i];
  75. }
  76. }
  77. if(wcscasecmp(L"/I", argv[i]) == 0) {
  78. if (argc <= i + 1)
  79. continue;
  80. i++;
  81. size_t length = wcslen(argv[i]);
  82. char *tmp = calloc(sizeof(char), length);
  83. if (!tmp)
  84. ExitProcess(1);
  85. netdata_claim_convert_str(tmp, argv[i], length - 1);
  86. if (i < argc)
  87. insecure = atoi(tmp);
  88. else
  89. insecure = 1;
  90. free(tmp);
  91. }
  92. }
  93. if (!token || !room)
  94. return 0;
  95. return argc;
  96. }
  97. static int netdata_claim_prepare_strings()
  98. {
  99. if (!token || !room)
  100. return -1;
  101. size_t length = wcslen(token) + 1;
  102. aToken = calloc(sizeof(char), length);
  103. if (!aToken)
  104. return -1;
  105. netdata_claim_convert_str(aToken, token, length - 1);
  106. length = wcslen(room) + 1;
  107. aRoom = calloc(sizeof(char), length - 1);
  108. if (!aRoom)
  109. return -1;
  110. netdata_claim_convert_str(aRoom, room, length - 1);
  111. if (proxy) {
  112. length = wcslen(proxy) + 1;
  113. aProxy = calloc(sizeof(char), length - 1);
  114. if (!aProxy)
  115. return -1;
  116. netdata_claim_convert_str(aProxy, proxy, length - 1);
  117. }
  118. return 0;
  119. }
  120. static void netdata_claim_exit_callback(int signal)
  121. {
  122. (void)signal;
  123. if (aToken)
  124. free(aToken);
  125. if (aRoom)
  126. free(aRoom);
  127. if (aProxy)
  128. free(aProxy);
  129. if (argv)
  130. LocalFree(argv);
  131. }
  132. static inline int netdata_claim_prepare_data(char *out, size_t length)
  133. {
  134. char *proxyLabel = (aProxy) ? "proxy = " : "# proxy = ";
  135. char *proxyValue = (aProxy) ? aProxy : "";
  136. return snprintf(out,
  137. length,
  138. "[global]\n url = https://app.netdata.cloud\n token = %s\n rooms = %s\n %s%s\n insecure = %s",
  139. aToken,
  140. aRoom,
  141. proxyLabel,
  142. proxyValue,
  143. (insecure) ? "YES" : "NO"
  144. );
  145. }
  146. static int netdata_claim_get_path(char *path)
  147. {
  148. char *usrPath = { "\\usr\\bin" };
  149. DWORD length = GetCurrentDirectoryA(WINDOWS_MAX_PATH, path);
  150. if (!length) {
  151. return -1;
  152. }
  153. if (strstr(path, usrPath)) {
  154. length -= 7;
  155. path[length] = '\0';
  156. }
  157. return 0;
  158. }
  159. static void netdata_claim_write_config(char *path)
  160. {
  161. char configPath[WINDOWS_MAX_PATH + 1];
  162. char data[WINDOWS_MAX_PATH + 1];
  163. snprintf(configPath, WINDOWS_MAX_PATH - 1, "%s\\etc\\netdata\\claim.conf", path);
  164. HANDLE hf = CreateFileA(configPath, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  165. if (hf == INVALID_HANDLE_VALUE)
  166. netdata_claim_error_exit(L"CreateFileA");
  167. DWORD length = netdata_claim_prepare_data(data, WINDOWS_MAX_PATH);
  168. DWORD written = 0;
  169. BOOL ret = WriteFile(hf, data, length, &written, NULL);
  170. if (!ret) {
  171. CloseHandle(hf);
  172. netdata_claim_error_exit(L"WriteFileA");
  173. }
  174. if (length != written)
  175. MessageBoxW(NULL, L"Cannot write claim.conf.", L"Error", MB_OK|MB_ICONERROR);
  176. CloseHandle(hf);
  177. }
  178. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  179. {
  180. signal(SIGABRT, netdata_claim_exit_callback);
  181. signal(SIGINT, netdata_claim_exit_callback);
  182. signal(SIGTERM, netdata_claim_exit_callback);
  183. int argc;
  184. LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc);
  185. if (argc)
  186. argc = nd_claim_parse_args(argc, argv);
  187. // When no data is given, user must to use graphic mode
  188. int ret = 0;
  189. if (!argc) {
  190. ret = netdata_claim_window_loop(hInstance, nCmdShow);
  191. } else {
  192. if (netdata_claim_prepare_strings()) {
  193. goto exit_claim;
  194. }
  195. char basePath[WINDOWS_MAX_PATH];
  196. if (!netdata_claim_get_path(basePath)) {
  197. netdata_claim_write_config(basePath);
  198. }
  199. }
  200. exit_claim:
  201. netdata_claim_exit_callback(0);
  202. return ret;
  203. }