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