home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume22 / queuer / part02 / queue.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-07  |  6.5 KB  |  307 lines

  1. /* Copyright 1990  The President and Fellows of Harvard University
  2.  
  3. Permission to use, copy, modify, and distribute this program for any
  4. purpose and without fee is hereby granted, provided that this
  5. copyright and permission notice appear on all copies and supporting
  6. documentation, the name of Harvard University not be used in advertising
  7. or publicity pertaining to distribution of the program, or to results
  8. derived from its use, without specific prior written permission, and notice
  9. be given in supporting documentation that copying and distribution is by
  10. permission of Harvard University.  Harvard University makes no
  11. representations about the suitability of this software for any purpose.
  12. It is provided "as is" without express or implied warranty.    */
  13.  
  14.  
  15. /* queue.c - Dan Lanciani '85 */
  16.  
  17. #include <stdio.h>
  18. #include <errno.h>
  19. #include <sys/param.h>
  20. #include <sys/stat.h>
  21. #include <sys/socket.h>
  22. #include <netinet/in.h>
  23. #include <netdb.h>
  24. #include <pwd.h>
  25. #include <grp.h>
  26. #include <signal.h>
  27.  
  28. #include "queue.h"
  29.  
  30. extern int errno, botch();
  31. struct servent *sp;
  32. struct passwd *pw;
  33. struct group *gr;
  34. struct sockaddr_in sin;
  35. long unid;
  36.  
  37. main(argc, argv, envp)
  38. char **argv, **envp;
  39. {
  40.     register struct optent *p, *op;
  41.     struct stat statb;
  42.     register FILE *n;
  43.     char wd[BUFSIZ], buf[BUFSIZ];
  44.     int i, s, se = -1, ng, fd, local = 1;
  45.     gid_t groups[NGROUPS];
  46.  
  47.     while((i = open("/dev/null", 2)) < 3);
  48.     close(i);
  49.     if(argc < 1) {
  50.         fprintf(stderr, "No arguments?\n");
  51.         exit(1);
  52.     }
  53.     if(rindex(argv[0], '/'))
  54.         argv[0] = rindex(argv[0], '/') + 1;
  55.     if(!(pw = getpwuid(getuid())) || !(gr = getgrgid(getgid()))) {
  56.         fprintf(stderr, "Who are you?\n");
  57.         exit(1);
  58.     }
  59.     if(!getwd(wd)) {
  60.         fprintf(stderr, "Can't get current directory\n");
  61.         exit(1);
  62.     }
  63.     if(i = readconf(argv[0])) {
  64.         fprintf(stderr, "Unknown configuration (%d)\n", i);
  65.         exit(1);
  66.     }
  67.     for(i = 1; i < argc; i++) {
  68.         op = NULL;
  69.         for(p = option; p; p = p->op_next) {
  70.             if(optcmp(p->op_name, argv[i])) {
  71.                 op = p;
  72.                 break;
  73.             }
  74.             if(!strcmp(p->op_name, "DEFAULT"))
  75.                 op = p;
  76.         }
  77.         if(!op) {
  78.             fprintf(stderr, "Unknown option (%s)\n", argv[i]);
  79.             exit(1);
  80.         }
  81.         switch(op->op_action) {
  82.  
  83.         case OPA_IGNORE:
  84.             if(!strcmp(op->op_arg, "ARG1"))
  85.                 i++;
  86.             break;
  87.  
  88.         case OPA_COPYIN:
  89.             p = (struct optent *)malloc(sizeof(struct optent));
  90.             *p = *op;
  91.             if(!strcmp(p->op_arg, "ARG0"))
  92.                 p->op_arg = newstring(argv[i]);
  93.             else if(!strcmp(p->op_arg, "ARG1"))
  94.                 p->op_arg = newstring(argv[++i]);
  95.             p->op_next = copyin;
  96.             copyin = p;
  97.             break;
  98.  
  99.         case OPA_COPYOUT:
  100.             p = (struct optent *)malloc(sizeof(struct optent));
  101.             *p = *op;
  102.             if(!strcmp(p->op_arg, "ARG0"))
  103.                 p->op_arg = newstring(argv[i]);
  104.             else if(!strcmp(p->op_arg, "ARG1"))
  105.                 p->op_arg = newstring(argv[++i]);
  106.             p->op_next = copyout;
  107.             copyout = p;
  108.             break;
  109.  
  110.         default:
  111.             fprintf(stderr, "Bad action (%d)\n", op->op_action);
  112.             exit(1);
  113.         }
  114.     }
  115.     selhost(argc, argv);
  116.     if(!(sp = getservbyname("queue", "tcp"))) {
  117.         fprintf(stderr, "queue: Bad service?!?\n");
  118.         exit(1);
  119.     }
  120.     for(i = 0; i < hcnt; i++)
  121.         if((s = qconnect(hosts[i])) >= 0) {
  122.             strcpy(host, hosts[i]);
  123.             goto found;
  124.         }
  125.     if(nolocal) {
  126.         fprintf(stderr, "No authorized host available\n");
  127.         fprintf(stderr, "Please contact a staff person.\n");
  128.         exit(1);
  129.     }
  130.     gethostname(host, sizeof(host));
  131.     if((s = qconnect(host)) < 0) {
  132.         fprintf(stderr, "Running locally\n");
  133.         cspawn(prog, argv);
  134.         wait(0);
  135.         exit(0);
  136.     }
  137. found:
  138.     gethostname(buf, BUFSIZ);
  139.     if(strcmp(host, buf) && strcmp(host, "localhost"))
  140.         local = 0;
  141.     if(mode == QM_INTERACTIVE) {
  142.         i = IPPORT_RESERVED - 2;
  143.         if((se = rresvport(&i)) < 0) {
  144.             perror("rresvport");
  145.             exit(1);
  146.         }
  147.         listen(se, 1);
  148.     }
  149.     else
  150.         i = 0;
  151.     setuid(getuid());
  152.     if(!(n = fdopen(s, "w"))) {
  153.         perror("fdopen");
  154.         exit(1);
  155.     }
  156.     putc(0, n);
  157.     fprintf(n, "%d", i);
  158.     putc('\0', n);
  159.     fflush(n);
  160.     if(i) {
  161.         int fromlen = sizeof(struct sockaddr_in);
  162.         struct sockaddr_in from;
  163.         signal(SIGALRM, botch);
  164.         alarm(30);
  165.         if((i = accept(se, &from, &fromlen)) < 0) {
  166.             perror("accept");
  167.             exit(1);
  168.         }
  169.         alarm(0);
  170.         signal(SIGALRM, SIG_DFL);
  171.         close(se);
  172.         se = i;
  173.         if(ntohs((u_short)from.sin_port) >= IPPORT_RESERVED) {
  174.             fprintf(stderr, "Protocol failed\n");
  175.             exit(1);
  176.         }
  177.     }
  178.     fprintf(n, "%ld", unid);
  179.     putc('\0', n);
  180.     fprintf(n, "%d", argc);
  181.     putc('\0', n);
  182.     for(i = 0; i < argc; i++)
  183.         xfputs(argv[i], n);
  184.     xfputs(pw->pw_name, n);
  185.     xfputs(gr->gr_name, n);
  186.     ng = getgroups(NGROUPS, groups);
  187.     fprintf(n, "%d", ng);
  188.     putc('\0', n);
  189.     for(i = 0; i < ng; i++)
  190.         if(gr = getgrgid(groups[i]))
  191.             xfputs(gr->gr_name, n);
  192.         else {
  193.             fprintf(stderr, "Who are you (groups)?\n");
  194.             exit(1);
  195.         }
  196.     xfputs(wd, n);
  197.     for(ng = 0; envp[ng]; ng++);
  198.     fprintf(n, "%d", ng);
  199.     putc('\0', n);
  200.     for(i = 0; i < ng; i++)
  201.         xfputs(envp[i], n);
  202.     if(!local) {
  203.         if(efs && infile(EFSFILE, host)) {
  204.             xfputs("efs", n);
  205.             i = 0;
  206.             for(p = copyout; p; p = p->op_next)
  207.                 i++;
  208.             for(p = copyin; p; p = p->op_next)
  209.                 i++;
  210.             fprintf(n, "%d", i);
  211.             putc('\0', n);
  212.             for(p = copyout; p; p = p->op_next) {
  213.                 xfputs(p->op_arg, n);
  214. #ifndef    SANEEFS
  215. #define apath(x) x
  216.                 xfputs(apath(p->op_arg), n);
  217. #endif
  218.             }
  219.             for(p = copyin; p; p = p->op_next) {
  220.                 xfputs(p->op_arg, n);
  221. #ifndef    SANEEFS
  222.                 xfputs(apath(p->op_arg), n);
  223. #endif
  224.             }
  225.             goto nocopy;
  226.         }
  227.         if(copyout) {
  228.             xfputs("copyout", n);
  229.             i = 0;
  230.             for(p = copyout; p; p = p->op_next)
  231.                 i++;
  232.             fprintf(n, "%d", i);
  233.             putc('\0', n);
  234.             for(p = copyout; p; p = p->op_next)
  235.                 xfputs(p->op_arg, n);
  236.         }
  237.         if(copyin) {
  238.             xfputs("copyin", n);
  239.             i = 0;
  240.             for(p = copyin; p; p = p->op_next)
  241.                 i++;
  242.             fprintf(n, "%d", i);
  243.             putc('\0', n);
  244.             for(p = copyin; p; p = p->op_next) {
  245.                 xfputs(p->op_arg, n);
  246.                 if((fd = open(p->op_arg, 0)) < 0)
  247.                     xfputs("-1", n);
  248.                 else {
  249.                     fstat(fd, &statb);
  250.                     fprintf(n, "%ld", statb.st_size);
  251.                     putc('\0', n);
  252.                     while(1) {
  253.                         i = read(fd, buf, BUFSIZ);
  254.                         if(i <= 0)
  255.                             break;
  256.                         fwrite(buf, sizeof(char), i, n);
  257.                     }
  258.                     close(fd);
  259.                 }
  260.             }
  261.         }
  262.     }
  263. nocopy:
  264.     xfputs("done", n);
  265.     fflush(n);
  266.     com(s, se);
  267. }
  268.  
  269. botch()
  270. {
  271.     fprintf(stderr, "Protocol timeout\n");
  272.     exit(1);
  273. }
  274.  
  275. qconnect(h)
  276. char *h;
  277. {
  278.     int s, trys, i;
  279.     register struct hostent *hp;
  280.  
  281.     if(!(hp = gethostbyname(h))) {
  282.         fprintf(stderr, "%s: Unknown host?!?\n", h);
  283.         return(-1);
  284.     }
  285.     trys = 0;
  286.     i = IPPORT_RESERVED - 1;
  287. retry:
  288.     if((s = rresvport(&i)) < 0) {
  289.         perror("rresvport");
  290.         return(-1);
  291.     }
  292.     sin.sin_family = hp->h_addrtype;
  293.     sin.sin_port = sp->s_port;
  294.     bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);
  295.     if(connect(s, &sin, sizeof(sin))) {
  296.         close(s);
  297.         if(trys++ < 5) {
  298.             sleep(trys);
  299.             i--;
  300.             goto retry;
  301.         }
  302.         perror("connect");
  303.         return(-1);
  304.     }
  305.     return(s);
  306. }
  307.