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

  1. /*#define PROCDEBUG*/
  2. /*
  3.  *  UUX.C
  4.  *
  5.  *  Copyright 1988 by William Loftus.    All rights reserved.
  6.  *  Copyright 1993 by Michael B. Smith. All rights reserved.
  7.  *
  8.  *  Example: uux mail-message "burdvax!rmail wpl"
  9.  *
  10.  *  NOTE:   UUX uses C.<host>N<seqno> instead of C.<host>A<seqno> to ensure
  11.  *        UUX transfers occur *after* any email
  12.  *
  13.  *  NOTE:   The DEFAULT grade is 'N'. The user may set it to whatever they wish.
  14.  *
  15.  *        The DEFAULT user is from "UserName" in UULib:Config. The user may
  16.  *        set it to whatever they wish.
  17.  *
  18.  *        The DEFAULT is to copy the file. Setting -c causes this not to
  19.  *        be done.
  20.  */
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <fcntl.h>
  26. #include "version.h"
  27. #include "protos.h"
  28. #include "owndevunit.h"
  29.  
  30. IDENT (".11");
  31.  
  32. #define ARRAY_SIZE  128
  33.  
  34. #ifdef PROCDEBUG
  35. #define D(x)        printf x
  36. #else
  37. #define D(x)
  38. #endif
  39.  
  40. #ifdef NULL
  41. #undef NULL
  42. #endif
  43.  
  44. #define NULL 0
  45.  
  46. char
  47.     *name           = NULL,
  48.     *NodeName      = NULL,
  49.     *request_addr  = NULL,        /* -a */
  50.     ExecFile       [ARRAY_SIZE],
  51.     RemoteExecFile [ARRAY_SIZE],
  52.     CommandFile    [ARRAY_SIZE],
  53.     DataFile       [ARRAY_SIZE],
  54.     RemoteDataFile [ARRAY_SIZE],
  55.     path           [ARRAY_SIZE];
  56.  
  57. int
  58.     _bufsiz = 8192, /* stdio buffer size */
  59.     UseSubDirs = 0,
  60.     nocopy = 0,    /* -c (also affects -C) */
  61.     nomail = 0,    /* -n */
  62.     prjobid = 0,    /* -j */
  63.     nouucico = 1,    /* -r -- we don't anyway */
  64.     mailonerr = 0,    /* -z */
  65.     linkit = 0,    /* -l */
  66.     usestdin = 0,    /* -p */
  67.     seq;
  68.  
  69. struct Library
  70.     *OwnDevUnitBase = NULL;
  71. static const char
  72.     odu_name [] = { ODU_NAME };
  73.  
  74. void myexit (void);
  75. int Copy (const BPTR, const char *);
  76. int Queue (const int, const char *, const BPTR,
  77.        const char *, const char *, const char *);
  78.  
  79. int
  80. usage (void)
  81. {
  82.     if (name) {
  83.         fprintf (stderr, "Usage: %s [-cCjlnpr] [-a addr] [-g grade] [-u user]\n"
  84.                  "\t\t[<filename> | -] <command>\n\n", name);
  85.         fprintf (stderr, "Example: %s mail-message \"burdvax!rmail wpl\"\n", name);
  86.     }
  87.  
  88.     exit (30);
  89. }
  90.  
  91. int
  92. brk (void)
  93. {
  94.     return 0;
  95. }
  96.  
  97. int
  98. main (int argc, char **argv)
  99. {
  100.     int
  101.         i,
  102.         avail,
  103.         error;
  104.     char
  105.         *user  = NULL,        /* -u */
  106.         *grade = "N",       /* -g */
  107.         *cmd   = NULL,        /* specified command */
  108.         *file  = NULL,        /* specified data file */
  109.         *tmp;
  110.     BPTR
  111.         fh     = NULL;        /* specified data file */
  112.  
  113.     if (argc == 0)
  114.         /* can't run from WB */
  115.         exit (30);
  116.  
  117.     name = argv [0];
  118.     memset (path, '\0', sizeof (path));
  119.  
  120.     atexit (myexit);
  121.     onbreak (brk);
  122.  
  123.     if ((OwnDevUnitBase = OpenLibrary (odu_name, 0)) == NULL) {
  124.         fprintf (stderr, "Unable to open %s\n", odu_name);
  125.         exit (30);
  126.     }
  127.  
  128.     tmp = GetConfig (USESUBDIRS, "n");
  129.     if (*tmp == 'y' || *tmp == 'Y' || *tmp == '1')
  130.         UseSubDirs = 1;
  131.     D (("UseSubDirs %ld\n", UseSubDirs));
  132.  
  133.     NodeName = FindConfig (NODENAME);
  134.     if (!NodeName) {
  135.         fprintf (stderr, "Cannot find local NodeName");
  136.         exit (30);
  137.     }
  138.     D (("NodeName '%s'\n", NodeName));
  139.  
  140.     if (argc < 3)
  141.         usage ();
  142.  
  143.     avail = argc - 1;
  144.     for (i = 1; i < argc; i++) {
  145.         tmp = argv [i];
  146.         if (*tmp != '-')
  147.             break;
  148.         avail--;
  149.         tmp++;
  150.         switch (*tmp) {
  151.             case '\0':
  152.             case 'p':
  153.                 /*
  154.                 ** use stdin as the file
  155.                 */
  156.                 nocopy = 0; /* make sure it gets copied */
  157.                 usestdin = 1;
  158.                 D (("set usestdin = 1, nocopy = 0\n"));
  159.                 break;
  160.  
  161.             case 'a':
  162.                 /*
  163.                 ** send mail to specified address
  164.                 */
  165.                 tmp++;
  166.  
  167.                 if (*tmp)
  168.                     request_addr = tmp;
  169.                 else {
  170.                     avail--;
  171.                     request_addr = argv [++i];
  172.                 }
  173.                 D (("set request_addr = '%s'\n", request_addr));
  174.                 break;
  175.  
  176.             case 'C':
  177.                 /*
  178.                 ** do copy local files to spool
  179.                 */
  180.                 nocopy = 0;
  181.                 D (("set nocopy = 0\n"));
  182.                 break;
  183.  
  184.             case 'c':
  185.                 /*
  186.                 ** do not copy local files to spool
  187.                 */
  188.                 nocopy = 1;
  189.                 D (("set nocopy = 1\n"));
  190.                 break;
  191.  
  192.             case 'g':
  193.                 /*
  194.                 ** set grade (priority) of transfer
  195.                 */
  196.                 tmp++;
  197.  
  198.                 if (*tmp)
  199.                     grade = tmp;
  200.                 else {
  201.                     avail--;
  202.                     grade = argv [++i];
  203.                 }
  204.  
  205.                 if (strlen (grade) > 1)
  206.                     usage ();
  207.  
  208.                 D (("set grade to '%s'\n", grade));
  209.                 break;
  210.  
  211.             case 'I':
  212.                 {
  213.                     char
  214.                         *configfile;
  215.  
  216.                     tmp++;
  217.                     if (*tmp)
  218.                         configfile = tmp;
  219.                     else {
  220.                         avail--;
  221.                         configfile = argv [++i];
  222.                     }
  223.                     D (("ignored config file '%s'\n", configfile));
  224.                     /* FIXME: implement alternate configuration files */
  225.                     fprintf (stderr, "Warning: the use alternate configuration files is not supported\n");
  226.                     break;
  227.                 }
  228.  
  229.             case 'j':
  230.                 /*
  231.                 ** print the jobid
  232.                 */
  233.                 prjobid = 1;
  234.                 D (("set prjobid = 1\n"));
  235.                 break;
  236.  
  237.             case 'l':
  238.                 /*
  239.                 ** link the file, instead of copying
  240.                 */
  241.                 if (DOSBase->dl_lib.lib_Version > 36) {
  242.                     linkit = 1;
  243.                     D (("set linkit = 1\n"));
  244.                 }
  245.                 else {
  246.                     D (("can't set linkit below 2.04\n"));
  247.                 }
  248.                 /* FIXME: next two lines (link vs. copy) */
  249.                 nocopy = 0;
  250.                 fprintf (stderr, "Warning: linking not implemented. File will be copied.\n");
  251.                 break;
  252.  
  253.             case 'n':
  254.                 /*
  255.                 ** do not send mail, even on error
  256.                 */
  257.                 nomail = 1;
  258.                 D (("set nomail = 1\n"));
  259.                 break;
  260.  
  261.             case 'r':
  262.                 /*
  263.                 ** don't start UUCICO immediately
  264.                 */
  265.                 nouucico = 1;
  266.                 /* FIXME: implement -r properly. Maybe. */
  267.                 D (("set nouucico = 1\n"));
  268.                 break;
  269.  
  270.             case 'u':
  271.                 /*
  272.                 ** we are this user
  273.                 */
  274.                 tmp++;
  275.  
  276.                 if (*tmp)
  277.                     user = tmp;
  278.                 else {
  279.                     avail--;
  280.                     user = argv [++i];
  281.                 }
  282.  
  283.                 D (("set user to '%s'\n", user));
  284.                 break;
  285.  
  286.             case 'x':
  287.                 /*
  288.                 ** set debugging options
  289.                 */
  290.                 {
  291.                     char
  292.                         *debug;
  293.  
  294.                     tmp++;
  295.                     if (tmp)
  296.                         debug = tmp;
  297.                     else {
  298.                         avail--;
  299.                         debug = argv [++i];
  300.                     }
  301.                     D (("ignored debug '%s'\n", debug));
  302.                     /* FIXME: implement debug */
  303.                     fprintf (stderr, "Warning: debug options not implemented\n");
  304.                     break;
  305.                 }
  306.  
  307.             case 'z':
  308.                 /*
  309.                 ** send mail on error
  310.                 */
  311.                 mailonerr = 1;
  312.                 D (("set mailonerr = 1\n"));
  313.                 break;
  314.  
  315.             default:
  316.                 usage ();
  317.         }
  318.     }
  319.  
  320.     if (avail != 2)
  321.         if (!(avail == 1 && usestdin)) {
  322.             D (("avail %ld\n", avail));
  323.             usage ();
  324.         }
  325.  
  326.     if (!user)
  327.         user = GetUserName ();
  328.     if (user == NULL) {
  329.         fprintf (stderr, "Cannot find local UserName\n");
  330.         exit (30);
  331.     }
  332.     D (("user '%s'\n", user));
  333.  
  334.     cmd  = argv [argc - 1];
  335.  
  336.     if (usestdin) {
  337.         file = "<stdin>";
  338.         fh = Input ();
  339.     }
  340.     else {
  341.         file = argv [argc - 2];
  342.         fh = Open (file, MODE_OLDFILE);
  343.     }
  344.  
  345.     if (!fh) {
  346.         fprintf (stderr, "Cannot open '%s' (error %ld)\n", file, IoErr ());
  347.         exit (30);
  348.     }
  349.  
  350.     getcwd (path, ARRAY_SIZE);
  351.     safe_chdir (GetConfigDir (UUSPOOL));
  352.  
  353.     seq = GetSequence (4);
  354.     if (seq >= 0) {
  355.         error = Queue (nocopy, file, fh, user, grade, cmd);
  356.  
  357.         UnLockFile (ExecFile);
  358.         UnLockFile (CommandFile);
  359.         UnLockFile (DataFile);
  360.     }
  361.  
  362.     if (usestdin == 0)
  363.         Close (fh);
  364.  
  365.     if (seq < 0 || error < 0)
  366.         exit (30);
  367.  
  368.     exit (0);
  369. }
  370.  
  371. void
  372. myexit (void)
  373. {
  374.     UnLockFiles ();
  375.  
  376.     if (OwnDevUnitBase) {
  377.         CloseLibrary(OwnDevUnitBase);
  378.         OwnDevUnitBase = NULL;
  379.     }
  380.  
  381.     return;
  382. }
  383.  
  384. int
  385. Queue (const int nocopy, const char *filename, const BPTR fh,
  386.        const char *user, const char *grade, const char *command)
  387. {
  388.     char
  389.         *p,
  390.         *q,
  391.         *pseq = SeqToName (seq),
  392.         system_name [32];
  393.     int
  394.         it_is_me;
  395.     BPTR
  396.         lock;
  397.     FILE
  398.         *fp;
  399.  
  400.     p = command;
  401.     q = system_name;
  402.  
  403.     while (*p != '!')
  404.         *q++ = *p++;
  405.     *q = '\0';
  406.     p++;    /* points after ! now */
  407.  
  408.     it_is_me = stricmp (system_name, NodeName) ? 0 : 1;
  409.     if (it_is_me == 0 && !is_in_L_sys_file (system_name)) {
  410.         fprintf (stderr, "System \"%s\" not in L.sys file.\n", system_name);
  411.         return -1;
  412.     }
  413.     D (("system_name '%s', NodeName '%s', it_is_me %ld\n", system_name, NodeName, it_is_me));
  414.  
  415.     /* we are currently in UUSPOOL, see if we need to switch directories */
  416.     if (UseSubDirs && (lock = Lock (system_name, ACCESS_READ))) {
  417.         safe_chdir (system_name);
  418.         UnLock (lock);
  419.         D (("in uuspool:%s\n", system_name));
  420.     }
  421.     else
  422.         UseSubDirs = 0;
  423.  
  424.     /*
  425.      *  exec_file        Exec file as it appears on remote machine
  426.      *  x_exec_file     Remote's Exec file as it appears on this machine
  427.      *  command_file    Command file (this machine only)
  428.      *  data_file        DataFile as it appears on
  429.      *  x_data_file
  430.      *
  431.      *    local (overload)    txfer_to            remote (uunet)
  432.      *
  433.      *    C.uunetNxxxx        <not txfered>        command file
  434.      *    D.uunetXxxxx        X.overloaXxxxx        exec / Coexec
  435.      *    D.uunetBxxxx        D.overloaBxxxx        data file
  436.      */
  437.  
  438.     sprintf (CommandFile, "C.%.7s%s%s", system_name, grade, pseq);
  439.  
  440.     if (it_is_me) {
  441.         sprintf (ExecFile,    "X.%.7sX%s", system_name, pseq);
  442.     }
  443.     else {
  444.         sprintf (ExecFile,    "D.%.7sX%s", system_name, pseq);
  445.     }
  446.  
  447.     if (nocopy) {
  448.         char
  449.             *p = path + (strlen (path) - 1);
  450.  
  451.         if (*p == ':' || *p == '/')
  452.             sprintf (DataFile, "%s%s", path, filename);
  453.         else
  454.             sprintf (DataFile, "%s/%s", path, filename);
  455.     }
  456.     else {
  457.         sprintf (DataFile, "D.%.7sB%s", system_name, pseq);
  458.     }
  459.  
  460.     ++seq;
  461.     sprintf (RemoteExecFile, "X.%.7sX%s", NodeName, SeqToName (seq));
  462.     ++seq;
  463.     sprintf (RemoteDataFile, "D.%.7sB%s", NodeName, SeqToName (seq));
  464.  
  465.     D (("nocopy %ld UseSubDirs %ld file '%s' user '%s' grade '%s'\n",
  466.         nocopy, UseSubDirs, filename, user, grade));
  467.     D (("Datafile '%s'\n", DataFile));
  468.     D (("Execfile '%s'\n", ExecFile));
  469.     D (("Cmdfile  '%s'\n", CommandFile));
  470.     D (("RmtExec  '%s'\n", RemoteExecFile));
  471.     D (("RmtData  '%s'\n", RemoteDataFile));
  472.  
  473.     LockFile (CommandFile);
  474.     LockFile (ExecFile);
  475.     LockFile (DataFile);
  476.  
  477.     fp = fopen (ExecFile, "w");
  478.     if (!fp) {
  479.         perror (ExecFile);
  480.         return -1;
  481.     }
  482.  
  483.     fprintf (fp, "U %s %s\n", user, NodeName);
  484.     fprintf (fp, "F %s\n", it_is_me ? DataFile : RemoteDataFile);
  485.     fprintf (fp, "I %s\n", it_is_me ? DataFile : RemoteDataFile);
  486.     fprintf (fp, "C %s\n", p);
  487.     if (mailonerr)
  488.         fprintf (fp, "Z\n");
  489.     if (nomail)
  490.         fprintf (fp, "N\n");
  491.     if (request_addr)
  492.         fprintf (fp, "R %s\n", request_addr);
  493.     fclose (fp);
  494.  
  495.     if (it_is_me == 0) {
  496.         fp = fopen (CommandFile, "w");
  497.         if (!fp) {
  498.             perror (CommandFile);
  499.             return -1;
  500.         }
  501.  
  502.         fprintf (fp,"S %s %s %s - %s 0666\n",
  503.             DataFile, RemoteDataFile, user, DataFile);
  504.         fprintf (fp,"S %s %s %s - %s 0666\n",
  505.             ExecFile, RemoteExecFile, user, ExecFile);
  506.  
  507.         fclose (fp);
  508.  
  509.         if (prjobid)
  510.             printf ("job %s\n", CommandFile + 2);
  511.     }
  512.     else
  513.         if (prjobid)
  514.             printf ("job %s\n", ExecFile + 2);
  515.  
  516.     if (nocopy)
  517.         return 1;
  518.  
  519.     return Copy (fh, DataFile);
  520. }
  521.  
  522. int
  523. Copy (const BPTR fh, const char *to)
  524. {
  525.     BPTR
  526.         fo;
  527.     int
  528.         len;
  529.     static char
  530.         to_buf [2048];
  531.  
  532.     DeleteFile (to);
  533.     fo = Open (to, MODE_NEWFILE);
  534.     if (!fo) {
  535.         fprintf (stderr, "Cannot open '%s' (error %ld)\n", to, IoErr ());
  536.         return -1;
  537.     }
  538.  
  539.     Seek (fh, 0, OFFSET_BEGINNING);
  540.  
  541.     while ((len = Read (fh, to_buf, sizeof (to_buf))) > 0) {
  542.         Write (fo, to_buf, len);
  543.     }
  544.  
  545.     Close (fo);
  546.  
  547.     return 1;
  548. }
  549.