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