-cp
- if(generate_keys)
- {
- read_server_config();
- exit(keygen(generate_keys));
- }
-
- if(kill_tincd)
- exit(kill_other(kill_tincd));
-
- if(read_server_config())
- exit(1);
-cp
- if(detach())
- exit(0);
-cp
- for(;;)
- {
- if(!setup_network_connections())
- {
- main_loop();
- cleanup_and_exit(1);
- }
-
- log(0, TLOG_ERROR, _("Unrecoverable error"));
- cp_trace();
-
- if(do_detach)
- {
- log(0, TLOG_NOTICE, _("Restarting in %d seconds!"), maxtimeout);
- sleep(maxtimeout);
- }
- else
- {
- log(0, TLOG_ERROR, _("Not restarting."));
- exit(1);
- }
- }
+#ifdef HAVE_MINGW
+ io_add_event(&stop_io, stop_handler, NULL, WSACreateEvent());
+
+ if(stop_io.event == FALSE) {
+ abort();
+ }
+
+ int result;
+
+ if(!do_detach || !init_service()) {
+ SetConsoleCtrlHandler(console_ctrl_handler, TRUE);
+ result = main2(argc, argv);
+ } else {
+ result = 1;
+ }
+
+ if(WSACloseEvent(stop_io.event) == FALSE) {
+ abort();
+ }
+
+ io_del(&stop_io);
+ return result;
+}
+
+int main2(int argc, char **argv) {
+#endif
+ char *priority = NULL;
+
+ if(!detach()) {
+ return 1;
+ }
+
+#ifdef HAVE_MLOCKALL
+
+ /* Lock all pages into memory if requested.
+ * This has to be done after daemon()/fork() so it works for child.
+ * No need to do that in parent as it's very short-lived. */
+ if(do_mlock && mlockall(MCL_CURRENT | MCL_FUTURE) != 0) {
+ logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "mlockall",
+ strerror(errno));
+ return 1;
+ }
+
+#endif
+
+ /* Setup sockets and open device. */
+
+ if(!setup_network()) {
+ goto end;
+ }
+
+ /* Change process priority */
+
+ if(get_config_string(lookup_config(config_tree, "ProcessPriority"), &priority)) {
+ if(!strcasecmp(priority, "Normal")) {
+ if(setpriority(NORMAL_PRIORITY_CLASS) != 0) {
+ logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setpriority", strerror(errno));
+ goto end;
+ }
+ } else if(!strcasecmp(priority, "Low")) {
+ if(setpriority(BELOW_NORMAL_PRIORITY_CLASS) != 0) {
+ logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setpriority", strerror(errno));
+ goto end;
+ }
+ } else if(!strcasecmp(priority, "High")) {
+ if(setpriority(HIGH_PRIORITY_CLASS) != 0) {
+ logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setpriority", strerror(errno));
+ goto end;
+ }
+ } else {
+ logger(DEBUG_ALWAYS, LOG_ERR, "Invalid priority `%s`!", priority);
+ goto end;
+ }
+ }
+
+ /* drop privileges */
+ if(!drop_privs()) {
+ goto end;
+ }
+
+ /* Start main loop. It only exits when tinc is killed. */
+
+ logger(DEBUG_ALWAYS, LOG_NOTICE, "Ready");
+
+ if(umbilical) { // snip!
+ write(umbilical, "", 1);
+ close(umbilical);
+ umbilical = 0;
+ }
+
+ try_outgoing_connections();
+
+ status = main_loop();
+
+ /* Shutdown properly. */
+
+end:
+ close_network_connections();
+
+ logger(DEBUG_ALWAYS, LOG_NOTICE, "Terminating");
+
+ free(priority);
+
+ crypto_exit();
+
+ exit_configuration(&config_tree);
+ free(cmdline_conf);
+ free_names();
+
+ return status;