static void clear_pidfile(active_db_h * s) { const char *pidfile = NULL; s_data *itt = NULL; /* ok, search for pidfiles */ while ((pidfile = get_next_string(&PIDFILE, s, &itt))) { if (pidfile) { /* check it's an absolute path after variable substitution */ if (pidfile[0] == '/') { if (unlink(pidfile) != 0 && errno != ENOENT) { F_("Could not remove stale pidfile " "\"%s\"\n", pidfile); } break; } else { F_("%s has pid_file with relative path " "\"%s\"\n", s->name, pidfile); /* check_valid_pidfile_path() can detect * certain dangerous typos, but it can't * prevent loading. Stop to be safe */ return; } } } }
static void makeutmp(int runlevel) { D_("Making utmp file for runlevel %d\n", runlevel); struct utmp utmp; time_t t; /* * this is created by bootmisc, if this isn't there we can't set * runlevel. */ if (access(UTMP_FILE, F_OK) < 0) { F_("/var/run/utmp does not exist, this should be created by " "bootmisc.i\n"); return; } /* TODO, is this a good idea or a bad idea? utmpname("/var/run/utmp"); */ setutent(); memset(&utmp, 0, sizeof(utmp)); utmp.ut_type = RUN_LVL; utmp.ut_pid = ('#' << 8) + runlevel + '0'; time(&t); utmp.ut_time = (int)t; if (!pututline(&utmp)) { F_("pututline failed\n"); endutent(); return; } endutent(); return; }
/* * This function tries to update the process pid from a pidfile or pidof */ static int try_get_pid(active_db_h * s) { pid_t pid = -1; D_("Trying to get pid of %s\n", s->name); /* Try get the pid from PIDOF is set */ if (is(&PIDOF, s)) { D_("getting pid by PIDOF!\n"); /* get pid by process name */ pid = get_pidof(s); D_("result : %d\n", pid); /* Try get the pid from PIDFILE if set */ } else if (is(&PIDFILE, s)) { D_("getting pid by PIDFILE!\n"); pid = get_pidfile(s); D_("result : %d\n", pid); } else { F_("No one of PIDOF or PIDFILE are set, but initng is " "waiting for a pid.\n"); return FALSE; } /* check if a process with that pid exits in the system */ if (pid > 0 && kill(pid, 0) < 0 && (errno == ESRCH)) { F_("Got a non-existent pid %i for daemon \"%s\", maybe there " "is a stale pidfile around.", pid, s->name); pid = -1; /* reset */ } else if (pid > 0) { process_h *p = NULL; /* get the process to handle */ if (!(p = initng_process_db_get(&T_DAEMON, s))) { F_("Did not find a daemon process on this " "service!\n"); initng_common_mark_service(s, &DAEMON_UP_CHECK_FAILED); return FALSE; } /* finally set the new pid - but not if forks=no, because that can cause problems */ if (is(&FORKS, s)) p->pid = pid; /* check with up_check */ if (initng_depend_up_check(s) == FAIL) { initng_common_mark_service(s, &DAEMON_UP_CHECK_FAILED); return FALSE; } /* set the new state */ initng_common_mark_service(s, &DAEMON_RUNNING); /* return HAPPILY */ return TRUE; } return FALSE; }
string ConnectivityManager::getInformation() { if (g_is_running) { return "Connectivity settings are being configured; try again later"; } // string autoStatus = ok() ? str(F_("enabled - %1%") % getStatus()) : "disabled"; string mode; switch (SETTING(INCOMING_CONNECTIONS)) { case SettingsManager::INCOMING_DIRECT: { mode = "Active mode"; break; } case SettingsManager::INCOMING_FIREWALL_UPNP: { const auto l_status = MappingManager::getInstance()->getStatus(); mode = str(F_("Active mode behind a router can configure; port mapping status: %2%") % l_status); #ifdef FLYLINKDC_USE_GATHER_STATISTICS g_fly_server_stat.m_upnp_router_name = MappingManager::getInstance()->getDeviceString(); g_fly_server_stat.m_upnp_status = l_status; #endif break; } case SettingsManager::INCOMING_FIREWALL_PASSIVE: { mode = "Passive mode"; break; } } auto field = [](const string & s) { return s.empty() ? "undefined" : s; }; return str(F_( "Connectivity information:\n" "\tExternal IP (v4): %1%\n" "\tBound interface (v4): %2%\n" "\tTransfer port: %3%\n" "\tEncrypted transfer port: %4%\n" "\tSearch port: %5%\n" "\tTorrent port: %6%\n" "\tStatus: %7%" ) % field(SETTING(EXTERNAL_IP)) % field(SETTING(BIND_ADDRESS)) % field(Util::toString(ConnectionManager::getInstance()->getPort())) % field(Util::toString(ConnectionManager::getInstance()->getSecurePort())) % field(SearchManager::getSearchPort()) % field(Util::toString(SETTING(DHT_PORT))) % field(getStatus()) ); }
static void service_state(s_event * event) { active_db_h *service; active_db_h *current = NULL; assert(event->event_type == &EVENT_IS_CHANGE); service = event->data; assert(service); assert(service->name); const char *tmp = NULL; s_data *itt = NULL; switch (GET_STATE(service)) { /* if service is loading, start all in ALSO_START */ case IS_STARTING: while ((tmp = get_next_string(&ALSO_START, service, &itt))) { current = initng_active_db_find_by_name(tmp); if (current) { if (!initng_handler_start_service(current)) { F_("Failed to also_start %s.\n", tmp); } else { D_("Service also_start %s already " "running.\n", tmp); } continue; } if (!initng_handler_start_new_service_named(tmp)) { F_("%s also_start %s could not start!\n", service->name, tmp); initng_handler_stop_service(service); break; } } break; /* if this service is stopping, stop all in ALSO_STOP */ case IS_STOPPING: while ((tmp = get_next_string(&ALSO_STOP, service, &itt))) { current = initng_active_db_find_by_name(tmp); if (current) { /* Tell this verbose */ D_("service %s also stops %s\n", service->name, tmp); if (!initng_handler_stop_service(current)) { F_("Could not stop also_stop " "service %s\n", current->name); } } } break; } }
char *initng_io_readwhole(const char *path) { int fd; struct stat stat_buf; int res; /* Result of read */ char *buf; fd = open(path, O_RDONLY); /* Open config file. */ if (fd == -1) { D_("error opening %s: %s (%d)\n", path, strerror(errno), errno); return NULL; } if (fstat(fd, &stat_buf) == -1) { D_("error getting %s file size: %s (%d)\n", path, strerror(errno), errno); close(fd); return NULL; } /* Allocate a file buffer */ buf = (char *)initng_toolbox_calloc((stat_buf.st_size + 1), 1); /* Read whole file */ res = read(fd, buf, stat_buf.st_size); if (res == -1) { F_("error reading %s: %s (%d)\n", path, strerror(errno), errno); goto error; } else if (res != stat_buf.st_size) { F_("read %d instead of %d bytes from %s\n", (int)res, (int)stat_buf.st_size, path); goto error; } /* Normally we wouldn't care about this, but as this is init(ng)? */ if (close(fd) < 0) { F_("error closing %s: %s (%d)\n", path, strerror(errno), errno); goto error; } buf[stat_buf.st_size] = '\0'; /* nil-terminate buffer */ return buf; error: free(buf); close(fd); return NULL; }
static void init_DAEMON_STOP_DEPS_MET(active_db_h * service) { process_h *process = NULL; /* find the daemon, and check so it still exits */ if (!(process = initng_process_db_get(&T_DAEMON, service))) { F_("Could not find process to kill!\n"); return; } /* Check so process have a valid pid */ if (process->pid <= 0) { D_("Pid is unvalid, marked as DAEMON_STOPPED\n"); initng_common_mark_service(service, &DAEMON_STOPPED); return; } if (kill(process->pid, 0) && errno == ESRCH) { D_("Dont exist a process with pid %i, mark as " "DAEMON_STOPPED\n", process->pid); initng_common_mark_service(service, &DAEMON_STOPPED); return; } /* launch stop service */ switch (initng_execute_launch(service, &T_KILL, NULL)) { case FAIL: F_(" -- (%s): fail launch stop!\n", service->name); initng_common_mark_service(service, &DAEMON_FAIL_STOPPING); return; case FALSE: { /* if there is no module that wanna kill this * daemon, we do it ourself. */ kill_daemon(service, SIGTERM); if (!initng_common_mark_service(service, &DAEMON_TERM)) return; break; } default: /* Set its state to GOING_KILLED, to mark that we put * some effort on killing it. */ if (!initng_common_mark_service(service, &DAEMON_TERM)) return; break; } }
static void handle_DAEMON_WAITING_FOR_START_DEP(active_db_h * daemon) { assert(daemon); /* * this checks depencncy. * initng_depend_start_dep_met() will return: * TRUE (dep is met) * FALSE (dep is not met) * FAIL (dep is failed) */ switch (initng_depend_start_dep_met(daemon, FALSE)) { case TRUE: break; case FAIL: initng_common_mark_service(daemon, &DAEMON_START_DEPS_FAILED); return; default: /* return and hope that this handler will be called again. */ return; } /* if system is shutting down, Don't start anything. */ if (g.sys_state != STATE_STARTING && g.sys_state != STATE_UP) { F_("Can't start daemon, when system status is: %i !\n", g.sys_state); initng_common_mark_service(daemon, &DAEMON_STOPPED); return; } /* set status to START_DEP_MET */ initng_common_mark_service(daemon, &DAEMON_START_DEPS_MET); }
/* * Timeout reached. * * What to do when timeout reached. */ static void timeout_DAEMON_WAIT_FOR_PID_FILE(active_db_h * s) { /* check if timeout have appeared */ if (g.now.tv_sec > s->time_current_state.tv_sec + PID_TIMEOUT) { process_h *process = NULL; F_("Service \"%s\" wait for pidfile timed out! Will kill " "daemon now.\n", s->name); initng_common_mark_service(s, &DAEMON_FAIL_START_TIMEOUT_PIDFILE); kill_daemon(s, SIGKILL); /* Free the process if found */ process = initng_process_db_get(&T_DAEMON, s); if (process) { initng_process_db_free(process); } return; } /* * NOW, start check for a pid */ if (!try_get_pid(s)) { /* try again in 1 second */ initng_handler_set_alarm(s, 1); } }
/* this will get the pid of PIDFILE entry of service */ static pid_t get_pidfile(active_db_h * s) { pid_t pid; const char *pidfile = NULL; s_data *itt = NULL; /* get the pidfile */ while ((pidfile = get_next_string(&PIDFILE, s, &itt))) { /* make sure the first char is a '/' so its a full path */ if (pidfile[0] != '/') { F_("%s has pid_file with relative path \"%s\"\n", s->name, pidfile); /* check_valid_pidfile_path() can detect certain * dangerous typos, but it can't prevent loading. * Stop to be safe */ return -1; } /* get the pid from the file */ pid = pid_from_file(pidfile); /* return the pid */ if (pid > 1) return (pid); } return -1; }
/* this function set rlimit if it should, w-o overwriting old values. */ static int set_limit(s_entry * soft, s_entry * hard, active_db_h * service, int ltype, int times) { int si = FALSE; int sh = FALSE; struct rlimit l; /* check if the limits are set */ si = is(soft, service); sh = is(hard, service); /* make sure any is set */ if (si == FALSE && sh == FALSE) return (0); /* get the current limit data */ if (getrlimit(ltype, &l) != 0) { F_("getrlimit failed!, service %s, limit type %i: %s\n", service->name, ltype, err_desc()); return -1; } D_("current: soft: %i, hard: %i\n", (int)l.rlim_cur, (int)l.rlim_max); /* if soft limit is set, get it */ if (si) l.rlim_cur = (get_int(soft, service) * times); /* if hard limit is set, get it */ if (sh) l.rlim_max = (get_int(hard, service) * times); /* make sure hard is at least same big, but hopefully bigger. */ if (l.rlim_cur > l.rlim_max) l.rlim_max = l.rlim_cur; D_("now: soft: %i, hard: %i\n", (int)l.rlim_cur, (int)l.rlim_max); /* set the limit and return status */ if (setrlimit(ltype, &l) != 0) { F_("setrlimit failed, service: %s, limit type %i: %s\n", service->name, ltype, err_desc()); return -1; } return 0; }
static void program_output(s_event * event) { s_event_buffer_watcher_data *data; const char *filename = NULL; int len = 0; int fd = -1; assert(event->event_type == &EVENT_BUFFER_WATCHER); assert(event->data); data = event->data; assert(data->service); assert(data->service->name); assert(data->process); /*D_("%s process fd: # %i, %i, service %s, have something to say\n", data->process->pt->name, data->process->out_pipe[0], data->process->out_pipe[1], data->service->name); */ /* get the filename */ filename = get_string(&LOGFILE, data->service); if (!filename) { D_("Logfile not set\n"); return; } /* open the file */ fd = open(filename, O_WRONLY | O_CREAT | O_APPEND, 0644); if (fd < 1) { F_("Error opening %s, err : %s\n", filename, strerror(errno)); return; } /* Write data to logfile */ D_("Writing data...\n"); len = strlen(data->buffer_pos); if (write(fd, data->buffer_pos, len) != len) F_("Error writing to %s's log, err : %s\n", data->service->name, strerror(errno)); close(fd); }
void initng_main_new_init(void) { initng_main_set_sys_state(STATE_EXECVE); if (!g.new_init || !g.new_init[0]) { F_(" g.new_init is not set!\n"); return; } P_("\n\n\n Launching new init (%s)\n\n", g.new_init[0]); execve(g.new_init[0], g.new_init, environ); }
/* when DAEMON_TERM timeout, kill it instead */ static void timeout_DAEMON_TERM(active_db_h * daemon) { F_("Service %s TERM_TIMEOUT reached!, sending KILL signal.\n", daemon->name); kill_daemon(daemon, SIGKILL); /* Set it to DAEMON_KILL state, monitoring that TERM signal is * sent. */ initng_common_mark_service(daemon, &DAEMON_KILL); }
/* set SIGKILL on every timeout */ static void timeout_DAEMON_KILL(active_db_h * daemon) { F_("Service %s KILL_TIMEOUT of %i seconds reached! " "(%i seconds passed), sending another KILL signal.\n", daemon->name, DEFAULT_KILL_TIMEOUT, MS_DIFF(g.now, daemon->time_current_state)); kill_daemon(daemon, SIGKILL); /* Dont be afraid to kill again */ initng_handler_set_alarm(daemon, DEFAULT_KILL_TIMEOUT); }
long double Z(long double x, int n, long double ep, long double *v) { long double t; int i; *v = V(x, ep); for (i = n - 2; i > 0; i--) { t = F_(*v/x + F(x)); if (isnan(t)) break; x = t; } return (*v-x + x*F(x)); }
inline static void pipes_create(process_h *process) { pipe_h *current_pipe = NULL; while_pipes(current_pipe, process) { if (current_pipe->dir == IN_AND_OUT_PIPE) { /* create an two directional pipe with socketpair */ if (socketpair(AF_UNIX, SOCK_STREAM, 0, current_pipe->pipe) < 0) { F_("Fail call socketpair: \"%s\"\n", strerror(errno)); } } else { /* create an one directional pipe with pipe */ if (pipe(current_pipe->pipe) != 0) { F_("Failed adding pipe ! %s\n", strerror(errno)); } } } }
int SearchManager::run() { boost::scoped_array<uint8_t> buf(new uint8_t[BUFSIZE]); int len; string remoteAddr; while(!stop) { try { while( true ) { // Patch from FlylinkDC++, see: // http://code.google.com/p/flylinkdc/source/detail?r=6132 // http://bazaar.launchpad.net/~dcplusplus-team/dcplusplus/trunk/revision/2414 // . // @todo: remove this workaround for http://bugs.winehq.org/show_bug.cgi?id=22291 // if that's fixed by reverting to simpler while (read(...) > 0) {...} code. while (socket->wait(400, Socket::WAIT_READ) != Socket::WAIT_READ); if (stop || (len = socket->read(&buf[0], BUFSIZE, remoteAddr)) <= 0) break; onData(&buf[0], len, remoteAddr); } } catch(const SocketException& e) { dcdebug("SearchManager::run Error: %s\n", e.getError().c_str()); } bool failed = false; while(!stop) { try { socket->disconnect(); socket->create(Socket::TYPE_UDP); socket->setBlocking(true); socket->bind(port, SETTING(BIND_ADDRESS)); if(failed) { LogManager::getInstance()->message(_("Search enabled again")); failed = false; } break; } catch(const SocketException& e) { dcdebug("SearchManager::run Stopped listening: %s\n", e.getError().c_str()); if(!failed) { LogManager::getInstance()->message(str(F_("Search disabled: %1%") % e.getError())); failed = true; } // Spin for 60 seconds for(int i = 0; i < 60 && !stop; ++i) { Thread::sleep(1000); } } } } return 0; }
int SearchManager::run() { boost::scoped_array<uint8_t> buf(new uint8_t[BUFSIZE]); int len; string remoteAddr; while(!stop) { try { if(!socket->wait(400, true, false).first) { continue; } if((len = socket->read(&buf[0], BUFSIZE, remoteAddr)) > 0) { string data(reinterpret_cast<char*>(&buf[0]), len); if(PluginManager::getInstance()->onUDP(false, remoteAddr, port, data)) continue; onData(data, remoteAddr); continue; } } catch(const SocketException& e) { dcdebug("SearchManager::run Error: %s\n", e.getError().c_str()); } bool failed = false; while(!stop) { try { socket->disconnect(); port = socket->listen(Util::toString(CONNSETTING(UDP_PORT))); if(failed) { LogManager::getInstance()->message(_("Search enabled again")); failed = false; } break; } catch(const SocketException& e) { dcdebug("SearchManager::run Stopped listening: %s\n", e.getError().c_str()); if(!failed) { LogManager::getInstance()->message(str(F_("Search disabled: %1%") % e.getError())); failed = true; } // Spin for 60 seconds for(auto i = 0; i < 60 && !stop; ++i) { Thread::sleep(1000); } } } } return 0; }
void HttpConnection::on(BufferedSocketListener::Data, uint8_t* aBuf, size_t aLen) noexcept { if(size != -1 && static_cast<size_t>(size - done) < aLen) { abortRequest(true); connState = CONN_FAILED; fire(HttpConnectionListener::Failed(), this, str(F_("Too much data in response body (%1%)") % url)); return; } done += aLen; updateSpeed(); fire(HttpConnectionListener::Data(), this, aBuf, aLen); }
static void kill_daemon(active_db_h * service, int sig) { process_h *process = NULL; assert(service); /* make sure we got a process */ if (!(process = initng_process_db_get(&T_DAEMON, service))) { F_("Service doesn't have any processes, don't know how to " "kill then.\n"); return; } /* check so that pid is good */ if (process->pid <= 0) { F_("Bad PID %d in database!\n", process->pid); initng_process_db_free(process); return; } /* check so there exits an process with this pid */ if (kill(process->pid, 0) && errno == ESRCH) { F_("Trying to kill a service (%s) with a pid (%d), but there " "exists no process with this pid!\n", service->name, process->pid); initng_process_db_free(process); return; } /* if system is not stopping, generate a warning */ /*if (g.sys_state != STATE_STOPPING) { W_(" Sending the process %i of %s, the SIGTERM signal!\n", process->pid, service->name); } */ /* Uhm, this doesn't work : kill(-service->start_process->pid, SIGKILL); */ kill(process->pid, sig); }
/* * Check if a pidfile exists, if it exists, update the * pid in the active_db entry. and return TRUE */ static pid_t pid_from_file(const char *name) { unsigned int i = 0; pid_t ret = 0; int fd = 0; unsigned int len = 0; char buf[21]; assert(name); /* open pid file */ fd = open(name, O_RDONLY); /* If we cant open pidfile, this is bad */ if (fd == -1) return -1; /* Read data from buffer */ len = read(fd, buf, 20); close(fd); if (len < 1) { F_("Read 0 chars from %s, It's empty.\n", name); return -1; } for (i = 0; i < len && !isdigit(buf[i]); i++) ; for (; i < len && isdigit(buf[i]); i++) ret = ret * 10 - '0' + buf[i]; if (!ret && i > len) { F_("bufferoverrun: no pid fetched from '%s'.", name); } else if (ret && i > len) { F_("bufferoverrun: the pid received from '%s' is pid (%i).", name, ret); } return ret; }
void ConnectivityManager::detectConnection() { if (running) return; running = true; //fire(ConnectivityManagerListener::Started()); // restore connectivity settings to their default value. SettingsManager::getInstance()->unset(SettingsManager::TCP_PORT); SettingsManager::getInstance()->unset(SettingsManager::UDP_PORT); SettingsManager::getInstance()->unset(SettingsManager::TLS_PORT); SettingsManager::getInstance()->unset(SettingsManager::EXTERNAL_IP); SettingsManager::getInstance()->unset(SettingsManager::NO_IP_OVERRIDE); //SettingsManager::getInstance()->unset(SettingsManager::MAPPER); SettingsManager::getInstance()->unset(SettingsManager::BIND_ADDRESS); if (UPnPManager::getInstance()->getOpened()) { UPnPManager::getInstance()->close(); } disconnect(); log(_("Determining the best connectivity settings...")); try { listen(); } catch(const Exception& e) { SettingsManager::getInstance()->set(SettingsManager::INCOMING_CONNECTIONS, SettingsManager::INCOMING_FIREWALL_PASSIVE); log(str(F_("Unable to open %1% port(s); connectivity settings must be configured manually") % e.getError())); fire(ConnectivityManagerListener::Finished()); running = false; return; } autoDetected = true; if (!Util::isPrivateIp(Util::getLocalIp())) { SettingsManager::getInstance()->set(SettingsManager::INCOMING_CONNECTIONS, SettingsManager::INCOMING_DIRECT); log(_("Public IP address detected, selecting active mode with direct connection")); fire(ConnectivityManagerListener::Finished()); running = false; return; } SettingsManager::getInstance()->set(SettingsManager::INCOMING_CONNECTIONS, SettingsManager::INCOMING_FIREWALL_UPNP); log(_("Local network with possible NAT detected, trying to map the ports using UPnP...")); if (!UPnPManager::getInstance()->open()) { running = false; } }
int module_init(void) { utmp_stored = FALSE; initctl_control_open(); if (!initng_event_hook_register(&EVENT_SIGNAL, &hup_request) || !initng_event_hook_register(&EVENT_SYSTEM_CHANGE, &is_system_up)) { F_("Fail add hook!\n"); return FALSE; } return TRUE; }
static int simple_exec_fork(process_h * process_to_exec, active_db_h * s, size_t argc, char **argv) { /* This is the real service kicker */ pid_t pid_fork; /* pid got from fork() */ pid_fork = initng_fork(s, process_to_exec); if (pid_fork == 0) { /* run g.AFTER_FORK from other modules */ initng_fork_aforkhooks(s, process_to_exec); #ifdef DEBUG D_("FROM_FORK simple_exec(%i,%s, ...);\n", argc, argv[0]); /*D_argv("simple_exec: ", argv); */ #endif /* FINALLY EXECUTE *//* execve replaces the running process */ execve(argv[0], argv, initng_env_new(s)); /* Will never get here if execve succeeded */ F_("ERROR!\n"); F_("Can't execute source %s!\n", argv[0]); _exit(1); } /* save pid of fork */ D_("FROM_FORK Forkstarted pid %i.\n", pid_fork); if (pid_fork > 0) return TRUE; process_to_exec->pid = 0; return FALSE; /* if to test want to lock this up until fork is done ... * waitpid(pid_fork,0,0); */ }
static int initctl_control_open(void) { D_("initctl control open (%d)\n", pipe_fd.fds); /* First, try to create /dev/initctl if not present. */ if (stat(INIT_FIFO, &st2) < 0 && errno == ENOENT) (void)mkfifo(INIT_FIFO, 0600); /* * If /dev/initctl is open, stat the file to see if it * is still the _same_ inode. */ if (pipe_fd.fds > 2) { if (fstat(pipe_fd.fds, &st) < 0) initctl_control_close(); if (stat(INIT_FIFO, &st2) < 0 || st.st_dev != st2.st_dev || st.st_ino != st2.st_ino) { initctl_control_close(); } } /* If the pipe isn't open, try to open it. */ if (pipe_fd.fds < 3) { /* the file descriptor has to be over 2 to be valid */ pipe_fd.fds = open(INIT_FIFO, O_RDWR | O_NONBLOCK); if (pipe_fd.fds < 3) return FALSE; D_("Opened on fd %i\n", pipe_fd.fds); fstat(pipe_fd.fds, &st); if (!S_ISFIFO(st.st_mode)) { /* /dev/initctl is there, but we can't open it */ F_("%s is not a fifo\n", INIT_FIFO); if (pipe_fd.fds >= 0) { close(pipe_fd.fds); pipe_fd.fds = -1; } return FALSE; } initng_io_set_cloexec(pipe_fd.fds); /* ok, finally add hook */ initng_event_hook_register(&EVENT_IO_WATCHER, &pipe_io_handler); } return TRUE; }
/* try open FIFO, every started service */ static void hup_request(s_event * event) { int *signal; assert(event->event_type == &EVENT_SIGNAL); signal = event->data; /* Look for the right signal */ if (*signal == SIGHUP) { if (!initctl_control_open()) { F_("Warning, failed to open /dev/initctl\n"); } } }
static int simple_exec_try(const char *exec, active_db_h * service, process_h * process) { char *exec_args = NULL; char **argv = NULL; size_t argc = 0; int ret; D_("exec: %s, service: %s, process: %s\n", exec, service->name, process->pt->name); /* exec_args should be parsed at the moment, too */ exec_args = (char *)get_string_var(&EXEC_ARGS, process->pt->name, service); if (exec_args) { initng_string_fix_escapes(exec_args); /* split the string, with entries to an array of strings */ argv = initng_string_split_delim(exec_args + 1, WHITESPACE, &argc); /* make sure it succeeded */ if (!argv || !argv[0]) { if (argv) initng_string_split_delim_free(argv); F_("initng_string_split_delim exec_args returns NULL.\n"); return FALSE; } } else { /* we need a empty argv anyway */ argv = (char **)initng_toolbox_calloc(2, sizeof(char *)); argv[1] = NULL; argc = 0; } argv[0] = (char *)exec; ret = simple_exec_fork(process, service, argc, argv); if (argv) initng_string_split_delim_free(argv); return ret; }
/* this will check socket, and reopen on failure */ static void check_socket(s_event * event) { int *signal; struct stat st; assert(event->event_type == &EVENT_SIGNAL); signal = event->data; if (*signal != SIGHUP) return; #define PING "<event type=\"ping\"/>\n" send_to_all(PING, strlen(PING)); D_("Checking socket\n"); /* Check if socket needs reopening */ if (io_event_acceptor.fds <= 0) { D_("io_event_acceptor.fds not set, opening new socket.\n"); open_initiator_socket(); return; } /* stat the socket, reopen on failure */ memset(&st, 0, sizeof(st)); if (stat(socket_filename, &st) < 0) { W_("Stat failed! Opening new socket.\n"); open_initiator_socket(); return; } /* compare socket file, with the one that we know, reopen on failure */ if (st.st_dev != sock_stat.st_dev || st.st_ino != sock_stat.st_ino || st.st_mtime != sock_stat.st_mtime) { F_("Invalid socket found, reopening\n"); open_initiator_socket(); return; } D_("Socket ok.\n"); return; }
void Transfer::getParams(const UserConnection& aSource, StringMap& params) { params["userCID"] = aSource.getUser()->getCID().toBase32(); params["userNI"] = Util::toString(ClientManager::getInstance()->getNicks(aSource.getUser()->getCID(), aSource.getHubUrl())); params["userI4"] = aSource.getRemoteIp(); StringList hubNames = ClientManager::getInstance()->getHubNames(aSource.getUser()->getCID(), aSource.getHubUrl()); if(hubNames.empty()) hubNames.push_back(_("Offline")); params["hub"] = Util::toString(hubNames); StringList hubs = ClientManager::getInstance()->getHubs(aSource.getUser()->getCID(), aSource.getHubUrl()); if(hubs.empty()) hubs.push_back(_("Offline")); params["hubURL"] = Util::toString(hubs); params["fileSI"] = Util::toString(getSize()); params["fileSIshort"] = Util::formatBytes(getSize()); params["fileSIactual"] = Util::toString(getActual()); params["fileSIactualshort"] = Util::formatBytes(getActual()); params["speed"] = str(F_("%1%/s") % Util::formatBytes(getAverageSpeed())); params["time"] = Util::formatSeconds((GET_TICK() - getStart()) / 1000); params["fileTR"] = getTTH().toBase32(); }