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. XSHAR_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.