|
|
1.1 root 1: /* conn.c
2: Connection routines for the Taylor UUCP package.
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 conn_rcsid[] = "$Id: conn.c,v 1.1 93/07/30 07:52:56 bin Exp Locker: bin $";
30: #endif
31:
32: #include <ctype.h>
33:
34: #include "uudefs.h"
35: #include "uuconf.h"
36: #include "conn.h"
37:
38: static boolean fcdo_dial P((struct sconnection *qconn, pointer puuconf,
39: struct uuconf_dialer *qdialer,
40: const char *zphone, boolean ftranslate));
41:
42: /* Create a new connection. This relies on system dependent functions
43: to set the qcmds and psysdep fields. If qport is NULL, it opens a
44: standard input port. */
45:
46: boolean
47: fconn_init (qport, qconn)
48: struct uuconf_port *qport;
49: struct sconnection *qconn;
50: {
51: qconn->qport = qport;
52: switch (qport == NULL ? UUCONF_PORTTYPE_STDIN : qport->uuconf_ttype)
53: {
54: case UUCONF_PORTTYPE_STDIN:
55: return fsysdep_stdin_init (qconn);
56: case UUCONF_PORTTYPE_MODEM:
57: return fsysdep_modem_init (qconn);
58: case UUCONF_PORTTYPE_DIRECT:
59: return fsysdep_direct_init (qconn);
60: #if HAVE_TCP
61: case UUCONF_PORTTYPE_TCP:
62: return fsysdep_tcp_init (qconn);
63: #endif
64: #if HAVE_TLI
65: case UUCONF_PORTTYPE_TLI:
66: return fsysdep_tli_init (qconn);
67: #endif
68: default:
69: ulog (LOG_ERROR, "Unknown port type");
70: return FALSE;
71: }
72: }
73:
74: /* Connection dispatch routines. */
75:
76: /* Free a connection. */
77:
78: void
79: uconn_free (qconn)
80: struct sconnection *qconn;
81: {
82: (*qconn->qcmds->pufree) (qconn);
83: }
84:
85: /* Lock a connection. */
86:
87: boolean
88: fconn_lock (qconn, fin)
89: struct sconnection *qconn;
90: boolean fin;
91: {
92: boolean (*pflock) P((struct sconnection *, boolean));
93:
94: pflock = qconn->qcmds->pflock;
95: if (pflock == NULL)
96: return TRUE;
97: return (*pflock) (qconn, fin);
98: }
99:
100: /* Unlock a connection. */
101:
102: boolean
103: fconn_unlock (qconn)
104: struct sconnection *qconn;
105: {
106: boolean (*pfunlock) P((struct sconnection *));
107:
108: pfunlock = qconn->qcmds->pfunlock;
109: if (pfunlock == NULL)
110: return TRUE;
111: return (*pfunlock) (qconn);
112: }
113:
114: /* Open a connection. */
115:
116: boolean
117: fconn_open (qconn, ibaud, ihighbaud, fwait)
118: struct sconnection *qconn;
119: long ibaud;
120: long ihighbaud;
121: boolean fwait;
122: {
123: boolean fret;
124:
125: #if DEBUG > 1
126: if (FDEBUGGING (DEBUG_PORT))
127: {
128: char abspeed[20];
129:
130: if (ibaud == (long) 0)
131: strcpy (abspeed, "default speed");
132: else
133: sprintf (abspeed, "speed %ld", ibaud);
134:
135: if (qconn->qport == NULL)
136: ulog (LOG_DEBUG, "fconn_open: Opening stdin port (%s)",
137: abspeed);
138: else if (qconn->qport->uuconf_zname == NULL)
139: ulog (LOG_DEBUG, "fconn_open: Opening unnamed port (%s)",
140: abspeed);
141: else
142: ulog (LOG_DEBUG, "fconn_open: Opening port %s (%s)",
143: qconn->qport->uuconf_zname, abspeed);
144: }
145: #endif
146:
147: /* If the system provides a range of baud rates, we select the
148: highest baud rate supported by the port. */
149: if (ihighbaud != 0 && qconn->qport != NULL)
150: {
151: struct uuconf_port *qport;
152:
153: qport = qconn->qport;
154: ibaud = ihighbaud;
155: if (qport->uuconf_ttype == UUCONF_PORTTYPE_MODEM)
156: {
157: if (qport->uuconf_u.uuconf_smodem.uuconf_ilowbaud != 0)
158: {
159: if (qport->uuconf_u.uuconf_smodem.uuconf_ihighbaud < ibaud)
160: ibaud = qport->uuconf_u.uuconf_smodem.uuconf_ihighbaud;
161: }
162: else if (qport->uuconf_u.uuconf_smodem.uuconf_ibaud != 0)
163: ibaud = qport->uuconf_u.uuconf_smodem.uuconf_ibaud;
164: }
165: else if (qport->uuconf_ttype == UUCONF_PORTTYPE_DIRECT)
166: {
167: if (qport->uuconf_u.uuconf_sdirect.uuconf_ibaud != 0)
168: ibaud = qport->uuconf_u.uuconf_sdirect.uuconf_ibaud;
169: }
170: }
171:
172: /* This will normally be overridden by the port specific open
173: routine. */
174: if (qconn->qport == NULL)
175: ulog_device ("stdin");
176: else
177: ulog_device (qconn->qport->uuconf_zname);
178:
179: fret = (*qconn->qcmds->pfopen) (qconn, ibaud, fwait);
180:
181: if (! fret)
182: ulog_device ((const char *) NULL);
183:
184: return fret;
185: }
186:
187: /* Close a connection. */
188:
189: boolean
190: fconn_close (qconn, puuconf, qdialer, fsuccess)
191: struct sconnection *qconn;
192: pointer puuconf;
193: struct uuconf_dialer *qdialer;
194: boolean fsuccess;
195: {
196: boolean fret;
197:
198: DEBUG_MESSAGE0 (DEBUG_PORT, "fconn_close: Closing connection");
199:
200: /* Don't report hangup signals while we're closing. */
201: fLog_sighup = FALSE;
202:
203: fret = (*qconn->qcmds->pfclose) (qconn, puuconf, qdialer, fsuccess);
204:
205: /* Make sure any signal reporting has been done before we set
206: fLog_sighup back to TRUE. */
207: ulog (LOG_ERROR, (const char *) NULL);
208: fLog_sighup = TRUE;
209:
210: ulog_device ((const char *) NULL);
211:
212: return fret;
213: }
214:
215: /* Reset the connection. */
216:
217: boolean
218: fconn_reset (qconn)
219: struct sconnection *qconn;
220: {
221: DEBUG_MESSAGE0 (DEBUG_PORT, "fconn_reset: Resetting connection");
222:
223: return (*qconn->qcmds->pfreset) (qconn);
224: }
225:
226: /* Dial out on the connection. */
227:
228: boolean
229: fconn_dial (qconn, puuconf, qsys, zphone, qdialer, ptdialerfound)
230: struct sconnection *qconn;
231: pointer puuconf;
232: const struct uuconf_system *qsys;
233: const char *zphone;
234: struct uuconf_dialer *qdialer;
235: enum tdialerfound *ptdialerfound;
236: {
237: struct uuconf_dialer sdialer;
238: enum tdialerfound tfound;
239: boolean (*pfdial) P((struct sconnection *, pointer,
240: const struct uuconf_system *, const char *,
241: struct uuconf_dialer *, enum tdialerfound *));
242:
243: if (qdialer == NULL)
244: qdialer = &sdialer;
245: if (ptdialerfound == NULL)
246: ptdialerfound = &tfound;
247:
248: qdialer->uuconf_zname = NULL;
249: *ptdialerfound = DIALERFOUND_FALSE;
250:
251: pfdial = qconn->qcmds->pfdial;
252: if (pfdial == NULL)
253: return TRUE;
254: return (*pfdial) (qconn, puuconf, qsys, zphone, qdialer, ptdialerfound);
255: }
256:
257: /* Read data from the connection. */
258:
259: boolean
260: fconn_read (qconn, zbuf, pclen, cmin, ctimeout, freport)
261: struct sconnection *qconn;
262: char *zbuf;
263: size_t *pclen;
264: size_t cmin;
265: int ctimeout;
266: boolean freport;
267: {
268: boolean fret;
269:
270: fret = (*qconn->qcmds->pfread) (qconn, zbuf, pclen, cmin, ctimeout,
271: freport);
272:
273: #if DEBUG > 1
274: if (FDEBUGGING (DEBUG_INCOMING))
275: udebug_buffer ("fconn_read: Read", zbuf, *pclen);
276: else if (FDEBUGGING (DEBUG_PORT))
277: ulog (LOG_DEBUG, "fconn_read: Read %lu", (unsigned long) *pclen);
278: #endif
279:
280: return fret;
281: }
282:
283: /* Write data to the connection. */
284:
285: boolean
286: fconn_write (qconn, zbuf, clen)
287: struct sconnection *qconn;
288: const char *zbuf;
289: size_t clen;
290: {
291: #if DEBUG > 1
292: if (FDEBUGGING (DEBUG_OUTGOING))
293: udebug_buffer ("fconn_write: Writing", zbuf, clen);
294: else if (FDEBUGGING (DEBUG_PORT))
295: ulog (LOG_DEBUG, "fconn_write: Writing %lu", (unsigned long) clen);
296: #endif
297:
298: return (*qconn->qcmds->pfwrite) (qconn, zbuf, clen);
299: }
300:
301: /* Read and write data. */
302:
303: boolean
304: fconn_io (qconn, zwrite, pcwrite, zread, pcread)
305: struct sconnection *qconn;
306: const char *zwrite;
307: size_t *pcwrite;
308: char *zread;
309: size_t *pcread;
310: {
311: boolean fret;
312: #if DEBUG > 1
313: size_t cwrite = *pcwrite;
314: size_t cread = *pcread;
315:
316: if (cread == 0 || cwrite == 0)
317: ulog (LOG_FATAL, "fconn_io: cread %lu; cwrite %lu",
318: (unsigned long) cread, (unsigned long) cwrite);
319: #endif
320:
321: #if DEBUG > 1
322: if (FDEBUGGING (DEBUG_OUTGOING))
323: udebug_buffer ("fconn_io: Writing", zwrite, cwrite);
324: #endif
325:
326: fret = (*qconn->qcmds->pfio) (qconn, zwrite, pcwrite, zread, pcread);
327:
328: DEBUG_MESSAGE4 (DEBUG_PORT,
329: "fconn_io: Wrote %lu of %lu, read %lu of %lu",
330: (unsigned long) *pcwrite, (unsigned long) cwrite,
331: (unsigned long) *pcread, (unsigned long) cread);
332:
333: #if DEBUG > 1
334: if (*pcread > 0 && FDEBUGGING (DEBUG_INCOMING))
335: udebug_buffer ("fconn_io: Read", zread, *pcread);
336: #endif
337:
338: return fret;
339: }
340:
341: /* Send a break character to a connection. Some port types may not
342: support break characters, in which case we just return TRUE. */
343:
344: boolean
345: fconn_break (qconn)
346: struct sconnection *qconn;
347: {
348: boolean (*pfbreak) P((struct sconnection *));
349:
350: pfbreak = *qconn->qcmds->pfbreak;
351: if (pfbreak == NULL)
352: return TRUE;
353:
354: DEBUG_MESSAGE0 (DEBUG_PORT, "fconn_break: Sending break character");
355:
356: return (*pfbreak) (qconn);
357: }
358:
359: /* Change the setting of a connection. Some port types may not
360: support this, in which case we just return TRUE. */
361:
362: boolean
363: fconn_set (qconn, tparity, tstrip, txonxoff)
364: struct sconnection *qconn;
365: enum tparitysetting tparity;
366: enum tstripsetting tstrip;
367: enum txonxoffsetting txonxoff;
368: {
369: boolean (*pfset) P((struct sconnection *, enum tparitysetting,
370: enum tstripsetting, enum txonxoffsetting));
371:
372: pfset = qconn->qcmds->pfset;
373: if (pfset == NULL)
374: return TRUE;
375:
376: DEBUG_MESSAGE3 (DEBUG_PORT,
377: "fconn_set: Changing setting to %d, %d, %d",
378: (int) tparity, (int) tstrip, (int) txonxoff);
379:
380: return (*pfset) (qconn, tparity, tstrip, txonxoff);
381: }
382:
383: /* Require or ignore carrier on a connection. */
384:
385: boolean
386: fconn_carrier (qconn, fcarrier)
387: struct sconnection *qconn;
388: boolean fcarrier;
389: {
390: boolean (*pfcarrier) P((struct sconnection *, boolean));
391:
392: pfcarrier = qconn->qcmds->pfcarrier;
393: if (pfcarrier == NULL)
394: return TRUE;
395: return (*pfcarrier) (qconn, fcarrier);
396: }
397:
398: /* Run a chat program on a connection. */
399:
400: boolean
401: fconn_run_chat (qconn, pzprog)
402: struct sconnection *qconn;
403: char **pzprog;
404: {
405: return (*qconn->qcmds->pfchat) (qconn, pzprog);
406: }
407:
408: /* Get the baud rate of a connection. */
409:
410: long
411: iconn_baud (qconn)
412: struct sconnection *qconn;
413: {
414: long (*pibaud) P((struct sconnection *));
415:
416: pibaud = qconn->qcmds->pibaud;
417: if (pibaud == NULL)
418: return 0;
419: return (*pibaud) (qconn);
420: }
421:
422: /* Modem dialing routines. */
423:
424: /*ARGSUSED*/
425: boolean
426: fmodem_dial (qconn, puuconf, qsys, zphone, qdialer, ptdialerfound)
427: struct sconnection *qconn;
428: pointer puuconf;
429: const struct uuconf_system *qsys;
430: const char *zphone;
431: struct uuconf_dialer *qdialer;
432: enum tdialerfound *ptdialerfound;
433: {
434: *ptdialerfound = DIALERFOUND_FALSE;
435:
436: if (qconn->qport->uuconf_u.uuconf_smodem.uuconf_pzdialer != NULL)
437: {
438: char **pz;
439: boolean ffirst;
440:
441: /* The pzdialer field is a sequence of dialer/token pairs. The
442: dialer portion names a dialer to use. The token portion is
443: what \D and \T in the chat script expand to. If there is no
444: token for the last dialer, the phone number for the system is
445: used. */
446: ffirst = TRUE;
447: pz = qconn->qport->uuconf_u.uuconf_smodem.uuconf_pzdialer;
448: while (*pz != NULL)
449: {
450: int iuuconf;
451: struct uuconf_dialer *q;
452: struct uuconf_dialer s;
453: const char *ztoken;
454: boolean ftranslate;
455:
456: if (! ffirst)
457: q = &s;
458: else
459: q = qdialer;
460:
461: iuuconf = uuconf_dialer_info (puuconf, *pz, q);
462: if (iuuconf == UUCONF_NOT_FOUND)
463: {
464: ulog (LOG_ERROR, "%s: Dialer not found", *pz);
465: return FALSE;
466: }
467: else if (iuuconf != UUCONF_SUCCESS)
468: {
469: ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
470: return FALSE;
471: }
472:
473: ++pz;
474: ztoken = *pz;
475:
476: ftranslate = FALSE;
477: if (ztoken == NULL
478: || strcmp (ztoken, "\\D") == 0)
479: ztoken = zphone;
480: else if (strcmp (ztoken, "\\T") == 0)
481: {
482: ztoken = zphone;
483: ftranslate = TRUE;
484: }
485:
486: if (! fcdo_dial (qconn, puuconf, q, ztoken, ftranslate))
487: {
488: (void) uuconf_dialer_free (puuconf, q);
489: if (! ffirst)
490: (void) uuconf_dialer_free (puuconf, qdialer);
491: return FALSE;
492: }
493:
494: if (ffirst)
495: {
496: *ptdialerfound = DIALERFOUND_FREE;
497: ffirst = FALSE;
498: }
499: else
500: (void) uuconf_dialer_free (puuconf, q);
501:
502: if (*pz != NULL)
503: ++pz;
504: }
505:
506: return TRUE;
507: }
508: else if (qconn->qport->uuconf_u.uuconf_smodem.uuconf_qdialer != NULL)
509: {
510: struct uuconf_dialer *q;
511:
512: q = qconn->qport->uuconf_u.uuconf_smodem.uuconf_qdialer;
513: *qdialer = *q;
514: *ptdialerfound = DIALERFOUND_TRUE;
515: return fcdo_dial (qconn, puuconf, q, zphone, FALSE);
516: }
517: else
518: {
519: ulog (LOG_ERROR, "No dialer information");
520: return FALSE;
521: }
522: }
523:
524: /* Actually use a dialer. We set up the modem (which may include
525: opening the dialer device), run the chat script, and finish dealing
526: with the modem. */
527:
528: static boolean
529: fcdo_dial (qconn, puuconf, qdial, zphone, ftranslate)
530: struct sconnection *qconn;
531: pointer puuconf;
532: struct uuconf_dialer *qdial;
533: const char *zphone;
534: boolean ftranslate;
535: {
536: const char *zname;
537:
538: if (! fsysdep_modem_begin_dial (qconn, qdial))
539: return FALSE;
540:
541: if (qconn->qport == NULL)
542: zname = NULL;
543: else
544: zname = qconn->qport->uuconf_zname;
545:
546: if (! fchat (qconn, puuconf, &qdial->uuconf_schat,
547: (const struct uuconf_system *) NULL, qdial,
548: zphone, ftranslate, zname, iconn_baud (qconn)))
549: return FALSE;
550:
551: return fsysdep_modem_end_dial (qconn, qdial);
552: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.