home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / uucp / duucp-1.17 / AU-117b4-src.lha / src / uucico / uucp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-29  |  9.7 KB  |  534 lines

  1. /*#define DEBUG*/
  2. /*
  3.  *   UUCP.c originally written by William Loftus
  4.  *
  5.  *   Copyright 1988 by William Loftus.     All rights reserved.
  6.  *   Copyright 1990 by Matthew Dillon.     All rights reserved.
  7.  *   Copyright 1993, 1994 by Michael B. Smith. All rights reserved.
  8.  */
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include "version.h"
  14. #include "protos.h"
  15. #include <owndevunit.h>
  16.  
  17. IDENT (".07");
  18.  
  19. #define ARRAY_SIZE 128
  20.  
  21. #ifdef DEBUG
  22. #define D(x)    printf x
  23. #else
  24. #define D(x)
  25. #endif
  26.  
  27. char
  28.     *config      = NULL, /* -I */
  29.     *name         = NULL,
  30.     *mailuser    = NULL, /* -n */
  31.     path         [ARRAY_SIZE],
  32.     command_file [ARRAY_SIZE],
  33.     data_file    [ARRAY_SIZE];
  34. int
  35.     UseSubDirs = 0,
  36.     prJobid    = 0, /* -j */
  37.     doCopy       = 0, /* -c/-C */
  38.     doCreate   = 1, /* -d/-f */
  39.     noUUCICO   = 1, /* -r is the only way we work */
  40.     mailstat   = 0, /* -m (& -n) */
  41.     seq;
  42. struct Library
  43.     *OwnDevUnitBase = NULL;
  44. static const char
  45.     odu_name [] = { ODU_NAME };
  46.  
  47. void BuildSendFile (const char *cmd, const char *file, const char *grade, const char *user);
  48. void BuildReceiveFile (const char *cmd, const char *file, const char *grade, const char *user);
  49. void myexit (void);
  50. const char *expand_file (const char *file_name);
  51. int Copy (const BPTR fh, const char *to);
  52.  
  53. void
  54. usage (void)
  55. {
  56.     fprintf (stderr, "usage: %s [-g grade] [-u user] from_file to_file\n", name);
  57.     exit (30);
  58. }
  59.  
  60. int
  61. main (int argc, char **argv)
  62. {
  63.     int
  64.         avail,
  65.         i;
  66.     char
  67.         *tmp,
  68.         *grade = "A",
  69.         *user = NULL,
  70.         *from,
  71.         *from_buf,
  72.         *dest,
  73.         *to_buf;
  74.  
  75.     name = argv [0];
  76.  
  77.     if (argc == 0)
  78.         exit (30);
  79.     if (argc < 3)
  80.         usage ();
  81.  
  82.     if (argc > 3) {
  83.         avail = argc - 1;
  84.         for (i = 1; i < argc; i++) {
  85.             tmp = argv [i];
  86.             if (*tmp != '-')
  87.                 break;
  88.             tmp++;
  89.             avail--;
  90.             switch (*tmp) {
  91.                 case 'c':
  92.                     doCopy = 0;
  93.                     D (("set doCopy = 0\n"));
  94.                     break;
  95.  
  96.                 case 'C':
  97.                     doCopy = 1;
  98.                     D (("set doCopy = 1\n"));
  99.                     break;
  100.  
  101.                 case 'd':
  102.                     doCreate = 1;
  103.                     D (("set doCreate = 1\n"));
  104.                     break;
  105.  
  106.                 case 'f':
  107.                     doCreate = 0;
  108.                     D (("set doCreate = 0\n"));
  109.                     break;
  110.  
  111.                 case 'g':
  112.                     tmp++;
  113.                     if (*tmp)
  114.                         grade = tmp;
  115.                     else {
  116.                         avail--;
  117.                         grade = argv [++i];
  118.                     }
  119.  
  120.                     if (strlen (grade) > 1)
  121.                         usage ();
  122.  
  123.                     D (("set grade to '%s'\n", grade));
  124.                     break;
  125.  
  126.                 case 'I':
  127.                     /* FIXME: -I config option */
  128.                     tmp++;
  129.                     if (*tmp)
  130.                         config = tmp;
  131.                     else {
  132.                         avail--;
  133.                         config = argv [++i];
  134.                     }
  135.                     D (("config '%s'\n", config));
  136.                     fprintf (stderr, "Warning: setting '-I %s' is ignored\n", config);
  137.                     break;
  138.  
  139.                 case 'j':
  140.                     prJobid = 1;
  141.                     D (("set prJobid = 1\n"));
  142.                     break;
  143.  
  144.                 case 'm':
  145.                     mailstat = 1;
  146.                     D (("set mailstat = 1\n"));
  147.                     break;
  148.  
  149.                 case 'n':
  150.                     tmp++;
  151.                     if (*tmp)
  152.                         mailuser = tmp;
  153.                     else {
  154.                         avail--;
  155.                         mailuser = argv [++i];
  156.                     }
  157.                     D (("mailuser '%s'\n", mailuser));
  158.                     break;
  159.  
  160.                 case 'r':
  161.                     noUUCICO = 1;
  162.                     D (("set noUUCICO = 1\n"));
  163.                     break;
  164.  
  165.                 case 'u':
  166.                     tmp++;
  167.                     if (*tmp)
  168.                         user = tmp;
  169.                     else {
  170.                         avail--;
  171.                         user = argv [++i];
  172.                     }
  173.  
  174.                     D (("set user to '%s'\n", user));
  175.                     break;
  176.  
  177.                 case 'x':
  178.                     tmp++;
  179.                     if (*tmp)
  180.                         ;
  181.                     else {
  182.                         avail--;
  183.                         tmp = argv [++i];
  184.                     }
  185.                     /* FIXME: -x debug options? */
  186.                     fprintf (stderr, "Warning: setting '-x %s' is ignored\n", tmp);
  187.                     break;
  188.  
  189.                 default:
  190.                     usage ();
  191.             }
  192.         }
  193.  
  194.         if (avail != 2)
  195.             usage ();
  196.     }
  197.  
  198.     from_buf = argv [argc - 2];
  199.     to_buf     = argv [argc - 1];
  200.  
  201.     getcwd (path, ARRAY_SIZE);
  202.     atexit (myexit);
  203.  
  204.     if ((OwnDevUnitBase = OpenLibrary (odu_name, 0)) == NULL) {
  205.         fprintf (stderr, "Unable to open %s\n", odu_name);
  206.         exit (30);
  207.     }
  208.  
  209.     if (safe_chdir (GetConfigDir (UUSPOOL))) {
  210.         fprintf (stderr, "Couldn't change current working directory to %s\n", GetConfigDir (UUSPOOL));
  211.         exit (30);
  212.     }
  213.  
  214.     if (!user)
  215.         user = GetUserName ();
  216.     if (!user) {
  217.         fprintf (stderr, "Can't find USERNAME in UULib:Config\n");
  218.         exit (30);
  219.     }
  220.  
  221.     tmp = GetConfig (USESUBDIRS, "0");
  222.     if (*tmp == 'y' || *tmp == 'Y' || *tmp == '1')
  223.         UseSubDirs = 1;
  224.  
  225.     seq = GetSequence (2);
  226.     if (seq < 0) {
  227.         exit (30);
  228.     }
  229.  
  230.     from = strchr (from_buf, '!');
  231.     dest = strchr (to_buf,     '!');
  232.  
  233.     D (("from_buf '%s'\n", from_buf));
  234.     D (("to_buf   '%s'\n", to_buf));
  235.  
  236.     if (from && dest) {
  237.         fprintf (stderr, "Can't specify a remote system in both arguments.\n");
  238.         exit (30);
  239.     }
  240.     if (from == NULL && dest == NULL) {
  241.         fprintf (stderr, "No remote system specified.\n");
  242.         exit (30);
  243.     }
  244.  
  245.     if (from) {
  246.         BuildReceiveFile (from_buf, to_buf, grade, user);
  247.     }
  248.  
  249.     if (dest) {
  250.         BuildSendFile (to_buf, from_buf, grade, user);
  251.     }
  252.  
  253.     exit (0);
  254. }
  255.  
  256. void
  257. myexit (void)
  258. {
  259.     UnLockFiles ();
  260.  
  261.     if (OwnDevUnitBase) {
  262.         CloseLibrary (OwnDevUnitBase);
  263.         OwnDevUnitBase = NULL;
  264.     }
  265.  
  266.     return;
  267. }
  268.  
  269. char
  270.     system_name [32];
  271.  
  272. char *
  273. set_system_name (const char *buf)
  274. {
  275.     /*
  276.     **  set_system_name
  277.     **
  278.     **    Puts the UUCP name from buf into system_name.
  279.     **    Verifies that the system_name is in UULib:L.Sys
  280.     **
  281.     **    Returns the character after the '!' in buf
  282.     */
  283.     char
  284.         *p,
  285.         *q;
  286.  
  287.     p = buf;
  288.     q = system_name;
  289.  
  290.     while (*p != '!')
  291.         *q++ = *p++;
  292.     *q = '\0';
  293.     D (("system_name '%s'\n", system_name));
  294.  
  295.     if (!is_in_L_sys_file (system_name)) {
  296.         fprintf (stderr, "System \"%s\" not in L.sys file.\n", system_name);
  297.         exit (30);
  298.     }
  299.  
  300.     return ++p;
  301. }
  302.  
  303. FILE *
  304. open_command_file (const char *system_name, const char *grade)
  305. {
  306.     FILE
  307.         *fp;
  308.     BPTR
  309.         lock;
  310.     char
  311.         *ptr;
  312.  
  313.     if (UseSubDirs && (lock = Lock ((UBYTE *) system_name, ACCESS_READ))) {
  314.         UnLock (lock);
  315.         strcpy (command_file, system_name);
  316.         strcat (command_file, "/");
  317.         ptr = command_file + strlen (command_file);
  318.     }
  319.     else {
  320.         ptr = command_file;
  321.         *ptr = '\0';
  322.     }
  323.  
  324.     strcpy (data_file, ptr);
  325.  
  326.     sprintf (ptr, "C.%.7s%s%s", system_name, grade, SeqToName (seq));
  327.     D (("command file name '%s'\n", command_file));
  328.  
  329.     /* I may never use data_file, but lets prepare it for use, anyway */
  330.     sprintf (data_file + strlen (data_file), "D.%.7sB%s", system_name, SeqToName (seq));
  331.  
  332.     LockFile (command_file);
  333.     LockFile (data_file);
  334.  
  335.     fp = fopen (command_file, "w");
  336.     if (!fp) {
  337.         perror (command_file);
  338.         UnLockFile (data_file);
  339.         UnLockFile (command_file);
  340.         exit (30);
  341.     }
  342.  
  343.     if (prJobid)
  344.         printf ("job %s\n", ptr + 2);
  345.  
  346.     return fp;
  347. }
  348.  
  349. void
  350. BuildSendFile (const char *cmd, const char *file,
  351.            const char *grade, const char *user)
  352. {
  353.     BPTR
  354.         fh;
  355.     FILE
  356.         *fp;
  357.     char
  358.         *empty = "",
  359.         *which_file,
  360.         *ex_file,
  361.         *p,
  362.         options [7];
  363.  
  364.     D (("BuildSendFile: cmd '%s', grade '%s', user '%s'\n",
  365.         cmd, grade, user));
  366.  
  367.     ex_file = expand_file (file);
  368.     if (!(fh = Lock (ex_file, ACCESS_READ))) {
  369.         fprintf (stderr, "Local file does not exist '%s'\n", ex_file);
  370.         exit (30);
  371.     }
  372.     UnLock (fh);
  373.  
  374.     p = set_system_name (cmd);
  375.  
  376.     fp = open_command_file (system_name, grade);
  377.  
  378.     fh = Open (ex_file, MODE_OLDFILE);
  379.     if (!fh) {
  380.         fprintf (stderr, "Your system is screwy '%s'\n", ex_file);
  381.         exit (30);
  382.     }
  383.     if (doCopy && (Copy (fh, data_file) < 0)) {
  384.         Close (fh);
  385.         fprintf (stderr, "Local copy failed\n");
  386.         exit (30);
  387.     }
  388.     Close (fh);
  389.  
  390.     sprintf (options, "-%s%s%s%s",
  391.         doCopy     ? "C" : "c",
  392.         doCreate ? "d" : "f",
  393.         mailstat ? "m" : "",
  394.         mailuser ? "n" : ""
  395.     );
  396.  
  397.     /* srcnam destnam who flags temp mode who */
  398.     if (doCopy)
  399.         which_file = data_file;
  400.     else
  401.         which_file = ex_file;
  402.  
  403.     fprintf (fp, "S %s %s %s %s %s %s %s\n",
  404.         /*
  405.         **  FROM - what file was the original
  406.         **  TO     - name of destination file
  407.         **  USER - name of user who requested transfer
  408.         **  OPTS - options for transfer
  409.         **  TEMP - if opt C then file to copy from, else if c then FROM
  410.         **       (TEMP is deleted after transfer if C)
  411.         **  MODE - Unix executable mode. Forced to 0666
  412.         **  NOTI - if opt n, then the mailaddress to send notification
  413.         **       to about the transfer.
  414.         */
  415.         which_file, p, user, options, which_file, "0666",
  416.         mailuser ? mailuser : user
  417.     );
  418.  
  419.     fclose (fp);
  420.     UnLockFile (data_file);
  421.     UnLockFile (command_file);
  422.  
  423.     printf ("Command queued for transfer to %s.\n", system_name);
  424.  
  425.     return;
  426. }
  427.  
  428. void
  429. BuildReceiveFile (const char *cmd, const char *file,
  430.           const char *grade, const char *user)
  431. {
  432.     FILE
  433.         *fp;
  434.     char
  435.         *ex_file,
  436.         *p,
  437.         options [6];
  438.  
  439.  
  440.     D (("BuildReceiveFile: cmd '%s', grade '%s', user '%s'\n",
  441.         cmd, grade, user));
  442.  
  443.     ex_file = expand_file (file);
  444.     p = set_system_name (cmd);
  445.  
  446.     fp = open_command_file (system_name, grade);
  447.  
  448.     /*
  449.     **  FROM - name of file to be sent to us
  450.     **  TO     - what the file will be called here
  451.     **  USER - name of the user requesting the transfer
  452.     **  OPTS - d - create directories
  453.     **       f - fail if directories not present
  454.     **       m - send mail to USER when transfer complete
  455.     **       c - damned if I know. left for historical reasons.
  456.     */
  457.     sprintf (options, "-c%s%s",
  458.         doCreate ? "d" : "f",
  459.         (mailuser || mailstat) ? "m" : ""
  460.     );
  461.  
  462.     /* srcnam destnam who flags */
  463.     fprintf (fp, "R %s %s %s %s\n",
  464.         p,
  465.         ex_file,
  466.         mailuser ? mailuser : user,
  467.         options
  468.     );
  469.  
  470.     fclose (fp);
  471.     UnLockFile (data_file);
  472.     UnLockFile (command_file);
  473.  
  474.     printf ("Command queued for transfer from %s.\n", system_name);
  475.  
  476.     return;
  477. }
  478.  
  479. const char *
  480. expand_file (const char *file_name)
  481. {
  482.     char
  483.         *colon;
  484.     static char
  485.         name [ARRAY_SIZE];
  486.  
  487.     colon = strchr (file_name, ':');
  488.     if (colon && (colon != file_name)) {
  489.         D (("expand_file result1 '%s'\n", file_name));
  490.  
  491.         return file_name;
  492.     }
  493.  
  494.     if (path [strlen (path) - 1] != ':') {
  495.         sprintf (name, "%s/%s", path, file_name);
  496.         D (("expand_file result2 '%s'\n", name));
  497.  
  498.         return name;
  499.     }
  500.  
  501.     sprintf (name, "%s%s", path, file_name);
  502.     D (("expand_file result3 '%s'\n", name));
  503.  
  504.     return name;
  505. }
  506.  
  507. int
  508. Copy (const BPTR fh, const char *to)
  509. {
  510.     BPTR
  511.         fo;
  512.     int
  513.         len;
  514.     static char
  515.         to_buf [2048];
  516.  
  517.     DeleteFile (to);
  518.     fo = Open (to, MODE_NEWFILE);
  519.     if (!fo) {
  520.         fprintf (stderr, "Cannot open '%s' (error %ld)\n", to, IoErr ());
  521.         return -1;
  522.     }
  523.  
  524.     Seek (fh, 0, OFFSET_BEGINNING);
  525.  
  526.     while ((len = Read (fh, to_buf, sizeof (to_buf))) > 0) {
  527.         Write (fo, to_buf, len);
  528.     }
  529.  
  530.     Close (fo);
  531.  
  532.     return 1;
  533. }
  534.