[8608] in Athena Bugs

home help back first fref pref prev next nref lref last post

a few bugfixes for xzwrite

daemon@ATHENA.MIT.EDU (Barr3y Jaspan)
Fri Nov 15 18:35:42 1991

Date: Fri, 15 Nov 91 18:35:43 -0500
From: "Barr3y Jaspan" <bjaspan@Athena.MIT.EDU>
To: bugs@Athena.MIT.EDU


I just made a few bugfixes for xzwrite.  The source in the Zephyr
locker has already been fixed (under RCS, obviously) but here are the
patches anyway.  The changes are:

o If no destinations are specified, assume a single destination of
"..." instead of aborting.  (The program should run without any
particular dotfiles available.)

o Use jtkohl's "unsubscription" feature for destination lists.

o putenv() is used instead of setenv() if USE_PUTENV is defined;
this is necessary under SunOs 4.something.  This should probably be
controlled from config.Imakefile.

o "Unexpected" notices caused by a zlocate bug in the Zephyr
library are specifically ignored unless xzwrite is in debug mode.
Also, the "unexpected notice" message has been made more friendly,
since it was scaring users.

o Use gecos information for the signature if neither zwrite-signature
nor xzwrite-signature is defined; this code was taken from zwrite.

o The man page has been updated to reflect these changes.

Most of these changes qualify as "trivial" (the non-trivial ones were
already done, and I just merged them in), but they have not been
significantly tested nor audited.

Barry

--- snip snip ---

*** /tmp/,RCSt1a19695	Fri Nov 15 17:56:03 1991
--- destlist.c	Fri Nov 15 17:53:46 1991
***************
*** 78,86 ****
       if (defs.read_anyone)
  	  _get_default_dest(ANYONE_FILE);
  
!      if (DynSize(dests) == 0)
! 	  Error("No destinations specified", NULL);
  
       sort_destinations();
       return ((char **) DynGet(dests, 0));
  }
--- 78,96 ----
       if (defs.read_anyone)
  	  _get_default_dest(ANYONE_FILE);
  
!      if (DynSize(dests) == 0) {
! 	  char *def;
! 	  
! 	  Warning("XZwrite: No destinations specified, using default.",
! 		  NULL);
  
+ 	  def = (char *) Malloc(strlen("...") + 1, "adding default dests",
+ 				NULL);
+ 	  strcpy(def, "...");
+ 	  if (DynAdd(dests, (char *) &def) == DYN_NOMEM)
+ 	       Error("Out of memory adding default destinations.", NULL);
+      }
+ 
       sort_destinations();
       return ((char **) DynGet(dests, 0));
  }
***************
*** 218,229 ****
  	  return strcmp(s1, s2);
  }
  
  char **sort_destinations()
  {
!      char	**d;
  
       d = (char **) DynGet(dests, 0);
!      qsort(d, DynSize(dests), sizeof(char *), sort_dest_func);
       return d;
  }
  
--- 228,292 ----
  	  return strcmp(s1, s2);
  }
  
+ static int
+ binary_find_dest(key)
+ char *key;
+ {
+     register int low = 0, high = DynSize(dests), mid;
+     register int val;
+     register char **d;
+ 
+     d = (char **) DynGet(dests, 0);
+ 
+     /* do binary search */
+     while (low <= high) {
+ 	mid = (low + high) / 2;
+ 	val = sort_dest_func(&key, &d[mid]);
+ 	if (val < 0) {
+ 	    high = mid - 1;
+ 	} else if (val > 0) {
+ 	    low = mid + 1;
+ 	} else {
+ 	    return (mid);
+ 	}
+     }
+ 
+     return -1;
+ }
+ 
  char **sort_destinations()
  {
!      register char **d;
!      register int idx, idx2;
!      int dsiz = DynSize(dests);
  
       d = (char **) DynGet(dests, 0);
!      qsort(d, dsiz, sizeof(char *), sort_dest_func);
!      
!      for (idx = 0; idx < DynSize(dests);) {
! 	if (d[idx][0] == '!') {
! 	    /* unsubscription */
! 	    char *next = d[idx];
! 	    next++;
! 	    while ((idx2 = binary_find_dest(next)) >= 0) {
! 		/* found one to nuke */
! 		DynDelete(dests, idx2);
! 		if (idx2 <= idx) {
! 		    /* indexes shifted, so restart this pass. */
! 		    idx--;
! 		    if (idx <= 0)
! 			idx = 0;
! 		    continue;
! 		}
! 	    }
! 	    /* ok, no more to nuke from this one, so delete it and
! 	       move on. */
! 	    DynDelete(dests, idx);
! 	    continue;
! 	}
! 	/* nope, continue on to next unsub */
! 	idx++;
!      }
       return d;
  }
  
*** /tmp/,RCSt1a19701	Fri Nov 15 17:56:16 1991
--- interface.c	Fri Nov 15 17:54:21 1991
***************
*** 131,145 ****
  	  path1 = (char *) getenv("XFILESEARCHPATH");
  	  if (! path1) path1 = "";
  	  path2 = (char *) malloc(strlen(path1) +
  				  strlen(XZWRITE_SEARCH_PATHS) + 2);
! 	  if (path2 != NULL)
! 	    {
! 		sprintf(path2, "%s:%s", path1, XZWRITE_SEARCH_PATHS);
! 		setenv("XFILESEARCHPATH", path2, 1);
! 		free(path2);
! 	    }
       }
! 
       toplevel = XtVaAppInitialize(&app_con, "XZwrite", app_options,
  #if XtSpecificationRelease > 4
  				  num_options, argc, argv,
--- 131,153 ----
  	  path1 = (char *) getenv("XFILESEARCHPATH");
  	  if (! path1) path1 = "";
  	  path2 = (char *) malloc(strlen(path1) +
+ #ifdef USE_PUTENV
+ 				  strlen("XFILESEARCHPATH=") +
+ #endif
  				  strlen(XZWRITE_SEARCH_PATHS) + 2);
! 	  if (path2 != NULL) {
! #ifdef USE_PUTENV
! 	       sprintf(path2, "XFILESEARCHPATH=%s:%s", path1,
! 		       XZWRITE_SEARCH_PATHS);
! 	       putenv(path2);
! #else
! 	       sprintf(path2, "%s:%s", path1, XZWRITE_SEARCH_PATHS);
! 	       setenv("XFILESEARCHPATH", path2, 1);
! 	       free(path2);
! #endif
! 	  }
       }
!      
       toplevel = XtVaAppInitialize(&app_con, "XZwrite", app_options,
  #if XtSpecificationRelease > 4
  				  num_options, argc, argv,
*** /tmp/,RCSt1a19706	Fri Nov 15 17:56:35 1991
--- zephyr.c	Fri Nov 15 17:54:44 1991
***************
*** 28,39 ****
  	      (! strcmp(notice.z_opcode, "USER_LOGIN") ||
  	       ! strcmp(notice.z_opcode, "USER_LOGOUT")))
  	       logins_deal(&notice);
  	  else if (defs.auto_reply &&
  		   ! strcasecmp(notice.z_class, DEFAULT_CLASS) &&
  		   ! strcasecmp(notice.z_recipient, ZGetSender()))
  	       dest_add_reply(&notice);
! 	  else {
! 	       Warning("Invalid notice.\n", "To: <", notice.z_class, ", ",
  		       notice.z_class_inst, ", ", (*notice.z_recipient) ?
  		       notice.z_recipient : "*", ">\n",
  		       "From: ", notice.z_sender, "\nOpcode: ",
--- 28,45 ----
  	      (! strcmp(notice.z_opcode, "USER_LOGIN") ||
  	       ! strcmp(notice.z_opcode, "USER_LOGOUT")))
  	       logins_deal(&notice);
+ 
  	  else if (defs.auto_reply &&
  		   ! strcasecmp(notice.z_class, DEFAULT_CLASS) &&
  		   ! strcasecmp(notice.z_recipient, ZGetSender()))
  	       dest_add_reply(&notice);
! 	  
! 	  /* Handle the zlocating bug the Zephyr library explicitly. */
! 	  /* Only display bogon zlocate packets in debug mode */
! 	  else if (strcmp(notice.z_class, LOCATE_CLASS) || defs.debug) {
! 	       Warning("XZwrite: Unexpected notice received.  ",
! 		       "You can probably ignore this.\n",
! 		       "To: <", notice.z_class, ", ",
  		       notice.z_class_inst, ", ", (*notice.z_recipient) ?
  		       notice.z_recipient : "*", ">\n",
  		       "From: ", notice.z_sender, "\nOpcode: ",
*** /tmp/,RCSt1a19805	Fri Nov 15 18:26:12 1991
--- xzwrite.c	Fri Nov 15 18:26:03 1991
***************
*** 1,4 ****
--- 1,5 ----
  #include <stdio.h>
+ #include <pwd.h>
  
  #include "xzwrite.h"
  
***************
*** 8,13 ****
--- 9,16 ----
     int	argc;
     char	**argv;
  {
+      char sigbfr[BUFSIZ];
+      
       zeph_init();
  
       build_interface(&argc, argv);
***************
*** 14,32 ****
  
       if (argc > 1) usage();
  
!      /* Do magic with signature */
!      if (! *defs.signature) {
! 	  char *sig;
! 
! 	  sig = (char *) zeph_get_signature();
! 	  if (sig) {
! 	       defs.signature = (char *) Malloc(strlen(sig) + 1,
! 						"getting signature",
! 						NULL);
! 	       strcpy(defs.signature, sig);
! 	  }
!      }
! 	 
       dest_init();
       yank_init();
       edit_win_init();
--- 17,23 ----
  
       if (argc > 1) usage();
  
!      set_signature();
       dest_init();
       yank_init();
       edit_win_init();
***************
*** 41,46 ****
--- 32,80 ----
  
       go();
  }
+ 
+ set_signature()
+ {
+      char *sig, sigbfr[BUFSIZ];
+      
+      /* Do magic with signature */
+      if (*defs.signature)
+ 	  return;
+ 
+      sig = (char *) zeph_get_signature();
+      if (!sig) {
+ 	  /* try to find name in the password file */
+ 	  register struct passwd *pwd;
+ 	  register char *cp = sigbfr;
+ 	  register char *cp2, *pp;
+ 	  
+ 	  pwd = getpwuid(getuid());
+ 	  if (pwd) {
+ 	       cp2 = pwd->pw_gecos;
+ 	       for (; *cp2 && *cp2 != ',' ; cp2++) {
+ 		    if (*cp2 == '&') {
+ 			 pp = pwd->pw_name;
+ 			 *cp++ = islower(*pp) ? toupper(*pp) : *pp;
+ 			 pp++;
+ 			 while (*pp)
+ 			      *cp++ = *pp++;
+ 		    } else
+ 			 *cp++ = *cp2;
+ 	       }
+ 	       *cp = '\0';
+ 	       sig = sigbfr;
+ 	  }
+      }	
+      
+      if (sig) {
+ 	  defs.signature = (char *) Malloc(strlen(sig) + 1,
+ 					   "getting signature",
+ 					   NULL);
+ 	  strcpy(defs.signature, sig);
+      }
+ }
+ 	 
+ 
  
  usage()
  {
*** /tmp/,RCSt1a19818	Fri Nov 15 18:32:09 1991
--- xzwrite.1	Fri Nov 15 18:31:55 1991
***************
*** 32,38 ****
  is taken to mean <MESSAGE,PERSONAL,string>; a line with one comma is
  taken to be either <class,instance,*> or <MESSAGE,instance,recipient>
  depending on the value of the classInst resource (see below); a line
! with two commas is taken to be <class,instance,recipient>.  The lines
  must appear
  .B WITHOUT WHITESPACE 
  between the fields and with a linefeed between each line.  Blank lines
--- 32,41 ----
  is taken to mean <MESSAGE,PERSONAL,string>; a line with one comma is
  taken to be either <class,instance,*> or <MESSAGE,instance,recipient>
  depending on the value of the classInst resource (see below); a line
! with two commas is taken to be <class,instance,recipient>.  A line
! that begins with an exclamation point (!) is treated as an
! "unsubscription" and has the effect of removing destinations read
! from any other file that match the destination on that line.  The lines
  must appear
  .B WITHOUT WHITESPACE 
  between the fields and with a linefeed between each line.  Blank lines
***************
*** 255,261 ****
  .I Xzwrite
  will also look in the user's .zephyr.vars file to a signature, first
  for the variable xzwrite-signature and then for the variable
! zwrite-signature.
  .TP
  .B +n (ping = true)
  .br
--- 258,266 ----
  .I Xzwrite
  will also look in the user's .zephyr.vars file to a signature, first
  for the variable xzwrite-signature and then for the variable
! zwrite-signature.  If neither is found, 
! .I Xzwrite
! will look in the /etc/passwd file for the user's name.
  .TP
  .B +n (ping = true)
  .br
***************
*** 372,377 ****
--- 377,385 ----
  /usr/sipb/lib/app-defaults/XZwrite
  Xzwrite program defaults
  .TP
+ /etc/passwd
+ Signature field (from gecos information)
+ .TP
  ~/.Xresources
  user X resources database file
  .TP
***************
*** 395,400 ****
  
  .SH AUTHOR
  
! Written by Barr3y Jaspan (bjaspan@athena.mit.edu), MIT Project Athena
! and MIT Student Information Processing Board, for X11R4, the X
! Toolkit, and the Athena Widgets.
--- 403,407 ----
  
  .SH AUTHOR
  
! Written by Barry Jaspan (bjaspan@mit.edu), MIT Project Athena
! and MIT Student Information Processing Board.



home help back first fref pref prev next nref lref last post