xref: /titanic_44/usr/src/lib/libnsl/dial/conn.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
24*7c478bd9Sstevel@tonic-gate 
25*7c478bd9Sstevel@tonic-gate 
26*7c478bd9Sstevel@tonic-gate /*
27*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
28*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
29*7c478bd9Sstevel@tonic-gate  */
30*7c478bd9Sstevel@tonic-gate 
31*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate #include "uucp.h"
34*7c478bd9Sstevel@tonic-gate #include <rpc/trace.h>
35*7c478bd9Sstevel@tonic-gate GLOBAL char _Protocol[40];	/* working protocol string */
36*7c478bd9Sstevel@tonic-gate static char _ProtoSys[40];	/* protocol string from Systems file entry */
37*7c478bd9Sstevel@tonic-gate static char _ProtoDev[40];	/* protocol string from Devices file entry */
38*7c478bd9Sstevel@tonic-gate EXTERN char _ProtoCfg[];	/* protocol string from Config  file entry */
39*7c478bd9Sstevel@tonic-gate 
40*7c478bd9Sstevel@tonic-gate EXTERN jmp_buf Sjbuf;
41*7c478bd9Sstevel@tonic-gate EXTERN unsigned expecttime;
42*7c478bd9Sstevel@tonic-gate 
43*7c478bd9Sstevel@tonic-gate GLOBAL int	Modemctrl;
44*7c478bd9Sstevel@tonic-gate 
45*7c478bd9Sstevel@tonic-gate EXTERN void alarmtr();
46*7c478bd9Sstevel@tonic-gate static void addProto(), mergeProto(), removeProto();
47*7c478bd9Sstevel@tonic-gate static char *nextProto();
48*7c478bd9Sstevel@tonic-gate EXTERN char *findProto();
49*7c478bd9Sstevel@tonic-gate static void getProto();
50*7c478bd9Sstevel@tonic-gate static int finds();
51*7c478bd9Sstevel@tonic-gate EXTERN int getto();		/* make this static when ct uses altconn() */
52*7c478bd9Sstevel@tonic-gate EXTERN int chat(), rddev(), expect(), wrstr(), wrchr();
53*7c478bd9Sstevel@tonic-gate EXTERN int processdev(), getdevline(), getsysline(), sysaccess();
54*7c478bd9Sstevel@tonic-gate EXTERN int clear_hup();
55*7c478bd9Sstevel@tonic-gate EXTERN char *currsys(), *currdev();
56*7c478bd9Sstevel@tonic-gate static int finds();
57*7c478bd9Sstevel@tonic-gate static int wait_for_hangup(), expect_str();
58*7c478bd9Sstevel@tonic-gate 
59*7c478bd9Sstevel@tonic-gate EXTERN void sendthem(), nap();
60*7c478bd9Sstevel@tonic-gate static int notin(), ifdate(), classmatch();
61*7c478bd9Sstevel@tonic-gate 
62*7c478bd9Sstevel@tonic-gate GLOBAL char *Myline = CNULL;	/* to force which line will be used */
63*7c478bd9Sstevel@tonic-gate GLOBAL char *Mytype = CNULL;	/* to force selection of specific device type */
64*7c478bd9Sstevel@tonic-gate 
65*7c478bd9Sstevel@tonic-gate /*
66*7c478bd9Sstevel@tonic-gate  * conn - place a telephone call to system and login, etc.
67*7c478bd9Sstevel@tonic-gate  *
68*7c478bd9Sstevel@tonic-gate  * return codes:
69*7c478bd9Sstevel@tonic-gate  *	FAIL - connection failed
70*7c478bd9Sstevel@tonic-gate  *	>0  - file no.  -  connect ok
71*7c478bd9Sstevel@tonic-gate  * When a failure occurs, Uerror is set.
72*7c478bd9Sstevel@tonic-gate  */
73*7c478bd9Sstevel@tonic-gate 
74*7c478bd9Sstevel@tonic-gate GLOBAL int
75*7c478bd9Sstevel@tonic-gate conn(system)
76*7c478bd9Sstevel@tonic-gate char *system;
77*7c478bd9Sstevel@tonic-gate {
78*7c478bd9Sstevel@tonic-gate 	int nf, fn = FAIL;
79*7c478bd9Sstevel@tonic-gate 	char *flds[F_MAX+1];
80*7c478bd9Sstevel@tonic-gate 	EXTERN void sysreset();
81*7c478bd9Sstevel@tonic-gate 
82*7c478bd9Sstevel@tonic-gate 
83*7c478bd9Sstevel@tonic-gate 	trace1(TR_conn, 0);
84*7c478bd9Sstevel@tonic-gate 	CDEBUG(4, "conn(%s)\n", system);
85*7c478bd9Sstevel@tonic-gate 	Uerror = 0;
86*7c478bd9Sstevel@tonic-gate 	while ((nf = finds(system, flds, F_MAX)) > 0) {
87*7c478bd9Sstevel@tonic-gate 		fn = getto(flds);
88*7c478bd9Sstevel@tonic-gate 		CDEBUG(4, "getto ret %d\n", fn);
89*7c478bd9Sstevel@tonic-gate 		if (fn < 0)
90*7c478bd9Sstevel@tonic-gate 			continue;
91*7c478bd9Sstevel@tonic-gate 		if (EQUALS(Progname, "uucico")) {
92*7c478bd9Sstevel@tonic-gate 			if (chat(nf - F_LOGIN, flds + F_LOGIN, fn,"","") == SUCCESS) {
93*7c478bd9Sstevel@tonic-gate 				sysreset();
94*7c478bd9Sstevel@tonic-gate 				trace1(TR_conn, 1);
95*7c478bd9Sstevel@tonic-gate 				return (fn); /* successful return */
96*7c478bd9Sstevel@tonic-gate 			}
97*7c478bd9Sstevel@tonic-gate 
98*7c478bd9Sstevel@tonic-gate 			/* login failed */
99*7c478bd9Sstevel@tonic-gate 			DEBUG(6, "close caller (%d)\n", fn);
100*7c478bd9Sstevel@tonic-gate 			fd_rmlock(fn);
101*7c478bd9Sstevel@tonic-gate 			close(fn);
102*7c478bd9Sstevel@tonic-gate 			if (Dc[0] != NULLCHAR) {
103*7c478bd9Sstevel@tonic-gate 			/*EMPTY*/
104*7c478bd9Sstevel@tonic-gate 			DEBUG(6, "delock line (%s)\n", Dc);
105*7c478bd9Sstevel@tonic-gate 			}
106*7c478bd9Sstevel@tonic-gate 		} else {
107*7c478bd9Sstevel@tonic-gate 			sysreset();
108*7c478bd9Sstevel@tonic-gate 			trace1(TR_conn, 1);
109*7c478bd9Sstevel@tonic-gate 			return (fn);
110*7c478bd9Sstevel@tonic-gate 		}
111*7c478bd9Sstevel@tonic-gate 	}
112*7c478bd9Sstevel@tonic-gate 
113*7c478bd9Sstevel@tonic-gate 	/* finds or getto failed */
114*7c478bd9Sstevel@tonic-gate 	sysreset();
115*7c478bd9Sstevel@tonic-gate 	CDEBUG(1, "Call Failed: %s\n", UERRORTEXT);
116*7c478bd9Sstevel@tonic-gate 	trace1(TR_conn, 1);
117*7c478bd9Sstevel@tonic-gate 	return (FAIL);
118*7c478bd9Sstevel@tonic-gate }
119*7c478bd9Sstevel@tonic-gate 
120*7c478bd9Sstevel@tonic-gate /*
121*7c478bd9Sstevel@tonic-gate  * getto - connect to remote machine
122*7c478bd9Sstevel@tonic-gate  *
123*7c478bd9Sstevel@tonic-gate  * return codes:
124*7c478bd9Sstevel@tonic-gate  *	>0  -  file number - ok
125*7c478bd9Sstevel@tonic-gate  *	FAIL  -  failed
126*7c478bd9Sstevel@tonic-gate  */
127*7c478bd9Sstevel@tonic-gate 
128*7c478bd9Sstevel@tonic-gate GLOBAL int
129*7c478bd9Sstevel@tonic-gate getto(flds)
130*7c478bd9Sstevel@tonic-gate char *flds[];
131*7c478bd9Sstevel@tonic-gate {
132*7c478bd9Sstevel@tonic-gate 	char *dev[D_MAX+2], devbuf[BUFSIZ];
133*7c478bd9Sstevel@tonic-gate 	register int status;
134*7c478bd9Sstevel@tonic-gate 	register int dcf = -1;
135*7c478bd9Sstevel@tonic-gate 	int reread = 0;
136*7c478bd9Sstevel@tonic-gate 	int tries = 0;	/* count of call attempts - for limit purposes */
137*7c478bd9Sstevel@tonic-gate 	EXTERN void devreset();
138*7c478bd9Sstevel@tonic-gate 
139*7c478bd9Sstevel@tonic-gate 
140*7c478bd9Sstevel@tonic-gate 	trace1(TR_getto, 0);
141*7c478bd9Sstevel@tonic-gate 	CDEBUG(1, "Device Type %s wanted\n", flds[F_TYPE]);
142*7c478bd9Sstevel@tonic-gate 	Uerror = 0;
143*7c478bd9Sstevel@tonic-gate 	while (tries < TRYCALLS) {
144*7c478bd9Sstevel@tonic-gate 		if ((status=rddev(flds[F_TYPE], dev, devbuf, D_MAX)) == FAIL) {
145*7c478bd9Sstevel@tonic-gate 			if (tries == 0 || ++reread >= TRYCALLS)
146*7c478bd9Sstevel@tonic-gate 				break;
147*7c478bd9Sstevel@tonic-gate 			devreset();
148*7c478bd9Sstevel@tonic-gate 			continue;
149*7c478bd9Sstevel@tonic-gate 		}
150*7c478bd9Sstevel@tonic-gate 		/* check class, check (and possibly set) speed */
151*7c478bd9Sstevel@tonic-gate 		if (classmatch(flds, dev) != SUCCESS) {
152*7c478bd9Sstevel@tonic-gate 			DEBUG(7, "Skipping entry in '%s'", currdev());
153*7c478bd9Sstevel@tonic-gate 			DEBUG(7, " - class (%s) not wanted.\n", dev[D_CLASS]);
154*7c478bd9Sstevel@tonic-gate 			continue;
155*7c478bd9Sstevel@tonic-gate 		}
156*7c478bd9Sstevel@tonic-gate 		DEBUG(5, "Trying device entry from '%s'.\n", currdev());
157*7c478bd9Sstevel@tonic-gate 		if ((dcf = processdev(flds, dev)) >= 0)
158*7c478bd9Sstevel@tonic-gate 			break;
159*7c478bd9Sstevel@tonic-gate 
160*7c478bd9Sstevel@tonic-gate 		switch(Uerror) {
161*7c478bd9Sstevel@tonic-gate 		case SS_CANT_ACCESS_DEVICE:
162*7c478bd9Sstevel@tonic-gate 		case SS_DEVICE_FAILED:
163*7c478bd9Sstevel@tonic-gate 		case SS_LOCKED_DEVICE:
164*7c478bd9Sstevel@tonic-gate 			break;
165*7c478bd9Sstevel@tonic-gate 		default:
166*7c478bd9Sstevel@tonic-gate 			tries++;
167*7c478bd9Sstevel@tonic-gate 			break;
168*7c478bd9Sstevel@tonic-gate 		}
169*7c478bd9Sstevel@tonic-gate 	}
170*7c478bd9Sstevel@tonic-gate 	devreset();	/* reset devices file(s) */
171*7c478bd9Sstevel@tonic-gate 	if (status == FAIL && !Uerror) {
172*7c478bd9Sstevel@tonic-gate 		CDEBUG(1, "Requested Device Type Not Found\n%s", "");
173*7c478bd9Sstevel@tonic-gate 		Uerror = SS_NO_DEVICE;
174*7c478bd9Sstevel@tonic-gate 	}
175*7c478bd9Sstevel@tonic-gate 	trace1(TR_getto, 1);
176*7c478bd9Sstevel@tonic-gate 	return (dcf);
177*7c478bd9Sstevel@tonic-gate }
178*7c478bd9Sstevel@tonic-gate 
179*7c478bd9Sstevel@tonic-gate /*
180*7c478bd9Sstevel@tonic-gate  * classmatch - process 'Any' in Devices and Systems and
181*7c478bd9Sstevel@tonic-gate  * 	determine the correct speed, or match for ==
182*7c478bd9Sstevel@tonic-gate  */
183*7c478bd9Sstevel@tonic-gate 
184*7c478bd9Sstevel@tonic-gate static int
185*7c478bd9Sstevel@tonic-gate classmatch(flds, dev)
186*7c478bd9Sstevel@tonic-gate char *flds[];
187*7c478bd9Sstevel@tonic-gate char *dev[];
188*7c478bd9Sstevel@tonic-gate {
189*7c478bd9Sstevel@tonic-gate 	/* check class, check (and possibly set) speed */
190*7c478bd9Sstevel@tonic-gate 	trace1(TR_classmatch, 0);
191*7c478bd9Sstevel@tonic-gate 	if (EQUALS(flds[F_CLASS], "Any")
192*7c478bd9Sstevel@tonic-gate 	   && EQUALS(dev[D_CLASS], "Any")) {
193*7c478bd9Sstevel@tonic-gate 		dev[D_CLASS] = DEFAULT_BAUDRATE;
194*7c478bd9Sstevel@tonic-gate 		trace1(TR_classmatch, 1);
195*7c478bd9Sstevel@tonic-gate 		return (SUCCESS);
196*7c478bd9Sstevel@tonic-gate 	} else if (EQUALS(dev[D_CLASS], "Any")) {
197*7c478bd9Sstevel@tonic-gate 		dev[D_CLASS] = flds[F_CLASS];
198*7c478bd9Sstevel@tonic-gate 		trace1(TR_classmatch, 1);
199*7c478bd9Sstevel@tonic-gate 		return (SUCCESS);
200*7c478bd9Sstevel@tonic-gate 	} else if (EQUALS(flds[F_CLASS], "Any") ||
201*7c478bd9Sstevel@tonic-gate 	EQUALS(flds[F_CLASS], dev[D_CLASS])) {
202*7c478bd9Sstevel@tonic-gate 		trace1(TR_classmatch, 1);
203*7c478bd9Sstevel@tonic-gate 		return (SUCCESS);
204*7c478bd9Sstevel@tonic-gate 	}
205*7c478bd9Sstevel@tonic-gate 	else {
206*7c478bd9Sstevel@tonic-gate 		trace1(TR_classmatch, 1);
207*7c478bd9Sstevel@tonic-gate 		return (FAIL);
208*7c478bd9Sstevel@tonic-gate 	}
209*7c478bd9Sstevel@tonic-gate }
210*7c478bd9Sstevel@tonic-gate 
211*7c478bd9Sstevel@tonic-gate 
212*7c478bd9Sstevel@tonic-gate /*
213*7c478bd9Sstevel@tonic-gate  *	rddev - find and unpack a line from device file for this caller type
214*7c478bd9Sstevel@tonic-gate  *	lines starting with whitespace of '#' are comments
215*7c478bd9Sstevel@tonic-gate  *
216*7c478bd9Sstevel@tonic-gate  *	return codes:
217*7c478bd9Sstevel@tonic-gate  *		>0  -  number of arguments in vector - succeeded
218*7c478bd9Sstevel@tonic-gate  *		FAIL - EOF
219*7c478bd9Sstevel@tonic-gate  */
220*7c478bd9Sstevel@tonic-gate 
221*7c478bd9Sstevel@tonic-gate GLOBAL int
222*7c478bd9Sstevel@tonic-gate rddev(char *type, char *dev[], char *buf, int devcount)
223*7c478bd9Sstevel@tonic-gate {
224*7c478bd9Sstevel@tonic-gate 	char *commap, d_type[BUFSIZ];
225*7c478bd9Sstevel@tonic-gate 	int na;
226*7c478bd9Sstevel@tonic-gate 
227*7c478bd9Sstevel@tonic-gate 
228*7c478bd9Sstevel@tonic-gate 	trace1(TR_rddev, 0);
229*7c478bd9Sstevel@tonic-gate 	while (getdevline(buf, BUFSIZ)) {
230*7c478bd9Sstevel@tonic-gate 		if (buf[0] == ' ' || buf[0] == '\t'
231*7c478bd9Sstevel@tonic-gate 			||  buf[0] == '\n' || buf[0] == '\0' || buf[0] == '#')
232*7c478bd9Sstevel@tonic-gate 			continue;
233*7c478bd9Sstevel@tonic-gate 		na = getargs(buf, dev, devcount);
234*7c478bd9Sstevel@tonic-gate 		ASSERT(na >= D_CALLER, "BAD LINE", buf, na);
235*7c478bd9Sstevel@tonic-gate 
236*7c478bd9Sstevel@tonic-gate 		if (strncmp(dev[D_LINE],"/dev/",5) == 0) {
237*7c478bd9Sstevel@tonic-gate 			/* since cu (altconn()) strips off leading */
238*7c478bd9Sstevel@tonic-gate 			/* "/dev/",  do the same here.  */
239*7c478bd9Sstevel@tonic-gate 			strcpy(dev[D_LINE], &(dev[D_LINE][5]));
240*7c478bd9Sstevel@tonic-gate 		}
241*7c478bd9Sstevel@tonic-gate 
242*7c478bd9Sstevel@tonic-gate 		/* may have ",M" subfield in D_LINE */
243*7c478bd9Sstevel@tonic-gate 		Modemctrl = FALSE;
244*7c478bd9Sstevel@tonic-gate 		if ((commap = strchr(dev[D_LINE], ',')) != (char *)NULL) {
245*7c478bd9Sstevel@tonic-gate 			if (strcmp(commap, ",M") == SAME)
246*7c478bd9Sstevel@tonic-gate 				Modemctrl = TRUE;
247*7c478bd9Sstevel@tonic-gate 			*commap = '\0';
248*7c478bd9Sstevel@tonic-gate 		}
249*7c478bd9Sstevel@tonic-gate 
250*7c478bd9Sstevel@tonic-gate 		/*
251*7c478bd9Sstevel@tonic-gate 		 * D_TYPE field may have protocol subfield, which
252*7c478bd9Sstevel@tonic-gate 		 * must be pulled off before comparing to desired type.
253*7c478bd9Sstevel@tonic-gate 		 */
254*7c478bd9Sstevel@tonic-gate 		(void)strcpy(d_type, dev[D_TYPE]);
255*7c478bd9Sstevel@tonic-gate 		if ((commap = strchr(d_type, ',')) != (char *)NULL)
256*7c478bd9Sstevel@tonic-gate 			*commap = '\0';
257*7c478bd9Sstevel@tonic-gate 
258*7c478bd9Sstevel@tonic-gate 		/* to force the requested device type to be used. */
259*7c478bd9Sstevel@tonic-gate 		if ((Mytype != NULL) && (!EQUALS(Mytype, d_type)))
260*7c478bd9Sstevel@tonic-gate 			continue;
261*7c478bd9Sstevel@tonic-gate 		/* to force the requested line to be used */
262*7c478bd9Sstevel@tonic-gate 		if ((Myline != NULL) && (!EQUALS(Myline, dev[D_LINE])))
263*7c478bd9Sstevel@tonic-gate 			continue;
264*7c478bd9Sstevel@tonic-gate 
265*7c478bd9Sstevel@tonic-gate 		bsfix(dev);	/* replace \X fields */
266*7c478bd9Sstevel@tonic-gate 
267*7c478bd9Sstevel@tonic-gate 		if (EQUALS(d_type, type)) {
268*7c478bd9Sstevel@tonic-gate 			getProto(_ProtoDev, dev[D_TYPE]);
269*7c478bd9Sstevel@tonic-gate 			trace1(TR_rddev, 1);
270*7c478bd9Sstevel@tonic-gate 			return (na);
271*7c478bd9Sstevel@tonic-gate 		}
272*7c478bd9Sstevel@tonic-gate 	}
273*7c478bd9Sstevel@tonic-gate 	trace1(TR_rddev, 1);
274*7c478bd9Sstevel@tonic-gate 	return (FAIL);
275*7c478bd9Sstevel@tonic-gate }
276*7c478bd9Sstevel@tonic-gate 
277*7c478bd9Sstevel@tonic-gate 
278*7c478bd9Sstevel@tonic-gate /*
279*7c478bd9Sstevel@tonic-gate  * finds	- set system attribute vector
280*7c478bd9Sstevel@tonic-gate  *
281*7c478bd9Sstevel@tonic-gate  * input:
282*7c478bd9Sstevel@tonic-gate  *	fsys - open Systems file descriptor
283*7c478bd9Sstevel@tonic-gate  *	sysnam - system name to find
284*7c478bd9Sstevel@tonic-gate  * output:
285*7c478bd9Sstevel@tonic-gate  *	flds - attibute vector from Systems file
286*7c478bd9Sstevel@tonic-gate  *	fldcount - number of fields in flds
287*7c478bd9Sstevel@tonic-gate  * return codes:
288*7c478bd9Sstevel@tonic-gate  *	>0  -  number of arguments in vector - succeeded
289*7c478bd9Sstevel@tonic-gate  *	FAIL - failed
290*7c478bd9Sstevel@tonic-gate  * Uerror set:
291*7c478bd9Sstevel@tonic-gate  *	0 - found a line in Systems file
292*7c478bd9Sstevel@tonic-gate  *	SS_BADSYSTEM - no line found in Systems file
293*7c478bd9Sstevel@tonic-gate  *	SS_TIME_WRONG - wrong time to call
294*7c478bd9Sstevel@tonic-gate  */
295*7c478bd9Sstevel@tonic-gate 
296*7c478bd9Sstevel@tonic-gate static int
297*7c478bd9Sstevel@tonic-gate finds(char *sysnam, char *flds[], int fldcount)
298*7c478bd9Sstevel@tonic-gate {
299*7c478bd9Sstevel@tonic-gate 	static char *info;	/* dynamically allocated BUFSIZ */
300*7c478bd9Sstevel@tonic-gate 	int na;
301*7c478bd9Sstevel@tonic-gate 
302*7c478bd9Sstevel@tonic-gate 	/* format of fields
303*7c478bd9Sstevel@tonic-gate 	 *	0 name;
304*7c478bd9Sstevel@tonic-gate 	 *	1 time
305*7c478bd9Sstevel@tonic-gate 	 *	2 acu/hardwired
306*7c478bd9Sstevel@tonic-gate 	 *	3 speed
307*7c478bd9Sstevel@tonic-gate 	 *	etc
308*7c478bd9Sstevel@tonic-gate 	 */
309*7c478bd9Sstevel@tonic-gate 
310*7c478bd9Sstevel@tonic-gate 	trace1(TR_finds, 0);
311*7c478bd9Sstevel@tonic-gate 	if (sysnam == 0 || *sysnam == 0) {
312*7c478bd9Sstevel@tonic-gate 		Uerror = SS_BADSYSTEM;
313*7c478bd9Sstevel@tonic-gate 		trace1(TR_finds, 1);
314*7c478bd9Sstevel@tonic-gate 		return (FAIL);
315*7c478bd9Sstevel@tonic-gate 	}
316*7c478bd9Sstevel@tonic-gate 
317*7c478bd9Sstevel@tonic-gate 	if (info == NULL) {
318*7c478bd9Sstevel@tonic-gate 		info = (char *)malloc(BUFSIZ);
319*7c478bd9Sstevel@tonic-gate 		if (info == NULL) {
320*7c478bd9Sstevel@tonic-gate 			DEBUG(1, "malloc failed for info in finds\n", 0);
321*7c478bd9Sstevel@tonic-gate 			return (0);
322*7c478bd9Sstevel@tonic-gate 		}
323*7c478bd9Sstevel@tonic-gate 	}
324*7c478bd9Sstevel@tonic-gate 	while (getsysline(info, BUFSIZ)) {
325*7c478bd9Sstevel@tonic-gate 		na = getargs(info, flds, fldcount);
326*7c478bd9Sstevel@tonic-gate 		bsfix(flds);	/* replace \X fields */
327*7c478bd9Sstevel@tonic-gate 		if (!EQUALSN(sysnam, flds[F_NAME], MAXBASENAME))
328*7c478bd9Sstevel@tonic-gate 			continue;
329*7c478bd9Sstevel@tonic-gate 		/* check if requested Mytype device type */
330*7c478bd9Sstevel@tonic-gate 		if ((Mytype != CNULL)
331*7c478bd9Sstevel@tonic-gate 			&& (!EQUALSN(flds[F_TYPE], Mytype, strlen(Mytype)))) {
332*7c478bd9Sstevel@tonic-gate 			DEBUG(7, "Skipping entry in '%s'", currsys());
333*7c478bd9Sstevel@tonic-gate 			DEBUG(7, " - type (%s) not wanted.\n", flds[F_TYPE]);
334*7c478bd9Sstevel@tonic-gate 			continue;
335*7c478bd9Sstevel@tonic-gate 		} else {
336*7c478bd9Sstevel@tonic-gate 			/*EMPTY*/
337*7c478bd9Sstevel@tonic-gate 			DEBUG(5, "Trying entry from '%s'", currsys());
338*7c478bd9Sstevel@tonic-gate 			DEBUG(5, " - device type %s.\n", flds[F_TYPE]);
339*7c478bd9Sstevel@tonic-gate 		}
340*7c478bd9Sstevel@tonic-gate 		/* OK if not uucico (ie. ct or cu) or the time is right */
341*7c478bd9Sstevel@tonic-gate 		if (!EQUALS(Progname, "uucico") || ifdate(flds[F_TIME])) {
342*7c478bd9Sstevel@tonic-gate 			/*  found a good entry  */
343*7c478bd9Sstevel@tonic-gate 			getProto(_ProtoSys, flds[F_TYPE]);
344*7c478bd9Sstevel@tonic-gate 			Uerror = 0;
345*7c478bd9Sstevel@tonic-gate 			trace1(TR_finds, 1);
346*7c478bd9Sstevel@tonic-gate 			return (na);	/* FOUND OK LINE */
347*7c478bd9Sstevel@tonic-gate 		}
348*7c478bd9Sstevel@tonic-gate 		CDEBUG(1, "Wrong Time To Call: %s\n", flds[F_TIME]);
349*7c478bd9Sstevel@tonic-gate 		Uerror = SS_TIME_WRONG;
350*7c478bd9Sstevel@tonic-gate 	}
351*7c478bd9Sstevel@tonic-gate 	if (!Uerror)
352*7c478bd9Sstevel@tonic-gate 		Uerror = SS_BADSYSTEM;
353*7c478bd9Sstevel@tonic-gate 	trace1(TR_finds, 1);
354*7c478bd9Sstevel@tonic-gate 	return (FAIL);
355*7c478bd9Sstevel@tonic-gate }
356*7c478bd9Sstevel@tonic-gate 
357*7c478bd9Sstevel@tonic-gate /*
358*7c478bd9Sstevel@tonic-gate  * getProto - get the protocol letters from the input string.
359*7c478bd9Sstevel@tonic-gate  * input:
360*7c478bd9Sstevel@tonic-gate  *	str - string from Systems/Devices/Config file,
361*7c478bd9Sstevel@tonic-gate  *		a ',' delimits the protocol string
362*7c478bd9Sstevel@tonic-gate  *		e.g. ACU,g or DK,d
363*7c478bd9Sstevel@tonic-gate  * output:
364*7c478bd9Sstevel@tonic-gate  *	str - the , (if present) will be replaced with NULLCHAR
365*7c478bd9Sstevel@tonic-gate  *
366*7c478bd9Sstevel@tonic-gate  * return:  none
367*7c478bd9Sstevel@tonic-gate  */
368*7c478bd9Sstevel@tonic-gate 
369*7c478bd9Sstevel@tonic-gate static void
370*7c478bd9Sstevel@tonic-gate getProto(save, str)
371*7c478bd9Sstevel@tonic-gate char *save;
372*7c478bd9Sstevel@tonic-gate char *str;
373*7c478bd9Sstevel@tonic-gate {
374*7c478bd9Sstevel@tonic-gate 	register char *p;
375*7c478bd9Sstevel@tonic-gate 
376*7c478bd9Sstevel@tonic-gate 
377*7c478bd9Sstevel@tonic-gate 	trace1(TR_getProto, 0);
378*7c478bd9Sstevel@tonic-gate 	*save = NULLCHAR;
379*7c478bd9Sstevel@tonic-gate 	if ((p=strchr(str, ',')) != NULL) {
380*7c478bd9Sstevel@tonic-gate 		*p = NULLCHAR;
381*7c478bd9Sstevel@tonic-gate 		(void) strcpy(save, p+1);
382*7c478bd9Sstevel@tonic-gate 		DEBUG(7, "Protocol = %s\n", save);
383*7c478bd9Sstevel@tonic-gate 	}
384*7c478bd9Sstevel@tonic-gate 	trace1(TR_getProto, 1);
385*7c478bd9Sstevel@tonic-gate 	return;
386*7c478bd9Sstevel@tonic-gate }
387*7c478bd9Sstevel@tonic-gate 
388*7c478bd9Sstevel@tonic-gate /*
389*7c478bd9Sstevel@tonic-gate  * check for a specified protocol selection string
390*7c478bd9Sstevel@tonic-gate  * return:
391*7c478bd9Sstevel@tonic-gate  *	protocol string pointer
392*7c478bd9Sstevel@tonic-gate  *	NULL if none specified for LOGNAME
393*7c478bd9Sstevel@tonic-gate  */
394*7c478bd9Sstevel@tonic-gate GLOBAL char *
395*7c478bd9Sstevel@tonic-gate protoString(valid)
396*7c478bd9Sstevel@tonic-gate char *valid;
397*7c478bd9Sstevel@tonic-gate {
398*7c478bd9Sstevel@tonic-gate 	char *save;
399*7c478bd9Sstevel@tonic-gate 
400*7c478bd9Sstevel@tonic-gate 
401*7c478bd9Sstevel@tonic-gate 	trace1(TR_protoString, 0);
402*7c478bd9Sstevel@tonic-gate 	save =strdup(valid);
403*7c478bd9Sstevel@tonic-gate 	_Protocol[0] = '\0';
404*7c478bd9Sstevel@tonic-gate 
405*7c478bd9Sstevel@tonic-gate 	if (_ProtoSys[0] != '\0')
406*7c478bd9Sstevel@tonic-gate 		addProto(_ProtoSys, valid);
407*7c478bd9Sstevel@tonic-gate 	if (_ProtoDev[0] != '\0')
408*7c478bd9Sstevel@tonic-gate 		addProto(_ProtoDev, valid);
409*7c478bd9Sstevel@tonic-gate 	if (_ProtoCfg[0] != '\0')
410*7c478bd9Sstevel@tonic-gate 		addProto(_ProtoCfg, valid);
411*7c478bd9Sstevel@tonic-gate 
412*7c478bd9Sstevel@tonic-gate 	if (_Protocol[0] == '\0') {
413*7c478bd9Sstevel@tonic-gate 		(void) strcpy(valid, save);
414*7c478bd9Sstevel@tonic-gate 		(void) strcpy(_Protocol, save);
415*7c478bd9Sstevel@tonic-gate 	}
416*7c478bd9Sstevel@tonic-gate 
417*7c478bd9Sstevel@tonic-gate 	trace1(TR_protoString, 1);
418*7c478bd9Sstevel@tonic-gate 	return (_Protocol[0] == NULLCHAR ? NULL : _Protocol);
419*7c478bd9Sstevel@tonic-gate }
420*7c478bd9Sstevel@tonic-gate 
421*7c478bd9Sstevel@tonic-gate /*
422*7c478bd9Sstevel@tonic-gate  * addProto
423*7c478bd9Sstevel@tonic-gate  *
424*7c478bd9Sstevel@tonic-gate  * Verify that the desired protocols from the Systems and Devices file
425*7c478bd9Sstevel@tonic-gate  * have been compiled into this application.
426*7c478bd9Sstevel@tonic-gate  *
427*7c478bd9Sstevel@tonic-gate  * 	desired -	list of desired protocols
428*7c478bd9Sstevel@tonic-gate  *	valid -		list of protocols that are compiled in.
429*7c478bd9Sstevel@tonic-gate  */
430*7c478bd9Sstevel@tonic-gate 
431*7c478bd9Sstevel@tonic-gate static void
432*7c478bd9Sstevel@tonic-gate addProto (desired, valid)
433*7c478bd9Sstevel@tonic-gate char *desired;
434*7c478bd9Sstevel@tonic-gate char *valid;
435*7c478bd9Sstevel@tonic-gate {
436*7c478bd9Sstevel@tonic-gate 	register char * protoPtr;
437*7c478bd9Sstevel@tonic-gate 	register char *	wantPtr;
438*7c478bd9Sstevel@tonic-gate 
439*7c478bd9Sstevel@tonic-gate 	trace1(TR_addProto, 0);
440*7c478bd9Sstevel@tonic-gate 	if (*desired == '\0') {
441*7c478bd9Sstevel@tonic-gate 		trace1(TR_addProto, 1);
442*7c478bd9Sstevel@tonic-gate 		return;
443*7c478bd9Sstevel@tonic-gate 	}
444*7c478bd9Sstevel@tonic-gate 
445*7c478bd9Sstevel@tonic-gate 	if (*(protoPtr = _Protocol) != NULLCHAR) {
446*7c478bd9Sstevel@tonic-gate 		while (*(protoPtr = nextProto(protoPtr)) != NULLCHAR) {
447*7c478bd9Sstevel@tonic-gate 		if (*(wantPtr = findProto(desired, *protoPtr)) == NULLCHAR) {
448*7c478bd9Sstevel@tonic-gate 			removeProto(valid, *protoPtr);
449*7c478bd9Sstevel@tonic-gate 			removeProto(protoPtr, *protoPtr);
450*7c478bd9Sstevel@tonic-gate 		} else {
451*7c478bd9Sstevel@tonic-gate 			mergeProto(protoPtr, wantPtr);
452*7c478bd9Sstevel@tonic-gate 			protoPtr++;
453*7c478bd9Sstevel@tonic-gate 		}
454*7c478bd9Sstevel@tonic-gate 		}
455*7c478bd9Sstevel@tonic-gate 	} else {
456*7c478bd9Sstevel@tonic-gate 		wantPtr = desired;
457*7c478bd9Sstevel@tonic-gate 		while (*(wantPtr = nextProto(wantPtr)) != NULLCHAR) {
458*7c478bd9Sstevel@tonic-gate 		if (*(findProto(valid, *wantPtr)) != NULLCHAR) {
459*7c478bd9Sstevel@tonic-gate 			mergeProto(protoPtr, wantPtr);
460*7c478bd9Sstevel@tonic-gate 		}
461*7c478bd9Sstevel@tonic-gate 		wantPtr++;
462*7c478bd9Sstevel@tonic-gate 		}
463*7c478bd9Sstevel@tonic-gate 	}
464*7c478bd9Sstevel@tonic-gate 	if (*(protoPtr = _Protocol) != NULLCHAR) {
465*7c478bd9Sstevel@tonic-gate 		while (*(protoPtr = nextProto(protoPtr)) != NULLCHAR)
466*7c478bd9Sstevel@tonic-gate 		*(valid++) = *(protoPtr++);
467*7c478bd9Sstevel@tonic-gate 		*valid = NULLCHAR;
468*7c478bd9Sstevel@tonic-gate 	}
469*7c478bd9Sstevel@tonic-gate 	trace1(TR_addProto, 1);
470*7c478bd9Sstevel@tonic-gate 	return;
471*7c478bd9Sstevel@tonic-gate }
472*7c478bd9Sstevel@tonic-gate 
473*7c478bd9Sstevel@tonic-gate /*
474*7c478bd9Sstevel@tonic-gate  * mergeProto
475*7c478bd9Sstevel@tonic-gate  *
476*7c478bd9Sstevel@tonic-gate  * input
477*7c478bd9Sstevel@tonic-gate  * 	char *tostring, *fromstring;
478*7c478bd9Sstevel@tonic-gate  */
479*7c478bd9Sstevel@tonic-gate static void
480*7c478bd9Sstevel@tonic-gate mergeProto(tostring, fromstring)
481*7c478bd9Sstevel@tonic-gate char *tostring, *fromstring;
482*7c478bd9Sstevel@tonic-gate {
483*7c478bd9Sstevel@tonic-gate 	char buffer[BUFSIZ];
484*7c478bd9Sstevel@tonic-gate 	int length;
485*7c478bd9Sstevel@tonic-gate 
486*7c478bd9Sstevel@tonic-gate 	trace1(TR_mergeProto, 0);
487*7c478bd9Sstevel@tonic-gate 	while (*(tostring = nextProto(tostring)) != NULLCHAR) {
488*7c478bd9Sstevel@tonic-gate 		if (*tostring == *fromstring)
489*7c478bd9Sstevel@tonic-gate 		break;
490*7c478bd9Sstevel@tonic-gate 		else
491*7c478bd9Sstevel@tonic-gate 		tostring++;
492*7c478bd9Sstevel@tonic-gate 	}
493*7c478bd9Sstevel@tonic-gate 
494*7c478bd9Sstevel@tonic-gate 	if (*tostring == NULLCHAR) {
495*7c478bd9Sstevel@tonic-gate 		length = nextProto(fromstring + 1) - fromstring;
496*7c478bd9Sstevel@tonic-gate 		(void) strncpy(tostring, fromstring, length);
497*7c478bd9Sstevel@tonic-gate 		*(tostring + length) = NULLCHAR;
498*7c478bd9Sstevel@tonic-gate 	} else {
499*7c478bd9Sstevel@tonic-gate 		tostring++;
500*7c478bd9Sstevel@tonic-gate 		fromstring++;
501*7c478bd9Sstevel@tonic-gate 		if ((*tostring !=  '(') && (*fromstring == '(')) {
502*7c478bd9Sstevel@tonic-gate 		(void) strcpy(buffer, tostring);
503*7c478bd9Sstevel@tonic-gate 		length = nextProto(fromstring) - fromstring;
504*7c478bd9Sstevel@tonic-gate 			(void) strncpy(tostring, fromstring, length);
505*7c478bd9Sstevel@tonic-gate 		(void) strcpy(tostring+length, buffer);
506*7c478bd9Sstevel@tonic-gate 		}
507*7c478bd9Sstevel@tonic-gate 	}
508*7c478bd9Sstevel@tonic-gate 	trace1(TR_mergeProto, 1);
509*7c478bd9Sstevel@tonic-gate 	return;
510*7c478bd9Sstevel@tonic-gate }
511*7c478bd9Sstevel@tonic-gate 
512*7c478bd9Sstevel@tonic-gate /*
513*7c478bd9Sstevel@tonic-gate  * removeProto
514*7c478bd9Sstevel@tonic-gate  *
515*7c478bd9Sstevel@tonic-gate  * char *old
516*7c478bd9Sstevel@tonic-gate  * char letter
517*7c478bd9Sstevel@tonic-gate  *
518*7c478bd9Sstevel@tonic-gate  * return
519*7c478bd9Sstevel@tonic-gate  *	none
520*7c478bd9Sstevel@tonic-gate  */
521*7c478bd9Sstevel@tonic-gate static void
522*7c478bd9Sstevel@tonic-gate removeProto(string, letter)
523*7c478bd9Sstevel@tonic-gate char *string, letter;
524*7c478bd9Sstevel@tonic-gate {
525*7c478bd9Sstevel@tonic-gate 	trace1(TR_removeProto, 0);
526*7c478bd9Sstevel@tonic-gate 	while (*(string = nextProto(string)) != NULLCHAR) {
527*7c478bd9Sstevel@tonic-gate 		if (*string == letter)
528*7c478bd9Sstevel@tonic-gate 		(void) strcpy(string, nextProto(string+1));
529*7c478bd9Sstevel@tonic-gate 		else
530*7c478bd9Sstevel@tonic-gate 		string++;
531*7c478bd9Sstevel@tonic-gate 	}
532*7c478bd9Sstevel@tonic-gate 	trace1(TR_removeProto, 1);
533*7c478bd9Sstevel@tonic-gate }
534*7c478bd9Sstevel@tonic-gate 
535*7c478bd9Sstevel@tonic-gate /*
536*7c478bd9Sstevel@tonic-gate  * nextProto
537*7c478bd9Sstevel@tonic-gate  *	char *string;
538*7c478bd9Sstevel@tonic-gate  * return
539*7c478bd9Sstevel@tonic-gate  *	char * to next non-parameter letter
540*7c478bd9Sstevel@tonic-gate  */
541*7c478bd9Sstevel@tonic-gate static char *
542*7c478bd9Sstevel@tonic-gate nextProto(string)
543*7c478bd9Sstevel@tonic-gate char *string;
544*7c478bd9Sstevel@tonic-gate {
545*7c478bd9Sstevel@tonic-gate 	trace1(TR_nextProto, 0);
546*7c478bd9Sstevel@tonic-gate 	if (*string == '(')
547*7c478bd9Sstevel@tonic-gate 		while (*string != NULLCHAR)
548*7c478bd9Sstevel@tonic-gate 		if (*(string++) == ')')
549*7c478bd9Sstevel@tonic-gate 			break;
550*7c478bd9Sstevel@tonic-gate 	trace1(TR_nextProto, 1);
551*7c478bd9Sstevel@tonic-gate 	return (string);
552*7c478bd9Sstevel@tonic-gate }
553*7c478bd9Sstevel@tonic-gate 
554*7c478bd9Sstevel@tonic-gate /*
555*7c478bd9Sstevel@tonic-gate  * findProto
556*7c478bd9Sstevel@tonic-gate  *	char *desired,
557*7c478bd9Sstevel@tonic-gate  *	char protoPtr;
558*7c478bd9Sstevel@tonic-gate  * return
559*7c478bd9Sstevel@tonic-gate  *	char *pointer to found or string terminating NULLCHAR
560*7c478bd9Sstevel@tonic-gate  */
561*7c478bd9Sstevel@tonic-gate GLOBAL char *
562*7c478bd9Sstevel@tonic-gate findProto(string, letter)
563*7c478bd9Sstevel@tonic-gate char *string;
564*7c478bd9Sstevel@tonic-gate char letter;
565*7c478bd9Sstevel@tonic-gate {
566*7c478bd9Sstevel@tonic-gate 	trace1(TR_findProto, 0);
567*7c478bd9Sstevel@tonic-gate 	while (*(string = nextProto(string)) != NULLCHAR)
568*7c478bd9Sstevel@tonic-gate 		if (*string == letter)
569*7c478bd9Sstevel@tonic-gate 		break;
570*7c478bd9Sstevel@tonic-gate 		else
571*7c478bd9Sstevel@tonic-gate 		string++;
572*7c478bd9Sstevel@tonic-gate 	trace1(TR_findProto, 1);
573*7c478bd9Sstevel@tonic-gate 	return (string);
574*7c478bd9Sstevel@tonic-gate }
575*7c478bd9Sstevel@tonic-gate 
576*7c478bd9Sstevel@tonic-gate /*
577*7c478bd9Sstevel@tonic-gate  * chat -	do conversation
578*7c478bd9Sstevel@tonic-gate  * input:
579*7c478bd9Sstevel@tonic-gate  *	nf - number of fields in flds array
580*7c478bd9Sstevel@tonic-gate  *	flds - fields from Systems file
581*7c478bd9Sstevel@tonic-gate  *	fn - write file number
582*7c478bd9Sstevel@tonic-gate  *	phstr1 - phone number to replace \D
583*7c478bd9Sstevel@tonic-gate  *	phstr2 - phone number to replace \T
584*7c478bd9Sstevel@tonic-gate  *
585*7c478bd9Sstevel@tonic-gate  *	return codes:  0  |  FAIL
586*7c478bd9Sstevel@tonic-gate  */
587*7c478bd9Sstevel@tonic-gate 
588*7c478bd9Sstevel@tonic-gate GLOBAL int
589*7c478bd9Sstevel@tonic-gate chat(nf, flds, fn, phstr1, phstr2)
590*7c478bd9Sstevel@tonic-gate char *flds[], *phstr1, *phstr2;
591*7c478bd9Sstevel@tonic-gate int nf, fn;
592*7c478bd9Sstevel@tonic-gate {
593*7c478bd9Sstevel@tonic-gate 	char *want, *altern;
594*7c478bd9Sstevel@tonic-gate 	int k, ok;
595*7c478bd9Sstevel@tonic-gate 
596*7c478bd9Sstevel@tonic-gate 	trace3(TR_chat, 0, nf, fn);
597*7c478bd9Sstevel@tonic-gate 	for (k = 0; k < nf; k += 2) {
598*7c478bd9Sstevel@tonic-gate 		want = flds[k];
599*7c478bd9Sstevel@tonic-gate 		ok = FAIL;
600*7c478bd9Sstevel@tonic-gate 		while (ok != 0) {
601*7c478bd9Sstevel@tonic-gate 			altern = index(want, '-');
602*7c478bd9Sstevel@tonic-gate 			if (altern != NULL)
603*7c478bd9Sstevel@tonic-gate 				*altern++ = NULLCHAR;
604*7c478bd9Sstevel@tonic-gate 			ok = expect(want, fn);
605*7c478bd9Sstevel@tonic-gate 			if (ok == 0)
606*7c478bd9Sstevel@tonic-gate 				break;
607*7c478bd9Sstevel@tonic-gate 			if (altern == NULL) {
608*7c478bd9Sstevel@tonic-gate 				Uerror = SS_LOGIN_FAILED;
609*7c478bd9Sstevel@tonic-gate 				logent(UERRORTEXT, "FAILED");
610*7c478bd9Sstevel@tonic-gate 				trace1(TR_chat, 1);
611*7c478bd9Sstevel@tonic-gate 				return (FAIL);
612*7c478bd9Sstevel@tonic-gate 			}
613*7c478bd9Sstevel@tonic-gate 			want = index(altern, '-');
614*7c478bd9Sstevel@tonic-gate 			if (want != NULL)
615*7c478bd9Sstevel@tonic-gate 				*want++ = NULLCHAR;
616*7c478bd9Sstevel@tonic-gate 			sendthem(altern, fn, phstr1, phstr2);
617*7c478bd9Sstevel@tonic-gate 		}
618*7c478bd9Sstevel@tonic-gate 		sleep(2);
619*7c478bd9Sstevel@tonic-gate 		if (flds[k+1])
620*7c478bd9Sstevel@tonic-gate 			sendthem(flds[k+1], fn, phstr1, phstr2);
621*7c478bd9Sstevel@tonic-gate 	}
622*7c478bd9Sstevel@tonic-gate 	trace1(TR_chat, 1);
623*7c478bd9Sstevel@tonic-gate 	return (0);
624*7c478bd9Sstevel@tonic-gate }
625*7c478bd9Sstevel@tonic-gate 
626*7c478bd9Sstevel@tonic-gate #define MR 1000
627*7c478bd9Sstevel@tonic-gate 
628*7c478bd9Sstevel@tonic-gate /*
629*7c478bd9Sstevel@tonic-gate  *	expect(str, fn)	look for expected string w/ possible special chars
630*7c478bd9Sstevel@tonic-gate  *	char *str;
631*7c478bd9Sstevel@tonic-gate  *
632*7c478bd9Sstevel@tonic-gate  *	return codes:
633*7c478bd9Sstevel@tonic-gate  *		0  -  found
634*7c478bd9Sstevel@tonic-gate  *		FAIL  -  lost line or too many characters read
635*7c478bd9Sstevel@tonic-gate  *		some character  -  timed out
636*7c478bd9Sstevel@tonic-gate  */
637*7c478bd9Sstevel@tonic-gate 
638*7c478bd9Sstevel@tonic-gate GLOBAL int
639*7c478bd9Sstevel@tonic-gate expect(str, fn)
640*7c478bd9Sstevel@tonic-gate char *str;
641*7c478bd9Sstevel@tonic-gate int fn;
642*7c478bd9Sstevel@tonic-gate {
643*7c478bd9Sstevel@tonic-gate 	register char *bptr, *sptr;
644*7c478bd9Sstevel@tonic-gate 	char    buf[BUFSIZ];
645*7c478bd9Sstevel@tonic-gate 
646*7c478bd9Sstevel@tonic-gate 	bptr = buf;
647*7c478bd9Sstevel@tonic-gate 
648*7c478bd9Sstevel@tonic-gate 	for (sptr = str; *sptr; sptr++) {
649*7c478bd9Sstevel@tonic-gate 		if (*sptr == '\\') {
650*7c478bd9Sstevel@tonic-gate 			switch (*++sptr) {
651*7c478bd9Sstevel@tonic-gate 			case 'H':
652*7c478bd9Sstevel@tonic-gate 				*bptr++ = '\0';
653*7c478bd9Sstevel@tonic-gate 				if (expect_str(buf, fn) == FAIL) {
654*7c478bd9Sstevel@tonic-gate 					return (FAIL);
655*7c478bd9Sstevel@tonic-gate 				}
656*7c478bd9Sstevel@tonic-gate 				if (wait_for_hangup(fn) == FAIL) {
657*7c478bd9Sstevel@tonic-gate 					return (FAIL);
658*7c478bd9Sstevel@tonic-gate 				}
659*7c478bd9Sstevel@tonic-gate 				bptr = buf;
660*7c478bd9Sstevel@tonic-gate 				continue;
661*7c478bd9Sstevel@tonic-gate 			case '\\':
662*7c478bd9Sstevel@tonic-gate 				*bptr++ = '\\';
663*7c478bd9Sstevel@tonic-gate 				continue;
664*7c478bd9Sstevel@tonic-gate 			default:
665*7c478bd9Sstevel@tonic-gate 				*bptr++ = '\\';
666*7c478bd9Sstevel@tonic-gate 				*bptr++ = *sptr;
667*7c478bd9Sstevel@tonic-gate 				continue;
668*7c478bd9Sstevel@tonic-gate 			}
669*7c478bd9Sstevel@tonic-gate 		} else
670*7c478bd9Sstevel@tonic-gate 			*bptr++ = *sptr;
671*7c478bd9Sstevel@tonic-gate 	}
672*7c478bd9Sstevel@tonic-gate 	*bptr = '\0';
673*7c478bd9Sstevel@tonic-gate 	if (expect_str(buf, fn) == FAIL) {
674*7c478bd9Sstevel@tonic-gate 		return (FAIL);
675*7c478bd9Sstevel@tonic-gate 	}
676*7c478bd9Sstevel@tonic-gate 	return (0);
677*7c478bd9Sstevel@tonic-gate }
678*7c478bd9Sstevel@tonic-gate 
679*7c478bd9Sstevel@tonic-gate /*
680*7c478bd9Sstevel@tonic-gate  *	expect_str(str, fn)	look for expected string, w/ no special chars
681*7c478bd9Sstevel@tonic-gate  *
682*7c478bd9Sstevel@tonic-gate  *	return codes:
683*7c478bd9Sstevel@tonic-gate  *		0  -  found
684*7c478bd9Sstevel@tonic-gate  *		FAIL  -  too many characters read
685*7c478bd9Sstevel@tonic-gate  *		some character  -  timed out
686*7c478bd9Sstevel@tonic-gate  */
687*7c478bd9Sstevel@tonic-gate 
688*7c478bd9Sstevel@tonic-gate GLOBAL int
689*7c478bd9Sstevel@tonic-gate expect_str(str, fn)
690*7c478bd9Sstevel@tonic-gate char *str;
691*7c478bd9Sstevel@tonic-gate int fn;
692*7c478bd9Sstevel@tonic-gate {
693*7c478bd9Sstevel@tonic-gate 	static char rdvec[MR];
694*7c478bd9Sstevel@tonic-gate 	char *rp = rdvec;
695*7c478bd9Sstevel@tonic-gate 	register int kr, c;
696*7c478bd9Sstevel@tonic-gate 	char nextch;
697*7c478bd9Sstevel@tonic-gate 
698*7c478bd9Sstevel@tonic-gate 	trace2(TR_expect, 0, fn);
699*7c478bd9Sstevel@tonic-gate 	*rp = 0;
700*7c478bd9Sstevel@tonic-gate 
701*7c478bd9Sstevel@tonic-gate 	CDEBUG(4, "expect: (%s", "");
702*7c478bd9Sstevel@tonic-gate 	for (c=0; (kr=str[c]) != 0 ; c++)
703*7c478bd9Sstevel@tonic-gate 		if (kr < 040) {
704*7c478bd9Sstevel@tonic-gate 			/*EMPTY*/
705*7c478bd9Sstevel@tonic-gate 			CDEBUG(4, "^%c", kr | 0100);
706*7c478bd9Sstevel@tonic-gate 		} else {
707*7c478bd9Sstevel@tonic-gate 			/*EMPTY*/
708*7c478bd9Sstevel@tonic-gate 			CDEBUG(4, "%c", kr);
709*7c478bd9Sstevel@tonic-gate 		}
710*7c478bd9Sstevel@tonic-gate 	CDEBUG(4, ")\n%s", "");
711*7c478bd9Sstevel@tonic-gate 
712*7c478bd9Sstevel@tonic-gate 	if (EQUALS(str, "\"\"")) {
713*7c478bd9Sstevel@tonic-gate 		CDEBUG(4, "got it\n%s", "");
714*7c478bd9Sstevel@tonic-gate 		trace1(TR_expect, 1);
715*7c478bd9Sstevel@tonic-gate 		return (0);
716*7c478bd9Sstevel@tonic-gate 	}
717*7c478bd9Sstevel@tonic-gate 	if (*str== '\0') {
718*7c478bd9Sstevel@tonic-gate 		return(0);
719*7c478bd9Sstevel@tonic-gate 	}
720*7c478bd9Sstevel@tonic-gate 	if (setjmp(Sjbuf)) {
721*7c478bd9Sstevel@tonic-gate 		trace1(TR_expect, 1);
722*7c478bd9Sstevel@tonic-gate 		return (FAIL);
723*7c478bd9Sstevel@tonic-gate 	}
724*7c478bd9Sstevel@tonic-gate 	(void) signal(SIGALRM, alarmtr);
725*7c478bd9Sstevel@tonic-gate 	alarm(expecttime);
726*7c478bd9Sstevel@tonic-gate 	while (notin(str, rdvec)) {
727*7c478bd9Sstevel@tonic-gate 		errno = 0;
728*7c478bd9Sstevel@tonic-gate 		kr = (*Read)(fn, &nextch, 1);
729*7c478bd9Sstevel@tonic-gate 		if (kr <= 0) {
730*7c478bd9Sstevel@tonic-gate 			alarm(0);
731*7c478bd9Sstevel@tonic-gate 			CDEBUG(4, "lost line errno - %d\n", errno);
732*7c478bd9Sstevel@tonic-gate 			logent("LOGIN", "LOST LINE");
733*7c478bd9Sstevel@tonic-gate 			trace1(TR_expect, 1);
734*7c478bd9Sstevel@tonic-gate 			return (FAIL);
735*7c478bd9Sstevel@tonic-gate 		}
736*7c478bd9Sstevel@tonic-gate 		c = nextch & 0177;
737*7c478bd9Sstevel@tonic-gate 		CDEBUG(4, "%s", c < 040 ? "^" : "");
738*7c478bd9Sstevel@tonic-gate 		CDEBUG(4, "%c", c < 040 ? c | 0100 : c);
739*7c478bd9Sstevel@tonic-gate 		if ((*rp = nextch & 0177) != NULLCHAR)
740*7c478bd9Sstevel@tonic-gate 			rp++;
741*7c478bd9Sstevel@tonic-gate 		if (rp >= rdvec + MR) {
742*7c478bd9Sstevel@tonic-gate 			CDEBUG(4, "enough already\n%s", "");
743*7c478bd9Sstevel@tonic-gate 			alarm(0);
744*7c478bd9Sstevel@tonic-gate 			trace1(TR_expect, 1);
745*7c478bd9Sstevel@tonic-gate 			return (FAIL);
746*7c478bd9Sstevel@tonic-gate 		}
747*7c478bd9Sstevel@tonic-gate 		*rp = NULLCHAR;
748*7c478bd9Sstevel@tonic-gate 	}
749*7c478bd9Sstevel@tonic-gate 	alarm(0);
750*7c478bd9Sstevel@tonic-gate 	CDEBUG(4, "got it\n%s", "");
751*7c478bd9Sstevel@tonic-gate 	trace1(TR_expect, 1);
752*7c478bd9Sstevel@tonic-gate 	return (0);
753*7c478bd9Sstevel@tonic-gate }
754*7c478bd9Sstevel@tonic-gate 
755*7c478bd9Sstevel@tonic-gate 
756*7c478bd9Sstevel@tonic-gate /*
757*7c478bd9Sstevel@tonic-gate  *	alarmtr()  -  catch alarm routine for "expect".
758*7c478bd9Sstevel@tonic-gate  */
759*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
760*7c478bd9Sstevel@tonic-gate GLOBAL void
761*7c478bd9Sstevel@tonic-gate alarmtr(sig)
762*7c478bd9Sstevel@tonic-gate int sig;
763*7c478bd9Sstevel@tonic-gate {
764*7c478bd9Sstevel@tonic-gate 	trace2(TR_alarmtr, 0, sig);
765*7c478bd9Sstevel@tonic-gate 	CDEBUG(6, "timed out\n%s", "");
766*7c478bd9Sstevel@tonic-gate 	longjmp(Sjbuf, 1);
767*7c478bd9Sstevel@tonic-gate 	trace2(TR_alarmtr, 1, sig);
768*7c478bd9Sstevel@tonic-gate }
769*7c478bd9Sstevel@tonic-gate 
770*7c478bd9Sstevel@tonic-gate /*
771*7c478bd9Sstevel@tonic-gate  *	wait_for_hangup() - wait for a hangup to occur on the given device
772*7c478bd9Sstevel@tonic-gate  */
773*7c478bd9Sstevel@tonic-gate int
774*7c478bd9Sstevel@tonic-gate wait_for_hangup(dcf)
775*7c478bd9Sstevel@tonic-gate 	int dcf;
776*7c478bd9Sstevel@tonic-gate {
777*7c478bd9Sstevel@tonic-gate 	int rval;
778*7c478bd9Sstevel@tonic-gate 	char buff[BUFSIZ];
779*7c478bd9Sstevel@tonic-gate 
780*7c478bd9Sstevel@tonic-gate 	CDEBUG(4, "Waiting for hangup\n%s", "");
781*7c478bd9Sstevel@tonic-gate 	while((rval = read(dcf, buff, BUFSIZ)) > 0);
782*7c478bd9Sstevel@tonic-gate 
783*7c478bd9Sstevel@tonic-gate 	if (rval < 0) {
784*7c478bd9Sstevel@tonic-gate 		return (FAIL);
785*7c478bd9Sstevel@tonic-gate 	}
786*7c478bd9Sstevel@tonic-gate 	CDEBUG(4, "Received hangup\n%s", "");
787*7c478bd9Sstevel@tonic-gate 
788*7c478bd9Sstevel@tonic-gate 	if (clear_hup(dcf) != SUCCESS) {
789*7c478bd9Sstevel@tonic-gate 	    CDEBUG(4, "Unable to clear hup on device\n%s", "");
790*7c478bd9Sstevel@tonic-gate 	    return (FAIL);
791*7c478bd9Sstevel@tonic-gate 	}
792*7c478bd9Sstevel@tonic-gate 	return (SUCCESS);
793*7c478bd9Sstevel@tonic-gate }
794*7c478bd9Sstevel@tonic-gate 
795*7c478bd9Sstevel@tonic-gate /*
796*7c478bd9Sstevel@tonic-gate  *	sendthem(str, fn, phstr1, phstr2)	send line of chat sequence
797*7c478bd9Sstevel@tonic-gate  *	char *str, *phstr;
798*7c478bd9Sstevel@tonic-gate  *
799*7c478bd9Sstevel@tonic-gate  *	return codes:  none
800*7c478bd9Sstevel@tonic-gate  */
801*7c478bd9Sstevel@tonic-gate 
802*7c478bd9Sstevel@tonic-gate #define FLUSH() {\
803*7c478bd9Sstevel@tonic-gate 	if ((bptr - buf) > 0)\
804*7c478bd9Sstevel@tonic-gate 		if (wrstr(fn, buf, bptr - buf, echocheck) != SUCCESS)\
805*7c478bd9Sstevel@tonic-gate 			goto err;\
806*7c478bd9Sstevel@tonic-gate 	bptr = buf;\
807*7c478bd9Sstevel@tonic-gate }
808*7c478bd9Sstevel@tonic-gate 
809*7c478bd9Sstevel@tonic-gate GLOBAL void
810*7c478bd9Sstevel@tonic-gate sendthem(str, fn, phstr1, phstr2)
811*7c478bd9Sstevel@tonic-gate char *str, *phstr1, *phstr2;
812*7c478bd9Sstevel@tonic-gate int fn;
813*7c478bd9Sstevel@tonic-gate {
814*7c478bd9Sstevel@tonic-gate 	int sendcr = 1, echocheck = 0;
815*7c478bd9Sstevel@tonic-gate 	register char	*sptr, *bptr;
816*7c478bd9Sstevel@tonic-gate 	char	buf[BUFSIZ];
817*7c478bd9Sstevel@tonic-gate 	struct termio	ttybuf;
818*7c478bd9Sstevel@tonic-gate 
819*7c478bd9Sstevel@tonic-gate 	/* should be EQUALS, but previous versions had BREAK n for integer n */
820*7c478bd9Sstevel@tonic-gate 
821*7c478bd9Sstevel@tonic-gate 	trace2(TR_sendthem, 0, fn);
822*7c478bd9Sstevel@tonic-gate 	if (PREFIX("BREAK", str)) {
823*7c478bd9Sstevel@tonic-gate 		/* send break */
824*7c478bd9Sstevel@tonic-gate 		CDEBUG(5, "BREAK\n%s", "");
825*7c478bd9Sstevel@tonic-gate 		(*genbrk)(fn);
826*7c478bd9Sstevel@tonic-gate 		trace1(TR_sendthem, 1);
827*7c478bd9Sstevel@tonic-gate 		return;
828*7c478bd9Sstevel@tonic-gate 	}
829*7c478bd9Sstevel@tonic-gate 
830*7c478bd9Sstevel@tonic-gate 	if (EQUALS(str, "EOT")) {
831*7c478bd9Sstevel@tonic-gate 		CDEBUG(5, "EOT\n%s", "");
832*7c478bd9Sstevel@tonic-gate 		(void) (*Write)(fn, EOTMSG, strlen(EOTMSG));
833*7c478bd9Sstevel@tonic-gate 		trace1(TR_sendthem, 1);
834*7c478bd9Sstevel@tonic-gate 		return;
835*7c478bd9Sstevel@tonic-gate 	}
836*7c478bd9Sstevel@tonic-gate 
837*7c478bd9Sstevel@tonic-gate 	if (EQUALS(str, "\"\"")) {
838*7c478bd9Sstevel@tonic-gate 		CDEBUG(5, "\"\"\n%s", "");
839*7c478bd9Sstevel@tonic-gate 		str += 2;
840*7c478bd9Sstevel@tonic-gate 	}
841*7c478bd9Sstevel@tonic-gate 
842*7c478bd9Sstevel@tonic-gate 	bptr = buf;
843*7c478bd9Sstevel@tonic-gate 	CDEBUG(5, "sendthem (%s", "");
844*7c478bd9Sstevel@tonic-gate 	for (sptr = str; *sptr; sptr++) {
845*7c478bd9Sstevel@tonic-gate 		if (*sptr == '\\') {
846*7c478bd9Sstevel@tonic-gate 			switch(*++sptr) {
847*7c478bd9Sstevel@tonic-gate 
848*7c478bd9Sstevel@tonic-gate 			/* adjust switches */
849*7c478bd9Sstevel@tonic-gate 			case 'c':	/* no CR after string */
850*7c478bd9Sstevel@tonic-gate 				FLUSH();
851*7c478bd9Sstevel@tonic-gate 				if (sptr[1] == NULLCHAR) {
852*7c478bd9Sstevel@tonic-gate 					CDEBUG(5, "<NO CR>%s", "");
853*7c478bd9Sstevel@tonic-gate 					sendcr = 0;
854*7c478bd9Sstevel@tonic-gate 				} else {
855*7c478bd9Sstevel@tonic-gate 					/*EMPTY*/
856*7c478bd9Sstevel@tonic-gate 					CDEBUG(5, "<NO CR IGNORED>\n%s", "");
857*7c478bd9Sstevel@tonic-gate 				}
858*7c478bd9Sstevel@tonic-gate 				continue;
859*7c478bd9Sstevel@tonic-gate 			}
860*7c478bd9Sstevel@tonic-gate 
861*7c478bd9Sstevel@tonic-gate 			/* stash in buf and continue */
862*7c478bd9Sstevel@tonic-gate 			switch(*sptr) {
863*7c478bd9Sstevel@tonic-gate 			case 'D':	/* raw phnum */
864*7c478bd9Sstevel@tonic-gate 				strcpy(bptr, phstr1);
865*7c478bd9Sstevel@tonic-gate 				bptr += strlen(bptr);
866*7c478bd9Sstevel@tonic-gate 				continue;
867*7c478bd9Sstevel@tonic-gate 			case 'T':	/* translated phnum */
868*7c478bd9Sstevel@tonic-gate 				strcpy(bptr, phstr2);
869*7c478bd9Sstevel@tonic-gate 				bptr += strlen(bptr);
870*7c478bd9Sstevel@tonic-gate 				continue;
871*7c478bd9Sstevel@tonic-gate 			case 'N':	/* null */
872*7c478bd9Sstevel@tonic-gate 				*bptr++ = 0;
873*7c478bd9Sstevel@tonic-gate 				continue;
874*7c478bd9Sstevel@tonic-gate 			case 's':	/* space */
875*7c478bd9Sstevel@tonic-gate 				*bptr++ = ' ';
876*7c478bd9Sstevel@tonic-gate 				continue;
877*7c478bd9Sstevel@tonic-gate 			case '\\':	/* backslash escapes itself */
878*7c478bd9Sstevel@tonic-gate 				*bptr++ = *sptr;
879*7c478bd9Sstevel@tonic-gate 				continue;
880*7c478bd9Sstevel@tonic-gate 			default:	/* send the backslash */
881*7c478bd9Sstevel@tonic-gate 				*bptr++ = '\\';
882*7c478bd9Sstevel@tonic-gate 				*bptr++ = *sptr;
883*7c478bd9Sstevel@tonic-gate 				continue;
884*7c478bd9Sstevel@tonic-gate 
885*7c478bd9Sstevel@tonic-gate 			/* flush buf, perform action, and continue */
886*7c478bd9Sstevel@tonic-gate 			case 'E':	/* echo check on */
887*7c478bd9Sstevel@tonic-gate 				FLUSH();
888*7c478bd9Sstevel@tonic-gate 				CDEBUG(5, "ECHO CHECK ON\n%s", "");
889*7c478bd9Sstevel@tonic-gate 				echocheck = 1;
890*7c478bd9Sstevel@tonic-gate 				continue;
891*7c478bd9Sstevel@tonic-gate 			case 'e':	/* echo check off */
892*7c478bd9Sstevel@tonic-gate 				FLUSH();
893*7c478bd9Sstevel@tonic-gate 				CDEBUG(5, "ECHO CHECK OFF\n%s", "");
894*7c478bd9Sstevel@tonic-gate 				echocheck = 0;
895*7c478bd9Sstevel@tonic-gate 				continue;
896*7c478bd9Sstevel@tonic-gate 			case 'd':	/* sleep briefly */
897*7c478bd9Sstevel@tonic-gate 				FLUSH();
898*7c478bd9Sstevel@tonic-gate 				CDEBUG(5, "DELAY\n%s", "");
899*7c478bd9Sstevel@tonic-gate 				sleep(2);
900*7c478bd9Sstevel@tonic-gate 				continue;
901*7c478bd9Sstevel@tonic-gate 			case 'p':	/* pause momentarily */
902*7c478bd9Sstevel@tonic-gate 				FLUSH();
903*7c478bd9Sstevel@tonic-gate 				CDEBUG(5, "PAUSE\n%s", "");
904*7c478bd9Sstevel@tonic-gate 				nap(HZ/4);	/* approximately 1/4 second */
905*7c478bd9Sstevel@tonic-gate 				continue;
906*7c478bd9Sstevel@tonic-gate 			case 'K':	/* inline break */
907*7c478bd9Sstevel@tonic-gate 				FLUSH();
908*7c478bd9Sstevel@tonic-gate 				CDEBUG(5, "BREAK\n%s", "");
909*7c478bd9Sstevel@tonic-gate 				(*genbrk)(fn);
910*7c478bd9Sstevel@tonic-gate 				continue;
911*7c478bd9Sstevel@tonic-gate 			case 'M':	/* modem control - set CLOCAL */
912*7c478bd9Sstevel@tonic-gate 			case 'm':	/* no modem control - clear CLOCAL */
913*7c478bd9Sstevel@tonic-gate 				FLUSH();
914*7c478bd9Sstevel@tonic-gate 				CDEBUG(5, ")\n%s CLOCAL ",
915*7c478bd9Sstevel@tonic-gate 					(*sptr == 'M' ? "set" : "clear"));
916*7c478bd9Sstevel@tonic-gate 				if ((*Ioctl)(fn, TCGETA, &ttybuf) != 0 ) {
917*7c478bd9Sstevel@tonic-gate 					/*EMPTY*/
918*7c478bd9Sstevel@tonic-gate 					CDEBUG(5, "ignored. TCGETA failed, errno %d", errno);
919*7c478bd9Sstevel@tonic-gate 				} else {
920*7c478bd9Sstevel@tonic-gate 					if (*sptr == 'M')
921*7c478bd9Sstevel@tonic-gate 					ttybuf.c_cflag |= CLOCAL;
922*7c478bd9Sstevel@tonic-gate 					else
923*7c478bd9Sstevel@tonic-gate 					ttybuf.c_cflag &= ~CLOCAL;
924*7c478bd9Sstevel@tonic-gate 					if ((*Ioctl)(fn, TCSETAW, &ttybuf) != 0)
925*7c478bd9Sstevel@tonic-gate 					/*EMPTY*/
926*7c478bd9Sstevel@tonic-gate 					CDEBUG(5, "failed. TCSETAW failed, errno %d", errno);
927*7c478bd9Sstevel@tonic-gate 				}
928*7c478bd9Sstevel@tonic-gate 				CDEBUG(5, "\n%s", "");
929*7c478bd9Sstevel@tonic-gate 				continue;
930*7c478bd9Sstevel@tonic-gate 			}
931*7c478bd9Sstevel@tonic-gate 		} else
932*7c478bd9Sstevel@tonic-gate 			*bptr++ = *sptr;
933*7c478bd9Sstevel@tonic-gate 	}
934*7c478bd9Sstevel@tonic-gate 	if (sendcr)
935*7c478bd9Sstevel@tonic-gate 		*bptr++ = '\r';
936*7c478bd9Sstevel@tonic-gate 	if ((bptr - buf) > 0)
937*7c478bd9Sstevel@tonic-gate 		(void) wrstr(fn, buf, bptr - buf, echocheck);
938*7c478bd9Sstevel@tonic-gate 
939*7c478bd9Sstevel@tonic-gate err:
940*7c478bd9Sstevel@tonic-gate 	CDEBUG(5, ")\n%s", "");
941*7c478bd9Sstevel@tonic-gate 	trace1(TR_sendthem, 1);
942*7c478bd9Sstevel@tonic-gate 	return;
943*7c478bd9Sstevel@tonic-gate }
944*7c478bd9Sstevel@tonic-gate 
945*7c478bd9Sstevel@tonic-gate #undef FLUSH
946*7c478bd9Sstevel@tonic-gate 
947*7c478bd9Sstevel@tonic-gate GLOBAL int
948*7c478bd9Sstevel@tonic-gate wrstr(int fn, char *buf, int len, int echocheck)
949*7c478bd9Sstevel@tonic-gate {
950*7c478bd9Sstevel@tonic-gate 	int 	i;
951*7c478bd9Sstevel@tonic-gate 	int	 dummy;
952*7c478bd9Sstevel@tonic-gate 	char dbuf[BUFSIZ], *dbptr = dbuf;
953*7c478bd9Sstevel@tonic-gate 
954*7c478bd9Sstevel@tonic-gate 	trace1(TR_wrstr, 0);
955*7c478bd9Sstevel@tonic-gate 	buf[len] = 0;
956*7c478bd9Sstevel@tonic-gate 
957*7c478bd9Sstevel@tonic-gate 	if (echocheck) {
958*7c478bd9Sstevel@tonic-gate 		dummy = wrchr(fn, buf, len);
959*7c478bd9Sstevel@tonic-gate 		trace1(TR_wrstr, 1);
960*7c478bd9Sstevel@tonic-gate 		return (dummy);
961*7c478bd9Sstevel@tonic-gate 	}
962*7c478bd9Sstevel@tonic-gate 
963*7c478bd9Sstevel@tonic-gate 	if (Debug >= 5) {
964*7c478bd9Sstevel@tonic-gate 		if (sysaccess(ACCESS_SYSTEMS) == 0) { /* Systems file access ok */
965*7c478bd9Sstevel@tonic-gate 			for (i = 0; i < len; i++) {
966*7c478bd9Sstevel@tonic-gate 				*dbptr = buf[i];
967*7c478bd9Sstevel@tonic-gate 				if (*dbptr < 040) {
968*7c478bd9Sstevel@tonic-gate 					*dbptr++ = '^';
969*7c478bd9Sstevel@tonic-gate 					*dbptr = buf[i] | 0100;
970*7c478bd9Sstevel@tonic-gate 				}
971*7c478bd9Sstevel@tonic-gate 				dbptr++;
972*7c478bd9Sstevel@tonic-gate 			}
973*7c478bd9Sstevel@tonic-gate 			*dbptr = 0;
974*7c478bd9Sstevel@tonic-gate 		} else
975*7c478bd9Sstevel@tonic-gate 			strcpy(dbuf, "????????");
976*7c478bd9Sstevel@tonic-gate 		CDEBUG(5, "%s", dbuf);
977*7c478bd9Sstevel@tonic-gate 	}
978*7c478bd9Sstevel@tonic-gate 	if ((*Write)(fn, buf, len) != len) {
979*7c478bd9Sstevel@tonic-gate 		trace1(TR_wrstr, 1);
980*7c478bd9Sstevel@tonic-gate 		return (FAIL);
981*7c478bd9Sstevel@tonic-gate 	}
982*7c478bd9Sstevel@tonic-gate 	trace1(TR_wrstr, 1);
983*7c478bd9Sstevel@tonic-gate 	return (SUCCESS);
984*7c478bd9Sstevel@tonic-gate }
985*7c478bd9Sstevel@tonic-gate 
986*7c478bd9Sstevel@tonic-gate GLOBAL int
987*7c478bd9Sstevel@tonic-gate wrchr(int fn, char *buf, int len)
988*7c478bd9Sstevel@tonic-gate {
989*7c478bd9Sstevel@tonic-gate 	int 	i, saccess;
990*7c478bd9Sstevel@tonic-gate 	char	cin, cout;
991*7c478bd9Sstevel@tonic-gate 
992*7c478bd9Sstevel@tonic-gate 	trace2(TR_wrchr, 0, fn);
993*7c478bd9Sstevel@tonic-gate 	saccess = (sysaccess(ACCESS_SYSTEMS) == 0); /* protect Systems file */
994*7c478bd9Sstevel@tonic-gate 	if (setjmp(Sjbuf)) {
995*7c478bd9Sstevel@tonic-gate 		trace1(TR_wrchr, 1);
996*7c478bd9Sstevel@tonic-gate 		return (FAIL);
997*7c478bd9Sstevel@tonic-gate 	}
998*7c478bd9Sstevel@tonic-gate 	(void) signal(SIGALRM, alarmtr);
999*7c478bd9Sstevel@tonic-gate 
1000*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < len; i++) {
1001*7c478bd9Sstevel@tonic-gate 		cout = buf[i];
1002*7c478bd9Sstevel@tonic-gate 		if (saccess) {
1003*7c478bd9Sstevel@tonic-gate 			/*EMPTY*/
1004*7c478bd9Sstevel@tonic-gate 			CDEBUG(5, "%s", cout < 040 ? "^" : "");
1005*7c478bd9Sstevel@tonic-gate 			CDEBUG(5, "%c", cout < 040 ? cout | 0100 : cout);
1006*7c478bd9Sstevel@tonic-gate 		} else {
1007*7c478bd9Sstevel@tonic-gate 			/*EMPTY*/
1008*7c478bd9Sstevel@tonic-gate 			CDEBUG(5, "?%s", "");
1009*7c478bd9Sstevel@tonic-gate 		}
1010*7c478bd9Sstevel@tonic-gate 		if (((*Write)(fn, &cout, 1)) != 1) {
1011*7c478bd9Sstevel@tonic-gate 			trace1(TR_wrchr, 1);
1012*7c478bd9Sstevel@tonic-gate 			return (FAIL);
1013*7c478bd9Sstevel@tonic-gate 		}
1014*7c478bd9Sstevel@tonic-gate 		do {
1015*7c478bd9Sstevel@tonic-gate 			(void) alarm(expecttime);
1016*7c478bd9Sstevel@tonic-gate 			if ((*Read)(fn, &cin, 1) != 1) {
1017*7c478bd9Sstevel@tonic-gate 				trace1(TR_wrchr, 1);
1018*7c478bd9Sstevel@tonic-gate 				return (FAIL);
1019*7c478bd9Sstevel@tonic-gate 			}
1020*7c478bd9Sstevel@tonic-gate 			(void) alarm(0);
1021*7c478bd9Sstevel@tonic-gate 			cin &= 0177;
1022*7c478bd9Sstevel@tonic-gate 			if (saccess) {
1023*7c478bd9Sstevel@tonic-gate 				/*EMPTY*/
1024*7c478bd9Sstevel@tonic-gate 				CDEBUG(5, "%s", cin < 040 ? "^" : "");
1025*7c478bd9Sstevel@tonic-gate 				CDEBUG(5, "%c", cin < 040 ? cin | 0100 : cin);
1026*7c478bd9Sstevel@tonic-gate 			} else {
1027*7c478bd9Sstevel@tonic-gate 				/*EMPTY*/
1028*7c478bd9Sstevel@tonic-gate 				CDEBUG(5, "?%s", "");
1029*7c478bd9Sstevel@tonic-gate 			}
1030*7c478bd9Sstevel@tonic-gate 		} while (cout != (cin & 0177));
1031*7c478bd9Sstevel@tonic-gate 	}
1032*7c478bd9Sstevel@tonic-gate 	trace1(TR_wrchr, 1);
1033*7c478bd9Sstevel@tonic-gate 	return (SUCCESS);
1034*7c478bd9Sstevel@tonic-gate }
1035*7c478bd9Sstevel@tonic-gate 
1036*7c478bd9Sstevel@tonic-gate 
1037*7c478bd9Sstevel@tonic-gate /*
1038*7c478bd9Sstevel@tonic-gate  *	notin(sh, lg)	check for occurrence of substring "sh"
1039*7c478bd9Sstevel@tonic-gate  *	char *sh, *lg;
1040*7c478bd9Sstevel@tonic-gate  *
1041*7c478bd9Sstevel@tonic-gate  *	return codes:
1042*7c478bd9Sstevel@tonic-gate  *		0  -  found the string
1043*7c478bd9Sstevel@tonic-gate  *		1  -  not in the string
1044*7c478bd9Sstevel@tonic-gate  */
1045*7c478bd9Sstevel@tonic-gate 
1046*7c478bd9Sstevel@tonic-gate static int
1047*7c478bd9Sstevel@tonic-gate notin(sh, lg)
1048*7c478bd9Sstevel@tonic-gate char *sh, *lg;
1049*7c478bd9Sstevel@tonic-gate {
1050*7c478bd9Sstevel@tonic-gate 	trace1(TR_notin, 0);
1051*7c478bd9Sstevel@tonic-gate 	while (*lg != NULLCHAR) {
1052*7c478bd9Sstevel@tonic-gate 		if (PREFIX(sh, lg)) {
1053*7c478bd9Sstevel@tonic-gate 			trace1(TR_notin, 1);
1054*7c478bd9Sstevel@tonic-gate 			return (0);
1055*7c478bd9Sstevel@tonic-gate 		}
1056*7c478bd9Sstevel@tonic-gate 		else
1057*7c478bd9Sstevel@tonic-gate 			lg++;
1058*7c478bd9Sstevel@tonic-gate 	}
1059*7c478bd9Sstevel@tonic-gate 	trace1(TR_notin, 1);
1060*7c478bd9Sstevel@tonic-gate 	return (1);
1061*7c478bd9Sstevel@tonic-gate }
1062*7c478bd9Sstevel@tonic-gate 
1063*7c478bd9Sstevel@tonic-gate 
1064*7c478bd9Sstevel@tonic-gate /*
1065*7c478bd9Sstevel@tonic-gate  *	ifdate(s)
1066*7c478bd9Sstevel@tonic-gate  *	char *s;
1067*7c478bd9Sstevel@tonic-gate  *
1068*7c478bd9Sstevel@tonic-gate  *	ifdate  -  this routine will check a string (s)
1069*7c478bd9Sstevel@tonic-gate  *	like "MoTu0800-1730" to see if the present
1070*7c478bd9Sstevel@tonic-gate  *	time is within the given limits.
1071*7c478bd9Sstevel@tonic-gate  *	SIDE EFFECT - Retrytime is set to number following ";"
1072*7c478bd9Sstevel@tonic-gate  *
1073*7c478bd9Sstevel@tonic-gate  *	String alternatives:
1074*7c478bd9Sstevel@tonic-gate  *		Wk - Mo thru Fr
1075*7c478bd9Sstevel@tonic-gate  *		zero or one time means all day
1076*7c478bd9Sstevel@tonic-gate  *		Any - any day
1077*7c478bd9Sstevel@tonic-gate  *
1078*7c478bd9Sstevel@tonic-gate  *	return codes:
1079*7c478bd9Sstevel@tonic-gate  *		0  -  not within limits
1080*7c478bd9Sstevel@tonic-gate  *		1  -  within limits
1081*7c478bd9Sstevel@tonic-gate  */
1082*7c478bd9Sstevel@tonic-gate 
1083*7c478bd9Sstevel@tonic-gate static int
1084*7c478bd9Sstevel@tonic-gate ifdate(s)
1085*7c478bd9Sstevel@tonic-gate char *s;
1086*7c478bd9Sstevel@tonic-gate {
1087*7c478bd9Sstevel@tonic-gate 	static char *days[] = {
1088*7c478bd9Sstevel@tonic-gate 		"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", 0
1089*7c478bd9Sstevel@tonic-gate 	};
1090*7c478bd9Sstevel@tonic-gate 	time_t	clock;
1091*7c478bd9Sstevel@tonic-gate 	int	t__now;
1092*7c478bd9Sstevel@tonic-gate 	char	*p;
1093*7c478bd9Sstevel@tonic-gate 	struct tm	*tp;
1094*7c478bd9Sstevel@tonic-gate 
1095*7c478bd9Sstevel@tonic-gate 	trace1(TR_ifdate, 0);
1096*7c478bd9Sstevel@tonic-gate 	time(&clock);
1097*7c478bd9Sstevel@tonic-gate 	tp = localtime(&clock);
1098*7c478bd9Sstevel@tonic-gate 	t__now = tp->tm_hour * 100 + tp->tm_min;	/* "navy" time */
1099*7c478bd9Sstevel@tonic-gate 
1100*7c478bd9Sstevel@tonic-gate 	/*
1101*7c478bd9Sstevel@tonic-gate 	 *	pick up retry time for failures
1102*7c478bd9Sstevel@tonic-gate 	 *	global variable Retrytime is set here
1103*7c478bd9Sstevel@tonic-gate 	 */
1104*7c478bd9Sstevel@tonic-gate 	if ((p = rindex(s, ';')) != NULL)
1105*7c478bd9Sstevel@tonic-gate 		if (isdigit(p[1])) {
1106*7c478bd9Sstevel@tonic-gate 		if (sscanf(p+1, "%ld", &Retrytime) < 1)
1107*7c478bd9Sstevel@tonic-gate 			Retrytime = 5;	/* 5 minutes is error default */
1108*7c478bd9Sstevel@tonic-gate 		Retrytime  *= 60;
1109*7c478bd9Sstevel@tonic-gate 		*p = NULLCHAR;
1110*7c478bd9Sstevel@tonic-gate 		}
1111*7c478bd9Sstevel@tonic-gate 
1112*7c478bd9Sstevel@tonic-gate 	while (*s) {
1113*7c478bd9Sstevel@tonic-gate 		int	i, dayok;
1114*7c478bd9Sstevel@tonic-gate 
1115*7c478bd9Sstevel@tonic-gate 		for (dayok = 0; (!dayok) && isalpha(*s); s++) {
1116*7c478bd9Sstevel@tonic-gate 			if (PREFIX("Any", s))
1117*7c478bd9Sstevel@tonic-gate 				dayok = 1;
1118*7c478bd9Sstevel@tonic-gate 			else if (PREFIX("Wk", s)) {
1119*7c478bd9Sstevel@tonic-gate 				if (tp->tm_wday >= 1 && tp->tm_wday <= 5)
1120*7c478bd9Sstevel@tonic-gate 					dayok = 1;
1121*7c478bd9Sstevel@tonic-gate 			} else
1122*7c478bd9Sstevel@tonic-gate 				for (i = 0; days[i]; i++)
1123*7c478bd9Sstevel@tonic-gate 					if (PREFIX(days[i], s))
1124*7c478bd9Sstevel@tonic-gate 						if (tp->tm_wday == i)
1125*7c478bd9Sstevel@tonic-gate 							dayok = 1;
1126*7c478bd9Sstevel@tonic-gate 		}
1127*7c478bd9Sstevel@tonic-gate 
1128*7c478bd9Sstevel@tonic-gate 		if (dayok) {
1129*7c478bd9Sstevel@tonic-gate 			int	t__low, t__high;
1130*7c478bd9Sstevel@tonic-gate 
1131*7c478bd9Sstevel@tonic-gate 			while (isalpha(*s))	/* flush remaining day stuff */
1132*7c478bd9Sstevel@tonic-gate 				s++;
1133*7c478bd9Sstevel@tonic-gate 
1134*7c478bd9Sstevel@tonic-gate 			if ((sscanf(s, "%d-%d", &t__low, &t__high) < 2)
1135*7c478bd9Sstevel@tonic-gate 			 || (t__low == t__high)) {
1136*7c478bd9Sstevel@tonic-gate 				trace1(TR_ifdate, 1);
1137*7c478bd9Sstevel@tonic-gate 				return (1);
1138*7c478bd9Sstevel@tonic-gate 			}
1139*7c478bd9Sstevel@tonic-gate 
1140*7c478bd9Sstevel@tonic-gate 			/* 0000 crossover? */
1141*7c478bd9Sstevel@tonic-gate 			if (t__low < t__high) {
1142*7c478bd9Sstevel@tonic-gate 				if (t__low <= t__now && t__now <= t__high) {
1143*7c478bd9Sstevel@tonic-gate 					trace1(TR_ifdate, 1);
1144*7c478bd9Sstevel@tonic-gate 					return (1);
1145*7c478bd9Sstevel@tonic-gate 				}
1146*7c478bd9Sstevel@tonic-gate 			} else if (t__low <= t__now || t__now <= t__high) {
1147*7c478bd9Sstevel@tonic-gate 				trace1(TR_ifdate, 1);
1148*7c478bd9Sstevel@tonic-gate 				return (1);
1149*7c478bd9Sstevel@tonic-gate 			}
1150*7c478bd9Sstevel@tonic-gate 
1151*7c478bd9Sstevel@tonic-gate 			/* aim at next time slot */
1152*7c478bd9Sstevel@tonic-gate 			if ((s = index(s, ',')) == NULL)
1153*7c478bd9Sstevel@tonic-gate 				break;
1154*7c478bd9Sstevel@tonic-gate 		}
1155*7c478bd9Sstevel@tonic-gate 		if (*s)
1156*7c478bd9Sstevel@tonic-gate 			s++;
1157*7c478bd9Sstevel@tonic-gate 	}
1158*7c478bd9Sstevel@tonic-gate 	trace1(TR_ifdate, 1);
1159*7c478bd9Sstevel@tonic-gate 	return (0);
1160*7c478bd9Sstevel@tonic-gate }
1161*7c478bd9Sstevel@tonic-gate 
1162*7c478bd9Sstevel@tonic-gate /*
1163*7c478bd9Sstevel@tonic-gate  *	char *
1164*7c478bd9Sstevel@tonic-gate  *	fdig(cp)	find first digit in string
1165*7c478bd9Sstevel@tonic-gate  *
1166*7c478bd9Sstevel@tonic-gate  *	return - pointer to first digit in string or end of string
1167*7c478bd9Sstevel@tonic-gate  */
1168*7c478bd9Sstevel@tonic-gate 
1169*7c478bd9Sstevel@tonic-gate GLOBAL char *
1170*7c478bd9Sstevel@tonic-gate fdig(cp)
1171*7c478bd9Sstevel@tonic-gate char *cp;
1172*7c478bd9Sstevel@tonic-gate {
1173*7c478bd9Sstevel@tonic-gate 	char *c;
1174*7c478bd9Sstevel@tonic-gate 
1175*7c478bd9Sstevel@tonic-gate 	trace1(TR_fdig, 0);
1176*7c478bd9Sstevel@tonic-gate 	for (c = cp; *c; c++)
1177*7c478bd9Sstevel@tonic-gate 		if (*c >= '0' && *c <= '9')
1178*7c478bd9Sstevel@tonic-gate 			break;
1179*7c478bd9Sstevel@tonic-gate 	trace1(TR_fdig, 1);
1180*7c478bd9Sstevel@tonic-gate 	return (c);
1181*7c478bd9Sstevel@tonic-gate }
1182*7c478bd9Sstevel@tonic-gate 
1183*7c478bd9Sstevel@tonic-gate 
1184*7c478bd9Sstevel@tonic-gate #ifdef FASTTIMER
1185*7c478bd9Sstevel@tonic-gate /*	Sleep in increments of 60ths of second.	*/
1186*7c478bd9Sstevel@tonic-gate GLOBAL void
1187*7c478bd9Sstevel@tonic-gate nap (time)
1188*7c478bd9Sstevel@tonic-gate register int time;
1189*7c478bd9Sstevel@tonic-gate {
1190*7c478bd9Sstevel@tonic-gate 	static int fd;
1191*7c478bd9Sstevel@tonic-gate 
1192*7c478bd9Sstevel@tonic-gate 	trace2(TR_nap, 0, time);
1193*7c478bd9Sstevel@tonic-gate 	if (fd == 0)
1194*7c478bd9Sstevel@tonic-gate 		fd = open (FASTTIMER, 0);
1195*7c478bd9Sstevel@tonic-gate 
1196*7c478bd9Sstevel@tonic-gate 	(void) (*Read)(fd, 0, time);
1197*7c478bd9Sstevel@tonic-gate 	trace1(TR_nap, 1);
1198*7c478bd9Sstevel@tonic-gate 	return;
1199*7c478bd9Sstevel@tonic-gate }
1200*7c478bd9Sstevel@tonic-gate 
1201*7c478bd9Sstevel@tonic-gate #endif /* FASTTIMER */
1202*7c478bd9Sstevel@tonic-gate 
1203*7c478bd9Sstevel@tonic-gate #if defined(BSD4_2) || defined(ATTSVR4)
1204*7c478bd9Sstevel@tonic-gate 
1205*7c478bd9Sstevel@tonic-gate 	/* nap(n) -- sleep for 'n' ticks of 1/60th sec each. */
1206*7c478bd9Sstevel@tonic-gate 	/* This version uses the select system call */
1207*7c478bd9Sstevel@tonic-gate 
1208*7c478bd9Sstevel@tonic-gate 
1209*7c478bd9Sstevel@tonic-gate GLOBAL void
1210*7c478bd9Sstevel@tonic-gate nap(n)
1211*7c478bd9Sstevel@tonic-gate unsigned n;
1212*7c478bd9Sstevel@tonic-gate {
1213*7c478bd9Sstevel@tonic-gate 	struct timeval tv;
1214*7c478bd9Sstevel@tonic-gate 	int rc;
1215*7c478bd9Sstevel@tonic-gate 
1216*7c478bd9Sstevel@tonic-gate 	trace2(TR_nap, 0, n);
1217*7c478bd9Sstevel@tonic-gate 	if (n==0) {
1218*7c478bd9Sstevel@tonic-gate 		trace1(TR_nap, 1);
1219*7c478bd9Sstevel@tonic-gate 		return;
1220*7c478bd9Sstevel@tonic-gate 	}
1221*7c478bd9Sstevel@tonic-gate 	tv.tv_sec = n/60;
1222*7c478bd9Sstevel@tonic-gate 	tv.tv_usec = ((n%60)*1000000L)/60;
1223*7c478bd9Sstevel@tonic-gate 	rc = select(32, 0, 0, 0, &tv);
1224*7c478bd9Sstevel@tonic-gate 	trace1(TR_nap, 1);
1225*7c478bd9Sstevel@tonic-gate 	return;
1226*7c478bd9Sstevel@tonic-gate }
1227*7c478bd9Sstevel@tonic-gate 
1228*7c478bd9Sstevel@tonic-gate #endif /* BSD4_2 || ATTSVR4 */
1229*7c478bd9Sstevel@tonic-gate 
1230*7c478bd9Sstevel@tonic-gate #ifdef NONAP
1231*7c478bd9Sstevel@tonic-gate 
1232*7c478bd9Sstevel@tonic-gate /*	nap(n) where n is ticks
1233*7c478bd9Sstevel@tonic-gate  *
1234*7c478bd9Sstevel@tonic-gate  *	loop using n/HZ part of a second
1235*7c478bd9Sstevel@tonic-gate  *	if n represents more than 1 second, then
1236*7c478bd9Sstevel@tonic-gate  *	use sleep(time) where time is the equivalent
1237*7c478bd9Sstevel@tonic-gate  *	seconds rounded off to full seconds
1238*7c478bd9Sstevel@tonic-gate  *	NOTE - this is a rough approximation and chews up
1239*7c478bd9Sstevel@tonic-gate  *	processor resource!
1240*7c478bd9Sstevel@tonic-gate  */
1241*7c478bd9Sstevel@tonic-gate 
1242*7c478bd9Sstevel@tonic-gate GLOBAL void
1243*7c478bd9Sstevel@tonic-gate nap(n)
1244*7c478bd9Sstevel@tonic-gate unsigned n;
1245*7c478bd9Sstevel@tonic-gate {
1246*7c478bd9Sstevel@tonic-gate 	struct tms	tbuf;
1247*7c478bd9Sstevel@tonic-gate 	long endtime;
1248*7c478bd9Sstevel@tonic-gate 	int i;
1249*7c478bd9Sstevel@tonic-gate 
1250*7c478bd9Sstevel@tonic-gate 	trace2(TR_nap, 0, n);
1251*7c478bd9Sstevel@tonic-gate 	if (n > HZ) {
1252*7c478bd9Sstevel@tonic-gate 		/* > second, use sleep, rounding time */
1253*7c478bd9Sstevel@tonic-gate 		sleep((int) (((n)+HZ/2)/HZ));
1254*7c478bd9Sstevel@tonic-gate 		trace1(TR_nap, 1);
1255*7c478bd9Sstevel@tonic-gate 		return;
1256*7c478bd9Sstevel@tonic-gate 	}
1257*7c478bd9Sstevel@tonic-gate 
1258*7c478bd9Sstevel@tonic-gate 	/* use timing loop for < 1 second */
1259*7c478bd9Sstevel@tonic-gate 	endtime = times(&tbuf) + 3*n/4;	/* use 3/4 because of scheduler! */
1260*7c478bd9Sstevel@tonic-gate 	while (times(&tbuf) < endtime) {
1261*7c478bd9Sstevel@tonic-gate 		for (i=0; i<1000; i++, (void) (i*i))
1262*7c478bd9Sstevel@tonic-gate 		;
1263*7c478bd9Sstevel@tonic-gate 	}
1264*7c478bd9Sstevel@tonic-gate 	trace1(TR_nap, 1);
1265*7c478bd9Sstevel@tonic-gate 	return;
1266*7c478bd9Sstevel@tonic-gate }
1267*7c478bd9Sstevel@tonic-gate 
1268*7c478bd9Sstevel@tonic-gate #endif /* NONAP */
1269*7c478bd9Sstevel@tonic-gate 
1270*7c478bd9Sstevel@tonic-gate /*
1271*7c478bd9Sstevel@tonic-gate 
1272*7c478bd9Sstevel@tonic-gate  * altconn - place a telephone call to system
1273*7c478bd9Sstevel@tonic-gate  * from cu when telephone number or direct line used
1274*7c478bd9Sstevel@tonic-gate  *
1275*7c478bd9Sstevel@tonic-gate  * return codes:
1276*7c478bd9Sstevel@tonic-gate  *	FAIL - connection failed
1277*7c478bd9Sstevel@tonic-gate  *	>0  - file no.  -  connect ok
1278*7c478bd9Sstevel@tonic-gate  * When a failure occurs, Uerror is set.
1279*7c478bd9Sstevel@tonic-gate  */
1280*7c478bd9Sstevel@tonic-gate GLOBAL int
1281*7c478bd9Sstevel@tonic-gate altconn(call)
1282*7c478bd9Sstevel@tonic-gate struct call *call;
1283*7c478bd9Sstevel@tonic-gate {
1284*7c478bd9Sstevel@tonic-gate 	int fn = FAIL;
1285*7c478bd9Sstevel@tonic-gate 	char *alt[7];
1286*7c478bd9Sstevel@tonic-gate 	EXTERN char *Myline;
1287*7c478bd9Sstevel@tonic-gate 
1288*7c478bd9Sstevel@tonic-gate 	/*
1289*7c478bd9Sstevel@tonic-gate 	 * replace the Systems file fields
1290*7c478bd9Sstevel@tonic-gate 	 * needed for getto(); [F_TYPE] and
1291*7c478bd9Sstevel@tonic-gate 	 * [F_PHONE] assignment below.
1292*7c478bd9Sstevel@tonic-gate 	 */
1293*7c478bd9Sstevel@tonic-gate 	alt[F_NAME] = "dummy";
1294*7c478bd9Sstevel@tonic-gate 	alt[F_TIME] = "Any";
1295*7c478bd9Sstevel@tonic-gate 	alt[F_TYPE] = "";
1296*7c478bd9Sstevel@tonic-gate 	alt[F_CLASS] = call->speed;
1297*7c478bd9Sstevel@tonic-gate 	alt[F_PHONE] = "";
1298*7c478bd9Sstevel@tonic-gate 	alt[F_LOGIN] = "";
1299*7c478bd9Sstevel@tonic-gate 	alt[6] = NULL;
1300*7c478bd9Sstevel@tonic-gate 
1301*7c478bd9Sstevel@tonic-gate 	trace1(TR_altconn, 0);
1302*7c478bd9Sstevel@tonic-gate 	CDEBUG(4,"altconn called\r\n%s", "");
1303*7c478bd9Sstevel@tonic-gate 
1304*7c478bd9Sstevel@tonic-gate 	/* cu -l dev ...					*/
1305*7c478bd9Sstevel@tonic-gate 	/* if is "/dev/device", strip off "/dev/" because must	*/
1306*7c478bd9Sstevel@tonic-gate 	/* exactly match entries in Devices file, which usually	*/
1307*7c478bd9Sstevel@tonic-gate 	/* omit the "/dev/".  if doesn't begin with "/dev/",	*/
1308*7c478bd9Sstevel@tonic-gate 	/* either they've omitted the "/dev/" or it's a non-	*/
1309*7c478bd9Sstevel@tonic-gate 	/* standard path name.  in either case, leave it as is	*/
1310*7c478bd9Sstevel@tonic-gate 
1311*7c478bd9Sstevel@tonic-gate 	if (call->line != NULL) {
1312*7c478bd9Sstevel@tonic-gate 		if (strncmp(call->line, "/dev/", 5) == 0) {
1313*7c478bd9Sstevel@tonic-gate 			Myline = (call->line + 5);
1314*7c478bd9Sstevel@tonic-gate 		} else {
1315*7c478bd9Sstevel@tonic-gate 			Myline = call->line;
1316*7c478bd9Sstevel@tonic-gate 		}
1317*7c478bd9Sstevel@tonic-gate 	}
1318*7c478bd9Sstevel@tonic-gate 
1319*7c478bd9Sstevel@tonic-gate 	/* cu  ... telno */
1320*7c478bd9Sstevel@tonic-gate 	if (call->telno != NULL) {
1321*7c478bd9Sstevel@tonic-gate 		alt[F_PHONE] = call->telno;
1322*7c478bd9Sstevel@tonic-gate 		alt[F_TYPE] = "ACU";
1323*7c478bd9Sstevel@tonic-gate 	} else {
1324*7c478bd9Sstevel@tonic-gate 	/* cu direct line */
1325*7c478bd9Sstevel@tonic-gate 		alt[F_TYPE] = "Direct";
1326*7c478bd9Sstevel@tonic-gate 	}
1327*7c478bd9Sstevel@tonic-gate 	if (call->type != NULL)
1328*7c478bd9Sstevel@tonic-gate 		alt[F_TYPE] = call->type;
1329*7c478bd9Sstevel@tonic-gate 	fn = getto(alt);
1330*7c478bd9Sstevel@tonic-gate 	CDEBUG(4, "getto ret %d\n", fn);
1331*7c478bd9Sstevel@tonic-gate 
1332*7c478bd9Sstevel@tonic-gate 	trace1(TR_altconn, 1);
1333*7c478bd9Sstevel@tonic-gate 	return (fn);
1334*7c478bd9Sstevel@tonic-gate 
1335*7c478bd9Sstevel@tonic-gate }
1336