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