diff -cN 7.2.5/README 7.2.6-a1/README *** 7.2.5/README Fri Oct 30 11:55:04 1992 --- 7.2.6-a1/README Sun Jul 9 12:52:40 1995 *************** *** 44,51 **** Mush runs on various flavors of unix. To build mush, you should identify which unix you are running: ! SunOS (all versions from 3.5 and higher). ! BSD (versions 4.2 and up, or SunOS earlier than 3.5) System-V / Version 7 / System III (Bell Labs) Xenix (this might be tricky) Hybrids including HP-UX and IRIX (Version 4.0 and up is best) --- 44,53 ---- Mush runs on various flavors of unix. To build mush, you should identify which unix you are running: ! Solaris or a System-V Release-4 variant (including IRIX 5.x) ! LINUX, BSDI, or a POSIX-like system ! SunOS (all versions from 3.5 and higher, but not 5.x (Solaris)) ! BSD (versions 4.2 and up, or SunOS earlier than 3.5, but not BSDI) System-V / Version 7 / System III (Bell Labs) Xenix (this might be tricky) Hybrids including HP-UX and IRIX (Version 4.0 and up is best) *************** *** 72,78 **** --------------- Which makefile to use: ! If you are on a Sun Workstation: makefile.sun applies only to suns and creates a binary called "mush." If the binary ends in "tool", then the graphics (suntools) mode will be --- 74,80 ---- --------------- Which makefile to use: ! If you are on a Sun Workstation, pre-Solaris: makefile.sun applies only to suns and creates a binary called "mush." If the binary ends in "tool", then the graphics (suntools) mode will be *************** *** 84,90 **** If you know that you're not going to use the suntools mode then you should use makefile.bsd so that SUNTOOL won't be defined and unnecessary ! files will not be compiled so the binary will be smaller. Whether or not you define SUNTOOL, you should define one of SUN_3_5, SUN_4_0, or SUN_4_1 depending on your SunOS version. If SUNTOOL is --- 86,93 ---- If you know that you're not going to use the suntools mode then you should use makefile.bsd so that SUNTOOL won't be defined and unnecessary ! files will not be compiled so the binary will be smaller. You may ! also need to add -DBASENAME -DDNAME to CFLAGS. Whether or not you define SUNTOOL, you should define one of SUN_3_5, SUN_4_0, or SUN_4_1 depending on your SunOS version. If SUNTOOL is *************** *** 100,105 **** --- 103,121 ---- You should use the makefile.bsd makefile. + There may be problems building on BSD 4.4, BSDI, FreeBSD, and similar + "unencumbered" variants; these procedures have been thoroughly tested + only up to BSD 4.3. + + If you have LINUX or another closely POSIX system: + + Use makefile.linux. If you don't actually have LINUX, you may need + to try makefile.bsdi. + + If you have BSDI or a POSIX-like system: + + Use makefile.bsdi. + If you are using XENIX: There is one makefile for xenix: makefile.xenix. However, SCO-xenix *************** *** 135,147 **** It may also be desirable to change MANDIR to /usr/man/man.C and MANEXT to C in the makefile. SCO UNIX V.3.2 users should avoid -lx like the plague, and should define DIRECTORY and SELECT instead. MicroPort sys-v users should probably remove the -O compiler option from the makefile, and may have trouble with the msg_bit() macro defined in mush.h. It should be fairly trivial to generate an equivalent function. ! If you have System V Release 4: Use makefile.sys.v as above, but define SVR4 and DIRECTORY. You should also change --- 151,174 ---- It may also be desirable to change MANDIR to /usr/man/man.C and MANEXT to C in the makefile. SCO UNIX V.3.2 users should avoid -lx like the plague, and should define DIRECTORY and SELECT instead. + Suggested for SCO was + CFLAGS= -O -DSYSV -DUSG -DCURSES -DREGCMP \ + -DSIGRET=void -DDIRECTORY -DSELECT + LIBS= -ltinfo -lc_s + Under SCO 3.2v2.0 you may also need -lc, and prior to 3.2v2 you + may find you need -lPW. MicroPort sys-v users should probably remove the -O compiler option from the makefile, and may have trouble with the msg_bit() macro defined in mush.h. It should be fairly trivial to generate an equivalent function. ! Interactive UNIX users should try ! CFLAGS= -O -DSYSV -DUSG -DCURSES -DREGCMP \ ! -DSIGRET=void -DDIRECTORY ! LIBS= -lPW -ltermlib -lc_s ! ! If you have System V Release 4 (including Solaris with SunSoft compiler): Use makefile.sys.v as above, but define SVR4 and DIRECTORY. You should also change *************** *** 149,154 **** --- 176,191 ---- to LIBS= -lcurses -lgen + DG/UX 5.40 (and later?) -- change to: + LIBS= -lcurses -lgen -ldgc + + Also for DG/UX, #define MAILDIR "/usr/mail", and you may need to + add -DDGUX to CFLAGS. Also consider -lmalloc (see HP-UX, below). + + If you have Solaris but are using GCC: + + Use makefile.solaris. + If you are using Ultrix: Start with makefile.bsd. *************** *** 180,185 **** --- 217,231 ---- from the CFLAGS. This will cause the portable directory access routines in that file to be compiled. + On HP/UX up to 9.x, note use of the -lmalloc library; the behavior + of the default malloc in libc is pathologically bad for the way mush + allocates memory. HP/UX 10.x may be better, but -lmalloc is still + probably recommended. + + NOTE: ftp://hpux.cae.wisc.edu/HPUX/Networking/Mail/mush-7.2 is + reported to be pre-tweaked to compile with HPUX compilers. + However, it may not be up-to-date with the latest sources. + If you are using Apollo Domain/OS: Good luck. *************** *** 215,220 **** --- 261,268 ---- compatibility with sun workstations, or something like that. You may be able to get by with -lbsd. + For IRIX 5, you're on your own. Start with the SVR4 directions. + If you are using a hybrid BSD/SysV system: You may have to use a combination of many of the defines listed *************** *** 305,312 **** On a SYSV system, define MAIL_DELIVERY as /bin/rmail. POP: ! Define POP3_SUPPORT. You may also need to define HOMEMAIL; see config.h ! for additional configuration of HOMEMAIL. You will still need to define other macros appropriately for the transport agent that is used to *send* mail from your machine. --- 353,365 ---- On a SYSV system, define MAIL_DELIVERY as /bin/rmail. POP: ! Add -DPOP3_SUPPORT to your CFLAGS. You may also need to define ! HOMEMAIL; see config.h for additional configuration of HOMEMAIL. ! ! See config.h for additional POP3 definitions, including Kerberos ! and Hesiod support. If you define MAIL_FROM_POPHOST to make mush ! believe that the local host and the pop host are the same, be sure ! to adjust the definition of DEFAULT_POPHOST to your environment. You will still need to define other macros appropriately for the transport agent that is used to *send* mail from your machine. diff -cN 7.2.5/config.h-dist 7.2.6-a1/config.h-dist *** 7.2.5/config.h-dist Fri Oct 30 11:55:29 1992 --- 7.2.6-a1/config.h-dist Sun Jul 9 12:52:41 1995 *************** *** 101,106 **** --- 101,107 ---- #define MAIL_DELIVERY "/usr/lib/mail/execmail" # define VERBOSE_ARG "-v" # define METOO_ARG "-m" + #define MTA_EXIT 0 /* exit status for successful execmail */ #else /* M_EXECMAIL */ #define MAIL_DELIVERY "exec /usr/mmdf/bin/submit -mlnr" #define VERBOSE_ARG "Ww" *************** *** 110,116 **** --- 111,121 ---- /* * If you are not using MMDF, check these definitions. */ + #ifdef __FreeBSD__ + #define MAIL_DELIVERY "/usr/sbin/sendmail -i" /* "-i" works like "-oi" */ + #else #define MAIL_DELIVERY "/usr/lib/sendmail -i" /* "-i" works like "-oi" */ + #endif #define VERBOSE_ARG "-v" /* undef if none exists */ #define METOO_ARG "-m" /* man sendmail for more info. */ #define MTA_EXIT 0 /* exit status for successful mail delivery */ *************** *** 192,200 **** * later sun versions (3.0+ ?). Typically not true for BSD systems, but * that will probably change in the future. */ ! #if defined(SYSV) || defined(sun) #define VPRINTF ! #endif /* SYSV || sun */ /* If your system uses the getwd() system call (as opposed to getcwd()), * and your system is not a BSD system (e.g. MIPS), define GETWD below. --- 197,205 ---- * later sun versions (3.0+ ?). Typically not true for BSD systems, but * that will probably change in the future. */ ! #if defined(SYSV) || defined(sun) || defined(BSD44) || defined(linux) #define VPRINTF ! #endif /* SYSV || sun || BSD44 || linux */ /* If your system uses the getwd() system call (as opposed to getcwd()), * and your system is not a BSD system (e.g. MIPS), define GETWD below. *************** *** 208,220 **** #define DIRECTORY #endif /* SVR4 */ /* If your system has the POSIX "utimbuf" structure for utime(2), * define POSIX_UTIME. You may have to change to * in mush.h. */ ! #if defined(SVR4) && !defined(sun) #define POSIX_UTIME ! #endif /* SVR4 && !sun */ /* The remainder of this file attempt to automatically supply some sanity. * You shouldn't need to change this part unless your system is really odd. --- 213,242 ---- #define DIRECTORY #endif /* SVR4 */ + /* If your system does not have bzero, remove this */ + #define HAS_BZERO + /* If your system has the POSIX "utimbuf" structure for utime(2), * define POSIX_UTIME. You may have to change to * in mush.h. */ ! #if defined(POSIX) || (defined(SVR4) && !defined(sun)) #define POSIX_UTIME ! #endif /* POSIX || ( SVR4 && !sun) */ ! ! #ifdef POP3_SUPPORT ! /* ! * Define MAIL_FROM_POPHOST if mail should appear to have been sent ! * from the POP server machine rather than the local client machine. ! */ ! /* #define MAIL_FROM_POPHOST /**/ ! /* #define HESIOD /* Define if using the hesiod informational services */ ! /* #define KERBEROS /* Define if using the Kerberos authentication system */ ! #ifdef MAIL_FROM_POPHOST ! /* #define DEFAULT_POPHOST "popserver.podunc.edu" /*Name of your POP server*/ ! #define gethostname(name, namelen) pophostname(name, namelen) ! #endif /* MAIL_FROM_POPHOST */ ! #endif /* POP3_SUPPORT */ /* The remainder of this file attempt to automatically supply some sanity. * You shouldn't need to change this part unless your system is really odd. diff -cN 7.2.5/curs_io.c 7.2.6-a1/curs_io.c *** 7.2.5/curs_io.c Fri Oct 30 11:55:30 1992 --- 7.2.6-a1/curs_io.c Sun Jul 9 12:52:41 1995 *************** *** 5,10 **** --- 5,14 ---- #include "bindings.h" #include "glob.h" + #if defined(IRIX4) && defined(SELECT) + #include + #endif + static backspace(); #if !defined(M_XENIX) || (defined(M_XENIX) && !defined(CURSES)) *************** *** 18,24 **** "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", ! "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~", "^?" }; #endif /* !M_XENIX || (M_XENIX && !CURSES) */ --- 22,39 ---- "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", ! "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~", "^?", ! /* Another 128 characters for TTY drivers that aren't 7-bit limited. */ ! " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", ! " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", ! " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", ! " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", ! " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", ! " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", ! " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", ! " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", ! " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", ! " ", " " }; #endif /* !M_XENIX || (M_XENIX && !CURSES) */ *************** *** 515,521 **** int showlist; /* Display list, complete if also ignore */ int ignore; /* Ignore the fignore matches, do complete */ { ! char buf[MAXPATHLEN], *b = buf, **exp; int n = *count, f, len, prefix, trim, overstrike, expandall; if (!*string || !*count) --- 530,536 ---- int showlist; /* Display list, complete if also ignore */ int ignore; /* Ignore the fignore matches, do complete */ { ! char buf[MAXPATHLEN], *b = buf, **exp = 0; int n = *count, f, len, prefix, trim, overstrike, expandall; if (!*string || !*count) *************** *** 527,533 **** if (n > 0 || index(DELIM, string[n])) n++; b = buf + (len = Strcpy(buf, &string[n])); ! Debug("\nexpanding (%s) ... ", buf); if (!any(buf, FMETA)) { expandall = 0; overstrike = (*buf == '+' || *buf == '~' || *buf == '%'); --- 542,548 ---- if (n > 0 || index(DELIM, string[n])) n++; b = buf + (len = Strcpy(buf, &string[n])); ! Debug("\nexpanding (%s) show=%d, ign=%d ... ", buf, showlist, ignore); if (!any(buf, FMETA)) { expandall = 0; overstrike = (*buf == '+' || *buf == '~' || *buf == '%'); diff -cN 7.2.5/curses.c 7.2.6-a1/curses.c *** 7.2.5/curses.c Fri Oct 30 11:55:31 1992 --- 7.2.6-a1/curses.c Sun Jul 9 12:52:41 1995 *************** *** 12,18 **** --- 12,20 ---- char buf[80]; extern char *UP; #ifndef M_UNIX + #ifndef BSD44 extern char ttytype[]; + #endif #endif /* M_UNIX */ if (argv && *++argv && !strcmp(*argv, "-?")) *************** *** 46,51 **** --- 48,56 ---- echom(); nocrmode(); #endif /* attrset */ + #ifdef linux + LINES=COLS=0; /* this is a quick hack to fix a linux libc 4.2 bug */ + #endif (void) initscr(); #ifdef SIGCONT /* initscr will play with signals -- make sure they're set right. */ *************** *** 487,504 **** /* order messages (sort) and redisplay the headers */ when C_SORT : case C_REV_SORT : ! (void) strcpy(file, "sort"); ! if (c == C_REV_SORT) { ! print("Reverse "), turnon(glob_flags, CONT_PRNT); ! (void) strcat(file, " -"); ! } ! print( ! "Order messages by [author, date, length, Status, subject, priority]: " ! ); ! if ((c = m_getchar()) == 'a' || c == 'd' || c == 'l' || ! c == 'S' || c == 's' || c == 'R' || c == 'p') { print("reordering messages..."); ! (void) cmd_line(sprintf(buf, "%s %c", file, c), msg_list); print_more("done."); if (ison(glob_flags, CNTD_CMD)) putchar('\n'), puts(compose_hdr(current_msg)); --- 492,506 ---- /* order messages (sort) and redisplay the headers */ when C_SORT : case C_REV_SORT : ! print((c == C_SORT) ? "Order " : "Reverse order "); ! turnon(glob_flags, CONT_PRNT); ! print("by [author, date, length, Status, subject, priority, to]: "); ! n = m_getchar(); ! if (index("adlSRspt", n)) { print("reordering messages..."); ! sprintf(buf, "sort %s%c%s", (c == C_SORT) ? "" : "r", n, ! (n == 'd' || n == 'l') ? "" : "d"); ! (void) cmd_line(buf, msg_list); print_more("done."); if (ison(glob_flags, CNTD_CMD)) putchar('\n'), puts(compose_hdr(current_msg)); *************** *** 783,794 **** putchar('\n'); return 0; } ! print("Update folder [y]? "); ! if ((c = getchar()) != 'y' && c != 'Y' && c != '\n' && !isspace(c)) { ! print("Folder unchanged."); ! if (ison(glob_flags, CNTD_CMD)) ! putchar('\n'); ! return 0; } if (*redo < 0) return 1; --- 785,799 ---- putchar('\n'); return 0; } ! if (chk_option("verify", "update")) { ! print("Update folder [y]? "); ! if ((c = getchar()) != 'y' && c != 'Y' && c != '\n' && ! !isspace(c)) { ! print("Folder unchanged."); ! if (ison(glob_flags, CNTD_CMD)) ! putchar('\n'); ! return 0; ! } } if (*redo < 0) return 1; *************** *** 804,812 **** scrn_line(line, buf) char *buf; { ! #ifndef AIX #ifndef A_CHARTEXT (void) strncpy(buf, stdscr->_y[line], COLS-1); buf[COLS-1] = 0; /* strncpy does not null terminate */ #else int n; --- 809,821 ---- scrn_line(line, buf) char *buf; { ! #if !defined(AIX) && !defined(BSD44) #ifndef A_CHARTEXT + #ifdef NCURSES + (void) strncpy(buf, stdscr->lines[line], COLS-1); + #else (void) strncpy(buf, stdscr->_y[line], COLS-1); + #endif buf[COLS-1] = 0; /* strncpy does not null terminate */ #else int n; *************** *** 904,915 **** --- 913,929 ---- { int hlp_siz = LINES - 2 - curses_help_msg(FALSE); + #ifndef BSD44 if (!do_set(set_options, "screen")) + #ifdef POSIX + switch (cfgetospeed(&_tty)) + #else /* POSIX */ #ifdef USG switch (_tty.sg_ospeed & CBAUD) #else /* USG */ switch (_tty.sg_ospeed) #endif /* USG */ + #endif /* POSIX */ { case B300 : screen = min(hlp_siz, 7); when B1200 : screen = min(hlp_siz, 14); *************** *** 917,922 **** --- 931,937 ---- otherwise : screen = hlp_siz; } else + #endif /* BSD44 */ screen = min(screen, hlp_siz); } diff -cN 7.2.5/dates.c 7.2.6-a1/dates.c *** 7.2.5/dates.c Fri Oct 30 11:55:05 1992 --- 7.2.6-a1/dates.c Sun Jul 9 12:52:41 1995 *************** *** 122,128 **** { struct tm *T; char *tz; ! #if defined(SYSV) || defined(TIMEZONE) long x; (void) time(&x); --- 122,128 ---- { struct tm *T; char *tz; ! #if defined(SYSV) || defined(TIMEZONE) || defined(POSIX) long x; (void) time(&x); *************** *** 133,139 **** tz = tzname[T->tm_isdst]; } #endif /* TIMEZONE */ ! #else /* SYSV || TIMEZONE */ extern char *timezone(); struct timeval mytime; struct timezone myzone; --- 133,139 ---- tz = tzname[T->tm_isdst]; } #endif /* TIMEZONE */ ! #else /* SYSV || TIMEZONE || POSIX */ extern char *timezone(); struct timeval mytime; struct timezone myzone; diff -cN 7.2.5/doproc.c 7.2.6-a1/doproc.c *** 7.2.5/doproc.c Fri Oct 30 11:55:08 1992 --- 7.2.6-a1/doproc.c Sun Jul 9 12:52:42 1995 *************** *** 799,804 **** --- 799,808 ---- ok_box(buf) char *buf; { + if (!istool) { + print("%s", buf); + return; + } #ifdef SUN_4_0 (void) alert_prompt(tool, (Event *)NULL, ALERT_MESSAGE_STRINGS, buf, NULL, diff -cN 7.2.5/execute.c 7.2.6-a1/execute.c *** 7.2.5/execute.c Tue Mar 31 14:03:47 1992 --- 7.2.6-a1/execute.c Sun Jul 9 12:52:42 1995 *************** *** 1,7 **** /* execute.c (c) copyright 10/28/86 (Dan Heller) */ #include "mush.h" ! #if defined(BSD) || defined(IRIX4) #include #else #ifndef SYSV --- 1,7 ---- /* execute.c (c) copyright 10/28/86 (Dan Heller) */ #include "mush.h" ! #if defined(BSD) || defined(IRIX4) || defined(POSIX) #include #else #ifndef SYSV *************** *** 88,98 **** execute(argv) char **argv; { ! #ifdef SYSV int status; #else union wait status; ! #endif /* SYSV */ #ifdef SIGCONT SIGRET (*oldstop)(), (*oldcont)(); #endif /* SIGCONT */ --- 88,98 ---- execute(argv) char **argv; { ! #if defined(SYSV) || defined(POSIX) || defined (BSD44) int status; #else union wait status; ! #endif /* SYSV || POSIX || BSD44 */ #ifdef SIGCONT SIGRET (*oldstop)(), (*oldcont)(); #endif /* SIGCONT */ *************** *** 142,155 **** SIGRET sigchldcatcher() { ! #ifdef SYSV int status; #else union wait status; ! #endif /* SYSV */ int pid; ! #if defined(BSD) || defined(IRIX4) while ((pid = wait3(&status, WNOHANG, (struct rusage *)0)) > 0) { Debug("%d died...\n", pid); if (pid == exec_pid) --- 142,163 ---- SIGRET sigchldcatcher() { ! #if defined(SYSV) || defined(POSIX) || defined(BSD44) int status; #else union wait status; ! #endif /* SYSV || POSIX || BSD44 */ int pid; ! #if defined(POSIX) && !defined(linux) ! /* this could probably be done smarter */ ! while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { ! Debug("%d died...\n", pid); ! if (pid == exec_pid) ! break; ! } ! #else ! #if defined(BSD) || defined(IRIX4) || defined(linux) while ((pid = wait3(&status, WNOHANG, (struct rusage *)0)) > 0) { Debug("%d died...\n", pid); if (pid == exec_pid) *************** *** 164,169 **** --- 172,178 ---- Debug("%d died...\n", pid); #endif /* SYSV */ #endif /* BSD || IRIX4 */ + #endif /* POSIX */ if (pid == exec_pid && pid > 0) { exec_pid = 0; longjmp(execjbuf, 1); diff -cN 7.2.5/file.c 7.2.6-a1/file.c *** 7.2.5/file.c Fri Oct 30 11:55:32 1992 --- 7.2.6-a1/file.c Sun Jul 9 12:52:42 1995 *************** *** 37,43 **** * if '/' exists, separate into tmp="user" p="subpath" */ struct passwd *ent, *getpwnam(); ! char *p2 = p+1; if (p = index(p2, '/')) *p++ = 0; if (!(ent = getpwnam(p2))) { --- 37,44 ---- * if '/' exists, separate into tmp="user" p="subpath" */ struct passwd *ent, *getpwnam(); ! char tmp[MAXPATHLEN], *p2 = tmp+1; ! strcpy(tmp, p); if (p = index(p2, '/')) *p++ = 0; if (!(ent = getpwnam(p2))) { Common subdirectories: 7.2.5/fixed and 7.2.6-a1/fixed diff -cN 7.2.5/folders.c 7.2.6-a1/folders.c *** 7.2.5/folders.c Tue Mar 31 14:03:48 1992 --- 7.2.6-a1/folders.c Sun Jul 9 12:52:42 1995 *************** *** 85,91 **** */ n = 0; if (*tmp != '/') { ! if (!GetCwd(buf, sizeof buf)) { error("getcwd: %s",buf); return -1; } --- 85,92 ---- */ n = 0; if (*tmp != '/') { ! buf[0] = '\0'; ! if (GetCwd(buf, sizeof buf) == NULL) { error("getcwd: %s",buf); return -1; } *************** *** 107,114 **** return -1; } /* If the file can't be opened for writing, autoset READ_ONLY */ ! if (!(statbuf.st_mode & 0200)) do_read_only = 1; if (!(n=copyback(updating?"Update folder?":"Change anyway?",!updating))) { #ifdef SUNTOOL --- 108,117 ---- return -1; } /* If the file can't be opened for writing, autoset READ_ONLY */ ! if ((n = open(buf, O_RDWR)) < 0) do_read_only = 1; + else + close(n); if (!(n=copyback(updating?"Update folder?":"Change anyway?",!updating))) { #ifdef SUNTOOL *************** *** 132,137 **** --- 135,149 ---- xfree(msg[msg_cnt].m_date_recv); xfree(msg[msg_cnt].m_date_sent); msg[msg_cnt].m_date_recv = msg[msg_cnt].m_date_sent = NO_STRING; + xfree(msg[msg_cnt].m_subject); + xfree(msg[msg_cnt].m_to); + xfree(msg[msg_cnt].m_from); + xfree(msg[msg_cnt].m_name); + xfree(msg[msg_cnt].m_addr); + msg[msg_cnt].m_subject = NULL; + msg[msg_cnt].m_to = msg[msg_cnt].m_from = NULL; + msg[msg_cnt].m_name = msg[msg_cnt].m_addr = NULL; + msg[msg_cnt].m_author = 0; } msg_cnt = 0, msg[0].m_offset = 0L; turnoff(glob_flags, CONT_PRNT); diff -cN 7.2.5/glob.c 7.2.6-a1/glob.c *** 7.2.5/glob.c Thu May 3 12:40:15 1990 --- 7.2.6-a1/glob.c Sun Jul 9 12:52:43 1995 *************** *** 1,6 **** --- 1,23 ---- + /* glob.c Copyright 1990, 1991 Z-Code Software Corp. */ + + #ifndef TEST #include "mush.h" + #else /* !TEST */ + #include + #ifdef BSD + #define DIRECTORY + #include + #include + #include + #endif /* BSD */ + #endif /* TEST */ #include "glob.h" + #ifndef BSD + #undef bcopy + #define bcopy(s,d,n) memcpy(d,s,n) + #endif /* BSD */ + /* * Buried somewhere in here is the skeleton of a pattern matcher posted * by koblas@mips.COM (David Koblas). It has been hacked almost beyond *************** *** 23,32 **** #define min(x,y) ((x) > (y) ? (y) : (x)) #endif /* min */ #define xfree free #undef wprint #define wprint printf #define debug 0 ! #undef sprintf #define TESTGLOB(str1,str2) \ printf("%s %s = %s\n",str1,str2,glob(str1,str2)?"TRUE":"FALSE") --- 40,56 ---- #define min(x,y) ((x) > (y) ? (y) : (x)) #endif /* min */ #define xfree free + #define free_vec(v) \ + do { int i; for (i = 0; (v) && (v)[i]; free((v)[i++])); } while (0) #undef wprint #define wprint printf #define debug 0 ! ! #define DUBL_NULL (char **)0 ! #define TRPL_NULL (char ***)0 ! #define TRUE 1 ! #define FALSE 0 ! #define MAXPATHLEN 1024 #define TESTGLOB(str1,str2) \ printf("%s %s = %s\n",str1,str2,glob(str1,str2)?"TRUE":"FALSE") *************** *** 42,50 **** 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 */ TESTGLOB("abcdefg", "abcdefg"); TESTGLOB("abcdefg", "a?cd?fg"); --- 66,85 ---- while (*++argv) { (void) printf("%s -->\n", *argv); if (f = filexp(*argv, &e)) { ! (void) columnate(f, e, 0, (char ***)0); } } + else { + char buf[1024]; + + e = (char **)0; + f = 0; + while (fgets(buf, sizeof buf, stdin)) { + buf[strlen(buf)-1] = 0; + f = catv(f, &e, 1, unitv(buf)); + } + (void) columnate(f, e, 0, (char ***)0); + } #ifdef TEST2 /* Define TEST2 to automatically run these test cases */ TESTGLOB("abcdefg", "abcdefg"); TESTGLOB("abcdefg", "a?cd?fg"); *************** *** 58,64 **** TESTGLOB("./der/den/deq/der/", "*deq*"); TESTGLOB("./bc/def/gh/ij", "*ij"); TESTGLOB("./ij", ".?ij"); ! TESTGLOB("./bc/def/gh/ij", "./*"); TESTGLOB("abcdef", "*def"); TESTGLOB("abcdef", "*abcdef"); TESTGLOB("abcdef", "abc*"); --- 93,99 ---- TESTGLOB("./der/den/deq/der/", "*deq*"); TESTGLOB("./bc/def/gh/ij", "*ij"); TESTGLOB("./ij", ".?ij"); ! TESTGLOB("./bc/def/gh/ij", "./\052"); /* dot-slash-star */ TESTGLOB("abcdef", "*def"); TESTGLOB("abcdef", "*abcdef"); TESTGLOB("abcdef", "abc*"); *************** *** 92,117 **** return 0; } ! #endif /* TEST */ /* ! * Make a string into a one-element vector */ ! char ** ! unitv(s) ! char *s; { ! char **v; ! if (v = (char **)malloc((unsigned)(2 * sizeof(char *)))) { ! v[0] = savestr(s); ! v[1] = NULL; } ! return v; } /* ! * Append one vector to another */ catv(s1, v1, s2, v2) int s1, s2; --- 127,198 ---- return 0; } ! char * ! rany(s1, s2) ! register char *s1, *s2; ! { ! register char *p, *p2 = s1; ! ! if (!s1 || !*s1 || !s2 || !*s2) ! return NULL; ! s1 += strlen(s1); /* Skip to last character in s1 */ ! while (s1-- > p2) { ! for (p = s2; *p; p++) ! if (*p == *s1) ! return s1; ! } ! return NULL; ! } /* ! * Copy a vector -- returns number of elements */ ! vcpy(v1, v2) ! char ***v1, **v2; { ! int i, s2; ! if (!v1 || !v2) ! return -1; ! for (s2 = 0; v2[s2]; s2++) ! ; ! *v1 = (char **)malloc((unsigned)((s2 + 1) * sizeof(char **))); ! if (*v1) { ! for (i = 0; i < s2; i++) { ! (*v1)[i] = savestr(v2[i]); ! if (!(*v1)[i]) { ! free_vec(*v1); ! *v1 = DUBL_NULL; ! return -1; ! } ! } ! (*v1)[i] = NULL; ! return i; } ! return -1; } /* ! * Append one vector to another -- frees v2 ! */ ! vcat(v1, v2) ! char ***v1, **v2; ! { ! int s1 = 0, s2 = 0; ! ! if (!v1) ! return -1; ! if (*v1) ! for (s1 = 0; (*v1)[s1]; s1++) ! ; ! if (v2) ! for (s2 = 0; v2[s2]; s2++) ! ; ! return catv(s1, v1, s2, v2); ! } ! ! /* ! * Speedier vector append when sizes are known */ catv(s1, v1, s2, v2) int s1, s2; *************** *** 127,146 **** /* realloc(NULL, size) should be legal, but Sun doesn't support it. */ if (*v1) *v1 = (char **)realloc(*v1,(unsigned)((s1+s2+1) * sizeof(char **))); ! else ! *v1 = (char **)malloc((unsigned)((s1+s2+1) * sizeof(char **))); if (*v1) { for (i = 0; i < s2 && v2[i]; i++) (*v1)[s1 + i] = v2[i]; (*v1)[s1 + i] = NULL; ! xfree(v2); return s1 + i; } return -1; } /* * A duplicate-eliminating comparison for sorting. It treats an empty * string as greater than any other string, and forces empty one of any * pair of of equal strings. Two passes are sufficient to move the empty --- 208,246 ---- /* realloc(NULL, size) should be legal, but Sun doesn't support it. */ if (*v1) *v1 = (char **)realloc(*v1,(unsigned)((s1+s2+1) * sizeof(char **))); ! else { ! *v1 = v2; /* Do the obvious optimzation */ ! return s2; ! } if (*v1) { for (i = 0; i < s2 && v2[i]; i++) (*v1)[s1 + i] = v2[i]; (*v1)[s1 + i] = NULL; ! xfree((char *)v2); return s1 + i; } return -1; } /* + * Make a string into a one-element vector + */ + char ** + unitv(s) + char *s; + { + char **v; + + if (v = (char **)malloc((unsigned)(2 * sizeof(char *)))) { + v[0] = savestr(s); + v[1] = NULL; + } + return v; + } + + #ifdef NOT_NOW + /* * A duplicate-eliminating comparison for sorting. It treats an empty * string as greater than any other string, and forces empty one of any * pair of of equal strings. Two passes are sufficient to move the empty *************** *** 149,154 **** --- 249,255 ---- * This is NOT compatible with the ANSI C qsort(), which requires that the * comparison function will not modify its arguments! */ + int uniqcmp(p1, p2) char **p1, **p2; { *************** *** 163,202 **** **p2 = 0; return -1; } /* * Expand a pattern into a list of file names. Returns the number of * matches. As in csh, names generated from pattern sets are returned * even if there are no actual matches. */ filexp(pat, exp) char *pat, ***exp; { char **t1, **t2; ! int n, new, cnt; if (!exp) return -1; if (!pat || !*pat) return 0; if ((n = sxp(pat, &t1)) > 0) cnt = 0; else return n; *exp = DUBL_NULL; while (n--) ! if ((new = fxp(t1[n], &t2)) > 0 || new++ == 0 && t2) cnt = catv(cnt, exp, new, t2); - if (cnt > 1) { - /* 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; } --- 264,370 ---- **p2 = 0; return -1; } + #endif /* NOT_NOW */ + + /* + * String comparison function for qsort. An empty string is greater + * than any other, otherwise strcmp is used. + */ + int + strptrcmp(p1, p2) + char **p1, **p2; + { + if (!**p1 || !**p2) + return **p2 - **p1; + return strcmp(*p1, *p2); + } + + #endif /* TEST */ + + /* + * Remove duplicate entries in a sorted array, usually the result of qsort. + * Returns the number of unique entries, or -1 on error. + * Moves the redundant stuff to the end, in case it needs to be deallocated + * or something. + */ + int + crunch(base, nel, width, cmp) + char *base; + int nel, width, (*cmp)(); + { + int i, j; + char *temp = malloc(width); + + if (!temp) + return -1; + + j = 0; + for (i = 0; i < nel; ++i) { + if (i == 0 || (*cmp)(base+i*width, base+(j-1)*width) != 0) { + if (i != j) { + bcopy(base+j*width, temp, width); + bcopy(base+i*width, base+j*width, width); + bcopy(temp, base+i*width, width); + } + j++; + } + } + + xfree(temp); + + return j; + } + + /* + * Qsort and remove duplicates. Returns the final number of entries. + */ + int + qsort_and_crunch(base, nel, width, cmp) + char *base; + int nel, width, (*cmp)(); + { + qsort(base, nel, width, cmp); + return crunch(base, nel, width, cmp); + } /* * Expand a pattern into a list of file names. Returns the number of * matches. As in csh, names generated from pattern sets are returned * even if there are no actual matches. */ + int filexp(pat, exp) char *pat, ***exp; { char **t1, **t2; ! int n, new, crunched_new, cnt; if (!exp) return -1; if (!pat || !*pat) return 0; + /* Note that sxp() returns its list in reverse order, so we then + * step through it in reverse order to complete the expansion. + */ if ((n = sxp(pat, &t1)) > 0) cnt = 0; else return n; *exp = DUBL_NULL; while (n--) ! if ((new = fxp(t1[n], &t2)) > 0 || new++ == 0 && t2) { ! if (new > 1) { ! crunched_new = ! qsort_and_crunch((char *)t2, new, sizeof(char *), strptrcmp); ! while (new > crunched_new) { ! xfree(t2[--new]); ! t2[new] = NULL; ! } ! } cnt = catv(cnt, exp, new, t2); } ! free_vec(t1); return cnt; } *************** *** 209,214 **** --- 377,383 ---- * The list of expansions is placed in *exp, and the number of matches * is returned, or -1 on an error. */ + int fxp(name, exp) char *name, ***exp; { *************** *** 224,230 **** return -1; else if (isdir) return ((*exp = unitv(p)) ? 1 : -1); ! return pglob(p, 0, exp); } /* --- 393,399 ---- return -1; else if (isdir) return ((*exp = unitv(p)) ? 1 : -1); ! return pglob((*name == '\\') ? name : p, 0, exp); } /* *************** *** 239,244 **** --- 408,414 ---- * and returned even when there are no matches (ala csh generation of names * from pattern sets). pglob() still returns zero in this case. */ + int pglob(path, skip, exp) char *path, ***exp; int skip; *************** *** 250,257 **** return -1; *exp = DUBL_NULL; /* Must be null in case of zero matches and no sets */ ! for (t = t2 = path + skip; (t2 = any(t2, META)) && *t2 == '/'; t = t2++) ! ; if (!t2) { ret = ((*exp = unitv(path)) ? 1 : -1); if (ret > 0 && Access(path, F_OK) < 0) --- 420,429 ---- return -1; *exp = DUBL_NULL; /* Must be null in case of zero matches and no sets */ ! for (t = t2 = path + skip; (t2 = any(t2, META)); t = t2++) { ! if (*t2 != '/') ! break; ! } if (!t2) { ret = ((*exp = unitv(path)) ? 1 : -1); if (ret > 0 && Access(path, F_OK) < 0) *************** *** 269,306 **** ret = dglob("", t, t2, exp); } } return ret; } /* * Search a directory (possibly recursively) for glob matches. * Argument pat1 is a pattern to be matched in this directory, * and pat2 is a pattern to be matched in matched subdirectories. * * Matches are returned through *exp. */ dglob(dir, pat1, pat2, exp) char *dir, *pat1, *pat2, ***exp; { DIR *dirp; struct dirent *dp; ! char *b, *d, buf[MAXPATHLEN], **tmp; ! int n, ret = 0, skip; if (!dir || !exp) return -1; d = (*dir ? dir : "."); ! if (!(dirp = opendir(d))) return -1; ! b = buf + Strcpy(buf, dir); ! if (b > buf && *(b - 1) != '/') ! *b++ = '/'; skip = b - buf; /* We know this much matches, don't glob it again */ while (ret >= 0 && (dp = readdir(dirp))) { if (fglob(dp->d_name, pat1)) { if (pat2) { (void) sprintf(b, "%s/%s", dp->d_name, pat2); ! n = pglob(buf, skip, &tmp); ret = catv(ret, exp, n, tmp); } else { (void) strcpy(b, dp->d_name); --- 441,537 ---- ret = dglob("", t, t2, exp); } } + /* + * If we're going to return zero with something in exp, then we're + * returning for an sxp() pattern as described above. Strip the + * '\\' character as if we'd actually found a file that matches. + * Note that in this case we know there's only one element in exp. + */ + if (ret == 0 && *exp && **exp) { + for (t = t2 = exp[0][0]; t && *t; *t2++ = *t++) { + if (*t == '\\' && t[1]) + t++; + } + *t2 = 0; + } return ret; } /* + * Terminate a failing dglob() by gluing a path name back together out + * of the several components. If the reassembled path doesn't contain + * any globbing metacharacters, add it to the exp list. This deals with + * the lowest level {foo,bar} pattern notation as described for pglob(). + * + * Note that we know from the circumstances in which this is called by + * dglob() that the exp array is empty within xglob()'s context. This + * function should be considered part of dglob() and should not be used + * from other parts of the code. If C could do nested function decls, + * this would be a perfect candidate. + */ + static int + xglob(buf, b, pat1, pat2, exp) + char *buf, *b; + const char *pat1, *pat2; + char ***exp; + { + while (*pat1) { + if (index(FMETA, *pat1)) + return 0; + else if (*pat1 == QNXT && pat1[1]) + pat1++; + *b++ = *pat1++; + } + if (pat2) { + *b++ = SLASH; + while (*pat2) { + if (index(FMETA, *pat2)) + return 0; + else if (*pat2 == '\\' && pat2[1]) + pat2++; + *b++ = *pat2++; + } + } + *b = 0; + return catv(0, exp, 1, unitv(buf)); + } + + /* * Search a directory (possibly recursively) for glob matches. * Argument pat1 is a pattern to be matched in this directory, * and pat2 is a pattern to be matched in matched subdirectories. * * Matches are returned through *exp. */ + int dglob(dir, pat1, pat2, exp) char *dir, *pat1, *pat2, ***exp; { DIR *dirp; struct dirent *dp; ! char *b, buf[MAXPATHLEN], **tmp; ! char *d; ! int n, ret = 0, skip, hits = 0; if (!dir || !exp) return -1; d = (*dir ? dir : "."); ! ! errno = 0; ! if (!(dirp = opendir(d))) { ! if ((errno == ENOENT || errno == ENOTDIR) && ! xglob(buf, b, pat1, pat2, exp) > 0) ! return 0; return -1; ! } skip = b - buf; /* We know this much matches, don't glob it again */ while (ret >= 0 && (dp = readdir(dirp))) { + /* XXX casting away const */ if (fglob(dp->d_name, pat1)) { + hits++; if (pat2) { (void) sprintf(b, "%s/%s", dp->d_name, pat2); ! n = pglob(buf, skip + strlen(dp->d_name), &tmp); ret = catv(ret, exp, n, tmp); } else { (void) strcpy(b, dp->d_name); *************** *** 309,320 **** --- 540,554 ---- } } closedir(dirp); + if (hits == 0 && *pat1) + (void) xglob(buf, b, pat1, pat2, exp); return ret; } /* * Match file names. This means that metachars do not match leading ".". */ + int fglob(str, pat) char *str, *pat; { *************** *** 340,345 **** --- 574,663 ---- } /* + * Match a pattern set {s1,s2,...} followed by any other pattern. + * Pattern sets and other patterns may nest arbitrarily. + * + * If "mat" is not a null pointer, a vector of possible expansions + * is generated and placed in *mat; otherwise, the expansions are + * matched against str and a truth value is returned ("/" is NOT + * treated as a directory separator in this case). NOTE: The vector + * of expansions may still contain nested pattern sets, which must + * be expanded separately. See sxp(). + * + * Currently allows at most 256 alternatives per set. Enough? :-) + */ + static int + sglob(str, pat, mat) + char *str, *pat, ***mat; + { + char *p, *newpat[256], *oldpat[256], buf[MAXPATHLEN], *b = buf; + int copy = 1, had_nest = 0, nest = 0, i = 0, ret = 0; + + if (!pat) + return FALSE; + + while (*pat) { + if (copy) + if (*pat != '{') /*}*/ { + if (*pat == '\\' && pat[1]) + *b++ = *pat++; + *b++ = *pat++; + continue; + } else { + copy = 0; + pat++; + } + p = pat; + while (*pat && (nest || *pat != ',' && /*{*/ *pat != '}')) { + if (*pat == '\\') + pat++; + else if (*pat == '{') + had_nest = nest++; + else if (*pat == '}') + nest--; + if (*pat) + pat++; + } + if (*pat) { + oldpat[i] = pat; + newpat[i++] = p; + if (*pat != ',') { + *pat++ = 0; + break; + } else + *pat++ = 0; + } + } + oldpat[i] = NULL; + if (i > 0 && mat) { + *mat = (char **)malloc((unsigned)((i + 1) * sizeof(char *))); + if (*mat) + (*mat)[i] = NULL; + else + return -1; + ret = i; + } + while (!mat && i-- > 0) + if (ret = glob2(str, newpat[i], pat)) + break; + for (i = 0; oldpat[i]; i++) { + if (mat && *mat) { + (void) sprintf(b, "%s%s", newpat[i], pat); + (*mat)[i] = savestr(buf); + } + if (oldpat[i + 1]) + oldpat[i][0] = ','; + else + oldpat[i][0] = /*{*/ '}'; + } + if (ret == 0 && b > buf && mat) { + *b = 0; + ret = ((*mat = unitv(buf)) ? 1 : -1); + } + return ret; + } + + /* * The basic globbing matcher. * * "*" = match 0 or more occurances of anything *************** *** 348,353 **** --- 666,672 ---- * "xx", "yy" can be any pattern or empty * "?" = match any character */ + int glob(str, pat) char *str, *pat; { *************** *** 357,377 **** return FALSE; while (*pat && !done && (*str || (*pat == '{' || *pat == '*'))) /*}*/ { /* * First look for a literal match, stepping over backslashes * in the pattern to match against the "protected" character. - * Ordering and precendence are important in this expression! */ ! if (*pat == '\\' && *str == *++pat || *str == *pat) { str++; pat++; ! } else switch (*pat++) { case '*': /* Match any string */ ! if (!*pat) { ! while (*str) ! str++; ! break; ! } /* * Try the rest of the glob against every * possible suffix of the string. A bit --- 676,696 ---- return FALSE; while (*pat && !done && (*str || (*pat == '{' || *pat == '*'))) /*}*/ { + char c; /* * First look for a literal match, stepping over backslashes * in the pattern to match against the "protected" character. */ ! if (*pat == '\\' && *str == *++pat) { str++; pat++; ! } else switch (c = *pat++) { case '*': /* Match any string */ ! /* Any number of consecutive '*' are equivalent */ ! while (*pat == '*') ! pat++; ! if (!*pat) ! return TRUE; /* * Try the rest of the glob against every * possible suffix of the string. A bit *************** *** 389,396 **** break; } /* Check for a range. */ ! if (*(pat + 1) == '-') { ! char c = *pat++; /* We don't handle open-ended ranges. */ if (*++pat == ']' || *pat == '\\' && !*++pat) { done = TRUE; --- 708,715 ---- break; } /* Check for a range. */ ! if (pat[1] == '-') { ! c = *pat++; /* We don't handle open-ended ranges. */ if (*++pat == ']' || *pat == '\\' && !*++pat) { done = TRUE; *************** *** 428,529 **** return sglob(str, pat - 1, TRPL_NULL); break; default: ! done = TRUE; } } while (*pat == '*') pat++; return ((*str == '\0') && (*pat == '\0')); } /* - * Match a pattern set {s1,s2,...} followed by any other pattern. - * Pattern sets and other patterns may nest arbitrarily. - * - * If "mat" is not a null pointer, a vector of possible expansions - * is generated and placed in *mat; otherwise, the expansions are - * matched against str and a truth value is returned ("/" is NOT - * treated as a directory separator in this case). NOTE: The vector - * of expansions may still contain nested pattern sets, which must - * be expanded separately. See sxp(). - * - * Currently allows at most 256 alternatives per set. Enough? :-) - */ - static - sglob(str, pat, mat) - char *str, *pat, ***mat; - { - char *p, *newpat[256], *oldpat[256], buf[MAXPATHLEN], *b = buf; - int copy = 1, nest = 0, i = 0, ret = 0; - - if (!pat) - return FALSE; - - while (*pat) { - if (copy) - if (*pat != '{') /*}*/ { - if (*pat == '\\' && pat[1]) - *b++ = *pat++; - *b++ = *pat++; - continue; - } else { - copy = 0; - pat++; - } - p = pat; - while (*pat && (nest || *pat != ',' && /*{*/ *pat != '}')) { - if (*pat == '\\') - pat++; - else if (*pat == '{') - nest++; - else if (*pat == '}') - nest--; - if (*pat) - pat++; - } - if (*pat) { - oldpat[i] = pat; - newpat[i++] = p; - if (*pat != ',') { - *pat++ = 0; - break; - } else - *pat++ = 0; - } - } - oldpat[i] = NULL; - if (i > 0 && mat) { - *mat = (char **)malloc((unsigned)((i + 1) * sizeof(char *))); - if (*mat) - (*mat)[i] = NULL; - else - return -1; - ret = i; - } - while (!mat && i-- > 0) - if (ret = glob2(str, newpat[i], pat)) - break; - for (i = 0; oldpat[i]; i++) { - if (mat && *mat) { - (void) sprintf(b, "%s%s", newpat[i], pat); - (*mat)[i] = savestr(buf); - } - if (oldpat[i + 1]) - oldpat[i][0] = ','; - else - oldpat[i][0] = /*{*/ '}'; - } - if (ret == 0 && b > buf && mat) { - *b = 0; - ret = ((*mat = unitv(buf)) ? 1 : -1); - } - return ret; - } - - /* * Pre-expand pattern set notations so sets containing "/" separators * can be globbed successfully. Returns the number of expansions. */ sxp(pat, exp) char *pat, ***exp; { --- 747,769 ---- return sglob(str, pat - 1, TRPL_NULL); break; default: ! if (*str == c) ! str++; ! else ! done = TRUE; } } + /* Any number of trailing '*' are equivalent */ while (*pat == '*') pat++; return ((*str == '\0') && (*pat == '\0')); } /* * Pre-expand pattern set notations so sets containing "/" separators * can be globbed successfully. Returns the number of expansions. */ + int sxp(pat, exp) char *pat, ***exp; { *************** *** 531,545 **** int n, new, cnt = 0; if ((n = sglob(NULL, pat, &t1)) < 2) { ! *exp = t1; ! return n; } *exp = DUBL_NULL; while (n-- && cnt >= 0) { new = sxp(t1[n], &t2); cnt = catv(cnt, exp, new, t2); } ! xfree(t1); return cnt; } --- 771,800 ---- int n, new, cnt = 0; if ((n = sglob(NULL, pat, &t1)) < 2) { ! char *b = NULL; ! ! /* ! * Determine whether we need to do a recursive expansion. ! */ ! if (t1 && t1[0]) { ! for (pat = t1[0]; *pat && (b = index(pat, '{' /*}*/)); pat++) { ! if (b == t1[0] || b[-1] != '\\') ! break; ! else ! pat = b; ! } ! } ! if (!b) { ! *exp = t1; ! return n; ! } } *exp = DUBL_NULL; while (n-- && cnt >= 0) { new = sxp(t1[n], &t2); cnt = catv(cnt, exp, new, t2); } ! free_vec(t1); return cnt; } *************** *** 548,562 **** * The "glob difference" means to remove all strings from argv that * match any of the glob patterns in patv. * * Returns the number of strings remaining in *argvp. The strings "removed" * from argv are actually left at the end of *argvp, so they can still be * accessed; their number will of course be argc - (returned value). */ gdiffv(argc, argvp, patc, patv) int argc, patc; char ***argvp, **patv; { ! char **argv, *t; int ac, pc, oldac = argc; if (argc < 1 || patc < 1 || !patv || !*patv) --- 803,822 ---- * The "glob difference" means to remove all strings from argv that * match any of the glob patterns in patv. * + * Consecutive slashes in the pattern match literally! This is not a true + * file path "glob". Metacharacters may match '/' characters in some + * circumstances. + * * Returns the number of strings remaining in *argvp. The strings "removed" * from argv are actually left at the end of *argvp, so they can still be * accessed; their number will of course be argc - (returned value). */ + int gdiffv(argc, argvp, patc, patv) int argc, patc; char ***argvp, **patv; { ! char **argv, *t, *h; int ac, pc, oldac = argc; if (argc < 1 || patc < 1 || !patv || !*patv) *************** *** 565,576 **** return -1; for (ac = 0; ac < argc && argv[ac]; ac++) { for (pc = 0; ac < argc && pc < patc && patv[pc]; pc++) { /* ! * We shouldn't cross '/' characters, so test ! * only the "tail" of each element of argv. */ ! if (!(t = rindex(argv[ac], '/'))) ! t = argv[ac]; if (glob(t, patv[pc])) { /* Move matches to the end and reduce argc */ t = argv[ac]; --- 825,849 ---- return -1; for (ac = 0; ac < argc && argv[ac]; ac++) { for (pc = 0; ac < argc && pc < patc && patv[pc]; pc++) { + int l = strlen(argv[ac]); + if (l == 0) + continue; /* ! * We shouldn't cross '/' characters unless they appear ! * in the pattern, so test only as much of the "tail" of ! * each element of argv as necessary. If the first char ! * of the pattern is a '/', match from the beginning. */ ! h = patv[pc]; ! if (*h != '/') { ! for (t = &argv[ac][--l]; t > argv[ac]; t--) { ! if (*t =='/' && !((h = index(h, '/')) && h++)) { ! t++; ! break; ! } ! } ! } else ! t = argv[ac]; if (glob(t, patv[pc])) { /* Move matches to the end and reduce argc */ t = argv[ac]; *************** *** 582,594 **** } } /* ! * Sort the two parts of the argv. uniqcmp() works here only if ! * there already are no duplicates, but we assume that for now. */ if (argc) ! qsort((char *)argv, argc, sizeof(char *), uniqcmp); if (oldac > argc) ! qsort((char *)&argv[argc], oldac - argc, sizeof(char *), uniqcmp); return argc; } --- 855,866 ---- } } /* ! * Sort the two parts of the argv. */ if (argc) ! qsort((char *)argv, argc, sizeof(char *), strptrcmp); if (oldac > argc) ! qsort((char *)&argv[argc], oldac - argc, sizeof(char *), strptrcmp); return argc; } *************** *** 600,605 **** --- 872,878 ---- * * Returns the length of the longest common prefix. */ + int lcprefix(vec, skip) char **vec; int skip; *************** *** 607,613 **** char c, **v; int done = FALSE; ! if (!vec || !*vec || skip < 0) return 0; do { for (v = vec + 1, c = vec[0][skip]; c && *v; v++) --- 880,886 ---- char c, **v; int done = FALSE; ! if (!vec || !*vec || !vec[1] || skip < 0) return 0; do { for (v = vec + 1, c = vec[0][skip]; c && *v; v++) *************** *** 630,648 **** /* * 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); int minwidth, maxwidth, *widths; ! int maxword = 0, n, c; if (argc <= 0 || !argv || !*argv) return -1; --- 903,928 ---- /* * Print a vector in columns * + * If "outv" is non-null, it will be loaded with an allocated vector + * where each element is one line of the columnated text to be output. + * Strings in outv do NOT include a trailing newline! Returns the number + * of elements in outv (or the number of lines printed if outv is null). + * * 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. */ ! int ! columnate(argc, argv, skip, outv) int argc; ! char **argv, ***outv; int skip; { int colstep, colwidth[MAXCOLS + 1]; int maxcols = min(argc, MAXCOLS); int minwidth, maxwidth, *widths; ! int maxword = 0, n, c, lines = 0; ! char *out = NULL; if (argc <= 0 || !argv || !*argv) return -1; *************** *** 683,709 **** } xfree(widths); if (maxcols < 2 && minwidth <= MAXWIDTH / 2) { /* ! * 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; } #ifndef DIRECTORY --- 963,1032 ---- } xfree(widths); + if (outv) + *outv = DUBL_NULL; /* for catv() */ + if (maxcols < 2 && minwidth <= MAXWIDTH / 2) { + char **tmpv = DUBL_NULL; /* ! * If the maxword fills too much screen, redo everything * above it, print maxword, then do everything below it. */ ! if (maxword > 0 && (lines = columnate(maxword, argv, skip, outv)) < 0) return -1; ! if (outv) { ! if ((n = catv(lines, outv, 1, unitv(argv[maxword] + skip))) < 0) { ! if (*outv) ! free_vec(*outv); ! *outv = DUBL_NULL; ! return -1; ! } else ! lines = n; ! } else ! wprint("%s\n", argv[maxword] + skip); if (argc - maxword < 2) ! return lines; ! else if (outv) ! tmpv = *outv; ! n = columnate(argc - maxword - 1, &argv[maxword + 1], skip, outv); ! if (tmpv) { ! if (n < 0 || (n = catv(lines, &tmpv, n, *outv)) < 0) { ! free_vec(tmpv); ! *outv = DUBL_NULL; ! } else ! *outv = tmpv; ! } ! return n; } + if (!(out = malloc((unsigned)(MAXWIDTH + 1)))) { + if (outv && *outv) + free_vec(*outv); + if (outv) + *outv = DUBL_NULL; + return -1; + } for (n = 0; n < colstep; n++) { ! char *p = out; ! for (c = 0; c < maxcols && n + c * colstep < argc - colstep; c++) { ! (void) sprintf(p, "%-*.*s", colwidth[c], colwidth[c], argv[n + c * colstep] + skip); ! p += strlen(p); ! } ! sprintf(p, "%s", argv[n + c * colstep] + skip); ! if (outv) { ! if ((lines = catv(lines, outv, 1, unitv(out))) < 0) { ! if (*outv) ! free_vec(*outv); ! *outv = DUBL_NULL; ! return -1; ! } ! } else ! wprint("%s\n", out); } + xfree(out); ! return lines; } #ifndef DIRECTORY *************** *** 787,793 **** dir.d_fileno = dp->od_ino ; strncpy(dir.d_name, dp->od_name, ODIRSIZ) ; dir.d_name[ODIRSIZ] = '\0' ; /* Ensure termination. */ ! dir.d_namlen = strlen(dir.d_name) ; dir.d_reclen = DIRSIZ(&dir) ; return(&dir) ; } --- 1110,1116 ---- dir.d_fileno = dp->od_ino ; strncpy(dir.d_name, dp->od_name, ODIRSIZ) ; dir.d_name[ODIRSIZ] = '\0' ; /* Ensure termination. */ ! dir.d_namlen = strlen(dir.d_name) + 1; dir.d_reclen = DIRSIZ(&dir) ; return(&dir) ; } diff -cN 7.2.5/hdrs.c 7.2.6-a1/hdrs.c *** 7.2.5/hdrs.c Fri Oct 30 11:55:32 1992 --- 7.2.6-a1/hdrs.c Sun Jul 9 12:52:43 1995 *************** *** 52,58 **** * "buf" and return its address. */ char * ! header_field(n, str) char *str; { static char buf[HDRSIZ]; --- 52,58 ---- * "buf" and return its address. */ char * ! real_header_field(n, str) char *str; { static char buf[HDRSIZ]; *************** *** 91,96 **** --- 91,123 ---- return (*buf)? buf: NULL; } + char * + header_field(n, str) + char *str; + { + register char *p, *q; + + if (!lcase_strcmp(str, "from")) { + if (!(p = q = msg[n].m_from)) + p = real_header_field(n, str); + if (p == NULL) return NULL; + if (q == NULL) msg[n].m_from = savestr(p); + } else if (!lcase_strcmp(str, "subject")) { + if (!(p = q = msg[n].m_subject)) + p = real_header_field(n, str); + if (p == NULL) return NULL; + if (q == NULL) msg[n].m_subject = savestr(p); + } else if (!lcase_strcmp(str, "to")) { + if (!(p = q = msg[n].m_to)) + p = real_header_field(n, str); + if (p == NULL) return NULL; + if (q == NULL) msg[n].m_to = savestr(p); + } else + p = real_header_field(n,str); + + return p; + } + do_hdrs(argc, argv, list) register char **argv, list[]; { *************** *** 393,398 **** --- 420,427 ---- (p = header_field(cnt, "to")) || (p = header_field(cnt, "apparently-to"))) Strncpy(to, p); + else + show_to = 0; /* who's the message from */ if ((p = header_field(cnt, "from")) && strcpy(from, p) *************** *** 412,418 **** * Use take_me_off() to be sure the message really is from the current * user and not just someone with the same login at another site. */ ! if (show_to && !strncmp(p, login, strlen(login))) (void) take_me_off(from); if (show_to && (isauthor = !*from)) { /* assign and test */ (void) get_name_n_addr(to, name+4, addr+4); --- 441,447 ---- * Use take_me_off() to be sure the message really is from the current * user and not just someone with the same login at another site. */ ! if (show_to && (alternates || !strncmp(p, login, strlen(login)))) (void) take_me_off(from); if (show_to && (isauthor = !*from)) { /* assign and test */ (void) get_name_n_addr(to, name+4, addr+4); *************** *** 658,668 **** return ""; skipspaces(1); /* Extra work to handle quoted tokens */ ! while (p2 = any(p, "\" ")) { if (*p2 == '"') { ! if (p2 = index(p2 + 1, '"')) ! p2++; ! else return ""; } else break; --- 687,695 ---- return ""; skipspaces(1); /* Extra work to handle quoted tokens */ ! for (p2 = p; p2 = any(p2, "\" "); p2++) { if (*p2 == '"') { ! if (!(p2 = index(p2 + 1, '"'))) return ""; } else break; *************** *** 672,679 **** if (!unscramble_addr(p, line)) { /* p is safely recopied to line */ p2 = addr; goto BrokenFrom; ! } else p2 = NULL; #else /* MSG_SEPARATOR */ wprint("Warning: unable to find who msg %d is from!\n", n+1); p2 = addr; --- 699,708 ---- if (!unscramble_addr(p, line)) { /* p is safely recopied to line */ p2 = addr; goto BrokenFrom; ! } else { p2 = NULL; + p = line; + } #else /* MSG_SEPARATOR */ wprint("Warning: unable to find who msg %d is from!\n", n+1); p2 = addr; diff -cN 7.2.5/init.c 7.2.6-a1/init.c *** 7.2.5/init.c Fri Oct 30 11:55:33 1992 --- 7.2.6-a1/init.c Sun Jul 9 12:52:43 1995 *************** *** 19,25 **** --- 19,27 ---- extern char *getlogin(); char buf[MAXPATHLEN]; #if defined(SYSV) && !defined(HPUX) && !defined(IRIX4) + #ifndef __linux__ extern struct passwd *getpwuid(); /* sys-v forgot this in pwd.h! */ + #endif struct utsname ourhost; #else char ourhost[128]; *************** *** 37,51 **** } argv[1] = "="; argv[3] = NULL; ! ! if (!(entry = getpwuid(getuid()))) ! if (p = getlogin()) strdup(login, p); else { strdup(login, "unknown"); print("I don't know you, but that's ok.\n"); } ! else { strdup(login, entry->pw_name); if (!home || !*home) home = entry->pw_dir; --- 39,69 ---- } argv[1] = "="; argv[3] = NULL; ! ! #ifndef ROOTMAIL ! /* We want the real user name in the From fields instead of the ! * anonymous root when somebody sends a mail in "su" ! */ ! entry = 0; ! if (getuid() == 0) { ! p = getlogin(); ! if(p && *p) { ! entry = getpwnam(p); ! if (entry && entry->pw_dir && *(entry->pw_dir)) ! home = NULL; ! } ! } ! if (!entry) ! #endif ROOTMAIL ! entry = getpwuid(getuid()); ! if (!entry) { ! if (p = getlogin()) strdup(login, p); else { strdup(login, "unknown"); print("I don't know you, but that's ok.\n"); } ! } else { strdup(login, entry->pw_name); if (!home || !*home) home = entry->pw_dir; diff -cN 7.2.5/lock.c 7.2.6-a1/lock.c *** 7.2.5/lock.c Fri Oct 30 11:55:34 1992 --- 7.2.6-a1/lock.c Sun Jul 9 12:52:44 1995 *************** *** 1,3 **** --- 1,9 ---- + #ifdef linux + /* apparently, linux likes USG locks */ + #define USG + #define SYSV + #endif + /* * lock.c -- deal with file locking on various architectures and UNIXs. * dot_lock() creates a file with the same name as the parameter passed *************** *** 76,81 **** --- 82,89 ---- if (!myname) myname = argv[0]; + else + myname++; if (strcmp(myname, DOLOCK_NAME) != 0 || argc != 3) exit(-1); *************** *** 154,160 **** (void) sprintf(buf, "%s.lock", filename); #endif /* M_XENIX */ on_intr(); ! while ((lockfd = xcreat(buf, 0444)) == -1) { if (errno != EEXIST) { error("unable to lock %s", filename); break; --- 162,168 ---- (void) sprintf(buf, "%s.lock", filename); #endif /* M_XENIX */ on_intr(); ! while ((lockfd = xcreat(buf, 0444)) < 0) { if (errno != EEXIST) { error("unable to lock %s", filename); break; *************** *** 170,176 **** } } off_intr(); ! if (lockfd != -1) { if (cnt) print("done.\n"); (void) close(lockfd); --- 178,184 ---- } } off_intr(); ! if (lockfd >= 0) { if (cnt) print("done.\n"); (void) close(lockfd); *************** *** 185,191 **** #else setgid(getgid()); #endif /* BSD */ ! return lockfd == -1? -1 : 0; #endif /* LOCK_PROG */ } --- 193,199 ---- #else setgid(getgid()); #endif /* BSD */ ! return lockfd < 0? -1 : 0; #endif /* LOCK_PROG */ } *************** *** 253,258 **** --- 261,267 ---- /* * Define some BSD names for the SYSV world */ + #if !defined(LOCK_SH) && !defined(__linux__) #ifdef USG #define LOCK_SH F_RDLCK #define LOCK_EX F_WRLCK *************** *** 263,268 **** --- 272,278 ---- #define LOCK_UN LK_UNLCK #endif /* USG */ #define LOCK_NB 0 /* Always non-blocking in this case */ + #endif /* !LOCK_SH && !__linux__ */ #ifdef EWOULDBLOCK #undef EWOULDBLOCK diff -cN 7.2.5/loop.c 7.2.6-a1/loop.c *** 7.2.5/loop.c Fri Oct 30 11:55:35 1992 --- 7.2.6-a1/loop.c Sun Jul 9 12:52:44 1995 *************** *** 9,15 **** #include "mush.h" #include "version.h" ! #ifdef BSD #include #else #ifndef SYSV --- 9,15 ---- #include "mush.h" #include "version.h" ! #if defined(BSD) || defined(POSIX) #include #else #ifndef SYSV *************** *** 22,28 **** --- 22,30 ---- #define isdelimeter(c) (index(" \t;|", c)) char *alias_expand(), *hist_expand(), *reference_hist(), *hist_from_str(); + #ifndef __STDC__ char *calloc(); + #endif struct history { int histno; *************** *** 31,36 **** --- 33,41 ---- struct history *next; }; static struct history *hist_head, *hist_tail; + #ifdef malloc + #undef malloc + #endif #define malloc(n) (struct history *)calloc((unsigned)1,(unsigned)(n)) #define NULL_HIST (struct history *)0 *************** *** 942,951 **** if (debug > 3) (void) printf("Working on: %s\n",str); /* If final is true, do variable expansions first */ if (final) { - (void) strcpy(buf, str); - str = buf; if (!variable_expand(str)) return DUBL_NULL; } --- 947,956 ---- if (debug > 3) (void) printf("Working on: %s\n",str); + (void) strcpy(buf, str); + str = buf; /* If final is true, do variable expansions first */ if (final) { if (!variable_expand(str)) return DUBL_NULL; } *************** *** 1186,1192 **** --- 1191,1202 ---- char buf[BUFSIZ]; struct history *hist; #ifndef REGCMP + # ifdef REGCOMP + char *rex = NULL; + extern char *regcomp(); + # else extern char *re_comp(); + # endif #else char *rex = NULL; extern char *regcmp(); *************** *** 1207,1213 **** --- 1217,1227 ---- } if (*str) { #ifndef REGCMP + # ifdef REGCOMP + if (!(rex = regcomp(str))) /* Assign and test */ + # else if (re_comp(str)) + # endif #else if (!(rex = regcmp(str, NULL))) /* Assign and test */ #endif /* REGCMP */ *************** *** 1237,1243 **** --- 1251,1261 ---- } else found = #ifndef REGCMP + # ifdef REGCOMP + !!regexec(rex, buf) + # else re_exec(buf) + # endif #else !!regex(rex, buf, NULL) /* convert to boolean value */ #endif /* REGCMP */ *************** *** 1246,1256 **** --- 1264,1290 ---- *hist_number = hist->histno; Debug("Found it in history #%d\n", *hist_number); *p = c; + #ifdef REGCMP + /* XXX: regfree */ + free(rex); + #else + # ifdef REGCOMP + free(rex); + # endif + #endif return (*p == '?' ? p + 1 : p); } } hist_error("%s: event not found\n", str); *p = c; + #ifdef REGCMP + free(rex); + #else + # ifdef REGCOMP + /* XXX: regfree */ + free(rex); + # endif + #endif return NULL; } diff -cN 7.2.5/macros.c 7.2.6-a1/macros.c *** 7.2.5/macros.c Thu May 3 12:40:28 1990 --- 7.2.6-a1/macros.c Sun Jul 9 12:52:44 1995 *************** *** 236,243 **** --- 236,247 ---- turnoff(glob_flags, IN_MACRO); turnoff(glob_flags, LINE_MACRO); turnoff(glob_flags, QUOTE_MACRO); + retry: + errno = 0; while ((c = getchar()) == 0) /* Ignore NUL chars from stdin */ ; /* until better solution found */ + if (c == EOF && errno == EINTR) + goto retry; return c; } } diff -cN 7.2.5/mail.c 7.2.6-a1/mail.c *** 7.2.5/mail.c Fri Oct 30 11:55:36 1992 --- 7.2.6-a1/mail.c Sun Jul 9 12:52:45 1995 *************** *** 19,25 **** static int killme; static u_long flags; static SIGRET (*oldterm)(), (*oldint)(), (*oldquit)(); ! static int finish_up_letter(), send_it(), start_file(); static long add_headers(); static jmp_buf cntrl_c_buf; static char *Hfile, *edfile; --- 19,25 ---- static int killme; static u_long flags; static SIGRET (*oldterm)(), (*oldint)(), (*oldquit)(); ! static int finish_up_letter(), send_it(), start_file(), mail_someone(); static long add_headers(); static jmp_buf cntrl_c_buf; static char *Hfile, *edfile; *************** *** 1076,1089 **** tmpf = ed_fp; msg[msg_cnt].m_offset = 0L; ! if (p = header_field(msg_cnt, "to")) { (void) strcpy(To, p); Cc[0] = Bcc[0] = 0; ! if (p = header_field(msg_cnt, "cc")) (void) strcpy(Cc, p); ! if (p = header_field(msg_cnt, "bcc")) (void) strcpy(Bcc, p); ! if (p = header_field(msg_cnt, "fcc")) next_file += find_files(p, names+next_file, size-next_file, 1); } else *To = 0; /* Error caught below */ --- 1076,1089 ---- tmpf = ed_fp; msg[msg_cnt].m_offset = 0L; ! if (p = real_header_field(msg_cnt, "to")) { (void) strcpy(To, p); Cc[0] = Bcc[0] = 0; ! if (p = real_header_field(msg_cnt, "cc")) (void) strcpy(Cc, p); ! if (p = real_header_field(msg_cnt, "bcc")) (void) strcpy(Bcc, p); ! if (p = real_header_field(msg_cnt, "fcc")) next_file += find_files(p, names+next_file, size-next_file, 1); } else *To = 0; /* Error caught below */ *************** *** 1236,1242 **** if (isoff(flags, VERBOSE) && debug < 3) switch (fork_pid = fork()) { case 0: /* the child will send the letter. ignore signals */ ! #if defined(SYSV) && !defined(AUX) && !defined(IRIX4) if (setpgrp() == -1) #else /* !SYSV || AUX || IRIX4 */ if (setpgrp(0, getpid()) == -1) --- 1236,1242 ---- if (isoff(flags, VERBOSE) && debug < 3) switch (fork_pid = fork()) { case 0: /* the child will send the letter. ignore signals */ ! #if (defined(SYSV) && !defined(AUX) && !defined(IRIX4)) || defined(linux) if (setpgrp() == -1) #else /* !SYSV || AUX || IRIX4 */ if (setpgrp(0, getpid()) == -1) *************** *** 1499,1504 **** --- 1499,1505 ---- int i, for_editor = (fp == NULL_FILE); int got_date = for_editor, got_from = for_editor; struct options *opts; + char facebuf[1024]; if (for_editor && hfile) { i = file_to_fp(hfile, files[0], "r"); *************** *** 1664,1669 **** --- 1665,1671 ---- !lcase_strncmp(p, "bcc:", 4) || !lcase_strncmp(p, "fcc:", 4) || !lcase_strncmp(p, "x-mailer:", 9) || + !lcase_strncmp(p, "x-face:", 7) || !lcase_strncmp(p, "status:", 7)) print_hdr = FALSE; else if (!lcase_strncmp(p, "date:", 5)) *************** *** 1713,1718 **** --- 1715,1721 ---- (void) wrap_addrs(To, 80); (void) wrap_addrs(Cc, 80); (void) wrap_addrs(Bcc, 80); + (void) load_xface(facebuf); for (i = 0; i < size; i++) { if (!files[i]) continue; *************** *** 1727,1732 **** --- 1730,1737 ---- #ifdef PICKY_MAILER } #endif /* PICKY_MAILER */ + if (facebuf[0]) + (void) fprintf(files[i], "X-Face: %s", facebuf); (void) fprintf(files[i], "X-Mailer: %s\n", check_internal("version")); (void) fprintf(files[i], "%sTo: %s\n", ison(flags, FORWARD) ? "Resent-" : "", To); *************** *** 1788,1795 **** --- 1793,1807 ---- (void) signal(sig, rm_edfile); killme = 1; print("\n** interrupt -- one more to kill letter **\n"); + #ifdef __linux__ + m_getchar(); + #endif longjmp(cntrl_c_buf, 1); } + #ifdef __linux__ + if (sig > 0) + m_getchar(); + #endif killme = 0; /* if sig == -1, force a save into dead.letter. * else, check for nosave not being set and save anyway if it's not set diff -cN 7.2.5/main.c 7.2.6-a1/main.c *** 7.2.5/main.c Fri Oct 30 11:55:37 1992 --- 7.2.6-a1/main.c Sun Jul 9 12:52:45 1995 *************** *** 333,338 **** --- 333,339 ---- { char cwd[MAXPATHLEN]; + errno=0; if (GetCwd(cwd, MAXPATHLEN) == NULL) { error("set_cwd: %s", cwd); (void) un_set(&set_options, "cwd"); diff -cN 7.2.5/makefile.bsd 7.2.6-a1/makefile.bsd *** 7.2.5/makefile.bsd Fri Oct 30 11:55:06 1992 --- 7.2.6-a1/makefile.bsd Sun Jul 9 12:52:45 1995 *************** *** 30,38 **** # Use some variant of this one if you #define MMDF in config.h #OTHERLIBS=/usr/src/mmdf/lib/libmmdf.a mush: $(OBJS) @echo loading... ! @cc $(LDFLAGS) $(OBJS) $(LIBS) $(OTHERLIBS) -o mush $(OBJS): config.h mush.h loop.o: version.h --- 30,41 ---- # Use some variant of this one if you #define MMDF in config.h #OTHERLIBS=/usr/src/mmdf/lib/libmmdf.a + # GCC needs -fwritable-strings + #CC= gcc -fwritable-strings + mush: $(OBJS) @echo loading... ! @$(CC) $(LDFLAGS) $(OBJS) $(LIBS) $(OTHERLIBS) -o mush $(OBJS): config.h mush.h loop.o: version.h diff -cN 7.2.5/makefile.bsdi 7.2.6-a1/makefile.bsdi *** 7.2.5/makefile.bsdi Wed Dec 31 16:00:00 1969 --- 7.2.6-a1/makefile.bsdi Sun Jul 9 12:52:51 1995 *************** *** 0 **** --- 1,74 ---- + # makefile.bsdi + # + HDRS= mush.h config.h-dist strings.h bindings.h options.h version.h glob.h pop.h + + SRCS= main.c init.c misc.c mail.c hdrs.c execute.c commands.c print.c dates.c \ + signals.c setopts.c msgs.c pick.c sort.c expr.c folders.c \ + loop.c viewopts.c curses.c curs_io.c bind.c file.c strings.c \ + lock.c macros.c options.c addrs.c malloc.c glob.c command2.c \ + pop.c pmush.c xcreat.c + OBJS= main.o init.o misc.o mail.o hdrs.o execute.o commands.o print.o file.o \ + signals.o setopts.o msgs.o pick.o sort.o expr.o strings.o \ + folders.o dates.o loop.o viewopts.o curses.o curs_io.o bind.o \ + lock.o macros.o options.o addrs.o malloc.o glob.o command2.o \ + pop.o pmush.o xcreat.o + + HELP_FILES= README README-7.0 README-7.1 README-7.2.0 README-7.2.2 \ + README-7.2.4 mush.1 cmd_help Mushrc Mailrc Gnurc \ + sample.mushrc advanced.mushrc digestify + + MAKES= makefile.bsdi makefile.bsd makefile.xenix makefile.sys.v makefile.hpux makefile.sun makefile.solaris + + CFLAGS= -g -DCURSES -DBSD -DSIGRET=void -DBSD44 + LDFLAGS= -g + LINTFLAGS= -bxah -Dlint -DCURSES -DBSD + LIBS= -lcurses -ltermlib -lcompat + OTHERLIBS= + # Use some variant of this one if you #define MMDF in config.h + #OTHERLIBS=/usr/src/mmdf/lib/libmmdf.a + + mush: $(OBJS) + @echo loading... + @$(CC) $(LDFLAGS) $(OBJS) $(LIBS) $(OTHERLIBS) -o mush + + $(OBJS): config.h mush.h + loop.o: version.h + + tape: + @tar cv $(MAKES) $(HDRS) $(SRCS) $(HELP_FILES) + + tar: + @tar fcv MUSH $(MAKES) $(HDRS) $(SRCS) $(HELP_FILES) + + tarmail: + tar fcv - $(MAKES) $(HDRS) $(SRCS) $(HELP_FILES) | \ + compress | btoa > mush.tarmail + + lint: + lint $(LINTFLAGS) $(SRCS) + + clean: + rm -f *.o core mush + + BINDIR= /usr/local/bin + LIBDIR= /usr/local/lib + MRCDIR= /usr/share/misc + MANDIR= /usr/local/man/man1 + MANEXT= 1 + + install: mush + mv mush $(BINDIR) + strip $(BINDIR)/mush + chmod 0755 $(BINDIR)/mush + cp mush.1 $(MANDIR)/mush.$(MANEXT) + chmod 0644 $(MANDIR)/mush.$(MANEXT) + cp cmd_help $(LIBDIR) + chmod 0644 $(LIBDIR)/cmd_help + cp Mushrc $(MRCDIR)/Mushrc + chmod 0644 $(MRCDIR)/Mushrc + + + glob: glob.c + $(CC) $(CFLAGS) -DTEST -DTEST2 glob.c $(LIBS) $(OTHERLIBS) -o glob + + diff -cN 7.2.5/makefile.hpux 7.2.6-a1/makefile.hpux *** 7.2.5/makefile.hpux Fri Oct 30 11:55:06 1992 --- 7.2.6-a1/makefile.hpux Sun Jul 9 12:52:45 1995 *************** *** 29,34 **** --- 29,38 ---- OTHERLIBS= # Use some variant of this one if you #define MMDF in config.h #OTHERLIBS=/usr/src/mmdf/lib/libmmdf.a + + # GCC needs -fwritable-strings + #CC= gcc -fwritable-strings + PROG= mush $(PROG): $(OBJS1) $(OBJS2) diff -cN 7.2.5/makefile.linux 7.2.6-a1/makefile.linux *** 7.2.5/makefile.linux Wed Dec 31 16:00:00 1969 --- 7.2.6-a1/makefile.linux Sun Jul 9 12:52:51 1995 *************** *** 0 **** --- 1,63 ---- + # Mush makefile modified for linux. + # based on Makefile.sys.v + + HDRS1= mush.h config.h + HDRS2= strings.h options.h + HDRS3= bindings.h glob.h + HDRS4= version.h pop.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 + SRCS2= bind.c curs_io.c curses.c file.c strings.c macros.c \ + addrs.c malloc.c glob.c command2.c pop.c pmush.c xcreat.c + + OBJS1= commands.o dates.o execute.o expr.o folders.o \ + hdrs.o init.o loop.o mail.o main.o misc.o msgs.o pick.o \ + print.o setopts.o signals.o sort.o viewopts.o options.o lock.o + OBJS2= bind.o curs_io.o curses.o file.o strings.o macros.o \ + addrs.o malloc.o glob.o command2.o pop.o pmush.o xcreat.o + + HELP= README README-7.0 README-7.1 README-7.2.0 README-7.2.2 \ + README-7.2.4 mush.1 cmd_help Mushrc Mailrc Gnurc \ + sample.mushrc advanced.mushrc digestify + + DEBUG=-O6 + # DEBUG=-g + CFLAGS= $(DEBUG) -DPOSIX -DSIGRET=void -fwritable-strings -DCURSES + LDFLAGS= $(DEBUG) + LIBS= -lcurses -ltermcap + OTHERLIBS= + # Use some variant of this one if you #define MMDF in config.h + #OTHERLIBS=/usr/src/mmdf/lib/libmmdf.a + PROG= mush + + $(PROG): $(OBJS1) $(OBJS2) + @echo loading... + @$(CC) $(LDFLAGS) $(OBJS1) $(OBJS2) -o $(PROG) $(LIBS) $(OTHERLIBS) + + $(OBJS1): $(HDRS1) $(HDRS2) + $(OBJS2): $(HDRS1) $(HDRS2) $(HDRS3) + loop.o: version.h + + #PREFIX= /usr/packages/mush + PREFIX= /usr + BINDIR= $(PREFIX)/bin + LIBDIR= $(PREFIX)/lib + MRCDIR= $(PREFIX)/lib + MANDIR= $(PREFIX)/man1 + MANEXT= 1 + + install: mush + -mkdir $(PREFIX) $(PREFIX)/{bin,lib,man,man/man1} + cp mush $(BINDIR) + strip $(BINDIR)/mush + chmod 0755 $(BINDIR)/mush + cp mush.1 $(MANDIR)/mush.$(MANEXT) + chmod 0644 $(MANDIR)/mush.$(MANEXT) + cp cmd_help $(LIBDIR) + chmod 0644 $(LIBDIR)/cmd_help + cp Mushrc $(MRCDIR)/Mushrc + chmod 0644 $(MRCDIR)/Mushrc + + clean: + rm -f *.o *~ core TAGS tags a.out mush diff -cN 7.2.5/makefile.solaris 7.2.6-a1/makefile.solaris *** 7.2.5/makefile.solaris Wed Dec 31 16:00:00 1969 --- 7.2.6-a1/makefile.solaris Sun Jul 9 12:52:51 1995 *************** *** 0 **** --- 1,65 ---- + # + # Mush makefile for Solaris with gcc 2.5.8 + # + CC=gcc + HDRS1= mush.h config.h + HDRS2= strings.h options.h + HDRS3= bindings.h glob.h + HDRS4= version.h pop.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 + SRCS2= bind.c curs_io.c curses.c file.c strings.c macros.c \ + addrs.c malloc.c command2.c pop.c pmush.c xcreat.c glob.c + + OBJS1= commands.o dates.o execute.o expr.o folders.o \ + hdrs.o init.o loop.o mail.o main.o misc.o msgs.o pick.o \ + print.o setopts.o signals.o sort.o viewopts.o options.o lock.o + OBJS2= bind.o curs_io.o curses.o file.o strings.o macros.o \ + addrs.o malloc.o command2.o pop.o pmush.o xcreat.o glob.o + + HELP= README README-7.0 README-7.1 README-7.2.0 README-7.2.2 \ + README-7.2.4 mush.1 cmd_help Mushrc Mailrc Gnurc \ + sample.mushrc advanced.mushrc digestify + # + # + # + CFLAGS= -g -DSYSV -DUSG -DCURSES -DSIGRET=void -DSVR4 -DREGCMP + LDFLAGS= -g + LIBS= -L/usr/ccs/lib -lcurses -lgen -ltermlib + OTHERLIBS= + # Use some variant of this one if you #define MMDF in config.h + #OTHERLIBS=/usr/src/mmdf/lib/libmmdf.a + PROG= mush + + $(PROG): $(OBJS1) $(OBJS2) + @echo loading... + @$(CC) $(LDFLAGS) $(OBJS1) $(OBJS2) -o $(PROG) $(LIBS) $(OTHERLIBS) + + $(OBJS1): $(HDRS1) $(HDRS2) + $(OBJS2): $(HDRS1) $(HDRS2) $(HDRS3) + loop.o: version.h + + BINDIR= /usr/local/bin + LIBDIR= /usr/local/lib + MRCDIR= /usr/local/lib + MANDIR= /usr/local/man/man1 + MANEXT= 1 + + install: mush + cp mush $(BINDIR) + strip $(BINDIR)/mush + chmod 0755 $(BINDIR)/mush + cp mush.1 $(MANDIR)/mush.$(MANEXT) + chmod 0644 $(MANDIR)/mush.$(MANEXT) + cp cmd_help $(LIBDIR) + chmod 0644 $(LIBDIR)/cmd_help + cp Mushrc $(MRCDIR)/Mushrc + chmod 0644 $(MRCDIR)/Mushrc + + + clean: + rm -f *.o mush + + glob: glob.c + $(CC) $(LDFLAGS) $(CFLAGS) -DTEST -DTEST2 glob.c -o glob $(LIBS) $(OTHERLIBS) diff -cN 7.2.5/makefile.sun 7.2.6-a1/makefile.sun *** 7.2.5/makefile.sun Fri Oct 30 11:55:06 1992 --- 7.2.6-a1/makefile.sun Sun Jul 9 12:52:45 1995 *************** *** 37,42 **** --- 37,45 ---- #OTHERLIBS=/usr/src/mmdf/lib/libmmdf.a LINTFLAGS= -bxah -Dlint + # GCC needs -fwritable-strings + #CC= gcc -fwritable-strings + mush: $(OBJS) @echo loading... @cc $(LDFLAGS) $(OBJS) $(LIBS) $(OTHERLIBS) -o mush diff -cN 7.2.5/makefile.sys.v 7.2.6-a1/makefile.sys.v *** 7.2.5/makefile.sys.v Fri Oct 30 11:55:07 1992 --- 7.2.6-a1/makefile.sys.v Sun Jul 9 12:52:46 1995 *************** *** 37,42 **** --- 37,46 ---- OTHERLIBS= # Use some variant of this one if you #define MMDF in config.h #OTHERLIBS=/usr/src/mmdf/lib/libmmdf.a + + # GCC needs -fwritable-strings + #CC= gcc -fwritable-strings + PROG= mush $(PROG): $(OBJS1) $(OBJS2) diff -cN 7.2.5/makefile.xenix 7.2.6-a1/makefile.xenix *** 7.2.5/makefile.xenix Fri Oct 30 11:55:07 1992 --- 7.2.6-a1/makefile.xenix Sun Jul 9 12:52:46 1995 *************** *** 40,45 **** --- 40,48 ---- # Use some variant of this one if you #define MMDF in config.h #OTHERLIBS=/usr/src/mmdf/lib/libmmdf.a + # GCC needs -fwritable-strings + #CC= gcc -fwritable-strings + mush: $(OBJS) @echo loading... @cc $(LDFLAGS) $(OBJS) $(LIBS) $(OTHERLIBS) -o mush diff -cN 7.2.5/misc.c 7.2.6-a1/misc.c *** 7.2.5/misc.c Fri Oct 30 11:55:37 1992 --- 7.2.6-a1/misc.c Sun Jul 9 12:52:46 1995 *************** *** 762,767 **** --- 762,791 ---- (void) fflush(stdout); /* for sys-v and older xenix */ } + /* + * Load an X-Face header from a file + */ + int + load_xface(facebuf) + char *facebuf; + { + FILE *fp; + char buf[MAXPATHLEN]; + int n = 0; + + facebuf[0] = '\0'; + (void) strcpy(buf, getpath("~/.face", &n)); + if (n == 0 && (fp = fopen(buf, "r"))) { + while (fgets(buf, MAXPATHLEN, fp) != NULL) { + if (facebuf[0] != '\0' && buf[strlen(buf) - 1] == '\n') + (void) strcat(facebuf, " "); + (void) strcat(facebuf, buf); + } + (void) fclose(fp); + return 1; + } else + return 0; + } /* return -1 since function doesn't affect messages */ check_flags(flags) diff -cN 7.2.5/msgs.c 7.2.6-a1/msgs.c *** 7.2.5/msgs.c Fri Oct 30 11:55:39 1992 --- 7.2.6-a1/msgs.c Sun Jul 9 12:52:46 1995 *************** *** 171,177 **** } if (ison(flags, UPDATE_STATUS)) ! if (!strncmp(line, "Status:", 7) || !strncmp(line, "Priority:", 9)) continue; /* ignore "Status" and "Priority" lines */ else if (!on_hdr) { int i, write_priority = 0; --- 171,178 ---- } if (ison(flags, UPDATE_STATUS)) ! if (!lscase_strncmp(line, "Status:", 7) || ! !lcase_strncmp(line, "Priority:", 9)) continue; /* ignore "Status" and "Priority" lines */ else if (!on_hdr) { int i, write_priority = 0; *************** *** 325,330 **** --- 326,332 ---- return 1; if (ison(glob_flags, READ_ONLY)) { print("Unable to update %s: read only\n", mailfile); + print("Please use \"exit\" instead of \"quit\".\n"); return 0; /* user should use "exit" instead of "quit". */ } if (!msg_cnt) /* prevent unnecessary overwrite */ *************** *** 516,522 **** --- 518,527 ---- struct utimbuf times[1]; (void) fflush(mail_fp); /* just in case */ times[0].modtime = time(×[0].actime) - 2; + #ifndef linux + /* this isn't in MY posix manual (IEEE Std 1003.1-1988, 5.6.6.1) */ times[0].ausec = times[0].modusec = 0; + #endif #else /* !POSIX_UTIME */ long times[2]; (void) fflush(mail_fp); /* just in case */ *************** *** 744,757 **** path[0] = '\0'; while (fgets(buf, sizeof buf, fp)) { ! if (strncmp(buf, ">From ", 6)) break; p = buf + 6; (void) sscanf(p, "%s", user); while (p = index(p+1, 'r')) { ! if (!strncmp(p, "remote from ", 12)) { char *p2 = path+strlen(path); skipspaces(12); (void) sscanf(p, "%s", p2); /* add the new machine to current path */ --- 749,762 ---- path[0] = '\0'; while (fgets(buf, sizeof buf, fp)) { ! if (lcase_strncmp(buf, ">From ", 6)) break; p = buf + 6; (void) sscanf(p, "%s", user); while (p = index(p+1, 'r')) { ! if (!lcase_strncmp(p, "remote from ", 12)) { char *p2 = path+strlen(path); skipspaces(12); (void) sscanf(p, "%s", p2); /* add the new machine to current path */ *************** *** 922,935 **** strdup(msg[cnt].m_date_recv, p); } else #endif /* MMDF */ ! if (!strncmp(buf, "Date:", 5)) strdup(msg[cnt].m_date_sent, parse_date(p+5)); else if (!msg[cnt].m_date_sent && ! !strncmp(buf, "Resent-Date:", 12)) msg[cnt].m_date_sent = savestr(parse_date(p+12)); ! else if (!strncmp(buf, "Content-Type:", 13)) turnon(msg[cnt].m_flags, METAMAIL); ! else if (!strncmp(buf, "Priority:", 9)) { for (p += 9 ; *p != '\n'; p++) { if (!isalpha(*p) || upper(*p) > 'A' + MAX_PRIORITY) continue; --- 927,940 ---- strdup(msg[cnt].m_date_recv, p); } else #endif /* MMDF */ ! if (!lcase_strncmp(buf, "Date:", 5)) strdup(msg[cnt].m_date_sent, parse_date(p+5)); else if (!msg[cnt].m_date_sent && ! !lcase_strncmp(buf, "Resent-Date:", 12)) msg[cnt].m_date_sent = savestr(parse_date(p+12)); ! else if (!lcase_strncmp(buf, "content-type:", 13)) turnon(msg[cnt].m_flags, METAMAIL); ! else if (!lcase_strncmp(buf, "Priority:", 9)) { for (p += 9 ; *p != '\n'; p++) { if (!isalpha(*p) || upper(*p) > 'A' + MAX_PRIORITY) continue; *************** *** 937,943 **** M_PRIORITY(upper(*p) - 'A' + 1)); } } else if (get_status && ! !(get_status = strncmp(p, "Status:", 7))) { /* new mail should not have a Status: field! */ turnon(msg[cnt].m_flags, OLD); for (p += 7 ; *p != '\n'; p++) { --- 942,948 ---- M_PRIORITY(upper(*p) - 'A' + 1)); } } else if (get_status && ! !(get_status = lcase_strncmp(p, "Status:", 7))) { /* new mail should not have a Status: field! */ turnon(msg[cnt].m_flags, OLD); for (p += 7 ; *p != '\n'; p++) { *************** *** 1009,1014 **** --- 1014,1026 ---- if (!append) (void) fputs(END_MSG_SEP, tmpf); #endif /* MMDF */ + /* + * Try a little harder to detect i/o errors. + */ + if (isoff(glob_flags, READ_ONLY) && fflush(tmpf) != 0) { + error(tempfile); + had_error++; + } if (had_error) { if (!append) msg[cnt] = old; diff -cN 7.2.5/mush.1 7.2.6-a1/mush.1 *** 7.2.5/mush.1 Fri Oct 30 11:55:03 1992 --- 7.2.6-a1/mush.1 Sun Jul 9 12:52:47 1995 *************** *** 5035,5040 **** --- 5035,5041 ---- .in +4 .\" \& escapes are to make obvious the tab after each word mail\&\& Confirm sending of mail (as above). + update\&\& Confirm updating of mailfolders. save\&\& Confirm save-item selections (tool only). .in -4 .fi diff -cN 7.2.5/mush.h 7.2.6-a1/mush.h *** 7.2.5/mush.h Fri Oct 30 11:55:40 1992 --- 7.2.6-a1/mush.h Sun Jul 9 12:52:48 1995 *************** *** 2,9 **** --- 2,26 ---- #include "config.h" + /* POSIX -- a collection of standardized parts from SYSV and BSD */ + #ifdef POSIX + #include + #include + #define SIGRET void + #endif + + /* STDC -- i.e. ANSI C, a collection of standardized modifications to + * the C language, often accompanied by [partial] POSIX compliance + */ + #ifdef __STDC__ + #ifndef VPRINTF + #define VPRINTF + #endif + #endif + #ifdef CURSES + #ifndef POSIX #ifdef USG # define _USG # undef USG *************** *** 12,18 **** # define _SYSV # undef SYSV #endif /* SYSV */ ! #include #ifdef timeout #undef timeout --- 29,41 ---- # define _SYSV # undef SYSV #endif /* SYSV */ ! #endif /* POSIX */ ! ! #ifndef __linux__ ! # include ! #else ! # include ! #endif #ifdef timeout #undef timeout *************** *** 30,37 **** --- 53,67 ---- #else /* CURSES */ #include + #ifdef POSIX + #include + #else /* POSIX */ #if defined(SYSV) && defined(USG) || defined(AIX) #include + #ifdef DGUX + #include + #endif /* DGUX */ + #endif /* POSIX */ #endif /* SYSV && USG */ #endif /* CURSES */ *************** *** 44,53 **** --- 74,85 ---- #include #include "strings.h" + #ifndef __STDC__ extern char *malloc(), /* allocate memory */ *calloc(), /* allocate and clear memory */ *realloc(); /* re-allocate memory */ + #endif extern void free_vec(), /* free a malloc'ed argv */ *************** *** 57,67 **** #define fputs Fputs /* See comments in print.c */ #endif /* BSD */ ! #if defined(BSD) || defined(GETWD) extern char *getwd(); #define GetCwd(buf,len) getwd(buf) #else extern char *getcwd(); #define GetCwd(buf,len) getcwd(buf,len) #endif /* BSD || GETWD */ --- 89,101 ---- #define fputs Fputs /* See comments in print.c */ #endif /* BSD */ ! #if (defined(BSD) || defined(GETWD)) && !defined(__STDC__) extern char *getwd(); #define GetCwd(buf,len) getwd(buf) #else + #ifndef __STDC__ extern char *getcwd(); + #endif #define GetCwd(buf,len) getcwd(buf,len) #endif /* BSD || GETWD */ *************** *** 91,97 **** --- 125,135 ---- #endif /* SUNTOOL */ #ifdef POSIX_UTIME + #ifdef POSIX + #include + #else /* POSIX */ #include + #endif /* POSIX */ #endif /* POSIX_UTIME */ #include #include *************** *** 166,178 **** #endif /* TIOCSETN */ /* for system-V machines that run termio */ ! #if defined(SYSV) && defined(USG) || defined(AIX) #ifdef crmode #undef crmode #undef nocrmode #endif /* nocrmode */ unsigned char vmin, vtime; #define sg_erase c_cc[2] #define sg_flags c_lflag #define sg_kill c_cc[3] --- 204,238 ---- #endif /* TIOCSETN */ /* for system-V machines that run termio */ ! #if defined(SYSV) && defined(USG) || defined(AIX) || defined(POSIX) || defined(BSD44) #ifdef crmode #undef crmode #undef nocrmode #endif /* nocrmode */ unsigned char vmin, vtime; + + #ifdef __linux__ + # undef TCGETA + # undef TCSETAW + # define TCGETA TCGETS + # define TCSETAW TCSETSW + #endif + #ifdef BSD44 + # undef TCGETA + # undef TCSETAW + # define TCGETA TIOCGETA + # define TCSETAW TIOCSETAW + #endif + + #ifdef POSIX + #define sg_erase c_cc[VERASE] + #define sg_flags c_lflag + #define sg_kill c_cc[VKILL] + #define gtty(fd, SGTTYbuf) tcgetattr(fd, SGTTYbuf) + #undef stty + #define stty(fd, SGTTYbuf) tcsetattr(fd, TCSADRAIN, SGTTYbuf) + #else /* !POSIX */ #define sg_erase c_cc[2] #define sg_flags c_lflag #define sg_kill c_cc[3] *************** *** 180,185 **** --- 240,247 ---- #define gtty(fd, SGTTYbuf) ioctl(fd, TCGETA, SGTTYbuf) #undef stty #define stty(fd, SGTTYbuf) ioctl(fd, TCSETAW, SGTTYbuf) + #endif /* POSIX */ + #define echon() (_tty.sg_flags |= (ECHO|ECHOE), stty(0, &_tty)) #define echoff() (_tty.sg_flags &= ~ECHO, stty(0, &_tty)) #define cbrkon() \ *************** *** 187,205 **** #define cbrkoff() \ (_tty.sg_flags |= ICANON,_tty.c_cc[VMIN] = vmin,_tty.c_iflag |= ICRNL, \ _tty.c_cc[VTIME] = vtime, stty(0, &_tty)) ! #define savetty() \ (void) gtty(0, &_tty), vtime = _tty.c_cc[VTIME], vmin = _tty.c_cc[VMIN] ! #define cbreak() cbrkon() ! #define nocbreak() cbrkoff() /* If curses isn't defined, declare our 'tty' and macros for echo/cbreak */ #ifndef CURSES typedef struct termio SGTTY; #define echom() echon() #define noechom() echoff() #define crmode() cbrkon() #define nocrmode() cbrkoff() #else /* CURSES */ /* If curses is defined, use the echo/cbreak commands in library only * if curses is running. If curses isn't running, use macros above. --- 249,289 ---- #define cbrkoff() \ (_tty.sg_flags |= ICANON,_tty.c_cc[VMIN] = vmin,_tty.c_iflag |= ICRNL, \ _tty.c_cc[VTIME] = vtime, stty(0, &_tty)) ! ! #ifdef __linux__ ! # undef savetty ! # undef cbreak ! # undef nocbreak ! #endif ! ! #ifndef savetty ! # define savetty() \ (void) gtty(0, &_tty), vtime = _tty.c_cc[VTIME], vmin = _tty.c_cc[VMIN] ! #endif ! #ifndef cbreak ! # define cbreak() cbrkon() ! #endif ! #ifndef nocbreak ! # define nocbreak() cbrkoff() ! #endif /* If curses isn't defined, declare our 'tty' and macros for echo/cbreak */ #ifndef CURSES + #ifdef POSIX + typedef struct termios SGTTY; + #else typedef struct termio SGTTY; + #endif #define echom() echon() #define noechom() echoff() #define crmode() cbrkon() #define nocrmode() cbrkoff() + /* These two moved from above; is that right?? Were they misplaced? */ + /* are these even needed? I don't think any code (except below) uses them. */ + #define cbreak() cbrkon() + #define nocbreak() cbrkoff() + #else /* CURSES */ /* If curses is defined, use the echo/cbreak commands in library only * if curses is running. If curses isn't running, use macros above. *************** *** 209,217 **** #define crmode() ((iscurses) ? cbreak() : cbrkon()) #define nocrmode() ((iscurses) ? nocbreak() : cbrkoff()) #endif /* CURSES */ ! #endif /* SYSV && USG || AIX */ ! #if !defined(USG) && !defined(AIX) #ifndef CURSES /* if curses is not defined, simulate the same tty based macros */ typedef struct sgttyb SGTTY; --- 293,301 ---- #define crmode() ((iscurses) ? cbreak() : cbrkon()) #define nocrmode() ((iscurses) ? nocbreak() : cbrkoff()) #endif /* CURSES */ ! #endif /* SYSV && USG || AIX || POSIX || BSD44 */ ! #if !defined(USG) && !defined(AIX) && !defined(POSIX) && !defined(BSD44) #ifndef CURSES /* if curses is not defined, simulate the same tty based macros */ typedef struct sgttyb SGTTY; *************** *** 299,305 **** --- 383,393 ---- #if defined(CURSES) || defined(SUNTOOL) #define print_more turnon(glob_flags, CONT_PRNT), print + #ifdef __STDC__ + void print(char *fmt,...); /* compliance with ansi header for varargs */ + #else /* __STDC__ */ void print(); /* printf to window or curses or tty accordingly */ + #endif /* __STDC__ */ #endif /* CURSES || SUNTOOL */ #define ArraySize(o) (sizeof(o) / sizeof(*o)) *************** *** 328,338 **** #define ison(flg,val) ((u_long)(flg) & (u_long)(val)) #define isoff(flg,val) (!ison((flg), (val))) #define set_replied(n) \ ! if (isoff(msg[n].m_flags, REPLIED)) \ ! turnon(glob_flags, DO_UPDATE), turnon(msg[n].m_flags, REPLIED) #define set_isread(n) \ ! if (turnon(msg[n].m_flags, DO_UPDATE) && ison(msg[n].m_flags, UNREAD)) \ ! turnon(glob_flags, DO_UPDATE), turnoff(msg[n].m_flags, UNREAD) #define in_pipe() (ison(glob_flags, DO_PIPE|IS_PIPE)) #define in_macro() (ison(glob_flags, LINE_MACRO|IN_MACRO)) --- 416,428 ---- #define ison(flg,val) ((u_long)(flg) & (u_long)(val)) #define isoff(flg,val) (!ison((flg), (val))) #define set_replied(n) \ ! (isoff(msg[n].m_flags, REPLIED)? \ ! turnon(glob_flags, DO_UPDATE), turnon(msg[n].m_flags, REPLIED) : \ ! (u_long)0) #define set_isread(n) \ ! (ison(glob_flags, READ_ONLY)? turnoff(msg[n].m_flags, UNREAD) : \ ! (turnon(msg[n].m_flags, DO_UPDATE) && ison(msg[n].m_flags, UNREAD)? \ ! turnon(glob_flags, DO_UPDATE), turnoff(msg[n].m_flags, UNREAD))) #define in_pipe() (ison(glob_flags, DO_PIPE|IS_PIPE)) #define in_macro() (ison(glob_flags, LINE_MACRO|IN_MACRO)) *************** *** 403,408 **** --- 493,500 ---- #define HELP_TEXT ULBIT(25) /* create textsw frame for paging help messages */ #define CORRUPTED ULBIT(26) /* error loading new mail has occurred */ + #define DONT_CHECK (DO_SHELL|IS_PIPE|IGN_SIGS|IS_GETTING|READ_ONLY|REDIRECT|CNTD_CMD|IS_SENDING|IN_MACRO) + /* flags to control composition */ #define VERBOSE ULBIT(0) /* verbose flag for sendmail */ #define INCLUDE ULBIT(1) /* include msg in response */ *************** *** 446,451 **** --- 538,549 ---- int m_lines; /* number of lines in msg */ char *m_date_recv;/* Date user received msg (see dates.c for fmt) */ char *m_date_sent;/* Date author sent msg (see dates.c for fmt) */ + char *m_to; /* Cached To: field */ + char *m_subject; /* Cached Subject: field */ + char *m_from; /* Cached Reply-To: or From: field */ + char *m_addr; /* Cached Reply-To: or From: field */ + char *m_name; /* Cached Reply-To: or From: field */ + char m_author; /* if any of the 3 preceding ones has been inited */ } msg[MAXMSGS]; struct options { *************** *** 476,484 **** *lock_fopen(), /* open and lock a file as an atomic operation */ *popen(); /* this should be in stdio.h */ extern char ! *sys_errlist[], /* system's list of global error messages */ **environ; /* user's environment variables */ extern int errno; /* global system error number */ jmp_buf jmpbuf; /* longjmp to jmpbuf on sigs (not in tool) */ --- 574,586 ---- *lock_fopen(), /* open and lock a file as an atomic operation */ *popen(); /* this should be in stdio.h */ + #ifndef __STDC__ extern char ! #ifndef BSD44 ! *sys_errlist[], /* system's list of global error messages */ ! #endif **environ; /* user's environment variables */ + #endif extern int errno; /* global system error number */ jmp_buf jmpbuf; /* longjmp to jmpbuf on sigs (not in tool) */ *************** *** 526,532 **** *cc_to(), /* when responding, return str which is the cc-list */ *compose_hdr(), /* passes hdr_format to format_hdr() for displays */ *format_hdr(), /* returns a formatted line describing passed msg # */ ! *header_field(), /* the line in msg described by arg (message header) */ *reply_to(), /* who do we reply to when responding */ *subject_to(), /* when responding, return str which is the subject */ --- 628,635 ---- *cc_to(), /* when responding, return str which is the cc-list */ *compose_hdr(), /* passes hdr_format to format_hdr() for displays */ *format_hdr(), /* returns a formatted line describing passed msg # */ ! *real_header_field(),/* the line in msg described by arg (message header) */ ! *header_field(), /* the line in msg described by arg (possibly cached) */ *reply_to(), /* who do we reply to when responding */ *subject_to(), /* when responding, return str which is the subject */ *************** *** 614,619 **** --- 717,725 ---- #define MIN_TIME_OUT (15 * 60) /* 15 min. checks */ extern void popchkmail(); extern void popgetmail(); + #ifdef MAIL_FROM_POPHOST + extern char *pophostname(); + #endif /* MAIL_FROM_POPHOST */ #else #define MIN_TIME_OUT 30 /* 30 sec. checks */ #endif /* POP3_SUPPORT */ diff -cN 7.2.5/pick.c 7.2.6-a1/pick.c *** 7.2.5/pick.c Fri Oct 30 11:55:41 1992 --- 7.2.6-a1/pick.c Sun Jul 9 12:52:48 1995 *************** *** 9,14 **** --- 9,22 ---- static int pick(); static void month_day_year(); + #ifdef REGCOMP + regerror(msg) + char *msg; + { + printf("regcomp error: %s\n", msg); + } + #endif + do_pick(n, argv, list) register int n; register char **argv, list[]; *************** *** 293,299 **** --- 301,311 ---- #ifdef REGCMP char *regcmp(), *regex(); #else /* REGCMP */ + # ifdef REGCOMP + char *regcomp(), *regexec(); + # else char *re_comp(); + # endif #endif /* REGCMP */ if (p && *p == '\\') *************** *** 310,320 **** --- 322,339 ---- return -1; } #else /* REGCMP */ + # ifdef REGCOMP + if ((err = regcomp(p)) == NULL) { + clear_msg_list(ret_list); + return -1; + } + # else if (err = re_comp(p)) { print("re_comp error: %s\n", err); clear_msg_list(ret_list); return -1; } + # endif #endif /* REGCMP */ } else if (err == NULL && mdy[1] <= 0 && match_priority == 0) { print("No previous regular expression\n"); *************** *** 396,402 **** --- 415,425 ---- #ifdef REGCMP val = !!regex(err, p, NULL); /* convert value to a boolean */ #else /* REGCMP */ + # ifdef REGCOMP + val = !!regexec(err, p); + # else val = re_exec(p); + # endif #endif /* REGCMP */ if (val == -1) { /* doesn't apply in system V */ print("Internal error for pattern search.\n"); *************** *** 417,422 **** --- 440,451 ---- #ifdef REGCMP if (err) free(err); + #else + # ifdef REGCOMP + if (err) + /* XXX: regfree soon */ + free(err); + # endif #endif /* REGCMP */ return matches; } *************** *** 439,445 **** --- 468,478 ---- #ifdef REGCMP char *regex(), *regcmp(); #else /* REGCMP */ + # ifdef REGCOMP + char *regcomp(), *regexec(); + # else char *re_comp(); + # endif #endif /* REGCMP */ if (msg_cnt <= 1) { *************** *** 468,477 **** --- 501,517 ---- return 0; } #else /* REGCMP */ + # ifdef REGCOMP + if (*pattern && !(err = regcomp(pattern, NULL))) { + print("Error in regcomp in %s", pattern); + return 0; + } + # else if (err = re_comp(pattern)) { print(err); return 0; } + # endif #endif /* REGCMP */ move(LINES-1, 0), refresh(); on_intr(); *************** *** 486,496 **** --- 526,551 ---- #ifdef REGCMP val = !!regex(err, p, NULL); /* convert value to a boolean */ #else /* REGCMP */ + # ifdef REGCOMP + val = !!regexec(err, p); + # else val = re_exec(p); + # endif #endif /* REGCMP */ if (val == -1) /* doesn't apply in system V */ print("Internal error for pattern search.\n"); } while (!val && current_msg != this_msg && isoff(glob_flags, WAS_INTR)); + + #ifdef REGCMP + if (err) + free(err); + #else + # ifdef REGCOMP + if (err) + /* XXX: regfree soon */ + free(err); + # endif + #endif /* REGCMP */ if (ison(glob_flags, WAS_INTR)) { print("Pattern search interrupted."); diff -cN 7.2.5/pmush.c 7.2.6-a1/pmush.c *** 7.2.5/pmush.c Fri Oct 30 11:56:16 1992 --- 7.2.6-a1/pmush.c Sun Jul 9 12:52:48 1995 *************** *** 9,17 **** variable POP3_SUPPORT is defined. **************************************************************************/ #ifdef POP3_SUPPORT - #include "config.h" #include "mush.h" #include "pop.h" --- 9,18 ---- variable POP3_SUPPORT is defined. **************************************************************************/ + #include "config.h" + #ifdef POP3_SUPPORT #include "mush.h" #include "pop.h" *************** *** 74,80 **** free(val); return (0); } ! ptr += strlen(val); while (*ptr && ((*ptr == ' ') || (*ptr == '\t'))) ptr++; --- 75,81 ---- free(val); return (0); } ! ptr += strlen(val) - (*val == '\n'); while (*ptr && ((*ptr == ' ') || (*ptr == '\t'))) ptr++; *************** *** 95,101 **** * Athena. * * Modified to get rid of dependence on that hideous B-news yacc parser. - * Mush already has a perfectly good date parser, let's use it. -- Bart */ static char * date(msg) --- 96,101 ---- *************** *** 105,123 **** long t; int size; ! real = header(msg, "Date"); ! ! if (real) { ! machine = parse_date(real); ! free(real); ! if (machine) { ! machine = date_to_ctime(machine); ! } ! } ! if (!machine) { ! t = time((long *)0); ! machine = ctime(&t); ! } size = strlen(machine); machine[size - 1] = '\0'; /* get rid of newline */ real = malloc(size); --- 105,112 ---- long t; int size; ! t = time((long *)0); ! machine = ctime(&t); size = strlen(machine); machine[size - 1] = '\0'; /* get rid of newline */ real = malloc(size); *************** *** 166,181 **** * arrived during the Mush session. */ static void ! loadmail() { PopServer postinfo; int msgcount, msgsize, i, flags = 0; char mailbox[MAXPATHLEN], *msgptr, *dateline, *fromline; FILE *mfstream; - struct stat mfstat; static char pass[64]; ! *mailbox = (char) NULL; /* Clear string */ strcat(mailbox, getenv("HOME")); strcat(mailbox, "/"); strcat(mailbox, MAILFILE); --- 155,170 ---- * arrived during the Mush session. */ static void ! loadmail(master) ! int master; { PopServer postinfo; int msgcount, msgsize, i, flags = 0; char mailbox[MAXPATHLEN], *msgptr, *dateline, *fromline; FILE *mfstream; static char pass[64]; ! *mailbox = 0; /* Clear string */ strcat(mailbox, getenv("HOME")); strcat(mailbox, "/"); strcat(mailbox, MAILFILE); *************** *** 198,233 **** return; } /* Begin loading mailbox */ ! if (stat(mailbox, &mfstat)) { ! if (errno == ENOENT) { ! close(open(mailbox, O_WRONLY | O_CREAT | O_EXCL, 0600)); ! } ! } ! if (!(mfstream = fopen(mailbox, "a"))) { ! perror("Error opening mailbox in loadmail"); pop_close(postinfo); return; } for (i = 1; i <= msgcount; i++) { /* Load new messages */ ! msgptr = pop_retrieve(postinfo, i); ! dateline = date(msgptr); ! fromline = from_line(msgptr); ! if (fprintf(mfstream, "\nFrom %s %s\n%s", fromline, dateline, msgptr) ! < (strlen(fromline) + strlen(dateline) + strlen(msgptr))) { ! fprintf(stderr, "Error writing mailbox file\n"); pop_close(postinfo); ! cleanup(-1); } - free(dateline); - free(fromline); free(msgptr); if (pop_delete(postinfo, i)) { fprintf(stderr, "Error deleting message from post office: %s\n", pop_error); } } ! if (fclose(mfstream) == EOF) { ! perror("Error closing mailbox file in loadmail"); pop_close(postinfo); return; } --- 187,231 ---- return; } /* Begin loading mailbox */ ! if (!(mfstream = lock_fopen(mailbox, "a"))) { ! perror(mailbox); pop_close(postinfo); return; } for (i = 1; i <= msgcount; i++) { /* Load new messages */ ! if (!(msgptr = pop_retrieve(postinfo, i))) ! break; ! if (strncmp(msgptr, "From ", 5) != 0) { ! dateline = date(msgptr); ! fromline = from_line(msgptr); ! if (fprintf(mfstream, "\nFrom %s %s\n%s", ! fromline, dateline, msgptr) ! < (strlen(fromline) + strlen(dateline) + strlen(msgptr))) { ! fprintf(stderr, "Error writing mailbox file\n"); ! pop_close(postinfo); ! if (master) ! cleanup(-1); ! else ! exit(1); ! } ! free(dateline); ! free(fromline); ! } else if (fprintf(mfstream, "%s", msgptr) < (strlen(msgptr))) { ! perror(mailbox); pop_close(postinfo); ! if (master) ! cleanup(-1); ! else ! exit(1); } free(msgptr); if (pop_delete(postinfo, i)) { fprintf(stderr, "Error deleting message from post office: %s\n", pop_error); } } ! if (close_lock(mailbox, mfstream) == EOF) { ! perror(mailbox); pop_close(postinfo); return; } *************** *** 244,250 **** void popgetmail() { ! loadmail(); } /* This function calls loadmail, after first forking, releasing stdin, --- 242,248 ---- void popgetmail() { ! loadmail(TRUE); } /* This function calls loadmail, after first forking, releasing stdin, *************** *** 277,283 **** signal(SIGTERM, SIG_IGN); signal(SIGIO, SIG_IGN); signal(SIGPIPE, SIG_IGN); ! loadmail(); _exit(0); } else { if (cpid == -1) { --- 275,281 ---- signal(SIGTERM, SIG_IGN); signal(SIGIO, SIG_IGN); signal(SIGPIPE, SIG_IGN); ! loadmail(FALSE); _exit(0); } else { if (cpid == -1) { *************** *** 286,290 **** --- 284,316 ---- return; } } + + #ifdef MAIL_FROM_POPHOST + /* + * Get the name of the pop host + */ + int + pophostname(name, namelen) + char *name; + int namelen; + { + char *host = getenv("MAILHOST"); + + if (!host || !*host) { + #ifdef DEFAULT_POPHOST + host = DEFAULT_POPHOST; + #else /* !DEFAULT_POPHOST */ + errno = 0; + host = ""; + #endif /* !DEFAULT_POPHOST */ + } + strcpy(name, host); + + if (!*host) + return -1; + else + return 0; + } + #endif /* MAIL_FROM_POPHOST */ #endif /* POP3_SUPPORT */ diff -cN 7.2.5/pop.c 7.2.6-a1/pop.c *** 7.2.5/pop.c Fri Oct 30 11:56:14 1992 --- 7.2.6-a1/pop.c Sun Jul 9 12:52:49 1995 *************** *** 6,11 **** --- 6,13 ---- * August 13, 1991 */ + #include "config.h" + #ifdef POP3_SUPPORT #include *************** *** 41,52 **** --- 43,61 ---- #endif /* HESIOD */ #include + #ifdef SYSV #include + #endif + #ifdef BSD #include + #endif extern char * strstr( /* char *, char * */ ); + extern char * + index( /* char *, char */); + #include #include #include *************** *** 179,186 **** --- 188,199 ---- if (!host) { host = getenv("MAILHOST"); if (!host) { + #ifdef DEFAULT_POPHOST + host = DEFAULT_POPHOST; + #else /* !DEFAULT_POPHOST */ strcpy(pop_error, "Could not determine POP server"); return (0); + #endif /* !DEFAULT_POPHOST */ } } /* Determine the password */ *************** *** 221,228 **** server->data = 0; server->dp = server->buffer; ! if (getok(server)) return (0); /* * I really shouldn't use the pop_error variable like this, but.... --- 234,243 ---- server->data = 0; server->dp = server->buffer; ! if (getok(server)) { ! pop_close(server); return (0); + } /* * I really shouldn't use the pop_error variable like this, but.... *************** *** 233,241 **** "Username too long; recompile pop.c with larger ERROR_MAX"); return (0); } - sprintf(pop_error, "USER %s", username); ! if (sendline(server, pop_error) || getok(server)) { return (0); } if (strlen(password) > ERROR_MAX - 6) { --- 248,257 ---- "Username too long; recompile pop.c with larger ERROR_MAX"); return (0); } ! sprintf(buf, "USER %s", username); ! if (sendline(server, buf) || getok(server)) { ! pop_close(server); return (0); } if (strlen(password) > ERROR_MAX - 6) { *************** *** 244,258 **** "Password too long; recompile pop.c with larger ERROR_MAX"); return (0); } ! sprintf(pop_error, "PASS %s", password); ! ! if (sendline(server, pop_error) || getok(server)) { return (0); } return (server); } /* * Function: pop_stat * * Purpose: Issue the STAT command to the server and return (in the --- 260,319 ---- "Password too long; recompile pop.c with larger ERROR_MAX"); return (0); } ! sprintf(buf, "PASS %s", password); ! mailserver_SetPassword(mserv, password); ! if (sendline(server, buf) || getok(server)) { ! /* pf Fri Feb 18 11:36:16 1994 ! * this is a hack but it works.. make sure the error string ! * is the same as what pop_init is expecting. Do not localize ! * this. ! */ ! if (strstr(pop_error, "assword")) { ! strcpy(pop_error, "-ERR invalid password"); ! mailserver_UnsetPassword(mserv); ! } ! pop_close(server); return (0); } return (server); } /* + * pop_top: issue TOP command to pop server, with given msg num & # of + * lines. assumes open connection. puts results into pserv. + * doesn't report pop errs + */ + int pop_top(pserv, tdata, msgnum, lines) + PopServer pserv; + char *tdata; + int msgnum, lines; + { + char buf[32]; + char *p; + int size; + + pserv->data = 0; + if (!tdata) + return (-1); + *tdata = 0; + sprintf(buf, "TOP %d %d", msgnum, lines); + if (sendline(pserv, buf) || getok(pserv)) + return (-1); + while (TRUE) { + if (!(p = getline(pserv))) + return (-1); + if (p[0] == '.' && !p[1]) + break; + size = strlen(p); + strncpy(tdata, p, size + 1); + tdata += size; + *tdata++ = '\n'; + *tdata = '\0'; + } + return 0; + } /* pop_top */ + + /* * Function: pop_stat * * Purpose: Issue the STAT command to the server and return (in the *************** *** 261,268 **** * * Return value: 0 on success, or non-zero with an error in pop_error * in failure. - * - * Side effects: Closes the connection on failure. */ int pop_stat(server, count, size) --- 322,327 ---- *************** *** 276,282 **** if (strncmp(fromserver, "+OK ", 4)) { strcpy(pop_error, "Unexpected response from POP server in pop_stat"); - pop_close(); return (-1); } *count = atoi(&fromserver[4]); --- 335,340 ---- *************** *** 285,291 **** if (!fromserver) { strcpy(pop_error, "Badly formatted response from server in pop_stat"); - pop_close(server); return (-1); } *size = atoi(fromserver + 1); --- 343,348 ---- *************** *** 309,315 **** * Return value: 0 on success, non-zero with error in pop_error on * failure. * - * Side effects: Closes the connection on error. */ int pop_list(server, message, IDs, sizes) --- 366,371 ---- *************** *** 333,339 **** *sizes = (int *) malloc((how_many + 1) * sizeof(int)); if (!(*IDs && *sizes)) { strcpy(pop_error, "Out of memory in pop_list"); - pop_close(server); return (-1); } if (message) { --- 389,394 ---- *************** *** 349,362 **** return (-1); } if (strncmp(fromserver, "+OK ", 4)) { ! if (!strncmp(fromserver, "-ERR", 4)) ! strncpy(pop_error, fromserver, ERROR_MAX); ! else strcpy(pop_error, "Unexpected response from server in pop_list"); free((char *) *IDs); free((char *) *sizes); - pop_close(server); return (-1); } (*IDs)[0] = atoi(&fromserver[4]); --- 404,417 ---- return (-1); } if (strncmp(fromserver, "+OK ", 4)) { ! if (!strncmp(fromserver, "-ERR", 4)) { ! pop_error[0] = 0; ! strncat(pop_error, fromserver+4, ERROR_MAX); ! } else strcpy(pop_error, "Unexpected response from server in pop_list"); free((char *) *IDs); free((char *) *sizes); return (-1); } (*IDs)[0] = atoi(&fromserver[4]); *************** *** 366,372 **** "Badly formatted response from server in pop_list"); free((char *) *IDs); free((char *) *sizes); - pop_close(server); return (-1); } (*sizes)[0] = atoi(fromserver); --- 421,426 ---- *************** *** 391,397 **** "Badly formatted response from server in pop_list"); free((char *) *IDs); free((char *) *sizes); - pop_close(server); return (-1); } (*sizes)[i] = atoi(fromserver); --- 445,450 ---- *************** *** 417,424 **** * * Return value: A string pointing to the message, if successful, or * null with pop_error set if not. - * - * Side effects: Closes the connection on error. */ char * pop_retrieve(server, message) --- 470,475 ---- *************** *** 441,447 **** if (!ptr) { strcpy(pop_error, "Out of memory in pop_retrieve"); - pop_close(server); return (0); } *cp = '\0'; --- 492,497 ---- *************** *** 452,458 **** if (!fromserver) { free(ptr); - pop_close(server); return (0); } if (fromserver[0] == '.') { --- 502,507 ---- *************** *** 488,494 **** sprintf(pop_error, "DELE %d", message); if (sendline(server, pop_error) || getok(server)) { - pop_close(server); return (-1); } return (0); --- 537,542 ---- *************** *** 504,520 **** * * Return value: 0 on success, non-zero with error in pop_error * otherwise. - * - * Side effects: Closes connection on error. */ int pop_noop(server) PopServer server; { if (sendline(server, "NOOP") || getok(server)) ! return (-1); ! return (0); } /* --- 552,567 ---- * * Return value: 0 on success, non-zero with error in pop_error * otherwise. */ int pop_noop(server) PopServer server; { + int ret = 0; if (sendline(server, "NOOP") || getok(server)) ! ret = -1; ! return ret; } /* *************** *** 528,559 **** * Return value: If successful, the highest seen message, which is * greater than or equal to 0. Otherwise, a negative number with * the error explained in pop_error. - * - * Side effects: Closes the connection on error. */ int pop_last(server) PopServer server; { char *fromserver; ! if (sendline(server, "LAST")) ! return (-1); ! ! if (!(fromserver = getline(server))) ! return (-1); ! ! if (!strncmp(fromserver, "-ERR", 4)) { ! strncpy(pop_error, fromserver, ERROR_MAX); ! pop_close(server); ! return (-1); ! } else if (strncmp(fromserver, "+OK", 3)) { ! strcpy(pop_error, "Unexpected response from server in pop_last"); ! pop_close(server); ! return (-1); ! } else { ! return (atoi(&fromserver[4])); } } /* --- 575,607 ---- * Return value: If successful, the highest seen message, which is * greater than or equal to 0. Otherwise, a negative number with * the error explained in pop_error. */ int pop_last(server) PopServer server; { char *fromserver; + int ret = -1; ! if (sendline(server, "LAST") == 0) ! { ! fromserver = getline(server); ! if (fromserver) ! { ! if (!strncmp(fromserver, "-ERR", 4)) ! { ! pop_error[0] = 0; ! strncat(pop_error, fromserver+4, ERROR_MAX); ! } else if (strncmp(fromserver, "+OK", 3)) ! { ! strcpy(pop_error, ! "Unexpected response from server in pop_last"); ! } else { ! ret = atoi(&fromserver[4]); ! } ! } } + return ret; } /* *************** *** 566,583 **** * * Return value: 0 for success, non-0 with error in pop_error * otherwise. - * - * Side effects: Closes the connection on error. */ int pop_reset(server) PopServer server; { ! if (sendline(server, "RSET") || getok(server)) { ! pop_close(server); ! return (-1); ! } ! return (0); } /* --- 614,629 ---- * * Return value: 0 for success, non-0 with error in pop_error * otherwise. */ int pop_reset(server) PopServer server; { ! int ret = 0; ! if (sendline(server, "RSET") || getok(server)) ! ret = -1; ! ! return ret; } /* *************** *** 753,760 **** * error, with an error message copied into pop_error. * * Notes: The line returned is overwritten with each call to getline. - * - * Side effects: Closes the connection on error. */ static char * getline(server) --- 799,804 ---- *************** *** 793,810 **** strcpy(pop_error, GETLINE_ERROR); strncat(pop_error, strerror(errno), GETLINE_MAX - sizeof(GETLINE_ERROR)); - pop_close(server); return (0); } else if (ret == 0) { strcpy(pop_error, "Unexpected EOF from server in getline"); - pop_close(server); return (0); } else { ! char *cp = strstr(server->buffer, "\r\n"); server->data += ret; ! if (cp) { *cp = '\0'; server->data -= (&cp[2] - server->dp); server->dp = &cp[2]; --- 837,853 ---- strcpy(pop_error, GETLINE_ERROR); strncat(pop_error, strerror(errno), GETLINE_MAX - sizeof(GETLINE_ERROR)); return (0); } else if (ret == 0) { strcpy(pop_error, "Unexpected EOF from server in getline"); return (0); } else { ! char *cp; server->data += ret; + server->buffer[server->data] = 0; ! if ((cp = strstr(server->buffer, "\r\n")) != 0) { *cp = '\0'; server->data -= (&cp[2] - server->dp); server->dp = &cp[2]; *************** *** 817,823 **** } strcpy(pop_error, "Line too long reading from server; compile pop.c with larger GETLINE_MAX"); - pop_close(server); return (0); } --- 860,865 ---- *************** *** 836,843 **** * Return value: Upon successful completion, a value of 0 will be * returned. Otherwise, a non-zero value will be returned, and * an error will be copied into pop_error. - * - * Side effects: Closes the connection on error. */ static int sendline(server, line) --- 878,883 ---- *************** *** 845,858 **** char *line; { #define SENDLINE_ERROR "Error writing to POP server: " ! int ret; ! ret = fullwrite(server->file, line, strlen(line)); if (ret >= 0) { /* 0 indicates that a blank line was written */ ret = fullwrite(server->file, "\r\n", 2); } if (ret < 0) { - pop_close(server); strcpy(pop_error, SENDLINE_ERROR); strncat(pop_error, strerror(errno), ERROR_MAX - sizeof(SENDLINE_ERROR)); --- 885,898 ---- char *line; { #define SENDLINE_ERROR "Error writing to POP server: " ! int ret = 0; ! if (*line) ! ret = fullwrite(server->file, line, strlen(line)); if (ret >= 0) { /* 0 indicates that a blank line was written */ ret = fullwrite(server->file, "\r\n", 2); } if (ret < 0) { strcpy(pop_error, SENDLINE_ERROR); strncat(pop_error, strerror(errno), ERROR_MAX - sizeof(SENDLINE_ERROR)); *************** *** 881,893 **** char *cp; int ret; cp = buf; while ((ret = write(fd, cp, nbytes)) > 0) { cp += ret; nbytes -= ret; } ! return (ret); } /* --- 921,940 ---- char *cp; int ret; + if (nbytes == 0) /* Write of 0 bytes may fail with -1, be we don't */ + return 0; + cp = buf; while ((ret = write(fd, cp, nbytes)) > 0) { cp += ret; nbytes -= ret; + if (nbytes == 0) { + ret = 0; /* The next write, of 0 bytes, could fail with -1 */ + break; /* So don't go around the loop another time */ + } } ! return ret == 0 ? cp - buf : ret; /* Return bytes copied, or -1 */ } /* *************** *** 901,931 **** * server The server to read from. * * Returns: 0 for success, else for failure and puts error in pop_error. - * - * Side effects: Closes the connection on error. */ static int getok(server) PopServer server; { char *fromline; ! if (!(fromline = getline(server))) { ! return (-1); ! } ! if (!strncmp(fromline, "+OK", 3)) ! return (0); ! else if (!strncmp(fromline, "-ERR", 4)) { ! strncpy(pop_error, fromline, ERROR_MAX); ! pop_error[ERROR_MAX - 1] = '\0'; ! pop_close(server); ! return (-1); ! } else { ! strcpy(pop_error, ! "Unknown response from server; expecting +OK or -ERR"); ! pop_close(server); ! return (-1); } } /* --- 948,981 ---- * server The server to read from. * * Returns: 0 for success, else for failure and puts error in pop_error. */ static int getok(server) PopServer server; { char *fromline; + int ret = -1; ! if (fromline = getline(server)) ! { ! if (!strncmp(fromline, "+OK", 3)) ! { ! ret = 0; ! pop_error[0] = '\0'; ! if (fromline[3]) ! strncat(pop_error, fromline+4, ERROR_MAX); ! } ! else if (!strncmp(fromline, "-ERR", 4)) ! { ! pop_error[0] = '\0'; ! strncat(pop_error, fromline+4, ERROR_MAX); ! } else ! { ! strcpy(pop_error, ! "Unknown response from server; expecting +OK or -ERR"); ! } } + return ret; } /* *************** *** 935,960 **** * line (nothing but a dot). * * Return value: 0 on success, non-zero with pop_error set on error. - * - * Side effects: Closes the connection on error. */ static int gettermination(server) PopServer server; { char *fromserver; fromserver = getline(server); ! if (!fromserver) ! return (-1); ! ! if (strcmp(fromserver, ".")) { ! strcpy(pop_error, "Unexpected response from server in gettermination"); ! pop_close(server); ! return (-1); } ! return (0); } /* --- 985,1007 ---- * line (nothing but a dot). * * Return value: 0 on success, non-zero with pop_error set on error. */ static int gettermination(server) PopServer server; { char *fromserver; + int ret = -1; fromserver = getline(server); ! if (fromserver) { ! if (strcmp(fromserver, ".")) { ! strcpy(pop_error, "Unexpected response from server in gettermination"); ! } ! else ret = 0; } ! return (ret); } /* *************** *** 973,983 **** --- 1020,1036 ---- pop_close(server) PopServer server; { + static int closing = 0; + + if (closing) + return; + closing = 1; sendline(server, "RSET"); sendline(server, "QUIT"); close(server->file); free((char *) server); + closing = 0; return; } diff -cN 7.2.5/print.c 7.2.6-a1/print.c *** 7.2.5/print.c Sun Oct 21 19:25:01 1990 --- 7.2.6-a1/print.c Sun Jul 9 12:52:49 1995 *************** *** 1,7 **** --- 1,11 ---- /* @(#)print.c 2.4 (c) copyright 10/15/86 (Dan Heller) */ #include "mush.h" + #ifdef __STDC__ + #include + #else #include + #endif /*ARGSUSED*/ /*VARARGS1*/ *************** *** 29,41 **** * If you're running SUN3.2 or higher, the typecast (unsigned char *)msgbuf * (where indicated) otherwise, msgbuf is not typecast at all. */ /*VARARGS*/ void print(va_alist) va_dcl { - static char msgbuf[BUFSIZ]; char *fmt; va_list args; #ifndef VPRINTF FILE foo; --- 33,53 ---- * If you're running SUN3.2 or higher, the typecast (unsigned char *)msgbuf * (where indicated) otherwise, msgbuf is not typecast at all. */ + #ifdef __STDC__ + /* WARNING: the below has become a twistly little maze of ifdef's, all + * different */ + void + print(char *fmt,...) + { + #else /* __STDC__ */ /*VARARGS*/ void print(va_alist) va_dcl { char *fmt; + #endif /* __STDC__ */ + static char msgbuf[BUFSIZ]; va_list args; #ifndef VPRINTF FILE foo; *************** *** 50,57 **** --- 62,73 ---- } else #endif /* CURSES */ if (istool < 2) { + #ifdef __STDC__ + va_start(args,fmt); + #else va_start(args); fmt = va_arg(args, char *); + #endif #ifdef VPRINTF (void) vprintf(fmt, args); #else /* VPRINTF */ *************** *** 61,68 **** --- 77,88 ---- (void) fflush(stdout); return; } + #ifdef __STDC__ + va_start(args,fmt); + #else va_start(args); fmt = va_arg(args, char *); + #endif if (fmt) { #ifdef VPRINTF (void) vsprintf(msgbuf, fmt, args); /* NULL in fmt reprints last msg */ diff -cN 7.2.5/signals.c 7.2.6-a1/signals.c *** 7.2.5/signals.c Fri Oct 30 11:55:42 1992 --- 7.2.6-a1/signals.c Sun Jul 9 12:52:49 1995 *************** *** 8,15 **** --- 8,18 ---- static int was_stopped; + #if !defined(__linux__) && !defined(BSD44) #ifndef SYSV + #ifndef __STDC__ extern char *sys_siglist[]; + #endif #else /* sys-v doesn't have normal sys_siglist */ static char *sys_siglist[] = { *************** *** 34,40 **** /* SIGCLD */ "death of a child", /* SIGPWR */ "power-fail restart" }; ! #endif /* SYSV */ SIGRET intrpt(sig) --- 37,44 ---- /* SIGCLD */ "death of a child", /* SIGPWR */ "power-fail restart" }; ! #endif /* !SYSV */ ! #endif /* !__linux__ */ SIGRET intrpt(sig) *************** *** 425,431 **** if (last_check < 0) last_check = time((long *)0); ! if (istool || time((long *)0) - last_check > time_out) { popchkmail(); last_check = time((long *)0); } --- 429,436 ---- if (last_check < 0) last_check = time((long *)0); ! if (isoff(glob_flags,DONT_CHECK) ! && (istool || time((long *)0) - last_check > time_out)) { popchkmail(); last_check = time((long *)0); } diff -cN 7.2.5/sort.c 7.2.6-a1/sort.c *** 7.2.5/sort.c Sun Oct 21 19:25:03 1990 --- 7.2.6-a1/sort.c Sun Jul 9 12:52:49 1995 *************** *** 12,23 **** static int depth, order, ignore_case; static jmp_buf sortbuf; sort(argc, argv, list) register int argc; register char *argv[], list[]; { - int msg_cmp(); SIGRET (*oldint)(), (*oldquit)(); int n, offset = -1, range = 0; long curr_msg_off = msg[current_msg].m_offset; --- 12,24 ---- static int depth, order, ignore_case; static jmp_buf sortbuf; + static int msg_cmp(); + int sort(argc, argv, list) register int argc; register char *argv[], list[]; { SIGRET (*oldint)(), (*oldquit)(); int n, offset = -1, range = 0; long curr_msg_off = msg[current_msg].m_offset; *************** *** 40,45 **** --- 41,47 ---- case 'l': /* sort by length in bytes */ case 'S': /* sort by message status */ case 'p': /* sort by message priority */ + case 't': /* sort by addressee */ /* skip consecutive repeats of the same flag */ if (depth < 1 || subsort[depth-1] != argv[0][n]) subsort[depth++] = argv[0][n]; *************** *** 168,175 **** char buf1[HDRSIZ], buf2[HDRSIZ]; int retval; ! (void) reply_to(msg1 - msg, 0, buf1); /* "0" for "author only" */ ! (void) reply_to(msg2 - msg, 0, buf2); Debug("author: msg %d: %s, msg %d: %s\n", msg1-msg, buf1, msg2-msg, buf2); if (ignore_case) retval = lcase_strncmp(buf1, buf2, -1) * order; --- 170,177 ---- char buf1[HDRSIZ], buf2[HDRSIZ]; int retval; ! (void) author_to(msg1 - msg, buf1); ! (void) author_to(msg2 - msg, buf2); Debug("author: msg %d: %s, msg %d: %s\n", msg1-msg, buf1, msg2-msg, buf2); if (ignore_case) retval = lcase_strncmp(buf1, buf2, -1) * order; *************** *** 249,254 **** --- 251,280 ---- return retval ? retval : msg_cmp(msg1, msg2); } + /* + * compare addressee strings from two messages. + */ + addressee_cmp(msg1, msg2) + register struct msg *msg1, *msg2; + { + char buf1[HDRSIZ], buf2[HDRSIZ], *p; + int retval; + + if (!(p = header_field(msg1 - msg, "to"))) + p = ""; + (void) strcpy(buf1, p); + if (!(p = header_field(msg2 - msg, "to"))) + p = ""; + (void) strcpy(buf2, p); + Debug("addressees: (%d): \"%s\" (%d): \"%s\"\n", + msg1-msg, buf1, msg2-msg, buf2); + if (ignore_case) + retval = lcase_strncmp(buf1, buf2, -1) * order; + else + retval = strcmp(buf1, buf2) * order; + return retval ? retval : msg_cmp(msg1, msg2); + } + date_cmp(msg1, msg2) register struct msg *msg1, *msg2; { *************** *** 306,311 **** --- 332,338 ---- when 'R': retval = subj_with_re(msg1, msg2); when 'l': retval = size_cmp(msg1, msg2); /* length compare */ when 'p': retval = pri_cmp(msg1, msg2); + when 't': retval = addressee_cmp(msg1, msg2); otherwise: retval = status_cmp(msg1, msg2); } depth = sv_depth; diff -cN 7.2.5/strings.c 7.2.6-a1/strings.c *** 7.2.5/strings.c Wed Jul 4 07:26:33 1990 --- 7.2.6-a1/strings.c Sun Jul 9 12:52:50 1995 *************** *** 55,60 **** --- 55,85 ---- return NULL; } + static int + chk_one_item(item, len, list, delimiters) + const char *item; + char *list, *delimiters; + int len; + { + char *p; + + if (!item || !list || !len) + return 0; + + /* Find first delimiter, skipping leading delimiters */ + while (*list && (p = any(list, delimiters)) == list) + list++; + if (!*list) + return 0; + + if (p) { + if (len != p - list || lcase_strncmp(item, list, len) != 0) + return chk_one_item(item, len, p + 1, delimiters); + return 1; + } + return (lcase_strncmp(item, list, len) == 0 && strlen(list) == len); + } + /* check two lists of strings each of which contain substrings. * Each substring is delimited by any char in "delimiters" * return true if any elements in list1 are on list2. *************** *** 65,108 **** * example returns 1 because "baz" exists in both lists * NOTE: case is ignored. */ chk_two_lists(list1, list2, delimiters) register char *list1, *list2, *delimiters; { ! register char *p, c; ! register int found = 0; if (!list1 || !list2) return 0; ! if (p = any(list1, delimiters)) { ! if (p > list1) { ! c = *p; *p = 0; ! /* Check list2 against the first word of list1. ! * Swap places of list2 and list1 to step through list2. */ ! found = chk_two_lists(list2, list1, delimiters); ! *p = c; } ! if (found) return 1; ! for (p++; *p && index(delimiters, *p); p++) ! ; ! if (!*p) ! return 0; ! } else if (!any(list2, delimiters)) ! /* Do the trivial case of single words */ ! return !lcase_strncmp(list1, list2, -1); ! else ! p = list1; ! ! /* Either only list2 has delims or the first word of list1 ! * did not match anything in list2. Check list2 against the ! * rest of list1. This could be more efficient by using a ! * different function to avoid repeating the any() calls. ! */ ! return chk_two_lists(list2, p, delimiters); } bzero(addr, size) register char *addr; register int size; --- 90,163 ---- * example returns 1 because "baz" exists in both lists * NOTE: case is ignored. */ + int chk_two_lists(list1, list2, delimiters) register char *list1, *list2, *delimiters; { ! register char *p1, *p2; if (!list1 || !list2) return 0; ! /* Find first delimiter, skipping leading delimiters */ ! while (*list1 && (p1 = any(list1, delimiters)) == list1) ! list1++; ! if (!*list1) ! return 0; ! while (*list2 && (p2 = any(list2, delimiters)) == list2) ! list2++; ! if (!*list2) ! return 0; ! ! /* ! * p1 as boolean represents the presence of a delimiter in list1 ! * p1 as pointer represents the end of the first item in list1 ! * p1 - list1 gives the length of the first item in list1 ! * p1 + 1 gives the "rest" of list1 ! * ! * same for p2 and list2 ! */ ! ! /* Check all cases of booleans for p1 and p2 */ ! if (p1 && p2) { ! if (p1 - list1 != p2 - list2) { ! /* Lengths different, check first item against rest of list2, ! * then if that fails, rest of list1 against all of list2 */ ! return (chk_one_item(list1, p1 - list1, p2 + 1, delimiters) || ! chk_two_lists(p1 + 1, list2, delimiters)); } ! /* Lengths of items same, compare strings */ ! if (lcase_strncmp(list1, list2, p1 - list1) == 0) return 1; ! /* Check this item of list2 against rest of list1, ! * then check all of list1 against rest of list2 ! */ ! return (chk_one_item(list2, p2 - list2, p1 + 1, delimiters) || ! chk_two_lists(list1, p2 + 1, delimiters)); ! } ! if (p1 /* && !p2 */) { ! /* Do strncmp() before strlen(), it fails quickly */ ! if (lcase_strncmp(list1, list2, p1 - list1) == 0 && ! strlen(list2) == p1 - list1) ! return 1; ! /* Only one item in list2, check it against rest of list1 */ ! return chk_one_item(list2, strlen(list2), p1 + 1, delimiters); ! } ! if (p2 /* && !p1 */) { ! /* Do strncmp() before strlen(), it fails quickly */ ! if (lcase_strncmp(list1, list2, p2 - list2) == 0 && ! strlen(list1) == p2 - list2) ! return 1; ! /* Only one item in list1, check it against rest of list2 */ ! return chk_one_item(list1, strlen(list1), p2 + 1, delimiters); ! } ! ! /* Only one item in each list */ ! return (lcase_strncmp(list1, list2, -1) == 0); } + #ifndef HAS_BZERO bzero(addr, size) register char *addr; register int size; *************** *** 110,115 **** --- 165,171 ---- while (size-- > 0) addr[size] = 0; } + #endif /* do an atoi() on the string passed and return in "val" the decimal value. * the function returns a pointer to the location in the string that is not *************** *** 225,230 **** --- 281,300 ---- * if you know your system's sprintf returns a char *, you can remove the * define in strings.h */ + #ifdef __STDC__ + #include + char * + Sprintf(char *buf,char *fmt, ...) + { + va_list ap; + + va_start(ap,fmt); + (void) vsprintf(buf, fmt, ap); + va_end(ap); + return buf; + } + #else + #include /*VARARGS*/ /*ARGSUSED*/ *************** *** 253,258 **** --- 323,329 ---- va_end(ap); return buf; } + #endif void print_argv(argv) *************** *** 443,454 **** return start; } /* * This routine returns a pointer to the file portion of a path/file name. */ char * basename(path) ! register char *path; { char *file; --- 514,526 ---- return start; } + #ifdef BASENAME /* * This routine returns a pointer to the file portion of a path/file name. */ char * basename(path) ! char *path; { char *file; *************** *** 456,458 **** --- 528,531 ---- return ++file; return path; } + #endif diff -cN 7.2.5/strings.h 7.2.6-a1/strings.h *** 7.2.5/strings.h Wed Jul 4 15:51:50 1990 --- 7.2.6-a1/strings.h Sun Jul 9 12:52:50 1995 *************** *** 10,24 **** --- 10,32 ---- #define rindex strrchr #endif /* SYSV */ + #ifdef __STDC__ + #include + #else /* External function definitions for routines described in string(3). */ extern char *strcat(), *strncat(), *strcpy(), *strncpy(), *index(), *rindex(), *getenv(); extern int strcmp(), strncmp(), strlen(); + #endif extern char + #ifdef __STDC__ + *Sprintf(char *buf, char *fmt, ...), /* ansi header for varargs */ + #else *Sprintf(), /* See comments above function in strings.c */ + #endif *argv_to_string(), /* convert a vector of strings into one string */ *any(), /* return first char in str2 that exists in str1 */ *basename(), /* return the last component of a file path */ diff -cN 7.2.5/version.h 7.2.6-a1/version.h *** 7.2.5/version.h Fri Oct 30 11:55:25 1992 --- 7.2.6-a1/version.h Sun Jul 9 12:52:50 1995 *************** *** 1,7 **** /* @(#)version.h (c) Copyright 1989, 1990, 1991 (Dan Heller) */ #define MUSHNAME "Mail User's Shell" ! #define RELEASE_DATE "10/14/92" #define RELEASE 7 #define REVISION "2" ! #define PATCHLEVEL 5 --- 1,7 ---- /* @(#)version.h (c) Copyright 1989, 1990, 1991 (Dan Heller) */ #define MUSHNAME "Mail User's Shell" ! #define RELEASE_DATE "alpha 7/5/95" #define RELEASE 7 #define REVISION "2" ! #define PATCHLEVEL 6 diff -cN 7.2.5/viewopts.c 7.2.6-a1/viewopts.c *** 7.2.5/viewopts.c Thu Dec 6 16:53:22 1990 --- 7.2.6-a1/viewopts.c Sun Jul 9 12:52:50 1995 *************** *** 115,120 **** --- 115,122 ---- "Alternate pixmap to use when tool is closed to an icon." }, { "mbox", "Filename:", "Filename to use instead of ~/mbox for default mailbox." }, + { "metamail", "Program:", + "Pathname and arguments of a MIME decoder." }, { "metoo", NULL, "When replying to mail, metoo preserves your name on mailing list." }, { "mil_time", NULL, diff -cN 7.2.5/xcreat.c 7.2.6-a1/xcreat.c *** 7.2.5/xcreat.c Fri Oct 30 11:56:16 1992 --- 7.2.6-a1/xcreat.c Sun Jul 9 12:52:51 1995 *************** *** 35,46 **** #endif /* XCTEST */ #endif /* XCTEST_LOUDLY */ ! #ifdef XCTEST #define hostname() "xctest" #else extern char **ourname; #define hostname() ourname[0] ! #endif /* XCTEST */ #ifdef DECLARE_ERRNO extern int errno; --- 35,46 ---- #endif /* XCTEST */ #endif /* XCTEST_LOUDLY */ ! #if defined(XCTEST) || defined(LOCK_PROG) #define hostname() "xctest" #else extern char **ourname; #define hostname() ourname[0] ! #endif /* XCTEST || LOCK_PROG */ #ifdef DECLARE_ERRNO extern int errno; *************** *** 157,171 **** int j = -2, i; q = rindex(name, '/'); ! if (q) ! i = q - name; ! else { i = 0; /* Creating in the current directory */ } p = strncpy(buf, name, i); if (unique(p, p + i, mode)) j = myrename(p, name); /* try and rename it, fails if nonexclusive */ - free(p); return j; } --- 157,170 ---- int j = -2, i; q = rindex(name, '/'); ! if (q) { ! i = (q - name) + 1; ! } else { i = 0; /* Creating in the current directory */ } p = strncpy(buf, name, i); if (unique(p, p + i, mode)) j = myrename(p, name); /* try and rename it, fails if nonexclusive */ return j; }