1 /* rec.c
2    Routines to receive 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
28 const char rec_rcsid[] = "$FreeBSD$";
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 /* If the other side does not tell us the size of a file it wants to
40    send us, we assume it is this long.  This is only used for free
41    space checking.  */
42 #define CASSUMED_FILE_SIZE (10240)
43 
44 /* We keep this information in the pinfo field of the stransfer
45    structure.  */
46 struct srecinfo
47 {
48   /* Local user to send mail to (may be NULL).  */
49   char *zmail;
50   /* Full file name.  */
51   char *zfile;
52   /* Temporary file name.  */
53   char *ztemp;
54   /* TRUE if this is a spool directory file.  */
55   boolean fspool;
56   /* TRUE if this was a local request.  */
57   boolean flocal;
58   /* TRUE if the file has been completely received.  */
59   boolean freceived;
60   /* TRUE if remote request has been replied to.  */
61   boolean freplied;
62   /* TRUE if we moved the file to the final destination.  */
63   boolean fmoved;
64 };
65 
66 /* This structure is kept in the pinfo field if we are refusing a
67    remote request.  */
68 struct srecfailinfo
69 {
70   /* Reason for refusal.  */
71   enum tfailure twhy;
72   /* TRUE if we have sent the reason for refusal.  */
73   boolean fsent;
74   /* TRUE if we have seen the end of the file.  */
75   boolean freceived;
76 };
77 
78 /* Local functions.  */
79 
80 static void urrec_free P((struct stransfer *qtrans));
81 static boolean flocal_rec_fail P((struct stransfer *qtrans,
82 				  struct scmd *qcmd,
83 				  const struct uuconf_system *qsys,
84 				  const char *zwhy));
85 static boolean flocal_rec_send_request P((struct stransfer *qtrans,
86 					  struct sdaemon *qdaemon));
87 static boolean flocal_rec_await_reply P((struct stransfer *qtrans,
88 					 struct sdaemon *qdaemon,
89 					 const char *zdata,
90 					 size_t cdata));
91 static boolean fremote_send_reply P((struct stransfer *qtrans,
92 				     struct sdaemon *qdaemon));
93 static boolean fremote_send_fail P((struct sdaemon *qdaemon,
94 				    struct scmd *qcmd,
95 				    enum tfailure twhy,
96 				    int iremote));
97 static boolean fremote_send_fail_send P((struct stransfer *qtrans,
98 					 struct sdaemon *qdaemon));
99 static boolean fremote_discard P((struct stransfer *qtrans,
100 				  struct sdaemon *qdaemon,
101 				  const char *zdata, size_t cdata));
102 static boolean frec_file_end P((struct stransfer *qtrans,
103 				struct sdaemon *qdaemon,
104 				const char *zdata, size_t cdata));
105 static boolean frec_file_send_confirm P((struct stransfer *qtrans,
106 					 struct sdaemon *qdaemon));
107 
108 /* Free up a receive stransfer structure.  */
109 
110 static void
urrec_free(qtrans)111 urrec_free (qtrans)
112      struct stransfer *qtrans;
113 {
114   struct srecinfo *qinfo = (struct srecinfo *) qtrans->pinfo;
115 
116   if (qinfo != NULL)
117     {
118       ubuffree (qinfo->zmail);
119       ubuffree (qinfo->zfile);
120       ubuffree (qinfo->ztemp);
121       xfree (qtrans->pinfo);
122     }
123 
124   utransfree (qtrans);
125 }
126 
127 /* Set up a request for a file from the remote system.  This may be
128    called before the remote system has been called.
129 
130    This is the order of function calls:
131 
132    flocal_rec_file_init --> fqueue_local
133    flocal_rec_send_request (send R ...) --> fqueue_receive
134    flocal_rec_await_reply (open file, call pffile) --> fqueue_receive
135    receive file
136    frec_file_end (close and move file, call pffile) --> fqueue_send
137    frec_file_send_confirm (send CY)
138    */
139 
140 boolean
flocal_rec_file_init(qdaemon,qcmd)141 flocal_rec_file_init (qdaemon, qcmd)
142      struct sdaemon *qdaemon;
143      struct scmd *qcmd;
144 {
145   const struct uuconf_system *qsys;
146   boolean fspool;
147   char *zfile;
148   struct srecinfo *qinfo;
149   struct stransfer *qtrans;
150 
151   qsys = qdaemon->qsys;
152 
153   /* Make sure we are permitted to transfer files.  */
154   if (qdaemon->fcaller
155       ? ! qsys->uuconf_fcall_transfer
156       : ! qsys->uuconf_fcalled_transfer)
157     {
158       /* This case will have been checked by uucp or uux, but it could
159 	 have changed.  */
160       if (! qsys->uuconf_fcall_transfer
161 	  && ! qsys->uuconf_fcalled_transfer)
162 	return flocal_rec_fail ((struct stransfer *) NULL, qcmd, qsys,
163 				"not permitted to request files");
164       return TRUE;
165     }
166 
167   fspool = fspool_file (qcmd->zto);
168 
169   if (fspool)
170     {
171       pointer puuconf;
172       int iuuconf;
173       const char *zlocalname;
174       struct uuconf_system slocalsys;
175 
176       /* Normal users are not allowed to request files to be received
177 	 into the spool directory.  To support uux forwarding, we use
178 	 the special option '9'.  This permits a file to be received
179 	 into the spool directory for the local system only without
180 	 the usual checking.  This is only done for local requests, of
181 	 course.  */
182       if (qcmd->zto[0] != 'D'
183 	  || strchr (qcmd->zoptions, '9') == NULL)
184 	return flocal_rec_fail ((struct stransfer *) NULL, qcmd, qsys,
185 				"not permitted to receive");
186 
187       puuconf = qdaemon->puuconf;
188       iuuconf = uuconf_localname (puuconf, &zlocalname);
189       if (iuuconf == UUCONF_NOT_FOUND)
190 	{
191 	  zlocalname = zsysdep_localname ();
192 	  if (zlocalname == NULL)
193 	    return FALSE;
194 	}
195       else if (iuuconf != UUCONF_SUCCESS)
196 	{
197 	  ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
198 	  return FALSE;
199 	}
200 
201       iuuconf = uuconf_system_info (puuconf, zlocalname, &slocalsys);
202       if (iuuconf == UUCONF_NOT_FOUND)
203 	{
204 	  iuuconf = uuconf_system_local (puuconf, &slocalsys);
205 	  if (iuuconf != UUCONF_SUCCESS)
206 	    {
207 	      ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
208 	      return FALSE;
209 	    }
210 	  slocalsys.uuconf_zname = (char *) zlocalname;
211 	}
212       else if (iuuconf != UUCONF_SUCCESS)
213 	{
214 	  ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
215 	  return FALSE;
216 	}
217 
218       zfile = zsysdep_spool_file_name (&slocalsys, qcmd->zto, qcmd->pseq);
219 
220       (void) uuconf_system_free (puuconf, &slocalsys);
221 
222       if (zfile == NULL)
223 	return FALSE;
224     }
225   else
226     {
227       zfile = zsysdep_add_base (qcmd->zto, qcmd->zfrom);
228       if (zfile == NULL)
229 	return FALSE;
230 
231       /* Check permissions.  */
232       if (! fin_directory_list (zfile, qsys->uuconf_pzlocal_receive,
233 				qsys->uuconf_zpubdir, TRUE,
234 				FALSE, qcmd->zuser))
235 	{
236 	  ubuffree (zfile);
237 	  return flocal_rec_fail ((struct stransfer *) NULL, qcmd, qsys,
238 				  "not permitted to receive");
239 	}
240 
241       /* The 'f' option means that directories should not
242 	 be created if they do not already exist.  */
243       if (strchr (qcmd->zoptions, 'f') == NULL)
244 	{
245 	  if (! fsysdep_make_dirs (zfile, TRUE))
246 	    {
247 	      ubuffree (zfile);
248 	      return flocal_rec_fail ((struct stransfer *) NULL, qcmd,
249 				      qsys, "cannot create directories");
250 	    }
251 	}
252     }
253 
254   qinfo = (struct srecinfo *) xmalloc (sizeof (struct srecinfo));
255   if (strchr (qcmd->zoptions, 'm') == NULL)
256     qinfo->zmail = NULL;
257   else
258     qinfo->zmail = zbufcpy (qcmd->zuser);
259   qinfo->zfile = zfile;
260   qinfo->ztemp = NULL;
261   qinfo->fspool = fspool;
262   qinfo->flocal = TRUE;
263   qinfo->freceived = FALSE;
264   qinfo->freplied = TRUE;
265 
266   qtrans = qtransalc (qcmd);
267   qtrans->psendfn = flocal_rec_send_request;
268   qtrans->pinfo = (pointer) qinfo;
269 
270   return fqueue_local (qdaemon, qtrans);
271 }
272 
273 /* Report an error for a local receive request.  */
274 
275 static boolean
flocal_rec_fail(qtrans,qcmd,qsys,zwhy)276 flocal_rec_fail (qtrans, qcmd, qsys, zwhy)
277      struct stransfer *qtrans;
278      struct scmd *qcmd;
279      const struct uuconf_system *qsys;
280      const char *zwhy;
281 {
282   if (zwhy != NULL)
283     {
284       ulog (LOG_ERROR, "%s: %s", qcmd->zfrom, zwhy);
285       (void) fmail_transfer (FALSE, qcmd->zuser, (const char *) NULL, zwhy,
286 			     qcmd->zfrom, qsys->uuconf_zname,
287 			     qcmd->zto, (const char *) NULL,
288 			     (const char *) NULL);
289       (void) fsysdep_did_work (qcmd->pseq);
290     }
291   if (qtrans != NULL)
292     urrec_free (qtrans);
293   return TRUE;
294 }
295 
296 /* This is called when we are ready to send the actual request to the
297    other system.  */
298 
299 static boolean
flocal_rec_send_request(qtrans,qdaemon)300 flocal_rec_send_request (qtrans, qdaemon)
301      struct stransfer *qtrans;
302      struct sdaemon *qdaemon;
303 {
304   struct srecinfo *qinfo = (struct srecinfo *) qtrans->pinfo;
305   long cbytes, cbytes2;
306   boolean fquote;
307   const struct scmd *qcmd;
308   struct scmd squoted;
309   size_t clen;
310   char *zsend;
311   boolean fret;
312 
313   qinfo->ztemp = zsysdep_receive_temp (qdaemon->qsys, qinfo->zfile,
314 				       (const char *) NULL,
315 				       (qdaemon->qproto->frestart
316 					&& (qdaemon->ifeatures
317 					    & FEATURE_RESTART) != 0));
318   if (qinfo->ztemp == NULL)
319     {
320       urrec_free (qtrans);
321       return FALSE;
322     }
323 
324   qtrans->fcmd = TRUE;
325   qtrans->precfn = flocal_rec_await_reply;
326 
327   if (! fqueue_receive (qdaemon, qtrans))
328     return FALSE;
329 
330   /* Check the amount of free space available for both the temporary
331      file and the real file.  */
332   cbytes = csysdep_bytes_free (qinfo->ztemp);
333   cbytes2 = csysdep_bytes_free (qinfo->zfile);
334   if (cbytes < cbytes2)
335     cbytes = cbytes2;
336   if (cbytes != -1)
337     {
338       cbytes -= qdaemon->qsys->uuconf_cfree_space;
339       if (cbytes < 0)
340 	cbytes = 0;
341     }
342 
343   if (qdaemon->clocal_size != -1
344       && (cbytes == -1 || qdaemon->clocal_size < cbytes))
345     cbytes = qdaemon->clocal_size;
346 
347   fquote = fcmd_needs_quotes (&qtrans->s);
348   if (! fquote)
349     qcmd = &qtrans->s;
350   else
351     {
352       if ((qdaemon->ifeatures & FEATURE_QUOTES) == 0)
353 	return flocal_rec_fail (qtrans, &qtrans->s, qdaemon->qsys,
354 				"remote system does not support required quoting");
355       uquote_cmd (&qtrans->s, &squoted);
356       qcmd = &squoted;
357     }
358 
359   /* We send the string
360      R from to user options
361 
362      We put a dash in front of options.  If we are talking to a
363      counterpart, we also send the maximum size file we are prepared
364      to accept, as returned by esysdep_open_receive.  */
365   clen = (strlen (qcmd->zfrom) + strlen (qcmd->zto)
366 	  + strlen (qcmd->zuser) + strlen (qcmd->zoptions) + 30);
367   zsend = zbufalc (clen);
368   if ((qdaemon->ifeatures & FEATURE_SIZES) == 0)
369     sprintf (zsend, "R %s %s %s -%s", qcmd->zfrom, qcmd->zto,
370 	     qcmd->zuser, qcmd->zoptions);
371   else if ((qdaemon->ifeatures & FEATURE_V103) == 0)
372     sprintf (zsend, "R %s %s %s -%s 0x%lx", qcmd->zfrom, qcmd->zto,
373 	     qcmd->zuser, qcmd->zoptions, (unsigned long) cbytes);
374   else
375     sprintf (zsend, "R %s %s %s -%s %ld", qcmd->zfrom, qcmd->zto,
376 	     qcmd->zuser, qcmd->zoptions, cbytes);
377 
378   fret = (*qdaemon->qproto->pfsendcmd) (qdaemon, zsend, qtrans->ilocal,
379 					qtrans->iremote);
380   ubuffree (zsend);
381 
382   if (fquote)
383     ufree_quoted_cmd (&squoted);
384 
385   /* There is a potential space leak here: if pfsendcmd fails, we
386      might need to free qtrans.  However, it is possible that by the
387      time pfsendcmd returns, a response will have been received which
388      led to the freeing of qtrans anyhow.  One way to fix this would
389      be some sort of counter in qtrans to track allocations, but since
390      the space leak is small, and the conversation has failed anyhow,
391      it doesn't seem worth it.  */
392 
393   return fret;
394 }
395 
396 /* This is called when a reply is received for the request.  */
397 
398 /*ARGSUSED*/
399 static boolean
flocal_rec_await_reply(qtrans,qdaemon,zdata,cdata)400 flocal_rec_await_reply (qtrans, qdaemon, zdata, cdata)
401      struct stransfer *qtrans;
402      struct sdaemon *qdaemon;
403      const char *zdata;
404      size_t cdata ATTRIBUTE_UNUSED;
405 {
406   struct srecinfo *qinfo = (struct srecinfo *) qtrans->pinfo;
407   const char *zlog;
408   char *zend;
409 
410   if (zdata[0] != 'R'
411       || (zdata[1] != 'Y' && zdata[1] != 'N'))
412     {
413       ulog (LOG_ERROR, "%s: bad response to receive request: \"%s\"",
414 	    qtrans->s.zfrom, zdata);
415       urrec_free (qtrans);
416       return FALSE;
417     }
418 
419   if (zdata[1] == 'N')
420     {
421       boolean fnever;
422       const char *zerr;
423 
424       fnever = TRUE;
425       if (zdata[2] == '2')
426 	zerr = "no such file";
427       else if (zdata[2] == '6')
428 	{
429 	  /* We sent over the maximum file size we were prepared to
430 	     receive, and the remote system is telling us that the
431 	     file is larger than that.  Try again later.  It would be
432 	     better if we could know whether there will ever be enough
433 	     room.  */
434 	  zerr = "too large to receive now";
435 	  fnever = FALSE;
436 	}
437       else if (zdata[2] == '9')
438 	{
439 	  /* Remote has run out of channels.  */
440 	  zerr = "too many channels for remote";
441 	  fnever = FALSE;
442 
443 	  /* Drop one channel; using exactly one channel causes
444 	     slightly different behahaviour in a few places, so don't
445 	     decrement to one.  */
446 	  if (qdaemon->cchans > 2)
447 	    --qdaemon->cchans;
448 	}
449       else
450 	zerr = "unknown reason";
451 
452       if (fnever)
453 	return flocal_rec_fail (qtrans, &qtrans->s, qdaemon->qsys, zerr);
454 
455       ulog (LOG_ERROR, "%s: %s", qtrans->s.zfrom, zerr);
456 
457       urrec_free (qtrans);
458 
459       return TRUE;
460     }
461 
462   /* The mode should have been sent as "RY 0%o".  If it wasn't, we use
463      0666.  */
464   qtrans->s.imode = (unsigned int) strtol ((char *) (zdata + 2),
465 					   &zend, 8);
466   if (qtrans->s.imode == 0)
467     qtrans->s.imode = 0666;
468 
469   /* If there is an M after the mode, the remote has requested a
470      hangup.  */
471   if (*zend == 'M' && qdaemon->fmaster)
472     {
473       DEBUG_MESSAGE0 (DEBUG_UUCP_PROTO,
474 		      "flocal_rec_await_reply: Remote has requested transfer of control");
475       qdaemon->fhangup_requested = TRUE;
476     }
477 
478   /* Open the file to receive into.  We just ignore any restart count,
479      since we have no way to tell it to the other side.  SVR4 may have
480      some way to do this, but I don't know what it is.  */
481   qtrans->e = esysdep_open_receive (qdaemon->qsys, qinfo->zfile,
482 				    (const char *) NULL, qinfo->ztemp,
483 				    (long *) NULL);
484   if (! ffileisopen (qtrans->e))
485     return flocal_rec_fail (qtrans, &qtrans->s, qdaemon->qsys,
486 			    "cannot open file");
487 
488   if (qinfo->fspool)
489     zlog = qtrans->s.zto;
490   else
491     zlog = qinfo->zfile;
492   qtrans->zlog = zbufalc (sizeof "Receiving " + strlen (zlog));
493   sprintf (qtrans->zlog, "Receiving %s", zlog);
494 
495   if (qdaemon->qproto->pffile != NULL)
496     {
497       boolean fhandled;
498 
499       if (! (*qdaemon->qproto->pffile) (qdaemon, qtrans, TRUE, FALSE,
500 					(long) -1, &fhandled))
501 	return flocal_rec_fail (qtrans, &qtrans->s, qdaemon->qsys,
502 				(const char *) NULL);
503       if (fhandled)
504 	return TRUE;
505     }
506 
507   qtrans->frecfile = TRUE;
508   qtrans->psendfn = frec_file_send_confirm;
509   qtrans->precfn = frec_file_end;
510 
511   return fqueue_receive (qdaemon, qtrans);
512 }
513 
514 /* Make sure there is still enough disk space available to receive a
515    file.  */
516 
517 boolean
frec_check_free(qtrans,cfree_space)518 frec_check_free (qtrans, cfree_space)
519      struct stransfer *qtrans;
520      long cfree_space;
521 {
522   struct srecinfo *qinfo = (struct srecinfo *) qtrans->pinfo;
523   long cfree1, cfree2;
524 
525   cfree1 = csysdep_bytes_free (qinfo->ztemp);
526   cfree2 = csysdep_bytes_free (qinfo->zfile);
527   if (cfree1 < cfree2)
528     cfree1 = cfree2;
529   if (cfree1 != -1 && cfree1 < cfree_space)
530     {
531       ulog (LOG_ERROR, "%s: too big to receive now", qinfo->zfile);
532       return FALSE;
533     }
534 
535   return TRUE;
536 }
537 
538 /* A remote request to send a file to the local system, meaning that
539    we are going to receive a file.
540 
541    If we are using a protocol which does not support multiple
542    channels, the remote system will not start sending us the file
543    until it has received our confirmation.  In that case, the order of
544    functions is as follows:
545 
546    fremote_send_file_init (open file) --> fqueue_remote
547    fremote_send_reply (send SY, call pffile) --> fqueue_receive
548    receive file
549    frec_file_end (close and move file, call pffile) --> fqueue_send
550    frec_file_send_confirm (send CY)
551 
552    If the protocol supports multiple channels, then the remote system
553    will start sending the file immediately after the send request.
554    That means that the data may come in before remote_send_reply is
555    called, so frec_file_end may be called before fremote_send_reply.
556    Note that this means the pffile entry points may be called in
557    reverse order for such a protocol.
558 
559    If the send request is rejected, via fremote_send_fail, and the
560    protocol supports multiple channels, we must accept and discard
561    data until a zero byte buffer is received from the other side,
562    indicating that it has received our rejection.
563 
564    This code also handles execution requests, which are very similar
565    to send requests.  */
566 
567 boolean
fremote_send_file_init(qdaemon,qcmd,iremote)568 fremote_send_file_init (qdaemon, qcmd, iremote)
569      struct sdaemon *qdaemon;
570      struct scmd *qcmd;
571      int iremote;
572 {
573   const struct uuconf_system *qsys;
574   boolean fspool;
575   char *zfile;
576   openfile_t e;
577   char *ztemp;
578   long cbytes, cbytes2;
579   long crestart;
580   struct srecinfo *qinfo;
581   struct stransfer *qtrans;
582   const char *zlog;
583 
584   qsys = qdaemon->qsys;
585 
586   if (! qsys->uuconf_frec_request)
587     {
588       ulog (LOG_ERROR, "%s: not permitted to receive files from remote",
589 	    qcmd->zfrom);
590       return fremote_send_fail (qdaemon, qcmd, FAILURE_PERM, iremote);
591     }
592 
593   fspool = fspool_file (qcmd->zto);
594 
595   /* We don't accept remote command files.  An execution request may
596      only send a simple data file.  */
597   if ((fspool && qcmd->zto[0] == 'C')
598       || (qcmd->bcmd == 'E'
599 	  && (! fspool || qcmd->zto[0] != 'D')))
600     {
601       ulog (LOG_ERROR, "%s: not permitted to receive", qcmd->zfrom);
602       return fremote_send_fail (qdaemon, qcmd, FAILURE_PERM, iremote);
603     }
604 
605   /* See if we have already received this file in a previous
606      conversation.  */
607   if (fsysdep_already_received (qsys, qcmd->zto, qcmd->ztemp))
608     return fremote_send_fail (qdaemon, qcmd, FAILURE_RECEIVED, iremote);
609 
610   if (fspool)
611     {
612       zfile = zsysdep_spool_file_name (qsys, qcmd->zto, (pointer) NULL);
613       if (zfile == NULL)
614 	return FALSE;
615     }
616   else
617     {
618       boolean fbadname;
619 
620       zfile = zsysdep_local_file (qcmd->zto, qsys->uuconf_zpubdir,
621 				  &fbadname);
622       if (zfile == NULL && fbadname)
623 	{
624 	  ulog (LOG_ERROR, "%s: bad local file name", qcmd->zto);
625 	  return fremote_send_fail (qdaemon, qcmd, FAILURE_PERM, iremote);
626 	}
627       if (zfile != NULL)
628 	{
629 	  char *zadd;
630 
631 	  zadd = zsysdep_add_base (zfile, qcmd->zfrom);
632 	  ubuffree (zfile);
633 	  zfile = zadd;
634 	}
635       if (zfile == NULL)
636 	return FALSE;
637 
638       /* Check permissions.  */
639       if (! fin_directory_list (zfile, qsys->uuconf_pzremote_receive,
640 				qsys->uuconf_zpubdir, TRUE,
641 				FALSE, (const char *) NULL))
642 	{
643 	  ulog (LOG_ERROR, "%s: not permitted to receive", zfile);
644 	  ubuffree (zfile);
645 	  return fremote_send_fail (qdaemon, qcmd, FAILURE_PERM, iremote);
646 	}
647 
648       if (strchr (qcmd->zoptions, 'f') == NULL)
649 	{
650 	  if (! fsysdep_make_dirs (zfile, TRUE))
651 	    {
652 	      ubuffree (zfile);
653 	      return fremote_send_fail (qdaemon, qcmd, FAILURE_OPEN,
654 					iremote);
655 	    }
656 	}
657     }
658 
659   ztemp = zsysdep_receive_temp (qsys, zfile, qcmd->ztemp,
660 				(qdaemon->qproto->frestart
661 				 && (qdaemon->ifeatures
662 				     & FEATURE_RESTART) != 0));
663 
664   /* Adjust the number of bytes we are prepared to receive according
665      to the amount of free space we are supposed to leave available
666      and the maximum file size we are permitted to transfer.  */
667   cbytes = csysdep_bytes_free (ztemp);
668   cbytes2 = csysdep_bytes_free (zfile);
669   if (cbytes < cbytes2)
670     cbytes = cbytes2;
671 
672   if (cbytes != -1)
673     {
674       cbytes -= qsys->uuconf_cfree_space;
675       if (cbytes < 0)
676 	cbytes = 0;
677     }
678 
679   if (qdaemon->cremote_size != -1
680       && (cbytes == -1 || qdaemon->cremote_size < cbytes))
681     cbytes = qdaemon->cremote_size;
682 
683   /* If the number of bytes we are prepared to receive is less than
684      the file size, we must fail.  If the remote did not tell us the
685      file size, arbitrarily assumed that it is 10240 bytes.  */
686   if (cbytes != -1)
687     {
688       long csize;
689 
690       csize = qcmd->cbytes;
691       if (csize == -1)
692 	csize = CASSUMED_FILE_SIZE;
693       if (cbytes < csize)
694 	{
695 	  ulog (LOG_ERROR, "%s: too big to receive", zfile);
696 	  ubuffree (ztemp);
697 	  ubuffree (zfile);
698 	  return fremote_send_fail (qdaemon, qcmd, FAILURE_SIZE, iremote);
699 	}
700     }
701 
702   /* Open the file to receive into.  This may find an old copy of the
703      file, which will be used for file restart if the other side
704      supports it.  */
705   crestart = -1;
706   e = esysdep_open_receive (qsys, zfile, qcmd->ztemp, ztemp,
707 			    ((qdaemon->qproto->frestart
708 			      && (qdaemon->ifeatures
709 				  & FEATURE_RESTART) != 0)
710 			     ? &crestart
711 			     : (long *) NULL));
712   if (! ffileisopen (e))
713     {
714       ubuffree (ztemp);
715       ubuffree (zfile);
716       return fremote_send_fail (qdaemon, qcmd, FAILURE_OPEN, iremote);
717     }
718 
719   if (crestart > 0)
720     {
721       DEBUG_MESSAGE1 (DEBUG_UUCP_PROTO,
722 		      "fremote_send_file_init: Restarting receive from %ld",
723 		      crestart);
724       if (! ffileseek (e, crestart))
725 	{
726 	  ulog (LOG_ERROR, "seek: %s", strerror (errno));
727 	  (void) ffileclose (e);
728 	  ubuffree (ztemp);
729 	  ubuffree (zfile);
730 	  return FALSE;
731 	}
732     }
733 
734   qinfo = (struct srecinfo *) xmalloc (sizeof (struct srecinfo));
735   if (strchr (qcmd->zoptions, 'n') == NULL)
736     qinfo->zmail = NULL;
737   else
738     qinfo->zmail = zbufcpy (qcmd->znotify);
739   qinfo->zfile = zfile;
740   qinfo->ztemp = ztemp;
741   qinfo->fspool = fspool;
742   qinfo->flocal = FALSE;
743   qinfo->freceived = FALSE;
744   qinfo->freplied = FALSE;
745 
746   qtrans = qtransalc (qcmd);
747   qtrans->psendfn = fremote_send_reply;
748   qtrans->precfn = frec_file_end;
749   qtrans->iremote = iremote;
750   qtrans->pinfo = (pointer) qinfo;
751   qtrans->frecfile = TRUE;
752   qtrans->e = e;
753   if (crestart > 0)
754     qtrans->ipos = crestart;
755 
756   if (qcmd->bcmd == 'E')
757     zlog = qcmd->zcmd;
758   else
759     {
760       if (qinfo->fspool)
761 	zlog = qcmd->zto;
762       else
763 	zlog = qinfo->zfile;
764     }
765   qtrans->zlog = zbufalc (sizeof "Receiving ( bytes resume at )"
766 			  + strlen (zlog) + 50);
767   sprintf (qtrans->zlog, "Receiving %s", zlog);
768   if (crestart > 0 || qcmd->cbytes > 0)
769     {
770       strcat (qtrans->zlog, " (");
771       if (qcmd->cbytes > 0)
772 	{
773 	  sprintf (qtrans->zlog + strlen (qtrans->zlog), "%ld bytes",
774 		   qcmd->cbytes);
775 	  if (crestart > 0)
776 	    strcat (qtrans->zlog, " ");
777 	}
778       if (crestart > 0)
779 	sprintf (qtrans->zlog + strlen (qtrans->zlog), "resume at %ld",
780 		 crestart);
781       strcat (qtrans->zlog, ")");
782     }
783 
784   return fqueue_remote (qdaemon, qtrans);
785 }
786 
787 /* Reply to a send request, and prepare to receive the file.  */
788 
789 static boolean
fremote_send_reply(qtrans,qdaemon)790 fremote_send_reply (qtrans, qdaemon)
791      struct stransfer *qtrans;
792      struct sdaemon *qdaemon;
793 {
794   struct srecinfo *qinfo = (struct srecinfo *) qtrans->pinfo;
795   boolean fret;
796   char ab[50];
797 
798   /* If the file has been completely received, we just want to send
799      the final confirmation.  Otherwise, we must wait for the file
800      first.  */
801   qtrans->psendfn = frec_file_send_confirm;
802   if (qinfo->freceived)
803     fret = fqueue_send (qdaemon, qtrans);
804   else
805     fret = fqueue_receive (qdaemon, qtrans);
806   if (! fret)
807     return FALSE;
808 
809   ab[0] = qtrans->s.bcmd;
810   ab[1] = 'Y';
811   if (qtrans->ipos <= 0)
812     ab[2] = '\0';
813   else
814     sprintf (ab + 2, " 0x%lx", (unsigned long) qtrans->ipos);
815 
816   qinfo->freplied = TRUE;
817 
818   if (! (*qdaemon->qproto->pfsendcmd) (qdaemon, ab, qtrans->ilocal,
819 				       qtrans->iremote))
820     {
821       (void) ffileclose (qtrans->e);
822       qtrans->e = EFILECLOSED;
823       (void) remove (qinfo->ztemp);
824       /* Should probably free qtrans here, but see the comment at the
825          end of flocal_rec_send_request.  */
826       return FALSE;
827     }
828 
829   if (qdaemon->qproto->pffile != NULL)
830     {
831       boolean fhandled;
832 
833       if (! (*qdaemon->qproto->pffile) (qdaemon, qtrans, TRUE, FALSE,
834 					(long) -1, &fhandled))
835 	{
836 	  (void) remove (qinfo->ztemp);
837 	  urrec_free (qtrans);
838 	  return FALSE;
839 	}
840     }
841 
842   return TRUE;
843 }
844 
845 /* If we can't receive a file, queue up a response to the remote
846    system.  */
847 
848 static boolean
fremote_send_fail(qdaemon,qcmd,twhy,iremote)849 fremote_send_fail (qdaemon, qcmd, twhy, iremote)
850      struct sdaemon *qdaemon;
851      struct scmd *qcmd;
852      enum tfailure twhy;
853      int iremote;
854 {
855   struct srecfailinfo *qinfo;
856   struct stransfer *qtrans;
857 
858   qinfo = (struct srecfailinfo *) xmalloc (sizeof (struct srecfailinfo));
859   qinfo->twhy = twhy;
860   qinfo->fsent = FALSE;
861 
862   /* If the protocol does not support multiple channels (cchans <= 1),
863      then we have essentially already received the entire file.  */
864   qinfo->freceived = qdaemon->cchans <= 1;
865 
866   qtrans = qtransalc (qcmd);
867   qtrans->psendfn = fremote_send_fail_send;
868   qtrans->precfn = fremote_discard;
869   qtrans->iremote = iremote;
870   qtrans->pinfo = (pointer) qinfo;
871 
872   return fqueue_remote (qdaemon, qtrans);
873 }
874 
875 /* Send a failure string for a send command to the remote system;
876    this is called when we are ready to reply to the command.  */
877 
878 static boolean
fremote_send_fail_send(qtrans,qdaemon)879 fremote_send_fail_send (qtrans, qdaemon)
880      struct stransfer *qtrans;
881      struct sdaemon *qdaemon;
882 {
883   struct srecfailinfo *qinfo = (struct srecfailinfo *) qtrans->pinfo;
884   char ab[4];
885   int ilocal, iremote;
886 
887   ab[0] = qtrans->s.bcmd;
888   ab[1] = 'N';
889 
890   switch (qinfo->twhy)
891     {
892     case FAILURE_PERM:
893       ab[2] = '2';
894       break;
895     case FAILURE_OPEN:
896       ab[2] = '4';
897       break;
898     case FAILURE_SIZE:
899       ab[2] = '6';
900       break;
901     case FAILURE_RECEIVED:
902       /* Remember this file as though we successfully received it;
903 	 when the other side acknowledges our rejection, we know that
904 	 we no longer have to remember that we received this file.  */
905       usent_receive_ack (qdaemon, qtrans);
906       ab[2] = '8';
907       break;
908     default:
909       ab[2] = '\0';
910       break;
911     }
912 
913   ab[3] = '\0';
914 
915   ilocal = qtrans->ilocal;
916   iremote = qtrans->iremote;
917 
918   /* Wait for the end of file marker if we haven't gotten it yet.  */
919   if (! qinfo->freceived)
920     {
921       qinfo->fsent = TRUE;
922       if (! fqueue_receive (qdaemon, qtrans))
923 	return FALSE;
924     }
925   else
926     {
927       xfree (qtrans->pinfo);
928       utransfree (qtrans);
929     }
930 
931   return (*qdaemon->qproto->pfsendcmd) (qdaemon, ab, ilocal, iremote);
932 }
933 
934 /* Discard data until we reach the end of the file.  This is used for
935    a protocol with multiple channels, since the remote system may
936    start sending the file before the confirmation is sent.  If we
937    refuse the file, the remote system will get us back in synch by
938    sending an empty buffer, which is what we look for here.  */
939 
940 /*ARGSUSED*/
941 static boolean
fremote_discard(qtrans,qdaemon,zdata,cdata)942 fremote_discard (qtrans, qdaemon, zdata, cdata)
943      struct stransfer *qtrans;
944      struct sdaemon *qdaemon ATTRIBUTE_UNUSED;
945      const char *zdata ATTRIBUTE_UNUSED;
946      size_t cdata;
947 {
948   struct srecfailinfo *qinfo = (struct srecfailinfo *) qtrans->pinfo;
949 
950   DEBUG_MESSAGE1 (DEBUG_UUCP_PROTO,
951 		  "fremote_discard: Discarding %lu bytes",
952 		  (unsigned long) cdata);
953 
954   if (cdata != 0)
955     return TRUE;
956 
957   qinfo->freceived = TRUE;
958 
959   /* If we have already sent the denial, we are done.  */
960   if (qinfo->fsent)
961     {
962       xfree (qtrans->pinfo);
963       utransfree (qtrans);
964     }
965 
966   return TRUE;
967 }
968 
969 /* This is called when a file has been completely received.  It sends
970    a response to the remote system.  */
971 
972 /*ARGSUSED*/
973 static boolean
frec_file_end(qtrans,qdaemon,zdata,cdata)974 frec_file_end (qtrans, qdaemon, zdata, cdata)
975      struct stransfer *qtrans;
976      struct sdaemon *qdaemon;
977      const char *zdata ATTRIBUTE_UNUSED;
978      size_t cdata ATTRIBUTE_UNUSED;
979 {
980   struct srecinfo *qinfo = (struct srecinfo *) qtrans->pinfo;
981   char *zalc;
982   const char *zerr;
983   boolean fnever;
984 
985   DEBUG_MESSAGE3 (DEBUG_UUCP_PROTO, "frec_file_end: %s to %s (freplied %s)",
986 		  qtrans->s.zfrom, qtrans->s.zto,
987 		  qinfo->freplied ? "TRUE" : "FALSE");
988 
989   if (qdaemon->qproto->pffile != NULL)
990     {
991       boolean fhandled;
992 
993       if (! (*qdaemon->qproto->pffile) (qdaemon, qtrans, FALSE, FALSE,
994 					(long) -1, &fhandled))
995 	{
996 	  (void) remove (qinfo->ztemp);
997 	  urrec_free (qtrans);
998 	  return FALSE;
999 	}
1000       if (fhandled)
1001 	return TRUE;
1002     }
1003 
1004   qinfo->freceived = TRUE;
1005 
1006   fnever = FALSE;
1007 
1008   zalc = NULL;
1009 
1010   if (! fsysdep_sync (qtrans->e, qtrans->s.zto))
1011     {
1012       zerr = strerror (errno);
1013       (void) ffileclose (qtrans->e);
1014       qtrans->e = EFILECLOSED;
1015       (void) remove (qinfo->ztemp);
1016     }
1017   else if (! ffileclose (qtrans->e))
1018     {
1019       zerr = strerror (errno);
1020       ulog (LOG_ERROR, "%s: close: %s", qtrans->s.zto, zerr);
1021       (void) remove (qinfo->ztemp);
1022       qtrans->e = EFILECLOSED;
1023     }
1024   else
1025     {
1026       qtrans->e = EFILECLOSED;
1027       if (! fsysdep_move_file (qinfo->ztemp, qinfo->zfile, qinfo->fspool,
1028 			       FALSE, ! qinfo->fspool,
1029 			       (qinfo->flocal
1030 				? qtrans->s.zuser
1031 				: (const char *) NULL)))
1032 	{
1033 	  long cspace;
1034 
1035 	  /* Keep the temporary file if there is 1.5 times the amount
1036 	     of required free space.  This is just a random guess, to
1037 	     make an unusual situtation potentially less painful.  */
1038 	  cspace = csysdep_bytes_free (qinfo->ztemp);
1039 	  if (cspace == -1)
1040 	    cspace = FREE_SPACE_DELTA;
1041 	  cspace -= (qdaemon->qsys->uuconf_cfree_space
1042 		     + qdaemon->qsys->uuconf_cfree_space / 2);
1043 	  if (cspace < 0)
1044 	    {
1045 	      (void) remove (qinfo->ztemp);
1046 	      zerr = "could not move to final location";
1047 	    }
1048 	  else
1049 	    {
1050 	      const char *az[20];
1051 	      int i;
1052 
1053 	      zalc = zbufalc (sizeof "could not move to final location (left as )"
1054 			      + strlen (qinfo->ztemp));
1055 	      sprintf (zalc, "could not move to final location (left as %s)",
1056 		       qinfo->ztemp);
1057 	      zerr = zalc;
1058 
1059 	      i = 0;
1060 	      az[i++] = "The file\n\t";
1061 	      az[i++] = qinfo->ztemp;
1062 	      az[i++] =
1063 		"\nwas saved because the move to the final location failed.\n";
1064 	      az[i++] = "See the UUCP logs for more details.\n";
1065 	      az[i++] = "The file transfer was from\n\t";
1066 	      az[i++] = qdaemon->qsys->uuconf_zname;
1067 	      az[i++] = "!";
1068 	      az[i++] = qtrans->s.zfrom;
1069 	      az[i++] = "\nto\n\t";
1070 	      az[i++] = qtrans->s.zto;
1071 	      az[i++] = "\nand was requested by\n\t";
1072 	      az[i++] = qtrans->s.zuser;
1073 	      az[i++] = "\n";
1074 	      (void) fsysdep_mail (OWNER, "UUCP temporary file saved", i, az);
1075 	    }
1076 	  ulog (LOG_ERROR, "%s: %s", qinfo->zfile, zerr);
1077 	  fnever = TRUE;
1078 	}
1079       else
1080 	{
1081 	  if (! qinfo->fspool)
1082 	    {
1083 	      unsigned int imode;
1084 
1085 	      /* Unless we can change the ownership of the file, the
1086 		 only choice to make about these bits is whether to
1087 		 set the execute bit or not.  */
1088 	      if ((qtrans->s.imode & 0111) != 0)
1089 		imode = 0777;
1090 	      else
1091 		imode = 0666;
1092 	      (void) fsysdep_change_mode (qinfo->zfile, imode);
1093 	    }
1094 
1095 	  zerr = NULL;
1096 	}
1097     }
1098 
1099   ustats (zerr == NULL, qtrans->s.zuser, qdaemon->qsys->uuconf_zname,
1100 	  FALSE, qtrans->cbytes, qtrans->isecs, qtrans->imicros,
1101 	  qdaemon->fcaller);
1102   qdaemon->creceived += qtrans->cbytes;
1103 
1104   if (zerr == NULL)
1105     {
1106       if (qinfo->zmail != NULL && *qinfo->zmail != '\0')
1107 	(void) fmail_transfer (TRUE, qtrans->s.zuser, qinfo->zmail,
1108 			       (const char *) NULL,
1109 			       qtrans->s.zfrom, qdaemon->qsys->uuconf_zname,
1110 			       qtrans->s.zto, (const char *) NULL,
1111 			       (const char *) NULL);
1112 
1113       if (qtrans->s.pseq != NULL)
1114 	(void) fsysdep_did_work (qtrans->s.pseq);
1115 
1116       if (! qinfo->flocal)
1117 	{
1118 	  /* Remember that we have received this file, so that if the
1119 	     connection drops at this point we won't receive it again.
1120 	     We could check the return value here, but if we return
1121 	     FALSE we couldn't do anything but drop the connection,
1122 	     which would hardly be reasonable.  Instead we trust that
1123 	     the administrator will notice and handle any error
1124 	     messages, which are very unlikely to occur if everything
1125 	     is set up correctly.  */
1126 	  (void) fsysdep_remember_reception (qdaemon->qsys, qtrans->s.zto,
1127 					     qtrans->s.ztemp);
1128 	}
1129     }
1130   else
1131     {
1132       /* If the transfer failed, we send mail if it was requested
1133 	 locally and if it can never succeed.  */
1134       if (qinfo->flocal && fnever)
1135 	{
1136 	  (void) fmail_transfer (FALSE, qtrans->s.zuser, qinfo->zmail,
1137 				 zerr, qtrans->s.zfrom,
1138 				 qdaemon->qsys->uuconf_zname,
1139 				 qtrans->s.zto, (const char *) NULL,
1140 				 (const char *) NULL);
1141 	  (void) fsysdep_did_work (qtrans->s.pseq);
1142 	}
1143     }
1144 
1145   ubuffree (zalc);
1146 
1147   /* If this is an execution request, we must create the execution
1148      file itself.  */
1149   if (qtrans->s.bcmd == 'E' && zerr == NULL)
1150     {
1151       char *zxqt, *zxqtfile, *ztemp;
1152       FILE *e;
1153       boolean fbad;
1154 
1155       /* We get an execution file name by simply replacing the leading
1156 	 D in the received file name with an X.  This pretty much
1157 	 always has to work since we can always receive a file name
1158 	 starting with X, so the system dependent code must be
1159 	 prepared to see one.  */
1160       zxqt = zbufcpy (qtrans->s.zto);
1161       zxqt[0] = 'X';
1162       zxqtfile = zsysdep_spool_file_name (qdaemon->qsys, zxqt,
1163 					  (pointer) NULL);
1164       ubuffree (zxqt);
1165 
1166       if (zxqtfile == NULL)
1167 	{
1168 	  urrec_free (qtrans);
1169 	  return FALSE;
1170 	}
1171 
1172       /* We have to write via a temporary file, because otherwise
1173 	 uuxqt might pick up the file before we have finished writing
1174 	 it.  */
1175       e = NULL;
1176       ztemp = zsysdep_receive_temp (qdaemon->qsys, zxqtfile, "D.0",
1177 				    (qdaemon->qproto->frestart
1178 				     && (qdaemon->ifeatures
1179 					 & FEATURE_RESTART) != 0));
1180       if (ztemp != NULL)
1181 	e = esysdep_fopen (ztemp, FALSE, FALSE, TRUE);
1182 
1183       if (e == NULL)
1184 	{
1185 	  ubuffree (zxqtfile);
1186 	  ubuffree (ztemp);
1187 	  urrec_free (qtrans);
1188 	  return FALSE;
1189 	}
1190 
1191       if (! fcmd_needs_quotes (&qtrans->s))
1192 	{
1193 	  fprintf (e, "U %s %s\n", qtrans->s.zuser,
1194 		   qdaemon->qsys->uuconf_zname);
1195 	  fprintf (e, "F %s\n", qtrans->s.zto);
1196 	  fprintf (e, "I %s\n", qtrans->s.zto);
1197 	  if (strchr (qtrans->s.zoptions, 'R') != NULL)
1198 	    fprintf (e, "R %s\n", qtrans->s.znotify);
1199 	  fprintf (e, "C %s\n", qtrans->s.zcmd);
1200 	}
1201       else
1202 	{
1203 	  char *z1;
1204 	  char *z2;
1205 
1206 	  fprintf (e, "Q\n");
1207 
1208 	  z1 = zquote_cmd_string (qtrans->s.zuser, FALSE);
1209 	  z2 = zquote_cmd_string (qdaemon->qsys->uuconf_zname, FALSE);
1210 	  fprintf (e, "U %s %s\n", z1, z2);
1211 	  ubuffree (z1);
1212 	  ubuffree (z2);
1213 
1214 	  z1 = zquote_cmd_string (qtrans->s.zto, FALSE);
1215 	  fprintf (e, "F %s\n", z1);
1216 	  fprintf (e, "I %s\n", z1);
1217 	  ubuffree (z1);
1218 
1219 	  if (strchr (qtrans->s.zoptions, 'R') != NULL)
1220 	    {
1221 	      z1 = zquote_cmd_string (qtrans->s.znotify, FALSE);
1222 	      fprintf (e, "R %s\n", z1);
1223 	      ubuffree (z1);
1224 	    }
1225 
1226 	  z1 = zquote_cmd_string (qtrans->s.zcmd, TRUE);
1227 	  fprintf (e, "C %s\n", z1);
1228 	  ubuffree (z1);
1229 	}
1230 
1231       if (strchr (qtrans->s.zoptions, 'N') != NULL)
1232 	fprintf (e, "N\n");
1233       if (strchr (qtrans->s.zoptions, 'Z') != NULL)
1234 	fprintf (e, "Z\n");
1235       if (strchr (qtrans->s.zoptions, 'e') != NULL)
1236 	fprintf (e, "e\n");
1237 
1238       fbad = FALSE;
1239 
1240       if (! fstdiosync (e, ztemp))
1241 	{
1242 	  (void) fclose (e);
1243 	  (void) remove (ztemp);
1244 	  fbad = TRUE;
1245 	}
1246 
1247       if (! fbad)
1248 	{
1249 	  if (fclose (e) == EOF)
1250 	    {
1251 	      ulog (LOG_ERROR, "fclose: %s", strerror (errno));
1252 	      (void) remove (ztemp);
1253 	      fbad = TRUE;
1254 	    }
1255 	}
1256 
1257       if (! fbad)
1258 	{
1259 	  if (! fsysdep_move_file (ztemp, zxqtfile, TRUE, FALSE, FALSE,
1260 				   (const char *) NULL))
1261 	    {
1262 	      (void) remove (ztemp);
1263 	      fbad = TRUE;
1264 	    }
1265 	}
1266 
1267       ubuffree (zxqtfile);
1268       ubuffree (ztemp);
1269 
1270       if (fbad)
1271 	{
1272 	  urrec_free (qtrans);
1273 	  return FALSE;
1274 	}
1275     }
1276 
1277   /* See if we should spawn a uuxqt process.  */
1278   if (zerr == NULL
1279       && (qtrans->s.bcmd == 'E'
1280 	  || (qinfo->fspool && qtrans->s.zto[0] == 'X')))
1281     {
1282       ++qdaemon->cxfiles_received;
1283       if (qdaemon->irunuuxqt > 0
1284 	  && qdaemon->cxfiles_received >= qdaemon->irunuuxqt)
1285 	{
1286 	  if (fspawn_uuxqt (TRUE, qdaemon->qsys->uuconf_zname,
1287 			    qdaemon->zconfig))
1288 	    qdaemon->cxfiles_received = 0;
1289 	}
1290     }
1291 
1292   /* Prepare to send the completion string to the remote system.  If
1293      we have not yet replied to the remote send request, we leave the
1294      transfer structure on the remote queue.  Otherwise we add it to
1295      the send queue.  The psendfn field will already be set.  */
1296   qinfo->fmoved = zerr == NULL;
1297   if (qinfo->freplied)
1298     return fqueue_send (qdaemon, qtrans);
1299 
1300   return TRUE;
1301 }
1302 
1303 /* Send the final confirmation string to the remote system.  */
1304 
1305 static boolean
frec_file_send_confirm(qtrans,qdaemon)1306 frec_file_send_confirm (qtrans, qdaemon)
1307      struct stransfer *qtrans;
1308      struct sdaemon *qdaemon;
1309 {
1310   struct srecinfo *qinfo = (struct srecinfo *) qtrans->pinfo;
1311   const char *zsend;
1312   int ilocal, iremote;
1313 
1314   if (! qinfo->fmoved)
1315     zsend = "CN5";
1316   else if (! qdaemon->frequest_hangup)
1317     zsend = "CY";
1318   else
1319     {
1320 #if DEBUG > 0
1321       if (qdaemon->fmaster)
1322 	ulog (LOG_FATAL, "frec_file_send_confirm: Can't happen");
1323 #endif
1324 
1325       DEBUG_MESSAGE0 (DEBUG_UUCP_PROTO,
1326 		      "frec_send_file_confirm: Requesting remote to transfer control");
1327       zsend = "CYM";
1328     }
1329 
1330   /* If that was a remote command, then, when the confirmation message
1331      is acked, we no longer have to remember that we received that
1332      file.  */
1333   if (! qinfo->flocal && qinfo->fmoved)
1334     usent_receive_ack (qdaemon, qtrans);
1335 
1336   ilocal = qtrans->ilocal;
1337   iremote = qtrans->iremote;
1338 
1339   urrec_free (qtrans);
1340 
1341   return (*qdaemon->qproto->pfsendcmd) (qdaemon, zsend, ilocal, iremote);
1342 }
1343 
1344 /* Discard a temporary file if it is not useful.  A temporary file is
1345    useful if it could be used to restart a receive.  This is called if
1346    the connection is lost.  It is only called if qtrans->frecfile is
1347    TRUE.  */
1348 
1349 boolean
frec_discard_temp(qdaemon,qtrans)1350 frec_discard_temp (qdaemon, qtrans)
1351      struct sdaemon *qdaemon;
1352      struct stransfer *qtrans;
1353 {
1354   struct srecinfo *qinfo = (struct srecinfo *) qtrans->pinfo;
1355 
1356   if ((qdaemon->ifeatures & FEATURE_RESTART) == 0
1357       || qtrans->s.ztemp == NULL
1358       || qtrans->s.ztemp[0] != 'D'
1359       || strcmp (qtrans->s.ztemp, "D.0") == 0)
1360     (void) remove (qinfo->ztemp);
1361   return TRUE;
1362 }
1363