113695Ssam #ifndef lint 2*23691Sbloom static char sccsid[] = "@(#)uux.c 5.4 (Berkeley) 06/23/85"; 313695Ssam #endif 413695Ssam 513695Ssam #include "uucp.h" 613695Ssam 713695Ssam #define NOSYSPART 0 813695Ssam #define HASSYSPART 1 913695Ssam 1013695Ssam #define APPCMD(d) {\ 1117845Sralph char *p; for (p = d; *p != '\0';) *cmdp++ = *p++; *cmdp++ = ' '; *cmdp = '\0';} 1213695Ssam 1313695Ssam #define GENSEND(f, a, b, c, d, e) {\ 1417845Sralph fprintf(f, "S %s %s %s -%s %s 0666\n", a, b, c, d, e); } 1517845Sralph #define GENRCV(f, a, b, c) {fprintf(f, "R %s %s %s - \n", a, b, c);} 1613695Ssam 1713695Ssam main(argc, argv) 1813695Ssam char *argv[]; 1913695Ssam { 2013695Ssam char cfile[NAMESIZE]; /* send commands for files from here */ 2113695Ssam char dfile[NAMESIZE]; /* used for all data files from here */ 2213695Ssam char rxfile[NAMESIZE]; /* to be sent to xqt file (X. ...) */ 2313695Ssam char tfile[NAMESIZE]; /* temporary file name */ 2413695Ssam char tcfile[NAMESIZE]; /* temporary file name */ 2513695Ssam char t2file[NAMESIZE]; /* temporary file name */ 2613695Ssam int cflag = 0; /* commands in C. file flag */ 2713695Ssam int rflag = 0; /* C. files for receiving flag */ 2817845Sralph #ifdef DONTCOPY 2917845Sralph int Copy = 0; /* Don't Copy spool files */ 3017845Sralph #else !DONTCOPY 3113695Ssam int Copy = 1; /* Copy spool files */ 3217845Sralph #endif !DONTCOPY 3317845Sralph int Linkit = 0; /* Try link before copy */ 3413695Ssam char buf[BUFSIZ]; 3513695Ssam char inargs[BUFSIZ]; 3613695Ssam int pipein = 0; 3713695Ssam int startjob = 1; 3813695Ssam char Grade = 'A'; 3913695Ssam char path[MAXFULLNAME]; 4013695Ssam char cmd[BUFSIZ]; 4113695Ssam char *ap, *cmdp; 4213695Ssam char prm[BUFSIZ]; 43*23691Sbloom char syspart[MAXBASENAME+1], rest[MAXFULLNAME]; 44*23691Sbloom char Xsys[MAXBASENAME+1], local[MAXBASENAME+1]; 4518627Sralph char *xsys = Xsys; 4613695Ssam FILE *fprx, *fpc, *fpd, *fp; 4713695Ssam extern char *getprm(), *lastpart(); 4813695Ssam extern FILE *ufopen(); 4913695Ssam int uid, ret; 5013695Ssam char redir = '\0'; 5113695Ssam int nonoti = 0; 5213695Ssam int nonzero = 0; 5317845Sralph int link_failed; 5417845Sralph char *ReturnTo = NULL; 5517845Sralph extern int LocalOnly; 5613695Ssam 5713695Ssam strcpy(Progname, "uux"); 5813695Ssam uucpname(Myname); 5913695Ssam umask(WFMASK); 6013695Ssam Ofn = 1; 6113695Ssam Ifn = 0; 6217845Sralph #ifdef VMS 6317845Sralph arg_fix(argc, argv); 6417845Sralph #endif 6513695Ssam while (argc>1 && argv[1][0] == '-') { 6613695Ssam switch(argv[1][1]){ 6713695Ssam case 'p': 6813695Ssam case '\0': 6913695Ssam pipein = 1; 7013695Ssam break; 7113695Ssam case 'r': 7213695Ssam startjob = 0; 7313695Ssam break; 7413695Ssam case 'c': 7517845Sralph Copy = 0; 7617845Sralph Linkit = 0; 7717845Sralph break; 7813695Ssam case 'l': 7913695Ssam Copy = 0; 8017845Sralph Linkit = 1; 8113695Ssam break; 8217845Sralph case 'C': 8317845Sralph Copy = 1; 8417845Sralph Linkit = 0; 8517845Sralph break; 8613695Ssam case 'g': 8713695Ssam Grade = argv[1][2]; 8813695Ssam break; 8913695Ssam case 'x': 9017845Sralph chkdebug(); 9113695Ssam Debug = atoi(&argv[1][2]); 9213695Ssam if (Debug <= 0) 9313695Ssam Debug = 1; 9413695Ssam break; 9513695Ssam case 'n': 9613695Ssam nonoti = 1; 9713695Ssam break; 9813695Ssam case 'z': 9913695Ssam nonzero = 1; 10013695Ssam break; 10117845Sralph case 'L': 10217845Sralph LocalOnly++; 10317845Sralph break; 10417845Sralph case 'a': 10517845Sralph ReturnTo = &argv[1][2]; 106*23691Sbloom if (prefix(Myname, ReturnTo) && ReturnTo[strlen(Myname)] == '!') 107*23691Sbloom ReturnTo = index(ReturnTo, '!') + 1; 10817845Sralph break; 10913695Ssam default: 11013695Ssam fprintf(stderr, "unknown flag %s\n", argv[1]); 11113695Ssam break; 11213695Ssam } 11313695Ssam --argc; argv++; 11413695Ssam } 11517845Sralph if (argc > 2) { 116*23691Sbloom ap = getwd(Wrkdir); 117*23691Sbloom if (ap == 0) { 11817845Sralph fprintf(stderr, "can't get working directory; will try to continue\n"); 11917845Sralph strcpy(Wrkdir, "/UNKNOWN"); 12017845Sralph } 12117845Sralph } 12213695Ssam 12313695Ssam DEBUG(4, "\n\n** %s **\n", "START"); 12413695Ssam 12513695Ssam inargs[0] = '\0'; 12613695Ssam for (argv++; argc > 1; argc--) { 12713695Ssam DEBUG(4, "arg - %s:", *argv); 12813695Ssam strcat(inargs, " "); 12913695Ssam strcat(inargs, *argv++); 13013695Ssam } 13113695Ssam DEBUG(4, "arg - %s\n", inargs); 13217845Sralph ret = subchdir(Spool); 13317845Sralph ASSERT(ret >= 0, "CHDIR FAILED", Spool, ret); 13413695Ssam uid = getuid(); 13513695Ssam guinfo(uid, User, path); 13613695Ssam 137*23691Sbloom strncpy(local, Myname, MAXBASENAME); 13813695Ssam cmdp = cmd; 13913695Ssam *cmdp = '\0'; 14013695Ssam gename(DATAPRE, local, 'X', rxfile); 14113695Ssam fprx = ufopen(rxfile, "w"); 14213695Ssam ASSERT(fprx != NULL, "CAN'T OPEN", rxfile, 0); 14313695Ssam gename(DATAPRE, local, 'T', tcfile); 14413695Ssam fpc = ufopen(tcfile, "w"); 14513695Ssam ASSERT(fpc != NULL, "CAN'T OPEN", tcfile, 0); 14613695Ssam fprintf(fprx, "%c %s %s\n", X_USER, User, local); 14713695Ssam if (nonoti) 14813695Ssam fprintf(fprx, "%c\n", X_NONOTI); 14913695Ssam if (nonzero) 15013695Ssam fprintf(fprx, "%c\n", X_NONZERO); 15117845Sralph if (ReturnTo == NULL || *ReturnTo == '\0') 15217845Sralph ReturnTo = User; 15317845Sralph fprintf(fprx, "%c %s\n", X_RETURNTO, ReturnTo); 15413695Ssam 15513695Ssam /* find remote system name */ 15613695Ssam ap = inargs; 15713695Ssam xsys[0] = '\0'; 15813695Ssam while ((ap = getprm(ap, prm)) != NULL) { 15913695Ssam if (prm[0] == '>' || prm[0] == '<') { 16013695Ssam ap = getprm(ap, prm); 16113695Ssam continue; 16213695Ssam } 16313695Ssam 16413695Ssam 16513695Ssam split(prm, xsys, rest); 16613695Ssam break; 16713695Ssam } 16813695Ssam if (xsys[0] == '\0') 16913695Ssam strcpy(xsys, local); 170*23691Sbloom strncpy(Rmtname, xsys, MAXBASENAME); 17113695Ssam DEBUG(4, "xsys %s\n", xsys); 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 18013695Ssam if (pipein) { 18113695Ssam gename(DATAPRE, local, 'B', dfile); 18213695Ssam fpd = ufopen(dfile, "w"); 18313695Ssam ASSERT(fpd != NULL, "CAN'T OPEN", dfile, 0); 18413695Ssam while (!feof(stdin)) { 18513695Ssam ret = fread(buf, 1, BUFSIZ, stdin); 18613695Ssam fwrite(buf, 1, ret, fpd); 18713695Ssam } 18813695Ssam fclose(fpd); 18917845Sralph strcpy(tfile, dfile); 19013695Ssam if (strcmp(local, xsys) != SAME) { 19117845Sralph tfile[strlen(local) + 2] = 'S'; 19217845Sralph GENSEND(fpc, dfile, tfile, User, "", dfile); 19313695Ssam cflag++; 19413695Ssam } 19517845Sralph fprintf(fprx, "%c %s\n", X_RQDFILE, tfile); 19617845Sralph fprintf(fprx, "%c %s\n", X_STDIN, tfile); 19713695Ssam } 19813695Ssam /* parse command */ 19913695Ssam ap = inargs; 20013695Ssam while ((ap = getprm(ap, prm)) != NULL) { 20113695Ssam DEBUG(4, "prm - %s\n", prm); 20213695Ssam if (prm[0] == '>' || prm[0] == '<') { 20313695Ssam redir = prm[0]; 20413695Ssam continue; 20513695Ssam } 20613695Ssam 20713695Ssam if (prm[0] == ';') { 20813695Ssam APPCMD(prm); 20913695Ssam continue; 21013695Ssam } 21113695Ssam 21213695Ssam if (prm[0] == '|' || prm[0] == '^') { 21313695Ssam if (cmdp != cmd) 21413695Ssam APPCMD(prm); 21513695Ssam continue; 21613695Ssam } 21713695Ssam 21813695Ssam /* process command or file or option */ 21913695Ssam ret = split(prm, syspart, rest); 22013695Ssam DEBUG(4, "s - %s, ", syspart); 22113695Ssam DEBUG(4, "r - %s, ", rest); 22213695Ssam DEBUG(4, "ret - %d\n", ret); 22313695Ssam if (syspart[0] == '\0') 22413695Ssam strcpy(syspart, local); 22513695Ssam 22613695Ssam if (cmdp == cmd && redir == '\0') { 22713695Ssam /* command */ 22813695Ssam APPCMD(rest); 22913695Ssam continue; 23013695Ssam } 23113695Ssam 23213695Ssam /* process file or option */ 23313695Ssam DEBUG(4, "file s- %s, ", syspart); 23413695Ssam DEBUG(4, "local - %s\n", local); 23513695Ssam /* process file */ 23613695Ssam if (redir == '>') { 23713695Ssam if (rest[0] != '~') 23813695Ssam if (ckexpf(rest)) 23913695Ssam cleanup(EX_CANTCREAT); 24013695Ssam fprintf(fprx, "%c %s %s\n", X_STDOUT, rest, 24113695Ssam syspart); 24213695Ssam redir = '\0'; 24313695Ssam continue; 24413695Ssam } 24513695Ssam 24613695Ssam if (ret == NOSYSPART && redir == '\0') { 24713695Ssam /* option */ 24813695Ssam APPCMD(rest); 24913695Ssam continue; 25013695Ssam } 25113695Ssam 25213695Ssam if (strcmp(xsys, local) == SAME 25313695Ssam && strcmp(xsys, syspart) == SAME) { 25413695Ssam if (ckexpf(rest)) 25513695Ssam cleanup(EX_CANTCREAT); 25613695Ssam if (redir == '<') 25713695Ssam fprintf(fprx, "%c %s\n", X_STDIN, rest); 25813695Ssam else 25913695Ssam APPCMD(rest); 26013695Ssam redir = '\0'; 26113695Ssam continue; 26213695Ssam } 26313695Ssam 26413695Ssam if (strcmp(syspart, local) == SAME) { 26513695Ssam /* generate send file */ 26613695Ssam if (ckexpf(rest)) 26713695Ssam cleanup(EX_CANTCREAT); 26813695Ssam gename(DATAPRE, local, 'A', dfile); 26913695Ssam DEBUG(4, "rest %s\n", rest); 27013695Ssam if ((chkpth(User, "", rest) || anyread(rest)) != 0) { 27113695Ssam fprintf(stderr, "permission denied %s\n", rest); 27213695Ssam cleanup(EX_NOINPUT); 27313695Ssam } 27417845Sralph link_failed = 0; 27517845Sralph if (Linkit) { 27617845Sralph if (link(subfile(rest), subfile(dfile)) != 0) 27717845Sralph link_failed++; 27817845Sralph else 27917845Sralph GENSEND(fpc, rest, dfile, User, "", dfile); 28017845Sralph } 28117845Sralph if (Copy || link_failed) { 28213695Ssam if (xcp(rest, dfile) != 0) { 28313695Ssam fprintf(stderr, "can't copy %s to %s\n", rest, dfile); 28413695Ssam cleanup(EX_NOINPUT); 28513695Ssam } 28613695Ssam GENSEND(fpc, rest, dfile, User, "", dfile); 28713695Ssam } 28817845Sralph if (!Copy && !Linkit) { 28913695Ssam GENSEND(fpc, rest, dfile, User, "c", "D.0"); 29013695Ssam } 29113695Ssam cflag++; 29213695Ssam if (redir == '<') { 29313695Ssam fprintf(fprx, "%c %s\n", X_STDIN, dfile); 29413695Ssam fprintf(fprx, "%c %s\n", X_RQDFILE, dfile); 29518627Sralph } else { 29613695Ssam APPCMD(lastpart(rest)); 29713695Ssam fprintf(fprx, "%c %s %s\n", X_RQDFILE, 29813695Ssam dfile, lastpart(rest)); 29913695Ssam } 30013695Ssam redir = '\0'; 30113695Ssam continue; 30213695Ssam } 30313695Ssam 30413695Ssam if (strcmp(local, xsys) == SAME) { 30513695Ssam /* generate local receive */ 30613695Ssam gename(CMDPRE, syspart, 'R', tfile); 30713695Ssam strcpy(dfile, tfile); 30813695Ssam dfile[0] = DATAPRE; 30913695Ssam fp = ufopen(tfile, "w"); 31013695Ssam ASSERT(fp != NULL, "CAN'T OPEN", tfile, 0); 31113695Ssam if (ckexpf(rest)) 31213695Ssam cleanup(EX_CANTCREAT); 31313695Ssam GENRCV(fp, rest, dfile, User); 31413695Ssam fclose(fp); 31513695Ssam rflag++; 31613695Ssam if (rest[0] != '~') 31713695Ssam if (ckexpf(rest)) 31813695Ssam cleanup(EX_CANTCREAT); 31913695Ssam if (redir == '<') { 32013695Ssam fprintf(fprx, "%c %s\n", X_RQDFILE, dfile); 32113695Ssam fprintf(fprx, "%c %s\n", X_STDIN, dfile); 32218627Sralph } else { 32313695Ssam fprintf(fprx, "%c %s %s\n", X_RQDFILE, dfile, 32413695Ssam lastpart(rest)); 32513695Ssam APPCMD(lastpart(rest)); 32613695Ssam } 32713695Ssam 32813695Ssam redir = '\0'; 32913695Ssam continue; 33013695Ssam } 33113695Ssam 33213695Ssam if (strcmp(syspart, xsys) != SAME) { 33313695Ssam /* generate remote receives */ 33413695Ssam gename(DATAPRE, syspart, 'R', dfile); 33513695Ssam strcpy(tfile, dfile); 33613695Ssam tfile[0] = CMDPRE; 33713695Ssam fpd = ufopen(dfile, "w"); 33813695Ssam ASSERT(fpd != NULL, "CAN'T OPEN", dfile, 0); 33913695Ssam gename(DATAPRE, local, 'T', t2file); 34013695Ssam GENRCV(fpd, rest, t2file, User); 34113695Ssam fclose(fpd); 34213695Ssam GENSEND(fpc, dfile, tfile, User, "", dfile); 34313695Ssam cflag++; 34413695Ssam if (redir == '<') { 34513695Ssam fprintf(fprx, "%c %s\n", X_RQDFILE, t2file); 34613695Ssam fprintf(fprx, "%c %s\n", X_STDIN, t2file); 34718627Sralph } else { 34813695Ssam fprintf(fprx, "%c %s %s\n", X_RQDFILE, t2file, 34913695Ssam lastpart(rest)); 35013695Ssam APPCMD(lastpart(rest)); 35113695Ssam } 35213695Ssam redir = '\0'; 35313695Ssam continue; 35413695Ssam } 35513695Ssam 35613695Ssam /* file on remote system */ 35713695Ssam if (rest[0] != '~') 35813695Ssam if (ckexpf(rest)) 35913695Ssam cleanup(EX_CANTCREAT); 36013695Ssam if (redir == '<') 36113695Ssam fprintf(fprx, "%c %s\n", X_STDIN, rest); 36213695Ssam else 36313695Ssam APPCMD(rest); 36413695Ssam redir = '\0'; 36513695Ssam continue; 36613695Ssam 36713695Ssam } 36817845Sralph /* 36917845Sralph * clean up trailing ' ' in command. 37017845Sralph */ 37117845Sralph if (cmdp > cmd && cmdp[0] == '\0' && cmdp[-1] == ' ') 37217845Sralph *--cmdp = '\0'; 37317845Sralph /* block multi-hop uux, which doesn't work */ 37417845Sralph for (ap = cmd; *ap && *ap != ' '; ap++) 37517845Sralph if (*ap == '!') { 37617845Sralph fprintf(stderr, "uux handles only adjacent sites.\n"); 37717845Sralph fprintf(stderr, "Try uusend for multi-hop delivery.\n"); 37817845Sralph cleanup(1); 37917845Sralph } 38013695Ssam 38113695Ssam fprintf(fprx, "%c %s\n", X_CMD, cmd); 38213695Ssam logent(cmd, "XQT QUE'D"); 38313695Ssam fclose(fprx); 38413695Ssam 38517845Sralph gename(XQTPRE, local, Grade, tfile); 38613695Ssam if (strcmp(xsys, local) == SAME) { 38713695Ssam /* rti!trt: xmv() works across filesystems, link(II) doesnt */ 38813695Ssam xmv(rxfile, tfile); 38913695Ssam if (startjob) 39013695Ssam if (rflag) 39113695Ssam xuucico(xsys); 39213695Ssam else 39313695Ssam xuuxqt(); 39413695Ssam } 39513695Ssam else { 39613695Ssam GENSEND(fpc, rxfile, tfile, User, "", rxfile); 39713695Ssam cflag++; 39813695Ssam } 39913695Ssam 40013695Ssam fclose(fpc); 40113695Ssam if (cflag) { 40213695Ssam gename(CMDPRE, xsys, Grade, cfile); 40313695Ssam /* rti!trt: use xmv() rather than link(II) */ 40413695Ssam xmv(tcfile, cfile); 40513695Ssam if (startjob) 40613695Ssam xuucico(xsys); 40713695Ssam cleanup(0); 40813695Ssam } 40913695Ssam else 41013695Ssam unlink(subfile(tcfile)); 41118627Sralph exit(0); 41213695Ssam } 41313695Ssam 41413695Ssam #define FTABSIZE 30 41513695Ssam char Fname[FTABSIZE][NAMESIZE]; 41613695Ssam int Fnamect = 0; 41713695Ssam 41817845Sralph /* 41917845Sralph * cleanup and unlink if error 42013695Ssam * 42113695Ssam * return - none - do exit() 42213695Ssam */ 42313695Ssam 42413695Ssam cleanup(code) 42513695Ssam int code; 42613695Ssam { 42713695Ssam int i; 42813695Ssam 42913695Ssam logcls(); 43013695Ssam rmlock(CNULL); 43113695Ssam if (code) { 43213695Ssam for (i = 0; i < Fnamect; i++) 43313695Ssam unlink(subfile(Fname[i])); 43413695Ssam fprintf(stderr, "uux failed. code %d\n", code); 43513695Ssam } 43613695Ssam DEBUG(1, "exit code %d\n", code); 43713695Ssam exit(code); 43813695Ssam } 43913695Ssam 44017845Sralph /* 44117845Sralph * open file and record name 44213695Ssam * 44313695Ssam * return file pointer. 44413695Ssam */ 44513695Ssam 44613695Ssam FILE *ufopen(file, mode) 44713695Ssam char *file, *mode; 44813695Ssam { 44913695Ssam if (Fnamect < FTABSIZE) 45013695Ssam strcpy(Fname[Fnamect++], file); 45113695Ssam else 45213695Ssam logent("Fname", "TABLE OVERFLOW"); 45317845Sralph return fopen(subfile(file), mode); 45413695Ssam } 45517845Sralph #ifdef VMS 45617845Sralph /* 45717845Sralph * EUNICE bug: 45817845Sralph * quotes are not stripped from DCL. Do it here. 45917845Sralph * Note if we are running under Unix shell we don't 46017845Sralph * do the right thing. 46117845Sralph */ 46217845Sralph arg_fix(argc, argv) 46317845Sralph char **argv; 46417845Sralph { 46517845Sralph register char *cp, *tp; 46617845Sralph 46717845Sralph for (; argc > 0; --argc, argv++) { 46817845Sralph cp = *argv; 46917845Sralph if (cp == (char *)0 || *cp++ != '"') 47017845Sralph continue; 47117845Sralph tp = cp; 47217845Sralph while (*tp++) ; 47317845Sralph tp -= 2; 47417845Sralph if (*tp == '"') { 47517845Sralph *tp = '\0'; 47617845Sralph *argv = cp; 47717845Sralph } 47817845Sralph } 47917845Sralph } 48017845Sralph #endif VMS 481