1*13695Ssam #ifndef lint 2*13695Ssam static char sccsid[] = "@(#)uux.c 5.1 (Berkeley) 07/02/83"; 3*13695Ssam #endif 4*13695Ssam 5*13695Ssam /* 6*13695Ssam * Grade option "-g<g>" added. See cbosgd.2611 (Mark Horton) 7*13695Ssam * no-copy option "-c" added. Suggested by Steve Bellovin 8*13695Ssam * "-l" is synonym for "-c". 9*13695Ssam * "X" files use local system name, avoids conflict. Steve Bellovin 10*13695Ssam */ 11*13695Ssam #include "uucp.h" 12*13695Ssam 13*13695Ssam #define NOSYSPART 0 14*13695Ssam #define HASSYSPART 1 15*13695Ssam 16*13695Ssam #define APPCMD(d) {\ 17*13695Ssam char *p;\ 18*13695Ssam for (p = d; *p != '\0';) *cmdp++ = *p++;\ 19*13695Ssam *cmdp++ = ' ';\ 20*13695Ssam *cmdp = '\0';} 21*13695Ssam 22*13695Ssam #define GENSEND(f, a, b, c, d, e) {\ 23*13695Ssam fprintf(f, "S %s %s %s -%s %s 0666\n", a, b, c, d, e);\ 24*13695Ssam } 25*13695Ssam #define GENRCV(f, a, b, c) {\ 26*13695Ssam fprintf(f, "R %s %s %s - \n", a, b, c);\ 27*13695Ssam } 28*13695Ssam 29*13695Ssam 30*13695Ssam /* 31*13695Ssam * 32*13695Ssam */ 33*13695Ssam 34*13695Ssam main(argc, argv) 35*13695Ssam char *argv[]; 36*13695Ssam { 37*13695Ssam char cfile[NAMESIZE]; /* send commands for files from here */ 38*13695Ssam char dfile[NAMESIZE]; /* used for all data files from here */ 39*13695Ssam char rxfile[NAMESIZE]; /* to be sent to xqt file (X. ...) */ 40*13695Ssam char tfile[NAMESIZE]; /* temporary file name */ 41*13695Ssam char tcfile[NAMESIZE]; /* temporary file name */ 42*13695Ssam char t2file[NAMESIZE]; /* temporary file name */ 43*13695Ssam int cflag = 0; /* commands in C. file flag */ 44*13695Ssam int rflag = 0; /* C. files for receiving flag */ 45*13695Ssam int Copy = 1; /* Copy spool files */ 46*13695Ssam char buf[BUFSIZ]; 47*13695Ssam char inargs[BUFSIZ]; 48*13695Ssam int pipein = 0; 49*13695Ssam int startjob = 1; 50*13695Ssam char Grade = 'A'; 51*13695Ssam char path[MAXFULLNAME]; 52*13695Ssam char cmd[BUFSIZ]; 53*13695Ssam char *ap, *cmdp; 54*13695Ssam char prm[BUFSIZ]; 55*13695Ssam char syspart[8], rest[MAXFULLNAME]; 56*13695Ssam char xsys[8], local[8]; 57*13695Ssam FILE *fprx, *fpc, *fpd, *fp; 58*13695Ssam extern char *getprm(), *lastpart(); 59*13695Ssam extern FILE *ufopen(); 60*13695Ssam int uid, ret; 61*13695Ssam char redir = '\0'; 62*13695Ssam int nonoti = 0; 63*13695Ssam int nonzero = 0; 64*13695Ssam int orig_uid = getuid(); 65*13695Ssam 66*13695Ssam strcpy(Progname, "uux"); 67*13695Ssam uucpname(Myname); 68*13695Ssam umask(WFMASK); 69*13695Ssam Ofn = 1; 70*13695Ssam Ifn = 0; 71*13695Ssam while (argc>1 && argv[1][0] == '-') { 72*13695Ssam switch(argv[1][1]){ 73*13695Ssam case 'p': 74*13695Ssam case '\0': 75*13695Ssam pipein = 1; 76*13695Ssam break; 77*13695Ssam case 'r': 78*13695Ssam startjob = 0; 79*13695Ssam break; 80*13695Ssam case 'c': 81*13695Ssam case 'l': 82*13695Ssam Copy = 0; 83*13695Ssam break; 84*13695Ssam case 'g': 85*13695Ssam Grade = argv[1][2]; 86*13695Ssam break; 87*13695Ssam case 'x': 88*13695Ssam chkdebug(orig_uid); 89*13695Ssam Debug = atoi(&argv[1][2]); 90*13695Ssam if (Debug <= 0) 91*13695Ssam Debug = 1; 92*13695Ssam break; 93*13695Ssam case 'n': 94*13695Ssam nonoti = 1; 95*13695Ssam break; 96*13695Ssam case 'z': 97*13695Ssam nonzero = 1; 98*13695Ssam break; 99*13695Ssam default: 100*13695Ssam fprintf(stderr, "unknown flag %s\n", argv[1]); 101*13695Ssam break; 102*13695Ssam } 103*13695Ssam --argc; argv++; 104*13695Ssam } 105*13695Ssam 106*13695Ssam DEBUG(4, "\n\n** %s **\n", "START"); 107*13695Ssam 108*13695Ssam inargs[0] = '\0'; 109*13695Ssam for (argv++; argc > 1; argc--) { 110*13695Ssam DEBUG(4, "arg - %s:", *argv); 111*13695Ssam strcat(inargs, " "); 112*13695Ssam strcat(inargs, *argv++); 113*13695Ssam } 114*13695Ssam DEBUG(4, "arg - %s\n", inargs); 115*13695Ssam ret = gwd(Wrkdir); 116*13695Ssam if (ret != 0) { 117*13695Ssam fprintf(stderr, "can't get working directory; will try to continue\n"); 118*13695Ssam strcpy(Wrkdir, "/UNKNOWN"); 119*13695Ssam } 120*13695Ssam subchdir(Spool); 121*13695Ssam uid = getuid(); 122*13695Ssam guinfo(uid, User, path); 123*13695Ssam 124*13695Ssam sprintf(local, "%.7s", Myname); 125*13695Ssam cmdp = cmd; 126*13695Ssam *cmdp = '\0'; 127*13695Ssam gename(DATAPRE, local, 'X', rxfile); 128*13695Ssam fprx = ufopen(rxfile, "w"); 129*13695Ssam ASSERT(fprx != NULL, "CAN'T OPEN", rxfile, 0); 130*13695Ssam gename(DATAPRE, local, 'T', tcfile); 131*13695Ssam fpc = ufopen(tcfile, "w"); 132*13695Ssam ASSERT(fpc != NULL, "CAN'T OPEN", tcfile, 0); 133*13695Ssam fprintf(fprx, "%c %s %s\n", X_USER, User, local); 134*13695Ssam if (nonoti) 135*13695Ssam fprintf(fprx, "%c\n", X_NONOTI); 136*13695Ssam if (nonzero) 137*13695Ssam fprintf(fprx, "%c\n", X_NONZERO); 138*13695Ssam 139*13695Ssam /* find remote system name */ 140*13695Ssam ap = inargs; 141*13695Ssam xsys[0] = '\0'; 142*13695Ssam while ((ap = getprm(ap, prm)) != NULL) { 143*13695Ssam if (prm[0] == '>' || prm[0] == '<') { 144*13695Ssam ap = getprm(ap, prm); 145*13695Ssam continue; 146*13695Ssam } 147*13695Ssam 148*13695Ssam 149*13695Ssam split(prm, xsys, rest); 150*13695Ssam break; 151*13695Ssam } 152*13695Ssam if (xsys[0] == '\0') 153*13695Ssam strcpy(xsys, local); 154*13695Ssam sprintf(Rmtname, "%.7s", xsys); 155*13695Ssam DEBUG(4, "xsys %s\n", xsys); 156*13695Ssam if (versys(xsys) != 0) { 157*13695Ssam /* bad system name */ 158*13695Ssam fprintf(stderr, "bad system name: %s\n", xsys); 159*13695Ssam fclose(fprx); 160*13695Ssam fclose(fpc); 161*13695Ssam cleanup(EX_NOHOST); 162*13695Ssam } 163*13695Ssam 164*13695Ssam if (pipein) { 165*13695Ssam gename(DATAPRE, local, 'B', dfile); 166*13695Ssam fpd = ufopen(dfile, "w"); 167*13695Ssam ASSERT(fpd != NULL, "CAN'T OPEN", dfile, 0); 168*13695Ssam while (!feof(stdin)) { 169*13695Ssam ret = fread(buf, 1, BUFSIZ, stdin); 170*13695Ssam fwrite(buf, 1, ret, fpd); 171*13695Ssam } 172*13695Ssam fclose(fpd); 173*13695Ssam if (strcmp(local, xsys) != SAME) { 174*13695Ssam GENSEND(fpc, dfile, dfile, User, "", dfile); 175*13695Ssam cflag++; 176*13695Ssam } 177*13695Ssam fprintf(fprx, "%c %s\n", X_RQDFILE, dfile); 178*13695Ssam fprintf(fprx, "%c %s\n", X_STDIN, dfile); 179*13695Ssam } 180*13695Ssam /* parse command */ 181*13695Ssam ap = inargs; 182*13695Ssam while ((ap = getprm(ap, prm)) != NULL) { 183*13695Ssam DEBUG(4, "prm - %s\n", prm); 184*13695Ssam if (prm[0] == '>' || prm[0] == '<') { 185*13695Ssam redir = prm[0]; 186*13695Ssam continue; 187*13695Ssam } 188*13695Ssam 189*13695Ssam if (prm[0] == ';') { 190*13695Ssam APPCMD(prm); 191*13695Ssam continue; 192*13695Ssam } 193*13695Ssam 194*13695Ssam if (prm[0] == '|' || prm[0] == '^') { 195*13695Ssam if (cmdp != cmd) 196*13695Ssam APPCMD(prm); 197*13695Ssam continue; 198*13695Ssam } 199*13695Ssam 200*13695Ssam /* process command or file or option */ 201*13695Ssam ret = split(prm, syspart, rest); 202*13695Ssam DEBUG(4, "s - %s, ", syspart); 203*13695Ssam DEBUG(4, "r - %s, ", rest); 204*13695Ssam DEBUG(4, "ret - %d\n", ret); 205*13695Ssam if (syspart[0] == '\0') 206*13695Ssam strcpy(syspart, local); 207*13695Ssam 208*13695Ssam if (cmdp == cmd && redir == '\0') { 209*13695Ssam /* command */ 210*13695Ssam APPCMD(rest); 211*13695Ssam continue; 212*13695Ssam } 213*13695Ssam 214*13695Ssam /* process file or option */ 215*13695Ssam DEBUG(4, "file s- %s, ", syspart); 216*13695Ssam DEBUG(4, "local - %s\n", local); 217*13695Ssam /* process file */ 218*13695Ssam if (redir == '>') { 219*13695Ssam if (rest[0] != '~') 220*13695Ssam if (ckexpf(rest)) 221*13695Ssam cleanup(EX_CANTCREAT); 222*13695Ssam fprintf(fprx, "%c %s %s\n", X_STDOUT, rest, 223*13695Ssam syspart); 224*13695Ssam redir = '\0'; 225*13695Ssam continue; 226*13695Ssam } 227*13695Ssam 228*13695Ssam if (ret == NOSYSPART && redir == '\0') { 229*13695Ssam /* option */ 230*13695Ssam APPCMD(rest); 231*13695Ssam continue; 232*13695Ssam } 233*13695Ssam 234*13695Ssam if (strcmp(xsys, local) == SAME 235*13695Ssam && strcmp(xsys, syspart) == SAME) { 236*13695Ssam if (ckexpf(rest)) 237*13695Ssam cleanup(EX_CANTCREAT); 238*13695Ssam if (redir == '<') 239*13695Ssam fprintf(fprx, "%c %s\n", X_STDIN, rest); 240*13695Ssam else 241*13695Ssam APPCMD(rest); 242*13695Ssam redir = '\0'; 243*13695Ssam continue; 244*13695Ssam } 245*13695Ssam 246*13695Ssam if (strcmp(syspart, local) == SAME) { 247*13695Ssam /* generate send file */ 248*13695Ssam if (ckexpf(rest)) 249*13695Ssam cleanup(EX_CANTCREAT); 250*13695Ssam gename(DATAPRE, local, 'A', dfile); 251*13695Ssam DEBUG(4, "rest %s\n", rest); 252*13695Ssam if ((chkpth(User, "", rest) || anyread(rest)) != 0) { 253*13695Ssam fprintf(stderr, "permission denied %s\n", rest); 254*13695Ssam cleanup(EX_NOINPUT); 255*13695Ssam } 256*13695Ssam if (Copy) { 257*13695Ssam if (xcp(rest, dfile) != 0) { 258*13695Ssam fprintf(stderr, "can't copy %s to %s\n", rest, dfile); 259*13695Ssam cleanup(EX_NOINPUT); 260*13695Ssam } 261*13695Ssam GENSEND(fpc, rest, dfile, User, "", dfile); 262*13695Ssam } 263*13695Ssam else { 264*13695Ssam GENSEND(fpc, rest, dfile, User, "c", "D.0"); 265*13695Ssam } 266*13695Ssam cflag++; 267*13695Ssam if (redir == '<') { 268*13695Ssam fprintf(fprx, "%c %s\n", X_STDIN, dfile); 269*13695Ssam fprintf(fprx, "%c %s\n", X_RQDFILE, dfile); 270*13695Ssam } 271*13695Ssam else { 272*13695Ssam APPCMD(lastpart(rest)); 273*13695Ssam fprintf(fprx, "%c %s %s\n", X_RQDFILE, 274*13695Ssam dfile, lastpart(rest)); 275*13695Ssam } 276*13695Ssam redir = '\0'; 277*13695Ssam continue; 278*13695Ssam } 279*13695Ssam 280*13695Ssam if (strcmp(local, xsys) == SAME) { 281*13695Ssam /* generate local receive */ 282*13695Ssam gename(CMDPRE, syspart, 'R', tfile); 283*13695Ssam strcpy(dfile, tfile); 284*13695Ssam dfile[0] = DATAPRE; 285*13695Ssam fp = ufopen(tfile, "w"); 286*13695Ssam ASSERT(fp != NULL, "CAN'T OPEN", tfile, 0); 287*13695Ssam if (ckexpf(rest)) 288*13695Ssam cleanup(EX_CANTCREAT); 289*13695Ssam GENRCV(fp, rest, dfile, User); 290*13695Ssam fclose(fp); 291*13695Ssam rflag++; 292*13695Ssam if (rest[0] != '~') 293*13695Ssam if (ckexpf(rest)) 294*13695Ssam cleanup(EX_CANTCREAT); 295*13695Ssam if (redir == '<') { 296*13695Ssam fprintf(fprx, "%c %s\n", X_RQDFILE, dfile); 297*13695Ssam fprintf(fprx, "%c %s\n", X_STDIN, dfile); 298*13695Ssam } 299*13695Ssam else { 300*13695Ssam fprintf(fprx, "%c %s %s\n", X_RQDFILE, dfile, 301*13695Ssam lastpart(rest)); 302*13695Ssam APPCMD(lastpart(rest)); 303*13695Ssam } 304*13695Ssam 305*13695Ssam redir = '\0'; 306*13695Ssam continue; 307*13695Ssam } 308*13695Ssam 309*13695Ssam if (strcmp(syspart, xsys) != SAME) { 310*13695Ssam /* generate remote receives */ 311*13695Ssam gename(DATAPRE, syspart, 'R', dfile); 312*13695Ssam strcpy(tfile, dfile); 313*13695Ssam tfile[0] = CMDPRE; 314*13695Ssam fpd = ufopen(dfile, "w"); 315*13695Ssam ASSERT(fpd != NULL, "CAN'T OPEN", dfile, 0); 316*13695Ssam gename(DATAPRE, local, 'T', t2file); 317*13695Ssam GENRCV(fpd, rest, t2file, User); 318*13695Ssam fclose(fpd); 319*13695Ssam GENSEND(fpc, dfile, tfile, User, "", dfile); 320*13695Ssam cflag++; 321*13695Ssam if (redir == '<') { 322*13695Ssam fprintf(fprx, "%c %s\n", X_RQDFILE, t2file); 323*13695Ssam fprintf(fprx, "%c %s\n", X_STDIN, t2file); 324*13695Ssam } 325*13695Ssam else { 326*13695Ssam fprintf(fprx, "%c %s %s\n", X_RQDFILE, t2file, 327*13695Ssam lastpart(rest)); 328*13695Ssam APPCMD(lastpart(rest)); 329*13695Ssam } 330*13695Ssam redir = '\0'; 331*13695Ssam continue; 332*13695Ssam } 333*13695Ssam 334*13695Ssam /* file on remote system */ 335*13695Ssam if (rest[0] != '~') 336*13695Ssam if (ckexpf(rest)) 337*13695Ssam cleanup(EX_CANTCREAT); 338*13695Ssam if (redir == '<') 339*13695Ssam fprintf(fprx, "%c %s\n", X_STDIN, rest); 340*13695Ssam else 341*13695Ssam APPCMD(rest); 342*13695Ssam redir = '\0'; 343*13695Ssam continue; 344*13695Ssam 345*13695Ssam } 346*13695Ssam 347*13695Ssam fprintf(fprx, "%c %s\n", X_CMD, cmd); 348*13695Ssam logent(cmd, "XQT QUE'D"); 349*13695Ssam fclose(fprx); 350*13695Ssam 351*13695Ssam strcpy(tfile, rxfile); 352*13695Ssam tfile[0] = XQTPRE; 353*13695Ssam if (strcmp(xsys, local) == SAME) { 354*13695Ssam /* rti!trt: xmv() works across filesystems, link(II) doesnt */ 355*13695Ssam xmv(rxfile, tfile); 356*13695Ssam if (startjob) 357*13695Ssam if (rflag) 358*13695Ssam xuucico(xsys); 359*13695Ssam else 360*13695Ssam xuuxqt(); 361*13695Ssam } 362*13695Ssam else { 363*13695Ssam GENSEND(fpc, rxfile, tfile, User, "", rxfile); 364*13695Ssam cflag++; 365*13695Ssam } 366*13695Ssam 367*13695Ssam fclose(fpc); 368*13695Ssam if (cflag) { 369*13695Ssam gename(CMDPRE, xsys, Grade, cfile); 370*13695Ssam /* rti!trt: use xmv() rather than link(II) */ 371*13695Ssam xmv(tcfile, cfile); 372*13695Ssam if (startjob) 373*13695Ssam xuucico(xsys); 374*13695Ssam cleanup(0); 375*13695Ssam } 376*13695Ssam else 377*13695Ssam unlink(subfile(tcfile)); 378*13695Ssam } 379*13695Ssam 380*13695Ssam #define FTABSIZE 30 381*13695Ssam char Fname[FTABSIZE][NAMESIZE]; 382*13695Ssam int Fnamect = 0; 383*13695Ssam 384*13695Ssam /*** 385*13695Ssam * cleanup - cleanup and unlink if error 386*13695Ssam * 387*13695Ssam * return - none - do exit() 388*13695Ssam */ 389*13695Ssam 390*13695Ssam cleanup(code) 391*13695Ssam int code; 392*13695Ssam { 393*13695Ssam int i; 394*13695Ssam 395*13695Ssam logcls(); 396*13695Ssam rmlock(CNULL); 397*13695Ssam if (code) { 398*13695Ssam for (i = 0; i < Fnamect; i++) 399*13695Ssam unlink(subfile(Fname[i])); 400*13695Ssam fprintf(stderr, "uux failed. code %d\n", code); 401*13695Ssam } 402*13695Ssam DEBUG(1, "exit code %d\n", code); 403*13695Ssam exit(code); 404*13695Ssam } 405*13695Ssam 406*13695Ssam /*** 407*13695Ssam * ufopen - open file and record name 408*13695Ssam * 409*13695Ssam * return file pointer. 410*13695Ssam */ 411*13695Ssam 412*13695Ssam FILE *ufopen(file, mode) 413*13695Ssam char *file, *mode; 414*13695Ssam { 415*13695Ssam if (Fnamect < FTABSIZE) 416*13695Ssam strcpy(Fname[Fnamect++], file); 417*13695Ssam else 418*13695Ssam logent("Fname", "TABLE OVERFLOW"); 419*13695Ssam return(fopen(subfile(file), mode)); 420*13695Ssam } 421