1 /* trans.c
2    Routines to handle file transfers.
3 
4    Copyright (C) 1992, 1993, 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 trans_rcsid[] = "$FreeBSD$";
29 #endif
30 
31 #include <errno.h>
32 
33 #include "uudefs.h"
34 #include "uuconf.h"
35 #include "prot.h"
36 #include "system.h"
37 #include "trans.h"
38 
39 /* To avoid wasting a lot of time scanning the spool directory, which
40    might cause the remote system to time out, we limit each scan to
41    pick up at most a certain number of files.  */
42 #define COMMANDS_PER_SCAN (200)
43 
44 /* The structure we use when waiting for an acknowledgement of a
45    confirmed received file in fsent_receive_ack.  */
46 
47 struct sreceive_ack
48 {
49   struct sreceive_ack *qnext;
50   char *zto;
51   char *ztemp;
52   boolean fmarked;
53 };
54 
55 /* Local functions.  */
56 
57 static void utqueue P((struct stransfer **, struct stransfer *,
58 		       boolean fhead));
59 static void utdequeue P((struct stransfer *));
60 static void utchanalc P((struct sdaemon *qdaemon, struct stransfer *qtrans));
61 __inline__ static struct stransfer *qtchan P((int ichan));
62 __inline__ static void utchanfree P((struct stransfer *qtrans));
63 static void utfree_queue P((struct stransfer **pq));
64 static boolean fttime P((struct sdaemon *qdaemon, long *pisecs,
65 			 long *pimicros));
66 static boolean fcheck_queue P((struct sdaemon *qdaemon));
67 static boolean ftadd_cmd P((struct sdaemon *qdaemon, const char *z,
68 			    size_t cdata, int iremote, boolean flast));
69 static boolean fremote_hangup_reply P((struct stransfer *qtrans,
70 				       struct sdaemon *qdaemon));
71 static void utfree_receive_ack P((struct sreceive_ack *q));
72 static void utfree_acked P((void));
73 static boolean flocal_poll_file P((struct stransfer *qtrans,
74 				   struct sdaemon *qdaemon));
75 
76 /* Queue of transfer structures that are ready to start which have
77    been requested by the local system.  These are only permitted to
78    start when the local system is the master.  */
79 static struct stransfer *qTlocal;
80 
81 /* Queue of transfer structures that are ready to start which have
82    been requested by the remote system.  These are responses to
83    commands received from the remote system, and should be started as
84    soon as possible.  */
85 static struct stransfer *qTremote;
86 
87 /* Queue of transfer structures that have been started and want to
88    send information.  This should be static, but the 'a' protocol
89    looks at it, at least for now.  */
90 struct stransfer *qTsend;
91 
92 /* Queue of transfer structures that have been started and are waiting
93    to receive information.  */
94 static struct stransfer *qTreceive;
95 
96 /* Queue of free transfer structures.  */
97 static struct stransfer *qTavail;
98 
99 /* Array of transfer structures indexed by local channel number.  This
100    is maintained for local jobs.  */
101 static struct stransfer *aqTchan[IMAX_CHAN + 1];
102 
103 /* Number of local channel numbers currently allocated.  */
104 static int cTchans;
105 
106 /* Next channel number to allocate.  */
107 static int iTchan;
108 
109 /* Array of transfer structures indexed by remote channel number.
110    This is maintained for remote jobs.  */
111 static struct stransfer *aqTremote[IMAX_CHAN + 1];
112 
113 /* The transaction we are currently receiving.  This is used to avoid
114    getting the time too frequently.  */
115 static struct stransfer *qTtiming_rec;
116 
117 /* The time from which to charge any received data.  This is either
118    the last time we charged for received data, or the last time
119    something was put on the empty receive queue.  */
120 static long iTrecsecs;
121 static long iTrecmicros;
122 
123 /* The minimum amount of time, in seconds, to wait between times we
124    check the spool directory, if we are busy transferring data.  If we
125    have nothing to do, we will check the spool directory regardless of
126    how long ago the last check was.  This should probably be
127    configurable.  */
128 #define CCHECKWAIT (600)
129 
130 /* The time we last checked the spool directory for work.  This is set
131    from the return value of ixsysdep_process_time, not ixsysdep_time,
132    for convenience in the routines which use it.  */
133 static long iTchecktime;
134 
135 /* The size of the command we have read so far in ftadd_cmd.  */
136 static size_t cTcmdlen;
137 
138 /* A list of structures used when waiting for an acknowledgement of a
139    confirmed received file in fsent_receive_ack.  */
140 static struct sreceive_ack *qTreceive_ack;
141 
142 /* Queue up a transfer structure before *pq.  This puts it at the head
143    or the tail of the list headed by *pq.  */
144 
145 static void
utqueue(pq,q,fhead)146 utqueue (pq, q, fhead)
147      struct stransfer **pq;
148      struct stransfer *q;
149      boolean fhead;
150 {
151   if (*pq == NULL)
152     {
153       *pq = q;
154       q->qprev = q->qnext = q;
155     }
156   else
157     {
158       q->qnext = *pq;
159       q->qprev = (*pq)->qprev;
160       q->qprev->qnext = q;
161       q->qnext->qprev = q;
162       if (fhead)
163 	*pq = q;
164     }
165   q->pqqueue = pq;
166 }
167 
168 /* Dequeue a transfer structure.  */
169 
170 static void
utdequeue(q)171 utdequeue (q)
172      struct stransfer *q;
173 {
174   if (q->pqqueue != NULL)
175     {
176       if (*(q->pqqueue) == q)
177 	{
178 	  if (q->qnext == q)
179 	    *(q->pqqueue) = NULL;
180 	  else
181 	    *(q->pqqueue) = q->qnext;
182 	}
183       q->pqqueue = NULL;
184     }
185   if (q->qprev != NULL)
186     q->qprev->qnext = q->qnext;
187   if (q->qnext != NULL)
188     q->qnext->qprev = q->qprev;
189   q->qprev = NULL;
190   q->qnext = NULL;
191 }
192 
193 /* Queue up a transfer structure requested by the local system.  */
194 
195 /*ARGSIGNORED*/
196 boolean
fqueue_local(qdaemon,qtrans)197 fqueue_local (qdaemon, qtrans)
198      struct sdaemon *qdaemon ATTRIBUTE_UNUSED;
199      struct stransfer *qtrans;
200 {
201   utdequeue (qtrans);
202   utqueue (&qTlocal, qtrans, FALSE);
203   return TRUE;
204 }
205 
206 /* Queue up a transfer structure requested by the remote system.  The
207    stransfer structure should have the iremote field set.  We need to
208    record it, so that any subsequent data associated with this
209    channel can be routed to the right place.  */
210 
211 boolean
fqueue_remote(qdaemon,qtrans)212 fqueue_remote (qdaemon, qtrans)
213      struct sdaemon *qdaemon ATTRIBUTE_UNUSED;
214      struct stransfer *qtrans;
215 {
216   DEBUG_MESSAGE1 (DEBUG_UUCP_PROTO, "fqueue_remote: Channel %d",
217 		  qtrans->iremote);
218   if (qtrans->iremote > 0)
219     aqTremote[qtrans->iremote] = qtrans;
220   utdequeue (qtrans);
221   utqueue (&qTremote, qtrans, FALSE);
222   return TRUE;
223 }
224 
225 /* Queue up a transfer with something to send.  */
226 
227 boolean
fqueue_send(qdaemon,qtrans)228 fqueue_send (qdaemon, qtrans)
229      struct sdaemon *qdaemon ATTRIBUTE_UNUSED;
230      struct stransfer *qtrans;
231 {
232 #if DEBUG > 0
233   if (qtrans->psendfn == NULL)
234     ulog (LOG_FATAL, "fqueue_send: Bad call");
235 #endif
236   utdequeue (qtrans);
237 
238   /* Sort the send queue to always send commands before files, and to
239      sort jobs by grade.  */
240   if (qTsend == NULL)
241     utqueue (&qTsend, qtrans, FALSE);
242   else
243     {
244       register struct stransfer *q;
245       boolean ffirst;
246 
247       ffirst = TRUE;
248       q = qTsend;
249       do
250 	{
251 	  if (! qtrans->fsendfile && q->fsendfile)
252 	    break;
253 	  if ((! qtrans->fsendfile || q->fsendfile)
254 	      && UUCONF_GRADE_CMP (qtrans->s.bgrade, q->s.bgrade) < 0)
255 	    break;
256 
257 	  ffirst = FALSE;
258 	  q = q->qnext;
259 	}
260       while (q != qTsend);
261 
262       qtrans->qnext = q;
263       qtrans->qprev = q->qprev;
264       q->qprev = qtrans;
265       qtrans->qprev->qnext = qtrans;
266       if (ffirst)
267 	qTsend = qtrans;
268       qtrans->pqqueue = &qTsend;
269     }
270 
271   return TRUE;
272 }
273 
274 /* Queue up a transfer with something to receive.  */
275 
276 boolean
fqueue_receive(qdaemon,qtrans)277 fqueue_receive (qdaemon, qtrans)
278      struct sdaemon *qdaemon ATTRIBUTE_UNUSED;
279      struct stransfer *qtrans;
280 {
281 #if DEBUG > 0
282   if (qtrans->precfn == NULL)
283     ulog (LOG_FATAL, "fqueue_receive: Bad call");
284 #endif
285 
286   /* If this is the only item on the receive queue, we do not want to
287      charge it for any time during which we have not been waiting for
288      anything, so update the receive timestamp.  */
289   if (qTreceive == NULL)
290     iTrecsecs = ixsysdep_process_time (&iTrecmicros);
291 
292   utdequeue (qtrans);
293   utqueue (&qTreceive, qtrans, FALSE);
294 
295   return TRUE;
296 }
297 
298 /* Get a new local channel number.  */
299 
300 static void
utchanalc(qdaemon,qtrans)301 utchanalc (qdaemon, qtrans)
302      struct sdaemon *qdaemon;
303      struct stransfer *qtrans;
304 {
305   do
306     {
307       ++iTchan;
308       if (iTchan > qdaemon->cchans)
309 	iTchan = 1;
310     }
311   while (aqTchan[iTchan] != NULL);
312 
313   qtrans->ilocal = iTchan;
314   aqTchan[iTchan] = qtrans;
315   ++cTchans;
316 }
317 
318 /* Return the transfer for a channel number.  */
319 
320 __inline__
321 static struct stransfer *
qtchan(ic)322 qtchan (ic)
323      int ic;
324 {
325   return aqTchan[ic];
326 }
327 
328 /* Clear the channel number for a transfer.  */
329 
330 __inline__
331 static void
utchanfree(qt)332 utchanfree (qt)
333      struct stransfer *qt;
334 {
335   if (qt->ilocal != 0)
336     {
337       aqTchan[qt->ilocal] = NULL;
338       qt->ilocal = 0;
339       --cTchans;
340     }
341 }
342 
343 /* Allocate a new transfer structure.  */
344 
345 struct stransfer *
qtransalc(qcmd)346 qtransalc (qcmd)
347      struct scmd *qcmd;
348 {
349   register struct stransfer *q;
350 
351   q = qTavail;
352   if (q != NULL)
353     utdequeue (q);
354   else
355     q = (struct stransfer *) xmalloc (sizeof (struct stransfer));
356   q->qnext = NULL;
357   q->qprev = NULL;
358   q->pqqueue = NULL;
359   q->psendfn = NULL;
360   q->precfn = NULL;
361   q->pinfo = NULL;
362   q->fsendfile = FALSE;
363   q->frecfile = FALSE;
364   q->e = EFILECLOSED;
365   q->ipos = 0;
366   q->fcmd = FALSE;
367   q->zcmd = NULL;
368   q->ccmd = 0;
369   q->ilocal = 0;
370   q->iremote = 0;
371   if (qcmd != NULL)
372     {
373       q->s = *qcmd;
374       q->s.zfrom = zbufcpy (qcmd->zfrom);
375       q->s.zto = zbufcpy (qcmd->zto);
376       q->s.zuser = zbufcpy (qcmd->zuser);
377       q->s.zoptions = zbufcpy (qcmd->zoptions);
378       q->s.ztemp = zbufcpy (qcmd->ztemp);
379       q->s.znotify = zbufcpy (qcmd->znotify);
380       q->s.zcmd = zbufcpy (qcmd->zcmd);
381     }
382   else
383     {
384       q->s.zfrom = NULL;
385       q->s.zto = NULL;
386       q->s.zuser = NULL;
387       q->s.zoptions = NULL;
388       q->s.ztemp = NULL;
389       q->s.znotify = NULL;
390       q->s.zcmd = NULL;
391     }
392   q->zlog = NULL;
393   q->isecs = 0;
394   q->imicros = 0;
395   q->cbytes = 0;
396 
397   return q;
398 }
399 
400 /* Free a transfer structure.  This does not free any pinfo
401    information that may have been allocated.  */
402 
403 void
utransfree(q)404 utransfree (q)
405      struct stransfer *q;
406 {
407   ubuffree (q->zcmd);
408   ubuffree ((char *) q->s.zfrom);
409   ubuffree ((char *) q->s.zto);
410   ubuffree ((char *) q->s.zuser);
411   ubuffree ((char *) q->s.zoptions);
412   ubuffree ((char *) q->s.ztemp);
413   ubuffree ((char *) q->s.znotify);
414   ubuffree ((char *) q->s.zcmd);
415 
416   utchanfree (q);
417   if (q->iremote > 0)
418     {
419       aqTremote[q->iremote] = NULL;
420       q->iremote = 0;
421     }
422 
423   if (ffileisopen (q->e))
424     {
425       (void) ffileclose (q->e);
426       q->e = EFILECLOSED;
427     }
428 
429 #if DEBUG > 0
430   q->zcmd = NULL;
431   q->s.zfrom = NULL;
432   q->s.zto = NULL;
433   q->s.zuser = NULL;
434   q->s.zoptions = NULL;
435   q->s.ztemp = NULL;
436   q->s.znotify = NULL;
437   q->s.zcmd = NULL;
438   q->psendfn = NULL;
439   q->precfn = NULL;
440 #endif
441 
442   /* Avoid any possible confusion in the timing code.  */
443   if (qTtiming_rec == q)
444     qTtiming_rec = NULL;
445 
446   utdequeue (q);
447   utqueue (&qTavail, q, FALSE);
448 }
449 
450 /* Free a queue of transfer structures.  */
451 
452 static void
utfree_queue(pq)453 utfree_queue (pq)
454      struct stransfer **pq;
455 {
456   while (*pq != NULL)
457     utransfree (*pq);
458 }
459 
460 /* Get the time.  This is a wrapper around ixsysdep_process_time.  If
461    enough time has elapsed since the last time we got the time, check
462    the work queue.  */
463 
464 static boolean
fttime(qdaemon,pisecs,pimicros)465 fttime (qdaemon, pisecs, pimicros)
466      struct sdaemon *qdaemon;
467      long *pisecs;
468      long *pimicros;
469 {
470   *pisecs = ixsysdep_process_time (pimicros);
471   if (*pisecs - iTchecktime >= CCHECKWAIT)
472     {
473       if (! fcheck_queue (qdaemon))
474 	return FALSE;
475     }
476   return TRUE;
477 }
478 
479 /* Gather local commands and queue them up for later processing.  Also
480    recompute time based control values.  */
481 
482 boolean
fqueue(qdaemon,pfany)483 fqueue (qdaemon, pfany)
484      struct sdaemon *qdaemon;
485      boolean *pfany;
486 {
487   const struct uuconf_system *qsys;
488   long ival;
489   int bgrade;
490   struct uuconf_timespan *qlocal_size, *qremote_size;
491 
492   if (pfany != NULL)
493     *pfany = FALSE;
494 
495   qsys = qdaemon->qsys;
496 
497   /* If we are not the caller, the grade will be set during the
498      initial handshake, although this may be overridden by the
499      calledtimegrade configuration option.  */
500   if (! qdaemon->fcaller)
501     {
502       if (! ftimespan_match (qsys->uuconf_qcalledtimegrade, &ival,
503 			     (int *) NULL))
504 	bgrade = qdaemon->bgrade;
505       else
506 	bgrade = (char) ival;
507     }
508   else
509     {
510       if (! ftimespan_match (qsys->uuconf_qtimegrade, &ival,
511 			     (int *) NULL))
512 	bgrade = '\0';
513       else
514 	bgrade = (char) ival;
515     }
516 
517   /* Determine the maximum sizes we can send and receive.  */
518   if (qdaemon->fcaller)
519     {
520       qlocal_size = qsys->uuconf_qcall_local_size;
521       qremote_size = qsys->uuconf_qcall_remote_size;
522     }
523   else
524     {
525       qlocal_size = qsys->uuconf_qcalled_local_size;
526       qremote_size = qsys->uuconf_qcalled_remote_size;
527     }
528 
529   if (! ftimespan_match (qlocal_size, &qdaemon->clocal_size, (int *) NULL))
530     qdaemon->clocal_size = (long) -1;
531   if (! ftimespan_match (qremote_size, &qdaemon->cremote_size, (int *) NULL))
532     qdaemon->cremote_size = (long) -1;
533 
534   if (bgrade == '\0')
535     return TRUE;
536 
537   if (! fsysdep_get_work_init (qsys, bgrade, COMMANDS_PER_SCAN))
538     return FALSE;
539 
540   while (TRUE)
541     {
542       struct scmd s;
543 
544       if (! fsysdep_get_work (qsys, bgrade, COMMANDS_PER_SCAN, &s))
545 	return FALSE;
546 
547       if (s.bcmd == 'H')
548 	{
549 	  ulog_user ((const char *) NULL);
550 	  break;
551 	}
552 
553       if (s.bcmd == 'P')
554 	{
555 	  struct stransfer *qtrans;
556 
557 	  /* A poll file.  */
558 	  ulog_user ((const char *) NULL);
559 	  qtrans = qtransalc (&s);
560 	  qtrans->psendfn = flocal_poll_file;
561 	  if (! fqueue_local (qdaemon, qtrans))
562 	    return FALSE;
563 	  continue;
564 	}
565 
566       ulog_user (s.zuser);
567 
568       switch (s.bcmd)
569 	{
570 	case 'S':
571 	case 'E':
572 	  if (! flocal_send_file_init (qdaemon, &s))
573 	    return FALSE;
574 	  break;
575 	case 'R':
576 	  if (! flocal_rec_file_init (qdaemon, &s))
577 	    return FALSE;
578 	  break;
579 	case 'X':
580 	  if (! flocal_xcmd_init (qdaemon, &s))
581 	    return FALSE;
582 	  break;
583 #if DEBUG > 0
584 	default:
585 	  ulog (LOG_FATAL, "fqueue: Can't happen");
586 	  break;
587 #endif
588 	}
589     }
590 
591   if (pfany != NULL)
592     *pfany = qTlocal != NULL;
593 
594   iTchecktime = ixsysdep_process_time ((long *) NULL);
595 
596   return TRUE;
597 }
598 
599 /* Clear everything off the work queue.  This is used when the call is
600    complete, or if the call is never made.  */
601 
602 void
uclear_queue(qdaemon)603 uclear_queue (qdaemon)
604      struct sdaemon *qdaemon;
605 {
606   int i;
607 
608   usysdep_get_work_free (qdaemon->qsys);
609 
610   utfree_queue (&qTlocal);
611   utfree_queue (&qTremote);
612   utfree_queue (&qTsend);
613   utfree_queue (&qTreceive);
614   cTchans = 0;
615   iTchan = 0;
616   qTtiming_rec = NULL;
617   cTcmdlen = 0;
618   if (qTreceive_ack != NULL)
619     utfree_acked ();
620   for (i = 0; i < IMAX_CHAN + 1; i++)
621     {
622       aqTchan[i] = NULL;
623       aqTremote[i] = NULL;
624     }
625 }
626 
627 /* Recheck the work queue during a conversation.  This is only called
628    if it's been more than CCHECKWAIT seconds since the last time the
629    queue was checked.  */
630 
631 static boolean
fcheck_queue(qdaemon)632 fcheck_queue (qdaemon)
633      struct sdaemon *qdaemon;
634 {
635   /* Only check if we are the master, or if there are multiple
636      channels, or if we aren't already trying to get the other side to
637      hang up.  Otherwise, there's nothing we can do with any new jobs
638      we might find.  */
639   if (qdaemon->fmaster
640       || qdaemon->cchans > 1
641       || ! qdaemon->frequest_hangup)
642     {
643       boolean fany;
644 
645       DEBUG_MESSAGE0 (DEBUG_UUCP_PROTO,
646 		      "fcheck_queue: Rechecking work queue");
647       if (! fqueue (qdaemon, &fany))
648 	return FALSE;
649 
650       /* If we found something to do, and we're not the master, and we
651 	 don't have multiple channels to send new jobs over, try to
652 	 get the other side to hang up.  */
653       if (fany && ! qdaemon->fmaster && qdaemon->cchans <= 1)
654 	qdaemon->frequest_hangup = TRUE;
655     }
656 
657   return TRUE;
658 }
659 
660 /* The main transfer loop.  The uucico daemon spends essentially all
661    its time in this function.  */
662 
663 boolean
floop(qdaemon)664 floop (qdaemon)
665      struct sdaemon *qdaemon;
666 {
667   boolean fret;
668 
669   fret = TRUE;
670 
671   while (! qdaemon->fhangup)
672     {
673       register struct stransfer *q;
674 
675 #if DEBUG > 1
676       /* If we're doing any debugging, close the log and debugging
677 	 files regularly.  This will let people copy them off and
678 	 remove them while the conversation is in progresss.  */
679       if (iDebug != 0)
680 	{
681 	  ulog_close ();
682 	  ustats_close ();
683 	}
684 #endif
685 
686       if (qdaemon->fmaster)
687 	{
688 	  boolean fhangup;
689 
690 	  /* We've managed to become the master, so we no longer want
691 	     to request a hangup.  */
692 	  qdaemon->frequest_hangup = FALSE;
693 
694 	  fhangup = FALSE;
695 
696 	  if (qdaemon->fhangup_requested
697 	      && qTsend == NULL
698 	      && (qTreceive == NULL || qdaemon->cchans > 1))
699 	    {
700 	      /* The remote system has requested that we transfer
701 		 control by sending CYM after receiving a file.  */
702 	      DEBUG_MESSAGE0 (DEBUG_UUCP_PROTO,
703 			      "floop: Transferring control at remote request");
704 	      fhangup = TRUE;
705 	    }
706 	  else if (qTremote == NULL
707 		   && qTlocal == NULL
708 		   && qTsend == NULL
709 		   && qTreceive == NULL)
710 	    {
711 	      /* We don't have anything to do.  Try to find some new
712 		 jobs.  If we can't, transfer control.  */
713 	      if (! fqueue (qdaemon, (boolean *) NULL))
714 		{
715 		  fret = FALSE;
716 		  break;
717 		}
718 	      if (qTlocal == NULL)
719 		{
720 		  DEBUG_MESSAGE0 (DEBUG_UUCP_PROTO,
721 				  "floop: No work for master");
722 		  fhangup = TRUE;
723 		}
724 	    }
725 
726 	  if (fhangup)
727 	    {
728 	      if (! (*qdaemon->qproto->pfsendcmd) (qdaemon, "H", 0, 0))
729 		{
730 		  fret = FALSE;
731 		  break;
732 		}
733 	      qdaemon->fmaster = FALSE;
734 	    }
735 	}
736 
737       /* If we are no long the master, clear any requested hangup.  We
738 	 may have already hung up before checking this variable in the
739 	 block above.  */
740       if (! qdaemon->fmaster)
741 	qdaemon->fhangup_requested = FALSE;
742 
743       /* Immediately queue up any remote jobs.  We don't need local
744 	 channel numbers for them, since we can disambiguate based on
745 	 the remote channel number.  */
746       while (qTremote != NULL)
747 	{
748 	  q = qTremote;
749 	  utdequeue (q);
750 	  utqueue (&qTsend, q, TRUE);
751 	}
752 
753       /* If we are the master, or if we have multiple channels, try to
754 	 queue up additional local jobs.  */
755       if (qdaemon->fmaster || qdaemon->cchans > 1)
756 	{
757 	  while (qTlocal != NULL && cTchans < qdaemon->cchans)
758 	    {
759 	      /* We have room for an additional channel.  */
760 	      q = qTlocal;
761 	      if (! fqueue_send (qdaemon, q))
762 		{
763 		  fret = FALSE;
764 		  break;
765 		}
766 	      utchanalc (qdaemon, q);
767 	    }
768 	  if (! fret)
769 	    break;
770 	}
771 
772       q = qTsend;
773 
774       if (q == NULL)
775 	{
776 	  ulog_user ((const char *) NULL);
777 	  DEBUG_MESSAGE0 (DEBUG_UUCP_PROTO, "floop: Waiting for data");
778 	  if (! (*qdaemon->qproto->pfwait) (qdaemon))
779 	    {
780 	      fret = FALSE;
781 	      break;
782 	    }
783 	}
784       else
785 	{
786 	  ulog_user (q->s.zuser);
787 
788 	  if (! q->fsendfile)
789 	    {
790 	      /* Technically, we should add the time required for this
791                  call to q->isecs and q->imicros.  In practice, the
792                  amount of time required should be sufficiently small
793                  that it can be safely disregarded.  */
794 	      if (! (*q->psendfn) (q, qdaemon))
795 		{
796 		  fret = FALSE;
797 		  break;
798 		}
799 	    }
800 	  else
801 	    {
802 	      long isecs, imicros;
803 	      boolean fcharged;
804 	      long cmax_time;
805 	      long istart = 0;
806 	      long inextsecs = 0, inextmicros;
807 
808 	      if (! fttime (qdaemon, &isecs, &imicros))
809 		{
810 		  fret = FALSE;
811 		  break;
812 		}
813 	      fcharged = FALSE;
814 
815 	      if (q->zlog != NULL)
816 		{
817 		  ulog (LOG_NORMAL, "%s", q->zlog);
818 		  ubuffree (q->zlog);
819 		  q->zlog = NULL;
820 		}
821 
822 	      cmax_time = qdaemon->qsys->uuconf_cmax_file_time;
823 	      if (qdaemon->cchans <= 1)
824 		cmax_time = 0;
825 	      if (cmax_time > 0)
826 		istart = ixsysdep_time (NULL);
827 
828 	      /* We can read the file in a tight loop until we have a
829 		 command to send, or the file send has been cancelled,
830 		 or we have a remote job to deal with, or the maximum
831 		 file send time has been exceeded.  We can disregard
832 		 any changes to qTlocal since we already have
833 		 something to send anyhow.  */
834 	      while (q == qTsend
835 		     && q->fsendfile
836 		     && qTremote == NULL)
837 		{
838 		  char *zdata;
839 		  size_t cdata;
840 		  long ipos;
841 
842 		  zdata = (*qdaemon->qproto->pzgetspace) (qdaemon, &cdata);
843 		  if (zdata == NULL)
844 		    {
845 		      fret = FALSE;
846 		      break;
847 		    }
848 
849 		  if (ffileeof (q->e))
850 		    cdata = 0;
851 		  else
852 		    {
853 		      cdata = cfileread (q->e, zdata, cdata);
854 		      if (ffileioerror (q->e, cdata))
855 			{
856 			  /* There is no way to report a file reading
857 			     error, so we just drop the connection.  */
858 			  ulog (LOG_ERROR, "read: %s", strerror (errno));
859 			  fret = FALSE;
860 			  break;
861 			}
862 		    }
863 
864 		  ipos = q->ipos;
865 		  q->ipos += cdata;
866 		  q->cbytes += cdata;
867 
868 		  if (! (*qdaemon->qproto->pfsenddata) (qdaemon, zdata,
869 							cdata, q->ilocal,
870 							q->iremote, ipos))
871 		    {
872 		      fret = FALSE;
873 		      break;
874 		    }
875 
876 		  if (cdata == 0)
877 		    {
878 		      /* We must update the time now, because this
879 			 call may make an entry in the statistics
880 			 file.  */
881 		      inextsecs = ixsysdep_process_time (&inextmicros);
882 		      DEBUG_MESSAGE4 (DEBUG_UUCP_PROTO,
883 				      "floop: Charging %ld to %c %s %s",
884 				      ((inextsecs - isecs) * 1000000
885 				       + inextmicros - imicros),
886 				      q->s.bcmd, q->s.zfrom, q->s.zto);
887 		      q->isecs += inextsecs - isecs;
888 		      q->imicros += inextmicros - imicros;
889 		      fcharged = TRUE;
890 
891 		      q->fsendfile = FALSE;
892 
893 		      if (! (*q->psendfn) (q, qdaemon))
894 			fret = FALSE;
895 
896 		      break;
897 		    }
898 
899 		  if (cmax_time > 0
900 		      && q->qnext != q
901 		      && ixsysdep_time (NULL) - istart >= cmax_time)
902 		    {
903 		      DEBUG_MESSAGE0 (DEBUG_UUCP_PROTO, "floop: Switch file");
904 		      utdequeue (q);
905 		      utqueue (&qTsend, q, FALSE);
906 		    }
907 		}
908 
909 	      if (! fret)
910 		break;
911 
912 	      if (! fcharged)
913 		{
914 		  inextsecs = ixsysdep_process_time (&inextmicros);
915 		  DEBUG_MESSAGE4 (DEBUG_UUCP_PROTO,
916 				  "floop: Charging %ld to %c %s %s",
917 				  ((inextsecs - isecs) * 1000000
918 				   + inextmicros - imicros),
919 				  q->s.bcmd, q->s.zfrom, q->s.zto);
920 		  q->isecs += inextsecs - isecs;
921 		  q->imicros += inextmicros - imicros;
922 		}
923 
924 	      if (inextsecs - iTchecktime >= CCHECKWAIT)
925 		{
926 		  if (! fcheck_queue (qdaemon))
927 		    {
928 		      fret = FALSE;
929 		      break;
930 		    }
931 		}
932 	    }
933 	}
934     }
935 
936   ulog_user ((const char *) NULL);
937 
938   (void) (*qdaemon->qproto->pfshutdown) (qdaemon);
939 
940   if (fret)
941     uwindow_acked (qdaemon, TRUE);
942   else
943     ufailed (qdaemon);
944 
945   return fret;
946 }
947 
948 /* This is called by the protocol routines when they have received
949    some data.  If pfexit is not NULL, *pfexit should be set to TRUE if
950    the protocol receive loop should exit back to the main floop
951    routine, above.  It is only important to set *pfexit to TRUE if the
952    main loop called the pfwait entry point, so we need never set it to
953    TRUE if we just receive data for a file.  This routine never sets
954    *pfexit to FALSE.  */
955 
956 boolean
fgot_data(qdaemon,zfirst,cfirst,zsecond,csecond,ilocal,iremote,ipos,fallacked,pfexit)957 fgot_data (qdaemon, zfirst, cfirst, zsecond, csecond, ilocal, iremote, ipos,
958 	   fallacked, pfexit)
959      struct sdaemon *qdaemon;
960      const char *zfirst;
961      size_t cfirst;
962      const char *zsecond;
963      size_t csecond;
964      int ilocal;
965      int iremote;
966      long ipos;
967      boolean fallacked;
968      boolean *pfexit;
969 {
970   struct stransfer *q;
971   int cwrote;
972   boolean fret;
973   long isecs, imicros;
974 
975   if (fallacked && qTreceive_ack != NULL)
976     uwindow_acked (qdaemon, TRUE);
977 
978   /* Now we have to decide which transfer structure gets the data.  If
979      ilocal is -1, it means that the protocol does not know where to
980      route the data.  In that case we route it to the first transfer
981      that is waiting for data, or, if none, as a new command.  If
982      ilocal is 0, we either select based on the remote channel number
983      or we have a new command.  */
984   if (ilocal == -1 && qTreceive != NULL)
985     q = qTreceive;
986   else if (ilocal == 0 && iremote > 0 && aqTremote[iremote] != NULL)
987     q = aqTremote[iremote];
988   else if (ilocal <= 0)
989     {
990       const char *znull;
991 
992       ulog_user ((const char *) NULL);
993 
994       /* This data is part of a command.  If there is no null
995 	 character in the data, this string will be continued by the
996 	 next packet.  Otherwise this must be the last string in the
997 	 command, and we don't care about what comes after the null
998 	 byte.  */
999       znull = (const char *) memchr (zfirst, '\0', cfirst);
1000       if (znull != NULL)
1001 	fret = ftadd_cmd (qdaemon, zfirst, (size_t) (znull - zfirst),
1002 			  iremote, TRUE);
1003       else
1004 	{
1005 	  fret = ftadd_cmd (qdaemon, zfirst, cfirst, iremote, FALSE);
1006 	  if (fret && csecond > 0)
1007 	    {
1008 	      znull = (const char *) memchr (zsecond, '\0', csecond);
1009 	      if (znull != NULL)
1010 		fret = ftadd_cmd (qdaemon, zsecond,
1011 				  (size_t) (znull - zsecond), iremote, TRUE);
1012 	      else
1013 		fret = ftadd_cmd (qdaemon, zsecond, csecond, iremote, FALSE);
1014 	    }
1015 	}
1016 
1017       if (pfexit != NULL && (qdaemon->fhangup || qTremote != NULL))
1018 	*pfexit = TRUE;
1019 
1020       /* Time spent waiting for a new command is not charged to
1021          anybody.  */
1022       if (! fttime (qdaemon, &iTrecsecs, &iTrecmicros))
1023 	fret = FALSE;
1024 
1025       return fret;
1026     }
1027   else
1028     {
1029       /* Get the transfer structure this data is intended for.  */
1030       q = qtchan (ilocal);
1031     }
1032 
1033 #if DEBUG > 0
1034   if (q == NULL || q->precfn == NULL)
1035     {
1036       ulog (LOG_ERROR, "Protocol error: %lu bytes remote %d local %d",
1037 	    (unsigned long) (cfirst + csecond),
1038 	    iremote, ilocal);
1039       return FALSE;
1040     }
1041 #endif
1042 
1043   ulog_user (q->s.zuser);
1044 
1045   fret = TRUE;
1046 
1047   if (q->zlog != NULL && ! q->fsendfile)
1048     {
1049       ulog (LOG_NORMAL, "%s", q->zlog);
1050       ubuffree (q->zlog);
1051       q->zlog = NULL;
1052     }
1053 
1054   if (cfirst == 0 || q->fcmd || ! q->frecfile || q != qTtiming_rec)
1055     {
1056       struct stransfer *qcharge;
1057 
1058       /* Either we are receiving some sort of command, or we are
1059          receiving data for a transfer other than the one we are
1060          currently timing.  It we are currently timing a transfer,
1061          charge any accumulated time to it.  Otherwise, if we
1062          currently have something to send, just forget about the
1063          accumulated time (when using a bidirectional protocol, it's
1064          very difficult to charge this time correctly).  Otherwise,
1065          charge it to whatever transfer receives it.  */
1066       if (! fttime (qdaemon, &isecs, &imicros))
1067 	fret = FALSE;
1068       if (qTtiming_rec != NULL)
1069 	qcharge = qTtiming_rec;
1070       else if (qTsend != NULL)
1071 	qcharge = NULL;
1072       else
1073 	qcharge = q;
1074       if (qcharge != NULL)
1075 	{
1076 	  DEBUG_MESSAGE4 (DEBUG_UUCP_PROTO,
1077 			  "fgot_data: Charging %ld to %c %s %s",
1078 			  ((isecs - iTrecsecs) * 1000000
1079 			   + imicros - iTrecmicros),
1080 			  qcharge->s.bcmd, qcharge->s.zfrom,
1081 			  qcharge->s.zto);
1082 	  qcharge->isecs += isecs - iTrecsecs;
1083 	  qcharge->imicros += imicros - iTrecmicros;
1084 	}
1085       iTrecsecs = isecs;
1086       iTrecmicros = imicros;
1087 
1088       /* If we received file data, start timing the new transfer.  */
1089       if (cfirst == 0 || q->fcmd || ! q->frecfile)
1090 	qTtiming_rec = NULL;
1091       else
1092 	qTtiming_rec = q;
1093     }
1094 
1095   /* If we're receiving a command, then accumulate it up to the null
1096      byte.  */
1097   if (q->fcmd)
1098     {
1099       const char *znull;
1100 
1101       znull = NULL;
1102       while (cfirst > 0)
1103 	{
1104 	  size_t cnew;
1105 	  char *znew;
1106 
1107 	  znull = (const char *) memchr (zfirst, '\0', cfirst);
1108 	  if (znull != NULL)
1109 	    cnew = znull - zfirst;
1110 	  else
1111 	    cnew = cfirst;
1112 	  znew = zbufalc (q->ccmd + cnew + 1);
1113 	  if (q->ccmd > 0)
1114 	    memcpy (znew, q->zcmd, q->ccmd);
1115 	  memcpy (znew + q->ccmd, zfirst, cnew);
1116 	  znew[q->ccmd + cnew] = '\0';
1117 	  ubuffree (q->zcmd);
1118 	  q->zcmd = znew;
1119 	  q->ccmd += cnew;
1120 
1121 	  if (znull != NULL)
1122 	    break;
1123 
1124 	  zfirst = zsecond;
1125 	  cfirst = csecond;
1126 	  csecond = 0;
1127 	}
1128 
1129       if (znull != NULL)
1130 	{
1131 	  char *zcmd;
1132 	  size_t ccmd;
1133 
1134 	  zcmd = q->zcmd;
1135 	  ccmd = q->ccmd;
1136 	  q->fcmd = FALSE;
1137 	  q->zcmd = NULL;
1138 	  q->ccmd = 0;
1139 	  if (! (*q->precfn) (q, qdaemon, zcmd, ccmd + 1))
1140 	    fret = FALSE;
1141 	  ubuffree (zcmd);
1142 	}
1143 
1144       if (pfexit != NULL
1145 	  && (qdaemon->fhangup
1146 	      || qdaemon->fmaster
1147 	      || qTsend != NULL))
1148 	*pfexit = TRUE;
1149     }
1150   else if (! q->frecfile || cfirst == 0)
1151     {
1152       /* We're either not receiving a file or the file transfer is
1153 	 complete.  */
1154       q->frecfile = FALSE;
1155       if (! (*q->precfn) (q, qdaemon, zfirst, cfirst))
1156 	fret = FALSE;
1157       if (fret && csecond > 0)
1158 	return fgot_data (qdaemon, zsecond, csecond,
1159 			  (const char *) NULL, (size_t) 0,
1160 			  ilocal, iremote, ipos + (long) cfirst,
1161 			  FALSE, pfexit);
1162       if (pfexit != NULL
1163 	  && (qdaemon->fhangup
1164 	      || qdaemon->fmaster
1165 	      || qTsend != NULL))
1166 	*pfexit = TRUE;
1167     }
1168   else
1169     {
1170       if (ipos != -1 && ipos != q->ipos)
1171 	{
1172 	  DEBUG_MESSAGE1 (DEBUG_UUCP_PROTO,
1173 			  "fgot_data: Seeking to %ld", ipos);
1174 	  if (! ffileseek (q->e, ipos))
1175 	    {
1176 	      ulog (LOG_ERROR, "seek: %s", strerror (errno));
1177 	      fret = FALSE;
1178 	    }
1179 	  q->ipos = ipos;
1180 	}
1181 
1182       if (fret)
1183 	{
1184 	  while (cfirst > 0)
1185 	    {
1186 	      cwrote = cfilewrite (q->e, (char *) zfirst, cfirst);
1187 	      if (cwrote >= 0 && (size_t) cwrote == cfirst)
1188 		{
1189 #if FREE_SPACE_DELTA > 0
1190 		  long cfree_space;
1191 
1192 		  /* Check that there is still enough space on the
1193 		     disk.  If there isn't, we drop the connection,
1194 		     because we have no way to abort a file transfer
1195 		     in progress.  */
1196 		  cfree_space = qdaemon->qsys->uuconf_cfree_space;
1197 		  if (cfree_space > 0
1198 		      && ((size_t) (q->cbytes / FREE_SPACE_DELTA)
1199 			  != (q->cbytes + cfirst) / FREE_SPACE_DELTA)
1200 		      && ! frec_check_free (q, cfree_space))
1201 		    {
1202 		      fret = FALSE;
1203 		      break;
1204 		    }
1205 #endif
1206 		  q->cbytes += cfirst;
1207 		  q->ipos += cfirst;
1208 		}
1209 	      else
1210 		{
1211 		  if (ffileioerror (q->e, cwrote))
1212 		    ulog (LOG_ERROR, "write: %s", strerror (errno));
1213 		  else
1214 		    ulog (LOG_ERROR,
1215 			  "Wrote %d to file when trying to write %lu",
1216 			  cwrote, (unsigned long) cfirst);
1217 
1218 		  /* Any write error is almost certainly a temporary
1219 		     condition, or else UUCP would not be functioning
1220 		     at all.  If we continue to accept the file, we
1221 		     will wind up rejecting it at the end (what else
1222 		     could we do?)  and the remote system will throw
1223 		     away the request.  We're better off just dropping
1224 		     the connection, which is what happens when we
1225 		     return FALSE, and trying again later.  */
1226 		  fret = FALSE;
1227 		  break;
1228 		}
1229 
1230 	      zfirst = zsecond;
1231 	      cfirst = csecond;
1232 	      csecond = 0;
1233 	    }
1234 	}
1235 
1236       if (pfexit != NULL && qdaemon->fhangup)
1237 	*pfexit = TRUE;
1238     }
1239 
1240   return fret;
1241 }
1242 
1243 /* Accumulate a string into a command.  If the command is complete,
1244    start up a new transfer.  */
1245 
1246 static boolean
ftadd_cmd(qdaemon,z,clen,iremote,flast)1247 ftadd_cmd (qdaemon, z, clen, iremote, flast)
1248      struct sdaemon *qdaemon;
1249      const char *z;
1250      size_t clen;
1251      int iremote;
1252      boolean flast;
1253 {
1254   static char *zbuf;
1255   static size_t cbuf;
1256   size_t cneed;
1257   struct scmd s;
1258 
1259   cneed = cTcmdlen + clen + 1;
1260   if (cneed > cbuf)
1261     {
1262       zbuf = (char *) xrealloc ((pointer) zbuf, cneed);
1263       cbuf = cneed;
1264     }
1265 
1266   memcpy (zbuf + cTcmdlen, z, clen);
1267   zbuf[cTcmdlen + clen] = '\0';
1268 
1269   if (! flast)
1270     {
1271       cTcmdlen += clen;
1272       return TRUE;
1273     }
1274 
1275   /* Don't save this string for next time.  */
1276   cTcmdlen = 0;
1277 
1278   DEBUG_MESSAGE1 (DEBUG_UUCP_PROTO,
1279 		  "ftadd_cmd: Got command \"%s\"", zbuf);
1280 
1281   if (! fparse_cmd (zbuf, &s)
1282       || s.bcmd == 'P')
1283     {
1284       ulog (LOG_ERROR, "Received garbled command \"%s\"", zbuf);
1285       return TRUE;
1286     }
1287 
1288   /* Some systems seem to sometimes send garbage at the end of the
1289      command.  Avoid interpreting it as a size if sizes are not
1290      supported.  */
1291   if ((qdaemon->ifeatures & FEATURE_SIZES) == 0)
1292     s.cbytes = -1;
1293 
1294   if (s.bcmd != 'H' && s.bcmd != 'Y' && s.bcmd != 'N')
1295     ulog_user (s.zuser);
1296   else
1297     ulog_user ((const char *) NULL);
1298 
1299   switch (s.bcmd)
1300     {
1301     case 'S':
1302     case 'E':
1303       return fremote_send_file_init (qdaemon, &s, iremote);
1304     case 'R':
1305       return fremote_rec_file_init (qdaemon, &s, iremote);
1306     case 'X':
1307       return fremote_xcmd_init (qdaemon, &s, iremote);
1308     case 'H':
1309       /* This is a remote request for a hangup.  We close the log
1310 	 files so that they may be moved at this point.  */
1311       ulog_close ();
1312       ustats_close ();
1313       {
1314 	struct stransfer *q;
1315 
1316 	q = qtransalc ((struct scmd *) NULL);
1317 	q->psendfn = fremote_hangup_reply;
1318 	q->iremote = iremote;
1319 	q->s.bcmd = 'H';
1320 	return fqueue_remote (qdaemon, q);
1321       }
1322     case 'N':
1323       /* This means a hangup request is being denied; we just ignore
1324 	 this and wait for further commands.  */
1325       return TRUE;
1326     case 'Y':
1327       /* This is a remote confirmation of a hangup.  We reconfirm.  */
1328       if (qdaemon->fhangup)
1329 	return TRUE;
1330 #if DEBUG > 0
1331       if (qdaemon->fmaster)
1332 	ulog (LOG_ERROR, "Got hangup reply as master");
1333 #endif
1334       /* Don't check errors rigorously here, since the other side
1335 	 might jump the gun and hang up.  The fLog_sighup variable
1336 	 will get set TRUE again when the port is closed.  */
1337       fLog_sighup = FALSE;
1338       (void) (*qdaemon->qproto->pfsendcmd) (qdaemon, "HY", 0, iremote);
1339       qdaemon->fhangup = TRUE;
1340       return TRUE;
1341 #if DEBUG > 0
1342     default:
1343       ulog (LOG_FATAL, "ftadd_cmd: Can't happen");
1344       return FALSE;
1345 #endif
1346     }
1347 }
1348 
1349 /* The remote system is requesting a hang up.  If we have something to
1350    do, send an HN.  Otherwise send two HY commands (the other side is
1351    presumed to send an HY command between the first and second, but we
1352    don't bother to wait for it) and hang up.  */
1353 
1354 static boolean
fremote_hangup_reply(qtrans,qdaemon)1355 fremote_hangup_reply (qtrans, qdaemon)
1356      struct stransfer *qtrans;
1357      struct sdaemon *qdaemon;
1358 {
1359   boolean fret;
1360 
1361   utransfree (qtrans);
1362 
1363   if (qTremote == NULL
1364       && qTlocal == NULL
1365       && qTsend == NULL
1366       && qTreceive == NULL)
1367     {
1368       if (! fqueue (qdaemon, (boolean *) NULL))
1369 	return FALSE;
1370 
1371       if (qTlocal == NULL)
1372 	{
1373 	  DEBUG_MESSAGE0 (DEBUG_UUCP_PROTO, "fremote_hangup_reply: No work");
1374 	  fret = ((*qdaemon->qproto->pfsendcmd) (qdaemon, "HY", 0, 0)
1375 		  && (*qdaemon->qproto->pfsendcmd) (qdaemon, "HY", 0, 0));
1376 	  qdaemon->fhangup = TRUE;
1377 	  return fret;
1378 	}
1379     }
1380 
1381   DEBUG_MESSAGE0 (DEBUG_UUCP_PROTO, "fremote_hangup_reply: Found work");
1382   fret = (*qdaemon->qproto->pfsendcmd) (qdaemon, "HN", 0, 0);
1383   qdaemon->fmaster = TRUE;
1384   return fret;
1385 }
1386 
1387 /* As described in system.h, we need to keep track of which files have
1388    been successfully received for which we do not know that the other
1389    system has received our acknowledgement.  This routine is called to
1390    keep a list of such files.  */
1391 
1392 static struct sreceive_ack *qTfree_receive_ack;
1393 
1394 void
usent_receive_ack(qdaemon,qtrans)1395 usent_receive_ack (qdaemon, qtrans)
1396      struct sdaemon *qdaemon ATTRIBUTE_UNUSED;
1397      struct stransfer *qtrans;
1398 {
1399   struct sreceive_ack *q;
1400 
1401   if (qTfree_receive_ack == NULL)
1402     q = (struct sreceive_ack *) xmalloc (sizeof (struct sreceive_ack));
1403   else
1404     {
1405       q = qTfree_receive_ack;
1406       qTfree_receive_ack = q->qnext;
1407     }
1408 
1409   q->qnext = qTreceive_ack;
1410   q->zto = zbufcpy (qtrans->s.zto);
1411   q->ztemp = zbufcpy (qtrans->s.ztemp);
1412   q->fmarked = FALSE;
1413 
1414   qTreceive_ack = q;
1415 }
1416 
1417 /* Free an sreceive_ack structure.  */
1418 
1419 static void
utfree_receive_ack(q)1420 utfree_receive_ack (q)
1421      struct sreceive_ack *q;
1422 {
1423   ubuffree (q->zto);
1424   ubuffree (q->ztemp);
1425   q->qnext = qTfree_receive_ack;
1426   qTfree_receive_ack = q;
1427 }
1428 
1429 /* This routine is called by the protocol code when either all
1430    outstanding data has been acknowledged or one complete window has
1431    passed.  It may be called directly by the protocol, or it may be
1432    called via fgot_data.  If one complete window has passed, then all
1433    unmarked receives are marked, and we know that all marked ones have
1434    been acked.  */
1435 
1436 void
uwindow_acked(qdaemon,fallacked)1437 uwindow_acked (qdaemon, fallacked)
1438      struct sdaemon *qdaemon;
1439      boolean fallacked;
1440 {
1441   register struct sreceive_ack **pq;
1442 
1443   pq = &qTreceive_ack;
1444   while (*pq != NULL)
1445     {
1446       if (fallacked || (*pq)->fmarked)
1447 	{
1448 	  struct sreceive_ack *q;
1449 
1450 	  q = *pq;
1451 	  (void) fsysdep_forget_reception (qdaemon->qsys, q->zto, q->ztemp);
1452 	  *pq = q->qnext;
1453 	  utfree_receive_ack (q);
1454 	}
1455       else
1456 	{
1457 	  (*pq)->fmarked = TRUE;
1458 	  pq = &(*pq)->qnext;
1459 	}
1460     }
1461 }
1462 
1463 /* Free the qTreceive_ack list.  */
1464 
1465 static void
utfree_acked()1466 utfree_acked ()
1467 {
1468   struct sreceive_ack *q;
1469 
1470   q = qTreceive_ack;
1471   while (q != NULL)
1472     {
1473       struct sreceive_ack *qnext;
1474 
1475       qnext = q->qnext;
1476       utfree_receive_ack (q);
1477       q = qnext;
1478     }
1479   qTreceive_ack = NULL;
1480 }
1481 
1482 /* This routine is called when an error occurred and we are crashing
1483    out of the connection.  It is used to report statistics on failed
1484    transfers to the statistics file, and it also discards useless
1485    temporary files for file receptions.  Note that the number of bytes
1486    we report as having been sent has little or nothing to do with the
1487    number of bytes the remote site actually received.  */
1488 
1489 void
ufailed(qdaemon)1490 ufailed (qdaemon)
1491      struct sdaemon *qdaemon;
1492 {
1493   register struct stransfer *q;
1494 
1495   if (qTsend != NULL)
1496     {
1497       q = qTsend;
1498       do
1499 	{
1500 	  if ((q->fsendfile || q->frecfile)
1501 	      && q->cbytes > 0)
1502 	    {
1503 	      ustats (FALSE, q->s.zuser, qdaemon->qsys->uuconf_zname,
1504 		      q->fsendfile, q->cbytes, q->isecs, q->imicros,
1505 		      qdaemon->fcaller);
1506 	      if (q->fsendfile)
1507 		qdaemon->csent += q->cbytes;
1508 	      else
1509 		qdaemon->creceived += q->cbytes;
1510 	    }
1511 	  if (q->frecfile)
1512 	    (void) frec_discard_temp (qdaemon, q);
1513 	  q = q->qnext;
1514 	}
1515       while (q != qTsend);
1516     }
1517 
1518   if (qTreceive != NULL)
1519     {
1520       q = qTreceive;
1521       do
1522 	{
1523 	  if ((q->fsendfile || q->frecfile)
1524 	      && q->cbytes > 0)
1525 	    {
1526 	      ustats (FALSE, q->s.zuser, qdaemon->qsys->uuconf_zname,
1527 		      q->fsendfile, q->cbytes, q->isecs, q->imicros,
1528 		      qdaemon->fcaller);
1529 	      if (q->fsendfile)
1530 		qdaemon->csent += q->cbytes;
1531 	      else
1532 		qdaemon->creceived += q->cbytes;
1533 	    }
1534 	  if (q->frecfile)
1535 	    (void) frec_discard_temp (qdaemon, q);
1536 	  q = q->qnext;
1537 	}
1538       while (q != qTreceive);
1539     }
1540 }
1541 
1542 /* When a local poll file is found, it is entered on the queue like
1543    any other job.  When it is pulled off the queue, this function is
1544    called.  It just calls fsysdep_did_work, which will remove the poll
1545    file.  This ensures that poll files are only removed if the system
1546    is actually called.  */
1547 
1548 /*ARGSUSED*/
1549 static boolean
flocal_poll_file(qtrans,qdaemon)1550 flocal_poll_file (qtrans, qdaemon)
1551      struct stransfer *qtrans;
1552      struct sdaemon *qdaemon ATTRIBUTE_UNUSED;
1553 {
1554   boolean fret;
1555 
1556   fret = fsysdep_did_work (qtrans->s.pseq);
1557   utransfree (qtrans);
1558   return fret;
1559 }
1560