113695Ssam #ifndef lint 2*25146Sbloom static char sccsid[] = "@(#)uux.c 5.5 (Berkeley) 10/09/85"; 313695Ssam #endif 413695Ssam 513695Ssam #include "uucp.h" 613695Ssam 713695Ssam #define NOSYSPART 0 813695Ssam #define HASSYSPART 1 913695Ssam 10*25146Sbloom #define LQUOTE '(' 11*25146Sbloom #define RQUOTE ')' 12*25146Sbloom 1313695Ssam #define APPCMD(d) {\ 1417845Sralph char *p; for (p = d; *p != '\0';) *cmdp++ = *p++; *cmdp++ = ' '; *cmdp = '\0';} 1513695Ssam 1613695Ssam #define GENSEND(f, a, b, c, d, e) {\ 1717845Sralph fprintf(f, "S %s %s %s -%s %s 0666\n", a, b, c, d, e); } 1817845Sralph #define GENRCV(f, a, b, c) {fprintf(f, "R %s %s %s - \n", a, b, c);} 1913695Ssam 20*25146Sbloom struct timeb Now; 21*25146Sbloom 2213695Ssam main(argc, argv) 2313695Ssam char *argv[]; 2413695Ssam { 2513695Ssam char cfile[NAMESIZE]; /* send commands for files from here */ 2613695Ssam char dfile[NAMESIZE]; /* used for all data files from here */ 2713695Ssam char rxfile[NAMESIZE]; /* to be sent to xqt file (X. ...) */ 2813695Ssam char tfile[NAMESIZE]; /* temporary file name */ 2913695Ssam char tcfile[NAMESIZE]; /* temporary file name */ 3013695Ssam char t2file[NAMESIZE]; /* temporary file name */ 3113695Ssam int cflag = 0; /* commands in C. file flag */ 3213695Ssam int rflag = 0; /* C. files for receiving flag */ 3317845Sralph #ifdef DONTCOPY 3417845Sralph int Copy = 0; /* Don't Copy spool files */ 3517845Sralph #else !DONTCOPY 3613695Ssam int Copy = 1; /* Copy spool files */ 3717845Sralph #endif !DONTCOPY 3817845Sralph int Linkit = 0; /* Try link before copy */ 3913695Ssam char buf[BUFSIZ]; 4013695Ssam char inargs[BUFSIZ]; 4113695Ssam int pipein = 0; 4213695Ssam int startjob = 1; 4313695Ssam char Grade = 'A'; 4413695Ssam char path[MAXFULLNAME]; 4513695Ssam char cmd[BUFSIZ]; 4613695Ssam char *ap, *cmdp; 4713695Ssam char prm[BUFSIZ]; 4823691Sbloom char syspart[MAXBASENAME+1], rest[MAXFULLNAME]; 4923691Sbloom char Xsys[MAXBASENAME+1], local[MAXBASENAME+1]; 5018627Sralph char *xsys = Xsys; 5113695Ssam FILE *fprx, *fpc, *fpd, *fp; 5213695Ssam extern char *getprm(), *lastpart(); 5313695Ssam extern FILE *ufopen(); 5413695Ssam int uid, ret; 5513695Ssam char redir = '\0'; 5613695Ssam int nonoti = 0; 5713695Ssam int nonzero = 0; 5817845Sralph int link_failed; 5917845Sralph char *ReturnTo = NULL; 6017845Sralph extern int LocalOnly; 6113695Ssam 6213695Ssam strcpy(Progname, "uux"); 6313695Ssam uucpname(Myname); 6413695Ssam umask(WFMASK); 6513695Ssam Ofn = 1; 6613695Ssam Ifn = 0; 6717845Sralph #ifdef VMS 6817845Sralph arg_fix(argc, argv); 6917845Sralph #endif 7013695Ssam while (argc>1 && argv[1][0] == '-') { 7113695Ssam switch(argv[1][1]){ 7213695Ssam case 'p': 7313695Ssam case '\0': 7413695Ssam pipein = 1; 7513695Ssam break; 7613695Ssam case 'r': 7713695Ssam startjob = 0; 7813695Ssam break; 7913695Ssam case 'c': 8017845Sralph Copy = 0; 8117845Sralph Linkit = 0; 8217845Sralph break; 8313695Ssam case 'l': 8413695Ssam Copy = 0; 8517845Sralph Linkit = 1; 8613695Ssam break; 8717845Sralph case 'C': 8817845Sralph Copy = 1; 8917845Sralph Linkit = 0; 9017845Sralph break; 9113695Ssam case 'g': 9213695Ssam Grade = argv[1][2]; 9313695Ssam break; 9413695Ssam case 'x': 9517845Sralph chkdebug(); 9613695Ssam Debug = atoi(&argv[1][2]); 9713695Ssam if (Debug <= 0) 9813695Ssam Debug = 1; 9913695Ssam break; 10013695Ssam case 'n': 10113695Ssam nonoti = 1; 10213695Ssam break; 10313695Ssam case 'z': 10413695Ssam nonzero = 1; 10513695Ssam break; 10617845Sralph case 'L': 10717845Sralph LocalOnly++; 10817845Sralph break; 10917845Sralph case 'a': 11017845Sralph ReturnTo = &argv[1][2]; 11123691Sbloom if (prefix(Myname, ReturnTo) && ReturnTo[strlen(Myname)] == '!') 11223691Sbloom ReturnTo = index(ReturnTo, '!') + 1; 11317845Sralph break; 11413695Ssam default: 11513695Ssam fprintf(stderr, "unknown flag %s\n", argv[1]); 11613695Ssam break; 11713695Ssam } 11813695Ssam --argc; argv++; 11913695Ssam } 120*25146Sbloom ap = getwd(Wrkdir); 121*25146Sbloom if (ap == 0) { 122*25146Sbloom fprintf(stderr, "can't get working directory; will try to continue\n"); 123*25146Sbloom strcpy(Wrkdir, "/UNKNOWN"); 12417845Sralph } 12513695Ssam 12613695Ssam DEBUG(4, "\n\n** %s **\n", "START"); 12713695Ssam 12813695Ssam inargs[0] = '\0'; 12913695Ssam for (argv++; argc > 1; argc--) { 13013695Ssam DEBUG(4, "arg - %s:", *argv); 13113695Ssam strcat(inargs, " "); 13213695Ssam strcat(inargs, *argv++); 13313695Ssam } 13413695Ssam DEBUG(4, "arg - %s\n", inargs); 13517845Sralph ret = subchdir(Spool); 13617845Sralph ASSERT(ret >= 0, "CHDIR FAILED", Spool, ret); 13713695Ssam uid = getuid(); 13813695Ssam guinfo(uid, User, path); 13913695Ssam 14023691Sbloom strncpy(local, Myname, MAXBASENAME); 14113695Ssam cmdp = cmd; 14213695Ssam *cmdp = '\0'; 14313695Ssam gename(DATAPRE, local, 'X', rxfile); 14413695Ssam fprx = ufopen(rxfile, "w"); 14513695Ssam ASSERT(fprx != NULL, "CAN'T OPEN", rxfile, 0); 14613695Ssam gename(DATAPRE, local, 'T', tcfile); 14713695Ssam fpc = ufopen(tcfile, "w"); 14813695Ssam ASSERT(fpc != NULL, "CAN'T OPEN", tcfile, 0); 14913695Ssam fprintf(fprx, "%c %s %s\n", X_USER, User, local); 15013695Ssam if (nonoti) 15113695Ssam fprintf(fprx, "%c\n", X_NONOTI); 15213695Ssam if (nonzero) 15313695Ssam fprintf(fprx, "%c\n", X_NONZERO); 15417845Sralph if (ReturnTo == NULL || *ReturnTo == '\0') 15517845Sralph ReturnTo = User; 15617845Sralph fprintf(fprx, "%c %s\n", X_RETURNTO, ReturnTo); 15713695Ssam 15813695Ssam /* find remote system name */ 15913695Ssam ap = inargs; 16013695Ssam xsys[0] = '\0'; 16113695Ssam while ((ap = getprm(ap, prm)) != NULL) { 16213695Ssam if (prm[0] == '>' || prm[0] == '<') { 16313695Ssam ap = getprm(ap, prm); 16413695Ssam continue; 16513695Ssam } 16613695Ssam 16713695Ssam split(prm, xsys, rest); 16813695Ssam break; 16913695Ssam } 17013695Ssam if (xsys[0] == '\0') 17113695Ssam strcpy(xsys, local); 17218627Sralph if (versys(&xsys) != 0) { 17313695Ssam /* bad system name */ 17413695Ssam fprintf(stderr, "bad system name: %s\n", xsys); 17513695Ssam fclose(fprx); 17613695Ssam fclose(fpc); 17713695Ssam cleanup(EX_NOHOST); 17813695Ssam } 17913695Ssam 180*25146Sbloom strncpy(Rmtname, xsys, MAXBASENAME); 181*25146Sbloom DEBUG(4, "xsys %s\n", xsys); 182*25146Sbloom 18313695Ssam if (pipein) { 18413695Ssam gename(DATAPRE, local, 'B', dfile); 18513695Ssam fpd = ufopen(dfile, "w"); 18613695Ssam ASSERT(fpd != NULL, "CAN'T OPEN", dfile, 0); 18713695Ssam while (!feof(stdin)) { 18813695Ssam ret = fread(buf, 1, BUFSIZ, stdin); 18913695Ssam fwrite(buf, 1, ret, fpd); 19013695Ssam } 19113695Ssam fclose(fpd); 19217845Sralph strcpy(tfile, dfile); 19313695Ssam if (strcmp(local, xsys) != SAME) { 194*25146Sbloom register int Len = strlen(local); 195*25146Sbloom if (Len > SYSNSIZE) 196*25146Sbloom Len = SYSNSIZE; 197*25146Sbloom tfile[Len + 2] = 'S'; 19817845Sralph GENSEND(fpc, dfile, tfile, User, "", dfile); 19913695Ssam cflag++; 20013695Ssam } 20117845Sralph fprintf(fprx, "%c %s\n", X_RQDFILE, tfile); 20217845Sralph fprintf(fprx, "%c %s\n", X_STDIN, tfile); 20313695Ssam } 20413695Ssam /* parse command */ 20513695Ssam ap = inargs; 20613695Ssam while ((ap = getprm(ap, prm)) != NULL) { 20713695Ssam DEBUG(4, "prm - %s\n", prm); 20813695Ssam if (prm[0] == '>' || prm[0] == '<') { 20913695Ssam redir = prm[0]; 21013695Ssam continue; 21113695Ssam } 21213695Ssam 21313695Ssam if (prm[0] == ';') { 21413695Ssam APPCMD(prm); 21513695Ssam continue; 21613695Ssam } 21713695Ssam 21813695Ssam if (prm[0] == '|' || prm[0] == '^') { 21913695Ssam if (cmdp != cmd) 22013695Ssam APPCMD(prm); 22113695Ssam continue; 22213695Ssam } 22313695Ssam 22413695Ssam /* process command or file or option */ 22513695Ssam ret = split(prm, syspart, rest); 22613695Ssam DEBUG(4, "s - %s, ", syspart); 22713695Ssam DEBUG(4, "r - %s, ", rest); 22813695Ssam DEBUG(4, "ret - %d\n", ret); 22913695Ssam if (syspart[0] == '\0') 23013695Ssam strcpy(syspart, local); 23113695Ssam 23213695Ssam if (cmdp == cmd && redir == '\0') { 23313695Ssam /* command */ 23413695Ssam APPCMD(rest); 23513695Ssam continue; 23613695Ssam } 23713695Ssam 23813695Ssam /* process file or option */ 23913695Ssam DEBUG(4, "file s- %s, ", syspart); 24013695Ssam DEBUG(4, "local - %s\n", local); 24113695Ssam /* process file */ 24213695Ssam if (redir == '>') { 24313695Ssam if (rest[0] != '~') 24413695Ssam if (ckexpf(rest)) 24513695Ssam cleanup(EX_CANTCREAT); 24613695Ssam fprintf(fprx, "%c %s %s\n", X_STDOUT, rest, 24713695Ssam syspart); 24813695Ssam redir = '\0'; 24913695Ssam continue; 25013695Ssam } 25113695Ssam 25213695Ssam if (ret == NOSYSPART && redir == '\0') { 25313695Ssam /* option */ 25413695Ssam APPCMD(rest); 25513695Ssam continue; 25613695Ssam } 25713695Ssam 25813695Ssam if (strcmp(xsys, local) == SAME 25913695Ssam && strcmp(xsys, syspart) == SAME) { 26013695Ssam if (ckexpf(rest)) 26113695Ssam cleanup(EX_CANTCREAT); 26213695Ssam if (redir == '<') 26313695Ssam fprintf(fprx, "%c %s\n", X_STDIN, rest); 26413695Ssam else 26513695Ssam APPCMD(rest); 26613695Ssam redir = '\0'; 26713695Ssam continue; 26813695Ssam } 26913695Ssam 27013695Ssam if (strcmp(syspart, local) == SAME) { 27113695Ssam /* generate send file */ 27213695Ssam if (ckexpf(rest)) 27313695Ssam cleanup(EX_CANTCREAT); 27413695Ssam gename(DATAPRE, local, 'A', dfile); 27513695Ssam DEBUG(4, "rest %s\n", rest); 27613695Ssam if ((chkpth(User, "", rest) || anyread(rest)) != 0) { 27713695Ssam fprintf(stderr, "permission denied %s\n", rest); 27813695Ssam cleanup(EX_NOINPUT); 27913695Ssam } 28017845Sralph link_failed = 0; 28117845Sralph if (Linkit) { 28217845Sralph if (link(subfile(rest), subfile(dfile)) != 0) 28317845Sralph link_failed++; 28417845Sralph else 28517845Sralph GENSEND(fpc, rest, dfile, User, "", dfile); 28617845Sralph } 28717845Sralph if (Copy || link_failed) { 28813695Ssam if (xcp(rest, dfile) != 0) { 28913695Ssam fprintf(stderr, "can't copy %s to %s\n", rest, dfile); 29013695Ssam cleanup(EX_NOINPUT); 29113695Ssam } 29213695Ssam GENSEND(fpc, rest, dfile, User, "", dfile); 29313695Ssam } 29417845Sralph if (!Copy && !Linkit) { 29513695Ssam GENSEND(fpc, rest, dfile, User, "c", "D.0"); 29613695Ssam } 29713695Ssam cflag++; 29813695Ssam if (redir == '<') { 29913695Ssam fprintf(fprx, "%c %s\n", X_STDIN, dfile); 30013695Ssam fprintf(fprx, "%c %s\n", X_RQDFILE, dfile); 30118627Sralph } else { 30213695Ssam APPCMD(lastpart(rest)); 30313695Ssam fprintf(fprx, "%c %s %s\n", X_RQDFILE, 30413695Ssam dfile, lastpart(rest)); 30513695Ssam } 30613695Ssam redir = '\0'; 30713695Ssam continue; 30813695Ssam } 30913695Ssam 31013695Ssam if (strcmp(local, xsys) == SAME) { 31113695Ssam /* generate local receive */ 31213695Ssam gename(CMDPRE, syspart, 'R', tfile); 31313695Ssam strcpy(dfile, tfile); 31413695Ssam dfile[0] = DATAPRE; 31513695Ssam fp = ufopen(tfile, "w"); 31613695Ssam ASSERT(fp != NULL, "CAN'T OPEN", tfile, 0); 31713695Ssam if (ckexpf(rest)) 31813695Ssam cleanup(EX_CANTCREAT); 31913695Ssam GENRCV(fp, rest, dfile, User); 32013695Ssam fclose(fp); 32113695Ssam rflag++; 32213695Ssam if (rest[0] != '~') 32313695Ssam if (ckexpf(rest)) 32413695Ssam cleanup(EX_CANTCREAT); 32513695Ssam if (redir == '<') { 32613695Ssam fprintf(fprx, "%c %s\n", X_RQDFILE, dfile); 32713695Ssam fprintf(fprx, "%c %s\n", X_STDIN, dfile); 32818627Sralph } else { 32913695Ssam fprintf(fprx, "%c %s %s\n", X_RQDFILE, dfile, 33013695Ssam lastpart(rest)); 33113695Ssam APPCMD(lastpart(rest)); 33213695Ssam } 33313695Ssam 33413695Ssam redir = '\0'; 33513695Ssam continue; 33613695Ssam } 33713695Ssam 33813695Ssam if (strcmp(syspart, xsys) != SAME) { 33913695Ssam /* generate remote receives */ 34013695Ssam gename(DATAPRE, syspart, 'R', dfile); 34113695Ssam strcpy(tfile, dfile); 34213695Ssam tfile[0] = CMDPRE; 34313695Ssam fpd = ufopen(dfile, "w"); 34413695Ssam ASSERT(fpd != NULL, "CAN'T OPEN", dfile, 0); 34513695Ssam gename(DATAPRE, local, 'T', t2file); 34613695Ssam GENRCV(fpd, rest, t2file, User); 34713695Ssam fclose(fpd); 34813695Ssam GENSEND(fpc, dfile, tfile, User, "", dfile); 34913695Ssam cflag++; 35013695Ssam if (redir == '<') { 35113695Ssam fprintf(fprx, "%c %s\n", X_RQDFILE, t2file); 35213695Ssam fprintf(fprx, "%c %s\n", X_STDIN, t2file); 35318627Sralph } else { 35413695Ssam fprintf(fprx, "%c %s %s\n", X_RQDFILE, t2file, 35513695Ssam lastpart(rest)); 35613695Ssam APPCMD(lastpart(rest)); 35713695Ssam } 35813695Ssam redir = '\0'; 35913695Ssam continue; 36013695Ssam } 36113695Ssam 36213695Ssam /* file on remote system */ 36313695Ssam if (rest[0] != '~') 36413695Ssam if (ckexpf(rest)) 36513695Ssam cleanup(EX_CANTCREAT); 36613695Ssam if (redir == '<') 36713695Ssam fprintf(fprx, "%c %s\n", X_STDIN, rest); 36813695Ssam else 36913695Ssam APPCMD(rest); 37013695Ssam redir = '\0'; 37113695Ssam continue; 37213695Ssam 37313695Ssam } 37417845Sralph /* 37517845Sralph * clean up trailing ' ' in command. 37617845Sralph */ 37717845Sralph if (cmdp > cmd && cmdp[0] == '\0' && cmdp[-1] == ' ') 37817845Sralph *--cmdp = '\0'; 37917845Sralph /* block multi-hop uux, which doesn't work */ 38017845Sralph for (ap = cmd; *ap && *ap != ' '; ap++) 38117845Sralph if (*ap == '!') { 38217845Sralph fprintf(stderr, "uux handles only adjacent sites.\n"); 38317845Sralph fprintf(stderr, "Try uusend for multi-hop delivery.\n"); 38417845Sralph cleanup(1); 38517845Sralph } 38613695Ssam 38713695Ssam fprintf(fprx, "%c %s\n", X_CMD, cmd); 38813695Ssam logent(cmd, "XQT QUE'D"); 38913695Ssam fclose(fprx); 39013695Ssam 39117845Sralph gename(XQTPRE, local, Grade, tfile); 39213695Ssam if (strcmp(xsys, local) == SAME) { 39313695Ssam /* rti!trt: xmv() works across filesystems, link(II) doesnt */ 39413695Ssam xmv(rxfile, tfile); 39513695Ssam if (startjob) 39613695Ssam if (rflag) 39713695Ssam xuucico(xsys); 39813695Ssam else 39913695Ssam xuuxqt(); 40013695Ssam } 40113695Ssam else { 40213695Ssam GENSEND(fpc, rxfile, tfile, User, "", rxfile); 40313695Ssam cflag++; 40413695Ssam } 40513695Ssam 40613695Ssam fclose(fpc); 40713695Ssam if (cflag) { 40813695Ssam gename(CMDPRE, xsys, Grade, cfile); 40913695Ssam /* rti!trt: use xmv() rather than link(II) */ 41013695Ssam xmv(tcfile, cfile); 41113695Ssam if (startjob) 41213695Ssam xuucico(xsys); 41313695Ssam cleanup(0); 41413695Ssam } 41513695Ssam else 41613695Ssam unlink(subfile(tcfile)); 41718627Sralph exit(0); 41813695Ssam } 41913695Ssam 42013695Ssam #define FTABSIZE 30 42113695Ssam char Fname[FTABSIZE][NAMESIZE]; 42213695Ssam int Fnamect = 0; 42313695Ssam 42417845Sralph /* 42517845Sralph * cleanup and unlink if error 42613695Ssam * 42713695Ssam * return - none - do exit() 42813695Ssam */ 42913695Ssam 43013695Ssam cleanup(code) 43113695Ssam int code; 43213695Ssam { 43313695Ssam int i; 43413695Ssam 43513695Ssam logcls(); 43613695Ssam rmlock(CNULL); 43713695Ssam if (code) { 43813695Ssam for (i = 0; i < Fnamect; i++) 43913695Ssam unlink(subfile(Fname[i])); 44013695Ssam fprintf(stderr, "uux failed. code %d\n", code); 44113695Ssam } 44213695Ssam DEBUG(1, "exit code %d\n", code); 44313695Ssam exit(code); 44413695Ssam } 44513695Ssam 44617845Sralph /* 44717845Sralph * open file and record name 44813695Ssam * 44913695Ssam * return file pointer. 45013695Ssam */ 45113695Ssam 45213695Ssam FILE *ufopen(file, mode) 45313695Ssam char *file, *mode; 45413695Ssam { 45513695Ssam if (Fnamect < FTABSIZE) 45613695Ssam strcpy(Fname[Fnamect++], file); 45713695Ssam else 45813695Ssam logent("Fname", "TABLE OVERFLOW"); 45917845Sralph return fopen(subfile(file), mode); 46013695Ssam } 46117845Sralph #ifdef VMS 46217845Sralph /* 46317845Sralph * EUNICE bug: 46417845Sralph * quotes are not stripped from DCL. Do it here. 46517845Sralph * Note if we are running under Unix shell we don't 46617845Sralph * do the right thing. 46717845Sralph */ 46817845Sralph arg_fix(argc, argv) 46917845Sralph char **argv; 47017845Sralph { 47117845Sralph register char *cp, *tp; 47217845Sralph 47317845Sralph for (; argc > 0; --argc, argv++) { 47417845Sralph cp = *argv; 47517845Sralph if (cp == (char *)0 || *cp++ != '"') 47617845Sralph continue; 47717845Sralph tp = cp; 47817845Sralph while (*tp++) ; 47917845Sralph tp -= 2; 48017845Sralph if (*tp == '"') { 48117845Sralph *tp = '\0'; 48217845Sralph *argv = cp; 48317845Sralph } 48417845Sralph } 48517845Sralph } 48617845Sralph #endif VMS 487*25146Sbloom 488*25146Sbloom /* 489*25146Sbloom * split into system and file part 490*25146Sbloom * 491*25146Sbloom * return codes: 492*25146Sbloom * NOSYSPART 493*25146Sbloom * HASSYSPART 494*25146Sbloom */ 495*25146Sbloom 496*25146Sbloom split(name, sys, rest) 497*25146Sbloom register char *name, *rest; 498*25146Sbloom char *sys; 499*25146Sbloom { 500*25146Sbloom register char *c; 501*25146Sbloom register int i; 502*25146Sbloom 503*25146Sbloom if (*name == LQUOTE) { 504*25146Sbloom if ((c = index(name + 1, RQUOTE)) != NULL) { 505*25146Sbloom /* strip off quotes */ 506*25146Sbloom name++; 507*25146Sbloom while (c != name) 508*25146Sbloom *rest++ = *name++; 509*25146Sbloom *rest = '\0'; 510*25146Sbloom *sys = '\0'; 511*25146Sbloom return NOSYSPART; 512*25146Sbloom } 513*25146Sbloom } 514*25146Sbloom 515*25146Sbloom if ((c = index(name, '!')) == NULL) { 516*25146Sbloom strcpy(rest, name); 517*25146Sbloom *sys = '\0'; 518*25146Sbloom return NOSYSPART; 519*25146Sbloom } 520*25146Sbloom 521*25146Sbloom *c++ = '\0'; 522*25146Sbloom strncpy(sys, name, MAXBASENAME); 523*25146Sbloom sys[MAXBASENAME] = '\0'; 524*25146Sbloom 525*25146Sbloom strcpy(rest, c); 526*25146Sbloom return HASSYSPART; 527*25146Sbloom } 528