int dns_resolve (const char *q, const char qtype[2]) { int r = 0; char servers[64]; iopause_fd x[1]; struct taia stamp; struct taia deadline; if (dns_resolvconfip (servers) == -1) return -1; memset (&dns_resolve_tx, 0, sizeof (dns_resolve_tx)); r = dns_transmit_start (&dns_resolve_tx, servers, 1, q, qtype, "\0\0\0\0"); if (r == -1) return -1; for (;;) { taia_now (&stamp); taia_uint (&deadline, 120); taia_add (&deadline, &deadline, &stamp); dns_transmit_io (&dns_resolve_tx, x, &deadline); iopause (x, 1, &deadline, &stamp); r = dns_transmit_get (&dns_resolve_tx, x, &stamp); if (r == -1) return -1; if (r == 1) return 0; } }
int timeoutconn6(int s,const char ip[16],uint16 port,unsigned int scope_id,unsigned int timeout) { struct taia now; struct taia deadline; iopause_fd x; if (socket_connect6(s,ip,port,scope_id) == -1) { if ((errno != EWOULDBLOCK) && (errno != EINPROGRESS)) return -1; x.fd = s; x.events = IOPAUSE_WRITE; taia_now(&now); taia_uint(&deadline,timeout); taia_add(&deadline,&now,&deadline); for (;;) { taia_now(&now); iopause(&x,1,&deadline,&now); if (x.revents) break; if (taia_less(&deadline,&now)) { errno = ETIMEDOUT; /* note that connect attempt is continuing */ return -1; } } if (!socket_connected(s)) return -1; } if (ndelay_off(s) == -1) return -1; return 0; }
int timeoutconn(int s,char ip[4],uint16 port,unsigned int timeout) { struct taia now; struct taia deadline; iopause_fd x; if (socket_connect4(s,ip,port) == -1) { if ((errno != error_wouldblock) && (errno != error_inprogress)) return -1; x.fd = s; x.events = IOPAUSE_WRITE; taia_now(&now); taia_uint(&deadline,timeout); taia_add(&deadline,&now,&deadline); for (;;) { taia_now(&now); iopause(&x,1,&deadline,&now); if (x.revents) break; if (taia_less(&deadline,&now)) { errno = error_timeout; /* note that connect attempt is continuing */ return -1; } } if (!socket_connected(s)) return -1; } if (ndelay_off(s) == -1) return -1; return 0; }
static int myread(int fd,char *buf,int len) { iopause_fd x; x.fd = fd; x.events = IOPAUSE_READ; for (;;) { taia_now(&now); iopause(&x,1,&deadline,&now); if (x.revents) break; if (taia_less(&deadline,&now)) { errno = error_timeout; return -1; } } return read(fd,buf,len); }
int ssl_timeoutaccept(SSL *ssl,unsigned int timeout) { struct taia now; struct taia deadline; iopause_fd x; int r; int rfd; int wfd; taia_now(&now); taia_uint(&deadline,timeout); taia_add(&deadline,&now,&deadline); rfd = SSL_get_fd(ssl); /* XXX */ wfd = SSL_get_fd(ssl); /* XXX */ SSL_set_accept_state(ssl); for (;;) { r = SSL_accept(ssl); if (r == 1) return 0; ssl_errno = SSL_get_error(ssl,r); errno = error_proto; if ((ssl_errno != SSL_ERROR_WANT_READ) && (ssl_errno != SSL_ERROR_WANT_WRITE)) return -1; if (ssl_errno == SSL_ERROR_WANT_READ) { x.events = IOPAUSE_READ; x.fd = rfd; if (x.fd == -1) return -1; } else { x.events = IOPAUSE_WRITE; x.fd = wfd; if (x.fd == -1) return -1; } for (;;) { taia_now(&now); iopause(&x,1,&deadline,&now); if (x.revents) break; if (taia_less(&deadline,&now)) return -1; } } }
int dns_resolve(const char *q,const char qtype[2]) { struct taia stamp; struct taia deadline; char servers[256]; iopause_fd x[1]; int r; if (dns_resolvconfip(servers) == -1) return -1; if (dns_transmit_start(&dns_resolve_tx,servers,1,q,qtype,V6any) == -1) return -1; for (;;) { taia_now(&stamp); taia_uint(&deadline,120); taia_add(&deadline,&deadline,&stamp); dns_transmit_io(&dns_resolve_tx,x,&deadline); iopause(x,1,&deadline,&stamp); r = dns_transmit_get(&dns_resolve_tx,x,&stamp); if (r == -1) return -1; if (r == 1) return 0; } }
int resolve(char *q,char qtype[2],char servers[256]) { struct taia stamp; struct taia deadline; iopause_fd x[1]; int r; if (dns_transmit_start(&tx,servers,0,q,qtype,V6any) == -1) return -1; for (;;) { taia_now(&stamp); taia_uint(&deadline,120); taia_add(&deadline,&deadline,&stamp); dns_transmit_io(&tx,x,&deadline); iopause(x,1,&deadline,&stamp); r = dns_transmit_get(&tx,x,&stamp); if (r == -1) return -1; if (r == 1) break; } return 0; }
int timeoutread(int t,int fd,char *buf,int len) { struct taia now; struct taia deadline; iopause_fd x; taia_now(&now); taia_uint(&deadline,t); taia_add(&deadline,&now,&deadline); x.fd = fd; x.events = IOPAUSE_READ; for (;;) { taia_now(&now); iopause(&x,1,&deadline,&now); if (x.revents) break; if (taia_less(&deadline,&now)) { errno = ETIMEDOUT; return -1; } } return read(fd,buf,len); }
int timeoutwrite(int t,int fd,const char *buf,int len) { struct taia now; struct taia deadline; iopause_fd x; taia_now(&now); taia_uint(&deadline,t); taia_add(&deadline,&now,&deadline); x.fd = fd; x.events = IOPAUSE_WRITE; for (;;) { taia_now(&now); iopause(&x,1,&deadline,&now); if (x.revents) break; if (taia_less(&deadline,&now)) { errno = error_timeout; return -1; } } return write(fd,buf,len); }
int resolve(char *q,char qtype[2],char ip[16]) { struct taia start; struct taia stamp; struct taia deadline; char servers[256]; iopause_fd x[1]; int r; taia_now(&start); byte_zero(servers,256); byte_copy(servers,16,ip); if (dns_transmit_start(&tx,servers,0,q,qtype,"\0\0\0\0") == -1) return -1; for (;;) { taia_now(&stamp); taia_uint(&deadline,120); taia_add(&deadline,&deadline,&stamp); dns_transmit_io(&tx,x,&deadline); iopause(x,1,&deadline,&stamp); r = dns_transmit_get(&tx,x,&stamp); if (r == -1) return -1; if (r == 1) break; } taia_now(&stamp); taia_sub(&stamp,&stamp,&start); taia_uint(&deadline,1); if (taia_less(&deadline,&stamp)) { buffer_put(buffer_1,querystr.s,querystr.len); buffer_puts(buffer_1,"ALERT:took more than 1 second\n"); } return 0; }
int timeoutaccept6(int s,char ip[16],uint16 *port,unsigned int timeout,uint32 *scope_id) { struct taia now; struct taia deadline; iopause_fd x; x.fd = s; x.events = IOPAUSE_READ; taia_now(&now); taia_uint(&deadline,timeout); taia_add(&deadline,&now,&deadline); for (;;) { taia_now(&now); iopause(&x,1,&deadline,&now); if (x.revents) break; if (taia_less(&deadline,&now)) { errno = ETIMEDOUT; /* note that connect attempt is continuing */ return -1; } } if (!socket_connected(s)) return -1; if (ndelay_off(s) == -1) return -1; return socket_accept6(s,ip,port,scope_id); }
int main(int argc, char **argv) { struct stat s; time_t mtime =0; int wstat; int curdir; int pid; struct taia deadline; struct taia now; struct taia stampcheck; char ch; int i; progname =*argv++; if (! argv || ! *argv) usage(); if (**argv == '-') { switch (*(*argv +1)) { case 'P': pgrp =1; case '-': ++argv; } if (! argv || ! *argv) usage(); } sig_catch(sig_term, s_term); sig_catch(sig_hangup, s_hangup); svdir =*argv++; if (argv && *argv) { rplog =*argv; if (setup_log() != 1) { rplog =0; warn3x("log service disabled.", 0, 0); } } if ((curdir =open_read(".")) == -1) fatal("unable to open current directory", 0); coe(curdir); taia_now(&stampcheck); for (;;) { /* collect children */ for (;;) { if ((pid =wait_nohang(&wstat)) <= 0) break; for (i =0; i < svnum; i++) { if (pid == sv[i].pid) { /* runsv has gone */ sv[i].pid =0; check =1; break; } } } taia_now(&now); if (now.sec.x < (stampcheck.sec.x -3)) { /* time warp */ warn3x("time warp: resetting time stamp.", 0, 0); taia_now(&stampcheck); taia_now(&now); if (rplog) taia_now(&stamplog); } if (taia_less(&now, &stampcheck) == 0) { /* wait at least a second */ taia_uint(&deadline, 1); taia_add(&stampcheck, &now, &deadline); if (stat(svdir, &s) != -1) { if (check || \ s.st_mtime != mtime || s.st_ino != ino || s.st_dev != dev) { /* svdir modified */ if (chdir(svdir) != -1) { mtime =s.st_mtime; dev =s.st_dev; ino =s.st_ino; check =0; if (now.sec.x <= (4611686018427387914ULL +(uint64)mtime)) sleep(1); runsvdir(); while (fchdir(curdir) == -1) { warn("unable to change directory, pausing", 0); sleep(5); } } else warn("unable to change directory to ", svdir); } } else warn("unable to stat ", svdir); } if (rplog) if (taia_less(&now, &stamplog) == 0) { write(logpipe[1], ".", 1); taia_uint(&deadline, 900); taia_add(&stamplog, &now, &deadline); } /* half a second */ deadline.sec.x =0; deadline.nano =500000000UL; deadline.atto =0; taia_add(&deadline, &now, &deadline); sig_block(sig_child); if (rplog) iopause(io, 1, &deadline, &now); else iopause(0, 0, &deadline, &now); sig_unblock(sig_child); if (rplog && (io[0].revents | IOPAUSE_READ)) while (read(logpipe[0], &ch, 1) > 0) if (ch) { for (i =6; i < rploglen; i++) rplog[i -1] =rplog[i]; rplog[rploglen -1] =ch; } switch(exitsoon) { case 1: _exit(0); case 2: for (i =0; i < svnum; i++) if (sv[i].pid) kill(sv[i].pid, SIGTERM); _exit(111); } } /* for (;;) */ /* not reached */ _exit(0); }
int main (int argc, char *argv[]) { time_t t = 0; char *x = NULL; struct sigaction sa; iopause_fd *iop = NULL; int i = 0, n = 0, *udp53 = NULL; prog = strdup ((x = strrchr (argv[0], '/')) != NULL ? x + 1 : argv[0]); sa.sa_handler = handle_term; sigaction (SIGINT, &sa, NULL); sigaction (SIGTERM, &sa, NULL); sa.sa_handler = SIG_IGN; sigaction (SIGPIPE, &sa, NULL); i = check_option (argc, argv); argc -= i; argv += i; if (mode & DAEMON) { i = fork (); if (i == -1) err (-1, "could not fork a daemon process"); if (i > 0) return 0; } time (&t); memset (buf, 0, sizeof (buf)); strftime (buf, sizeof (buf), "%b-%d %Y %T %Z", localtime (&t)); warnx ("version %s: starting: %s\n", VERSION, buf); set_timezone (); if (debug_level) warnx ("TIMEZONE: %s", env_get ("TZ")); initialize (); if (!debug_level) if ((x = env_get ("DEBUG_LEVEL"))) debug_level = atol (x); warnx ("DEBUG_LEVEL set to `%d'", debug_level); if ((x = env_get ("DATALIMIT"))) { struct rlimit r; unsigned long dlimit = atol (x); if (getrlimit (RLIMIT_DATA, &r) != 0) err (-1, "could not get resource RLIMIT_DATA"); r.rlim_cur = (dlimit <= r.rlim_max) ? dlimit : r.rlim_max; if (setrlimit (RLIMIT_DATA, &r) != 0) err (-1, "could not set resource RLIMIT_DATA"); if (debug_level) warnx ("DATALIMIT set to `%ld' bytes", r.rlim_cur); } if (!(x = env_get ("IP"))) err (-1, "$IP not set"); for (i = 0; (unsigned)i < strlen (x); i++) n = (x[i] == ',') ? n+1 : n; if (!(udp53 = calloc (n+1, sizeof (int)))) err (-1, "could not allocate enough memory for udp53"); if (!(iop = calloc (n+1, sizeof (iopause_fd)))) err (-1, "could not allocate enough memory for iop"); i = n = 0; while (x[i]) { unsigned int l = 0; if (!(l = ip4_scan(x+i, ip))) errx (-1, "could not parse IP address `%s'", x + i); udp53[n] = socket_udp(); if (udp53[n] == -1) errx (-1, "could not open UDP socket"); if (socket_bind4_reuse (udp53[n], ip, server_port) == -1) errx (-1, "could not bind UDP socket"); ndelay_off (udp53[n]); socket_tryreservein (udp53[n], 65536); iop[n].fd = udp53[n]; iop[n].events = IOPAUSE_READ; n++; i += (x[i + l] == ',') ? l + 1 : l; } droproot (); while (1) { struct taia stamp; struct in_addr odst; /* original destination IP */ struct taia deadline; taia_now (&stamp); taia_uint (&deadline, 300); taia_add (&deadline, &deadline, &stamp); iopause (iop, n, &deadline, &stamp); for (i = 0; i < n; i++) { if (!iop[i].revents) continue; len = socket_recv4 (udp53[i], buf, sizeof (buf), ip, &port, &odst); if (len < 0) continue; if (!doit ()) continue; if (response_len > 512) response_tc (); /* may block for buffer space; if it fails, too bad */ len = socket_send4 (udp53[i], response, response_len, ip, port, &odst); if (len < 0) continue; if (debug_level > 1) log_querydone(qnum, response, response_len); } } return 0; }
static void doit (void) { struct taia stamp; struct taia deadline; int j = 0, r = 0, iolen = 0; for (;;) { taia_now (&stamp); taia_uint (&deadline, 120); taia_add (&deadline, &deadline, &stamp); iolen = 0; udp53io = io + iolen++; udp53io->fd = udp53; udp53io->events = IOPAUSE_READ; tcp53io = io + iolen++; tcp53io->fd = tcp53; tcp53io->events = IOPAUSE_READ; for (j = 0; j < MAXUDP; ++j) { if (u[j].active) { u[j].io = io + iolen++; query_io (&u[j].q, u[j].io, &deadline); } } for (j = 0; j < MAXTCP; ++j) { if (t[j].active) { t[j].io = io + iolen++; if (t[j].state == 0) query_io (&t[j].q, t[j].io, &deadline); else { if (taia_less (&t[j].timeout, &deadline)) deadline = t[j].timeout; t[j].io->fd = t[j].tcp; t[j].io->events = (t[j].state > 0) ? IOPAUSE_READ : IOPAUSE_WRITE; } } } iopause (io, iolen, &deadline, &stamp); for (j = 0; j < MAXUDP; ++j) { if (u[j].active) { r = query_get (&u[j].q, u[j].io, &stamp); if (r == -1) u_drop (j); if (r == 1) u_respond (j); } } for (j = 0; j < MAXTCP; ++j) { if (t[j].active) { if (t[j].io->revents) t_timeout (j); if (t[j].state == 0) { r = query_get (&t[j].q, t[j].io, &stamp); if (r == -1) t_drop (j); if (r == 1) t_respond (j); } else if (t[j].io->revents || taia_less (&t[j].timeout, &stamp)) t_rw (j); } } if (udp53io && udp53io->revents) u_new(); if (tcp53io && tcp53io->revents) t_new(); } }
void doit(int fdleft,int fdright) /* copy 0 -> fdleft, copy fdright -> 1 */ { struct taia stamp; struct taia deadline; iopause_fd x[4]; int xlen; iopause_fd *io0; iopause_fd *ioleft; iopause_fd *io1; iopause_fd *ioright; int r; for (;;) { xlen = 0; io0 = 0; if (leftstatus == 0) { io0 = &x[xlen++]; io0->fd = 0; io0->events = IOPAUSE_READ; } ioleft = 0; if (leftstatus == 1) { ioleft = &x[xlen++]; ioleft->fd = fdleft; ioleft->events = IOPAUSE_WRITE; } ioright = 0; if (rightstatus == 0) { ioright = &x[xlen++]; ioright->fd = fdright; ioright->events = IOPAUSE_READ; } io1 = 0; if (rightstatus == 1) { io1 = &x[xlen++]; io1->fd = 1; io1->events = IOPAUSE_WRITE; } taia_now(&stamp); taia_uint(&deadline,3600); taia_add(&deadline,&stamp,&deadline); iopause(x,xlen,&deadline,&stamp); if (io0 && io0->revents) { r = read(0,leftbuf,sizeof leftbuf); if (r <= 0) { leftstatus = -1; close(fdleft); buffer_puts(&ssrecord,pid); buffer_puts(&ssrecord," < [EOF]\n"); buffer_flush(&ssrecord); } else { leftstatus = 1; leftpos = 0; leftlen = r; record(leftbuf,r," < "); } } if (ioleft && ioleft->revents) { r = write(fdleft,leftbuf + leftpos,leftlen - leftpos); if (r == -1) break; leftpos += r; if (leftpos == leftlen) leftstatus = 0; } if (ioright && ioright->revents) { r = read(fdright,rightbuf,sizeof rightbuf); if (r <= 0) { buffer_puts(&ssrecord,pid); buffer_puts(&ssrecord," > [EOF]\n"); buffer_flush(&ssrecord); break; } rightstatus = 1; rightpos = 0; rightlen = r; record(rightbuf,r," > "); } if (io1 && io1->revents) { r = write(1,rightbuf + rightpos,rightlen - rightpos); if (r == -1) break; rightpos += r; if (rightpos == rightlen) rightstatus = 0; } } _exit(0); }
int main (void) { PROG = "s6-ftrigrd" ; if (ndelay_on(0) < 0) strerr_diefu2sys(111, "ndelay_on ", "0") ; if (ndelay_on(1) < 0) strerr_diefu2sys(111, "ndelay_on ", "1") ; if (sig_ignore(SIGPIPE) < 0) strerr_diefu1sys(111, "ignore SIGPIPE") ; { tain_t deadline ; tain_now_g() ; tain_addsec_g(&deadline, 2) ; if (!skaclient_server_01x_init_g(FTRIGR_BANNER1, FTRIGR_BANNER1_LEN, FTRIGR_BANNER2, FTRIGR_BANNER2_LEN, &deadline)) strerr_diefu1sys(111, "sync with client") ; } for (;;) { iopause_fd x[3 + n] ; unsigned int i = 0 ; x[0].fd = 0 ; x[0].events = IOPAUSE_EXCEPT | IOPAUSE_READ ; x[1].fd = 1 ; x[1].events = IOPAUSE_EXCEPT | (unixmessage_sender_isempty(unixmessage_sender_1) ? 0 : IOPAUSE_WRITE) ; x[2].fd = unixmessage_sender_fd(unixmessage_sender_x) ; x[2].events = IOPAUSE_EXCEPT | (unixmessage_sender_isempty(unixmessage_sender_x) ? 0 : IOPAUSE_WRITE) ; for (; i < n ; i++) { a[i].xindex = 3 + i ; x[3+i].fd = a[i].trig.fd ; x[3+i].events = IOPAUSE_READ ; } if (iopause(x, 3 + n, 0, 0) < 0) { cleanup() ; strerr_diefu1sys(111, "iopause") ; } /* client closed */ if ((x[0].revents | x[1].revents) & IOPAUSE_EXCEPT) break ; /* client is reading */ if (x[1].revents & IOPAUSE_WRITE) if (!unixmessage_sender_flush(unixmessage_sender_1) && !error_isagain(errno)) { cleanup() ; strerr_diefu1sys(111, "flush stdout") ; } if (x[2].revents & IOPAUSE_WRITE) if (!unixmessage_sender_flush(unixmessage_sender_x) && !error_isagain(errno)) { cleanup() ; strerr_diefu1sys(111, "flush asyncout") ; } /* scan listening ftrigs */ for (i = 0 ; i < n ; i++) { if (x[a[i].xindex].revents & IOPAUSE_READ) if (!ftrigio_read(a+i)) remove(i--) ; } /* client is writing */ if (!unixmessage_receiver_isempty(unixmessage_receiver_0) || x[0].revents & IOPAUSE_READ) { if (unixmessage_handle(unixmessage_receiver_0, &parse_protocol, 0) < 0) { if (errno == EPIPE) break ; /* normal exit */ cleanup() ; strerr_diefu1sys(111, "handle messages from client") ; } } } cleanup() ; return 0 ; }
static void doit() { iopause_fd x[2]; struct taia deadline; struct taia stamp; int wstat; long int time_cmp = 0; int r; char ch; char warn_message[2048]; int coredumped = 0; char restart_cmd[2048]; announce(); x[0].fd = selfpipe[0]; x[0].events = IOPAUSE_READ; x[1].fd = fdcontrol; x[1].events = IOPAUSE_READ; while (1) { if (flagexit && !pid) break; taia_now(&stamp); taia_uint(&deadline, 3600); taia_add(&deadline, &stamp, &deadline); sig_unblock(sig_child); iopause(x, 2, &deadline, &stamp); sig_block(sig_child); while (read(selfpipe[0], &ch, 1) == 1); while (1) { //waitpid(-1,&wstat,WNOHANG);WNOHANG : return immediately if no child has exited r = wait_nohang(&wstat); //r==0 if one or more child(ren) exit(s) but have not yet changed state if (!r) break; //r == -1 && errno == error_intr means waitpid is interrupted by a signal, we should call waitpid again. //here is not necessary cause we call waitpid with a WNOHANG argument. if (r == -1 && errno != error_intr) break; if (r == pid) { pid = 0; pidchange(); announce(); time_now = time((time_t *)0); if(time_old) { time_cmp = time_now - time_old; if(time_cmp >= time_alarm) //cmp { num = 0; } time_old = time_now; } else { time_cmp = 0; time_old = time_now; } if (0 != restart_sh[0]) { if (num == INT_MAX) num = 0; num++; if (snprintf(restart_cmd, sizeof(restart_cmd), "%s %d", restart_sh, num) > 1) { system(restart_cmd); write_log(fdlog, NOTICE, "restart_cmd: ", restart_cmd, " is called.\n"); } } else { if (WCOREDUMP(wstat)) { have_coredumped++; coredumped = 1; } bzero(warn_message, 2048); create_warn_message(warn_message, coredumped); write_log(fdlog, NOTICE, "service exited", coredumped ? " with coredump" : "", "!\n"); coredumped = 0; if (!closealarm && alarm_interval > 0 && have_tried++ == 0) { alarm(alarm_interval); do_alarm(warn_message); } if (flagexit || (alarm_interval > 0 && have_tried > max_tries && max_tries > 0) || (alarm_interval > 0 && have_coredumped > max_tries_if_coredumped && max_tries_if_coredumped > 0)) { write_log(fdlog, NOTICE, "supervise refused to restart ", service, " any more and exited itself!\n"); alarm(0); return; } } if (flagwant && flagwantup) { write_log(fdlog, NOTICE, "supervise is trying to restart ", service, "...\n"); trystart(); } break; } } if (read(fdcontrol, &ch, 1) != 1) continue; switch(ch) { // -s: Silent. Do not alarm any more. case 's': closealarm = 1; announce(); break; case 'n': closealarm = 0; announce(); break; case 'r': parse_conf(); break; // -d: Down. If the service is running, send it a TERM signal and then a CONT signal. // After it stops, do not restart it. case 'd': flagwant = 1; flagwantup = 0; if (pid) { kill(pid, SIGTERM); kill(pid, SIGCONT); flagpaused = 0; } announce(); break; // -u: Up. If the service is not running, start it. If the service stops, restart it. case 'u': flagwant = 1; flagwantup = 1; announce(); if (!pid) trystart(); break; // -o: Once. If the service is not running, start it. Do not restart it if it stops. case 'o': flagwant = 0; announce(); if (!pid) trystart(); break; // -a: Alarm. Send the service an ALRM signal. case 'a': if (pid) kill(pid, SIGALRM); break; // -h: Hangup. Send the service a HUP signal. case 'h': if (pid) kill(pid, SIGHUP); break; // -k: Kill. Send the service a KILL signal. case 'k': if (pid) kill(pid, SIGKILL); break; //* -t: Terminate. Send the service a TERM signal. case 't': if (pid) kill(pid, SIGTERM); break; // -i: Interrupt. Send the service an INT signal. case 'i': if (pid) kill(pid, SIGINT); break; // -p: Pause. Send the service a STOP signal. case 'p': flagpaused = 1; announce(); if (pid) kill(pid, SIGSTOP); break; // -c: Continue. Send the service a CONT signal. case 'c': flagpaused = 0; announce(); if (pid) kill(pid, SIGCONT); break; // -x: Exit. supervise will exit as soon as the service is down. If you use this option on a //stable system, you're doing something wrong; supervise is designed to run forever. case 'x': flagexit = 1; announce(); break; } //end switch } //end while }
int main(int argc,char **argv) { struct taia stamp; struct taia deadline; int opt; unsigned long u; int i; int j; int r; while ((opt = getopt(argc,argv,"c:l:")) != opteof) switch(opt) { case 'c': scan_ulong(optarg,&u); if (u < 1) u = 1; if (u > 1000) u = 1000; maxactive = u; break; case 'l': scan_ulong(optarg,&u); if (u < 1) u = 1; if (u > 1000000) u = 1000000; xmax = u; break; default: strerr_die1x(111,"dnsfilter: usage: dnsfilter [ -c concurrency ] [ -l lines ]"); } x = (struct line *) alloc(xmax * sizeof(struct line)); if (!x) nomem(); byte_zero(x,xmax * sizeof(struct line)); io = (iopause_fd *) alloc((xmax + 1) * sizeof(iopause_fd)); if (!io) nomem(); if (!stralloc_copys(&partial,"")) nomem(); while (flag0 || inbuflen || partial.len || xnum) { taia_now(&stamp); taia_uint(&deadline,120); taia_add(&deadline,&deadline,&stamp); iolen = 0; if (flag0) if (inbuflen < sizeof inbuf) { inio = io + iolen++; inio->fd = 0; inio->events = IOPAUSE_READ; } for (i = 0;i < xnum;++i) if (x[i].flagactive) { x[i].io = io + iolen++; dns_transmit_io(&x[i].dt,x[i].io,&deadline); } iopause(io,iolen,&deadline,&stamp); if (flag0) if (inbuflen < sizeof inbuf) if (inio->revents) { r = read(0,inbuf + inbuflen,(sizeof inbuf) - inbuflen); if (r <= 0) flag0 = 0; else inbuflen += r; } for (i = 0;i < xnum;++i) if (x[i].flagactive) { r = dns_transmit_get(&x[i].dt,x[i].io,&stamp); if (r == -1) { errout(i); x[i].flagactive = 0; --numactive; } else if (r == 1) { if (dns_name_packet(&x[i].middle,x[i].dt.packet,x[i].dt.packetlen) == -1) errout(i); if (x[i].middle.len) if (!stralloc_cats(&x[i].left,"=")) nomem(); x[i].flagactive = 0; --numactive; } } for (;;) { if (xnum && !x[0].flagactive) { buffer_put(buffer_1,x[0].left.s,x[0].left.len); buffer_put(buffer_1,x[0].middle.s,x[0].middle.len); buffer_put(buffer_1,x[0].right.s,x[0].right.len); buffer_flush(buffer_1); --xnum; tmp = x[0]; for (i = 0;i < xnum;++i) x[i] = x[i + 1]; x[xnum] = tmp; continue; } if ((xnum < xmax) && (numactive < maxactive)) { i = byte_chr(inbuf,inbuflen,'\n'); if (inbuflen && (i == inbuflen)) { if (!stralloc_catb(&partial,inbuf,inbuflen)) nomem(); inbuflen = 0; continue; } if ((i < inbuflen) || (!flag0 && partial.len)) { if (i < inbuflen) ++i; if (!stralloc_catb(&partial,inbuf,i)) nomem(); inbuflen -= i; for (j = 0;j < inbuflen;++j) inbuf[j] = inbuf[j + i]; if (partial.len) { i = byte_chr(partial.s,partial.len,'\n'); i = byte_chr(partial.s,i,'\t'); i = byte_chr(partial.s,i,' '); if (!stralloc_copyb(&x[xnum].left,partial.s,i)) nomem(); if (!stralloc_copys(&x[xnum].middle,"")) nomem(); if (!stralloc_copyb(&x[xnum].right,partial.s + i,partial.len - i)) nomem(); x[xnum].flagactive = 0; partial.len = i; if (!stralloc_0(&partial)) nomem(); if (ip4_scan(partial.s,ip)) { dns_name4_domain(name,ip); if (dns_resolvconfip(servers) == -1) strerr_die2sys(111,FATAL,"unable to read /etc/resolv.conf: "); if (dns_transmit_start(&x[xnum].dt,servers,1,name,DNS_T_PTR,"\0\0\0\0") == -1) errout(xnum); else { x[xnum].flagactive = 1; ++numactive; } } ++xnum; } partial.len = 0; continue; } } break; } } _exit(0); }
int main (void) { stralloc indata = STRALLOC_ZERO ; unsigned int instate = 0 ; PROG = "s6-ftrigrd" ; if (ndelay_on(0) < 0) strerr_diefu2sys(111, "ndelay_on ", "0") ; if (ndelay_on(1) < 0) strerr_diefu2sys(111, "ndelay_on ", "1") ; if (sig_ignore(SIGPIPE) < 0) strerr_diefu1sys(111, "ignore SIGPIPE") ; { struct taia deadline, stamp ; taia_now(&stamp) ; taia_addsec(&deadline, &stamp, 2) ; if (!skaserver2_sync(&asyncout, FTRIGR_BANNER1, FTRIGR_BANNER1_LEN, FTRIGR_BANNER2, FTRIGR_BANNER2_LEN, &deadline, &stamp)) strerr_diefu1sys(111, "sync with client") ; } for (;;) { register unsigned int n = genalloc_len(ftrigio_t, &a) ; iopause_fd x[3 + n] ; unsigned int i = 0 ; int r ; x[0].fd = 0 ; x[0].events = IOPAUSE_EXCEPT | IOPAUSE_READ ; x[1].fd = 1 ; x[1].events = IOPAUSE_EXCEPT | (bufalloc_len(bufalloc_1) ? IOPAUSE_WRITE : 0) ; x[2].fd = bufalloc_fd(&asyncout) ; x[2].events = IOPAUSE_EXCEPT | (bufalloc_len(&asyncout) ? IOPAUSE_WRITE : 0) ; for (; i < n ; i++) { register ftrigio_t_ref p = genalloc_s(ftrigio_t, &a) + i ; p->xindex = 3 + i ; x[3+i].fd = p->trig.fd ; x[3+i].events = IOPAUSE_READ ; } r = iopause(x, 3 + n, 0, 0) ; if (r < 0) { cleanup() ; strerr_diefu1sys(111, "iopause") ; } /* client closed => exit */ if ((x[0].revents | x[1].revents) & IOPAUSE_EXCEPT) break ; /* client reading => flush pending data */ if (x[1].revents & IOPAUSE_WRITE) if ((bufalloc_flush(bufalloc_1) == -1) && !error_isagain(errno)) { cleanup() ; strerr_diefu1sys(111, "flush stdout") ; } if (x[2].revents & IOPAUSE_WRITE) if ((bufalloc_flush(&asyncout) == -1) && !error_isagain(errno)) { cleanup() ; strerr_diefu1sys(111, "flush asyncout") ; } /* scan listening ftrigs */ for (i = 0 ; i < genalloc_len(ftrigio_t, &a) ; i++) { register ftrigio_t_ref p = genalloc_s(ftrigio_t, &a) + i ; if (x[p->xindex].revents & IOPAUSE_READ) { char c ; register int r = sanitize_read(fd_read(p->trig.fd, &c, 1)) ; if (!r) continue ; if (r < 0) { trig(p->id, 'd', errno) ; remove(i--) ; } else if (!sredfa_feed(p->re, &p->dfastate, c)) { trig(p->id, 'd', ENOEXEC) ; remove(i--) ; } else if (p->dfastate & SREDFA_ACCEPT) { trig(p->id, '!', c) ; if (p->options & FTRIGR_REPEAT) p->dfastate = SREDFA_START ; else remove(i--) ; } } } /* client writing => get data and parse it */ if (buffer_len(buffer_0small) || x[0].revents & IOPAUSE_READ) { int r ; for (;;) { uint16 id ; r = sanitize_read(netstring_get(buffer_0small, &indata, &instate)) ; if (r <= 0) break ; if (indata.len < 3) { cleanup() ; strerr_dief1x(100, "invalid client request") ; } uint16_unpack_big(indata.s, &id) ; switch (indata.s[2]) /* protocol parsing */ { case 'U' : /* unsubscribe */ { register unsigned int i = genalloc_len(ftrigio_t, &a) ; for (; i ; i--) if (genalloc_s(ftrigio_t, &a)[i-1].id == id) break ; if (i) remove(i-1) ; answer(0) ; break ; } case 'L' : /* subscribe to path and match re */ { ftrigio_t f = FTRIGIO_ZERO ; uint32 pathlen, relen ; if (indata.len < 18) { answer(EPROTO) ; break ; } uint32_unpack_big(indata.s + 3, &f.options) ; uint32_unpack_big(indata.s + 7, &pathlen) ; uint32_unpack_big(indata.s + 11, &relen) ; if (((pathlen + relen + 16) != indata.len) || indata.s[15 + pathlen]) { answer(EPROTO) ; break ; } f.id = id ; if (!stralloc_0(&indata)) { answer(errno) ; break ; } f.re = sredfa_new() ; if (!f.re) { answer(errno) ; break ; } if (!sredfa_from_regexp(f.re, indata.s + 16 + pathlen) || !ftrig1_make(&f.trig, indata.s + 15)) { sredfa_delete(f.re) ; answer(errno) ; break ; } if (!genalloc_append(ftrigio_t, &a, &f)) { ftrigio_deepfree(&f) ; answer(errno) ; break ; } answer(0) ; break ; } default : { cleanup() ; strerr_dief1x(100, "invalid client request") ; } } indata.len = 0 ; } /* end loop: parse input from client */ if (r < 0) { if (errno == EPIPE) break ; /* client closed */ else { cleanup() ; strerr_diefu1sys(111, "read a netstring") ; } } } /* end if: stuff to read on stdin */ } /* end loop: main iopause */ cleanup() ; return 0 ; }
void doio(void) { iopause_fd x[2]; struct taia deadline; struct taia now; struct taia timeout; if (! stralloc_ready(&encinbuf, bufsizein)) die_nomem(); encin.buf =encin.start =encin.end =encinbuf.s; encin.size =bufsizein; if (! stralloc_ready(&decinbuf, bufsizein)) die_nomem(); decin.buf =decin.start =decin.end =decinbuf.s; decin.size =bufsizein; if (! stralloc_ready(&encoubuf, bufsizeou)) die_nomem(); encou.buf =encou.start =encou.end =encoubuf.s; encou.size =bufsizeou; if (! stralloc_ready(&decoubuf, bufsizeou)) die_nomem(); decou.buf =decou.start =decou.end =decoubuf.s; decou.size =bufsizeou; if (client) { rc =matrixSslEncodeClientHello(ssl, &decou, 0); if (rc != 0) fatalx("unable to encode client hello"); if (write(fdstdou, decou.start, decou.end -decou.start) != (decou.end -decou.start)) fatal("unable to send client hello"); if (verbose > 2) info("sending client hello"); if (verbose > 2) infou("write bytes: ", decou.end -decou.start); bytesou +=decou.end -decou.start; decou.start =decou.end =decou.buf; } taia_now(&now); taia_uint(&timeout, handshake_timeout); taia_add(&timeout, &now, &timeout); for (;;) { iopause_fd *xx =x; int l =2; x[0].fd =encpipe[0]; x[0].events =IOPAUSE_READ; x[0].revents =0; x[1].fd =fdstdin; x[1].events =IOPAUSE_READ; x[1].revents =0; if ((x[0].fd == -1) || handshake) { --l; ++xx; } if (x[1].fd == -1) --l; if (! l) return; taia_now(&now); if (handshake) { if (taia_less(&timeout, &now)) { if (verbose) info("ssl handshake timeout, exit."); return; } deadline.sec =timeout.sec; deadline.nano =timeout.nano; deadline.atto =timeout.atto; } else { taia_uint(&deadline, 30); taia_add(&deadline, &now, &deadline); } iopause(xx, l, &deadline, &now); if (x[0].revents) encode(); if (x[1].revents) decode(); } }
void doit(void) { iopause_fd x[2]; struct taia deadline; struct taia stamp; int wstat; int r; char ch; announce(); for (;;) { if (flagexit && !pid) return; sig_unblock(sig_child); x[0].fd = selfpipe[0]; x[0].events = IOPAUSE_READ; x[1].fd = fdcontrol; x[1].events = IOPAUSE_READ; taia_now(&stamp); taia_uint(&deadline,3600); taia_add(&deadline,&stamp,&deadline); iopause(x,2,&deadline,&stamp); sig_block(sig_child); while (read(selfpipe[0],&ch,1) == 1) ; for (;;) { r = wait_nohang(&wstat); if (!r) break; if ((r == -1) && (errno != error_intr)) break; if (r == pid) { pid = 0; pidchange(); announce(); if (flagexit) return; if (flagwant && flagwantup) trystart(); break; } } if (read(fdcontrol,&ch,1) == 1) switch(ch) { case 'd': flagwant = 1; flagwantup = 0; if (pid) { kill(pid,SIGTERM); kill(pid,SIGCONT); flagpaused = 0; } announce(); break; case 'u': flagwant = 1; flagwantup = 1; announce(); if (!pid) trystart(); break; case 'o': flagwant = 0; announce(); if (!pid) trystart(); break; case 'a': if (pid) kill(pid,SIGALRM); break; case 'h': if (pid) kill(pid,SIGHUP); break; case 'k': if (pid) kill(pid,SIGKILL); break; case 't': if (pid) kill(pid,SIGTERM); break; case 'i': if (pid) kill(pid,SIGINT); break; case 'p': flagpaused = 1; announce(); if (pid) kill(pid,SIGSTOP); break; case 'c': flagpaused = 0; announce(); if (pid) kill(pid,SIGCONT); break; case 'x': flagexit = 1; announce(); break; } } }
void doit(int fdleft,int fdright) { struct taia stamp; struct taia deadline; iopause_fd x[4]; int xlen; iopause_fd *io0; iopause_fd *ioleft; iopause_fd *io1; iopause_fd *ioright; int r; int i; char ch; for (;;) { xlen = 0; io0 = 0; if (leftstatus == 0) { io0 = &x[xlen++]; io0->fd = 0; io0->events = IOPAUSE_READ; } ioleft = 0; if (leftstatus == 1) { ioleft = &x[xlen++]; ioleft->fd = fdleft; ioleft->events = IOPAUSE_WRITE; } ioright = 0; if (rightstatus == 0) { ioright = &x[xlen++]; ioright->fd = fdright; ioright->events = IOPAUSE_READ; } io1 = 0; if (rightstatus == 1) { io1 = &x[xlen++]; io1->fd = 1; io1->events = IOPAUSE_WRITE; } taia_now(&stamp); taia_uint(&deadline,3600); taia_add(&deadline,&stamp,&deadline); iopause(x,xlen,&deadline,&stamp); if (io0 && io0->revents) { r = read(0,prebuf,sizeof prebuf); if (r <= 0) { leftstatus = -1; close(fdleft); } else { leftstatus = 1; leftpos = 0; leftlen = 0; for (i = 0;i < r;++i) { ch = prebuf[i]; if (ch == '\n') if (!leftflagcr) leftbuf[leftlen++] = '\r'; leftbuf[leftlen++] = ch; leftflagcr = (ch == '\r'); } } } if (ioleft && ioleft->revents) { r = write(fdleft,leftbuf + leftpos,leftlen - leftpos); if (r == -1) break; leftpos += r; if (leftpos == leftlen) leftstatus = 0; } if (ioright && ioright->revents) { r = read(fdright,prebuf,sizeof prebuf); if (r <= 0) break; rightstatus = 1; rightpos = 0; rightlen = 0; for (i = 0;i < r;++i) { ch = prebuf[i]; if (ch == '\n') if (!rightflagcr) rightbuf[rightlen++] = '\r'; rightbuf[rightlen++] = ch; rightflagcr = (ch == '\r'); } } if (io1 && io1->revents) { r = write(1,rightbuf + rightpos,rightlen - rightpos); if (r == -1) break; rightpos += r; if (rightpos == rightlen) rightstatus = 0; } } _exit(0); }
int main(int argc,char * const *argv) { int opt; const char *path; mode_t m; iopause_fd x; struct taia deadline; struct taia stamp; int pid = 0; char ch; int wstat; while ((opt = getopt(argc,argv,"wWdDt:")) != opteof) switch(opt) { case 't': scan_uint(optarg,&timeout); break; case 'w': flagwait = 1; break; case 'W': flagwait = 0; break; case 'd': flagdelete = 1; break; case 'D': flagdelete = 0; break; default: usage(); } argv += optind; path = *argv++; if (!path) usage(); if (flagdelete) { m = umask(0); unlink(path); fifo_make(path,0666); umask(m); } fdr = open_read(path); if (fdr == -1) strerr_die4sys(111,FATAL,"cannot read ",path,": "); ndelay_on(fdr); fdw = open_write(path); if (fdw == -1) strerr_die4sys(111,FATAL,"cannot write ",path,": "); if (*argv) { pid = fork(); switch (pid) { case 0: close(fdr); close(fdw); pathexec(argv); strerr_die4sys(111,FATAL,"cannot run ",*argv,": "); case -1: strerr_die4sys(111,FATAL,"cannot fork ",*argv,": "); break; default: break; } } else flagwait = 0; x.fd = fdr; x.events = IOPAUSE_READ; taia_now(&stamp); taia_uint(&deadline,timeout); taia_add(&deadline,&stamp,&deadline); for (;;) { taia_now(&stamp); iopause(&x,1,&deadline,&stamp); if (x.revents) { waiting = 0; break; } if (taia_less(&deadline,&stamp)) { waiting = 99; break; } } if (!waiting) if (read(fdr,&ch,1) != 1) waiting = 0; if (flagwait) if (wait_pid(&wstat,pid) != pid) strerr_die2x(111,FATAL,"cannot reap child process"); _exit(waiting); }