Beispiel #1
0
char *mylocalhost (void)
{
  if (!myLocalHost) {
    char tmp[MAILTMPLEN];
    if (!wsa_initted++) {	/* init Windows Sockets */
      WSADATA wsock;
      if (WSAStartup (WINSOCK_VERSION,&wsock)) {
	wsa_initted = 0;
	return "random-pc";	/* try again later? */
      }
    }
    myLocalHost = cpystr ((gethostname (tmp,MAILTMPLEN-1) == SOCKET_ERROR) ?
			  "random-pc" : tcp_canonical (tmp));
  }
  return myLocalHost;
}
Beispiel #2
0
TCPSTREAM *tcp_aopen (NETMBX *mb,char *service,char *usrbuf)
{
  TCPSTREAM *stream = NIL;
  void *adr;
  char host[MAILTMPLEN],tmp[MAILTMPLEN],*path,*argv[MAXARGV+1],*r;
  int i,ti,pipei[2],pipeo[2];
  size_t len;
  time_t now;
  struct timeval tmo;
  fd_set fds,efds;
  blocknotify_t bn = (blocknotify_t) mail_parameters (NIL,GET_BLOCKNOTIFY,NIL);
#ifdef SSHPATH			/* ssh path defined yet? */
  if (!sshpath) sshpath = cpystr (SSHPATH);
#endif
#ifdef RSHPATH			/* rsh path defined yet? */
  if (!rshpath) rshpath = cpystr (RSHPATH);
#endif
  if (*service == '*') {	/* want ssh? */
				/* return immediately if ssh disabled */
    if (!(sshpath && (ti = sshtimeout))) return NIL;
				/* ssh command prototype defined yet? */
    if (!sshcommand) sshcommand = cpystr ("%s %s -l %s exec /etc/r%sd");
  }
				/* want rsh? */
  else if (rshpath && (ti = rshtimeout)) {
				/* rsh command prototype defined yet? */
    if (!rshcommand) rshcommand = cpystr ("%s %s -l %s exec /etc/r%sd");
  }
  else return NIL;		/* rsh disabled */
				/* look like domain literal? */
  if (mb->host[0] == '[' && mb->host[i = (strlen (mb->host))-1] == ']') {
    strcpy (host,mb->host+1);	/* yes, copy without brackets */
    host[i-1] = '\0';
				/* validate domain literal */
    if (adr = ip_stringtoaddr (host,&len,&i)) fs_give ((void **) &adr);
    else {
      sprintf (tmp,"Bad format domain-literal: %.80s",host);
      mm_log (tmp,ERROR);
      return NIL;
    }
  }
  else strcpy (host,tcp_canonical (mb->host));

  if (*service == '*')		/* build ssh command */
    sprintf (tmp,sshcommand,sshpath,host,
	     mb->user[0] ? mb->user : myusername (),service + 1);
  else sprintf (tmp,rshcommand,rshpath,host,
		mb->user[0] ? mb->user : myusername (),service);
  if (tcpdebug) {
    char msg[MAILTMPLEN];
    sprintf (msg,"Trying %.100s",tmp);
    mm_log (msg,TCPDEBUG);
  }
				/* parse command into argv */
  for (i = 1,path = argv[0] = strtok_r (tmp," ",&r);
       (i < MAXARGV) && (argv[i] = strtok_r (NIL," ",&r)); i++);
  argv[i] = NIL;		/* make sure argv tied off */
				/* make command pipes */
  if (pipe (pipei) < 0) return NIL;
  if ((pipei[0] >= FD_SETSIZE) || (pipei[1] >= FD_SETSIZE) ||
      (pipe (pipeo) < 0)) {
    close (pipei[0]); close (pipei[1]);
    return NIL;
  }
  (*bn) (BLOCK_TCPOPEN,NIL);	/* quell alarm up here for NeXT */
  if ((pipeo[0] >= FD_SETSIZE) || (pipeo[1] >= FD_SETSIZE) ||
      ((i = fork ()) < 0)) {	/* make inferior process */
    close (pipei[0]); close (pipei[1]);
    close (pipeo[0]); close (pipeo[1]);
    (*bn) (BLOCK_NONE,NIL);
    return NIL;
  }
  if (!i) {			/* if child */
    alarm (0);			/* never have alarms in children */
    if (!fork ()) {		/* make grandchild so it's inherited by init */
      int cf;			/* don't alter parent vars in case vfork() */
      int maxfd = max (20,max (max(pipei[0],pipei[1]),max(pipeo[0],pipeo[1])));
      dup2 (pipei[1],1);	/* parent's input is my output */
      dup2 (pipei[1],2);	/* parent's input is my error output too */
      dup2 (pipeo[0],0);	/* parent's output is my input */
				/* close all unnecessary descriptors */
      for (cf = 3; cf <= maxfd; cf++) close (cf);
      setpgrp (0,getpid ());	/* be our own process group */
      _exit (execv (path,argv));/* now run it */
    }
    _exit (1);			/* child is done */
  }
  grim_pid_reap (i,NIL);	/* reap child; grandchild now owned by init */
  close (pipei[1]);		/* close child's side of the pipes */
  close (pipeo[0]);

				/* create TCP/IP stream */
  stream = (TCPSTREAM *) memset (fs_get (sizeof (TCPSTREAM)),0,
				 sizeof (TCPSTREAM));
				/* copy remote host name from argument */
  stream->remotehost = cpystr (stream->host = cpystr (host));
  stream->tcpsi = pipei[0];	/* init sockets */
  stream->tcpso = pipeo[1];
  stream->ictr = 0;		/* init input counter */
  stream->port = 0xffffffff;	/* no port number */
  ti += now = time (0);		/* open timeout */
  tmo.tv_usec = 0;		/* initialize usec timeout */
  FD_ZERO (&fds);		/* initialize selection vector */
  FD_ZERO (&efds);		/* handle errors too */
  FD_SET (stream->tcpsi,&fds);	/* set bit in selection vector */
  FD_SET (stream->tcpsi,&efds);	/* set bit in error selection vector */
  FD_SET (stream->tcpso,&efds);	/* set bit in error selection vector */
  do {				/* block under timeout */
    tmo.tv_sec = ti - now;
    i = select (max (stream->tcpsi,stream->tcpso)+1,&fds,NIL,&efds,&tmo);
    now = time (0);		/* fake timeout if interrupt & time expired */
    if ((i < 0) && (errno == EINTR) && ti && (ti <= now)) i = 0;
  } while ((i < 0) && (errno == EINTR));
  if (i <= 0) {			/* timeout or error? */
    sprintf (tmp,i ? "error in %s to IMAP server" :
	     "%s to IMAP server timed out",(*service == '*') ? "ssh" : "rsh");
    mm_log (tmp,WARN);
    tcp_close (stream);		/* punt stream */
    stream = NIL;
  }
  (*bn) (BLOCK_NONE,NIL);
				/* return user name */
  strcpy (usrbuf,mb->user[0] ? mb->user : myusername ());
  return stream;		/* return success */
}