|
|
1.1 ! root 1: /* uucp.c ! 2: Prepare to copy a file to or from a remote system. ! 3: ! 4: Copyright (C) 1991, 1992 Ian Lance Taylor ! 5: ! 6: This file is part of the Taylor UUCP package. ! 7: ! 8: This program is free software; you can redistribute it and/or ! 9: modify it under the terms of the GNU General Public License as ! 10: published by the Free Software Foundation; either version 2 of the ! 11: License, or (at your option) any later version. ! 12: ! 13: This program is distributed in the hope that it will be useful, but ! 14: WITHOUT ANY WARRANTY; without even the implied warranty of ! 15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 16: General Public License for more details. ! 17: ! 18: You should have received a copy of the GNU General Public License ! 19: along with this program; if not, write to the Free Software ! 20: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ! 21: ! 22: The author of the program may be contacted at [email protected] or ! 23: c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254. ! 24: */ ! 25: ! 26: #include "uucp.h" ! 27: ! 28: #if USE_RCS_ID ! 29: const char uucp_rcsid[] = "$Id: uucp.c,v 1.1 93/07/30 07:58:25 bin Exp Locker: bin $"; ! 30: #endif ! 31: ! 32: #include <ctype.h> ! 33: #include <errno.h> ! 34: ! 35: #include "getopt.h" ! 36: ! 37: #include "uudefs.h" ! 38: #include "uuconf.h" ! 39: #include "system.h" ! 40: ! 41: /* Local functions. */ ! 42: ! 43: static void ucusage P((void)); ! 44: static void ucdirfile P((const char *zdir, const char *zfile, ! 45: pointer pinfo)); ! 46: static void uccopy P((const char *zfile, const char *zdest)); ! 47: static void ucadd_cmd P((const struct uuconf_system *qsys, ! 48: const struct scmd *qcmd, const char *zlog)); ! 49: static void ucspool_cmds P((boolean fjobid)); ! 50: static const char *zcone_system P((boolean *pfany)); ! 51: static void ucrecord_file P((const char *zfile)); ! 52: static void ucabort P((void)); ! 53: ! 54: /* The program name. */ ! 55: char abProgram[] = "uucp"; ! 56: ! 57: /* Long getopt options. */ ! 58: static const struct option asClongopts[] = { { NULL, 0, NULL, 0 } }; ! 59: ! 60: /* Local variables. There are a bunch of these, mostly set by the ! 61: options and the last (the destination) argument. These have file ! 62: scope so that they may be easily passed into uccopy; they could for ! 63: the most part also be wrapped up in a structure and passed in. */ ! 64: ! 65: /* The uuconf global pointer. */ ! 66: static pointer pCuuconf; ! 67: ! 68: /* TRUE if source files should be copied to the spool directory. */ ! 69: static boolean fCcopy = TRUE; ! 70: ! 71: /* Grade to use. */ ! 72: static char bCgrade = BDEFAULT_UUCP_GRADE; ! 73: ! 74: /* Whether to send mail to the requesting user when the copy is ! 75: complete. */ ! 76: static boolean fCmail = FALSE; ! 77: ! 78: /* User to notify on remote system. */ ! 79: static const char *zCnotify = ""; ! 80: ! 81: /* TRUE if remote files should be prefixed with the current working ! 82: directory. */ ! 83: static boolean fCexpand = TRUE; ! 84: ! 85: /* TRUE if necessary directories should be created on the destination ! 86: system. */ ! 87: static boolean fCmkdirs = TRUE; ! 88: ! 89: /* Local name. */ ! 90: static const char *zClocalname; ! 91: ! 92: /* User name. */ ! 93: static const char *zCuser = NULL; ! 94: ! 95: /* TRUE if this is a remote request. */ ! 96: static boolean fCremote = FALSE; ! 97: ! 98: /* TRUE if the destination is this system. */ ! 99: static boolean fClocaldest; ! 100: ! 101: /* Destination system. */ ! 102: static struct uuconf_system sCdestsys; ! 103: ! 104: /* Systems to forward to, if not NULL. */ ! 105: static char *zCforward; ! 106: ! 107: /* Options to use when sending a file. */ ! 108: static char abCsend_options[20]; ! 109: ! 110: /* Options to use when receiving a file. */ ! 111: static char abCrec_options[20]; ! 112: ! 113: /* TRUE if the current file being copied from is in the cwd. */ ! 114: static boolean fCneeds_cwd; ! 115: ! 116: /* The main program. */ ! 117: ! 118: int ! 119: main (argc, argv) ! 120: int argc; ! 121: char **argv; ! 122: { ! 123: /* -I: configuration file name. */ ! 124: const char *zconfig = NULL; ! 125: /* -j: output job id. */ ! 126: boolean fjobid = FALSE; ! 127: /* -r: don't start uucico when finished. */ ! 128: boolean fuucico = TRUE; ! 129: /* -R: copy directories recursively. */ ! 130: boolean frecursive = FALSE; ! 131: /* -s: report status to named file. */ ! 132: const char *zstatus_file = NULL; ! 133: /* -t: emulate uuto. */ ! 134: boolean fuuto = FALSE; ! 135: int iopt; ! 136: pointer puuconf; ! 137: int iuuconf; ! 138: int i; ! 139: boolean fgetcwd; ! 140: char *zexclam; ! 141: char *zdestfile; ! 142: const char *zdestsys; ! 143: char *zoptions; ! 144: boolean fexit; ! 145: ! 146: while ((iopt = getopt_long (argc, argv, "cCdfg:I:jmn:prRs:tu:Wx:", ! 147: asClongopts, (int *) NULL)) != EOF) ! 148: { ! 149: switch (iopt) ! 150: { ! 151: case 'c': ! 152: /* Do not copy local files to spool directory. */ ! 153: fCcopy = FALSE; ! 154: break; ! 155: ! 156: case 'p': ! 157: case 'C': ! 158: /* Copy local files to spool directory. */ ! 159: fCcopy = TRUE; ! 160: break; ! 161: ! 162: case 'd': ! 163: /* Create directories if necessary. */ ! 164: fCmkdirs = TRUE; ! 165: break; ! 166: ! 167: case 'f': ! 168: /* Do not create directories if they don't exist. */ ! 169: fCmkdirs = FALSE; ! 170: break; ! 171: ! 172: case 'g': ! 173: /* Set job grade. */ ! 174: bCgrade = optarg[0]; ! 175: break; ! 176: ! 177: case 'I': ! 178: /* Name configuration file. */ ! 179: if (fsysdep_other_config (optarg)) ! 180: zconfig = optarg; ! 181: break; ! 182: ! 183: case 'j': ! 184: /* Output job id. */ ! 185: fjobid = TRUE; ! 186: break; ! 187: ! 188: case 'm': ! 189: /* Mail to requesting user. */ ! 190: fCmail = TRUE; ! 191: break; ! 192: ! 193: case 'n': ! 194: /* Notify remote user. */ ! 195: zCnotify = optarg; ! 196: break; ! 197: ! 198: case 'r': ! 199: /* Don't start uucico when finished. */ ! 200: fuucico = FALSE; ! 201: break; ! 202: ! 203: case 'R': ! 204: /* Copy directories recursively. */ ! 205: frecursive = TRUE; ! 206: break; ! 207: ! 208: case 's': ! 209: /* Report status to named file. */ ! 210: zstatus_file = optarg; ! 211: break; ! 212: ! 213: case 't': ! 214: /* Emulate uuto. */ ! 215: fuuto = TRUE; ! 216: break; ! 217: ! 218: case 'u': ! 219: /* Set user name. */ ! 220: zCuser = optarg; ! 221: break; ! 222: ! 223: case 'W': ! 224: /* Expand only local file names. */ ! 225: fCexpand = FALSE; ! 226: break; ! 227: ! 228: case 'x': ! 229: #if DEBUG > 1 ! 230: /* Set debugging level. */ ! 231: iDebug |= idebug_parse (optarg); ! 232: #endif ! 233: break; ! 234: ! 235: case 0: ! 236: /* Long option found and flag set. */ ! 237: break; ! 238: ! 239: default: ! 240: ucusage (); ! 241: break; ! 242: } ! 243: } ! 244: ! 245: if (! UUCONF_GRADE_LEGAL (bCgrade)) ! 246: { ! 247: ulog (LOG_ERROR, "Ignoring illegal grade"); ! 248: bCgrade = BDEFAULT_UUCP_GRADE; ! 249: } ! 250: ! 251: /* The user name must contain a '!', which is treated as a remote ! 252: name, to avoid spoofing of other users (there is no advantage to ! 253: spoofing remote users, except to send them random bits of mail, ! 254: which you can do anyhow). */ ! 255: if (zCuser != NULL) ! 256: { ! 257: if (strchr (zCuser, '!') != NULL) ! 258: fCremote = TRUE; ! 259: else ! 260: { ! 261: ulog (LOG_ERROR, "Ignoring local user name"); ! 262: zCuser = NULL; ! 263: } ! 264: } ! 265: ! 266: if (argc - optind < 2) ! 267: ucusage (); ! 268: ! 269: iuuconf = uuconf_init (&puuconf, (const char *) NULL, zconfig); ! 270: if (iuuconf != UUCONF_SUCCESS) ! 271: ulog_uuconf (LOG_FATAL, puuconf, iuuconf); ! 272: pCuuconf = puuconf; ! 273: ! 274: #if DEBUG > 1 ! 275: { ! 276: const char *zdebug; ! 277: ! 278: iuuconf = uuconf_debuglevel (puuconf, &zdebug); ! 279: if (iuuconf != UUCONF_SUCCESS) ! 280: ulog_uuconf (LOG_FATAL, puuconf, iuuconf); ! 281: if (zdebug != NULL) ! 282: iDebug |= idebug_parse (zdebug); ! 283: } ! 284: #endif ! 285: ! 286: /* See if we are going to need to know the current directory. We ! 287: just check each argument to see whether it's an absolute ! 288: pathname. We actually aren't going to need the cwd if fCexpand ! 289: is FALSE and the file is remote, but so what. */ ! 290: fgetcwd = FALSE; ! 291: for (i = optind; i < argc; i++) ! 292: { ! 293: zexclam = strrchr (argv[i], '!'); ! 294: if (zexclam == NULL) ! 295: zexclam = argv[i]; ! 296: else ! 297: ++zexclam; ! 298: if (fsysdep_needs_cwd (zexclam)) ! 299: { ! 300: fgetcwd = TRUE; ! 301: break; ! 302: } ! 303: } ! 304: ! 305: #ifdef SIGINT ! 306: usysdep_signal (SIGINT); ! 307: #endif ! 308: #ifdef SIGHUP ! 309: usysdep_signal (SIGHUP); ! 310: #endif ! 311: #ifdef SIGQUIT ! 312: usysdep_signal (SIGQUIT); ! 313: #endif ! 314: #ifdef SIGTERM ! 315: usysdep_signal (SIGTERM); ! 316: #endif ! 317: #ifdef SIGPIPE ! 318: usysdep_signal (SIGPIPE); ! 319: #endif ! 320: ! 321: usysdep_initialize (puuconf, INIT_SUID | (fgetcwd ? INIT_GETCWD : 0)); ! 322: ! 323: ulog_fatal_fn (ucabort); ! 324: ! 325: if (zCuser == NULL) ! 326: zCuser = zsysdep_login_name (); ! 327: ! 328: iuuconf = uuconf_localname (puuconf, &zClocalname); ! 329: if (iuuconf == UUCONF_NOT_FOUND) ! 330: { ! 331: zClocalname = zsysdep_localname (); ! 332: if (zClocalname == NULL) ! 333: exit (EXIT_FAILURE); ! 334: } ! 335: else if (iuuconf != UUCONF_SUCCESS) ! 336: ulog_uuconf (LOG_FATAL, puuconf, iuuconf); ! 337: ! 338: /* If we are emulating uuto, translate the destination argument, and ! 339: notify the destination user. This had better not turn into ! 340: something that requires the current directory, or we may have ! 341: passed INIT_GETCWD incorrectly. */ ! 342: if (fuuto) ! 343: { ! 344: if (*zCnotify == '\0') ! 345: { ! 346: zexclam = strrchr (argv[argc - 1], '!'); ! 347: if (zexclam == NULL) ! 348: ucusage (); ! 349: zCnotify = zexclam + 1; ! 350: } ! 351: argv[argc - 1] = zsysdep_uuto (argv[argc - 1], zClocalname); ! 352: if (argv[argc - 1] == NULL) ! 353: ucusage (); ! 354: } ! 355: ! 356: /* Set up the file transfer options. */ ! 357: zoptions = abCsend_options; ! 358: if (fCcopy) ! 359: *zoptions++ = 'C'; ! 360: else ! 361: *zoptions++ = 'c'; ! 362: if (fCmkdirs) ! 363: *zoptions++ = 'd'; ! 364: else ! 365: *zoptions++ = 'f'; ! 366: if (fCmail) ! 367: *zoptions++ = 'm'; ! 368: if (*zCnotify != '\0') ! 369: *zoptions++ = 'n'; ! 370: *zoptions = '\0'; ! 371: ! 372: zoptions = abCrec_options; ! 373: if (fCmkdirs) ! 374: *zoptions++ = 'd'; ! 375: else ! 376: *zoptions++ = 'f'; ! 377: if (fCmail) ! 378: *zoptions++ = 'm'; ! 379: *zoptions = '\0'; ! 380: ! 381: zexclam = strchr (argv[argc - 1], '!'); ! 382: if (zexclam == NULL) ! 383: { ! 384: zdestsys = zClocalname; ! 385: zdestfile = argv[argc - 1]; ! 386: fClocaldest = TRUE; ! 387: } ! 388: else ! 389: { ! 390: size_t clen; ! 391: char *zcopy; ! 392: ! 393: clen = zexclam - argv[argc - 1]; ! 394: zcopy = zbufalc (clen + 1); ! 395: memcpy (zcopy, argv[argc - 1], clen); ! 396: zcopy[clen] = '\0'; ! 397: zdestsys = zcopy; ! 398: ! 399: zdestfile = zexclam + 1; ! 400: ! 401: fClocaldest = FALSE; ! 402: } ! 403: ! 404: iuuconf = uuconf_system_info (puuconf, zdestsys, &sCdestsys); ! 405: if (iuuconf != UUCONF_SUCCESS) ! 406: { ! 407: if (iuuconf != UUCONF_NOT_FOUND) ! 408: ulog_uuconf (LOG_FATAL, puuconf, iuuconf); ! 409: if (fClocaldest) ! 410: { ! 411: iuuconf = uuconf_system_local (puuconf, &sCdestsys); ! 412: if (iuuconf != UUCONF_SUCCESS) ! 413: ulog_uuconf (LOG_FATAL, puuconf, iuuconf); ! 414: sCdestsys.uuconf_zname = (char *) zClocalname; ! 415: } ! 416: else ! 417: { ! 418: if (! funknown_system (puuconf, zdestsys, &sCdestsys)) ! 419: ulog (LOG_FATAL, "%s: System not found", zdestsys); ! 420: } ! 421: } ! 422: ! 423: /* Here zdestfile is the destination file name following the ! 424: destination system name (if any); it may contain other systems to ! 425: forward the files through. Isolate the file from the list of ! 426: systems. */ ! 427: zexclam = strrchr (zdestfile, '!'); ! 428: if (zexclam == NULL) ! 429: zCforward = NULL; ! 430: else ! 431: { ! 432: size_t clen; ! 433: ! 434: #if DEBUG > 0 ! 435: if (fClocaldest) ! 436: ulog (LOG_FATAL, "Can't happen"); ! 437: #endif ! 438: clen = zexclam - zdestfile; ! 439: zCforward = zbufalc (clen + 1); ! 440: memcpy (zCforward, zdestfile, clen); ! 441: zCforward[clen] = '\0'; ! 442: zdestfile = zexclam + 1; ! 443: } ! 444: ! 445: /* Turn the destination into an absolute path, unless it is on a ! 446: remote system and -W was used. */ ! 447: if (fClocaldest) ! 448: zdestfile = zsysdep_local_file_cwd (zdestfile, sCdestsys.uuconf_zpubdir); ! 449: else if (fCexpand) ! 450: zdestfile = zsysdep_add_cwd (zdestfile); ! 451: if (zdestfile == NULL) ! 452: { ! 453: ulog_close (); ! 454: usysdep_exit (FALSE); ! 455: } ! 456: ! 457: /* Process each source argument. */ ! 458: for (i = optind; i < argc - 1 && ! FGOT_SIGNAL (); i++) ! 459: { ! 460: boolean flocal; ! 461: char *zfrom; ! 462: ! 463: fCneeds_cwd = FALSE; ! 464: ! 465: if (strchr (argv[i], '!') != NULL) ! 466: { ! 467: flocal = FALSE; ! 468: zfrom = zbufcpy (argv[i]); ! 469: } ! 470: else ! 471: { ! 472: /* This is a local file. Make sure we get it out of the ! 473: original directory. We don't support local wildcards, ! 474: leaving that to the shell. */ ! 475: flocal = TRUE; ! 476: if (fsysdep_needs_cwd (argv[i])) ! 477: fCneeds_cwd = TRUE; ! 478: zfrom = zsysdep_local_file_cwd (argv[i], ! 479: sCdestsys.uuconf_zpubdir); ! 480: if (zfrom == NULL) ! 481: ucabort (); ! 482: } ! 483: ! 484: if (! flocal || ! fsysdep_directory (zfrom)) ! 485: uccopy (zfrom, zdestfile); ! 486: else ! 487: { ! 488: char *zbase, *zindir; ! 489: ! 490: if (! frecursive) ! 491: ulog (LOG_FATAL, "%s: directory without -R", zfrom); ! 492: ! 493: zbase = zsysdep_base_name (zfrom); ! 494: if (zbase == NULL) ! 495: ucabort (); ! 496: zindir = zsysdep_in_dir (zdestfile, zbase); ! 497: ubuffree (zbase); ! 498: if (zindir == NULL) ! 499: ucabort (); ! 500: usysdep_walk_tree (zfrom, ucdirfile, zindir); ! 501: ubuffree (zindir); ! 502: } ! 503: ! 504: ubuffree (zfrom); ! 505: } ! 506: ! 507: /* See if we got an interrupt, presumably from the user. */ ! 508: if (FGOT_SIGNAL ()) ! 509: ucabort (); ! 510: ! 511: /* Now push out the actual commands, making log entries for them. */ ! 512: ulog_to_file (puuconf, TRUE); ! 513: ulog_user (zCuser); ! 514: ! 515: ucspool_cmds (fjobid); ! 516: ! 517: ulog_close (); ! 518: ! 519: if (! fuucico) ! 520: fexit = TRUE; ! 521: else ! 522: { ! 523: const char *zsys; ! 524: boolean fany; ! 525: ! 526: zsys = zcone_system (&fany); ! 527: if (zsys != NULL) ! 528: fexit = fsysdep_run ("uucico", "-s", zsys); ! 529: else if (fany) ! 530: fexit = fsysdep_run ("uucico", "-r1", (const char *) NULL); ! 531: else ! 532: fexit = TRUE; ! 533: } ! 534: ! 535: usysdep_exit (fexit); ! 536: ! 537: /* Avoid error about not returning. */ ! 538: return 0; ! 539: } ! 540: ! 541: static void ! 542: ucusage () ! 543: { ! 544: fprintf (stderr, ! 545: "Taylor UUCP version %s, copyright (C) 1991, 1992 Ian Lance Taylor\n", ! 546: VERSION); ! 547: fprintf (stderr, ! 548: "Usage: uucp [options] file1 [file2 ...] dest\n"); ! 549: fprintf (stderr, ! 550: " -c: Do not copy local files to spool directory\n"); ! 551: fprintf (stderr, ! 552: " -C, -p: Copy local files to spool directory (default)\n"); ! 553: fprintf (stderr, ! 554: " -d: Create necessary directories (default)\n"); ! 555: fprintf (stderr, ! 556: " -f: Do not create directories (fail if they do not exist)\n"); ! 557: fprintf (stderr, ! 558: " -g grade: Set job grade (must be alphabetic)\n"); ! 559: fprintf (stderr, ! 560: " -m: Report status of copy by mail\n"); ! 561: fprintf (stderr, ! 562: " -n user: Report status of copy by mail to remote user\n"); ! 563: fprintf (stderr, ! 564: " -R: Copy directories recursively\n"); ! 565: fprintf (stderr, ! 566: " -r: Do not start uucico daemon\n"); ! 567: fprintf (stderr, ! 568: " -s file: Report completion status to file\n"); ! 569: fprintf (stderr, ! 570: " -j: Report job id\n"); ! 571: fprintf (stderr, ! 572: " -W: Do not add current directory to remote filenames\n"); ! 573: fprintf (stderr, ! 574: " -t: Emulate uuto\n"); ! 575: fprintf (stderr, ! 576: " -u name: Set user name\n"); ! 577: fprintf (stderr, ! 578: " -x debug: Set debugging level\n"); ! 579: #if HAVE_TAYLOR_CONFIG ! 580: fprintf (stderr, ! 581: " -I file: Set configuration file to use\n"); ! 582: #endif /* HAVE_TAYLOR_CONFIG */ ! 583: exit (EXIT_FAILURE); ! 584: } ! 585: ! 586: /* This is called for each file in a directory heirarchy. */ ! 587: ! 588: static void ! 589: ucdirfile (zfull, zrelative, pinfo) ! 590: const char *zfull; ! 591: const char *zrelative; ! 592: pointer pinfo; ! 593: { ! 594: const char *zdestfile = (const char *) pinfo; ! 595: char *zto; ! 596: ! 597: zto = zsysdep_in_dir (zdestfile, zrelative); ! 598: if (zto == NULL) ! 599: ucabort (); ! 600: ! 601: uccopy (zfull, zto); ! 602: ! 603: ubuffree (zto); ! 604: } ! 605: ! 606: /* Handle the copying of one regular file. The zdest argument is the ! 607: destination file; if we are recursively copying a directory, it ! 608: will be extended by any subdirectory names. Note that zdest is an ! 609: absolute path. */ ! 610: ! 611: static void ! 612: uccopy (zfile, zdest) ! 613: const char *zfile; ! 614: const char *zdest; ! 615: { ! 616: struct scmd s; ! 617: char *zexclam; ! 618: char *zto; ! 619: ! 620: zexclam = strchr (zfile, '!'); ! 621: ! 622: if (zexclam == NULL) ! 623: { ! 624: openfile_t efrom; ! 625: ! 626: /* Copy from a local file. Make sure the user has access to ! 627: this file, since we are running setuid. */ ! 628: if (! fsysdep_access (zfile)) ! 629: ucabort (); ! 630: ! 631: /* If this copy is being requested by a remote system, we may ! 632: transfer the file if it needs the current working directory ! 633: (meaning, I hope, that it is in the execution directory) or ! 634: it is on the permitted transfer list. Note that unlike most ! 635: of the other checks, this one is not double-checked by ! 636: uucico. */ ! 637: if (fCremote ! 638: && ! fCneeds_cwd ! 639: && ! fin_directory_list (zfile, sCdestsys.uuconf_pzremote_send, ! 640: sCdestsys.uuconf_zpubdir, TRUE, ! 641: TRUE, (const char *) NULL)) ! 642: ulog (LOG_FATAL, "Not permitted to send %s", zfile); ! 643: ! 644: if (fClocaldest) ! 645: { ! 646: boolean fok; ! 647: ! 648: /* Copy one local file to another. */ ! 649: ! 650: /* Check that we have permission to receive into the desired ! 651: directory. */ ! 652: if (fCremote) ! 653: fok = fin_directory_list (zdest, ! 654: sCdestsys.uuconf_pzremote_receive, ! 655: sCdestsys.uuconf_zpubdir, TRUE, ! 656: FALSE, (const char *) NULL); ! 657: else ! 658: fok = fin_directory_list (zdest, ! 659: sCdestsys.uuconf_pzlocal_receive, ! 660: sCdestsys.uuconf_zpubdir, TRUE, ! 661: FALSE, zCuser); ! 662: if (! fok) ! 663: ulog (LOG_FATAL, "Not permitted to receive to %s", zdest); ! 664: ! 665: zto = zsysdep_add_base (zdest, zfile); ! 666: if (zto == NULL) ! 667: ucabort (); ! 668: ! 669: efrom = esysdep_user_fopen (zfile, TRUE, TRUE); ! 670: if (! ffileisopen (efrom)) ! 671: ucabort (); ! 672: if (! fcopy_open_file (efrom, zto, FALSE, fCmkdirs)) ! 673: ucabort (); ! 674: (void) ffileclose (efrom); ! 675: ubuffree (zto); ! 676: } ! 677: else ! 678: { ! 679: const char *zloc; ! 680: char abtname[CFILE_NAME_LEN]; ! 681: unsigned int imode; ! 682: char *ztemp; ! 683: ! 684: /* Copy a local file to a remote file. We may have to ! 685: copy the local file to the spool directory. */ ! 686: imode = ixsysdep_file_mode (zfile); ! 687: if (imode == 0) ! 688: ucabort (); ! 689: ! 690: zloc = sCdestsys.uuconf_zlocalname; ! 691: if (zloc == NULL) ! 692: zloc = zClocalname; ! 693: ! 694: ztemp = zsysdep_data_file_name (&sCdestsys, zloc, bCgrade, ! 695: FALSE, abtname, (char *) NULL, ! 696: (char *) NULL); ! 697: if (ztemp == NULL) ! 698: ucabort (); ! 699: ! 700: if (! fCcopy) ! 701: { ! 702: /* If we are copying the file, we don't actually use the ! 703: temporary file; we still want to get a name for the ! 704: other system to use as a key for file restart. */ ! 705: ubuffree (ztemp); ! 706: ! 707: /* Make sure the daemon will be permitted to send ! 708: this file. */ ! 709: if (! fsysdep_daemon_access (zfile)) ! 710: ucabort (); ! 711: if (! fin_directory_list (zfile, sCdestsys.uuconf_pzlocal_send, ! 712: sCdestsys.uuconf_zpubdir, TRUE, TRUE, ! 713: (fCremote ! 714: ? (const char *) NULL ! 715: : zCuser))) ! 716: ulog (LOG_FATAL, "Not permitted to send %s", zfile); ! 717: } ! 718: else ! 719: { ! 720: efrom = esysdep_user_fopen (zfile, TRUE, TRUE); ! 721: if (! ffileisopen (efrom)) ! 722: ucabort (); ! 723: ucrecord_file (ztemp); ! 724: if (! fcopy_open_file (efrom, ztemp, FALSE, TRUE)) ! 725: ucabort (); ! 726: (void) ffileclose (efrom); ! 727: } ! 728: ! 729: if (zCforward == NULL) ! 730: { ! 731: /* We're not forwarding. Just send the file. */ ! 732: s.bcmd = 'S'; ! 733: s.pseq = NULL; ! 734: s.zfrom = zbufcpy (zfile); ! 735: s.zto = zbufcpy (zdest); ! 736: s.zuser = zCuser; ! 737: s.zoptions = abCsend_options; ! 738: s.ztemp = zbufcpy (abtname); ! 739: s.imode = imode; ! 740: s.znotify = zCnotify; ! 741: s.cbytes = -1; ! 742: s.zcmd = NULL; ! 743: s.ipos = 0; ! 744: ! 745: ucadd_cmd (&sCdestsys, &s, (const char *) NULL); ! 746: } ! 747: else ! 748: { ! 749: char *zbase; ! 750: char *zxqt; ! 751: char abxtname[CFILE_NAME_LEN]; ! 752: char abdname[CFILE_NAME_LEN]; ! 753: char abxname[CFILE_NAME_LEN]; ! 754: FILE *e; ! 755: char *zlog; ! 756: ! 757: /* We want to forward this file through sCdestsys to ! 758: some other system(s). We set up a remote execution ! 759: of uucp on sCdestsys to forward the file along. */ ! 760: zbase = zsysdep_base_name (zfile); ! 761: if (zbase == NULL) ! 762: ucabort (); ! 763: ! 764: zxqt = zsysdep_data_file_name (&sCdestsys, zloc, bCgrade, ! 765: TRUE, abxtname, abdname, ! 766: abxname); ! 767: if (zxqt == NULL) ! 768: ucabort (); ! 769: e = esysdep_fopen (zxqt, FALSE, FALSE, TRUE); ! 770: if (e == NULL) ! 771: ucabort (); ! 772: ucrecord_file (zxqt); ! 773: ! 774: fprintf (e, "U %s %s\n", zCuser, zloc); ! 775: fprintf (e, "F %s %s\n", abdname, zbase); ! 776: fprintf (e, "C uucp -C"); ! 777: if (fCmkdirs) ! 778: fprintf (e, " -d"); ! 779: else ! 780: fprintf (e, " -f"); ! 781: fprintf (e, " -g %c", bCgrade); ! 782: if (fCmail) ! 783: fprintf (e, " -m"); ! 784: if (*zCnotify != '\0') ! 785: fprintf (e, " -n %s", zCnotify); ! 786: if (! fCexpand) ! 787: fprintf (e, " -W"); ! 788: fprintf (e, " %s %s!%s\n", zbase, zCforward, zdest); ! 789: ! 790: ubuffree (zbase); ! 791: ! 792: if (fclose (e) != 0) ! 793: ulog (LOG_FATAL, "fclose: %s", strerror (errno)); ! 794: ! 795: /* Send the execution file. */ ! 796: s.bcmd = 'S'; ! 797: s.pseq = NULL; ! 798: s.zfrom = zbufcpy (abxtname); ! 799: s.zto = zbufcpy (abxname); ! 800: s.zuser = zCuser; ! 801: s.zoptions = "C"; ! 802: s.ztemp = s.zfrom; ! 803: s.imode = 0666; ! 804: s.znotify = NULL; ! 805: s.cbytes = -1; ! 806: s.zcmd = NULL; ! 807: s.ipos = 0; ! 808: ! 809: zlog = zbufalc (sizeof "Queuing uucp !" + strlen (zfile) ! 810: + strlen (zCforward) + strlen (zdest)); ! 811: sprintf (zlog, "Queuing uucp %s %s!%s", zfile, zCforward, ! 812: zdest); ! 813: ! 814: ucadd_cmd (&sCdestsys, &s, zlog); ! 815: ! 816: /* Send the data file. */ ! 817: s.bcmd = 'S'; ! 818: s.pseq = NULL; ! 819: s.zfrom = zbufcpy (zfile); ! 820: s.zto = zbufcpy (abdname); ! 821: s.zuser = zCuser; ! 822: s.zoptions = fCcopy ? "C" : "c"; ! 823: s.ztemp = zbufcpy (abtname); ! 824: s.imode = 0666; ! 825: s.znotify = NULL; ! 826: s.cbytes = -1; ! 827: s.zcmd = NULL; ! 828: s.ipos = 0; ! 829: ! 830: ucadd_cmd (&sCdestsys, &s, ""); ! 831: } ! 832: } ! 833: } ! 834: else ! 835: { ! 836: char *zfrom; ! 837: char *zforward; ! 838: size_t clen; ! 839: char *zcopy; ! 840: struct uuconf_system *qfromsys; ! 841: int iuuconf; ! 842: const char *zloc; ! 843: ! 844: /* Copy from a remote file. Get the file name after any systems ! 845: we may need to forward the file from. */ ! 846: zfrom = strrchr (zfile, '!'); ! 847: if (zfrom == zexclam) ! 848: zforward = NULL; ! 849: else ! 850: { ! 851: clen = zfrom - zexclam - 1; ! 852: zforward = zbufalc (clen + 1); ! 853: memcpy (zforward, zexclam + 1, clen); ! 854: } ! 855: ! 856: ++zfrom; ! 857: if (fCexpand) ! 858: { ! 859: /* Add the current directory to the filename if it's not ! 860: already there. */ ! 861: zfrom = zsysdep_add_cwd (zfrom); ! 862: if (zfrom == NULL) ! 863: ucabort (); ! 864: } ! 865: ! 866: /* Read the system information. */ ! 867: clen = zexclam - zfile; ! 868: zcopy = zbufalc (clen + 1); ! 869: memcpy (zcopy, zfile, clen); ! 870: zcopy[clen] = '\0'; ! 871: ! 872: qfromsys = ((struct uuconf_system *) ! 873: xmalloc (sizeof (struct uuconf_system))); ! 874: ! 875: iuuconf = uuconf_system_info (pCuuconf, zcopy, qfromsys); ! 876: if (iuuconf == UUCONF_NOT_FOUND) ! 877: { ! 878: if (! funknown_system (pCuuconf, zcopy, qfromsys)) ! 879: ulog (LOG_FATAL, "%s: System not found", zcopy); ! 880: } ! 881: else if (iuuconf != UUCONF_SUCCESS) ! 882: ulog_uuconf (LOG_FATAL, pCuuconf, iuuconf); ! 883: ubuffree (zcopy); ! 884: ! 885: zloc = qfromsys->uuconf_zlocalname; ! 886: if (zloc == NULL) ! 887: zloc = zClocalname; ! 888: ! 889: if (zforward == NULL && fClocaldest) ! 890: { ! 891: boolean fok; ! 892: ! 893: /* The file is to come directly from qfromsys to the local ! 894: system. */ ! 895: ! 896: /* Check that we have permission to receive into the desired ! 897: directory. If we don't have permission, uucico will ! 898: fail. */ ! 899: if (fCremote) ! 900: fok = fin_directory_list (zdest, ! 901: qfromsys->uuconf_pzremote_receive, ! 902: qfromsys->uuconf_zpubdir, TRUE, ! 903: FALSE, (const char *) NULL); ! 904: else ! 905: fok = fin_directory_list (zdest, ! 906: qfromsys->uuconf_pzlocal_receive, ! 907: qfromsys->uuconf_zpubdir, TRUE, ! 908: FALSE, zCuser); ! 909: if (! fok) ! 910: ulog (LOG_FATAL, "Not permitted to receive to %s", zdest); ! 911: ! 912: /* If the remote filespec is wildcarded, we must generate an ! 913: 'X' request. We currently check for Unix shell ! 914: wildcards. Note that it should do no harm to mistake a ! 915: non-wildcard for a wildcard. */ ! 916: if (zfrom[strcspn (zfrom, "*?[")] != '\0') ! 917: { ! 918: s.bcmd = 'X'; ! 919: zto = zbufalc (strlen (zloc) + strlen (zdest) + sizeof "!"); ! 920: sprintf (zto, "%s!%s", zloc, zdest); ! 921: } ! 922: else ! 923: { ! 924: s.bcmd = 'R'; ! 925: zto = zbufcpy (zdest); ! 926: } ! 927: ! 928: s.pseq = NULL; ! 929: s.zfrom = zfrom; ! 930: s.zto = zto; ! 931: s.zuser = zCuser; ! 932: s.zoptions = abCrec_options; ! 933: s.ztemp = ""; ! 934: s.imode = 0; ! 935: s.znotify = ""; ! 936: s.cbytes = -1; ! 937: s.zcmd = NULL; ! 938: s.ipos = 0; ! 939: ! 940: ucadd_cmd (qfromsys, &s, (const char *) NULL); ! 941: } ! 942: else ! 943: { ! 944: char *zxqt; ! 945: char abtname[CFILE_NAME_LEN]; ! 946: char abxname[CFILE_NAME_LEN]; ! 947: FILE *e; ! 948: char *zcmd; ! 949: char *zlog; ! 950: ! 951: /* The file either comes from some other system through ! 952: qfromsys or is intended for some other system. Send an ! 953: execution request to qfromsys to handle everything. */ ! 954: zxqt = zsysdep_data_file_name (qfromsys, zloc, bCgrade, TRUE, ! 955: abtname, (char *) NULL, ! 956: abxname); ! 957: if (zxqt == NULL) ! 958: ucabort (); ! 959: e = esysdep_fopen (zxqt, FALSE, FALSE, TRUE); ! 960: if (e == NULL) ! 961: ucabort (); ! 962: ucrecord_file (zxqt); ! 963: ! 964: fprintf (e, "U %s %s\n", zCuser, zloc); ! 965: fprintf (e, "C uucp -C"); ! 966: if (fCmkdirs) ! 967: fprintf (e, " -d"); ! 968: else ! 969: fprintf (e, " -f"); ! 970: fprintf (e, " -g %c", bCgrade); ! 971: if (fCmail) ! 972: fprintf (e, " -m"); ! 973: if (*zCnotify != '\0') ! 974: fprintf (e, " -n %s", zCnotify); ! 975: if (! fCexpand) ! 976: fprintf (e, " -W"); ! 977: ! 978: clen = (strlen (zfrom) + strlen (zloc) ! 979: + strlen (sCdestsys.uuconf_zname) + strlen (zdest)); ! 980: if (zforward != NULL) ! 981: clen += strlen (zforward); ! 982: if (zCforward != NULL) ! 983: clen += strlen (zCforward); ! 984: zcmd = zbufalc (sizeof "! !!!" + clen); ! 985: *zcmd = '\0'; ! 986: if (zforward != NULL) ! 987: sprintf (zcmd + strlen (zcmd), "%s!", zforward); ! 988: sprintf (zcmd + strlen (zcmd), "%s %s!", zfrom, zloc); ! 989: if (! fClocaldest) ! 990: sprintf (zcmd + strlen (zcmd), "%s!", sCdestsys.uuconf_zname); ! 991: if (zCforward != NULL) ! 992: sprintf (zcmd + strlen (zcmd), "%s!", zCforward); ! 993: sprintf (zcmd + strlen (zcmd), "%s", zdest); ! 994: ! 995: fprintf (e, " %s\n", zcmd); ! 996: ! 997: if (fclose (e) != 0) ! 998: ulog (LOG_FATAL, "fclose: %s", strerror (errno)); ! 999: ! 1000: /* Send the execution file. */ ! 1001: s.bcmd = 'S'; ! 1002: s.pseq = NULL; ! 1003: s.zfrom = zbufcpy (abtname); ! 1004: s.zto = zbufcpy (abxname); ! 1005: s.zuser = zCuser; ! 1006: s.zoptions = "C"; ! 1007: s.ztemp = s.zfrom; ! 1008: s.imode = 0666; ! 1009: s.znotify = NULL; ! 1010: s.cbytes = -1; ! 1011: s.zcmd = NULL; ! 1012: s.ipos = 0; ! 1013: ! 1014: zlog = zbufalc (sizeof "Queueing uucp " + strlen (zcmd)); ! 1015: sprintf (zlog, "Queueing uucp %s", zcmd); ! 1016: ! 1017: ucadd_cmd (qfromsys, &s, zlog); ! 1018: ! 1019: ubuffree (zcmd); ! 1020: ubuffree (zforward); ! 1021: } ! 1022: } ! 1023: } ! 1024: ! 1025: /* We keep a list of jobs for each system. */ ! 1026: ! 1027: struct sjob ! 1028: { ! 1029: struct sjob *qnext; ! 1030: const struct uuconf_system *qsys; ! 1031: int ccmds; ! 1032: struct scmd *pascmds; ! 1033: const char **pazlogs; ! 1034: }; ! 1035: ! 1036: static struct sjob *qCjobs; ! 1037: ! 1038: static void ! 1039: ucadd_cmd (qsys, qcmd, zlog) ! 1040: const struct uuconf_system *qsys; ! 1041: const struct scmd *qcmd; ! 1042: const char *zlog; ! 1043: { ! 1044: struct sjob *qjob; ! 1045: ! 1046: if (! qsys->uuconf_fcall_transfer ! 1047: && ! qsys->uuconf_fcalled_transfer) ! 1048: ulog (LOG_FATAL, "Not permitted to transfer files to or from %s", ! 1049: qsys->uuconf_zname); ! 1050: ! 1051: for (qjob = qCjobs; qjob != NULL; qjob = qjob->qnext) ! 1052: if (strcmp (qjob->qsys->uuconf_zname, qsys->uuconf_zname) == 0) ! 1053: break; ! 1054: ! 1055: if (qjob == NULL) ! 1056: { ! 1057: qjob = (struct sjob *) xmalloc (sizeof (struct sjob)); ! 1058: qjob->qnext = qCjobs; ! 1059: qjob->qsys = qsys; ! 1060: qjob->ccmds = 0; ! 1061: qjob->pascmds = NULL; ! 1062: qjob->pazlogs = NULL; ! 1063: qCjobs = qjob; ! 1064: } ! 1065: ! 1066: qjob->pascmds = ((struct scmd *) ! 1067: xrealloc ((pointer) qjob->pascmds, ! 1068: (qjob->ccmds + 1) * sizeof (struct scmd))); ! 1069: qjob->pascmds[qjob->ccmds] = *qcmd; ! 1070: qjob->pazlogs = ((const char **) ! 1071: xrealloc ((pointer) qjob->pazlogs, ! 1072: (qjob->ccmds + 1) * sizeof (const char *))); ! 1073: qjob->pazlogs[qjob->ccmds] = zlog; ! 1074: ++qjob->ccmds; ! 1075: } ! 1076: ! 1077: static void ! 1078: ucspool_cmds (fjobid) ! 1079: boolean fjobid; ! 1080: { ! 1081: struct sjob *qjob; ! 1082: char *zjobid; ! 1083: ! 1084: for (qjob = qCjobs; qjob != NULL; qjob = qjob->qnext) ! 1085: { ! 1086: ulog_system (qjob->qsys->uuconf_zname); ! 1087: zjobid = zsysdep_spool_commands (qjob->qsys, bCgrade, qjob->ccmds, ! 1088: qjob->pascmds); ! 1089: if (zjobid != NULL) ! 1090: { ! 1091: int i; ! 1092: struct scmd *qcmd; ! 1093: const char **pz; ! 1094: ! 1095: for (i = 0, qcmd = qjob->pascmds, pz = qjob->pazlogs; ! 1096: i < qjob->ccmds; ! 1097: i++, qcmd++, pz++) ! 1098: { ! 1099: if (*pz != NULL) ! 1100: { ! 1101: if (**pz != '\0') ! 1102: ulog (LOG_NORMAL, "%s", *pz); ! 1103: } ! 1104: else if (qcmd->bcmd == 'S') ! 1105: ulog (LOG_NORMAL, "Queuing send of %s to %s", ! 1106: qcmd->zfrom, qcmd->zto); ! 1107: else if (qcmd->bcmd == 'R') ! 1108: ulog (LOG_NORMAL, "Queuing request of %s to %s", ! 1109: qcmd->zfrom, qcmd->zto); ! 1110: else ! 1111: { ! 1112: const char *zto; ! 1113: ! 1114: zto = strrchr (qcmd->zto, '!'); ! 1115: if (zto != NULL) ! 1116: ++zto; ! 1117: else ! 1118: zto = qcmd->zto; ! 1119: ulog (LOG_NORMAL, "Queuing request of %s to %s", ! 1120: qcmd->zfrom, zto); ! 1121: } ! 1122: } ! 1123: ! 1124: if (fjobid) ! 1125: printf ("%s\n", zjobid); ! 1126: ! 1127: ubuffree (zjobid); ! 1128: } ! 1129: } ! 1130: } ! 1131: ! 1132: /* Return the system name for which we have created commands, or NULL ! 1133: if we've created commands for more than one system. Set *pfany to ! 1134: FALSE if we didn't create work for any system. */ ! 1135: ! 1136: static const char * ! 1137: zcone_system (pfany) ! 1138: boolean *pfany; ! 1139: { ! 1140: if (qCjobs == NULL) ! 1141: { ! 1142: *pfany = FALSE; ! 1143: return NULL; ! 1144: } ! 1145: ! 1146: *pfany = TRUE; ! 1147: ! 1148: if (qCjobs->qnext == NULL) ! 1149: return qCjobs->qsys->uuconf_zname; ! 1150: else ! 1151: return NULL; ! 1152: } ! 1153: ! 1154: /* Keep track of all files we have created so that we can delete them ! 1155: if we get a signal. The argument will be on the heap. */ ! 1156: ! 1157: static int cCfiles; ! 1158: static const char **pCaz; ! 1159: ! 1160: static void ! 1161: ucrecord_file (zfile) ! 1162: const char *zfile; ! 1163: { ! 1164: pCaz = (const char **) xrealloc ((pointer) pCaz, ! 1165: (cCfiles + 1) * sizeof (const char *)); ! 1166: pCaz[cCfiles] = zfile; ! 1167: ++cCfiles; ! 1168: } ! 1169: ! 1170: /* Delete all the files we have recorded and exit. */ ! 1171: ! 1172: static void ! 1173: ucabort () ! 1174: { ! 1175: int i; ! 1176: ! 1177: for (i = 0; i < cCfiles; i++) ! 1178: (void) remove (pCaz[i]); ! 1179: ulog_close (); ! 1180: usysdep_exit (FALSE); ! 1181: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.