int main (int argc, const char * const *argv, const char * const *envp) { int opt; int wtmp =0; progname =*argv; while ((opt =getopt(argc, argv, "wV")) != opteof) { switch(opt) { case 'w': wtmp =1; break; case 'V': strerr_warn1("$Id: cb399098f794012a7f5e6a3a7090b2d53b86c08c $", 0); case '?': usage(); } } argv +=optind; if (! argv || ! *argv) usage(); if (utmp_logout(*argv) == -1) strerr_die4x(111, WARNING, "unable to logout line ", *argv, " in utmp: no such entry"); if (wtmp) if (wtmp_logout(*argv) == -1) strerr_die4sys(111, WARNING, "unable to logout line ", *argv, " in wtmp: "); _exit(0); }
void snap_dump(char *filename, stralloc *sa) { dAVLCursor c; dAVLNode *node; char strip[IP6_FMT]; char strnum[FMT_ULONG]; int fd; fd = open_trunc("filename"); if(fd == -1) strerr_warn1(ARGV0 "warning: unable to open for tcp.tmp for writing", &strerr_sys); buffer_init(&wb, write, fd, wbspace, sizeof wbspace); node = dAVLFirst(&c, t); while(node) { buffer_put(&wb, strnum, fmt_ulong(strnum, node->key)); buffer_puts(&wb, ","); buffer_put(&wb, strip, ip4_fmt(strip, node->ip4)); buffer_puts(&wb, ","); buffer_put(&wb, strip, ip6_fmt(strip, node->ip6)); buffer_puts(&wb, ",LOC\n"); node = dAVLNext(&c); } buffer_flush(&wb); close(fd); }
char *generate_answer(stralloc *answer, uint32 uid, char *lip, uint16 lport, char *rip, uint16 rport) { char *problem = "ok"; char *x; char buf[5]; stralloc out = {0}; stralloc tmp = {0}; stralloc key = {0}; /* get key from enviroment */ x = env_get("KEY"); if (!x) { problem = "$KEY not set"; strerr_warn1("didentd warning: $KEY not set using 'snakeoilkey'", NULL); x = "snakeoilkey"; } /* initialize rijndael with $KEY */ stralloc_copys(&key, x); txtparse(&key); pad(&key, 32); rijndaelKeySched(6, 8, key.s); /* build answer */ stralloc_cats(answer, " : USERID : OTHER : "); uint32_pack(buf, uid); stralloc_catb(&tmp, buf, 4); uint16_pack(buf, lport); stralloc_catb(&tmp, buf, 2); uint16_pack(buf, rport); stralloc_catb(&tmp, buf, 2); uint32_pack(buf, time(NULL)); stralloc_catb(&tmp, buf, 4); stralloc_catb(&tmp, lip, 4); stralloc_catb(&tmp, rip, 8); /* encrypt last part of answer with rijndael */ rijndaelEncrypt(tmp.s); stralloc_readyplus(&out, 32); base64encode(out.s, tmp.s, 24); stralloc_catb(answer, out.s, 32); stralloc_cats(answer, "\r\n"); stralloc_0(answer); return problem; }
/* this is out work routine which is called by DJBs server code */ int respond(char *q, char qtype[2]) { int flaga; int flagaaaa; int flagloc; char ip[IP6_FMT]; stralloc filename = { 0 }; int fd; buffer b; char bspace[1024]; static stralloc line; int match = 1; unsigned long linenum = 0; int data = 0; stralloc f[NUMFIELDS] = {{0}}; /* check what the client is requesting */ flaga = byte_equal(qtype,2,DNS_T_A); flagloc = byte_equal(qtype,2,DNS_T_LOC); flagaaaa = byte_equal(qtype,2,DNS_T_AAAA); if (byte_equal(qtype,2,DNS_T_ANY)) flaga = flagloc = flagaaaa = 1; /* find out in which file we should look */ query2filename(q, &filename); buffer_put(buffer_2, filename.s, filename.len); buffer_puts(buffer_2, "\n"); buffer_flush(buffer_2); fd = open_read(filename.s); if (fd == -1) { strerr_warn3("unable to open file: ", filename.s, ": ", &strerr_sys); match = 0; } buffer_init(&b, read, fd, bspace, sizeof bspace); /* Work through the file and handout the data. */ while(match) { ++linenum; if(getln(&b, &line, &match, '\n') == -1) { strerr_warn1("unable to read line: ", &strerr_sys); break; } /* clean up line end */ stralloc_cleanlineend(&line); /* skip comments & empty lines */ if(line.s[0] == '#') continue; if(line.s[0] == 0) continue; /* seperate fields */ fieldsep(f, NUMFIELDS, &line, ','); /* IPv4 */ if(f[0].s[0] == '=') { if (flaga) { ip4_scan(f[2].s, ip); data++; /* put type and ttl (60s) */ if (!response_rstart(q, DNS_T_A, "\0\0\0\74")) return 0; /* put ip */ if (!response_addbytes(ip, 4)) return 0; /* record finished */ response_rfinish(RESPONSE_ANSWER); } } /* IPv6 */ if(f[0].s[0] == '6') { if (flagaaaa) { ip6_scan(f[0].s, ip); data++; /* put type and ttl (60s) */ if (!response_rstart(q, DNS_T_AAAA, "\0\0\0\74")) return 0; /* put ip */ if (!response_addbytes(ip, 16)) return 0; /* record finished */ response_rfinish(RESPONSE_ANSWER); } } /* LOC */ if(f[0].s[0] == 'L') { if (flagloc) { txtparse(&f[2]); if(f[2].len <= 16) { buffer_puts(buffer_2, "filedns: warning: LOC record seems to short\n"); buffer_flush(buffer_2); } data++; /* put type and ttl (60s) */ if (!response_rstart(q, DNS_T_LOC, "\0\0\0\74")) return 0; /* put ip */ if (!response_addbytes(f[2].s, 16)) return 0; /* record finished */ response_rfinish(RESPONSE_ANSWER); } } } /* Disclaimer ;-) */ if (!response_rstart(q, DNS_T_TXT, "\0\0\0\74")) return 0; if (!response_addbytes("this is a response from an alpha quality dns-server", 51)) return 0; response_rfinish(RESPONSE_ADDITIONAL); if (!response_rstart(q, DNS_T_TXT, "\0\0\0\74")) return 0; if (!response_addbytes("filednes 0.00 - if problems arise contact [email protected]", 54)) return 0; response_rfinish(RESPONSE_ADDITIONAL); // if (flaga || flagptr) // { // if (dd(q,"",ip) == 4) // { // if (flaga) // { // if (!response_rstart(q,DNS_T_A,"\0\12\0\0")) return 0; // if (!response_addbytes(ip,4)) return 0; // response_rfinish(RESPONSE_ANSWER); // } // return 1; // } // j = dd(q,"\7in-addr\4arpa",ip); // if (j >= 0) // { if(data > 0) return 1; /* nothing found */ buffer_puts(buffer_2, "notfound\n"); buffer_flush(buffer_2); // XXX: this is somehow broken /* response 0-1 is transaction id */ /* set response flags */ /* clear authority bit */ response[2] &= ~4; /* clear last 4 bits */ response[3] &= ~15; /* flag not found */ response[3] |= 3; /* response[4..5]: nr of questions * response[6..7]: nr of answers rr * response[8..9]: nr of authority rr * response[10..11]: nr of additional rr */ return 1; }
int main(int argc, char **argv) { unsigned int i, done; char *x; progname =*argv; for (i =str_len(*argv); i; --i) if ((*argv)[i -1] == '/') break; *argv +=i; optprogname =progname =*argv; service =argv; services =1; lsb =(str_diff(progname, "sv")); if ((x =env_get("SVDIR"))) varservice =x; if ((x =env_get("SVWAIT"))) scan_ulong(x, &wait); while ((i =getopt(argc, (const char* const*)argv, "w:vV")) != opteof) { switch(i) { case 'w': scan_ulong(optarg, &wait); case 'v': verbose =1; break; case 'V': strerr_warn1(VERSION, 0); case '?': usage(); } } argv +=optind; argc -=optind; if (!(action =*argv++)) usage(); --argc; if (!lsb) { service =argv; services =argc; } if (!*service) usage(); taia_now(&tnow); tstart =tnow; if ((curdir =open_read(".")) == -1) fatal("unable to open current directory"); act =&control; acts ="s"; if (verbose) cbk =✓ switch (*action) { case 'x': case 'e': acts ="x"; break; case 'X': case 'E': acts ="x"; kll =1; cbk =✓ break; case 'D': acts ="d"; kll =1; cbk =✓ break; case 'T': acts ="tc"; kll =1; cbk =✓ break; case 'c': if (!str_diff(action, "check")) { act =0; acts ="C"; cbk =✓ break; } case 'u': case 'd': case 'o': case 't': case 'p': case 'h': case 'a': case 'i': case 'k': case 'q': case '1': case '2': action[1] =0; acts =action; break; case 's': if (!str_diff(action, "shutdown")) { acts ="x"; cbk =✓ break; } if (!str_diff(action, "start")) { acts ="u"; cbk =✓ break; } if (!str_diff(action, "stop")) { acts ="d"; cbk =✓ break; } if (lsb && str_diff(action, "status")) usage(); act =&status; cbk =0; break; case 'r': if (!str_diff(action, "restart")) { acts ="tcu"; cbk =✓ break; } usage(); case 'f': if (!str_diff(action, "force-reload")) { acts ="tc"; kll =1; cbk =✓ break; } if (!str_diff(action, "force-restart")) { acts ="tcu"; kll =1; cbk =✓ break; } if (!str_diff(action, "force-shutdown")) { acts ="x"; kll =1; cbk =✓ break; } if (!str_diff(action, "force-stop")) { acts ="d"; kll =1; cbk =✓ break; } default: usage(); } servicex =service; for (i =0; i < services; ++i) { if ((**service != '/') && (**service != '.') && **service && ((*service)[str_len(*service) -1] != '/')) { if ((chdir(varservice) == -1) || (chdir(*service) == -1)) { fail("unable to change to service directory"); *service =0; } } else if (chdir(*service) == -1) { fail("unable to change to service directory"); *service =0; } if (*service) if (act && (act(acts) == -1)) *service =0; if (fchdir(curdir) == -1) fatal("unable to change to original directory"); service++; } if (*cbk) for (;;) { taia_sub(&tdiff, &tnow, &tstart); service =servicex; done =1; for (i =0; i < services; ++i, ++service) { if (!*service) continue; if ((**service != '/') && (**service != '.')) { if ((chdir(varservice) == -1) || (chdir(*service) == -1)) { fail("unable to change to service directory"); *service =0; } } else if (chdir(*service) == -1) { fail("unable to change to service directory"); *service =0; } if (*service) { if (cbk(acts) != 0) *service =0; else done =0; } if (*service && taia_approx(&tdiff) > wait) { kll ? outs(KILL) : outs(TIMEOUT); if (svstatus_get() > 0) { svstatus_print(*service); ++rc; } flush("\n"); if (kll) control("k"); *service =0; } if (fchdir(curdir) == -1) fatal("unable to change to original directory"); } if (done) break; usleep(420000); taia_now(&tnow); } return(rc > 99 ? 99 : rc); }
int main(int argc, const char * const *argv) { int opt; unsigned long sec =600; int verbose =0; int doexit =0; int dokill =0; int wdir; int fd; char status[20]; int r; unsigned long pid; struct tai start; struct tai now; progname =*argv; while ((opt =getopt(argc, argv, "t:xkvV")) != opteof) { switch(opt) { case 't': scan_ulong(optarg, &sec); if ((sec < 1) || (sec > 6000)) usage(); break; case 'x': doexit =1; break; case 'k': dokill =1; break; case 'v': verbose =1; break; case 'V': strerr_warn1(VERSION, 0); case '?': usage(); } } argv +=optind; if (! argv || ! *argv) usage(); if ((wdir =open_read(".")) == -1) fatal("unable to open current working directory"); for (dir =argv; *dir; ++dir) { if (dir != argv) if (fchdir(wdir) == -1) fatal("unable to switch to starting directory"); if (chdir(*dir) == -1) continue; /* bummer */ if ((fd =open_write("supervise/control")) == -1) continue; /* bummer */ if (write(fd, "dx", 1 +doexit) != (1 +doexit)) { close(fd); continue; /* bummer */ } close(fd); } dir =argv; tai_now(&start); while (*dir) { if (fchdir(wdir) == -1) fatal("unable to switch to starting directory"); if (chdir(*dir) == -1) { warn(*dir, ": unable to change directory: ", &strerr_sys); continue; } if ((fd =open_write("supervise/ok")) == -1) { if (errno == error_nodevice) { if (verbose) strerr_warn3(INFO, *dir, ": runsv not running.", 0); dir++; } else warn(*dir, ": unable to open supervise/ok: ", &strerr_sys); continue; } close(fd); if ((fd =open_read("supervise/status")) == -1) { warn(*dir, "unable to open supervise/status: ", &strerr_sys); continue; } r =buffer_unixread(fd, status, 20); close(fd); if ((r < 18) || (r == 19)) { /* supervise compatibility */ if (r == -1) warn(*dir, "unable to read supervise/status: ", &strerr_sys); else warn(*dir, ": unable to read supervise/status: bad format.", 0); continue; } pid =(unsigned char)status[15]; pid <<=8; pid +=(unsigned char)status[14]; pid <<=8; pid +=(unsigned char)status[13]; pid <<=8; pid +=(unsigned char)status[12]; if (! doexit && ! pid) { /* ok, service is down */ if (verbose) strerr_warn3(INFO, *dir, ": down.", 0); dir++; continue; } if (status[17] != 'd') { /* catch previous failures */ if ((fd =open_write("supervise/control")) == -1) { warn(*dir, ": unable to open supervise/control: ", &strerr_sys); continue; } if (write(fd, "dx", 1 +doexit) != (1 +doexit)) { warn(*dir, ": unable to write to supervise/control: ", &strerr_sys); close(fd); continue; } close(fd); } tai_now(&now); tai_sub(&now, &now, &start); if (tai_approx(&now) >= sec) { /* timeout */ if (verbose) strerr_warn2(INFO, "timeout.", 0); if (dokill) { if (chdir(*dir) == -1) { warn(*dir, ": unable to change directory: ", &strerr_sys); continue; } if ((fd =open_write("supervise/control")) == -1) { if (errno == error_nodevice) { if (verbose) strerr_warn3(INFO, *dir, ": runsv not running.", 0); dir++; } else warn(*argv, ": unable to open supervise/control: ", &strerr_sys); continue; } if (write(fd, "k", 1) != 1) warn(*argv, ": unable to write to supervise/control: ", &strerr_sys); else strerr_warn3(INFO, *dir, ": killed.", 0); close(fd); dir++; if (! *dir) _exit(111); continue; } _exit(111); } sleep(1); } if (fchdir(wdir) == -1) strerr_warn2(WARN, "unable to switch to starting directory: ", &strerr_sys); close(wdir); if (rc > 100) rc =100; _exit(rc); }
int main(int argc, const char * const *argv) { int opt; int verbose =0; char status[18]; int fd; int is; int r; int wdir; unsigned long pid; struct tai when; struct tai now; char sulong[FMT_ULONG]; progname =*argv; while ((opt =getopt(argc, argv, "s:vV")) != opteof) { switch(opt) { case 's': scan_ulong(optarg, &sec); if ((sec < 1) || (sec > 600)) usage(); break; case 'v': verbose =1; break; case 'V': strerr_warn1("$Id: e2d6c574c5e56f9931323fbc0e539c7f9b829b73 $", 0); case '?': usage(); } } argv +=optind; if (! argv || ! *argv) usage(); if ((wdir =open_read(".")) == -1) fatal("unable to open current working directory"); dir =argv; while (*dir) { if (dir != argv) if (fchdir(wdir) == -1) fatal("unable to switch to starting directory"); if (chdir(*dir) == -1) { warn(*dir, ": unable to change directory: ", &strerr_sys); continue; } if ((fd =open_write("supervise/ok")) == -1) { if (errno == error_nodevice) warn(*dir, ": runsv not running.", 0); else warn(*dir, ": unable to open supervise/ok: ", &strerr_sys); continue; } close(fd); if ((fd =open_read("supervise/status")) == -1) { warn(*dir, "unable to open supervise/status: ", &strerr_sys); continue; } r =buffer_unixread(fd, status, sizeof status); close(fd); if (r < sizeof status) { if (r == -1) warn(*dir, "unable to read supervise/status: ", &strerr_sys); else warn(*dir, ": unable to read supervise/status: bad format.", 0); continue; } pid =(unsigned char)status[15]; pid <<=8; pid +=(unsigned char)status[14]; pid <<=8; pid +=(unsigned char)status[13]; pid <<=8; pid +=(unsigned char)status[12]; if (! pid) { warn(*dir, ": is down.", 0); continue; } tai_unpack(status, &when); tai_now(&now); if (tai_less(&now, &when)) when =now; tai_sub(&when, &now, &when); is =tai_approx(&when); if (is >= sec) { /* ok */ if (verbose) { sulong[fmt_ulong(sulong, is)] =0; strerr_warn5(INFO, *dir, ": is up (", sulong, " seconds)", 0); } dir++; continue; } sleep(sec -is); } if (fchdir(wdir) == -1) strerr_warn2(WARN, "unable to switch to starting directory: ", &strerr_sys); close(wdir); if (rc > 100) rc =100; _exit(rc); }
int main(int argc, char **argv) { int opt; char *user =0; char *host; unsigned long port; int pid; int s; int conn; int delim; progname =*argv; phccmax =0; #ifdef SSLSVD while ((opt =getopt(argc, (const char **)argv, "c:C:i:x:u:l:Eb:hpt:vVU:/:Z:K:")) != opteof) { #else while ((opt =getopt(argc, (const char **)argv, "c:C:i:x:u:l:Eb:hpt:vV")) != opteof) { #endif switch(opt) { case 'c': scan_ulong(optarg, &cmax); if (cmax < 1) usage(); break; case 'C': delim =scan_ulong(optarg, &phccmax); if (phccmax < 1) usage(); if (optarg[delim] == ':') { if (ipsvd_fmt_msg(&msg, optarg +delim +1) == -1) die_nomem(); if (! stralloc_0(&msg)) die_nomem(); phccmsg =msg.s; } break; case 'i': if (instructs) usage(); instructs =optarg; break; case 'x': if (instructs) usage(); instructs =optarg; iscdb =1; break; case 'u': user =(char*)optarg; break; case 'l': if (! stralloc_copys(&local_hostname, optarg)) die_nomem(); if (! stralloc_0(&local_hostname)) die_nomem(); break; case 'E': ucspi =0; break; case 'b': scan_ulong(optarg, &backlog); break; case 'h': lookuphost =1; break; case 'p': lookuphost =1; paranoid =1; break; case 't': scan_ulong(optarg, &timeout); break; case 'v': ++verbose; break; #ifdef SSLSVD case 'U': ssluser =(char*)optarg; break; case '/': root =(char*)optarg; break; case 'Z': cert =(char*)optarg; break; case 'K': key =(char*)optarg; break; #endif case 'V': strerr_warn1(VERSION, 0); case '?': usage(); } } argv +=optind; if (! argv || ! *argv) usage(); host =*argv++; if (! argv || ! *argv) usage(); local_port =*argv++; if (! argv || ! *argv) usage(); prog =(const char **)argv; if (phccmax > cmax) phccmax =cmax; if (user) if (! uidgids_get(&ugid, user)) { if (errno) strerr_die4sys(111, FATAL, "unable to get user/group: ", user, ": "); strerr_die3x(100, FATAL, "unknown user/group: ", user); } #ifdef SSLSVD svuser =user; client =0; if ((getuid() == 0) && (! ssluser)) strerr_die2x(100, FATAL, "-U ssluser must be set when running as root"); if (ssluser) if (! uidgids_get(&sslugid, ssluser)) { if (errno) strerr_die4sys(111, FATAL, "unable to get user/group: ", ssluser, ": "); strerr_die3x(100, FATAL, "unknown user/group: ", ssluser); } if (! cert) cert ="./cert.pem"; if (! key) key =cert; if (matrixSslOpen() < 0) fatal("unable to initialize ssl"); if (matrixSslReadKeys(&keys, cert, key, 0, ca) < 0) { if (client) fatal("unable to read cert, key, or ca file"); fatal("unable to read cert or key file"); } if (matrixSslNewSession(&ssl, keys, 0, SSL_FLAGS_SERVER) < 0) strerr_die2x(111, FATAL, "unable to create ssl session"); #endif dns_random_init(seed); sig_block(sig_child); sig_catch(sig_child, sig_child_handler); sig_catch(sig_term, sig_term_handler); sig_ignore(sig_pipe); if (phccmax) if (ipsvd_phcc_init(cmax) == -1) die_nomem(); if (str_equal(host, "")) host ="0.0.0.0"; if (str_equal(host, "0")) host ="0.0.0.0"; if (! ipsvd_scan_port(local_port, "tcp", &port)) strerr_die3x(100, FATAL, "unknown port number or name: ", local_port); if (! stralloc_copys(&sa, host)) die_nomem(); if ((dns_ip4(&ips, &sa) == -1) || (ips.len < 4)) if (dns_ip4_qualify(&ips, &fqdn, &sa) == -1) fatal2("unable to look up ip address", host); if (ips.len < 4) strerr_die3x(100, FATAL, "unable to look up ip address: ", host); ips.len =4; if (! stralloc_0(&ips)) die_nomem(); local_ip[ipsvd_fmt_ip(local_ip, ips.s)] =0; if (! lookuphost) { if (! stralloc_copys(&remote_hostname, "")) die_nomem(); if (! stralloc_0(&remote_hostname)) die_nomem(); } if ((s =socket_tcp()) == -1) fatal("unable to create socket"); if (socket_bind4_reuse(s, ips.s, port) == -1) fatal("unable to bind socket"); if (listen(s, backlog) == -1) fatal("unable to listen"); ndelay_off(s); #ifdef SSLSVD #else if (user) { /* drop permissions */ if (setgroups(ugid.gids, ugid.gid) == -1) fatal("unable to set groups"); if (setgid(*ugid.gid) == -1) fatal("unable to set gid"); if (prot_uid(ugid.uid) == -1) fatal("unable to set uid"); } #endif close(0); if (verbose) { out(INFO); out("listening on "); outfix(local_ip); out(":"); outfix(local_port); #ifdef SSLSVD #else if (user) { bufnum[fmt_ulong(bufnum, (unsigned long)ugid.uid)] =0; out(", uid "); out(bufnum); bufnum[fmt_ulong(bufnum, (unsigned long)ugid.gid)] =0; out(", gid "); out(bufnum); } #endif flush(", starting.\n"); } for (;;) { while (cnum >= cmax) sig_pause(); socka_size =sizeof(socka); sig_unblock(sig_child); conn =accept(s, (struct sockaddr *)&socka, &socka_size); sig_block(sig_child); if (conn == -1) { if (errno != error_intr) warn("unable to accept connection"); continue; } cnum++; if (verbose) connection_status(); if (phccmax) phcc =ipsvd_phcc_add((char*)&socka.sin_addr); if ((pid =fork()) == -1) { warn2("drop connection", "unable to fork"); close(conn); continue; } if (pid == 0) { /* child */ close(s); #ifdef SSLSVD if (*progname) *progname ='\\'; #endif connection_accept(conn); } if (phccmax) ipsvd_phcc_setpid(pid); close(conn); } _exit(0); }
int main(int argc, const char **argv) { int opt; int i; unsigned long ul; progname =argv[0]; for (i =str_len(progname); i; --i) if (progname[i -1] == '/') { progname +=i; break; } if (progname[0] == 'd') ++progname; /* argv[0] */ if (str_equal(progname, "setuidgid")) setuidgid(argc, argv); if (str_equal(progname, "envuidgid")) envuidgid(argc, argv); if (str_equal(progname, "envdir")) envdir(argc, argv); if (str_equal(progname, "pgrphack")) pgrphack(argc, argv); if (str_equal(progname, "setlock")) setlock(argc, argv); if (str_equal(progname, "softlimit")) softlimit(argc, argv); while ((opt =getopt(argc, argv, "u:U:b:e:m:d:o:p:f:c:r:t:/:n:l:L:vP012V")) != opteof) switch(opt) { case 'u': set_user =(char*)optarg; break; case 'U': env_user =(char*)optarg; break; case 'b': argv0 =(char*)optarg; break; case 'e': env_dir =optarg; break; case 'm': if (optarg[scan_ulong(optarg, &ul)]) usage(); limits =limitl =limita =limitd =ul; break; case 'd': if (optarg[scan_ulong(optarg, &ul)]) usage(); limitd =ul; break; case 'o': if (optarg[scan_ulong(optarg, &ul)]) usage(); limito =ul; break; case 'p': if (optarg[scan_ulong(optarg, &ul)]) usage(); limitp =ul; break; case 'f': if (optarg[scan_ulong(optarg, &ul)]) usage(); limitf =ul; break; case 'c': if (optarg[scan_ulong(optarg, &ul)]) usage(); limitc =ul; break; case 'r': if (optarg[scan_ulong(optarg, &ul)]) usage(); limitr =ul; break; case 't': if (optarg[scan_ulong(optarg, &ul)]) usage(); limitt =ul; break; case '/': root =optarg; break; case 'n': switch (*optarg) { case '-': if (optarg[scan_ulong(++optarg, &ul)]) usage(); nicelvl =ul; nicelvl *=-1; break; case '+': ++optarg; default: if (optarg[scan_ulong(optarg, &ul)]) usage(); nicelvl =ul; break; } break; case 'l': if (lock) usage(); lock =optarg; lockdelay =1; break; case 'L': if (lock) usage(); lock =optarg; lockdelay =0; break; case 'v': verbose =1; break; case 'P': pgrp =1; break; case '0': nostdin =1; break; case '1': nostdout =1; break; case '2': nostderr =1; break; case 'V': strerr_warn1("$Id: f279d44141c981dd7535a12260efcf1ef7beed26 $", 0); case '?': usage(); } argv +=optind; if (! argv || ! *argv) usage(); if (pgrp) setsid(); if (env_dir) edir(env_dir); if (root) { if (chdir(root) == -1) fatal2("unable to change directory", root); if (chroot(".") == -1) fatal("unable to change root directory"); } if (nicelvl) { errno =0; if (nice(nicelvl) == -1) if (errno) fatal("unable to set nice level"); } if (env_user) euidgid(env_user, 1); if (set_user) suidgid(set_user, 1); if (lock) slock(lock, lockdelay, 0); if (nostdin) if (close(0) == -1) fatal("unable to close stdin"); if (nostdout) if (close(1) == -1) fatal("unable to close stdout"); if (nostderr) if (close(2) == -1) fatal("unable to close stderr"); slimit(); progname =*argv; if (argv0) *argv =argv0; pathexec_env_run(progname, argv); fatal2("unable to run", *argv); return(0); }