[comp.unix.sysv386] Bidirectional Modem Port on Open Desktop

rob@lafayet.UUCP (Rob Freyder) (09/11/90)

Greetings
	I am trying to get a bidirectional modem port to work properly under
Open Desktop.  I have Telebit T2500 connected to tty1a.  Can someone help
me with the configuration.  

If the port is disabled we are successful at dialing out.  When we enable
the port we can dial in but it disconnects immediately.  (DTR drops low).

We are using uugetty instead of getty..  any suggestions ?

thanks in advance.  Rob. 
-- 
Rob Freyder                                  Core Laboratories a division of
____    ____     ____                        Western Atlas International Inc.
\   \  /   /\   /   /\                       =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 \   \/   /  \ /   /  \                      Humans     (318) 235-9431
  \  /   / \  /   /\   \                     Internet   rob@lafayet.UUCP
   \/___/   \/___/  \___\                    Bang    ...!uunet!rouge!lafayet!rob

rick@tmiuv0.uucp (09/12/90)

In article <699@lafayet.UUCP>, rob@lafayet.UUCP (Rob Freyder) writes:
> Greetings

Greetings, Earthling.   8-)
> 	I am trying to get a bidirectional modem port to work properly under
> Open Desktop.  I have Telebit T2500 connected to tty1a.  Can someone help
> me with the configuration.  
> 
> If the port is disabled we are successful at dialing out.  When we enable
> the port we can dial in but it disconnects immediately.  (DTR drops low).
> 
> We are using uugetty instead of getty..  any suggestions ?

Uhm, do you have the modem programmed to not output any status messages?
All you want the modem to do is assert CD, but not have any "RING" or
"CONNECT" messages spit out.  It's possible that your (uu)getty is seeing
those messages as an attempt to log in.  Make sure you're modem is set to
"quiet" mode.  On my T1000 in enhanced command mode, I have it set to

    ATE0 Q4 S51=255 S52=1 S53=2 S54=3

(I put in spaces to make it more readable).  I have that saved in the NVRAM.
Check your manual, there's a section on suggested unattended S-register
settings.  I used that as a starting basis.

This seems to work fine under ESIX SVR3.2.2-D.  Perhaps they'll work for
you.

----------------------------------------------------------------------------
[- O] Rick Stevens, Technology Marketing Incorporated
  ?   EMail: uunet!zardoz!tmiuv0!rick -or- uunet!zardoz!xyclone!sysop
  V   CIS: 75006,1355 (75006.1355@compuserve.com from Internet)
      (Opinions are mine.  No one listens to me here anyway.)

"Lead, follow, or get the h*ll out of the way!"
----------------------------------------------------------------------------

wht@n4hgf.Mt-Park.GA.US (Warren Tucker) (09/13/90)

In article <699@lafayet.UUCP> rob@lafayet.UUCP (Rob Freyder) writes:
>Greetings
>	I am trying to get a bidirectional modem port to work properly under
>Open Desktop.  I have Telebit T2500 connected to tty1a.  Can someone help
>me with the configuration.  
>
>If the port is disabled we are successful at dialing out.  When we enable
>the port we can dial in but it disconnects immediately.  (DTR drops low).
>
>We are using uugetty instead of getty..  any suggestions ?
>
>thanks in advance.  Rob. 

You need to make sure S64=1, so that the knee-jerk login prompt that
get spit out by getty doesn't knock your connection down.  I wish
getty/uugetty would delay 1/2 to 1 second after DCD is detected
(the open with no O_NDELAY succeeds) before issuing the login prompt.

Try making yourself a Devices line that looks like:

ACU tty?? - 300-19200 /usr/lib/uucp/dialgT2500

and put this program in /usr/lib/uucp:

#!/bin/sh
# This is gendial-T2500, a shell archive (shar 3.46)
# made 09/12/1990 18:11 UTC by root@n4hgf
# Source directory /usr/lib/uucp/dialers
#
# existing files will NOT be overwritten unless -c is specified
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#   1990 -rw-r--r-- Makefile
#    327 -rw-r--r-- README
#   6534 -rw-r--r-- dialer.h
#  25754 -rw-r--r-- gendial.c
#  18403 -rw-r--r-- dceT2500.c
#
# ============= Makefile ==============
if test -f 'Makefile' -a X"$1" != X"-c"; then
	echo 'x - skipping Makefile (File already exists)'
else
echo 'x - extracting Makefile (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
X#  CHK=0xE274
X#
X# uucp dialer makefile
X#
X#+:EDITS:*/
X#:07-19-1990-17:12-root@n4hgf-add gendial/dialgT2500
X#:11-24-1989-15:38-wht-edit for dial_wht additions
X
XLDFLAGS = -s -i
XCFLAGS  = -Octl -DHDUU
X
X#EXES   = dialUSR2400 dialMCOM9624 dialMCOM2400
X#EXES   = dialHA12 dialHA24 dialMUL dialTBIT dialVA3450
X#EXES    = dialMPAD
X#EXES   = dialUSR2400 dialMCOM9624 dialMCOM2400 dialMPAD dialTBIT dialgT2500 dialgMC9624
XEXES   = dialgT2500 dialgMC9624
XOBJS    =
XLIBS    = -lx
X
X.SUFFIXES:
X.SUFFIXES: .c .o .h
X
X.c.o:; cc -c $(CFLAGS) $*.c
X
Xall: dialgT2500
X#all:    $(EXES)
X
XdialUSR2400: dial_wht.c
X	cc $(CFLAGS) -DUSR2400 dial_wht.c $(LIBS) -o $@
X	chown uucp $@; chgrp uucp $@; chmod 711 $@
X
XdialMCOM9624: dial_wht.c
X	cc $(CFLAGS) -DMCOM9624C dial_wht.c $(LIBS) -o $@
X	chown uucp $@; chgrp uucp $@; chmod 711 $@
X
XdialgMC9624: gendial.o dceMC9624.o
X	cc $(CFLAGS) gendial.o dceMC9624.o $(LIBS) -o $@
X	chown uucp $@; chgrp uucp $@; chmod 711 $@
X
XdialMCOM2400: dial_wht.c
X	cc $(CFLAGS) -DMCOM2400 dial_wht.c $(LIBS) -o $@
X	chown uucp $@; chgrp uucp $@; chmod 711 $@
X
XdialMPAD: dial_wht.c
X	cc $(CFLAGS) -DMPAD dial_wht.c $(LIBS) -o $@
X	chown uucp $@; chgrp uucp $@; chmod 711 $@
X
XdialHA12: dialHA12.c
X	cc $(CFLAGS) dialHA12.c $(LIBS) -o $@
X	chown uucp $@; chgrp uucp $@; chmod 711 $@
X
XdialHA24: dialHA24.c
X	cc $(CFLAGS) dialHA24.c $(LIBS) -o $@
X	chown uucp $@; chgrp uucp $@; chmod 711 $@
X
XdialMUL: dialMUL.c
X	cc $(CFLAGS) dialMUL.c $(LIBS) -o $@
X	chown uucp $@; chgrp uucp $@; chmod 711 $@
X
XdialTBIT: dialTBIT.c
X	cc $(CFLAGS) dialTBIT.c $(LIBS) -o $@
X	chown uucp $@; chgrp uucp $@; chmod 711 $@
X
XdialT2500: dialT2500.c
X	cc $(CFLAGS) dialT2500.c $(LIBS) -o $@
X	chown uucp $@; chgrp uucp $@; chmod 711 $@
X
XdialgT2500: gendial.o dceT2500.o
X	cc $(CFLAGS) gendial.o dceT2500.o $(LIBS) -o $@
X	chown uucp $@; chgrp uucp $@; chmod 711 $@
X
XdialVA3450: dialVA3450.c
X	cc $(CFLAGS) dialVA3450.c $(LIBS) -o $@
X	chown uucp $@; chgrp uucp $@; chmod 711 $@
X
Xgendial.o: dialer.h
XdceT2500.o: dialer.h
XdceMC9624.o: dialer.h
SHAR_EOF
chmod 0644 Makefile ||
echo 'restore of Makefile failed'
Wc_c="`wc -c < 'Makefile'`"
test 1990 -eq "$Wc_c" ||
	echo 'Makefile: original size 1990, current size' "$Wc_c"
fi
# ============= README ==============
if test -f 'README' -a X"$1" != X"-c"; then
	echo 'x - skipping README (File already exists)'
else
echo 'x - extracting README (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'README' &&
XThis is a preliminary release of a T2500 dialer for SCO
XUNIX with HDB UUCP.  It should also work with XENIX with HDB.
XThe program will work fine; I use it every day.  The preliminary
Xpart of it is that this is part of a series of integrated
Xmodem dialers I've been gestating for a while; they jest ain't
Xreddy for releece yit.
SHAR_EOF
chmod 0644 README ||
echo 'restore of README failed'
Wc_c="`wc -c < 'README'`"
test 327 -eq "$Wc_c" ||
	echo 'README: original size 327, current size' "$Wc_c"
fi
# ============= dialer.h ==============
if test -f 'dialer.h' -a X"$1" != X"-c"; then
	echo 'x - skipping dialer.h (File already exists)'
else
echo 'x - extracting dialer.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'dialer.h' &&
X/* CHK=0x6F3B */
X/*+-------------------------------------------------------------------------
X	dialer.h - SCO UUCP generic dialer program definitions
X	wht%n4hgf.uucp@emory.mathcs.emory.edu -or- emory!n4hgf!wht
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:05-26-1990-02:14-wht@n4hgf-creation */
X
X#include <stdio.h>
X#include <ctype.h>
X#include <errno.h>
X#include <fcntl.h>
X#include <setjmp.h>
X#include <signal.h>
X#include <sys/types.h>
X#include <sys/errno.h>
X#include <sys/ioctl.h>
X#include <sys/stat.h>
X#include <termio.h>
X#include <time.h>
X#include <pwd.h>
X
X#define ff fprintf
X#define se stderr
X
Xchar *strdup();
Xchar *strchr();
Xchar *strrchr();
Xstruct passwd *getpwnam();
X
Xextern int errno;
Xextern char *sys_errlist[];
X
Xextern int gargc;					/* global copy of main's argv */
Xextern char **gargv;				/* global copy of main's argv */
Xextern char *dce_name;				/* full pathname of ACU device */
Xextern char *telno;					/* phone number if dial type request */
Xextern struct termio dce_termio;	/* last termio for device */
Xextern int Debug;					/* set per -x flag */
Xextern int dialing;					/* set while dialing in progress */
Xextern int fddce;					/* file descriptor for dce_name */
Xextern int DialerExitCode; 			/* return code */
Xextern int status;					/* set on errors */
Xextern int hangup_flag;				/* set when DCE being hung up */
Xextern int hiCBAUD;					/* highest permissible baud rate */
Xextern int loCBAUD;					/* lowest permissible baud rate */
Xextern int uid;						/* user id of executor */
Xextern int uid_uucp;				/* user id of uucp */
Xextern int secure;					/* non-zero to suppress display of secure
X									 * DCE traffic
X									 */
X
Xunsigned char dialer_codes[26];	/* A-Z embedded phone number codes */
X/* return codes: these are set up so that an abort signal at any time can */
X/* set the fail bit and return to the caller with the correct status */
X#define	SUCCESS		0
X#define	RC_FAIL		0x80	/* 1 = failed to connect */
X#define	RC_ENABLED	0x10	/* enabled flag: 1 = ungetty -r required to
X							 * restore the line
X							 */
X#define	RC_BAUD		0x0f	/* CBAUD connected at (0=same as dialed speed) */
X
X/* DCE result device independent flag */
X#define	rfNumeric	0x40000000
X
X/* program exit codes */
X#define	RCE_NULL	0	/* general purpose or unknown error code */
X#define	RCE_INUSE	1	/* line in use */
X#define	RCE_SIG		2	/* signal aborted dialer */
X#define	RCE_ARGS	3	/* invalid arguments */
X#define	RCE_PHNO	4	/* invalid phone number */
X#define	RCE_SPEED	5	/* invalid baud rate -or- bad connect baud */
X#define	RCE_OPEN	6	/* can't open line */
X#define	RCE_IOCTL	7	/* ioctl error */
X#define	RCE_TIMOUT	8	/* timeout */
X#define	RCE_NOTONE	9	/* no dial tone */
X#define	RCE_HANGUP	10	/* hangup failed */
X#define RCE_NORESP	11	/* Modem didn't respond. */
X#define	RCE_BUSY	13	/* phone is busy */
X#define	RCE_NOCARR	14	/* no carrier */
X#define	RCE_ANSWER	15	/* no answer */
X
X/* ungetty return codes */
X#define	UG_NOTENAB	0
X#define	UG_ENAB		1
X#define	UG_RESTART	1
X#define	UG_FAIL		2
X
X/* size for various buffers */
X#define MAXLINE		80
X
X/* How many errors allowed before call retry fails */
X#define	DIAL_ERRORS_MAX	4
X
X/* DCE message to code mapping struct ... array DCE_results of these
X * must be terminated with { (char *)0,0 } */
Xtypedef struct dce_result
X{
X	char *result;
X	long code;
X} DCE_RESULT;
X
X#define DEBUG(level,fmt,arg) if (Debug >= level) fprintf(stderr,fmt,arg)
X#if !defined(DBG)
X#define	DBG	0
X#endif
X
X/*
X * what the hell does __STDC__ mean in reality?  An __STDC__ compiler is
X * more nouveau than an older one.  ANSI C (or 'D') just stirred new
X * food for "standard" readers who went off and did what they wanted
X * to do.  We use __STDC__ to decide between two opinions of
X * what constitute "ANSI prototypes."  As of this writing, __STDC__ is
X * defined by the UNIX (MSC 5) compiler and not by the XENIX (MSC 4)
X * compiler.
X */
X#ifdef __STDC__
Xextern  int DCE_baud_to_CBAUD(unsigned int baud);
Xextern  void DCE_hangup(void );
Xextern  int DCE_dial(char *telno);
Xextern  void DCE_abort(int sig);
Xextern  void DCE_exit(int exitcode);
Xextern  int DCE_argv_hook(int argc,char * *argv,int optind,int unrecognized_switches);
Xextern  int get_uucp_uid(void );
Xextern  int instr(char *s1,char *s2);
Xextern  void translate(char *ttab,char *str);
Xextern  int decode_phone_number(char *userphno,char *result,int resultlen);
Xextern  char *make_printable(unsigned char ch);
Xextern  char *RCE_text(int value);
Xextern  void myexit(int code);
Xextern  int dial_abort(int sig);
Xextern  void cleanup(int stat);
Xextern  int SIGALRM_abort(int sig);
Xextern  int SIGALRM_alert(int sig);
Xextern  long _lread(int rtime,int error_ok);
Xextern  long lread_ignore(int rtime);
Xextern  long lread(int rtime);
Xextern  int lflush(void );
Xextern  void _lputc(char lchar);
Xextern  void _lputc_paced(long pace_msec,char lchar);
Xextern  void _lputs(char *string);
Xextern  void _lputs_paced(long pace_msec,char *string);
Xextern  int lwrite(char *str);
Xextern  int ltoggleDTR(long msec);
Xextern  int call_ungetty(char call_type);
Xextern  void display_termio(struct termio *ttt,char *text);
Xextern  int open_dce(void );
Xextern  int main(int argc,char * *argv);
X#else
Xextern  int DCE_baud_to_CBAUD(unsigned int baud);
Xextern  void DCE_hangup(void );
Xextern  int DCE_dial(char *telno);
Xextern  void DCE_abort(int sig);
Xextern  void DCE_exit(int exitcode);
Xextern  int DCE_argv_hook(int argc,char * *argv,int optind,int unrecognized_switches);
Xextern  int get_uucp_uid(void );
Xextern  int instr(char *s1,char *s2);
Xextern  void translate(char *ttab,char *str);
Xextern  int decode_phone_number(char *userphno,char *result,int resultlen);
Xextern  char *make_printable(unsigned char ch);
Xextern  char *RCE_text(int value);
Xextern  void myexit(int code);
Xextern  int dial_abort(int sig);
Xextern  void cleanup(int stat);
Xextern  int SIGALRM_abort(int sig);
Xextern  int SIGALRM_alert(int sig);
Xextern  long _lread(int rtime,int error_ok);
Xextern  long lread_ignore(int rtime);
Xextern  long lread(int rtime);
Xextern  int lflush(void );
Xextern  void _lputc(char lchar);
Xextern  void _lputc_paced(long pace_msec,char lchar);
Xextern  void _lputs(char *string);
Xextern  void _lputs_paced(long pace_msec,char *string);
Xextern  int lwrite(char *str);
Xextern  int ltoggleDTR(long msec);
Xextern  int call_ungetty(char call_type);
Xextern  void display_termio(struct termio *ttt,char *text);
Xextern  int open_dce(void );
Xextern  int main(int argc,char * *argv);
X#endif
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of dialer.h */
SHAR_EOF
chmod 0644 dialer.h ||
echo 'restore of dialer.h failed'
Wc_c="`wc -c < 'dialer.h'`"
test 6534 -eq "$Wc_c" ||
	echo 'dialer.h: original size 6534, current size' "$Wc_c"
fi
# ============= gendial.c ==============
if test -f 'gendial.c' -a X"$1" != X"-c"; then
	echo 'x - skipping gendial.c (File already exists)'
else
echo 'x - extracting gendial.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'gendial.c' &&
X/* CHK=0xC086 */
Xchar *revision = "x1.01";
X/*+-------------------------------------------------------------------------
X	gendial.c - SCO UUCP dialer program device independent portion
X	wht@n4hgf.Mt-Park.GA.US
X
X  Configuration symbols:
X	HDUU		defined if HDB UUCP used on system, else old Version 2 
X
X  Defined functions:
X	RCE_text(value)
X	SIGALRM_alert(sig)
X	_lputc(lchar)
X	_lputc_paced(pace_msec,lchar)
X	_lputs(string)
X	_lputs_paced(pace_msec,string)
X	_lread(rtime,error_ok)
X	call_ungetty(call_type)
X	cleanup(stat)
X	decode_phone_number(userphno,result,resultlen)
X	dial_abort(sig)
X	display_termio(ttt,text)
X	get_uucp_uid()
X	instr(s1,s2)
X	lflush()
X	lread(rtime)
X	lread_ignore(rtime)
X	ltoggleDTR(msec)
X	lwrite(str)
X	main(argc,argv)
X	make_printable(ch)
X	myexit(code)
X	open_dce()
X	translate(ttab,str)
X
X  Usage:	dial ttyname telnumber speed 
X			dial -h ttyname speed
X
X  ttyname may be of style "ttyxx" or "/dev/ttyxx" (this is not standard)
X
X  Returns:
X		0x80	bit = 1 if connection failed
X		0x10	bit = 1 if line is also used for dialin #if !defined(OLDUUCP)
X		0x0f	if msb=1: error code
X				if msb=0: connected baud rate (0=same as dialed baud)
X                Note: this dialer always returns 0 in the low nibble
X                since cu and uucp expect it
X
X  Note: getty calls the dialer with -h whenever it starts up on a line
X  enabled in /etc/ttys and listed in Devices with this dialer.
X
X  Error codes are split into two categories:
X
X    1) (codes 0-11) Local problems are defined as tty port, or DCE
X    problems: problems that can be worked around by using a different
X    device.
X
X    2) (codes 12-15) Remote problems are phone busy, no answer, etc.:
X    attempt to connect to this remote system should be stopped.
X
X  Note: This dialer can be used both for the old "Version 2" 
X  new HoneyDanBer UUCP.  In HDB, uugetty is used and ungetty is not
X  necessary. Define HDUU for HDB UUCP.
X
X  Note: This version of the dialer will NOT display the telephone number
X  on the console unless the actual uid is root.  If dial logging is
X  used, make sure the dial_ttyXX.log file is precreated, owned by root
X  and has -rw--w--w- mode (0622).  Now, if uucico would just suppress
X  username and password information it sends out!
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:07-19-1990-17:14-root@n4hgf-modify lread fata timeout handler */
X/*:05-26-1990-02:15-wht@n4hgf-creation */
X
X#include "dialer.h"
X
X/* must be defined by device dependent module */
Xextern long DCE_DTR_low_msec;		/* msecs DTR must be low to be recognized */
Xextern long DCE_DTR_high_msec;		/* msecs for DCE to recover */
Xextern long DCE_write_pace_msec;	/* msecs between chars written to DCE */
Xextern DCE_RESULT DCE_results[];	/* DCE result codes */
Xextern char *DCE_name;				/* name of DCE */
Xextern char *DCE_revision;			/* DCE-dependent code revision */
Xextern short DCE_hangup_CBAUD;		/* BXXX DCE hangup baud rate or zero */
X
X/* globals available to device dependent module */
Xint gargc;					/* global copy of main's argv */
Xchar **gargv;				/* global copy of main's argv */
Xchar *dce_name;					/* full pathname of ACU device */
Xchar *telno = (char *)0;	/* phone number if dial type request */
Xstruct termio dce_termio;	/* last termio for device */
Xint Debug = DBG;			/* set per -x flag */
Xint dialing = 0;			/* set while dialing in progress */
Xint fddce = -1;				/* file descriptor for dce_name */
Xint DialerExitCode = RC_FAIL; /* return code */
Xint status = 0;				/* set on errors */
Xint hangup_flag = 0;		/* set when DCE being hung up */
Xint hiCBAUD;				/* highest permissible baud rate */
Xint loCBAUD;				/* lowest permissible baud rate */
Xint uid;					/* user id of executor */
Xint uid_uucp;				/* user id of uucp */
Xint secure = 0;				/* non-zero to suppress display of secure
X							 * DCE traffic
X							 */
X
Xunsigned char dialer_codes[26];	/* A-Z embedded phone number codes */
X
Xjmp_buf	SIGALRM_alert_jmpbuf;
XDCE_RESULT *last_result;
X
X/*+-------------------------------------------------------------------------
X	get_uucp_uid()
X--------------------------------------------------------------------------*/
Xint
Xget_uucp_uid()
X{
Xstruct passwd *p = getpwnam("uucp");
X	endpwent();
X	if(p)
X		return(p->pw_uid);
X	else
X		return(-1);
X}	/* end of get_uucp_uid */
X
X/*+-------------------------------------------------------------------------
X	instr(s1,s2)
X
X  find s2 in s1; returns 1 if found, 0 if not found
X--------------------------------------------------------------------------*/
Xinstr(s1,s2)
Xregister char *s1;
Xchar *s2;
X{
X	register len = strlen(s2);
X	while(s1 = strchr(s1,*s2))
X	{
X		if(!strncmp(s2,s1,len))
X			return(1);
X		s1++;
X	}
X	return(0);
X}	/* end of instr */
X
X/*+-------------------------------------------------------------------------
X	translate(ttab,str)
X
X  translate the pairs of characters present in the first string
X  whenever the first of the pair appears in the second string
X  (this routine from standard SCO dialer code)
X--------------------------------------------------------------------------*/
Xvoid
Xtranslate(ttab,str)
Xregister char *ttab;
Xchar *str;
X{
X	register char *cptr;
X
X	while(*ttab && *(ttab + 1))
X	{
X		for(cptr = str; *cptr; cptr++)
X		{
X			if(*ttab == *cptr)
X				*cptr = *(ttab + 1);
X		}
X		ttab += 2;
X	}
X}	/* end of translate */
X
X/*+-------------------------------------------------------------------------
X	decode_phone_number(userphno,result,resultlen)
X
Xdecode user flags in phone number, returning phone number in
Xresult, character flags in global dialer_codes[], 'A' or 'a'
Xresults in dialer_codes[0] being 1, etc.  Only letter codes are
Xextracted.
X
XFor example, if userphno contains "123,D45f", result returned
X"123,45" and only elements 3 and 5 of dialer_codes set to 1
X
XFunction returns 0 if successful, -1 if result buffer too small
X--------------------------------------------------------------------------*/
Xint
Xdecode_phone_number(userphno,result,resultlen)
Xregister char *userphno;
Xregister char *result;
Xint resultlen;
X{
Xregister itmp;
X
X	for(itmp = 0; itmp < sizeof(dialer_codes); itmp++)
X		dialer_codes[itmp] = 0;
X
X	if(!resultlen)
X		return(-1);
X	resultlen--;	/* leave room for null */
X
X	while(*userphno)
X	{
X		if(isalpha(*userphno))
X			dialer_codes[*userphno - ((isupper(*userphno)) ? 'A' : 'a')] = 1;
X		else
X		{
X			if(!resultlen--)
X				return(-1);
X			*result++ = *userphno;
X		}
X		userphno++;
X	}
X	*result = 0;
X	return(0);
X}	/* end of decode_phone_number */
X
X/*+-------------------------------------------------------------------------
X	make_printable(ch) - make a character "printable"
X--------------------------------------------------------------------------*/
Xchar *
Xmake_printable(ch)
Xunsigned char ch;
X{
Xstatic char buffer[10];
Xchar *cptr;
X#define	to_print(x)	((x)<' '?((x)+'@'):'?')
X
X	cptr = buffer;
X	/* if not root or uucp and info needs securing */
X	if(uid && (uid != uid_uucp) && secure)
X	{
X		*cptr++ = '?';	/* hide it */
X		*cptr = 0;
X		return(buffer);
X	}
X
X	if(iscntrl(ch) || !isprint(ch))
X	{
X		if(!isascii(ch))
X		{			/* Top bit is set */
X			*cptr++ = 'M';
X			*cptr++ = '-';
X			ch = toascii(ch);			/* Strip it */
X		}
X		if(iscntrl(ch))
X		{
X			*cptr++ = '^';
X			ch = to_print(ch);			/* Make it printable */
X		}
X	}
X	*cptr++ = ch;
X	*cptr = 0;
X	return(buffer);
X}	/* end of make_printable */
X
X/*+-------------------------------------------------------------------------
X	RCE_text(value)
X--------------------------------------------------------------------------*/
Xchar *
XRCE_text(value)
Xint value;
X{
Xstatic char errant[32];
X
X	switch(value & 0x0F)
X	{
X		case RCE_NULL: return("unknown or unclassified error");
X		case RCE_INUSE: return("line in use");
X		case RCE_SIG: return("killed with signal");
X		case RCE_ARGS: return("invalid arguments");
X		case RCE_PHNO: return("invalid phone number");
X		case RCE_SPEED: return("invalid line speed or bad connect speed");
X		case RCE_OPEN: return("cannot open line");
X		case RCE_IOCTL: return("ioctl error");
X		case RCE_TIMOUT: return("timeout");
X		case RCE_NOTONE: return("NO DIAL TONE");
X		case RCE_HANGUP: return("hangup failed\n");
X		case RCE_NORESP: return("DCE didn't respond.\n");
X		case RCE_BUSY: return("BUSY");
X		case RCE_NOCARR: return("NO CARRIER");
X		case RCE_ANSWER: return("NO ANSWER");
X	}
X	sprintf(errant,"code 0x%04x",value);
X	return(errant);
X
X}	/* end of RCE_text */
X
X/*+-------------------------------------------------------------------------
X	myexit(code) - all threads exit() thru here
X--------------------------------------------------------------------------*/
Xvoid
Xmyexit(code)
Xint code;
X{
X	if(dialing)
X	{
X		if(code & RC_FAIL)
X		{
X			DEBUG(1,"dial failed: %s\n",RCE_text(code));
X		}
X		else
X		{
X			DEBUG(1,"dial succeeded\n",0);
X		}
X	}
X	DCE_exit(code);	/* should not return */
X	exit(code);		/* in case it does */
X
X}	/* end of myexit */
X
X/*+-------------------------------------------------------------------------
X	dial_abort(sig)
X--------------------------------------------------------------------------*/
Xdial_abort(sig)
Xint sig;
X{
X	if(sig)
X	{
X		DEBUG(2,"\ndialer received signal %d\n\n",sig);
X	}
X	else
X	{
X		DEBUG(2,"\ndialer aborted, fail status = %d\n",DialerExitCode);
X	}
X	DCE_abort(sig);
X	if(fddce != -1)
X	{
X		ioctl(fddce,TCGETA,&dce_termio);
X		dce_termio.c_cflag |= HUPCL;		/* make sure DCE hangs up */
X		ioctl(fddce,TCSETA,&dce_termio);
X		close(fddce);
X	}
X	if(sig)
X		DialerExitCode |= (RC_FAIL | RCE_SIG);
X	myexit(DialerExitCode);
X}	/* end of dial_abort */
X
X/*+-------------------------------------------------------------------------
X	cleanup(stat) - close device and exit
X--------------------------------------------------------------------------*/
Xvoid
Xcleanup(stat)
Xint stat;
X{
X	if(stat & RC_FAIL)
X	{	/* if we failed, drop DTR (in dial_abort) */
X		DialerExitCode = stat;
X		dial_abort(0);
X	}
X	else 
X		myexit(stat);
X}	/* end of cleanup */
X
X/*+-------------------------------------------------------------------------
X	SIGALRM_alert(sig) - catch alarm call and do longjmp
X--------------------------------------------------------------------------*/
XSIGALRM_alert(sig)
Xint sig;
X{
X	longjmp(SIGALRM_alert_jmpbuf,1);
X}	/* end of SIGALRM_alert */
X
X/*+-------------------------------------------------------------------------
X	_lread(rtime,error_ok)
X
X  Common code for lread() and lread_ignore()
X
X  Returns DCE_RESULT->code from matching DCE_RESULT->result
X  or if no match is found and the first digit of the modem
X  response is numeric, the the numeric value is returned ored
X  with 0x4000.
X
X  If error_ok is true and a timeout occurs, -1 is returned.
X  If error_ok is false and a timeout occurs,
X     cleanup(RC_FAIL | RCE_TIMOUT | DialerExitCode);
X     is called, which results in dial_abort(0) thus DCE_abort(0)
X     being called.
X--------------------------------------------------------------------------*/
Xlong
X_lread(rtime,error_ok)
Xint rtime;
Xint error_ok;
X{
Xint itmp;
Xchar rdchar;
XDCE_RESULT *mr;
Xchar buf[MAXLINE];
Xregister char *bp = buf;
Xchar *cptr;
X
X	if(error_ok)
X	{
X		signal(SIGALRM,SIGALRM_alert);
X		if(setjmp(SIGALRM_alert_jmpbuf) != 0)
X		{
X			DEBUG(6,">>-%s\n","TIMEOUT (NON-FATAL)");
X			return(-1);
X		}
X	}
X	else
X	{
X		signal(SIGALRM,SIGALRM_alert);
X		if(setjmp(SIGALRM_alert_jmpbuf) != 0)
X		{
X			DEBUG(6,">>-%s\n","TIMEOUT (FATAL)");
X			cleanup(RC_FAIL | RCE_TIMOUT | DialerExitCode);
X		}
X	}
X
X	alarm(rtime);
X	DEBUG(6,"DCE returned %s","<<");
X
X	while((itmp = read(fddce,&rdchar,1)) == 1)
X	{
X		*bp++ = (rdchar &= 0x7F);
X		DEBUG(6,"%s",make_printable(rdchar));
X		if(rdchar == 0x0A)
X			DEBUG(6,"\n",0);
X		if(bp >= buf + MAXLINE)
X		{
X			alarm(0);
X			DEBUG(6,"\n>>-FAIL (%s)\n","BUFFER OVERFLOW");
X			myexit(RC_FAIL | RCE_NULL);
X		}
X		*bp = 0;
X		if(rdchar == '\r')
X		{
X			cptr = buf;
X			if(*cptr == 0x0A)
X				cptr++;
X			for(mr = DCE_results; mr->result; ++mr)
X			{
X				if(instr(buf,mr->result))
X				{
X					alarm(0);
X					DEBUG(6,">>-%s\n","SUCCESS");
X					DEBUG(4,"got %s\n",mr->result);
X					last_result = mr;
X					return(mr->code);
X				}
X			}
X
X			if(isdigit(*cptr))
X			{
X				alarm(0);
X				itmp = atoi(cptr);
X				DEBUG(6,">>-SUCCESS (NUMERIC RESULT %d)\n",itmp);
X				return(rfNumeric | itmp);
X			}
X
X			bp = buf;
X		}
X	}
X
X	alarm(0);
X	if(Debug >= 6)
X	{
X		ff(se,">>-FAIL (%s %d)",
X			(itmp < 0) ? "READ ERRNO" : "READ LENGTH",
X			(itmp < 0) ? errno : 0);
X	}
X	DEBUG(4," incomplete or no response\n",0);
X	return(-1);
X}	/* end of _lread */
X
X/*+-------------------------------------------------------------------------
X	lread_ignore(rtime)
X
X  Reads from the ACU until it finds a valid response (found in
X  DCE_results), a numeric result code (e.g., S-register value), or times
X  out after rtime seconds.  The numeric response feature is designed
X  for Hayes-style DCEs and may not be useful for other DCE types
X
X  Returns: DCE_RESULT code, numeric result + 128, or -1 on timeout or error
X--------------------------------------------------------------------------*/
Xlong
Xlread_ignore(rtime)
Xint rtime;
X{
X	return(_lread(rtime,1));
X}	/* end of lread_ignore */
X
X/*+-------------------------------------------------------------------------
X	lread(rtime)
X
X  Same as lread_ignore, but does not return on timeout or error
X--------------------------------------------------------------------------*/
Xlong
Xlread(rtime)
Xint rtime;
X{
Xint rtn = _lread(rtime,0);
X	if(rtn < 0)
X		myexit(RC_FAIL | RCE_TIMOUT);
X	return(rtn);
X}	/* end of lread */
X
X/*+-------------------------------------------------------------------------
X	lflush() - flushes input clists for DCE
X--------------------------------------------------------------------------*/
Xlflush()
X{
X	ioctl(fddce,TCFLSH,0);
X}	/* end of lflush */
X
X/*+-----------------------------------------------------------------------
X	_lputc(lchar) -- write char to comm line
X------------------------------------------------------------------------*/
Xvoid
X_lputc(lchar)
Xchar lchar;
X{
X	write(fddce,&lchar,1);
X	DEBUG(6,"%s",make_printable(lchar));
X}	/* end of _lputc */
X
X/*+-----------------------------------------------------------------------
X	_lputc_paced(pace_msec,lchar) -- write char to comm line with pacing
X------------------------------------------------------------------------*/
Xvoid
X_lputc_paced(pace_msec,lchar)
Xregister long pace_msec;
Xregister char lchar;
X{
X	_lputc(lchar);
X	if(pace_msec)
X		nap(pace_msec);
X}	/* end of _lputc_paced */
X
X/*+-----------------------------------------------------------------------
X	_lputs(string) -- write string to comm line
X------------------------------------------------------------------------*/
Xvoid
X_lputs(string)
Xregister char *string;
X{
X	while(*string)
X		_lputc(*string++);
X}
X
X/*+-----------------------------------------------------------------------
X	_lputs_paced(pace_msec,string) -- write string to comm line
X  with time between each character 
X------------------------------------------------------------------------*/
Xvoid
X_lputs_paced(pace_msec,string)
Xregister long pace_msec;
Xregister char *string;
X{
X	while(*string)
X		_lputc_paced(pace_msec,*string++);
X
X}	/* end of _lputs_paced */
X
X/*+-------------------------------------------------------------------------
X	lwrite(str) - output string to dce_name
X  Returns:	0 on completion, -1 on write errors.
X--------------------------------------------------------------------------*/
Xlwrite(str)
Xregister char *str;
X{
Xint err;
X
X	nap(200L);
X	DEBUG(6,"Sent DCE %s","<<");
X	_lputs_paced(DCE_write_pace_msec,str);
X	DEBUG(6,">>-%s\n","SUCCESS");
X	ioctl(fddce,TCSETAW,&dce_termio);	/* wait for I/O to drain */
X	return(0);
X
X}	/* end of lwrite */
X
X/*+-------------------------------------------------------------------------
X	ltoggleDTR(msec) - drop DTR, pause, raise DTR
X
XIf msec != 0, drop DTR for that period of time, else DCE_DTR_low_msec
XThis routine trusts that the DTE has already been opened and ioctl'ed
Xonce and that no error checking need be done; this may not catch all
Xchanges in the universe, but the assumption is not naive
X--------------------------------------------------------------------------*/
XltoggleDTR(msec)
Xlong msec;
X{
X	dce_termio.c_cflag &= ~(CBAUD);	/* set to B0 */
X	dce_termio.c_cflag |= HUPCL;
X	ioctl(fddce,TCSETA,&dce_termio);
X	close(fddce);
X	nap((msec) ? msec : (long)DCE_DTR_low_msec);
X	(void)open_dce();
X	if(DCE_DTR_high_msec)
X		nap((long)DCE_DTR_high_msec);
X}	/* end of ltoggleDTR */
X
X/*+-------------------------------------------------------------------------
X	call_ungetty(call_type)
X
Xtype: 'a' - acquire dce_name
X      't' - test to see if dce_name should be returned
X      'r' - return dce_name
X
XThis function is a no-op in HDB UUCP versions
X--------------------------------------------------------------------------*/
Xcall_ungetty(call_type)
Xchar call_type;
X{
X#if defined(HDUU)
X	switch(call_type)
X	{
X		case 'a': return(UG_NOTENAB);		/* simulate complete success */
X		case 't': return(UG_RESTART);		/* simulate need for re-setup */
X		case 'r': return(0);				/* simulate complete success */
X	}
X	return(0);
X#else /* HDUU */
Xint itmp;
Xint pid;
Xunsigned int wait_status;
Xstatic char *ungetty = "/usr/lib/uucp/ungetty";
X
X	if((pid = fork()) == 0)
X	{
X		if(Debug >= 5)
X			ff(se,"%s: %s %s called\n",*gargv,ungetty,dce_name);
X		switch(call_type)
X		{
X			case 'a':
X				execl(ungetty,"ungetty",dce_name + 5,(char *)0);
X				break;
X			case 't':
X				execl(ungetty,"ungetty","-t",dce_name + 5,(char *)0);
X				break;
X			case 'r':
X				execl(ungetty,"ungetty","-r",dce_name + 5,(char *)0);
X				break;
X		}
X		ff(se,"%s exec error %d (%s)\n",ungetty,errno,sys_errlist[errno]);
X		__exit(-1);
X	}
X
X	while(((itmp = wait(&wait_status)) != pid) && itmp != -1)
X		;
X
X	if(Debug >= 6)
X		ff(se,"%s pid %d exit status 0x%04x\n",ungetty,itmp,wait_status);
X
X	return((wait_status >> 8) & 0xFF);
X#endif /* HDUU */
X}	/* end of call_ungetty */
X
X/*+-----------------------------------------------------------------------
X	display_termio(ttt)
X  display termio 'ttt' on se
X------------------------------------------------------------------------*/
Xvoid
Xdisplay_termio(ttt,text)
Xstruct termio *ttt;
Xchar *text;
X{
Xregister flag;
Xregister i_cc;
Xregister char *cptr;
Xint dbits;
Xchar parity;
X
X	ff(se,"----->> %s\n",text);
X
X	flag = ttt->c_iflag;
X	ff(se,
X"iflag: %07o IGNBRK:%d BRKINT:%d IGNPAR:%d PARMRK:%d INPCK:%d ISTRIP:%d\n",
X				flag,
X				(flag & IGNBRK) ? 1 : 0,
X				(flag & BRKINT) ? 1 : 0,
X				(flag & IGNPAR) ? 1 : 0,
X				(flag & PARMRK) ? 1 : 0,
X				(flag & INPCK ) ? 1 : 0,
X				(flag & ISTRIP) ? 1 : 0);
X	ff(se,
X"       INLCR:%d IGNCR:%d ICRNL:%d IUCLC:%d IXON:%d IXANY:%d IXOFF:%d\n",
X				(flag & INLCR ) ? 1 : 0,
X				(flag & IGNCR ) ? 1 : 0,
X				(flag & ICRNL ) ? 1 : 0,
X				(flag & IUCLC ) ? 1 : 0,
X				(flag & IXON  ) ? 1 : 0,
X				(flag & IXANY ) ? 1 : 0,
X				(flag & IXOFF ) ? 1 : 0);
X
X	flag = ttt->c_oflag;
X	ff(se,
X"oflag: %07o OPOST:%d OLCUC:%d ONLCR:%d OCRNL:%d ONOCR:%d ONLRET:%d OFDEL:%d\n",
X				flag,
X				(flag & OPOST ) ? 1 : 0,
X				(flag & OLCUC ) ? 1 : 0,
X				(flag & ONLCR ) ? 1 : 0,
X				(flag & OCRNL ) ? 1 : 0,
X				(flag & ONOCR ) ? 1 : 0,
X				(flag & ONLRET) ? 1 : 0,
X				(flag & OFDEL ) ? 1 : 0);
X
X	flag = ttt->c_cflag;
X	ff(se,"cflag: %07o ",ttt->c_cflag);
X	switch(flag & CBAUD)
X	{
X		case B0:	cptr = "HUP"; break;
X		case B50:	cptr = "50"; break;
X		case B75:	cptr = "75"; break;
X		case B110:	cptr = "110"; break;
X		case B134:	cptr = "134.5"; break;
X		case B150:	cptr = "150"; break;
X		case B200:	cptr = "200"; break;
X		case B300:	cptr = "300"; break;
X		case B600:	cptr = "600"; break;
X		case B1200:	cptr = "1200"; break;
X		case B1800:	cptr = "1800"; break;
X		case B2400:	cptr = "2400"; break;
X		case B4800:	cptr = "4800"; break;
X		case B9600:	cptr = "9600"; break;
X		case EXTA:	cptr = "EXTA(19200?)"; break;
X		case EXTB:	cptr = "EXTB(38400?)"; break;
X		default:	cptr = "????"; break;
X	}
X	dbits = 5 + ((flag & CSIZE) >> 4);
X	parity = (flag & PARENB) ? ((flag & PARODD) ? 'O' : 'E') : 'N';
X	ff(se,"%s-%d-%c-%d ",cptr,dbits,parity,(flag & CSTOPB) ? 2 : 1);
X	switch(flag & CS8)
X	{
X		case CS8: fputs("CS8 ",se); break;
X		case CS7: fputs("CS7 ",se); break;
X		case CS6: fputs("CS6 ",se); break;
X		case CS5: fputs("CS5 ",se); break;
X	}
X	ff(se,"CREAD:%d HUPCL:%d CLOCAL:%d",
X				(flag & CREAD ) ? 1 : 0,
X				(flag & HUPCL ) ? 1 : 0,
X				(flag & CLOCAL) ? 1 : 0);
X#if defined(RTSFLOW)
X	ff(se," RTSFLOW:%d  CTSFLOW:%d",
X				(flag & RTSFLOW ) ? 1 : 0,
X				(flag & CTSFLOW ) ? 1 : 0);
X#endif
X	ff(se,"\n");
X
X	flag = ttt->c_lflag;
X	ff(se,"lflag: %07o ISIG:%d ICANON:%d XCASE:%d ECHO:%d ECHOE:%d\n",
X				flag,
X				(flag & ISIG  ) ? 1 : 0,
X				(flag & ICANON) ? 1 : 0,
X				(flag & XCASE ) ? 1 : 0,
X				(flag & ECHO  ) ? 1 : 0,
X				(flag & ECHOE ) ? 1 : 0);
X	ff(se,"       ECHOK:%d  ECHONL:%d  NOFLSH:%d  XCLUDE:%d\n",
X				(flag & ECHOK ) ? 1 : 0,
X				(flag & ECHONL) ? 1 : 0,
X				(flag & NOFLSH) ? 1 : 0,
X				(flag & XCLUDE) ? 1 : 0);
X
X	ff(se,
X"           INTR QUIT ERAS KILL EOF  EOL  EOL2 SWTCH VMIN==EOF VTIME==EOL\n");
X	ff(se,"ctl chars: ");
X	for(i_cc = 0; i_cc < NCC; i_cc++)
X		ff(se,"%02x   ",ttt->c_cc[i_cc]);
X	ff(se,"  (hex)\n");
X
X}	/* end of display_termio */
X
X/*+-------------------------------------------------------------------------
X	open_dce() - open the dce_name (DCE)
Xplugs global 'fddce' and returns fd of open DCE line
X--------------------------------------------------------------------------*/
Xint
Xopen_dce()
X{
Xint fd1;
Xint fd2;
Xstatic int first_open = 1;	/* true if first time ACU opened */
X
X	/*  open with O_NDELAY set or the open probably will hang */
X	if((fd1 = open(dce_name,O_RDWR | O_NDELAY)) < 0)
X	{
X		ff(se,"%s: Can't open device: %s\n",*gargv,dce_name);
X		myexit(RC_FAIL | RCE_OPEN | DialerExitCode);
X	}
X
X	ioctl(fd1,TCGETA,&dce_termio);
X	dce_termio.c_oflag = 0;
X	dce_termio.c_iflag = 0;
X	dce_termio.c_cflag &= ~(CBAUD | HUPCL);
X	dce_termio.c_cflag |= CLOCAL		|
X		((hangup_flag) ? HUPCL : 0)		|
X		((hangup_flag && DCE_hangup_CBAUD) ? DCE_hangup_CBAUD : hiCBAUD);
X	dce_termio.c_lflag &= ~ECHO;
X	dce_termio.c_cc[VMIN] = 1;
X	dce_termio.c_cc[VTIME] = 0;
X
X	if (Debug >= 10)
X		display_termio(&dce_termio,"setting line termio");
X
X	if(status = ioctl(fd1,TCSETA,&dce_termio))
X	{
X		DEBUG(1,"%s: ioctl error on %s",dce_name);
X		DEBUG(1,"%s",dce_name);
X		DEBUG(1," errno=%d\n",errno);
X		cleanup(RC_FAIL | RCE_IOCTL | DialerExitCode);
X	}
X
X	/* reopen line without O_NDELAY */
X	fd2 = fd1;
X	if((fd1 = open(dce_name,O_RDWR)) < 0)
X	{
X		ff(se,"%s: Can't open device w/o O_NDELAY: %s\n",*gargv,dce_name);
X		myexit(RC_FAIL | RCE_OPEN | DialerExitCode);
X	}
X	close(fd2);
X
X	ioctl(fd1,TCFLSH,2);		/* flush any residue in clists */
X	fddce = fd1;				/* save fd in global */
X	return(fd1);
X
X}	/* end of open_dce */
X
X/*+-------------------------------------------------------------------------
X	main(argc,argv)
X--------------------------------------------------------------------------*/
Xmain(argc,argv)
Xint argc;
Xchar **argv;
X{
Xint itmp;
Xint unrecognized_switches = 0;
Xchar *cptr;
Xextern int optind;
Xextern int opterr;
Xextern char *optarg;
X
X	setbuf(stderr,NULL);
X	setbuf(stdout,NULL);
X
X/* security considerations */
X	uid = getuid();
X	uid_uucp = get_uucp_uid();
X	secure = 0;
X
X	gargv = argv;
X	gargc = argc;
X
X	signal(SIGILL,dial_abort);
X	signal(SIGIOT,dial_abort);
X	signal(SIGEMT,dial_abort);
X	signal(SIGFPE,dial_abort);
X	signal(SIGBUS,dial_abort);
X	signal(SIGSEGV,dial_abort);
X	signal(SIGSYS,dial_abort);
X	signal(SIGTERM,dial_abort);
X	signal(SIGINT,dial_abort);
X
X	opterr = 0;	
X	while((itmp = getopt(argc,argv,"hx:")) != EOF)
X	{
X		switch(itmp)
X		{
X			case 'h':
X				hangup_flag++;
X				break;
X			case 'x':
X				Debug = atoi(optarg);
X				break;
X			case '?':	/* dialer-specific code may want to handle these */
X				unrecognized_switches++;
X				break;
X		}
X	}
X
X/* announce who we are and our arguments if debugging */
X	if(Debug > 1)
X	{
X		ff(se,"\ngeneric dialer %s (%s %s)\n",revision,
X			DCE_name,DCE_revision);
X		if(!uid)
X		{
X			ff(se,"(args ");
X			for(itmp = 0; itmp < argc; itmp++)
X				ff(se,"%s ",argv[itmp]);
X			fputs(")\n",se);
X		}
X		if(Debug >= 8)
X			ff(se,"uid = %d  euid=%d\n",uid,geteuid());
X	}
X
X	chdir("/usr/spool/uucp");	/* in case of core dump */
X
X	/* give DCE-specific code a chance at the entire command line */
X	if(status = DCE_argv_hook(argc,argv,optind,unrecognized_switches))
X	{
X		DEBUG(1,"dialer failed: %s\n",RCE_text(status));
X		exit(status);
X	}
X
X/* check argument count */
X	if(hangup_flag)
X	{
X		if((argc - optind) != 2)
X			status++;
X	}
X	else if((argc - optind) != 3)
X		status++;
X
X/* die with usage if argument error */
X	if(status)
X	{
X		if(hangup_flag)
X			ff(se,"Usage: %s -h devicename speed\n",argv[0]);
X		else
X			ff(se,"Usage: %s devicename number speed\n",argv[0]);
X		myexit(RC_FAIL | RCE_ARGS);
X	}
X
X/* if called with "ttyxx" style ttyname, convert to "/dev/ttyxx" */
X	cptr = argv[optind++];
X	if(!strncmp(cptr,"tty",3))
X	{
X	char s32[32];
X		strcpy(s32,"/dev/");
X		strcat(s32,cptr);
X		dce_name = strdup(s32);
X	}
X	else
X		dce_name = cptr;
X
X/* save phone number */
X	if(!hangup_flag)
X		telno = argv[optind++];
X
X/* get baud rates (validated by DCE-dependent code) */
X	loCBAUD = hiCBAUD = DCE_baud_to_CBAUD(atoi(argv[optind]));
X	if(cptr = strchr(argv[optind],'-'))
X		hiCBAUD = DCE_baud_to_CBAUD(atoi(++cptr));
X
X	(void)open_dce();	/* open the line */
X
X/*   H A N G U P     R E Q U E S T   */
X	if(hangup_flag)
X	{
X		if(call_ungetty('t') != UG_RESTART)
X			cleanup(SUCCESS);
X		DCE_hangup();
X		cleanup((call_ungetty('r')) ? RC_FAIL : SUCCESS );
X	}
X
X/*   D I A L    R E Q U E S T    */
X
X	switch(call_ungetty('a'))
X	{
X		case UG_NOTENAB:	/* line acquired: not enabled */
X			status = SUCCESS;
X			break;
X		case UG_ENAB:		/* line acquired: need ungetty -r when done */
X			status = RC_ENABLED;
X			break;
X		case UG_FAIL:		/* could not acquire line */
X			myexit(RC_FAIL | RCE_INUSE);
X		case 255:
X			myexit(RC_FAIL | RCE_NULL);
X	}
X
X	dialing = 1;
X	if(!(status = DCE_dial(telno)))		/* if dial succeeded ... */
X		myexit(status);				/* ... exit with good news */
X
X	/* dialling did not succeed */
X	myexit(RC_FAIL | status);
X}	/* end of main */
X
X/* end of gendial.c */
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
chmod 0644 gendial.c ||
echo 'restore of gendial.c failed'
Wc_c="`wc -c < 'gendial.c'`"
test 25754 -eq "$Wc_c" ||
	echo 'gendial.c: original size 25754, current size' "$Wc_c"
fi
# ============= dceT2500.c ==============
if test -f 'dceT2500.c' -a X"$1" != X"-c"; then
	echo 'x - skipping dceT2500.c (File already exists)'
else
echo 'x - extracting dceT2500.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'dceT2500.c' &&
X/* #define TRUSTING		/* trust user has -z'd before use */
X#define WHT
X/*+-------------------------------------------------------------------------
X	dceT2500.c - DCE-specific portion of generic SCO UUCP dialer
X	Driver for Telebit T2500
X	wht@n4hgf.Mt-Park.GA.US
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
X
X#include "dialer.h"
X
X/*
X * DCE_DTR_low_msec - milliseconds to hold DTR low to ensure DCE
X *                    sees the transition; this value may be changed
X *                    as necessary before each call to ltoggleDTR(),
X * but, generally, a constant value will do.
X */
Xlong DCE_DTR_low_msec = 500;
X
X/*
X * DCE_DTR_high_msec - milliseconds DTR must remain high before the
X *                     DCE may be expected to be ready to be commanded
X */
Xlong DCE_DTR_high_msec = 500;
X
X/*
X * DCE_write_pase_msec - milliseconds to pause between each character
X *                       sent to the DCE (zero if streaming I/O is
X *                       permitted); this value may be changed as
X * necessary before each call to lwrite(), but, generally, a constant
X * value will do.  Note that this value is used to feed a value to nap(),
X * which has a granularity of .010 seconds on UNIX/386, .020 on XENIX/286
X * and .050 seconds on XENIX/86.
X */
Xlong DCE_write_pace_msec = 0;
X
X/*
X * DCE_name     - short name for DCE
X * DCE_revision - revision number for this module
X */
Xchar *DCE_name = "Telebit T2500";
Xchar *DCE_revision = "x1.01";
X
X/*
X * DCE_hangup_CBAUD - baud rate to use for hanging up DCE
X *                    and readying it for dial in access
X *                    (BXXX mask); use a value of zero if the speed
X *                    specified by the invoker is to be used.
X * This value is useful for DCEs such as the early Hayes 2400
X * which are so unfortunately compatible with their 1200 predecessor
X * that they refuse to answer at 2400 baud unless you last spoke to
X * them at that rate. For such bad boys, use B2400 below.
X */
Xint DCE_hangup_CBAUD = 0;
X/* int DCE_hangup_CBAUD = B2400; */
X
X/*
X * DCE_results - a table of DCE response strings and a token
X *               code for each; when you call lread() or lread_ignore(),
X *               if the read routine detects one of the strings,
X * the appropriate code is returned.  If no string matches, then
X * lread()/lread_ignore examines the DCE result string for a
X * numeric value; if one is found, the numeric value or'd with
X * 0x40000000 is returned (in this way, e.g., you can read "modem
X * S registers").  If nothing agrees with this search, lread()
X * will abort the program with RC|FAIL|RCE_TIMOUT, lread_ignore()
X * will return -1.  You may use any value between 0 and 0x3FFFFFFF.
X * This module is the only consumer  of the codes, although they
X * are decoded by gendial.c's _lread()
X */
X
X/* flag bits */
X#define rfConnect		0x00800000
X#define rfREL			0x00400000
X#define rfFAST			0x00200000
X#define rfV32			0x00100000
X#define rfMASK			0x0000FFFF	/* mask off rfBits */
X
X/* unique codes */
X#define rOk				0
X#define rNoCarrier		1
X#define rError			2
X#define rNoDialTone 	3
X#define rBusy			4
X#define rNoAnswer		5
X#define rRring			6
X#define rConnect300		(  300  | rfConnect)
X#define rConnect1200	( 1200  | rfConnect)
X#define rConnect2400	( 1200  | rfConnect)
X#define rConnect300R	(  300  | rfConnect | rfREL)
X#define rConnect1200R	( 1200  | rfConnect | rfREL)
X#define rConnect2400R	( 2400  | rfConnect | rfREL)
X#define rConnectFASTK	(19200  | rfConnect | rfFAST)	/* may be 9600 */
X#define rConnectFASTX	(19200  | rfConnect | rfFAST)
X#define rConnectFASTU	(19200  | rfConnect | rfFAST)
X#define rConnectFAST	(19200  | rfConnect | rfFAST)
X#define rConnect9600	( 9600  | rfConnect | rfV32)
X
XDCE_RESULT DCE_results[] =
X{
X	{ "OK",						rOk,			},
X	{ "NO CARRIER",				rNoCarrier,		},
X	{ "ERROR",					rError			},
X	{ "NO DIALTONE",			rNoDialTone,	},
X	{ "BUSY",					rBusy			},
X	{ "NO ANSWER",				rNoAnswer		},
X	{ "RRING",					rRring			},
X	{ "CONNECT 300/REL",		rConnect300R	},
X	{ "CONNECT 1200/REL",		rConnect1200R	},
X	{ "CONNECT 2400/REL",		rConnect2400R	},
X	{ "CONNECT 300",			rConnect300		},
X	{ "CONNECT 1200",			rConnect1200	},
X	{ "CONNECT 2400",			rConnect2400	},
X	{ "CONNECT FAST/KERM",		rConnectFASTK	},
X	{ "CONNECT FAST/XMDM",		rConnectFASTX	},
X	{ "CONNECT FAST/UUCP",		rConnectFASTU	},
X	{ "CONNECT FAST",			rConnectFAST	},
X	{ "CONNECT 9600",			rConnect9600	},
X	{ (char *)0,				-1				}		/* end table */
X};
X
X/*+-------------------------------------------------------------------------
X	DCE_baud_to_CBAUD(baud) - check for valid baud rates supported by DCE
X
X  DCE dependent function must validate baud rates supported by DCE
X  returns baud rate in struct termio c_cflag fashion
X  or terminates program with error
X--------------------------------------------------------------------------*/
Xint
XDCE_baud_to_CBAUD(baud)
Xunsigned int baud;
X{
X	switch(baud)
X	{
X		case 110:  return(B110);
X		case 300:  return(B300);
X		case 1200: return(B1200);
X		case 2400: return(B2400);
X		case 9600: return(B9600);
X
X#if defined(B19200)
X		case 19200: return(B19200);
X#else
X#ifdef EXTA
X		case 19200: return(EXTA);
X#endif
X#endif
X
X#if defined(B38400)
X		case 38400: return(B38400);
X#else
X#ifdef EXTB
X		case 38400: return(EXTB);
X#endif
X#endif
X
X	}
X	myexit(RC_FAIL | RCE_SPEED);
X}	/* end of DCE_baud_to_CBAUD */
X
X/*+-------------------------------------------------------------------------
X	sync_Telebit() - sync modem with our DTE speed
X--------------------------------------------------------------------------*/
Xvoid
Xsync_Telebit()
X{
Xregister int maxretry = 8;
Xregister int count;
Xunsigned char rdchar;
X
X	while(maxretry--)
X	{
X		lflush();
X		write(fddce,"a",1);
X		count = 5;
X		while(count)	/* wait 50-200 msec for character, depending on HZ */
X		{
X			if(rdchk(fddce))
X				break;
X			nap(20L);
X			count--;
X		}
X		if(count && (read(fddce,&rdchar,1) == 1) && (rdchar == 'a'))
X			return;
X	}
X
X	DEBUG(1,"Telebit SYNC FAILED\n",0);
X	myexit(RC_FAIL | RCE_TIMOUT);
X
X}	/* end of sync_Telebit */
X
X/*+-------------------------------------------------------------------------
X	init_T2500() - init T2500 from scratch, assuming nothing
X
X	reset to factory defaults, then set
X    E0          no local echo in command mode
X    F1          no local echo in data transfer mode
X    M0          speaker off
X    Q4          generate reult codes, but not RING
X    V1          verbal result codes
X    X3          extended result codes
X    S0=1        answer on first ring
X    S2=255      escape essentially disabled
X    S11=50      50 msec DTMF timing
X    S45=1       enable remote access
X    S48=1       all 8 bits are significant
X    S50=0       use automatic connect speed determination
X    S51=252     set serial port baud rate automatically (no typeahead)
X    S52=2       go on hook when dtr drops and reset to NV-RAM
X    S53=1       DCD signal follows remote carrier, DSR on when modem ready
X    S54=3       pass BREAK signal to remote modem
X    S55=0       respond to command escape sequence
X    S58=2       DTE uses CTS/RTS flow control.
X    S64=1       ignore characters sent by DTE while answering
X    S66=0       don't lock interface speed, just go with the flow.
X    S68=255     DCE uses whatever flow control DTE uses
X    S92=1       PEP tones at the end of answer sequence
X    S95=0       no MNP
X    S110=255    use data compression when the remote modem requests it.
X    S111=255    accept any protocol
X	write to nonvolatile RAM
X--------------------------------------------------------------------------*/
Xvoid
Xinit_T2500()
X{
Xregister itmp;
Xint maxretry = 4;
Xchar *init0 = "AT&FE0F1M0Q4V1X3\r";
Xchar *init1 = "ATS0=1S2=255S11=50S45=1S48=1S50=0S51=252S52=2S53=1S54=3\r";
Xchar *init2 = "ATS55=0S58=2S64=1S66=0S68=255S92=1S95=0S110=255S111=255&W\r";
X
X	DEBUG(7,"INITIALIZING %s\n",dce_name);
X
X	ltoggleDTR(0L);
X
X	sync_Telebit();
X
X	/*
X	 * set to factory default (bless them for this command)
X	 * and a few initial beachhead values
X	 */
X	for(itmp = 0; itmp < maxretry; itmp++)
X	{
X		lwrite("AT&FE0F1M0Q4V1X3\r");
X		if(lread(2) == rOk)
X			break;
X	}
X	if(itmp == maxretry)
X	{
X		DEBUG(1,"INIT FAILED (init0)\n",0);
X		myexit(RC_FAIL | RCE_TIMOUT);
X	}
X
X	/*
X	 * send initialization string 1
X	 */
X	for(itmp = 0; itmp < maxretry; itmp++)
X	{
X		lwrite(init1);
X		if(lread(2) == rOk)
X			break;
X	}
X	if(itmp == maxretry)
X	{
X		DEBUG(1,"INIT FAILED (init1)\n",0);
X		myexit(RC_FAIL | RCE_TIMOUT);
X	}
X
X	/*
X	 * send initialization string 2
X	 */
X	for(itmp = 0; itmp < maxretry; itmp++)
X	{
X		lwrite(init2);
X		if(lread(2) == rOk)
X			break;
X	}
X	if(itmp == maxretry)
X	{
X		DEBUG(1,"INIT FAILED (init2)\n",0);
X		myexit(RC_FAIL | RCE_TIMOUT);
X	}
X
X}	/* end of init_T2500 */
X
X/*+-------------------------------------------------------------------------
X	DCE_hangup() - issue hangup command to DCE
X
XThis function should do whatever is necessary to ensure
X1) any active connection is terminated
X2) the DCE is ready to receive an incoming call if DTR is asserted
X3) the DCE will not accept an incoming call if DTR is false
X
XThe function should return when done.
X
XAny necessary switch setting or other configuration necessary for this
Xfunction to succeed should be documented at the top of the module.
X--------------------------------------------------------------------------*/
Xvoid
XDCE_hangup()
X{
X#ifdef TRUSTING
X	DEBUG(7,"RESETING %s\n",dce_name);
X	ltoggle_DTR(0L);
X	lwrite("ATZ\r");
X	(void)lread_ignore(1);
X#else /* !TRUSTING */
X	init_T2500();
X#endif
X
X}	/* end of DCE_hangup */
X
X/*+-------------------------------------------------------------------------
X	DCE_dial(telno) - dial a remote DCE
X
XThis function should connect to the remote DCE and use any success
Xindication to modify the tty baud rate if necessary before returning.
X
XUpon successful connection, return 0.
X
XUpon unsuccessful connection, return RC_FAIL or'd with an appropriate
XRCE_XXX value from dialer.h.
X
Xlwrite() is used to write to the DCE.
X
Xlread() and lread_ignore() are used to read from the DCE.  Read timeouts
Xfrom calling lread() will result automatically in the proper error
Xtermination of the program.  Read timeouts from calling lread_ignore()
Xreturn -1; you handle the execption here.
X
XAny necessary coding of phone numbers, switch settings or other
Xconfiguration necessary for this function to succeed should be
Xdocumented at the top of the module.
X
XT2500-specific comments:
X S0=0        dont allow connect while dialing
X S54=3       pass BREAK signal to remote modem
X S64=0       abort dialing if characters sent by DTE
X S66=1       lock the interface speed
X S110=0      disable data compression unless requested otherwise
X--------------------------------------------------------------------------*/
Xint
XDCE_dial(telno)
Xchar *telno;
X{
Xchar cmd[128];
Xchar phone[50];
Xint s50_set = 0;
Xint s111_set = 0;
Xint timeout;
Xint result;
Xint rrings = 0;
Xlong then;
Xlong now;
Xchar *cptr;
Xchar *dialout_default = "ATS0=0S7=40S54=3S64=0S66=1S110=0\r";
X#define MDVALID	 "0123456789CcEeFfKkMmNnPpRrSsUuWwXxVv*#,!/()-"
X
X/* preliminary setup */
X	translate("=,-,",telno);
X	if(strspn(telno,MDVALID) != strlen(telno))
X	{
X		DEBUG(1,"phone number has invalid characters\n",0);
X		return(RC_FAIL | RCE_PHNO);
X	}
X	if(decode_phone_number(telno,phone,sizeof(phone)))
X	{
X		DEBUG(1,"phone number too long\n",0);
X		return(RC_FAIL | RCE_PHNO);
X	}
X
X/* walk through dialer codes, doing custom setup */
X	strcpy(cmd,"AT");
X	cptr = cmd + strlen(cmd) - 1;
X	if(dialer_codes['C' - 'A'])
X	{
X		DEBUG(5,"COMPRESSION requested\n",0);
X		strcat(cmd,"S110=1");
X	}
X	if(dialer_codes['E' - 'A'])
X	{
X		DEBUG(5,"ECHO SUPPRESSION requested\n",0);
X		strcat(cmd,"S121=1");
X	}
X	if(dialer_codes['F' - 'A'])
X	{
X		DEBUG(5,"XON/XOFF FLOW CONTROL requested\n",0);
X		strcat(cmd,"S58=3");
X	}
X	if(dialer_codes['K' - 'A'])
X	{
X		DEBUG(5,"KERMIT requested\n",0);
X		strcat(cmd,"S111=10");
X		s111_set++;
X	}
X	if(dialer_codes['X' - 'A'])
X	{
X		DEBUG(5,"XMODEM requested\n",0);
X		strcat(cmd,"S111=20");
X		s111_set++;
X	}
X	if(dialer_codes['U' - 'A'])
X	{
X		DEBUG(5,"UUCP requested\n",0);
X		strcat(cmd,"S111=30");
X		s111_set++;
X	}
X	if(dialer_codes['M' - 'A'])
X	{
X		DEBUG(5,"MNP requested\n",0);
X		strcat(cmd,"S95=1");
X	}
X
X	if(dialer_codes['V' - 'A'])
X	{
X		DEBUG(5,"V.32 requested\n",0);
X		if(hiCBAUD != B9600)
X		{
X			DEBUG(1,"V.32 baud rate not 9600\n",0);
X			return(RC_FAIL | RCE_SPEED);
X		}
X		if((dialer_codes['P' - 'A']) || s111_set)
X		{
X			DEBUG(1,"both PEP and V.32 requested\n",0);
X			return(RC_FAIL | RCE_ARGS);
X		}
X		strcat(cmd,"S50=6");
X	}
X
X	if((dialer_codes['P' - 'A']) || s111_set ||
X		((hiCBAUD >= B9600) && (!dialer_codes['V' - 'A'])))
X	{
X		if(hiCBAUD < B9600)
X		{
X			DEBUG(1,"baud rate not high enough for PEP\n",0);
X			return(RC_FAIL | RCE_SPEED);
X		}
X		if(dialer_codes['P' - 'A'])
X			DEBUG(5,"PEP requested\n",0);
X		else
X			DEBUG(5,"PEP inferred: speed >= 9600 and no V.32 requested\n",0);
X
X		dialer_codes['P' - 'A'] = 1;
X		strcat(cmd,"S50=255");
X	}
X
X#ifndef TRUSTING
X	init_T2500();
X#endif
X
X	DEBUG(6,"--> issuing default setup command\n",0);
X	sync_Telebit();
X	lwrite(dialout_default);
X	if(lread(2) != rOk)
X	{
X		DEBUG(1,"default dialout setup failed\n",0);
X		return(RC_FAIL | RCE_NULL);
X	}
X
X/* issue the custom setup command */
X	if(*cptr)
X	{
X		DEBUG(5,"--> issuing custom setup cmd\n",0);
X		strcat(cmd,"\r");
X		sync_Telebit();
X		lwrite(cmd);
X		if(lread(2) != rOk)
X		{
X			DEBUG(1,"custom modem setup failed\n",0);
X			return(RC_FAIL | RCE_NULL);
X		}
X	}
X
X/*
X * calculate a timeout for the connect
X * allow a minimum of 40 seconds, but if V.32 or PEP, 90
X * also if long distance (North American calculation here)
X * make it 132 (S7 is calculated as timeout * .9)
X */
X	timeout = 40;
X	if((phone[0] == '1') && (phone[0] != '0'))
X		timeout = 132;
X	if((timeout < 90) && (dialer_codes['V' - 'A'] || dialer_codes['P' - 'A']))
X		timeout = 90;
X	for(cptr = phone; cptr = strchr(cptr,','); cptr++)
X		timeout += 2;	/* add extra time for pause characters */
X	DEBUG(6,"timeout waiting for connect = %d seconds\n",timeout);
X
X/* indicate non-root should not see DTE->DCE traffic */
X	secure = 1;
X
X/*
X * build and issue the actual dialing command
X * if root, let him see number, otherwise just say "remote system"
X */
X	DEBUG(1,"--> dialing %s\n", (uid) ? "remote system" : telno);
X#ifdef WHT
X	if(!strncmp(*gargv,"ECU",3))
X		dialer_codes['S' - 'A'] = 1;
X#endif
X	sprintf(cmd,"ATM%dS7=%dDT%s\r",
X		((dialer_codes['S' - 'A']) && !(dialer_codes['N' - 'A'])) ? 1 : 0,
X		(timeout * 9) / 10,
X		phone);
X
X	/* cmd string can only be 80 characters including "AT" */
X	if(strlen(cmd) > 80)
X	{
X		DEBUG(1,"phone number string too long\n",0);
X		cleanup(RC_FAIL | RCE_PHNO);
X	}
X
X	sync_Telebit();
X	lwrite(cmd);
X
X/* indicate non-root can see DTE->DCE traffic */
X	secure = 0;
X
X/* wait for connect */
XWAIT_FOR_CONNECT:
X	time(&then);
X	result = lread(timeout);
X	if(!(result & rfConnect))
X	{
X		switch(result & rfMASK)
X		{
X		case rNoCarrier:
X			return(RC_FAIL | ((rrings > 2) ? RCE_ANSWER : RCE_NOTONE));
X		case rNoDialTone:
X			return(RC_FAIL | RCE_NOTONE);
X		case rBusy:
X			return(RC_FAIL | RCE_BUSY);
X		case rNoAnswer:
X			return(RC_FAIL | RCE_ANSWER);
X		case rRring:
X			if(rrings++ > 7)
X				return(RC_FAIL | RCE_ANSWER);
X			time(&now);
X			if((timeout -= ((int)(then - now))) > 0)
X				goto WAIT_FOR_CONNECT;
X		case rError:
X		default:
X			return(RC_FAIL | RCE_NULL);
X		}
X	}
X
X	return(0);		/* succeeded */
X
X}	/* end of DCE_dial */
X
X/**********************************************************
X*  You probably do not need to modify the code below here *
X**********************************************************/
X
X/*+-------------------------------------------------------------------------
X	DCE_abort(sig) - dial attempt aborted
X
X sig =  0 if non-signal abort (read timeout, most likely)
X     != 0 if non-SIGALRM signal caught
X
X extern int dialing set  1 if dialing request was active,
X                    else 0 if hangup request was active
X
XThis is a chance for the DCE-specific code to do anything it
Xneeds to cl,ean up after a failure.  Note that if a dialing
Xcall fails, it is the responsibility of the higher-level
Xprogram calling the dialer to call it again with a hangup request, so
Xthis function is usually a no-op.
X--------------------------------------------------------------------------*/
Xvoid
XDCE_abort(sig)
Xint sig;
X{
X	DEBUG(10,"DCE_abort(%d);\n",sig);
X}	/* end of DCE_abort */
X
X/*+-------------------------------------------------------------------------
X	DCE_exit(exitcode) - "last chance for gas" in this incarnation
X
XThe independent portion of the dialer program calls this routine in
Xlieu of exit() in every case except one (see DCE_argv_hook() below).
XNormally, this function just passes it's argument to exit(), but
Xany necessary post-processing can be done.  The function must,
Xhowever, eventually call exit(exitcode);
X--------------------------------------------------------------------------*/
Xvoid
XDCE_exit(exitcode)
Xint exitcode;
X{
X	DEBUG(10,"DCE_exit(%d);\n",exitcode);
X	exit(exitcode);
X}	/* end of DCE_exit */
X
X/*+-------------------------------------------------------------------------
X	DCE_argv_hook(argc,argv,optind,unrecognized_switches)
X
XThis hook gives DCE-specific code a chance to look over the entire
Xcommand line, such as for -z Telebit processing.
X
Xargc andf argv are the same values passed to main(),
X
Xoptind is the value of optind at the end of normal getopt processing.
X
Xunrecognized_switches is the count of switches not handled by main().
XSpecifically, -h and -x are standard switches.
X
XNormally, this function should just return RC_FAIL|RCE_ARGS if there are
Xany unrecognized switches, otherwise zero.  If you keep your nose clean
Xthough, you can do anything you need to do here and exit the program.
X
XNote: only simple switches (with no argument) may be used with this
Xfacility if the functrion is to return,' since main()'s getopt() will
Xstop processing switches if it runs into an unrecognized switch with an
Xargument.
X
XIf the function returns a non-zero value, then the value will be passed
XDIRECTLY to exit() with no further ado.  Thus, a non-zero value must be
Xof the format expected by dialer program callers, with RC_FAIL set as a
Xminimum.
X--------------------------------------------------------------------------*/
Xint
XDCE_argv_hook(argc,argv,optind,unrecognized_switches)
Xint argc;
Xchar **argv;
Xint optind;
Xint unrecognized_switches;
X{
X	if(unrecognized_switches)
X		return(RC_FAIL | RCE_ARGS);
X	return(0);
X}	/* end of DCE_argv_hook */
X
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
chmod 0644 dceT2500.c ||
echo 'restore of dceT2500.c failed'
Wc_c="`wc -c < 'dceT2500.c'`"
test 18403 -eq "$Wc_c" ||
	echo 'dceT2500.c: original size 18403, current size' "$Wc_c"
fi
exit 0
 
-----------------------------------------------------------------------
Warren Tucker, March Hare   gatech!n4hgf!wht or wht@n4hgf.Mt-Park.GA.US
"Tell the moon; don't tell the March Hare:  He is here to look around."

jmd@gtenmc.UUCP (jmd) (09/16/90)

In <356@tmiuv0.uucp> rick@tmiuv0.uucp writes:

>In article <699@lafayet.UUCP>, rob@lafayet.UUCP (Rob Freyder) writes:
>> Greetings

>Greetings, Earthling.   8-)
>> 	I am trying to get a bidirectional modem port to work properly under
>> Open Desktop.  I have Telebit T2500 connected to tty1a.  Can someone help
________________________________________________________^
If in fact you are using ``lowercase'' ``a'', then this implies direct
connect -- use instead ``tty1A'' for full modem control.

John Dashner
A happy ODT user

wengland@stephsf.stephsf.com (Bill England) (09/17/90)

In article <699@lafayet.UUCP> rob@lafayet.UUCP (Rob Freyder) writes:
>Greetings
>    I am trying to get a bidirectional modem port to work properly under
>Open Desktop.  I have Telebit T2500 connected to tty1a.  Can someone help
>me with the configuration.  

  Rob ... getting the T2500 to work on SCO software at 19200 is a 
  royal pain.

  I have just had a lengthy e-mail discussion with SCO. 
  In Summary: 

  A>  SCO drivers, even in the Sys V 3.2v2 release, are not supported
      above 9600 baud.  The good news is that the serial drivers in
      the v2 release do support the 16550 chips. ( I don't know if
      that means that they take advantage of that chips buffering 
      features however. )

  B>  Flow control is well ... not completely supported.  

     >"The serial driver only supports RTS/CTS in write mode which can be 
     >a problem if you are using this protocol with the Telebit. Presumably 
     >the workaround is to use xon/xoff instead."

  C>  SCO will not comment on the use of the FAS driver with their
      OS.  If fact they completely ignore all referances to FAS in
      all of my correspondance.

  D>  YOUR SPECIFIC PROBLEM is not related to the above 3 items 
      however :-).  Your problem is that the 19200 baud stuff is
      not even available in any part of the login terminal files
      Specificly gettydefs as released by SCO is *wrong*.  To fix
      this so that others can log into your system you must add
      the following line to your getty defs file: ( The key here
      is using EXTA for the baud rate instead of 19200 which
      as mentioned above is not supported by SCO. )

tbit# EXTA OPOST ONLCR TAB3 BRKINT IGNPAR IXON IXANY PARENB ISTRIP ECHO ECHOE EC
HOK ICANON ISIG CS7 CREAD # EXTA OPOST ONLCR TAB3 BRKINT IGNPAR IXON IXANY PAREN
B ISTRIP ECHO ECHOE ECHOK ICANON ISIG CS7 CREAD #login: #tbit

      I also added an additional line for a 9600 baud TBIT gettydef
      so that at least I have a supported version to test with. 

tbit_s# B9600 OPOST ONLCR TAB3 BRKINT IGNPAR IXON IXANY PARENB ISTRIP ECHO ECHOE
 ECHOK ICANON ISIG CS7 CREAD # B9600 OPOST ONLCR TAB3 BRKINT IGNPAR IXON IXANY P
ARENB ISTRIP ECHO ECHOE ECHOK ICANON ISIG CS7 CREAD #login: #tbit_s

-------

   The following configuration will lock the tbit at 9600 baud.  To use
   19200 substitute tbit for tbit_s in the inittab file and change
   the tbit registers so that the tbit is locked at 19200 instead of
   9600.

--- tbit T2500 configuration ---

   Note: when configuring the tbit you should have the serial port 
   disabled from dialin calls  because the Dialer file can cause 
   a different setup for the modem when waiting for dialin.

E0 F1 M1 Q1 T V1 W0 X3 Y0 &P0 &T4     Version GE6.01-T2500 
S00=001 S01=000 S02=043 S03=013 S04=010 S05=008 S06=002 S07:050 S08=002 S09=006 S10=007 S11=070 S12=050 S18=000 S25=005 S26=000 S38=000
S41:002 S45=000 S47=004 S48:001 S49=000
S50=000 S51:004 S52:002 S54:003 S55=000 S56=017 S57=019 S58=003 S59=000
S61:045 S62=003 S63=001 S64=000 S65=000 S66:001 S67=000 S68=255 S69=000
S90=000 S91=000 S92:001 S93=008 S94=001 S95:001 S96=001 S97=000 S98=003
S100=000 S101=000 S102=000 S104=000 S105=001 S106=000 S107=020
S110:001 S111:030 S112=001
S121:001 S130=002 S131:001
S150=000 S151=004 S152=001 S153=001 S154=000 S155=000
S160=010 S161=020 S162=002 S163=003 S164=007 S255=000

To program:

ATS07=050
S41=002
S48=001
S51=004
S52=002
S54=003
S61=045
S66=001
S92=001
S95=001
S110=001
S111=030
S121=001

  Stop !!

S131=1

Programming S131=1 is not as easy as it appears.  Save the config before
prgramming S131=1. Change S52=1 and save the config, this prevents the 
config from being overwritten when cu disconnects.  Set S131=1 cu
will hang up, go back into cu change S52=2&w and you should be set.

Wheeh !!

ATE0Q1T

For 19200 operation change S51 to 5.

You will have a problem when communicating at 19200. All traffic will
stop suddenly and resume two to three seconds later. Sigh, this is,
I am afraid, related to the flow control problem mentioned above. A
possible solution may be to run the FAS driver even if you do not
have a 16550 installed. I have not yet tried this out.

-----uucp/Devices----
tb_f tty1A -   9600 tbfast \D
tb_s tty1A -   9600 tbslow \D
Direct tty1A - 9600 direct

#tb_f tty1A -   19200 tbfast \D
#tb_s tty1A -   19200 tbslow \D
#Direct tty1A - 19200 direct

#Comment out the 9600 baud entries and uncomment the 19200 baud
#entries for 19200 operation

------uucp/Dialers------
# Telebit
tbfast =,-, "" A\pA\pA\pA\pA\pT\pE1Q0S0=0X3Q0\r\c OK-AT-OK A\pT\pS95=0S50=255DT\
T\r\c CONNECT\sFAST-\r-ogin:
&tbfast =,-, "" ATZ\r\c

#
# Slow telebit connection
#
tbslow =,-,    "" A\pA\pA\pA\pA\pT\pE1Q0S0=0X3Q0\r\c OK-AT-OK A\pT\pS95=0DT\T\r\
c CONNECT \d@
&tbslow =,-, "" ATZ\r\c

#
# Note here that PEP works even when the T2500's are locked to the
# system at 9600 baud. No changes need to be made to the Dialers
# file when changing TBIT baud rates.

-------uucp/Systems------
uunet Any tb_f 9600-19200 18008776550  ogin:-BREAK-ogin:-BREAK-ogin: yyyyyyy ssword: xxxxxx 

-------etc/inittab-------
Se1A:23:respawn:/usr/lib/uucp/uugetty  -r -t 60 tty1A tbit_s
Se1a:23:off:/etc/getty tty1a m
Se2A:23:off:/usr/lib/uucp/uugetty -r -t 60 tty2A 19200

# Subsitute tbit above for tbit_s when locking the T2500 in 
# 19200 mode.
--------------------

  Good Luck !!
  And dont forget to re-enable the serial port.


 +--------
 |  Bill England
 |  wengland@stephsf.COM
 |
  * *      H -> He +24Mev
 * * * ... Oooo, we're having so much fun making itty bitty suns *
  * *