home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-05-06 | 54.6 KB | 1,872 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 17 (of 19)."
- # Contents: mush/README-7.1 mush/hdr_sw.c mush/malloc.c
- # mush/misc_frame.c mush/strings.c
- # Wrapped by argv@turnpike on Wed May 2 13:59:49 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'mush/README-7.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mush/README-7.1'\"
- else
- echo shar: Extracting \"'mush/README-7.1'\" \(11036 characters\)
- sed "s/^X//" >'mush/README-7.1' <<'END_OF_FILE'
- XThis is release 7.1.0 of the SunView implementation of mush.
- X
- XVersion 7.1.0 differs from 7.0.4 mostly in the appearance of the screen
- Xand the additional functionality that is allowed to show through to the
- Xtool from the underlying interpreter. This is a significant enough change
- Xin "look and feel" that the revision number was increased from 0 to 1.
- X
- XThanks to Bill Randle <billr@saab.cna.tek.com> for extensive SunOS 3.5
- Xtesting, and to Bill and also Don Lewis <del@mlb.semi.harris.com> for
- Xtheir contributions to the new toolmode composition features and function
- Xkey handling.
- X
- XTool mode changes include:
- X * Compilation now keys on definitions of SUN_4_1, SUN_4_0 or SUN_3_5
- X in makefile.sun, rather than assuming SunOS4.0 when SIGRET=void.
- X You still have to define SUNTOOL to get the tool mode capability.
- X If you define SUNTOOL but not the others, SUN_4_0 is assumed.
- X * The header summary display window has a scrollbar; the <Prev> and
- X <Next> buttons for scrolling are gone.
- X * The placement of buttons and items has changed a lot. Buttons and
- X items dealing with folders and general setup have moved to the top
- X of the frame, and items dealing with individual messages and with
- X composition have been placed in a single row between the headers
- X and messsage display subwindows.
- X * The <Folders> and <Save> buttons each have a text entry item.
- X Furthermore, file completion with the ESC key works in those items.
- X * The <Sort> menu has been unscrambled, so you actually get the sort
- X criteria that you select. (Don't ask.)
- X * The <Aliases> and <Headers> buttons have moved into a menu under
- X the <Options> button. This clears up some confusion about exactly
- X what it was that <Headers> meant, and provides a hook for future
- X addition of a window for defining your own outgoing message headers.
- X * The <Display> button is gone; its operations are now handled by
- X opening the <Options> frame and toggling show_deleted or no_reverse.
- X * The small one-line print window is gone; messages previously shown
- X there now go to the scrollable status window. There may be some
- X remaining bugs with missing newlines here. This frees up some more
- X file descriptors in SunOS 3.5, to keep other things working longer.
- X * Function keys are recognized in most parts of the main frame. In
- X anticipation of the day when window manager function keys can be
- X redefined, the messages about "L7 not defined" etc. are still shown
- X unless suppressed through $quiet (see below).
- X * The composition frame has more control buttons, providing more of
- X the functions of line and curses mode message composition. Some
- X of the "chattiness" of message composition has gone away. In fact,
- X the whole chatty subwindow in the compose frame has gone away,
- X possibly to return in a later patch when a better way to decide
- X what frame a message should go to has been worked out. In the
- X meantime, all messages go to the main frame.
- X * Tilde escapes are supported in the tool mode composition textsw,
- X with a few minor exceptions accessible from the control buttons.
- X * Typing a <return> while entering header field text in tool mode
- X will move automatically to the next header when this is sensible.
- X The cursor becomes a bent arrow to indicate that this will happen.
- X * User-definable icons can be installed through the $mail_icon and
- X $newmail_icon variables, and $quiet has a field to suppress the
- X message-number label so your pretty pictures won't be trashed.
- X * Files that are not readable as folders are left out of the menus
- X for the <Folder> and <Save> items.
- X
- XGeneral changes include:
- X
- X * There is a new defined constant, DIRECTORY, which indicates whether
- X your system has BSD-compatible directory-access routines. It turns
- X out to be much too hard to figure this out on an OS-by-OS basis.
- X DIRECTORY is automatically defined when BSD is defined, and is in
- X the default CFLAGS in makefile.hpux; you others are on your own.
- X * Some compilers were confused by "/*" appearing in the META string
- X defined in glob.h. The characters in META have been rearranged.
- X * Using "exit" in a nested "if" in a source/init file no longer
- X causes error messages about "missing endif".
- X * Redefining "folder" via a "cmd" in .mushrc no longer causes the
- X initial folder load to bomb. Similarly with "sort".
- X * Date parsing and sorting now understand timezones. There may
- X still be some rough edges in date parsing on some of the less
- X common date formats, but RFC-822 and ctime (From_ line) dates
- X are handled correctly. If the dates mush displays are really
- X off the wall, the order of the sscanf's in parse_date() may need
- X to be changed, or we may need to add some cases rather than
- X using partial matches to skip missing timezone fields. There
- X are also some strange nonstandard abbreviations out there (what,
- X for example, is ECT?) which will all be treated as GMT unless
- X you hack them into the tables in dates.c. Missing timezones are
- X treated as the local zone to get the date-received right (the
- X From_ line ctime-date almost never has a timezone).
- X * Mush now warns you if a file you attempt to load does not "look
- X like" a folder (i.e. no messages can be read). If you are already
- X in the shell, this leaves you in an empty folder as it did before.
- X If you are just starting up (e.g. with "mush -f"), mush will exit.
- X * Additional checking is now done when collecting new mail and when
- X updating folders to detect corruptions, warn the user, and allow
- X a chance to recover. Mush still reinitializes the spool folder if
- X it shrinks, but if this is detected at update time (as opposed to
- X new-mail-check time), the user is allowed to abort the update and
- X salvage the current folder contents.
- X * Curses mode now respects the user's presetting of $crt, unless the
- X user's value is larger than the actual screen size. This allows
- X "set crt=2" to be used to force use of $pager.
- X
- XChanges in commands:
- X
- Xmush -h -
- X The -h (-draft) option will now accept "-" as a filename indicating
- X standard input. Note that this causes the input message to be sent
- X immediately; interactive use cannot be combined with redirected input.
- X The internal "mail -h" command will NOT interpret "-" as standard in.
- X
- Xalts *user
- X This syntax, analogous to the $autosign2 syntax, allows you to specify
- X any user name anywhere as "you" for purposes of $metoo, etc.
- X
- Xfolder -n
- X This command changes folders without updating; it replaces the old
- X "folder !" notation, though the old form is still supported. See
- X also the general notes above for behavior on attempts to load files
- X that are not folders.
- X
- Xfrom pattern
- X Given an argument that is not parseable as a message list, "from" will
- X automatically invoke "pick -f pattern". Mixing message lists and
- X patterns is slightly counter-intuitive; if the message list precedes
- X the pattern, it will restrict the pattern search to that list, e.g.
- X "from 3-7 johnsmith" will show those messages in the range 3-7 that
- X are from johnsmith. If the message list follows the pattern, it will
- X not be detected at all, but will be considered part of the pattern.
- X Also, "from jim bob sally" will treat the entire "jim bob sally" list
- X as a single pattern, as "pick" would; this may change in the future.
- X
- Xpipe -p /pat1/,/pat2/
- X The pattern supplied may now have the form /pat1/,/pat2/ to indicate
- X that extraction should begin at pat1 and end at pat2, inclusive.
- X Patterns are still matched literally at beginning-of-line (no regex
- X matching), and there is not currently any way to imbed a slash in
- X patterns of this form. To allow searching for file paths, slashes
- X are significant only if the second slash is followed by a comma.
- X
- Xsave/copy
- X Unless told to clobber the file (-f), these commands now check that
- X the file to which they are appending "looks like" a folder. If the
- X file seems to be something else, the user is prompted to confirm the
- X save or copy.
- X
- Xset
- X Several minor fixes. Piping to "set" now clears the variable if the
- X input message list is empty, rather than leaving the old value. For
- X backwards compatibility, however, an unset variable does not become
- X set when an empty message list is piped to it. Also, some of the
- X more esoteric abuses of the variable=value syntax have either been
- X made legal (`set var=' is the same as `set var') or made illegal
- X (`set var=value = value' won't create a variable named "var=value").
- X
- Xsort
- X Sorting by multiple criteria at once is now supported. The flags to
- X sort have changed; "-" to reverse sorting is now obsolete, replaced
- X by "-r", and all the sort criteria should now be prefixed with a "-"
- X (-a,-d,-l,-R,-s,-S) like options to any other command. A significant
- X subset of the old syntax is still recognized as a special case.
- X
- XNew/changed variables:
- X
- X $cmd_help
- X (Also $tool_help) The path given for this variable may contain
- X the usual filename metacharacters (~+).
- X
- X $hangup
- X When set, mush updates the folder on SIGHUP instead of saving
- X the tempfile. This is a bit dangerous -- in rare circumstances
- X (mainly when two or more MUAs are modifying the same folder)
- X some new mail could be lost. Old mail should never be lost.
- X
- X $hdr_format
- X The format spec %Z returns the time zone part of the date.
- X
- X $mail_icon
- X Names an icon file to be used in the normal case, when no new
- X mail is present. This icon will replace the mailbox with the
- X flag down.
- X
- X $newmail_icon
- X Names an icon file to be used when new mail is present, replacing
- X the mailbox with the flag up.
- X
- X $output
- X The message-list output of the last successful command is stored
- X in this variable. This allows easy recovery from broken pipes
- X etc. Note that any successful command that does not produce a
- X message list will clear $output (e.g. "echo").
- X
- X $quiet
- X If the field "newmail" is present in the multi-value, the usual
- X "New mail (#X): ..." messages are not displayed. The new mail
- X is still automatically incorporated into the mailbox. In tool
- X mode, this shuts off the new mail bell (the "tool" field still
- X silences ALL tool mode bells).
- X
- X If the field "fkey" is present in tool mode, warning messages
- X about unbound keys are not printed.
- X
- X If the field "iconlabel" is present in tool mode, the current
- X number of messages is not displayed in the mush icon.
- X
- X $status
- X This is set to the success (0) or failure (-1) status of the
- X previously executed command. Note that some curses-mode commands
- X return a failure status to indicate that the display has been
- X corrupted even if the command itself succeeded, so this variable
- X is mostly useful in scripts.
- END_OF_FILE
- if test 11036 -ne `wc -c <'mush/README-7.1'`; then
- echo shar: \"'mush/README-7.1'\" unpacked with wrong size!
- fi
- # end of 'mush/README-7.1'
- fi
- if test -f 'mush/hdr_sw.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mush/hdr_sw.c'\"
- else
- echo shar: Extracting \"'mush/hdr_sw.c'\" \(11559 characters\)
- sed "s/^X//" >'mush/hdr_sw.c' <<'END_OF_FILE'
- X/* @(#)hdr_sw.c (c) copyright 2/17/90 (Dan Heller) */
- X
- X/* This file handles all the header subwindow code. It would be much
- X * better if this subwindow, which displays the headers for the current
- X * folder, were a textsw. That way, this file would go away completely.
- X * Until then, we have to create the window (canvas), define an event
- X * handler for when events happen in this window, create our own scrollbar,
- X * figure out when the user scrolls with it, attach our own popup menu to
- X * the canvas, handle events for that, let's see... kitchen sink? Oh,
- X * that's over there in the corner.
- X */
- X#include "mush.h"
- X#ifdef SUN_4_0 /* SunOS 4.0+ */
- X#include <sunwindow/win_keymap.h>
- X#endif /* SUN_4_0 */
- X
- Xextern Panel hdr_panel;
- Xextern void hdr_io(), fkey_interposer();
- X
- Xstatic Notify_value scroll_hdr();
- Xstatic void msg_menu_func(), do_menu(), msg_menu_notify();
- Xstatic Menu msg_menu;
- Xstatic Menu_item cur_msg_item;
- X
- Xvoid
- Xmake_hdr_sw(parent)
- XFrame parent;
- X{
- X Textsw tmpsw;
- X
- X if (!(hdr_sw = window_create(parent, CANVAS,
- X WIN_HEIGHT, 10 + screen*l_height(),
- X WIN_WIDTH, WIN_EXTEND_TO_EDGE,
- X WIN_BELOW, hdr_panel,
- X WIN_EVENT_PROC, hdr_io,
- X CANVAS_AUTO_CLEAR, TRUE,
- X CANVAS_RETAINED, TRUE,
- X WIN_CONSUME_KBD_EVENTS,
- X WIN_ASCII_EVENTS, WIN_LEFT_KEYS, WIN_TOP_KEYS, WIN_RIGHT_KEYS, NULL,
- X WIN_IGNORE_KBD_EVENTS,
- X WIN_UP_ASCII_EVENTS, NULL,
- X WIN_CONSUME_PICK_EVENTS,
- X LOC_WINENTER, WIN_MOUSE_BUTTONS, LOC_MOVE, NULL,
- X WIN_VERTICAL_SCROLLBAR, scrollbar_create(0),
- X NULL)))
- X perror("hdr_sw"), cleanup(0);
- X hdr_win = canvas_pixwin(hdr_sw);
- X (void) notify_interpose_event_func(hdr_sw, fkey_interposer, NOTIFY_SAFE);
- X (void) notify_interpose_event_func(hdr_sw, scroll_hdr, NOTIFY_SAFE);
- X scrollbar_set((Scrollbar)window_get(hdr_sw, WIN_VERTICAL_SCROLLBAR),
- X SCROLL_NORMALIZE, FALSE,
- X SCROLL_ADVANCED_MODE, TRUE,
- X SCROLL_LINE_HEIGHT, l_height(),
- X SCROLL_VIEW_LENGTH, screen,
- X NULL);
- X#ifdef SUN_4_0 /* SunOS 4.0+ */
- X /* This is a particularly ugly hack. If Sun only documented the correct
- X * way to set up the key mapping for a window the way that textsw's do
- X * then we wouldn't have to do anything this awful. Maybe in 4.2.....
- X *
- X * The object here is to get the same translation table for our header
- X * canvas as for a textsw (more or less anyway). This way the arrow
- X * keys and such work right.
- X */
- X tmpsw = window_create(parent, TEXTSW, NULL);
- X#ifdef SUN_4_1
- X keymap_from_fd[(int)window_get(hdr_sw, WIN_FD)].keymap =
- X keymap_from_fd[(int)window_get(tmpsw, WIN_FD)].keymap;
- X keymap_from_fd[(int)window_get(tmpsw, WIN_FD)].keymap = (Keymap *) 0;
- X#else /* !SUN_4_1 */
- X keymap_from_fd[(int)window_get(hdr_sw, WIN_FD)].kf_keymap =
- X keymap_from_fd[(int)window_get(tmpsw, WIN_FD)].kf_keymap;
- X keymap_from_fd[(int)window_get(tmpsw, WIN_FD)].kf_keymap = (Keymap *) 0;
- X#endif /* SUN_4_1 */
- X (void) window_destroy(tmpsw);
- X#endif /* SUN_4_0 */
- X}
- X
- Xstatic Notify_value
- Xscroll_hdr(canvas, event, arg, type)
- XCanvas canvas;
- XEvent *event;
- XNotify_arg arg;
- XNotify_event_type type;
- X{
- X int amount, count, i;
- X int show_deleted = !!do_set(set_options, "show_deleted");
- X char *argv[3], msgnum[8];
- X Scrollbar sb;
- X argv[0] = "headers";
- X argv[1] = msgnum;
- X argv[2] = NULL;
- X
- X switch (decode_scroll((Notify_client) canvas, event, screen, &amount)) {
- X case MUSH_SCROLL_PASS_EVENT:
- X switch(ID) {
- X case SCROLL_ENTER:
- X case SCROLL_EXIT:
- X return NOTIFY_IGNORED;
- X case SCROLL_REQUEST:
- X sb = (Scrollbar)arg;
- X switch( (Scroll_motion)
- X scrollbar_get(sb, SCROLL_REQUEST_MOTION)) {
- X case SCROLL_LINE_FORWARD:
- X amount = 1;
- X break;
- X case SCROLL_LINE_BACKWARD:
- X amount = -1;
- X break;
- X case SCROLL_ABSOLUTE:
- X i = (int)scrollbar_get(sb, SCROLL_VIEW_START);
- X if (!show_deleted) {
- X count = i;
- X for (i = 0; i < msg_cnt-1; i++)
- X if (!ison(msg[i].m_flags, DELETE) &&
- X count-- == 0)
- X break;
- X }
- X (void) sprintf(msgnum, "%d", i+1);
- X argv[1] = msgnum;
- X (void) do_hdrs(2, argv, NULL);
- X return(NOTIFY_DONE);
- X default:
- X amount =
- X (int)scrollbar_get(sb, SCROLL_VIEW_START) -
- X (int)scrollbar_get(sb, SCROLL_LAST_VIEW_START);
- X break;
- X }
- X break;
- X default:
- X return notify_next_event_func(canvas, event, arg, type);
- X }
- X break;
- X case MUSH_SCROLL_IGNORE:
- X return NOTIFY_IGNORED;
- X case MUSH_SCROLL_TO:
- X if (amount == 1) {
- X argv[1] = "1";
- X (void) do_hdrs(2, argv, NULL);
- X return NOTIFY_DONE;
- X } else {
- X (void) sprintf(msgnum, "%d", msg_cnt - screen + 1);
- X argv[1] = msgnum;
- X (void) do_hdrs(2, argv, NULL);
- X return NOTIFY_DONE;
- X }
- X }
- X if (amount == screen)
- X argv[1] = "+";
- X else if (amount == -screen)
- X argv[1] = "-";
- X else if (amount >= 0) {
- X if (amount < screen)
- X (void) sprintf(msgnum, "%d", min(n_array[amount]+1, msg_cnt-1));
- X else {
- X /* so much for layering */
- X for (i = n_array[0]+1; i < msg_cnt-1 && amount > 0; i++)
- X if (show_deleted || !ison(msg[i].m_flags, DELETE))
- X amount--;
- X (void) sprintf(msgnum, "%d", i);
- X }
- X } else {
- X /* so much for layering */
- X for (i = n_array[0]; i > 0 && amount < 0; i--)
- X if (show_deleted || !ison(msg[i-1].m_flags, DELETE))
- X amount++;
- X (void) sprintf(msgnum, "%d", i + 1);
- X }
- X (void) do_hdrs(2, argv, NULL);
- X return NOTIFY_DONE;
- X}
- X
- X/*
- X * Routines to handle io on the hdr_sw (canvas).
- X */
- X
- X/* if MENU button goes down on a hdr, drawbox around hdr and popup menu */
- X#define draw(x1,y1,x2,y2) (void) pw_vector(hdr_win, x1,y1,x2,y2,PIX_XOR,1)
- X#define box(x1,y1,x2,y2) \
- X draw(x1,y1, x1,y2), draw(x1,y2, x2,y2), \
- X draw(x2,y2, x2,y1), draw(x2,y1, x1,y1)
- X
- X#define READ_MSG (char *)'r'
- X#define DEL_MSG (char *)'d'
- X#define UNDEL_MSG (char *)'u'
- X#define REPL_MSG (char *)'R'
- X#define SAVE_MSG (char *)'s'
- X#define PRNT_MSG (char *)'p'
- X#define PRE_MSG (char *)'P'
- X#define HELP_MSG (char *)'H'
- X
- X/*ARGSUSED*/
- Xvoid
- Xhdr_io(canvas, event, arg)
- XCanvas canvas;
- XEvent *event;
- Xcaddr_t arg;
- X{
- X static int which_cursor;
- X int line;
- X
- X if (ID == WIN_REPAINT) {
- X if (is_iconic != (int) window_get(tool, FRAME_CLOSED)) {
- X check_new_mail();
- X
- X /* Reload time with value of timeout upon timer expiration. */
- X mail_timer.it_interval.tv_sec = time_out;
- X
- X mail_timer.it_value.tv_sec = time_out;
- X (void) notify_set_itimer_func(tool, do_check,
- X ITIMER_REAL, &mail_timer, (struct itimerval *) 0);
- X is_iconic = 0;
- X }
- X }
- X
- X /* make cursor change which button is lit */
- X switch (which_cursor) {
- X case 0 : (void) window_set(canvas, WIN_CURSOR, l_cursor, NULL);
- X when 1 : (void) window_set(canvas, WIN_CURSOR, m_cursor, NULL);
- X when 2 : (void) window_set(canvas, WIN_CURSOR, r_cursor, NULL);
- X }
- X
- X which_cursor = (which_cursor+1) % 3;
- X
- X /* just return -- we just wanted to make the cursor flicker */
- X if (ID == LOC_STILL || ID == LOC_MOVE || ID == LOC_WINENTER ||
- X ID == LOC_RGNENTER || ID == KBD_USE || ID == KBD_DONE)
- X return;
- X
- X if (event_is_button(event) && event_is_down(event)) {
- X line = (event_y(event) - 5) / l_height();
- X if (line < 0)
- X line = 0;
- X else if (line >= screen)
- X line = screen - 1;
- X if (!msg_cnt || n_array[line] > msg_cnt)
- X return;
- X if (ID == MS_RIGHT)
- X do_menu(hdr_sw, event, window_get(hdr_sw, WIN_FD), n_array[line]);
- X else if (ID == MS_MIDDLE) {
- X set_isread(n_array[line]);
- X msg_menu_func(DEL_MSG, n_array[line]);
- X } else {
- X int do_do_hdrs = 0;
- X if (current_msg != n_array[line]) {
- X current_msg = n_array[line];
- X do_do_hdrs++;
- X }
- X if (ison(msg[current_msg].m_flags, UNREAD))
- X do_do_hdrs++;
- X (void) display_msg(n_array[line], (u_long)0);
- X if (do_do_hdrs)
- X (void) do_hdrs(0, DUBL_NULL, NULL);
- X }
- X } else
- X window_default_event_proc(canvas, event, NULL);
- X}
- X
- Xstatic struct menu_rec {
- X char *str; /* Menu item label. */
- X char *data; /* Menu item client data. */
- X};
- X
- Xstatic void
- Xget_msg_menu()
- X{
- X int i;
- X Menu_item mi = NULL;
- X
- X static struct menu_rec msg_items[] = {
- X { "Read", READ_MSG },
- X { "Delete", DEL_MSG },
- X { "Undelete", UNDEL_MSG },
- X { "Reply", REPL_MSG },
- X { "Save", SAVE_MSG },
- X { "Preserve", PRE_MSG },
- X { "Print", PRNT_MSG },
- X { "Help", HELP_MSG },
- X };
- X
- X msg_menu = menu_create(MENU_NOTIFY_PROC, msg_menu_notify, NULL);
- X for (i = 0; i < ArraySize(msg_items); i++) {
- X mi = menu_create_item(MENU_STRING, msg_items[i].str,
- X MENU_CLIENT_DATA, msg_items[i].data,
- X NULL);
- X (void) menu_set(msg_menu, MENU_APPEND_ITEM, mi, NULL);
- X }
- X}
- X
- Xstatic void
- Xmsg_menu_notify(menu, item)
- XMenu menu;
- XMenu_item item;
- X{
- X cur_msg_item = item;
- X}
- X
- Xstatic void
- Xdo_menu(can_sw, event, fd, message)
- XCanvas can_sw;
- XEvent *event;
- Xint fd, message;
- X{
- X char *action;
- X static char buf[16];
- X
- X if (!msg_cnt) {
- X wprint("No Messages.\n");
- X return;
- X }
- X if (fd) {
- X int line;
- X Rect *hdr_rect;
- X
- X if (!msg_menu)
- X get_msg_menu();
- X (void) sprintf(buf, "Message #%d", message+1);
- X /* provide feedback about what message the menu references */
- X for (line = 0; line <= n_array[screen-1]; line++)
- X if (n_array[line] == message)
- X break;
- X hdr_rect = (Rect *)window_get(hdr_sw, WIN_RECT);
- X box(0, 5 + line * l_height(),
- X hdr_rect->r_width, 5 + (line+1) * l_height());
- X /* show menu */
- X menu_show(msg_menu, can_sw, event, NULL);
- X /* remove feedback */
- X box(0, 5 + line * l_height(),
- X hdr_rect->r_width, 5 + (line+1) * l_height());
- X /* if user selected something, figure out what was selected. */
- X if (!cur_msg_item)
- X return;
- X action = (char *) menu_get(cur_msg_item, MENU_CLIENT_DATA);
- X cur_msg_item = (Menu_item)NULL;
- X } else
- X action = (char *) event;
- X
- X set_isread(message);
- X switch ((int) action) {
- X case SAVE_MSG : {
- X extern Panel_item msg_num_item, save_item;
- X (void) panel_set(msg_num_item, PANEL_VALUE,
- X sprintf(buf, "%d", message+1), NULL);
- X event_id(event) = MS_LEFT;
- X do_file_dir(save_item, 0, event);
- X (void) panel_set(msg_num_item, PANEL_VALUE, NO_STRING, NULL);
- X }
- X when HELP_MSG :
- X help(0, "headers", tool_help);
- X when PRNT_MSG : case PRE_MSG : case UNDEL_MSG : case DEL_MSG :
- X msg_menu_func(action, message);
- X when REPL_MSG : {
- X extern Panel_item reply_item;
- X (void) open_compose();
- X /* reply_item shouldn't be here */
- X respond_mail(reply_item, message, NO_EVENT);
- X }
- X otherwise :
- X if (current_msg != message) {
- X current_msg = message;
- X (void) do_hdrs(0, DUBL_NULL, NULL);
- X }
- X#ifdef SUN_3_5
- X /* Test for a shortage of file descriptors */
- X if (nopenfiles(0) > 3)
- X#endif /* SUN_3_5 */
- X turnon(glob_flags, NEW_FRAME);
- X more_prompt = compose_hdr(message);
- X display_msg(message, (u_long)0);
- X }
- X}
- X
- X/* msg_menu_func() is a function called to perform message menu actions
- X * that are either selected from the popup menu in the header window or
- X * from mouse actions that function as accelerators.
- X */
- Xstatic void
- Xmsg_menu_func(action, message)
- Xchar *action;
- X{
- X int argc;
- X register char **argv;
- X char buf[32];
- X
- X wprint("Message #%d ", message+1);
- X if (action == UNDEL_MSG || action == DEL_MSG)
- X wprint("%sd.\n", sprintf(buf, "%selete",
- X (action == DEL_MSG)? "d": "und"));
- X else if (action == PRNT_MSG) {
- X wprint("sent to printer.\n");
- X (void) strcpy(buf, "lpr");
- X } else if (action == PRE_MSG)
- X wprint("%sd.\n", strcpy(buf, "preserve"));
- X (void) sprintf(&buf[strlen(buf)], " %d", message+1);
- X
- X if (argv = make_command(buf, (char ***) DUBL_NULL, &argc))
- X (void) do_command(argc, argv, msg_list);
- X}
- END_OF_FILE
- if test 11559 -ne `wc -c <'mush/hdr_sw.c'`; then
- echo shar: \"'mush/hdr_sw.c'\" unpacked with wrong size!
- fi
- # end of 'mush/hdr_sw.c'
- fi
- if test -f 'mush/malloc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mush/malloc.c'\"
- else
- echo shar: Extracting \"'mush/malloc.c'\" \(10827 characters\)
- sed "s/^X//" >'mush/malloc.c' <<'END_OF_FILE'
- X/*
- X * This is a slightly modified version of the malloc.c distributed with
- X * Larry Wall's perl 2.0 sources. RCS and sccs information has been
- X * retained, but modified so that it will not actually affect checkin
- X * or checkout of this file if revision control is used for Mush.
- X *
- X * Other changes include:
- X * Removal of the ASSERT macro and other code related to the
- X * preprocessor definition "debug"
- X *
- X * Replaced #include "perl.h" with #include "mush.h" (guess why)
- X *
- X * Warning messages are now printed with the mush Debug macro,
- X * that is, they are normally suppressed
- X *
- X * Added a calloc() function, using mush's bzero()
- X *
- X * Also, the mush xfree() and free_vec() functions have been moved here.
- X */
- X
- X#include "mush.h"
- X
- X/*
- X * Compile this portion only if configured for INTERNAL_MALLOC
- X */
- X#ifdef INTERNAL_MALLOC
- X#ifdef SYSV
- X#include <memory.h>
- X#define bcopy(src,dst,len) memcpy(dst,src,len)
- X#endif /* SYSV */
- X#define free xfree /* rename free for mush purposes */
- X
- X/* Begin modified perl malloc.c */
- X
- X/* Header: malloc.c,v 2.0 88/06/05 00:09:16 root Exp
- X *
- X * Log: malloc.c,v
- X * Revision 2.0 88/06/05 00:09:16 root
- X * Baseline version 2.0.
- X *
- X */
- X
- X#ifndef lint
- Xstatic char sccsid[] = "malloc.c 4.3 (Berkeley) 9/16/83";
- X#endif /* !lint */
- X
- X#define RCHECK
- X/*
- X * malloc.c (Caltech) 2/21/82
- X * Chris Kingsley, kingsley@cit-20.
- X *
- X * This is a very fast storage allocator. It allocates blocks of a small
- X * number of different sizes, and keeps free lists of each size. Blocks that
- X * don't exactly fit are passed up to the next larger size. In this
- X * implementation, the available sizes are 2^n-4 (or 2^n-12) bytes long.
- X * This is designed for use in a program that uses vast quantities of memory,
- X * but bombs when it runs out.
- X */
- X
- X/* I don't much care whether these are defined in sys/types.h--LAW */
- X
- X#undef u_char
- X#define u_char unsigned char
- X#undef u_int
- X#define u_int unsigned int
- X#undef u_short
- X#define u_short unsigned short
- X
- X/*
- X * The overhead on a block is at least 4 bytes. When free, this space
- X * contains a pointer to the next free block, and the bottom two bits must
- X * be zero. When in use, the first byte is set to MAGIC, and the second
- X * byte is the size index. The remaining bytes are for alignment.
- X * If range checking is enabled and the size of the block fits
- X * in two bytes, then the top two bytes hold the size of the requested block
- X * plus the range checking words, and the header word MINUS ONE.
- X */
- Xunion overhead {
- X union overhead *ov_next; /* when free */
- X struct {
- X u_char ovu_magic; /* magic number */
- X u_char ovu_index; /* bucket # */
- X#ifdef RCHECK
- X u_short ovu_size; /* actual block size */
- X u_int ovu_rmagic; /* range magic number */
- X#endif /* RCHECK */
- X } ovu;
- X#define ov_magic ovu.ovu_magic
- X#define ov_index ovu.ovu_index
- X#define ov_size ovu.ovu_size
- X#define ov_rmagic ovu.ovu_rmagic
- X};
- X
- X#define MAGIC 0xff /* magic # on accounting info */
- X#define OLDMAGIC 0x7f /* same after a free() */
- X#define RMAGIC 0x55555555 /* magic # on range info */
- X#ifdef RCHECK
- X#define RSLOP sizeof (u_int)
- X#else /* !RCHECK */
- X#define RSLOP 0
- X#endif /* RCHECK */
- X
- X/*
- X * nextf[i] is the pointer to the next free block of size 2^(i+3). The
- X * smallest allocatable block is 8 bytes. The overhead information
- X * precedes the data area returned to the user.
- X */
- X#define NBUCKETS 30
- Xstatic union overhead *nextf[NBUCKETS];
- Xextern char *sbrk();
- X
- X#ifdef MSTATS
- X/*
- X * nmalloc[i] is the difference between the number of mallocs and frees
- X * for a given block size.
- X */
- Xstatic u_int nmalloc[NBUCKETS];
- X#endif /* MSTATS */
- X
- Xchar *
- Xmalloc(nbytes)
- X register unsigned nbytes;
- X{
- X register union overhead *p;
- X register int bucket = 0;
- X register unsigned shiftr;
- X
- X /*
- X * Convert amount of memory requested into
- X * closest block size stored in hash buckets
- X * which satisfies request. Account for
- X * space used per block for accounting.
- X */
- X nbytes += sizeof (union overhead) + RSLOP;
- X nbytes = (nbytes + 3) &~ 3;
- X shiftr = (nbytes - 1) >> 2;
- X /* apart from this loop, this is O(1) */
- X while (shiftr >>= 1)
- X bucket++;
- X /*
- X * If nothing in hash bucket right now,
- X * request more memory from the system.
- X */
- X if (nextf[bucket] == (union overhead *)0)
- X morecore(bucket);
- X if ((p = (union overhead *)nextf[bucket]) == (union overhead *)0)
- X return (NULL);
- X /* remove from linked list */
- X if (*((int*)p) > 0x10000000)
- X Debug("Corrupt malloc ptr 0x%x at 0x%x\n",*((int*)p),p);
- X nextf[bucket] = nextf[bucket]->ov_next;
- X p->ov_magic = MAGIC;
- X p->ov_index= bucket;
- X#ifdef MSTATS
- X nmalloc[bucket]++;
- X#endif /* MSTATS */
- X#ifdef RCHECK
- X /*
- X * Record allocated size of block and
- X * bound space with magic numbers.
- X */
- X if (nbytes <= 0x10000)
- X p->ov_size = nbytes - 1;
- X p->ov_rmagic = RMAGIC;
- X *((u_int *)((caddr_t)p + nbytes - RSLOP)) = RMAGIC;
- X#endif /* RCHECK */
- X return ((char *)(p + 1));
- X}
- X
- X/*
- X * Allocate more memory to the indicated bucket.
- X */
- Xstatic
- Xmorecore(bucket)
- X register bucket;
- X{
- X register union overhead *op;
- X register int rnu; /* 2^rnu bytes will be requested */
- X register int nblks; /* become nblks blocks of the desired size */
- X register int siz;
- X
- X if (nextf[bucket])
- X return;
- X /*
- X * Insure memory is allocated
- X * on a page boundary. Should
- X * make getpageize call?
- X */
- X op = (union overhead *)sbrk(0);
- X if ((long)op & 0x3ff)
- X sbrk(1024 - ((long)op & 0x3ff));
- X /* take 2k unless the block is bigger than that */
- X rnu = (bucket <= 8) ? 11 : bucket + 3;
- X nblks = 1 << (rnu - (bucket + 3)); /* how many blocks to get */
- X if (rnu < bucket)
- X rnu = bucket;
- X op = (union overhead *)sbrk(1 << rnu);
- X /* no more room! */
- X if ((long)op == -1)
- X return;
- X /*
- X * Round up to minimum allocation size boundary
- X * and deduct from block count to reflect.
- X */
- X if ((long)op & 7) {
- X op = (union overhead *)(((long)op + 8) &~ 7);
- X nblks--;
- X }
- X /*
- X * Add new memory allocated to that on
- X * free list for this hash bucket.
- X */
- X nextf[bucket] = op;
- X siz = 1 << (bucket + 3);
- X while (--nblks > 0) {
- X op->ov_next = (union overhead *)((caddr_t)op + siz);
- X op = (union overhead *)((caddr_t)op + siz);
- X }
- X}
- X
- Xvoid
- Xfree(cp)
- X char *cp;
- X{
- X register int size;
- X register union overhead *op;
- X
- X if (cp == NULL || debug < 5)
- X return;
- X op = (union overhead *)((caddr_t)cp - sizeof (union overhead));
- X if (op->ov_magic != MAGIC) {
- X Debug("%s free() ignored\n",
- X op->ov_magic == OLDMAGIC ? "Duplicate" : "Bad");
- X return; /* sanity */
- X }
- X op->ov_magic = OLDMAGIC;
- X#ifdef RCHECK
- X if (op->ov_rmagic != RMAGIC) {
- X Debug("Range check failed, free() ignored\n");
- X return;
- X }
- X if (op->ov_index <= 13 &&
- X *(u_int *)((caddr_t)op + op->ov_size + 1 - RSLOP) != RMAGIC) {
- X Debug("Range check failed, free() ignored\n");
- X return;
- X }
- X#endif /* RCHECK */
- X if (op->ov_index >= NBUCKETS)
- X return;
- X size = op->ov_index;
- X op->ov_next = nextf[size];
- X nextf[size] = op;
- X#ifdef MSTATS
- X nmalloc[size]--;
- X#endif /* MSTATS */
- X}
- X
- X/*
- X * When a program attempts "storage compaction" as mentioned in the
- X * old malloc man page, it realloc's an already freed block. Usually
- X * this is the last block it freed; occasionally it might be farther
- X * back. We have to search all the free lists for the block in order
- X * to determine its bucket: 1st we make one pass thru the lists
- X * checking only the first block in each; if that fails we search
- X * ``reall_srchlen'' blocks in each list for a match (the variable
- X * is extern so the caller can modify it). If that fails we just copy
- X * however many bytes was given to realloc() and hope it's not huge.
- X */
- Xint reall_srchlen = 4; /* 4 should be plenty, -1 =>'s whole list */
- X
- Xchar *
- Xrealloc(cp, nbytes)
- X char *cp;
- X unsigned nbytes;
- X{
- X register u_int onb;
- X union overhead *op;
- X char *res;
- X register int i;
- X int was_alloced = 0;
- X
- X if (cp == NULL)
- X return (malloc(nbytes));
- X op = (union overhead *)((caddr_t)cp - sizeof (union overhead));
- X if (op->ov_magic == MAGIC) {
- X was_alloced++;
- X i = op->ov_index;
- X } else {
- X /*
- X * Already free, doing "compaction".
- X *
- X * Search for the old block of memory on the
- X * free list. First, check the most common
- X * case (last element free'd), then (this failing)
- X * the last ``reall_srchlen'' items free'd.
- X * If all lookups fail, then assume the size of
- X * the memory block being realloc'd is the
- X * smallest possible.
- X */
- X if ((i = findbucket(op, 1)) < 0 &&
- X (i = findbucket(op, reall_srchlen)) < 0)
- X i = 0;
- X }
- X onb = (1 << (i + 3)) - sizeof (*op) - RSLOP;
- X /* avoid the copy if same size block */
- X if (was_alloced &&
- X nbytes <= onb && nbytes > (onb >> 1) - sizeof(*op) - RSLOP)
- X return(cp);
- X if ((res = malloc(nbytes)) == NULL)
- X return (NULL);
- X if (cp != res) /* common optimization */
- X bcopy(cp, res, (nbytes < onb) ? nbytes : onb);
- X if (was_alloced)
- X free(cp);
- X return (res);
- X}
- X
- X/*
- X * Search ``srchlen'' elements of each free list for a block whose
- X * header starts at ``freep''. If srchlen is -1 search the whole list.
- X * Return bucket number, or -1 if not found.
- X */
- Xstatic
- Xfindbucket(freep, srchlen)
- X union overhead *freep;
- X int srchlen;
- X{
- X register union overhead *p;
- X register int i, j;
- X
- X for (i = 0; i < NBUCKETS; i++) {
- X j = 0;
- X for (p = nextf[i]; p && j != srchlen; p = p->ov_next) {
- X if (p == freep)
- X return (i);
- X j++;
- X }
- X }
- X return (-1);
- X}
- X
- X#ifdef MSTATS
- X/*
- X * mstats - print out statistics about malloc
- X *
- X * Prints two lines of numbers, one showing the length of the free list
- X * for each size category, the second showing the number of mallocs -
- X * frees for each size category.
- X */
- Xmstats(s)
- X char *s;
- X{
- X register int i, j;
- X register union overhead *p;
- X int totfree = 0,
- X totused = 0;
- X
- X Debug("Memory allocation statistics %s\nfree:\t", s);
- X for (i = 0; i < NBUCKETS; i++) {
- X for (j = 0, p = nextf[i]; p; p = p->ov_next, j++)
- X ;
- X Debug(" %d", j);
- X totfree += j * (1 << (i + 3));
- X }
- X Debug("\nused:\t");
- X for (i = 0; i < NBUCKETS; i++) {
- X Debug( " %d", nmalloc[i]);
- X totused += nmalloc[i] * (1 << (i + 3));
- X }
- X Debug("\n\tTotal in use: %d, total free: %d\n",
- X totused, totfree);
- X}
- X#endif /* MSTATS */
- X
- X/* End of modified perl malloc.c */
- X
- Xchar *
- Xcalloc(nitems, itemsz)
- Xu_int nitems, itemsz;
- X{
- X char *cp;
- X
- X cp = malloc(nitems * itemsz);
- X bzero(cp, nitems * itemsz);
- X return cp;
- X}
- X
- X/* These are needed for curses and other external linkage */
- X
- X#undef free
- X
- Xchar *
- Xcfree(p, n, s)
- Xchar *p;
- Xu_int n, s;
- X{
- X xfree(p);
- X return NULL;
- X}
- X
- Xchar *
- Xfree(p)
- Xchar *p;
- X{
- X xfree(p);
- X return NULL;
- X}
- X
- X#else /* INTERNAL_MALLOC */
- X
- Xchar *stackbottom; /* set first thing in main() */
- X
- Xvoid
- Xxfree(cp)
- Xchar *cp;
- X{
- X extern char end[];
- X
- X if (cp >= end && cp < stackbottom && cp < (char *) &cp && debug < 5)
- X free(cp);
- X}
- X
- X#endif /* INTERNAL_MALLOC */
- X
- Xvoid
- Xfree_vec(argv)
- Xchar **argv;
- X{
- X register int n;
- X if (!argv)
- X return;
- X for (n = 0; argv[n]; n++)
- X xfree(argv[n]);
- X xfree((char *)argv);
- X}
- END_OF_FILE
- if test 10827 -ne `wc -c <'mush/malloc.c'`; then
- echo shar: \"'mush/malloc.c'\" unpacked with wrong size!
- fi
- # end of 'mush/malloc.c'
- fi
- if test -f 'mush/misc_frame.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mush/misc_frame.c'\"
- else
- echo shar: Extracting \"'mush/misc_frame.c'\" \(7659 characters\)
- sed "s/^X//" >'mush/misc_frame.c' <<'END_OF_FILE'
- X/* @(#) misc_frame.c (c) copyright 9/29/89 (Dan Heller) */
- X
- X/*
- X * This file contains several functions which create dialog box frames
- X * for (currently) mail aliases and ignored headers. Each dialog box
- X * has a list of some kind and a way to add or delete items from the
- X * list. The list is a textsw which is updated (currently) by do_set().
- X * Public routines:
- X * update_list_textsw(struct options **) updates the textsw list.
- X * do_alias() creates the alias dialog frame box
- X * do_ignore() creates the ignored headers dialog frame box
- X */
- X
- X#include "mush.h"
- X
- Xextern Notify_value fkey_interposer();
- X
- X/****************** Mail Aliases ********************/
- X
- XFrame alias_frame;
- XPanel_item alias_msg, alias_name, alias_value, alias_list_textsw;
- Xstatic void set_alias();
- X
- XFrame ignore_frame;
- XPanel_item ignore_msg, ignore_name, ignore_list_textsw;
- Xstatic Panel_setting set_ignore();
- X
- X#define MY_FRAME_WIDTH 600
- X
- Xstatic void
- Xframe_help(item)
- XPanel_item item;
- X{
- X (void) help(0, panel_get(item, PANEL_CLIENT_DATA), tool_help);
- X}
- X
- Xvoid
- Xupdate_list_textsw(list)
- Xstruct options **list;
- X{
- X Textsw save = pager_textsw;
- X
- X if (list == &aliases)
- X pager_textsw = alias_list_textsw;
- X else if (list == &ignore_hdr)
- X pager_textsw = ignore_list_textsw;
- X else
- X /* no textsw for this guy yet */
- X return;
- X
- X if (pager_textsw && !!window_get(pager_textsw, WIN_SHOW))
- X (void) do_set(*list, NULL);
- X pager_textsw = save;
- X}
- X
- Xstatic void
- Xalias_done()
- X{
- X window_destroy(alias_frame);
- X alias_frame = (Frame) 0;
- X}
- X
- Xvoid
- Xdo_aliases()
- X{
- X Panel panel;
- X
- X if (alias_frame) {
- X window_set(alias_frame, WIN_SHOW, TRUE, NULL);
- X return;
- X }
- X#ifdef SUN_3_5
- X if (nopenfiles(0) < 5) {
- X print("Too many frames; close one first!\n");
- X return;
- X }
- X#endif /* SUN_3_5 */
- X
- X alias_frame = window_create(tool, FRAME,
- X FRAME_SHOW_LABEL, TRUE,
- X FRAME_LABEL, "Mail Aliases",
- X FRAME_NO_CONFIRM, TRUE,
- X FRAME_DONE_PROC, alias_done,
- X WIN_SHOW, TRUE,
- X WIN_WIDTH, MY_FRAME_WIDTH,
- X NULL);
- X
- X panel = window_create(alias_frame, PANEL,
- X PANEL_WIDTH, MY_FRAME_WIDTH,
- X NULL);
- X notify_interpose_event_func(panel, fkey_interposer, NOTIFY_SAFE);
- X
- X panel_create_item(panel, PANEL_BUTTON,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Help", 4, mush_font),
- X PANEL_CLIENT_DATA, "aliases",
- X PANEL_NOTIFY_PROC, frame_help,
- X NULL);
- X panel_create_item(panel, PANEL_BUTTON,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Set", 3, mush_font),
- X PANEL_NOTIFY_PROC, set_alias,
- X PANEL_CLIENT_DATA, TRUE,
- X NULL);
- X panel_create_item(panel, PANEL_BUTTON,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Unset", 5, mush_font),
- X PANEL_NOTIFY_PROC, set_alias,
- X PANEL_CLIENT_DATA, FALSE,
- X NULL);
- X
- X alias_msg = panel_create_item(panel, PANEL_MESSAGE,
- X PANEL_LABEL_STRING,
- X "Type name of alias and address list and select <set> or <unset>",
- X NULL);
- X
- X alias_name = panel_create_item(panel, PANEL_TEXT,
- X PANEL_LABEL_STRING, "Alias Name:",
- X PANEL_VALUE_DISPLAY_LENGTH, 60,
- X NULL);
- X alias_value = panel_create_item(panel, PANEL_TEXT,
- X PANEL_LABEL_STRING, "Alias Address(es):",
- X PANEL_VALUE_DISPLAY_LENGTH, 60,
- X NULL);
- X window_fit_height(panel);
- X
- X alias_list_textsw = window_create(alias_frame, TEXTSW,
- X WIN_BELOW, panel,
- X WIN_WIDTH, MY_FRAME_WIDTH,
- X WIN_HEIGHT, 15 * l_height(),
- X#ifdef SUN_4_0 /* SunOS 4.0+ */
- X TEXTSW_LINE_BREAK_ACTION, TEXTSW_WRAP_AT_WORD,
- X#else /* SUN_4_0 */
- X TEXTSW_LINE_BREAK_ACTION, TEXTSW_WRAP_AT_CHAR,
- X#endif /* SUN_4_0 */
- X NULL);
- X (void) notify_interpose_event_func(alias_list_textsw,
- X fkey_interposer, NOTIFY_SAFE);
- X
- X window_fit_height(alias_frame);
- X update_list_textsw(&aliases);
- X}
- X
- Xstatic void
- Xset_alias(item)
- XPanel_item item;
- X{
- X int argc, set_it = (int)panel_get(item, PANEL_CLIENT_DATA);
- X char buf[BUFSIZ], **argv, *name, *value;
- X
- X name = panel_get_value(alias_name);
- X if (!*name) {
- X panel_set(alias_msg, PANEL_LABEL_STRING, "Need an alias name.", NULL);
- X return;
- X }
- X if (any(name, " \t")) {
- X panel_set(alias_msg,
- X PANEL_LABEL_STRING, "Alias name may not contain spaces.",
- X NULL);
- X return;
- X }
- X if (set_it) {
- X value = panel_get_value(alias_value);
- X if (!*value) {
- X panel_set(alias_msg,
- X PANEL_LABEL_STRING, "Specify alias address(es).",
- X NULL);
- X return;
- X }
- X sprintf(buf, "alias %s %s", name, value);
- X } else
- X sprintf(buf, "unalias %s", name);
- X if (!(argv = mk_argv(buf, &argc, TRUE)) || do_alias(argc, argv) == -1)
- X panel_set(alias_msg,
- X PANEL_LABEL_STRING, "Couldn't set alias.",
- X NULL);
- X else
- X panel_set(alias_msg,
- X PANEL_LABEL_STRING, "",
- X NULL);
- X panel_set_value(alias_name, "");
- X panel_set_value(alias_value, "");
- X free_vec(argv);
- X}
- X
- X/* int cuz it's also the callback for the text item */
- Xstatic Panel_setting
- Xset_ignore(item)
- XPanel_item item;
- X{
- X int argc, set_it = (int)panel_get(item, PANEL_CLIENT_DATA);
- X char buf[BUFSIZ], *name, **argv;
- X
- X name = panel_get_value(ignore_name);
- X if (!*name) {
- X panel_set(ignore_msg, PANEL_LABEL_STRING, "Missing header name.", NULL);
- X return PANEL_NONE;
- X }
- X if (set_it)
- X sprintf(buf, "ignore %s", name);
- X else
- X sprintf(buf, "unignore %s", name);
- X /* set() will call update_list_textsw() */
- X if (!(argv = mk_argv(buf, &argc, TRUE)) || set(argc, argv, NULL) == -1)
- X panel_set(ignore_msg,
- X PANEL_LABEL_STRING, "Internal Error!?",
- X NULL);
- X else
- X panel_set(ignore_msg,
- X PANEL_LABEL_STRING, "",
- X NULL);
- X free_vec(argv);
- X panel_set_value(ignore_name, "");
- X return PANEL_NONE;
- X}
- X
- Xstatic void
- Xignore_done()
- X{
- X window_destroy(ignore_frame);
- X ignore_frame = (Frame) 0;
- X}
- X
- Xvoid
- Xdo_ignore()
- X{
- X Panel panel;
- X
- X if (ignore_frame) {
- X window_set(ignore_frame, WIN_SHOW, TRUE, NULL);
- X return;
- X }
- X#ifdef SUN_3_5
- X if (nopenfiles(0) < 5) {
- X print("Too many frames; close one first!\n");
- X return;
- X }
- X#endif /* SUN_3_5 */
- X
- X ignore_frame = window_create(tool, FRAME,
- X FRAME_SHOW_LABEL, TRUE,
- X FRAME_LABEL, "Ignored Headers",
- X FRAME_NO_CONFIRM, TRUE,
- X FRAME_DONE_PROC, ignore_done,
- X WIN_SHOW, TRUE,
- X WIN_WIDTH, MY_FRAME_WIDTH,
- X NULL);
- X
- X panel = window_create(ignore_frame, PANEL,
- X PANEL_WIDTH, MY_FRAME_WIDTH,
- X NULL);
- X (void) notify_interpose_event_func(panel, fkey_interposer, NOTIFY_SAFE);
- X (void) panel_create_item(panel, PANEL_BUTTON,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Help", 4, mush_font),
- X PANEL_NOTIFY_PROC, frame_help,
- X PANEL_CLIENT_DATA, "ignore",
- X NULL);
- X (void) panel_create_item(panel, PANEL_BUTTON,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Set", 3, mush_font),
- X PANEL_NOTIFY_PROC, set_ignore,
- X PANEL_CLIENT_DATA, TRUE,
- X NULL);
- X panel_create_item(panel, PANEL_BUTTON,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Unset", 5, mush_font),
- X PANEL_NOTIFY_PROC, set_ignore,
- X PANEL_CLIENT_DATA, FALSE,
- X NULL);
- X
- X ignore_msg = panel_create_item(panel, PANEL_MESSAGE,
- X PANEL_LABEL_STRING,
- X "Type name of header to ignore and then <set> or <unset>",
- X NULL);
- X
- X ignore_name = panel_create_item(panel, PANEL_TEXT,
- X PANEL_LABEL_STRING, "Ignored Header:",
- X PANEL_NOTIFY_PROC, set_ignore,
- X PANEL_CLIENT_DATA, 1,
- X PANEL_VALUE_DISPLAY_LENGTH, 60,
- X NULL);
- X window_fit_height(panel);
- X
- X ignore_list_textsw = window_create(ignore_frame, TEXTSW,
- X WIN_BELOW, panel,
- X WIN_WIDTH, MY_FRAME_WIDTH,
- X WIN_HEIGHT, 15 * l_height(),
- X#ifdef SUN_4_0 /* SunOS 4.0+ */
- X TEXTSW_LINE_BREAK_ACTION, TEXTSW_WRAP_AT_WORD,
- X#else /* SUN_4_0 */
- X TEXTSW_LINE_BREAK_ACTION, TEXTSW_WRAP_AT_CHAR,
- X#endif /* SUN_4_0 */
- X NULL);
- X (void) notify_interpose_event_func(ignore_list_textsw,
- X fkey_interposer, NOTIFY_SAFE);
- X
- X window_fit_height(ignore_frame);
- X update_list_textsw(&ignore_hdr);
- X}
- END_OF_FILE
- if test 7659 -ne `wc -c <'mush/misc_frame.c'`; then
- echo shar: \"'mush/misc_frame.c'\" unpacked with wrong size!
- fi
- # end of 'mush/misc_frame.c'
- fi
- if test -f 'mush/strings.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mush/strings.c'\"
- else
- echo shar: Extracting \"'mush/strings.c'\" \(9988 characters\)
- sed "s/^X//" >'mush/strings.c' <<'END_OF_FILE'
- X/* strings.c Copyright(1988) Dan Heller */
- X
- X#include "mush.h"
- X
- X/*
- X * reverse a string. Useful for uucp-style address comparisons.
- X */
- Xchar *
- Xreverse(s)
- Xchar s[];
- X{
- X int n = strlen(s), m;
- X char c;
- X
- X if (n < 1)
- X return 0;
- X if (n & 1)
- X n = n/2 + 1, m = n - 2;
- X else
- X n /= 2, m = n - 1;
- X for ( ; m >= 0; m--, n++)
- X c = s[n], s[n] = s[m], s[m] = c;
- X return s;
- X}
- X
- X/*
- X * lose the newline character, trailing whitespace, and return the end of p
- X * test for '\n' separately since some _ctype_[] arrays may not have the
- X * _S bit set for the newline character. see <ctype.h> for more info.
- X */
- Xchar *
- Xno_newln(p)
- Xregister char *p;
- X{
- X register char *p2 = p + strlen(p); /* point it to the null terminator */
- X
- X while (p2 > p && *--p2 == '\n' || isspace(*p2))
- X *p2 = 0; /* get rid of newline and trailing spaces */
- X return p2;
- X}
- X
- X/* find any character in s1 that's in s2; return pointer to char in s1. */
- Xchar *
- Xany(s1, s2)
- Xregister char *s1, *s2;
- X{
- X register char *p;
- X if (!s1 || !*s1 || !s2 || !*s2)
- X return NULL;
- X for( ; *s1; s1++) {
- X for(p = s2; *p; p++)
- X if (*p == *s1)
- X return s1;
- X }
- X return NULL;
- X}
- X
- X/* check two lists of strings each of which contain substrings.
- X * Each substring is delimited by any char in "delimiters"
- X * return true if any elements in list1 are on list2.
- X * thus:
- X * string1 = "foo, bar, baz"
- X * string2 = "foobar, baz, etc"
- X * delimiters = ", \t"
- X * example returns 1 because "baz" exists in both lists
- X * NOTE: case is ignored.
- X */
- Xchk_two_lists(list1, list2, delimiters)
- Xregister char *list1, *list2, *delimiters;
- X{
- X register char *p, c;
- X register int found = 0;
- X
- X if (!list1 || !list2)
- X return 0;
- X
- X if (p = any(list1, delimiters)) {
- X if (p > list1) {
- X c = *p; *p = 0;
- X /* Check list2 against the first word of list1.
- X * Swap places of list2 and list1 to step through list2.
- X */
- X found = chk_two_lists(list2, list1, delimiters);
- X *p = c;
- X }
- X if (found)
- X return 1;
- X for (p++; *p && index(delimiters, *p); p++)
- X ;
- X if (!*p)
- X return 0;
- X } else if (!any(list2, delimiters))
- X /* Do the trivial case of single words */
- X return !lcase_strncmp(list1, list2, -1);
- X else
- X p = list1;
- X
- X /* Either only list2 has delims or the first word of list1
- X * did not match anything in list2. Check list2 against the
- X * rest of list1. This could be more efficient by using a
- X * different function to avoid repeating the any() calls.
- X */
- X return chk_two_lists(list2, p, delimiters);
- X}
- X
- Xbzero(addr, size)
- Xregister char *addr;
- Xregister int size;
- X{
- X while (size-- > 0)
- X addr[size] = 0;
- X}
- X
- X/* do an atoi() on the string passed and return in "val" the decimal value.
- X * the function returns a pointer to the location in the string that is not
- X * a digit.
- X */
- Xchar *
- Xmy_atoi(p, val)
- Xregister char *p;
- Xregister int *val;
- X{
- X int positive = 1;
- X
- X if (!p)
- X return NULL;
- X *val = 0;
- X if (*p == '-')
- X positive = -1, p++;
- X while (isdigit(*p))
- X *val = (*val) * 10 + *p++ - '0';
- X *val *= positive;
- X return p;
- X}
- X
- X/* strcmp ignoring case */
- Xlcase_strncmp(str1, str2, n)
- Xregister char *str1, *str2;
- X{
- X while (*str1 && *str2 && --n != 0)
- X if (lower(*str1) != lower(*str2))
- X break;
- X else
- X str1++, str2++;
- X return lower(*str1) - lower(*str2);
- X}
- X
- X/* strcpy converting everything to lower case (arbitrary) to ignore cases */
- Xchar *
- Xlcase_strcpy(dst, src)
- Xregister char *dst, *src;
- X{
- X register char *s = dst;
- X
- X /* "lower" is a macro, don't increment its argument! */
- X while (*dst++ = lower(*src))
- X src++;
- X return s;
- X}
- X
- X/* this strcpy returns number of bytes copied */
- XStrcpy(dst, src)
- Xregister char *dst, *src;
- X{
- X register int n = 0;
- X if (!dst || !src)
- X return 0;
- X while (*dst++ = *src++)
- X n++;
- X return n;
- X}
- X
- Xchar *
- Xsavestr(s)
- Xregister char *s;
- X{
- X register char *p;
- X
- X if (!s)
- X s = "";
- X if (!(p = malloc((unsigned) (strlen(s) + 1)))) {
- X error("out of memory saving %s", s);
- X return NULL;
- X }
- X return strcpy(p, s);
- X}
- X
- X/* copy a vector of strings into one string -- return the end of the string */
- Xchar *
- Xargv_to_string(p, argv)
- Xregister char *p, **argv;
- X{
- X register int i;
- X register char *ptr = p;
- X
- X *p = 0;
- X if (!argv[0])
- X return "";
- X for (i = 0; argv[i]; i++)
- X ptr += strlen(sprintf(ptr, "%s ", argv[i]));
- X *--ptr = 0; /* get rid of the last space */
- X return ptr;
- X}
- X
- Xchar *
- Xitoa(n)
- X{
- X static char buf[10];
- X return sprintf(buf, "%d", n);
- X}
- X
- X/*
- X * There are two different kinds of sprintf() --those that return char * and
- X * those that return int. System-V returns int (the length of the resulting
- X * string). BSD has historically returned a pointer to the resulting string
- X * instead. Mush was originally written under BSD, so the usage has always
- X * been to assume the char * method. Because the system-v method is far more
- X * useful, mush should some day change to use that method, but until then,
- X * this routine was written to allow all the unix'es to appear the same to
- X * the programmer regardless of which sprintf is actually used. The "latest"
- X * version of 4.3BSD (as of Fall 1988) has changed its format to go from the
- X * historical BSD method to the sys-v method. It is no longer possible to
- X * simply #ifdef this routine for sys-v --it is now required to use this
- X * routine regardless of which sprintf is notice to your machine. However,
- X * if you know your system's sprintf returns a char *, you can remove the
- X * define in strings.h
- X */
- X#include <varargs.h>
- X/*VARARGS*/
- X/*ARGSUSED*/
- Xchar *
- XSprintf(va_alist)
- Xva_dcl
- X{
- X char *buf, *fmt;
- X va_list ap;
- X
- X va_start(ap);
- X buf = va_arg(ap, char *);
- X fmt = va_arg(ap, char *);
- X#ifdef VPRINTF
- X (void) vsprintf(buf, fmt, ap);
- X#else
- X {
- X FILE foo;
- X foo._cnt = BUFSIZ;
- X foo._base = foo._ptr = buf; /* may have to be cast (unsigned char *) */
- X foo._flag = _IOWRT+_IOSTRG;
- X (void) _doprnt(fmt, ap, &foo);
- X *foo._ptr = '\0'; /* plant terminating null character */
- X }
- X#endif /* VPRINTF */
- X va_end(ap);
- X return buf;
- X}
- X
- Xvoid
- Xprint_argv(argv)
- Xchar **argv;
- X{
- X while (*argv)
- X if (debug)
- X wprint("(%s) ", *argv++);
- X else
- X wprint("%s ", *argv++);
- X wprint("\n");
- X}
- X
- X/*
- X * putstring -- put a string into a file. Expand \t's into tabs and \n's
- X * into newlines. Append a \n and fflush(fp);
- X */
- Xvoid
- Xputstring(p, fp)
- Xregister char *p;
- Xregister FILE *fp;
- X{
- X for ( ; *p; ++p)
- X if (*p != '\\')
- X (void) fputc(*p, fp);
- X else
- X switch(*++p) {
- X case 'n': (void) fputc('\n', fp);
- X when 't': (void) fputc('\t', fp);
- X otherwise: (void) fputc(*p, fp);
- X }
- X (void) fputc('\n', fp);
- X (void) fflush(fp);
- X}
- X
- X#define chtoi(c) ((int)(c) - (int)'0')
- X
- X/* m_xlate(str) converts strings of chars which contain ascii representations
- X * of control characters appearing in str into the literal characters they
- X * represent. The usual curses-mode character expansions (\Cx -> control-x)
- X * are honored, as are most C escapes. Unrecognized portions are unchanged.
- X */
- Xchar *
- Xm_xlate (str)
- Xregister char *str;
- X{
- X register char *r, *s, *t;
- X int dv, nd;
- X
- X /*
- X * r will receive the new string, s will track the old one,
- X * and t will step through escape sequences
- X * This allows the translation to be done in place
- X */
- X r = s = str;
- X while (s && *s) {
- X if (*s == '\\') {
- X t = s + 1;
- X /*
- X * After each case below, t should point to the character
- X * following the escape sequence
- X */
- X switch(*t) {
- X case '\0' :
- X /*
- X * Hmmm ... a backslash followed by the string
- X * terminator. Copy the backslash ONLY.
- X */
- X *r++ = *s++;
- X break;
- X case '0' :
- X case '1' :
- X case '2' :
- X case '3' :
- X case '4' :
- X case '5' :
- X case '6' :
- X case '7' :
- X /*
- X * Convert up to 3 octal digits to their ascii value
- X */
- X dv = chtoi(*t++);
- X for (nd = 0; (isdigit(*t) && (nd < 2)); nd++)
- X if (chtoi(*t) < 8)
- X dv = (8 * dv) + chtoi(*t++);
- X else
- X break;
- X if (dv < 256 && dv > 0)
- X /* Valid octal number escaped */
- X *r++ = (char)dv;
- X else
- X /* Invalid octal number, so copy unchanged */
- X while (s < t)
- X *r++ = *s++;
- X break;
- X case 'b' :
- X *r++ = '\b';
- X t++;
- X break;
- X case 'C' :
- X t++;
- X if (*t == '?')
- X *r++ = '\177';
- X else if (*t == '~')
- X *r++ = '\036';
- X else if (*t == '/')
- X *r++ = '\037';
- X else if (isalpha(*t) || *t > '\132' && *t < '\140')
- X *r++ = *t & 037;
- X else
- X while (s <= t) *r++ = *s++;
- X t++;
- X break;
- X case 'E' :
- X *r++ = '\033';
- X t++;
- X break;
- X case 'f' :
- X *r++ = '\f';
- X t++;
- X break;
- X case 'n' :
- X *r++ = '\n';
- X t++;
- X break;
- X case 'r' :
- X *r++ = '\r';
- X t++;
- X break;
- X case 't' :
- X *r++ = '\t';
- X t++;
- X break;
- X case '\\' :
- X *r++ = *t++;
- X break;
- X default :
- X /*
- X * Not recognized, so copy both characters
- X */
- X *r++ = *s++;
- X *r++ = *s++;
- X break;
- X }
- X /*
- X * Now make sure s also points to the character after the
- X * escape sequence, by comparing to t
- X */
- X if (t > s)
- X s = t;
- X } else
- X *r++ = *s++;
- X }
- X *r = '\0';
- X return str;
- X}
- X
- X/*
- X * Convert control characters to ascii format (reverse effect of m_xlate()).
- X */
- Xchar *
- Xctrl_strcpy(s_out, s_in, bind_format)
- Xregister char *s_out, *s_in;
- X{
- X#if !defined(M_XENIX) || (defined(M_XENIX) && !defined(CURSES))
- X extern char *_unctrl[];
- X#endif /* !M_XENIX || M_XENIX && !CURSES */
- X char *start = s_out;
- X
- X for (; *s_in; s_in++)
- X if (*s_in == '\n')
- X *s_out++ = '\\', *s_out++ = 'n';
- X else if (*s_in == '\r')
- X *s_out++ = '\\', *s_out++ = 'r';
- X else if (*s_in == '\t')
- X *s_out++ = '\\', *s_out++ = 't';
- X else if (*s_in == ESC)
- X *s_out++ = '\\', *s_out++ = 'E';
- X else if (iscntrl(*s_in)) {
- X if (bind_format)
- X *s_out++ = '\\', *s_out++ = 'C';
- X else
- X *s_out++ = '^';
- X *s_out++ = _unctrl[*s_in][1];
- X } else
- X *s_out++ = *s_in;
- X *s_out = 0;
- X return start;
- X}
- END_OF_FILE
- if test 9988 -ne `wc -c <'mush/strings.c'`; then
- echo shar: \"'mush/strings.c'\" unpacked with wrong size!
- fi
- # end of 'mush/strings.c'
- fi
- echo shar: End of archive 17 \(of 19\).
- cp /dev/null ark17isdone
- 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
-
-
-