[mod.sources] v06i087: System V generic dial routines

sources-request@mirror.UUCP (08/04/86)

Submitted by: ihnp4!quest!gene
Mod.sources: Volume 6, Issue 87
Archive-name: sysVdial/Part2

[  I did not try to compile this, as we run BSD exlusively.  It appears
   that the hardest part of doing the port will be emulating the timed-
   out reads (c_cc[VTIME]) in dial.c  --r$  ]

#	Generic Modem Dialer subroutine and support programs for system V.
#	
#	Modem configuration is done in the user configured file
#	dialinfo.  Should be able to dial any modem (eg Vadic, Hayes)
#	with a built-in auto dialer.   Replaces ATT dial(3C).
#	Works with CU, uucico, lp, etc.
#	
#	This is part 2 of 3.
#	
#	The parts are:
#	
#	1)	README file and all documentation.
#	2)	Makefile, dialinfo, *.h, some *.c files
#	3)	dial.c
#	
#--------CUT---------CUT---------CUT---------CUT--------#
#########################################################
#                                                       #
# This is a shell archive file.  To extract files:      #
#                                                       #
#    1)	Create an empty directory for the files.        #
#    2) Write a file, such as "file.shar", containing   #
#       this archive file into the directory.           #
#    3) Type "sh file.shar".  Do not use csh.           #
#                                                       #
#########################################################
echo Creating: Makefile
sed -e 's/^#//' >Makefile <<'end_Makefile'
##	Copyright 1986, Gene H. Olson, Quest Research, Burnsville MN.
##	Permission to copy and distribute for any purpose,
##	so long as this notice is preserved.
#
#CFLAGS =
#
#PROGS = dialer dialprint
#
#N = @nroff -man
#
#all: $(PROGS)
#
#doc:
#	$N dialer.1
#	$N dialprint.1
#	$N dial.3
#	$N dialinfo.4
#
#dialprint: libdial.a dialprint.o
#	cc dialprint.o libdial.a -o dialprint
#
#dialer: libdial.a dialer.o
#	cc dialer.o libdial.a -o dialer
#
#libdial.a: readinfo.o dialinfo.o dial.o
#	rm -f libdial.a
#	ar cr libdial.a dial.o dialinfo.o readinfo.o
#
#readinfo.o: readinfo.h
#dialinfo.o: readinfo.h dialinfo.h
#dial.o: dialinfo.h readinfo.h dial.h
#dialprint.o: dialinfo.h dial.h
#dialer.o: dial.h
#
#lint:
#	lint readinfo.c dialinfo.c dialprint.c
#	lint readinfo.c dialinfo.c dial.c dialer.c
#
#install: $(PROGS)
#	cp dialinfo /usr/lib/uucp
#	cp $(PROGS) /usr/lbin
#	: cp dial.h /usr/include
#	: cp libdial.a /usr/lib/libdial.a
#	: ar r /lib/libc.a dial.o dialinfo.o readinfo.o
#
#clean:
#	rm -f $(PROGS) libdial.a *.o
end_Makefile
echo Creating: dialinfo
sed -e 's/^#//' >dialinfo <<'end_dialinfo'
###############################################################
##       Dialinfo - Dialer procedure definitions              #
##                                                            #
##    See dialer.1 dialprint.1 dial.2 dialinfo.7 for          #
##    more information.   And good luck.                      #
##                                                            #
##                                Gene H. Olson (author)      #
###############################################################
#
##	Hayes modem dialer.
#
#hayes,
#	star=*, pound=#, flash=H0\,H1,
#	delay=\,, wait=\,, retry=20,
#	s0=P1 M"AT Q0\r" [OK]1 [in:]4 [IN:]4 [rd:]4 [RD:]4 S10 T3,
#	s1=E"dialing %1 %2 %3 %4 %{DIALDEBUG}" M"AT DT%N\r" [CONNECT]10 [NO CARRIER]2 S60 T3,
#	s2=E"no answer ..." D1 R3 G0,
#	s3=E"no modem response ..." D1 R10 G0,
#	s4=E"hung up unix system ..." D1 R5 G0,
#	s6=\$hello \${hello},
#	s10=C1 G+,
#
#
##	Hayes entry to call another UNIX system.
#
#uhayes,
#	s10=E"looking for login ..." C1 [login:]40 [ssword:]11 H31 S2  T11,
#	s11=R1 M"^M"  [login:]40 [ssword:]11 H31 S5  T12,
#	s12=M"^M"     [login:]40 [ssword:]11 H31 S5  T13,
#	s13=M"^D^D^D" [login:]40 [ssword:]11 H31 S10 T14,
#	s14=B         [login:]40 [ssword:]11 H31 S10 T15,
#	s15=M"^M"     [login:]40 [ssword:]11 H31 S5  T16,
#	s16=B         [login:]40 [ssword:]11 H31 S10 T17,
#	s17=M"^M"     [login:]40 [ssword:]11 H31 S5  T18,
#	s18=B         [login:]40 [ssword:]11 H31 S10 T19,
#	s19=M"^M"     [login:]40 [ssword:]11 H31 S5  T20,
#	s20=B         [login:]40 [ssword:]11 H31 S10 T21,
#	s21=M"^M"     [login:]40 [ssword:]11 H31 S5  T30,
#
#	s30=E"No response from remote ..." R10 G0,
#	s31=E"Remote system hung up ..." R3 G0,
#
#	s40=M"^M"     G+,
#	use=hayes,
#
##	Vadic 3451
#
#vadic|va3451,
#	delay=K, wait=KK, retry=5,
#	s0=G1,
#	s1=M"^E^M" [Y\n*] S4 T10,
#	s2=M"D^M" [NUMBER]3 [ERROR]11 [*]11 T0,
#	s3=M"%P^M" [%N]4 [ERROR]11 [*]11 T0,
#	s4=M"^M" [ING:],
#	s5=[CONNECT]+ [NO CARRIER]12 T30,
#	s10=E"No response from dialer" R2 G0,
#	s11=E"Comm error with dialer" R2 G0,
#	s12=E"Connect failed" R1 G0,
#	use=prometheus,
end_dialinfo
echo Creating: dial.h
sed -e 's/^#//' >dial.h <<'end_dial.h'
#/****************************************************************
# *	Copyright 1986, Gene H. Olson, Quest Research, Burnsville   *
# *	Minnesota.   Permission to copy and distribute this         *
# *	program, all associated code in source and binary form,     *
# *	for any purpose, so long as this notice is preserved.       *
# ****************************************************************/
#
#/*	Dial(3C) return codes */
#
##define	INTRPT   (-1)   /* Interrupt during dial */
##define	D_HUNG   (-2)   /* Dialer hung */
##define	NO_ANS   (-3)   /* Busy or no answer */
##define	ILL_BD   (-4)   /* Illegal/unknown baud rate */
##define	A_PROB   (-5)   /* Dialinfo(4) configuration error */
##define	L_PROB   (-6)   /* TTY device error */
##define	NO_Ldv   (-7)   /* L-devices file unreadable */
##define	DV_NT_A  (-8)   /* Requested device not available */
##define	DV_NT_K  (-9)   /* Requested device unknown */
##define	NO_BD_A  (-10)  /* Nothing available at requested speed */
##define	NO_BD_K  (-11)  /* No device known at requested speed */
#
#/*	Dial(3C) Call structure */
#
#typedef struct {
#	struct termio  *attr;     /* Final terminal attributes */
#	int            baud;      /* Baud rate to use after dialing */
#	int            speed;     /* Baud rate to use during dialing */
#	char           *line;     /* TTY device name */
#	char           *telno;    /* Phone number(s) or system name */
#	int            modem;     /* Modem control for direct lines */
#	char           *device;   /* ACU or dialer name */
#	int            dev_len;   /* Length of device name (not used) */
#} CALL;
#
#/*	External definitions */
#
#extern int nolock ;	/* Don't use the lock file */
#
#extern int dial() ;
#extern void undial() ;
#extern void dialmsg() ;
end_dial.h
echo Creating: dialinfo.h
sed -e 's/^#//' >dialinfo.h <<'end_dialinfo.h'
#/****************************************************************
# *	Copyright 1986, Gene H. Olson, Quest Research, Burnsville   *
# *	Minnesota.   Permission to copy and distribute this         *
# *	program, all associated code in source and binary form,     *
# *	for any purpose, so long as this notice is preserved.       *
# ****************************************************************/
#
#/*********************************************************************
# *           DIALINFO  dialer description header file.               *
# *********************************************************************/
#
#
##define NSTATE	100				/* Max number of keyboard states */
#
#/*
# *	Dialer Information (dialinfo) structure to define
# *	characteristics of a dialer.
# */
#
#typedef struct dialinfo {
#	char	*di_star ;				/* "*" button push string */
#	char	*di_pound ;				/* "#"	button push string */
#	char	*di_delay ;				/* "-"  delay 4 sec */
#	char	*di_wait ;				/* "="	wait for dial tone */
#	char	*di_flash ;				/* "f"	flash off hook 1 sec */
#	short	di_retry ;				/* Retry count */
#	char	*di_state[NSTATE];		/* State list */
#	} DINFO ;
#
#extern void dialfree() ;
end_dialinfo.h
echo Creating: readinfo.h
sed -e 's/^#//' >readinfo.h <<'end_readinfo.h'
#/****************************************************************
# *	Copyright 1986, Gene H. Olson, Quest Research, Burnsville   *
# *	Minnesota.   Permission to copy and distribute this         *
# *	program, all associated code in source and binary form,     *
# *	for any purpose, so long as this notice is preserved.       *
# ****************************************************************/
#
#/***********************************************************
# *     Header file for common info file string/keyword     *
# *     unpacking routines.                                 *
# ***********************************************************/
#
#
##define IKEYSIZE	10				/* Max keyword length */
##define ITEXTSIZE	100				/* Max key value length */
end_readinfo.h
echo Creating: readinfo.c
sed -e 's/^#//' >readinfo.c <<'end_readinfo.c'
#/****************************************************************
# *	Copyright 1986, Gene H. Olson, Quest Research, Burnsville   *
# *	Minnesota.   Permission to copy and distribute this         *
# *	program, all associated code in source and binary form,     *
# *	for any purpose, so long as this notice is preserved.       *
# ****************************************************************/
#
#
#/***************************************************************
# *        Procedures to read "info" files in the style         *
# *        of "terminfo" or "dialinfo".                         *
# ***************************************************************/
#
#
##include <stdio.h>
##include <ctype.h>
#
##include "readinfo.h"
#
##define loop for(;;)
#
#extern char *strcpy() ;
#extern char *getenv() ;
#
#/******
# *	findinfo - Find entry in info file.
# *
# *	Returns: 0=found, -1=not found.
# */
#
#static int
#findinfo(file, entry)
#register FILE *file ;				/* Open file to search in */
#register char *entry ;				/* Entry to search for */
#{
#	register short ch ;
#	register char *cp ;
#
#	/*
#	 *	Always start from the beginning
#	 *	of the file.
#	 */
#
#	(void) fseek(file, 0L, 0) ;
#
#	/*
#	 *	Loop through lines in the file.
#	 */
#
#	loop {
#
#		/*
#		 *	If the first character of the line is
#		 *	alphanumeric,  scan the line for strings
#		 *	separated by "|" characters which exactly
#		 *	match the entry name.
#		 */
#
#		ch = getc(file) ;
#		if (isalnum(ch) || ch == '/') {
#			loop {
#
#				/*
#				 *	Scan for a match terminated by '|' or ','.
#				 *	If found, succeed with the file pointer
#				 *	positioned to the first field entry.
#				 */
#
#				cp = entry ;
#				while (ch == *cp) {
#					ch = getc(file) ;
#					cp++ ;
#					}
#
#    			if (*cp == 0 && (ch == '|' || ch == ',')) {
#					loop {
#						if (ch == ',') return(0) ;
#						if (ch == '\n') break ;
#						if (ch == EOF) return(-1) ;
#						ch = getc(file) ;
#						}
#					}
#
#				/*
#				 *	If no match found, position past any "|"
#				 *	character found and try again.  Otherwise
#				 *	the entry is not on this line.
#				 */
#
#				loop {
#					if (ch == '|' || ch == ',' || ch == '\n') break ;
#					ch = getc(file) ;
#					if (ch == EOF) return(-1) ;
#					}
#
#				if (ch != '|') break ;
#
#				ch = getc(file) ;
#				}
#			}
#
#		/*
#		 *	Skip to end-of-line.
#		 */
#
#		loop {
#			if (ch == EOF) return(-1) ;
#			if (ch == '\n') break ;
#			ch = getc(file) ;
#			}
#		}
#	}
#
#
#
#/******
# *	getnext - Get next character from descriptor file, or
# *	          embedded environment variable.
# */
#
#int
#getnext(file, cpp)
#register FILE *file ;		/* File to read char from */
#register char **cpp ;		/* Macro string/state pointer */
#{
#	register int ch ;
#	register int i ;
#	char name[21] ;
#	static char defaddr ;
#
#	/*
#	 *	Loop until we find a character to return.
#	 */
#
#	loop {
#
#		/*
#		 *	If reading a default string from the file,
#		 *	read until a unescaped "}" character is seen.
#		 */
#
#		if (*cpp == &defaddr) {
#			ch = getc(file) ;
#			if (ch == '}') *cpp = 0 ;
#			else if (ch == '\\') {
#				ch = getc(file) ;
#				if (ch == '}') return(ch) ;
#				(void) ungetc(ch, file) ;
#				return('\\') ;
#				}
#			else return(ch) ;
#			}
#
#		/*
#		 *	If in a macro string, get the next character.
#		 */
#
#		else if (*cpp) {
#			if (**cpp == 0) *cpp = 0 ;
#			else {
#				ch = *(*cpp)++ ;
#				return(ch) ;
#				}
#			}
#
#		/*
#		 *	Otherwise, just get the next character from
#		 *	the file.   Unless of course it is an unescaped
#		 *	"${" sequence which begins an environment variable
#		 *	specification.
#		 */
#
#		else {
#			ch = getc(file) ;
#
#			if (ch == '\\') {
#				ch = getc(file) ;
#				if (ch != '$') {
#					(void) ungetc(ch, file) ;
#					return('\\') ;
#					}
#				return('$') ;
#				}
#
#			if (ch != '$') return(ch) ;
#
#			ch = getc(file) ;
#			if (ch != '{') {
#				(void) ungetc(ch, file) ;
#				return('$') ;
#				}
#
#			/*
#			 *	We saw an unescaped "${".  Get the environment
#			 *	variable name and look it up.
#			 *
#			 *	If the variable is found, set *cpp to return
#			 *	its value, and skip over any default string seen.
#			 *
#			 *	If not found, and a default string is given, set
#			 *	*cpp so the default string will be read from the
#			 *	file.
#			 */
#
#			i = 0 ;
#			loop {
#				ch = getc(file) ;
#				if (ch == EOF) return(EOF) ;
#				if (ch == '-' || ch == '}') break ;
#				if (i < sizeof(name)-1) name[i++] = ch ;
#				}
#			name[i] = 0 ;
#
#			*cpp = getenv(name) ;
#
#			if (ch == '-') {
#				if (*cpp) {
#					loop {
#						ch = getc(file) ;
#						if (ch == EOF) return(EOF) ;
#						if (ch == '}') break ;
#						if (ch == '\\') {
#							ch = getc(file) ;
#							if (ch == EOF) return(EOF) ;
#							}
#						}
#					}
#				else *cpp = &defaddr ;
#				}
#			}
#		}
#	}
#
#
#
#/******
# *	getinfo - Get next key=text entry in info description.
# *
# *	Returns:	1=found, 0=end of entry, -1=error.
# */
#
#static int
#getinfo(file, cpp, key, text)
#FILE *file ;					/* Info file pointer */
#char **cpp ;					/* Macro char pointer */
#char *key ;						/* Returned key string */
#char *text ;					/* Returned text string */
#{
#	register short ch ;
#	register char *cp ;
#	register short count ;
#
#	/*
#	 *	Scan for the next keyword.
#	 */
#
#	ch = getnext(file, cpp) ;
#	loop {
#		if (ch == EOF) return(0) ;
#
#		if (isalpha(ch)) break ;
#
#		if (ch == '\n') {
#			ch = getnext(file, cpp) ;
#			if (isalpha(ch)) return(0) ;
#			}
#
#		else if (ch == '#') {
#			loop {
#				ch = getnext(file, cpp) ;
#				if (ch == EOF) return(-1) ;
#				if (ch == '\n') break ;
#				}
#			}
#
#		else if (ch == ' ' || ch == '\t' || ch == ',')
#			ch = getnext(file, cpp) ;
#
#		else return(-1) ;
#		}
#
#	/*
#	 *	Pick up keyword.
#	 */
#
#	count = 0 ;
#	cp = key ;
#
#	while (isalnum(ch)) {
#		if (++count > IKEYSIZE) return(-1) ;
#		*cp++ = ch ;
#		ch = getnext(file, cpp) ;
#		}
#
#	*cp = 0 ;
#
#	if (ch != '=') return(-1) ;
#
#	/*
#	 *	Pick up associated string text.
#	 */
#
#	count = 0 ;
#	cp = text ;
#
#	loop {
#		ch = getnext(file, cpp) ;
#		if (ch == ',') break ;
#
#		if (ch == EOF) return(-1) ;
#
#		if (ch == '\\') {
#			ch = getnext(file, cpp) ;
#			if (ch == EOF) return(-1) ;
#			if (ch != ',') {
#				*cp++ = '\\' ;
#				count++ ;
#				}
#			}
#
#		if (++count > ITEXTSIZE) return(-1) ;
#
#		*cp++ = ch ;
#		}
#
#	*cp = 0 ;
#
#	return(1) ;
#	}
#
#
#
#/******
# *	readinfo - Read info file for data.
# */
#
#int
#readinfo(fname, entry, build, info)
#char *fname ;					/* Info File name to read */
#char *entry ;					/* Info entry name to return */
#int (*build)() ;				/* Build entry procedure */
#char *info ;					/* Info pointer */
#{
#	register FILE *file ;
#	register int i ;
#	register int usecount ;
#
#	char *cp ;
#	char key[IKEYSIZE+1] ;
#	char text[ITEXTSIZE+1] ;
#	char use[ITEXTSIZE+1] ;
#
#	/*
#	 *	Open info file.
#	 */
#
#	file = fopen(fname,"r") ;
#	if (file == 0) {
#		(void) fprintf(stderr, "Cannot open: %s\n", fname) ;
#		return(-1) ;
#		}
#	
#	/*
#	 *	Loop to read all info entries in "use" list.
#	 */
#
#	usecount = 20 ;
#	loop {
#
#		/*
#		 *	Find entry name in file.
#		 */
#
#		if (findinfo(file, entry) < 0) {
#			(void) fprintf(stderr, "File %s, no entry found: %s\n",
#				fname, entry) ;
#			(void) fclose(file) ;
#			return(-1) ;
#			}
#
##ifdef DEBUG
#		(void) fprintf(stderr,"Found entry: %s\n",entry) ;
##endif
#
#		/*
#		 *	Unpack and process all entries.
#		 */
#
#		cp = 0 ;
#		loop {
#			i = getinfo(file,&cp,key,text) ;
#			if (i == 0) {
#				(void) fclose(file) ;
#				return(0) ;
#				}
#
#			if (i < 0) {
#				(void) fprintf(stderr, "File %s, corrupted entry: %s\n",
#					fname, entry) ;
#				(void) fclose(file) ;
#				return(-1) ;
#				}
#
##ifdef DEBUG
#			(void) fprintf(stderr,"Got %s=%s\n",key,text) ;
##endif
#
#			/*
#			 *	Follow "use" list chain to next entry.
#			 */
#
#			if (strcmp(key, "use") == 0) {
#				(void) strcpy(use, text) ;
#				entry = use ;
#				if (--usecount > 0) break ;
#				(void) fclose(file) ;
#				return(-1) ;
#				}
#
#			/*
#			 *	Add data to info entry.
#			 */
#
#			if ((*build)(info, key, text) < 0) {
#				(void) fprintf(stderr,
#					"Error in file %s, entry %s, %s=%s\n",
#					fname, entry, key, text) ;
#				(void) fclose(file) ;
#				return(-1) ;
#				}
#			}
#		}
#	}
end_readinfo.c
echo Creating: dialinfo.c
sed -e 's/^#//' >dialinfo.c <<'end_dialinfo.c'
#/****************************************************************
# *	Copyright 1986, Gene H. Olson, Quest Research, Burnsville   *
# *	Minnesota.   Permission to copy and distribute this         *
# *	program, all associated code in source and binary form,     *
# *	for any purpose, so long as this notice is preserved.       *
# ****************************************************************/
#
#
#/**************************************************************
# *          Procedures to read and decode dialinfo            *
# *                   dialer entries.                          *
# **************************************************************/
#
##include <stdio.h>
##include <ctype.h>
#
##include "readinfo.h"
##include "dialinfo.h"
#
##define loop for (;;)
#
#extern void free() ;
#extern char *malloc() ;
#extern char *strcpy() ;
#extern char *getenv() ;
#
#
#/******
# *	stralloc - Allocate string.
# */
#
#static char *
#stralloc(str)
#char *str ;							/* String to copy */
#{
#	register char *p ;
#
#	p = malloc((unsigned) (strlen(str)+1)) ;
#	if (p != 0) (void) strcpy(p, str) ;
#	return(p) ;
#	}
#
#
#
#/*****
# *	parseshort - Parse out short.
# *
# *	Returns: advanced ptr=okay, 0=error.
# */
#
#char *
#parseshort(cp, num, low, high)
#register char *cp ;					/* Start character */
#short *num ;						/* Short to fetch */
#short low ;							/* Lowest legal value */
#short high ;						/* Highest legal value */
#{
#	register short n ;
#
#	if (!isdigit(*cp)) return(0) ;
#
#	n = 0 ;
#
#	do {
#		n = 10 * n + *cp++ - '0' ;
#		} while (isdigit(*cp)) ;
#
#	if (n < low || n > high) return(0) ;
#
#	*num = n ;
#	return(cp) ;
#	}
#
#
#
#/*******
# *	buildinfo - Build information entry for key=text string.
# *
# *	Returns: 0=info built, -1=error.
# */
#
#static int
#buildinfo(dinfo,key,text)
#char *dinfo ;						/* Dialer info structure */
#char *key ;							/* Keyword name */
#char *text ;						/* Associated text */
#{
#	register DINFO *di ;
#	register char *cp ;
#	register char **cpp ;
#	short state ;
#
#	di = (DINFO *) dinfo ;
#
#	/*
#	 *	Build phone number character replacement strings.
#	 */
#
#	if (strcmp(key,"star") == 0) {
#		if (di->di_star == 0) di->di_star = stralloc(text) ;
#		}
#
#	else if (strcmp(key,"pound") == 0) {
#		if (di->di_pound == 0) di->di_pound = stralloc(text) ;
#		}
#
#	else if (strcmp(key,"delay") == 0) {
#		if (di->di_delay == 0) di->di_delay = stralloc(text) ;
#		}
#
#	else if (strcmp(key, "wait") == 0) {
#		if (di->di_wait == 0) di->di_wait = stralloc(text) ;
#		}
#
#	else if (strcmp(key,"flash") == 0) {
#		if (di->di_flash == 0) di->di_flash = stralloc(text) ;
#		}
#
#	/*
#	 *	Build "retry" count.
#	 */
#
#	else if (strcmp(key, "retry") == 0) {
#		if (di->di_retry < 0) {
#			cp = parseshort(text, &di->di_retry, 0, 1000) ;
#			if (cp == 0 || *cp != 0) return(-1) ;
#			}
#		}
#
#	/*
#	 *	Build dial defintions.
#	 */
#
#	else if
#		(	key[0] == 's'
#		&&	(cp = parseshort(key+1, &state, 0, NSTATE-1))
#		&&	*cp == 0
#		)
#	{
#		cpp = &di->di_state[state] ;
#		if (*cpp == 0) *cpp = stralloc(text) ;
#		}
#
#	else return(-1) ;
#
#	return(0) ;
#	}
#
#
#
#/******
# *	dialinfo - Get dial information for entry "dialer".
# */
#
#int
#dialinfo(dinfo, dialer)
#DINFO *dinfo ;						/* Retrieved dialer info */
#char *dialer ;						/* Dialer name */
#{
#	register int i ;
#	register char *fname ;
#
#	/*
#	 *	Initialize dialinfo entry.
#	 */
#
#	dinfo->di_star = 0 ;
#	dinfo->di_pound = 0 ;
#	dinfo->di_delay = 0 ;
#	dinfo->di_wait = 0 ;
#	dinfo->di_flash = 0 ;
#	dinfo->di_retry = -1 ;
#	for (i = 0 ; i < NSTATE ; i++) dinfo->di_state[i] = 0 ;
#
#	/*
#	 *	Get dialinfo file name from environment if specified.
#	 */
#
#	fname = getenv("DIALINFO") ;
#	if (fname == 0 || *fname == 0) fname = "/usr/lib/uucp/dialinfo" ;
#
#	/*
#	 *	Read the file and return status.
#	 */
#
#	return( readinfo(fname, dialer, buildinfo, (char *)dinfo) ) ;
#	}
#
#
#/******
# *	dialfree - Free storage associated with dialinfo entry.
# */
#
#void
#dialfree(di)
#register DINFO *di ;			/* Dialinfo entry */
#{
#	register int i ;
#	register char **spp ;
#
#	if (di->di_delay) free(di->di_delay) ;
#	if (di->di_wait) free(di->di_wait) ;
#	if (di->di_star) free(di->di_star) ;
#	if (di->di_pound) free(di->di_pound) ;
#	if (di->di_flash) free(di->di_flash) ;
#
#	i = 0 ;
#	spp = &di->di_state[0] ;
#
#	while (i < NSTATE) {
#		if (*spp) free(*spp) ;
#		i++ ;
#		spp++ ;
#		}
#	}
end_dialinfo.c
echo Creating: dialprint.c
sed -e 's/^#//' >dialprint.c <<'end_dialprint.c'
#/****************************************************************
# *	Copyright 1986, Gene H. Olson, Quest Research, Burnsville   *
# *	Minnesota.   Permission to copy and distribute this         *
# *	program, all associated code in source and binary form,     *
# *	for any purpose, so long as this notice is preserved.       *
# ****************************************************************/
#
#/***************************************************************
# *         Program to print out DIALINFO entries               *
# ***************************************************************/
#
##include <stdio.h>
#
##include "readinfo.h"
##include "dialinfo.h"
#
#
#/******
# *	dialprint - Print dialer info.
# */
#
#dialprint(dinfo, dialer)
#register DINFO *dinfo ;					/* Entry to print */
#char *dialer ;							/* Dialer name */
#{
#	register char **cpp ;
#	register int i ;
#	
#	(void) printf("%s,\n", dialer) ;
#
#	if (dinfo->di_star) (void) printf("\tstar=%s,\n", dinfo->di_star) ;
#
#	if (dinfo->di_pound) (void) printf("\tpound=%s,\n", dinfo->di_pound) ;
#
#	if (dinfo->di_delay) (void) printf("\tdelay=%s,\n", dinfo->di_delay) ;
#
#	if (dinfo->di_wait) (void) printf("\twait=%s,\n", dinfo->di_wait) ;
#
#	if (dinfo->di_flash) (void) printf("\tflash=%s,\n", dinfo->di_flash) ;
#
#	if (dinfo->di_retry >= 0) (void) printf("\tretry=%d,\n", dinfo->di_retry) ;
#
#	i = 0 ;
#	cpp = &dinfo->di_state[0] ;
#
#	while (i < NSTATE) {
#		if (*cpp) (void) printf("\ts%d=%s,\n", i, *cpp) ;
#		i++ ;
#		cpp++ ;
#		}
#	}
#
#
#
#main(argc,argv)
#int argc ;							/* Argument count */
#char **argv ;						/* Argument vector */
#{
#	DINFO dinfo ;
#
#	if (argc != 2) {
#		(void) fprintf(stderr, "Bad arg count\n") ;
#		return(2) ;
#		}
#
#	(void) dialinfo(&dinfo, argv[1]) ;
#
#	dialprint(&dinfo, argv[1]) ;
#
#	dialfree(&dinfo) ;
#
#	return(0) ;
#	}
end_dialprint.c
echo Creating: dialer.c
sed -e 's/^#//' >dialer.c <<'end_dialer.c'
#/****************************************************************
# *	Copyright 1986, Gene H. Olson, Quest Research, Burnsville   *
# *	Minnesota.   Permission to copy and distribute this         *
# *	program, all associated code in source and binary form,     *
# *	for any purpose, so long as this notice is preserved.       *
# ****************************************************************/
#
##include <stdio.h>
##include <signal.h>
##include <termio.h>
#
##include "dial.h"
#
#extern int nolock ;					/* See dial(3C) */
#extern int optind ;					/* See getopt(3) */
#extern char *optarg ;				/* See getopt(3) */
#
#extern unsigned sleep() ;
#extern void perror() ;
#extern void exit() ;
#extern char *malloc() ;
#
#static struct termio myterm ;		/* My terminal flags */
#static int dialfd ;					/* Dial file descriptor */
#
#
#/*****
# *	quit - exit gracefully.
# */
#
#quit(status)
#{
#	(void) signal(SIGHUP, SIG_IGN) ;
#	(void) signal(SIGINT, SIG_IGN) ;
#	(void) signal(SIGQUIT, SIG_IGN) ;
#	(void) signal(SIGPIPE, SIG_IGN) ;
#	(void) signal(SIGTERM, SIG_IGN) ;
#
#	if (dialfd >= 0) undial(dialfd) ;
#	(void) ioctl(0, TCSETA, &myterm) ;
#
#	exit(status) ;
#	}
#
#
#/*****
# *	catch - catch interrupt.
# */
#
#catch()
#{
#	quit(INTRPT) ;
#	}
#
#
#
#/*****
# *	main - Main program.
# */
#
#main(argc,argv)
#int argc ;
#char **argv ;
#{
#	register short opt ;
#	register FILE *dialfile ;
#	register short ch ;
#	register int err ;
#	register int i ;
#	unsigned waitfree ;
#	unsigned redial ;
#	short copy ;
#	struct termio tio ;
#	CALL call ;
#
#	waitfree = 0 ;
#	redial = 0 ;
#	copy = 0 ;
#
#	/*
#	 *	Set up tty options to be used when
#	 *	modem control is enabled.
#	 */
#
#	tio.c_iflag = IGNPAR | IGNBRK | ISTRIP | IXON ;
#	tio.c_oflag = 0 ;
#	tio.c_cflag = CS8 | CREAD | HUPCL | CLOCAL ;
#	tio.c_lflag = NOFLSH ;
#
#	tio.c_cc[VMIN] = 10 ;
#	tio.c_cc[VTIME] = 1 ;
#
#	/*
#	 *	Initialize call structure.
#	 */
#
#	call.attr = &tio ;
#	call.baud = 0 ;
#	call.speed = 0 ;
#	call.line = 0 ;
#	call.telno = 0 ;
#	call.modem = 0 ;
#	call.device = 0 ;
#
#	/*
#	 *	Decode options.
#	 */
#
#	while ((opt = getopt(argc,argv,"ceonrwb:l:s:")) != EOF) {
#		switch (opt) {
#
#			/*
#			 *	Copy standard input to remote.
#			 */
#
#			case 'c':
#				copy = 1 ;
#				break ;
#
#			/*
#			 *	Even parity after carrier detect.
#			 */
#
#			case 'e':
#				tio.c_cflag &= ~(CSIZE | PARENB | PARODD) ;
#				tio.c_cflag |= CS7 | PARENB ;
#				break ;
#
#			/*
#			 *	Odd parity after carrier detect.
#			 */
#
#			case 'o':
#				tio.c_cflag &= ~(CSIZE | PARENB | PARODD) ;
#				tio.c_cflag |= CS7 | PARENB | PARODD ;
#				break ;
#
#			/*
#			 *	No lock file.  Caller allocates it for us.
#			 */
#
#			case 'n':
#				nolock = 1 ;
#				break ;
#
#			/*
#			 *	Redial if no answer.
#			 */
#
#			case 'r':
#				redial = 60 ;
#				break ;
#
#			/*
#			 *	Wait for free outgoing line.
#			 */
#
#			case 'w':
#				waitfree = 30 ;
#				break ;
#
#			/*
#			 *	Device name for outgoing line.
#			 */
#
#			case 'l':
#				call.line = optarg ;
#				break ;
#
#			/*
#			 *	Baud rate for initial dial.
#			 */
#
#			case 'b':
#				call.baud = atoi(optarg) ;
#				break ;
#
#			/*
#			 *	Baud rate after connect.
#			 */
#
#			case 's':
#				call.speed = atoi(optarg) ;
#				break ;
#					
#			/*
#			 *	Bad parameter.
#			 */
#
#			default:
#				exit(2) ;
#			}
#		}
#
#	/*
#	 *	Get phone number.
#	 */
#
#	if (optind != argc) call.telno = argv[optind] ;
#
#	/*
#	 *	Setup signal catching stuff.
#	 */
#
#	dialfd = -1 ;
#
#	(void) ioctl(0, TCGETA, &myterm) ;
#
#	if (signal(SIGHUP, SIG_IGN) == SIG_DFL) (void) signal(SIGHUP, catch) ;
#	if (signal(SIGINT, SIG_IGN) == SIG_DFL) (void) signal(SIGINT, catch) ;
#	if (signal(SIGQUIT, SIG_IGN) == SIG_DFL) (void) signal(SIGQUIT, catch) ;
#	if (signal(SIGPIPE, SIG_IGN) == SIG_DFL) (void) signal(SIGPIPE, catch) ;
#	if (signal(SIGTERM, SIG_IGN) == SIG_DFL) (void) signal(SIGTERM, catch) ;
#
#	/*
#	 *	Attempt the dial.
#	 */
#
#	for (;;) {
#		dialfd = dial(call) ;
#
#		if (dialfd == NO_ANS && redial) {
#			dialmsg("No answer, redial in %d seconds.\n", redial) ;
#			(void) sleep(redial) ;
#			}
#
#		else if ((dialfd == DV_NT_A || dialfd == NO_BD_A) && waitfree) {
#			dialmsg("No outgoing line, will retry in %d seconds.\n", waitfree) ;
#			(void) sleep(waitfree) ;
#			}
#
#		else break ;
#		}
#
#	if (dialfd < 0) quit(-dialfd) ;
#
#	/*
#	 *	If a copy operation is selected, copy standard
#	 *	input to the dialed-up device.
#	 */
#
#	if (copy) {
#
#		dialfile = fdopen(dialfd, "w") ;
#		if (dialfile == 0) {
#			perror("fdopen") ;
#			quit(-L_PROB) ;
#			}
#
#		(void) setvbuf(dialfile, malloc(BUFSIZ), _IONBF, BUFSIZ) ;
#
#		err = 0 ;
#
#		while (err >= 0 && (ch = getchar()) != EOF)
#			err = putc(ch, dialfile) ;
#
#		for (i = 0 ; i < 10 ; i++)
#			err = putc('\000',dialfile) ;
#
#		if (err >= 0) err = fflush(dialfile) ;
#
#		if (err < 0) {
#			perror("copy write error") ;
#			quit(-L_PROB) ;
#			}
#		}
#
#	quit(0) ;
#	return(0) ;
#	}
end_dialer.c