home *** CD-ROM | disk | FTP | other *** search
- /* xcmd.c
- Routines to handle work requests.
-
- Copyright (C) 1991, 1992, 1993, 1995 Ian Lance Taylor
-
- This file is part of the Taylor UUCP package.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The author of the program may be contacted at ian@airs.com or
- c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144.
- */
-
- #include "uucp.h"
-
- #if USE_RCS_ID
- const char xcmd_rcsid[] = "$Id: xcmd.c,v 1.19 1995/06/21 20:20:42 ian Rel $";
- #endif
-
- #include <errno.h>
-
- #include "uudefs.h"
- #include "uuconf.h"
- #include "system.h"
- #include "prot.h"
- #include "trans.h"
-
- /* Local functions. */
-
- static boolean flocal_xcmd_request P((struct stransfer *qtrans,
- struct sdaemon *qdaemon));
- static boolean flocal_xcmd_await_reply P((struct stransfer *qtrans,
- struct sdaemon *qdaemon,
- const char *zdata, size_t cdata));
- static boolean fremote_xcmd_reply P((struct stransfer *qtrans,
- struct sdaemon *qdaemon));
-
- /* Handle a local work request. We just set up the request for
- transmission. */
-
- boolean
- flocal_xcmd_init (qdaemon, qcmd)
- struct sdaemon *qdaemon;
- struct scmd *qcmd;
- {
- struct stransfer *qtrans;
-
- qtrans = qtransalc (qcmd);
- qtrans->psendfn = flocal_xcmd_request;
-
- return fqueue_local (qdaemon, qtrans);
- }
-
- /* Send the execution request to the remote system. */
-
- static boolean
- flocal_xcmd_request (qtrans, qdaemon)
- struct stransfer *qtrans;
- struct sdaemon *qdaemon;
- {
- size_t clen;
- char *zsend;
- boolean fret;
-
- ulog (LOG_NORMAL, "Requesting work: %s to %s", qtrans->s.zfrom,
- qtrans->s.zto);
-
-
- qtrans->fcmd = TRUE;
- qtrans->precfn = flocal_xcmd_await_reply;
-
- if (! fqueue_receive (qdaemon, qtrans))
- return FALSE;
-
- /* We send the string
- X from to user options
- We put a dash in front of options. */
- clen = (strlen (qtrans->s.zfrom) + strlen (qtrans->s.zto)
- + strlen (qtrans->s.zuser) + strlen (qtrans->s.zoptions) + 7);
- zsend = zbufalc (clen);
- sprintf (zsend, "X %s %s %s -%s", qtrans->s.zfrom, qtrans->s.zto,
- qtrans->s.zuser, qtrans->s.zoptions);
-
- fret = (*qdaemon->qproto->pfsendcmd) (qdaemon, zsend, qtrans->ilocal,
- qtrans->iremote);
- ubuffree (zsend);
-
- /* If fret is FALSE, we should free qtrans here, but see the comment
- at the end of flocal_rec_send_request. */
-
- return fret;
- }
-
- /* Get a reply to an execution request from the remote system. */
-
- /*ARGSUSED*/
- static boolean
- flocal_xcmd_await_reply (qtrans, qdaemon, zdata, cdata)
- struct stransfer *qtrans;
- struct sdaemon *qdaemon;
- const char *zdata;
- size_t cdata;
- {
- qtrans->precfn = NULL;
-
- if (zdata[0] != 'X'
- || (zdata[1] != 'Y' && zdata[1] != 'N'))
- {
- ulog (LOG_ERROR, "Bad response to work request");
- utransfree (qtrans);
- return FALSE;
- }
-
- if (zdata[1] == 'N')
- {
- ulog (LOG_ERROR, "%s: work request denied", qtrans->s.zfrom);
- (void) fmail_transfer (FALSE, qtrans->s.zuser, (const char *) NULL,
- "work request denied",
- qtrans->s.zfrom, qdaemon->qsys->uuconf_zname,
- qtrans->s.zto, (const char *) NULL,
- (const char *) NULL);
- }
-
- (void) fsysdep_did_work (qtrans->s.pseq);
- utransfree (qtrans);
-
- return TRUE;
- }
-
- /* Handle a remote work request. This just queues up the requests for
- later processing. */
-
- boolean
- fremote_xcmd_init (qdaemon, qcmd, iremote)
- struct sdaemon *qdaemon;
- struct scmd *qcmd;
- int iremote;
- {
- const struct uuconf_system *qsys;
- const char *zexclam;
- const struct uuconf_system *qdestsys;
- struct uuconf_system sdestsys;
- char *zdestfile;
- boolean fmkdirs;
- struct stransfer *qtrans;
- char *zuser;
- char aboptions[5];
- char *zfrom;
- boolean fret;
- char *zfile;
-
- ulog (LOG_NORMAL, "Work requested: %s to %s", qcmd->zfrom,
- qcmd->zto);
-
- qsys = qdaemon->qsys;
-
- zexclam = strchr (qcmd->zto, '!');
- if (zexclam == NULL
- || zexclam == qcmd->zto
- || strncmp (qdaemon->zlocalname, qcmd->zto,
- (size_t) (zexclam - qcmd->zto)) == 0)
- {
- const char *zconst;
-
- /* The files are supposed to be copied to the local system. */
- qdestsys = NULL;
- if (zexclam == NULL)
- zconst = qcmd->zto;
- else
- zconst = zexclam + 1;
-
- zdestfile = zsysdep_local_file (zconst, qsys->uuconf_zpubdir,
- (boolean *) NULL);
- if (zdestfile == NULL)
- return FALSE;
-
- zuser = NULL;
- fmkdirs = strchr (qcmd->zoptions, 'f') != NULL;
- }
- else
- {
- size_t clen;
- char *zcopy;
- int iuuconf;
- char *zoptions;
-
- clen = zexclam - qcmd->zto;
- zcopy = zbufalc (clen + 1);
- memcpy (zcopy, qcmd->zto, clen);
- zcopy[clen] = '\0';
-
- iuuconf = uuconf_system_info (qdaemon->puuconf, zcopy, &sdestsys);
- if (iuuconf == UUCONF_NOT_FOUND)
- {
- if (! funknown_system (qdaemon->puuconf, zcopy, &sdestsys))
- {
- ulog (LOG_ERROR, "%s: System not found", zcopy);
- ubuffree (zcopy);
- qtrans = qtransalc (qcmd);
- qtrans->psendfn = fremote_xcmd_reply;
- qtrans->pinfo = (pointer) "XN";
- qtrans->iremote = iremote;
- return fqueue_remote (qdaemon, qtrans);
- }
- }
- else if (iuuconf != UUCONF_SUCCESS)
- {
- ulog_uuconf (LOG_ERROR, qdaemon->puuconf, iuuconf);
- ubuffree (zcopy);
- return FALSE;
- }
-
- ubuffree (zcopy);
-
- qdestsys = &sdestsys;
- zdestfile = zbufcpy (zexclam + 1);
-
- zuser = zbufalc (strlen (qdestsys->uuconf_zname)
- + strlen (qcmd->zuser) + sizeof "!");
- sprintf (zuser, "%s!%s", qdestsys->uuconf_zname, qcmd->zuser);
- zoptions = aboptions;
- *zoptions++ = 'C';
- if (strchr (qcmd->zoptions, 'd') != NULL)
- *zoptions++ = 'd';
- if (strchr (qcmd->zoptions, 'm') != NULL)
- *zoptions++ = 'm';
- *zoptions = '\0';
- fmkdirs = TRUE;
- }
-
- /* At this point we prepare to confirm the remote request. We could
- actually fork here and let the child spool up the requests. */
- qtrans = qtransalc (qcmd);
- qtrans->psendfn = fremote_xcmd_reply;
- qtrans->pinfo = (pointer) "XY";
- qtrans->iremote = iremote;
- if (! fqueue_remote (qdaemon, qtrans))
- {
- ubuffree (zdestfile);
- ubuffree (zuser);
- return FALSE;
- }
-
- /* Now we have to process each source file. The source
- specification may or may use wildcards. */
- zfrom = zsysdep_local_file (qcmd->zfrom, qsys->uuconf_zpubdir,
- (boolean *) NULL);
- if (zfrom == NULL)
- {
- ubuffree (zdestfile);
- ubuffree (zuser);
- return FALSE;
- }
-
- if (! fsysdep_wildcard_start (zfrom))
- {
- ubuffree (zfrom);
- ubuffree (zdestfile);
- ubuffree (zuser);
- return FALSE;
- }
-
- fret = TRUE;
-
- while ((zfile = zsysdep_wildcard (zfrom)) != NULL)
- {
- char *zto;
- char abtname[CFILE_NAME_LEN];
-
- if (! fsysdep_file_exists (zfile))
- {
- ulog (LOG_ERROR, "%s: no such file", zfile);
- continue;
- }
-
- /* Make sure the remote system is permitted to read the
- specified file. */
- if (! fin_directory_list (zfile, qsys->uuconf_pzremote_send,
- qsys->uuconf_zpubdir, TRUE, TRUE,
- (const char *) NULL))
- {
- ulog (LOG_ERROR, "%s: not permitted to send", zfile);
- break;
- }
-
- if (qdestsys != NULL)
- {
- /* We really should get the original grade here. */
- zto = zsysdep_data_file_name (qdestsys, qdaemon->zlocalname,
- BDEFAULT_UUCP_GRADE, FALSE,
- abtname, (char *) NULL,
- (char *) NULL);
- if (zto == NULL)
- {
- fret = FALSE;
- break;
- }
- }
- else
- {
- zto = zsysdep_add_base (zdestfile, zfile);
- if (zto == NULL)
- {
- fret = FALSE;
- break;
- }
- /* We only accept a local destination if the remote system
- has the right to create files there. */
- if (! fin_directory_list (zto, qsys->uuconf_pzremote_receive,
- qsys->uuconf_zpubdir, TRUE, FALSE,
- (const char *) NULL))
- {
- ulog (LOG_ERROR, "%s: not permitted to receive", zto);
- ubuffree (zto);
- break;
- }
- }
-
- /* Copy the file either to the final destination or to the
- spool directory. */
- if (! fcopy_file (zfile, zto, qdestsys == NULL, fmkdirs, FALSE))
- {
- ubuffree (zto);
- break;
- }
-
- ubuffree (zto);
-
- /* If there is a destination system, queue it up. */
- if (qdestsys != NULL)
- {
- struct scmd ssend;
- char *zjobid;
-
- ssend.bcmd = 'S';
- ssend.bgrade = BDEFAULT_UUCP_GRADE;
- ssend.pseq = NULL;
- ssend.zfrom = zfile;
- ssend.zto = zdestfile;
- ssend.zuser = zuser;
- ssend.zoptions = aboptions;
- ssend.ztemp = abtname;
- ssend.imode = ixsysdep_file_mode (zfile);
- ssend.znotify = "";
- ssend.cbytes = -1;
- ssend.zcmd = NULL;
- ssend.ipos = 0;
-
- zjobid = zsysdep_spool_commands (qdestsys, BDEFAULT_UUCP_GRADE,
- 1, &ssend);
- if (zjobid == NULL)
- break;
- ubuffree (zjobid);
- }
-
- ubuffree (zfile);
- }
-
- if (zfile != NULL)
- ubuffree (zfile);
-
- (void) fsysdep_wildcard_end ();
-
- ubuffree (zdestfile);
- if (qdestsys != NULL)
- (void) uuconf_system_free (qdaemon->puuconf, &sdestsys);
-
- ubuffree (zfrom);
- ubuffree (zuser);
-
- return fret;
- }
-
- /* Reply to a remote work request. */
-
- static boolean
- fremote_xcmd_reply (qtrans, qdaemon)
- struct stransfer *qtrans;
- struct sdaemon *qdaemon;
- {
- boolean fret;
-
- fret = (*qdaemon->qproto->pfsendcmd) (qdaemon,
- (const char *) qtrans->pinfo,
- qtrans->ilocal,
- qtrans->iremote);
- utransfree (qtrans);
- return fret;
- }
-