/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#pragma ident "%Z%%M% %I% %E% SMI"
#include "uucp.h"
/* Parity control during login procedure */
#define P_ZERO 0
static void bld_partab();
static char *nextProto();
static void getProto();
static int finds();
static int wait_for_hangup(), expect_str();
/*
* conn - place a telephone call to system and login, etc.
*
* return codes:
* FAIL - connection failed
* >0 - file no. - connect ok
* When a failure occurs, Uerror is set.
*/
GLOBAL int
char *system;
{
Uerror = 0;
if (fn < 0)
continue;
#ifdef TIOCSPGRP
{
#ifdef ATTSV
#else
#endif
}
#endif
sysreset();
return(fn); /* successful return */
}
/* login failed */
}
} else {
sysreset();
return(fn);
}
}
/* finds or getto failed */
sysreset();
return(FAIL);
}
/*
* getto - connect to remote machine
*
* return codes:
* >0 - file number - ok
* FAIL - failed
*/
GLOBAL int
char *flds[];
{
int status;
int reread = 0;
Uerror = 0;
break;
devreset();
continue;
}
/* check class, check (and possibly set) speed */
continue;
}
break;
switch(Uerror) {
case SS_CANT_ACCESS_DEVICE:
case SS_DEVICE_FAILED:
case SS_LOCKED_DEVICE:
case SS_CHAT_FAILED:
break;
default:
tries++;
break;
}
}
devreset(); /* reset devices file(s) */
}
return(dcf);
}
/*
* classmatch - process 'Any' in Devices and Systems and
* determine the correct speed, or match for ==
*/
static int
{
/* check class, check (and possibly set) speed */
return(SUCCESS);
return(SUCCESS);
return(SUCCESS);
else
return(FAIL);
}
/*
* rddev - find and unpack a line from device file for this caller type
* lines starting with whitespace of '#' are comments
*
* return codes:
* >0 - number of arguments in vector - succeeded
* FAIL - EOF
*/
GLOBAL int
char *type;
char *dev[];
char *buf;
{
int na;
continue;
/* since cu (altconn()) strips off leading */
/* "/dev/", do the same here. */
}
/* may have ",M" subfield in D_LINE */
*commap = '\0';
}
/*
* D_TYPE field may have protocol subfield, which
* must be pulled off before comparing to desired type.
*/
*commap = '\0';
/* to force the requested device type to be used. */
continue;
/* to force the requested line to be used */
continue;
return(na);
}
}
return(FAIL);
}
/*
* finds - set system attribute vector
*
* input:
* fsys - open Systems file descriptor
* sysnam - system name to find
* output:
* flds - attibute vector from Systems file
* fldcount - number of fields in flds
* return codes:
* >0 - number of arguments in vector - succeeded
* FAIL - failed
* Uerror set:
* 0 - found a line in Systems file
* SS_BADSYSTEM - no line found in Systems file
* SS_TIME_WRONG - wrong time to call
*/
static int
{
int na;
/* format of fields
* 0 name;
* 1 time
* 3 speed
* etc
*/
return(FAIL);
}
continue;
/* check if requested Mytype device type */
continue;
} else {
}
/* OK if not uucico (ie. ct or cu) or the time is right */
/* found a good entry */
Uerror = 0;
return(na); /* FOUND OK LINE */
}
} else {
if (!Uerror)
}
}
if (!Uerror)
return(FAIL);
}
/*
* getProto - get the protocol letters from the input string.
* input:
* a ',' delimits the protocol string
* e.g. ACU,g or DK,d
* output:
* str - the , (if present) will be replaced with NULLCHAR
*
* return: none
*/
static void
char *save;
char *str;
{
char *p;
*p = NULLCHAR;
}
return;
}
/*
* check for a specified protocol selection string
* return:
* protocol string pointer
* NULL if none specified for LOGNAME
*/
GLOBAL char *
char *valid;
{
char *save;
_Protocol[0] = '\0';
if ( _ProtoSys[0] != '\0' )
if ( _ProtoDev[0] != '\0' )
if ( _ProtoCfg[0] != '\0' )
if ( _Protocol[0] == '\0' ) {
}
}
/*
* addProto
*
* Verify that the desired protocols from the Systems and Devices file
* have been compiled into this application.
*
* desired - list of desired protocols
* valid - list of protocols that are compiled in.
*/
static void
char *desired;
char *valid;
{
char *protoPtr;
char *wantPtr;
if ( *desired == '\0' )
return;
} else {
protoPtr++;
}
}
} else {
}
wantPtr++;
}
}
}
return;
}
/*
* mergeProto
*
* input
* char *tostring, *fromstring;
*/
static void
char *tostring, *fromstring;
{
int length;
if ( *tostring == *fromstring )
break;
else
tostring++;
}
} else {
tostring++;
fromstring++;
}
}
return;
}
/*
* removeProto
*
* char *old
* char letter
*
* return
* none
*/
static void
{
else
string++;
}
}
/*
* nextProto
* char *string;
* return
* char * to next non-parameter letter
*/
static char *
char *string;
{
if ( *string == '(' )
if ( *(string++) == ')' )
break;
return(string);
}
/*
* findProto
* char *desired,
* char protoPtr;
* return
* char *pointer to found or string terminating NULLCHAR
*/
GLOBAL char *
char *string;
char letter;
{
break;
else
string++;
return(string);
}
/*
* chat - do conversation
* input:
* nf - number of fields in flds array
* flds - fields from Systems file
* fn - write file number
* phstr1 - phone number to replace \D
* phstr2 - phone number to replace \T
*
* return codes: 0 | FAIL
*/
GLOBAL int
{
int k, ok;
for (k = 0; k < nf; k += 2) {
while (ok != 0) {
if (ok == 0)
break;
return(FAIL);
}
}
sleep(2);
if (flds[k+1])
}
return(0);
}
/*
* expect(str, fn) look for expected string w/ possible special chars
*
* return codes:
* 0 - found
* FAIL - too many characters read
* some character - timed out
*/
GLOBAL int
char *str;
int fn;
{
if (*sptr == '\\') {
switch (*++sptr) {
case 'H':
*bptr++ = '\0';
return (FAIL);
}
return (FAIL);
}
continue;
case '\\':
*bptr++ = '\\';
continue;
default:
*bptr++ = '\\';
continue;
}
} else
}
*bptr = '\0';
return (FAIL);
}
return (0);
}
/*
* expect_str(str, fn) look for expected string, w/ no special chars
*
* return codes:
* 0 - found
* FAIL - too many characters read
* some character - timed out
*/
GLOBAL int
char *str;
int fn;
{
int kr, c;
char nextch;
*rp = 0;
if (kr < 040) {
} else
return(0);
}
if (*str== '\0') {
return(0);
}
return (FAIL);
}
errno = 0;
if (kr <= 0) {
alarm(0);
return(FAIL);
}
c = nextch & 0177;
rp++;
alarm(0);
return(FAIL);
}
}
alarm(0);
return(0);
}
/*
* alarmtr() - catch alarm routine for "expect".
*/
/*ARGSUSED*/
GLOBAL void
int sig;
{
}
/*
* wait_for_hangup() - wait for a hangup to occur on the given device
*/
int
int dcf;
{
int rval;
if (rval < 0) {
return (FAIL);
}
return (FAIL);
}
return (SUCCESS);
}
/*
* sendthem(str, fn, phstr1, phstr2) send line of chat sequence
* char *str, *phstr;
*
* return codes: none
*/
#define FLUSH() {\
goto err;\
}
GLOBAL void
int fn;
{
static int p_init = 0;
if (!p_init) {
p_init++;
}
/* should be EQUALS, but previous versions had BREAK n for integer n */
/* send break */
return;
}
return;
}
return;
}
/* Set parity as needed */
return;
}
return;
}
return;
}
return;
}
str += 2;
}
if (*sptr == '\\') {
switch(*++sptr) {
/* adjust switches */
case 'c': /* no CR after string */
FLUSH();
sendcr = 0;
} else
continue;
/* stash in buf and continue */
case 'D': /* raw phnum */
continue;
case 'T': /* translated phnum */
continue;
case 'N': /* null */
*bptr++ = 0;
continue;
case 's': /* space */
*bptr++ = ' ';
continue;
case '\\': /* backslash escapes itself */
continue;
default: /* send the backslash */
*bptr++ = '\\';
continue;
/* flush buf, perform action, and continue */
case 'E': /* echo check on */
FLUSH();
echocheck = 1;
continue;
case 'e': /* echo check off */
FLUSH();
echocheck = 0;
continue;
case 'd': /* sleep briefly */
FLUSH();
sleep(2);
continue;
case 'p': /* pause momentarily */
FLUSH();
continue;
case 'K': /* inline break */
FLUSH();
continue;
case 'M': /* modem control - set CLOCAL */
case 'm': /* no modem control - clear CLOCAL */
FLUSH();
#ifdef ATTSVTTY
} else {
if (*sptr == 'M')
else
}
#endif
continue;
}
} else
}
if (sendcr)
*bptr++ = '\r';
err:
return;
}
/*
* generate parity table for use by sendthem.
*/
static void
int type;
{
int i, j, n;
for (i = 0; i < 128; i++) {
n = 0;
for (j = i&0177; j; j = (j-1)&j)
n++;
par_tab[i] = i;
par_tab[i] |= 0200;
}
}
GLOBAL int
char *buf;
{
int i;
if (echocheck)
if (Debug >= 5) {
for (i = 0; i < len; i++) {
if (*dbptr < 040) {
*dbptr++ = '^';
}
dbptr++;
}
*dbptr = 0;
} else
}
for (i = 0; i < len; i++)
return(FAIL);
return(SUCCESS);
}
GLOBAL int
int fn;
char *buf;
{
int i, saccess;
return(FAIL);
for (i = 0; i < len; i++) {
if (saccess) {
} else
return(FAIL);
do {
(void) alarm(expecttime);
return(FAIL);
(void) alarm(0);
cin &= 0177;
if (saccess) {
} else
}
return(SUCCESS);
}
/*
* notin(sh, lg) check for occurrence of substring "sh"
* char *sh, *lg;
*
* return codes:
* 0 - found the string
* 1 - not in the string
*/
static int
{
return(0);
else
lg++;
}
return(1);
}
/*
* ifdate(s)
* char *s;
*
* ifdate - this routine will check a string (s)
* like "MoTu0800-1730" to see if the present
* time is within the given limits.
*
* SIDE EFFECT - Retrytime is set to number following ";"
* SIDE EFFECT - MaxGrade is set to character following "/"
*
* if a grade is specified, iswrk() is consulted, so that we don't
* place calls when there's only low priority work. this will appear
* as a "wrong time to call" in the status file. sorry.
*
* String alternatives:
* Wk - Mo thru Fr
* zero or one time means all day
* Any - any day
*
* return codes:
* 0 - not within limits, or grade too low
* 1 - within limits
*/
static int
ifdate(s)
char *s;
{
char *r;
#ifdef MAXGRADE
char *m, grade;
#endif
int t__now;
/*
* pick up retry time for failures and max grade
* global variables Retrytime and MaxGrade are set here
*/
r = strrchr(s, ';');
/* set retry time */
if (r != NULL) {
if (isdigit(r[1])) {
*r = NULLCHAR; /* blow away retry time field */
}
} else
Retrytime = 0; /* use exponential backoff */
#ifdef MAXGRADE
/* set grade */
m = strrchr(s, '/');
if (m != NULL) {
if (isalnum(m[1]))
*m = NULLCHAR; /* blow away max grade field */
}
/* test grade */
return(0);
}
}
#endif /* MAXGRADE */
s = strchr(s, ',');
if (s == CNULL)
return(0);
s++;
}
return(1);
}
/* worker function for ifdate() */
static int
char *s;
int t__now;
{
static char *days[] = {
"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", 0
};
int i;
/*
* check day of week
*/
while (isalpha(*s)) {
if (PREFIX("Any", s))
for (i = 0; days[i]; i++)
s++;
}
return(0); /* day match failed */
}
/* day match ok -- check time */
static int
char *s;
int t__now;
{
while (isalpha(*s)) /* flush day stuff */
s++;
return(1); /* time match ok (default) */
return(1);
/* 0000 crossover? */
return(1);
} else {
return(1);
}
return(0);
}
/*
* char *
* fdig(cp) find first digit in string
*
* return - pointer to first digit in string or end of string
*/
GLOBAL char *
char *cp;
{
char *c;
for (c = cp; *c; c++)
if (*c >= '0' && *c <= '9')
break;
return(c);
}
#ifdef FASTTIMER
/* Sleep in increments of 60ths of second. */
GLOBAL void
int time;
{
static int fd;
if (fd == 0)
return;
}
#endif /* FASTTIMER */
/* nap(n) -- sleep for 'n' ticks of 1/60th sec each. */
/* This version uses the select system call */
GLOBAL void
nap(n)
unsigned n;
{
if (n==0)
return;
return;
}
#endif /* BSD4_2 || ATTSVR4 */
#ifdef NONAP
/* nap(n) where n is ticks
*
* if n represents more than 1 second, then
* use sleep(time) where time is the equivalent
* seconds rounded off to full seconds
* NOTE - this is a rough approximation and chews up
* processor resource!
*/
GLOBAL void
nap(n)
unsigned n;
{
long endtime;
int i;
if (n > HZ) {
/* > second, use sleep, rounding time */
return;
}
/* use timing loop for < 1 second */
for (i=0; i<1000; i++, (void) (i*i))
;
}
return;
}
#endif /* NONAP */
/*
* altconn - place a telephone call to system
* from cu when telephone number or direct line used
*
* return codes:
* FAIL - connection failed
* >0 - file no. - connect ok
* When a failure occurs, Uerror is set.
*/
GLOBAL int
{
/* cu -l dev ... */
/* exactly match entries in Devices file, which usually */
/* omit the "/dev/". if doesn't begin with "/dev/", */
/* either they've omitted the "/dev/" or it's a non- */
/* standard path name. in either case, leave it as is */
} else {
}
}
/* cu ... telno */
} else {
/* cu direct line */
}
return(fn);
}