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