|
|
1.1 root 1: /* xcmd.c
2: Routines to handle work requests.
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 xcmd_rcsid[] = "$Id: xcmd.c,v 1.1 93/07/30 08:00:19 bin Exp Locker: bin $";
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: /* We send the string
81: X from to user options
82: We put a dash in front of options. */
83: clen = (strlen (qtrans->s.zfrom) + strlen (qtrans->s.zto)
84: + strlen (qtrans->s.zuser) + strlen (qtrans->s.zoptions) + 7);
85: zsend = zbufalc (clen);
86: sprintf (zsend, "X %s %s %s -%s", qtrans->s.zfrom, qtrans->s.zto,
87: qtrans->s.zuser, qtrans->s.zoptions);
88:
89: fret = (*qdaemon->qproto->pfsendcmd) (qdaemon, zsend, qtrans->ilocal,
90: qtrans->iremote);
91: ubuffree (zsend);
92: if (! fret)
93: {
94: utransfree (qtrans);
95: return FALSE;
96: }
97:
98: qtrans->fcmd = TRUE;
99: qtrans->precfn = flocal_xcmd_await_reply;
100:
101: return fqueue_receive (qdaemon, qtrans);
102: }
103:
104: /* Get a reply to an execution request from the remote system. */
105:
106: /*ARGSUSED*/
107: static boolean
108: flocal_xcmd_await_reply (qtrans, qdaemon, zdata, cdata)
109: struct stransfer *qtrans;
110: struct sdaemon *qdaemon;
111: const char *zdata;
112: size_t cdata;
113: {
114: qtrans->precfn = NULL;
115:
116: if (zdata[0] != 'X'
117: || (zdata[1] != 'Y' && zdata[1] != 'N'))
118: {
119: ulog (LOG_ERROR, "Bad response to work request");
120: utransfree (qtrans);
121: return FALSE;
122: }
123:
124: if (zdata[1] == 'N')
125: {
126: ulog (LOG_ERROR, "%s: work request denied", qtrans->s.zfrom);
127: (void) fmail_transfer (FALSE, qtrans->s.zuser, (const char *) NULL,
128: "work request denied",
129: qtrans->s.zfrom, qdaemon->qsys->uuconf_zname,
130: qtrans->s.zto, (const char *) NULL,
131: (const char *) NULL);
132: }
133:
134: (void) fsysdep_did_work (qtrans->s.pseq);
135: utransfree (qtrans);
136:
137: return TRUE;
138: }
139:
140: /* Handle a remote work request. This just queues up the requests for
141: later processing. */
142:
143: boolean
144: fremote_xcmd_init (qdaemon, qcmd, iremote)
145: struct sdaemon *qdaemon;
146: struct scmd *qcmd;
147: int iremote;
148: {
149: const struct uuconf_system *qsys;
150: const char *zexclam;
151: const struct uuconf_system *qdestsys;
152: struct uuconf_system sdestsys;
153: char *zdestfile;
154: boolean fmkdirs;
155: struct stransfer *qtrans;
156: char *zuser;
157: char aboptions[5];
158: char *zfrom;
159: boolean fret;
160: char *zfile;
161:
162: ulog (LOG_NORMAL, "Work requested: %s to %s", qcmd->zfrom,
163: qcmd->zto);
164:
165: qsys = qdaemon->qsys;
166:
167: zexclam = strchr (qcmd->zto, '!');
168: if (zexclam == NULL
169: || zexclam == qcmd->zto
170: || strncmp (qdaemon->zlocalname, qcmd->zto,
171: (size_t) (zexclam - qcmd->zto)) == 0)
172: {
173: const char *zconst;
174:
175: /* The files are supposed to be copied to the local system. */
176: qdestsys = NULL;
177: if (zexclam == NULL)
178: zconst = qcmd->zto;
179: else
180: zconst = zexclam + 1;
181:
182: zdestfile = zsysdep_local_file (zconst, qsys->uuconf_zpubdir);
183: if (zdestfile == NULL)
184: return FALSE;
185:
186: zuser = NULL;
187: fmkdirs = strchr (qcmd->zoptions, 'f') != NULL;
188: }
189: else
190: {
191: size_t clen;
192: char *zcopy;
193: int iuuconf;
194: char *zoptions;
195:
196: clen = zexclam - qcmd->zto;
197: zcopy = zbufalc (clen + 1);
198: memcpy (zcopy, qcmd->zto, clen);
199: zcopy[clen] = '\0';
200:
201: iuuconf = uuconf_system_info (qdaemon->puuconf, zcopy, &sdestsys);
202: if (iuuconf == UUCONF_NOT_FOUND)
203: {
204: if (! funknown_system (qdaemon->puuconf, zcopy, &sdestsys))
205: {
206: ulog (LOG_ERROR, "%s: System not found", zcopy);
207: ubuffree (zcopy);
208: qtrans = qtransalc (qcmd);
209: qtrans->psendfn = fremote_xcmd_reply;
210: qtrans->pinfo = (pointer) "XN";
211: qtrans->iremote = iremote;
212: return fqueue_remote (qdaemon, qtrans);
213: }
214: }
215: else if (iuuconf != UUCONF_SUCCESS)
216: {
217: ulog_uuconf (LOG_ERROR, qdaemon->puuconf, iuuconf);
218: ubuffree (zcopy);
219: return FALSE;
220: }
221:
222: ubuffree (zcopy);
223:
224: qdestsys = &sdestsys;
225: zdestfile = zbufcpy (zexclam + 1);
226:
227: zuser = zbufalc (strlen (qdestsys->uuconf_zname)
228: + strlen (qcmd->zuser) + sizeof "!");
229: sprintf (zuser, "%s!%s", qdestsys->uuconf_zname, qcmd->zuser);
230: zoptions = aboptions;
231: *zoptions++ = 'C';
232: if (strchr (qcmd->zoptions, 'd') != NULL)
233: *zoptions++ = 'd';
234: if (strchr (qcmd->zoptions, 'm') != NULL)
235: *zoptions++ = 'm';
236: *zoptions = '\0';
237: fmkdirs = TRUE;
238: }
239:
240: /* At this point we prepare to confirm the remote request. We could
241: actually fork here and let the child spool up the requests. */
242: qtrans = qtransalc (qcmd);
243: qtrans->psendfn = fremote_xcmd_reply;
244: qtrans->pinfo = (pointer) "XY";
245: qtrans->iremote = iremote;
246: if (! fqueue_remote (qdaemon, qtrans))
247: {
248: ubuffree (zdestfile);
249: ubuffree (zuser);
250: return FALSE;
251: }
252:
253: /* Now we have to process each source file. The source
254: specification may or may use wildcards. */
255: zfrom = zsysdep_local_file (qcmd->zfrom, qsys->uuconf_zpubdir);
256: if (zfrom == NULL)
257: {
258: ubuffree (zdestfile);
259: ubuffree (zuser);
260: return FALSE;
261: }
262:
263: if (! fsysdep_wildcard_start (zfrom))
264: {
265: ubuffree (zfrom);
266: ubuffree (zdestfile);
267: ubuffree (zuser);
268: return FALSE;
269: }
270:
271: fret = TRUE;
272:
273: while ((zfile = zsysdep_wildcard (zfrom)) != NULL)
274: {
275: char *zto;
276: char abtname[CFILE_NAME_LEN];
277:
278: if (! fsysdep_file_exists (zfile))
279: {
280: ulog (LOG_ERROR, "%s: no such file", zfile);
281: continue;
282: }
283:
284: /* Make sure the remote system is permitted to read the
285: specified file. */
286: if (! fin_directory_list (zfile, qsys->uuconf_pzremote_send,
287: qsys->uuconf_zpubdir, TRUE, TRUE,
288: (const char *) NULL))
289: {
290: ulog (LOG_ERROR, "%s: not permitted to send", zfile);
291: break;
292: }
293:
294: if (qdestsys != NULL)
295: {
296: /* We really should get the original grade here. */
297: zto = zsysdep_data_file_name (qdestsys, qdaemon->zlocalname,
298: BDEFAULT_UUCP_GRADE, FALSE,
299: abtname, (char *) NULL,
300: (char *) NULL);
301: if (zto == NULL)
302: {
303: fret = FALSE;
304: break;
305: }
306: }
307: else
308: {
309: zto = zsysdep_add_base (zdestfile, zfile);
310: if (zto == NULL)
311: {
312: fret = FALSE;
313: break;
314: }
315: /* We only accept a local destination if the remote system
316: has the right to create files there. */
317: if (! fin_directory_list (zto, qsys->uuconf_pzremote_receive,
318: qsys->uuconf_zpubdir, TRUE, FALSE,
319: (const char *) NULL))
320: {
321: ulog (LOG_ERROR, "%s: not permitted to receive", zto);
322: ubuffree (zto);
323: break;
324: }
325: }
326:
327: /* Copy the file either to the final destination or to the
328: spool directory. */
329: if (! fcopy_file (zfile, zto, qdestsys == NULL, fmkdirs))
330: {
331: ubuffree (zto);
332: break;
333: }
334:
335: ubuffree (zto);
336:
337: /* If there is a destination system, queue it up. */
338: if (qdestsys != NULL)
339: {
340: struct scmd ssend;
341: char *zjobid;
342:
343: ssend.bcmd = 'S';
344: ssend.pseq = NULL;
345: ssend.zfrom = zfile;
346: ssend.zto = zdestfile;
347: ssend.zuser = zuser;
348: ssend.zoptions = aboptions;
349: ssend.ztemp = abtname;
350: ssend.imode = ixsysdep_file_mode (zfile);
351: ssend.znotify = "";
352: ssend.cbytes = -1;
353: ssend.zcmd = NULL;
354: ssend.ipos = 0;
355:
356: zjobid = zsysdep_spool_commands (qdestsys, BDEFAULT_UUCP_GRADE,
357: 1, &ssend);
358: if (zjobid == NULL)
359: break;
360: ubuffree (zjobid);
361: }
362:
363: ubuffree (zfile);
364: }
365:
366: if (zfile != NULL)
367: ubuffree (zfile);
368:
369: (void) fsysdep_wildcard_end ();
370:
371: ubuffree (zdestfile);
372: if (qdestsys != NULL)
373: (void) uuconf_system_free (qdaemon->puuconf, &sdestsys);
374:
375: ubuffree (zfrom);
376: ubuffree (zuser);
377:
378: return fret;
379: }
380:
381: /* Reply to a remote work request. */
382:
383: static boolean
384: fremote_xcmd_reply (qtrans, qdaemon)
385: struct stransfer *qtrans;
386: struct sdaemon *qdaemon;
387: {
388: boolean fret;
389:
390: fret = (*qdaemon->qproto->pfsendcmd) (qdaemon,
391: (const char *) qtrans->pinfo,
392: qtrans->ilocal,
393: qtrans->iremote);
394: utransfree (qtrans);
395: return fret;
396: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.