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

  1. /* Public domain. */
  2.  
  3. #include <stdio.h>
  4. #include <sys/types.h>
  5. #include <sys/file.h>
  6. #include <signal.h>
  7. #include <fcntl.h>
  8. #include "dupdup.h"
  9. #include "malloc.h"
  10. #include "errno.h"
  11. #include "username.h"
  12. #include "env.h"
  13. #include "getopt.h"
  14. #include "numfiles.h"
  15.  
  16. #ifndef F_LOCK
  17. #define F_LOCK 1
  18. #endif
  19. #ifndef O_RDONLY
  20. #define O_RDONLY 0
  21. #endif
  22. #ifndef O_WRONLY
  23. #define O_WRONLY 1
  24. #endif
  25. #ifndef O_RDWR
  26. #define O_RDWR 2
  27. #endif
  28.  
  29. static int flagverbose = 1;
  30.  
  31. static char errbuf[500];
  32. void die(n,s) int n; char *s;
  33. { if (flagverbose) fprintf(stderr,"npipeclient: fatal: %s\n",s); exit(n); }
  34. void dies(n,s,t) int n; char *s; char *t;
  35. { if (flagverbose) fprintf(stderr,"npipeclient: fatal: %s%s\n",s,t); exit(n); }
  36. void diep(n,s) int n; char *s;
  37. { if (flagverbose) sprintf(errbuf,"npipeclient: fatal: %s",s); perror(errbuf); exit(n); }
  38. void warnp(s) char *s;
  39. { if (flagverbose) sprintf(errbuf,"npipeclient: warning: %s",s); perror(errbuf); }
  40. void warnsp(s,t) char *s; char *t;
  41. { if (flagverbose) sprintf(errbuf,"npipeclient: warning: %s%s",s,t); perror(errbuf); }
  42.  
  43. main(argc,argv,envp)
  44. int argc;
  45. char *argv[];
  46. char *envp[];
  47. {
  48.  int *d;
  49.  int numfiles;
  50.  int arguid;
  51.  int uid;
  52.  int i;
  53.  static char npipelocal[200];
  54.  static char npiperemote[300];
  55.  int fdserv;
  56.  int fdlock;
  57.  int fds2c;
  58.  int fdc2s;
  59.  char fnlock[200];
  60.  char fns2c[200];
  61.  char fnc2s[200];
  62.  char fnserv[200];
  63.  int m;
  64.  int n;
  65.  int r;
  66.  char buf[100];
  67.  char *uname;
  68.  int pid;
  69.  int opt;
  70.  
  71.  pid = getpid();
  72.  
  73.  while ((opt = getopt(argc,argv,"qQ")) != EOF)
  74.    switch(opt)
  75.     {
  76.      case 'q':
  77.        flagverbose = 0; break;
  78.      case 'Q':
  79.        flagverbose = 1; break;
  80.      case '?':
  81.        break; /*XXX*/
  82.      default:
  83.        break; /*XXX*/
  84.     }
  85.  argc -= optind; argv += optind;
  86.  
  87.  if (argc < 3)
  88.    die(1,"need at least three arguments");
  89.  
  90.  uid = getuid();
  91.  if (username2uid(argv[0],&arguid) == -1)
  92.    dies(2,"cannot figure out username ",argv[0]);
  93.  /* XXX: any permission checks? */
  94.  
  95.  for (i = 0;argv[0][i];++i)
  96.    if ((argv[0][i] == '/') || (argv[0][i] == ':') || (argv[0][i] == '.') || (argv[0][i] == '\n'))
  97.      dies(4,"illegal characters in username ",argv[0]);
  98.  
  99.  for (i = 0;argv[1][i];++i)
  100.    if ((argv[1][i] == '/') || (argv[1][i] == '.') || (argv[0][i] == '\n'))
  101.      dies(5,"illegal characters in service ",argv[1]);
  102.  
  103.  close(6);
  104.  close(7); /* XXX: these have implications that should be documented */
  105.  
  106.  signal(SIGPIPE,SIG_IGN);
  107.  
  108.  if (uid2username(uid,&uname) == -1) /* will never happen */
  109.    die(2,"cannot figure out my own username");
  110.  
  111.  numfiles = NUMFILES;
  112.  d = (int *) malloc(numfiles * sizeof(int));
  113.  if (!d)
  114.    die(6,"cannot malloc");
  115.  for (i = 0;i < numfiles;++i)
  116.    d[i] = -1;
  117.  
  118.  if (strlen(NPIPEDIR) + strlen(argv[0]) + strlen(argv[1]) + 1 > 90) /*XXX*/
  119.    die(8,"server filenames too long");
  120.  sprintf(fnserv,"%s/%ds%s",NPIPEDIR,arguid,argv[1]);
  121.  sprintf(fnlock,"%s/%dl%s",NPIPEDIR,arguid,argv[1]);
  122.  sprintf(fns2c,"%s/s2c.%d",NPIPEDIR,pid);
  123.  sprintf(fnc2s,"%s/c2s.%d",NPIPEDIR,pid);
  124.  sprintf(buf,"%d",pid);
  125.  n = strlen(buf);
  126.  if (n + strlen(uname) + 10 > sizeof(buf))
  127.    die(8,"username too long");
  128.  strcpy(buf + n + 1,uname);
  129.  n += strlen(uname) + 2;
  130.  
  131.  if (env_init() == -1)
  132.    die(11,"cannot init environment");
  133.  if (env_put("PROTO=NPIPE") == -1)
  134.    die(11,"out of memory putting PROTO into environment");
  135.  sprintf(npipelocal,"NPIPELOCAL=%s",uname);
  136.  if (env_put(npipelocal) == -1)
  137.    die(11,"out of memory putting NPIPELOCAL into environment");
  138.  sprintf(npiperemote,"NPIPEREMOTE=%s:%s",argv[0],argv[1]);
  139.  if (env_put(npiperemote) == -1)
  140.    die(11,"out of memory putting NPIPEREMOTE into environment");
  141.  
  142.  /* XXX: fork? not necessary here */
  143.  
  144.  /* Action! */
  145.  
  146.  fdlock = open(fnlock,O_RDWR,0);
  147.  if (fdlock == -1)
  148.    diep(1,"cannot open lock file");
  149.  /* Here's the tricky bit: file locking. :-( */
  150.  /* XXX: We assume that anyone with named pipes also has lockf(). */
  151.  if (lockf(fdlock,F_LOCK,1) == -1)
  152.    diep(1,"cannot wait for lock on lock file");
  153.  
  154.  fdserv = open(fnserv,O_WRONLY,0);
  155.  if (fdserv == -1)
  156.    diep(1,"cannot open server's named pipe");
  157.  
  158.  if (mknod(fns2c,010600,0) == -1)
  159.    diep(1,"cannot create server-to-client pipe");
  160.  if (mknod(fnc2s,010600,0) == -1)
  161.   {
  162.    unlink(fns2c);
  163.    diep(1,"cannot create client-to-server pipe");
  164.   }
  165.  
  166.  m = 0;
  167.  r = 0;
  168.  while ((m < n) && ((r = write(fdserv,buf + m,n - m)) > 0))
  169.    m += r;
  170.  if (r <= 0)
  171.   {
  172.    unlink(fnc2s);
  173.    unlink(fns2c);
  174.    die(1,"cannot write pid and username to server");
  175.   }
  176.  close(fdserv); /*XXX*/
  177.  
  178.  fds2c = open(fns2c,O_RDONLY,0); /* blocks */
  179.  unlink(fns2c);
  180.  if (fds2c == -1)
  181.   {
  182.    unlink(fnc2s);
  183.    die(1,"cannot open server-to-client pipe");
  184.   }
  185.  fdc2s = open(fnc2s,O_WRONLY,0); /* blocks */
  186.  unlink(fnc2s);
  187.  if (fdc2s == -1)
  188.    die(1,"cannot open client-to-server pipe");
  189.  
  190.  if (read(fds2c,buf,1) < 1)
  191.    diep(1,"cannot read from server-to-client pipe");
  192.  
  193.  close(fdlock);
  194.  
  195.  /* Now put fds2c into descriptor 6 and fdc2s into descriptor 7. */
  196.  /* XXX: should check that fdc2s and fds2c are small enough */
  197.  d[fds2c] = 6;
  198.  d[fdc2s] = 7;
  199.  if (dupdup(d,numfiles) == -1)
  200.    diep(10,"cannot dup connection to server");
  201.  
  202.  if (setreuid(uid,uid) == -1)
  203.    diep(1,"cannot setreuid"); /* will never happen */
  204.  signal(SIGPIPE,SIG_DFL);
  205.  execvp(argv[2],argv + 2);
  206.  warnsp("cannot exec ",argv[2]);
  207.  exit(1);
  208. }
  209.