home *** CD-ROM | disk | FTP | other *** search
/ Openstep 4.2 (Developer) / Openstep Developer 4.2.iso / NextDeveloper / Source / GNU / uucp / uucico / xcmd.c < prev   
Encoding:
C/C++ Source or Header  |  1995-08-20  |  9.8 KB  |  402 lines

  1. /* xcmd.c
  2.    Routines to handle work requests.
  3.  
  4.    Copyright (C) 1991, 1992, 1993, 1995 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  21.  
  22.    The author of the program may be contacted at ian@airs.com or
  23.    c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144.
  24.    */
  25.  
  26. #include "uucp.h"
  27.  
  28. #if USE_RCS_ID
  29. const char xcmd_rcsid[] = "$Id: xcmd.c,v 1.19 1995/06/21 20:20:42 ian Rel $";
  30. #endif
  31.  
  32. #include <errno.h>
  33.  
  34. #include "uudefs.h"
  35. #include "uuconf.h"
  36. #include "system.h"
  37. #include "prot.h"
  38. #include "trans.h"
  39.  
  40. /* Local functions.  */
  41.  
  42. static boolean flocal_xcmd_request P((struct stransfer *qtrans,
  43.                       struct sdaemon *qdaemon));
  44. static boolean flocal_xcmd_await_reply P((struct stransfer *qtrans,
  45.                       struct sdaemon *qdaemon,
  46.                       const char *zdata, size_t cdata));
  47. static boolean fremote_xcmd_reply P((struct stransfer *qtrans,
  48.                      struct sdaemon *qdaemon));
  49.  
  50. /* Handle a local work request.  We just set up the request for
  51.    transmission.  */
  52.  
  53. boolean
  54. flocal_xcmd_init (qdaemon, qcmd)
  55.      struct sdaemon *qdaemon;
  56.      struct scmd *qcmd;
  57. {
  58.   struct stransfer *qtrans;
  59.  
  60.   qtrans = qtransalc (qcmd);
  61.   qtrans->psendfn = flocal_xcmd_request;
  62.  
  63.   return fqueue_local (qdaemon, qtrans);
  64. }
  65.  
  66. /* Send the execution request to the remote system.  */
  67.  
  68. static boolean
  69. flocal_xcmd_request (qtrans, qdaemon)
  70.      struct stransfer *qtrans;
  71.      struct sdaemon *qdaemon;
  72. {
  73.   size_t clen;
  74.   char *zsend;
  75.   boolean fret;
  76.  
  77.   ulog (LOG_NORMAL, "Requesting work: %s to %s", qtrans->s.zfrom,
  78.     qtrans->s.zto);
  79.  
  80.  
  81.   qtrans->fcmd = TRUE;
  82.   qtrans->precfn = flocal_xcmd_await_reply;
  83.  
  84.   if (! fqueue_receive (qdaemon, qtrans))
  85.     return FALSE;
  86.  
  87.   /* We send the string
  88.      X from to user options
  89.      We put a dash in front of options.  */
  90.   clen = (strlen (qtrans->s.zfrom) + strlen (qtrans->s.zto)
  91.       + strlen (qtrans->s.zuser) + strlen (qtrans->s.zoptions) + 7);
  92.   zsend = zbufalc (clen);
  93.   sprintf (zsend, "X %s %s %s -%s", qtrans->s.zfrom, qtrans->s.zto,
  94.        qtrans->s.zuser, qtrans->s.zoptions);
  95.  
  96.   fret = (*qdaemon->qproto->pfsendcmd) (qdaemon, zsend, qtrans->ilocal,
  97.                     qtrans->iremote);
  98.   ubuffree (zsend);
  99.  
  100.   /* If fret is FALSE, we should free qtrans here, but see the comment
  101.      at the end of flocal_rec_send_request.  */
  102.  
  103.   return fret;
  104. }
  105.  
  106. /* Get a reply to an execution request from the remote system.  */
  107.  
  108. /*ARGSUSED*/
  109. static boolean
  110. flocal_xcmd_await_reply (qtrans, qdaemon, zdata, cdata)
  111.      struct stransfer *qtrans;
  112.      struct sdaemon *qdaemon;
  113.      const char *zdata;
  114.      size_t cdata;
  115. {
  116.   qtrans->precfn = NULL;
  117.  
  118.   if (zdata[0] != 'X'
  119.       || (zdata[1] != 'Y' && zdata[1] != 'N'))
  120.     {
  121.       ulog (LOG_ERROR, "Bad response to work request");
  122.       utransfree (qtrans);
  123.       return FALSE;
  124.     }
  125.  
  126.   if (zdata[1] == 'N')
  127.     {
  128.       ulog (LOG_ERROR, "%s: work request denied", qtrans->s.zfrom);
  129.       (void) fmail_transfer (FALSE, qtrans->s.zuser, (const char *) NULL,
  130.                  "work request denied",
  131.                  qtrans->s.zfrom, qdaemon->qsys->uuconf_zname,
  132.                  qtrans->s.zto, (const char *) NULL,
  133.                  (const char *) NULL);
  134.     }
  135.  
  136.   (void) fsysdep_did_work (qtrans->s.pseq);
  137.   utransfree (qtrans);
  138.  
  139.   return TRUE;
  140. }
  141.  
  142. /* Handle a remote work request.  This just queues up the requests for
  143.    later processing.  */
  144.  
  145. boolean
  146. fremote_xcmd_init (qdaemon, qcmd, iremote)
  147.      struct sdaemon *qdaemon;
  148.      struct scmd *qcmd;
  149.      int iremote;
  150. {
  151.   const struct uuconf_system *qsys;
  152.   const char *zexclam;
  153.   const struct uuconf_system *qdestsys;
  154.   struct uuconf_system sdestsys;
  155.   char *zdestfile;
  156.   boolean fmkdirs;
  157.   struct stransfer *qtrans;
  158.   char *zuser;
  159.   char aboptions[5];
  160.   char *zfrom;
  161.   boolean fret;
  162.   char *zfile;
  163.  
  164.   ulog (LOG_NORMAL, "Work requested: %s to %s", qcmd->zfrom,
  165.     qcmd->zto);
  166.  
  167.   qsys = qdaemon->qsys;
  168.  
  169.   zexclam = strchr (qcmd->zto, '!');
  170.   if (zexclam == NULL
  171.       || zexclam == qcmd->zto
  172.       || strncmp (qdaemon->zlocalname, qcmd->zto,
  173.           (size_t) (zexclam - qcmd->zto)) == 0)
  174.     {
  175.       const char *zconst;
  176.  
  177.       /* The files are supposed to be copied to the local system.  */
  178.       qdestsys = NULL;
  179.       if (zexclam == NULL)
  180.     zconst = qcmd->zto;
  181.       else
  182.     zconst = zexclam + 1;
  183.  
  184.       zdestfile = zsysdep_local_file (zconst, qsys->uuconf_zpubdir,
  185.                       (boolean *) NULL);
  186.       if (zdestfile == NULL)
  187.     return FALSE;
  188.  
  189.       zuser = NULL;
  190.       fmkdirs = strchr (qcmd->zoptions, 'f') != NULL;
  191.     }
  192.   else
  193.     {
  194.       size_t clen;
  195.       char *zcopy;
  196.       int iuuconf;
  197.       char *zoptions;
  198.  
  199.       clen = zexclam - qcmd->zto;
  200.       zcopy = zbufalc (clen + 1);
  201.       memcpy (zcopy, qcmd->zto, clen);
  202.       zcopy[clen] = '\0';
  203.  
  204.       iuuconf = uuconf_system_info (qdaemon->puuconf, zcopy, &sdestsys);
  205.       if (iuuconf == UUCONF_NOT_FOUND)
  206.     {
  207.       if (! funknown_system (qdaemon->puuconf, zcopy, &sdestsys))
  208.         {
  209.           ulog (LOG_ERROR, "%s: System not found", zcopy);
  210.           ubuffree (zcopy);
  211.           qtrans = qtransalc (qcmd);
  212.           qtrans->psendfn = fremote_xcmd_reply;
  213.           qtrans->pinfo = (pointer) "XN";
  214.           qtrans->iremote = iremote;
  215.           return fqueue_remote (qdaemon, qtrans);
  216.         }
  217.     }
  218.       else if (iuuconf != UUCONF_SUCCESS)
  219.     {
  220.       ulog_uuconf (LOG_ERROR, qdaemon->puuconf, iuuconf);
  221.       ubuffree (zcopy);
  222.       return FALSE;
  223.     }
  224.  
  225.       ubuffree (zcopy);
  226.  
  227.       qdestsys = &sdestsys;
  228.       zdestfile = zbufcpy (zexclam + 1);
  229.  
  230.       zuser = zbufalc (strlen (qdestsys->uuconf_zname)
  231.                + strlen (qcmd->zuser) + sizeof "!");
  232.       sprintf (zuser, "%s!%s", qdestsys->uuconf_zname, qcmd->zuser);
  233.       zoptions = aboptions;
  234.       *zoptions++ = 'C';
  235.       if (strchr (qcmd->zoptions, 'd') != NULL)
  236.     *zoptions++ = 'd';
  237.       if (strchr (qcmd->zoptions, 'm') != NULL)
  238.     *zoptions++ = 'm';
  239.       *zoptions = '\0';
  240.       fmkdirs = TRUE;
  241.     }
  242.  
  243.   /* At this point we prepare to confirm the remote request.  We could
  244.      actually fork here and let the child spool up the requests.  */
  245.   qtrans = qtransalc (qcmd);
  246.   qtrans->psendfn = fremote_xcmd_reply;
  247.   qtrans->pinfo = (pointer) "XY";
  248.   qtrans->iremote = iremote;
  249.   if (! fqueue_remote (qdaemon, qtrans))
  250.     {
  251.       ubuffree (zdestfile);
  252.       ubuffree (zuser);
  253.       return FALSE;
  254.     }
  255.  
  256.   /* Now we have to process each source file.  The source
  257.      specification may or may use wildcards.  */
  258.   zfrom = zsysdep_local_file (qcmd->zfrom, qsys->uuconf_zpubdir,
  259.                   (boolean *) NULL);
  260.   if (zfrom == NULL)
  261.     {
  262.       ubuffree (zdestfile);
  263.       ubuffree (zuser);
  264.       return FALSE;
  265.     }
  266.  
  267.   if (! fsysdep_wildcard_start (zfrom))
  268.     {
  269.       ubuffree (zfrom);
  270.       ubuffree (zdestfile);
  271.       ubuffree (zuser);
  272.       return FALSE;
  273.     }
  274.  
  275.   fret = TRUE;
  276.  
  277.   while ((zfile = zsysdep_wildcard (zfrom)) != NULL)
  278.     {
  279.       char *zto;
  280.       char abtname[CFILE_NAME_LEN];
  281.  
  282.       if (! fsysdep_file_exists (zfile))
  283.     {
  284.       ulog (LOG_ERROR, "%s: no such file", zfile);
  285.       continue;
  286.     }
  287.  
  288.       /* Make sure the remote system is permitted to read the
  289.      specified file.  */
  290.       if (! fin_directory_list (zfile, qsys->uuconf_pzremote_send,
  291.                 qsys->uuconf_zpubdir, TRUE, TRUE,
  292.                 (const char *) NULL))
  293.     {
  294.       ulog (LOG_ERROR, "%s: not permitted to send", zfile);
  295.       break;
  296.     }
  297.  
  298.       if (qdestsys != NULL)
  299.     {
  300.       /* We really should get the original grade here.  */
  301.       zto = zsysdep_data_file_name (qdestsys, qdaemon->zlocalname,
  302.                     BDEFAULT_UUCP_GRADE, FALSE,
  303.                     abtname, (char *) NULL,
  304.                     (char *) NULL);
  305.       if (zto == NULL)
  306.         {
  307.           fret = FALSE;
  308.           break;
  309.         }
  310.     }
  311.       else
  312.     {
  313.       zto = zsysdep_add_base (zdestfile, zfile);
  314.       if (zto == NULL)
  315.         {
  316.           fret = FALSE;
  317.           break;
  318.         }
  319.       /* We only accept a local destination if the remote system
  320.          has the right to create files there.  */
  321.       if (! fin_directory_list (zto, qsys->uuconf_pzremote_receive,
  322.                     qsys->uuconf_zpubdir, TRUE, FALSE,
  323.                     (const char *) NULL))
  324.         {
  325.           ulog (LOG_ERROR, "%s: not permitted to receive", zto);
  326.           ubuffree (zto);
  327.           break;
  328.         }
  329.     }
  330.  
  331.       /* Copy the file either to the final destination or to the
  332.      spool directory.  */
  333.       if (! fcopy_file (zfile, zto, qdestsys == NULL, fmkdirs, FALSE))
  334.     {
  335.       ubuffree (zto);
  336.       break;
  337.     }
  338.  
  339.       ubuffree (zto);
  340.  
  341.       /* If there is a destination system, queue it up.  */
  342.       if (qdestsys != NULL)
  343.     {
  344.       struct scmd ssend;
  345.       char *zjobid;
  346.  
  347.       ssend.bcmd = 'S';
  348.       ssend.bgrade = BDEFAULT_UUCP_GRADE;
  349.       ssend.pseq = NULL;
  350.       ssend.zfrom = zfile;
  351.       ssend.zto = zdestfile;
  352.       ssend.zuser = zuser;
  353.       ssend.zoptions = aboptions;
  354.       ssend.ztemp = abtname;
  355.       ssend.imode = ixsysdep_file_mode (zfile);
  356.       ssend.znotify = "";
  357.       ssend.cbytes = -1;
  358.       ssend.zcmd = NULL;
  359.       ssend.ipos = 0;
  360.  
  361.       zjobid = zsysdep_spool_commands (qdestsys, BDEFAULT_UUCP_GRADE,
  362.                        1, &ssend);
  363.       if (zjobid == NULL)
  364.         break;
  365.       ubuffree (zjobid);
  366.     }
  367.  
  368.       ubuffree (zfile);
  369.     }
  370.  
  371.   if (zfile != NULL)
  372.     ubuffree (zfile);
  373.  
  374.   (void) fsysdep_wildcard_end ();
  375.  
  376.   ubuffree (zdestfile);
  377.   if (qdestsys != NULL)
  378.     (void) uuconf_system_free (qdaemon->puuconf, &sdestsys);
  379.  
  380.   ubuffree (zfrom);
  381.   ubuffree (zuser);
  382.  
  383.   return fret;
  384. }
  385.  
  386. /* Reply to a remote work request.  */
  387.  
  388. static boolean
  389. fremote_xcmd_reply (qtrans, qdaemon)
  390.      struct stransfer *qtrans;
  391.      struct sdaemon *qdaemon;
  392. {
  393.   boolean fret;
  394.  
  395.   fret = (*qdaemon->qproto->pfsendcmd) (qdaemon,
  396.                     (const char *) qtrans->pinfo,
  397.                     qtrans->ilocal,
  398.                     qtrans->iremote);
  399.   utransfree (qtrans);
  400.   return fret;
  401. }
  402.