Net2/usr/src/contrib/isode/others/quipu/uips/fred/mh-patches

[ mh-patches - Tue Jul 18 00:47:38 1989 - WP patches to MH - /mtr ]


Here are patches to MH 6.5 to allow send/whom to expand names into addresses.

	NOTE WELL: These are very different from the patches supplied earlier
	in the file MH-patches.  You should revert your MH sources back to
	their original condition and then apply the patches here...

     The user specifies a name by bracketing a WhitePages query between
     '<<' and '>>' using the user-friendly naming syntax, e.g.,

	To: << rose, psi, us >>

     At the "What now?" prompt, the user can say "whom" to have the
     names expanded into addresses.  Alternately, the "send" option can
     be used as well.  For each query appearing between '<<' and '>>',
     the DA-server will be asked to perform a white pages resolution.  All
     matches are printed and the user is asked to select one.  If one is
     not selected, the user returns to what-now level.

     Note that expansion can occur only if whom/send is invoked
     interactively.  If you use push, then the expansion will fail
     because the DA-server will be unable to query you to select/confirm the
     right entry to use for the substitution.

     To enable these patches, add

	options WP

    to your MH config file, run mhconfig, apply the patches, and then
    do "make" from the top-level.  Note that this code will not work if you
    have

	options	BERK

     in your config file.  Specifying this option will disable the WP option.

     Finally, you must run a DA-server.  The Administrator's Guide says
     how to do this.  Basically:

	1. start /usr/etc/dad from /etc/rc.local

	2. (optionally) add

		set server hostname

	   to your /usr/etc/fredrc file, where "hostname" is the
	   domain-name or IP-address of the machine running dad.

	3. tell your MH users to add

		da-server: hostname

	   to their MH profile.

/mtr
cd /wp2/home/src/uci/mh-6.6
diff -c sbr/addrsbr.c.orig		sbr/addrsbr.c
diff -c sbr/m_whatnow.c.orig		sbr/m_whatnow.c
diff -c uip/post.c.orig			uip/post.c
diff -c uip/whatnowsbr.c.orig		uip/whatnowsbr.c
diff -c uip/whom.c.orig			uip/whom.c
diff -c zotnet/mf/mf.c.orig		zotnet/mf/mf.c
diff -c zotnet/mts/client.c.orig	zotnet/mts/client.c

*** sbr/addrsbr.c.orig	Thu Jan 10 02:12:32 1991
--- sbr/addrsbr.c	Thu Jan 10 03:53:04 1991
***************
*** 4,12 ****
  #include "../h/addrsbr.h"
  #include "../zotnet/mf.h"
  #include <stdio.h>
! #ifdef	BERK
  #include <ctype.h>
! #endif	BERK
  
  /* High level parsing of addresses:
  
--- 4,12 ----
  #include "../h/addrsbr.h"
  #include "../zotnet/mf.h"
  #include <stdio.h>
! #if	defined(BERK) || defined(WP)
  #include <ctype.h>
! #endif
  
  /* High level parsing of addresses:
  
***************
*** 103,108 ****
--- 103,117 ----
  
  char   *getusr ();
  
+ 
+ #ifdef	BERK
+ #undef	WP
+ #endif
+ 
+ #ifdef	WP
+ int	do_wp = 0;
+ #endif
+ 
  /*  */
  
  char   *getname (addrs)
***************
*** 824,826 ****
--- 833,1211 ----
  
      return 0;
  }
+ 
+ /*  */
+ 
+ #ifdef	WP
+ #include <setjmp.h>
+ #include <signal.h>
+ #include <sys/ioctl.h>
+ 
+ 
+ static	char	das_response[BUFSIZ];
+ static	char	das_host[BUFSIZ];
+ static	char	das_port[BUFSIZ];
+ 
+ static	FILE   *das_input = NULL;
+ static	FILE   *das_output;
+ 
+ static	int	armed = 0;
+ static	int	interrupted;
+ static	jmp_buf	intrenv;
+ 
+ int	intrser ();
+ 
+ 
+ extern	int	errno;
+ 
+ /*  */
+ 
+ char   *wp_expand (query, error)
+ char   *query,
+        *error;
+ {
+     int	    result,
+ 	  (*istat) ();
+     char    buffer[BUFSIZ];
+ 
+     if (error)
+ 	(void) strcpy (error, "unable to expand WhitePages query: ");
+ 
+     if (!isatty (fileno (stdout))) {
+ 	if (error)
+ 	    (void) strcat (error, "not a tty");
+ 
+ 	return NULLCP;
+     }
+ 
+     if (das_input == NULL && das_init () == NOTOK) {
+ 	if (error)
+ 	    (void) strcat (error, das_response);
+ 
+ 	return NULLCP;
+     }
+ 
+     fprintf (stderr, "\n[ Expanding %s ]\n", query);
+     (void) fflush (stderr);
+ 
+     (void) sprintf (buffer, "fred -ufn -mailbox,%s", query);
+ 
+     setsigx (istat, SIGINT, intrser);
+     interrupted = 0;
+     
+     result = das_lookup (buffer);
+ 
+     (void) signal (SIGINT, istat);
+ 
+     if (result == NOTOK) {
+ 	if (error)
+ 	    (void) strcat (error, das_response);
+ 
+ 	return NULLCP;
+     }
+ 
+     if (error)
+ 	error[0] = NULL;
+     return (getcpy (das_response));
+ }
+ 
+ /*  */
+ 
+ static int  das_init ()
+ {
+     int	    fd1,
+     	    fd2;
+     char  *daserver = m_find ("da-server");
+ 
+     if (!daserver && !(daserver = getenv ("DA-SERVER"))) {
+ 	(void) strcpy (das_response, "no entry for DA-server in MH-profile");
+ 	return NOTOK;
+     }
+ 
+     if ((fd1 = client (daserver, "tcp", "411", 0, das_response)) == NOTOK)
+ 	return NOTOK;
+     (void) ioctl (fd1, FIOCLEX, NULLCP);
+ 
+     if ((fd2 = dup (fd1)) == NOTOK) {
+ 	(void) sprintf (das_response,
+ 			"unable to dup connection descriptor: Errno %d",
+ 			errno);
+ 	(void) close (fd1);
+ 	return NOTOK;
+     }
+     (void) ioctl (fd2, FIOCLEX, NULLCP);
+ 
+     if ((das_input = fdopen (fd1, "r")) == NULL
+ 	    || (das_output = fdopen (fd2, "w")) == NULL) {
+ 	(void) strcpy (das_response, "fdopen failed on connection descriptor");
+ 	if (das_input)
+ 	    (void) fclose (das_input), das_input = NULL;
+ 	else
+ 	    (void) close (fd1);
+ 	(void) close (fd2);
+ 	return NOTOK;
+     }
+ 
+     (void) signal (SIGPIPE, SIG_IGN);
+ 
+     switch (getline (das_response, sizeof das_response, das_input)) {
+ 	case OK: 
+ 	    if (*das_response == '+') {
+ 		int     a[5];
+ 		
+ 		if (sscanf (das_response + sizeof "+OK " - 1,
+ 			    "%d.%d.%d.%d %u", a, a + 1, a + 2, a + 3, a + 4)
+ 		        != 5) {
+ 		    (void) strcpy (das_host, das_response);
+ 		    (void) sprintf (das_response,
+ 				    "malformed response from DA-server (%s)",
+ 				    das_host);
+ 		    goto losing;
+ 		}
+ 		(void) sprintf (das_host, "%d.%d.%d.%d",
+ 				a[0], a[1], a[2], a[3]);
+ 		(void) sprintf (das_port, "%u", a[4]);
+ 
+ 		return OK;
+ 	    }
+ 	    /* else fall... */
+ 
+ 	case NOTOK: 
+ 	case DONE: 
+ losing: ;
+ 	    (void) fclose (das_input);
+ 	    (void) fclose (das_output);
+ 	    das_input = das_output = NULL;
+ 	    return NOTOK;
+     }
+ /* NOTREACHED */
+ }
+ 
+ /*  */
+ 
+ static int das_lookup (who)
+ char   *who;
+ {
+     int	    fd1,
+ 	    fd2;
+     FILE   *in,
+ 	   *out;
+ 
+     if ((fd1 = client (das_host, "tcp", das_port, 0, das_response)) == NOTOK) {
+ losing: ;
+ 	(void) fclose (das_input);
+ 	(void) fclose (das_output);
+ 	das_input = das_output = NULL;
+ 	return NOTOK;
+     }
+ 
+     if ((fd2 = dup (fd1)) == NOTOK) {
+ 	(void) sprintf (das_response,
+ 			"unable to dup connection descriptor: Errno %d",
+ 			errno);
+ 	(void) close (fd1);
+ 	goto losing;
+     }
+ 
+     if ((in = fdopen (fd1, "r")) == NULL
+ 	    || (out = fdopen (fd2, "w")) == NULL) {
+ 	(void) strcpy (das_response, "fdopen failed on connection descriptor");
+ 	if (in)
+ 	    (void) fclose (in);
+ 	else
+ 	    (void) close (fd1);
+ 	(void) close (fd2);
+ 	goto losing;
+     }
+     
+     if (putline (who, out) == NOTOK) {
+ real_losing: ;
+ 	(void) fclose (in);
+ 	(void) fclose (out);
+ 	goto losing;
+     }
+ 
+     for (;;) {
+ 	char	c,
+ 		input[BUFSIZ];
+ 
+ 	if (getline (input, sizeof input, in) != OK)
+ 	    goto real_losing;
+ 
+ 	switch (c = input[0]) {
+ 	    case 'm':
+ 		fprintf (stdout, "\n%s\n", input + 1);
+ 		(void) strcpy (input, "m");
+ 		goto stuff_it;
+ 
+ 	    case 'y':
+ 		fprintf (stdout, "%s", input + 1);
+ 		(void) fflush (stdout);
+ 		switch (yesno ()) {
+ 		    case DONE:
+ 		        (void) strcpy (das_response, "interrupted");
+ 			goto real_losing;
+ 
+ 		    case NOTOK:
+ 		    default:
+ 			input[0] = 'n';
+ 			break;
+ 
+ 		    case OK:
+ 			input[0] = 'y';
+ 			break;
+ 		}
+ 		input[1] = NULL;
+ stuff_it: ;
+ 		if (putline (input, out) == NOTOK)
+ 		    goto real_losing;
+ 		continue;
+ 
+ 	    case 'e':
+ 	    case 'p':
+ 	    case 'L':
+ 	    case 'l':
+ 	    case 'd':
+ unexpected: ;
+ 		(void) sprintf (das_response,
+ 				"unexpected response from DAP-listener: %c",
+ 				c);
+ 		goto real_losing;
+ 
+ 	    case '1':
+ 		(void) strcpy (das_response, input + 1);
+ 		(void) fclose (in);
+ 		(void) fclose (out);
+ 		return OK;
+ 
+ 	    case '2':
+ 		(void) strcpy (das_response, input + 1);
+ 		goto real_losing;
+ 
+ 	    default:
+ 		if (isdigit (c))
+ 		    goto unexpected;
+ 
+ 		(void) sprintf (das_response,
+ 				"unknown response from DAP-listener: %c", c);
+ 		goto real_losing;
+ 	}
+     }
+ }
+ 
+ /*  */
+ 
+ static int  getline (s, n, iop)
+ char   *s;
+ int     n;
+ FILE * iop;
+ {
+     int     c;
+     char   *p;
+ 
+     p = s;
+     while (--n > 0 && (c = fgetc (iop)) != EOF)
+ 	if ((*p++ = c) == '\n')
+ 	    break;
+     if (ferror (iop) && c != EOF) {
+ 	(void) strcpy (das_response, "error on connection");
+ 	return NOTOK;
+     }
+     if (c == EOF && p == s) {
+ 	(void) strcpy (das_response, "connection closed by foreign host");
+ 	return DONE;
+     }
+     *p = NULL;
+     if (*--p == '\n')
+ 	*p = NULL;
+     if (*--p == '\r')
+ 	*p = NULL;
+ 
+     return OK;
+ }
+ 
+ 
+ static  putline (s, iop)
+ char   *s;
+ FILE * iop;
+ {
+     (void) fprintf (iop, "%s\n", s);
+     (void) fflush (iop);
+     if (ferror (iop)) {
+ 	(void) strcpy (das_response, "lost connection");
+ 	return NOTOK;
+     }
+ 
+     return OK;
+ }
+ 
+ /*  */
+ 
+ static int  yesno () {
+     int     x,
+             y,
+             result;
+ 
+     if (interrupted) {
+ 	interrupted = 0;
+ 	return DONE;
+     }
+ 
+     switch (setjmp (intrenv)) {
+ 	case OK: 
+ 	    armed++;
+ 	    break;
+ 
+ 	case NOTOK: 
+ 	default: 
+ 	    printf ("\n");
+ 	    armed = 0;
+ 	    return DONE;
+     }
+     
+ again: ;
+     x = y = getc (stdin);
+     while (y != '\n' && y != EOF)
+ 	y = getc (stdin);
+ 
+     switch (x) {
+ 	case 'y': 
+ 	case '\n':
+ 	    result = OK;
+ 	    break;
+ 
+ 	case 'n': 
+ 	    result = NOTOK;
+ 	    break;
+ 
+ 	case EOF: 
+ 	    result = DONE;
+ 	    clearerr (stdin);
+ 	    break;
+ 
+ 	default: 
+ 	    printf ("Please type 'y' or 'n': ");
+ 	    goto again;
+     }
+ 
+     armed = 0;
+ 
+     return result;
+ }
+ 
+ 
+ /* ARGSUSED */
+ 
+ static int  intrser (i)
+ int	i;
+ {
+ #ifndef	BSD42
+     (void) signal (SIGINT, intrser);
+ #endif
+ 
+     if (armed)
+ 	longjmp (intrenv, NOTOK);
+ 
+     interrupted++;
+ }
+ #endif
*** sbr/m_whatnow.c.orig	Thu Oct 29 15:00:45 1987
--- sbr/m_whatnow.c	Thu Jan 10 02:46:15 1991
***************
*** 27,32 ****
--- 27,34 ----
      vec[vecp++] = r1bindex (whatnowproc, '/');
      vec[vecp] = NULL;
  
+     if (bp = m_find ("da-server"))
+ 	(void) putenv ("DA-SERVER", bp);
      (void) putenv ("mhdraft", file);
      if (mp)
  	(void) putenv ("mhfolder", mp -> foldpath);
*** uip/post.c.orig	Thu Jan 10 02:14:15 1991
--- uip/post.c	Wed Jan  9 14:26:56 1991
***************
*** 122,127 ****
--- 122,130 ----
  #define	SNOOPSW	29
      "snoop", -5,
  
+ #define	FILLSW	30
+     "fill-in file", -7,
+ 
      NULL, NULL
  };
  
***************
*** 284,289 ****
--- 287,302 ----
  static int  encryptsw = 0;	/* encrypt it */
  
  
+ #ifdef	BERK
+ #undef	WP
+ #endif
+ 
+ #ifdef	WP
+ extern int	do_wp;		/* fill-in white pages queries */
+ #endif
+ static char    *fill_in = NULLCP;
+ 
+ 
  long	lseek (), time ();
  
  /*    MAIN */
***************
*** 486,491 ****
--- 499,511 ----
  		    snoop++;
  		    continue;
  #endif	SENDMTS
+ 
+ 		case FILLSW:
+ #ifdef	WP
+ 		    if (!(fill_in = *argp++) || *fill_in == '-')
+ 			adios (NULLCP, "missing argument to %s", argp[-2]);
+ #endif
+ 		    continue;
  	    }
  	if (msg)
  	    adios (NULLCP, "only one message at a time!");
***************
*** 494,499 ****
--- 514,522 ----
      }
  
      (void) alias (AliasFile);
+ #ifdef	WP
+     do_wp++;
+ #endif
  
  /*  */
  
***************
*** 534,540 ****
      else
  #endif	MHMTS
  	if (whomsw) {
! 	    if ((out = fopen ("/dev/null", "w")) == NULL)
  		adios ("/dev/null", "unable to open");
  	}
  	else {
--- 557,563 ----
      else
  #endif	MHMTS
  	if (whomsw) {
! 	    if ((out = fopen (fill_in ? fill_in : "/dev/null", "w")) == NULL)
  		adios ("/dev/null", "unable to open");
  	}
  	else {
***************
*** 575,581 ****
  	    case BODY: 
  	    case BODYEOF: 
  		finish_headers (out);
! 		if (whomsw)
  		    break;
  		fprintf (out, "\n%s", buf);
  		while (state == BODY) {
--- 598,604 ----
  	    case BODY: 
  	    case BODYEOF: 
  		finish_headers (out);
! 		if (whomsw && !fill_in)
  		    break;
  		fprintf (out, "\n%s", buf);
  		while (state == BODY) {
***************
*** 699,709 ****
      }
  
      hdr = &hdrtab[i];
!     if (hdr -> flags & HIGN)
  	return;
      if (hdr -> flags & HBAD) {
! 	advise (NULLCP, "illegal header line -- %s:", name);
! 	badmsg++;
  	return;
      }
      msgflags |= (hdr -> set & ~(MVIS | MINV));
--- 722,739 ----
      }
  
      hdr = &hdrtab[i];
!     if (hdr -> flags & HIGN) {
! 	if (fill_in)
! 	    fprintf (out, "%s: %s", name, str);
  	return;
+     }
      if (hdr -> flags & HBAD) {
! 	if (fill_in)
! 	    fprintf (out, "%s: %s", name, str);
! 	else {
! 	    advise (NULLCP, "illegal header line -- %s:", name);
! 	    badmsg++;
! 	}
  	return;
      }
      msgflags |= (hdr -> set & ~(MVIS | MINV));
***************
*** 711,716 ****
--- 741,751 ----
      if (hdr -> flags & HSUB)
  	subject = subject ? add (str, add ("\t", subject)) : getcpy (str);
      if (hdr -> flags & HFCC) {
+ 	if (fill_in) {
+ 	    fprintf (out, "%s: %s", name, str);
+ 	    return;
+ 	}
+ 
  	if (cp = rindex (str, '\n'))
  	    *cp = NULL;
  	for (cp = pp = str; cp = index (pp, ','); pp = cp) {
***************
*** 759,765 ****
  
      nameoutput = linepos = 0;
      (void) sprintf (namep, "%s%s",
! 	    (hdr -> flags & HMNG) ? "Original-" : "", name);
  
      for (grp = 0, mp = tmpaddrs.m_next; mp; mp = np)
  	if (mp -> m_nohost) {	/* also used to test (hdr -> flags & HTRY) */
--- 794,801 ----
  
      nameoutput = linepos = 0;
      (void) sprintf (namep, "%s%s",
! 		    !fill_in && (hdr -> flags & HMNG) ? "Original-" : "",
! 		    name);
  
      for (grp = 0, mp = tmpaddrs.m_next; mp; mp = np)
  	if (mp -> m_nohost) {	/* also used to test (hdr -> flags & HTRY) */
***************
*** 810,817 ****
  	advise (NULLCP, "%s: field does not allow groups", name);
  	badmsg++;
      }
!     if (linepos)
  	(void) putc ('\n', out);
  }
  
  /*  */
--- 846,856 ----
  	advise (NULLCP, "%s: field does not allow groups", name);
  	badmsg++;
      }
!     if (linepos) {
! 	if (fill_in && grp > 0)
! 	    (void) putc (';', out);
  	(void) putc ('\n', out);
+     }
  }
  
  /*  */
***************
*** 942,948 ****
  
      if (mp -> m_mbox == NULL || ((flags & HTRY) && !insert (mp)))
  	return 0;
!     if ((flags & HBCC) || mp -> m_ingrp)
  	return 1;
  
      if (!nameoutput) {
--- 981,987 ----
  
      if (mp -> m_mbox == NULL || ((flags & HTRY) && !insert (mp)))
  	return 0;
!     if (!fill_in && ((flags & HBCC) || mp -> m_ingrp))
  	return 1;
  
      if (!nameoutput) {
***************
*** 953,959 ****
      if (*aka && mp -> m_type != UUCPHOST && !mp -> m_pers)
  	mp -> m_pers = getcpy (aka);
      if (format) {
! 	if (mp -> m_gname)
  	    (void) sprintf (cp = buffer, "%s;", mp -> m_gname);
  	else
  	    cp = adrformat (mp);
--- 992,998 ----
      if (*aka && mp -> m_type != UUCPHOST && !mp -> m_pers)
  	mp -> m_pers = getcpy (aka);
      if (format) {
! 	if (mp -> m_gname && !fill_in)
  	    (void) sprintf (cp = buffer, "%s;", mp -> m_gname);
  	else
  	    cp = adrformat (mp);
***************
*** 987,1004 ****
      int     len;
      char   *cp;
  
!     if (flags & HBCC)
  	return;
  
      if (!nameoutput) {
  	fprintf (out, "%s: ", name);
  	linepos += (nameoutput = strlen (name) + 2);
      }
  
!     cp = concat (group, ";", NULLCP);
      len = strlen (cp);
  
!     if (linepos != nameoutput)
  	if (len + linepos + 2 > outputlinelen) {
  	    fprintf (out, ",\n%*s", nameoutput, "");
  	    linepos = nameoutput;
--- 1026,1045 ----
      int     len;
      char   *cp;
  
!     if (!fill_in && (flags & HBCC))
  	return;
  
      if (!nameoutput) {
  	fprintf (out, "%s: ", name);
  	linepos += (nameoutput = strlen (name) + 2);
+ 	if (fill_in)
+ 	    linepos -= strlen (group);
      }
  
!     cp = fill_in ? group : concat (group, ";", NULLCP);
      len = strlen (cp);
  
!     if (linepos > nameoutput)
  	if (len + linepos + 2 > outputlinelen) {
  	    fprintf (out, ",\n%*s", nameoutput, "");
  	    linepos = nameoutput;
*** uip/whatnowsbr.c.orig	Thu Jan 10 02:14:55 1991
--- uip/whatnowsbr.c	Wed Jan  9 14:27:35 1991
***************
*** 6,11 ****
--- 6,16 ----
  #include <sys/types.h>
  #include <sys/stat.h>
  
+ 
+ #ifdef	BERK
+ #undef	WP
+ #endif
+ 
  /*  */
  
  static struct swit whatnowswitches[] = {
***************
*** 758,764 ****
--- 763,778 ----
      int     pid;
      register int    vecp;
      char   *vec[MAXARGS];
+ #ifdef	WP
+     char   *cp,
+ 	    draft[BUFSIZ],
+ 	    backup[BUFSIZ];
+ #endif
  
+ #ifdef	WP
+     (void) strcpy (draft, m_scratch (file, invo_name));
+ #endif
+ 
      m_update ();
      (void) fflush (stdout);
  
***************
*** 774,779 ****
--- 788,797 ----
  	    if (arg)
  		while (*arg)
  		    vec[vecp++] = *arg++;
+ #ifdef	WP
+ 	    vec[vecp++] = "-fill-in";
+ 	    vec[vecp++] = draft;
+ #endif
  	    vec[vecp] = NULL;
  
  	    execvp (whomproc, vec);
***************
*** 782,787 ****
--- 800,827 ----
  	    _exit (-1);		/* NOTREACHED */
  
  	default: 
+ #ifndef	WP
  	    return (pidwait (pid, NOTOK) & 0377 ? 1 : 0);
+ #else
+ 	    if (pidwait (pid, NOTOK)) {
+ 		(void) unlink (draft);
+ 		return 1;
+ 	    }
+ 	    break;
+ #endif
      }
+ 
+ #ifdef	WP
+     if (rename (file, cp = m_backup (file)) == NOTOK) {
+ 	advise (cp, "unable to rename %s to", file);
+ 	(void) unlink (draft);
+ 	return 1;
+     }
+     if (rename (draft, file) == NOTOK) {
+ 	advise (file, "unable to rename %s to ", draft);
+ 	return 1;
+     }
+ 
+     return 0;
+ #endif
  }
*** uip/whom.c.orig	Thu Jan 10 02:15:30 1991
--- uip/whom.c	Mon Jul 17 09:22:31 1989
***************
*** 35,40 ****
--- 35,43 ----
  #define	SNOOPSW	10
      "snoop", -5,
  
+ #define	FILLSW	11
+     "fill-in file", -7,
+ 
      NULL, NULL
  };
  
***************
*** 125,130 ****
--- 128,134 ----
  		case ALIASW: 
  		case CLIESW: 
  		case SERVSW: 
+ 		case FILLSW:
  		    vec[vecp++] = --cp;
  		    if (!(cp = *argp++) || *cp == '-')
  			adios (NULLCP, "missing argument to %s", argp[-2]);
*** zotnet/mf/mf.c.orig	Thu Jan 10 02:10:25 1991
--- zotnet/mf/mf.c	Wed Jan  9 14:27:34 1991
***************
*** 4,9 ****
--- 4,14 ----
  #include <ctype.h>
  #include <stdio.h>
  
+ 
+ #ifdef	BERK
+ #undef	WP
+ #endif
+ 
  /*  */
  
  static char *getcpy (s)
***************
*** 298,303 ****
--- 303,311 ----
  
  #define	QUOTE	'\\'
  
+ #ifdef	WP
+ #define	LX_WP	(-1)
+ #endif
  #define	LX_END	0
  #define	LX_ERR	1
  #define	LX_ATOM	2
***************
*** 351,361 ****
--- 359,380 ----
  
  static struct adrx  adrxs2;
  
+ 
+ #ifdef	WP
+ char   *concat ();
+ 
+ extern int	do_wp;
+ char   *wp_expand ();
+ #endif
+ 
  /*  */
  
  struct adrx *getadrx (addrs)
  register char   *addrs;
  {
+ #ifdef	WP
+     int	    save_lex;
+ #endif
      register char   *bp;
      register struct adrx *adrxp = &adrxs2;
  
***************
*** 385,390 ****
--- 404,432 ----
  	    return NULL;
  	}
  
+ #ifdef	WP
+     bp = cp, save_lex = last_lex;
+     if (my_lex (adr) == LX_WP) {
+ 	register char *ep,
+ 		      *fp;
+ 
+ 	if (fp = wp_expand (adr, err)) {
+ 	    *bp = NULL;
+ 	    ep = concat (dp, fp, cp, (char *) NULL);
+ 	    cp = ep + strlen (dp), last_lex = save_lex;
+ 	    free (dp);
+ 	    dp = ep;
+ 	    free (fp);
+ 	}
+ 	else {
+ 	    ap = bp, save_lex = last_lex;
+ 	    goto out;
+ 	}
+     }
+     else
+ 	cp = bp, last_lex = save_lex;
+ #endif
+ 
      switch (parse_address ()) {
  	case DONE:
  	    free (dp);
***************
*** 409,414 ****
--- 451,459 ----
  	    break;
  	}
  
+ #ifdef	WP
+ out: ;
+ #endif
      if (err[0])
  	for (;;) {
  	    switch (last_lex) {
***************
*** 798,803 ****
--- 843,863 ----
  	cp = NULL;
  	return (last_lex = LX_END);
      }
+ 
+ #ifdef	WP
+     if (do_wp && c == '<' && *cp == '<')
+ 	for (cp++;;)
+ 	    switch (c = *cp++) {
+ 		case '>':
+ 		    *bp = NULL;
+ 		    cp++;
+ 		    return (last_lex = LX_WP);
+ 
+ 		default:
+ 		    *bp++ = c;
+ 		    continue;
+ 	    }
+ #endif
  
      if (c == '(')
  	for (*bp++ = c, i = 0;;)
*** zotnet/mts/client.c.orig	Thu Jan 10 02:09:09 1991
--- zotnet/mts/client.c	Thu Jan 10 02:09:48 1991
***************
*** 50,55 ****
--- 50,56 ----
  static struct addrent *he, *hz;
  static struct addrent hosts[MAXHOSTS];
  
+ struct hostent *gethostbystring ();
  
  char *getcpy (), **brkstring (), **copyip ();
  
***************
*** 63,68 ****
--- 64,70 ----
  int	rproto;
  {
      int     sd;
+     unsigned int portno;
      register char **ap;
      char   *arguments[MAXARGS];
      register struct hostent *hp;
***************
*** 71,80 ****
  #endif	BIND
      register struct servent *sp;
  
!     if ((sp = getservbyname (service, protocol)) == NULL) {
! 	(void) sprintf (response, "%s/%s: unknown service", protocol, service);
! 	return NOTOK;
!     }
  
      ap = arguments;
      if (args != NULL && *args != NULL)
--- 73,86 ----
  #endif	BIND
      register struct servent *sp;
  
!     if (sp = getservbyname (service, protocol))
! 	portno = sp -> s_port;
!     else
! 	if (sscanf (service, "%u", &portno) != 1) {
! 	    (void) sprintf (response, "%s/%s: unknown service",
! 			    protocol, service);
! 	    return NOTOK;
! 	}
  
      ap = arguments;
      if (args != NULL && *args != NULL)
***************
*** 98,104 ****
  		while (hp = gethostent ())
  		    if (np -> n_addrtype == hp -> h_addrtype
  			    && inet (hp, np -> n_net)) {
! 			switch (sd = rcaux (sp, hp, rproto, response)) {
  			    case NOTOK: 
  				continue;
  			    case OOPS1: 
--- 104,110 ----
  		while (hp = gethostent ())
  		    if (np -> n_addrtype == hp -> h_addrtype
  			    && inet (hp, np -> n_net)) {
! 			switch (sd = rcaux (portno, hp, rproto, response)) {
  			    case NOTOK: 
  				continue;
  			    case OOPS1: 
***************
*** 116,123 ****
  	    continue;
  	}
  
! 	if (hp = gethostbyname (*ap)) {
! 	    switch (sd = rcaux (sp, hp, rproto, response)) {
  		case NOTOK: 
  		case OOPS1: 
  		    break;
--- 122,129 ----
  	    continue;
  	}
  
! 	if (hp = gethostbystring (*ap)) {
! 	    switch (sd = rcaux (portno, hp, rproto, response)) {
  		case NOTOK: 
  		case OOPS1: 
  		    break;
***************
*** 137,144 ****
  
  /*  */
  
! static int  rcaux (sp, hp, rproto, response)
! register struct servent *sp;
  register struct hostent *hp;
  int	rproto;
  register char *response;
--- 143,150 ----
  
  /*  */
  
! static int  rcaux (portno, hp, rproto, response)
! unsigned int portno;
  register struct hostent *hp;
  int	rproto;
  register char *response;
***************
*** 163,169 ****
  
      bzero ((char *) isock, sizeof *isock);
      isock -> sin_family = hp -> h_addrtype;
!     isock -> sin_port = sp -> s_port;
      bcopy (hp -> h_addr, (char *) &isock -> sin_addr, hp -> h_length);
  
      if (connect (sd, (struct sockaddr *) isock, sizeof *isock) == NOTOK)
--- 169,175 ----
  
      bzero ((char *) isock, sizeof *isock);
      isock -> sin_family = hp -> h_addrtype;
!     isock -> sin_port = portno;
      bcopy (hp -> h_addr, (char *) &isock -> sin_addr, hp -> h_length);
  
      if (connect (sd, (struct sockaddr *) isock, sizeof *isock) == NOTOK)
***************
*** 245,250 ****
--- 251,301 ----
  		return NOTOK;
  	}
      }
+ }
+ 
+ /*  */
+ 
+ #if	defined(BIND) && !defined(h_addr)
+ #define	h_addr	h_addr_list[0]
+ #endif
+ 
+     
+ static char *empty = NULL;
+ #ifdef	h_addr
+ static char *addrs[2] = { NULL };
+ #endif
+ 
+ struct hostent *gethostbystring (s)
+ char   *s;
+ {
+     register struct hostent *h;
+ #ifndef	DG
+     static u_long iaddr;
+ #else
+     static struct in_addr iaddr;
+ #endif
+     static struct hostent   hs;
+ 
+     iaddr = inet_addr (s);
+ #ifndef	DG
+     if (iaddr == NOTOK)
+ #else
+     if (iaddr.s_addr == NOTOK)
+ #endif
+ 	return gethostbyname (s);
+ 
+     h = &hs;
+     h -> h_name = s;
+     h -> h_aliases = &empty;
+     h -> h_addrtype = AF_INET;
+     h -> h_length = sizeof (iaddr);
+ #ifdef	h_addr
+     h -> h_addr_list = addrs;
+     bzero ((char *) addrs, sizeof addrs);
+ #endif
+     h -> h_addr = (char *) &iaddr;
+ 
+     return h;
  }
  
  /*  */