Esempio n. 1
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 != 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;
}
Esempio n. 2
0
void livesync_bind_mcast( ot_ip6 ip, uint16_t port) {
  char tmpip[4] = {0,0,0,0};
  char *v4ip;

  if( !ip6_isv4mapped(ip))
    exerr("v6 mcast support not yet available.");
  v4ip = ip+12;

  if( g_socket_in != -1 )
    exerr("Error: Livesync listen ip specified twice.");

  if( ( g_socket_in = socket_udp4( )) < 0)
    exerr("Error: Cant create live sync incoming socket." );
  ndelay_off(g_socket_in);

  if( socket_bind4_reuse( g_socket_in, tmpip, port ) == -1 )
    exerr("Error: Cant bind live sync incoming socket." );

  if( socket_mcjoin4( g_socket_in, groupip_1, v4ip ) )
    exerr("Error: Cant make live sync incoming socket join mcast group.");

  if( ( g_socket_out = socket_udp4()) < 0)
    exerr("Error: Cant create live sync outgoing socket." );
  if( socket_bind4_reuse( g_socket_out, v4ip, port ) == -1 )
    exerr("Error: Cant bind live sync outgoing socket." );

  socket_mcttl4(g_socket_out, 1);
  socket_mcloop4(g_socket_out, 1);
}
int open_truncatb (int dirfd, char const *name)
{
  int fd = open_truncat(dirfd, name) ;
  if (fd < 0) return -1 ;
  if (ndelay_off(fd) < 0) return -1 ;
  return fd ;
}
Esempio n. 4
0
int main()
{
  char *x;
  int udp53;

  x = env_get("IP");
  if (!x)
    strerr_die2x(111,fatal,"$IP not set");
  if (!ip4_scan(x,ip))
    strerr_die3x(111,fatal,"unable to parse IP address ",x);

  udp53 = socket_udp();
  if (udp53 == -1)
    strerr_die2sys(111,fatal,"unable to create UDP socket: ");
  if (socket_bind4_reuse(udp53,ip,53) == -1)
    strerr_die2sys(111,fatal,"unable to bind UDP socket: ");

  droproot(fatal);

  initialize();
  
  ndelay_off(udp53);
  socket_tryreservein(udp53,65536);

  buffer_putsflush(buffer_2,starting);

  for (;;) {
    len = socket_recv4(udp53,buf,sizeof buf,ip,&port);
    if (len < 0) continue;
    if (!doit()) continue;
    if (response_len > 512) response_tc();
    socket_send4(udp53,response,response_len,ip,port);
    /* may block for buffer space; if it fails, too bad */
  }
}
Esempio n. 5
0
int timeoutconn4(int s,struct ip_address *ip,unsigned int port,int timeout)
{
  char ch;
  struct sockaddr_in sin;
  char *x;
  fd_set wfds;
  struct timeval tv;

  byte_zero(&sin,sizeof(sin));
  byte_copy(&sin.sin_addr,4,ip);
  x = (char *) &sin.sin_port;
  x[1] = port; port >>= 8; x[0] = port;
  sin.sin_family = AF_INET;

  if (ndelay_on(s) == -1) return -1;

  /* XXX: could bind s */

  if (connect(s,(struct sockaddr *) &sin,sizeof(sin)) == 0) {
    ndelay_off(s);
    return 0;
  }
  if ((errno != error_inprogress) && (errno != error_wouldblock)) return -1;

  FD_ZERO(&wfds);
  FD_SET(s,&wfds);
  tv.tv_sec = timeout; tv.tv_usec = 0;

  if (select(s + 1,(fd_set *) 0,&wfds,(fd_set *) 0,&tv) == -1) return -1;
  if (FD_ISSET(s,&wfds)) {
    int dummy;
    dummy = sizeof(sin);
    if (getpeername(s,(struct sockaddr *) &sin,(socklen_t *)&dummy) == -1) {
      /* get return value of read to prevent warn_unused_result */
      //int x = 
      read(s,&ch,1);
      return -1;
    }
    ndelay_off(s);
    return 0;
  }

  errno = error_timeout; /* note that connect attempt is continuing */
  return -1;
}
Esempio n. 6
0
int main (int argc, char const *const *argv, char const *const *envp)
{
  int fd, fd2 ;
  unsigned int flags = 0 ;
  int what = -1 ;
  int changemode = 0 ;
  PROG = "redirfd" ;
  {
    subgetopt_t l = SUBGETOPT_ZERO ;
    for (;;)
    {
      register int opt = subgetopt_r(argc, argv, "rwuacxnb", &l) ;
      if (opt == -1) break ;
      switch (opt)
      {
        case 'r' : what = O_RDONLY ; flags &= ~(O_APPEND|O_CREAT|O_TRUNC|O_EXCL) ; break ;
        case 'w' : what = O_WRONLY ; flags |= O_CREAT|O_TRUNC ; flags &= ~(O_APPEND|O_EXCL) ; break ;
        case 'u' : what = O_RDWR ; flags &= ~(O_APPEND|O_CREAT|O_TRUNC|O_EXCL) ; break ;
        case 'a' : what = O_WRONLY ; flags |= O_CREAT|O_APPEND ; flags &= ~(O_TRUNC|O_EXCL) ; break ;
        case 'c' : what = O_WRONLY ; flags |= O_APPEND ; flags &= ~(O_CREAT|O_TRUNC|O_EXCL) ; break ;
        case 'x' : what = O_WRONLY ; flags |= O_CREAT|O_EXCL ; flags &= ~(O_APPEND|O_TRUNC) ; break ;
        case 'n' : flags |= O_NONBLOCK ; break ;
        case 'b' : changemode = 1 ; break ;
        default : dieusage() ;
      }
    }
    argc -= l.ind ; argv += l.ind ;
  }
  if ((argc < 3) || (what == -1)) dieusage() ;
  if (!uint0_scan(argv[0], (unsigned int *)&fd)) dieusage() ;
  flags |= what ;
  fd2 = open3(argv[1], flags, 0666) ;
  if ((fd2 == -1) && (what == O_WRONLY) && (errno == ENXIO))
  {
    register int e ;
    int fdr = open_read(argv[1]) ;
    if (fdr == -1) strerr_diefu2sys(111, "open_read ", argv[1]) ;
    fd2 = open3(argv[1], flags, 0666) ;
    e = errno ;
    fd_close(fdr) ;
    errno = e ;
  }
  if (fd2 == -1) strerr_diefu2sys(111, "open ", argv[1]) ;
  if (fd_move(fd, fd2) == -1)
  {
    char fmt[UINT_FMT] ;
    fmt[uint_fmt(fmt, fd2)] = 0 ;
    strerr_diefu4sys(111, "move fd ", fmt, " to fd ", argv[0]) ;
  }
  if (changemode)
  {
    if (((flags & O_NONBLOCK) ? ndelay_off(fd) : ndelay_on(fd)) < 0)
      strerr_diefu1sys(111, "change blocking mode") ;
  }
  pathexec_run(argv[2], argv+2, envp) ;
  strerr_dieexec(111, argv[2]) ;
}
Esempio n. 7
0
static int make_connection(char* ip,uint16 port,uint32 scope_id) {
  int v6=byte_diff(ip,12,V4mappedprefix);
  int s;
  if (v6) {
    s=socket_tcp6();
    if (s==-1)
      panic("socket_tcp6()");
    ndelay_off(s);
    if (bindport) {
      for (;;) {
	int r=socket_bind6_reuse(s,V6any,bindport,0);
	if (++bindport<1024) bindport=1024;
	if (r==0) break;
	if (errno!=EADDRINUSE)
	  panic("socket_bind6");
      }
    }
    if (socket_connect6(s,ip,port,scope_id)==-1) {
      carp("socket_connect6");
      close(s);
      return -1;
    }
  } else {
    s=socket_tcp4();
    if (s==-1)
      panic("socket_tcp4()");
    ndelay_off(s);
    if (bindport) {
      for (;;) {
	int r=socket_bind4_reuse(s,V6any,bindport);
	if (++bindport<1024) bindport=1024;
	if (r==0) break;
	if (errno!=EADDRINUSE)
	  panic("socket_bind4");
      }
    }
    if (socket_connect4(s,ip+12,port)==-1) {
      carp("socket_connect4");
      close(s);
      return -1;
    }
  }
  return s;
}
static void alarm_handler(int sig UNUSED_PARAM)
{
    /* This is the escape hatch!  Poor serial line users and the like
     * arrive here when their connection is broken.
     * We don't want to block here */
    ndelay_on(1);
    printf("\r\nLogin timed out after %d seconds\r\n", TIMEOUT);
    fflush_all();
    /* unix API is brain damaged regarding O_NONBLOCK,
     * we should undo it, or else we can affect other processes */
    ndelay_off(1);
    _exit(EXIT_SUCCESS);
}
Esempio n. 9
0
int socket_internal (int domain, int type, int protocol, unsigned int flags)
{
  int s = socket(domain, type, protocol) ;
  if (s == -1) return -1 ;
  if ((((flags & DJBUNIX_FLAG_NB) ? ndelay_on(s) : ndelay_off(s)) < 0)
   || (((flags & DJBUNIX_FLAG_COE) ? coe(s) : uncoe(s)) < 0))
  {
    register int e = errno ;
    fd_close(s) ;
    errno = e ;
    return -1 ;
  }
  return s ;
}
Esempio n. 10
0
int socketpair_internal (int domain, int type, int protocol, unsigned int flags, int *sv)
{
  int fd[2] ;
  if (socketpair(domain, type, protocol, fd) < 0) return -1 ;
  if (flags & DJBUNIX_FLAG_NB)
  {
    if (ndelay_on(fd[0]) < 0) goto err ;
    if (ndelay_on(fd[1]) < 0) goto err ;
  }
  else
  {
    if (ndelay_off(fd[0]) < 0) goto err ;
    if (ndelay_off(fd[1]) < 0) goto err ;
  }
  if (flags & DJBUNIX_FLAG_COE)
  {
    if (coe(fd[0]) < 0) goto err ;
    if (coe(fd[1]) < 0) goto err ;
  }
  else
  {
    if (uncoe(fd[0]) < 0) goto err ;
    if (uncoe(fd[1]) < 0) goto err ;
  }
  sv[0] = fd[0] ;
  sv[1] = fd[1] ;
  return 0 ;

 err:
  {
    register int e = errno ;
    fd_close(fd[1]) ;
    fd_close(fd[0]) ;
    errno = e ;
  }
  return -1 ;
}
Esempio n. 11
0
int main(int argc,const char *const *argv)
{
  int opt;
  int fd;
  const char *dir;

  sig_ignore(sig_pipe);

  while ((opt = getopt(argc,argv,"?vudopchaitkx")) != opteof)
    if (opt == 'v'){
      puts("version: 0.76d");
      exit(0);
    }
    else if (opt == '?')
      strerr_die1x(100,"svc options: u up, d down, o once, x exit, p pause, c continue, h hup, a alarm, i interrupt, t term, k kill");
    else
      if (datalen < sizeof data)
        if (byte_chr(data,datalen,opt) == datalen)
          data[datalen++] = opt;
  argv += optind;

  fdorigdir = open_read(".");
  if (fdorigdir == -1)
    strerr_die2sys(111,FATAL,"unable to open current directory: ");

  while (dir = *argv++) {
    if (chdir(dir) == -1)
      strerr_warn4(WARNING,"unable to chdir to ",dir,": ",&strerr_sys);
    else {
      fd = open_write("supervise/control");
      if (fd == -1)
        if (errno == error_nodevice)
          strerr_warn4(WARNING,"unable to control ",dir,": supervise not running",0);
        else
          strerr_warn4(WARNING,"unable to control ",dir,": ",&strerr_sys);
      else {
        ndelay_off(fd);
        buffer_init(&b,buffer_unixwrite,fd,bspace,sizeof bspace);
        if (buffer_putflush(&b,data,datalen) == -1)
          strerr_warn4(WARNING,"error writing commands to ",dir,": ",&strerr_sys);
        close(fd);
      }
    }
    if (fchdir(fdorigdir) == -1)
      strerr_die2sys(111,FATAL,"unable to set directory: ");
  }

  _exit(0);
}
Esempio n. 12
0
File: s6_svc_write.c Progetto: 8l/s6
int s6_svc_write (char const *fifo, char const *data, unsigned int datalen)
{
  int fd = open_write(fifo) ;
  if (fd < 0) return (errno == ENXIO) ? 0 : -1 ;
  else if (ndelay_off(fd) == -1) return -1 ;
  else if (fd_write(fd, data, datalen) == -1)
  {
    register int e = errno ;
    fd_close(fd) ;
    errno = e ;
    return -1 ;
  }
  fd_close(fd) ;
  return 1 ;
}
Esempio n. 13
0
int ipc_accept_internal (int s, char *p, unsigned int l, int *trunc, unsigned int options)
{
  struct sockaddr_un sa ;
  socklen_t dummy = sizeof sa ;
  register int fd ;
  byte_zero((char*)&sa, (unsigned int)dummy) ;
  do
#ifdef SKALIBS_HASACCEPT4
    fd = accept4(s, (struct sockaddr *)&sa, &dummy, ((options & DJBUNIX_FLAG_NB) ? SOCK_NONBLOCK : 0) | ((options & DJBUNIX_FLAG_COE) ? SOCK_CLOEXEC : 0)) ;
#else
    fd = accept(s, (struct sockaddr *)&sa, &dummy) ;
#endif
  while ((fd == -1) && (errno == EINTR)) ;
  if (fd == -1) return -1 ;
#ifndef SKALIBS_HASACCEPT4
  if ((((options & DJBUNIX_FLAG_NB) ? ndelay_on(fd) : ndelay_off(fd)) < 0)
   || (((options & DJBUNIX_FLAG_COE) ? coe(fd) : uncoe(fd)) < 0))
  {
    register int e = errno ;
    fd_close(fd) ;
    errno = e ;
    return -1 ;
  }
#endif

  if (p)
  {
    dummy = byte_chr(sa.sun_path, dummy, 0) ;
    *trunc = 1 ;
    if (!l) return fd ;
    if (l < (dummy + 1)) dummy = l - 1 ;
    else *trunc = 0 ;
    byte_copy(p, dummy, sa.sun_path) ;
    p[dummy] = 0 ;
  }
  return fd ;
}
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);
}
Esempio n. 15
0
int main(int argc,char **argv)
{
  char *hostname;
//  char *portname;
  int opt;
  struct servent *se;
  char *x;
  unsigned long u;
  int s;
  int t;

  while ((opt = getopt(argc,argv,"4dDvqQhHrR1UXx:t:u:g:l:b:B:c:I:pPoO")) != opteof)
    switch(opt) {
      case 'b': scan_ulong(optarg,&backlog); break;
      case 'c': scan_ulong(optarg,&limit); break;
      case 'X': flagallownorules = 1; break;
      case 'x': fnrules = optarg; break;
      case 'B': banner = optarg; break;
      case 'd': flagdelay = 1; break;
      case 'D': flagdelay = 0; break;
      case 'v': verbosity = 2; break;
      case 'q': verbosity = 0; break;
      case 'Q': verbosity = 1; break;
      case 'P': flagparanoid = 0; break;
      case 'p': flagparanoid = 1; break;
      case 'O': flagkillopts = 1; break;
      case 'o': flagkillopts = 0; break;
      case 'H': flagremotehost = 0; break;
      case 'h': flagremotehost = 1; break;
//      case 'R': flagremoteinfo = 0; break;
      case 'r': flagremoteinfo = 1; break;
      case 't': scan_ulong(optarg,&timeout); break;
      case 'U': x = env_get("UID"); if (x) scan_ulong(x,&uid);
        x = env_get("GID"); if (x) scan_ulong(x,&gid); break;
      case 'u': scan_ulong(optarg,&uid); break;
      case 'g': scan_ulong(optarg,&gid); break;
      case 'I': netif=socket_getifidx(optarg); break;
      case '1': flag1 = 1; break;
//      case '4': noipv6 = 1; break;
      case '4': ipv4socket = 1; break;
//      case '6': forcev6 = 1; break;
      case 'l': localhost = optarg; break;
      default: usage();
    }
  argc -= optind;
  argv += optind;

  if (!verbosity)
    buffer_2->fd = -1;

  hostname = *argv++;
  if (!hostname) usage();
  if (str_equal(hostname,"")) hostname = "0";

  x = *argv++;
  if (!x) usage();
  if (!x[scan_ulong(x,&u)])
    localport = u;
  else {
    se = getservbyname(x,"tcp");
    if (!se)
      errint(EHARD,B("unable to figure out port number for ",x));
    uint16_unpack_big((char*)&se->s_port,&localport);
  }

  if (!*argv) usage();

  sig_block(sig_child);
  sig_catch(sig_child,sigchld);
  sig_catch(sig_term,sigterm);
  sig_ignore(sig_pipe);

  if (str_equal(hostname,"0")) {
    byte_zero(localip,sizeof localip);
  } else {
    if (!stralloc_copys(&tmp,hostname)) errmem;
    if (dns_ip6_qualify(&addresses,&fqdn,&tmp) == -1)
      errint(EHARD,B("temporarily unable to figure out IP address for ",hostname,": "));
    if (addresses.len < 16)
	  errint(EHARD,B("no IP address for ",hostname));
    byte_copy(localip,16,addresses.s);
    if (ip6_isv4mapped(localip))
      ipv4socket = 1;
  }

  s = socket_tcp();
  if (s == -1)
    errint(EHARD,"unable to create socket: ");
  if (socket_bind_reuse(s,localip,localport,netif) == -1)
    errint(EHARD,"unable to bind: ");

  if (!ipv4socket) ipv4socket = ip6_isv4mapped(localip);

  if (socket_local(s,localip,&localport,&netif) == -1)
    errint(EHARD,"unable to get local address: ");
  if (socket_listen(s,backlog) == -1)
    errint(EHARD,"unable to listen: ");
  ndelay_off(s);

  if (gid) if (prot_gid(gid) == -1)
    errint(EHARD,"unable to set gid: ");
  if (uid) if (prot_uid(uid) == -1)
    errint(EHARD,"unable to set uid: ");


  localportstr[fmt_ulong(localportstr,localport)] = 0;
  if (flag1) {
    buffer_init(&b,write,1,bspace,sizeof bspace);
    buffer_puts(&b,localportstr);
    buffer_puts(&b,"\n");
    buffer_flush(&b);
  }

  close(0);
  close(1);
  printstatus();

  for (;;) {
    while (numchildren >= limit) sig_pause();

    sig_unblock(sig_child);
    t = socket_accept(s,remoteip,&remoteport,&netif);
    sig_block(sig_child);

    if (t == -1) continue;
    ++numchildren; printstatus();

    switch(fork()) {
      case 0:
        close(s);
        doit(t);
        if ((fd_move(0,t) == -1) || (fd_copy(1,0) == -1))
          errint(EHARD,"unable to set up descriptors: ");
        sig_uncatch(sig_child);
        sig_unblock(sig_child);
        sig_uncatch(sig_term);
        sig_uncatch(sig_pipe);
        pathexec(argv);
        errint(EHARD,B("unable to run ",*argv,": "));
      case -1:
        errlog(ESOFT,NOTICE,"unable to fork: ");
        --numchildren; printstatus();
    }
    close(t);
  }
}
Esempio n. 16
0
int main(int argc,char * const *argv) {
  const char *hostname;
  int opt;
  char *x;
  unsigned long u;
  int s;
  int t;
  int flagv4 = 1, flagv6 = 1, rc;
  struct addrinfo *localai = NULL, hints = {0}, *ai;
 
  while ((opt = getopt(argc,argv,"dDvqQhHrR1UXx:t:T:u:g:l:b:B:c:pPoO3IiEeSsw:nN46")) != opteof)
    switch(opt) {
      case 'b': scan_ulong(optarg,&backlog); break;
      case 'c': scan_ulong(optarg,&limit); break;
      case 'X': flagallownorules = 1; break;
      case 'x': fnrules = optarg; break;
      case 'B': banner = optarg; break;
      case 'd': flagdelay = 1; break;
      case 'D': flagdelay = 0; break;
      case 'v': verbosity = 2; break;
      case 'q': verbosity = 0; break;
      case 'Q': verbosity = 1; break;
      case 'P': flagparanoid = 0; break;
      case 'p': flagparanoid = 1; break;
      case 'O': flagkillopts = 1; break;
      case 'o': flagkillopts = 0; break;
      case 'H': flagremotehost = 0; break;
      case 'h': flagremotehost = 1; break;
      case 'R': flagremoteinfo = 0; break;
      case 'r': flagremoteinfo = 1; break;
      case 't': scan_ulong(optarg,&timeout); break;
      case 'T': scan_ulong(optarg,&ssltimeout); break;
      case 'w': scan_uint(optarg,&progtimeout); break;
      case 'U': x = env_get("UID"); if (x) scan_ulong(x,&uid);
		x = env_get("GID"); if (x) scan_ulong(x,&gid); break;
      case 'u': scan_ulong(optarg,&uid); break;
      case 'g': scan_ulong(optarg,&gid); break;
      case '1': flag1 = 1; break;
      case 'l': localhost = optarg; break;
      case '3': flag3 = 1; break;
      case 'I': flagclientcert = 0; break;
      case 'i': flagclientcert = 1; break;
      case 'S': flagsslenv = 0; break;
      case 's': flagsslenv = 1; break;
      case 'E': flagtcpenv = 0; break;
      case 'e': flagtcpenv = 1; break;
      case 'n': flagsslwait = 1; break;
      case 'N': flagsslwait = 0; break;
      case '4': flagv6 = 0; break;
      case '6': flagv4 = 0; break;
      default: usage();
    }
  if (flagv4 == flagv6) { flagv4 = flagv6 = 1; }
  argc -= optind;
  argv += optind;

  if (!verbosity)
    buffer_2->fd = -1;
 
  hostname = *argv++;
  if (!hostname) usage();
  if (str_equal(hostname,"")) hostname = NULL;
  if (str_equal(hostname,"0")) hostname = NULL;

  x = *argv++;
  if (!x) usage();
  prog = argv;
  if (!*argv) usage();

  hints.ai_family = flagv4 == flagv6 ? AF_UNSPEC : flagv4 ? AF_INET : AF_INET6;
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_flags = AI_PASSIVE;
  if ((rc = getaddrinfo(hostname, x, &hints, &localai))) {
    strerr_die(111,FATAL "unable to figure out address for ", hostname ? hostname : "0",
		" ",x,": ",gai_strerror(rc),0);
  }
  if (!localai) {
    strerr_die2x(111,FATAL,"address not found");
  }

  if (x = env_get("VERIFYDEPTH")) {
    scan_ulong(x,&u);
    verifydepth = u;
  }

  if (x = env_get("CAFILE")) cafile = x;
  if (cafile && str_equal(cafile,"")) cafile = 0;

  if (x = env_get("CCAFILE")) ccafile = x;
  if (ccafile && str_equal(ccafile,"")) ccafile = 0;
  if (!flagclientcert) ccafile = 0;

  if (x = env_get("CADIR")) cadir = x;
  if (cadir && str_equal(cadir,"")) cadir= 0;

  if (x = env_get("CERTCHAINFILE")) certchainfile = x;
  if (certchainfile && str_equal(certchainfile,"")) certchainfile = 0;

  if (x = env_get("CERTFILE")) certfile = x;
  if (certfile && str_equal(certfile,"")) certfile = 0;

  if (x = env_get("KEYFILE")) keyfile = x;
  if (keyfile && str_equal(keyfile,"")) keyfile = 0;

  if (x = env_get("DHFILE")) dhfile = x;
  if (dhfile && str_equal(dhfile,"")) dhfile = 0;

  if (x = env_get("CIPHERS")) ciphers = x;
  if (ciphers && str_equal(ciphers,"")) ciphers = 0;

  sig_block(sig_child);
  sig_catch(sig_child,sigchld);
  sig_catch(sig_term,sigterm);
  sig_ignore(sig_pipe);

  for (ai = localai; ai; ai = ai->ai_next) { 
    s = socket_tcp(ai->ai_family, ai->ai_protocol);
    if (s == -1)
      strerr_die2sys(111,FATAL,"unable to create socket: ");

    if (socket_bind_reuse(s,ai) == -1)
      strerr_die2sys(111,FATAL,"unable to bind: ");

    if (socket_local(s,&localaddr,&localport) == -1)
      strerr_die2sys(111,FATAL,"unable to get local address: ");
    if (socket_listen(s,backlog) == -1)
      strerr_die2sys(111,FATAL,"unable to listen: ");
    break;
  }
  freeaddrinfo(localai); localai = NULL;
  ndelay_off(s);

  localportstr[fmt_ulong(localportstr,localport)] = 0;
  if (flag1) {
    buffer_init(&b,buffer_unixwrite,1,bspace,sizeof bspace);
    buffer_puts(&b,localportstr);
    buffer_puts(&b,"\n");
    buffer_flush(&b);
  }
 
  if (flag3) read_passwd();

  ctx = ssl_server();
  ssl_errstr();
  if (!ctx) strerr_die2x(111,FATAL,"unable to create SSL context");

  if (certchainfile) {
    switch (ssl_chainfile(ctx,certchainfile,keyfile,passwd_cb)) {
      case -1: strerr_die2x(111,FATAL,"unable to load certificate chain file");
      case -2: strerr_die2x(111,FATAL,"unable to load key");
      case -3: strerr_die2x(111,FATAL,"key does not match certificate");
      default: break;
    }
  } 
  else {  
    switch (ssl_certkey(ctx,certfile,keyfile,passwd_cb)) {
      case -1: strerr_die2x(111,FATAL,"unable to load certificate");
      case -2: strerr_die2x(111,FATAL,"unable to load key");
      case -3: strerr_die2x(111,FATAL,"key does not match certificate");
      default: break;
    }
  }

  if (!ssl_ca(ctx,cafile,cadir,verifydepth))
    strerr_die2x(111,FATAL,"unable to load CA list");

  if (!ssl_cca(ctx,ccafile))
    strerr_die2x(111,FATAL,"unable to load client CA list");

  if (!ssl_params(ctx,dhfile,rsalen))
    strerr_die2x(111,FATAL,"unable to set DH/RSA parameters");

  if (!ssl_ciphers(ctx,ciphers))
    strerr_die2x(111,FATAL,"unable to set cipher list");

  if (verbosity >= 2) {
    strnum[fmt_ulong(strnum,getpid())] = 0;
    strnum2[fmt_ulong(strnum2,rsalen)] = 0;
    strerr_warn4("sslserver: cafile ",strnum," ",cafile,0);
    strerr_warn4("sslserver: ccafile ",strnum," ",ccafile,0);
    strerr_warn4("sslserver: cadir ",strnum," ",cadir,0);
    strerr_warn4("sslserver: chainfile ",strnum," ",certchainfile,0);
    strerr_warn4("sslserver: cert ",strnum," ",certfile,0);
    strerr_warn4("sslserver: key ",strnum," ",keyfile,0);
    strerr_warn6("sslserver: param ",strnum," ",dhfile," ",strnum2,0);
  }

  close(0); open_read("/dev/null");
  close(1); open_append("/dev/null");

  printstatus();
 
  for (;;) {
    while (numchildren >= limit) sig_pause();

    sig_unblock(sig_child);
    t = socket_accept(s,&remoteaddr,&remoteport);
    sig_block(sig_child);

    if (t == -1) continue;
    ++numchildren; printstatus();
 
    switch(fork()) {
      case 0:
        close(s);
        doit(t);
	strerr_die4sys(111,DROP,"unable to run ",*argv,": ");
      case -1:
        strerr_warn2(DROP,"unable to fork: ",&strerr_sys);
        --numchildren; printstatus();
    }
    close(t);
  }
}
Esempio n. 17
0
int
main(int argc, char* argv[]) {
  int s;
  uint16 port = 2342;
  uint32 scope_id = 0;
  char ip[16];
  char buf[8192];
  int i;
  struct pollfd p[2];

  if(argc < 3) {
  usage:
    __write2("usage: client ip port\n\nexample: dump -0 -f - | client 10.0.0.149 8000\n");
    return 0;
  }
  if(argv[1][i = scan_ip6if(argv[1], ip, &scope_id)]) {
    __write2("client: error: invalid ip address!\n");
    goto usage;
  }
  if(argv[2][scan_ushort(argv[2], &port)]) {
    __write2("client: error: invalid port number!\n");
    goto usage;
  }
  if(byte_equal(ip, 12, V4mappedprefix)) {
    s = socket_tcp4b();
    if(s == -1)
      panic("client: error: socket() failed");
    if(socket_connect4(s, ip + 12, port) == -1)
      panic("client: error: connect() failed");
  } else {
    s = socket_tcp6b();
    if(s == -1)
      panic("client: error: socket() failed");
    if(socket_connect6(s, ip, port, scope_id) == -1)
      panic("client: error: connect() failed");
  }
  ndelay_off(s);
  p[0].fd = 0;
  p[0].events = POLLIN;
  p[1].fd = s;
  p[1].events = POLLIN;
  while(poll(p, 2, 5000)) {
    if(p[0].revents) {
      int j;
      if(p[0].revents & POLLERR)
        panic("client: error: poll() signals POLLERR\n");
      i = read(0, buf, sizeof(buf));
      if(i == 0) {
        shutdown(s, SHUT_WR);
        blockingcopy(s, 1);
      }
      for(j = 0; j < i;) {
        int k = write(s, buf + j, i - j);
        if(k == -1)
          panic("client: error: write() failed");
        if(k == 0)
          panic("client: error: short write!\n");
        j += k;
      }
    }
    if(p[1].revents) {
      int j;
      if(p[1].revents & POLLERR)
        panic("client: error: poll() signals POLLERR\n");
      i = read(s, buf, sizeof(buf));
      if(i == 0) {
        shutdown(1, SHUT_WR);
        blockingcopy(0, s);
      }
      for(j = 0; j < i;) {
        int k = write(1, buf + j, i - j);
        if(k == -1)
          panic("client: error: write() failed");
        if(k == 0)
          panic("client: error: short write!\n");
        j += k;
      }
    }
  }
  return 0;
}
Esempio n. 18
0
int main(int argc,char* argv[]) {
  int s,t;
  uint16 port=2342;
  uint32 scope_id=0;
  char ip[16];
  char buf[8192];
  int i;
  struct pollfd p[2];

  if (argc<3) {
usage:
    __write2("usage: server ip port\n\nexample: server 0 8000 | restore x -f -\n");
    return 0;
  }
  if (!strcmp(argv[1],"0"))
    byte_zero(ip,16);
  else
    if (argv[1][i=scan_ip6if(argv[1],ip,&scope_id)]) {
      __write2("server: error: invalid ip address!\n");
      goto usage;
    }
  if (argv[2][scan_ushort(argv[2],&port)]) {
    __write2("server: error: invalid port number!\n");
    goto usage;
  }
  if (byte_equal(ip,12,V4mappedprefix)) {
    s=socket_tcp4b();
    if (s==-1) panic("server: error: socket() failed");
    if (socket_bind4_reuse(s,ip+12,port)==-1) panic("server: error: bind() failed");
    if (socket_listen(s,1)==-1) panic("server: error: listen() failed");
    ndelay_off(s);
    if ((t=socket_accept4(s,0,0))==-1) panic("server: error: accept() failed");
  } else {
    s=socket_tcp6b();
    if (s==-1) panic("server: error: socket() failed");
    if (socket_bind6_reuse(s,ip,port,scope_id)==-1) panic("server: error: bind() failed");
    if (socket_listen(s,1)==-1) panic("server: error: listen() failed");
    ndelay_off(s);
    if ((t=socket_accept6(s,0,0,0))==-1) panic("server: error: accept() failed");
  }
  close(s);
  p[0].fd=0; p[0].events=POLLIN;
  p[1].fd=t; p[1].events=POLLIN;
  while (poll(p,2,5000)) {
    if (p[0].revents) {
      int j;
      if (p[0].revents&POLLERR)
	panic("server: error: poll() signals POLLERR\n");
      i=read(0,buf,sizeof(buf));
      if (i==0) { shutdown(t,SHUT_WR); blockingcopy(t,1); }
      for (j=0; j<i; ) {
	int k=write(t,buf+j,i-j);
	if (k==-1) panic("server: error: write() failed");
	if (k==0) panic("server: error: short write!\n");
	j+=k;
      }
    }
    if (p[1].revents) {
      int j;
      if (p[1].revents&POLLERR)
	panic("server: error: poll() signals POLLERR\n");
      i=read(t,buf,sizeof(buf));
      if (i==0) { shutdown(1,SHUT_WR); blockingcopy(0,t); }
      for (j=0; j<i; ) {
	int k=write(1,buf+j,i-j);
	if (k==-1) panic("server: error: write() failed");
	if (k==0) panic("server: error: short write!\n");
	j+=k;
      }
    }
  }
  return 0;
}
Esempio n. 19
0
static void NOINLINE retrieve_file_data(FILE *dfp)
{
#if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT
# if ENABLE_FEATURE_WGET_TIMEOUT
	unsigned second_cnt;
# endif
	struct pollfd polldata;

	polldata.fd = fileno(dfp);
	polldata.events = POLLIN | POLLPRI;
#endif
	progress_meter(PROGRESS_START);

	if (G.chunked)
		goto get_clen;

	/* Loops only if chunked */
	while (1) {

#if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT
		/* Must use nonblocking I/O, otherwise fread will loop
		 * and *block* until it reads full buffer,
		 * which messes up progress bar and/or timeout logic.
		 * Because of nonblocking I/O, we need to dance
		 * very carefully around EAGAIN. See explanation at
		 * clearerr() call.
		 */
		ndelay_on(polldata.fd);
#endif
		while (1) {
			int n;
			unsigned rdsz;

			rdsz = sizeof(G.wget_buf);
			if (G.got_clen) {
				if (G.content_len < (off_t)sizeof(G.wget_buf)) {
					if ((int)G.content_len <= 0)
						break;
					rdsz = (unsigned)G.content_len;
				}
			}

#if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT
# if ENABLE_FEATURE_WGET_TIMEOUT
			second_cnt = G.timeout_seconds;
# endif
			while (1) {
				if (safe_poll(&polldata, 1, 1000) != 0)
					break; /* error, EOF, or data is available */
# if ENABLE_FEATURE_WGET_TIMEOUT
				if (second_cnt != 0 && --second_cnt == 0) {
					progress_meter(PROGRESS_END);
					bb_error_msg_and_die("download timed out");
				}
# endif
				/* Needed for "stalled" indicator */
				progress_meter(PROGRESS_BUMP);
			}

			/* fread internally uses read loop, which in our case
			 * is usually exited when we get EAGAIN.
			 * In this case, libc sets error marker on the stream.
			 * Need to clear it before next fread to avoid possible
			 * rare false positive ferror below. Rare because usually
			 * fread gets more than zero bytes, and we don't fall
			 * into if (n <= 0) ...
			 */
			clearerr(dfp);
			errno = 0;
#endif
			n = fread(G.wget_buf, 1, rdsz, dfp);
			/* man fread:
			 * If error occurs, or EOF is reached, the return value
			 * is a short item count (or zero).
			 * fread does not distinguish between EOF and error.
			 */
			if (n <= 0) {
#if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT
				if (errno == EAGAIN) /* poll lied, there is no data? */
					continue; /* yes */
#endif
				if (ferror(dfp))
					bb_perror_msg_and_die(bb_msg_read_error);
				break; /* EOF, not error */
			}

			xwrite(G.output_fd, G.wget_buf, n);

#if ENABLE_FEATURE_WGET_STATUSBAR
			G.transferred += n;
			progress_meter(PROGRESS_BUMP);
#endif
			if (G.got_clen) {
				G.content_len -= n;
				if (G.content_len == 0)
					break;
			}
		}
#if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT
		clearerr(dfp);
		ndelay_off(polldata.fd); /* else fgets can get very unhappy */
#endif
		if (!G.chunked)
			break;

		fgets_and_trim(dfp); /* Eat empty line */
 get_clen:
		fgets_and_trim(dfp);
		G.content_len = STRTOOFF(G.wget_buf, NULL, 16);
		/* FIXME: error check? */
		if (G.content_len == 0)
			break; /* all done! */
		G.got_clen = 1;
	}

	/* If -c failed, we restart from the beginning,
	 * but we do not truncate file then, we do it only now, at the end.
	 * This lets user to ^C if his 99% complete 10 GB file download
	 * failed to restart *without* losing the almost complete file.
	 */
	{
		off_t pos = lseek(G.output_fd, 0, SEEK_CUR);
		if (pos != (off_t)-1)
			ftruncate(G.output_fd, pos);
	}

	/* Draw full bar and free its resources */
	G.chunked = 0;  /* makes it show 100% even for chunked download */
	G.got_clen = 1; /* makes it show 100% even for download of (formerly) unknown size */
	progress_meter(PROGRESS_END);
}
int main(int argc,char * const *argv) {
  const char *hostname;
  int opt;
  struct servent *se;
  char *x;
  unsigned long u;
  int s;
  int t;

  io_opt = ssl_io_opt_default;
  io_opt.timeout = 3600;

  while ((opt = getopt(argc,argv,"46dDvqQhHrR1UXx:t:T:u:g:l:b:B:c:Z:pPoO3IiEeSsaAw:nNyYuUjJ")) != opteof)
    switch(opt) {
      case 'b': scan_ulong(optarg,&backlog); break;
      case 'c': scan_ulong(optarg,&limit); break;
      case 'X': flagallownorules = 1; break;
      case 'x': fnrules = optarg; break;
      case 'B': banner = optarg; break;
      case 'd': flagdelay = 1; break;
      case 'D': flagdelay = 0; break;
      case 'v': verbosity = 2; break;
      case 'q': verbosity = 0; break;
      case 'Q': verbosity = 1; break;
      case 'P': flagparanoid = 0; break;
      case 'p': flagparanoid = 1; break;
      case 'O': flagkillopts = 1; break;
      case 'o': flagkillopts = 0; break;
      case 'H': flagremotehost = 0; break;
      case 'h': flagremotehost = 1; break;
      case 'R': flagremoteinfo = 0; break;
      case 'r': flagremoteinfo = 1; break;
      case 't': scan_ulong(optarg,&timeout); break;
      case 'T': scan_ulong(optarg,&ssltimeout); break;
      case 'w': scan_uint(optarg,&io_opt.timeout); break;
      case 'U': x = env_get("UID"); if (x) scan_ulong(x,&uid);
		x = env_get("GID"); if (x) scan_ulong(x,&gid); break;
      case 'u': scan_ulong(optarg,&uid); break;
      case 'g': scan_ulong(optarg,&gid); break;
      case 'Z': netif=socket_getifidx(optarg); break;
      case '1': flag1 = 1; break;
      case '4': noipv6 = 1; break;
      case '6': forcev6 = 1; break;
      case 'l': localhost = optarg; break;
      case '3': flag3 = 1; break;
      case 'I': flagclientcert = 0; break;
      case 'i': flagclientcert = 1; break;
      case 'S': flagsslenv = 0; break;
      case 's': flagsslenv = 1; break;
      case 'E': flagtcpenv = 0; break;
      case 'e': flagtcpenv = 1; break;
      case 'n': case 'y': flagsslwait = 1; break;
      case 'N': case 'Y': flagsslwait = 0; break;
      case 'j': io_opt.just_shutdown = 1; break;
      case 'J': io_opt.just_shutdown = 0; break;
      default: usage();
    }
  argc -= optind;
  argv += optind;

  if (!verbosity)
    buffer_2->fd = -1;
 
  hostname = *argv++;
  if (!hostname) usage();
  if (str_equal(hostname,"")) hostname = "0";

  x = *argv++;
  if (!x) usage();
  prog = argv;
  if (!*argv) usage();
  if (!x[scan_ulong(x,&u)])
    localport = u;
  else {
    se = getservbyname(x,"tcp");
    if (!se)
      strerr_die3x(111,FATAL,"unable to figure out port number for ",x);
    uint16_unpack_big((char*)&se->s_port,&localport);
  }

  if (x = env_get("VERIFYDEPTH")) {
    scan_ulong(x,&u);
    verifydepth = u;
  }

  if (x = env_get("CAFILE")) cafile = x;
  if (cafile && str_equal(cafile,"")) cafile = 0;

  if (x = env_get("CCAFILE")) ccafile = x;
  if (ccafile && str_equal(ccafile,"")) ccafile = 0;
  if (!flagclientcert) ccafile = 0;

  if (x = env_get("CADIR")) cadir = x;
  if (cadir && str_equal(cadir,"")) cadir= 0;

  if (x = env_get("CERTFILE")) certfile = x;
  if (certfile && str_equal(certfile,"")) certfile = 0;

  if (x = env_get("KEYFILE")) keyfile = x;
  if (keyfile && str_equal(keyfile,"")) keyfile = 0;

  if (x = env_get("DHFILE")) dhfile = x;
  if (dhfile && str_equal(dhfile,"")) dhfile = 0;

  if (x = env_get("CIPHERS")) ciphers = x;
  if (ciphers && str_equal(ciphers,"")) ciphers = 0;

  sig_block(sig_child);
  sig_catch(sig_child,sigchld);
  sig_catch(sig_term,sigterm);
  sig_ignore(sig_pipe);
 
  if (str_equal(hostname,"0")) {
    byte_zero(localip,sizeof localip);
  } else {
    if (!stralloc_copys(&tmp,hostname))
      strerr_die2x(111,FATAL,"out of memory");
    if (dns_ip6_qualify(&addresses,&fqdn,&tmp) == -1)
      strerr_die4sys(111,FATAL,"temporarily unable to figure out IP address for ",hostname,": ");
    if (addresses.len < 16)
      strerr_die3x(111,FATAL,"no IP address for ",hostname);
    byte_copy(localip,16,addresses.s);
    if (ip6_isv4mapped(localip))
      noipv6=1;
  }

  s = socket_tcp6();
  if (s == -1)
    strerr_die2sys(111,FATAL,"unable to create socket: ");

  if (socket_bind6_reuse(s,localip,localport,netif) == -1)
    strerr_die2sys(111,FATAL,"unable to bind: ");

  if (socket_local6(s,localip,&localport,&netif) == -1)
    strerr_die2sys(111,FATAL,"unable to get local address: ");
  if (socket_listen(s,backlog) == -1)
    strerr_die2sys(111,FATAL,"unable to listen: ");
  ndelay_off(s);

  localportstr[fmt_ulong(localportstr,localport)] = 0;
  if (flag1) {
    buffer_init(&b,buffer_unixwrite,1,bspace,sizeof bspace);
    buffer_puts(&b,localportstr);
    buffer_puts(&b,"\n");
    buffer_flush(&b);
  }
 
  if (flag3) read_passwd();

  ctx = ssl_server();
  ssl_errstr();
  if (!ctx) strerr_die2x(111,FATAL,"unable to create SSL context");

  switch (ssl_certkey(ctx,certfile,keyfile,passwd_cb)) {
    case -1: strerr_die2x(111,FATAL,"unable to load certificate");
    case -2: strerr_die2x(111,FATAL,"unable to load key");
    case -3: strerr_die2x(111,FATAL,"key does not match certificate");
    default: break;
  }

  if (!ssl_ca(ctx,cafile,cadir,verifydepth))
    strerr_die2x(111,FATAL,"unable to load CA list");

  if (!ssl_cca(ctx,ccafile))
    strerr_die2x(111,FATAL,"unable to load client CA list");

  if (!ssl_params(ctx,dhfile,rsalen))
    strerr_die2x(111,FATAL,"unable to set cipher parameters");

  if (!ssl_ciphers(ctx,ciphers))
    strerr_die2x(111,FATAL,"unable to set cipher list");

  if (verbosity >= 2) {
    strnum[fmt_ulong(strnum,getpid())] = 0;
    strnum2[fmt_ulong(strnum2,rsalen)] = 0;
    strerr_warn4("sslserver: cafile ",strnum," ",cafile,0);
    strerr_warn4("sslserver: ccafile ",strnum," ",ccafile,0);
    strerr_warn4("sslserver: cadir ",strnum," ",cadir,0);
    strerr_warn4("sslserver: cert ",strnum," ",certfile,0);
    strerr_warn4("sslserver: key ",strnum," ",keyfile,0);
    strerr_warn6("sslserver: param ",strnum," ",dhfile," ",strnum2,0);
  }

  close(0); open_read("/dev/null");
  close(1); open_append("/dev/null");

  printstatus();
 
  for (;;) {
    while (numchildren >= limit) sig_pause();

    sig_unblock(sig_child);
    t = socket_accept6(s,remoteip,&remoteport,&netif);
    sig_block(sig_child);

    if (t == -1) continue;
    ++numchildren; printstatus();
 
    switch(fork()) {
      case 0:
        close(s);
        doit(t);
	strerr_die4sys(111,DROP,"unable to run ",*argv,": ");
      case -1:
        strerr_warn2(DROP,"unable to fork: ",&strerr_sys);
        --numchildren; printstatus();
    }
    close(t);
  }
}
Esempio n. 21
0
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);
}
Esempio n. 22
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;
}
Esempio n. 23
0
static int
retrieve_file_data(struct globals *state,
                   FILE *dfp,
                   int (*progress)(void *data, int current, int total),
                   int (*output_func)(void *data, char *bytes, int len),
                   void *data)
{
	char buf[4*1024]; /* made bigger to speed up local xfers */
	unsigned second_cnt;
	struct pollfd polldata;

	polldata.fd = fileno(dfp);
	polldata.events = POLLIN | POLLPRI;
	progress(data, 0, state->total_len);

	if (state->chunked)
		goto get_clen;

	/* Loops only if chunked */
	while (1) {

		ndelay_on(polldata.fd);
		while (1) {
			int n;
			unsigned rdsz;

			rdsz = sizeof(buf);
			if (state->got_clen) {
				if (state->content_len < (off_t)sizeof(buf)) {
					if ((int)state->content_len <= 0)
						break;
					rdsz = (unsigned)state->content_len;
				}
			}
			second_cnt = state->timeout_seconds;
			while (1) {
				if (safe_poll(&polldata, 1, 1000) != 0)
					break; /* error, EOF, or data is available */
				if (second_cnt != 0 && --second_cnt == 0) {
					progress(data, -1, state->total_len);
					ERROR("download timed out");
					return -1;
				}
				/* Needed for "stalled" indicator */
				progress(data, state->transferred, state->total_len);
			}
			/* fread internally uses read loop, which in our case
			 * is usually exited when we get EAGAIN.
			 * In this case, libc sets error marker on the stream.
			 * Need to clear it before next fread to avoid possible
			 * rare false positive ferror below. Rare because usually
			 * fread gets more than zero bytes, and we don't fall
			 * into if (n <= 0) ...
			 */
			clearerr(dfp);
			errno = 0;
			n = safe_fread(buf, rdsz, dfp);
			/* man fread:
			 * If error occurs, or EOF is reached, the return value
			 * is a short item count (or zero).
			 * fread does not distinguish between EOF and error.
			 */
			if (n <= 0) {
				if (errno == EAGAIN) /* poll lied, there is no data? */
					continue; /* yes */
				if (ferror(dfp))
					ERROR("Could not read file");
				break; /* EOF, not error */
			}

			output_func(data, buf, n);
			state->transferred += n;
			progress(data, state->transferred, state->total_len);
			if (state->got_clen) {
				state->content_len -= n;
				if (state->content_len == 0)
					break;
			}
		}
		ndelay_off(polldata.fd);

		if (!state->chunked)
			break;

		safe_fgets(buf, sizeof(buf), dfp); /* This is a newline */
 get_clen:
		safe_fgets(buf, sizeof(buf), dfp);
		state->content_len = strtol(buf, NULL, 16);
		/* FIXME: error check? */
		if (state->content_len == 0)
			break; /* all done! */
		state->got_clen = 1;
	}

	progress(data, state->transferred, state->total_len);
	return 0;
}
Esempio n. 24
0
int stty_main(int argc UNUSED_PARAM, char **argv)
{
	struct termios mode;
	void (*output_func)(const struct termios *, int);
	const char *file_name = NULL;
	int display_all = 0;
	int stty_state;
	int k;

	INIT_G();

	stty_state = STTY_noargs;
	output_func = do_display;

	/* First pass: only parse/verify command line params */
	k = 0;
	while (argv[++k]) {
		const struct mode_info *mp;
		const struct control_info *cp;
		const char *arg = argv[k];
		const char *argnext = argv[k+1];
		int param;

		if (arg[0] == '-') {
			int i;
			mp = find_mode(arg+1);
			if (mp) {
				if (!(mp->flags & REV))
					goto invalid_argument;
				stty_state &= ~STTY_noargs;
				continue;
			}
			/* It is an option - parse it */
			i = 0;
			while (arg[++i]) {
				switch (arg[i]) {
				case 'a':
					stty_state |= STTY_verbose_output;
					output_func = do_display;
					display_all = 1;
					break;
				case 'g':
					stty_state |= STTY_recoverable_output;
					output_func = display_recoverable;
					break;
				case 'F':
					if (file_name)
						bb_error_msg_and_die("only one device may be specified");
					file_name = &arg[i+1]; /* "-Fdevice" ? */
					if (!file_name[0]) { /* nope, "-F device" */
						int p = k+1; /* argv[p] is argnext */
						file_name = argnext;
						if (!file_name)
							bb_error_msg_and_die(bb_msg_requires_arg, "-F");
						/* remove -F param from arg[vc] */
						while (argv[p]) {
							argv[p] = argv[p+1];
							++p;
						}
					}
					goto end_option;
				default:
					goto invalid_argument;
				}
			}
 end_option:
			continue;
		}

		mp = find_mode(arg);
		if (mp) {
			stty_state &= ~STTY_noargs;
			continue;
		}

		cp = find_control(arg);
		if (cp) {
			if (!argnext)
				bb_error_msg_and_die(bb_msg_requires_arg, arg);
			/* called for the side effect of xfunc death only */
			set_control_char_or_die(cp, argnext, &mode);
			stty_state &= ~STTY_noargs;
			++k;
			continue;
		}

		param = find_param(arg);
		if (param & param_need_arg) {
			if (!argnext)
				bb_error_msg_and_die(bb_msg_requires_arg, arg);
			++k;
		}

		switch (param) {
#ifdef __linux__
		case param_line:
# ifndef TIOCGWINSZ
			xatoul_range_sfx(argnext, 1, INT_MAX, stty_suffixes);
			break;
# endif /* else fall-through */
#endif
#ifdef TIOCGWINSZ
		case param_rows:
		case param_cols:
		case param_columns:
			xatoul_range_sfx(argnext, 1, INT_MAX, stty_suffixes);
			break;
		case param_size:
#endif
		case param_speed:
			break;
		case param_ispeed:
			/* called for the side effect of xfunc death only */
			set_speed_or_die(input_speed, argnext, &mode);
			break;
		case param_ospeed:
			/* called for the side effect of xfunc death only */
			set_speed_or_die(output_speed, argnext, &mode);
			break;
		default:
			if (recover_mode(arg, &mode) == 1) break;
			if (tty_value_to_baud(xatou(arg)) != (speed_t) -1) break;
 invalid_argument:
			bb_error_msg_and_die("invalid argument '%s'", arg);
		}
		stty_state &= ~STTY_noargs;
	}

	/* Specifying both -a and -g is an error */
	if ((stty_state & (STTY_verbose_output | STTY_recoverable_output)) ==
		(STTY_verbose_output | STTY_recoverable_output)
	) {
		bb_error_msg_and_die("-a and -g are mutually exclusive");
	}
	/* Specifying -a or -g with non-options is an error */
	if ((stty_state & (STTY_verbose_output | STTY_recoverable_output))
	 && !(stty_state & STTY_noargs)
	) {
		bb_error_msg_and_die("modes may not be set when -a or -g is used");
	}

	/* Now it is safe to start doing things */
	if (file_name) {
		G.device_name = file_name;
		xmove_fd(xopen_nonblocking(G.device_name), STDIN_FILENO);
		ndelay_off(STDIN_FILENO);
	}

	/* Initialize to all zeroes so there is no risk memcmp will report a
	   spurious difference in an uninitialized portion of the structure */
	memset(&mode, 0, sizeof(mode));
	if (tcgetattr(STDIN_FILENO, &mode))
		perror_on_device_and_die("%s");

	if (stty_state & (STTY_verbose_output | STTY_recoverable_output | STTY_noargs)) {
		G.max_col = get_terminal_width(STDOUT_FILENO);
		output_func(&mode, display_all);
		return EXIT_SUCCESS;
	}

	/* Second pass: perform actions */
	k = 0;
	while (argv[++k]) {
		const struct mode_info *mp;
		const struct control_info *cp;
		const char *arg = argv[k];
		const char *argnext = argv[k+1];
		int param;

		if (arg[0] == '-') {
			mp = find_mode(arg+1);
			if (mp) {
				set_mode(mp, 1 /* reversed */, &mode);
				stty_state |= STTY_require_set_attr;
			}
			/* It is an option - already parsed. Skip it */
			continue;
		}

		mp = find_mode(arg);
		if (mp) {
			set_mode(mp, 0 /* non-reversed */, &mode);
			stty_state |= STTY_require_set_attr;
			continue;
		}

		cp = find_control(arg);
		if (cp) {
			++k;
			set_control_char_or_die(cp, argnext, &mode);
			stty_state |= STTY_require_set_attr;
			continue;
		}

		param = find_param(arg);
		if (param & param_need_arg) {
			++k;
		}

		switch (param) {
#ifdef __linux__
		case param_line:
			mode.c_line = xatoul_sfx(argnext, stty_suffixes);
			stty_state |= STTY_require_set_attr;
			break;
#endif
#ifdef TIOCGWINSZ
		case param_cols:
		case param_columns:
			set_window_size(-1, xatoul_sfx(argnext, stty_suffixes));
			break;
		case param_size:
			display_window_size(0);
			break;
		case param_rows:
			set_window_size(xatoul_sfx(argnext, stty_suffixes), -1);
			break;
#endif
		case param_speed:
			display_speed(&mode, 0);
			break;
		case param_ispeed:
			set_speed_or_die(input_speed, argnext, &mode);
			stty_state |= (STTY_require_set_attr | STTY_speed_was_set);
			break;
		case param_ospeed:
			set_speed_or_die(output_speed, argnext, &mode);
			stty_state |= (STTY_require_set_attr | STTY_speed_was_set);
			break;
		default:
			if (recover_mode(arg, &mode) == 1)
				stty_state |= STTY_require_set_attr;
			else /* true: if (tty_value_to_baud(xatou(arg)) != (speed_t) -1) */{
				set_speed_or_die(both_speeds, arg, &mode);
				stty_state |= (STTY_require_set_attr | STTY_speed_was_set);
			} /* else - impossible (caught in the first pass):
				bb_error_msg_and_die("invalid argument '%s'", arg); */
		}
	}

	if (stty_state & STTY_require_set_attr) {
		struct termios new_mode;

		if (tcsetattr(STDIN_FILENO, TCSADRAIN, &mode))
			perror_on_device_and_die("%s");

		/* POSIX (according to Zlotnick's book) tcsetattr returns zero if
		   it performs *any* of the requested operations.  This means it
		   can report 'success' when it has actually failed to perform
		   some proper subset of the requested operations.  To detect
		   this partial failure, get the current terminal attributes and
		   compare them to the requested ones */

		/* Initialize to all zeroes so there is no risk memcmp will report a
		   spurious difference in an uninitialized portion of the structure */
		memset(&new_mode, 0, sizeof(new_mode));
		if (tcgetattr(STDIN_FILENO, &new_mode))
			perror_on_device_and_die("%s");

		if (memcmp(&mode, &new_mode, sizeof(mode)) != 0) {
/*
 * I think the below chunk is not necessary on Linux.
 * If you are deleting it, also delete STTY_speed_was_set bit -
 * it is only ever checked here.
 */
#if 0 /* was "if CIBAUD" */
			/* SunOS 4.1.3 (at least) has the problem that after this sequence,
			   tcgetattr (&m1); tcsetattr (&m1); tcgetattr (&m2);
			   sometimes (m1 != m2).  The only difference is in the four bits
			   of the c_cflag field corresponding to the baud rate.  To save
			   Sun users a little confusion, don't report an error if this
			   happens.  But suppress the error only if we haven't tried to
			   set the baud rate explicitly -- otherwise we'd never give an
			   error for a true failure to set the baud rate */

			new_mode.c_cflag &= (~CIBAUD);
			if ((stty_state & STTY_speed_was_set)
			 || memcmp(&mode, &new_mode, sizeof(mode)) != 0)
#endif
				perror_on_device_and_die("%s: cannot perform all requested operations");
		}
	}

	return EXIT_SUCCESS;
}
Esempio n. 25
0
FILE *start_wget(char *url, int *total)
{
	char buf[512];
	struct host_info server, target;
	len_and_sockaddr *lsa;
	int redir_limit;
#if ENABLE_FEATURE_WGET_LONG_OPTIONS
	char *post_data;
	char *extra_headers = NULL;
	llist_t *headers_llist = NULL;
#endif
	FILE *sfp;                      /* socket to web/ftp server         */
	int use_proxy = 0;              /* Use proxies if env vars are set  */
	const char *user_agent = "Wget";/* "User-Agent" header field        */
	struct globals state;
	char *str;
	int status;
    bzero(&state, sizeof(state));

	static const char keywords[] =
		"content-length\0""transfer-encoding\0""chunked\0""location\0";
	enum {
		KEY_content_length = 1, KEY_transfer_encoding, KEY_chunked, KEY_location
	};

	target.user = NULL;
	parse_url(url, &target);

	state.timeout_seconds = 900;
	server.port = target.port;
	server.host = target.host;

#if 0
	if (opt & WGET_OPT_CONTINUE) {
		output_fd = open(fname_out, O_WRONLY);
		if (output_fd >= 0) {
			state.beg_range = xlseek(output_fd, 0, SEEK_END);
		}
		/* File doesn't exist. We do not create file here yet.
		 * We are not sure it exists on remove side */
	}
#endif

	redir_limit = 5;
 resolve_lsa:
	lsa = xhost2sockaddr(server.host, server.port);
 establish_session:
	/*
	 *  HTTP session
	 */

	/* Open socket to http server */
	sfp = open_socket(lsa);
	if (!sfp) {
		ERROR("Couldn't connect to %s:%d", server.host, server.port);
		return NULL;
	}

	/* Send HTTP request */
	fprintf(sfp, "GET /%s HTTP/1.1\r\n", target.path);

	fprintf(sfp, "Host: %s\r\nUser-Agent: %s\r\n",
		target.host, user_agent);

	/* Ask server to close the connection as soon as we are done
	 * (IOW: we do not intend to send more requests)
	 */
	fprintf(sfp, "Connection: close\r\n");

	if (state.beg_range)
		fprintf(sfp, "Range: bytes=%lu-\r\n", state.beg_range);

	fprintf(sfp, "\r\n");
	fflush(sfp);


	/*
	 * Retrieve HTTP response line and check for "200" status code.
	 */
 read_response:
	if (fgets(buf, sizeof(buf), sfp) == NULL)
		ERROR("no response from server");

	str = buf;
	str = skip_non_whitespace(str);
	str = skip_whitespace(str);
	// FIXME: no error check
	// xatou wouldn't work: "200 OK"
	status = atoi(str);
	switch (status) {
	case 0:
	case 100:
		while (gethdr(buf, sizeof(buf), sfp /*, &n*/) != NULL)
			/* eat all remaining headers */;
		goto read_response;
	case 200:
/*
Response 204 doesn't say "null file", it says "metadata
has changed but data didn't":

"10.2.5 204 No Content
The server has fulfilled the request but does not need to return
an entity-body, and might want to return updated metainformation.
The response MAY include new or updated metainformation in the form
of entity-headers, which if present SHOULD be associated with
the requested variant.

If the client is a user agent, it SHOULD NOT change its document
view from that which caused the request to be sent. This response
is primarily intended to allow input for actions to take place
without causing a change to the user agent's active document view,
although any new or updated metainformation SHOULD be applied
to the document currently in the user agent's active view.

The 204 response MUST NOT include a message-body, and thus
is always terminated by the first empty line after the header fields."

However, in real world it was observed that some web servers
(e.g. Boa/0.94.14rc21) simply use code 204 when file size is zero.
*/
	case 204:
		break;
	case 300:  /* redirection */
	case 301:
	case 302:
	case 303:
		break;
	case 206:
		if (state.beg_range)
			break;
		/* fall through */
	default:
		ERROR("server returned error: %s", sanitize_string(buf));
	}

	/*
	 * Retrieve HTTP headers.
	 */
	while ((str = gethdr(buf, sizeof(buf), sfp /*, &n*/)) != NULL) {
		/* gethdr converted "FOO:" string to lowercase */
		smalluint key;
		/* strip trailing whitespace */
		char *s = strchrnul(str, '\0') - 1;
		while (s >= str && (*s == ' ' || *s == '\t')) {
			*s = '\0';
			s--;
		}
		key = index_in_strings(keywords, buf) + 1;
		if (key == KEY_content_length) {
			state.content_len = strtoul(str, NULL, 10);
			state.total_len   = strtoul(str, NULL, 10);
			if (state.content_len < 0 || errno) {
				ERROR("content-length %s is garbage", sanitize_string(str));
			}
			state.got_clen = 1;
			continue;
		}
		if (key == KEY_transfer_encoding) {
			if (index_in_strings(keywords, str_tolower(str)) + 1 != KEY_chunked)
				ERROR("transfer encoding '%s' is not supported", sanitize_string(str));
			state.chunked = state.got_clen = 1;
		}
		if (key == KEY_location && status >= 300) {
			if (--redir_limit == 0)
				ERROR("too many redirections");
			fclose(sfp);
			state.got_clen = 0;
			state.chunked = 0;
			if (str[0] == '/')
				/* free(target.allocated); */
				target.path = /* target.allocated = */ strdup(str+1);
				/* lsa stays the same: it's on the same server */
			else {
				parse_url(str, &target);
				if (!use_proxy) {
					server.host = target.host;
					server.port = target.port;
					free(lsa);
					goto resolve_lsa;
				} /* else: lsa stays the same: we use proxy */
			}
			goto establish_session;
		}
	}
//		if (status >= 300)
//			ERROR("bad redirection (no Location: header from server)");


	if (total)
		*total = state.content_len;
	ndelay_off(fileno(sfp));
	clearerr(sfp);
	return sfp;
#if 0
	if (retrieve_file_data(&state, sfp, progress, handle, data))
		return -1;
	handle(data, NULL, 0);

	return EXIT_SUCCESS;
#endif
}
Esempio n. 26
0
/* Devilishly complex routine.
 *
 * Has to deal with EOF and EPIPE on input,
 * with line wrapping, with last line not ending in '\n'
 * (possibly not ending YET!), with backspace and tabs.
 * It reads input again if last time we got an EOF (thus supporting
 * growing files) or EPIPE (watching output of slow process like make).
 *
 * Variables used:
 * flines[] - array of lines already read. Linewrap may cause
 *      one source file line to occupy several flines[n].
 * flines[max_fline] - last line, possibly incomplete.
 * terminated - 1 if flines[max_fline] is 'terminated'
 *      (if there was '\n' [which isn't stored itself, we just remember
 *      that it was seen])
 * max_lineno - last line's number, this one doesn't increment
 *      on line wrap, only on "real" new lines.
 * readbuf[0..readeof-1] - small preliminary buffer.
 * readbuf[readpos] - next character to add to current line.
 * last_line_pos - screen line position of next char to be read
 *      (takes into account tabs and backspaces)
 * eof_error - < 0 error, == 0 EOF, > 0 not EOF/error
 */
static void read_lines(void)
{
#define readbuf bb_common_bufsiz1
	char *current_line, *p;
	int w = width;
	char last_terminated = terminated;
#if ENABLE_FEATURE_LESS_REGEXP
	unsigned old_max_fline = max_fline;
	time_t last_time = 0;
	unsigned seconds_p1 = 3; /* seconds_to_loop + 1 */
#endif

	if (option_mask32 & FLAG_N)
		w -= 8;

 IF_FEATURE_LESS_REGEXP(again0:)

	p = current_line = ((char*)xmalloc(w + 4)) + 4;
	max_fline += last_terminated;
	if (!last_terminated) {
		const char *cp = flines[max_fline];
		strcpy(p, cp);
		p += strlen(current_line);
		free(MEMPTR(flines[max_fline]));
		/* last_line_pos is still valid from previous read_lines() */
	} else {
		last_line_pos = 0;
	}

	while (1) { /* read lines until we reach cur_fline or wanted_match */
		*p = '\0';
		terminated = 0;
		while (1) { /* read chars until we have a line */
			char c;
			/* if no unprocessed chars left, eat more */
			if (readpos >= readeof) {
				ndelay_on(0);
				eof_error = safe_read(STDIN_FILENO, readbuf, sizeof(readbuf));
				ndelay_off(0);
				readpos = 0;
				readeof = eof_error;
				if (eof_error <= 0)
					goto reached_eof;
			}
			c = readbuf[readpos];
			/* backspace? [needed for manpages] */
			/* <tab><bs> is (a) insane and */
			/* (b) harder to do correctly, so we refuse to do it */
			if (c == '\x8' && last_line_pos && p[-1] != '\t') {
				readpos++; /* eat it */
				last_line_pos--;
			/* was buggy (p could end up <= current_line)... */
				*--p = '\0';
				continue;
			}
			{
				size_t new_last_line_pos = last_line_pos + 1;
				if (c == '\t') {
					new_last_line_pos += 7;
					new_last_line_pos &= (~7);
				}
				if ((int)new_last_line_pos >= w)
					break;
				last_line_pos = new_last_line_pos;
			}
			/* ok, we will eat this char */
			readpos++;
			if (c == '\n') {
				terminated = 1;
				last_line_pos = 0;
				break;
			}
			/* NUL is substituted by '\n'! */
			if (c == '\0') c = '\n';
			*p++ = c;
			*p = '\0';
		} /* end of "read chars until we have a line" loop */
		/* Corner case: linewrap with only "" wrapping to next line */
		/* Looks ugly on screen, so we do not store this empty line */
		if (!last_terminated && !current_line[0]) {
			last_terminated = 1;
			max_lineno++;
			continue;
		}
 reached_eof:
		last_terminated = terminated;
		flines = xrealloc_vector(flines, 8, max_fline);

		flines[max_fline] = (char*)xrealloc(MEMPTR(current_line), strlen(current_line) + 1 + 4) + 4;
		LINENO(flines[max_fline]) = max_lineno;
		if (terminated)
			max_lineno++;

		if (max_fline >= MAXLINES) {
			eof_error = 0; /* Pretend we saw EOF */
			break;
		}
		if (!(option_mask32 & FLAG_S)
		  ? (max_fline > cur_fline + max_displayed_line)
		  : (max_fline >= cur_fline
		     && max_lineno > LINENO(flines[cur_fline]) + max_displayed_line)
		) {
#if !ENABLE_FEATURE_LESS_REGEXP
			break;
#else
			if (wanted_match >= num_matches) { /* goto_match called us */
				fill_match_lines(old_max_fline);
				old_max_fline = max_fline;
			}
			if (wanted_match < num_matches)
				break;
#endif
		}
		if (eof_error <= 0) {
			if (eof_error < 0) {
				if (errno == EAGAIN) {
					/* not yet eof or error, reset flag (or else
					 * we will hog CPU - select() will return
					 * immediately */
					eof_error = 1;
				} else {
					print_statusline(bb_msg_read_error);
				}
			}
#if !ENABLE_FEATURE_LESS_REGEXP
			break;
#else
			if (wanted_match < num_matches) {
				break;
			} else { /* goto_match called us */
				time_t t = time(NULL);
				if (t != last_time) {
					last_time = t;
					if (--seconds_p1 == 0)
						break;
				}
				sched_yield();
				goto again0; /* go loop again (max 2 seconds) */
			}
#endif
		}
		max_fline++;
		current_line = ((char*)xmalloc(w + 4)) + 4;
		p = current_line;
		last_line_pos = 0;
	} /* end of "read lines until we reach cur_fline" loop */
	fill_match_lines(old_max_fline);
#if ENABLE_FEATURE_LESS_REGEXP
	/* prevent us from being stuck in search for a match */
	wanted_match = -1;
#endif
#undef readbuf
}
Esempio n. 27
0
int main(int argc,char **argv)
{
 char *hostname, *x;
 int c, s, t;
 unsigned int u;
 unsigned int cpid = 0;

 opterr = 0;

 while ((c = getopt(argc, argv, "dDoOC:k:c:")) != -1)
  switch (c) {
	case 'c':
	 limit = atoi(optarg);
	 if (limit == 0) usage();
	 break;
	case 'd': flagdelay = 1; break;
	case 'D': flagdelay = 0; break;
	case 'O': flagkillopts = 1; break;
	case 'o': flagkillopts = 0; break;
	case 'C': cacheprogram = 1; break;
	case 'k':
	 autokill = atoi(optarg);
	 if (autokill == 0) usage();
	 break;
	default: abort();
  }
 argc -= optind;
 argv += optind;

 hostname = *argv++;
 if (!hostname) usage();

 x = *argv++;
 if (!x) usage();
 u = 0;
 u = atoi(x);
 if (u != 0) localport = u;
 else usage();

 if (!*argv) usage();

 sig_block(sig_child);
 sig_catch(sig_child,sigchld);
 sig_catch(sig_term,sigterm);
 sig_catch(sig_int,sigint);
 sig_ignore(sig_pipe);

 inet_aton(hostname, (struct in_addr *) &localip);

 if (autokill != 0) pt = ptable_init(limit);

 s = socket_tcp();
 if (s == -1) die(111, "unable to create socket");
 if (socket_bind4_reuse(s,localip,localport) == -1) die(111, "unable to bind");
 if (socket_local4(s,localip,&localport) == -1) die(111, "unable to get local address");
 if (socket_listen(s,20) == -1) die(111, "unable to listen");
 ndelay_off(s);

 fprintf(stderr, "bind: %s:%d\n", hostname, localport);

 close(0);
 close(1);
 printstatus();

 if (cacheprogram) {

   FILE *fp1;
   int fp2;
   char path[1024];
   ssize_t n;

   fp1 = popen(*argv, "r");
   if (fp1 == NULL) {
     fprintf(stderr, "Failed to run command\n");
     exit(1);
   }

   fp2 = open("/var/tmp/tcpd.cache", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
   if (fp2 == -1) {
     fprintf(stderr, "Can't open cache file\n");
     exit(1);
   }

   while ((n = fgets(path, sizeof(path)-1, fp1)) != NULL) {
     if (write(fp2, path, n) == n) {
       fprintf(stderr, "Error occured while creating cache\n");
       exit(1);
     }
   }

   /* close */
   pclose(fp1);
   close(fp2);

   // read cache file into memory
   FILE *f = fopen("/var/tmp/tcpd.cache", "rb");
   fseek(f, 0, SEEK_END);
   cachesize = ftell(f);
   fseek(f, 0, SEEK_SET);  //same as rewind(f);
   cache = malloc(cachesize + 1);
   n = fread(cache, cachesize, 1, f);
   fclose(f);
   cache[cachesize] = 0;
 }

 for (;;) {
   while (numchildren >= limit) {
    if (autokill != 0) ptable_autokill(pt, limit, autokill);
    sig_pause();
   }

   sig_unblock(sig_child);
   t = socket_accept4(s,remoteip,&remoteport);
   sig_block(sig_child);

   if (t == -1) continue;
   ++numchildren; printstatus();
   fprintf(stderr, "inbound connection from %d.%d.%d.%d:%d\n", (unsigned char) remoteip[0], (unsigned char) remoteip[1], (unsigned char) remoteip[2], (unsigned char) remoteip[3], remoteport);

   if (autokill != 0) ptable_autokill(pt,limit,autokill);

   cpid = fork();
   switch(cpid) {
	case 0:
	 close(s);
	 if(flagkillopts) socket_ipoptionskill(t);
	 if(!flagdelay) socket_tcpnodelay(t);
	 if((fd_move(0,t) == -1) || (fd_copy(1,0) == -1)) die(111,"unable to setup descriptors");
	 sig_uncatch(sig_child);
	 sig_unblock(sig_child);
	 sig_uncatch(sig_term);
	 sig_uncatch(sig_int);
	 sig_uncatch(sig_pipe);

	 if (cacheprogram) {
	   printf("%s", cache);
	   close(t);
	   exit(0);
	 } else {
	   if(execve(*argv,argv,NULL) == 0) {
	     close(t);
	     exit(0);
	   } else {
	     die(111, "unable to run argv");
	   }
	 }
	 break;
	case -1:
	 // unable to fork
	 eprint(P_WARN,"unable to fork");
	 --numchildren; printstatus();
	 break;
	default:
	 fprintf(stderr, "fork: child pid %d\n", cpid);
	 if (autokill != 0) ptable_set(pt, limit, cpid, time(NULL));
	 break;
   }
   close(t);
 }
}