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