home *** CD-ROM | disk | FTP | other *** search
- /* Copyright 1990 The President and Fellows of Harvard University
-
- Permission to use, copy, modify, and distribute this program for any
- purpose and without fee is hereby granted, provided that this
- copyright and permission notice appear on all copies and supporting
- documentation, the name of Harvard University not be used in advertising
- or publicity pertaining to distribution of the program, or to results
- derived from its use, without specific prior written permission, and notice
- be given in supporting documentation that copying and distribution is by
- permission of Harvard University. Harvard University makes no
- representations about the suitability of this software for any purpose.
- It is provided "as is" without express or implied warranty. */
-
-
- /* queue.c - Dan Lanciani '85 */
-
- #include <stdio.h>
- #include <errno.h>
- #include <sys/param.h>
- #include <sys/stat.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <pwd.h>
- #include <grp.h>
- #include <signal.h>
-
- #include "queue.h"
-
- extern int errno, botch();
- struct servent *sp;
- struct passwd *pw;
- struct group *gr;
- struct sockaddr_in sin;
- long unid;
-
- main(argc, argv, envp)
- char **argv, **envp;
- {
- register struct optent *p, *op;
- struct stat statb;
- register FILE *n;
- char wd[BUFSIZ], buf[BUFSIZ];
- int i, s, se = -1, ng, fd, local = 1;
- gid_t groups[NGROUPS];
-
- while((i = open("/dev/null", 2)) < 3);
- close(i);
- if(argc < 1) {
- fprintf(stderr, "No arguments?\n");
- exit(1);
- }
- if(rindex(argv[0], '/'))
- argv[0] = rindex(argv[0], '/') + 1;
- if(!(pw = getpwuid(getuid())) || !(gr = getgrgid(getgid()))) {
- fprintf(stderr, "Who are you?\n");
- exit(1);
- }
- if(!getwd(wd)) {
- fprintf(stderr, "Can't get current directory\n");
- exit(1);
- }
- if(i = readconf(argv[0])) {
- fprintf(stderr, "Unknown configuration (%d)\n", i);
- exit(1);
- }
- for(i = 1; i < argc; i++) {
- op = NULL;
- for(p = option; p; p = p->op_next) {
- if(optcmp(p->op_name, argv[i])) {
- op = p;
- break;
- }
- if(!strcmp(p->op_name, "DEFAULT"))
- op = p;
- }
- if(!op) {
- fprintf(stderr, "Unknown option (%s)\n", argv[i]);
- exit(1);
- }
- switch(op->op_action) {
-
- case OPA_IGNORE:
- if(!strcmp(op->op_arg, "ARG1"))
- i++;
- break;
-
- case OPA_COPYIN:
- p = (struct optent *)malloc(sizeof(struct optent));
- *p = *op;
- if(!strcmp(p->op_arg, "ARG0"))
- p->op_arg = newstring(argv[i]);
- else if(!strcmp(p->op_arg, "ARG1"))
- p->op_arg = newstring(argv[++i]);
- p->op_next = copyin;
- copyin = p;
- break;
-
- case OPA_COPYOUT:
- p = (struct optent *)malloc(sizeof(struct optent));
- *p = *op;
- if(!strcmp(p->op_arg, "ARG0"))
- p->op_arg = newstring(argv[i]);
- else if(!strcmp(p->op_arg, "ARG1"))
- p->op_arg = newstring(argv[++i]);
- p->op_next = copyout;
- copyout = p;
- break;
-
- default:
- fprintf(stderr, "Bad action (%d)\n", op->op_action);
- exit(1);
- }
- }
- selhost(argc, argv);
- if(!(sp = getservbyname("queue", "tcp"))) {
- fprintf(stderr, "queue: Bad service?!?\n");
- exit(1);
- }
- for(i = 0; i < hcnt; i++)
- if((s = qconnect(hosts[i])) >= 0) {
- strcpy(host, hosts[i]);
- goto found;
- }
- if(nolocal) {
- fprintf(stderr, "No authorized host available\n");
- fprintf(stderr, "Please contact a staff person.\n");
- exit(1);
- }
- gethostname(host, sizeof(host));
- if((s = qconnect(host)) < 0) {
- fprintf(stderr, "Running locally\n");
- cspawn(prog, argv);
- wait(0);
- exit(0);
- }
- found:
- gethostname(buf, BUFSIZ);
- if(strcmp(host, buf) && strcmp(host, "localhost"))
- local = 0;
- if(mode == QM_INTERACTIVE) {
- i = IPPORT_RESERVED - 2;
- if((se = rresvport(&i)) < 0) {
- perror("rresvport");
- exit(1);
- }
- listen(se, 1);
- }
- else
- i = 0;
- setuid(getuid());
- if(!(n = fdopen(s, "w"))) {
- perror("fdopen");
- exit(1);
- }
- putc(0, n);
- fprintf(n, "%d", i);
- putc('\0', n);
- fflush(n);
- if(i) {
- int fromlen = sizeof(struct sockaddr_in);
- struct sockaddr_in from;
- signal(SIGALRM, botch);
- alarm(30);
- if((i = accept(se, &from, &fromlen)) < 0) {
- perror("accept");
- exit(1);
- }
- alarm(0);
- signal(SIGALRM, SIG_DFL);
- close(se);
- se = i;
- if(ntohs((u_short)from.sin_port) >= IPPORT_RESERVED) {
- fprintf(stderr, "Protocol failed\n");
- exit(1);
- }
- }
- fprintf(n, "%ld", unid);
- putc('\0', n);
- fprintf(n, "%d", argc);
- putc('\0', n);
- for(i = 0; i < argc; i++)
- xfputs(argv[i], n);
- xfputs(pw->pw_name, n);
- xfputs(gr->gr_name, n);
- ng = getgroups(NGROUPS, groups);
- fprintf(n, "%d", ng);
- putc('\0', n);
- for(i = 0; i < ng; i++)
- if(gr = getgrgid(groups[i]))
- xfputs(gr->gr_name, n);
- else {
- fprintf(stderr, "Who are you (groups)?\n");
- exit(1);
- }
- xfputs(wd, n);
- for(ng = 0; envp[ng]; ng++);
- fprintf(n, "%d", ng);
- putc('\0', n);
- for(i = 0; i < ng; i++)
- xfputs(envp[i], n);
- if(!local) {
- if(efs && infile(EFSFILE, host)) {
- xfputs("efs", n);
- i = 0;
- for(p = copyout; p; p = p->op_next)
- i++;
- for(p = copyin; p; p = p->op_next)
- i++;
- fprintf(n, "%d", i);
- putc('\0', n);
- for(p = copyout; p; p = p->op_next) {
- xfputs(p->op_arg, n);
- #ifndef SANEEFS
- #define apath(x) x
- xfputs(apath(p->op_arg), n);
- #endif
- }
- for(p = copyin; p; p = p->op_next) {
- xfputs(p->op_arg, n);
- #ifndef SANEEFS
- xfputs(apath(p->op_arg), n);
- #endif
- }
- goto nocopy;
- }
- if(copyout) {
- xfputs("copyout", n);
- i = 0;
- for(p = copyout; p; p = p->op_next)
- i++;
- fprintf(n, "%d", i);
- putc('\0', n);
- for(p = copyout; p; p = p->op_next)
- xfputs(p->op_arg, n);
- }
- if(copyin) {
- xfputs("copyin", n);
- i = 0;
- for(p = copyin; p; p = p->op_next)
- i++;
- fprintf(n, "%d", i);
- putc('\0', n);
- for(p = copyin; p; p = p->op_next) {
- xfputs(p->op_arg, n);
- if((fd = open(p->op_arg, 0)) < 0)
- xfputs("-1", n);
- else {
- fstat(fd, &statb);
- fprintf(n, "%ld", statb.st_size);
- putc('\0', n);
- while(1) {
- i = read(fd, buf, BUFSIZ);
- if(i <= 0)
- break;
- fwrite(buf, sizeof(char), i, n);
- }
- close(fd);
- }
- }
- }
- }
- nocopy:
- xfputs("done", n);
- fflush(n);
- com(s, se);
- }
-
- botch()
- {
- fprintf(stderr, "Protocol timeout\n");
- exit(1);
- }
-
- qconnect(h)
- char *h;
- {
- int s, trys, i;
- register struct hostent *hp;
-
- if(!(hp = gethostbyname(h))) {
- fprintf(stderr, "%s: Unknown host?!?\n", h);
- return(-1);
- }
- trys = 0;
- i = IPPORT_RESERVED - 1;
- retry:
- if((s = rresvport(&i)) < 0) {
- perror("rresvport");
- return(-1);
- }
- sin.sin_family = hp->h_addrtype;
- sin.sin_port = sp->s_port;
- bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);
- if(connect(s, &sin, sizeof(sin))) {
- close(s);
- if(trys++ < 5) {
- sleep(trys);
- i--;
- goto retry;
- }
- perror("connect");
- return(-1);
- }
- return(s);
- }
-