[alt.sources] ecu - SCO XENIX V/{2,3}86 Extended CU part 32/47

wht@tridom.uucp (Warren Tucker) (10/12/89)

---- Cut Here and unpack ----
#!/bin/sh
# this is part 32 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file sea/sealink.doc continued
#
CurArch=32
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
     exit 1; fi
( read Scheck
  if test "$Scheck" != $CurArch
  then echo "Please unpack part $Scheck next!"
       exit 1;
  else exit 0; fi
) < s2_seq_.tmp || exit 1
echo "x - Continuing file sea/sealink.doc"
sed 's/^X//' << 'SHAR_EOF' >> sea/sealink.doc
X
X     2) If  you  modify  it in such a way that your version cannot converse
X        with the original code as supplied by us,  then you should refer to
X        it as "SEAlink derived",  or as a "variation of SEAlink",  or words
X        to that effect.
X
X     In short,  we're not asking for any money,  but we'd like to get  some
X     credit for our work.
X
X
X     This  document  is  not  meant  to  be  a  rigorous  definition of the
X     protocol.  The code provided should serve to document the details  and
X     fine  points  of  implementing SEAlink.  We will,  however,  present a
X     brief synopsis of how SEAlink adds sliding windows to XMODEM,  and why
X     XMODEM doesn't mind.
X
X     First of all,  SEAlink adds a block number to the ACK and NAK used  in
X     XMODEM.(1)  We  thus  create  "ACK/NAK  packets",  with  the following
X     structure:
X
X         Byte 0:   ACK, NAK, or C
X         Byte 1:   Block number
X         Byte 2:   One's compliment of block number
X
X     This is identical in form to the first three bytes of a  data  packet,
X     except that the SOH has been replaced with an ACK or NAK.(2)
X
X     From the receiver's point of view,  it does not matter if  the  trans-
X     mitter  is using sliding window or not.  The receiver simply sends ACK
X     and NAK packets as appropriate.  Any XMODEM driver tested to date will
X     simply ignore this excess data behind the ACK or NAK.
X
X     From the transmitter's point of view,  it just barely matters  if  the
X     receiver can handle sliding window.  The transmitter always acts as if
X     it  is  sending sliding window,  but varies the window size.  If it is
X     seeing valid block numbers and check values behind the  received  ACKs
X     and NAKs,  it sets the window size to six blocks.  Otherwise,  it sets
X     the  window  size  to  one  block.  The  result is that it only "sends
X     ahead" if the receiver can handle it.
X
X     It  should  be  a fairly simple matter to apply the underlying SEAlink
X     logic to almost any variant of XMODEM.
X
X
X     The  SEAlink  routines  provided  in  this package are also capable of
X     passing system dependent information,  such as true file size and time
X     of  last modification.  This data is passed in a special header block.
X     The header block looks exactly like any other block, except that it is
X     block number zero.
X
X     This is still backwards compatible with XMODEM,  as a SEAlink receiver
X     does  not  mind if block zero is missing,  and any XMODEM receiver yet
X     tested will regard block zero as a duplicate block and ACK it.
X
X     The data portion of block zero contains the following fields:
X
X
X         Offset    Size      Contents
X         ======    ====      ========
X
X            0        4       Original file length.
X            4        4       Date  and  time  file  was  last mofified,  in
X                             seconds since 1979.
X            8       17       Original  file  name,  as  a  null  terminated
X                             string.
X           25       15       Name  of  transmitting  program,   as  a  null
X                             terminated string.
X           40       88       Null filler and expansion area.
X
X
X     (1) XMODEM/CRC uses a "C" in place of  a  NAK  to  indicate  CRC  error
X         detection.  SEAlink  follows  this convention,  and supports either
X         checksum or CRC.  For brevity,  this document will use the term NAK
X         to mean either a true NAK (hex 15) or a C (hex 43).
X     (2) See previous footnote.
X
X     Any field which the transmitter cannot support should be  set  to  all
X     zeros.  Conversly,  the  receiver  should ignore any null fields.  The
X     receiver may ignore any field which he cannot support.
X
X
X
X     The  routines  enclosed  in  this package should be reasonably easy to
X     implement in your application.  We have attempted to exclude  compiler
X     dependent and system dependent logic from these routines.
X
X
X     You will need to alter our references to our communications driver  to
X     conform  to  your  own driver.  The communications related routines we
X     use are:
X
X         com_putc(c)         Output character c to comm port.
X
X         int com_getc(t)     Get character from comm port within  t  tenths
X                             of   a  second.   Return  EOF  if  time  limit
X                             expires.
X
X         com_dump()          Discard any pending output without sending it.
X
X
X     In  addition,  we  use  the  following  routines for controlling timed
X     loops:
X
X         long timerset(t)    Set a timer.  Returns a timer value which will
X                             expire in t tenths of a second.
X
X         int timeup(z)       Check a timer.  Returns true if  timer  z  has
X                             expired yet, or false otherwise.
X
X
X     These routines also make reference to the following functions for
X     system dependent information, which is optional:
X
X         filestat(name,&fs)  Read directory entry for  a  file  and  return
X                             system dependent information.
X
X         setstamp(f,dtg)     Set a file's date/time of last modification.
X
X
X
X
X     The SEAlink  implementation  provided  in  this  package  is  used  by
X     invoking the two primary routines:
X
X
X         int xmtfile(name)             /* transmit a file */
X         char *name;                   /* name of file to transmit */
X
X     This  routine is used to send a file.  One file is sent at a time.  If
X     the  name  is blank (name is null or *name points to a null),  then an
X     end of transmission marker is sent.
X
X     This routine returns a one if the file is successfully transmitted, or
X     a zero if a fatal error occurs.
X
X
X         char *rcvfile(name)           /* receive a file */
X         char *name;                   /* name of file (optional) */
X
X     This routine is used to receive a file.  One file is  received.  If  a
X     name is specified for the file,  then that name WILL be used,  and any
X     name  sent  by  the transmitter will be ignored.  If the name is blank
X     (name is null or *name points to a null),  then the  transmitter  must
X     provide a name for the file.
X
X     This routine returns a pointer to  the  name  of  the  file  that  was
X     received.  If the file transfer is not successful, then a null pointer
X     is returned.
X
X     The  pointer  returned  by  rcvfile()  points to a static data buffer.
X     This does not have to be freed (and should not be),  but  it  will  be
X     overwritten the next time rcvfile() is called.
X
X     The  rcvfile()  function  works  on a temporary file whose name is the
X     same as the final file,  but with a dash ("-") added at the beginning.
X     If  a  file  transfer  is  aborted,  then  this temporary file will be
X     retained.  An aborted file transfer will not harm a pre-existing  file
X     of the same name.
X
X
X
X     These  routines  can  be  used  for  either  single  or  multiple file
X     transfers.
X
X     To  send  multiple  files,  send  each  file one by one until either a
X     transmit fails or all files are sent.  If all  files  are  sent,  then
X     signal the end by calling xmtfile() with a null pointer.
X
X     To receive multiple files,  call rcvfile() repeatedly until it returns
X     a null pointer.
X
X
X
X     This  package includes a demonstration program named CLINK (pronounced
X     "clink"),  which is a  simple  TTY  program  for  doing  SEAlink  file
X     transfers.  CLINK  does  not  perform  any  sort of terminal emulation
X     whatsoever.  However,  she will make use of the ANSI.SYS screen driver
X     if you have it installed.
X
X
X     CLINK may be used in either of two ways: interactive mode or command
X     mode.
X
X     To use CLINK in the interactive mode, give the command "CLINK" with no
X     arguments.  Press  the  "ESCape"  key to give a command to CLINK.  The
X     command "?" (question mark) instructs CLINK to tell you what  commands
X     she understands.
X
X     To  use  CLINK  in the command mode,  give the command "CLINK" with an
X     argument.  There are three arguments you can give CLINK in the command
X     mode.  These are:
X
X      1) Receive files;  Do this with a command of the form:
X
X              CLINK R
X
X         CLINK  will  attempt  to receive one or more files from COM1,  and
X         will terminate as soon as all files  are  received,  or  when  the
X         transfer aborts.
X
X      2) Transmit files; Do this with a command of the form:
X
X              CLINK T <filename> ...
X
X         CLINK  will  attempt  to transmit the listed files over COM1,  and
X         will terminate as soon as all files are sent,  or the transfer  is
X         aborted.  <filename> may be one or more file names with or without
X         drive and path specifiers.  Wildcards may be used.
X
X      3) Give help;  If you type:
X
X              CLINK ?
X
X         or any invalid command,  CLINK will display a  brief  reminder  of
X         what arguments she understands in command mode.
X
X     In all cases, CLINK in the command mode will not alter the serial port
X     other than to set eight data bits,  one stop bit,  and no parity.  Any
X     previously installed serial drivers will be  replaced,  and  the  baud
X     rate will not be changed.
X
X
X
X     CLINK comes with her own serial driver built in for the IBM PC  family
X     and true compatibles,  but she is capable of using any standard FOSSIL
X     driver.
XSHAR_EOF
echo "File sea/sealink.doc is complete"
chmod 0660 sea/sealink.doc || echo "restore of sea/sealink.doc fails"
echo "x - extracting sea/lint_args.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > sea/lint_args.h &&
X/* CHK=0x23C0 */
X/*+-----------------------------------------------------------------------
X	lint_args.h
X------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:07-03-1989-22:58-wht------------- ecu 2.00 ---------------- */
X/*:05-29-1989-18:39-afterlint-creation */
X
X#ifndef BUILDING_LINT_ARGS
X#ifdef LINT_ARGS
X
X/* ecusea.c */
Xchar *receive_file(void);
Xchar *sf_state_text(int );
Xint cancel_transaction(int );
Xint main(int ,char * *,char * *);
Xint receive_block(char *);
Xint send_comm_block(char *,int );
Xint send_file(char *);
Xunsigned int lgetc_timeout(int );
Xunsigned short crc_update(int ,unsigned int );
Xvoid send_file_block(struct _iobuf *,int );
Xvoid set_sf_state(int ,int );
Xvoid set_utime_1980(char *,long );
Xvoid wait_for_rcvr_response(void);
Xvoid xmit_ack(int );
Xvoid xmit_cancel(void);
Xvoid xmit_nak(int );
X/* scurses.c */
Xchar *get_elapsed_time(long );
Xchar *get_tod(int ,char *);
Xint clear_area(struct _win_st *,int ,int ,int );
Xint clear_area_char(struct _win_st *,int ,int ,int ,char );
Xint report_comm_baud_rate(unsigned int );
Xint report_error_count(void);
Xint report_file_byte_io(long );
Xint report_file_open_length(long );
Xint report_file_rcv_started(char *,long ,long );
Xint report_protocol_crc_type(char *);
Xint report_rx_tx_count(void);
Xvoid report_file_close(void);
Xvoid report_file_open_tod(void);
Xvoid report_file_send_open(char *,struct stat *);
Xvoid report_init(char *);
Xvoid report_last_rxhdr(char *,int );
Xvoid report_last_txhdr(char *,int );
Xvoid report_mode(int );
Xvoid report_rx_ind(int );
Xvoid report_rxpos(long );
Xvoid report_str(char *,int );
Xvoid report_top_line(char *);
Xvoid report_transaction(char *);
Xvoid report_tx_ind(int );
Xvoid report_txpos(long );
Xvoid report_uninit(void);
X
X#else		/* compiler doesn't know about prototyping */
X
X/* ecusea.c */
Xchar *receive_file();
Xchar *sf_state_text();
Xunsigned int lgetc_timeout();
Xunsigned short crc_update();
Xvoid send_file_block();
Xvoid set_sf_state();
Xvoid set_utime_1980();
Xvoid wait_for_rcvr_response();
Xvoid xmit_ack();
Xvoid xmit_cancel();
Xvoid xmit_nak();
X/* scurses.c */
Xchar *get_elapsed_time();
Xchar *get_tod();
Xvoid report_file_close();
Xvoid report_file_open_tod();
Xvoid report_file_send_open();
Xvoid report_init();
Xvoid report_last_rxhdr();
Xvoid report_last_txhdr();
Xvoid report_mode();
Xvoid report_rx_ind();
Xvoid report_rxpos();
Xvoid report_str();
Xvoid report_top_line();
Xvoid report_transaction();
Xvoid report_tx_ind();
Xvoid report_txpos();
Xvoid report_uninit();
X
X#endif /* LINT_ARGS */
X#endif /* BUILDING_LINT_ARGS */
X
X/* end of lint_args.h */
SHAR_EOF
chmod 0644 sea/lint_args.h || echo "restore of sea/lint_args.h fails"
echo "x - extracting uucp/dialhclone.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > uucp/dialhclone.c &&
X/* CHK=0x8345 */
X/* vi: set tabstop=4 shiftwidth=4: */
X/*+-------------------------------------------------------------------------
X	dialhclone.c - SCO UUCP dialer program for several Hayes-type modems
X	...!gatech!emory!tridom!wht
X
X  Configuration symbols:
X	MCOM9624C	Microcom AX/9624c
X	MCOM2400	Microcom AX/2400
X	USR2400		USR Courier 2400
X	HDUU		defined if HDB UUCP used on system
X
X  This program assumes:
X	Touch-Tone phone line
X	S7 register set to 30 by mdsetup string (30 seconds timeout; see below)
X	modem pre-configured (by switches or nvram) to drop carrier on DTR loss
X	modem pre-configured to not reset to factory, nvram or switch settings
X	  on DTR loss
X
X  Defined functions:
X	_abort(sig)
X	alrmint()
X	call_ungetty(call_type)
X	checkbaud(baud)
X	cleanup(stat)
X	main(argc,argv,envp)
X	matchbaud(cbaud,low,high)
X	mdflush()
X	mdputc(lchar)
X	mdputc_paced(pace_msec,lchar)
X	mdputs(string)
X	mdputs_paced(pace_msec,string)
X	mdread(rtime)
X	mdwrite(c)
X	toprint(c)
X	open_acu()
X	substr(s,l)
X	translate(ttab,str)
X
X
X  Usage:	dial ttyname telnumber speed 
X			dial -h ttyname speed
X
X  Returns:
X		0x80	bit = 1 if connection failed
X		0x10	bit = 1 if line is also used for dialin #if !defined(HDUU)
X		0x0f	if msb=1: error code
X				if msb=0: connected baud rate (0=same as dialed baud)
X
X		Note: getty calls the dialer with -h whenever it starts up
X		on a line enabled in /etc/ttys and listed in Devices with
X		this dialer.
X
X		Error codes are split into two catagories: 1) (codes 0-11)
X		Local problems are defined as tty port, or modem problems:
X		problems that can be worked around by using a different device.
X		2) (codes 12-15) Remote problems are phone busy, no answer, etc.
X		: attempts to connect to this remote system should be stopped.
X
X  Note:	This source file can be used both for the old UUCP and
X		for the new HoneyDanBer UUCP.  For the latter, HDUU may
X		be defined to avoid calls to the HD ungetty program - which
X		assumes that uugetty is used, and so simply returns SUCCESS.
X		However, dialer binaries for the old UUCP are equally valid
X		for the new HoneyDanBer UUCP (but make an unnecessary call
X		to the null ungetty, supplied for backward compatibility).
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:07-23-1989-14:10-wht-consolidate dialers into one source */
X/*:07-23-1989-12:42hclone-improve integrity of -h code */
X/*:07-17-1989-13:51hclone-major rework */
X/*:07-02-1989-20:49hclone-beef up mdsetup */
X
X#include <stdio.h>
X#include <signal.h>
X#include <fcntl.h>
X#include <sys/types.h>
X#include <sys/ioctl.h>
X#include <termio.h>
X#include <errno.h>
X#include <ctype.h>
X
Xchar *toprint(unsigned char );
Xint mdread(int );
Xint mdflush(void);
Xvoid mdputc(char );
Xvoid mdputc_paced(int ,char );
Xvoid mdputs(char *);
Xvoid mdputs_paced(int ,char *);
Xint mdwrite(char *);
Xint call_ungetty(char );
Xvoid translate(char *,char *);
Xint _abort(int );
Xint open_acu(void);
Xint substr(char *,char *);
Xint alrmint(void);
Xint cleanup(int );
Xint checkbaud(unsigned int );
Xint matchbaud(int ,int ,int );
Xint main(int ,char * *,char * *);
X
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	RC_BAUD		0x0f	/* CBAUD connected at (0=same as dialed speed) */
X#define	RC_ENABLED	0x10	/* enabled flag: 1 = ungetty -r required to */
X							/* restore the line */
X#define	RC_FAIL		0x80	/* 1 = failed to connect */
X
X/* return code error 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_BUSY	13	/* phone is busy */
X#define	RCE_NOCARR	14	/* no carrier */
X#define	RCE_ANSWER	15	/* no answer */
X
X#define	SUCCESS	0
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#define SAME		0
X#define MAXLINE		80
X
X#define DEBUG(l, f, s)	if (Debug >= l) fprintf(stderr, f, s)
X#if !defined(DBG)
X#define	DBG	0
X#endif
X
X/* setup to call (S7=30 assumed by program) */
X#if defined(MCOM2400)
Xchar *mdsetup = "ATQ0V1E0TX4S0=0S2=43S7=30\\N0\\C1\\J1\r";
X#endif
X#if defined(MCOM9624C)
X#define MODEM9600
X#define MODEM19200
Xchar *mdsetup_NORM = "ATQ0E0V1&D2&C1S2=43S7=30\\N0\\Q0\\G0%C1%P2\r";
Xchar *mdsetup_REL  = "ATQ0E0V1&D2&C1S2=43S7=30\\N3\\Q1\\G1%C1%P2\r";
Xchar *mdsetup;
X#endif
X#if defined(USR2400)
Xchar *mdsetup = "ATQ0V1E0TX4S0=0S2=43S7=30S11=47\r";
X#endif
X
Xchar *mdreset = "ATZ\r";
Xchar *mdvalid = "0123456789PpTtRrSsWw,!@*#()-"; /* phone number characters */
Xchar *mddialin = "ATS0=1Q1V0E0\r"; /* setup for dial in */
Xchar *mddsblesc = "ATS2=128E0\r"; /* disable escape sequence */
X
X#define	DIAL_RETRY	4
X/*
X *  Possible messages produced by modem.
X *  We ignore RING since the HAYES only produces it when answering.
X */
X#define	OK			0
X#define	NOCARRIER		1
X#define	ERROR			2
X#define	BUSY			3
X#define	NOANSWER		4
X#define	NODIALTONE		5
X#define	CONNECT600		6
X#define	CONNECT1200		7
X#define	CONNECT2400		8
X#define	CONNECT4800		9
X#define	CONNECT9600		10
X#define	CONNECT19200	11
X#define	CONNECT			12
X
Xchar *mdmsgs[] = 
X{
X	/* 0 */ "OK",
X	/* 1 */ "NO CARRIER",
X	/* 2 */ "ERROR",
X	/* 3 */ "BUSY",
X	/* 4 */ "NO ANSWER",
X	/* 5 */ "NO DIALTONE",
X	/* 6 */ "CONNECT 600",
X	/* 7 */ "CONNECT 1200",
X	/* 8 */ "CONNECT 2400",
X	/* 8 */ "CONNECT 4800",
X	/* 8 */ "CONNECT 9600",
X	/* 8 */ "CONNECT 19200",
X	/* 9 */ "CONNECT",
X	0
X};
X
Xchar *strchr();
Xint alrmint();
X
Xstruct termio acu_termio;
X
Xchar *acu;						/* device to dial through */
Xint Debug = DBG;				/* set when debug flag is given */
Xint dialing;					/* set while modem is dialing */
Xint fd = -1;					/* file descriptor for acu */
Xint retcode = RC_FAIL;			/* return code */
Xint errflag = 0;				/* set on errors */
Xint hangup_flag = 0;			/* set to hangup modem */
Xint highbaud,lowbaud;			/* baud rate limits */
Xchar *ungetty = "/usr/lib/uucp/ungetty";
X
X/*+-------------------------------------------------------------------------
X	toprint(ch) - make a character "printable"
X--------------------------------------------------------------------------*/
Xchar *
Xtoprint(ch)
Xunsigned char ch;
X{
Xstatic char buffer[10];
Xchar *pnt;
X#define	toprint(x)	((x)<' '?((x)+'@'):'?')
X
X	pnt = buffer;
X	if(iscntrl(ch) || !isprint(ch))
X	{
X		if(!isascii(ch))
X		{			/* Top bit is set */
X			*pnt++ = 'M';
X			*pnt++ = '-';
X			ch = toascii(ch);			/* Strip it */
X		}
X		if(iscntrl(ch))
X		{
X			*pnt++ = '^';
X			ch = toprint(ch);			/* Make it printable */
X		}
X	}
X	*pnt++ = ch;
X	*pnt = 0;
X	return(buffer);
X}	/* end of toprint */
X
X/*+-------------------------------------------------------------------------
X	mdread(rtime)
X
X Reads from the ACU until it finds a valid response (found in mdmsgs),
X a numeric result code (e.g., S-register value),
X or times out after rtime seconds.
X
X Returns:	The index in mdmsgs of the modem response found,
X numeric result + 128 or -1 on timeout.
X--------------------------------------------------------------------------*/
Xint
Xmdread(rtime)
Xint rtime;
X{
Xint itmp;
Xchar rdchar,**mp;
Xregister char *bp;
Xchar buf[MAXLINE];
Xchar *cptr;
Xchar s10[10];
X
X	bp = buf;
X	alarm(rtime);
X	DEBUG(6,"MODEM returned %s","<<");
X
X	while(read(fd,&rdchar,1) == 1)
X	{
X		*bp++ = (rdchar &= 0x7F);
X		DEBUG(6,"%s",toprint(rdchar));
X		if(bp >= buf + MAXLINE)
X		{
X			alarm(0);
X			DEBUG(4,">>-%s\r\n","FAIL");
X			return(-1);
X		}
X		if(rdchar == '\r')
X		{
X			cptr = buf;
X			if(*cptr == 0x0A)
X				cptr++;
X			if(isdigit(*cptr))
X			{
X				alarm(0);
X				DEBUG(6,">>-%s\r\n","OK");
X				sprintf(s10,"%d",itmp = atoi(cptr));
X				DEBUG(4,"got numeric result %s\r\n",s10);
X				return(128 + itmp);
X			}
X
X			for(mp = mdmsgs; *mp; ++mp)
X			{
X				if(substr(*mp,buf) == 0)
X				{
X					alarm(0);
X					DEBUG(6,">>-%s\r\n","OK");
X					DEBUG(4,"got %s\r\n",mdmsgs[mp - mdmsgs]);
X					return(mp - mdmsgs);
X				}
X			}
X			bp = buf;
X		}
X	}
X
X	alarm(0);
X	DEBUG(6,">>-%s","FAIL");
X	DEBUG(4," no response\r\n",0);
X	return(-1);
X}	/* end of mdread */
X
X/*+-------------------------------------------------------------------------
X	mdflush() - flushes input clists for modem
X--------------------------------------------------------------------------*/
Xmdflush()
X{
X	ioctl(fd,TCFLSH,0);
X}	/* end of mdflush */
X
X/*+-----------------------------------------------------------------------
X	mdputc(lchar) -- write lchar to comm line
X------------------------------------------------------------------------*/
Xvoid
Xmdputc(lchar)
Xchar lchar;
X{
X	write(fd,&lchar,1);
X	DEBUG(6,"%s",toprint(lchar));
X}	/* end of mdputc */
X
X/*+-----------------------------------------------------------------------
X	mdputc_paced(pace_msec,lchar) -- write lchar to comm line
X  with time between each character 
X------------------------------------------------------------------------*/
Xvoid
Xmdputc_paced(pace_msec,lchar)
Xregister pace_msec;
Xregister char lchar;
X{
X	mdputc(lchar);
X	nap((long)pace_msec);
X}	/* end of mdputc_paced */
X
X/*+-----------------------------------------------------------------------
X	mdputs(string) -- write string to comm line
X------------------------------------------------------------------------*/
Xvoid
Xmdputs(string)
Xregister char *string;
X{
X	while(*string)
X		mdputc(*string++);
X}
X
X/*+-----------------------------------------------------------------------
X	mdputs_paced(pace_msec,string) -- write string to comm line
X  with time between each character 
X------------------------------------------------------------------------*/
Xvoid
Xmdputs_paced(pace_msec,string)
Xregister pace_msec;
Xregister char *string;
X{
X	while(*string)
X		mdputc_paced(pace_msec,*string++);
X
X}	/* end of mdputs_paced */
X
X/*+-------------------------------------------------------------------------
X	mdwrite(str) - output string to acu
X  Returns:	0 on completion, -1 on write errors.
X--------------------------------------------------------------------------*/
Xmdwrite(str)
Xregister char *str;
X{
Xint err;
X
X	nap(1000L);
X	DEBUG(6,"Sent MODEM %s","<<");
X	mdputs_paced(20,str);
X	DEBUG(6,">>-%s\r\n","OK");
X	return(0);
X
X}	/* end of mdwrite */
X
X/*+-------------------------------------------------------------------------
X	call_ungetty(call_type)
X
Xtype: 'a' - acquire acu
X      't' - test to see if acu should be returned
X      'r' - return acu
X--------------------------------------------------------------------------*/
Xcall_ungetty(call_type)
Xchar call_type;
X{
Xint itmp;
Xint pid;
Xint wait_status;
X
X	if((pid = fork()) == 0)
X	{
X		if(Debug >= 5)
X			fprintf(stderr,"dialer: %s %s called\r\n",ungetty,acu);
X		switch(call_type)
X		{
X			case 'a':
X				execl(ungetty,"ungetty",acu,NULL);
X				break;
X			case 't':
X				execl(ungetty,"ungetty","-t",acu,NULL);
X		}
X		fprintf(stderr,"ungetty exec error\r\n");
X		exit(-1);
X	}
X
X	while(((itmp = wait(&wait_status)) != pid) && itmp != -1)
X		;
X
X	if(Debug >= 5)
X		fprintf(stderr,"dialer: %s pid %d status 0x%04x\r\n",
X			ungetty,itmp,wait_status);
X
X	return(wait_status);
X}	/* end of call_ungetty */
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--------------------------------------------------------------------------*/
Xvoid
Xtranslate(ttab,str)
Xregister char *ttab,*str;
X{
X	register char *s;
X
X	for(;*ttab && *(ttab+1); ttab += 2)
X		for(s=str;*s;s++)
X			if(*ttab == *s)
X				*s = *(ttab+1);
X}	/* end of translate */
X
X/*+-------------------------------------------------------------------------
X	_abort(sig)
X--------------------------------------------------------------------------*/
X_abort(sig)
Xint sig;
X{
X	signal(SIGINT,SIG_IGN);
X	if(fd != -1)
X	{
X		ioctl(fd,TCGETA,&acu_termio);
X		acu_termio.c_cflag |= HUPCL;		/* make sure modem hangs up */
X		ioctl(fd,TCSETA,&acu_termio);
X		close(fd);
X	}
X	if(sig)
X		retcode |= (RC_FAIL | RCE_SIG);
X	exit(retcode);
X}	/* end of _abort */
X
X/*+-------------------------------------------------------------------------
X	open_acu() - open the acu (modem)
X
Xreturns 'fd' of open modem line
X--------------------------------------------------------------------------*/
Xint
Xopen_acu()
X{
Xint fd1;
Xint fd2;
X
X	/*  open with O_NDELAY set or the open probably will hang */
X	if((fd1 = open(acu,O_RDWR | O_NDELAY)) < 0)
X	{
X		fprintf(stderr,"dial: Can't open device: %s\r\n",acu);
X		exit(RC_FAIL | RCE_OPEN | retcode);
X	}
X
X	signal(SIGINT,_abort);
X
X	ioctl(fd1,TCGETA,&acu_termio);
X	acu_termio.c_cflag &= ~(CBAUD | HUPCL);
X	acu_termio.c_cflag |= CLOCAL | (hangup_flag ? (B2400|HUPCL) : highbaud);
X	acu_termio.c_lflag &= ~ECHO;
X	acu_termio.c_cc[VMIN] = '\1';
X	acu_termio.c_cc[VTIME] = 0;
X
X	if(errflag = ioctl(fd1,TCSETA,&acu_termio))
X	{
X		char buf[16];
X		DEBUG(1,"dial: ioctl error on %s",acu);
X		DEBUG(1," errno=%d\r\n",errno);
X		cleanup(RC_FAIL | RCE_IOCTL | retcode);
X	}
X	/* reopen line with clocal so we can talk without carrier present */
X	fd2 = fd1;
X	if((fd1 = open(acu,O_RDWR)) < 0)
X	{
X		fprintf(stderr,"dial: Can't open device local: %s\r\n",acu);
X		exit(RC_FAIL | RCE_OPEN | retcode);
X	}
X	close(fd2);
X	return(fd1);
X
X}	/* end of open_acu */
X
X/*+-------------------------------------------------------------------------
X	substr(s,l)
X
X Function:	Checks for the presence of the string pointed to by s
X somewhere within the string pointed to by l.
X
X Returns:	0 if found.
X 			-1 if not found.
X--------------------------------------------------------------------------*/
Xsubstr(s,l)
Xchar *s;
Xregister char *l;
X{
X	int len;
X
X	len = strlen(s);
X	while((l = strchr(l,*s)) != NULL)
X	{
X		if(strncmp(s,l,len) == SAME)
X			return(0);
X		l++;
X	}
X	return(-1);
X}	/* end of substr */
X
X/*+-------------------------------------------------------------------------
X	alrmint() - catch alarm call (signal 14) and exit
X--------------------------------------------------------------------------*/
Xalrmint()
X{
X	DEBUG(4,"\r\nTimeout waiting for %s\r\n",dialing ? "carrier" : "acu");
X	cleanup(RC_FAIL | RCE_TIMOUT | retcode);
X}	/* end of alrmint */
X
X/*+-------------------------------------------------------------------------
X	cleanup(stat) - close device and exit
X--------------------------------------------------------------------------*/
Xcleanup(stat)
Xint stat;
X{
X	if(stat & RC_FAIL)
X	{	/* if we failed, drop DTR (in _abort) */
X		retcode = stat;
X		_abort(0);
X	}
X	else 
X		exit(stat);
X}	/* end of cleanup */
X
X/*+-------------------------------------------------------------------------
X	checkbaud(baud) - check for valid baud rates
X  Returns:	The baud rate in struct termio c_cflag fashion
X--------------------------------------------------------------------------*/
Xcheckbaud(baud)
Xunsigned int baud;
X{
Xint b_value;
X
X	switch(baud)
X	{
X	case 110:  b_value = B110; break;
X	case 300:  b_value = B300; break;
X	case 1200: b_value = B1200; break;
X	case 2400: b_value = B2400; break;
X#if defined(MODEM9600)
X	case 4800: b_value = B4800; break;
X	case 9600: b_value = EXTA; break;
X#endif
X#if defined(MODEM19200)
X	case 19200: b_value = EXTB; break;
X#endif
X	default:
X		fprintf(stderr,"dial: Bad speed: %d\r\n",baud);
X		exit(RC_FAIL | RCE_SPEED);
X	}
X	return(b_value);
X}	/* end of checkbaud */
X
X/*+-------------------------------------------------------------------------
SHAR_EOF
echo "End of part 32"
echo "File uucp/dialhclone.c is continued in part 33"
echo "33" > s2_seq_.tmp
exit 0
-- 
-------------------------------------------------------------------
Warren Tucker, Tridom Corporation       ...!gatech!emory!tridom!wht 
Ker-au'-lo-phon.  An 8-foot partial flue-stop, having metal pipes
surmounted by adjustable rings, and with a hole bored near the top
of each pipe, producing a soft and "reedy" tone.