1313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/*
2313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Copyright (c) 1983 Regents of the University of California.
3313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * All rights reserved.
4313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *
5313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Redistribution and use in source and binary forms, with or without
6313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * modification, are permitted provided that the following conditions
7313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * are met:
8313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 1. Redistributions of source code must retain the above copyright
9313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *    notice, this list of conditions and the following disclaimer.
10313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 2. Redistributions in binary form must reproduce the above copyright
11313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *    notice, this list of conditions and the following disclaimer in the
12313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *    documentation and/or other materials provided with the distribution.
13313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 3. All advertising materials mentioning features or use of this software
14313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *    must display the following acknowledgement:
15313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *	This product includes software developed by the University of
16313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *	California, Berkeley and its contributors.
17313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 4. Neither the name of the University nor the names of its contributors
18313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *    may be used to endorse or promote products derived from this software
19313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *    without specific prior written permission.
20313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *
21313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * SUCH DAMAGE.
32313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */
33313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
34313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifndef lint
35313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/*static char sccsid[] = "from: @(#)tftpsubs.c	5.6 (Berkeley) 2/28/91";*/
36313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* static char rcsid[] = "$Id: tftpsubs.c,v 1.2 1993/08/01 18:07:04 mycroft Exp $"; */
37313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif /* not lint */
38313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
39313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* Simple minded read-ahead/write-behind subroutines for tftp user and
40313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti   server.  Written originally with multiple buffers in mind, but current
41313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti   implementation has two buffer logic wired in.
42313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
43313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti   Todo:  add some sort of final error check so when the write-buffer
44313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti   is finally flushed, the caller can detect if the disk filled up
45313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti   (or had an i/o error) and return a nak to the other side.
46313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
47313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			Jim Guyton 10/85
48313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */
49313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
50313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/types.h>
51313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/socket.h>
52313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/ioctl.h>
53313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <netinet/in.h>
54313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <unistd.h>
55313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <stdio.h>
56313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
57313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include "tftp.h"
58313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
59313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define PKTSIZE SEGSIZE+4       /* should be moved to tftp.h */
60313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
61313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistruct bf {
62313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	int counter;            /* size of data in buffer, or flag */
63313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	char buf[PKTSIZE];      /* room for data packet */
64313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} bfs[2];
65313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
66313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				/* Values for bf.counter  */
67313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define BF_ALLOC -3             /* alloc'd but not yet filled */
68313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define BF_FREE  -2             /* free */
69313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* [-1 .. SEGSIZE] = size of data in the data buffer */
70313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
71313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic int nextone;     /* index of next buffer to use */
72313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistatic int current;     /* index of buffer in use */
73313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
74313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			/* control flags for crlf conversions */
75313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint newline = 0;        /* fillbuf: in middle of newline expansion */
76313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint prevchar = -1;      /* putbuf: previous char (cr check) */
77313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
78313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistruct tftphdr *rw_init(int);
79313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
80313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistruct tftphdr *w_init() { return rw_init(0); }         /* write-behind */
81313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistruct tftphdr *r_init() { return rw_init(1); }         /* read-ahead */
82313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
83313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* init for either read-ahead or write-behind */
84313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* x is zero for write-behind, one for read-head */
85313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistruct tftphdr *rw_init(int x)
86313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{
87313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	newline = 0;            /* init crlf flag */
88313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	prevchar = -1;
89313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	bfs[0].counter =  BF_ALLOC;     /* pass out the first buffer */
90313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	current = 0;
91313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	bfs[1].counter = BF_FREE;
92313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	nextone = x;                    /* ahead or behind? */
93313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	return (struct tftphdr *)bfs[0].buf;
94313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}
95313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
96313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
97313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* Have emptied current buffer by sending to net and getting ack.
98313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti   Free it and return next buffer filled with data.
99313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */
100313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint readit(FILE * file, struct tftphdr **dpp, int convert)
101313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{
102313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	struct bf *b;
103313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
104313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	bfs[current].counter = BF_FREE; /* free old one */
105313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	current = !current;             /* "incr" current */
106313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
107313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	b = &bfs[current];              /* look at new buffer */
108313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	if (b->counter == BF_FREE)      /* if it's empty */
109313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		read_ahead(file, convert);      /* fill it */
110313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if 0
111313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	assert(b->counter != BF_FREE);  /* check */
112313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif
113313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	*dpp = (struct tftphdr *)b->buf;        /* set caller's ptr */
114313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	return b->counter;
115313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}
116313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
117313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/*
118313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * fill the input buffer, doing ascii conversions if requested
119313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * conversions are  lf -> cr,lf  and cr -> cr, nul
120313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */
121313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittivoid read_ahead(FILE *file, int convert)
122313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{
123313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	register int i;
124313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	register char *p;
125313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	register int c;
126313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	struct bf *b;
127313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	struct tftphdr *dp;
128313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
129313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	b = &bfs[nextone];              /* look at "next" buffer */
130313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	if (b->counter != BF_FREE)      /* nop if not free */
131313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		return;
132313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	nextone = !nextone;             /* "incr" next buffer ptr */
133313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
134313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	dp = (struct tftphdr *)b->buf;
135313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
136313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	if (convert == 0) {
137313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		b->counter = read(fileno(file), dp->th_data, SEGSIZE);
138313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		return;
139313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	}
140313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
141313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	p = dp->th_data;
142313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	for (i = 0 ; i < SEGSIZE; i++) {
143313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		if (newline) {
144313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (prevchar == '\n')
145313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				c = '\n';       /* lf to cr,lf */
146313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			else    c = '\0';       /* cr to cr,nul */
147313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			newline = 0;
148313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		}
149313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		else {
150313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			c = getc(file);
151313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (c == EOF) break;
152313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			if (c == '\n' || c == '\r') {
153313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				prevchar = c;
154313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				c = '\r';
155313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti				newline = 1;
156313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			}
157313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		}
158313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	       *p++ = c;
159313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	}
160313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	b->counter = (int)(p - dp->th_data);
161313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}
162313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
163313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* Update count associated with the buffer, get new buffer
164313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti   from the queue.  Calls write_behind only if next buffer not
165313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti   available.
166313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */
167313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint writeit(FILE *file, struct tftphdr **dpp, int ct, int convert)
168313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{
169313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	bfs[current].counter = ct;      /* set size of data to write */
170313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	current = !current;             /* switch to other buffer */
171313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	if (bfs[current].counter != BF_FREE)     /* if not free */
172313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		write_behind(file, convert);     /* flush it */
173313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	bfs[current].counter = BF_ALLOC;        /* mark as alloc'd */
174313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	*dpp =  (struct tftphdr *)bfs[current].buf;
175313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	return ct;                      /* this is a lie of course */
176313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}
177313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
178313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/*
179313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Output a buffer to a file, converting from netascii if requested.
180313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * CR,NUL -> CR  and CR,LF => LF.
181313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Note spec is undefined if we get CR as last byte of file or a
182313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * CR followed by anything else.  In this case we leave it alone.
183313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */
184313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint write_behind(FILE *file, int convert)
185313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{
186313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	char *buf;
187313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	int count;
188313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	register int ct;
189313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	register char *p;
190313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	register int c;                 /* current character */
191313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	struct bf *b;
192313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	struct tftphdr *dp;
193313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
194313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	b = &bfs[nextone];
195313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	if (b->counter < -1)            /* anything to flush? */
196313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		return 0;               /* just nop if nothing to do */
197313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
198313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	count = b->counter;             /* remember byte count */
199313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	b->counter = BF_FREE;           /* reset flag */
200313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	dp = (struct tftphdr *)b->buf;
201313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	nextone = !nextone;             /* incr for next time */
202313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	buf = dp->th_data;
203313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
204313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	if (count <= 0) return -1;      /* nak logic? */
205313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
206313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	if (convert == 0)
207313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		return write(fileno(file), buf, count);
208313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
209313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	p = buf;
210313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	ct = count;
211313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	while (ct--) {                  /* loop over the buffer */
212313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	    c = *p++;                   /* pick up a character */
213313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	    if (prevchar == '\r') {     /* if prev char was cr */
214313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		if (c == '\n')          /* if have cr,lf then just */
215313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		   fseek(file, -1, 1);  /* smash lf on top of the cr */
216313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		else
217313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		   if (c == '\0')       /* if have cr,nul then */
218313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			goto skipit;    /* just skip over the putc */
219313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		/* else just fall through and allow it */
220313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	    }
221313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	    putc(c, file);
222313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiskipit:
223313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	    prevchar = c;
224313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	}
225313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	return count;
226313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}
227313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
228313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
229313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* When an error has occurred, it is possible that the two sides
230313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * are out of synch.  Ie: that what I think is the other side's
231313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * response to packet N is really their response to packet N-1.
232313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *
233313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * So, to try to prevent that, we flush all the input queued up
234313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * for us on the network connection on our host.
235313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *
236313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * We return the number of packets we flushed (mostly for reporting
237313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * when trace is active).
238313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */
239313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
240313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint synchnet(int f)
241313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{
242313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	int j = 0;
243313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	char dummy;
244313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti
245313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	while (1) {
246313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		if (recv(f, &dummy, 1, MSG_DONTWAIT) < 0)
247313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti			break;
248313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti		j++;
249313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	}
250313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti	return j;
251313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}
252