int s6lock_release (s6lock_t *a, uint16 i, tain_t const *deadline, tain_t *stamp) { char *p = GENSETDYN_P(char, &a->data, i) ; if ((*p != EBUSY) && !error_isagain(*p)) { s6lock_check(a, i) ; return 1 ; } { char err ; char pack[3] = "-->" ; uint16_pack_big(pack, i) ; if (!skaclient_send(&a->connection, pack, 3, &skaclient_default_cb, &err, deadline, stamp)) return 0 ; if (err) return (errno = err, 0) ; } *p = EINVAL ; return gensetdyn_delete(&a->data, i) ; }
int timed_buffer_flush (buffer_ref b, struct taia const *deadline, struct taia *stamp) { iopause_fd x = { b->fd, IOPAUSE_WRITE, 0 } ; while (buffer_len(b)) { register int r = iopause_stamp(&x, 1, deadline, stamp) ; if (r < 0) return 0 ; else if (!r) return (errno = ETIMEDOUT, 0) ; else if (x.revents & IOPAUSE_WRITE) { if ((buffer_flush(b) < 0) && !error_isagain(errno)) return 0 ; } else if (x.revents & IOPAUSE_EXCEPT) { buffer_flush(b) ; /* sets errno */ return 0 ; } } return 1 ; }
int error_temp (register int e) { if (error_isagain(e)) return 1 ; switch (e) { case 0 : case EINTR : case ENOMEM : case ETXTBSY : case EIO : case ETIMEDOUT : case ENOBUFS : #ifdef EDEADLK case EDEADLK : #endif #ifdef EBUSY case EBUSY : #endif #ifdef ENFILE case ENFILE : #endif #ifdef EFBIG case EFBIG : #endif #ifdef ENOSPC case ENOSPC : #endif #ifdef ENETDOWN case ENETDOWN : #endif #ifdef ENETUNREACH case ENETUNREACH : #endif #ifdef ENETRESET case ENETRESET : #endif #ifdef ECONNABORTED case ECONNABORTED : #endif #ifdef ECONNRESET case ECONNRESET : #endif #ifdef ETOOMANYREFS case ETOOMANYREFS : #endif #ifdef ECONNREFUSED case ECONNREFUSED : #endif #ifdef EHOSTDOWN case EHOSTDOWN : #endif #ifdef EHOSTUNREACH case EHOSTUNREACH : #endif #ifdef EPROCLIM case EPROCLIM : #endif #ifdef EUSERS case EUSERS : #endif #ifdef EDQUOT case EDQUOT : #endif #ifdef ESTALE case ESTALE : #endif #ifdef ENOLCK case ENOLCK : #endif return 1 ; default : return 0 ; } }
int s6_fdholder_setdump (s6_fdholder_t *a, s6_fdholder_fd_t const *list, unsigned int ntot, tain_t const *deadline, tain_t *stamp) { uint32 trips ; if (!ntot) return 1 ; unsigned int i = 0 ; for (; i < ntot ; i++) { unsigned int zpos = byte_chr(list[i].id, S6_FDHOLDER_ID_SIZE + 1, 0) ; if (!zpos || zpos >= S6_FDHOLDER_ID_SIZE + 1) return (errno = EINVAL, 0) ; } { char pack[5] = "!" ; unixmessage_t m = { .s = pack, .len = 5, .fds = 0, .nfds = 0 } ; uint32_pack_big(pack+1, ntot) ; if (!unixmessage_put(&a->connection.out, &m)) return 0 ; if (!unixmessage_sender_timed_flush(&a->connection.out, deadline, stamp)) return 0 ; if (sanitize_read(unixmessage_timed_receive(&a->connection.in, &m, deadline, stamp)) < 0) return 0 ; if (!m.len || m.nfds) { unixmessage_drop(&m) ; return (errno = EPROTO, 0) ; } if (m.s[0]) return (errno = m.s[0], 0) ; if (m.len != 5) return (errno = EPROTO, 0) ; uint32_unpack_big(m.s + 1, &trips) ; if (trips != 1 + (ntot-1) / UNIXMESSAGE_MAXFDS) return (errno = EPROTO, 0) ; } for (i = 0 ; i < trips ; i++, ntot -= UNIXMESSAGE_MAXFDS) { { unsigned int n = ntot > UNIXMESSAGE_MAXFDS ? UNIXMESSAGE_MAXFDS : ntot ; unsigned int j = 0 ; siovec_t v[1 + (n<<1)] ; int fds[n] ; unixmessage_v_t m = { .v = v, .vlen = 1 + (n<<1), .fds = fds, .nfds = n } ; char pack[n * (TAIN_PACK+1)] ; v[0].s = "." ; v[0].len = 1 ; for (; j < n ; j++, list++, ntot--) { unsigned int len = str_len(list->id) ; v[1 + (j<<1)].s = pack + j * (TAIN_PACK+1) ; v[1 + (j<<1)].len = TAIN_PACK + 1 ; tain_pack(pack + j * (TAIN_PACK+1), &list->limit) ; pack[j * (TAIN_PACK+1) + TAIN_PACK] = (unsigned char)len ; v[2 + (j<<1)].s = (char *)list->id ; v[2 + (j<<1)].len = len + 1 ; fds[j] = list->fd ; } if (!unixmessage_putv(&a->connection.out, &m)) return 0 ; } if (!unixmessage_sender_timed_flush(&a->connection.out, deadline, stamp)) return 0 ; { unixmessage_t m ; if (sanitize_read(unixmessage_timed_receive(&a->connection.in, &m, deadline, stamp)) < 0) return 0 ; if (m.len != 1 || m.nfds) { unixmessage_drop(&m) ; return (errno = EPROTO, 0) ; } if (!error_isagain(m.s[0]) && i < trips-1) return errno = m.s[0] ? m.s[0] : EPROTO, 0 ; if (i == trips - 1 && m.s[0]) return errno = error_isagain(m.s[0]) ? EPROTO : m.s[0], 0 ; } } return 1 ; }
int main (int argc, char const *const *argv) { tain_t deadline ; int sfd ; PROG = "bevt_relayd" ; if (argc < 2) strerr_dieusage(100, USAGE) ; 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") ; sfd = selfpipe_init() ; if (sfd < 0) strerr_diefu1sys(111, "selfpipe_init") ; { sigset_t set ; sigemptyset(&set) ; sigaddset(&set, SIGCHLD) ; sigaddset(&set, SIGTERM) ; sigaddset(&set, SIGQUIT) ; sigaddset(&set, SIGHUP) ; sigaddset(&set, SIGABRT) ; sigaddset(&set, SIGINT) ; if (selfpipe_trapset(&set) < 0) strerr_diefu1sys(111, "trap signals") ; } if(bevt_relay_db_init(argv[1])<0) strerr_diefu1sys(111, "db init failed") ; tain_now_g() ; tain_addsec_g(&deadline, 2) ; if (!skaclient_server_01x_init_g(BEVT_RELAY_BANNER1, BEVT_RELAY_BANNER1_LEN, BEVT_RELAY_BANNER2, BEVT_RELAY_BANNER2_LEN, &deadline)) strerr_diefu1sys(111, "sync with client") ; for (;;) { register unsigned int n = 0 ; iopause_fd x[6 + n] ; int r ; if(mfd<0) handle_connect_central(); tain_add_g(&deadline, &tain_infinite_relative) ; 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 = sfd ; x[2].events = IOPAUSE_READ ; x[3].fd = bozclient_sfd(¢ral_client_g); x[3].events = IOPAUSE_READ ; x[4].fd = bozclient_sfd(¢ral_client_g); x[4].events = (bozclient_siswritable(¢ral_client_g) ? IOPAUSE_WRITE : 0) ; x[5].fd = unixmessage_sender_fd(unixmessage_sender_x) ; x[5].events = (unixmessage_sender_isempty(unixmessage_sender_x) ? 0 : IOPAUSE_WRITE) ; r = iopause_g(x, 5 + n, &deadline) ; if (r < 0) { cleanup() ; strerr_diefu1sys(111, "iopause") ; } /* client closed */ if ((x[0].revents | x[1].revents) & IOPAUSE_EXCEPT) break ; /* client is sync reading */ if (x[1].revents & IOPAUSE_WRITE) { if (!unixmessage_sender_flush(unixmessage_sender_1) && !error_isagain(errno)) { cleanup() ; strerr_diefu1sys(111, "flush sync out") ; } } /* client is async rzading */ if (x[5].revents & IOPAUSE_WRITE) { if (!unixmessage_sender_flush(unixmessage_sender_x) && !error_isagain(errno)) { cleanup() ; strerr_diefu1sys(111, "flush async out") ; } } /* signals arrived */ if (x[2].revents & (IOPAUSE_READ | IOPAUSE_EXCEPT)) handle_signals() ; /* main socket read or close */ if (x[3].revents & IOPAUSE_READ) { handle_close_central(); continue; } /* main socket close */ if (x[4].revents & IOPAUSE_WRITE) { bozclient_flush(¢ral_client_g); } /* main socket close */ if (x[5].revents & IOPAUSE_WRITE) { if (!unixmessage_sender_flush(unixmessage_sender_x) && !error_isagain(errno)) { cleanup() ; strerr_diefu1sys(111, "flush stdout") ; } } /* client is sync writing */ if (!unixmessage_receiver_isempty(unixmessage_receiver_0) || x[0].revents & IOPAUSE_READ) { if (unixmessage_handle(unixmessage_receiver_0, &bevt_relay_parse_prot_cmd, 0) < 0) { if (errno == EPIPE) break ; /* normal exit */ cleanup() ; strerr_diefu1sys(111, "handle messages from client") ; } } } cleanup() ; return 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 ; }
int socket_deadlineconnstamp6 (int s, char const *ip, uint16 port, struct taia const *deadline, struct taia *stamp) { if (socket_connect6(s, ip, port) >= 0) return 1 ; if (!error_isagain(errno) && !error_isalready(errno)) return 0 ; return socket_waitconn(s, deadline, stamp) ; }
int sanitize_read (int r) { return r == -1 ? error_isagain(errno) ? (errno = 0, 0) : -1 : !r ? (errno = EPIPE, -1) : r ; }
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 ; }