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