1/* send.c
2   Routines to send a file.
3
4   Copyright (C) 1991, 1992, 1993, 1994, 1995, 2002 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.
23   */
24
25#include "uucp.h"
26
27#if USE_RCS_ID
28const char send_rcsid[] = "$Id: send.c,v 1.57 2002/03/05 19:10:41 ian Rel $";
29#endif
30
31#include <errno.h>
32
33#include "uudefs.h"
34#include "uuconf.h"
35#include "system.h"
36#include "prot.h"
37#include "trans.h"
38
39/* We keep this information in the pinfo field of the stransfer
40   structure.  */
41struct ssendinfo
42{
43  /* Local user to send mail to (may be NULL).  */
44  char *zmail;
45  /* Full file name.  */
46  char *zfile;
47  /* Number of bytes in file.  */
48  long cbytes;
49  /* TRUE if this was a local request.  */
50  boolean flocal;
51  /* TRUE if this is a spool directory file.  */
52  boolean fspool;
53  /* TRUE if the file has been completely sent.  */
54  boolean fsent;
55  /* TRUE if the file send will never succeed; used by
56     flocal_send_cancelled.  */
57  boolean fnever;
58  /* Execution file for sending an unsupported E request.  */
59  char *zexec;
60  /* Confirmation command received in fsend_await_confirm.  */
61  char *zconfirm;
62};
63
64/* Local functions.  */
65
66static void usfree_send P((struct stransfer *qtrans));
67static boolean flocal_send_fail P((struct scmd *qcmd,
68				   struct sdaemon *qdaemon,
69				   const char *zwhy));
70static boolean flocal_send_request P((struct stransfer *qtrans,
71				      struct sdaemon *qdaemon));
72static boolean flocal_send_await_reply P((struct stransfer *qtrans,
73					  struct sdaemon *qdaemon,
74					  const char *zdata, size_t cdata));
75static boolean flocal_send_cancelled P((struct stransfer *qtrans,
76					struct sdaemon *qdaemon));
77static boolean flocal_send_open_file P((struct stransfer *qtrans,
78					struct sdaemon *qdaemon));
79static boolean fremote_rec_fail P((struct sdaemon *qdaemon,
80				   enum tfailure twhy, int iremote));
81static boolean fremote_rec_fail_send P((struct stransfer *qtrans,
82					struct sdaemon *qdaemon));
83static boolean fremote_rec_reply P((struct stransfer *qtrans,
84				    struct sdaemon *qdaemon));
85static boolean fsend_file_end P((struct stransfer *qtrans,
86				 struct sdaemon *qdaemon));
87static boolean fsend_await_confirm P((struct stransfer *qtrans,
88				      struct sdaemon *qdaemon,
89				      const char *zdata, size_t cdata));
90static boolean fsend_exec_file_init P((struct stransfer *qtrans,
91				       struct sdaemon *qdaemon));
92static void usadd_exec_line P((char **pz, size_t *pcalc, size_t *pclen,
93			       int bcmd, const char *z1, const char *z2,
94			       boolean fquote));
95static boolean fsend_exec_file P((struct stransfer *qtrans,
96				  struct sdaemon *qdaemon));
97
98/* Free up a send stransfer structure.  */
99
100static void
101usfree_send (qtrans)
102     struct stransfer *qtrans;
103{
104  struct ssendinfo *qinfo = (struct ssendinfo *) qtrans->pinfo;
105
106  if (qinfo != NULL)
107    {
108      ubuffree (qinfo->zmail);
109      ubuffree (qinfo->zfile);
110      ubuffree (qinfo->zexec);
111      ubuffree (qinfo->zconfirm);
112      xfree (qtrans->pinfo);
113    }
114
115  utransfree (qtrans);
116}
117
118/* Set up a local request to send a file.  This may be called before
119   we have even tried to call the remote system.
120
121   If we are using a traditional protocol, which doesn't support
122   channel numbers and doesn't permit the file to be sent until an
123   acknowledgement has been received, the sequence of function calls
124   looks like this:
125
126   flocal_send_file_init --> fqueue_local
127   flocal_send_request (sends S request) --> fqueue_receive
128   flocal_send_await_reply (waits for SY) --> fqueue_send
129   flocal_send_open_file (opens file, calls pffile) --> fqueue_send
130   send file
131   fsend_file_end (calls pffile) --> fqueue_receive
132   fsend_await_confirm (waits for CY)
133
134   If flocal_send_await_reply gets an SN, it deletes the request.  If
135   the SY reply contains a file position at which to start sending,
136   flocal_send_await_reply sets qinfo->ipos.
137
138   This gets more complex if the protocol supports channels.  In that
139   case, we want to start sending the file data immediately, to avoid
140   the round trip delay between flocal_send_request and
141   flocal_send_await_reply.  To do this, flocal_send_request calls
142   fqueue_send rather than fqueue_receive.  The main execution
143   sequence looks like this:
144
145   flocal_send_file_init --> fqueue_local
146   flocal_send_request (sends S request) --> fqueue_send
147   flocal_send_open_file (opens file, calls pffile) --> fqueue_send
148   send file
149   fsend_file_end (calls pffile) --> fqueue_receive
150   sometime: flocal_send_await_reply (waits for SY)
151   fsend_await_confirm (waits for CY)
152
153   In this case flocal_send_await_reply must be run before
154   fsend_await_confirm; it may be run anytime after
155   flocal_send_request.
156
157   If flocal_send_await_reply is called before the entire file has
158   been sent: if it gets an SN, it sets the file position to the end
159   and arranges to call flocal_send_cancelled.  If it gets a file
160   position request, it must adjust the file position accordingly.
161
162   If flocal_send_await_reply is called after the entire file has been
163   sent: if it gets an SN, it can simply delete the request.  It can
164   ignore any file position request.
165
166   If the request is not deleted, flocal_send_await_reply must arrange
167   for the next string to be passed to fsend_await_confirm.
168   Presumably fsend_await_confirm will only be called after the entire
169   file has been sent.
170
171   Just to make things even more complex, these same routines support
172   sending execution requests, since that is much like sending a file.
173   For an execution request, the bcmd character will be E rather than
174   S.  If an execution request is being sent to a system which does
175   not support them, it must be sent as two S requests instead.  The
176   second one will be the execution file, but no actual file is
177   created; instead the zexec and znext fields in the ssendinfo
178   structure are used.  So if the bcmd character is E, then if the
179   zexec field is NULL, the data file is being sent, otherwise the
180   fake execution file is being sent.  */
181
182boolean
183flocal_send_file_init (qdaemon, qcmd)
184     struct sdaemon *qdaemon;
185     struct scmd *qcmd;
186{
187  const struct uuconf_system *qsys;
188  boolean fspool;
189  char *zfile;
190  long cbytes;
191  struct ssendinfo *qinfo;
192  struct stransfer *qtrans;
193
194  qsys = qdaemon->qsys;
195
196  if (qdaemon->fcaller
197      ? ! qsys->uuconf_fcall_transfer
198      : ! qsys->uuconf_fcalled_transfer)
199    {
200      /* uux or uucp should have already made sure that the transfer
201	 is possible, but it might have changed since then.  */
202      if (! qsys->uuconf_fcall_transfer
203	  && ! qsys->uuconf_fcalled_transfer)
204	return flocal_send_fail (qcmd, qdaemon,
205				 "not permitted to transfer files");
206
207      /* We can't do the request now, but it may get done later.  */
208      return TRUE;
209    }
210
211  /* The 'C' option means that the file has been copied to the spool
212     directory.  */
213  if (strchr (qcmd->zoptions, 'C') == NULL
214      && ! fspool_file (qcmd->zfrom))
215    {
216      fspool = FALSE;
217      if (! fin_directory_list (qcmd->zfrom,
218				qsys->uuconf_pzlocal_send,
219				qsys->uuconf_zpubdir, TRUE,
220				TRUE, qcmd->zuser))
221	return flocal_send_fail (qcmd, qdaemon, "not permitted to send");
222      zfile = zbufcpy (qcmd->zfrom);
223    }
224  else
225    {
226      fspool = TRUE;
227      zfile = zsysdep_spool_file_name (qsys, qcmd->ztemp, qcmd->pseq);
228      if (zfile == NULL)
229	return FALSE;
230    }
231
232  /* Make sure we meet any local size restrictions.  The connection
233     may not have been opened at this point, so we can't check remote
234     size restrictions.  */
235  cbytes = csysdep_size (zfile);
236  if (cbytes < 0)
237    {
238      ubuffree (zfile);
239      if (cbytes != -1)
240	return flocal_send_fail (qcmd, qdaemon, "can not get size");
241      /* A cbytes value of -1 means that the file does not exist.
242	 This can happen legitimately if it has already been sent from
243	 the spool directory.  */
244      if (! fspool)
245	return flocal_send_fail (qcmd, qdaemon, "does not exist");
246      (void) fsysdep_did_work (qcmd->pseq);
247      return TRUE;
248    }
249
250  if (qdaemon->clocal_size != -1
251      && qdaemon->clocal_size < cbytes)
252    {
253      ubuffree (zfile);
254
255      if (qdaemon->cmax_ever == -2)
256	{
257	  long c1, c2;
258
259	  c1 = cmax_size_ever (qsys->uuconf_qcall_local_size);
260	  c2 = cmax_size_ever (qsys->uuconf_qcalled_local_size);
261	  if (c1 > c2)
262	    qdaemon->cmax_ever = c1;
263	  else
264	    qdaemon->cmax_ever = c2;
265	}
266
267      if (qdaemon->cmax_ever != -1
268	  && qdaemon->cmax_ever < qcmd->cbytes)
269	return flocal_send_fail (qcmd, qdaemon, "too large to send");
270
271      return TRUE;
272    }
273
274  /* We are now prepared to send the command to the remote system.  We
275     queue up a transfer request to send the command when we are
276     ready.  */
277  qinfo = (struct ssendinfo *) xmalloc (sizeof (struct ssendinfo));
278  if (strchr (qcmd->zoptions, 'm') == NULL)
279    qinfo->zmail = NULL;
280  else
281    qinfo->zmail = zbufcpy (qcmd->zuser);
282  qinfo->zfile = zfile;
283  qinfo->cbytes = cbytes;
284  qinfo->flocal = strchr (qcmd->zuser, '!') == NULL;
285  qinfo->fspool = fspool;
286  qinfo->fsent = FALSE;
287  qinfo->zexec = NULL;
288  qinfo->zconfirm = NULL;
289
290  qtrans = qtransalc (qcmd);
291  qtrans->psendfn = flocal_send_request;
292  qtrans->pinfo = (pointer) qinfo;
293
294  return fqueue_local (qdaemon, qtrans);
295}
296
297/* Clean up after a failing local send request.  If zwhy is not NULL,
298   this reports an error to the log file and to the user.  */
299
300static boolean
301flocal_send_fail (qcmd, qdaemon, zwhy)
302     struct scmd *qcmd;
303     struct sdaemon *qdaemon;
304     const char *zwhy;
305{
306  if (zwhy != NULL)
307    {
308      const char *zfrom;
309      char *zfree;
310      const char *ztemp;
311
312      if (qcmd->bcmd != 'E')
313	{
314	  zfrom = qcmd->zfrom;
315	  zfree = NULL;
316	}
317      else
318	{
319	  zfree = zbufalc (strlen (qcmd->zfrom)
320			   + sizeof " (execution of \"\")"
321			   + strlen (qcmd->zcmd));
322	  sprintf (zfree, "%s (execution of \"%s\")", qcmd->zfrom,
323		   qcmd->zcmd);
324	  zfrom = zfree;
325	}
326
327      ulog (LOG_ERROR, "%s: %s", zfrom, zwhy);
328
329      /* We only save the temporary file if this is a request from the
330	 local system; otherwise a remote system could launch a denial
331	 of service attack by filling up the .Preserve directory
332	 (local users have much simpler methods for this type of
333	 denial of service attack, so there is little point to using a
334	 more sophisticated scheme).  */
335      if (strchr (qcmd->zuser, '!') == NULL)
336	ztemp = zsysdep_save_temp_file (qcmd->pseq);
337      else
338	ztemp = NULL;
339      (void) fmail_transfer (FALSE, qcmd->zuser, (const char *) NULL,
340			     zwhy, zfrom, (const char *) NULL,
341			     qcmd->zto, qdaemon->qsys->uuconf_zname, ztemp);
342
343      ubuffree (zfree);
344    }
345
346  (void) fsysdep_did_work (qcmd->pseq);
347
348  return TRUE;
349}
350
351/* This is called when we are ready to send the request to the remote
352   system.  We form the request and send it over.  If the protocol
353   does not support multiple channels, we start waiting for the
354   response; otherwise we can start sending the file immediately.  */
355
356static boolean
357flocal_send_request (qtrans, qdaemon)
358     struct stransfer *qtrans;
359     struct sdaemon *qdaemon;
360{
361  struct ssendinfo *qinfo = (struct ssendinfo *) qtrans->pinfo;
362  boolean fquote;
363  const struct scmd *qcmd;
364  struct scmd squoted;
365  const char *znotify;
366  char absize[20];
367  char *zsend;
368  boolean fret;
369
370  /* Make sure the file meets any remote size restrictions.  */
371  if (qdaemon->cmax_receive != -1
372      && qdaemon->cmax_receive < qinfo->cbytes)
373    {
374      fret = flocal_send_fail (&qtrans->s, qdaemon, "too large for receiver");
375      usfree_send (qtrans);
376      return fret;
377    }
378
379  /* Make sure the file still exists--it may have been removed between
380     the conversation startup and now.  After we have sent over the S
381     command we must give an error if we can't find the file.  */
382  if (! fsysdep_file_exists (qinfo->zfile))
383    {
384      (void) fsysdep_did_work (qtrans->s.pseq);
385      usfree_send (qtrans);
386      return TRUE;
387    }
388
389  /* If we are using a protocol which can make multiple channels, then
390     we can open and send the file whenever we are ready.  This is
391     because we will be able to distinguish the response by the
392     channel it is directed to.  This assumes that every protocol
393     which supports multiple channels also supports sending the file
394     position in mid-stream, since otherwise we would not be able to
395     restart files.  */
396  qtrans->fcmd = TRUE;
397  qtrans->psendfn = flocal_send_open_file;
398  qtrans->precfn = flocal_send_await_reply;
399
400  if (qdaemon->cchans > 1)
401    fret = fqueue_send (qdaemon, qtrans);
402  else
403    fret = fqueue_receive (qdaemon, qtrans);
404  if (! fret)
405    return FALSE;
406
407  fquote = fcmd_needs_quotes (&qtrans->s);
408  if (! fquote)
409    qcmd = &qtrans->s;
410  else
411    {
412      if ((qdaemon->ifeatures & FEATURE_QUOTES) == 0)
413	{
414	  fret = flocal_send_fail (&qtrans->s, qdaemon,
415				   "remote system does not support required quoting");
416	  usfree_send (qtrans);
417	  return fret;
418	}
419      uquote_cmd (&qtrans->s, &squoted);
420      qcmd = &squoted;
421    }
422
423  /* Construct the notify string to send.  If we are going to send a
424     size or an execution command, it must be non-empty.  */
425  znotify = qcmd->znotify;
426  if (znotify == NULL)
427    znotify = "";
428  if ((qdaemon->ifeatures & FEATURE_SIZES) != 0
429      || (qcmd->bcmd == 'E'
430	  && (qdaemon->ifeatures & FEATURE_EXEC) != 0))
431    {
432      if (*znotify == '\0')
433	znotify = "\"\"";
434    }
435  else
436    {
437      /* We don't need a notify string.  Some crufty UUCP code can't
438	 handle a pair of double quotes.  */
439      if (strcmp (znotify, "\"\"") == 0)
440	znotify = "";
441    }
442
443  /* Construct the size string to send.  */
444  if ((qdaemon->ifeatures & FEATURE_SIZES) == 0
445      && (qcmd->bcmd != 'E'
446	  || (qdaemon->ifeatures & FEATURE_EXEC) == 0))
447    absize[0] = '\0';
448  else if ((qdaemon->ifeatures & FEATURE_V103) == 0)
449    sprintf (absize, "0x%lx", (unsigned long) qinfo->cbytes);
450  else
451    sprintf (absize, "%ld", qinfo->cbytes);
452
453  zsend = zbufalc (strlen (qcmd->zfrom) + strlen (qcmd->zto)
454		   + strlen (qcmd->zuser) + strlen (qcmd->zoptions)
455		   + strlen (qcmd->ztemp) + strlen (znotify)
456		   + strlen (absize)
457		   + (qcmd->zcmd != NULL ? strlen (qcmd->zcmd) : 0)
458		   + 50);
459
460  /* If this an execution request and the other side supports
461     execution requests, we send an E command.  Otherwise we send an S
462     command.  The case of an execution request when we are sending
463     the fake execution file is handled just like an S request at this
464     point.  */
465  if (qcmd->bcmd == 'E'
466      && (qdaemon->ifeatures & FEATURE_EXEC) != 0)
467    {
468      /* Send the string
469	 E zfrom zto zuser zoptions ztemp imode znotify size zcmd
470	 to the remote system.  We put a '-' in front of the (possibly
471	 empty) options and a '0' in front of the mode.  */
472      sprintf (zsend, "E %s %s %s -%s %s 0%o %s %s %s", qcmd->zfrom,
473	       qcmd->zto, qcmd->zuser, qcmd->zoptions,
474	       qcmd->ztemp, qcmd->imode, znotify, absize,
475	       qcmd->zcmd);
476    }
477  else
478    {
479      const char *zoptions, *zdummy;
480
481      /* Send the string
482	 S zfrom zto zuser zoptions ztemp imode znotify
483	 to the remote system.  We put a '-' in front of the (possibly
484	 empty) options and a '0' in front of the mode.  If size
485	 negotiation is supported, we also send the size; in this case
486	 if znotify is empty we must send it as "".  If this is really
487	 an execution request, we have to simplify the options string
488	 to remove the various execution options which may confuse the
489	 remote system.  SVR4 expects a string "dummy" between the
490	 notify string and the size; I don't know why.  */
491      if (qcmd->bcmd != 'E')
492	zoptions = qcmd->zoptions;
493      else if (strchr (qcmd->zoptions, 'C') != NULL)
494	{
495	  /* This should set zoptions to "C", but at least one UUCP
496	     program gets confused by it.  That means that it will
497	     fail in certain cases, but I suppose we might as well
498	     kowtow to compatibility.  This shouldn't matter to any
499	     other program, I hope.  */
500	  zoptions = "";
501	}
502      else
503	zoptions = "c";
504
505      if ((qdaemon->ifeatures & FEATURE_SVR4) != 0)
506	zdummy = " dummy ";
507      else
508	zdummy = " ";
509
510      sprintf (zsend, "S %s %s %s -%s %s 0%o %s%s%s", qcmd->zfrom,
511	       qcmd->zto, qcmd->zuser, zoptions,
512	       qcmd->ztemp, qcmd->imode, znotify, zdummy,
513	       absize);
514    }
515
516  fret = (*qdaemon->qproto->pfsendcmd) (qdaemon, zsend, qtrans->ilocal,
517					qtrans->iremote);
518  ubuffree (zsend);
519
520  if (fquote)
521    ufree_quoted_cmd (&squoted);
522
523  /* If fret is FALSE, we should free qtrans here, but see the comment
524     at the end of flocal_rec_send_request.  */
525
526  return fret;
527}
528
529/* This is called when a reply is received for the send request.  As
530   described at length above, if the protocol supports multiple
531   channels we may be in the middle of sending the file, or we may
532   even finished sending the file.  */
533
534static boolean
535flocal_send_await_reply (qtrans, qdaemon, zdata, cdata)
536     struct stransfer *qtrans;
537     struct sdaemon *qdaemon;
538     const char *zdata;
539     size_t cdata ATTRIBUTE_UNUSED;
540{
541  struct ssendinfo *qinfo = (struct ssendinfo *) qtrans->pinfo;
542  char bcmd;
543
544  if (qtrans->s.bcmd == 'E'
545      && (qdaemon->ifeatures & FEATURE_EXEC) != 0)
546    bcmd = 'E';
547  else
548    bcmd = 'S';
549  if (zdata[0] != bcmd
550      || (zdata[1] != 'Y' && zdata[1] != 'N'))
551    {
552      ulog (LOG_ERROR, "%s: Bad response to %c request: \"%s\"",
553	    qtrans->s.zfrom, bcmd, zdata);
554      usfree_send (qtrans);
555      return FALSE;
556    }
557
558  if (zdata[1] == 'N')
559    {
560      const char *zerr;
561      boolean fnever;
562
563      fnever = TRUE;
564      if (zdata[2] == '2')
565	zerr = "permission denied by remote";
566      else if (zdata[2] == '4')
567	{
568	  zerr = "remote cannot create work files";
569	  fnever = FALSE;
570	}
571      else if (zdata[2] == '6')
572	{
573	  zerr = "too large for remote now";
574	  fnever = FALSE;
575	}
576      else if (zdata[2] == '7')
577	{
578	  /* The file is too large to ever send.  */
579	  zerr = "too large for remote";
580	}
581      else if (zdata[2] == '8')
582	{
583	  /* The file was already received by the remote system.  This
584	     is not an error, it just means that the ack from the
585	     remote was lost in the previous conversation, and there
586	     is no need to resend the file.  */
587	  zerr = NULL;
588	}
589      else if (zdata[2] == '9')
590	{
591	  /* Remote has run out of channels.  */
592	  zerr = "too many channels for remote";
593	  fnever = FALSE;
594
595	  /* Drop one channel; using exactly one channel causes
596	     slightly different behahaviour in a few places, so don't
597	     decrement to one.  */
598	  if (qdaemon->cchans > 2)
599	    --qdaemon->cchans;
600	}
601      else
602	zerr = "unknown reason";
603
604      if (! fnever
605	  || (qtrans->s.bcmd == 'E'
606	      && (qdaemon->ifeatures & FEATURE_EXEC) == 0
607	      && qinfo->zexec == NULL))
608	{
609	  if (qtrans->s.bcmd == 'E')
610	    ulog (LOG_ERROR, "%s (execution of \"%s\"): %s",
611		  qtrans->s.zfrom, qtrans->s.zcmd, zerr);
612	  else
613	    ulog (LOG_ERROR, "%s: %s", qtrans->s.zfrom, zerr);
614	}
615      else
616	{
617	  if (! flocal_send_fail (&qtrans->s, qdaemon, zerr))
618	    return FALSE;
619	}
620
621      /* If the protocol does not support multiple channels, we can
622	 simply remove the transaction.  Otherwise we must make sure
623	 the remote side knows that we have finished sending the file
624	 data.  If we have already sent the entire file, there will be
625	 no confusion.  */
626      if (qdaemon->cchans == 1 || qinfo->fsent)
627	{
628	  /* If we are breaking a 'E' command into two 'S' commands,
629	     and that was for the first 'S' command, we still have to
630	     send the second one.  */
631	  if (fnever
632	      && qtrans->s.bcmd == 'E'
633	      && (qdaemon->ifeatures & FEATURE_EXEC) == 0
634	      && qinfo->zexec == NULL)
635	    return fsend_exec_file_init (qtrans, qdaemon);
636
637	  usfree_send (qtrans);
638	  return TRUE;
639	}
640      else
641	{
642	  /* Seek to the end of the file so that the next read will
643	     send end of file.  We have to be careful here, because we
644	     may not have opened the file yet, or we may have actually
645	     already sent end of file--we could be being called
646	     because of data received while the end of file block was
647	     sent.  */
648	  if (qtrans->fsendfile && ! ffileseekend (qtrans->e))
649	    {
650	      ulog (LOG_ERROR, "seek to end: %s", strerror (errno));
651	      usfree_send (qtrans);
652	      return FALSE;
653	    }
654	  qtrans->psendfn = flocal_send_cancelled;
655	  qtrans->precfn = NULL;
656
657	  qinfo->fnever = fnever;
658
659	  return fqueue_send (qdaemon, qtrans);
660	}
661    }
662
663  /* A number following the SY or EY is the file position to start
664     sending from.  If we are already sending the file, we must set
665     the position accordingly.  */
666  if (zdata[2] != '\0')
667    {
668      long cskip;
669
670      cskip = strtol ((char *) (zdata + 2), (char **) NULL, 0);
671      if (cskip > 0 && qtrans->ipos < cskip)
672	{
673	  if (qtrans->fsendfile && ! qinfo->fsent)
674	    {
675	      if (! ffileseek (qtrans->e, cskip))
676		{
677		  ulog (LOG_ERROR, "seek: %s", strerror (errno));
678		  usfree_send (qtrans);
679		  return FALSE;
680		}
681	    }
682	  qtrans->ipos = cskip;
683	}
684    }
685
686  /* Now queue up to send the file or to wait for the confirmation.
687     We already set psendfn at the end of flocal_send_request.  If the
688     protocol supports multiple channels, we have already called
689     fqueue_send; calling it again would move the request in the
690     queue, which would make the log file a bit confusing.  */
691  qtrans->fcmd = TRUE;
692  qtrans->precfn = fsend_await_confirm;
693  if (qinfo->fsent)
694    return fqueue_receive (qdaemon, qtrans);
695  else if (qdaemon->cchans <= 1)
696    return fqueue_send (qdaemon, qtrans);
697  else
698    return TRUE;
699}
700
701/* Open the file, if any, and prepare to send it.  */
702
703static boolean
704flocal_send_open_file (qtrans, qdaemon)
705     struct stransfer *qtrans;
706     struct sdaemon *qdaemon;
707{
708  struct ssendinfo *qinfo = (struct ssendinfo *) qtrans->pinfo;
709  const char *zuser;
710
711  /* If this is not a fake execution file, open it.  */
712  if (qinfo->zexec == NULL)
713    {
714      /* If there is an ! in the user name, this is a remote request
715	 queued up by fremote_xcmd_init.  */
716      zuser = qtrans->s.zuser;
717      if (strchr (zuser, '!') != NULL)
718	zuser = NULL;
719
720      qtrans->e = esysdep_open_send (qdaemon->qsys, qinfo->zfile,
721				     ! qinfo->fspool, zuser);
722      if (! ffileisopen (qtrans->e))
723	{
724	  (void) fmail_transfer (FALSE, qtrans->s.zuser,
725				 (const char *) NULL,
726				 "cannot open file",
727				 qtrans->s.zfrom, (const char *) NULL,
728				 qtrans->s.zto,
729				 qdaemon->qsys->uuconf_zname,
730				 (qinfo->flocal
731				  ? zsysdep_save_temp_file (qtrans->s.pseq)
732				  : (const char *) NULL));
733	  (void) fsysdep_did_work (qtrans->s.pseq);
734	  usfree_send (qtrans);
735
736	  /* Unfortunately, there is no way to cancel a file send
737	     after we've already put it in progress.  So we have to
738	     return FALSE to drop the connection.  */
739	  return FALSE;
740	}
741    }
742
743  /* If flocal_send_await_reply has received a reply with a file
744     position, it will have set qtrans->ipos to the position at which
745     to start.  */
746  if (qtrans->ipos > 0)
747    {
748      if (qinfo->zexec != NULL)
749	{
750	  if (qtrans->ipos > qtrans->cbytes)
751	    qtrans->ipos = qtrans->cbytes;
752	}
753      else
754	{
755	  if (! ffileseek (qtrans->e, qtrans->ipos))
756	    {
757	      ulog (LOG_ERROR, "seek: %s", strerror (errno));
758	      usfree_send (qtrans);
759	      return FALSE;
760	    }
761	}
762    }
763
764  /* We don't bother to log sending the execution file.  */
765  if (qinfo->zexec == NULL)
766    {
767      const char *zsend;
768      char *zalc;
769
770      if (qtrans->s.bcmd != 'E')
771	{
772	  zsend = qtrans->s.zfrom;
773	  zalc = NULL;
774	}
775      else
776	{
777	  zalc = zbufalc (strlen (qtrans->s.zcmd) + sizeof " ()"
778			  + strlen (qtrans->s.zfrom));
779	  sprintf (zalc, "%s (%s)", qtrans->s.zcmd, qtrans->s.zfrom);
780	  zsend = zalc;
781	}
782
783      qtrans->zlog = zbufalc (sizeof "Sending ( bytes resume at )"
784			      + strlen (zsend) + 50);
785      sprintf (qtrans->zlog, "Sending %s (%ld bytes", zsend, qinfo->cbytes);
786      if (qtrans->ipos > 0)
787	sprintf (qtrans->zlog + strlen (qtrans->zlog), " resume at %ld",
788		 qtrans->ipos);
789      strcat (qtrans->zlog, ")");
790
791      ubuffree (zalc);
792    }
793
794  if (qdaemon->qproto->pffile != NULL)
795    {
796      boolean fhandled;
797
798      if (! (*qdaemon->qproto->pffile) (qdaemon, qtrans, TRUE, TRUE,
799					qinfo->cbytes - qtrans->ipos,
800					&fhandled))
801	{
802	  usfree_send (qtrans);
803	  return FALSE;
804	}
805
806      if (fhandled)
807	return TRUE;
808    }
809
810  if (qinfo->zexec != NULL)
811    qtrans->psendfn = fsend_exec_file;
812  else
813    {
814      qtrans->fsendfile = TRUE;
815      qtrans->psendfn = fsend_file_end;
816    }
817
818  return fqueue_send (qdaemon, qtrans);
819}
820
821/* Cancel a file send.  This is only called for a protocol which
822   supports multiple channels.  It is needed so that both systems
823   agree as to when a channel is no longer needed.  */
824
825static boolean
826flocal_send_cancelled (qtrans, qdaemon)
827     struct stransfer *qtrans;
828     struct sdaemon *qdaemon;
829{
830  struct ssendinfo *qinfo = (struct ssendinfo *) qtrans->pinfo;
831
832  /* If we are breaking a 'E' command into two 'S' commands, and that
833     was for the first 'S' command, and the first 'S' command will
834     never be sent, we still have to send the second one.  */
835  if (qinfo->fnever
836      && qtrans->s.bcmd == 'E'
837      && (qdaemon->ifeatures & FEATURE_EXEC) == 0
838      && qinfo->zexec == NULL)
839    return fsend_exec_file_init (qtrans, qdaemon);
840
841  usfree_send (qtrans);
842  return TRUE;
843}
844
845/* A remote request to receive a file (meaning that we have to send a
846   file).  The sequence of functions calls is as follows:
847
848   fremote_rec_file_init (open file) --> fqueue_remote
849   fremote_rec_reply (send RY, call pffile) --> fqueue_send
850   send file
851   fsend_file_end (calls pffile) --> fqueue_receive
852   fsend_await_confirm (waits for CY)
853   */
854
855boolean
856fremote_rec_file_init (qdaemon, qcmd, iremote)
857     struct sdaemon *qdaemon;
858     struct scmd *qcmd;
859     int iremote;
860{
861  const struct uuconf_system *qsys;
862  char *zfile;
863  boolean fbadname;
864  long cbytes;
865  unsigned int imode;
866  openfile_t e;
867  struct ssendinfo *qinfo;
868  struct stransfer *qtrans;
869
870  qsys = qdaemon->qsys;
871
872  if (! qsys->uuconf_fsend_request)
873    {
874      ulog (LOG_ERROR, "%s: not permitted to send files to remote",
875	    qcmd->zfrom);
876      return fremote_rec_fail (qdaemon, FAILURE_PERM, iremote);
877    }
878
879  if (fspool_file (qcmd->zfrom))
880    {
881      ulog (LOG_ERROR, "%s: not permitted to send", qcmd->zfrom);
882      return fremote_rec_fail (qdaemon, FAILURE_PERM, iremote);
883    }
884
885  zfile = zsysdep_local_file (qcmd->zfrom, qsys->uuconf_zpubdir, &fbadname);
886  if (zfile == NULL && fbadname)
887    {
888      ulog (LOG_ERROR, "%s: bad local file name", qcmd->zfrom);
889      return fremote_rec_fail (qdaemon, FAILURE_PERM, iremote);
890    }
891  if (zfile != NULL)
892    {
893      char *zbased;
894
895      zbased = zsysdep_add_base (zfile, qcmd->zto);
896      ubuffree (zfile);
897      zfile = zbased;
898    }
899  if (zfile == NULL)
900    return fremote_rec_fail (qdaemon, FAILURE_PERM, iremote);
901
902  if (! fin_directory_list (zfile, qsys->uuconf_pzremote_send,
903			    qsys->uuconf_zpubdir, TRUE, TRUE,
904			    (const char *) NULL))
905    {
906      ulog (LOG_ERROR, "%s: not permitted to send", zfile);
907      ubuffree (zfile);
908      return fremote_rec_fail (qdaemon, FAILURE_PERM, iremote);
909    }
910
911  /* If the file is larger than the amount of space the other side
912     reported, we can't send it.  Should we adjust this check based on
913     the restart position?  */
914  cbytes = csysdep_size (zfile);
915  if (cbytes != -1
916      && ((qcmd->cbytes != -1 && qcmd->cbytes < cbytes)
917	  || (qdaemon->cremote_size != -1
918	      && qdaemon->cremote_size < cbytes)
919	  || (qdaemon->cmax_receive != -1
920	      && qdaemon->cmax_receive < cbytes)))
921    {
922      ulog (LOG_ERROR, "%s: too large to send", zfile);
923      ubuffree (zfile);
924      return fremote_rec_fail (qdaemon, FAILURE_SIZE, iremote);
925    }
926
927  imode = ixsysdep_file_mode (zfile);
928
929  e = esysdep_open_send (qsys, zfile, TRUE, (const char *) NULL);
930  if (! ffileisopen (e))
931    {
932      ubuffree (zfile);
933      return fremote_rec_fail (qdaemon, FAILURE_OPEN, iremote);
934    }
935
936  /* If the remote requested that the file send start from a
937     particular position, arrange to do so.  */
938  if (qcmd->ipos > 0)
939    {
940      if (! ffileseek (e, qcmd->ipos))
941	{
942	  ulog (LOG_ERROR, "seek: %s", strerror (errno));
943	  ubuffree (zfile);
944	  return FALSE;
945	}
946    }
947
948  qinfo = (struct ssendinfo *) xmalloc (sizeof (struct ssendinfo));
949  qinfo->zmail = NULL;
950  qinfo->zfile = zfile;
951  qinfo->cbytes = cbytes;
952  qinfo->flocal = FALSE;
953  qinfo->fspool = FALSE;
954  qinfo->fsent = FALSE;
955  qinfo->zexec = NULL;
956  qinfo->zconfirm = NULL;
957
958  qtrans = qtransalc (qcmd);
959  qtrans->psendfn = fremote_rec_reply;
960  qtrans->iremote = iremote;
961  qtrans->pinfo = (pointer) qinfo;
962  qtrans->e = e;
963  qtrans->ipos = qcmd->ipos;
964  qtrans->s.imode = imode;
965
966  return fqueue_remote (qdaemon, qtrans);
967}
968
969/* Reply to a receive request from the remote system, and prepare to
970   start sending the file.  */
971
972static boolean
973fremote_rec_reply (qtrans, qdaemon)
974     struct stransfer *qtrans;
975     struct sdaemon *qdaemon;
976{
977  struct ssendinfo *qinfo = (struct ssendinfo *) qtrans->pinfo;
978  char absend[50];
979
980  qtrans->fsendfile = TRUE;
981  qtrans->psendfn = fsend_file_end;
982  qtrans->fcmd = TRUE;
983  qtrans->precfn = fsend_await_confirm;
984
985  if (! fqueue_send (qdaemon, qtrans))
986    return FALSE;
987
988  qtrans->zlog = zbufalc (sizeof "Sending ( bytes) "
989			  + strlen (qtrans->s.zfrom) + 25);
990  sprintf (qtrans->zlog, "Sending %s (%ld bytes)", qtrans->s.zfrom,
991	   qinfo->cbytes);
992
993  /* We send the file size because SVR4 UUCP does.  We don't look for
994     it.  We send a trailing M if we want to request a hangup.  We
995     send it both after the mode and at the end of the entire string;
996     I don't know where programs look for it.  */
997  if (qdaemon->frequest_hangup)
998    DEBUG_MESSAGE0 (DEBUG_UUCP_PROTO,
999		    "fremote_rec_reply: Requesting remote to transfer control");
1000  sprintf (absend, "RY 0%o%s 0x%lx%s", qtrans->s.imode,
1001	   qdaemon->frequest_hangup ? "M" : "",
1002	   (unsigned long) qinfo->cbytes,
1003	   qdaemon->frequest_hangup ? "M" : "");
1004  if (! (*qdaemon->qproto->pfsendcmd) (qdaemon, absend, qtrans->ilocal,
1005				       qtrans->iremote))
1006    {
1007      (void) ffileclose (qtrans->e);
1008      qtrans->e = EFILECLOSED;
1009      /* Should probably free qtrans here, but see the comment at the
1010         end of flocal_rec_send_request.  */
1011      return FALSE;
1012    }
1013
1014  if (qdaemon->qproto->pffile != NULL)
1015    {
1016      boolean fhandled;
1017
1018      if (! (*qdaemon->qproto->pffile) (qdaemon, qtrans, TRUE, TRUE,
1019					qinfo->cbytes, &fhandled))
1020	{
1021	  usfree_send (qtrans);
1022	  return FALSE;
1023	}
1024    }
1025
1026  return TRUE;
1027}
1028
1029/* If we can't send a file as requested by the remote system, queue up
1030   a failure reply which will be sent when possible.  */
1031
1032static boolean
1033fremote_rec_fail (qdaemon, twhy, iremote)
1034     struct sdaemon *qdaemon;
1035     enum tfailure twhy;
1036     int iremote;
1037{
1038  enum tfailure *ptinfo;
1039  struct stransfer *qtrans;
1040
1041  ptinfo = (enum tfailure *) xmalloc (sizeof (enum tfailure));
1042  *ptinfo = twhy;
1043
1044  qtrans = qtransalc ((struct scmd *) NULL);
1045  qtrans->psendfn = fremote_rec_fail_send;
1046  qtrans->iremote = iremote;
1047  qtrans->pinfo = (pointer) ptinfo;
1048
1049  return fqueue_remote (qdaemon, qtrans);
1050}
1051
1052/* Send a failure string for a receive command to the remote system;
1053   this is called when we are ready to reply to the command.  */
1054
1055static boolean
1056fremote_rec_fail_send (qtrans, qdaemon)
1057     struct stransfer *qtrans;
1058     struct sdaemon *qdaemon;
1059{
1060  enum tfailure *ptinfo = (enum tfailure *) qtrans->pinfo;
1061  const char *z;
1062  int ilocal, iremote;
1063
1064  switch (*ptinfo)
1065    {
1066    case FAILURE_PERM:
1067    case FAILURE_OPEN:
1068      z = "RN2";
1069      break;
1070    case FAILURE_SIZE:
1071      z = "RN6";
1072      break;
1073    default:
1074      z = "RN";
1075      break;
1076    }
1077
1078  ilocal = qtrans->ilocal;
1079  iremote = qtrans->iremote;
1080
1081  xfree (qtrans->pinfo);
1082  utransfree (qtrans);
1083
1084  return (*qdaemon->qproto->pfsendcmd) (qdaemon, z, ilocal, iremote);
1085}
1086
1087/* This is called when the main loop has finished sending a file.  It
1088   prepares to wait for a response from the remote system.  Note that
1089   if this is a local request and the protocol supports multiple
1090   channels, we may not even have received a confirmation of the send
1091   request.  */
1092
1093static boolean
1094fsend_file_end (qtrans, qdaemon)
1095     struct stransfer *qtrans;
1096     struct sdaemon *qdaemon;
1097{
1098  struct ssendinfo *qinfo = (struct ssendinfo *) qtrans->pinfo;
1099
1100  if (qdaemon->qproto->pffile != NULL)
1101    {
1102      boolean fhandled;
1103
1104      if (! (*qdaemon->qproto->pffile) (qdaemon, qtrans, FALSE, TRUE,
1105					(long) -1, &fhandled))
1106	{
1107	  usfree_send (qtrans);
1108	  return FALSE;
1109	}
1110
1111      if (fhandled)
1112	return TRUE;
1113    }
1114
1115  qinfo->fsent = TRUE;
1116
1117  /* If zconfirm is set, then we have already received the
1118     confirmation, and should call fsend_await_confirm directly.  */
1119  if (qinfo->zconfirm != NULL)
1120    return fsend_await_confirm (qtrans, qdaemon, qinfo->zconfirm,
1121				strlen (qinfo->zconfirm) + 1);
1122
1123  /* qtrans->precfn should have been set by a previous function.  */
1124  return fqueue_receive (qdaemon, qtrans);
1125}
1126
1127/* Handle the confirmation string received after sending a file.  */
1128
1129/*ARGSUSED*/
1130static boolean
1131fsend_await_confirm (qtrans, qdaemon, zdata, cdata)
1132     struct stransfer *qtrans;
1133     struct sdaemon *qdaemon;
1134     const char *zdata;
1135     size_t cdata ATTRIBUTE_UNUSED;
1136{
1137  struct ssendinfo *qinfo = (struct ssendinfo *) qtrans->pinfo;
1138  boolean fnever;
1139  const char *zerr;
1140
1141  /* If fsent is FALSE, it means that we have received the
1142     confirmation before fsend_file_end got called.  To avoid
1143     confusion, we save away the confirmation message, and let
1144     fsend_file_end call us directly.  If we did not do this, we would
1145     have to fix a thorny race condition in floop, which wants to
1146     refer to the qtrans structure after sending the end of the file.  */
1147  if (! qinfo->fsent)
1148    {
1149      qinfo->zconfirm = zbufcpy (zdata);
1150      return TRUE;
1151    }
1152
1153  if (qinfo->zexec == NULL)
1154    {
1155      (void) ffileclose (qtrans->e);
1156      qtrans->e = EFILECLOSED;
1157    }
1158
1159  fnever = FALSE;
1160  if (zdata[0] != 'C'
1161      || (zdata[1] != 'Y' && zdata[1] != 'N'))
1162    {
1163      zerr = "bad confirmation from remote";
1164      ulog (LOG_ERROR, "%s: %s \"%s\"", qtrans->s.zfrom, zerr, zdata);
1165    }
1166  else if (zdata[1] == 'N')
1167    {
1168      fnever = TRUE;
1169      if (zdata[2] == '5')
1170	{
1171	  zerr = "file could not be stored in final location";
1172	  ulog (LOG_ERROR, "%s: %s", qtrans->s.zfrom, zerr);
1173	}
1174      else
1175	{
1176	  zerr = "file send failed for unknown reason";
1177	  ulog (LOG_ERROR, "%s: %s \"%s\"", qtrans->s.zfrom, zerr, zdata);
1178	}
1179    }
1180  else
1181    {
1182      zerr = NULL;
1183
1184      /* If we receive CYM, it means that the other side wants us to
1185	 hang up so that they can send us something.  The
1186	 fhangup_requested field is checked in the main loop.  */
1187      if (zdata[2] == 'M' && qdaemon->fmaster)
1188	{
1189	  DEBUG_MESSAGE0 (DEBUG_UUCP_PROTO,
1190			  "fsend_await_confirm: Remote has requested transfer of control");
1191	  qdaemon->fhangup_requested = TRUE;
1192	}
1193    }
1194
1195  ustats (zerr == NULL, qtrans->s.zuser, qdaemon->qsys->uuconf_zname,
1196	  TRUE, qtrans->cbytes, qtrans->isecs, qtrans->imicros,
1197	  qdaemon->fcaller);
1198  qdaemon->csent += qtrans->cbytes;
1199
1200  if (zerr == NULL)
1201    {
1202      /* If this is an execution request, and the remote system
1203	 doesn't support execution requests, we have to set up the
1204	 fake execution file and loop around again.  */
1205      if (qtrans->s.bcmd == 'E'
1206	  && (qdaemon->ifeatures & FEATURE_EXEC) == 0
1207	  && qinfo->zexec == NULL)
1208	return fsend_exec_file_init (qtrans, qdaemon);
1209
1210      /* Send mail about the transfer if requested.  */
1211      if (qinfo->zmail != NULL && *qinfo->zmail != '\0')
1212	(void) fmail_transfer (TRUE, qtrans->s.zuser, qinfo->zmail,
1213			       (const char *) NULL,
1214			       qtrans->s.zfrom, (const char *) NULL,
1215			       qtrans->s.zto, qdaemon->qsys->uuconf_zname,
1216			       (const char *) NULL);
1217
1218      if (qtrans->s.pseq != NULL)
1219	(void) fsysdep_did_work (qtrans->s.pseq);
1220    }
1221  else
1222    {
1223      /* If the file send failed, we only try to save the file and
1224	 send mail if it was requested locally and it will never
1225	 succeed.  We send mail to qinfo->zmail if set, otherwise to
1226	 qtrans->s.zuser.  I hope this is reasonable.  */
1227      if (fnever && qinfo->flocal)
1228	{
1229	  (void) fmail_transfer (FALSE, qtrans->s.zuser, qinfo->zmail,
1230				 zerr, qtrans->s.zfrom, (const char *) NULL,
1231				 qtrans->s.zto, qdaemon->qsys->uuconf_zname,
1232				 zsysdep_save_temp_file (qtrans->s.pseq));
1233	  (void) fsysdep_did_work (qtrans->s.pseq);
1234	}
1235    }
1236
1237  usfree_send (qtrans);
1238
1239  return TRUE;
1240}
1241
1242/* Prepare to send an execution file to a system which does not
1243   support execution requests.  We build the execution file in memory,
1244   and then call flocal_send_request as though we were sending a real
1245   file.  Instead of sending a file, the code in flocal_send_open_file
1246   will arrange to call fsend_exec_file which will send data out of
1247   the buffer we have created.  */
1248
1249static boolean
1250fsend_exec_file_init (qtrans, qdaemon)
1251     struct stransfer *qtrans;
1252     struct sdaemon *qdaemon;
1253{
1254  struct ssendinfo *qinfo = (struct ssendinfo *) qtrans->pinfo;
1255  char *zxqtfile;
1256  char abtname[CFILE_NAME_LEN];
1257  char abxname[CFILE_NAME_LEN];
1258  char *z;
1259  size_t calc, clen;
1260  boolean fquote;
1261
1262  z = NULL;
1263  calc = 0;
1264  clen = 0;
1265
1266  fquote = fcmd_needs_quotes (&qtrans->s);
1267
1268  if (fquote)
1269    usadd_exec_line (&z, &calc, &clen, 'Q', "", "", TRUE);
1270
1271  usadd_exec_line (&z, &calc, &clen, 'U', qtrans->s.zuser,
1272		   qdaemon->zlocalname, fquote);
1273  usadd_exec_line (&z, &calc, &clen, 'F', qtrans->s.zto, "", fquote);
1274  usadd_exec_line (&z, &calc, &clen, 'I', qtrans->s.zto, "", fquote);
1275  if (strchr (qtrans->s.zoptions, 'N') != NULL)
1276    usadd_exec_line (&z, &calc, &clen, 'N', "", "", fquote);
1277  if (strchr (qtrans->s.zoptions, 'Z') != NULL)
1278    usadd_exec_line (&z, &calc, &clen, 'Z', "", "", fquote);
1279  if (strchr (qtrans->s.zoptions, 'R') != NULL)
1280    usadd_exec_line (&z, &calc, &clen, 'R', qtrans->s.znotify, "", fquote);
1281  if (strchr (qtrans->s.zoptions, 'e') != NULL)
1282    usadd_exec_line (&z, &calc, &clen, 'e', "", "", fquote);
1283
1284  /* For the command, we only quote backslashes.  If there is anything
1285     which requires fancier handling, uux will not have generated an
1286     'E' command.  */
1287  if (! fquote)
1288    usadd_exec_line (&z, &calc, &clen, 'C', qtrans->s.zcmd, "", FALSE);
1289  else
1290    {
1291      char *zquoted;
1292
1293      zquoted = zquote_cmd_string (qtrans->s.zcmd, TRUE);
1294      usadd_exec_line (&z, &calc, &clen, 'C', zquoted, "", FALSE);
1295      ubuffree (zquoted);
1296    }
1297
1298  qinfo->zexec = z;
1299  qinfo->cbytes = clen;
1300
1301  zxqtfile = zsysdep_data_file_name (qdaemon->qsys, qdaemon->zlocalname,
1302				     BDEFAULT_UUX_GRADE, TRUE, abtname,
1303				     (char *) NULL, abxname);
1304  if (zxqtfile == NULL)
1305    {
1306      usfree_send (qtrans);
1307      return FALSE;
1308    }
1309  ubuffree (zxqtfile);
1310
1311  ubuffree ((char *) qtrans->s.zfrom);
1312  qtrans->s.zfrom = zbufcpy (abtname);
1313  ubuffree ((char *) qtrans->s.zto);
1314  qtrans->s.zto = zbufcpy (abxname);
1315  ubuffree ((char *) qtrans->s.zoptions);
1316  qtrans->s.zoptions = zbufcpy ("C");
1317  ubuffree ((char *) qtrans->s.ztemp);
1318  qtrans->s.ztemp = zbufcpy (abtname);
1319
1320  qtrans->psendfn = flocal_send_request;
1321  qtrans->precfn = NULL;
1322  qtrans->ipos = 0;
1323  qtrans->cbytes = 0;
1324  qtrans->isecs = 0;
1325  qtrans->imicros = 0;
1326  qinfo->fsent = FALSE;
1327  ubuffree (qinfo->zconfirm);
1328  qinfo->zconfirm = NULL;
1329
1330  return fqueue_send (qdaemon, qtrans);
1331}
1332
1333/* Add a line to the fake execution file.  */
1334
1335static void
1336usadd_exec_line (pz, pcalc, pclen, bcmd, z1, z2, fquote)
1337     char **pz;
1338     size_t *pcalc;
1339     size_t *pclen;
1340     int bcmd;
1341     const char *z1;
1342     const char *z2;
1343     boolean fquote;
1344{
1345  char *z1q;
1346  char *z2q;
1347  size_t c1, c2;
1348  char *znew;
1349
1350  z1q = NULL;
1351  z2q = NULL;
1352  if (fquote)
1353    {
1354      if (*z1 != '\0')
1355	{
1356	  z1q = zquote_cmd_string (z1, FALSE);
1357	  z1 = z1q;
1358	}
1359
1360      if (*z2 != '\0')
1361	{
1362	  z2q = zquote_cmd_string (z2, FALSE);
1363	  z2 = z2q;
1364	}
1365    }
1366
1367  c1 = strlen (z1);
1368  c2 = strlen (z2);
1369
1370  if (*pclen + c1 + c2 + 4 >= *pcalc)
1371    {
1372      *pcalc += c1 + c2 + 100;
1373      znew = zbufalc (*pcalc);
1374      if (*pclen > 0)
1375	{
1376	  memcpy (znew, *pz, *pclen);
1377	  ubuffree (*pz);
1378	}
1379      *pz = znew;
1380    }
1381
1382  znew = *pz + *pclen;
1383  *znew++ = bcmd;
1384  if (*z1 != '\0')
1385    {
1386      *znew++ = ' ';
1387      memcpy (znew, z1, c1);
1388      znew += c1;
1389      if (*z2 != '\0')
1390	{
1391	  *znew++ = ' ';
1392	  memcpy (znew, z2, c2);
1393	  znew += c2;
1394	}
1395    }
1396
1397  if (fquote)
1398    {
1399      ubuffree (z1q);
1400      ubuffree (z2q);
1401    }
1402
1403  /* In some bizarre non-Unix case we might have to worry about the
1404     newline here.  We don't know how a newline is normally written
1405     out to a file, but whatever is written to a file is what we will
1406     normally transfer.  If that is not simply \n then this fake
1407     execution file will not look like other execution files.  */
1408  *znew++ = '\n';
1409
1410  *pclen = znew - *pz;
1411}
1412
1413/* This routine is called to send the contents of the fake execution
1414   file.  Normally file data is sent by the floop routine in trans.c,
1415   but since we don't have an actual file we must do it here.  This
1416   routine sends the complete buffer, followed by a zero length
1417   packet, and then calls fsend_file_end.  */
1418
1419static boolean
1420fsend_exec_file (qtrans, qdaemon)
1421     struct stransfer *qtrans;
1422     struct sdaemon *qdaemon;
1423{
1424  struct ssendinfo *qinfo = (struct ssendinfo *) qtrans->pinfo;
1425  char *zdata;
1426  size_t cdata;
1427  size_t csend;
1428
1429  zdata = (*qdaemon->qproto->pzgetspace) (qdaemon, &cdata);
1430  if (zdata == NULL)
1431    {
1432      usfree_send (qtrans);
1433      return FALSE;
1434    }
1435
1436  csend = qinfo->cbytes - qtrans->ipos;
1437  if (csend > cdata)
1438    csend = cdata;
1439
1440  memcpy (zdata, qinfo->zexec + qtrans->ipos, csend);
1441
1442  if (! (*qdaemon->qproto->pfsenddata) (qdaemon, zdata, csend,
1443					qtrans->ilocal, qtrans->iremote,
1444					qtrans->ipos))
1445    {
1446      usfree_send (qtrans);
1447      return FALSE;
1448    }
1449
1450  qtrans->cbytes += csend;
1451  qtrans->ipos += csend;
1452
1453  if (csend == 0)
1454    return fsend_file_end (qtrans, qdaemon);
1455
1456  /* Leave the job on the send queue.  */
1457
1458  return TRUE;
1459}
1460