17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 23*462be471Sceastha * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 287c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate #include "uucp.h" 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate GLOBAL char _Protocol[40] = ""; /* working protocol string */ 377c478bd9Sstevel@tonic-gate static char _ProtoSys[40] = ""; /* protocol string from Systems file entry */ 387c478bd9Sstevel@tonic-gate static char _ProtoDev[40] = ""; /* protocol string from Devices file entry */ 397c478bd9Sstevel@tonic-gate EXTERN char _ProtoCfg[]; /* protocol string from Config file entry */ 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate EXTERN jmp_buf Sjbuf; 427c478bd9Sstevel@tonic-gate EXTERN unsigned expecttime; 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate GLOBAL int Modemctrl; 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate /* Parity control during login procedure */ 477c478bd9Sstevel@tonic-gate #define P_ZERO 0 487c478bd9Sstevel@tonic-gate #define P_ONE 1 497c478bd9Sstevel@tonic-gate #define P_EVEN 2 507c478bd9Sstevel@tonic-gate #define P_ODD 3 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate static char par_tab[128]; 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate EXTERN void alarmtr(); 557c478bd9Sstevel@tonic-gate static void addProto(), mergeProto(), removeProto(); 56*462be471Sceastha static void bld_partab(); 577c478bd9Sstevel@tonic-gate static char *nextProto(); 587c478bd9Sstevel@tonic-gate EXTERN char *findProto(); 597c478bd9Sstevel@tonic-gate static void getProto(); 607c478bd9Sstevel@tonic-gate EXTERN int getto(); /* make this static when ct uses altconn() */ 617c478bd9Sstevel@tonic-gate EXTERN int chat(), rddev(), expect(), wrstr(), wrchr(); 627c478bd9Sstevel@tonic-gate EXTERN int processdev(), getdevline(), getsysline(), sysaccess(); 637c478bd9Sstevel@tonic-gate EXTERN int clear_hup(); 647c478bd9Sstevel@tonic-gate EXTERN char *currsys(), *currdev(); 657c478bd9Sstevel@tonic-gate static int finds(); 667c478bd9Sstevel@tonic-gate static int wait_for_hangup(), expect_str(); 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate EXTERN void sendthem(), nap(); 697c478bd9Sstevel@tonic-gate static int notin(), ifdate(), checkdate(), checktime(), classmatch(); 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate GLOBAL char *Myline = CNULL; /* to force which line will be used */ 727c478bd9Sstevel@tonic-gate GLOBAL char *Mytype = CNULL; /* to force selection of specific device type */ 737c478bd9Sstevel@tonic-gate GLOBAL int Dologin; /* to force login chat sequence */ 747c478bd9Sstevel@tonic-gate 757c478bd9Sstevel@tonic-gate /* 767c478bd9Sstevel@tonic-gate * conn - place a telephone call to system and login, etc. 777c478bd9Sstevel@tonic-gate * 787c478bd9Sstevel@tonic-gate * return codes: 797c478bd9Sstevel@tonic-gate * FAIL - connection failed 807c478bd9Sstevel@tonic-gate * >0 - file no. - connect ok 817c478bd9Sstevel@tonic-gate * When a failure occurs, Uerror is set. 827c478bd9Sstevel@tonic-gate */ 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate GLOBAL int 857c478bd9Sstevel@tonic-gate conn(system) 867c478bd9Sstevel@tonic-gate char *system; 877c478bd9Sstevel@tonic-gate { 887c478bd9Sstevel@tonic-gate int nf, fn; 897c478bd9Sstevel@tonic-gate char *flds[F_MAX+1]; 907c478bd9Sstevel@tonic-gate EXTERN void sysreset(); 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate CDEBUG(4, "conn(%s)\n", system); 937c478bd9Sstevel@tonic-gate Uerror = 0; 947c478bd9Sstevel@tonic-gate while ((nf = finds(system, flds, F_MAX)) > 0) { 957c478bd9Sstevel@tonic-gate fn = getto(flds); 967c478bd9Sstevel@tonic-gate CDEBUG(4, "getto ret %d\n", fn); 977c478bd9Sstevel@tonic-gate if (fn < 0) 987c478bd9Sstevel@tonic-gate continue; 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate #ifdef TIOCSPGRP 1017c478bd9Sstevel@tonic-gate { 1027c478bd9Sstevel@tonic-gate #ifdef ATTSV 1037c478bd9Sstevel@tonic-gate int pgrp = getpgrp(); 1047c478bd9Sstevel@tonic-gate #else 1057c478bd9Sstevel@tonic-gate int pgrp = getpgrp(0); 1067c478bd9Sstevel@tonic-gate #endif 1077c478bd9Sstevel@tonic-gate ioctl(fn, TIOCSPGRP, &pgrp); 1087c478bd9Sstevel@tonic-gate } 1097c478bd9Sstevel@tonic-gate #endif 1107c478bd9Sstevel@tonic-gate if (Dologin || EQUALS(Progname, "uucico")) { 1117c478bd9Sstevel@tonic-gate if (chat(nf - F_LOGIN, flds + F_LOGIN, fn,"","") == SUCCESS) { 1127c478bd9Sstevel@tonic-gate sysreset(); 1137c478bd9Sstevel@tonic-gate return(fn); /* successful return */ 1147c478bd9Sstevel@tonic-gate } 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate /* login failed */ 1177c478bd9Sstevel@tonic-gate DEBUG(6, "close caller (%d)\n", fn); 1187c478bd9Sstevel@tonic-gate fd_rmlock(fn); 1197c478bd9Sstevel@tonic-gate close(fn); 1207c478bd9Sstevel@tonic-gate if (Dc[0] != NULLCHAR) { 1217c478bd9Sstevel@tonic-gate DEBUG(6, "delock line (%s)\n", Dc); 1227c478bd9Sstevel@tonic-gate } 1237c478bd9Sstevel@tonic-gate } else { 1247c478bd9Sstevel@tonic-gate sysreset(); 1257c478bd9Sstevel@tonic-gate return(fn); 1267c478bd9Sstevel@tonic-gate } 1277c478bd9Sstevel@tonic-gate } 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate /* finds or getto failed */ 1307c478bd9Sstevel@tonic-gate sysreset(); 1317c478bd9Sstevel@tonic-gate CDEBUG(1, "Call Failed: %s\n", UERRORTEXT); 1327c478bd9Sstevel@tonic-gate return(FAIL); 1337c478bd9Sstevel@tonic-gate } 1347c478bd9Sstevel@tonic-gate 1357c478bd9Sstevel@tonic-gate /* 1367c478bd9Sstevel@tonic-gate * getto - connect to remote machine 1377c478bd9Sstevel@tonic-gate * 1387c478bd9Sstevel@tonic-gate * return codes: 1397c478bd9Sstevel@tonic-gate * >0 - file number - ok 1407c478bd9Sstevel@tonic-gate * FAIL - failed 1417c478bd9Sstevel@tonic-gate */ 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate GLOBAL int 1447c478bd9Sstevel@tonic-gate getto(flds) 1457c478bd9Sstevel@tonic-gate char *flds[]; 1467c478bd9Sstevel@tonic-gate { 1477c478bd9Sstevel@tonic-gate char *dev[D_MAX+2], devbuf[BUFSIZ]; 148*462be471Sceastha int status; 149*462be471Sceastha int dcf = -1; 1507c478bd9Sstevel@tonic-gate int reread = 0; 1517c478bd9Sstevel@tonic-gate int tries = 0; /* count of call attempts - for limit purposes */ 1527c478bd9Sstevel@tonic-gate EXTERN void devreset(); 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate CDEBUG(1, "Device Type %s wanted\n", flds[F_TYPE]); 1557c478bd9Sstevel@tonic-gate Uerror = 0; 1567c478bd9Sstevel@tonic-gate while (tries < TRYCALLS) { 1577c478bd9Sstevel@tonic-gate if ((status=rddev(flds[F_TYPE], dev, devbuf, D_MAX)) == FAIL) { 1587c478bd9Sstevel@tonic-gate if (tries == 0 || ++reread >= TRYCALLS) 1597c478bd9Sstevel@tonic-gate break; 1607c478bd9Sstevel@tonic-gate devreset(); 1617c478bd9Sstevel@tonic-gate continue; 1627c478bd9Sstevel@tonic-gate } 1637c478bd9Sstevel@tonic-gate /* check class, check (and possibly set) speed */ 1647c478bd9Sstevel@tonic-gate if (classmatch(flds, dev) != SUCCESS) { 1657c478bd9Sstevel@tonic-gate DEBUG(7, "Skipping entry in '%s'", currdev()); 1667c478bd9Sstevel@tonic-gate DEBUG(7, " - class (%s) not wanted.\n", dev[D_CLASS]); 1677c478bd9Sstevel@tonic-gate continue; 1687c478bd9Sstevel@tonic-gate } 1697c478bd9Sstevel@tonic-gate DEBUG(5, "Trying device entry '%s' ", dev[D_LINE]); 1707c478bd9Sstevel@tonic-gate DEBUG(5, "from '%s'.\n", currdev()); 1717c478bd9Sstevel@tonic-gate if ((dcf = processdev(flds, dev)) >= 0) 1727c478bd9Sstevel@tonic-gate break; 1737c478bd9Sstevel@tonic-gate 1747c478bd9Sstevel@tonic-gate switch(Uerror) { 1757c478bd9Sstevel@tonic-gate case SS_CANT_ACCESS_DEVICE: 1767c478bd9Sstevel@tonic-gate case SS_DEVICE_FAILED: 1777c478bd9Sstevel@tonic-gate case SS_LOCKED_DEVICE: 1787c478bd9Sstevel@tonic-gate case SS_CHAT_FAILED: 1797c478bd9Sstevel@tonic-gate break; 1807c478bd9Sstevel@tonic-gate default: 1817c478bd9Sstevel@tonic-gate tries++; 1827c478bd9Sstevel@tonic-gate break; 1837c478bd9Sstevel@tonic-gate } 1847c478bd9Sstevel@tonic-gate } 1857c478bd9Sstevel@tonic-gate devreset(); /* reset devices file(s) */ 1867c478bd9Sstevel@tonic-gate if (status == FAIL && !Uerror) { 1877c478bd9Sstevel@tonic-gate CDEBUG(1, "Requested Device Type Not Found\n%s", ""); 1887c478bd9Sstevel@tonic-gate Uerror = SS_NO_DEVICE; 1897c478bd9Sstevel@tonic-gate } 1907c478bd9Sstevel@tonic-gate return(dcf); 1917c478bd9Sstevel@tonic-gate } 1927c478bd9Sstevel@tonic-gate 1937c478bd9Sstevel@tonic-gate /* 1947c478bd9Sstevel@tonic-gate * classmatch - process 'Any' in Devices and Systems and 1957c478bd9Sstevel@tonic-gate * determine the correct speed, or match for == 1967c478bd9Sstevel@tonic-gate */ 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate static int 1997c478bd9Sstevel@tonic-gate classmatch(flds, dev) 2007c478bd9Sstevel@tonic-gate char *flds[], *dev[]; 2017c478bd9Sstevel@tonic-gate { 2027c478bd9Sstevel@tonic-gate /* check class, check (and possibly set) speed */ 2037c478bd9Sstevel@tonic-gate if (EQUALS(flds[F_CLASS], "Any") 2047c478bd9Sstevel@tonic-gate && EQUALS(dev[D_CLASS], "Any")) { 2057c478bd9Sstevel@tonic-gate dev[D_CLASS] = DEFAULT_BAUDRATE; 2067c478bd9Sstevel@tonic-gate return(SUCCESS); 2077c478bd9Sstevel@tonic-gate } else if (EQUALS(dev[D_CLASS], "Any")) { 2087c478bd9Sstevel@tonic-gate dev[D_CLASS] = flds[F_CLASS]; 2097c478bd9Sstevel@tonic-gate return(SUCCESS); 2107c478bd9Sstevel@tonic-gate } else if (EQUALS(flds[F_CLASS], "Any") || 2117c478bd9Sstevel@tonic-gate EQUALS(flds[F_CLASS], dev[D_CLASS])) 2127c478bd9Sstevel@tonic-gate return(SUCCESS); 2137c478bd9Sstevel@tonic-gate else 2147c478bd9Sstevel@tonic-gate return(FAIL); 2157c478bd9Sstevel@tonic-gate } 2167c478bd9Sstevel@tonic-gate 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate /* 2197c478bd9Sstevel@tonic-gate * rddev - find and unpack a line from device file for this caller type 2207c478bd9Sstevel@tonic-gate * lines starting with whitespace of '#' are comments 2217c478bd9Sstevel@tonic-gate * 2227c478bd9Sstevel@tonic-gate * return codes: 2237c478bd9Sstevel@tonic-gate * >0 - number of arguments in vector - succeeded 2247c478bd9Sstevel@tonic-gate * FAIL - EOF 2257c478bd9Sstevel@tonic-gate */ 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate GLOBAL int 2287c478bd9Sstevel@tonic-gate rddev(type, dev, buf, devcount) 2297c478bd9Sstevel@tonic-gate char *type; 2307c478bd9Sstevel@tonic-gate char *dev[]; 2317c478bd9Sstevel@tonic-gate char *buf; 2327c478bd9Sstevel@tonic-gate { 2337c478bd9Sstevel@tonic-gate char *commap, d_type[BUFSIZ]; 2347c478bd9Sstevel@tonic-gate int na; 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate while (getdevline(buf, BUFSIZ)) { 2377c478bd9Sstevel@tonic-gate if (buf[0] == ' ' || buf[0] == '\t' 2387c478bd9Sstevel@tonic-gate || buf[0] == '\n' || buf[0] == '\0' || buf[0] == '#') 2397c478bd9Sstevel@tonic-gate continue; 2407c478bd9Sstevel@tonic-gate na = getargs(buf, dev, devcount); 2417c478bd9Sstevel@tonic-gate ASSERT(na >= D_CALLER, "BAD LINE", buf, na); 2427c478bd9Sstevel@tonic-gate 2437c478bd9Sstevel@tonic-gate if ( strncmp(dev[D_LINE],"/dev/",5) == 0 ) { 2447c478bd9Sstevel@tonic-gate /* since cu (altconn()) strips off leading */ 2457c478bd9Sstevel@tonic-gate /* "/dev/", do the same here. */ 2467c478bd9Sstevel@tonic-gate strcpy(dev[D_LINE], &(dev[D_LINE][5]) ); 2477c478bd9Sstevel@tonic-gate } 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate /* may have ",M" subfield in D_LINE */ 2507c478bd9Sstevel@tonic-gate Modemctrl = FALSE; 2517c478bd9Sstevel@tonic-gate if ( (commap = strchr(dev[D_LINE], ',')) != (char *)NULL ) { 2527c478bd9Sstevel@tonic-gate if ( strcmp( commap, ",M") == SAME ) 2537c478bd9Sstevel@tonic-gate Modemctrl = TRUE; 2547c478bd9Sstevel@tonic-gate *commap = '\0'; 2557c478bd9Sstevel@tonic-gate } 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate /* 2587c478bd9Sstevel@tonic-gate * D_TYPE field may have protocol subfield, which 2597c478bd9Sstevel@tonic-gate * must be pulled off before comparing to desired type. 2607c478bd9Sstevel@tonic-gate */ 2617c478bd9Sstevel@tonic-gate (void)strcpy(d_type, dev[D_TYPE]); 2627c478bd9Sstevel@tonic-gate if ((commap = strchr(d_type, ',')) != (char *)NULL ) 2637c478bd9Sstevel@tonic-gate *commap = '\0'; 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gate /* to force the requested device type to be used. */ 2667c478bd9Sstevel@tonic-gate if ((Mytype != NULL) && (!EQUALS(Mytype, d_type)) ) 2677c478bd9Sstevel@tonic-gate continue; 2687c478bd9Sstevel@tonic-gate /* to force the requested line to be used */ 2697c478bd9Sstevel@tonic-gate if ((Myline != NULL) && (!EQUALS(Myline, dev[D_LINE])) ) 2707c478bd9Sstevel@tonic-gate continue; 2717c478bd9Sstevel@tonic-gate 2727c478bd9Sstevel@tonic-gate bsfix(dev); /* replace \X fields */ 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate if (EQUALS(d_type, type)) { 2757c478bd9Sstevel@tonic-gate getProto( _ProtoDev, dev[D_TYPE] ); 2767c478bd9Sstevel@tonic-gate return(na); 2777c478bd9Sstevel@tonic-gate } 2787c478bd9Sstevel@tonic-gate } 2797c478bd9Sstevel@tonic-gate return(FAIL); 2807c478bd9Sstevel@tonic-gate } 2817c478bd9Sstevel@tonic-gate 2827c478bd9Sstevel@tonic-gate 2837c478bd9Sstevel@tonic-gate /* 2847c478bd9Sstevel@tonic-gate * finds - set system attribute vector 2857c478bd9Sstevel@tonic-gate * 2867c478bd9Sstevel@tonic-gate * input: 2877c478bd9Sstevel@tonic-gate * fsys - open Systems file descriptor 2887c478bd9Sstevel@tonic-gate * sysnam - system name to find 2897c478bd9Sstevel@tonic-gate * output: 2907c478bd9Sstevel@tonic-gate * flds - attibute vector from Systems file 2917c478bd9Sstevel@tonic-gate * fldcount - number of fields in flds 2927c478bd9Sstevel@tonic-gate * return codes: 2937c478bd9Sstevel@tonic-gate * >0 - number of arguments in vector - succeeded 2947c478bd9Sstevel@tonic-gate * FAIL - failed 2957c478bd9Sstevel@tonic-gate * Uerror set: 2967c478bd9Sstevel@tonic-gate * 0 - found a line in Systems file 2977c478bd9Sstevel@tonic-gate * SS_BADSYSTEM - no line found in Systems file 2987c478bd9Sstevel@tonic-gate * SS_TIME_WRONG - wrong time to call 2997c478bd9Sstevel@tonic-gate */ 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gate static int 3027c478bd9Sstevel@tonic-gate finds(sysnam, flds, fldcount) 3037c478bd9Sstevel@tonic-gate char *sysnam, *flds[]; 3047c478bd9Sstevel@tonic-gate { 3057c478bd9Sstevel@tonic-gate static char info[BUFSIZ]; 3067c478bd9Sstevel@tonic-gate int na; 3077c478bd9Sstevel@tonic-gate 3087c478bd9Sstevel@tonic-gate /* format of fields 3097c478bd9Sstevel@tonic-gate * 0 name; 3107c478bd9Sstevel@tonic-gate * 1 time 3117c478bd9Sstevel@tonic-gate * 2 acu/hardwired 3127c478bd9Sstevel@tonic-gate * 3 speed 3137c478bd9Sstevel@tonic-gate * etc 3147c478bd9Sstevel@tonic-gate */ 3157c478bd9Sstevel@tonic-gate if (sysnam == 0 || *sysnam == 0 ) { 3167c478bd9Sstevel@tonic-gate Uerror = SS_BADSYSTEM; 3177c478bd9Sstevel@tonic-gate return(FAIL); 3187c478bd9Sstevel@tonic-gate } 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate while (getsysline(info, sizeof(info))) { 3217c478bd9Sstevel@tonic-gate na = getargs(info, flds, fldcount); 3227c478bd9Sstevel@tonic-gate bsfix(flds); /* replace \X fields */ 3237c478bd9Sstevel@tonic-gate if ( !EQUALSN(sysnam, flds[F_NAME], MAXBASENAME)) 3247c478bd9Sstevel@tonic-gate continue; 3257c478bd9Sstevel@tonic-gate /* check if requested Mytype device type */ 3267c478bd9Sstevel@tonic-gate if ((Mytype != CNULL) && 3277c478bd9Sstevel@tonic-gate (na <= F_TYPE || 3287c478bd9Sstevel@tonic-gate !EQUALSN(flds[F_TYPE], Mytype, strlen(Mytype)))) { 3297c478bd9Sstevel@tonic-gate DEBUG(7, "Skipping entry in '%s'", currsys()); 3307c478bd9Sstevel@tonic-gate DEBUG(7, " - type (%s) not wanted.\n", na > F_TYPE ? 3317c478bd9Sstevel@tonic-gate flds[F_TYPE] : "Missing type entry"); 3327c478bd9Sstevel@tonic-gate continue; 3337c478bd9Sstevel@tonic-gate } else { 3347c478bd9Sstevel@tonic-gate DEBUG(5, "Trying entry from '%s'", currsys()); 3357c478bd9Sstevel@tonic-gate DEBUG(5, " - device type %s.\n", na > F_TYPE ? 3367c478bd9Sstevel@tonic-gate flds[F_TYPE] : "<Missing type entry>"); 3377c478bd9Sstevel@tonic-gate } 3387c478bd9Sstevel@tonic-gate /* OK if not uucico (ie. ct or cu) or the time is right */ 3397c478bd9Sstevel@tonic-gate if (!EQUALS(Progname, "uucico") || 3407c478bd9Sstevel@tonic-gate (na > F_TIME && ifdate(flds[F_TIME]))) { 3417c478bd9Sstevel@tonic-gate /* found a good entry */ 3427c478bd9Sstevel@tonic-gate if (na > F_TYPE) { 3437c478bd9Sstevel@tonic-gate getProto(_ProtoSys, flds[F_TYPE]); 3447c478bd9Sstevel@tonic-gate Uerror = 0; 3457c478bd9Sstevel@tonic-gate return(na); /* FOUND OK LINE */ 3467c478bd9Sstevel@tonic-gate } 3477c478bd9Sstevel@tonic-gate DEBUG(5, "Trying entry from '%s'", currsys()); 3487c478bd9Sstevel@tonic-gate DEBUG(5, " - Missing type entry for <%s>.\n", 3497c478bd9Sstevel@tonic-gate flds[F_NAME]); 3507c478bd9Sstevel@tonic-gate } else { 3517c478bd9Sstevel@tonic-gate CDEBUG(1, "Wrong Time To Call: %s\n", na > F_TIME ? 3527c478bd9Sstevel@tonic-gate flds[F_TIME] : "<Missing time entry>"); 3537c478bd9Sstevel@tonic-gate if (!Uerror) 3547c478bd9Sstevel@tonic-gate Uerror = SS_TIME_WRONG; 3557c478bd9Sstevel@tonic-gate } 3567c478bd9Sstevel@tonic-gate } 3577c478bd9Sstevel@tonic-gate if (!Uerror) 3587c478bd9Sstevel@tonic-gate Uerror = SS_BADSYSTEM; 3597c478bd9Sstevel@tonic-gate return(FAIL); 3607c478bd9Sstevel@tonic-gate } 3617c478bd9Sstevel@tonic-gate 3627c478bd9Sstevel@tonic-gate /* 3637c478bd9Sstevel@tonic-gate * getProto - get the protocol letters from the input string. 3647c478bd9Sstevel@tonic-gate * input: 3657c478bd9Sstevel@tonic-gate * str - string from Systems/Devices/Config file, 3667c478bd9Sstevel@tonic-gate * a ',' delimits the protocol string 3677c478bd9Sstevel@tonic-gate * e.g. ACU,g or DK,d 3687c478bd9Sstevel@tonic-gate * output: 3697c478bd9Sstevel@tonic-gate * str - the , (if present) will be replaced with NULLCHAR 3707c478bd9Sstevel@tonic-gate * 3717c478bd9Sstevel@tonic-gate * return: none 3727c478bd9Sstevel@tonic-gate */ 3737c478bd9Sstevel@tonic-gate 3747c478bd9Sstevel@tonic-gate static void 3757c478bd9Sstevel@tonic-gate getProto(save, str) 3767c478bd9Sstevel@tonic-gate char *save; 3777c478bd9Sstevel@tonic-gate char *str; 3787c478bd9Sstevel@tonic-gate { 379*462be471Sceastha char *p; 3807c478bd9Sstevel@tonic-gate 3817c478bd9Sstevel@tonic-gate *save = NULLCHAR; 3827c478bd9Sstevel@tonic-gate if ( (p=strchr(str, ',')) != NULL) { 3837c478bd9Sstevel@tonic-gate *p = NULLCHAR; 3847c478bd9Sstevel@tonic-gate (void) strcpy(save, p+1); 3857c478bd9Sstevel@tonic-gate DEBUG(7, "Protocol = %s\n", save); 3867c478bd9Sstevel@tonic-gate } 3877c478bd9Sstevel@tonic-gate return; 3887c478bd9Sstevel@tonic-gate } 3897c478bd9Sstevel@tonic-gate 3907c478bd9Sstevel@tonic-gate /* 3917c478bd9Sstevel@tonic-gate * check for a specified protocol selection string 3927c478bd9Sstevel@tonic-gate * return: 3937c478bd9Sstevel@tonic-gate * protocol string pointer 3947c478bd9Sstevel@tonic-gate * NULL if none specified for LOGNAME 3957c478bd9Sstevel@tonic-gate */ 3967c478bd9Sstevel@tonic-gate GLOBAL char * 3977c478bd9Sstevel@tonic-gate protoString(valid) 3987c478bd9Sstevel@tonic-gate char *valid; 3997c478bd9Sstevel@tonic-gate { 4007c478bd9Sstevel@tonic-gate char *save; 4017c478bd9Sstevel@tonic-gate 4027c478bd9Sstevel@tonic-gate save =strdup(valid); 4037c478bd9Sstevel@tonic-gate _Protocol[0] = '\0'; 4047c478bd9Sstevel@tonic-gate 4057c478bd9Sstevel@tonic-gate if ( _ProtoSys[0] != '\0' ) 4067c478bd9Sstevel@tonic-gate addProto(_ProtoSys, valid); 4077c478bd9Sstevel@tonic-gate if ( _ProtoDev[0] != '\0' ) 4087c478bd9Sstevel@tonic-gate addProto(_ProtoDev, valid); 4097c478bd9Sstevel@tonic-gate if ( _ProtoCfg[0] != '\0' ) 4107c478bd9Sstevel@tonic-gate addProto(_ProtoCfg, valid); 4117c478bd9Sstevel@tonic-gate 4127c478bd9Sstevel@tonic-gate if ( _Protocol[0] == '\0' ) { 4137c478bd9Sstevel@tonic-gate (void) strcpy(valid, save); 4147c478bd9Sstevel@tonic-gate (void) strcpy(_Protocol, save); 4157c478bd9Sstevel@tonic-gate } 4167c478bd9Sstevel@tonic-gate 4177c478bd9Sstevel@tonic-gate return(_Protocol[0] == NULLCHAR ? NULL : _Protocol); 4187c478bd9Sstevel@tonic-gate } 4197c478bd9Sstevel@tonic-gate 4207c478bd9Sstevel@tonic-gate /* 4217c478bd9Sstevel@tonic-gate * addProto 4227c478bd9Sstevel@tonic-gate * 4237c478bd9Sstevel@tonic-gate * Verify that the desired protocols from the Systems and Devices file 4247c478bd9Sstevel@tonic-gate * have been compiled into this application. 4257c478bd9Sstevel@tonic-gate * 4267c478bd9Sstevel@tonic-gate * desired - list of desired protocols 4277c478bd9Sstevel@tonic-gate * valid - list of protocols that are compiled in. 4287c478bd9Sstevel@tonic-gate */ 4297c478bd9Sstevel@tonic-gate 4307c478bd9Sstevel@tonic-gate static void 4317c478bd9Sstevel@tonic-gate addProto (desired, valid) 4327c478bd9Sstevel@tonic-gate char *desired; 4337c478bd9Sstevel@tonic-gate char *valid; 4347c478bd9Sstevel@tonic-gate { 435*462be471Sceastha char *protoPtr; 436*462be471Sceastha char *wantPtr; 4377c478bd9Sstevel@tonic-gate 4387c478bd9Sstevel@tonic-gate if ( *desired == '\0' ) 4397c478bd9Sstevel@tonic-gate return; 4407c478bd9Sstevel@tonic-gate 4417c478bd9Sstevel@tonic-gate if ( *(protoPtr = _Protocol) != NULLCHAR ) { 4427c478bd9Sstevel@tonic-gate while ( *(protoPtr = nextProto(protoPtr)) != NULLCHAR ) { 4437c478bd9Sstevel@tonic-gate if ( *(wantPtr = findProto(desired, *protoPtr)) == NULLCHAR ) { 4447c478bd9Sstevel@tonic-gate removeProto(valid, *protoPtr); 4457c478bd9Sstevel@tonic-gate removeProto(protoPtr, *protoPtr); 4467c478bd9Sstevel@tonic-gate } else { 4477c478bd9Sstevel@tonic-gate mergeProto(protoPtr, wantPtr); 4487c478bd9Sstevel@tonic-gate protoPtr++; 4497c478bd9Sstevel@tonic-gate } 4507c478bd9Sstevel@tonic-gate } 4517c478bd9Sstevel@tonic-gate } else { 4527c478bd9Sstevel@tonic-gate wantPtr = desired; 4537c478bd9Sstevel@tonic-gate while ( *(wantPtr = nextProto(wantPtr)) != NULLCHAR ) { 4547c478bd9Sstevel@tonic-gate if ( *(findProto(valid, *wantPtr)) != NULLCHAR ) { 4557c478bd9Sstevel@tonic-gate mergeProto(protoPtr, wantPtr); 4567c478bd9Sstevel@tonic-gate } 4577c478bd9Sstevel@tonic-gate wantPtr++; 4587c478bd9Sstevel@tonic-gate } 4597c478bd9Sstevel@tonic-gate } 4607c478bd9Sstevel@tonic-gate if ( *(protoPtr = _Protocol) != NULLCHAR ) { 4617c478bd9Sstevel@tonic-gate while ( *(protoPtr = nextProto(protoPtr)) != NULLCHAR ) 4627c478bd9Sstevel@tonic-gate *(valid++) = *(protoPtr++); 4637c478bd9Sstevel@tonic-gate *valid = NULLCHAR; 4647c478bd9Sstevel@tonic-gate } 4657c478bd9Sstevel@tonic-gate return; 4667c478bd9Sstevel@tonic-gate } 4677c478bd9Sstevel@tonic-gate 4687c478bd9Sstevel@tonic-gate /* 4697c478bd9Sstevel@tonic-gate * mergeProto 4707c478bd9Sstevel@tonic-gate * 4717c478bd9Sstevel@tonic-gate * input 4727c478bd9Sstevel@tonic-gate * char *tostring, *fromstring; 4737c478bd9Sstevel@tonic-gate */ 4747c478bd9Sstevel@tonic-gate static void 4757c478bd9Sstevel@tonic-gate mergeProto(tostring, fromstring) 4767c478bd9Sstevel@tonic-gate char *tostring, *fromstring; 4777c478bd9Sstevel@tonic-gate { 4787c478bd9Sstevel@tonic-gate char buffer[BUFSIZ]; 4797c478bd9Sstevel@tonic-gate int length; 4807c478bd9Sstevel@tonic-gate 4817c478bd9Sstevel@tonic-gate while ( *(tostring = nextProto(tostring)) != NULLCHAR ) { 4827c478bd9Sstevel@tonic-gate if ( *tostring == *fromstring ) 4837c478bd9Sstevel@tonic-gate break; 4847c478bd9Sstevel@tonic-gate else 4857c478bd9Sstevel@tonic-gate tostring++; 4867c478bd9Sstevel@tonic-gate } 4877c478bd9Sstevel@tonic-gate 4887c478bd9Sstevel@tonic-gate if ( *tostring == NULLCHAR ) { 4897c478bd9Sstevel@tonic-gate length = nextProto(fromstring + 1) - fromstring; 4907c478bd9Sstevel@tonic-gate (void) strncpy(tostring, fromstring, length); 4917c478bd9Sstevel@tonic-gate *(tostring + length) = NULLCHAR; 4927c478bd9Sstevel@tonic-gate } else { 4937c478bd9Sstevel@tonic-gate tostring++; 4947c478bd9Sstevel@tonic-gate fromstring++; 4957c478bd9Sstevel@tonic-gate if ( (*tostring != '(') && (*fromstring == '(') ) { 4967c478bd9Sstevel@tonic-gate (void) strcpy(buffer, tostring); 4977c478bd9Sstevel@tonic-gate length = nextProto(fromstring) - fromstring; 4987c478bd9Sstevel@tonic-gate (void) strncpy(tostring, fromstring, length); 4997c478bd9Sstevel@tonic-gate (void) strcpy(tostring+length, buffer); 5007c478bd9Sstevel@tonic-gate } 5017c478bd9Sstevel@tonic-gate } 5027c478bd9Sstevel@tonic-gate return; 5037c478bd9Sstevel@tonic-gate } 5047c478bd9Sstevel@tonic-gate 5057c478bd9Sstevel@tonic-gate /* 5067c478bd9Sstevel@tonic-gate * removeProto 5077c478bd9Sstevel@tonic-gate * 5087c478bd9Sstevel@tonic-gate * char *old 5097c478bd9Sstevel@tonic-gate * char letter 5107c478bd9Sstevel@tonic-gate * 5117c478bd9Sstevel@tonic-gate * return 5127c478bd9Sstevel@tonic-gate * none 5137c478bd9Sstevel@tonic-gate */ 5147c478bd9Sstevel@tonic-gate static void 5157c478bd9Sstevel@tonic-gate removeProto(string, letter) 5167c478bd9Sstevel@tonic-gate char *string, letter; 5177c478bd9Sstevel@tonic-gate { 5187c478bd9Sstevel@tonic-gate while ( *(string = nextProto(string)) != NULLCHAR ) { 5197c478bd9Sstevel@tonic-gate if ( *string == letter ) 5207c478bd9Sstevel@tonic-gate (void) strcpy(string, nextProto(string+1)); 5217c478bd9Sstevel@tonic-gate else 5227c478bd9Sstevel@tonic-gate string++; 5237c478bd9Sstevel@tonic-gate } 5247c478bd9Sstevel@tonic-gate } 5257c478bd9Sstevel@tonic-gate 5267c478bd9Sstevel@tonic-gate /* 5277c478bd9Sstevel@tonic-gate * nextProto 5287c478bd9Sstevel@tonic-gate * char *string; 5297c478bd9Sstevel@tonic-gate * return 5307c478bd9Sstevel@tonic-gate * char * to next non-parameter letter 5317c478bd9Sstevel@tonic-gate */ 5327c478bd9Sstevel@tonic-gate static char * 5337c478bd9Sstevel@tonic-gate nextProto(string) 5347c478bd9Sstevel@tonic-gate char *string; 5357c478bd9Sstevel@tonic-gate { 5367c478bd9Sstevel@tonic-gate if ( *string == '(' ) 5377c478bd9Sstevel@tonic-gate while ( *string != NULLCHAR ) 5387c478bd9Sstevel@tonic-gate if ( *(string++) == ')' ) 5397c478bd9Sstevel@tonic-gate break; 5407c478bd9Sstevel@tonic-gate return(string); 5417c478bd9Sstevel@tonic-gate } 5427c478bd9Sstevel@tonic-gate 5437c478bd9Sstevel@tonic-gate /* 5447c478bd9Sstevel@tonic-gate * findProto 5457c478bd9Sstevel@tonic-gate * char *desired, 5467c478bd9Sstevel@tonic-gate * char protoPtr; 5477c478bd9Sstevel@tonic-gate * return 5487c478bd9Sstevel@tonic-gate * char *pointer to found or string terminating NULLCHAR 5497c478bd9Sstevel@tonic-gate */ 5507c478bd9Sstevel@tonic-gate GLOBAL char * 5517c478bd9Sstevel@tonic-gate findProto(string, letter) 5527c478bd9Sstevel@tonic-gate char *string; 5537c478bd9Sstevel@tonic-gate char letter; 5547c478bd9Sstevel@tonic-gate { 5557c478bd9Sstevel@tonic-gate while ( *(string = nextProto(string)) != NULLCHAR ) 5567c478bd9Sstevel@tonic-gate if ( *string == letter ) 5577c478bd9Sstevel@tonic-gate break; 5587c478bd9Sstevel@tonic-gate else 5597c478bd9Sstevel@tonic-gate string++; 5607c478bd9Sstevel@tonic-gate return(string); 5617c478bd9Sstevel@tonic-gate } 5627c478bd9Sstevel@tonic-gate 5637c478bd9Sstevel@tonic-gate /* 5647c478bd9Sstevel@tonic-gate * chat - do conversation 5657c478bd9Sstevel@tonic-gate * input: 5667c478bd9Sstevel@tonic-gate * nf - number of fields in flds array 5677c478bd9Sstevel@tonic-gate * flds - fields from Systems file 5687c478bd9Sstevel@tonic-gate * fn - write file number 5697c478bd9Sstevel@tonic-gate * phstr1 - phone number to replace \D 5707c478bd9Sstevel@tonic-gate * phstr2 - phone number to replace \T 5717c478bd9Sstevel@tonic-gate * 5727c478bd9Sstevel@tonic-gate * return codes: 0 | FAIL 5737c478bd9Sstevel@tonic-gate */ 5747c478bd9Sstevel@tonic-gate 5757c478bd9Sstevel@tonic-gate GLOBAL int 5767c478bd9Sstevel@tonic-gate chat(nf, flds, fn, phstr1, phstr2) 5777c478bd9Sstevel@tonic-gate char *flds[], *phstr1, *phstr2; 5787c478bd9Sstevel@tonic-gate int nf, fn; 5797c478bd9Sstevel@tonic-gate { 5807c478bd9Sstevel@tonic-gate char *want, *altern; 5817c478bd9Sstevel@tonic-gate int k, ok; 5827c478bd9Sstevel@tonic-gate 5837c478bd9Sstevel@tonic-gate for (k = 0; k < nf; k += 2) { 5847c478bd9Sstevel@tonic-gate want = flds[k]; 5857c478bd9Sstevel@tonic-gate ok = FAIL; 5867c478bd9Sstevel@tonic-gate while (ok != 0) { 5877c478bd9Sstevel@tonic-gate altern = index(want, '-'); 5887c478bd9Sstevel@tonic-gate if (altern != NULL) 5897c478bd9Sstevel@tonic-gate *altern++ = NULLCHAR; 5907c478bd9Sstevel@tonic-gate ok = expect(want, fn); 5917c478bd9Sstevel@tonic-gate if (ok == 0) 5927c478bd9Sstevel@tonic-gate break; 5937c478bd9Sstevel@tonic-gate if (altern == NULL) { 5947c478bd9Sstevel@tonic-gate Uerror = SS_LOGIN_FAILED; 5957c478bd9Sstevel@tonic-gate logent(UERRORTEXT, "FAILED"); 5967c478bd9Sstevel@tonic-gate return(FAIL); 5977c478bd9Sstevel@tonic-gate } 5987c478bd9Sstevel@tonic-gate want = index(altern, '-'); 5997c478bd9Sstevel@tonic-gate if (want != NULL) 6007c478bd9Sstevel@tonic-gate *want++ = NULLCHAR; 6017c478bd9Sstevel@tonic-gate sendthem(altern, fn, phstr1, phstr2); 6027c478bd9Sstevel@tonic-gate } 6037c478bd9Sstevel@tonic-gate sleep(2); 6047c478bd9Sstevel@tonic-gate if (flds[k+1]) 6057c478bd9Sstevel@tonic-gate sendthem(flds[k+1], fn, phstr1, phstr2); 6067c478bd9Sstevel@tonic-gate } 6077c478bd9Sstevel@tonic-gate return(0); 6087c478bd9Sstevel@tonic-gate } 6097c478bd9Sstevel@tonic-gate 6107c478bd9Sstevel@tonic-gate #define MR 1000 6117c478bd9Sstevel@tonic-gate 6127c478bd9Sstevel@tonic-gate /* 6137c478bd9Sstevel@tonic-gate * expect(str, fn) look for expected string w/ possible special chars 6147c478bd9Sstevel@tonic-gate * 6157c478bd9Sstevel@tonic-gate * return codes: 6167c478bd9Sstevel@tonic-gate * 0 - found 6177c478bd9Sstevel@tonic-gate * FAIL - too many characters read 6187c478bd9Sstevel@tonic-gate * some character - timed out 6197c478bd9Sstevel@tonic-gate */ 6207c478bd9Sstevel@tonic-gate 6217c478bd9Sstevel@tonic-gate GLOBAL int 6227c478bd9Sstevel@tonic-gate expect(str, fn) 6237c478bd9Sstevel@tonic-gate char *str; 6247c478bd9Sstevel@tonic-gate int fn; 6257c478bd9Sstevel@tonic-gate { 626*462be471Sceastha char *bptr, *sptr; 6277c478bd9Sstevel@tonic-gate char buf[BUFSIZ]; 6287c478bd9Sstevel@tonic-gate 6297c478bd9Sstevel@tonic-gate bptr = buf; 6307c478bd9Sstevel@tonic-gate 6317c478bd9Sstevel@tonic-gate for (sptr = str; *sptr; sptr++) { 6327c478bd9Sstevel@tonic-gate if (*sptr == '\\') { 6337c478bd9Sstevel@tonic-gate switch (*++sptr) { 6347c478bd9Sstevel@tonic-gate case 'H': 6357c478bd9Sstevel@tonic-gate *bptr++ = '\0'; 6367c478bd9Sstevel@tonic-gate if (expect_str(buf, fn) == FAIL) { 6377c478bd9Sstevel@tonic-gate return (FAIL); 6387c478bd9Sstevel@tonic-gate } 6397c478bd9Sstevel@tonic-gate if (wait_for_hangup(fn) == FAIL) { 6407c478bd9Sstevel@tonic-gate return (FAIL); 6417c478bd9Sstevel@tonic-gate } 6427c478bd9Sstevel@tonic-gate bptr = buf; 6437c478bd9Sstevel@tonic-gate continue; 6447c478bd9Sstevel@tonic-gate case '\\': 6457c478bd9Sstevel@tonic-gate *bptr++ = '\\'; 6467c478bd9Sstevel@tonic-gate continue; 6477c478bd9Sstevel@tonic-gate default: 6487c478bd9Sstevel@tonic-gate *bptr++ = '\\'; 6497c478bd9Sstevel@tonic-gate *bptr++ = *sptr; 6507c478bd9Sstevel@tonic-gate continue; 6517c478bd9Sstevel@tonic-gate } 6527c478bd9Sstevel@tonic-gate } else 6537c478bd9Sstevel@tonic-gate *bptr++ = *sptr; 6547c478bd9Sstevel@tonic-gate } 6557c478bd9Sstevel@tonic-gate *bptr = '\0'; 6567c478bd9Sstevel@tonic-gate if (expect_str(buf, fn) == FAIL) { 6577c478bd9Sstevel@tonic-gate return (FAIL); 6587c478bd9Sstevel@tonic-gate } 6597c478bd9Sstevel@tonic-gate return (0); 6607c478bd9Sstevel@tonic-gate } 6617c478bd9Sstevel@tonic-gate 6627c478bd9Sstevel@tonic-gate /* 6637c478bd9Sstevel@tonic-gate * expect_str(str, fn) look for expected string, w/ no special chars 6647c478bd9Sstevel@tonic-gate * 6657c478bd9Sstevel@tonic-gate * return codes: 6667c478bd9Sstevel@tonic-gate * 0 - found 6677c478bd9Sstevel@tonic-gate * FAIL - too many characters read 6687c478bd9Sstevel@tonic-gate * some character - timed out 6697c478bd9Sstevel@tonic-gate */ 6707c478bd9Sstevel@tonic-gate 6717c478bd9Sstevel@tonic-gate GLOBAL int 6727c478bd9Sstevel@tonic-gate expect_str(str, fn) 6737c478bd9Sstevel@tonic-gate char *str; 6747c478bd9Sstevel@tonic-gate int fn; 6757c478bd9Sstevel@tonic-gate { 6767c478bd9Sstevel@tonic-gate static char rdvec[MR]; 6777c478bd9Sstevel@tonic-gate char *rp = rdvec; 678*462be471Sceastha int kr, c; 6797c478bd9Sstevel@tonic-gate char nextch; 6807c478bd9Sstevel@tonic-gate 6817c478bd9Sstevel@tonic-gate *rp = 0; 6827c478bd9Sstevel@tonic-gate 6837c478bd9Sstevel@tonic-gate CDEBUG(4, "expect: (%s", ""); 6847c478bd9Sstevel@tonic-gate for (c=0; (kr=str[c]) != 0 ; c++) 6857c478bd9Sstevel@tonic-gate if (kr < 040) { 6867c478bd9Sstevel@tonic-gate CDEBUG(4, "^%c", kr | 0100); 6877c478bd9Sstevel@tonic-gate } else 6887c478bd9Sstevel@tonic-gate CDEBUG(4, "%c", kr); 6897c478bd9Sstevel@tonic-gate CDEBUG(4, ")\n%s", ""); 6907c478bd9Sstevel@tonic-gate 6917c478bd9Sstevel@tonic-gate if (EQUALS(str, "\"\"")) { 6927c478bd9Sstevel@tonic-gate CDEBUG(4, "got it\n%s", ""); 6937c478bd9Sstevel@tonic-gate return(0); 6947c478bd9Sstevel@tonic-gate } 6957c478bd9Sstevel@tonic-gate if (*str== '\0') { 6967c478bd9Sstevel@tonic-gate return(0); 6977c478bd9Sstevel@tonic-gate } 6987c478bd9Sstevel@tonic-gate if (setjmp(Sjbuf)) { 6997c478bd9Sstevel@tonic-gate return (FAIL); 7007c478bd9Sstevel@tonic-gate } 7017c478bd9Sstevel@tonic-gate (void) signal(SIGALRM, alarmtr); 7027c478bd9Sstevel@tonic-gate alarm(expecttime); 7037c478bd9Sstevel@tonic-gate while (notin(str, rdvec)) { 7047c478bd9Sstevel@tonic-gate errno = 0; 7057c478bd9Sstevel@tonic-gate kr = (*Read)(fn, &nextch, 1); 7067c478bd9Sstevel@tonic-gate if (kr <= 0) { 7077c478bd9Sstevel@tonic-gate alarm(0); 7087c478bd9Sstevel@tonic-gate CDEBUG(4, "lost line errno - %d\n", errno); 7097c478bd9Sstevel@tonic-gate logent("LOGIN", "LOST LINE"); 7107c478bd9Sstevel@tonic-gate return(FAIL); 7117c478bd9Sstevel@tonic-gate } 7127c478bd9Sstevel@tonic-gate c = nextch & 0177; 7137c478bd9Sstevel@tonic-gate CDEBUG(4, "%s", c < 040 ? "^" : ""); 7147c478bd9Sstevel@tonic-gate CDEBUG(4, "%c", c < 040 ? c | 0100 : c); 7157c478bd9Sstevel@tonic-gate if ((*rp = nextch & 0177) != NULLCHAR) 7167c478bd9Sstevel@tonic-gate rp++; 7177c478bd9Sstevel@tonic-gate if (rp >= rdvec + MR) { 7187c478bd9Sstevel@tonic-gate CDEBUG(4, "enough already\n%s", ""); 7197c478bd9Sstevel@tonic-gate alarm(0); 7207c478bd9Sstevel@tonic-gate return(FAIL); 7217c478bd9Sstevel@tonic-gate } 7227c478bd9Sstevel@tonic-gate *rp = NULLCHAR; 7237c478bd9Sstevel@tonic-gate } 7247c478bd9Sstevel@tonic-gate alarm(0); 7257c478bd9Sstevel@tonic-gate CDEBUG(4, "got it\n%s", ""); 7267c478bd9Sstevel@tonic-gate return(0); 7277c478bd9Sstevel@tonic-gate } 7287c478bd9Sstevel@tonic-gate /* 7297c478bd9Sstevel@tonic-gate * alarmtr() - catch alarm routine for "expect". 7307c478bd9Sstevel@tonic-gate */ 7317c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 7327c478bd9Sstevel@tonic-gate GLOBAL void 7337c478bd9Sstevel@tonic-gate alarmtr(sig) 7347c478bd9Sstevel@tonic-gate int sig; 7357c478bd9Sstevel@tonic-gate { 7367c478bd9Sstevel@tonic-gate CDEBUG(6, "timed out\n%s", ""); 7377c478bd9Sstevel@tonic-gate longjmp(Sjbuf, 1); 7387c478bd9Sstevel@tonic-gate } 7397c478bd9Sstevel@tonic-gate 7407c478bd9Sstevel@tonic-gate /* 7417c478bd9Sstevel@tonic-gate * wait_for_hangup() - wait for a hangup to occur on the given device 7427c478bd9Sstevel@tonic-gate */ 7437c478bd9Sstevel@tonic-gate int 7447c478bd9Sstevel@tonic-gate wait_for_hangup(dcf) 7457c478bd9Sstevel@tonic-gate int dcf; 7467c478bd9Sstevel@tonic-gate { 7477c478bd9Sstevel@tonic-gate int rval; 7487c478bd9Sstevel@tonic-gate char buff[BUFSIZ]; 7497c478bd9Sstevel@tonic-gate 7507c478bd9Sstevel@tonic-gate CDEBUG(4, "Waiting for hangup\n%s", ""); 7517c478bd9Sstevel@tonic-gate while((rval = read(dcf, buff, BUFSIZ)) > 0); 7527c478bd9Sstevel@tonic-gate 7537c478bd9Sstevel@tonic-gate if (rval < 0) { 7547c478bd9Sstevel@tonic-gate return (FAIL); 7557c478bd9Sstevel@tonic-gate } 7567c478bd9Sstevel@tonic-gate CDEBUG(4, "Received hangup\n%s", ""); 7577c478bd9Sstevel@tonic-gate 7587c478bd9Sstevel@tonic-gate if (clear_hup(dcf) != SUCCESS) { 7597c478bd9Sstevel@tonic-gate CDEBUG(4, "Unable to clear hup on device\n%s", ""); 7607c478bd9Sstevel@tonic-gate return (FAIL); 7617c478bd9Sstevel@tonic-gate } 7627c478bd9Sstevel@tonic-gate return (SUCCESS); 7637c478bd9Sstevel@tonic-gate } 7647c478bd9Sstevel@tonic-gate 7657c478bd9Sstevel@tonic-gate /* 7667c478bd9Sstevel@tonic-gate * sendthem(str, fn, phstr1, phstr2) send line of chat sequence 7677c478bd9Sstevel@tonic-gate * char *str, *phstr; 7687c478bd9Sstevel@tonic-gate * 7697c478bd9Sstevel@tonic-gate * return codes: none 7707c478bd9Sstevel@tonic-gate */ 7717c478bd9Sstevel@tonic-gate 7727c478bd9Sstevel@tonic-gate #define FLUSH() {\ 7737c478bd9Sstevel@tonic-gate if ((bptr - buf) > 0)\ 7747c478bd9Sstevel@tonic-gate if (wrstr(fn, buf, bptr - buf, echocheck) != SUCCESS)\ 7757c478bd9Sstevel@tonic-gate goto err;\ 7767c478bd9Sstevel@tonic-gate bptr = buf;\ 7777c478bd9Sstevel@tonic-gate } 7787c478bd9Sstevel@tonic-gate 7797c478bd9Sstevel@tonic-gate GLOBAL void 7807c478bd9Sstevel@tonic-gate sendthem(str, fn, phstr1, phstr2) 7817c478bd9Sstevel@tonic-gate char *str, *phstr1, *phstr2; 7827c478bd9Sstevel@tonic-gate int fn; 7837c478bd9Sstevel@tonic-gate { 7847c478bd9Sstevel@tonic-gate int sendcr = 1, echocheck = 0; 785*462be471Sceastha char *sptr, *bptr; 7867c478bd9Sstevel@tonic-gate char buf[BUFSIZ]; 7877c478bd9Sstevel@tonic-gate struct termio ttybuf; 7887c478bd9Sstevel@tonic-gate static int p_init = 0; 7897c478bd9Sstevel@tonic-gate 7907c478bd9Sstevel@tonic-gate if (!p_init) { 7917c478bd9Sstevel@tonic-gate p_init++; 7927c478bd9Sstevel@tonic-gate bld_partab(P_EVEN); 7937c478bd9Sstevel@tonic-gate } 7947c478bd9Sstevel@tonic-gate 7957c478bd9Sstevel@tonic-gate /* should be EQUALS, but previous versions had BREAK n for integer n */ 7967c478bd9Sstevel@tonic-gate if (PREFIX("BREAK", str)) { 7977c478bd9Sstevel@tonic-gate /* send break */ 7987c478bd9Sstevel@tonic-gate CDEBUG(5, "BREAK\n%s", ""); 7997c478bd9Sstevel@tonic-gate (*genbrk)(fn); 8007c478bd9Sstevel@tonic-gate return; 8017c478bd9Sstevel@tonic-gate } 8027c478bd9Sstevel@tonic-gate 8037c478bd9Sstevel@tonic-gate if (PREFIX("STTY=", str)) { 8047c478bd9Sstevel@tonic-gate CDEBUG(5, "STTY %s\n", str+5); 8057c478bd9Sstevel@tonic-gate setmode(str+5, fn); 8067c478bd9Sstevel@tonic-gate return; 8077c478bd9Sstevel@tonic-gate } 8087c478bd9Sstevel@tonic-gate 8097c478bd9Sstevel@tonic-gate if (EQUALS(str, "EOT")) { 8107c478bd9Sstevel@tonic-gate CDEBUG(5, "EOT\n%s", ""); 8117c478bd9Sstevel@tonic-gate bptr = buf; 8127c478bd9Sstevel@tonic-gate for (sptr = EOTMSG; *sptr; sptr++) 8137c478bd9Sstevel@tonic-gate *bptr++ = par_tab[*sptr&0177]; 8147c478bd9Sstevel@tonic-gate (void) (*Write)(fn, buf, bptr - buf); 8157c478bd9Sstevel@tonic-gate return; 8167c478bd9Sstevel@tonic-gate } 8177c478bd9Sstevel@tonic-gate 8187c478bd9Sstevel@tonic-gate /* Set parity as needed */ 8197c478bd9Sstevel@tonic-gate if (EQUALS(str, "P_ZERO")) { 8207c478bd9Sstevel@tonic-gate bld_partab(P_ZERO); 8217c478bd9Sstevel@tonic-gate return; 8227c478bd9Sstevel@tonic-gate } 8237c478bd9Sstevel@tonic-gate if (EQUALS(str, "P_ONE")) { 8247c478bd9Sstevel@tonic-gate bld_partab(P_ONE); 8257c478bd9Sstevel@tonic-gate return; 8267c478bd9Sstevel@tonic-gate } 8277c478bd9Sstevel@tonic-gate if (EQUALS(str, "P_EVEN")) { 8287c478bd9Sstevel@tonic-gate bld_partab(P_EVEN); 8297c478bd9Sstevel@tonic-gate return; 8307c478bd9Sstevel@tonic-gate } 8317c478bd9Sstevel@tonic-gate if (EQUALS(str, "P_ODD")) { 8327c478bd9Sstevel@tonic-gate bld_partab(P_ODD); 8337c478bd9Sstevel@tonic-gate return; 8347c478bd9Sstevel@tonic-gate } 8357c478bd9Sstevel@tonic-gate 8367c478bd9Sstevel@tonic-gate if (EQUALS(str, "\"\"")) { 8377c478bd9Sstevel@tonic-gate CDEBUG(5, "\"\"\n%s", ""); 8387c478bd9Sstevel@tonic-gate str += 2; 8397c478bd9Sstevel@tonic-gate } 8407c478bd9Sstevel@tonic-gate 8417c478bd9Sstevel@tonic-gate bptr = buf; 8427c478bd9Sstevel@tonic-gate CDEBUG(5, "sendthem (%s", ""); 8437c478bd9Sstevel@tonic-gate for (sptr = str; *sptr; sptr++) { 8447c478bd9Sstevel@tonic-gate if (*sptr == '\\') { 8457c478bd9Sstevel@tonic-gate switch(*++sptr) { 8467c478bd9Sstevel@tonic-gate 8477c478bd9Sstevel@tonic-gate /* adjust switches */ 8487c478bd9Sstevel@tonic-gate case 'c': /* no CR after string */ 8497c478bd9Sstevel@tonic-gate FLUSH(); 8507c478bd9Sstevel@tonic-gate if (sptr[1] == NULLCHAR) { 8517c478bd9Sstevel@tonic-gate CDEBUG(5, "<NO CR>%s", ""); 8527c478bd9Sstevel@tonic-gate sendcr = 0; 8537c478bd9Sstevel@tonic-gate } else 8547c478bd9Sstevel@tonic-gate CDEBUG(5, "<NO CR IGNORED>\n%s", ""); 8557c478bd9Sstevel@tonic-gate continue; 8567c478bd9Sstevel@tonic-gate 8577c478bd9Sstevel@tonic-gate /* stash in buf and continue */ 8587c478bd9Sstevel@tonic-gate case 'D': /* raw phnum */ 8597c478bd9Sstevel@tonic-gate strcpy(bptr, phstr1); 8607c478bd9Sstevel@tonic-gate bptr += strlen(bptr); 8617c478bd9Sstevel@tonic-gate continue; 8627c478bd9Sstevel@tonic-gate case 'T': /* translated phnum */ 8637c478bd9Sstevel@tonic-gate strcpy(bptr, phstr2); 8647c478bd9Sstevel@tonic-gate bptr += strlen(bptr); 8657c478bd9Sstevel@tonic-gate continue; 8667c478bd9Sstevel@tonic-gate case 'N': /* null */ 8677c478bd9Sstevel@tonic-gate *bptr++ = 0; 8687c478bd9Sstevel@tonic-gate continue; 8697c478bd9Sstevel@tonic-gate case 's': /* space */ 8707c478bd9Sstevel@tonic-gate *bptr++ = ' '; 8717c478bd9Sstevel@tonic-gate continue; 8727c478bd9Sstevel@tonic-gate case '\\': /* backslash escapes itself */ 8737c478bd9Sstevel@tonic-gate *bptr++ = *sptr; 8747c478bd9Sstevel@tonic-gate continue; 8757c478bd9Sstevel@tonic-gate default: /* send the backslash */ 8767c478bd9Sstevel@tonic-gate *bptr++ = '\\'; 8777c478bd9Sstevel@tonic-gate *bptr++ = *sptr; 8787c478bd9Sstevel@tonic-gate continue; 8797c478bd9Sstevel@tonic-gate 8807c478bd9Sstevel@tonic-gate /* flush buf, perform action, and continue */ 8817c478bd9Sstevel@tonic-gate case 'E': /* echo check on */ 8827c478bd9Sstevel@tonic-gate FLUSH(); 8837c478bd9Sstevel@tonic-gate CDEBUG(5, "ECHO CHECK ON\n%s", ""); 8847c478bd9Sstevel@tonic-gate echocheck = 1; 8857c478bd9Sstevel@tonic-gate continue; 8867c478bd9Sstevel@tonic-gate case 'e': /* echo check off */ 8877c478bd9Sstevel@tonic-gate FLUSH(); 8887c478bd9Sstevel@tonic-gate CDEBUG(5, "ECHO CHECK OFF\n%s", ""); 8897c478bd9Sstevel@tonic-gate echocheck = 0; 8907c478bd9Sstevel@tonic-gate continue; 8917c478bd9Sstevel@tonic-gate case 'd': /* sleep briefly */ 8927c478bd9Sstevel@tonic-gate FLUSH(); 8937c478bd9Sstevel@tonic-gate CDEBUG(5, "DELAY\n%s", ""); 8947c478bd9Sstevel@tonic-gate sleep(2); 8957c478bd9Sstevel@tonic-gate continue; 8967c478bd9Sstevel@tonic-gate case 'p': /* pause momentarily */ 8977c478bd9Sstevel@tonic-gate FLUSH(); 8987c478bd9Sstevel@tonic-gate CDEBUG(5, "PAUSE\n%s", ""); 8997c478bd9Sstevel@tonic-gate nap(HZ/4); /* approximately 1/4 second */ 9007c478bd9Sstevel@tonic-gate continue; 9017c478bd9Sstevel@tonic-gate case 'K': /* inline break */ 9027c478bd9Sstevel@tonic-gate FLUSH(); 9037c478bd9Sstevel@tonic-gate CDEBUG(5, "BREAK\n%s", ""); 9047c478bd9Sstevel@tonic-gate (*genbrk)(fn); 9057c478bd9Sstevel@tonic-gate continue; 9067c478bd9Sstevel@tonic-gate case 'M': /* modem control - set CLOCAL */ 9077c478bd9Sstevel@tonic-gate case 'm': /* no modem control - clear CLOCAL */ 9087c478bd9Sstevel@tonic-gate FLUSH(); 9097c478bd9Sstevel@tonic-gate CDEBUG(5, ")\n%s CLOCAL ", 9107c478bd9Sstevel@tonic-gate (*sptr == 'M' ? "set" : "clear")); 9117c478bd9Sstevel@tonic-gate #ifdef ATTSVTTY 9127c478bd9Sstevel@tonic-gate if ( (*Ioctl)(fn, TCGETA, &ttybuf) != 0 ) { 9137c478bd9Sstevel@tonic-gate CDEBUG(5, "ignored. TCGETA failed, errno %d", errno); 9147c478bd9Sstevel@tonic-gate } else { 9157c478bd9Sstevel@tonic-gate if (*sptr == 'M') 9167c478bd9Sstevel@tonic-gate ttybuf.c_cflag |= CLOCAL; 9177c478bd9Sstevel@tonic-gate else 9187c478bd9Sstevel@tonic-gate ttybuf.c_cflag &= ~CLOCAL; 9197c478bd9Sstevel@tonic-gate if ( (*Ioctl)(fn, TCSETAW, &ttybuf) != 0 ) 9207c478bd9Sstevel@tonic-gate CDEBUG(5, "failed. TCSETAW failed, errno %d", errno); 9217c478bd9Sstevel@tonic-gate } 9227c478bd9Sstevel@tonic-gate #endif 9237c478bd9Sstevel@tonic-gate CDEBUG(5, "\n%s", ""); 9247c478bd9Sstevel@tonic-gate continue; 9257c478bd9Sstevel@tonic-gate } 9267c478bd9Sstevel@tonic-gate } else 9277c478bd9Sstevel@tonic-gate *bptr++ = *sptr; 9287c478bd9Sstevel@tonic-gate } 9297c478bd9Sstevel@tonic-gate if (sendcr) 9307c478bd9Sstevel@tonic-gate *bptr++ = '\r'; 9317c478bd9Sstevel@tonic-gate if ( (bptr - buf) > 0 ) 9327c478bd9Sstevel@tonic-gate (void) wrstr(fn, buf, bptr - buf, echocheck); 9337c478bd9Sstevel@tonic-gate 9347c478bd9Sstevel@tonic-gate err: 9357c478bd9Sstevel@tonic-gate CDEBUG(5, ")\n%s", ""); 9367c478bd9Sstevel@tonic-gate return; 9377c478bd9Sstevel@tonic-gate } 9387c478bd9Sstevel@tonic-gate 9397c478bd9Sstevel@tonic-gate /* 9407c478bd9Sstevel@tonic-gate * generate parity table for use by sendthem. 9417c478bd9Sstevel@tonic-gate */ 942*462be471Sceastha static void 9437c478bd9Sstevel@tonic-gate bld_partab(type) 9447c478bd9Sstevel@tonic-gate int type; 9457c478bd9Sstevel@tonic-gate { 946*462be471Sceastha int i, j, n; 9477c478bd9Sstevel@tonic-gate 9487c478bd9Sstevel@tonic-gate for (i = 0; i < 128; i++) { 9497c478bd9Sstevel@tonic-gate n = 0; 9507c478bd9Sstevel@tonic-gate for (j = i&0177; j; j = (j-1)&j) 9517c478bd9Sstevel@tonic-gate n++; 9527c478bd9Sstevel@tonic-gate par_tab[i] = i; 9537c478bd9Sstevel@tonic-gate if (type == P_ONE 9547c478bd9Sstevel@tonic-gate || (type == P_EVEN && (n&01) != 0) 9557c478bd9Sstevel@tonic-gate || (type == P_ODD && (n&01) == 0)) 9567c478bd9Sstevel@tonic-gate par_tab[i] |= 0200; 9577c478bd9Sstevel@tonic-gate } 9587c478bd9Sstevel@tonic-gate } 9597c478bd9Sstevel@tonic-gate 9607c478bd9Sstevel@tonic-gate #undef FLUSH 9617c478bd9Sstevel@tonic-gate 9627c478bd9Sstevel@tonic-gate GLOBAL int 9637c478bd9Sstevel@tonic-gate wrstr(fn, buf, len, echocheck) 9647c478bd9Sstevel@tonic-gate char *buf; 9657c478bd9Sstevel@tonic-gate { 9667c478bd9Sstevel@tonic-gate int i; 9677c478bd9Sstevel@tonic-gate char dbuf[BUFSIZ], *dbptr = dbuf; 9687c478bd9Sstevel@tonic-gate 9697c478bd9Sstevel@tonic-gate if (echocheck) 9707c478bd9Sstevel@tonic-gate return(wrchr(fn, buf, len)); 9717c478bd9Sstevel@tonic-gate 9727c478bd9Sstevel@tonic-gate if (Debug >= 5) { 9737c478bd9Sstevel@tonic-gate if (sysaccess(ACCESS_SYSTEMS) == 0) { /* Systems file access ok */ 9747c478bd9Sstevel@tonic-gate for (i = 0; i < len; i++) { 9757c478bd9Sstevel@tonic-gate *dbptr = buf[i]; 9767c478bd9Sstevel@tonic-gate if (*dbptr < 040) { 9777c478bd9Sstevel@tonic-gate *dbptr++ = '^'; 9787c478bd9Sstevel@tonic-gate *dbptr = buf[i] | 0100; 9797c478bd9Sstevel@tonic-gate } 9807c478bd9Sstevel@tonic-gate dbptr++; 9817c478bd9Sstevel@tonic-gate } 9827c478bd9Sstevel@tonic-gate *dbptr = 0; 9837c478bd9Sstevel@tonic-gate } else 9847c478bd9Sstevel@tonic-gate strcpy(dbuf, "????????"); 9857c478bd9Sstevel@tonic-gate CDEBUG(5, "%s", dbuf); 9867c478bd9Sstevel@tonic-gate } 9877c478bd9Sstevel@tonic-gate dbptr = dbuf; 9887c478bd9Sstevel@tonic-gate for (i = 0; i < len; i++) 9897c478bd9Sstevel@tonic-gate *dbptr++ = par_tab[buf[i]&0177]; 9907c478bd9Sstevel@tonic-gate if ((*Write)(fn, dbuf, len) != len) 9917c478bd9Sstevel@tonic-gate return(FAIL); 9927c478bd9Sstevel@tonic-gate return(SUCCESS); 9937c478bd9Sstevel@tonic-gate } 9947c478bd9Sstevel@tonic-gate 9957c478bd9Sstevel@tonic-gate GLOBAL int 9967c478bd9Sstevel@tonic-gate wrchr(fn, buf, len) 997*462be471Sceastha int fn; 998*462be471Sceastha char *buf; 9997c478bd9Sstevel@tonic-gate { 10007c478bd9Sstevel@tonic-gate int i, saccess; 10017c478bd9Sstevel@tonic-gate char cin, cout; 10027c478bd9Sstevel@tonic-gate 10037c478bd9Sstevel@tonic-gate saccess = (sysaccess(ACCESS_SYSTEMS) == 0); /* protect Systems file */ 10047c478bd9Sstevel@tonic-gate if (setjmp(Sjbuf)) 10057c478bd9Sstevel@tonic-gate return(FAIL); 10067c478bd9Sstevel@tonic-gate (void) signal(SIGALRM, alarmtr); 10077c478bd9Sstevel@tonic-gate 10087c478bd9Sstevel@tonic-gate for (i = 0; i < len; i++) { 10097c478bd9Sstevel@tonic-gate cout = buf[i]&0177; 10107c478bd9Sstevel@tonic-gate if (saccess) { 10117c478bd9Sstevel@tonic-gate CDEBUG(5, "%s", cout < 040 ? "^" : ""); 10127c478bd9Sstevel@tonic-gate CDEBUG(5, "%c", cout < 040 ? cout | 0100 : cout); 10137c478bd9Sstevel@tonic-gate } else 10147c478bd9Sstevel@tonic-gate CDEBUG(5, "?%s", ""); 10157c478bd9Sstevel@tonic-gate if (((*Write)(fn, &par_tab[cout], 1)) != 1) 10167c478bd9Sstevel@tonic-gate return(FAIL); 10177c478bd9Sstevel@tonic-gate do { 10187c478bd9Sstevel@tonic-gate (void) alarm(expecttime); 10197c478bd9Sstevel@tonic-gate if ((*Read)(fn, &cin, 1) != 1) 10207c478bd9Sstevel@tonic-gate return(FAIL); 10217c478bd9Sstevel@tonic-gate (void) alarm(0); 10227c478bd9Sstevel@tonic-gate cin &= 0177; 10237c478bd9Sstevel@tonic-gate if (saccess) { 10247c478bd9Sstevel@tonic-gate CDEBUG(5, "%s", cin < 040 ? "^" : ""); 10257c478bd9Sstevel@tonic-gate CDEBUG(5, "%c", cin < 040 ? cin | 0100 : cin); 10267c478bd9Sstevel@tonic-gate } else 10277c478bd9Sstevel@tonic-gate CDEBUG(5, "?%s", ""); 10287c478bd9Sstevel@tonic-gate } while (cout != cin); 10297c478bd9Sstevel@tonic-gate } 10307c478bd9Sstevel@tonic-gate return(SUCCESS); 10317c478bd9Sstevel@tonic-gate } 10327c478bd9Sstevel@tonic-gate 10337c478bd9Sstevel@tonic-gate 10347c478bd9Sstevel@tonic-gate /* 10357c478bd9Sstevel@tonic-gate * notin(sh, lg) check for occurrence of substring "sh" 10367c478bd9Sstevel@tonic-gate * char *sh, *lg; 10377c478bd9Sstevel@tonic-gate * 10387c478bd9Sstevel@tonic-gate * return codes: 10397c478bd9Sstevel@tonic-gate * 0 - found the string 10407c478bd9Sstevel@tonic-gate * 1 - not in the string 10417c478bd9Sstevel@tonic-gate */ 10427c478bd9Sstevel@tonic-gate 10437c478bd9Sstevel@tonic-gate static int 10447c478bd9Sstevel@tonic-gate notin(sh, lg) 10457c478bd9Sstevel@tonic-gate char *sh, *lg; 10467c478bd9Sstevel@tonic-gate { 10477c478bd9Sstevel@tonic-gate while (*lg != NULLCHAR) { 10487c478bd9Sstevel@tonic-gate if (PREFIX(sh, lg)) 10497c478bd9Sstevel@tonic-gate return(0); 10507c478bd9Sstevel@tonic-gate else 10517c478bd9Sstevel@tonic-gate lg++; 10527c478bd9Sstevel@tonic-gate } 10537c478bd9Sstevel@tonic-gate return(1); 10547c478bd9Sstevel@tonic-gate } 10557c478bd9Sstevel@tonic-gate 10567c478bd9Sstevel@tonic-gate 10577c478bd9Sstevel@tonic-gate /* 10587c478bd9Sstevel@tonic-gate * ifdate(s) 10597c478bd9Sstevel@tonic-gate * char *s; 10607c478bd9Sstevel@tonic-gate * 10617c478bd9Sstevel@tonic-gate * ifdate - this routine will check a string (s) 10627c478bd9Sstevel@tonic-gate * like "MoTu0800-1730" to see if the present 10637c478bd9Sstevel@tonic-gate * time is within the given limits. 10647c478bd9Sstevel@tonic-gate * 10657c478bd9Sstevel@tonic-gate * SIDE EFFECT - Retrytime is set to number following ";" 10667c478bd9Sstevel@tonic-gate * SIDE EFFECT - MaxGrade is set to character following "/" 10677c478bd9Sstevel@tonic-gate * 10687c478bd9Sstevel@tonic-gate * if a grade is specified, iswrk() is consulted, so that we don't 10697c478bd9Sstevel@tonic-gate * place calls when there's only low priority work. this will appear 10707c478bd9Sstevel@tonic-gate * as a "wrong time to call" in the status file. sorry. 10717c478bd9Sstevel@tonic-gate * 10727c478bd9Sstevel@tonic-gate * String alternatives: 10737c478bd9Sstevel@tonic-gate * Wk - Mo thru Fr 10747c478bd9Sstevel@tonic-gate * zero or one time means all day 10757c478bd9Sstevel@tonic-gate * Any - any day 10767c478bd9Sstevel@tonic-gate * 10777c478bd9Sstevel@tonic-gate * return codes: 10787c478bd9Sstevel@tonic-gate * 0 - not within limits, or grade too low 10797c478bd9Sstevel@tonic-gate * 1 - within limits 10807c478bd9Sstevel@tonic-gate */ 10817c478bd9Sstevel@tonic-gate 10827c478bd9Sstevel@tonic-gate static int 10837c478bd9Sstevel@tonic-gate ifdate(s) 10847c478bd9Sstevel@tonic-gate char *s; 10857c478bd9Sstevel@tonic-gate { 10867c478bd9Sstevel@tonic-gate char *r; 10877c478bd9Sstevel@tonic-gate #ifdef MAXGRADE 10887c478bd9Sstevel@tonic-gate char *m, grade; 10897c478bd9Sstevel@tonic-gate #endif 10907c478bd9Sstevel@tonic-gate struct tm *tp; 10917c478bd9Sstevel@tonic-gate time_t clock; 10927c478bd9Sstevel@tonic-gate int t__now; 10937c478bd9Sstevel@tonic-gate 10947c478bd9Sstevel@tonic-gate time(&clock); 10957c478bd9Sstevel@tonic-gate tp = localtime(&clock); 10967c478bd9Sstevel@tonic-gate t__now = tp->tm_hour * 100 + tp->tm_min; /* "navy" time */ 10977c478bd9Sstevel@tonic-gate 10987c478bd9Sstevel@tonic-gate /* 10997c478bd9Sstevel@tonic-gate * pick up retry time for failures and max grade 11007c478bd9Sstevel@tonic-gate * global variables Retrytime and MaxGrade are set here 11017c478bd9Sstevel@tonic-gate */ 11027c478bd9Sstevel@tonic-gate r = strrchr(s, ';'); 11037c478bd9Sstevel@tonic-gate 11047c478bd9Sstevel@tonic-gate /* set retry time */ 11057c478bd9Sstevel@tonic-gate if (r != NULL) { 11067c478bd9Sstevel@tonic-gate if (isdigit(r[1])) { 11077c478bd9Sstevel@tonic-gate if (sscanf(r+1, "%ld", &Retrytime) < 1) 11087c478bd9Sstevel@tonic-gate Retrytime = 5; /* 5 minutes is error default */ 11097c478bd9Sstevel@tonic-gate DEBUG(5, "Retry time set to %d minutes\n", Retrytime); 11107c478bd9Sstevel@tonic-gate Retrytime *= 60; /* convert to seconds */ 11117c478bd9Sstevel@tonic-gate *r = NULLCHAR; /* blow away retry time field */ 11127c478bd9Sstevel@tonic-gate } 11137c478bd9Sstevel@tonic-gate } else 11147c478bd9Sstevel@tonic-gate Retrytime = 0; /* use exponential backoff */ 11157c478bd9Sstevel@tonic-gate 11167c478bd9Sstevel@tonic-gate #ifdef MAXGRADE 11177c478bd9Sstevel@tonic-gate /* set grade */ 11187c478bd9Sstevel@tonic-gate MaxGrade = NULLCHAR; /* default */ 11197c478bd9Sstevel@tonic-gate m = strrchr(s, '/'); 11207c478bd9Sstevel@tonic-gate if (m != NULL) { 11217c478bd9Sstevel@tonic-gate if (isalnum(m[1])) 11227c478bd9Sstevel@tonic-gate MaxGrade = m[1]; /* you asked for it! */ 11237c478bd9Sstevel@tonic-gate *m = NULLCHAR; /* blow away max grade field */ 11247c478bd9Sstevel@tonic-gate DEBUG(5, "Max Grade set to %c\n", MaxGrade); 11257c478bd9Sstevel@tonic-gate } 11267c478bd9Sstevel@tonic-gate 11277c478bd9Sstevel@tonic-gate /* test grade */ 11287c478bd9Sstevel@tonic-gate if (MaxGrade != NULLCHAR) { 11297c478bd9Sstevel@tonic-gate grade = iswrk(CNULL); 11307c478bd9Sstevel@tonic-gate if (grade == NULLCHAR || MaxGrade < grade) { 11317c478bd9Sstevel@tonic-gate DEBUG(4, "No work of grade %c -- no call\n", MaxGrade); 11327c478bd9Sstevel@tonic-gate return(0); 11337c478bd9Sstevel@tonic-gate } 11347c478bd9Sstevel@tonic-gate } 11357c478bd9Sstevel@tonic-gate #endif /* MAXGRADE */ 11367c478bd9Sstevel@tonic-gate 11377c478bd9Sstevel@tonic-gate 11387c478bd9Sstevel@tonic-gate while (checkdate(s, tp, t__now) == 0) { 11397c478bd9Sstevel@tonic-gate s = strchr(s, ','); 11407c478bd9Sstevel@tonic-gate if (s == CNULL) 11417c478bd9Sstevel@tonic-gate return(0); 11427c478bd9Sstevel@tonic-gate s++; 11437c478bd9Sstevel@tonic-gate } 11447c478bd9Sstevel@tonic-gate return(1); 11457c478bd9Sstevel@tonic-gate } 11467c478bd9Sstevel@tonic-gate 11477c478bd9Sstevel@tonic-gate /* worker function for ifdate() */ 11487c478bd9Sstevel@tonic-gate static int 11497c478bd9Sstevel@tonic-gate checkdate(s, tp, t__now) 11507c478bd9Sstevel@tonic-gate char *s; 11517c478bd9Sstevel@tonic-gate struct tm *tp; 11527c478bd9Sstevel@tonic-gate int t__now; 11537c478bd9Sstevel@tonic-gate { 11547c478bd9Sstevel@tonic-gate static char *days[] = { 11557c478bd9Sstevel@tonic-gate "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", 0 11567c478bd9Sstevel@tonic-gate }; 11577c478bd9Sstevel@tonic-gate int i; 11587c478bd9Sstevel@tonic-gate 11597c478bd9Sstevel@tonic-gate /* 11607c478bd9Sstevel@tonic-gate * check day of week 11617c478bd9Sstevel@tonic-gate */ 11627c478bd9Sstevel@tonic-gate 11637c478bd9Sstevel@tonic-gate while (isalpha(*s)) { 11647c478bd9Sstevel@tonic-gate if (PREFIX("Any", s)) 11657c478bd9Sstevel@tonic-gate return(checktime(s, t__now)); 11667c478bd9Sstevel@tonic-gate 11677c478bd9Sstevel@tonic-gate if (PREFIX("Wk", s) && tp->tm_wday >= 1 && tp->tm_wday <= 5) 11687c478bd9Sstevel@tonic-gate return(checktime(s, t__now)); 11697c478bd9Sstevel@tonic-gate 11707c478bd9Sstevel@tonic-gate for (i = 0; days[i]; i++) 11717c478bd9Sstevel@tonic-gate if (PREFIX(days[i], s) && tp->tm_wday == i) 11727c478bd9Sstevel@tonic-gate return(checktime(s, t__now)); 11737c478bd9Sstevel@tonic-gate s++; 11747c478bd9Sstevel@tonic-gate } 11757c478bd9Sstevel@tonic-gate 11767c478bd9Sstevel@tonic-gate return(0); /* day match failed */ 11777c478bd9Sstevel@tonic-gate } 11787c478bd9Sstevel@tonic-gate 11797c478bd9Sstevel@tonic-gate /* day match ok -- check time */ 11807c478bd9Sstevel@tonic-gate static int 11817c478bd9Sstevel@tonic-gate checktime(s, t__now) 11827c478bd9Sstevel@tonic-gate char *s; 11837c478bd9Sstevel@tonic-gate int t__now; 11847c478bd9Sstevel@tonic-gate { 11857c478bd9Sstevel@tonic-gate int t__low, t__high; 11867c478bd9Sstevel@tonic-gate 11877c478bd9Sstevel@tonic-gate while (isalpha(*s)) /* flush day stuff */ 11887c478bd9Sstevel@tonic-gate s++; 11897c478bd9Sstevel@tonic-gate 11907c478bd9Sstevel@tonic-gate if ((sscanf(s, "%d-%d", &t__low, &t__high) < 2)) 11917c478bd9Sstevel@tonic-gate return(1); /* time match ok (default) */ 11927c478bd9Sstevel@tonic-gate 11937c478bd9Sstevel@tonic-gate if (t__low == t__high) 11947c478bd9Sstevel@tonic-gate return(1); 11957c478bd9Sstevel@tonic-gate 11967c478bd9Sstevel@tonic-gate /* 0000 crossover? */ 11977c478bd9Sstevel@tonic-gate if (t__low < t__high) { 11987c478bd9Sstevel@tonic-gate if (t__low <= t__now && t__now <= t__high) 11997c478bd9Sstevel@tonic-gate return(1); 12007c478bd9Sstevel@tonic-gate } else { 12017c478bd9Sstevel@tonic-gate if (t__low <= t__now || t__now <= t__high) 12027c478bd9Sstevel@tonic-gate return(1); 12037c478bd9Sstevel@tonic-gate } 12047c478bd9Sstevel@tonic-gate 12057c478bd9Sstevel@tonic-gate return(0); 12067c478bd9Sstevel@tonic-gate } 12077c478bd9Sstevel@tonic-gate 12087c478bd9Sstevel@tonic-gate /* 12097c478bd9Sstevel@tonic-gate * char * 12107c478bd9Sstevel@tonic-gate * fdig(cp) find first digit in string 12117c478bd9Sstevel@tonic-gate * 12127c478bd9Sstevel@tonic-gate * return - pointer to first digit in string or end of string 12137c478bd9Sstevel@tonic-gate */ 12147c478bd9Sstevel@tonic-gate 12157c478bd9Sstevel@tonic-gate GLOBAL char * 12167c478bd9Sstevel@tonic-gate fdig(cp) 12177c478bd9Sstevel@tonic-gate char *cp; 12187c478bd9Sstevel@tonic-gate { 12197c478bd9Sstevel@tonic-gate char *c; 12207c478bd9Sstevel@tonic-gate 12217c478bd9Sstevel@tonic-gate for (c = cp; *c; c++) 12227c478bd9Sstevel@tonic-gate if (*c >= '0' && *c <= '9') 12237c478bd9Sstevel@tonic-gate break; 12247c478bd9Sstevel@tonic-gate return(c); 12257c478bd9Sstevel@tonic-gate } 12267c478bd9Sstevel@tonic-gate 12277c478bd9Sstevel@tonic-gate 12287c478bd9Sstevel@tonic-gate #ifdef FASTTIMER 12297c478bd9Sstevel@tonic-gate /* Sleep in increments of 60ths of second. */ 12307c478bd9Sstevel@tonic-gate GLOBAL void 12317c478bd9Sstevel@tonic-gate nap (time) 1232*462be471Sceastha int time; 12337c478bd9Sstevel@tonic-gate { 12347c478bd9Sstevel@tonic-gate static int fd; 12357c478bd9Sstevel@tonic-gate 12367c478bd9Sstevel@tonic-gate if (fd == 0) 12377c478bd9Sstevel@tonic-gate fd = open (FASTTIMER, 0); 12387c478bd9Sstevel@tonic-gate 12397c478bd9Sstevel@tonic-gate (void) (*Read)(fd, 0, time); 12407c478bd9Sstevel@tonic-gate return; 12417c478bd9Sstevel@tonic-gate } 12427c478bd9Sstevel@tonic-gate 12437c478bd9Sstevel@tonic-gate #endif /* FASTTIMER */ 12447c478bd9Sstevel@tonic-gate 12457c478bd9Sstevel@tonic-gate #if defined(BSD4_2) || defined(ATTSVR4) 12467c478bd9Sstevel@tonic-gate 12477c478bd9Sstevel@tonic-gate /* nap(n) -- sleep for 'n' ticks of 1/60th sec each. */ 12487c478bd9Sstevel@tonic-gate /* This version uses the select system call */ 12497c478bd9Sstevel@tonic-gate 12507c478bd9Sstevel@tonic-gate 12517c478bd9Sstevel@tonic-gate GLOBAL void 12527c478bd9Sstevel@tonic-gate nap(n) 12537c478bd9Sstevel@tonic-gate unsigned n; 12547c478bd9Sstevel@tonic-gate { 12557c478bd9Sstevel@tonic-gate struct timeval tv; 12567c478bd9Sstevel@tonic-gate 12577c478bd9Sstevel@tonic-gate if (n==0) 12587c478bd9Sstevel@tonic-gate return; 12597c478bd9Sstevel@tonic-gate tv.tv_sec = n/60; 12607c478bd9Sstevel@tonic-gate tv.tv_usec = ((n%60)*1000000L)/60; 12617c478bd9Sstevel@tonic-gate (void) select(32, 0, 0, 0, &tv); 12627c478bd9Sstevel@tonic-gate return; 12637c478bd9Sstevel@tonic-gate } 12647c478bd9Sstevel@tonic-gate 12657c478bd9Sstevel@tonic-gate #endif /* BSD4_2 || ATTSVR4 */ 12667c478bd9Sstevel@tonic-gate 12677c478bd9Sstevel@tonic-gate #ifdef NONAP 12687c478bd9Sstevel@tonic-gate 12697c478bd9Sstevel@tonic-gate /* nap(n) where n is ticks 12707c478bd9Sstevel@tonic-gate * 12717c478bd9Sstevel@tonic-gate * loop using n/HZ part of a second 12727c478bd9Sstevel@tonic-gate * if n represents more than 1 second, then 12737c478bd9Sstevel@tonic-gate * use sleep(time) where time is the equivalent 12747c478bd9Sstevel@tonic-gate * seconds rounded off to full seconds 12757c478bd9Sstevel@tonic-gate * NOTE - this is a rough approximation and chews up 12767c478bd9Sstevel@tonic-gate * processor resource! 12777c478bd9Sstevel@tonic-gate */ 12787c478bd9Sstevel@tonic-gate 12797c478bd9Sstevel@tonic-gate GLOBAL void 12807c478bd9Sstevel@tonic-gate nap(n) 12817c478bd9Sstevel@tonic-gate unsigned n; 12827c478bd9Sstevel@tonic-gate { 12837c478bd9Sstevel@tonic-gate struct tms tbuf; 12847c478bd9Sstevel@tonic-gate long endtime; 12857c478bd9Sstevel@tonic-gate int i; 12867c478bd9Sstevel@tonic-gate 12877c478bd9Sstevel@tonic-gate if (n > HZ) { 12887c478bd9Sstevel@tonic-gate /* > second, use sleep, rounding time */ 12897c478bd9Sstevel@tonic-gate sleep( (int) (((n)+HZ/2)/HZ) ); 12907c478bd9Sstevel@tonic-gate return; 12917c478bd9Sstevel@tonic-gate } 12927c478bd9Sstevel@tonic-gate 12937c478bd9Sstevel@tonic-gate /* use timing loop for < 1 second */ 12947c478bd9Sstevel@tonic-gate endtime = times(&tbuf) + 3*n/4; /* use 3/4 because of scheduler! */ 12957c478bd9Sstevel@tonic-gate while (times(&tbuf) < endtime) { 12967c478bd9Sstevel@tonic-gate for (i=0; i<1000; i++, (void) (i*i)) 12977c478bd9Sstevel@tonic-gate ; 12987c478bd9Sstevel@tonic-gate } 12997c478bd9Sstevel@tonic-gate return; 13007c478bd9Sstevel@tonic-gate } 13017c478bd9Sstevel@tonic-gate 13027c478bd9Sstevel@tonic-gate #endif /* NONAP */ 13037c478bd9Sstevel@tonic-gate 13047c478bd9Sstevel@tonic-gate /* 13057c478bd9Sstevel@tonic-gate 13067c478bd9Sstevel@tonic-gate * altconn - place a telephone call to system 13077c478bd9Sstevel@tonic-gate * from cu when telephone number or direct line used 13087c478bd9Sstevel@tonic-gate * 13097c478bd9Sstevel@tonic-gate * return codes: 13107c478bd9Sstevel@tonic-gate * FAIL - connection failed 13117c478bd9Sstevel@tonic-gate * >0 - file no. - connect ok 13127c478bd9Sstevel@tonic-gate * When a failure occurs, Uerror is set. 13137c478bd9Sstevel@tonic-gate */ 13147c478bd9Sstevel@tonic-gate GLOBAL int 13157c478bd9Sstevel@tonic-gate altconn(call) 13167c478bd9Sstevel@tonic-gate struct call *call; 13177c478bd9Sstevel@tonic-gate { 13187c478bd9Sstevel@tonic-gate int fn = FAIL; 13197c478bd9Sstevel@tonic-gate char *alt[7]; 13207c478bd9Sstevel@tonic-gate EXTERN char *Myline; 13217c478bd9Sstevel@tonic-gate 13227c478bd9Sstevel@tonic-gate alt[F_NAME] = "dummy"; /* to replace the Systems file fields */ 13237c478bd9Sstevel@tonic-gate alt[F_TIME] = "Any"; /* needed for getto(); [F_TYPE] and */ 13247c478bd9Sstevel@tonic-gate alt[F_TYPE] = ""; /* [F_PHONE] assignment below */ 13257c478bd9Sstevel@tonic-gate alt[F_CLASS] = call->speed; 13267c478bd9Sstevel@tonic-gate alt[F_PHONE] = ""; 13277c478bd9Sstevel@tonic-gate alt[F_LOGIN] = ""; 13287c478bd9Sstevel@tonic-gate alt[6] = NULL; 13297c478bd9Sstevel@tonic-gate 13307c478bd9Sstevel@tonic-gate CDEBUG(4,"altconn called\r\n%s", ""); 13317c478bd9Sstevel@tonic-gate 13327c478bd9Sstevel@tonic-gate /* cu -l dev ... */ 13337c478bd9Sstevel@tonic-gate /* if is "/dev/device", strip off "/dev/" because must */ 13347c478bd9Sstevel@tonic-gate /* exactly match entries in Devices file, which usually */ 13357c478bd9Sstevel@tonic-gate /* omit the "/dev/". if doesn't begin with "/dev/", */ 13367c478bd9Sstevel@tonic-gate /* either they've omitted the "/dev/" or it's a non- */ 13377c478bd9Sstevel@tonic-gate /* standard path name. in either case, leave it as is */ 13387c478bd9Sstevel@tonic-gate 13397c478bd9Sstevel@tonic-gate if(call->line != NULL ) { 13407c478bd9Sstevel@tonic-gate if ( strncmp(call->line, "/dev/", 5) == 0 ) { 13417c478bd9Sstevel@tonic-gate Myline = (call->line + 5); 13427c478bd9Sstevel@tonic-gate } else { 13437c478bd9Sstevel@tonic-gate Myline = call->line; 13447c478bd9Sstevel@tonic-gate } 13457c478bd9Sstevel@tonic-gate } 13467c478bd9Sstevel@tonic-gate 13477c478bd9Sstevel@tonic-gate /* cu ... telno */ 13487c478bd9Sstevel@tonic-gate if(call->telno != NULL) { 13497c478bd9Sstevel@tonic-gate alt[F_PHONE] = call->telno; 13507c478bd9Sstevel@tonic-gate alt[F_TYPE] = "ACU"; 13517c478bd9Sstevel@tonic-gate } else { 13527c478bd9Sstevel@tonic-gate /* cu direct line */ 13537c478bd9Sstevel@tonic-gate alt[F_TYPE] = "Direct"; 13547c478bd9Sstevel@tonic-gate } 13557c478bd9Sstevel@tonic-gate if (call->type != NULL) 13567c478bd9Sstevel@tonic-gate alt[F_TYPE] = call->type; 13577c478bd9Sstevel@tonic-gate fn = getto(alt); 13587c478bd9Sstevel@tonic-gate CDEBUG(4, "getto ret %d\n", fn); 13597c478bd9Sstevel@tonic-gate 13607c478bd9Sstevel@tonic-gate return(fn); 13617c478bd9Sstevel@tonic-gate 13627c478bd9Sstevel@tonic-gate } 1363