#ifndef lint static char sccsid[] = "@(#)uux.c 5.6 (Berkeley) 1/24/86"; #endif #include "uucp.h" #define NOSYSPART 0 #define HASSYSPART 1 #define LQUOTE '(' #define RQUOTE ')' #define APPCMD(d) {\ register char *p; for (p = d; *p != '\0';)\ {*cmdp++ = *p++;\ if(cmdp>(sizeof(cmd)+&cmd[0])){\ fprintf(stderr,"argument list too long\n");\ cleanup(EX_SOFTWARE);\ }\ }\ *cmdp++ = ' '; *cmdp = '\0';} #define GENSEND(f, a, b, c, d, e) {\ fprintf(f, "S %s %s %s -%s %s 0666\n", a, b, c, d, e); } #define GENRCV(f, a, b, c) {fprintf(f, "R %s %s %s - \n", a, b, c);} struct timeb Now; main(argc, argv) char *argv[]; { char cfile[NAMESIZE]; /* send commands for files from here */ char dfile[NAMESIZE]; /* used for all data files from here */ char rxfile[NAMESIZE]; /* to be sent to xqt file (X. ...) */ char tfile[NAMESIZE]; /* temporary file name */ char tcfile[NAMESIZE]; /* temporary file name */ char t2file[NAMESIZE]; /* temporary file name */ int cflag = 0; /* commands in C. file flag */ int rflag = 0; /* C. files for receiving flag */ #ifdef DONTCOPY int Copy = 0; /* Don't Copy spool files */ #else !DONTCOPY int Copy = 1; /* Copy spool files */ #endif !DONTCOPY int Linkit = 0; /* Try link before copy */ char buf[2*BUFSIZ]; char inargs[2*BUFSIZ]; int pipein = 0; int startjob = 1; char Grade = 'A'; char path[MAXFULLNAME]; char cmd[2*BUFSIZ]; char *ap, *cmdp; char prm[2*BUFSIZ]; char syspart[MAXBASENAME+1], rest[MAXFULLNAME]; char Xsys[MAXBASENAME+1], local[MAXBASENAME+1]; char *xsys = Xsys; FILE *fprx, *fpc, *fpd, *fp; extern char *getprm(), *lastpart(); extern FILE *ufopen(); int uid, ret; char redir = '\0'; int nonoti = 0; int nonzero = 0; int link_failed; char *ReturnTo = NULL; extern int LocalOnly; strcpy(Progname, "uux"); uucpname(Myname); umask(WFMASK); Ofn = 1; Ifn = 0; #ifdef VMS arg_fix(argc, argv); #endif while (argc>1 && argv[1][0] == '-') { switch(argv[1][1]){ case 'p': case '\0': pipein = 1; break; case 'r': startjob = 0; break; case 'c': Copy = 0; Linkit = 0; break; case 'l': Copy = 0; Linkit = 1; break; case 'C': Copy = 1; Linkit = 0; break; case 'g': Grade = argv[1][2]; break; case 'x': chkdebug(); Debug = atoi(&argv[1][2]); if (Debug <= 0) Debug = 1; break; case 'n': nonoti = 1; break; case 'z': nonzero = 1; break; case 'L': LocalOnly++; break; case 'a': ReturnTo = &argv[1][2]; if (prefix(Myname, ReturnTo) && ReturnTo[strlen(Myname)] == '!') ReturnTo = index(ReturnTo, '!') + 1; break; default: fprintf(stderr, "unknown flag %s\n", argv[1]); break; } --argc; argv++; } ap = getwd(Wrkdir); if (ap == 0) { fprintf(stderr, "can't get working directory; will try to continue\n"); strcpy(Wrkdir, "/UNKNOWN"); } DEBUG(4, "\n\n** %s **\n", "START"); inargs[0] = '\0'; for (argv++; argc > 1; argc--) { DEBUG(4, "arg - %s:", *argv); strcat(inargs, " "); strcat(inargs, *argv++); } DEBUG(4, "arg - %s\n", inargs); ret = subchdir(Spool); ASSERT(ret >= 0, "CHDIR FAILED", Spool, ret); uid = getuid(); guinfo(uid, User, path); strncpy(local, Myname, MAXBASENAME); cmdp = cmd; *cmdp = '\0'; gename(DATAPRE, local, 'X', rxfile); fprx = ufopen(rxfile, "w"); ASSERT(fprx != NULL, "CAN'T OPEN", rxfile, 0); gename(DATAPRE, local, 'T', tcfile); fpc = ufopen(tcfile, "w"); ASSERT(fpc != NULL, "CAN'T OPEN", tcfile, 0); fprintf(fprx, "%c %s %s\n", X_USER, User, local); if (nonoti) fprintf(fprx, "%c\n", X_NONOTI); if (nonzero) fprintf(fprx, "%c\n", X_NONZERO); if (ReturnTo == NULL || *ReturnTo == '\0') ReturnTo = User; fprintf(fprx, "%c %s\n", X_RETURNTO, ReturnTo); /* find remote system name */ ap = inargs; xsys[0] = '\0'; while ((ap = getprm(ap, prm)) != NULL) { if (prm[0] == '>' || prm[0] == '<') { ap = getprm(ap, prm); continue; } split(prm, xsys, rest); break; } if (xsys[0] == '\0') strcpy(xsys, local); if (versys(&xsys) != 0) { /* bad system name */ fprintf(stderr, "bad system name: %s\n", xsys); fclose(fprx); fclose(fpc); cleanup(EX_NOHOST); } strncpy(Rmtname, xsys, MAXBASENAME); DEBUG(4, "xsys %s\n", xsys); if (pipein) { gename(DATAPRE, local, 'B', dfile); fpd = ufopen(dfile, "w"); ASSERT(fpd != NULL, "CAN'T OPEN", dfile, 0); while (!feof(stdin)) { ret = fread(buf, 1, BUFSIZ, stdin); fwrite(buf, 1, ret, fpd); if (ferror(stdin)) { perror("stdin"); cleanup(EX_IOERR); } if (ferror(fpd)) { perror(dfile); cleanup(EX_IOERR); } } fclose(fpd); strcpy(tfile, dfile); if (strcmp(local, xsys) != SAME) { register int Len = strlen(local); if (Len > SYSNSIZE) Len = SYSNSIZE; tfile[Len + 2] = 'S'; GENSEND(fpc, dfile, tfile, User, "", dfile); cflag++; } fprintf(fprx, "%c %s\n", X_RQDFILE, tfile); fprintf(fprx, "%c %s\n", X_STDIN, tfile); } /* parse command */ ap = inargs; while ((ap = getprm(ap, prm)) != NULL) { DEBUG(4, "prm - %s\n", prm); if (prm[0] == '>' || prm[0] == '<') { redir = prm[0]; continue; } if (prm[0] == ';') { APPCMD(prm); continue; } if (prm[0] == '|' || prm[0] == '^') { if (cmdp != cmd) APPCMD(prm); continue; } /* process command or file or option */ ret = split(prm, syspart, rest); DEBUG(4, "s - %s, ", syspart); DEBUG(4, "r - %s, ", rest); DEBUG(4, "ret - %d\n", ret); if (syspart[0] == '\0') strcpy(syspart, local); if (cmdp == cmd && redir == '\0') { /* command */ APPCMD(rest); continue; } /* process file or option */ DEBUG(4, "file s- %s, ", syspart); DEBUG(4, "local - %s\n", local); /* process file */ if (redir == '>') { if (rest[0] != '~') if (ckexpf(rest)) cleanup(EX_CANTCREAT); fprintf(fprx, "%c %s %s\n", X_STDOUT, rest, syspart); redir = '\0'; continue; } if (ret == NOSYSPART && redir == '\0') { /* option */ APPCMD(rest); continue; } if (strcmp(xsys, local) == SAME && strcmp(xsys, syspart) == SAME) { if (ckexpf(rest)) cleanup(EX_CANTCREAT); if (redir == '<') fprintf(fprx, "%c %s\n", X_STDIN, rest); else APPCMD(rest); redir = '\0'; continue; } if (strcmp(syspart, local) == SAME) { /* generate send file */ if (ckexpf(rest)) cleanup(EX_CANTCREAT); gename(DATAPRE, local, 'A', dfile); DEBUG(4, "rest %s\n", rest); if ((chkpth(User, "", rest) || anyread(rest)) != 0) { fprintf(stderr, "permission denied %s\n", rest); cleanup(EX_NOINPUT); } link_failed = 0; if (Linkit) { if (link(subfile(rest), subfile(dfile)) != 0) link_failed++; else GENSEND(fpc, rest, dfile, User, "", dfile); } if (Copy || link_failed) { if (xcp(rest, dfile) != 0) { fprintf(stderr, "can't copy %s to %s\n", rest, dfile); cleanup(EX_NOINPUT); } GENSEND(fpc, rest, dfile, User, "", dfile); } if (!Copy && !Linkit) { GENSEND(fpc, rest, dfile, User, "c", "D.0"); } cflag++; if (redir == '<') { fprintf(fprx, "%c %s\n", X_STDIN, dfile); fprintf(fprx, "%c %s\n", X_RQDFILE, dfile); } else { APPCMD(lastpart(rest)); fprintf(fprx, "%c %s %s\n", X_RQDFILE, dfile, lastpart(rest)); } redir = '\0'; continue; } if (strcmp(local, xsys) == SAME) { /* generate local receive */ gename(CMDPRE, syspart, 'R', tfile); strcpy(dfile, tfile); dfile[0] = DATAPRE; fp = ufopen(tfile, "w"); ASSERT(fp != NULL, "CAN'T OPEN", tfile, 0); if (ckexpf(rest)) cleanup(EX_CANTCREAT); GENRCV(fp, rest, dfile, User); fclose(fp); rflag++; if (rest[0] != '~') if (ckexpf(rest)) cleanup(EX_CANTCREAT); if (redir == '<') { fprintf(fprx, "%c %s\n", X_RQDFILE, dfile); fprintf(fprx, "%c %s\n", X_STDIN, dfile); } else { fprintf(fprx, "%c %s %s\n", X_RQDFILE, dfile, lastpart(rest)); APPCMD(lastpart(rest)); } redir = '\0'; continue; } if (strcmp(syspart, xsys) != SAME) { /* generate remote receives */ gename(DATAPRE, syspart, 'R', dfile); strcpy(tfile, dfile); tfile[0] = CMDPRE; fpd = ufopen(dfile, "w"); ASSERT(fpd != NULL, "CAN'T OPEN", dfile, 0); gename(DATAPRE, local, 'T', t2file); GENRCV(fpd, rest, t2file, User); fclose(fpd); GENSEND(fpc, dfile, tfile, User, "", dfile); cflag++; if (redir == '<') { fprintf(fprx, "%c %s\n", X_RQDFILE, t2file); fprintf(fprx, "%c %s\n", X_STDIN, t2file); } else { fprintf(fprx, "%c %s %s\n", X_RQDFILE, t2file, lastpart(rest)); APPCMD(lastpart(rest)); } redir = '\0'; continue; } /* file on remote system */ if (rest[0] != '~') if (ckexpf(rest)) cleanup(EX_CANTCREAT); if (redir == '<') fprintf(fprx, "%c %s\n", X_STDIN, rest); else APPCMD(rest); redir = '\0'; continue; } /* * clean up trailing ' ' in command. */ if (cmdp > cmd && cmdp[0] == '\0' && cmdp[-1] == ' ') *--cmdp = '\0'; /* block multi-hop uux, which doesn't work */ for (ap = cmd; *ap && *ap != ' '; ap++) if (*ap == '!') { fprintf(stderr, "uux handles only adjacent sites.\n"); fprintf(stderr, "Try uusend for multi-hop delivery.\n"); cleanup(EX_USAGE); } fprintf(fprx, "%c %s\n", X_CMD, cmd); if (ferror(fprx)) { logent(cmd, "COULD NOT QUEUE XQT"); cleanup(EX_IOERR); } else logent(cmd, "XQT QUE'D"); fclose(fprx); gename(XQTPRE, local, Grade, tfile); if (strcmp(xsys, local) == SAME) { /* rti!trt: xmv() works across filesystems, link(II) doesnt */ xmv(rxfile, tfile); if (startjob) if (rflag) xuucico(xsys); else xuuxqt(); } else { GENSEND(fpc, rxfile, tfile, User, "", rxfile); cflag++; } if (ferror(fpc)) cleanup(EX_IOERR); fclose(fpc); if (cflag) { gename(CMDPRE, xsys, Grade, cfile); /* rti!trt: use xmv() rather than link(II) */ xmv(tcfile, cfile); if (startjob) xuucico(xsys); cleanup(0); } else unlink(subfile(tcfile)); exit(0); } #define FTABSIZE 30 char Fname[FTABSIZE][NAMESIZE]; int Fnamect = 0; /* * cleanup and unlink if error * * return - none - do exit() */ cleanup(code) int code; { int i; logcls(); rmlock(CNULL); if (code) { for (i = 0; i < Fnamect; i++) unlink(subfile(Fname[i])); fprintf(stderr, "uux failed. code %d\n", code); } DEBUG(1, "exit code %d\n", code); exit(code); } /* * open file and record name * * return file pointer. */ FILE *ufopen(file, mode) char *file, *mode; { if (Fnamect < FTABSIZE) strcpy(Fname[Fnamect++], file); else logent("Fname", "TABLE OVERFLOW"); return fopen(subfile(file), mode); } #ifdef VMS /* * EUNICE bug: * quotes are not stripped from DCL. Do it here. * Note if we are running under Unix shell we don't * do the right thing. */ arg_fix(argc, argv) char **argv; { register char *cp, *tp; for (; argc > 0; --argc, argv++) { cp = *argv; if (cp == (char *)0 || *cp++ != '"') continue; tp = cp; while (*tp++) ; tp -= 2; if (*tp == '"') { *tp = '\0'; *argv = cp; } } } #endif VMS /* * split into system and file part * * return codes: * NOSYSPART * HASSYSPART */ split(name, sys, rest) register char *name, *rest; char *sys; { register char *c; register int i; if (*name == LQUOTE) { if ((c = index(name + 1, RQUOTE)) != NULL) { /* strip off quotes */ name++; while (c != name) *rest++ = *name++; *rest = '\0'; *sys = '\0'; return NOSYSPART; } } if ((c = index(name, '!')) == NULL) { strcpy(rest, name); *sys = '\0'; return NOSYSPART; } *c++ = '\0'; strncpy(sys, name, MAXBASENAME); sys[MAXBASENAME] = '\0'; strcpy(rest, c); return HASSYSPART; }