[comp.mail.mush] Official Patch #2 for Mush 7.0

schaefer@ogicse.ogc.edu (Barton E. Schaefer) (12/20/89)

@OFF

This is Official Patch #2 for Mush 7.0.  It'll be the last one before the
new year; Dan Heller is out of the country until Jan. 5 and I will be out
in the cold (er, visiting family in Iowa, I mean) from Dec. 24 to Jan. 6.  

As usual, fully up-to-date versions are available for anonymous ftp from:

	    ucbvax.berkeley.edu: pub/mailers/mush-7.0.tar.Z

		cse.ogi.edu: pub/mush/mush-7.0.tar.Z

If you missed Official Patch #1, you can obtain it via E-mail by sending
a message to me:

	    <schaefer@cse.ogi.edu>
    or
	    {harvard,rutgers,garp,decwrl,ucsd,unmvax}!ogicse!schaefer

Include in your message a line of the form

@PATCH patch-number path-from-ogicse-to-you

To recieve a complete set of mush sources, use

@MUSH path-from-ogicse-to-you

The mush sources are mailed as a compressed tarfile, encoded for
shipping with the "btoa" utility and "split" into 9 parts.

Note that ogicse is still having some sendmail.cf troubles, so the
path-from-ogicse-to-you must either be an Internet address (no mixing
of !-paths and @-domains) or a uucp path that begins with a well-known
(and preferably connected-to-ogicse) host.  The mail server is now
able to do some uucp hostname lookups on its own, so hopefully there
will be few difficulties.

Changes/fixes in this patch:

    Special-cased file listing (completion) so that only file names (not
    paths) are shown when no metacharacters are used in the string to be
    completed.  Note that relative paths are (and have always been) used
    except when ~ or + appear in the string to be completed.

    Made changes to glob.c to support the above.  Also fixed some pointer
    initialization problems that caused odd behavior on Suns.  If you
    plan to make local changes to the glob routines, take care, because
    they are now used to construct menus of filenames in tool mode.

    Fixed problem with signal handler resets when mailing with $verbose.

    Added dependencies to the makefile.* to recompile proper .o's when
    version.h changes (as always happens when you apply a patch).

    Shortened some long lines in the man page and corrected some out-of-
    date passages.

    Fixed line-mode command calls from tool-mode items that could have
    incorrectly activated a user-defined cmd.

    The right-button menus of folders in tool mode Folder and Save are
    now sorted again, at least until new folders are added.  The first
    choice on the Save menu is always your $mbox, which means that if
    your $mbox is in your $folder directory, it'll appear twice on the
    Save menu.  New folders appear near the beginning of the menus as
    they are added, following the fixed choices.

Problems that remain:

    A reported seg fault under SunOS 3.5 using Respond right-button Help
    in the Compose frame still has not been resolved.  It seems likely
    that this is related to SunView running out of file descriptors at a
    spot where mush can't catch it, but we continue to investigate and
    would appreciate any additional reports (and stack traces) relating
    to this problem.

*** /tmp/,RCSt1012127	Tue Dec 19 12:58:12 1989
--- curs_io.c	Mon Dec 18 16:42:16 1989
***************
*** 521,527 ****
  	expandall = 0;
  	overstrike = (*buf == '+' || *buf == '~');
  	trim = (overstrike && len > 1);
! 	if (!overstrike || len > 1)
  	    *b++ = '*', *b = 0;
  	f = filexp(buf, &exp);
  	if (*--b == '*')
--- 521,527 ----
  	expandall = 0;
  	overstrike = (*buf == '+' || *buf == '~');
  	trim = (overstrike && len > 1);
! 	if (*buf != '~' || len > 1)
  	    *b++ = '*', *b = 0;
  	f = filexp(buf, &exp);
  	if (*--b == '*')
***************
*** 550,558 ****
  	return errbell(-1);
      } else if (f > 0) {
  	Debug("result is: "), print_argv(exp);
  	if (showlist) {
  	    putchar('\n');
! 	    if (columnate(f, exp) < 0)
  		(void) errbell(-1);
  	    /* Reprint the line */
  	    if (iscurses) {
--- 550,565 ----
  	return errbell(-1);
      } else if (f > 0) {
  	Debug("result is: "), print_argv(exp);
+ 	if (!expandall && f > 1)
+ 	    prefix = lcprefix(exp, overstrike ? 0 : len);
+ 	else
+ 	    prefix = 0;
  	if (showlist) {
+ 	    if (!expandall && f > 1)
+ 		while (prefix && exp[0][prefix - 1] != '/')
+ 		    --prefix;
  	    putchar('\n');
! 	    if (columnate(f, exp, prefix) < 0)
  		(void) errbell(-1);
  	    /* Reprint the line */
  	    if (iscurses) {
***************
*** 564,573 ****
  		wprint("%s", string);
  	    }
  	} else if (expandall || strlen(exp[0]) > len) {
- 	    if (!expandall && f > 1)
- 		prefix = lcprefix(exp, overstrike ? 0 : len);
- 	    else
- 		prefix = 0;
  	    Debug("%s", string);
  	    if (overstrike && (prefix || expandall || f == 1)) {
  		char *tmpv[3];
--- 571,576 ----
***************
*** 612,618 ****
  			Ungetstr(&exp[0][len]);
  		} else
  		    Debug("\nno longer prefix\n%s", string);
! 		(void) errbell(0);
  	    }
  	} else {
  	    Debug("no longer prefix\n%s", string);
--- 615,626 ----
  			Ungetstr(&exp[0][len]);
  		} else
  		    Debug("\nno longer prefix\n%s", string);
! 		/* Special case because "+" always tries to expand "+*"
! 		 * to get listings and avoid getpath()'s trailing '/'.
! 		 * No error bell is needed in those cases.
! 		 */
! 		if (strcmp(buf, "+") != 0)
! 		    (void) errbell(0);
  	    }
  	} else {
  	    Debug("no longer prefix\n%s", string);
*** /tmp/,RCSt1012127	Tue Dec 19 12:58:15 1989
--- execute.c	Fri Dec 15 12:42:48 1989
***************
*** 66,72 ****
--- 66,76 ----
  {
      print("Starting \"%s\"...\n", *argv);
      msg_rect = *(Rect *)window_get(msg_sw, WIN_RECT);
+ #ifdef ALERT_ATTR /* SunOS 4.0+ */
      window_set(msg_sw, WIN_SHOW, FALSE, NULL);
+ #else /* ALERT_ATTR */
+     textsw_set(msg_sw, WIN_SHOW, FALSE, NULL);
+ #endif /* ALERT_ATTR */
      (void) window_set(tty_sw,
  	WIN_RECT,	&msg_rect,
  	TTY_ARGV,	argv,
*** /tmp/,RCSt1012127	Tue Dec 19 12:58:16 1989
--- file.c	Mon Dec 18 16:07:56 1989
***************
*** 104,110 ****
  	*isdir = -1;
  	return sys_errlist[errno];
      }
!     *isdir = ((stat_buf.st_mode & S_IFDIR) != 0);
      return buf;
  }
  
--- 104,110 ----
  	*isdir = -1;
  	return sys_errlist[errno];
      }
!     *isdir = ((stat_buf.st_mode & S_IFMT) == S_IFDIR);
      return buf;
  }
  
*** /tmp/,RCSt1012127	Tue Dec 19 12:58:18 1989
--- glob.c	Tue Dec 19 12:57:25 1989
***************
*** 42,48 ****
  	while (*++argv) {
  	    (void) printf("%s -->\n", *argv);
  	    if (f = filexp(*argv, &e)) {
! 		columnate(f, e);
  	    }
  	}
  #ifdef TEST2	/* Define TEST2 to automatically run these test cases */
--- 42,48 ----
  	while (*++argv) {
  	    (void) printf("%s -->\n", *argv);
  	    if (f = filexp(*argv, &e)) {
! 		columnate(f, e, 0);
  	    }
  	}
  #ifdef TEST2	/* Define TEST2 to automatically run these test cases */
***************
*** 190,197 ****
  	/* Two sort passes to eliminate duplicates -- see uniqcmp() */
  	qsort((char *)*exp, cnt, sizeof(char *), uniqcmp);
  	qsort((char *)*exp, cnt, sizeof(char *), uniqcmp);
! 	while (!(*exp)[cnt - 1][0])
  	    xfree((*exp)[--cnt]);
      }
      return cnt;
  }
--- 190,199 ----
  	/* Two sort passes to eliminate duplicates -- see uniqcmp() */
  	qsort((char *)*exp, cnt, sizeof(char *), uniqcmp);
  	qsort((char *)*exp, cnt, sizeof(char *), uniqcmp);
! 	while (!(*exp)[cnt - 1][0]) {
  	    xfree((*exp)[--cnt]);
+ 	    (*exp)[cnt] = NULL;
+ 	}
      }
      return cnt;
  }
***************
*** 527,532 ****
--- 529,535 ----
  	*exp = t1;
  	return n;
      }
+     *exp = DUBL_NULL;
      while (n-- && cnt >= 0) {
  	new = sxp(t1[n], &t2);
  	cnt = catv(cnt, exp, new, t2);
***************
*** 620,630 ****
  #endif /* CURSES */
  
  /*
!  * Print a vector in columns.
   */
! columnate(argc, argv)
  int argc;
  char **argv;
  {
      int colstep, colwidth[MAXCOLS + 1];
      int maxcols = min(argc, MAXCOLS);
--- 623,638 ----
  #endif /* CURSES */
  
  /*
!  * Print a vector in columns
!  *
!  * If "skip" is nonzero, that many chars are assumed to be in common
!  * and are not printed.  WARNING: skip must be <= than the length of
!  * the shortest string in the vector!  Safest to call with skip = 0.
   */
! columnate(argc, argv, skip)
  int argc;
  char **argv;
+ int skip;
  {
      int colstep, colwidth[MAXCOLS + 1];
      int maxcols = min(argc, MAXCOLS);
***************
*** 642,648 ****
       * Also remember the minimum width.
       */
      for (minwidth = MAXWIDTH, maxwidth = n = 0; n < argc; n++) {
! 	widths[n] = max(strlen(argv[n]) + 2, MINWIDTH);
  	if (widths[n] > MAXWIDTH - MINWIDTH)
  	    break;
  	if (widths[n] > maxwidth) {
--- 650,656 ----
       * Also remember the minimum width.
       */
      for (minwidth = MAXWIDTH, maxwidth = n = 0; n < argc; n++) {
! 	widths[n] = max(strlen(argv[n] + skip) + 2, MINWIDTH);
  	if (widths[n] > MAXWIDTH - MINWIDTH)
  	    break;
  	if (widths[n] > maxwidth) {
***************
*** 675,692 ****
  	 * The maxword fills too much screen, so redo everything
  	 * above it, print maxword, then do everything below it.
  	 */
! 	if (maxword > 0 && columnate(maxword, argv) < 0)
  	    return -1;
! 	wprint("%s\n", argv[maxword]);
  	if (argc - maxword < 2)
  	    return 0;
! 	return columnate(argc - maxword - 1, &argv[maxword + 1]);
      }
  
      for (n = 0; n < colstep; n++) {
  	for (c = 0; c < maxcols && n + c * colstep < argc - colstep; c++)
! 	    wprint("%-*.*s", colwidth[c], colwidth[c], argv[n + c * colstep]);
! 	wprint("%s\n", argv[n + c * colstep]);
      }
  
      return 0;
--- 683,701 ----
  	 * The maxword fills too much screen, so redo everything
  	 * above it, print maxword, then do everything below it.
  	 */
! 	if (maxword > 0 && columnate(maxword, argv, skip) < 0)
  	    return -1;
! 	wprint("%s\n", argv[maxword] + skip);
  	if (argc - maxword < 2)
  	    return 0;
! 	return columnate(argc - maxword - 1, &argv[maxword + 1], skip);
      }
  
      for (n = 0; n < colstep; n++) {
  	for (c = 0; c < maxcols && n + c * colstep < argc - colstep; c++)
! 	    wprint("%-*.*s", colwidth[c], colwidth[c],
! 					    argv[n + c * colstep] + skip);
! 	wprint("%s\n", argv[n + c * colstep] + skip);
      }
  
      return 0;
*** /tmp/,RCSt1012127	Tue Dec 19 12:58:24 1989
--- mail.c	Tue Dec 19 12:06:59 1989
***************
*** 1,7 ****
  /* @(#)mail.c 	(c) copyright 1986 (Dan Heller) */
  
  #include "mush.h"
- #include "version.h"
  
  /*
   * mail.c --
--- 1,6 ----
***************
*** 688,694 ****
  		return 1;
  	    for (n = 0; n < msg_cnt; n++)
  		if (msg_bit(list, n)) {
- 		    (void) fputc('\n', ed_fp);
  		    if (line[1] == 'f') {
  			(void) reply_to(n, FALSE, buf);
  			(void) fprintf(ed_fp,
--- 687,692 ----
***************
*** 700,705 ****
--- 698,705 ----
  		    if (line[1] == 'f')
  			(void) fprintf(ed_fp,
  			    "\n--- End of forwarded message from %s\n\n", buf);
+ 		    else
+ 			(void) fputc('\n', ed_fp);
  		}
  	}
  	/* To: Cc: and Bcc: headers */
***************
*** 1411,1419 ****
  #endif /* VERBOSE_ARG */
  #endif /* SUNTOOL */
  
!     if ((ison(flags, VERBOSE) || debug > 2) && isoff(glob_flags, REDIRECT))
! 	wprint("sent.\n");
!     else
  	exit(0); /* not a user exit -- a child exit */
      return 0;
  }
--- 1411,1425 ----
  #endif /* VERBOSE_ARG */
  #endif /* SUNTOOL */
  
!     if (ison(flags, VERBOSE) || debug > 2) {
! 	if (isoff(glob_flags, REDIRECT))
! 	    wprint("sent.\n");
! 	if (!istool) {
! 	    (void) signal(SIGINT, oldint);
! 	    (void) signal(SIGQUIT, oldquit);
! 	    (void) signal(SIGTERM, oldterm);
! 	}
!     } else
  	exit(0); /* not a user exit -- a child exit */
      return 0;
  }
*** /tmp/,RCSt1012127	Tue Dec 19 12:58:28 1989
--- makefile.bsd	Tue Dec 19 12:13:48 1989
***************
*** 31,37 ****
  	@echo loading...
  	@cc $(LDFLAGS) $(OBJS) $(LIBES) $(OTHERLIBS) -o mush
  
! $(OBJS): config.h
  
  tape:
  	@tar cv $(MAKES) $(HDRS) $(SRCS) $(HELP_FILES)
--- 31,38 ----
  	@echo loading...
  	@cc $(LDFLAGS) $(OBJS) $(LIBES) $(OTHERLIBS) -o mush
  
! $(OBJS): config.h mush.h
! loop.o: version.h
  
  tape:
  	@tar cv $(MAKES) $(HDRS) $(SRCS) $(HELP_FILES)
*** /tmp/,RCSt1012127	Tue Dec 19 12:58:28 1989
--- makefile.hpux	Tue Dec 19 12:10:37 1989
***************
*** 2,8 ****
  #
  HDRS1= mush.h config.h
  HDRS2= strings.h options.h
! HDRS3= bindings.h version.h glob.h
  SRCS1= commands.c dates.c execute.c expr.c folders.c \
  	hdrs.c init.c loop.c mail.c main.c misc.c msgs.c pick.c \
  	print.c setopts.c signals.c sort.c viewopts.c options.c lock.c
--- 2,9 ----
  #
  HDRS1= mush.h config.h
  HDRS2= strings.h options.h
! HDRS3= bindings.h glob.h
! HDRS4= version.h
  SRCS1= commands.c dates.c execute.c expr.c folders.c \
  	hdrs.c init.c loop.c mail.c main.c misc.c msgs.c pick.c \
  	print.c setopts.c signals.c sort.c viewopts.c options.c lock.c
***************
*** 32,37 ****
--- 33,39 ----
  
  $(OBJS1): $(HDRS1) $(HDRS2)
  $(OBJS2): $(HDRS1) $(HDRS2) $(HDRS3)
+ loop.o: version.h
  
  BINDIR= /usr/local/bin
  LIBDIR= /usr/local/lib
*** /tmp/,RCSt1012127	Tue Dec 19 12:58:29 1989
--- makefile.sys.v	Tue Dec 19 12:13:16 1989
***************
*** 3,9 ****
  #
  HDRS1= mush.h config.h
  HDRS2= strings.h options.h
! HDRS3= bindings.h version.h glob.h
  SRCS1= commands.c dates.c execute.c expr.c folders.c \
  	hdrs.c init.c loop.c mail.c main.c misc.c msgs.c pick.c \
  	print.c setopts.c signals.c sort.c viewopts.c options.c lock.c
--- 3,10 ----
  #
  HDRS1= mush.h config.h
  HDRS2= strings.h options.h
! HDRS3= bindings.h glob.h
! HDRS4= version.h
  SRCS1= commands.c dates.c execute.c expr.c folders.c \
  	hdrs.c init.c loop.c mail.c main.c misc.c msgs.c pick.c \
  	print.c setopts.c signals.c sort.c viewopts.c options.c lock.c
***************
*** 37,42 ****
--- 38,44 ----
  
  $(OBJS1): $(HDRS1) $(HDRS2)
  $(OBJS2): $(HDRS1) $(HDRS2) $(HDRS3)
+ loop.o: version.h
  
  BINDIR= /usr/local/bin
  LIBDIR= /usr/local/lib
*** /tmp/,RCSt1012127	Tue Dec 19 12:58:29 1989
--- makefile.xenix	Tue Dec 19 12:13:34 1989
***************
*** 42,48 ****
  	@echo loading...
  	@cc $(LDFLAGS) $(OBJS) $(LIBES) $(OTHERLIBS) -o mush
  
! $(OBJS): config.h
  
  # For 80286 machines, use these two lines...
  # misc.o:	misc.c
--- 42,49 ----
  	@echo loading...
  	@cc $(LDFLAGS) $(OBJS) $(LIBES) $(OTHERLIBS) -o mush
  
! $(OBJS): config.h mush.h
! loop.o: version.h
  
  # For 80286 machines, use these two lines...
  # misc.o:	misc.c
*** /tmp/,RCSt1012127	Tue Dec 19 12:58:34 1989
--- mush.1	Sat Dec 16 13:31:44 1989
***************
*** 3486,3499 ****
  .sp
  .nf
  .ti +2
! set autosign2 = \*Q!island @berkeley.edu @mit.edu *schaefer root: \--dan\*U
  .fi
  .sp
  This means that any mail sent to 1) anyone at island, 2) anyone within
! the berkeley domain, 3) anyone within the mit domain, 4) Bart Schaefer
  (at any host anywhere -- even locally),
  and 4) root on the local machine only (or, root@local-machine-name)
! will be signed  by my \*Qalternate\*U signature.  If any address on the
  recipient list fails to satisfy these four matches, the mail will be
  signed by my regular signature.
  .sp
--- 3486,3500 ----
  .sp
  .nf
  .ti +2
! set autosign2 = \*Q!island @sun.com @mit.edu *schaefer root: \--dan\*U
  .fi
  .sp
  This means that any mail sent to 1) anyone at island, 2) anyone within
! the sun domain, 3) anyone within the mit domain, 4) Bart Schaefer
  (at any host anywhere -- even locally),
  and 4) root on the local machine only (or, root@local-machine-name)
! will be signed with the \*Qalternate\*U signature.
! If any address on the
  recipient list fails to satisfy these four matches, the mail will be
  signed by my regular signature.
  .sp
***************
*** 3720,3728 ****
  A valid Cc: header does not remove this restriction.
  You may have as many To: and Cc: headers as you like.
  .sp
! The From: header must not be altered.
! Altering this header will result in a warning and it will be replaced by a
! correct one.
  .sp
  The Date: header will always be replaced by one with a more accurate
  time and date stamp.
--- 3721,3729 ----
  A valid Cc: header does not remove this restriction.
  You may have as many To: and Cc: headers as you like.
  .sp
! The From: header normally should not be changed.
! If you change this header to an address that mush is unable to identify as
! authentic, mush will silently put back the original From: header.
  .sp
  The Date: header will always be replaced by one with a more accurate
  time and date stamp.
*** /tmp/,RCSt1012127	Tue Dec 19 12:58:47 1989
--- version.h	Mon Dec 18 10:45:57 1989
***************
*** 1,8 ****
  /* @(#)version.h	(c) Copyright 1989 (Dan Heller) */
  
  #define MUSHNAME	"Mail User's Shell"
! #define RELEASE_DATE	"12/13/89"
  #define RELEASE		7
  #define REVISION	"0"
! #define PATCHLEVEL	1
  #define ORIGINAL_DATE	"12/10/89"
--- 1,8 ----
  /* @(#)version.h	(c) Copyright 1989 (Dan Heller) */
  
  #define MUSHNAME	"Mail User's Shell"
! #define RELEASE_DATE	"12/18/89"
  #define RELEASE		7
  #define REVISION	"0"
! #define PATCHLEVEL	2
  #define ORIGINAL_DATE	"12/10/89"
*** /tmp/,RCSt1012282	Tue Dec 19 12:58:50 1989
--- doproc.c	Mon Dec 18 15:59:00 1989
***************
*** 41,47 ****
  	return;
      }
      /* delete current message */
!     print(sprintf(buf, "%sdelete %s",
  	((event_id(event) == MS_LEFT || val == 0)? "" : "un"),
  	panel_get_value(msg_num_item)));
      turnon(glob_flags, IGN_BANG);
--- 41,47 ----
  	return;
      }
      /* delete current message */
!     print(sprintf(buf, "\\%sdelete %s",
  	((event_id(event) == MS_LEFT || val == 0)? "" : "un"),
  	panel_get_value(msg_num_item)));
      turnon(glob_flags, IGN_BANG);
***************
*** 474,483 ****
  	current_msg = value, value = 0;
      wprint("Responding to message %d\n", current_msg+1);
      (void) sprintf(buf, "%s %s %d",
! 	(value == 2 || value == 3)? "replyall" : "replysender",
  	(value == 1 || value == 3)? "-i": NO_STRING, current_msg+1);
      current_msg = tmp;
!     if (cmd_line(buf, msg_list) != -1)
  	start_textsw_edit(FALSE);
  }
  
--- 474,483 ----
  	current_msg = value, value = 0;
      wprint("Responding to message %d\n", current_msg+1);
      (void) sprintf(buf, "%s %s %d",
! 	(value == 2 || value == 3)? "\\replyall" : "\\replysender",
  	(value == 1 || value == 3)? "-i": NO_STRING, current_msg+1);
      current_msg = tmp;
!     if (cmd_line(buf, NULL) != -1)
  	start_textsw_edit(FALSE);
  }
  
*** /tmp/,RCSt1012282	Tue Dec 19 12:58:52 1989
--- makefile.sun	Tue Dec 19 12:10:57 1989
***************
*** 35,41 ****
  	@echo loading...
  	@cc $(LDFLAGS) $(OBJS) $(LIBES) $(OTHERLIBS) -o mush
  
! $(OBJS): config.h
  
  lint:
  	lint $(LINTFLAGS) $(SRCS) -DSUNTOOL -DCURSES -DBSD
--- 35,42 ----
  	@echo loading...
  	@cc $(LDFLAGS) $(OBJS) $(LIBES) $(OTHERLIBS) -o mush
  
! $(OBJS): config.h mush.h
! loop.o: version.h
  
  lint:
  	lint $(LINTFLAGS) $(SRCS) -DSUNTOOL -DCURSES -DBSD
*** /tmp/,RCSt1012282	Tue Dec 19 12:58:55 1989
--- panels.c	Fri Dec 15 19:13:06 1989
***************
*** 428,434 ****
      /* don't add a folder to the list if user can't read it */
      if (stat(path, &s_buf) == -1 || !(s_buf.st_mode & S_IREAD))
  	return NULL;
!     if (s_buf.st_mode & S_IFDIR) {
  	int cnt = 0;
  	if (!(dirp = opendir(path)))
  	    return NULL; /* don't bother adding to list if we can't scan it */
--- 428,434 ----
      /* don't add a folder to the list if user can't read it */
      if (stat(path, &s_buf) == -1 || !(s_buf.st_mode & S_IREAD))
  	return NULL;
!     if ((s_buf.st_mode & S_IFMT) == S_IFDIR) {
  	int cnt = 0;
  	if (!(dirp = opendir(path)))
  	    return NULL; /* don't bother adding to list if we can't scan it */
***************
*** 460,467 ****
  char *path;
  int *n;
  {
!     DIR			*dirp;
!     struct dirent	*dp;
      struct stat 	s_buf;
      char		buf[MAXPATHLEN];
  
--- 460,466 ----
  char *path;
  int *n;
  {
!     char		**names, **np;
      struct stat 	s_buf;
      char		buf[MAXPATHLEN];
  
***************
*** 468,479 ****
      /* don't add a folder to the list if user can't read it */
      if (stat(path, &s_buf) == -1 || !(s_buf.st_mode & S_IREAD))
  	return;
!     if (s_buf.st_mode & S_IFDIR) {
! 	for (dirp = opendir(path); dp = readdir(dirp); )
! 	    if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, ".."))
! 		add_path_to_menu(item,
! 		    sprintf(buf, "%s/%s", path, dp->d_name), n);
! 	closedir(dirp);
      } else
  	panel_set(item,
  	    PANEL_CHOICE_STRING, (*n)++, savestr(trim_filename(path)),
--- 467,481 ----
      /* don't add a folder to the list if user can't read it */
      if (stat(path, &s_buf) == -1 || !(s_buf.st_mode & S_IREAD))
  	return;
!     if ((s_buf.st_mode & S_IFMT) == S_IFDIR) {
! 	sprintf(buf, "%s/{.*,*}", path);
! 	if (filexp(buf, &names) > 0) {
! 	    for (np = names; np && *np; np++) {
! 		if (!glob(*np, "*/{.,..}"))
! 		    add_path_to_menu(item, *np, n);
! 	    }
! 	    free_vec(names);
! 	}
      } else
  	panel_set(item,
  	    PANEL_CHOICE_STRING, (*n)++, savestr(trim_filename(path)),
-- 
Bart Schaefer     "Miserable miscreant!  Question MY integrity, will you?"
               "I have to see some *evidence* of it before I can question it."
                                                            -- Calvin & Hobbes
schaefer@cse.ogi.edu (used to be cse.ogc.edu)