[8608] in Athena Bugs
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(¬ice);
else if (defs.auto_reply &&
! strcasecmp(notice.z_class, DEFAULT_CLASS) &&
! strcasecmp(notice.z_recipient, ZGetSender()))
dest_add_reply(¬ice);
! 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(¬ice);
+
else if (defs.auto_reply &&
! strcasecmp(notice.z_class, DEFAULT_CLASS) &&
! strcasecmp(notice.z_recipient, ZGetSender()))
dest_add_reply(¬ice);
!
! /* 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.