v14i034: Mail User's Shell, version 6.0, Part02/14
Rich Salz
rsalz at bbn.com
Thu Apr 14 10:21:33 AEST 1988
Submitted-by: island!argv at sun.com (Dan Heller)
Posting-number: Volume 14, Issue 34
Archive-name: mush6.0/part02
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 2 (of 14)."
# Contents: aliases.c expr.c folders.c hdr_panel.c hdr_procs.c print.c
# rite.c sort.c strings.c tool.c
# Wrapped by rsalz at fig.bbn.com on Wed Apr 13 20:04:42 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'aliases.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'aliases.c'\"
else
echo shar: Extracting \"'aliases.c'\" \(4558 characters\)
sed "s/^X//" >'aliases.c' <<'END_OF_FILE'
X/* (c) copyright @(#)aliases.c 2.4 10/15/86 (Dan Heller) */
X
X#include "mush.h"
X
X/*
X * do_alias handles aliases, header settings, functions, and fkeys.
X * since they're all handled in the same manner, the same routine is
X * used. argv[0] determines which to use.
X * alias is given here as an example
X *
X * alias identify all aliases
X * alias name identify alias
X * alias name arg1 arg2 arg3... -> name="arg1 arg2 arg3"; call set_option
X * unalias arg1 [arg2 arg3 ... ] unalias args
X *
X * same is true for dealing with your own headers.
X * (also the expand command)
X * always return -1 since it nas no effect on messages
X */
do_alias(argc, argv)
register char **argv;
X{
X register char *cmd = *argv, *p;
X struct options **list;
X char firstchar = *cmd, buf[BUFSIZ];
X
X if (argc == 0)
X return -1;
X if (firstchar == 'u')
X firstchar = cmd[2];
X if (*++argv && !strcmp(*argv, "-?")) { /* doesn't apply for fkeys */
X register char *help_str;
X if (firstchar == 'a' || firstchar == 'e')
X help_str = "alias";
X else if (firstchar == 'c')
X help_str = "func_help";
X else if (firstchar == 'f')
X help_str = "fkey_help";
X else
X help_str = "own_hdrs";
X return help(0, help_str, cmd_help);
X }
X
X if (firstchar == 'a')
X list = &aliases;
X else if (firstchar == 'c')
X list = &functions;
X else if (firstchar == 'f')
X list = &fkeys;
X else
X list = &own_hdrs;
X
X if (*cmd == 'u') {
X if (!*argv)
X print("%s what?\n", cmd);
X /* unset a list separated by spaces or ',' */
X else while (*argv) {
X if (!strcmp(*argv, "*")) /* unset everything */
X while (*list)
X (void) un_set(list, (*list)->option);
X else if (!un_set(list, *argv))
X print("\"%s\" isn't set\n", *argv);
X argv++;
X }
X return -1;
X }
X
X if (!*argv && *cmd != 'e') {
X /* just type out all the aliases or own_hdrs */
X (void) do_set(*list, NULL);
X return -1;
X }
X
X if (*cmd == 'e') { /* command was "expand" (aliases only) */
X if (!*argv)
X print("expand which alias?\n");
X else
X do {
X print("%s: ", *argv);
X if (p = alias_to_address(*argv))
X print("%s\n", p);
X } while (*++argv);
X return -1;
X }
X
X /* at this point, *argv now points to a variable name ...
X * check for hdr -- if so, *argv better end with a ':' (check *p)
X */
X if (list == &own_hdrs && !(p = index(*argv, ':'))) {
X print("header labels must end with a ':' (%s)\n", *argv);
X return -1;
X }
X if (!argv[1] && !index(*argv, '='))
X if (p = do_set(*list, *argv))
X print("%s\n", p);
X else
X print("%s is not set\n", *argv);
X else {
X char *tmpargv[2];
X (void) argv_to_string(buf, argv);
X if ((p = any(buf, " \t=")) && *p != '=')
X *p = '=';
X /* if we're setting an alias, enforce the insertion of commas
X * between each well-formed address.
X */
X if (list == &aliases)
X fix_up_addr(p+1);
X tmpargv[0] = buf;
X tmpargv[1] = NULL;
X (void) add_option(list, tmpargv);
X }
X return -1;
X}
X
X/* takes string 's' which can be a name or list of names separated by
X * commas and checks to see if each is aliased to something else.
X * return address of the static buf.
X */
char *
alias_to_address(s)
register char *s;
X{
X static char buf[BUFSIZ];
X register char *p, *p2, *tmp;
X char newbuf[BUFSIZ], c;
X static int recursive;
X
X if (!aliases)
X return strcpy(buf, s);
X if (!s || !*s) {
X print("No recipeints!?!\n");
X return NULL;
X }
X if (!recursive) {
X bzero(buf, BUFSIZ);
X p2 = buf; /* if we're starting all this, p2 starts at &buf[0] */
X } else
X p2 = buf+strlen(buf); /* else, pick up where we left off */
X
X if (++recursive == 30) {
X print("alias references too many addresses!\n");
X recursive = 0;
X return NULL;
X }
X do {
X if (!(p = get_name_n_addr(s, NULL, NULL)))
X break;
X c = *p, *p = 0;
X
X /* if this is an alias, recurse this routine to expand it out */
X if ((tmp = do_set(aliases, s)) && *tmp) {
X if (!alias_to_address(strcpy(newbuf, tmp))) {
X *p = c;
X return NULL;
X } else
X p2 = buf+strlen(buf);
X /* Now, make sure the buffer doesn't overflow */
X } else if (strlen(s) + (p2-buf) + 2 > BUFSIZ) { /* add " " + NULL */
X print("address length too long.\n");
X recursive = 0;
X *p = c;
X return NULL;
X } else {
X /* append the new alias (or unchanged address) onto the buffer */
X p2 += Strcpy(p2, s);
X *p2++ = ',', *p2++ = ' ';
X }
X for (*p = c; *p == ',' || isspace(*p); p++)
X ;
X } while (*(s = p));
X if (recursive)
X recursive--;
X if (!recursive)
X *(p2-2) = 0; /* get rid of last ", " if end of recursion */
X return buf;
X}
END_OF_FILE
if test 4558 -ne `wc -c <'aliases.c'`; then
echo shar: \"'aliases.c'\" unpacked with wrong size!
fi
# end of 'aliases.c'
fi
if test -f 'expr.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'expr.c'\"
else
echo shar: Extracting \"'expr.c'\" \(4061 characters\)
sed "s/^X//" >'expr.c' <<'END_OF_FILE'
X/* @(#)expr.c 2.3 (c) copyright 10/15/86 (Dan Heller) */
X
X#include "mush.h"
X
char *eval_expr();
X
X/* Parse a string (p) to interpret numbers and ranges of numbers (n-m)
X * delimited by whitespace or comma's. Set msg_list bitfields using
X * macros in mush.h.
X * Return the address of the end of whatever we parsed (in case there's
X * more that the calling routine cares to deal with).
X * Finally, remember that user specifies one more than actual message number
X */
char *
do_range(p, list1)
register char *p, *list1;
X{
X register int num1 = -1, num2 = -1, except = 0;
X register char *p2;
X char list2[MAXMSGS_BITS];
X
X if (!p)
X return "";
X while (*p) {
X if (isdigit(*p) || *p == '$' || *p == '.' || *p == '^') {
X if (isdigit(*p)) {
X char c;
X p2 = p;
X skipdigits(0); /* find the end of the digits */
X c = *p, *p = 0; /* temporarily plug a null */
X if (!(num2 = chk_msg(p2))) {
X clear_msg_list(list1);
X return NULL;
X }
X *p = c;
X } else if (*p == '$')
X p++, num2 = msg_cnt;
X else if (*p == '.')
X p++, num2 = current_msg+1;
X else if (*p == '^')
X p++, num2 = 1;
X if (except)
X unset_msg_bit(list1, num2-1);
X else
X set_msg_bit(list1, num2-1);
X if (num1 >= 0) {
X if (num1 > num2) {
X print("syntax error: range sequence order reversed.\n");
X clear_msg_list(list1);
X return NULL;
X }
X while (++num1 < num2)
X if (except)
X unset_msg_bit(list1, num1-1);
X else
X set_msg_bit(list1, num1-1);
X num1 = num2 = -1;
X }
X }
X /* expressions to evaluate start with a `
X * p2 points to first char passed the last char parsed.
X */
X if (*p == '`') {
X clear_msg_list(list2);
X if (!(p = eval_expr(p, list2))) {
X clear_msg_list(list1);
X return NULL;
X } else {
X if (except)
X bitput(list2, list1, msg_cnt, &=~) /* MACRO */
X else
X bitput(list2, list1, msg_cnt, |=) /* MACRO */
X }
X }
X /* NOT operator: `* {5}' (everything except for 5)
X * `4-16 {8-10}' (4 thru 16 except for 8,9,10)
X */
X if (*p == '{' || *p == '}') {
X if (*p == '{' && (except || num1 >= 0))
X break;
X if (*p == '}' && !except) {
X print("syntax error: missing {\n"); /* } */
X break;
X }
X except = !except;
X } else if (*p == '-')
X if (num1 >= 0 || !index(" \t{},.*`$", *(p+1)) && !isdigit(*(p+1)))
X break;
X else
X num1 = num2;
X else if (*p == ',' || *p == '*') {
X if (num1 >= 0)
X break;
X else if (*p == '*') {
X if (except)
X clear_msg_list(list1);
X else
X for (num1 = 0; num1 < msg_cnt; num1++)
X set_msg_bit(list1, num1);
X num1 = -1;
X }
X } else if (!index(" \t`", *p))
X break;
X if (*p)
X skipspaces(1); /* don't make user type stuff squished together */
X }
X if (num1 >= 0 || except) {
X if (except)
X /* { */ print("syntax error: unmatched }\n");
X else
X print("syntax error: unfinished range\n");
X clear_msg_list(list1);
X return NULL;
X }
X return p;
X}
X
X/* evaluate expressions:
X * mail> delete `pick -f root` deletes all messages from root.
X * mail> save { `pick -s "Re:"` } save all message that don't have "Re:"
X * in the subject header.
X * mail> save `pick -x -s "Re:"` same
X * args as follows:
X * p should point to the first ` -- check for it.
X * on tells whether to turn bits on or off if messages match.
X */
char *
eval_expr(p, new_list)
register char *p, new_list[];
X{
X register char *p2, **argv;
X int argc;
X u_long save_flags = glob_flags;
X
X if (!(p2 = index(++p, '`'))) {
X print("unmatched backquote (`)\n");
X return NULL;
X }
X *p2 = 0;
X
X skipspaces(0);
X if (!*p) {
X print("Invalid null command\n");
X return NULL;
X }
X turnon(glob_flags, DO_PIPE);
X /* ignore sigs only because if user interrupts the do_command,
X * the long jump will corrupt the stack and the program is hosed.
X * fix is to have layers of jumpbuf's to return to different levels.
X */
X turnon(glob_flags, IGN_SIGS);
X if (*p && (argv = make_command(p, TRPL_NULL, &argc)))
X (void) do_command(argc, argv, new_list);
X glob_flags = save_flags;
X *p2 = '`';
X return p2+1;
X}
END_OF_FILE
if test 4061 -ne `wc -c <'expr.c'`; then
echo shar: \"'expr.c'\" unpacked with wrong size!
fi
# end of 'expr.c'
fi
if test -f 'folders.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'folders.c'\"
else
echo shar: Extracting \"'folders.c'\" \(5662 characters\)
sed "s/^X//" >'folders.c' <<'END_OF_FILE'
X/* @(#)folders.c (c) copyright 10/18/86 (Dan Heller) */
X
X#include "mush.h"
X
X/* folder %[user] --new mailfile is the spool/mail/login file [user].
X * folder # --new mailfile is the folder previous to the current folder
X * folder & --new mailfile is ~/mbox (or whatever "mbox" is set to)
X * folder +file --new mailfile is in the directory "folder"; name is 'file'
X * folder "path" --full path name or the one in current working directory.
X *
X * in all cases, changes are updated unless a '!' is specified after the
X * folder command (e.g. "f!", "folder !" "fo!" .. all permutations)
X * as usual, if new mail has arrived before the file is copied back, then
X * user will be notified beforehand.
X *
X * RETURN -1 on error -- else return 0. All bits in msg_list are set to true.
X */
folder(argc, argv, list)
register char **argv, list[];
X{
X int n, updating = !strcmp(*argv, "update"), do_read_only = 0, no_hdrs = 0;
X static char oldfolder[MAXPATHLEN];
X char *tmp, *newfolder = NULL, buf[MAXPATHLEN];
X struct stat statbuf;
X
X if (ison(glob_flags, DO_PIPE)) {
X print("You can't pipe to the folder command.\n");
X return -1;
X }
X while (*++argv && (**argv == '-' || **argv == '!'))
X if (!strcmp(*argv, "-?"))
X return help(0, "folder_help", cmd_help);
X else if (!strcmp(*argv, "-N"))
X no_hdrs = 1;
X else if (!strcmp(*argv, "-r"))
X do_read_only = 1;
X else if (!strcmp(*argv, "!"))
X turnoff(glob_flags, DO_UPDATE);
X
X if (updating) {
X (void) strcpy(buf, mailfile);
X if (ison(glob_flags, READ_ONLY))
X do_read_only = 1;
X } else {
X if (!*argv) {
X mail_status(0);
X return 0;
X }
X if (!strcmp(*argv, "#"))
X if (!*oldfolder) {
X print("No previous folder\n");
X return -1;
X } else
X newfolder = oldfolder;
X else if (!strcmp(*argv, "&")) {
X if (!(newfolder = do_set(set_options, "mbox")) || !*newfolder)
X newfolder = DEF_MBOX;
X } else
X newfolder = *argv;
X n = 0;
X tmp = getpath(newfolder, &n);
X if (n == -1) {
X print("%s: %s\n", newfolder, tmp);
X return -1;
X } else if (n == 1) {
X print("%s: is a directory\n", tmp);
X return -1;
X }
X /* strcpy so copyback() below (which calls getpath) doesn't change
X * the data that tmp intended to point to.
X */
X (void) strcpy(buf, tmp);
X }
X if (stat(buf, &statbuf) == -1 || !(statbuf.st_mode & 0400)) {
X error("Unable to read %s", buf);
X return -1;
X }
X /* If the file can't be opened for writing, autoset READ_ONLY */
X if (!(statbuf.st_mode & 0200))
X do_read_only = 1;
X#ifdef SUNTOOL
X if (istool) lock_cursors();
X#endif /* SUNTOOL */
X if (ison(glob_flags, DO_UPDATE) && !copyback()) {
X#ifdef SUNTOOL
X if (istool) unlock_cursors();
X#endif /* SUNTOOL */
X /* could be an error, but new mail probably came in */
X return -1;
X }
X if (!updating)
X (void) strcpy(oldfolder, mailfile);
X strdup(mailfile, buf);
X do_read_only? turnon(glob_flags,READ_ONLY) : turnoff(glob_flags,READ_ONLY);
X last_size = spool_size = 0L;
X msg_cnt = 0;
X turnoff(glob_flags, CONT_PRNT);
X
X turnon(glob_flags, IGN_SIGS);
X /* clear the tempfile */
X fclose(tmpf);
X if (!do_read_only) {
X if (!(tmpf = fopen(tempfile, "w"))) {
X error("error truncating %s", tempfile);
X turnoff(glob_flags, IGN_SIGS);
X return -1;
X }
X } else if (!(tmpf = fopen(mailfile, "r"))) {
X error(mailfile);
X return -1;
X }
X getmail();
X last_msg_cnt = msg_cnt; /* for check_new_mail */
X (void) mail_size();
X#ifdef SUNTOOL
X if (istool) {
X panel_set(next_scr, PANEL_SHOW_ITEM, FALSE, 0);
X panel_set(prev_scr, PANEL_SHOW_ITEM, FALSE, 0);
X pw_rop(hdr_win, 0,0, hdr_rect.r_width, hdr_rect.r_height,PIX_CLR,0,0,0);
X if (!msg_cnt) {
X add_folder_to_menu(folder_item, 3);
X add_folder_to_menu(save_item, 1);
X }
X }
X#endif /* SUNTOOL */
X current_msg = 0;
X turnoff(glob_flags, IGN_SIGS);
X
X /* now sort messages according a user_defined default */
X if (!updating && msg_cnt > 1 && !strcmp(mailfile, spoolfile) &&
X (tmp = do_set(set_options, "sort"))) {
X (void) sprintf(buf, "sort %s", tmp);
X if (argv = make_command(buf, TRPL_NULL, &argc)) {
X /* msg_list can't be null for do_command and since we're not
X * interested in the result, call sort directly
X */
X (void) sort(argc, argv, NULL);
X free_vec(argv);
X }
X }
X turnoff(glob_flags, DO_UPDATE);
X
X /* go to first NEW message */
X while (current_msg < msg_cnt && ison(msg[current_msg].m_flags, OLD))
X current_msg++;
X if (current_msg == msg_cnt)
X /* no new message found -- try first unread message */
X for (current_msg = 0;
X current_msg < msg_cnt && isoff(msg[current_msg].m_flags, UNREAD);
X current_msg++)
X ;
X if (current_msg == msg_cnt)
X current_msg = 0;
X
X if ((!istool || istool && !msg_cnt) && !iscurses)
X mail_status(0);
X /* be quite if we're piping */
X if ((istool || !updating) && isoff(glob_flags, IS_PIPE) &&
X (istool || !no_hdrs) && msg_cnt)
X (void) cmd_line(sprintf(buf, "headers %d", current_msg+1), msg_list);
X#ifdef SUNTOOL
X if (istool) {
X if (!msg_cnt)
X print("No Mail in %s\n", mailfile);
X if (!getting_opts)
X if (msg_cnt && isoff(glob_flags, IS_GETTING))
X display_msg(current_msg, (long)0);
X else
X do_clear();
X unlock_cursors();
X }
X#endif /* SUNTOOL */
X if (list) {
X clear_msg_list(list);
X bitput(list, list, msg_cnt, =~) /* macro */
X }
X return 0;
X}
X
folders(argc, argv)
register char **argv;
X{
X register char *p;
X char buf[128], unused[MAXMSGS_BITS];
X
X if (!(p = do_set(set_options, "folder")) || !*p)
X p = DEF_FOLDER;
X (void) sprintf(buf, "ls %s", p);
X if (argv = make_command(buf, TRPL_NULL, &argc))
X (void) do_command(argc, argv, unused);
X return -1;
X}
END_OF_FILE
if test 5662 -ne `wc -c <'folders.c'`; then
echo shar: \"'folders.c'\" unpacked with wrong size!
fi
# end of 'folders.c'
fi
if test -f 'hdr_panel.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'hdr_panel.c'\"
else
echo shar: Extracting \"'hdr_panel.c'\" \(4107 characters\)
sed "s/^X//" >'hdr_panel.c' <<'END_OF_FILE'
X/* @(#)hdr_panel.c (c) copyright 10/18/86 (Dan Heller) */
X
X#include "mush.h"
X
make_hdr_panel(choice_args, button_args)
char **choice_args, **button_args;
X{
X hdr_panel_sw = panel_create(tool,
X PANEL_HEIGHT, 30,
X 0);
X hdr_panel = (Panel)hdr_panel_sw->ts_data;
X
X msg_num_item = panel_create_item(hdr_panel, PANEL_TEXT,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_ITEM_X, 4,
X PANEL_ITEM_Y, 4,
X PANEL_LABEL_STRING, "Range:",
X PANEL_MENU_CHOICE_STRINGS, "Help", 0,
X PANEL_VALUE_DISPLAY_LENGTH, 10,
X PANEL_VALUE_STORED_LENGTH, 80,
X PANEL_LABEL_FONT, fonts[DEFAULT],
X PANEL_NOTIFY_STRING, "\n\r",
X PANEL_NOTIFY_PROC, msg_num_done,
X 0);
X
X sub_hdr_item[0] = panel_create_item(hdr_panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_ITEM_X, 149,
X PANEL_ITEM_Y, 4,
X PANEL_LABEL_IMAGE, &mouse_left,
X PANEL_CHOICE_STRINGS, "Help", 0,
X PANEL_NOTIFY_PROC, read_mail,
X 0);
X sub_hdr_item[1] = panel_create_item(hdr_panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_ITEM_X, 174,
X PANEL_ITEM_Y, 4,
X PANEL_LABEL_STRING, "Read ",
X PANEL_MENU_TITLE_IMAGE, &mouse_left,
X PANEL_CHOICE_STRINGS, "Help", 0,
X PANEL_NOTIFY_PROC, read_mail,
X 0);
X sub_hdr_item[2] = panel_create_item(hdr_panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_ITEM_X, 223,
X PANEL_ITEM_Y, 4,
X PANEL_LABEL_IMAGE, &mouse_middle,
X PANEL_CHOICE_STRINGS, "Help", 0,
X PANEL_NOTIFY_PROC, delete_mail,
X 0);
X sub_hdr_item[3] = panel_create_item(hdr_panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_ITEM_X, 248,
X PANEL_ITEM_Y, 4,
X PANEL_LABEL_STRING, "Delete ",
X PANEL_MENU_TITLE_IMAGE, &mouse_middle,
X PANEL_CHOICE_STRINGS, "Help", 0,
X PANEL_NOTIFY_PROC, delete_mail,
X 0);
X sub_hdr_item[4] = panel_create_item(hdr_panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_ITEM_X, 313,
X PANEL_ITEM_Y, 4,
X PANEL_LABEL_IMAGE, &mouse_right,
X PANEL_CHOICE_STRINGS, "Help", 0,
X PANEL_NOTIFY_PROC, read_mail,
X 0);
X sub_hdr_item[5] = panel_create_item(hdr_panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_ITEM_X, 338,
X PANEL_ITEM_Y, 4,
X PANEL_LABEL_STRING, "Menu ",
X PANEL_MENU_TITLE_IMAGE, &mouse_right,
X PANEL_CHOICE_STRINGS, "Help", 0,
X PANEL_NOTIFY_PROC, read_mail,
X 0);
X
X hdr_display = panel_create_item(hdr_panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_ITEM_X, 387,
X PANEL_ITEM_Y, 4,
X PANEL_LABEL_IMAGE,
X panel_button_image(hdr_panel, "Display", 7, fonts[DEFAULT]),
X PANEL_MENU_TITLE_STRING, "Header Display Formats",
X PANEL_CHOICE_STRINGS, "Show Deleted Messages",
X "Don't Show Deleted Messages",
X "Current Header in Bold Text",
X "Current Header in Reverse Text",
X "Help",
X 0,
X PANEL_NOTIFY_PROC, display_hdrs,
X 0);
X
X ignore_item = panel_create_item(hdr_panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_ITEM_X, 464,
X PANEL_ITEM_Y, 4,
X PANEL_LABEL_IMAGE,
X panel_button_image(hdr_panel, "Headers", 7, fonts[DEFAULT]),
X PANEL_MENU_TITLE_STRING, "Ignored Headers",
X PANEL_CHOICE_STRINGS, "Current Settings",
X "Add Values",
X "Delete Values",
X "Help",
X 0,
X PANEL_NOTIFY_PROC, p_set_opts,
X 0);
X
X next_scr = panel_create_item(hdr_panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_ITEM_X, 541,
X PANEL_ITEM_Y, 4,
X PANEL_LABEL_IMAGE,
X panel_button_image(hdr_panel, "Next", 4, fonts[DEFAULT]),
X PANEL_MENU_TITLE_STRING, "Display Message Headers",
X PANEL_CHOICE_STRINGS, "Show Next screenful",
X "Show Previous screenful",
X 0,
X PANEL_SHOW_ITEM, FALSE,
X PANEL_NOTIFY_PROC, do_hdr,
X 0);
X
X prev_scr = panel_create_item(hdr_panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_ITEM_X, 594,
X PANEL_ITEM_Y, 4,
X PANEL_LABEL_IMAGE,
X panel_button_image(hdr_panel, "Prev", 4, fonts[DEFAULT]),
X PANEL_MENU_TITLE_STRING, "Display Message Headers",
X PANEL_CHOICE_STRINGS, "Show Previous screenful",
X "Show Next screenful",
X 0,
X PANEL_SHOW_ITEM, FALSE,
X PANEL_NOTIFY_PROC, do_hdr,
X 0);
X}
END_OF_FILE
if test 4107 -ne `wc -c <'hdr_panel.c'`; then
echo shar: \"'hdr_panel.c'\" unpacked with wrong size!
fi
# end of 'hdr_panel.c'
fi
if test -f 'hdr_procs.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'hdr_procs.c'\"
else
echo shar: Extracting \"'hdr_procs.c'\" \(4239 characters\)
sed "s/^X//" >'hdr_procs.c' <<'END_OF_FILE'
X/* @(#)hdr_procs.c (c) copyright 10/18/86 (Dan Heller) */
X
X/* hdr_procs.c -- panel item procedures for the message hdrs */
X#include "mush.h"
X
X/* which message headers are to be displayed */
do_hdr(foo, value, event)
Panel_item foo;
int value;
struct inputevent *event;
X{
X register char *argv[3];
X argv[2] = NULL;
X argv[0] = "headers";
X
X if (!msg_cnt) {
X print("No Mail.");
X return;
X }
X if (!value || event->ie_code == MS_LEFT)
X argv[1] = (foo == next_scr)? "+": "-";
X else
X argv[1] = (foo == next_scr)? "-": "+";
X
X panel_set(foo, PANEL_VALUE, 0, 0);
X (void) do_hdrs(2, argv, NULL);
X}
X
X/* alters display of the message headers */
display_hdrs(foo, value, event)
Panel_item foo;
int value;
struct inputevent *event;
X{
X int show_deleted = !!do_set(set_options, "show_deleted");
X
X if (event->ie_code != MS_LEFT) {
X switch(value) {
X case 0 : case 1: {
X char buf[25];
X show_deleted = !value;
X (void) cmd_line(sprintf(buf, "%sset show_deleted",
X (value == 0)? "" : "un"), msg_list);
X }
X when 2 :
X turnoff(glob_flags, REV_VIDEO);
X when 3 :
X turnon(glob_flags, REV_VIDEO);
X when 4:
X return help(hdr_panel_sw->ts_windowfd, "headers", tool_help);
X }
X (void) do_hdrs(0, DUBL_NULL, NULL);
X }
X print("%sShow Deleted headers, \"Current Message\" header in %s",
X (show_deleted)? NO_STRING: "Don't ",
X (ison(glob_flags, REV_VIDEO))? "reverse": "boldface");
X}
X
p_set_opts(item, value, event)
Panel_item item;
int value;
struct inputevent *event;
X{
X static char *p, *oldp;
X static char buf[8];
X u_long bang = ison(glob_flags, IGN_BANG);
X
X if (event->ie_code == MS_LEFT)
X value = 0;
X if (value && (value != 3 || value != 2)
X && panel_get(input_item, PANEL_SHOW_ITEM)) {
X print("Need value for %s first!", oldp);
X return;
X } else if (!value && ison(glob_flags, IS_GETTING)) {
X print("Finish editing letter first");
X return;
X } else if (item == option_item) {
X if (!value) /* first menu item */
X view_options();
X else if (value == 1)
X set_fkeys();
X else
X (void) help(panel_sw->ts_windowfd, "opts", tool_help);
X return;
X } else if (item == ignore_item)
X if (value == 3)
X return help(hdr_panel_sw->ts_windowfd, "ignore", tool_help);
X else
X oldp = p = strcpy(buf, "ignore");
X else if (item == alias_item)
X if (value == 3)
X return help(panel_sw->ts_windowfd, "aliases", tool_help);
X else
X oldp = p = strcpy(buf, "alias");
X if (value) {
X char tmp[30];
X (void) sprintf(tmp, "%set %s:", (value == 1)? "S": "Uns", p);
X panel_set(input_item,
X PANEL_LABEL_STRING, tmp,
X PANEL_MENU_CHOICE_STRINGS, "Abort", 0,
X PANEL_SHOW_ITEM, TRUE,
X 0);
X oldp = p;
X return;
X }
X panel_set(item, PANEL_VALUE, 0, 0);
X do_clear();
X pw_text(msg_win, l_width(DEFAULT), 15, PIX_SRC, fonts[LARGE], p);
X if (item != ignore_item)
X pw_text(msg_win, 30*l_width(DEFAULT),15,PIX_SRC,fonts[LARGE],"Values");
X turnon(glob_flags, IGN_BANG);
X (void) cmd_line(p, msg_list);
X if (!bang)
X turnoff(glob_flags, IGN_BANG);
X}
X
msg_num_done(item, event)
Panel_item item;
struct inputevent *event;
X{
X char buf[82];
X u_long bang = ison(glob_flags, IGN_BANG);
X register char *p;
X int n;
X
X if (event->ie_code != '\n' && event->ie_code != '\r')
X return help(hdr_panel_sw->ts_windowfd, "message range", tool_help);
X (void) sprintf(buf, "headers %s", (p = (char *)panel_get_value(item)));
X panel_set(item, PANEL_VALUE, NO_STRING, 0);
X if (!(n = chk_msg(p)))
X return;
X current_msg = --n;
X turnon(glob_flags, IGN_BANG);
X (void) cmd_line(buf, msg_list);
X if (!bang)
X turnoff(glob_flags, IGN_BANG);
X display_msg(n, (long)0);
X}
X
do_sort(item, value, event)
Panel_item item;
int value;
struct inputevent *event;
X{
X register char *argv[3];
X argv[0] = "sort";
X argv[2] = NULL;
X if (event->ie_code == MS_LEFT)
X argv[1] = do_set(set_options, "sort");
X else switch(value) {
X case 0: argv[1] = "d";
X when 1: argv[1] = "a";
X when 2: argv[1] = "s";
X when 3: argv[1] = "S";
X when 4: argv[1] = "R";
X when 5: help(hdr_panel_sw->ts_windowfd, "sort", tool_help);
X }
X if (value != 5) {
X (void) sort(2, argv, NULL);
X (void) do_hdrs(0, DUBL_NULL, NULL);
X }
X panel_set(item, PANEL_VALUE, 0, 0);
X}
END_OF_FILE
if test 4239 -ne `wc -c <'hdr_procs.c'`; then
echo shar: \"'hdr_procs.c'\" unpacked with wrong size!
fi
# end of 'hdr_procs.c'
fi
if test -f 'print.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'print.c'\"
else
echo shar: Extracting \"'print.c'\" \(4945 characters\)
sed "s/^X//" >'print.c' <<'END_OF_FILE'
X/* @(#)print.c 2.4 (c) copyright 10/15/86 (Dan Heller) */
X
X#include "mush.h"
X#include <varargs.h>
X
X/*ARGSUSED*/
X/*VARARGS1*/
void
error(fmt, arg1, arg2, arg3, arg4)
register char *fmt;
char *arg1, *arg2, *arg3, *arg4;
X{
X print(fmt, arg1, arg2, arg3, arg4);
X print_more(": %s\n", sys_errlist[errno]);
X}
X
X#if defined(SUNTOOL) || defined(CURSES)
X/*
X * print just like printf -- to a window, to curses, or to stdout. Use vprintf
X * if available. msgbuf is the buffer used to print into if necessary.
X * If you're running SUN3.2 or higher, the typecast (unsigned char *)msgbuf
X * (where indicated) otherwise, msgbuf is not typecast at all.
X * Also note same casting in wprint().
X */
X/*VARARGS1*/
void
print(fmt, va_alist)
register char *fmt;
va_dcl
X{
X static char msgbuf[BUFSIZ];
X va_list args;
X#ifndef VPRINTF
X FILE foo;
X#endif /* VPRINTF */
X static int x; /* position on line saved for continued prints */
X char *p; /* same type as struct file _ptr,_buf in stdio.h */
X
X va_start(args); /* have args point to the beginning of argument stack */
X
X#ifdef CURSES
X if (iscurses) {
X if (isoff(glob_flags, CONT_PRNT))
X move(LINES-1, x = 0), refresh();
X } else
X#endif /* CURSES */
X if (istool < 2) {
X#ifdef VPRINTF
X vprintf(fmt, args);
X#else /* VPRINTF */
X _doprnt(fmt, args, stdout);
X#endif /* VPRINTF */
X fflush(stdout);
X va_end(args);
X return;
X }
X#ifdef VPRINTF
X if (fmt)
X vsprintf(msgbuf, fmt, args); /* NULL in fmt reprints last msg */
X#else /* VPRINTF */
X foo._cnt = BUFSIZ;
X foo._base = foo._ptr = msgbuf; /* may have to be cast(unsigned char *) */
X foo._flag = _IOWRT+_IOSTRG;
X if (fmt) { /* passing NULL (not "") reprints last message */
X (void) _doprnt(fmt, args, &foo);
X *foo._ptr = '\0'; /* plant terminating null character */
X }
X#endif /* VPIRNTF */
X va_end(args);
X p = msgbuf;
X if (iscurses || istool)
X while (p = index(p, '\n'))
X *p = ' ';
X#ifdef CURSES
X if (iscurses) {
X p = msgbuf;
X for (;;) {
X int len = COLS-1-x; /* space remaining at till the eol */
X /* don't wrap the line! Just print it and refresh() */
X printw("%-.*s", len, p), clrtoeol(), refresh();
X /* if length(p) (remainder of msgbuf) doesn't wrap, break loop */
X if ((x += strlen(p)) < COLS-1)
X break;
X /* the next print will overwrite bottom line, so \n first */
X putchar('\n'), move(LINES-1, x = 0); /* reset x */
X /* move p forward the number of chars we were able to display */
X p += len;
X turnon(glob_flags, CNTD_CMD); /* display ...continue... prompt */
X }
X turnoff(glob_flags, CONT_PRNT);
X return;
X }
X#endif /* CURSES */
X#ifdef SUNTOOL
X if (isoff(glob_flags, CONT_PRNT))
X x = 5;
X turnoff(glob_flags, CONT_PRNT);
X pw_text(print_win, x, l_height(LARGE), PIX_SRC, fonts[LARGE], msgbuf);
X pw_text(print_win, x+1, l_height(LARGE), PIX_SRC|PIX_DST,
X fonts[LARGE], msgbuf);
X x += strlen(msgbuf) * l_width(LARGE);
X Clrtoeol(print_win, x, l_height(LARGE), LARGE);
X#endif /* SUNTOOL */
X}
X#endif /* SUNTOOL || CURSES */
X
X#ifdef SUNTOOL
X/*VARARGS*/
void
wprint(fmt, va_alist)
register char *fmt;
va_dcl
X{
X#ifndef VPRINTF
X FILE foo;
X#endif /* VPRINTF */
X char msgbuf[BUFSIZ]; /* we're not getting huge strings */
X va_list args;
X
X va_start(args);
X
X if (istool < 2) {
X#ifdef VPRINTF
X vprintf(fmt, args);
X#else /* VPRINTF */
X _doprnt(fmt, args, stdout);
X#endif /* VPRINTF */
X va_end(args);
X fflush(stdout);
X return;
X }
X if (!fmt)
X return;
X#ifdef VPRINTF
X vsprintf(msgbuf, fmt, args); /* NULL in fmt reprints last msg */
X#else /* VPRINTF */
X foo._cnt = BUFSIZ;
X foo._base = foo._ptr = msgbuf; /* may have to typecast (unsigned char *) */
X foo._flag = _IOWRT+_IOSTRG;
X _doprnt(fmt, args, &foo); /* format like printf into msgbuf via foo */
X *foo._ptr = '\0'; /* plant terminating null character */
X#endif /* VPRINTF */
X Addstr(msgbuf); /* addstr() will scroll if necessary */
X}
X
X/*
X * scroll the msg_win "lines"
X * if `lines' is negative (backwards scroll) msg_pix can't be NULL
X */
void
scroll_win(lines)
register int lines;
X{
X register int y = lines * l_height(curfont);
X if (txt.y + y < msg_rect.r_height)
X y = 0; /* temporary */
X txt.x = 5;
X
X if (msg_pix) {
X if (txt.y + y >= msg_pix->pr_size.y - 5)
X y = msg_pix->pr_size.y - txt.y;
X still_more += y; /* let scrolling know where we are */
X txt.y += y;
X pw_rop(msg_win, 0, 5,
X msg_rect.r_width, crt * l_height(curfont),
X PIX_SRC, msg_pix, 0, txt.y - msg_rect.r_height + 3);
X tool_more(NULL);
X return;
X }
X /* y must be positive (forward scrolling) so we're scrolling typed
X * text or something like that (~p, ~?, etc...)
X */
X pw_copy(msg_win, 0, 0,
X msg_rect.r_width, msg_rect.r_height - y,
X PIX_SRC, msg_win, 0, y);
X pw_writebackground(msg_win, 0, msg_rect.r_height - y,
X msg_rect.r_width, y, PIX_CLR);
X txt.y -= y;
X}
X#endif /* SUNTOOL */
X
clr_bot_line()
X{
X print("");
X}
END_OF_FILE
if test 4945 -ne `wc -c <'print.c'`; then
echo shar: \"'print.c'\" unpacked with wrong size!
fi
# end of 'print.c'
fi
if test -f 'rite.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'rite.c'\"
else
echo shar: Extracting \"'rite.c'\" \(4181 characters\)
sed "s/^X//" >'rite.c' <<'END_OF_FILE'
X/* rite.c (c) copyright 1986 (Dan Heller) */
X
X#include "mush.h"
X
X#define LASTLINE (msg_rect.r_height - l_height(LARGE)-5)
X
static char String[BUFSIZ];
static int count, overflow, save_orig_x;
X
char *
rite(c)
register char c;
X{
X static int literal_next;
X
X if (c == ltchars.t_lnextc || literal_next) {
X if (literal_next)
X Addch(c);
X else /* don't call Addch to prevent cursor from advancing */
X pw_char(msg_win, txt.x, txt.y, PIX_SRC, fonts[curfont], '^');
X literal_next = !literal_next;
X return NULL;
X }
X literal_next = 0;
X if (c == _tty.sg_erase || c == CTRL(127) || c == CTRL(H)) {
X if (count)
X backspace();
X } else if (c == _tty.sg_kill) {
X if (count) {
X Clrtoeol(msg_win, txt.x = save_orig_x, txt.y,curfont);
X overflow = count = String[0] = 0;
X }
X } else if (c == ltchars.t_werasc)
X while (count) {
X char c = String[count-1];
X backspace();
X if (!count ||
X isspace(String[count-1]) && !isspace(c) ||
X !isalnum(String[count-1]) && isalnum(c))
X break;
X }
X else if (c == '\n' || c == '\r' || c == 13) {
X String[count] = 0;
X if ((txt.y += l_height(curfont)) >= LASTLINE && !getting_opts)
X scroll_win(1);
X /* else Clrtoeol(msg_win, txt.x, txt.y, curfont); */
X overflow = count = 0, txt.x = 5;
X return String;
X } else if (c == 12)
X if (ison(glob_flags, IS_GETTING))
X Addch(c);
X else
X do_clear();
X else if (count == BUFSIZ-1)
X print("Text too long for String!"), count--;
X else if (c == '\t')
X do Addch(' ');
X while (count % 8 && count < BUFSIZ);
X else
X Addch(c);
X return NULL;
X}
X
static
backspace()
X{
X if (overflow) {
X pw_text(msg_win, save_orig_x, txt.y, PIX_SRC, fonts[curfont],
X &String[--overflow]);
X Clrtoeol(msg_win, msg_rect.r_width-10-l_width(curfont), txt.y, curfont);
X String[--count] = 0;
X } else if ((txt.x -= l_width(curfont)) >= 5) {
X if (iscntrl(String[count-1])) {
X pw_char(msg_win, txt.x, txt.y, PIX_SRC, fonts[curfont], ' ');
X txt.x -= l_width(curfont);
X }
X pw_char(msg_win, txt.x, txt.y, PIX_SRC, fonts[curfont], ' ');
X String[--count] = 0;
X } else
X txt.x = 5;
X}
X
static
Addch(c)
register char c;
X{
X extern char *_unctrl[];
X
X if (!count)
X save_orig_x = txt.x, bzero(String, BUFSIZ);
X if (c > 31 && c != 127)
X String[count++] = c;
X else {
X Addch('^'), count--;
X Addch(_unctrl[c][1]);
X String[count-1] = c;
X return;
X }
X pw_char(msg_win, txt.x, txt.y, PIX_SRC, fonts[curfont], c);
X if ((txt.x += l_width(curfont)) <= msg_rect.r_width-5-l_width(curfont))
X return;
X if (getting_opts) {
X pw_text(msg_win, save_orig_x, txt.y, PIX_SRC, fonts[curfont],
X &String[++overflow]);
X txt.x -= l_width(curfont);
X pw_char(msg_win, txt.x, txt.y, PIX_SRC, fonts[curfont], ' ');
X } else {
X txt.x = 5;
X if ((txt.y += l_height(curfont)) >= LASTLINE)
X scroll_win(1);
X }
X}
X
Addstr(s)
register char *s;
X{
X char buf[BUFSIZ];
X register int cnt = 0, max_len;
X register char *p = buf, newline = 0;
X
X max_len = (msg_rect.r_width - 10) / l_width(curfont) + 1;
X
X while ((*p = *s++) && *p != '\n' && cnt < max_len)
X if (*p == '\t')
X do *p++ = ' ';
X while (++cnt % 8);
X else p++, cnt++;
X *p = 0;
X
X if (*--s)
X newline = *s, *s = 0; /* newline may or may not be a '\n' */
X else
X s = 0;
X
X if (*buf) {
X if (msg_pix) {
X struct pr_prpos pixr;
X pixr.pr = msg_pix;
X pixr.pos = txt;
X pf_text(pixr, PIX_SRC, fonts[curfont], buf);
X } else
X pw_text(msg_win, txt.x, txt.y, PIX_SRC, fonts[curfont], buf);
X txt.x += cnt * l_width(curfont);
X }
X if (newline) {
X if (newline != '\n')
X *s = newline;
X if ((txt.y += l_height(curfont)) >= LASTLINE && !msg_pix)
X scroll_win(1);
X txt.x = 5;
X if (newline == '\n' && !*++s)
X return;
X Addstr(s);
X }
X}
X
tool_more(p)
register char *p;
X{
X int percent;
X /* we are typing -- scrool the window */
X if (!msg_pix) {
X scroll_win(1);
X return;
X }
X if (p)
X print(p);
X else {
X if ((percent = (still_more * 100) / msg_pix->pr_size.y) >= 100)
X print( "--End of Message %d--", current_msg+1);
X else
X print("--Message %d--(%d%%)", current_msg+1, percent);
X if (ison(glob_flags, IS_GETTING))
X print_more(" ('q' returns to type-in mode)");
X }
X}
END_OF_FILE
if test 4181 -ne `wc -c <'rite.c'`; then
echo shar: \"'rite.c'\" unpacked with wrong size!
fi
# end of 'rite.c'
fi
if test -f 'sort.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'sort.c'\"
else
echo shar: Extracting \"'sort.c'\" \(5560 characters\)
sed "s/^X//" >'sort.c' <<'END_OF_FILE'
X/* sort.c 2.0 (c) copyright 1986 (Dan Heller) */
X
X#include "mush.h"
X/* #define MYQSORT */
X
static int order, ignore_case;
static jmp_buf sortbuf;
X
sort(argc, argv, list)
register int argc;
register char *argv[], list[];
X{
X int status_cmp(), author_cmp(), date_cmp(), subject_cmp(), subj_with_re();
X int (*oldint)(), (*oldquit)();
X int (*how)() = status_cmp;
X int n, offset = -1, range = 0;
X
X order = 1, ignore_case = FALSE;
X
X while (argc && *++argv) {
X n = 0;
X while (argv[0][n])
X switch(argv[0][n++]) {
X case '-': order = -1;
X when 'd': how = date_cmp;
X when 'a': how = author_cmp;
X when 's': how = subject_cmp;
X when 'R': how = subj_with_re;
X when 'S': how = status_cmp;
X when 'i': ignore_case = TRUE;
X otherwise: return help(0, "sort_help", cmd_help);
X }
X }
X if (msg_cnt <= 1) {
X print("Not enough messages to sort.\n");
X return -1;
X }
X on_intr();
X
X if (list && ison(glob_flags, IS_PIPE)) {
X for (n = 0; n < msg_cnt; n++)
X if (msg_bit(list, n)) {
X if (offset < 0)
X offset = n;
X range++;
X } else if (offset >= 0)
X break;
X } else
X offset = 0, range = msg_cnt;
X
X if (range < 2)
X print("Range not broad enough to sort anything\n");
X else {
X Debug("Sorting %d messages starting at message %d\n", range, offset+1);
X
X if (setjmp(sortbuf) == 0)
X qsort((char *)&msg[offset], range, sizeof (struct msg), how);
X else
X print("WARNING: Sorting interrupted: unpredictable order.\n");
X turnon(glob_flags, DO_UPDATE);
X }
X off_intr();
X return -1;
X}
X
X#ifdef MYQSORT
qsort(base, len, siz, compar)
register struct msg *base;
int (*compar)();
X{
X register int i, swapping;
X struct msg temp;
X
X do {
X swapping = 0;
X for (i = 0; i < len-1; ++i) {
X if (compar(base+i, base+i+1) > 0) {
X temp = base[i];
X base[i] = base[i+1];
X base[i+1] = temp;
X swapping = 1;
X }
X }
X } while (swapping);
X}
X#endif /* MYSORT */
X
status_cmp(msg1, msg2)
register struct msg *msg1, *msg2;
X{
X if (ison(glob_flags, WAS_INTR))
X longjmp(sortbuf, 1);
X if (msg1 < msg || msg2 < msg) {
X wprint("sort botch trying to sort %d and %d\n", msg1-msg, msg2-msg);
X return 0;
X }
X if (msg1->m_flags == msg2->m_flags)
X return 0;
X if (ison(msg1->m_flags, DELETE) && isoff(msg2->m_flags, DELETE))
X return order;
X if (isoff(msg1->m_flags, DELETE) && ison(msg2->m_flags, DELETE))
X return -order;
X if (isoff(msg1->m_flags, OLD) && ison(msg2->m_flags, OLD))
X return -order;
X if (ison(msg1->m_flags, OLD) && isoff(msg2->m_flags, OLD))
X return order;
X if (ison(msg1->m_flags, UNREAD) && isoff(msg2->m_flags, UNREAD))
X return -order;
X if (isoff(msg1->m_flags, UNREAD) && ison(msg2->m_flags, UNREAD))
X return order;
X if (ison(msg1->m_flags,PRESERVE) && isoff(msg2->m_flags,PRESERVE))
X return -order;
X if (isoff(msg1->m_flags,PRESERVE) && ison(msg2->m_flags,PRESERVE))
X return order;
X if (ison(msg1->m_flags,REPLIED) && isoff(msg2->m_flags,REPLIED))
X return -order;
X if (isoff(msg1->m_flags,REPLIED) && ison(msg2->m_flags,REPLIED))
X return order;
X
X return order;
X}
X
author_cmp(msg1, msg2)
register struct msg *msg1, *msg2;
X{
X char buf1[BUFSIZ], buf2[BUFSIZ];
X
X if (ison(glob_flags, WAS_INTR))
X longjmp(sortbuf, 1);
X if (msg1 < msg || msg2 < msg) {
X wprint("sort botch trying to sort %d and %d\n", msg1-msg, msg2-msg);
X return 0;
X }
X (void) reply_to(msg1 - msg, 0, buf1); /* "0" for "author only" */
X (void) reply_to(msg2 - msg, 0, buf2);
X Debug("author: msg %d: %s, msg %d: %s\n", msg1-msg, buf1, msg2-msg, buf2);
X if (ignore_case)
X return lcase_strcmp(buf1, buf2) * order;
X return strcmp(buf1, buf2) * order;
X}
X
X/*
X * Subject comparison ignoring Re: subject_to() appends an Re: if there is
X * any subject whatsoever.
X */
subject_cmp(msg1, msg2)
register struct msg *msg1, *msg2;
X{
X char buf1[BUFSIZ], buf2[BUFSIZ];
X
X if (ison(glob_flags, WAS_INTR))
X longjmp(sortbuf, 1);
X if (msg1 < msg || msg2 < msg) {
X wprint("sort botch trying to sort %d and %d\n", msg1-msg, msg2-msg);
X return 0;
X }
X (void) subject_to(msg1 - msg, buf1);
X (void) subject_to(msg2 - msg, buf2);
X Debug("subjects: (%d): \"%s\" (%d): \"%s\"\n", msg1-msg,buf1,msg2-msg,buf2);
X if (ignore_case)
X return lcase_strcmp(buf1, buf2) * order;
X return strcmp(buf1, buf2) * order;
X}
X
X/*
X * compare subject strings from two messages.
X * If Re is appended, so be it -- if user wants to ignore Re: use 'R' flag.
X */
subj_with_re(msg1, msg2)
register struct msg *msg1, *msg2;
X{
X char buf1[BUFSIZ], buf2[BUFSIZ], *p;
X
X if (ison(glob_flags, WAS_INTR))
X longjmp(sortbuf, 1);
X if (msg1 < msg || msg2 < msg) {
X wprint("sort botch trying to sort %d and %d\n", msg1-msg, msg2-msg);
X return 0;
X }
X if (!(p = header_field(msg1 - msg, "subject")))
X p = "";
X (void) strcpy(buf1, p);
X if (!(p = header_field(msg2 - msg, "subject")))
X p = "";
X (void) strcpy(buf2, p);
X Debug("subjects: (%d): \"%s\" (%d): \"%s\"\n",
X msg1-msg, buf1, msg2-msg, buf2);
X if (ignore_case)
X return lcase_strcmp(buf1, buf2) * order;
X return strcmp(buf1, buf2) * order;
X}
X
date_cmp(msg1, msg2)
register struct msg *msg1, *msg2;
X{
X char buf1[11], buf2[11];
X
X if (ison(glob_flags, WAS_INTR))
X longjmp(sortbuf, 1);
X if (msg1 < msg || msg2 < msg) {
X wprint("sort botch trying to sort %d and %d\n", msg1-msg, msg2-msg);
X return 0;
X }
X (void) strcpy(buf1, msg_date(msg1-msg));
X (void) strcpy(buf2, msg_date(msg2-msg));
X Debug("dates: msg %d: %s, msg %d: %s\n", msg1-msg, buf1, msg2-msg, buf2);
X return strcmp(buf1, buf2) * order;
X}
END_OF_FILE
if test 5560 -ne `wc -c <'sort.c'`; then
echo shar: \"'sort.c'\" unpacked with wrong size!
fi
# end of 'sort.c'
fi
if test -f 'strings.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'strings.c'\"
else
echo shar: Extracting \"'strings.c'\" \(4729 characters\)
sed "s/^X//" >'strings.c' <<'END_OF_FILE'
X/* strings.c Copyrite(1988) Dan Heller */
X
X#include "mush.h"
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 */
char *
no_newln(p)
register 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 string2 that's in string1 */
char *
any(s1, s2)
register 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 "delimeters"
X * return true if any elements in list1 are on list2.
X * thus:
X * string1 = "foo, bar, baz"
X * string2 = "foobar, baz, etc"
X * delimeters = ", \t"
X * example returns 1 because "baz" exists in both lists
X * NOTE: case is ignored.
X */
chk_two_lists(list1, list2, delimeters)
register char *list1, *list2, *delimeters;
X{
X register char *p, c;
X register int found = 0;
X
X if (p = any(list1, delimeters)) {
X for (p++; *p && index(delimeters, *p); p++)
X ;
X if (chk_two_lists(p, list2, delimeters))
X return 1;
X }
X if (p = any(list2, delimeters)) {
X for (p++; *p && index(delimeters, *p); p++)
X ;
X if (chk_two_lists(list1, p, delimeters))
X return 1;
X }
X if (p) {
X while (index(delimeters, *(p-1)))
X --p;
X c = *p, *p = 0;
X }
X found = !lcase_strcmp(list1, list2);
X if (p)
X *p = c;
X return found;
X}
X
bzero(addr, size)
register char *addr;
register 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 */
char *
my_atoi(p, val)
register char *p;
register 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 */
lcase_strcmp(str1, str2)
register char *str1, *str2;
X{
X while (*str1 && *str2)
X if (lower(*str1) != lower(*str2))
X break;
X else
X str1++, str2++;
X return *str1 - *str2;
X}
X
X/* strcpy coverting everything to lower case (arbitrary) to ignore cases */
char *
lcase_strcpy(dst, src)
register char *dst, *src;
X{
X register char *s = dst;
X
X /* "lower" is a macro, don't incrment its argument! */
X while (*dst++ = lower(*src))
X src++;
X return s;
X}
X
X/* this strcpy returns number of bytes copied */
Strcpy(dst, src)
register 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
void
xfree(cp)
char *cp;
X{
X extern char end[];
X
X if (cp >= end && cp < (char *) &cp && debug < 5)
X free(cp);
X}
X
char *
savestr(s)
register char *s;
X{
X register char *p;
X char *malloc();
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
void
free_vec(argv)
char **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}
X
X/* copy a vector of stirngs into one string -- return the end of the string */
char *
argv_to_string(p, argv)
register 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
X/* echo the command line. return -1 cuz no messages are affected */
do_echo(argc, argv)
register char **argv;
X{
X char buf[BUFSIZ];
X int no_return;
X
X if (argc > 1 && !strcmp(argv[1], "-?")) {
X print("usage: %s [-n] ...\n", *argv);
X return -1;
X }
X no_return = *++argv && !strcmp(*argv, "-n");
X (void) argv_to_string(buf, argv+no_return);
X print("%s%s", buf, (no_return)? "" : "\n");
X return -1;
X}
X
char *
itoa(n)
X{
X static char buf[10];
X return sprintf(buf, "%d", n);
X}
X
X#ifdef SYSV
char *
Sprintf(buf, fmt, args)
register char *buf, *fmt;
X{
X vsprintf(buf, fmt, &args);
X return buf;
X}
X#endif /* SYSV */
X
print_argv(argv)
char **argv;
X{
X while (*argv)
X if (debug)
X printf("(%s) ", *argv++);
X else
X wprint("%s ", *argv++);
X if (debug) {
X putchar('\n');
X fflush(stdout);
X } else
X wprint("\n");
X}
END_OF_FILE
if test 4729 -ne `wc -c <'strings.c'`; then
echo shar: \"'strings.c'\" unpacked with wrong size!
fi
# end of 'strings.c'
fi
if test -f 'tool.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'tool.c'\"
else
echo shar: Extracting \"'tool.c'\" \(4177 characters\)
sed "s/^X//" >'tool.c' <<'END_OF_FILE'
X/* @(#)tool.c (c) copyright 10/15/86 (Dan Heller) */
X
X/* tool.c --make the mailtool windows, panels, etc... */
X#include "mush.h"
X
make_tool(args)
char **args;
X{
X struct stat rootbuf, tmpbuf;
X struct inputmask im;
X register unsigned i;
X char **choice_args, **button_args, *p;
X char buf1[WIN_NAMESIZE], buf2[WIN_NAMESIZE];
X
X getfonts();
X mail_icon.ic_font = fonts[DEFAULT];
X
X if (p = do_set(set_options, "screen_win"))
X screen = atoi(p);
X else
X screen = 6;
X
X /* where to place text on mail icon -- how many messages there are */
X rect_construct(&mail_icon.ic_textrect,
X l_width(DEFAULT), 58-l_height(DEFAULT),
X 3*l_width(DEFAULT), l_height(DEFAULT));
X
X if (!(tool = tool_make(
X WIN_ICON, &mail_icon,
X WIN_HEIGHT, 700,
X WIN_WIDTH, 650,
X WIN_BOUNDARY_MGR, 1,
X WIN_ATTR_LIST, args,
X NULL)))
X perror(prog_name), cleanup(0);
X tool_free_attribute_list(args);
X
X choice_args = panel_make_list(
X PANEL_MENU_TITLE_FONT, fonts[LARGE],
X PANEL_DISPLAY_LEVEL, PANEL_NONE,
X PANEL_SHOW_MENU, TRUE,
X PANEL_SHOW_MENU_MARK, FALSE,
X 0);
X
X button_args = panel_make_list(
X PANEL_FEEDBACK, PANEL_INVERTED,
X PANEL_SHOW_MENU, FALSE,
X 0);
X
X make_hdr_panel(choice_args, button_args);
X
X if (!(hdr_sw = gfxsw_createtoolsubwindow(tool, "hdr_sw",
X TOOL_SWEXTENDTOEDGE, 10+ screen*l_height(DEFAULT), (char **)0)))
X perror("hdr_sw"), cleanup(0);
X gfxsw_getretained((struct gfxsubwindow *)hdr_sw->ts_data);
X hdr_win = ((struct gfxsubwindow *)(hdr_sw->ts_data))->gfx_pixwin;
X
X input_imnull(&im);
X win_setinputcodebit(&im, LOC_STILL);
X win_setinputcodebit(&im, LOC_MOVE);
X win_setinputcodebit(&im, LOC_WINENTER);
X for (i = VKEY_FIRSTFUNC; i <= VKEY_LASTFUNC; i++)
X win_setinputcodebit(&im, i);
X win_setinputmask(hdr_sw->ts_windowfd, &im, &im,
X win_fdtonumber(hdr_panel_sw->ts_windowfd));
X hdr_sw->ts_io.tio_selected = hdr_io;
X hdr_sw->ts_io.tio_handlesigwinch = hdrwin_handlesigwinch;
X
X make_main_panel(choice_args, button_args);
X xfree(choice_args), xfree(button_args);
X
X if (!(print_sw = gfxsw_createtoolsubwindow(tool, "print_sw",
X TOOL_SWEXTENDTOEDGE, l_height(LARGE) + 10, (char **)0)))
X perror("print_sw"), cleanup(0);
X print_win = ((struct gfxsubwindow *)(print_sw->ts_data))->gfx_pixwin;
X print_sw->ts_io.tio_handlesigwinch = print_sigwinch;
X
X /* text subwindow */
X if (!(msg_sw = gfxsw_createtoolsubwindow(tool, "msg_sw",
X TOOL_SWEXTENDTOEDGE, TOOL_SWEXTENDTOEDGE, (char **)0)))
X perror("msg_sw"), cleanup(0);
X gfxsw_getretained((struct gfxsubwindow *)msg_sw->ts_data);
X msg_win = ((struct gfxsubwindow *)(msg_sw->ts_data))->gfx_pixwin;
X
X /* everything we want the text window to pay attention to */
X input_imnull(&im);
X im.im_flags = IM_ASCII;
X im.im_flags &= ~IM_ANSI;
X for (i = VKEY_FIRSTFUNC; i <= VKEY_LASTFUNC; i++)
X win_setinputcodebit(&im, i);
X win_setinputmask(msg_sw->ts_windowfd, &im, &im, WIN_NULLLINK);
X msg_sw->ts_io.tio_selected = msg_io;
X msg_sw->ts_io.tio_handlesigwinch = msgwin_handlesigwinch;
X
X /* tty subwindow */
X if (!(tty_sw = ttytlsw_createtoolsubwindow(tool, "tty_sw",
X TOOL_SWEXTENDTOEDGE, 0, (char **)0)))
X perror("tty_sw"), cleanup(0);
X ttysw_handlesigwinch(tty_sw);
X win_setcursor(tty_sw->ts_windowfd, &write_cursor);
X
X (void) sprintf(blank, "%128c", ' ');
X (void) signal(SIGWINCH, sigwinchcatcher);
X (void) signal(SIGTERM, sigtermcatcher);
X (void) signal(SIGCHLD, sigchldcatcher);
X pw_writebackground(hdr_win, 0,0, hdr_rect.r_width, hdr_rect.r_height,
X PIX_CLR);
X if (ioctl(0, TIOCGETC, &tchars))
X perror("gtty failed"), cleanup(0);
X win_numbertoname (0, buf1);
X if ((rootfd = open(buf1, 0)) == -1)
X error("can't open %s", buf1), cleanup(0);
X if (fstat(rootfd, &rootbuf))
X error("can't stat %s", buf1), cleanup(0);
X for (parentfd = 3; parentfd < rootfd; parentfd++)
X if (fstat(parentfd, &tmpbuf))
X error("Can't stat fd-%d", parentfd);
X else if (tmpbuf.st_ino == rootbuf.st_ino) {
X (void) close(rootfd);
X rootfd = parentfd;
X break;
X }
X istool = 2;
X (void) do_version();
X lock_cursors();
X tool_install(tool);
X tool_display(tool);
X do_clear();
X}
END_OF_FILE
if test 4177 -ne `wc -c <'tool.c'`; then
echo shar: \"'tool.c'\" unpacked with wrong size!
fi
# end of 'tool.c'
fi
echo shar: End of archive 2 \(of 14\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 14 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
--
Please send comp.sources.unix-related mail to rsalz at uunet.uu.net.
More information about the Comp.sources.unix
mailing list