[comp.sources.misc] v05i055: Kermit patches to enable dial to use HDB database, like cu

eric@snark.UUCP (Eric S. Raymond) (11/22/88)

Posting-number: Volume 5, Issue 55
Submitted-by: "Eric S. Raymond" <eric@snark.UUCP>
Archive-name: kermit.hdb

[About gets():  anyone who'd use gets() with a *pointer* is begging for a
fingerd botch; at least my patch would make it obvious a lot sooner.  I do
concede that the trailing newline is something of a problem, though.  ++bsa]

This article is a patch set for the 4D release of C-Kermit.  The code changes
fix some minor compilation glitches under SVr2 UNIX, but more importantly they
enable the ckermit dial command to accept a system name agument (like cu) and
use the information represented in the Basic Networking Utilities (HoneyDanBer
UUCP) database to set line, speed and modem type for the dial out.

For this to work, the software must be compiled with -DSVR2 on. This can be
accomplished via 'make hdbx'. See the patch to ckuker.doc (first in the set)
for details.

These patches work, but they're a bit on the crude side (Dialcodes ought to
be supported, and the code could be taught how to interpret the Dialers file).
I hope the Kermit maintainers (wherever they are) will pick these up, polish
them a bit and include them in the next release.

If you are a Kermit maintainer, please ACK by email -- it would be nice to know
this posting hasn't just dropped into a void.

*** ckuker.doc-old	Sun Nov 20 00:37:52 1988
--- ckuker.doc	Sun Nov 20 00:46:21 1988
***************
*** 1284,1289 ****
--- 1284,1297 ----
  The device used for dialing out is the one selected in  the  most  recent  "set
  line"  command  (or on a workstation, the default line if no "set line" command
  was given).  The "dial" command calls locks the path (see the section  on  line
+ 
+ One special convenience feature is available in the dial command under SVR2 and
+ later UNIX systems using HoneyDanBer UUCP. If you give dial a system name
+ argument that it can find in the Systems file, it will search through the
+ Systems and Devices file and set the line, modem type and communication speed
+ in accordance with what it finds there. However, dial codes will *not* be
+ interpreted. Nor will the HDB modemcap be used; for now, the modem name in the
+ Devices file must match one of kermit's internally-supported types.
  
  
  
*** ckuker.mak-old	Thu Nov 17 16:32:09 1988
--- ckuker.mak	Thu Nov 17 18:34:45 1988
***************
*** 9,14 ****
--- 9,15 ----
  # for Berkeley Unix 2.9 (PDP-11), "make bsd29"
  # for DEC Ultrix 1.1 or 1.2, "make bsd"
  # for AT&T 3Bx systems, "make att3bx"
+ # for AT&T System V with HoneyDanBer UUCP, "make hdbx"
  # for AT&T generic System III/System V, "make sys3" or "make sys3nid"
  # for Bell Unix Version 7 (aka 7th Edition), "make v7" (but see below)
  # for Microsoft Xenix (/286, PC/AT, etc), "make xenix"
***************
*** 138,147 ****
  	@echo 'Make what?  You must tell which system to make C-Kermit for.'
  
  wermit: ckcmai.o ckucmd.o ckuusr.o ckuus2.o ckuus3.o ckcpro.o ckcfns.o \
! 		 ckcfn2.o ckucon.o ckutio.o ckufio.o ckudia.o ckuscr.o
  	$(CC2) $(LNKFLAGS) -o wermit ckcmai.o ckutio.o ckufio.o ckcfns.o \
  		 ckcfn2.o ckcpro.o ckucmd.o ckuus2.o ckuus3.o ckuusr.o \
! 		 ckucon.o ckudia.o ckuscr.o
  
  ckcmai.o: ckcmai.c ckcker.h ckcdeb.h
  
--- 139,148 ----
  	@echo 'Make what?  You must tell which system to make C-Kermit for.'
  
  wermit: ckcmai.o ckucmd.o ckuusr.o ckuus2.o ckuus3.o ckcpro.o ckcfns.o \
! 		 ckcfn2.o ckucon.o ckutio.o ckufio.o ckudia.o ckuscr.o ckubnu.o
  	$(CC2) $(LNKFLAGS) -o wermit ckcmai.o ckutio.o ckufio.o ckcfns.o \
  		 ckcfn2.o ckcpro.o ckucmd.o ckuus2.o ckuus3.o ckuusr.o \
! 		 ckucon.o ckudia.o ckuscr.o ckubnu.o
  
  ckcmai.o: ckcmai.c ckcker.h ckcdeb.h
  
***************
*** 175,181 ****
  
  ckudia.o: ckudia.c ckcker.h ckcdeb.h
  
! ckuscr.o: ckuscr.c ckcker.h ckcdeb.h
  #
  ###########################################################################
  #
--- 176,184 ----
  
  ckudia.o: ckudia.c ckcker.h ckcdeb.h
  
! ckuscr.o: ckuscr.c ckucmd.h ckcker.h ckcdeb.h
! 
! ckubnu.o: ckubnu.c ckcker.h ckcdeb.h
  #
  ###########################################################################
  #
***************
*** 208,222 ****
  	make wermit "CFLAGS = -DUXIII -DDEBUG -DTLOG -i -O" "LNKFLAGS = -i"
  
  
  #Generic ATT System III or System V (no I&D space)
  sys3nid:
  	make wermit "CFLAGS = -DUXIII -DDEBUG -DTLOG -O" "LNKFLAGS ="
  
  
  #AT&T 3B-series computers running System V
! #  Only difference from sys3 is lock file stuff...
  att3bx:
! 	make wermit "CFLAGS = -DUXIII -DATT3BX -DDEBUG -DTLOG -i -O" \
  		"LNKFLAGS = -i"
  
  
--- 211,230 ----
  	make wermit "CFLAGS = -DUXIII -DDEBUG -DTLOG -i -O" "LNKFLAGS = -i"
  
  
+ #Generic ATT System V with HoneyDanBer
+ hdbx:
+ 	make "CFLAGS = -DUXIII -DDEBUG -DTLOG -DSVR2 -O" "LNKFLAGS =" wermit
+ 
+ 
  #Generic ATT System III or System V (no I&D space)
  sys3nid:
  	make wermit "CFLAGS = -DUXIII -DDEBUG -DTLOG -O" "LNKFLAGS ="
  
  
  #AT&T 3B-series computers running System V
! #  Only difference from sys3 is lock file stuff & SVR2 support...
  att3bx:
! 	make wermit "CFLAGS = -DUXIII -DATT3BX -DDEBUG -DTLOG -DSVR2 -i -O" \
  		"LNKFLAGS = -i"
  
  
***************
*** 281,283 ****
--- 289,298 ----
  #Mostly Berkeley-like, but with some ATTisms
  c70:
  	make wermit "CFLAGS= -DBSD4 -DC70 -DDEBUG -DTLOG"
+ 
+ 
+ 
+ 
+ 
+ 
+ 
*** ckcdeb.h-old	Thu Nov 17 11:09:19 1988
--- ckcdeb.h	Thu Nov 17 17:10:27 1988
***************
*** 102,113 ****
  
  
  /* Some special includes for VAX/VMS */
! 
  #ifdef vax11c
  #include ssdef
  #include stsdef
  #endif
! 
  /* Program return codes for VMS, DECUS C, and Unix */
  
  #ifdef vax11c
--- 102,113 ----
  
  
  /* Some special includes for VAX/VMS */
! /*
  #ifdef vax11c
  #include ssdef
  #include stsdef
  #endif
! */
  /* Program return codes for VMS, DECUS C, and Unix */
  
  #ifdef vax11c
*** ckcfn2.c-old	Thu Nov 17 18:00:53 1988
--- ckcfn2.c	Thu Nov 17 18:02:48 1988
***************
*** 298,304 ****
    	if (t == 3) cccount++;		/* Count any control-C's */
  
  	if (t == eol) return('Q');
! 	*l = unchar(t);			/* Packet length */
  	debug(F101," pkt len","",*l);
  	if (*l + i + 2 > RBUFL) { 	/* Sticks out too far? */
  	    debug(F101," ** overrun","",i);
--- 298,304 ----
    	if (t == 3) cccount++;		/* Count any control-C's */
  
  	if (t == eol) return('Q');
! 	*l = todigit(t);			/* Packet length */
  	debug(F101," pkt len","",*l);
  	if (*l + i + 2 > RBUFL) { 	/* Sticks out too far? */
  	    debug(F101," ** overrun","",i);
***************
*** 310,316 ****
  	if ((t = recpkt[i++]) == stchr) continue;
  	if (cccount && (t == 3)) { conoll("^C^C exit..."); doexit(0); }
  	if (t == eol) return('Q');
! 	*n = unchar(t);
  	debug(F101,"rpack: n","",*n);
  
  /* cont'd... */
--- 310,316 ----
  	if ((t = recpkt[i++]) == stchr) continue;
  	if (cccount && (t == 3)) { conoll("^C^C exit..."); doexit(0); }
  	if (t == eol) return('Q');
! 	*n = todigit(t);
  	debug(F101,"rpack: n","",*n);
  
  /* cont'd... */
*** ckcfns.c-old	Thu Nov 17 18:01:08 1988
--- ckcfns.c	Thu Nov 17 18:02:41 1988
***************
*** 139,145 ****
      while ((a = *buf++) != '\0') {
  	if (rptflg) {			/* Repeat processing? */
  	    if (a == rptq) {		/* Yes, got a repeat prefix? */
! 		rpt = unchar(*buf++);	/* Yes, get the repeat count, */
  		a = *buf++;		/* and get the prefixed character. */
  	    }
  	}
--- 139,145 ----
      while ((a = *buf++) != '\0') {
  	if (rptflg) {			/* Repeat processing? */
  	    if (a == rptq) {		/* Yes, got a repeat prefix? */
! 		rpt = todigit(*buf++);	/* Yes, get the repeat count, */
  		a = *buf++;		/* and get the prefixed character. */
  	    }
  	}
***************
*** 640,660 ****
  
      len = strlen(data);		    	/* Number of fields */
  
!     x = (len-- > 0) ? unchar(data[0]) : DSPSIZ;	        /* Packet size */
      if (spsizf == 0)
  	spsiz = (x < 10) ? DSPSIZ : x;
  
!     x = (len-- > 0) ? unchar(data[1]) : DMYTIM;		/* Timeout */
      if (timef == 0)
  	timint = (x < 0) ? DMYTIM : x;
  
      npad = 0; padch = '\0';		    	    	/* Padding */
      if (len-- > 0) {
! 	npad = unchar(data[2]);
  	if (len-- > 0) padch = ctl(data[3]); else padch = 0;
      }
  
!     seol = (len-- > 0) ? unchar(data[4]) : '\r';	/* Terminator  */
      if ((seol < 2) || (seol > 037)) seol = '\r';
  
      ctlq = (len-- > 0) ? data[5] : CTLQ;    	    	/* Control prefix */
--- 640,660 ----
  
      len = strlen(data);		    	/* Number of fields */
  
!     x = (len-- > 0) ? todigit(data[0]) : DSPSIZ;	        /* Packet size */
      if (spsizf == 0)
  	spsiz = (x < 10) ? DSPSIZ : x;
  
!     x = (len-- > 0) ? todigit(data[1]) : DMYTIM;		/* Timeout */
      if (timef == 0)
  	timint = (x < 0) ? DMYTIM : x;
  
      npad = 0; padch = '\0';		    	    	/* Padding */
      if (len-- > 0) {
! 	npad = todigit(data[2]);
  	if (len-- > 0) padch = ctl(data[3]); else padch = 0;
      }
  
!     seol = (len-- > 0) ? todigit(data[4]) : '\r';	/* Terminator  */
      if ((seol < 2) || (seol > 037)) seol = '\r';
  
      ctlq = (len-- > 0) ? data[5] : CTLQ;    	    	/* Control prefix */
***************
*** 905,911 ****
  */
  
  cwd(vdir) char *vdir; {
!     vdir[unchar(*vdir) + 1] = '\0';	/* End with a null */
      if (zchdir(vdir+1)) {
  	encstr(vdir+1);
  	ack1(data);
--- 905,911 ----
  */
  
  cwd(vdir) char *vdir; {
!     vdir[todigit(*vdir) + 1] = '\0';	/* End with a null */
      if (zchdir(vdir+1)) {
  	encstr(vdir+1);
  	ack1(data);
*** ckcker.h-old	Thu Nov 17 17:50:01 1988
--- ckcker.h	Thu Nov 17 17:53:16 1988
***************
*** 84,89 ****
  /* Macros */
  
  #define tochar(ch)  ((ch) + SP )	/* Number to character */
! #define unchar(ch)  ((ch) - SP )	/* Character to number */
  #define ctl(ch)     ((ch) ^ 64 )	/* Controllify/Uncontrollify */
  #define unpar(ch)   ((ch) & 127)	/* Clear parity bit */
--- 84,89 ----
  /* Macros */
  
  #define tochar(ch)  ((ch) + SP )	/* Number to character */
! #define todigit(ch)  ((ch) - SP )	/* Character to number */
  #define ctl(ch)     ((ch) ^ 64 )	/* Controllify/Uncontrollify */
  #define unpar(ch)   ((ch) & 127)	/* Clear parity bit */
*** ckcpro.w-old	Sun Nov 20 00:17:08 1988
--- ckcpro.w	Sun Nov 20 00:17:56 1988
***************
*** 113,119 ****
      	     else { errpkt("Can't type file"); SERVE; } }
  
  <generic>U { x = *(srvcmd+1);			/* Disk Usage query */
!     	     x = ((x == '\0') || (x == unchar(0)));
  	     x = (x ? syscmd(SPACMD,"") : syscmd(SPACM2,srvcmd+2));
      	     if (x) BEGIN ssinit; else { errpkt("Can't check space"); SERVE; }}
  
--- 113,119 ----
      	     else { errpkt("Can't type file"); SERVE; } }
  
  <generic>U { x = *(srvcmd+1);			/* Disk Usage query */
!     	     x = ((x == '\0') || (x == todigit(0)));
  	     x = (x ? syscmd(SPACMD,"") : syscmd(SPACM2,srvcmd+2));
      	     if (x) BEGIN ssinit; else { errpkt("Can't check space"); SERVE; }}
  
*** ckubnu.c-old	Sun Nov 20 00:46:58 1988
--- ckubnu.c	Sat Nov 19 23:43:02 1988
***************
*** 0 ****
--- 1,153 ----
+ /*
+  * ckubnu.c -- set call parameters from the SVR2 database files
+  *
+  * A quick hack to make the dial command more convenient on systems with the
+  * HoneyDanBer UUCP database files available, by Eric S. Raymond (eric@snark).
+  * This code is released to the public domain, do with it what ye will.
+  *
+  * Theory: call bnuset() on the argument of a dial command before doing
+  * anything else. If the dial argument matches a system name in the UUCP
+  * database, the code will try to set speed, line, and modem-type properly;
+  * and bnuset() will modify its argument into the telephone number of the
+  * calling system.
+  *
+  * Implementation: mine all the stuff out of the Systems and Devices files,
+  * then write corresponding kermit commands to a disappearing take-file. This
+  * way we get all of kermit's normal command checking and debug options for
+  * free.
+  *
+  * Bugs: we don't interpret dialcodes. Nor do we use the Dialers file, which
+  * would make us independent of the hardwired modem-type cruft in ckudia.c.
+  * Like I said, this is a quick hack.
+  */
+ #ifdef SVR2
+ #include "ckcdeb.h"
+ #include "ckcker.h"
+ #include "ckuusr.h"
+ #include <stdio.h>
+ #include <ctype.h>
+ #include <string.h>
+ 
+ #define SYSTEMS	"/usr/lib/uucp/Systems"
+ #define DEVICES	"/usr/lib/uucp/Devices"
+ #define WSPC	"\t\n "
+ 
+ static char *
+ findline(key, qual, file)
+ /* find a line in the given file beginning with the given word, if any */
+ char	*key;
+ char	*qual;
+ char	*file;
+ {
+     char	buf[BUFSIZ], *cp;
+     FILE	*fp;
+ 
+ 	if ((fp = fopen(file, "r")) != (FILE *)NULL)
+ 	    while (fgets(buf, BUFSIZ, fp) != (char *)NULL)
+ 	    {
+ 		char	*sys;
+ 		int	foundqual = (qual == (char *)NULL);
+ 
+ 		/* skip comments */
+ 		if (cp = strchr(buf, '#'))
+ 		    *cp = '\0';
+ 
+ 		/* check that qual is present somewhere on the line */
+ 		if (!foundqual)
+ 		    for (cp = buf; *cp; cp++)
+ 			if (*cp == *qual && !strncmp(cp, qual, strlen(qual)))
+ 			{
+ 			    foundqual = 1;
+ 			    break;
+ 			}
+ 
+ 		/* if it is and the first token matches sys, jackpot! */
+ 		sys = strtok(buf, "\t ");
+ 		if (foundqual && (sys != (char *)NULL) && !strcmp(sys, key))
+ 		    return(buf);
+ 	    }
+ 
+ 	return((char *)NULL);
+ }
+ 
+ bnuset(telnbr)
+ char *telnbr;
+ {
+     char	*sysentry, *device, *cp, speedtok[BUFSIZ], devtok[BUFSIZ];
+     int		nspeed;
+ 
+ 	if (!isdigit(telnbr[0])
+ 		&& (sysentry = findline(telnbr, (char *)NULL, SYSTEMS)))
+ 	{
+ 	    (void) strtok((char *)NULL, WSPC);	/* skip call time */
+ 	    if (device = strtok((char*)NULL, WSPC))
+ 	    {
+ 		/* we'll deal with the device type below */
+ 		(void) strcpy(devtok, device);
+ 
+ 		/* look for the line speed field */
+ 		if (cp = strtok((char*)NULL, WSPC))
+ 		{
+ 		    /* set speed from this field */
+ 		    (void) strcpy(speedtok, cp);
+ 		    nspeed = atoi(cp);
+ 
+ 		    if (cp = strtok((char*)NULL, WSPC))
+ 		    {
+ 			/*
+ 			 * Set phone number from this field.
+ 			 * Someday, do Dialcodes processing here.
+ 			 */
+ 			(void) strcpy(telnbr, cp);
+ 
+ 			/* feed the rest of the line to script, maybe? */
+ 		    }
+ 		}
+ 
+ 		/* O.K., look for a devtype/speed match in DEVICES */
+ 		if ((device = findline(devtok,speedtok,DEVICES)) !=(char*)NULL)
+ 		{
+ 		    /* look for the device field */
+ 		    if (cp = strtok((char*)NULL, WSPC))
+ 		    {
+ 			extern char cmdbuf[], ttname[];
+ 			extern int speed, local, mdmtyp;
+ 			char fullname[BUFSIZ];
+ 			int	x;
+ 
+ 			/* it's field 2 */
+ 			(void) sprintf(fullname, "/dev/%s", cp);
+ 			if (ttopen(fullname,&x,mdmtyp) < 0 ) 
+ 			    perror("Sorry, can't open line");
+ 			else
+ 			{
+ 			    local = 1;
+ 			    (void) strcpy(ttname,fullname);
+ 			    debug(F111,"set line ",ttname,local);
+ 			    /*
+ 			     * Since we found a device, set speed too.
+ 			     * We found it in Devices, so assume it's valid.
+ 			     */
+ 			    speed = nspeed;
+ 			}
+ 
+ 			/* skip field 3, don't know what it's good for */
+ 			(void) strtok((char *)NULL, WSPC);
+ 
+ 			/* skip field 4, it's just the speed qualifier */
+ 			(void) strtok((char *)NULL, WSPC);
+ 
+ 			/* now set the modem type from field 5 */
+ 			if (cp = strtok((char *)NULL, WSPC))
+ 			{
+ 			    extern struct keytab mdmtab[];
+ 			    extern int nmdm;
+ 
+ 			    mdmtyp = lookup(mdmtab,cp,nmdm,&x);
+ 			}
+ 		    }
+ 		}
+ 	    }
+ 	}
+ }
+ #endif /* SVR2 */
*** ckucmd.h-old	Thu Nov 17 17:54:32 1988
--- ckucmd.h	Thu Nov 17 17:58:38 1988
***************
*** 9,14 ****
--- 9,20 ----
   copyright notice is retained.
  */
   
+ #ifdef SVR2
+ typedef void	catch_t;
+ #else
+ typedef int	catch_t;
+ #endif
+ 
  /* Special getchars... */
   
  #ifdef vax11c
*** ckudia.c-old	Thu Nov 17 11:33:43 1988
--- ckudia.c	Sat Nov 19 21:50:38 1988
***************
*** 441,448 ****
  
  static jmp_buf sjbuf;
  
! static int (*savAlrm)();	/* for saving alarm handler */
! static int (*savInt)();		/* for saving interrupt handler */
  
  dialtime() {			/* timer interrupt handler */
      longjmp( sjbuf, F_time );
--- 441,448 ----
  
  static jmp_buf sjbuf;
  
! static catch_t (*savAlrm)();	/* for saving alarm handler */
! static catch_t (*savInt)();	/* for saving interrupt handler */
  
  dialtime() {			/* timer interrupt handler */
      longjmp( sjbuf, F_time );
***************
*** 512,517 ****
--- 512,521 ----
      int n, n1;
      char *pc;		/* pointer to a character */
  
+ #ifdef SVR2
+ 	bnuset(telnbr);	/* try to set parameters from the SVR2 files */
+ #endif /* SVR2 */
+ 
  	if (!mdmtyp) {
  	    printf("Sorry, you must 'set modem' first\n");
  	    return(-2);
***************
*** 537,543 ****
  
  					/* interdigit waits for tone dial */
  /* ...dial, cont'd */
- 
  
  	waitct = 1*strlen(telnbr) ;	/* compute time to dial worst case */
  	waitct += pmdminf->dial_time;	/* dialtone + completion wait times */
--- 541,546 ----
*** ckuscr.c-old	Thu Nov 17 11:09:45 1988
--- ckuscr.c	Thu Nov 17 18:33:38 1988
***************
*** 32,37 ****
--- 32,38 ----
  #include <signal.h>
  #include <setjmp.h>
  #include "ckcker.h"
+ #include "ckucmd.h"
  
  extern int local, speed, flow, seslog, mdmtyp;
  extern char ttname[];
***************
*** 217,223 ****
  
  login(cmdstr) char *cmdstr; {
  
! 	int (*saveAlm)();	/* save incomming alarm function */
  	char *e;
  
  	s = cmdstr;			/* make global to ckuscr.c */
--- 218,224 ----
  
  login(cmdstr) char *cmdstr; {
  
! 	catch_t (*saveAlm)();	/* save incoming alarm function */
  	char *e;
  
  	s = cmdstr;			/* make global to ckuscr.c */
*** ckuusr.c-old	Thu Nov 17 12:14:47 1988
--- ckuusr.c	Thu Nov 17 20:51:16 1988
***************
*** 1042,1048 ****
      else {				/* Parent */
   
      	int wstat;			/* Kermit must wait for child */
! 	int (*istat)(), (*qstat)();
   
  	istat = signal(SIGINT,SIG_IGN);	/* Let the fork handle keyboard */
  	qstat = signal(SIGQUIT,SIG_IGN); /* interrupts itself... */
--- 1042,1048 ----
      else {				/* Parent */
   
      	int wstat;			/* Kermit must wait for child */
! 	catch_t (*istat)(), (*qstat)();
   
  	istat = signal(SIGINT,SIG_IGN);	/* Let the fork handle keyboard */
  	qstat = signal(SIGQUIT,SIG_IGN); /* interrupts itself... */
-- 
      Eric S. Raymond                     (the mad mastermind of TMN-Netnews)
      Email: eric@snark.uu.net                       CompuServe: [72037,2306]
      Post: 22 S. Warren Avenue, Malvern, PA 19355      Phone: (215)-296-5718