|
|
1.1 root 1: /* prot.c
2: Protocol support routines to move commands and data around.
3:
4: Copyright (C) 1991, 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA.
21:
22: The author of the program may be contacted at [email protected] or
23: c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
24: */
25:
26: #include "uucp.h"
27:
28: #if USE_RCS_ID
29: const char prot_rcsid[] = "$Id: prot.c,v 1.1 93/07/30 07:53:15 bin Exp Locker: bin $";
30: #endif
31:
32: #include <errno.h>
33:
34: #include "uudefs.h"
35: #include "system.h"
36: #include "conn.h"
37: #include "prot.h"
38:
39: /* Variables visible to the protocol-specific routines. */
40:
41: /* Buffer to hold received data. */
42: char abPrecbuf[CRECBUFLEN];
43:
44: /* Index of start of data in abPrecbuf. */
45: int iPrecstart;
46:
47: /* Index of end of data (first byte not included in data) in abPrecbuf. */
48: int iPrecend;
49:
50: /* We want to output and input at the same time, if supported on this
51: machine. If we have something to send, we send it all while
52: accepting a large amount of data. Once we have sent everything we
53: look at whatever we have received. If data comes in faster than we
54: can send it, we may run out of buffer space. */
55:
56: boolean
57: fsend_data (qconn, zsend, csend, fdoread)
58: struct sconnection *qconn;
59: const char *zsend;
60: size_t csend;
61: boolean fdoread;
62: {
63: if (! fdoread)
64: return fconn_write (qconn, zsend, csend);
65:
66: while (csend > 0)
67: {
68: size_t crec, csent;
69:
70: if (iPrecend < iPrecstart)
71: crec = iPrecstart - iPrecend - 1;
72: else
73: {
74: crec = CRECBUFLEN - iPrecend;
75: if (iPrecstart == 0)
76: --crec;
77: }
78:
79: csent = csend;
80:
81: if (! fconn_io (qconn, zsend, &csent, abPrecbuf + iPrecend, &crec))
82: return FALSE;
83:
84: csend -= csent;
85: zsend += csent;
86:
87: iPrecend = (iPrecend + crec) % CRECBUFLEN;
88: }
89:
90: return TRUE;
91: }
92:
93: /* Read data from the other system when we have nothing to send. The
94: argument cneed is the amount of data the caller wants, and ctimeout
95: is the timeout in seconds. The function sets *pcrec to the amount
96: of data which was actually received, which may be less than cneed
97: if there isn't enough room in the receive buffer. If no data is
98: received before the timeout expires, *pcrec will be returned as 0.
99: If an error occurs, the function returns FALSE. If the freport
100: argument is FALSE, no error should be reported. */
101:
102: boolean
103: freceive_data (qconn, cneed, pcrec, ctimeout, freport)
104: struct sconnection *qconn;
105: size_t cneed;
106: size_t *pcrec;
107: int ctimeout;
108: boolean freport;
109: {
110: /* Set *pcrec to the maximum amount of data we can read. fconn_read
111: expects *pcrec to be the buffer size, and sets it to the amount
112: actually received. */
113: if (iPrecend < iPrecstart)
114: *pcrec = iPrecstart - iPrecend - 1;
115: else
116: {
117: *pcrec = CRECBUFLEN - iPrecend;
118: if (iPrecstart == 0)
119: --(*pcrec);
120: }
121:
122: #if DEBUG > 0
123: /* If we have no room in the buffer, we're in trouble. The
124: protocols must be written to ensure that this can't happen. */
125: if (*pcrec == 0)
126: ulog (LOG_FATAL, "freceive_data: No room in buffer");
127: #endif
128:
129: /* If we don't have room for all the data the caller wants, we
130: simply have to expect less. We'll get the rest later. */
131: if (*pcrec < cneed)
132: cneed = *pcrec;
133:
134: if (! fconn_read (qconn, abPrecbuf + iPrecend, pcrec, cneed, ctimeout,
135: freport))
136: return FALSE;
137:
138: iPrecend = (iPrecend + *pcrec) % CRECBUFLEN;
139:
140: return TRUE;
141: }
142:
143: /* Read a single character. Get it out of the receive buffer if it's
144: there, otherwise ask freceive_data for at least one character.
145: This is used because as a protocol is shutting down freceive_data
146: may read ahead and eat characters that should be read outside the
147: protocol routines. We call freceive_data rather than fconn_read
148: with an argument of 1 so that we can get all the available data in
149: a single system call. The ctimeout argument is the timeout in
150: seconds; the freport argument is FALSE if no error should be
151: reported. This returns a character, or -1 on timeout or -2 on
152: error. */
153:
154: int
155: breceive_char (qconn, ctimeout, freport)
156: struct sconnection *qconn;
157: int ctimeout;
158: boolean freport;
159: {
160: char b;
161:
162: if (iPrecstart == iPrecend)
163: {
164: size_t crec;
165:
166: if (! freceive_data (qconn, sizeof (char), &crec, ctimeout, freport))
167: return -2;
168: if (crec == 0)
169: return -1;
170: }
171:
172: b = abPrecbuf[iPrecstart];
173: iPrecstart = (iPrecstart + 1) % CRECBUFLEN;
174: return BUCHAR (b);
175: }
176:
177: /* Send mail about a file transfer. We send to the given mailing
178: address if there is one, otherwise to the user. */
179:
180: boolean
181: fmail_transfer (fsuccess, zuser, zmail, zwhy, zfromfile, zfromsys,
182: ztofile, ztosys, zsaved)
183: boolean fsuccess;
184: const char *zuser;
185: const char *zmail;
186: const char *zwhy;
187: const char *zfromfile;
188: const char *zfromsys;
189: const char *ztofile;
190: const char *ztosys;
191: const char *zsaved;
192: {
193: const char *zsendto;
194: const char *az[20];
195: int i;
196:
197: if (zmail != NULL && *zmail != '\0')
198: zsendto = zmail;
199: else
200: zsendto = zuser;
201:
202: i = 0;
203: az[i++] = "The file\n\t";
204: if (zfromsys != NULL)
205: {
206: az[i++] = zfromsys;
207: az[i++] = "!";
208: }
209: az[i++] = zfromfile;
210: if (fsuccess)
211: az[i++] = "\nwas successfully transferred to\n\t";
212: else
213: az[i++] = "\ncould not be transferred to\n\t";
214: if (ztosys != NULL)
215: {
216: az[i++] = ztosys;
217: az[i++] = "!";
218: }
219: az[i++] = ztofile;
220: az[i++] = "\nas requested by\n\t";
221: az[i++] = zuser;
222: if (! fsuccess)
223: {
224: az[i++] = "\nfor the following reason:\n\t";
225: az[i++] = zwhy;
226: az[i++] = "\n";
227: }
228: if (zsaved != NULL)
229: {
230: az[i++] = zsaved;
231: az[i++] = "\n";
232: }
233:
234: return fsysdep_mail (zsendto,
235: fsuccess ? "UUCP succeeded" : "UUCP failed",
236: i, az);
237: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.