daemon.c (3387B)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <unistd.h> 5 #include <fcntl.h> 6 #include <sys/stat.h> 7 8 #include "cofyc/argparse.h" 9 #include "rxi/log.h" 10 11 #include "infrastructure/config.h" 12 #include "common/resp.h" 13 #include "../common.h" 14 #include "domain/scheduler.h" 15 #include "domain/config.h" 16 #include "daemon.h" 17 #include "interface/api/server.h" 18 #include "domain/daemon/session.h" 19 20 static void register_domain_commands(void) { 21 api_register_domain_cmd("session.create", domain_session_create); 22 api_register_domain_cmd("session.list", domain_session_list); 23 api_register_domain_cmd("session.info", domain_session_info); 24 api_register_domain_cmd("session.destroy", domain_session_destroy); 25 api_register_domain_cmd("session.socket.create.listen", domain_socket_create_listen); 26 api_register_domain_cmd("session.socket.create.connect", domain_socket_create_connect); 27 api_register_domain_cmd("session.socket.destroy", domain_socket_destroy); 28 api_register_domain_cmd("session.forward.list", domain_forward_list); 29 api_register_domain_cmd("session.forward.create", domain_forward_create); 30 api_register_domain_cmd("session.forward.destroy", domain_forward_destroy); 31 api_register_domain_cmd("session.count", domain_session_count); 32 api_register_domain_cmd("system.load", domain_system_load); 33 log_info("udphole: registered session.* commands"); 34 } 35 36 static int do_daemonize(void) { 37 pid_t pid = fork(); 38 if (pid < 0) { 39 log_fatal("fork: %m"); 40 return -1; 41 } 42 if (pid > 0) 43 _exit(0); 44 if (setsid() < 0) { 45 log_fatal("setsid: %m"); 46 _exit(1); 47 } 48 pid = fork(); 49 if (pid < 0) { 50 log_fatal("fork: %m"); 51 _exit(1); 52 } 53 if (pid > 0) 54 _exit(0); 55 if (chdir("/") != 0) {} 56 int fd; 57 for (fd = 0; fd < 3; fd++) 58 (void)close(fd); 59 fd = open("/dev/null", O_RDWR); 60 if (fd >= 0) { 61 dup2(fd, STDIN_FILENO); 62 dup2(fd, STDOUT_FILENO); 63 dup2(fd, STDERR_FILENO); 64 if (fd > 2) 65 close(fd); 66 } 67 return 0; 68 } 69 70 int cli_cmd_daemon(int argc, const char **argv) { 71 int daemonize_flag = 0; 72 int no_daemonize_flag = 0; 73 74 struct argparse argparse; 75 struct argparse_option options[] = { 76 OPT_HELP(), 77 OPT_BOOLEAN('d', "daemonize", &daemonize_flag, "run in background", NULL, 0, 0), 78 OPT_BOOLEAN('D', "no-daemonize", &no_daemonize_flag, "force foreground", NULL, 0, 0), 79 OPT_END(), 80 }; 81 argparse_init(&argparse, options, (const char *const[]){"udphole daemon", NULL}, ARGPARSE_STOP_AT_NON_OPTION); 82 argparse_parse(&argparse, argc, argv); 83 84 if (!no_daemonize_flag && daemonize_flag) { 85 do_daemonize(); 86 } 87 88 domain_config_init(); 89 90 if (global_cfg) { 91 resp_object *cfg_sec = resp_map_get(global_cfg, "udphole"); 92 if (cfg_sec) { 93 const char *ports_str = resp_map_get_string(cfg_sec, "ports"); 94 if (ports_str) { 95 int port_low = 7000, port_high = 7999; 96 sscanf(ports_str, "%d-%d", &port_low, &port_high); 97 domain_config_set_ports(port_low, port_high); 98 } 99 const char *advertise = resp_map_get_string(cfg_sec, "advertise"); 100 if (advertise) { 101 domain_config_set_advertise(advertise); 102 } 103 } 104 } 105 106 register_domain_commands(); 107 108 log_info("udphole: starting daemon"); 109 110 domain_schedmod_pt_create(api_server_pt, NULL); 111 domain_schedmod_pt_create(session_manager_pt, NULL); 112 113 log_info("udphole: daemon started"); 114 115 return domain_schedmod_main(); 116 }