int daemon_init(const char *pidfile) { int pid = check_pid(pidfile); if (pid) { fprintf(stderr, "mtask is already running, pid = %d.\n", pid); return 1; } #ifdef __APPLE__ fprintf(stderr, "'daemon' is deprecated: first deprecated in OS X 10.5 , use launchd instead.\n"); #else if (daemon(1,0)) { fprintf(stderr, "Can't daemonize.\n"); return 1; } #endif pid = write_pid(pidfile); if (pid == 0) { return 1; } return 0; }
int check_pid(int tpid){ // target pid look if ppid==pid for the process with pid=dir //printf("tpid=%d\n",tpid); int count=0; //lcount++; //if(lcount>LIMIT) return 0; char str[20],str1[20], str2[20], str3[20],str4[20]; int i; for(i=0;i<size;i++){ strcpy(str,"/proc/"); //char value[20]; //snprintf(value,20,"%d",pid); //strcat(str,value); strcat(str,table[i]); strcat(str,"/stat"); //printf("tpid=%d,path=%s\n",tpid,str); //printf("str= %s\n",str); FILE * fp; fp = fopen (str, "r"); if(fp==NULL){ //printf("NULL"); continue; } fscanf(fp, "%s %s %s %s", str1, str2, str3, str4); fclose(fp); int ppid=atoi(str4); if(ppid==0) //error continue; int pid=atoi(table[i]); if (pid==0) //error self continue; if(ppid==tpid){ //the process is a child of tpid process if(pid==1){ printf("pid=1 %s %d",table[i],tpid); } if(pid==0){ printf("pid=0 %s %d",table[i],tpid); } count+=check_pid(pid)+1; //go deeper,+1 for the child process itself } } return count; }
int main(int argc,char *argv[]) { init_table(); int pid=atoi(argv[1]); printf("%d\n",check_pid(pid)+1); //int i; //for (i=0;i<pos;i++) // printf("%s\n",table[i]); return 0; }
int sv_pid(callspace *cs, int argv[]) { int *array = array_get(g_cs, argv[0]); int array_c = array_length(g_cs, argv[0]); char* f = string_get(cs, array[0]); pid_t pid = pid_from_string(string_get(cs, array[0])); if (check_pid(pid) == TRUE) { g_last_pid = pid; sprintf(g_last_pid_str, "%d", g_last_pid); return TRUE; } return FALSE; }
int main (int argc, char **argv) { botcfg.state = STATE_INIT; //piHiPri (45); if (setup () != 0) { fprintf (stderr, "Error setting up\n"); return 1; } if (read_options (argc, argv) != 0) { fprintf (stderr, "Error reading options\n"); return 1; } if (botcfg.state == STATE_INIT) { //User didn't chose either record or replay, falling back to passthrough botcfg.state = STATE_RUNNING; } if (joystick_setup () != 0) { fprintf (stderr, "Error setting up joysticks\n"); return 1; } //drop_privs (); if (check_pid ()) { fprintf (stderr, "Are we already running?\n"); return 1; } main_loop (); clear_all_buttons (); fprintf (stdout, "Exiting...\n"); remove_pid (); return 0 ; }
int daemon_init(const char *pidfile) { // check stored process id is valid or not // if it is valid then indicate the process is already running, just return int pid = check_pid(pidfile); if (pid) { fprintf(stderr, "Skynet is already running, pid = %d.\n", pid); return 1; } #ifdef __APPLE__ fprintf(stderr, "'daemon' is deprecated: first deprecated in OS X 10.5 , use launchd instead.\n"); #else // int daemon(int nochdir, int noclose): // 1. this function is for programs wishing to detach themselves form the controlling terminal // and run in the background as system daemons. // 2. if `nochdir` is 0, it changes the calling process's current working directory // to the root directory (/); otherwise, the current working directory is left unchanged // 3. if `noclose` is 0, it redirects stdin stdout stderr to `/dev/null`, // otherwise, no changes are made to these file descriptors // daemonize current process: daemon or service is a background process that is designed to run auto without ui // and keep current working directory and redirect standand stream to `/dev/null`. if (daemon(1,0)) { fprintf(stderr, "Can't daemonize.\n"); return 1; } #endif // create the pid file if not exist // lock this pid file // get current process id and write to this file // note that the pid file is not closed pid = write_pid(pidfile); if (pid == 0) { return 1; } return 0; }
void actal_free_uncache(void *ptr) { int ret; struct actal_mem *user_p, *parent_p; ALOGI("[memory_free] actal_free_uncache"); check_pid(); //避免线程冲突 if (pthread_mutex_lock(&mutex) != 0) { ALOGE("actal_free_uncache: get mutex failed"); return ; } user_p = s_top_p; while(user_p->next != NULL) { parent_p = user_p; user_p = user_p->next; if(user_p->ptr == ptr) { ret = ion_free(user_p->fd, user_p->handle); munmap(ptr, user_p->len); close(user_p->map_fd); // ALOGD("free uncache len = %d, ptr = %#X, handle = %#X\n",user_p->len, (unsigned int)user_p->ptr, (unsigned int)user_p->handle); parent_p->next = user_p->next; if(user_p == s_current_p) { s_current_p = parent_p; } free(user_p); goto UNLOCK_MUTEX; } } actal_error("cannot find ptr in list\n"); UNLOCK_MUTEX: if (pthread_mutex_unlock(&mutex) != 0) { ALOGE("free mutex failed"); } return ; }
void actal_cache_flush_env(void *ptr) { long ret; long align; struct actal_mem *user_p, *parent_p; check_pid(); //避免线程冲突 if (pthread_mutex_lock(&mutex) != 0) { ALOGE("get mutex failed"); return ; } user_p = s_top_p; while(user_p->next != NULL) { parent_p = user_p; user_p = user_p->next; align = (char*)ptr - (char*)user_p->ptr; if((user_p->ptr <= ptr) && (align < user_p->len)) { if(user_p->flag & ION_FLAG_CACHED_NEEDS_SYNC) { ret = ion_cache(user_p->fd, user_p->handle, user_p->map_fd); } else { ALOGD("there is no need to flush!\n"); } goto UNLOCK_MUTEX; } } actal_error("cannot find ptr in list_flush\n"); UNLOCK_MUTEX: if (pthread_mutex_unlock(&mutex) != 0) { ALOGE("free mutex failed"); } return ; }
/* check for an existing tinc for this net, and write pid to pidfile */ static bool write_pidfile(void) { pid_t pid; pid = check_pid(pidfilename); if(pid) { if(netname) fprintf(stderr, "A tincd is already running for net `%s' with pid %ld.\n", netname, (long)pid); else fprintf(stderr, "A tincd is already running with pid %ld.\n", (long)pid); return false; } /* if it's locked, write-protected, or whatever */ if(!write_pid(pidfilename)) { fprintf(stderr, "Could write pid file %s: %s\n", pidfilename, strerror(errno)); return false; } return true; }
int start(char* command) { int pid = fork(); if (pid == -1) { fprintf(stderr, "Error: %s\n", strerror(errno)); exit(2); } if (pid > 0) { program_pid = pid; DEBUG("pid: %d\n", pid); write_to_log("Started '%s' with pid %d", command, pid); while (1) { /* We'll break out of this loops once we seem dead. */ if (check_pid(pid)) break; if (check_tcp_ports()) { write_to_log("One of our tcp ports is dead, time to kill our child."); DEBUG("One of our tcp ports is dead.. Let's send it a SIGKILL.\n"); kill(pid, SIGKILL); break; } sleep(interval); } fprintf(stderr, "Our child seems dead :( let's restart it.\n"); reset_tcp_ports(); execute_hooks(); write_to_log("Our child '%s' died", command); // start(command); return 0; } else if (pid == 0) { putenv("MALLOC_CHECK_=3"); const char *argv[] = { "sh", "-c", command, NULL }; execvp("sh", (char * const *) argv); fprintf(stderr, "execvp failed\n"); exit(2); } else { write_to_log("fork() returned %d, this is bad.", pid); DEBUG("fork() returned %d, this is bad.\n", pid); exit(3); } }
/* * Wait until the terminal is set into no echo mode. At least one su * (RH6 w/ Linux-PAM patches) sets noecho mode AFTER writing the Password: * prompt, using TCSAFLUSH. This flushes the terminal I/O queues, possibly * taking the password with it. So we wait until no echo mode is set * before writing the password. * Note that this is done on the slave fd. While Linux allows tcgetattr() on * the master side, Solaris doesn't. */ int PtyProcess::wait_slave() { int slave = open(m_TTY, O_RDWR); if (slave < 0) { E_WARNING(E_STRLOC ": could not open slave tty\n"); return -1; } // kdDebug(900) << k_lineinfo << "Child pid " << m_Pid << endl; struct termios tio; errno = 0; while (1) { if (!check_pid(m_Pid)) { close(slave); return -1; } if(tcgetattr(slave, &tio) < 0) { E_WARNING(E_STRLOC ": tcgetattr() failed with '%s'\n", strerror(errno)); close(slave); return -1; } if(tio.c_lflag & ECHO) { E_DEBUG(E_STRLOC ": echo mode still on\n"); wait_ms(slave,100); continue; } break; } close(slave); return 0; }
int main(int argc, char **argv) { struct timespec mtime = { 0 }; sigset_t mask, sigmask_orig; int c, fd; int ep_timeout = 0; int ignore_timer = 0; int new_events = 0; char *eventdir, *prog, **prog_args; struct option long_options[] = { { "help", no_argument, 0, 'h' }, { "version", no_argument, 0, 'V' }, { "foreground", no_argument, 0, 'f' }, { "loglevel", required_argument, 0, 'L' }, { "logfile", required_argument, 0, 'l' }, { "pidfile", required_argument, 0, 'p' }, { "timeout", required_argument, 0, 't' }, { 0, 0, 0, 0 } }; while ((c = getopt_long(argc, argv, "hVfL:l:p:", long_options, NULL)) != -1) { switch (c) { case 't': timeout = atoi(optarg); if (!timeout) timeout = DEFAULT_TIMEOUT; break; case 'p': pidfile = optarg; break; case 'l': logfile = optarg; break; case 'L': log_priority = logging_level(optarg); break; case 'f': daemonize = 0; break; case 'V': printf("%s %s\n", PROGRAM_NAME, VERSION); return EXIT_SUCCESS; default: case 'h': printf("Usage: %s [options] DIRECTORY PROGRAM [ARGS...]\n" "\nThe utility monitors the DIRECTORY and when\n" "new files appear run the PROGRAM.\n\n" "Options:\n" " -p, --pidfile=FILE pid file location;\n" " -l, --logfile=FILE log file;\n" " -L, --loglevel=LVL logging level;\n" " -t, --timeout=SEC number of seconds that need to wait" " for files before the PROGRAM launch;\n" " -f, --foreground stay in the foreground;\n" " -V, --version print program version and exit;\n" " -h, --help show this text and exit.\n" "\n", PROGRAM_NAME); return EXIT_SUCCESS; } } if (optind >= argc) error(EXIT_FAILURE, 0, "You must specify the directory"); eventdir = argv[optind++]; if (optind >= argc) error(EXIT_FAILURE, 0, "You must specify the program"); prog = canonicalize_file_name(argv[optind]); if (!prog) error(EXIT_FAILURE, errno, "Bad program"); argv[optind] = strrchr(prog, '/'); if (!argv[optind]) argv[optind] = prog; prog_args = argv + optind; if (!log_priority) log_priority = logging_level("info"); if (pidfile && check_pid(pidfile)) error(EXIT_FAILURE, 0, "%s: already running", PROGRAM_NAME); if (chdir("/") < 0) error(EXIT_FAILURE, errno, "%s: chdir(/)", PROGRAM_NAME); close(STDIN_FILENO); if ((fd = open("/dev/null", O_RDONLY)) < 0) error(EXIT_FAILURE, errno, "%s: open(/dev/null)", PROGRAM_NAME); if (fd != STDIN_FILENO) { dup2(fd, STDIN_FILENO); close(fd); } if (daemonize && daemon(0, 1) < 0) error(EXIT_FAILURE, errno, "%s: daemon", PROGRAM_NAME); logging_init(); info("starting version %s", VERSION); if (pidfile && write_pid(pidfile) == 0) return EXIT_FAILURE; sigfillset(&mask); sigprocmask(SIG_SETMASK, &mask, &sigmask_orig); sigdelset(&mask, SIGABRT); sigdelset(&mask, SIGSEGV); if ((fd_ep = epoll_create1(EPOLL_CLOEXEC)) < 0) fatal("epoll_create1: %m"); if ((fd_signal = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC)) < 0) fatal("signalfd: %m"); epollin_add(fd_ep, fd_signal); if ((fd_eventdir = inotify_init1(IN_NONBLOCK | IN_CLOEXEC)) < 0) fatal("inotify_init1: %m"); if (inotify_add_watch(fd_eventdir, eventdir, IN_ONLYDIR | IN_DONT_FOLLOW | IN_MOVED_TO | IN_CLOSE_WRITE) < 0) fatal("inotify_add_watch: %m"); epollin_add(fd_ep, fd_eventdir); ignore_timer = is_dir_not_empty(eventdir); if (clock_gettime(CLOCK_MONOTONIC, &now) < 0) fatal("clock_gettime: %m"); last.tv_sec = now.tv_sec; while (!do_exit) { struct epoll_event ev[42]; int i, fdcount; ssize_t size; if ((fdcount = epoll_wait(fd_ep, ev, ARRAY_SIZE(ev), ep_timeout)) < 0) continue; if (!ep_timeout) ep_timeout = timeout * 1000; for (i = 0; i < fdcount; i++) { if (!(ev[i].events & EPOLLIN)) { continue; } else if (ev[i].data.fd == fd_signal) { struct signalfd_siginfo fdsi; size = TEMP_FAILURE_RETRY(read(fd_signal, &fdsi, sizeof(struct signalfd_siginfo))); if (size != sizeof(struct signalfd_siginfo)) { err("unable to read signal info"); continue; } handle_signal(fdsi.ssi_signo); } else if (ev[i].data.fd == fd_eventdir) { read_inotify_events(fd_eventdir); new_events += 1; } } if (new_events) { struct stat sb; new_events = 0; if (lstat(eventdir, &sb) < 0) fatal("lstat: %s: %m", eventdir); if (mtime.tv_sec != sb.st_mtim.tv_sec || mtime.tv_nsec != sb.st_mtim.tv_nsec) { if (clock_gettime(CLOCK_MONOTONIC, &now) < 0) fatal("clock_gettime: %m"); last.tv_sec = now.tv_sec; } mtime.tv_sec = sb.st_mtim.tv_sec; mtime.tv_nsec = sb.st_mtim.tv_nsec; } if (worker_pid) continue; if (!ignore_timer) { if (clock_gettime(CLOCK_MONOTONIC, &now) < 0) fatal("clock_gettime: %m"); if (now.tv_sec < last.tv_sec || (now.tv_sec - last.tv_sec) < timeout) continue; } ignore_timer = 0; if ((worker_pid = spawn_worker(prog, prog_args)) < 0) fatal("spawn_worker: %m"); dbg("Run worker %d", worker_pid); } epollin_remove(fd_ep, fd_signal); epollin_remove(fd_ep, fd_eventdir); free(prog); if (pidfile) remove_pid(pidfile); logging_close(); return EXIT_SUCCESS; }
/*---------------------------------------------------------------------------* * program entry *---------------------------------------------------------------------------*/ int main(int argc, char **argv) { int i; msg_vr_req_t mvr; #ifdef I4B_EXTERNAL_MONITOR int sockfd = -1; /* local monitor socket */ #ifndef I4B_NOTCPIP_MONITOR int remotesockfd = -1; /* tcp/ip monitor socket */ #endif #endif setlocale (LC_ALL, ""); while ((i = getopt(argc, argv, "mc:d:fFlL:Pr:s:t:u:")) != -1) { switch (i) { #ifdef I4B_EXTERNAL_MONITOR case 'm': inhibit_monitor = 1; break; #endif case 'c': configfile = optarg; break; #ifdef DEBUG case 'd': if(*optarg == 'n') debug_noscreen = 1; else if((sscanf(optarg, "%i", &debug_flags)) == 1) do_debug = 1; else usage(); break; #endif case 'f': do_fullscreen = 1; do_fork = 0; #ifndef USE_CURSES fprintf(stderr, "Sorry, no fullscreen mode available - daemon compiled without USE_CURSES\n"); exit(1); #endif break; case 'F': do_fork = 0; break; case 'l': uselogfile = 1; break; case 'L': strlcpy(logfile, optarg, sizeof(logfile)); break; case 'P': do_print = 1; break; case 'r': rdev = optarg; do_rdev = 1; break; case 's': if(isdigit(*optarg)) { int facility; logfacility = strtoul(optarg, NULL, 10); facility = logfacility << 3; if((facility < LOG_KERN) || (facility > LOG_FTP && facility < LOG_LOCAL0) || (facility > LOG_LOCAL7)) { fprintf(stderr, "Error, option -s has invalid logging facility %d", logfacility); usage(); } logfacility = facility; } else { fprintf(stderr, "Error: option -s requires a numeric argument!\n"); usage(); } break; case 't': ttype = optarg; do_ttytype = 1; break; case 'u': if(isdigit(*optarg)) { unit_length = strtoul(optarg, NULL, 10); if(unit_length < ULSRC_CMDLMIN) unit_length = ULSRC_CMDLMIN; else if(unit_length > ULSRC_CMDLMAX) unit_length = ULSRC_CMDLMAX; got_unitlen = 1; } else { fprintf(stderr, "Error: option -T requires a numeric argument!\n"); usage(); } break; case '?': default: usage(); break; } } #ifdef DEBUG if(!do_debug) debug_noscreen = 0; #endif if(!do_print) { umask(UMASK); /* set our umask ... */ init_log(); /* initialize the logging subsystem */ } check_pid(); /* check if we are already running */ if(!do_print) { if(do_fork || (do_fullscreen && do_rdev)) /* daemon mode ? */ daemonize(); write_pid(); /* write our pid to file */ /* set signal handler(s) */ signal(SIGCHLD, sigchild_handler); /* process handling */ signal(SIGHUP, rereadconfig); /* reread configuration */ signal(SIGUSR1, reopenfiles); /* reopen acct/log files*/ signal(SIGPIPE, SIG_IGN); /* handled manually */ signal(SIGINT, do_exit); /* clean up on SIGINT */ signal(SIGTERM, do_exit); /* clean up on SIGTERM */ signal(SIGQUIT, do_exit); /* clean up on SIGQUIT */ } /* open isdn device */ if((isdnfd = open(I4BDEVICE, O_RDWR)) < 0) { dolog(LL_ERR, "main: cannot open %s: %s", I4BDEVICE, strerror(errno)); exit(1); } /* check kernel and userland have same version/release numbers */ if((ioctl(isdnfd, I4B_VR_REQ, &mvr)) < 0) { dolog(LL_ERR, "main: ioctl I4B_VR_REQ failed: %s", strerror(errno)); do_exit(1); } if(mvr.version != VERSION) { dolog(LL_ERR, "main: version mismatch, kernel %d, daemon %d", mvr.version, VERSION); do_exit(1); } if(mvr.release != REL) { dolog(LL_ERR, "main: release mismatch, kernel %d, daemon %d", mvr.release, REL); do_exit(1); } if(mvr.step != STEP) { dolog(LL_ERR, "main: step mismatch, kernel %d, daemon %d", mvr.step, STEP); do_exit(1); } /* init controller state array */ init_controller(); /* read runtime configuration file and configure ourselves */ configure(configfile, 0); if(config_error_flag) { dolog(LL_ERR, "there were %d error(s) in the configuration file, terminating!", config_error_flag); exit(1); } /* set controller ISDN protocol */ init_controller_protocol(); /* init active controllers, if any */ signal(SIGCHLD, SIG_IGN); /*XXX*/ init_active_controller(); signal(SIGCHLD, sigchild_handler); /*XXX*/ /* handle the rates stuff */ if((i = readrates(ratesfile)) == ERROR) { if(rate_error != NULL) dolog(LL_ERR, "%s", rate_error); exit(1); } if(i == GOOD) { got_rate = 1; /* flag, ratesfile read and ok */ DBGL(DL_RCCF, (dolog(LL_DBG, "ratesfile %s read successfully", ratesfile))); } else { if(rate_error != NULL) dolog(LL_WRN, "%s", rate_error); } /* if writing accounting info, open file, set unbuffered */ if(useacctfile) { if((acctfp = fopen(acctfile, "a")) == NULL) { dolog(LL_ERR, "ERROR, can't open acctfile %s for writing, terminating!", acctfile); exit(1); } setvbuf(acctfp, NULL, _IONBF, 0); } /* initialize alias processing */ if(aliasing) init_alias(aliasfile); /* init holidays */ init_holidays(holidayfile); /* init remote monitoring */ #ifdef I4B_EXTERNAL_MONITOR if(do_monitor) { monitor_init(); sockfd = monitor_create_local_socket(); #ifndef I4B_NOTCPIP_MONITOR remotesockfd = monitor_create_remote_socket(monitorport); #endif } #endif /* in case fullscreendisplay, initialize */ #ifdef USE_CURSES if(do_fullscreen) { init_screen(); } #endif /* init realtime priority */ #ifdef USE_RTPRIO if(rt_prio != RTPRIO_NOTUSED) { struct rtprio rtp; rtp.type = RTP_PRIO_REALTIME; rtp.prio = rt_prio; if((rtprio(RTP_SET, getpid(), &rtp)) == -1) { dolog(LL_ERR, "rtprio failed: %s", strerror(errno)); do_exit(1); } } #endif starttime = time(NULL); /* get starttime */ srandom(580403); /* init random number gen */ mloop( /* enter loop of no return .. */ #ifdef I4B_EXTERNAL_MONITOR sockfd #ifndef I4B_NOTCPIP_MONITOR , remotesockfd #endif #endif ); do_exit(0); return(0); }
void *actal_malloc_uncache(int size,void *phy_add) { int prot = PROT_READ | PROT_WRITE; int map_flags = MAP_SHARED; ion_user_handle_t handle; int map_fd, ret; void *ptr; ALOGI("[memory_malloc] actal_malloc_uncache: size: %d", size); if(size <= 0){ ALOGE("actal_malloc_uncache: size must be positive\n"); return NULL; //-EINVAL; } check_pid(); // actal_printf_list(); // actal_error("s_fd = %d\n", s_fd); if (size & ALIGN_MASK) { //4k对齐 size += (ALIGN_BYTES - (size & ALIGN_MASK)); } struct actal_mem * user_p; user_p = (struct actal_mem*)malloc(sizeof(struct actal_mem)); user_p->next = NULL; ret = ion_alloc(s_fd, size, 0, 1, 0, &handle); if(ret < 0) { ALOGE("actal_malloc_uncache: ion_alloc(size: %d) failed(%d)\n", size, ret); return NULL; } // ALOGD("handle :%#X\n", handle); ret = ion_map(s_fd , handle, size, prot, map_flags, 0, (unsigned char **)&ptr, &map_fd); user_p->handle = handle; user_p->len = size; user_p->fd = s_fd; user_p->ptr = ptr; user_p->map_fd = map_fd; user_p->flag = 0; ret = ion_phys(s_fd, handle,(unsigned long*)phy_add); if(ret < 0){ actal_error("actal_malloc_wt: get phy_addr error!\n"); return NULL; } user_p->phy_add = *((long*)phy_add); //避免线程冲突 if (pthread_mutex_lock(&mutex) != 0) { ALOGE("get mutex failed"); return NULL; } if(s_top_p == NULL) //处理头结点,头结点置空 { s_current_p = s_top_p = (struct actal_mem*)malloc(sizeof(struct actal_mem)); s_top_p->fd = 0; s_top_p->ptr = NULL; s_top_p->map_fd = 0; s_top_p->handle = -1; s_top_p->len = 0; s_top_p->phy_add = 0; s_top_p->flag = 0; } s_current_p->next = user_p; s_current_p = user_p; if (pthread_mutex_unlock(&mutex) != 0) { ALOGE("actal_malloc_wt: free mutex failed"); return NULL; } // ALOGD("malloc_uncache: ptr = %#X, phy_add = %#X, size = %d\n", (unsigned int)ptr, *phy_add, size); return (void *)ptr; }
static int continue_as_daemon() { int nullfd; printf("Closing stdin, stdout, stderr and going into background.\n"); switch (fork()) { case 0: break; case -1: DEBUG_CMD(Debug_Message("ERROR: fork() failed %d - %s", errno, strerror(errno))); return EXIT_FAILURE; break; default: _exit(0); break; } if (setsid() == -1) { DEBUG_CMD(Debug_Message("ERROR: setsid() failed %d - %s", errno, strerror(errno))); return EXIT_FAILURE; } setpgrp(); switch (fork()) { case 0: break; case -1: DEBUG_CMD(Debug_Message("ERROR: fork() failed %d - %s", errno, strerror(errno))); return EXIT_FAILURE; break; default: _exit(0); break; } if (!check_pid(PIDFILE)) { if (write_pid(PIDFILE)) { (void) atexit(remove_pidfile); } else { printf("Could not write pidfile\n"); } } else { /* A mapid already running and owning pidfile */ printf("A mapid is already running. Leaving pidfile alone\n"); } chdir("/"); nullfd = open("/dev/null", O_RDONLY); dup2(nullfd, STDIN_FILENO); close(nullfd); nullfd = open("/dev/null", O_WRONLY); dup2(nullfd, STDOUT_FILENO); dup2(nullfd, STDERR_FILENO); close(nullfd); return EXIT_SUCCESS; }
/** Run the daemon. * @param[in] argc Number of arguments in \a argv. * @param[in] argv Arguments to program execution. */ int main(int argc, char **argv) { CurrentTime = time(NULL); thisServer.argc = argc; thisServer.argv = argv; thisServer.uid = getuid(); thisServer.euid = geteuid(); #ifdef MDEBUG mem_dbg_initialise(); #endif #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_CORE) set_core_limit(); #endif umask(077); /* better safe than sorry --SRB */ memset(&me, 0, sizeof(me)); memset(&me_con, 0, sizeof(me_con)); cli_connect(&me) = &me_con; cli_fd(&me) = -1; parse_command_line(argc, argv); if (chdir(dpath)) { fprintf(stderr, "Fail: Cannot chdir(%s): %s, check DPATH\n", dpath, strerror(errno)); return 2; } if (!set_userid_if_needed()) return 3; /* Check paths for accessibility */ if (!check_file_access(SPATH, 'S', X_OK) || !check_file_access(configfile, 'C', R_OK)) return 4; if (!init_connection_limits()) return 9; close_connections(!(thisServer.bootopt & (BOOT_DEBUG | BOOT_TTY | BOOT_CHKCONF))); /* daemon_init() must be before event_init() because kqueue() FDs * are, perversely, not inherited across fork(). */ daemon_init(thisServer.bootopt & BOOT_TTY); #ifdef DEBUGMODE /* Must reserve fd 2... */ if (debuglevel >= 0 && !(thisServer.bootopt & BOOT_TTY)) { int fd; if ((fd = open("/dev/null", O_WRONLY)) < 0) { fprintf(stderr, "Unable to open /dev/null (to reserve fd 2): %s\n", strerror(errno)); return 8; } if (fd != 2 && dup2(fd, 2) < 0) { fprintf(stderr, "Unable to reserve fd 2; dup2 said: %s\n", strerror(errno)); return 8; } } #endif event_init(MAXCONNECTIONS); setup_signals(); feature_init(); /* initialize features... */ log_init(*argv); set_nomem_handler(outofmemory); initload(); init_list(); init_hash(); init_class(); initwhowas(); initmsgtree(); initstats(); /* we need this for now, when we're modular this should be removed -- hikari */ ircd_crypt_init(); motd_init(); if (!init_conf()) { log_write(LS_SYSTEM, L_CRIT, 0, "Failed to read configuration file %s", configfile); return 7; } if (thisServer.bootopt & BOOT_CHKCONF) { if (dbg_client) conf_debug_iline(dbg_client); fprintf(stderr, "Configuration file %s checked okay.\n", configfile); return 0; } debug_init(thisServer.bootopt & BOOT_TTY); if (check_pid()) { Debug((DEBUG_FATAL, "Failed to acquire PID file lock after fork")); exit(2); } init_server_identity(); uping_init(); stats_init(); IPcheck_init(); timer_add(timer_init(&connect_timer), try_connections, 0, TT_RELATIVE, 1); timer_add(timer_init(&ping_timer), check_pings, 0, TT_RELATIVE, 1); timer_add(timer_init(&destruct_event_timer), exec_expired_destruct_events, 0, TT_PERIODIC, 60); timer_add(timer_init(&mute_timer), check_expired_mutes, 0, TT_PERIODIC, 30); CurrentTime = time(NULL); SetMe(&me); cli_magic(&me) = CLIENT_MAGIC; cli_from(&me) = &me; make_server(&me); cli_serv(&me)->timestamp = TStime(); /* Abuse own link timestamp as start TS */ cli_serv(&me)->prot = atoi(MAJOR_PROTOCOL); cli_serv(&me)->up = &me; cli_serv(&me)->down = NULL; cli_handler(&me) = SERVER_HANDLER; SetYXXCapacity(&me, MAXCLIENTS); cli_lasttime(&me) = cli_since(&me) = cli_firsttime(&me) = CurrentTime; hAddClient(&me); write_pidfile(); init_counters(); Debug((DEBUG_NOTICE, "Server ready...")); log_write(LS_SYSTEM, L_NOTICE, 0, "Server Ready"); event_loop(); return 0; }
static int child(arg_data *args, home_data *data, uid_t uid, gid_t gid) { int ret = 0; /* check the pid file */ ret = check_pid(args); if (args->vers != true && args->chck != true) { if (ret == 122) return ret; if (ret < 0) return ret; } #ifdef OS_LINUX /* setuid()/setgid() only apply the current thread so we must do it now */ if (linuxset_user_group(args->user, uid, gid) != 0) return 4; #endif /* Initialize the Java VM */ if (java_init(args, data) != true) { log_debug("java_init failed"); return 1; } else log_debug("java_init done"); /* Check wether we need to dump the VM version */ if (args->vers == true) { log_error("jsvc (Apache Commons Daemon) " JSVC_VERSION_STRING); log_error("Copyright (c) 1999-2011 Apache Software Foundation."); if (java_version() != true) { return -1; } else return 0; } /* Check wether we need to dump the VM version */ else if (args->vershow == true) { if (java_version() != true) { return 7; } } /* Do we have to do a "check-only" initialization? */ if (args->chck == true) { if (java_check(args) != true) return 2; printf("Service \"%s\" checked successfully\n", args->clas); return 0; } /* Load the service */ if (java_load(args) != true) { log_debug("java_load failed"); return 3; } else log_debug("java_load done"); /* Downgrade user */ #ifdef OS_LINUX if (args->user && set_caps(0) != 0) { log_debug("set_caps (0) failed"); return 4; } #else if (set_user_group(args->user, uid, gid) != 0) return 4; #endif /* Start the service */ umask(envmask); if (java_start() != true) { log_debug("java_start failed"); return 5; } else log_debug("java_start done"); /* Install signal handlers */ handler_hup = signal_set(SIGHUP, handler); handler_usr1 = signal_set(SIGUSR1, handler); handler_usr2 = signal_set(SIGUSR2, handler); handler_trm = signal_set(SIGTERM, handler); handler_int = signal_set(SIGINT, handler); controlled = getpid(); log_debug("Waiting for a signal to be delivered"); create_tmp_file(args); while (!stopping) { #if defined(OSD_POSIX) java_sleep(60); /* pause(); */ #else /* pause() is not threadsafe */ sleep(60); #endif if(doreopen) { doreopen = false; set_output(args->outfile, args->errfile, args->redirectstdin, args->procname); } if(dosignal) { dosignal = false; java_signal(); } } remove_tmp_file(args); log_debug("Shutdown or reload requested: exiting"); /* Stop the service */ if (java_stop() != true) return 6; if (doreload == true) ret = 123; else ret = 0; /* Destroy the service */ java_destroy(); /* Destroy the Java VM */ if (JVM_destroy(ret) != true) return 7; return ret; }
int main (int argc, char **argv) { starter_config_t *cfg = NULL; starter_config_t *new_cfg; starter_conn_t *conn, *conn2; starter_ca_t *ca, *ca2; struct sigaction action; struct stat stb; int i; int id = 1; struct timespec ts; unsigned long auto_update = 0; time_t last_reload; bool no_fork = FALSE; bool attach_gdb = FALSE; bool load_warning = FALSE; library_init(NULL); atexit(library_deinit); libhydra_init("starter"); atexit(libhydra_deinit); /* parse command line */ for (i = 1; i < argc; i++) { if (streq(argv[i], "--debug")) { current_loglevel = 2; } else if (streq(argv[i], "--debug-more")) { current_loglevel = 3; } else if (streq(argv[i], "--debug-all")) { current_loglevel = 4; } else if (streq(argv[i], "--nolog")) { current_loglevel = 0; } else if (streq(argv[i], "--nofork")) { no_fork = TRUE; } else if (streq(argv[i], "--attach-gdb")) { no_fork = TRUE; attach_gdb = TRUE; } else if (streq(argv[i], "--auto-update") && i+1 < argc) { auto_update = atoi(argv[++i]); if (!auto_update) usage(argv[0]); } else if (streq(argv[i], "--daemon") && i+1 < argc) { daemon_name = argv[++i]; } else { usage(argv[0]); } } if (!set_daemon_name()) { DBG1(DBG_APP, "unable to set daemon name"); exit(LSB_RC_FAILURE); } init_log("ipsec_starter"); DBG1(DBG_APP, "Starting %sSwan "VERSION" IPsec [starter]...", lib->settings->get_bool(lib->settings, "charon.i_dont_care_about_security_and_use_aggressive_mode_psk", FALSE) ? "weak" : "strong"); #ifdef LOAD_WARNING load_warning = TRUE; #endif if (lib->settings->get_bool(lib->settings, "starter.load_warning", load_warning)) { if (lib->settings->get_str(lib->settings, "charon.load", NULL)) { DBG1(DBG_APP, "!! Your strongswan.conf contains manual plugin load options for charon."); DBG1(DBG_APP, "!! This is recommended for experts only, see"); DBG1(DBG_APP, "!! http://wiki.strongswan.org/projects/strongswan/wiki/PluginLoad"); } } /* verify that we can start */ if (getuid() != 0) { DBG1(DBG_APP, "permission denied (must be superuser)"); cleanup(); exit(LSB_RC_NOT_ALLOWED); } if (check_pid(pid_file)) { DBG1(DBG_APP, "%s is already running (%s exists) -- skipping daemon start", daemon_name, pid_file); } else { _action_ |= FLAG_ACTION_START_CHARON; } if (stat(DEV_RANDOM, &stb) != 0) { DBG1(DBG_APP, "unable to start strongSwan IPsec -- no %s!", DEV_RANDOM); cleanup(); exit(LSB_RC_FAILURE); } if (stat(DEV_URANDOM, &stb)!= 0) { DBG1(DBG_APP, "unable to start strongSwan IPsec -- no %s!", DEV_URANDOM); cleanup(); exit(LSB_RC_FAILURE); } cfg = confread_load(CONFIG_FILE); if (cfg == NULL || cfg->err > 0) { DBG1(DBG_APP, "unable to start strongSwan -- fatal errors in config"); if (cfg) { confread_free(cfg); } cleanup(); exit(LSB_RC_INVALID_ARGUMENT); } /* determine if we have a native netkey IPsec stack */ if (!starter_netkey_init()) { DBG1(DBG_APP, "no netkey IPsec stack detected"); if (!starter_klips_init()) { DBG1(DBG_APP, "no KLIPS IPsec stack detected"); DBG1(DBG_APP, "no known IPsec stack detected, ignoring!"); } } last_reload = time_monotonic(NULL); if (check_pid(starter_pid_file)) { DBG1(DBG_APP, "starter is already running (%s exists) -- no fork done", starter_pid_file); confread_free(cfg); cleanup(); exit(LSB_RC_SUCCESS); } #ifdef GENERATE_SELFCERT generate_selfcert(); #endif /* fork if we're not debugging stuff */ if (!no_fork) { log_to_stderr = FALSE; switch (fork()) { case 0: { int fnull; close_log(); closefrom(3); fnull = open("/dev/null", O_RDWR); if (fnull >= 0) { dup2(fnull, STDIN_FILENO); dup2(fnull, STDOUT_FILENO); dup2(fnull, STDERR_FILENO); close(fnull); } setsid(); init_log("ipsec_starter"); } break; case -1: DBG1(DBG_APP, "can't fork: %s", strerror(errno)); break; default: confread_free(cfg); cleanup(); exit(LSB_RC_SUCCESS); } } /* save pid file in /var/run/starter[.daemon_name].pid */ { FILE *fd = fopen(starter_pid_file, "w"); if (fd) { fprintf(fd, "%u\n", getpid()); fclose(fd); } } /* we handle these signals only in pselect() */ memset(&action, 0, sizeof(action)); sigemptyset(&action.sa_mask); sigaddset(&action.sa_mask, SIGHUP); sigaddset(&action.sa_mask, SIGINT); sigaddset(&action.sa_mask, SIGTERM); sigaddset(&action.sa_mask, SIGQUIT); sigaddset(&action.sa_mask, SIGALRM); sigaddset(&action.sa_mask, SIGUSR1); pthread_sigmask(SIG_SETMASK, &action.sa_mask, NULL); /* install a handler for fatal signals */ action.sa_handler = fatal_signal_handler; sigaction(SIGSEGV, &action, NULL); sigaction(SIGILL, &action, NULL); sigaction(SIGBUS, &action, NULL); action.sa_handler = SIG_IGN; sigaction(SIGPIPE, &action, NULL); /* install main signal handler */ action.sa_handler = signal_handler; sigaction(SIGHUP, &action, NULL); sigaction(SIGINT, &action, NULL); sigaction(SIGTERM, &action, NULL); sigaction(SIGQUIT, &action, NULL); sigaction(SIGALRM, &action, NULL); sigaction(SIGUSR1, &action, NULL); /* this is not blocked above as we want to receive it asynchronously */ sigaction(SIGCHLD, &action, NULL); /* empty mask for pselect() call below */ sigemptyset(&action.sa_mask); for (;;) { /* * Stop charon (if started) and exit */ if (_action_ & FLAG_ACTION_QUIT) { if (starter_charon_pid()) { starter_stop_charon(); } starter_netkey_cleanup(); confread_free(cfg); unlink(starter_pid_file); cleanup(); DBG1(DBG_APP, "ipsec starter stopped"); close_log(); exit(LSB_RC_SUCCESS); } /* * Delete all connections. Will be added below */ if (_action_ & FLAG_ACTION_RELOAD) { if (starter_charon_pid()) { for (conn = cfg->conn_first; conn; conn = conn->next) { if (conn->state == STATE_ADDED) { if (starter_charon_pid()) { if (conn->startup == STARTUP_ROUTE) { starter_stroke_unroute_conn(conn); } starter_stroke_del_conn(conn); } conn->state = STATE_TO_ADD; } } for (ca = cfg->ca_first; ca; ca = ca->next) { if (ca->state == STATE_ADDED) { if (starter_charon_pid()) { starter_stroke_del_ca(ca); } ca->state = STATE_TO_ADD; } } } _action_ &= ~FLAG_ACTION_RELOAD; } /* * Update configuration */ if (_action_ & FLAG_ACTION_UPDATE) { DBG2(DBG_APP, "Reloading config..."); new_cfg = confread_load(CONFIG_FILE); if (new_cfg && (new_cfg->err == 0)) { /* Switch to new config. New conn will be loaded below */ /* Look for new connections that are already loaded */ for (conn = cfg->conn_first; conn; conn = conn->next) { if (conn->state == STATE_ADDED) { for (conn2 = new_cfg->conn_first; conn2; conn2 = conn2->next) { if (conn2->state == STATE_TO_ADD && starter_cmp_conn(conn, conn2)) { conn->state = STATE_REPLACED; conn2->state = STATE_ADDED; conn2->id = conn->id; break; } } } } /* Remove conn sections that have become unused */ for (conn = cfg->conn_first; conn; conn = conn->next) { if (conn->state == STATE_ADDED) { if (starter_charon_pid()) { if (conn->startup == STARTUP_ROUTE) { starter_stroke_unroute_conn(conn); } starter_stroke_del_conn(conn); } } } /* Look for new ca sections that are already loaded */ for (ca = cfg->ca_first; ca; ca = ca->next) { if (ca->state == STATE_ADDED) { for (ca2 = new_cfg->ca_first; ca2; ca2 = ca2->next) { if (ca2->state == STATE_TO_ADD && starter_cmp_ca(ca, ca2)) { ca->state = STATE_REPLACED; ca2->state = STATE_ADDED; break; } } } } /* Remove ca sections that have become unused */ for (ca = cfg->ca_first; ca; ca = ca->next) { if (ca->state == STATE_ADDED) { if (starter_charon_pid()) { starter_stroke_del_ca(ca); } } } confread_free(cfg); cfg = new_cfg; } else { DBG1(DBG_APP, "can't reload config file due to errors -- keeping old one"); if (new_cfg) { confread_free(new_cfg); } } _action_ &= ~FLAG_ACTION_UPDATE; last_reload = time_monotonic(NULL); } /* * Start daemon */ if (_action_ & FLAG_ACTION_START_CHARON) { if (cfg->setup.charonstart && !starter_charon_pid()) { DBG2(DBG_APP, "Attempting to start %s...", daemon_name); if (starter_start_charon(cfg, no_fork, attach_gdb)) { /* schedule next try */ alarm(CHARON_RESTART_DELAY); } starter_stroke_configure(cfg); } _action_ &= ~FLAG_ACTION_START_CHARON; for (ca = cfg->ca_first; ca; ca = ca->next) { if (ca->state == STATE_ADDED) { ca->state = STATE_TO_ADD; } } for (conn = cfg->conn_first; conn; conn = conn->next) { if (conn->state == STATE_ADDED) { conn->state = STATE_TO_ADD; } } } /* * Add stale conn and ca sections */ if (starter_charon_pid()) { for (ca = cfg->ca_first; ca; ca = ca->next) { if (ca->state == STATE_TO_ADD) { if (starter_charon_pid()) { starter_stroke_add_ca(ca); } ca->state = STATE_ADDED; } } for (conn = cfg->conn_first; conn; conn = conn->next) { if (conn->state == STATE_TO_ADD) { if (conn->id == 0) { /* affect new unique id */ conn->id = id++; } if (starter_charon_pid()) { starter_stroke_add_conn(cfg, conn); } conn->state = STATE_ADDED; if (conn->startup == STARTUP_START) { if (starter_charon_pid()) { starter_stroke_initiate_conn(conn); } } else if (conn->startup == STARTUP_ROUTE) { if (starter_charon_pid()) { starter_stroke_route_conn(conn); } } } } } /* * If auto_update activated, when to stop select */ if (auto_update) { time_t now = time_monotonic(NULL); ts.tv_sec = (now < last_reload + auto_update) ? (last_reload + auto_update - now) : 0; ts.tv_nsec = 0; } /* * Wait for something to happen */ if (!_action_ && pselect(0, NULL, NULL, NULL, auto_update ? &ts : NULL, &action.sa_mask) == 0) { /* timeout -> auto_update */ _action_ |= FLAG_ACTION_UPDATE; } } exit(LSB_RC_SUCCESS); }
int client(char *pid, char *msg) { if (check_pid(pid) || send_msg(pid, msg)) return (1); return (0); }
void process_commandline(int argc, char **argv, SMSD_Parameters * params) { int opt; #ifdef HAVE_GETOPT_LONG struct option long_options[] = { {"help", 0, 0, 'h'}, {"version", 0, 0, 'v'}, {"config", 1, 0, 'c'}, {"daemon", 0, 0, 'd'}, {"pid", 1, 0, 'p'}, {"install-service", 0, 0, 'i'}, {"uninstall-service", 0, 0, 'u'}, {"start-service", 0, 0, 's'}, {"stop-service", 0, 0, 'k'}, {"run-as-service", 0, 0, 'S'}, {"user", 1, 0, 'U'}, {"group", 1, 0, 'G'}, {"service-name", 1, 0, 'n'}, {"suicide", 1, 0, 'X'}, {"max-failures", 1, 0, 'f'}, {"use-log", 0, 0, 'l'}, {"no-use-log", 0, 0, 'L'}, {"install-event-log", 0, 0, 'e'}, {"uninstall-event-log", 0, 0, 'E'}, {0, 0, 0, 0} }; int option_index; while ((opt = getopt_long(argc, argv, "hvdc:p:iusSkU:G:n:X:f:lLeE", long_options, &option_index)) != -1) { #elif defined(HAVE_GETOPT) while ((opt = getopt(argc, argv, "hvdc:p:iusSkU:G:n:X:f:lLeE")) != -1) { #else /* Poor mans getopt replacement */ int i; #define optarg argv[++i] for (i = 1; i < argc; i++) { if (strlen(argv[i]) != 2 || argv[i][0] != '-') { wrong_params(); } opt = argv[i][1]; #endif switch (opt) { case 'c': params->config_file = optarg; break; #ifdef HAVE_PIDFILE case 'p': params->pid_file = optarg; break; #endif #ifdef HAVE_UID case 'U': if (!fill_uid(params, optarg)) { fprintf(stderr, "Wrong user name/ID!\n"); exit(1); } break; case 'G': if (!fill_gid(params, optarg)) { fprintf(stderr, "Wrong group name/ID!\n"); exit(1); } break; #endif case 'f': params->max_failures = atoi(optarg); break; #ifdef HAVE_ALARM case 'X': alarm(atoi(optarg)); break; #endif #ifdef HAVE_DAEMON case 'd': params->daemonize = TRUE; break; #endif #ifdef HAVE_WINDOWS_EVENT_LOG case 'e': params->install_evlog = TRUE; break; case 'E': params->uninstall_evlog = TRUE; break; #endif #ifdef HAVE_WINDOWS_SERVICE case 'i': params->install_service = TRUE; break; case 'u': params->uninstall_service = TRUE; break; case 's': params->start_service = TRUE; break; case 'k': params->stop_service = TRUE; break; case 'S': params->run_service = TRUE; break; case 'n': strncpy(smsd_service_name, optarg, SERVICE_NAME_LENGTH); smsd_service_name[SERVICE_NAME_LENGTH - 1] = 0; break; #endif case 'v': version(); break; case 'l': params->use_log = TRUE; break; case 'L': params->use_log = FALSE; break; case '?': wrong_params(); case 'h': help(); exit(0); default: wrong_params(); break; } } #if defined(HAVE_GETOPT) || defined(HAVE_GETOPT_LONG) if (optind < argc) { wrong_params(); } #endif } void configure_daemon(SMSD_Parameters * params) { signal(SIGINT, smsd_interrupt); signal(SIGTERM, smsd_interrupt); #ifdef HAVE_SIGHUP signal(SIGHUP, smsd_reconfigure); #endif #ifdef HAVE_ALARM signal(SIGALRM, smsd_interrupt); #endif #if defined(HAVE_SIGUSR1) && defined(HAVE_SIGUSR2) signal(SIGUSR1, smsd_standby); signal(SIGUSR2, smsd_resume); #endif #ifdef HAVE_DAEMON /* Daemonize has to be before writing PID as it changes it */ if (params->daemonize) { if (daemon(1, 0) != 0) { fprintf(stderr, "daemonizing failed! (%s)\n", strerror(errno)); exit(1); } } #endif #ifdef HAVE_PIDFILE /* Writing PID file has to happen before dropping privileges */ if (params->pid_file != NULL && strlen(params->pid_file) > 0) { check_pid(params->pid_file); write_pid(params->pid_file); } #endif #ifdef HAVE_UID if (params->gid != -1 || params->uid != -1) { if (!set_uid_gid(params)) { fprintf(stderr, "changing uid/gid failed! (%s)\n", strerror(errno)); exit(1); } } #endif #ifdef HAVE_WINDOWS_SERVICE if (params->run_service) { if (!start_smsd_service_dispatcher()) { printf("Error starting %s service\n", smsd_service_name); service_print_error("Error running service"); exit(1); } SMSD_FreeConfig(config); exit(0); } #endif } int main(int argc, char **argv) { GSM_Error error; const char program_name[] = "gammu-smsd"; SMSD_Parameters params = { NULL, NULL, -1, -1, NULL, NULL, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, 0 }; /* * We don't need gettext, but need to set locales so that * charset conversion works. */ GSM_InitLocales(NULL); process_commandline(argc, argv, ¶ms); #ifdef HAVE_WINDOWS_SERVICE if (params.stop_service) { if (stop_smsd_service()) { printf("Service %s stopped sucessfully\n", smsd_service_name); exit(0); } else { printf("Error stopping %s service\n", smsd_service_name); service_print_error("Error stopping service"); exit(1); } } if (params.uninstall_service) { if (uninstall_smsd_service()) { printf("Service %s uninstalled sucessfully\n", smsd_service_name); exit(0); } else { printf("Error uninstalling %s service\n", smsd_service_name); service_print_error("Error uninstalling service"); exit(1); } } #endif #ifdef HAVE_WINDOWS_EVENT_LOG if (params.install_evlog) { if (eventlog_register()) { printf("Installed event log description\n"); exit(0); } else { printf("Failed to install event log description!\n"); exit(1); } } if (params.uninstall_evlog) { if (eventlog_deregister()) { printf("Uninstalled event log description\n"); exit(0); } else { printf("Failed to uninstall event log description!\n"); exit(1); } } #endif if (params.config_file == NULL) { #ifdef HAVE_DEFAULT_CONFIG params.config_file = default_config; #else fprintf(stderr, "No config file specified!\n"); help(); exit(1); #endif } #ifdef HAVE_WINDOWS_SERVICE if (params.install_service) { if (install_smsd_service(¶ms)) { printf("Service %s installed sucessfully\n", smsd_service_name); exit(0); } else { printf("Error installing %s service\n", smsd_service_name); service_print_error("Error installing service"); exit(1); } } if (params.start_service) { if (start_smsd_service()) { printf("Service %s started sucessfully\n", smsd_service_name); exit(0); } else { printf("Error starting %s service\n", smsd_service_name); service_print_error("Error starting service"); exit(1); } } #endif read_config: config = SMSD_NewConfig(program_name); assert(config != NULL); error = SMSD_ReadConfig(params.config_file, config, params.use_log); if (error != ERR_NONE) { printf("Failed to read config: %s\n", GSM_ErrorString(error)); SMSD_FreeConfig(config); return 2; } if (!reconfigure) configure_daemon(¶ms); reconfigure = FALSE; standby = FALSE; error = SMSD_MainLoop(config, FALSE, params.max_failures); if (error != ERR_NONE) { printf("Failed to run SMSD: %s\n", GSM_ErrorString(error)); SMSD_FreeConfig(config); return 2; } SMSD_FreeConfig(config); /* * Wait while we should be suspended. * Later we fall back to reconfigure bellow. */ while (standby) { sleep(1); } if (reconfigure) { goto read_config; } return 0; }
int main(int argc, char *argv[], char *envp[]) { log_open(LOG_FILE); FM_LOG_TRACE("---"); check_pid(); int sockfd; socklen_t clilen; struct sockaddr_in serv_addr{}; struct sockaddr_in cli_addr{}; const char *cfg_file; if (argc > 1) { cfg_file = argv[1]; } else { cfg_file = DEFAULT_CFG_FILE; } read_config(cfg_file); FM_LOG_TRACE("read_config"); sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { fatal_error("ERROR opening socket"); } FM_LOG_TRACE("socket"); bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; if (inet_aton(oj_config.ip, &serv_addr.sin_addr) == 0) { serv_addr.sin_addr.s_addr = INADDR_ANY; } serv_addr.sin_port = htons(oj_config.port); FM_LOG_NOTICE("IP address: %s %s", oj_config.ip, inet_ntoa(serv_addr.sin_addr)); FM_LOG_NOTICE("port: %d %d", oj_config.port, ntohs(serv_addr.sin_port)); int yes = 1; if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { fatal_error("setsockopt SO_REUSEADDR failed"); } if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { fatal_error("ERROR on binding"); } FM_LOG_TRACE("bind"); clilen = sizeof(cli_addr); if (listen(sockfd, oj_config.backlog) < 0) { fatal_error("ERROR on listening"); } FM_LOG_NOTICE("listen backlog: %d", oj_config.backlog); if (daemon(0, 0) == -1) { FM_LOG_FATAL("Cannot daemonize"); pidfile_remove(pfh); exit(EXIT_FAILURE); } print_word_dir(); print_user_group(); pidfile_write(pfh); struct sigaction sa{}; sa.sa_handler = signal_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if (sigaction(SIGTERM, &sa, nullptr) == -1) { // install signal hander for timeout FM_LOG_FATAL("cannot handle SIGTERM"); exit(EXIT_FAILURE); } else { FM_LOG_DEBUG("set signal_handler"); } for (int i = 0; i < oj_config.thread_num; i++) { std::thread t(ThreadWork); t.detach(); } FM_LOG_NOTICE("thread count: %d", oj_config.thread_num); std::thread(SendWork).detach(); while (isRunning) { int newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); if (newsockfd != -1) { work(newsockfd, cli_addr); } } pidfile_remove(pfh); close(sockfd); return 0; }