Example #1
0
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 ;
  }
}
Example #4
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 ;
}
Example #5
0
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(&central_client_g); x[3].events = IOPAUSE_READ ;
        x[4].fd = bozclient_sfd(&central_client_g); x[4].events = (bozclient_siswritable(&central_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(&central_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) ;
}
Example #8
0
int sanitize_read (int r)
{
  return r == -1 ? error_isagain(errno) ? (errno = 0, 0) : -1 :
         !r ? (errno = EPIPE, -1) : r ;
}
Example #9
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 ;
}