home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3543 / tcpclient.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-26  |  4.9 KB  |  200 lines

  1. /* Public domain. */
  2.  
  3. #include <stdio.h>
  4. #include <sys/types.h>
  5. #include <sys/socket.h>
  6. #include <sys/param.h>
  7. #include <netinet/in.h>
  8. #include <arpa/inet.h>
  9. #include <signal.h>
  10. #include "dupdup.h"
  11. #include "malloc.h"
  12. #include "errno.h"
  13. #include "username.h"
  14. #include "hostname.h"
  15. #include "portname.h"
  16. #include "env.h"
  17. #include "getopt.h"
  18. #include "authuser.h"
  19. #include "numfiles.h"
  20.  
  21. #ifndef MAXHOSTNAMELEN
  22. #define MAXHOSTNAMELEN 64
  23. #endif
  24.  
  25. static int flagdo931 = 1;
  26. static int flagverbose = 1;
  27. static struct sockaddr_in sa;
  28. static struct sockaddr_in saloc;
  29.  
  30. static char errbuf[500];
  31. void die(n,s) int n; char *s;
  32. { if (flagverbose) fprintf(stderr,"tcpclient: fatal: %s\n",s); exit(n); }
  33. void dies(n,s,t) int n; char *s; char *t;
  34. { if (flagverbose) fprintf(stderr,"tcpclient: fatal: %s%s\n",s,t); exit(n); }
  35. void diep(n,s) int n; char *s;
  36. { if (flagverbose) sprintf(errbuf,"tcpclient: fatal: %s",s); perror(errbuf); exit(n); }
  37. void warnp(s) char *s;
  38. { if (flagverbose) sprintf(errbuf,"tcpclient: warning: %s",s); perror(errbuf); }
  39. void warnsp(s,t) char *s; char *t;
  40. { if (flagverbose) sprintf(errbuf,"tcpclient: warning: %s%s",s,t); perror(errbuf); }
  41.  
  42. main(argc,argv,envp)
  43. int argc;
  44. char *argv[];
  45. char *envp[];
  46. {
  47.  int t;
  48.  int *d;
  49.  int tdup;
  50.  int numfiles;
  51.  int i;
  52.  static char tcplocal[200];
  53.  static char tcpremote[300];
  54.  int opt;
  55.  int uid;
  56.  char *uname;
  57.  char lochost[MAXHOSTNAMELEN];
  58.  struct in_addr locinaddr;
  59.  int port;
  60.  int locport;
  61.  int dummy;
  62.  char *ruser;
  63.  
  64.  locport = 0;
  65.  
  66.  while ((opt = getopt(argc,argv,"qQp:rR")) != EOF)
  67.    switch(opt)
  68.     {
  69.      case 'q':
  70.        flagverbose = 0; break;
  71.      case 'Q':
  72.        flagverbose = 1; break;
  73.      case 'p':
  74.        /* XXX: check that optarg is numeric? */
  75.        locport = atoi(optarg);
  76.        break;
  77.      case 'r':
  78.        flagdo931 = 1;
  79.        break;
  80.      case 'R':
  81.        flagdo931 = 0;
  82.        break;
  83.      case '?':
  84.        break; /*XXX*/
  85.      default:
  86.        break; /*XXX*/
  87.     }
  88.  argc -= optind; argv += optind;
  89.  
  90.  if (argc < 3)
  91.    die(1,"need at least three arguments");
  92.  
  93.  uid = getuid();
  94.  if (uid2username(uid,&uname) == -1) /* will never happen */
  95.    die(2,"cannot figure out my own username");
  96.  
  97.  gethostname(lochost,sizeof(lochost));
  98.  if (hostname2inaddr(lochost,&locinaddr) == -1)
  99.    die(2,"cannot figure out my own hostname");
  100.  
  101.  if ((argv[0][0] == '0') && (argv[0][1] == 0))
  102.    sa.sin_addr.s_addr = INADDR_ANY; /* special case "0" */
  103.  else
  104.   {
  105.    if (hostname2inaddr(argv[0],&sa.sin_addr) == -1)
  106.      dies(2,"cannot figure out hostname ",argv[0]);
  107.   }
  108.  
  109.  if (portname2port(argv[1],&port,"tcp") == -1)
  110.    dies(2,"cannot figure out portname ",argv[1]);
  111.  port = port & 65535;
  112.  sa.sin_port = htons((short) port);
  113.  
  114.  close(6);
  115.  close(7); /* XXX: these have implications that should be documented */
  116.  
  117.  signal(SIGPIPE,SIG_IGN);
  118.  
  119.  numfiles = NUMFILES;
  120.  d = (int *) malloc(numfiles * sizeof(int));
  121.  if (!d)
  122.    die(6,"cannot malloc");
  123.  for (i = 0;i < numfiles;++i)
  124.    d[i] = -1;
  125.  
  126.  if (env_init() == -1)
  127.    die(11,"cannot init environment");
  128.  if (env_put("PROTO=TCP") == -1)
  129.    die(11,"out of memory putting PROTO into environment");
  130.  
  131.  t = socket(AF_INET,SOCK_STREAM,0);
  132.  if (t == -1)
  133.    diep(7,"cannot create client socket");
  134.  sa.sin_family = AF_INET;
  135.  if (locport)
  136.   {
  137.    /* attempt to bind to given local port */
  138.    /* could do this in advance in all cases if we were desperate to 
  139.       get TCPLOCAL figured out as fast as possible */
  140.    saloc.sin_family = AF_INET;
  141.    saloc.sin_addr.s_addr = INADDR_ANY;
  142.    saloc.sin_port = htons((short) locport);
  143.    if (bind(t,&saloc,sizeof(saloc)) == -1)
  144.      diep(9,"cannot bind to local port");
  145.   }
  146.  if (connect(t,&sa,sizeof(sa)) == -1)
  147.    /* XXX: HRRFC says we should try alternate addresses */
  148.    diep(9,"cannot connect to server");
  149.  dummy = sizeof(saloc);
  150.  if (getsockname(t,&saloc,&dummy) == -1)
  151.    diep(9,"cannot figure out local connection address");
  152.  
  153.  locport = ntohs(saloc.sin_port);
  154.  
  155.  ruser = "";
  156.  if (flagdo931)
  157.   {
  158.    ruser = auth_tcpuser((unsigned long) sa.sin_addr.s_addr
  159.       ,(unsigned short) locport
  160.       ,(unsigned short) port);
  161.    if (!ruser)
  162.      ruser = ""; /* XXX: any other suggestions? */
  163.   }
  164.  
  165.  sprintf(tcplocal,"TCPLOCAL=%s@%s(%s):%d"
  166.    ,uname
  167.    ,inet_ntoa(locinaddr) /* could use saloc.sin_addr */
  168.    ,lochost /* could use hostname of saloc.sin_addr */
  169.    ,locport
  170.   );
  171.  if (env_put(tcplocal) == -1)
  172.    die(11,"out of memory putting TCPLOCAL into environment");
  173.  sprintf(tcpremote,"TCPREMOTE=%s@%s(%s):%d"
  174.    ,ruser
  175.    ,inet_ntoa(sa.sin_addr)
  176.    ,argv[0] /* could do lookup instead, but why bother? */
  177.    ,port
  178.   );
  179.  if (env_put(tcpremote) == -1)
  180.    die(11,"out of memory putting TCPREMOTE into environment");
  181.  
  182.  /* XXX: fork? not necessary here */
  183.  
  184.  tdup = dup(t);
  185.  if (tdup == -1)
  186.    diep(10,"cannot dup connection to server");
  187.  
  188.  /* Now put t into descriptor 6 and tdup into descriptor 7. */
  189.  /* XXX: should check that t and tdup are small enough */
  190.  d[t] = 6;
  191.  d[tdup] = 7;
  192.  if (dupdup(d,numfiles) == -1)
  193.    diep(10,"cannot dup connection to server");
  194.  
  195.  signal(SIGPIPE,SIG_DFL);
  196.  execvp(argv[2],argv + 2);
  197.  warnsp("cannot exec ",argv[2]);
  198.  exit(1);
  199. }
  200.