void doanddie(char *user, unsigned int userlen /* including 0 byte */, char *pass) { int child; int wstat; int pi[2]; close(3); if (pipe(pi) == -1) die_pipe(); if (pi[0] != 3) die_pipe(); switch(child = fork()) { case -1: die_fork(); case 0: close(pi[1]); sig_pipedefault(); execvp(*childargs,childargs); _exit(1); } close(pi[0]); substdio_fdbuf(&ssup,subwrite,pi[1],upbuf,sizeof upbuf); if (substdio_put(&ssup,user,userlen) == -1) die_write(); if (substdio_put(&ssup,pass,str_len(pass) + 1) == -1) die_write(); if (substdio_puts(&ssup,"<") == -1) die_write(); if (substdio_puts(&ssup,unique) == -1) die_write(); if (substdio_puts(&ssup,hostname) == -1) die_write(); if (substdio_put(&ssup,">",2) == -1) die_write(); if (substdio_flush(&ssup) == -1) die_write(); close(pi[1]); byte_zero(pass,str_len(pass)); byte_zero(upbuf,sizeof upbuf); if (wait_pid(&wstat,child) == -1) die(); if (wait_crashed(wstat)) die_childcrashed(); switch (wait_exitcode(wstat)) { case 0: die(); case 1: die_1(); case 2: die_2(); case 25: die_25(); case 3: die_3(); case 4: die_4(); case 5: die_5(); case 6: die_6(); case 61: die_61(); case 62: die_62(); case 7: die_7(); case 8: die_nomem(); default: die_unknown(); } die(); }
int main(int argc,const char * const *argv,const char * const *envp) { char ch; int wstat; int pi[2]; int i; int ignored; if (!argv[1]) strerr_die1x(100,"fghack: usage: fghack child"); if (pipe(pi) == -1) strerr_die2sys(111,FATAL,"unable to create pipe: "); switch(pid = fork()) { case -1: strerr_die2sys(111,FATAL,"unable to fork: "); case 0: close(pi[0]); for (i = 0;i < 30;++i) ignored = dup(pi[1]); pathexec_run(argv[1],argv + 1,envp); strerr_die4sys(111,FATAL,"unable to run ",argv[1],": "); } close(pi[1]); for (;;) { i = buffer_unixread(pi[0],&ch,1); if ((i == -1) && (errno == error_intr)) continue; if (i == 1) continue; break; } if (wait_pid(&wstat,pid) == -1) strerr_die2sys(111,FATAL,"wait failed: "); if (wait_crashed(wstat)) strerr_die2x(111,FATAL,"child crashed"); _exit(wait_exitcode(wstat)); }
void pbsexec(void) { char *(args[3]); int child, wstat; if (pbstool == 0 || *pbstool == 0) return; if (env_get("NOPBS")) return; switch (child = fork()) { case -1: return; case 0: /* the pbstool may not read or write to the connection */ close(0); open_read("/dev/null"); close(1); open_write("/dev/null"); close(3); args[0] = pbstool; args[1] = 0; execvp(*args, args); _exit(111); } wait_pid(&wstat,child); if (wait_crashed(wstat)) logit(2, "pbsexec: %s crashed\n", pbstool); else if (wait_exitcode(wstat)) logit(2, "pbsexec: %s failed, exit code %d\n", pbstool, wait_exitcode(wstat)); else logit(64, "pbsexec: %s OK\n", pbstool); return; }
int main (int argc, const char * const *argv, char * const *envp) { const char * prog[2]; int pid, pid2; int wstat; int st; iopause_fd x; #ifndef IOPAUSE_POLL fd_set rfds; struct timeval t; #endif char ch; int ttyfd; struct stat s; if (getpid() != 1) strerr_die2x(111, FATAL, "must be run as process no 1."); setsid(); sig_block(sig_alarm); sig_block(sig_child); sig_catch(sig_child, sig_child_handler); sig_block(sig_cont); sig_catch(sig_cont, sig_cont_handler); sig_block(sig_hangup); sig_block(sig_int); sig_catch(sig_int, sig_int_handler); sig_block(sig_pipe); sig_block(sig_term); /* console */ if ((ttyfd =open_write("/dev/console")) != -1) { dup2(ttyfd, 0); dup2(ttyfd, 1); dup2(ttyfd, 2); if (ttyfd > 2) close(ttyfd); } /* create selfpipe */ while (pipe(selfpipe) == -1) { strerr_warn2(FATAL, "unable to create selfpipe, pausing: ", &strerr_sys); sleep(5); } coe(selfpipe[0]); coe(selfpipe[1]); ndelay_on(selfpipe[0]); ndelay_on(selfpipe[1]); #ifdef RB_DISABLE_CAD /* activate ctrlaltdel handling, glibc, dietlibc */ if (RB_DISABLE_CAD == 0) reboot_system(0); #endif strerr_warn3(INFO, "$Id: 25da3b86f7bed4038b8a039d2f8e8c9bbcf0822b $", ": booting.", 0); /* runit */ for (st =0; st < 3; st++) { /* if (st == 2) logwtmp("~", "reboot", ""); */ while ((pid =fork()) == -1) { strerr_warn4(FATAL, "unable to fork for \"", stage[st], "\" pausing: ", &strerr_sys); sleep(5); } if (!pid) { /* child */ prog[0] =stage[st]; prog[1] =0; /* stage 1 gets full control of console */ if (st == 0) { if ((ttyfd =open("/dev/console", O_RDWR)) != -1) { #ifdef TIOCSCTTY ioctl(ttyfd, TIOCSCTTY, (char *)0); #endif dup2(ttyfd, 0); if (ttyfd > 2) close(ttyfd); } else strerr_warn2(WARNING, "unable to open /dev/console: ", &strerr_sys); } else setsid(); sig_unblock(sig_alarm); sig_unblock(sig_child); sig_uncatch(sig_child); sig_unblock(sig_cont); sig_ignore(sig_cont); sig_unblock(sig_hangup); sig_unblock(sig_int); sig_uncatch(sig_int); sig_unblock(sig_pipe); sig_unblock(sig_term); strerr_warn3(INFO, "enter stage: ", stage[st], 0); execve(*prog, (char *const *)prog, envp); strerr_die4sys(0, FATAL, "unable to start child: ", stage[st], ": "); } x.fd =selfpipe[0]; x.events =IOPAUSE_READ; for (;;) { int child; sig_unblock(sig_child); sig_unblock(sig_cont); sig_unblock(sig_int); #ifdef IOPAUSE_POLL poll(&x, 1, 14000); #else t.tv_sec =14; t.tv_usec =0; FD_ZERO(&rfds); FD_SET(x.fd, &rfds); select(x.fd +1, &rfds, (fd_set*)0, (fd_set*)0, &t); #endif sig_block(sig_cont); sig_block(sig_child); sig_block(sig_int); while (read(selfpipe[0], &ch, 1) == 1) {} while ((child =wait_nohang(&wstat)) > 0) if (child == pid) break; if (child == -1) { strerr_warn2(WARNING, "wait_nohang, pausing: ", &strerr_sys); sleep(5); } /* reget stderr */ if ((ttyfd =open_write("/dev/console")) != -1) { dup2(ttyfd, 2); if (ttyfd > 2) close(ttyfd); } if (child == pid) { if (wait_exitcode(wstat) != 0) { if (wait_crashed(wstat)) strerr_warn3(WARNING, "child crashed: ", stage[st], 0); else strerr_warn3(WARNING, "child failed: ", stage[st], 0); if (st == 0) /* this is stage 1 */ if (wait_crashed(wstat) || (wait_exitcode(wstat) == 100)) { strerr_warn3(INFO, "leave stage: ", stage[st], 0); strerr_warn2(WARNING, "skipping stage 2...", 0); st++; break; } if (st == 1) /* this is stage 2 */ if (wait_crashed(wstat) || (wait_exitcode(wstat) == 111)) { strerr_warn2(WARNING, "killing all processes in stage 2...", 0); kill(-pid, 9); sleep(5); strerr_warn2(WARNING, "restarting.", 0); st--; break; } } strerr_warn3(INFO, "leave stage: ", stage[st], 0); break; } if (child != 0) { /* collect terminated children */ write(selfpipe[1], "", 1); continue; } /* sig? */ if (!sigc && !sigi) { #ifdef DEBUG strerr_warn2(WARNING, "poll: ", &strerr_sys); #endif continue; } if (st != 1) { strerr_warn2(WARNING, "signals only work in stage 2.", 0); sigc =sigi =0; continue; } if (sigi && (stat(CTRLALTDEL, &s) != -1) && (s.st_mode & S_IXUSR)) { strerr_warn2(INFO, "ctrl-alt-del request...", 0); prog[0] =CTRLALTDEL; prog[1] =0; while ((pid2 =fork()) == -1) { strerr_warn4(FATAL, "unable to fork for \"", CTRLALTDEL, "\" pausing: ", &strerr_sys); sleep(5); } if (!pid2) { /* child */ strerr_warn3(INFO, "enter stage: ", prog[0], 0); execve(*prog, (char *const *) prog, envp); strerr_die4sys(0, FATAL, "unable to start child: ", prog[0], ": "); } if (wait_pid(&wstat, pid2) == -1) strerr_warn2(FATAL, "wait_pid: ", &strerr_sys); if (wait_crashed(wstat)) strerr_warn3(WARNING, "child crashed: ", CTRLALTDEL, 0); strerr_warn3(INFO, "leave stage: ", prog[0], 0); sigi =0; sigc++; } if (sigc && (stat(STOPIT, &s) != -1) && (s.st_mode & S_IXUSR)) { int i; /* unlink(STOPIT); */ chmod(STOPIT, 0); /* kill stage 2 */ #ifdef DEBUG strerr_warn2(WARNING, "sending sigterm...", 0); #endif kill(pid, sig_term); i =0; while (i < 5) { if ((child =wait_nohang(&wstat)) == pid) { #ifdef DEBUG strerr_warn2(WARNING, "stage 2 terminated.", 0); #endif pid =0; break; } if (child) continue; if (child == -1) strerr_warn2(WARNING, "wait_nohang: ", &strerr_sys); #ifdef DEBUG strerr_warn2(WARNING, "waiting...", 0); #endif sleep(1); i++; } if (pid) { /* still there */ strerr_warn2(WARNING, "stage 2 not terminated, sending sigkill...", 0); kill(pid, 9); if (wait_pid(&wstat, pid) == -1) strerr_warn2(WARNING, "wait_pid: ", &strerr_sys); } sigc =0; strerr_warn3(INFO, "leave stage: ", stage[st], 0); /* enter stage 3 */ break; } sigc =sigi =0; #ifdef DEBUG strerr_warn2(WARNING, "no request.", 0); #endif } } /* reget stderr */ if ((ttyfd =open_write("/dev/console")) != -1) { dup2(ttyfd, 2); if (ttyfd > 2) close(ttyfd); } #ifdef RB_AUTOBOOT /* fallthrough stage 3 */ strerr_warn2(INFO, "sending KILL signal to all processes...", 0); kill(-1, SIGKILL); pid =fork(); switch (pid) { case 0: case -1: if ((stat(REBOOT, &s) != -1) && (s.st_mode & S_IXUSR)) { strerr_warn2(INFO, "system reboot.", 0); sync(); reboot_system(RB_AUTOBOOT); } else { #ifdef RB_POWER_OFF strerr_warn2(INFO, "power off...", 0); sync(); reboot_system(RB_POWER_OFF); sleep(2); #endif #ifdef RB_HALT_SYSTEM strerr_warn2(INFO, "system halt.", 0); sync(); reboot_system(RB_HALT_SYSTEM); #else #ifdef RB_HALT strerr_warn2(INFO, "system halt.", 0); sync(); reboot_system(RB_HALT); #else strerr_warn2(INFO, "system reboot.", 0); sync(); reboot_system(RB_AUTOBOOT); #endif #endif } if (pid == 0) _exit(0); break; default: sig_unblock(sig_child); while (wait_pid(0, pid) == -1); } #endif for (;;) sig_pause(); /* not reached */ strerr_die2x(0, INFO, "exit."); return(0); }
void fullcurrent(struct cyclog *d) { int fd; int pid; int wstat; while (fchdir(d->fddir) == -1) pause3("unable to switch to ",d->dir,", pausing: "); while (fsync(d->fdcurrent) == -1) pause3("unable to write ",d->dir,"/current to disk, pausing: "); close(d->fdcurrent); while (rename("current","previous") == -1) pause3("unable to rename current to previous in directory ",d->dir,", pausing: "); while ((d->fdcurrent = open_append("current")) == -1) pause3("unable to create ",d->dir,"/current, pausing: "); coe(d->fdcurrent); d->bytes = 0; while (fchmod(d->fdcurrent,0644) == -1) pause3("unable to set mode of ",d->dir,"/current, pausing: "); while (chmod("previous",0744) == -1) pause3("unable to set mode of ",d->dir,"/previous, pausing: "); if (!d->processor) finish(d,"previous","s"); else { for (;;) { while ((pid = fork()) == -1) pause3("unable to fork for processor in ",d->dir,", pausing: "); if (!pid) { startprocessor(d); strerr_die4sys(111,FATAL,"unable to run ",d->processor,": "); } if (wait_pid(&wstat,pid) == -1) pause3("wait failed for processor in ",d->dir,", pausing: "); else if (wait_crashed(wstat)) pause3("processor crashed in ",d->dir,", pausing: "); else if (!wait_exitcode(wstat)) break; strerr_warn4(WARNING,"processor failed in ",d->dir,", pausing",0); deepsleep(5); } while ((fd = open_append("processed")) == -1) pause3("unable to create ",d->dir,"/processed, pausing: "); while (fsync(fd) == -1) pause3("unable to write ",d->dir,"/processed to disk, pausing: "); while (fchmod(fd,0744) == -1) pause3("unable to set mode of ",d->dir,"/processed, pausing: "); close(fd); while ((fd = open_append("newstate")) == -1) pause3("unable to create ",d->dir,"/newstate, pausing: "); while (fsync(fd) == -1) pause3("unable to write ",d->dir,"/newstate to disk, pausing: "); close(fd); while (unlink("previous") == -1) pause3("unable to remove ",d->dir,"/previous, pausing: "); while (rename("newstate","state") == -1) pause3("unable to rename newstate to state in directory ",d->dir,", pausing: "); finish(d,"processed","s"); } }
const char * auth_close(struct call *cc, stralloc *user, const char *pre) { const char *s; int wstat; int exitcode; char c; s = 0; c = 0; if ((long)cc->pid == -1) return "454 unable to start authentication process. " "(#4.3.0)\r\n"; if (cc->flagabort) s = "501 authentication exchange aborted. (#4.3.0)\r\n"; if (cc->flagerr) s = "454 authentication process write failure. (#4.3.0)\r\n"; if (!cc->flagerr && !cc->flagabort) { if (call_getc(cc, &c) == -1) { s = "454 authentication process read failure. " "(#4.3.0)\r\n"; } else switch (c) { case 'K': if (!stralloc_copys(user, pre!=0?pre:"")) { s = "421 out of memory (#4.3.0)\r\n"; break; } while (call_getc(cc, &c) == 1) { if (!stralloc_append(user, &c)) { s = "421 out of memory (#4.3.0)\r\n"; break; } } if (cc->flagerr) s = "454 authentication process read " "failure. (#4.3.0)\r\n"; else s = "235 nice to meet you\r\n"; break; case 'D': s = "535 authentication failure\r\n"; break; case 'Z': s = "501 authentication exchange failed\r\n"; break; default: s = "454 authentication process failure. (#4.3.0)\r\n"; break; } } close(cc->tofd); close(cc->fromfd); if ((unsigned long)wait_pid(&wstat,cc->pid) != cc->pid) return "454 authentication waitpid surprise (#4.3.0)\r\n"; if (wait_crashed(wstat)) return "454 authentication process crashed (#4.3.0)\r\n"; exitcode = wait_exitcode(wstat); switch (exitcode) { case 0: return s; default: return "454 temporary authentication failure (#4.3.0)\r\n"; } }