Annotation of coherent/g/usr/lib/uucp/tay104/uucp.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.