home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-05-06 | 54.7 KB | 1,738 lines |
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # If this archive is complete, you will see the following message at the end:
- # "End of archive 15 (of 19)."
- # Contents: mush/README-7.0 mush/glob.c mush/options.h mush/panels.c
- # Wrapped by argv@turnpike on Wed May 2 13:59:46 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'mush/README-7.0' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mush/README-7.0'\"
- else
- echo shar: Extracting \"'mush/README-7.0'\" \(15679 characters\)
- sed "s/^X//" >'mush/README-7.0' <<'END_OF_FILE'
- X
- XThis is the official release of the Mush port to SunView, referred to in
- Xalpha and beta versions as "mushview". This file describes most of the
- Xchanges from revision 6.5.6 of "mush" and "mushtool". Sorry, IBM, we
- Xnever managed to get the DOS code integrated. Note that this is version
- X7.0.0, not to be confused (we hope) with alpha-test releases that had a
- Xthird zero appended to the number. Check the dates if you aren't sure.
- X
- XThanks up front to Rich Burridge of Sun Australia for his work on
- Xconverting mush's SunWindows code to SunView, and for giving mush a really
- Xthorough linting, which it had needed for some time. Thanks also to the
- Xmany alpha and beta testers who sent valuable comments.
- X
- XVersion 7.0.0 differs from the several 6.5.6 Beta releases in that a
- Xlarge portion of the Sun code has changed to use text subwindows instead
- Xof pixrects. This is a significant enough change in "look and feel" that
- Xthe release number was increased from 6 to 7. Addition of file completion
- Xto the line/curses modes is also considered a major improvement, as are
- Xchanges to the "mail" command (described below).
- X
- XTool mode changes include:
- X * The message display window is a textsw, with scrollbars.
- X * The composition window is also a textsw, and opens in a separate
- X frame, so you can read messages in the main frame while composing.
- X You can still invoke an editor, and the default window size is
- X such that vi no longer gets confused (as far as we can tell).
- X * There are variables to control the sizes of most subwindows.
- X * Header-editing works in tool mode (in fact, you MUST use it).
- X * Help, options, and alias settings also pop up in their own frames.
- X The help descriptions have been improved (we believe).
- X * Interactive function-key binding is no longer supported; the clash
- X of mush function keys with SunView functions has been eliminated.
- X * The list of folders in your folder directory is made into a
- X walking menu. (Handling of this may improve in future patches.)
- X
- XIn addition to the SunView conversions and linting, which make up the bulk
- Xof the changes, there have been a number of bug fixes and enhancements to
- Xthe 6.5.6 baseline. These include:
- X
- Xmush -h file
- Xmush -U -h file
- Xmush -U! -h file
- X The new -h (-draft) options allows mush to read in a prepared message
- X for sending, in the same manner as Rnmail. The specified file must
- X contain the message headers (either when first read or after editing
- X by the user); mush will not add headers to it. The intended use of
- X this option is to write a partially finished message to a file and
- X then return to it later. (See commentary below on "mail -h".) The
- X new -U (-send) option allows the draft file to be sent immediately
- X without editing (-U means "unedited"). Signatures and fortunes are
- X not appended when -U! is used ("unsigned" as well as unedited).
- X
- Xmush -I file
- Xmush -I! file
- X The new -I (-init) option allows the user to specify an init file that
- X is read before any of the other init files. -I! causes the specified
- X file to replace the system Mushrc file; otherwise, the given file and
- X the system Mushrc are both read. -I has no effect on reading of the
- X user's own $HOME/.mushrc file (except that the indicated file could
- X "setenv MAILRC", thus changing the location of the user's file).
- X
- Xmush -n
- Xmush -n!
- X The first form of this option now works like the ucbMail -n option,
- X that is, it prevents sourcing of the system Mushrc but the user's own
- X $HOME/.mushrc is still read. The new -n! variation prevents either
- X file from being sourced, which was the old behavior of -n. Using -n
- X does not change the effect of -I, so the following are equivalent:
- X mush -n -I file mush -I! file
- X
- Xcd
- X The cdpath variable now works correctly when specified with either
- X colons or spaces separating the list of directories.
- X
- Xhelp
- X The help facility has been expanded; there is now a help file entry
- X consisting of a usage line and short explanation for every documented
- X line-mode command except "debug" and "version", all accessible via
- X "? command" or "command -?". In addition, there are variables:
- X set cmd_help = path Give new location for cmd_help file
- X set tool_help = path Give new location for tool_help file
- X These variables, which can be set in the system or user init files,
- X have replaced the old -1 and -2 startup options, i.e. cmd_help and
- X tool_help can no longer be specified on the mush command line.
- X
- Xmail -E
- Xmail -h file
- Xmail -H file
- Xmail -I
- Xmail -u
- Xmail -U -h file
- X The new "-h file" option of the mail command corresponds to the -h
- X option of mush itself, and is intended for reading in previously
- X begun letters. It implies -E (edit_hdrs). The previous meaning of
- X -h (include and indent a message with its headers) is now supported
- X by the -I option, corresponding to the ~I escape (see below). The
- X -H option is analogous to -h, except that the file need not contain
- X message headers (edit_hdrs is not implied). (Some alpha versions
- X used -H for the function now supplied by -I.)
- X The -E option no longer implies autoedit.
- X The new -u option turns off autosign and fortune. Most useful
- X with "-h file" when you want to continue editing the draft but a
- X signature or fortune has already been appended; but -h is not
- X required for -u. The new -U option sends the file immediately; it
- X cannot be used without -h or -H, and will be ignored if no To:
- X address has been specified.
- X Also, the user is no longer required to provide a To: address in
- X order to begin composing a letter (one is still required before
- X sending it), and the To: address may be only files and/or pipes if
- X desired (in which case the MTA is not run).
- X Finally, the tilde-escape ~I has replaced ~H for purposes of
- X including a message and its headers in the letter being composed.
- X This is analagous to the -i and -I options and the ~i escape.
- X
- Xmy_hdr From: address
- X This is now allowed (it is allowed but neither documented nor correctly
- X used in 6.5.6, and was not allowed previously). The user's From: header
- X is verified as best mush can, and used if it appears valid. It is up
- X to the MTA to assure authenticity and/or add a Sender: header. Mush
- X provides a From: if the user does not or if it cannot verify the one
- X given.
- X
- Xpipe -p pattern unix-command
- X The pipe command has been modified to allow its use as a shell script
- X extractor. See the man page and "pipe -?" for details. KNOWN BUG:
- X given a list of messages, all are sent to the same unix process.
- X This can cause havoc e.g. when each of the messages is a shell script
- X intended to be run by a virgin shell. Changes are being discussed.
- X Also, pipe is now affected by $alwaysignore (see below).
- X
- XPipe
- X See the comments under "write" below.
- X
- Xpwd
- X This now prints the actual current working directory rather than
- X simply echoing the value of $cwd.
- X
- Xreply
- X Assorted repairs have been made to to take_me_off() (implements the
- X inverse of $metoo) and reply_to(). These include doing a better
- X (though still not perfect) job of getting the name and address to
- X match when replying to forwarded mail.
- X
- Xsort
- X The current message now moves with the sort, that is, the same actual
- X message (not necessarily the same message *number*) will be the
- X current message after the sort as was current before the sort.
- X
- Xsave/copy
- X The 'p' (printed) and 'f' (forwarded) Status flags are now properly
- X saved when messages are saved/copied, and restored when the folders
- X are read. Also, a "-f" (force) flag has been added, which has the
- X same meaning as the old "!" flag, that is, overwrite the file rather
- X than appending to it. "save !" is still supported.
- X
- Xundigest -p pattern
- X The specified pattern is used as the article separator for unpacking
- X digests. The default is "--------". A literal match (no regexps or
- X wildcards) is done at beginning-of-line.
- X
- Xwrite
- X The write command (and other commands such as Pipe that omit message
- X headers) no longer outputs the blank line that separates the message
- X body from the headers, and also does not output the trailing blank
- X line that separates messages from one another. (This applies only
- X when MSG_SEPARATOR is not defined during compilation.) This makes
- X the command more useful for saving multi-part uuencoded files, etc.
- X
- X$$
- X$name:l
- X$name:u
- X$name:<number>
- X Four new variable forms. The first returns the PID of the running
- X mush; the second converts all alphabetics in the value of $name to
- X lower case; the third converts all alphabetics in the value of $name
- X to uppercase; the fourth splits the value into words and returns the
- X <number>th word. Only one modifier can be used at a time.
- X
- X$[%fmt]
- X This special variable form expands %fmt (a string with no spaces) as
- X a hdr_format format. E.g., $h%a is the author of the current message.
- X Any colon-modifier may be applied, e.g.
- X $[%n]:1 First name of author of current message
- X
- X$(%c)
- X This special variable form expands %c (c is a character) as a prompt
- X format. E.g., $(%T) is the current time. Colon-modifiers apply.
- X
- X$alwaysignore
- X This variable now actually works as documented. If you've gotten used
- X to the old behavior, you'll need to set this. Note, however, that the
- X documented behavior has changed slightly. The (erroneous) behavior of
- X Mush 6.5.6 when this variable was UNset is now achieved by:
- X set alwaysignore = "include,forward,pipe"
- X Setting this variable with no value has the same effect as in 6.5.6.
- X
- X$autosign
- X You can now specify a program to be run, whose output will sign the
- X letter; the syntax is
- X set autosign = '|program-name'
- X This syntax has not been finalized and may change. The argument list
- X passed to the program is the list of addresses that will go to the MTA,
- X in exactly the same form as that which will be used for the MTA (e.g.,
- X there may be a comma after each address).
- X
- X$complete
- X Mush now supports filename completion and will eventually support
- X command completion as well. This variable has a two-character "string"
- X value; the first character is used for name completion, the second for
- X listing, ala ESC and ^D in 4.3 BSD csh.
- X
- X$domain_route
- X This variable allows the user to specify that domain short-circuiting
- X should be done in conjunction with auto_route. Addresses that are
- X already in RFC822 domain form (user@domain) are not normally changed.
- X UUCP paths that contain fully-qualified domains are short-circuited
- X to the rightmost such domain. Optionally, domain_route may be set
- X to a string, in which case all addresses are rewritten to UUCP form,
- X short-circuited, and the given string is then prepended as the first
- X host in the path. This variable is intended for use at RFC976 Class 3
- X UUCP hosts, or UUCP sites with a connection to a Class 3 host.
- X
- X$fignore
- X This variable modifies the behavior of file completion by specifying
- X file name forms that should NOT be completed. See the man page for
- X more details.
- X
- X$hdr_format
- X A new formatting string now allows access to *any* message header.
- X The format is: %?header-name?
- X For example,
- X set hdr_format='%n "%?x-mailer?"'
- X might display
- X 1 > Barton E. Schaefer "Mail User's Shell (7.0.0 12/10/89)"
- X This can be used to avoid mush's TO: display for messages you
- X authored; just replace "%f" with "%?from?".
- X
- X$lister
- X Has been removed. The "folders" command now supplies its own set
- X of flags to ls, and "cmd ls 'ls ...'" suffices for other uses.
- X
- X$quiet
- X This variable now has a value of one to six comma-delimited words.
- X For compatibility with previous versions, setting quiet without a
- X value has the original behavior of suppressing the startup message.
- X The recognized words are:
- X autosign Don't tell me when a signature is appended
- X await Await command doesn't ring for new mail
- X complete Word completion doesn't ring on failure
- X fortune Don't tell me when a fortune is appended
- X startup Don't print the startup message
- X tool Tool mode doesn't ring for new mail
- X Errors in autosigning or fortunes are still reported. (Some beta
- X releases assigned three of these fields, with the on/off sense
- X reversed, to a variable named $bell; that variable is gone.)
- X
- X$version
- X The version string, as printed on startup.
- X____________
- X
- XMMDF Changes and File Locking Improvements
- X------------------------------------------
- X
- XThe MMDF support code has been modified to use the MMDF library calls for
- Xfile locking. The files makefile.* were modified to make the need to link
- Xin the MMDF library more obvious, and the comments in config.h-dist now
- Xreflect the current (simpler) installation instructions for MMDF sites.
- X
- XIn the course of these updates, the structure of the file locking calls
- Xwas reworked to make open and lock a single (non-atomic) operation. Many
- Xthanks to lmjm@doc.imperial.ac.uk (Lee McLoughlin) and marc@virginia.edu
- X(Marc Rouleau) for instigation and help with implementation and testing of
- Xthese changes.
- X
- XIn the course of making these changes, a number of errors were discovered
- Xand repaired:
- X
- X An "update" would remove empty files and then try to reload them,
- X generating error messages. The copyback() function now returns -1 if
- X it removes a file; folder() recognizes this and does not attempt to
- X load_folder() on a removed file.
- X
- X There was a remote possibility of a race condition in in copyback()
- X because open-and-lock is non-atomic. copyback() now checks for new
- X mail AFTER locking the spool file; this guarantees the MTA can't
- X slip a new message into the file just before it gets truncated. The
- X check_new_mail() function has been broken into three specialized
- X parts to allow this: get_new_mail() and show_new_mail() work as you
- X probably expect, and check_new_mail() now calls them.
- X
- X The mbox file ($HOME/mbox or whatever) is locked by copyback(), and
- X all folders are locked by save_msg().
- X
- X The dead.letter file is locked by dead_letter().
- X
- X "Reinitializing" of a folder that was modified behind mush's back
- X would do pretty strange things in curses mode. It now behaves more
- X sensibly. Also, if your spool folder shrinks while you are using a
- X non-spool folder, mush won't incorrectly re-initialize the current
- X folder (a bug no one ever saw, we hope).
- X
- X All mailboxes are locked for reading when they are first loaded or
- X when new mail comes in, whenever possible (DOT_LOCK and old Xenix
- X installations cannot read-lock). If the MTA also uses a compatible
- X locking scheme (as one would hope), this should prevent "truncation"
- X of new messages without unduly restricting the reading of folders.
- X
- X NOTE: All this precautionary locking has its drawbacks. Sending
- X mail can deadlock if you mention the same file twice in the list
- X of addresses. (Of course, before the advent of locking, this would
- X cause interleaved writes; which is the lesser evil?) Be careful.
- X
- XAdditional changes apply to installations where SYSV is defined:
- X
- X Because lockf() requires a file open for writing, the locking code
- X has been rewritten to call fcntl(F_SETLK) directly. Read and write
- X locks are used as appropriate.
- X
- X This locking code has been only minimally tested, because none of the
- X authors has direct access to a true SysV machine. Bug reports with
- X suggestions for improvement are requested.
- END_OF_FILE
- if test 15679 -ne `wc -c <'mush/README-7.0'`; then
- echo shar: \"'mush/README-7.0'\" unpacked with wrong size!
- fi
- # end of 'mush/README-7.0'
- fi
- if test -f 'mush/glob.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mush/glob.c'\"
- else
- echo shar: Extracting \"'mush/glob.c'\" \(19617 characters\)
- sed "s/^X//" >'mush/glob.c' <<'END_OF_FILE'
- X#include "mush.h"
- X#include "glob.h"
- X
- X/*
- X * Buried somewhere in here is the skeleton of a pattern matcher posted
- X * by koblas@mips.COM (David Koblas). It has been hacked almost beyond
- X * recognition to handle more complex patterns, and directory search has
- X * been added (patterns are split at '/' characters when file globbing).
- X */
- X
- X#ifdef TEST /* Define TEST to build a stand-alone file globbing program */
- X
- Xextern char *malloc(), *realloc();
- X
- X#define getpath(x,y) (*(y) = 0, (x))
- X#define Access access
- X#define Strcpy(x,y) (strcpy(x,y), strlen(x))
- X#define savestr(x) (strcpy(malloc(strlen(x)+1),x))
- X#ifndef max
- X#define max(x,y) ((x) > (y) ? (x) : (y))
- X#endif /* max */
- X#ifndef min
- X#define min(x,y) ((x) > (y) ? (y) : (x))
- X#endif /* min */
- X#define xfree free
- X#undef wprint
- X#define wprint printf
- X#define debug 0
- X#undef sprintf
- X
- X#define TESTGLOB(str1,str2) \
- X printf("%s %s = %s\n",str1,str2,glob(str1,str2)?"TRUE":"FALSE")
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X char **e;
- X int f;
- X
- X if (argc > 1)
- X while (*++argv) {
- X (void) printf("%s -->\n", *argv);
- X if (f = filexp(*argv, &e)) {
- X columnate(f, e, 0);
- X }
- X }
- X#ifdef TEST2 /* Define TEST2 to automatically run these test cases */
- X TESTGLOB("abcdefg", "abcdefg");
- X TESTGLOB("abcdefg", "a?cd?fg");
- X TESTGLOB("abcdefg", "ab[cde]defg");
- X TESTGLOB("abcdefg", "ab[a-z]defg");
- X TESTGLOB("abcdefg", "ab[a-z]defg");
- X TESTGLOB("ab]defg", "ab[a]c]defg");
- X TESTGLOB("ab]defg", "ab[a\\]c]defg");
- X TESTGLOB("abcdefg", "ab*fg");
- X TESTGLOB("./bc/def/gh/ij", "*de*");
- X TESTGLOB("./der/den/deq/der/", "*deq*");
- X TESTGLOB("./bc/def/gh/ij", "*ij");
- X TESTGLOB("./ij", ".?ij");
- X TESTGLOB("./bc/def/gh/ij", "./*");
- X TESTGLOB("abcdef", "*def");
- X TESTGLOB("abcdef", "*abcdef");
- X TESTGLOB("abcdef", "abc*");
- X TESTGLOB("abcdef", "abcdef*");
- X TESTGLOB("abcdef", "*?*{xxx,,yy}");
- X TESTGLOB("abcdef", "abcde{f}");
- X TESTGLOB("abcdef", "abcdef{xxx,,yyy}");
- X TESTGLOB("abcdef", "abc{def,qwrx}");
- X TESTGLOB("abcdef", "abc{ab,def,qwrx}");
- X TESTGLOB("abcdef", "{naqrwer,fuwnwer,as,abc,a}{ab,def,qwrx}");
- X TESTGLOB("abcdef", "{naqrwer,*,as,abc,a}{ab,def,qwrx}");
- X TESTGLOB("abcdef", "{{a*,b*},as,a}{ab,def,qwrx}");
- X TESTGLOB("abcdef", "{{c*,b*},as,a}{ab,def,qwrx}");
- X TESTGLOB("abcdef", "{{c*,?b*},as,a}{ab,def,qwrx}");
- X TESTGLOB("abcdef", "{naqrwer,fuwnwer,as,abc,a}{ab,d*f,qwrx}");
- X#endif /* TEST2 */
- X}
- X
- Xchar *
- Xany(s1, s2)
- Xregister char *s1, *s2;
- X{
- X register char *p;
- X if (!s1 || !*s1 || !s2 || !*s2)
- X return 0;
- X for( ; *s1; s1++) {
- X for(p = s2; *p; p++)
- X if (*p == *s1)
- X return s1;
- X }
- X return 0;
- X}
- X
- X#endif /* TEST */
- X
- X/*
- X * Make a string into a one-element vector
- X */
- Xchar **
- Xunitv(s)
- Xchar *s;
- X{
- X char **v;
- X
- X if (v = (char **)malloc((unsigned)(2 * sizeof(char *)))) {
- X v[0] = savestr(s);
- X v[1] = NULL;
- X }
- X return v;
- X}
- X
- X/*
- X * Append one vector to another
- X */
- Xcatv(s1, v1, s2, v2)
- Xint s1, s2;
- Xchar ***v1, **v2;
- X{
- X int i;
- X
- X if (s1 < 0 || !v1)
- X return -1;
- X if (s2 < 0 || !v2)
- X return s1;
- X
- X /* realloc(NULL, size) should be legal, but Sun doesn't support it. */
- X if (*v1)
- X *v1 = (char **)realloc(*v1,(unsigned)((s1+s2+1) * sizeof(char **)));
- X else
- X *v1 = (char **)malloc((unsigned)((s1+s2+1) * sizeof(char **)));
- X
- X if (*v1) {
- X for (i = 0; i < s2 && v2[i]; i++)
- X (*v1)[s1 + i] = v2[i];
- X (*v1)[s1 + i] = NULL;
- X xfree(v2);
- X return s1 + i;
- X }
- X return -1;
- X}
- X
- X/*
- X * A duplicate-eliminating comparison for sorting. It treats an empty
- X * string as greater than any other string, and forces empty one of any
- X * pair of of equal strings. Two passes are sufficient to move the empty
- X * strings to the end where they can be deleted by the calling function.
- X *
- X * This is NOT compatible with the ANSI C qsort(), which requires that the
- X * comparison function will not modify its arguments!
- X */
- Xuniqcmp(p1, p2)
- Xchar **p1, **p2;
- X{
- X int cmp;
- X
- X if (**p1 && !**p2)
- X return -1;
- X if (**p2 && !**p1)
- X return 1;
- X if (cmp = strcmp(*p1, *p2))
- X return cmp;
- X **p2 = 0;
- X return -1;
- X}
- X
- X/*
- X * Expand a pattern into a list of file names. Returns the number of
- X * matches. As in csh, names generated from pattern sets are returned
- X * even if there are no actual matches.
- X */
- Xfilexp(pat, exp)
- Xchar *pat, ***exp;
- X{
- X char **t1, **t2;
- X int n, new, cnt;
- X
- X if (!exp)
- X return -1;
- X if (!pat || !*pat)
- X return 0;
- X
- X if ((n = sxp(pat, &t1)) > 0)
- X cnt = 0;
- X else
- X return n;
- X *exp = DUBL_NULL;
- X while (n--)
- X if ((new = fxp(t1[n], &t2)) > 0 || new++ == 0 && t2)
- X cnt = catv(cnt, exp, new, t2);
- X if (cnt > 1) {
- X /* Two sort passes to eliminate duplicates -- see uniqcmp() */
- X qsort((char *)*exp, cnt, sizeof(char *), uniqcmp);
- X qsort((char *)*exp, cnt, sizeof(char *), uniqcmp);
- X while (!(*exp)[cnt - 1][0]) {
- X xfree((*exp)[--cnt]);
- X (*exp)[cnt] = NULL;
- X }
- X }
- X return cnt;
- X}
- X
- X/*
- X * Expand a filename with globbing chars into a list of matching filenames.
- X * Pattern set notatation which crosses directories is not handled, e.g.
- X * "fi{le/exp,nger/h}and" will NOT expand to "file/expand finger/hand".
- X * Such patterns must be pre-expanded by sxp() before calling fxp().
- X *
- X * The list of expansions is placed in *exp, and the number of matches
- X * is returned, or -1 on an error.
- X */
- Xfxp(name, exp)
- Xchar *name, ***exp;
- X{
- X char *p;
- X int isdir;
- X
- X if (!exp)
- X return -1;
- X
- X isdir = 1; /* ignore no such file */
- X p = getpath(name, &isdir);
- X if (isdir < 0)
- X return -1;
- X else if (isdir)
- X return ((*exp = unitv(p)) ? 1 : -1);
- X return pglob(p, 0, exp);
- X}
- X
- X/*
- X * Match all globbings in a path. Mutually recursive with dglob(), below.
- X * The first "skip" characters of the path are not globbed, see dglob().
- X *
- X * Returns the number of matches, or -1 on an error. *exp is set to the
- X * list of matches.
- X *
- X * If the path has no metachars, it is returned in *exp whether it matches
- X * a real file or not. This allows patterns built by sxp() to be recognized
- X * and returned even when there are no matches (ala csh generation of names
- X * from pattern sets). pglob() still returns zero in this case.
- X */
- Xpglob(path, skip, exp)
- Xchar *path, ***exp;
- Xint skip;
- X{
- X char *t, *t2;
- X int ret = 0;
- X
- X if (!path || !exp || skip < 0)
- X return -1;
- X *exp = DUBL_NULL; /* Must be null in case of zero matches and no sets */
- X
- X for (t = t2 = path + skip; (t2 = any(t2, META)) && *t2 == '/'; t = t2++)
- X ;
- X if (!t2) {
- X ret = ((*exp = unitv(path)) ? 1 : -1);
- X if (ret > 0 && Access(path, F_OK) < 0)
- X ret = 0;
- X } else {
- X if (t2 = index(t + 1, '/'))
- X *t2++ = 0;
- X if (*t == '/') {
- X *t++ = 0;
- X if (!*path)
- X ret = dglob("/", t, t2, exp);
- X else
- X ret = dglob(path, t, t2, exp);
- X } else {
- X ret = dglob("", t, t2, exp);
- X }
- X }
- X return ret;
- X}
- X
- X/*
- X * Search a directory (possibly recursively) for glob matches.
- X * Argument pat1 is a pattern to be matched in this directory,
- X * and pat2 is a pattern to be matched in matched subdirectories.
- X *
- X * Matches are returned through *exp.
- X */
- Xdglob(dir, pat1, pat2, exp)
- Xchar *dir, *pat1, *pat2, ***exp;
- X{
- X DIR *dirp;
- X struct dirent *dp;
- X char *b, *d, buf[MAXPATHLEN], **tmp;
- X int n, ret = 0, skip;
- X
- X if (!dir || !exp)
- X return -1;
- X d = (*dir ? dir : ".");
- X if (!(dirp = opendir(d)))
- X return -1;
- X b = buf + Strcpy(buf, dir);
- X if (b > buf && *(b - 1) != '/')
- X *b++ = '/';
- X skip = b - buf; /* We know this much matches, don't glob it again */
- X while (ret >= 0 && (dp = readdir(dirp))) {
- X if (fglob(dp->d_name, pat1)) {
- X if (pat2) {
- X (void) sprintf(b, "%s/%s", dp->d_name, pat2);
- X n = pglob(buf, skip, &tmp);
- X ret = catv(ret, exp, n, tmp);
- X } else {
- X (void) strcpy(b, dp->d_name);
- X ret = catv(ret, exp, 1, unitv(buf));
- X }
- X }
- X }
- X closedir(dirp);
- X return ret;
- X}
- X
- X/*
- X * Match file names. This means that metachars do not match leading ".".
- X */
- Xfglob(str, pat)
- Xchar *str, *pat;
- X{
- X if (!str || !pat || *str == '.' && *pat != '.')
- X return FALSE;
- X else
- X return glob(str, pat);
- X}
- X
- X/*
- X * Match two concatenated patterns. Mainly for use by sglob().
- X */
- Xstatic
- Xglob2(str, pat1, pat2)
- Xchar *str, *pat1, *pat2;
- X{
- X char buf[MAXPATHLEN];
- X
- X if (!str || !pat1 && !pat2)
- X return FALSE;
- X (void) sprintf(buf, "%s%s", pat1? pat1 : "", pat2? pat2 : "");
- X return glob(str, buf);
- X}
- X
- X/*
- X * The basic globbing matcher.
- X *
- X * "*" = match 0 or more occurances of anything
- X * "[abc]" = match any of "abc" (ranges supported)
- X * "{xx,yy,...}" = match any of "xx", "yy", ... where
- X * "xx", "yy" can be any pattern or empty
- X * "?" = match any character
- X */
- Xglob(str, pat)
- Xchar *str, *pat;
- X{
- X int done = FALSE, ret = FALSE;
- X
- X if (!str || !pat)
- X return FALSE;
- X
- X while (*pat && !done && (*str || (*pat == '{' || *pat == '*'))) /*}*/ {
- X /*
- X * First look for a literal match, stepping over backslashes
- X * in the pattern to match against the "protected" character.
- X * Ordering and precendence are important in this expression!
- X */
- X if (*pat == '\\' && *str == *++pat || *str == *pat) {
- X str++;
- X pat++;
- X } else switch (*pat++) {
- X case '*': /* Match any string */
- X if (!*pat) {
- X while (*str)
- X str++;
- X break;
- X }
- X /*
- X * Try the rest of the glob against every
- X * possible suffix of the string. A bit
- X * inefficient in cases that eventually fail.
- X */
- X while (*str && !(ret = glob(str++, pat)))
- X ;
- X return ret;
- X break;
- X case '[': /* Match a set */
- X repeat:
- X /* If we've hit the end of the set, give up. */
- X if (!*pat || *pat == ']' || *pat == '\\' && !*++pat) {
- X done = TRUE;
- X break;
- X }
- X /* Check for a range. */
- X if (*(pat + 1) == '-') {
- X char c = *pat++;
- X /* We don't handle open-ended ranges. */
- X if (*++pat == ']' || *pat == '\\' && !*++pat) {
- X done = TRUE;
- X break;
- X }
- X if (*str < c || *str > *pat) {
- X pat++;
- X goto repeat;
- X }
- X } else if (*pat != *str) {
- X pat++;
- X goto repeat;
- X }
- X /*
- X * We matched either the range or a literal member of
- X * the set. Skip to the end of the set.
- X */
- X pat++;
- X while (*pat && *pat != ']')
- X if (*pat++ == '\\' && *pat)
- X pat++;
- X /*
- X * If no pattern remains, the set was never closed,
- X * so don't increment. This will cause a FALSE return.
- X */
- X if (*pat) {
- X pat++;
- X str++;
- X }
- X break;
- X case '?': /* Match any one character */
- X str++;
- X break;
- X case '{': /* } Match any of a set of patterns */
- X return sglob(str, pat - 1, TRPL_NULL);
- X break;
- X default:
- X done = TRUE;
- X }
- X }
- X while (*pat == '*')
- X pat++;
- X return ((*str == '\0') && (*pat == '\0'));
- X}
- X
- X/*
- X * Match a pattern set {s1,s2,...} followed by any other pattern.
- X * Pattern sets and other patterns may nest arbitrarily.
- X *
- X * If "mat" is not a null pointer, a vector of possible expansions
- X * is generated and placed in *mat; otherwise, the expansions are
- X * matched against str and a truth value is returned ("/" is NOT
- X * treated as a directory separator in this case). NOTE: The vector
- X * of expansions may still contain nested pattern sets, which must
- X * be expanded separately. See sxp().
- X *
- X * Currently allows at most 256 alternatives per set. Enough? :-)
- X */
- Xstatic
- Xsglob(str, pat, mat)
- Xchar *str, *pat, ***mat;
- X{
- X char *p, *newpat[256], *oldpat[256], buf[MAXPATHLEN], *b = buf;
- X int copy = 1, nest = 0, i = 0, ret = 0;
- X
- X if (!pat)
- X return FALSE;
- X
- X while (*pat) {
- X if (copy)
- X if (*pat != '{') /*}*/ {
- X if (*pat == '\\' && pat[1])
- X *b++ = *pat++;
- X *b++ = *pat++;
- X continue;
- X } else {
- X copy = 0;
- X pat++;
- X }
- X p = pat;
- X while (*pat && (nest || *pat != ',' && /*{*/ *pat != '}')) {
- X if (*pat == '\\')
- X pat++;
- X else if (*pat == '{')
- X nest++;
- X else if (*pat == '}')
- X nest--;
- X if (*pat)
- X pat++;
- X }
- X if (*pat) {
- X oldpat[i] = pat;
- X newpat[i++] = p;
- X if (*pat != ',') {
- X *pat++ = 0;
- X break;
- X } else
- X *pat++ = 0;
- X }
- X }
- X oldpat[i] = NULL;
- X if (i > 0 && mat) {
- X *mat = (char **)malloc((unsigned)((i + 1) * sizeof(char *)));
- X if (*mat)
- X (*mat)[i] = NULL;
- X else
- X return -1;
- X ret = i;
- X }
- X while (!mat && i-- > 0)
- X if (ret = glob2(str, newpat[i], pat))
- X break;
- X for (i = 0; oldpat[i]; i++) {
- X if (mat && *mat) {
- X (void) sprintf(b, "%s%s", newpat[i], pat);
- X (*mat)[i] = savestr(buf);
- X }
- X if (oldpat[i + 1])
- X oldpat[i][0] = ',';
- X else
- X oldpat[i][0] = /*{*/ '}';
- X }
- X if (ret == 0 && b > buf && mat) {
- X *b = 0;
- X ret = ((*mat = unitv(buf)) ? 1 : -1);
- X }
- X return ret;
- X}
- X
- X/*
- X * Pre-expand pattern set notations so sets containing "/" separators
- X * can be globbed successfully. Returns the number of expansions.
- X */
- Xsxp(pat, exp)
- Xchar *pat, ***exp;
- X{
- X char **t1 = DUBL_NULL, **t2;
- X int n, new, cnt = 0;
- X
- X if ((n = sglob(NULL, pat, &t1)) < 2) {
- X *exp = t1;
- X return n;
- X }
- X *exp = DUBL_NULL;
- X while (n-- && cnt >= 0) {
- X new = sxp(t1[n], &t2);
- X cnt = catv(cnt, exp, new, t2);
- X }
- X xfree(t1);
- X return cnt;
- X}
- X
- X/*
- X * Generate the "glob difference" of two vectors (*argvp and patv).
- X * The "glob difference" means to remove all strings from argv that
- X * match any of the glob patterns in patv.
- X *
- X * Returns the number of strings remaining in *argvp. The strings "removed"
- X * from argv are actually left at the end of *argvp, so they can still be
- X * accessed; their number will of course be argc - (returned value).
- X */
- Xgdiffv(argc, argvp, patc, patv)
- Xint argc, patc;
- Xchar ***argvp, **patv;
- X{
- X char **argv, *t;
- X int ac, pc, oldac = argc;
- X
- X if (argc < 1 || patc < 1 || !patv || !*patv)
- X return argc;
- X if (!argvp || !(argv = *argvp) || !*argv)
- X return -1;
- X for (ac = 0; ac < argc && argv[ac]; ac++) {
- X for (pc = 0; ac < argc && pc < patc && patv[pc]; pc++) {
- X /*
- X * We shouldn't cross '/' characters, so test
- X * only the "tail" of each element of argv.
- X */
- X if (!(t = rindex(argv[ac], '/')))
- X t = argv[ac];
- X if (glob(t, patv[pc])) {
- X /* Move matches to the end and reduce argc */
- X t = argv[ac];
- X argv[ac] = argv[--argc];
- X argv[argc] = t;
- X /* Start patterns over on the new string */
- X pc = -1; /* It'll be incremented to 0 */
- X }
- X }
- X }
- X /*
- X * Sort the two parts of the argv. uniqcmp() works here only if
- X * there already are no duplicates, but we assume that for now.
- X */
- X if (argc)
- X qsort((char *)argv, argc, sizeof(char *), uniqcmp);
- X if (oldac > argc)
- X qsort((char *)&argv[argc], oldac - argc, sizeof(char *), uniqcmp);
- X return argc;
- X}
- X
- X/*
- X * Generate the longest common prefix from all strings in a vector
- X * If "skip" is nonzero, that many chars are assumed to be in common
- X * and are not tested. WARNING: skip must be <= than the length of
- X * the shortest string in the vector! Safest to call with skip = 0.
- X *
- X * Returns the length of the longest common prefix.
- X */
- Xlcprefix(vec, skip)
- Xchar **vec;
- Xint skip;
- X{
- X char c, **v;
- X int done = FALSE;
- X
- X if (!vec || !*vec || skip < 0)
- X return 0;
- X do {
- X for (v = vec + 1, c = vec[0][skip]; c && *v; v++)
- X if (v[0][skip] != c) {
- X done = TRUE;
- X break;
- X }
- X } while (!done && c && ++skip);
- X return skip;
- X}
- X
- X#define MAXCOLS 8 /* Max number of columns of words to make */
- X#define MINWIDTH 10 /* Minimum width of each column of words */
- X#ifdef CURSES
- X#define MAXWIDTH (iscurses? COLS : 80)
- X#else /* CURSES */
- X#define MAXWIDTH 80 /* Maximum width of all columns */
- X#endif /* CURSES */
- X
- X/*
- X * Print a vector in columns
- X *
- X * If "skip" is nonzero, that many chars are assumed to be in common
- X * and are not printed. WARNING: skip must be <= than the length of
- X * the shortest string in the vector! Safest to call with skip = 0.
- X */
- Xcolumnate(argc, argv, skip)
- Xint argc;
- Xchar **argv;
- Xint skip;
- X{
- X int colstep, colwidth[MAXCOLS + 1];
- X int maxcols = min(argc, MAXCOLS);
- X int minwidth, maxwidth, *widths;
- X int maxword = 0, n, c;
- X
- X if (argc <= 0 || !argv || !*argv)
- X return -1;
- X if (!(widths = (int *)malloc((unsigned)((argc + 1) * sizeof(int)))))
- X return -1;
- X
- X /*
- X * Compute the widths of all words in the vector, and
- X * remember the maximum width and which word had it.
- X * Also remember the minimum width.
- X */
- X for (minwidth = MAXWIDTH, maxwidth = n = 0; n < argc; n++) {
- X widths[n] = max(strlen(argv[n] + skip) + 2, MINWIDTH);
- X if (widths[n] > MAXWIDTH - MINWIDTH)
- X break;
- X if (widths[n] > maxwidth) {
- X maxwidth = widths[n];
- X maxword = n;
- X }
- X if (widths[n] < minwidth)
- X minwidth = widths[n];
- X }
- X
- X for (; maxcols > 0; maxcols--) {
- X if (argc % maxcols)
- X colstep = argc / maxcols + 1;
- X else
- X colstep = argc / maxcols;
- X colwidth[MAXCOLS] = 0;
- X for (c = 0; c < maxcols; c++) {
- X colwidth[c] = 0;
- X for (n = c * colstep; n < (c + 1) * colstep && n < argc; n++)
- X colwidth[c] = max(colwidth[c], widths[n]);
- X colwidth[MAXCOLS] += colwidth[c];
- X }
- X if (colwidth[MAXCOLS] <= MAXWIDTH)
- X break;
- X }
- X xfree(widths);
- X
- X if (maxcols < 2 && minwidth <= MAXWIDTH / 2) {
- X /*
- X * The maxword fills too much screen, so redo everything
- X * above it, print maxword, then do everything below it.
- X */
- X if (maxword > 0 && columnate(maxword, argv, skip) < 0)
- X return -1;
- X wprint("%s\n", argv[maxword] + skip);
- X if (argc - maxword < 2)
- X return 0;
- X return columnate(argc - maxword - 1, &argv[maxword + 1], skip);
- X }
- X
- X for (n = 0; n < colstep; n++) {
- X for (c = 0; c < maxcols && n + c * colstep < argc - colstep; c++)
- X wprint("%-*.*s", colwidth[c], colwidth[c],
- X argv[n + c * colstep] + skip);
- X wprint("%s\n", argv[n + c * colstep] + skip);
- X }
- X
- X return 0;
- X}
- X
- X#ifndef DIRECTORY
- X
- X#undef NULL
- X#define NULL 0
- X
- X/*
- X * 4.2BSD directory access emulation for non-4.2 systems.
- X * Based upon routines in appendix D of Portable C and Unix System
- X * Programming by J. E. Lapin (Rabbit Software).
- X *
- X * No responsibility is taken for any error in accuracies inherent
- X * either to the comments or the code of this program, but if
- X * reported to me then an attempt will be made to fix them.
- X */
- X
- X/* Support for Berkeley directory reading routines on a V7/SysV file
- X * system.
- X */
- X
- X/* Open a directory. */
- X
- XDIR *
- Xopendir(name)
- Xchar *name ;
- X{
- X register DIR *dirp ;
- X register int fd ;
- X
- X if ((fd = open(name, 0)) == -1) return NULL ;
- X if ((dirp = (DIR *) malloc(sizeof(DIR))) == NULL)
- X {
- X close(fd) ;
- X return NULL ;
- X }
- X dirp->dd_fd = fd ;
- X dirp->dd_loc = 0 ;
- X return dirp ;
- X}
- X
- X
- X/* Read an old style directory entry and present it as a new one. */
- X
- X#define ODIRSIZ 14
- X
- Xstruct olddirent
- X{
- X short od_ino ;
- X char od_name[ODIRSIZ] ;
- X} ;
- X
- X
- X/* Get next entry in a directory. */
- X
- Xstruct dirent *
- Xreaddir(dirp)
- Xregister DIR *dirp ;
- X{
- X register struct olddirent *dp ;
- X static struct dirent dir ;
- X
- X for (;;)
- X {
- X if (dirp->dd_loc == 0)
- X {
- X dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ) ;
- X if (dirp->dd_size <= 0) return NULL ;
- X }
- X if (dirp->dd_loc >= dirp->dd_size)
- X {
- X dirp->dd_loc = 0 ;
- X continue ;
- X }
- X
- X dp = (struct olddirent *)(dirp->dd_buf + dirp->dd_loc) ;
- X dirp->dd_loc += sizeof(struct olddirent) ;
- X
- X if (dp->od_ino == 0) continue ;
- X
- X dir.d_fileno = dp->od_ino ;
- X strncpy(dir.d_name, dp->od_name, ODIRSIZ) ;
- X dir.d_name[ODIRSIZ] = '\0' ; /* Ensure termination. */
- X dir.d_namlen = strlen(dir.d_name) ;
- X dir.d_reclen = DIRSIZ(&dir) ;
- X return(&dir) ;
- X }
- X}
- X
- X
- X/* Close a directory. */
- X
- Xvoid
- Xclosedir(dirp)
- Xregister DIR *dirp ;
- X{
- X close(dirp->dd_fd) ;
- X dirp->dd_fd = -1 ;
- X dirp->dd_loc = 0 ;
- X xfree(dirp) ;
- X}
- X
- X#endif /* DIRECTORY */
- END_OF_FILE
- if test 19617 -ne `wc -c <'mush/glob.c'`; then
- echo shar: \"'mush/glob.c'\" unpacked with wrong size!
- fi
- # end of 'mush/glob.c'
- fi
- if test -f 'mush/options.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mush/options.h'\"
- else
- echo shar: Extracting \"'mush/options.h'\" \(1248 characters\)
- sed "s/^X//" >'mush/options.h' <<'END_OF_FILE'
- X/* @(#)options.h (c) copyright 10/10/88 (Dan Heller, Bart Schaefer) */
- X
- X/* Must #include mush.h before #including this file */
- X
- X/* Structure to hold assorted information collected from command line flags.
- X * Other information is held in the following global variables:
- X * cmd_help General help file, specified by -1
- X * debug Debugging mode, toggled by -d
- X * glob_flags Bits set by -C, -e, -i, -S, -t and many commands
- X * hdrs_only Show headers and exit, specified by -H
- X * iscurses Curses mode, specified by -C or "curses" command
- X * istool Tool mode, specified by -t or -T
- X * mailfile File specified by -u or -f or "folder" command
- X * prog_name Name under which mush is running
- X * time_out Tool mode timeout, specified by -T
- X * tool_help Tool mode help file, specified by -2
- X */
- X
- Xstruct mush_flags {
- X u_long flg; /* Set by -v, -h, -U, vars */
- X char *init_file; /* Set by -I or -I! */
- X char *src_file; /* Set by -F */
- X int src_n_exit; /* Set by -F! */
- X char *folder; /* Set by -f or -u */
- X char *draft; /* Set by -h */
- X char f_flags[10]; /* Set by -r, -N, etc.; passed to folder() */
- X char *Subj; /* Set by -s */
- X char *Cc; /* Set by -c */
- X char *Bcc; /* Set by -b */
- X int source_rc; /* Set by -n */
- X};
- END_OF_FILE
- if test 1248 -ne `wc -c <'mush/options.h'`; then
- echo shar: \"'mush/options.h'\" unpacked with wrong size!
- fi
- # end of 'mush/options.h'
- fi
- if test -f 'mush/panels.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mush/panels.c'\"
- else
- echo shar: Extracting \"'mush/panels.c'\" \(15200 characters\)
- sed "s/^X//" >'mush/panels.c' <<'END_OF_FILE'
- X/* @(#)panel.c (c) copyright 10/18/86 (Dan Heller) */
- X/* @(#)panels.c (c) copyright 9/29/89 (Dan Heller) */
- X
- X#include "mush.h"
- X/* mouse symbols */
- Xshort dat_mouse_left[] = {
- X 0x1FF8, 0x3FFC, 0x336C, 0x336C, 0x336C, 0x336C, 0x336C, 0x336C,
- X 0x3FFC, 0x3FFC, 0x3FFC, 0x3FFC, 0x3FFC, 0x3FC4, 0x3FFC, 0x1FF8
- X};
- X
- Xshort dat_mouse_middle[] = {
- X 0x1FF8, 0x3FFC, 0x366C, 0x366C, 0x366C, 0x366C, 0x366C, 0x366C,
- X 0x3FFC, 0x3FFC, 0x3FFC, 0x3FFC, 0x3FFC, 0x3FC4, 0x3FFC, 0x1FF8
- X};
- X
- Xshort dat_mouse_right[] = {
- X 0x1FF8, 0x3FFC, 0x36CC, 0x36CC, 0x36CC, 0x36CC, 0x36CC, 0x36CC,
- X 0x3FFC, 0x3FFC, 0x3FFC, 0x3FFC, 0x3FFC, 0x3FC4, 0x3FFC, 0x1FF8
- X};
- X
- Xmpr_static(mouse_left, 16, 16, 1, dat_mouse_left);
- Xmpr_static(mouse_middle, 16, 16, 1, dat_mouse_middle);
- Xmpr_static(mouse_right, 16, 16, 1, dat_mouse_right);
- X
- XPanel_item
- X folder_item, /* change folders */
- X folder_text_item, /* text item for the folder item */
- X file_item, /* text item for the save item */
- X msg_num_item, /* text item explicitly states which message to read */
- X read_item, /* read the current message */
- X save_item, /* saves messages */
- X sub_hdr_item[6]; /* display items that just sit there and give help */
- X
- X/* These global panel items for letter composition should eventually go away */
- XPanel_item
- X edit_item, /* edit a message */
- X reply_item; /* reply button -- also called from hdr_sw menu */
- X
- Xextern void
- X close_frame(), do_options(), do_compose(), do_send(), do_sort(),
- X do_edit(), delete_mail(), respond_mail(), do_help(), do_lpr(),
- X do_update(), abort_mail(), do_include(), load_from_file(),
- X save_to_file(), tilde_from_menu(), fkey_interposer();
- X
- Xextern Panel_setting
- X msg_num_done(), file_dir();
- X
- XPanel
- Xmake_hdr_panel(parent, choice_args, button_args)
- XFrame parent;
- Xchar **choice_args, **button_args;
- X{
- X Panel panel = window_create(parent, PANEL,
- X WIN_CONSUME_KBD_EVENTS,
- X WIN_LEFT_KEYS, WIN_TOP_KEYS, WIN_RIGHT_KEYS, NULL,
- X NULL);
- X (void) notify_interpose_event_func(panel, fkey_interposer, NOTIFY_SAFE);
- X
- X (void) panel_create_item(panel, PANEL_CHOICE,
- X PANEL_ATTRIBUTE_LIST, choice_args,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Done", 4, mush_font),
- X PANEL_CHOICE_STRINGS,
- X "Close to Icon", "Quit Tool", "Help", NULL,
- X PANEL_NOTIFY_PROC, toolquit,
- X NULL);
- X
- X (void) panel_create_item(panel, PANEL_CHOICE,
- X PANEL_ATTRIBUTE_LIST, choice_args,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Help", 4, mush_font),
- X PANEL_CHOICE_STRINGS,
- X "General", "Help with \"help\"", "The Mouse", "Windows",
- X "Message headers", "Message lists", "Folders", NULL,
- X PANEL_NOTIFY_PROC, do_help,
- X NULL);
- X
- X folder_item = panel_create_item(panel, PANEL_CHOICE,
- X PANEL_ATTRIBUTE_LIST, choice_args,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Folder", 6, mush_font),
- X PANEL_CHOICE_STRINGS,
- X "System Mailbox", "Main Mailbox", "Last Accessed Folder", NULL,
- X PANEL_NOTIFY_PROC, do_file_dir,
- X NULL);
- X
- X add_folder_to_menu(folder_item, 3);
- X
- X folder_text_item = panel_create_item(panel, PANEL_TEXT,
- X PANEL_ATTRIBUTE_LIST, choice_args,
- X PANEL_LABEL_FONT, mush_font,
- X PANEL_LABEL_STRING, "Filename:",
- X PANEL_VALUE_DISPLAY_LENGTH, 28,
- X PANEL_NOTIFY_STRING, "\n\r\033",
- X PANEL_NOTIFY_PROC, file_dir,
- X NULL);
- X
- X (void) panel_create_item(panel, PANEL_CHOICE,
- X PANEL_ATTRIBUTE_LIST, choice_args,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Update", 6, mush_font),
- X PANEL_CHOICE_STRINGS, "New Mail", "Help", NULL,
- X PANEL_NOTIFY_PROC, do_update,
- X NULL);
- X
- X (void) panel_create_item(panel, PANEL_CHOICE,
- X PANEL_ATTRIBUTE_LIST, choice_args,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Options", 7, mush_font),
- X PANEL_CHOICE_STRINGS, "Variables", "Headers", "Aliases", NULL,
- X PANEL_NOTIFY_PROC, do_options,
- X NULL);
- X
- X msg_num_item = panel_create_item(panel, PANEL_TEXT,
- X PANEL_ATTRIBUTE_LIST, choice_args,
- X PANEL_LABEL_STRING, "Range:",
- X PANEL_MENU_CHOICE_STRINGS, "Help", NULL,
- X PANEL_VALUE_DISPLAY_LENGTH, 17,
- X PANEL_VALUE_STORED_LENGTH, 80,
- X PANEL_LABEL_FONT, mush_font,
- X PANEL_NOTIFY_STRING, "\n\r",
- X PANEL_NOTIFY_PROC, msg_num_done,
- X NULL);
- X
- X sub_hdr_item[0] = panel_create_item(panel, PANEL_CHOICE,
- X PANEL_ATTRIBUTE_LIST, choice_args,
- X PANEL_LABEL_IMAGE, &mouse_left,
- X PANEL_CHOICE_STRINGS, "Help", NULL,
- X PANEL_NOTIFY_PROC, read_mail,
- X NULL);
- X sub_hdr_item[1] = panel_create_item(panel, PANEL_CHOICE,
- X PANEL_ATTRIBUTE_LIST, choice_args,
- X PANEL_LABEL_STRING, "Read ",
- X PANEL_MENU_TITLE_IMAGE, &mouse_left,
- X PANEL_CHOICE_STRINGS, "Help", NULL,
- X PANEL_NOTIFY_PROC, read_mail,
- X NULL);
- X sub_hdr_item[2] = panel_create_item(panel, PANEL_CHOICE,
- X PANEL_ATTRIBUTE_LIST, choice_args,
- X PANEL_LABEL_IMAGE, &mouse_middle,
- X PANEL_CHOICE_STRINGS, "Help", NULL,
- X PANEL_NOTIFY_PROC, delete_mail,
- X NULL);
- X sub_hdr_item[3] = panel_create_item(panel, PANEL_CHOICE,
- X PANEL_ATTRIBUTE_LIST, choice_args,
- X PANEL_LABEL_STRING, "Delete ",
- X PANEL_MENU_TITLE_IMAGE, &mouse_middle,
- X PANEL_CHOICE_STRINGS, "Help", NULL,
- X PANEL_NOTIFY_PROC, delete_mail,
- X NULL);
- X sub_hdr_item[4] = panel_create_item(panel, PANEL_CHOICE,
- X PANEL_ATTRIBUTE_LIST, choice_args,
- X PANEL_LABEL_IMAGE, &mouse_right,
- X PANEL_CHOICE_STRINGS, "Help", NULL,
- X PANEL_NOTIFY_PROC, read_mail,
- X NULL);
- X sub_hdr_item[5] = panel_create_item(panel, PANEL_CHOICE,
- X PANEL_ATTRIBUTE_LIST, choice_args,
- X PANEL_LABEL_STRING, "Menu ",
- X PANEL_MENU_TITLE_IMAGE, &mouse_right,
- X PANEL_CHOICE_STRINGS, "Help", NULL,
- X PANEL_NOTIFY_PROC, read_mail,
- X NULL);
- X
- X (void) panel_create_item(panel, PANEL_CHOICE,
- X PANEL_ATTRIBUTE_LIST, choice_args,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Printer", 7, mush_font),
- X PANEL_CHOICE_STRINGS, "Help", NULL,
- X PANEL_NOTIFY_PROC, do_lpr,
- X NULL);
- X
- X (void) panel_create_item(panel, PANEL_CHOICE,
- X PANEL_ATTRIBUTE_LIST, choice_args,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Sort", 4, mush_font),
- X PANEL_CHOICE_STRINGS,
- X "By Date", "By Author", "By Size", "By Subject",
- X "By Subject (ignore Re:)", "By Status", "Help", NULL,
- X PANEL_NOTIFY_PROC, do_sort,
- X NULL);
- X
- X window_fit_height(panel);
- X return panel;
- X}
- X
- XPanel
- Xmake_main_panel(parent, choice_args, button_args)
- XFrame parent;
- Xchar **choice_args, **button_args;
- X{
- X /* main panel stuff: */
- X Panel panel = window_create(parent, PANEL,
- X WIN_CONSUME_KBD_EVENTS,
- X WIN_LEFT_KEYS, WIN_TOP_KEYS, WIN_RIGHT_KEYS, NULL,
- X NULL);
- X (void) notify_interpose_event_func(panel, fkey_interposer, NOTIFY_SAFE);
- X
- X read_item = panel_create_item(panel, PANEL_CHOICE,
- X PANEL_ATTRIBUTE_LIST, choice_args,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Next", 4, mush_font),
- X PANEL_CHOICE_STRINGS, "Help", NULL,
- X PANEL_NOTIFY_PROC, read_mail,
- X NULL);
- X
- X (void) panel_create_item(panel, PANEL_CHOICE,
- X PANEL_ATTRIBUTE_LIST, choice_args,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Delete", 6, mush_font),
- X PANEL_CHOICE_STRINGS, "Delete",
- X "Undelete",
- X "Help", NULL,
- X PANEL_NOTIFY_PROC, delete_mail,
- X NULL);
- X
- X {
- X char *mbox = do_set(set_options, "mbox");
- X if (!mbox || !*mbox)
- X mbox = DEF_MBOX;
- X save_item = panel_create_item(panel, PANEL_CHOICE,
- X PANEL_ATTRIBUTE_LIST, choice_args,
- X PANEL_LABEL_IMAGE, panel_button_image(panel, "Save", 4, mush_font),
- X PANEL_CHOICE_STRINGS, trim_filename(mbox), NULL,
- X PANEL_NOTIFY_PROC, do_file_dir,
- X NULL);
- X }
- X
- X add_folder_to_menu(save_item, 1);
- X
- X file_item = panel_create_item(panel, PANEL_TEXT,
- X PANEL_ATTRIBUTE_LIST, choice_args,
- X PANEL_LABEL_FONT, mush_font,
- X PANEL_SHOW_MENU, TRUE,
- X PANEL_LABEL_STRING, "Filename:",
- X PANEL_MENU_CHOICE_STRINGS, "Save message without message header",
- X NULL,
- X PANEL_VALUE_DISPLAY_LENGTH, 28,
- X PANEL_NOTIFY_STRING, "\n\r\033",
- X PANEL_NOTIFY_PROC, file_dir,
- X NULL);
- X
- X (void) panel_create_item(panel, PANEL_CHOICE,
- X PANEL_ATTRIBUTE_LIST, choice_args,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Compose", 7, mush_font),
- X PANEL_CHOICE_STRINGS, "Help", NULL,
- X PANEL_NOTIFY_PROC, do_compose,
- X NULL);
- X
- X reply_item = panel_create_item(panel, PANEL_CHOICE,
- X PANEL_ATTRIBUTE_LIST, choice_args,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Reply", 5, mush_font),
- X PANEL_CHOICE_STRINGS,
- X "Sender Only", "Sender Only (include msg)",
- X "All Recipients", "All Recipients (include msg)", "Help", NULL,
- X PANEL_NOTIFY_PROC, respond_mail,
- X NULL);
- X
- X window_fit_height(panel);
- X return panel;
- X}
- X
- XPanel
- Xmake_compose_panel(parent, choice_args, button_args)
- XFrame parent;
- Xchar **choice_args, **button_args;
- X{
- X Panel panel = window_create(parent, PANEL, NULL);
- X Panel_item filename_item, fortune_item, sign_item, send_item;
- X
- X (void) notify_interpose_event_func(panel, fkey_interposer, NOTIFY_SAFE);
- X
- X (void) panel_create_item(panel, PANEL_BUTTON,
- X PANEL_ATTRIBUTE_LIST, button_args,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Close", 5, mush_font),
- X PANEL_NOTIFY_PROC, close_frame,
- X NULL);
- X
- X (void) panel_create_item(panel, PANEL_CHOICE,
- X PANEL_ATTRIBUTE_LIST, choice_args,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Compose", 7, mush_font),
- X PANEL_CHOICE_STRINGS, "Help", NULL,
- X PANEL_NOTIFY_PROC, do_compose,
- X NULL);
- X
- X send_item = panel_create_item(panel, PANEL_BUTTON,
- X PANEL_ATTRIBUTE_LIST, button_args,
- X PANEL_SHOW_ITEM, FALSE,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Send", 4, mush_font),
- X PANEL_NOTIFY_PROC, do_send,
- X NULL);
- X
- X (void) panel_create_item(panel, PANEL_BUTTON,
- X PANEL_ATTRIBUTE_LIST, button_args,
- X PANEL_SHOW_ITEM, FALSE,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Abort", 5, mush_font),
- X PANEL_NOTIFY_PROC, abort_mail,
- X NULL);
- X
- X (void) panel_create_item(panel, PANEL_CHOICE,
- X PANEL_ATTRIBUTE_LIST, choice_args,
- X PANEL_SHOW_ITEM, FALSE,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Include", 7, mush_font),
- X PANEL_CHOICE_STRINGS, "Include Message",
- X "Forward Message",
- X "Help", NULL,
- X PANEL_NOTIFY_PROC, do_include,
- X NULL);
- X
- X edit_item = panel_create_item(panel, PANEL_BUTTON,
- X PANEL_ATTRIBUTE_LIST, button_args,
- X PANEL_SHOW_ITEM, FALSE,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Edit", 4, mush_font),
- X PANEL_NOTIFY_PROC, do_edit,
- X NULL);
- X
- X (void) panel_create_item(panel, PANEL_CHOICE,
- X PANEL_ATTRIBUTE_LIST, choice_args,
- X PANEL_SHOW_ITEM, FALSE,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Headers", 7, mush_font),
- X PANEL_CHOICE_STRINGS,
- X "ALL ~h", "To: ~t", "Subject: ~s",
- X "Cc: ~c", "Bcc: ~b", "Fcc:", NULL,
- X PANEL_NOTIFY_PROC, tilde_from_menu,
- X NULL);
- X
- X sign_item = panel_create_item(panel, PANEL_CHOICE,
- X PANEL_ATTRIBUTE_LIST, choice_args,
- X PANEL_DISPLAY_LEVEL, PANEL_ALL,
- X PANEL_SHOW_MENU_MARK, TRUE,
- X PANEL_SHOW_ITEM, FALSE,
- X PANEL_LABEL_STRING, "Autosign:",
- X PANEL_CHOICE_STRINGS, "Off", "On", NULL,
- X NULL);
- X panel_set_value(sign_item, !!do_set(set_options, "autosign"));
- X /* Create a link to avoid global */
- X panel_set(send_item, PANEL_CLIENT_DATA, sign_item, NULL);
- X
- X filename_item = panel_create_item(panel, PANEL_TEXT,
- X PANEL_ATTRIBUTE_LIST, button_args,
- X PANEL_SHOW_ITEM, FALSE,
- X PANEL_LABEL_STRING, "Filename:",
- X PANEL_VALUE_DISPLAY_LENGTH, 30,
- X PANEL_NOTIFY_STRING, "\033",
- X PANEL_NOTIFY_PROC, file_dir,
- X NULL);
- X
- X (void) panel_create_item(panel, PANEL_CHOICE,
- X PANEL_ATTRIBUTE_LIST, choice_args,
- X PANEL_SHOW_ITEM, FALSE,
- X PANEL_CLIENT_DATA, filename_item,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Import", 6, mush_font),
- X PANEL_CHOICE_STRINGS, "Insert", "Replace", NULL,
- X PANEL_NOTIFY_PROC, load_from_file,
- X NULL);
- X
- X (void) panel_create_item(panel, PANEL_BUTTON,
- X PANEL_ATTRIBUTE_LIST, button_args,
- X PANEL_SHOW_ITEM, FALSE,
- X PANEL_CLIENT_DATA, filename_item,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Export", 6, mush_font),
- X PANEL_NOTIFY_PROC, save_to_file,
- X NULL);
- X
- X fortune_item = panel_create_item(panel, PANEL_CHOICE,
- X PANEL_ATTRIBUTE_LIST, choice_args,
- X PANEL_DISPLAY_LEVEL, PANEL_ALL,
- X PANEL_SHOW_MENU_MARK, TRUE,
- X PANEL_SHOW_ITEM, FALSE,
- X PANEL_LABEL_STRING, "Fortune:",
- X PANEL_CHOICE_STRINGS, "Off", "On", NULL,
- X NULL);
- X panel_set_value(fortune_item, !!do_set(set_options, "fortune"));
- X /* Create a link to avoid global */
- X panel_set(sign_item, PANEL_CLIENT_DATA, fortune_item, NULL);
- X
- X window_fit_height(panel);
- X return panel;
- X}
- X
- X#include "glob.h"
- X
- X#ifdef WALK_MENUS
- Xfolder_menu_notify(menu, mi)
- XMenu menu;
- XMenu_item mi;
- X{
- X}
- X
- Xstatic Menu_item
- Xadd_path_to_menu(menu, path)
- XMenu menu;
- Xchar *path;
- X{
- X DIR *dirp;
- X struct dirent *dp;
- X struct stat s_buf;
- X Menu_item mi;
- X Menu next_menu;
- X char buf[MAXPATHLEN];
- X
- X /* don't add a folder to the list if user can't read it */
- X if (stat(path, &s_buf) == -1 || !(s_buf.st_mode & S_IREAD))
- X return NULL;
- X if ((s_buf.st_mode & S_IFMT) == S_IFDIR) {
- X int cnt = 0;
- X if (!(dirp = opendir(path)))
- X return NULL; /* don't bother adding to list if we can't scan it */
- X next_menu = menu_create(MENU_NOTIFY_PROC, folder_menu_notify, NULL);
- X while (dp = readdir(dirp))
- X if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, ".."))
- X if (mi = add_path_to_menu(next_menu,
- X sprintf(buf, "%s/%s", path, dp->d_name))) {
- X menu_set(next_menu, MENU_APPEND_ITEM, mi, NULL);
- X cnt++;
- X }
- X closedir(dirp);
- X mi = menu_create_item(MENU_STRING, trim_filename(path), NULL);
- X if (!cnt) {
- X menu_destroy(next_menu);
- X menu_set(mi, MENU_INACTIVE, TRUE, NULL);
- X } else
- X menu_set(mi, MENU_PULLRIGHT, next_menu, NULL);
- X return mi;
- X }
- X /* we should check that this file is actually a folder */
- X return menu_create_item(MENU_STRING, trim_filename(path), NULL);
- X}
- X#endif /* WALK_MENUS */
- X
- Xstatic
- Xadd_path_to_menu(item, path, n)
- XPanel_item item;
- Xchar *path;
- Xint *n;
- X{
- X char **names, **np;
- X struct stat s_buf;
- X char buf[MAXPATHLEN];
- X
- X /* don't add a folder to the list if user can't read it */
- X if (stat(path, &s_buf) == -1 || !(s_buf.st_mode & S_IREAD))
- X return;
- X if ((s_buf.st_mode & S_IFMT) == S_IFDIR) {
- X sprintf(buf, "%s/{.*,*}", path);
- X if (filexp(buf, &names) > 0) {
- X for (np = names; np && *np; np++) {
- X if (!glob(*np, "*/{.,..}"))
- X add_path_to_menu(item, *np, n);
- X }
- X free_vec(names);
- X }
- X } else if (test_folder(path, NULL))
- X panel_set(item,
- X PANEL_CHOICE_STRING, (*n)++, savestr(trim_filename(path)),
- X NULL);
- X}
- X
- X/*
- X * Open the user's mail folder (either user set or default path) and find all
- X * the files (assumed to be mail folders) and add them to the menu list of
- X * folders to use.
- X */
- Xadd_folder_to_menu(item, n)
- XPanel_item item;
- X{
- X char *tmp = NULL, *p;
- X#ifdef WALK_MENUS
- X Menu_item mi;
- X#endif /* WALK_MENUS */
- X
- X if (!(p = do_set(set_options, "folder")) || !*p)
- X p = DEF_FOLDER;
- X if (p) {
- X int x = 0;
- X tmp = getpath(p, &x);
- X if (x == -1) {
- X if (errno != ENOENT)
- X print("%s: %s\n", p, tmp);
- X tmp = NULL;
- X }
- X }
- X if (tmp) {
- X#ifdef WALK_MENUS
- X mi = add_path_to_menu(menu, tmp);
- X#else /* WALK_MENUS */
- X add_path_to_menu(item, tmp, &n);
- X#endif /* WALK_MENUS */
- X }
- X}
- END_OF_FILE
- if test 15200 -ne `wc -c <'mush/panels.c'`; then
- echo shar: \"'mush/panels.c'\" unpacked with wrong size!
- fi
- # end of 'mush/panels.c'
- fi
- echo shar: End of archive 15 \(of 19\).
- cp /dev/null ark15isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 19 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-
-
-