|
@@ -1,4 +1,4 @@
|
|
|
-/* Copyright (c) 2013-2015 the Civetweb developers
|
|
|
+/* Copyright (c) 2013-2016 the Civetweb developers
|
|
|
* Copyright (c) 2004-2013 Sergey Lyubka
|
|
|
*
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
@@ -512,7 +512,7 @@ read_config_file(const char *config_file, char **options)
|
|
|
|
|
|
|
|
|
static void
|
|
|
-process_command_line_arguments(char *argv[], char **options)
|
|
|
+process_command_line_arguments(int argc, char *argv[], char **options)
|
|
|
{
|
|
|
char *p;
|
|
|
size_t i, cmd_line_opts_start = 1;
|
|
@@ -521,21 +521,24 @@ process_command_line_arguments(char *argv[], char **options)
|
|
|
#endif
|
|
|
|
|
|
/* Should we use a config file ? */
|
|
|
- if (argv[1] != NULL && argv[1][0] != '-') {
|
|
|
- /* A config file was set */
|
|
|
+ if ((argc > 1) && (argv[1] != NULL) && (argv[1][0] != '-')
|
|
|
+ && (argv[1][0] != 0)) {
|
|
|
+ /* The first command line parameter is a config file name. */
|
|
|
snprintf(g_config_file_name,
|
|
|
sizeof(g_config_file_name) - 1,
|
|
|
"%s",
|
|
|
argv[1]);
|
|
|
cmd_line_opts_start = 2;
|
|
|
} else if ((p = strrchr(argv[0], DIRSEP)) == NULL) {
|
|
|
- /* No config file set. Use default file name in the current path. */
|
|
|
+ /* No config file set. No path in arg[0] found.
|
|
|
+ * Use default file name in the current path. */
|
|
|
snprintf(g_config_file_name,
|
|
|
sizeof(g_config_file_name) - 1,
|
|
|
"%s",
|
|
|
CONFIG_FILE);
|
|
|
} else {
|
|
|
- /* No config file set. Use default file name next to the executable. */
|
|
|
+ /* No config file set. Path to exe found in arg[0].
|
|
|
+ * Use default file name next to the executable. */
|
|
|
snprintf(g_config_file_name,
|
|
|
sizeof(g_config_file_name) - 1,
|
|
|
"%.*s%c%s",
|
|
@@ -838,7 +841,9 @@ start_civetweb(int argc, char *argv[])
|
|
|
char *options[2 * MAX_OPTIONS + 1];
|
|
|
int i;
|
|
|
|
|
|
- /* Show system information and exit */
|
|
|
+ /* Start option -I:
|
|
|
+ * Show system information and exit
|
|
|
+ * This is very useful for diagnosis. */
|
|
|
if (argc > 1 && !strcmp(argv[1], "-I")) {
|
|
|
const char *version = mg_version();
|
|
|
#if defined(_WIN32)
|
|
@@ -1052,7 +1057,7 @@ start_civetweb(int argc, char *argv[])
|
|
|
set_option(options, "document_root", ".");
|
|
|
|
|
|
/* Update config based on command line arguments */
|
|
|
- process_command_line_arguments(argv, options);
|
|
|
+ process_command_line_arguments(argc, argv, options);
|
|
|
|
|
|
/* Make sure we have absolute paths for files and directories */
|
|
|
set_absolute_path(options, "document_root", argv[0]);
|
|
@@ -1087,14 +1092,19 @@ start_civetweb(int argc, char *argv[])
|
|
|
memset(&callbacks, 0, sizeof(callbacks));
|
|
|
callbacks.log_message = &log_message;
|
|
|
g_ctx = mg_start(&callbacks, &g_user_data, (const char **)options);
|
|
|
+
|
|
|
+ /* mg_start copies all options to an internal buffer.
|
|
|
+ * The options data field here is not required anymore. */
|
|
|
for (i = 0; options[i] != NULL; i++) {
|
|
|
free(options[i]);
|
|
|
}
|
|
|
|
|
|
+ /* If mg_start fails, it returns NULL */
|
|
|
if (g_ctx == NULL) {
|
|
|
- die("Failed to start Civetweb:\n%s",
|
|
|
- (g_user_data.first_message == NULL) ? "unknown reason"
|
|
|
- : g_user_data.first_message);
|
|
|
+ die("Failed to start %s:\n%s",
|
|
|
+ g_server_name,
|
|
|
+ ((g_user_data.first_message == NULL) ? "unknown reason"
|
|
|
+ : g_user_data.first_message));
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1109,6 +1119,9 @@ stop_civetweb(void)
|
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
+/* Win32 has a small GUI.
|
|
|
+ * Define some GUI elements and Windows message handlers. */
|
|
|
+
|
|
|
enum {
|
|
|
ID_ICON = 100,
|
|
|
ID_QUIT,
|
|
@@ -1140,6 +1153,7 @@ enum {
|
|
|
ID_FILE_BUTTONS_DELTA = 1000
|
|
|
};
|
|
|
|
|
|
+
|
|
|
static HICON hIcon;
|
|
|
static SERVICE_STATUS ss;
|
|
|
static SERVICE_STATUS_HANDLE hStatus;
|
|
@@ -1247,6 +1261,7 @@ SettingsDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
|
(void)lParam;
|
|
|
|
|
|
switch (msg) {
|
|
|
+
|
|
|
case WM_CLOSE:
|
|
|
DestroyWindow(hDlg);
|
|
|
break;
|
|
@@ -2147,7 +2162,7 @@ manage_service(int action)
|
|
|
char path[PATH_MAX + 20] = ""; /* Path to executable plus magic argument */
|
|
|
int success = 1;
|
|
|
|
|
|
- descr.lpDescription = g_server_name;
|
|
|
+ descr.lpDescription = (LPSTR)g_server_name;
|
|
|
|
|
|
if ((hSCM = OpenSCManager(NULL,
|
|
|
NULL,
|
|
@@ -2213,10 +2228,11 @@ WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
|
service_argv[1] = NULL;
|
|
|
|
|
|
memset(service_table, 0, sizeof(service_table));
|
|
|
- service_table[0].lpServiceName = g_server_name;
|
|
|
+ service_table[0].lpServiceName = (LPSTR)g_server_name;
|
|
|
service_table[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
|
|
|
|
|
|
switch (msg) {
|
|
|
+
|
|
|
case WM_CREATE:
|
|
|
if (__argv[1] != NULL && !strcmp(__argv[1], service_magic_argument)) {
|
|
|
start_civetweb(1, service_argv);
|
|
@@ -2227,6 +2243,7 @@ WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
|
s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
|
|
|
}
|
|
|
break;
|
|
|
+
|
|
|
case WM_COMMAND:
|
|
|
switch (LOWORD(wParam)) {
|
|
|
case ID_QUIT:
|
|
@@ -2256,6 +2273,7 @@ WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
|
break;
|
|
|
}
|
|
|
break;
|
|
|
+
|
|
|
case WM_USER:
|
|
|
switch (lParam) {
|
|
|
case WM_RBUTTONUP:
|
|
@@ -2296,12 +2314,14 @@ WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
|
break;
|
|
|
}
|
|
|
break;
|
|
|
+
|
|
|
case WM_CLOSE:
|
|
|
stop_civetweb();
|
|
|
Shell_NotifyIcon(NIM_DELETE, &TrayIcon);
|
|
|
g_exit_flag = 1;
|
|
|
PostQuitMessage(0);
|
|
|
return 0; /* We've just sent our own quit message, with proper hwnd. */
|
|
|
+
|
|
|
default:
|
|
|
if (msg == s_uTaskbarRestart)
|
|
|
Shell_NotifyIcon(NIM_ADD, &TrayIcon);
|