v18i076: mush - Mail User's Shell, Part19/22
Dan Heller
argv at zipcode.com
Tue Apr 23 01:37:18 AEST 1991
Submitted-by: Dan Heller <argv at zipcode.com>
Posting-number: Volume 18, Issue 76
Archive-name: mush/part19
Supersedes: mush: Volume 12, Issue 28-47
#!/bin/sh
# do not concatenate these parts, unpack them in order with /bin/sh
# file options.c continued
#
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck
if test "$Scheck" != 19; then
echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping options.c'
else
echo 'x - continuing file options.c'
sed 's/^X//' << 'SHAR_EOF' >> 'options.c' &&
{
X int i;
X
X Debug("%s --> ", *argp);
X for (i = 0; word_flags[i][0]; i++) {
X int len = strlen(word_flags[i][0]);
X if (! strncmp(*argp, word_flags[i][0], len)) {
X char buf[BUFSIZ], *p = buf;
X p += Strcpy(buf, word_flags[i][1]);
X (void) strcpy(p, *argp + len);
X (void) strcpy(*argp, buf);
X }
X }
X Debug("%s\n", *argp);
}
X
/*
X * preparse the command line to determine whether or not we're going
X * to bail out after checking that the user has no mail. Also, check
X * to see if we're going to run a tool because it must be built first.
X */
preparse_opts(argcp, argv)
register int *argcp; /* Pointer to argument count */
register char **argv; /* Argument vector */
{
X int n = FALSE;
X char **args;
X
#ifdef SUNTOOL
X /* Note: we are assigning a boolean result to n and istool here */
X if (n = istool = (strlen(prog_name) > 3 &&
X (!strcmp(prog_name+strlen(prog_name)-4, "tool") ||
X !strcmp(prog_name+strlen(prog_name)-4, "view")))) {
X turnon(glob_flags, DO_SHELL);
X parse_tool_opts(argcp, argv);
X }
#endif /* SUNTOOL */
X
X if (!istool && *argcp > 1) {
X for (args = argv+1; *args && args[0][0] == '-'; args++) {
X int next = 1;
X fix_word_flag(&args[0]);
DoNext:
X switch (args[0][next]) {
#ifdef SUNTOOL
X case 'T' :
X if (args[1])
X args++;
X case 't' :
X /* Note: we won't ever get here if started as
X * "mushtool" or "mushview" because istool is true.
X */
X istool = 1;
X parse_tool_opts(argcp, argv);
X turnon(glob_flags, DO_SHELL);
X return TRUE;
X /* break; */
#endif /* SUNTOOL */
X case 'S' :
X turnon(glob_flags, DO_SHELL);
X n = TRUE;
X break;
X case 'f' :
X case 'F' :
X case 'h' :
X case 'm' :
X case 'u' :
X n = TRUE;
X case 'b' :
X case 'c' :
X case 'I' :
X case 's' :
X if (args[1]) {
X args++;
X next = 0;
X }
X break;
X case 'H' :
X if (args[0][next+1] == ':')
X next = 0;
X break;
X case '\0':
X next = 0;
X default : ;
X }
X if (next) {
X ++next;
X goto DoNext;
X }
X }
X if (*args) { /* unused args indicates sending mail to someone */
X n = TRUE;
X if (!istool)
X turnon(glob_flags, IS_SENDING);
X }
X }
X
X return n;
}
X
static char *usage_str =
#ifdef SUNTOOL
X "usage: %s [-t] [-C] [-i] [-f [folder] ] [-v] [-S] [-s subject] [users]\n";
#else
#ifdef CURSES
X "usage: %s [-C] [-i] [-f [folder] ] [-v] [-S] [-s subject] [user list]\n";
#else
X "usage: %s [-i] [-f [folder] ] [-v] [-S] [-s subject] [user list]\n";
#endif /* CURSES */
#endif /* SUNTOOL */
X
parse_options(argvp, flags)
register char ***argvp;
struct mush_flags *flags;
{
X char buf[256];
X
X bzero((char *) flags, sizeof (struct mush_flags));
X flags->source_rc = TRUE;
X flags->folder = "";
X
X for (++(*argvp); **argvp && ***argvp == '-'; (*argvp)++) {
X int look_again;
DoLookAgain:
X look_again = TRUE;
X switch ((*argvp)[0][1]) {
X case 'e':
X /*
X * don't set tty modes -- e.g. echo and cbreak modes aren't
X * changed.
X */
X turnon(glob_flags, ECHO_FLAG);
#ifdef CURSES
X when 'C':
X /* don't init curses -- don't even set iscurses. */
X if (istool) {
X puts("-C: You are already running in tool mode");
X turnoff(glob_flags, PRE_CURSES);
X } else if (hdrs_only)
X puts("headers only: ignoring -C flag");
X else
X turnon(glob_flags, PRE_CURSES);
#endif /* CURSES */
X when 'F':
X flags->src_n_exit = ((*argvp)[0][2] == '!');
X if (!(flags->src_file = *++(*argvp)))
X puts("specify filename to source"), exit(1);
X look_again = FALSE;
X /* fall thru! */
X case 'N':
X (void) strcat(flags->f_flags, "-N ");
X when 'r':
X (void) strcat(flags->f_flags, "-r "); /* folder() argument */
X when 'H':
X if (istool) {
X puts("running in tool-mode; -H option ignored.");
X break;
X }
X turnoff(glob_flags, PRE_CURSES);
X if (*(hdrs_only = (*(*argvp))+2) != ':')
X hdrs_only = ":a";
X else
X look_again = FALSE;
X /* read only cuz no updates */
X (void) strcat(flags->f_flags, "-N -r ");
X when 'i':
X /* force interactive even if !isatty(0) */
X turnoff(glob_flags, REDIRECT);
X when 'u': /* specify a user's mailbox */
X if (*(flags->folder))
X puts("You can't specify more than one mailbox"), exit(1);
#ifdef HOMEMAIL
X {
X char *p;
X int isdir = 1;
X (void) sprintf(buf, "%%%s",
X (*argvp)[1] ? (*argvp)[1] : "root");
X if ((p = getpath(buf, &isdir)) && !isdir)
X strdup(flags->folder, p);
X else if (isdir < 0)
X puts(p), exit(1);
X else if (isdir)
X (void) printf("\"%s\" is a directory\n", p), exit(1);
X }
#else /* HOMEMAIL */
X strdup(flags->folder, sprintf(buf, "%s/%s",
X MAILDIR, ((*argvp)[1])? (*argvp)[1] : "root"));
#endif /* HOMEMAIL */
X if ((*argvp)[1])
X ++(*argvp);
X look_again = FALSE;
X when 'h':
X if (istool)
X puts("bad option when run as a tool"), exit(1);
X if ((*argvp)[1])
X flags->draft = *++(*argvp);
X else
X (void) printf("-h: missing file name.\n"), exit(1);
X look_again = FALSE;
X turnon(glob_flags, IS_SENDING);
X when 'U':
X if (istool)
X puts("bad option when run as a tool"), exit(1);
X turnon(flags->flg, SEND_NOW);
X if ((*argvp)[0][2] == '!') {
X turnon(flags->flg, NO_SIGN);
X ++(**argvp);
X }
X when 'm':
X if ((*argvp)[1])
X strdup(spoolfile, *++(*argvp));
X else
X (void) printf("-m: missing mailbox name.\n"), exit(1);
X look_again = FALSE;
X when 'f':
X if (*(flags->folder))
X puts("You can't specify more than one mailbox"), exit(1);
X if ((*argvp)[1]) {
X strdup(flags->folder, *++(*argvp));
X look_again = FALSE;
X } else
X strdup(flags->folder, "&");
X when 's':
X if (istool)
X puts("bad option when run as a tool"), exit(1);
X else if ((*argvp)[1])
X flags->Subj = *++(*argvp);
X else
X puts("-s \"subject\""), exit(1);
X look_again = FALSE;
X when 'b':
X if (istool)
X puts("-b: bad option when run as a tool"), exit(1);
X else if ((*argvp)[1])
X flags->Bcc = *++(*argvp);
X else
X puts("-b \"bcc list\""), exit(1);
X look_again = FALSE;
X when 'c':
X if (istool)
X puts("-c: bad option when run as a tool"), exit(1);
X else if ((*argvp)[1])
X flags->Cc = *++(*argvp);
X else
X puts("-c \"cc list\""), exit(1);
X look_again = FALSE;
X break;
#ifdef VERBOSE_ARG
X case 'v':
X if (istool)
X puts("bad option when run as a tool"), exit(1);
X turnon(flags->flg, VERBOSE);
X break;
#endif /* VERBOSE_ARG */
#ifdef SUNTOOL
X case 'T':
X if ((time_out = atoi(*(*argvp))) <= 29)
X time_out = 30;
X look_again = FALSE;
X /* -T implies -t */
X case 't': istool = 1;
#endif /* SUNTOOL */
X case 'S': turnon(glob_flags, DO_SHELL);
X when 'n':
X if ((*argvp)[0][2] == '!') {
X ++(**argvp);
X flags->source_rc = -1; /* No init files sourced */
X } else
X flags->source_rc = 0; /* Only ~/.mushrc sourced */
X when 'I':
X if ((*argvp)[0][2] == '!' && flags->source_rc > 0)
X flags->source_rc = 0; /* Only ~/.mushrc sourced */
X if (!(flags->init_file = *++(*argvp)))
X puts("specify filename for init"), exit(1);
X look_again = FALSE;
X when 'd': debug = 1;
X when '\0' : look_again = FALSE;
X otherwise:
X print("%s: unknown option: `%c'\n", prog_name,
X (*argvp)[0][1]? (*argvp)[0][1] : '-');
X print(usage_str, prog_name);
X }
X if (look_again && ++(**argvp) != '\0')
X goto DoLookAgain;
X }
X
X if (ison(flags->flg, SEND_NOW) && !flags->draft) {
X print("You must specify a draft file to autosend\n");
X exit(1);
X }
}
SHAR_EOF
echo 'File options.c is complete' &&
chmod 0644 options.c ||
echo 'restore of options.c failed'
Wc_c="`wc -c < 'options.c'`"
test 8816 -eq "$Wc_c" ||
echo 'options.c: original size 8816, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= options.h ==============
if test -f 'options.h' -a X"$1" != X"-c"; then
echo 'x - skipping options.h (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting options.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'options.h' &&
/* @(#)options.h (c) copyright 10/10/88 (Dan Heller, Bart Schaefer) */
X
/* Must #include mush.h before #including this file */
X
/* Structure to hold assorted information collected from command line flags.
X * Other information is held in the following global variables:
X * cmd_help General help file, specified by -1
X * debug Debugging mode, toggled by -d
X * glob_flags Bits set by -C, -e, -i, -S, -t and many commands
X * hdrs_only Show headers and exit, specified by -H
X * iscurses Curses mode, specified by -C or "curses" command
X * istool Tool mode, specified by -t or -T
X * mailfile File specified by -u or -f or "folder" command
X * prog_name Name under which mush is running
X * time_out Tool mode timeout, specified by -T
X * tool_help Tool mode help file, specified by -2
X */
X
struct mush_flags {
X u_long flg; /* Set by -v, -h, -U, vars */
X char *init_file; /* Set by -I or -I! */
X char *src_file; /* Set by -F */
X int src_n_exit; /* Set by -F! */
X char *folder; /* Set by -f or -u */
X char *draft; /* Set by -h */
X char f_flags[10]; /* Set by -r, -N, etc.; passed to folder() */
X char *Subj; /* Set by -s */
X char *Cc; /* Set by -c */
X char *Bcc; /* Set by -b */
X int source_rc; /* Set by -n */
};
SHAR_EOF
chmod 0644 options.h ||
echo 'restore of options.h failed'
Wc_c="`wc -c < 'options.h'`"
test 1248 -eq "$Wc_c" ||
echo 'options.h: original size 1248, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= panels.c ==============
if test -f 'panels.c' -a X"$1" != X"-c"; then
echo 'x - skipping panels.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting panels.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'panels.c' &&
/* @(#)panel.c (c) copyright 10/18/86 (Dan Heller) */
/* @(#)panels.c (c) copyright 9/29/89 (Dan Heller) */
X
#include "mush.h"
/* mouse symbols */
short dat_mouse_left[] = {
X 0x1FF8, 0x3FFC, 0x336C, 0x336C, 0x336C, 0x336C, 0x336C, 0x336C,
X 0x3FFC, 0x3FFC, 0x3FFC, 0x3FFC, 0x3FFC, 0x3FC4, 0x3FFC, 0x1FF8
};
X
short dat_mouse_middle[] = {
X 0x1FF8, 0x3FFC, 0x366C, 0x366C, 0x366C, 0x366C, 0x366C, 0x366C,
X 0x3FFC, 0x3FFC, 0x3FFC, 0x3FFC, 0x3FFC, 0x3FC4, 0x3FFC, 0x1FF8
};
X
short dat_mouse_right[] = {
X 0x1FF8, 0x3FFC, 0x36CC, 0x36CC, 0x36CC, 0x36CC, 0x36CC, 0x36CC,
X 0x3FFC, 0x3FFC, 0x3FFC, 0x3FFC, 0x3FFC, 0x3FC4, 0x3FFC, 0x1FF8
};
X
mpr_static(mouse_left, 16, 16, 1, dat_mouse_left);
mpr_static(mouse_middle, 16, 16, 1, dat_mouse_middle);
mpr_static(mouse_right, 16, 16, 1, dat_mouse_right);
X
Panel_item
X folder_item, /* change folders */
X folder_text_item, /* text item for the folder item */
X file_item, /* text item for the save item */
X msg_num_item, /* text item explicitly states which message to read */
X read_item, /* read the current message */
X save_item, /* saves messages */
X sub_hdr_item[6]; /* display items that just sit there and give help */
X
#ifndef NO_WALK_MENUS
Panel
X folder_panel,
X save_panel;
Menu folder_menu; /* Menu of folders for folder button */
Menu save_menu; /* Menu of folders for save button */
Menu hdr_save_menu;/* Menu of folders for save option in hdr window */
extern Menu msg_menu; /* header subwindow menu, defined in hdr_sw.c */
walk_menu_event();
#endif /* NO_WALK_MENUS */
X
/* These global panel items for letter composition should eventually go away */
Panel_item
X edit_item, /* edit a message */
X reply_item; /* reply button -- also called from hdr_sw menu */
X
extern void
X close_frame(), do_options(), do_compose(), do_send(), do_sort(),
X do_edit(), delete_mail(), respond_mail(), do_help(), do_lpr(),
X do_update(), abort_mail(), do_include(), load_from_file(),
X save_to_file(), tilde_from_menu(), fkey_interposer(), do_mark(),
X close_compose();
X
extern Panel_setting
X msg_num_done(), file_dir();
X
Panel
make_hdr_panel(parent, choice_args, button_args)
Frame parent;
char **choice_args, **button_args;
{
X Panel panel = window_create(parent, PANEL,
X WIN_CONSUME_KBD_EVENTS,
X WIN_LEFT_KEYS, WIN_TOP_KEYS, WIN_RIGHT_KEYS, NULL,
X NULL);
X (void) notify_interpose_event_func(panel, fkey_interposer, NOTIFY_SAFE);
X
X (void) panel_create_item(panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_LABEL_IMAGE,
X panel_button_image(panel, "Done", 4, mush_font),
X PANEL_CHOICE_STRINGS,
X "Close to Icon", "Quit Tool", "Help", NULL,
X PANEL_NOTIFY_PROC, toolquit,
X NULL);
X
X (void) panel_create_item(panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_LABEL_IMAGE,
X panel_button_image(panel, "Help", 4, mush_font),
X PANEL_CHOICE_STRINGS,
X "About", "Help with \"help\"", "The Mouse", "Windows",
X "Message headers", "Message lists", "Folders", NULL,
X PANEL_NOTIFY_PROC, do_help,
X NULL);
X
#ifndef NO_WALK_MENUS
X folder_panel = panel;
X folder_item = panel_create_item(panel, PANEL_BUTTON,
X PANEL_ATTRIBUTE_LIST, button_args,
X PANEL_LABEL_IMAGE,
X panel_button_image(panel, "Folder", 6, mush_font),
X PANEL_NOTIFY_PROC, do_file_dir,
X PANEL_EVENT_PROC, walk_menu_event,
X NULL);
#else /* NO_WALK_MENUS */
X folder_item = panel_create_item(panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_LABEL_IMAGE,
X panel_button_image(panel, "Folder", 6, mush_font),
X PANEL_CHOICE_STRINGS,
X "System Mailbox", "Main Mailbox", "Last Accessed Folder", NULL,
X PANEL_NOTIFY_PROC, do_file_dir,
X NULL);
X
X add_folder_to_menu(folder_item, 3);
#endif /* NO_WALK_MENUS */
X
X folder_text_item = panel_create_item(panel, PANEL_TEXT,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_LABEL_FONT, mush_font,
X PANEL_LABEL_STRING, "Filename:",
X PANEL_VALUE_DISPLAY_LENGTH, 28,
X PANEL_NOTIFY_STRING, "\n\r\033",
X PANEL_NOTIFY_PROC, file_dir,
X NULL);
X
X (void) panel_create_item(panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_LABEL_IMAGE,
X panel_button_image(panel, "Update", 6, mush_font),
X PANEL_CHOICE_STRINGS, "New Mail", "Help", NULL,
X PANEL_NOTIFY_PROC, do_update,
X NULL);
X
X (void) panel_create_item(panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_LABEL_IMAGE,
X panel_button_image(panel, "Options", 7, mush_font),
X PANEL_CHOICE_STRINGS, "Variables", "Headers", "Aliases", NULL,
X PANEL_NOTIFY_PROC, do_options,
X NULL);
X
X msg_num_item = panel_create_item(panel, PANEL_TEXT,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_LABEL_STRING, "Range:",
X PANEL_MENU_CHOICE_STRINGS, "Help", NULL,
X PANEL_VALUE_DISPLAY_LENGTH, 17,
X PANEL_VALUE_STORED_LENGTH, 80,
X PANEL_LABEL_FONT, mush_font,
X PANEL_NOTIFY_STRING, "\n\r",
X PANEL_NOTIFY_PROC, msg_num_done,
X NULL);
X
X sub_hdr_item[0] = panel_create_item(panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_LABEL_IMAGE, &mouse_left,
X PANEL_CHOICE_STRINGS, "Help", NULL,
X PANEL_NOTIFY_PROC, read_mail,
X NULL);
X sub_hdr_item[1] = panel_create_item(panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_LABEL_STRING, "Read ",
X PANEL_MENU_TITLE_IMAGE, &mouse_left,
X PANEL_CHOICE_STRINGS, "Help", NULL,
X PANEL_NOTIFY_PROC, read_mail,
X NULL);
X sub_hdr_item[2] = panel_create_item(panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_LABEL_IMAGE, &mouse_middle,
X PANEL_CHOICE_STRINGS, "Help", NULL,
X PANEL_NOTIFY_PROC, delete_mail,
X NULL);
X sub_hdr_item[3] = panel_create_item(panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_LABEL_STRING, "Delete ",
X PANEL_MENU_TITLE_IMAGE, &mouse_middle,
X PANEL_CHOICE_STRINGS, "Help", NULL,
X PANEL_NOTIFY_PROC, delete_mail,
X NULL);
X sub_hdr_item[4] = panel_create_item(panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_LABEL_IMAGE, &mouse_right,
X PANEL_CHOICE_STRINGS, "Help", NULL,
X PANEL_NOTIFY_PROC, read_mail,
X NULL);
X sub_hdr_item[5] = panel_create_item(panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_LABEL_STRING, "Menu ",
X PANEL_MENU_TITLE_IMAGE, &mouse_right,
X PANEL_CHOICE_STRINGS, "Help", NULL,
X PANEL_NOTIFY_PROC, read_mail,
X NULL);
X
X (void) panel_create_item(panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_LABEL_IMAGE,
X panel_button_image(panel, "Mark", 4, mush_font),
X PANEL_CHOICE_STRINGS,
X "Toggle Mark", "Priority A", "Priority B", "Priority C",
X "Priority D", "Priority E", "Clear Priority", "Help", NULL,
X PANEL_NOTIFY_PROC, do_mark,
X NULL);
X
X (void) panel_create_item(panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_LABEL_IMAGE,
X panel_button_image(panel, "Printer", 7, mush_font),
X PANEL_CHOICE_STRINGS, "Help", NULL,
X PANEL_NOTIFY_PROC, do_lpr,
X NULL);
X
X (void) panel_create_item(panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_LABEL_IMAGE,
X panel_button_image(panel, "Sort", 4, mush_font),
X PANEL_CHOICE_STRINGS,
X "By Status", "By Author", "By Size", "By Subject",
X "By Subject (ignore Re:)", "By Date",
X "By Priority", "Value of $sort", "Help", NULL,
X PANEL_NOTIFY_PROC, do_sort,
X NULL);
X
X window_fit_height(panel);
X return panel;
}
X
Panel
make_main_panel(parent, choice_args, button_args)
Frame parent;
char **choice_args, **button_args;
{
X /* main panel stuff: */
X Panel panel = window_create(parent, PANEL,
X WIN_CONSUME_KBD_EVENTS,
X WIN_LEFT_KEYS, WIN_TOP_KEYS, WIN_RIGHT_KEYS, NULL,
X NULL);
X (void) notify_interpose_event_func(panel, fkey_interposer, NOTIFY_SAFE);
X
X read_item = panel_create_item(panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_LABEL_IMAGE,
X panel_button_image(panel, "Next", 4, mush_font),
X PANEL_CHOICE_STRINGS, "Help", NULL,
X PANEL_NOTIFY_PROC, read_mail,
X NULL);
X
X (void) panel_create_item(panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_LABEL_IMAGE,
X panel_button_image(panel, "Delete", 6, mush_font),
X PANEL_CHOICE_STRINGS, "Delete",
X "Undelete",
X "Help", NULL,
X PANEL_NOTIFY_PROC, delete_mail,
X NULL);
X
#ifndef NO_WALK_MENUS
X save_panel = panel;
X save_item = panel_create_item(panel, PANEL_BUTTON,
X PANEL_ATTRIBUTE_LIST, button_args,
X PANEL_LABEL_IMAGE, panel_button_image(panel, "Save", 4, mush_font),
X PANEL_NOTIFY_PROC, do_file_dir,
X PANEL_EVENT_PROC, walk_menu_event,
X NULL);
X
X create_folder_menus();
#else /* NO_WALK_MENUS */
X {
X char *mbox = do_set(set_options, "mbox");
X if (!mbox || !*mbox)
X mbox = DEF_MBOX;
X save_item = panel_create_item(panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_LABEL_IMAGE, panel_button_image(panel, "Save", 4, mush_font),
X PANEL_CHOICE_STRINGS, trim_filename(mbox), NULL,
X PANEL_NOTIFY_PROC, do_file_dir,
X NULL);
X }
X
X add_folder_to_menu(save_item, 1);
#endif /* NO_WALK_MENUS */
X
X file_item = panel_create_item(panel, PANEL_TEXT,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_LABEL_FONT, mush_font,
X PANEL_SHOW_MENU, TRUE,
X PANEL_LABEL_STRING, "Filename:",
X PANEL_MENU_CHOICE_STRINGS, "Save message without message header",
X NULL,
X PANEL_VALUE_DISPLAY_LENGTH, 28,
X PANEL_NOTIFY_STRING, "\n\r\033",
X PANEL_NOTIFY_PROC, file_dir,
X NULL);
X
X (void) panel_create_item(panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_LABEL_IMAGE,
X panel_button_image(panel, "Compose", 7, mush_font),
X PANEL_CHOICE_STRINGS, "Help", NULL,
X PANEL_NOTIFY_PROC, do_compose,
X NULL);
X
X reply_item = panel_create_item(panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_LABEL_IMAGE,
X panel_button_image(panel, "Reply", 5, mush_font),
X PANEL_CHOICE_STRINGS,
X "Sender Only", "Sender Only (include msg)",
X "All Recipients", "All Recipients (include msg)", "Help", NULL,
X PANEL_NOTIFY_PROC, respond_mail,
X NULL);
X
X window_fit_height(panel);
X return panel;
}
X
Panel
make_compose_panel(parent, choice_args, button_args)
Frame parent;
char **choice_args, **button_args;
{
X Panel panel = window_create(parent, PANEL, NULL);
X Panel_item filename_item, fortune_item, sign_item, send_item;
X
X (void) notify_interpose_event_func(panel, fkey_interposer, NOTIFY_SAFE);
X
X if (do_set(set_options, "compose_icon"))
X (void) panel_create_item(panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_LABEL_IMAGE,
X panel_button_image(panel, "Close", 5, mush_font),
X PANEL_CHOICE_STRINGS,
X "Close to Icon", "Quit", "Help", NULL,
X PANEL_NOTIFY_PROC, close_compose,
X NULL);
X else
X (void) panel_create_item(panel, PANEL_BUTTON,
X PANEL_ATTRIBUTE_LIST, button_args,
X PANEL_LABEL_IMAGE,
X panel_button_image(panel, "Close", 5, mush_font),
X PANEL_NOTIFY_PROC, close_frame,
X NULL);
X
X (void) panel_create_item(panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_LABEL_IMAGE,
X panel_button_image(panel, "Compose", 7, mush_font),
X PANEL_CHOICE_STRINGS, "Help", NULL,
X PANEL_NOTIFY_PROC, do_compose,
X NULL);
X
X send_item = panel_create_item(panel, PANEL_BUTTON,
X PANEL_ATTRIBUTE_LIST, button_args,
X PANEL_SHOW_ITEM, FALSE,
X PANEL_LABEL_IMAGE,
X panel_button_image(panel, "Send", 4, mush_font),
X PANEL_NOTIFY_PROC, do_send,
X NULL);
X
X (void) panel_create_item(panel, PANEL_BUTTON,
X PANEL_ATTRIBUTE_LIST, button_args,
X PANEL_SHOW_ITEM, FALSE,
X PANEL_LABEL_IMAGE,
X panel_button_image(panel, "Abort", 5, mush_font),
X PANEL_NOTIFY_PROC, abort_mail,
X NULL);
X
X (void) panel_create_item(panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_SHOW_ITEM, FALSE,
X PANEL_LABEL_IMAGE,
X panel_button_image(panel, "Include", 7, mush_font),
X PANEL_CHOICE_STRINGS, "Include Message",
X "Forward Message",
X "Help", NULL,
X PANEL_NOTIFY_PROC, do_include,
X NULL);
X
X edit_item = panel_create_item(panel, PANEL_BUTTON,
X PANEL_ATTRIBUTE_LIST, button_args,
X PANEL_SHOW_ITEM, FALSE,
X PANEL_LABEL_IMAGE,
X panel_button_image(panel, "Edit", 4, mush_font),
X PANEL_NOTIFY_PROC, do_edit,
X NULL);
X
X (void) panel_create_item(panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_SHOW_ITEM, FALSE,
X PANEL_LABEL_IMAGE,
X panel_button_image(panel, "Headers", 7, mush_font),
X PANEL_CHOICE_STRINGS,
X "ALL ~h", "To: ~t", "Subject: ~s",
X "Cc: ~c", "Bcc: ~b", "Fcc:", NULL,
X PANEL_NOTIFY_PROC, tilde_from_menu,
X NULL);
X
X sign_item = panel_create_item(panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_DISPLAY_LEVEL, PANEL_ALL,
X PANEL_SHOW_MENU_MARK, TRUE,
X PANEL_SHOW_ITEM, FALSE,
X PANEL_LABEL_STRING, "Autosign:",
X PANEL_CHOICE_STRINGS, "Off", "On", NULL,
X NULL);
X panel_set_value(sign_item, !!do_set(set_options, "autosign"));
X /* Create a link to avoid global */
X panel_set(send_item, PANEL_CLIENT_DATA, sign_item, NULL);
X
X filename_item = panel_create_item(panel, PANEL_TEXT,
X PANEL_ATTRIBUTE_LIST, button_args,
X PANEL_SHOW_ITEM, FALSE,
X PANEL_LABEL_STRING, "Filename:",
X PANEL_VALUE_DISPLAY_LENGTH, 30,
X PANEL_NOTIFY_STRING, "\033",
X PANEL_NOTIFY_PROC, file_dir,
X NULL);
X
X (void) panel_create_item(panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_SHOW_ITEM, FALSE,
X PANEL_CLIENT_DATA, filename_item,
X PANEL_LABEL_IMAGE,
X panel_button_image(panel, "Import", 6, mush_font),
X PANEL_CHOICE_STRINGS, "Insert", "Replace", NULL,
X PANEL_NOTIFY_PROC, load_from_file,
X NULL);
X
X (void) panel_create_item(panel, PANEL_BUTTON,
X PANEL_ATTRIBUTE_LIST, button_args,
X PANEL_SHOW_ITEM, FALSE,
X PANEL_CLIENT_DATA, filename_item,
X PANEL_LABEL_IMAGE,
X panel_button_image(panel, "Export", 6, mush_font),
X PANEL_NOTIFY_PROC, save_to_file,
X NULL);
X
X fortune_item = panel_create_item(panel, PANEL_CHOICE,
X PANEL_ATTRIBUTE_LIST, choice_args,
X PANEL_DISPLAY_LEVEL, PANEL_ALL,
X PANEL_SHOW_MENU_MARK, TRUE,
X PANEL_SHOW_ITEM, FALSE,
X PANEL_LABEL_STRING, "Fortune:",
X PANEL_CHOICE_STRINGS, "Off", "On", NULL,
X NULL);
X panel_set_value(fortune_item, !!do_set(set_options, "fortune"));
X /* Create a link to avoid global */
X panel_set(sign_item, PANEL_CLIENT_DATA, fortune_item, NULL);
X
X window_fit_height(panel);
X return panel;
}
X
#include "glob.h"
X
#ifndef NO_WALK_MENUS
X
static
Menu_item
make_folder_item(path)
char *path;
{
X Menu_item mi;
X Menu_item sub_mi;
X Menu next_menu;
X char **names, **np;
X struct stat s_buf;
X char buf[MAXPATHLEN];
X
X if (glob(path, "*/{.,..}")) {
X return NULL;
X }
X
X /* don't add a folder to the list if user can't read it */
X if (stat(path, &s_buf) == -1 || !(s_buf.st_mode & S_IREAD)) {
X return NULL;
X }
X mi = menu_create_item(
X MENU_STRING, savestr(basename(trim_filename(path))),
X MENU_CLIENT_DATA, NULL,
X MENU_RELEASE, /* no value */
X NULL);
X if ((s_buf.st_mode & S_IFMT) == S_IFDIR) {
X int cnt = 0;
X next_menu = menu_create(MENU_NOTIFY_PROC, menu_return_item, NULL);
X sprintf(buf, "%s/{.*,*}", path);
X if (filexp(buf, &names) > 0) {
X for (np = names; np && *np; np++) {
X if ((sub_mi = make_folder_item(*np)) != NULL) {
X menu_set(next_menu, MENU_APPEND_ITEM, sub_mi, NULL);
X ++cnt;
X }
X }
X free_vec(names);
X }
X if (! cnt) {
X menu_destroy(next_menu);
X menu_set(mi, MENU_INACTIVE, TRUE, NULL);
X } else {
X menu_set(mi, MENU_PULLRIGHT, next_menu, NULL);
X }
X } else if (test_folder(path, NULL)) {
X menu_set(mi, MENU_CLIENT_DATA, savestr(path), NULL);
X } else {
X menu_destroy(mi);
X mi = NULL;
X }
X return mi;
}
X
static
void
destroy_folder_item(menu_item, menu_type)
Menu_item menu_item;
Menu_attribute menu_type;
{
X char *ptr;
X
X if (menu_type == MENU_ITEM) {
X if ((ptr = (char *)menu_get(menu_item, MENU_STRING)) != NULL) {
X free(ptr);
X }
X if ((ptr = (char *)menu_get(menu_item, MENU_CLIENT_DATA)) != NULL) {
X free(ptr);
X }
X }
X return;
}
X
create_folder_menus()
{
X int item_number;
X Menu menu;
X Menu_item menu_item;
X int nitems;
X char *mbox;
X char *tmp = NULL;
X char *p;
X static int menus_exist = 0;
X
X if (menus_exist) {
X /* remove duplicated menu items from save_menu */
X for (item_number = (int)menu_get(save_menu, MENU_NITEMS) ;
X item_number > 1 ; --item_number) {
X menu_set(save_menu, MENU_REMOVE, item_number, NULL);
X }
X /* remove duplicated menu items from hdr_save_menu */
X for (item_number = (int)menu_get(hdr_save_menu, MENU_NITEMS) ;
X item_number > 1 ; --item_number) {
X menu_set(save_menu, MENU_REMOVE, item_number, NULL);
X }
X menu_destroy_with_proc(hdr_save_menu, destroy_folder_item);
X menu_destroy_with_proc(save_menu, destroy_folder_item);
X menu_destroy_with_proc(folder_menu, destroy_folder_item);
X }
X
X if (!(p = do_set(set_options, "folder")) || !*p) {
X p = DEF_FOLDER;
X }
X if (p) {
X int x = 0;
X tmp = getpath(p, &x);
X if (x == -1) {
X if (errno != ENOENT)
X print("%s: %s\n", p, tmp);
X tmp = NULL;
X }
X }
X menu = NULL;
X menu_item = NULL;
X if (tmp != NULL) {
X if ((menu_item = make_folder_item(tmp)) != NULL) {
X if ((menu = menu_get(menu_item, MENU_PULLRIGHT)) != NULL) {
X /* $folder was a directory, use the pullright
X * instead of the directory menu item.
X */
X /* "unhook" the pullright (so it is not released) */
X menu_set(menu_item, MENU_PULLRIGHT, NULL, NULL);
X /* destroy the menu item */
X menu_destroy_with_proc(menu_item, destroy_folder_item);
X menu_item = NULL;
X }
X }
X }
X if (menu == NULL) {
X menu = menu_create(MENU_NOTIFY_PROC, menu_return_item, NULL);
X if (menu_item != NULL) {
X menu_set(menu, MENU_APPEND_ITEM, menu_item, NULL);
X }
X }
X
X /* create save_menu */
X save_menu = menu_create(MENU_NOTIFY_PROC, menu_return_item, NULL);
X /* add magic first item */
X mbox = do_set(set_options, "mbox");
X if (!mbox || !*mbox) {
X mbox = DEF_MBOX;
X }
X menu_item = menu_create_item(
X MENU_STRING, savestr(trim_filename(mbox)),
X MENU_CLIENT_DATA, savestr(mbox),
X MENU_RELEASE, /* no value */
X NULL);
X menu_set(save_menu, MENU_APPEND_ITEM, menu_item, NULL);
X /* copy menu for save_menu */
X nitems = (int)menu_get(menu, MENU_NITEMS);
X for (item_number = 1 ; item_number <= nitems ; ++item_number) {
X menu_set(save_menu,
X MENU_APPEND_ITEM, menu_get(menu, MENU_NTH_ITEM, item_number),
X NULL);
X }
X
X /* create hdr_save_menu */
X hdr_save_menu = menu_create(MENU_NOTIFY_PROC, menu_return_item, NULL);
X /* add magic first item */
X menu_item = menu_create_item(
X MENU_STRING, savestr("use Filename:"),
X MENU_CLIENT_DATA, savestr(""), /* magic */
X MENU_RELEASE, /* no value */
X NULL);
X menu_set(hdr_save_menu, MENU_APPEND_ITEM, menu_item, NULL);
X /* copy save_menu for hdr_save_menu */
X nitems = (int)menu_get(save_menu, MENU_NITEMS);
X for (item_number = 1 ; item_number <= nitems ; ++item_number) {
X menu_set(hdr_save_menu,
X MENU_APPEND_ITEM, menu_get(save_menu, MENU_NTH_ITEM, item_number),
X NULL);
X }
X /* Make sure the header subwindow menu exists so we can tack on a
X * pullright for Save.
X */
X if (! msg_menu) {
X get_msg_menu();
X }
X if ((menu_item = menu_find(msg_menu, MENU_STRING, "Save", NULL))
X != NULL) {
X menu_set(menu_item, MENU_PULLRIGHT, hdr_save_menu, NULL);
X }
X
X /* insert folder-specific initial options to menu */
X folder_menu = menu;
X menu_item = menu_create_item(
X MENU_STRING, savestr("System Mailbox"),
X MENU_CLIENT_DATA, savestr("%"),
X MENU_RELEASE, /* no value */
X NULL);
X menu_set(folder_menu, MENU_INSERT, 0, menu_item, NULL);
X menu_item = menu_create_item(
X MENU_STRING, savestr("Main Mailbox"),
X MENU_CLIENT_DATA, savestr("&"),
X MENU_RELEASE, /* no value */
X NULL);
X menu_set(folder_menu, MENU_INSERT, 1, menu_item, NULL);
X menu_item = menu_create_item(
X MENU_STRING, savestr("Last Accessed Folder"),
X MENU_CLIENT_DATA, savestr("#"),
X MENU_RELEASE, /* no value */
X NULL);
X menu_set(folder_menu, MENU_INSERT, 2, menu_item, NULL);
X
X menus_exist = 1;
X return;
}
X
static
walk_menu_event(item, event)
Panel_item item;
Event *event;
{
X char *folder_name;
X Menu_item selection;
X Menu menu;
X Panel panel;
X void xx_file_dir();
X
X if (event_id(event) == MS_RIGHT && event_is_down(event)) {
X if (item == folder_item) {
X menu = folder_menu;
X panel = folder_panel;
X } else {
X menu = save_menu;
X panel = save_panel;
X }
X selection = (Menu_item)menu_show(menu, panel, event, 0);
X if (! selection) {
X /* no selection was made */
X return;
X }
X if ((folder_name = (char *)menu_get(selection, MENU_CLIENT_DATA))
X != NULL) {
X xx_file_dir(item, folder_name);
X }
X } else {
X panel_default_handle_event(item, event);
X }
}
X
#else /* NO_WALK_MENUS */
X
static
add_path_to_menu(item, path, n)
Panel_item item;
char *path;
int *n;
{
X char **names, **np;
X struct stat s_buf;
X char buf[MAXPATHLEN];
X
X /* don't add a folder to the list if user can't read it */
X if (stat(path, &s_buf) == -1 || !(s_buf.st_mode & S_IREAD))
X return;
X if ((s_buf.st_mode & S_IFMT) == S_IFDIR) {
X sprintf(buf, "%s/{.*,*}", path);
X if (filexp(buf, &names) > 0) {
X for (np = names; np && *np; np++) {
X if (!glob(*np, "*/{.,..}"))
X add_path_to_menu(item, *np, n);
X }
X free_vec(names);
X }
X } else if (test_folder(path, NULL))
X panel_set(item,
X PANEL_CHOICE_STRING, (*n)++, savestr(trim_filename(path)),
X NULL);
}
X
/*
X * Open the user's mail folder (either user set or default path) and find all
X * the files (assumed to be mail folders) and add them to the menu list of
X * folders to use.
X */
add_folder_to_menu(item, n)
Panel_item item;
{
X char *tmp = NULL, *p;
X
X if (!(p = do_set(set_options, "folder")) || !*p)
X p = DEF_FOLDER;
X if (p) {
X int x = 0;
X tmp = getpath(p, &x);
X if (x == -1) {
X if (errno != ENOENT)
X print("%s: %s\n", p, tmp);
X tmp = NULL;
X }
X }
X if (tmp) {
X add_path_to_menu(item, tmp, &n);
X }
}
#endif /* NO_WALK_MENUS */
SHAR_EOF
chmod 0644 panels.c ||
echo 'restore of panels.c failed'
Wc_c="`wc -c < 'panels.c'`"
test 22092 -eq "$Wc_c" ||
echo 'panels.c: original size 22092, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= pick.c ==============
if test -f 'pick.c' -a X"$1" != X"-c"; then
echo 'x - skipping pick.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting pick.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'pick.c' &&
/* @(#)pick.c 2.4 (c) copyright 10/18/86 (Dan Heller) */
X
#include "mush.h"
X
static int before, after, search_from, search_subj, search_to, xflg, icase;
static u_long match_priority;
static char search_hdr[64];
static int mdy[3];
static int pick();
static void month_day_year();
X
do_pick(n, argv, list)
register int n;
register char **argv, list[];
{
X char ret_list[MAXMSGS_BITS];
X
X if (n > 1 && !strcmp(argv[1], "-?"))
X return help(0, "pick", cmd_help);
X
X clear_msg_list(ret_list);
X /* if is_pipe, then the messages to search for are already set.
X * if not piped, then reverse the bits for all message numbers.
X * That is, search EACH message. only those matching will be returned.
X */
X if (isoff(glob_flags, IS_PIPE))
X bitput(ret_list, list, msg_cnt, =~); /* macro, turn on all bits */
X /* Use n temporarily as verbosity flag */
X n = (!chk_option("quiet", "pick") &&
X isoff(glob_flags, DO_PIPE));
X if ((n = pick(argv, list, ret_list, n)) == -1)
X return -1;
X if (istool && isoff(glob_flags, DO_PIPE))
X print("%d matches:\n", n);
X for (n = 0; n < msg_cnt; n++)
X if (msg_bit(ret_list, n)) {
X if (isoff(glob_flags, DO_PIPE))
X if (istool)
X print_more("%d ", n+1);
X else
X print("%s\n", compose_hdr(n));
X set_msg_bit(list, n);
X } else
X unset_msg_bit(list, n);
X return 0;
}
X
/*
X * search for messages. Return the number of matches. Errors such
X * as internal errors or syntax errors, return -1.
X * "head" and "tail" are specified using +<num> or -<num> as args.
X * Both can be specified and the order is significant.
X * pick +5 -3
X * returns the last three of the first five matches.
X * pick -3 +2
X * returns the first two of the last three matches.
X */
static int
pick(argv, list, ret_list, verbose)
register char **argv, list[], ret_list[];
{
X register char c;
X int matches = 0;
X char pattern[256];
X short head_first, head_cnt, tail_cnt, search = TRUE;
X int n;
X
X if (!msg_cnt) {
X print("No Messages.\n");
X return -1;
X }
X
X head_first = TRUE;
X head_cnt = tail_cnt = -1;
X match_priority = 0;
X icase = before = after = search_from = search_subj = search_to = xflg = 0;
X mdy[0] = mdy[1] = search_hdr[0] = 0;
X while (*argv && *++argv && (**argv == '-' || **argv == '+'))
X if (**argv == '+' || isdigit(argv[0][1])) {
X if (**argv == '+')
X head_cnt = atoi(&argv[0][1]);
X else {
X tail_cnt = atoi(&argv[0][1]);
X if (head_cnt == -1)
X head_first = FALSE;
X }
X if (head_cnt == 0 || tail_cnt == 0) {
X print("pick: invalid head/tail number: %s\n", &argv[0][1]);
X clear_msg_list(ret_list);
X return -1;
X }
X } else if ((c = argv[0][1]) == 'e') {
X if (!*++argv) {
X print("usage: -e expression...\n");
X return -1;
X }
X break;
X } else switch (c) {
X /* user specifies a range */
X case 'r': {
X int X = 2;
X /* if not a pipe, then clear all bits cuz we only want
X * to search the message specified here...
X * If it is a pipe, then add to the messages searched for.
X */
X if (isoff(glob_flags, IS_PIPE))
X clear_msg_list(list);
X /* "-r10-15"
X * ^argv[1][2] if NULL, then
X * list detached from "r" e.g. "-r" "5-20"
X */
X if (!argv[0][X])
X argv++, X = 0;
X (*argv) += X;
X n = get_msg_list(argv, list);
X (*argv) -= X;
X if (n == -1)
X return -1;
X argv += (n-1); /* we're going to increment another up top */
X }
X when 'a': {
X if ((n = ago_date(++argv)) == -1)
X return -1;
X argv += n;
X }
X when 'd':
X if (!*++argv) {
X print("Specify a date for -%c\n", c);
X return -1;
X }
X if (!date1(*argv))
X return -1;
X when 's' : case 'f': case 't': case 'h':
X if (search_subj + search_from + search_to + *search_hdr > 1) {
X print("Specify one of `s', `f', `t' or `h' only\n");
X return -1;
X }
X if (c == 's')
X search_subj = 1;
X else if (c == 'f')
X search_from = 1;
X else if (c == 'h')
X if (!*++argv)
X print("Specify header to search for.\n");
X else
X (void) lcase_strcpy(search_hdr, *argv);
X else
X search_to = 1;
X when 'p' : /* Select on priority field */
X if (!*++argv || (c = upper(**argv)) < 'A' ||
X c > MAX_PRIORITY + 'A') {
X print("pick: invalid priority: %s\n", argv[0]);
X clear_msg_list(ret_list);
X return -1;
X }
X turnon(match_priority, M_PRIORITY(c - 'A' + 1));
X when 'x' : xflg = 1;
X when 'i' : icase = 1;
X otherwise:
X print("pick: unknown flag: %c\n", argv[0][1]);
X clear_msg_list(ret_list);
X return -1;
X }
X if (xflg && head_cnt + tail_cnt >= 0) {
X print("Can't specify -x and head/tail options together.\n");
X return -1;
X }
X if (!mdy[1]) {
X pattern[0] = 0;
X (void) argv_to_string(pattern, argv);
X if (pattern[0] == '\0' && match_priority == 0 &&
X head_cnt + tail_cnt < 0) {
X print("No pattern specified\n");
X clear_msg_list(ret_list); /* doesn't matter really */
X return -1;
X }
X }
X search = (pattern[0] || mdy[1] || match_priority > 0);
X if (verbose) {
X if (head_cnt + tail_cnt >= 0) {
X print("Finding the ");
X if (head_cnt > 0) {
X if (head_first)
X if (tail_cnt == -1)
X print_more("first %d message%s",
X head_cnt, head_cnt > 1? "s" : "");
X else
X print_more("last %d message%s",
X tail_cnt, tail_cnt > 1? "s" : "");
X else /* there must be a tail_cnt and it comes first */
X print_more("first %d message%s",
X head_cnt, head_cnt > 1? "s" : "");
X } else
X print_more("last %d message%s",
X tail_cnt, tail_cnt > 1? "s" : "");
X if (tail_cnt > 0 && head_cnt > 0)
X if (head_first)
X print_more(" of the first %d", head_cnt);
X else
X print_more(" of the last %d", tail_cnt);
X } else
X print_more("Searching for %smessages",
X match_priority > 0 ? "priority " : "");
X if (!search) {
X if (tail_cnt > 0 && head_cnt > 0)
X print_more(" messages");
X if (ison(glob_flags, IS_PIPE))
X print_more(" from the input list");
X } else if (pattern[0]) {
X print_more(" that %scontain \"%s\"", (xflg)? "do not ": "",
X pattern);
X if (search_subj)
X print_more(" in subject line");
X else if (search_from)
X print_more(" from author names");
X else if (search_to)
X print_more(" from the To: field");
X else if (search_hdr[0])
X print_more(" from the message header \"%s:\"", search_hdr);
X } else if (mdy[1]) {
X extern char *month_names[]; /* from dates.c */
X print_more(" dated ");
X if (before || after)
X if (xflg)
X print_more("%s ", (!before)? "before": "after");
X else
X print_more("on or %s ", (before)? "before": "after");
X print_more("%s. %d, %d",
X month_names[mdy[0]], mdy[1], mdy[2] + 1900);
X }
X print_more(".\n");
X }
X if (mdy[1] > 0 && icase)
X print("using date: -i flag ignored.\n");
X if (!search) {
X for (n = 0; n < msg_cnt && (!head_first || matches < head_cnt); n++)
X if (msg_bit(list, n))
X ++matches, set_msg_bit(ret_list, n);
X } else
X matches = find_pattern(head_first? head_cnt : msg_cnt,
X pattern, list, ret_list);
X if (xflg && matches >= 0) {
X /* invert items in ret_list that also appear in list */
X bitput(list, ret_list, msg_cnt, ^=);
X /* there should be a faster way to do this count ... */
X for (matches = n = 0; n < msg_cnt; n++)
X if (msg_bit(ret_list, n))
X ++matches;
X }
X Debug("matches = %d\n", matches);
X if (!matches)
X return 0;
X
X /* ok, the list we've got is a list of matched messages. If "tailing"
X * is set, reduce the number of matches to at least tail_cnt.
X */
X if (tail_cnt >= 0)
X for (n = 0; n < msg_cnt && matches > tail_cnt; n++)
X if (msg_bit(ret_list, n)) {
X Debug("tail: dropping %d\n", n+1);
X unset_msg_bit(ret_list, n);
X matches--;
X }
X
X /* if tailing came before heading, we need to do the heading now. */
X if (!head_first && head_cnt >= 0)
X for (n = 0; n < msg_cnt; n++)
X if (msg_bit(ret_list, n))
X if (head_cnt > 0)
X head_cnt--;
X else {
X unset_msg_bit(ret_list, n);
X matches--;
X }
X return matches;
}
X
/*
X * find_pattern will search thru all the messages set in the check_list
X * until the list runs out or "cnt" has been exhasted. ret_list contains
X * the list of messages which have matched the pattern.
X * return -1 for internal error or # of pattern matches.
X */
find_pattern(cnt, p, check_list, ret_list)
int cnt;
register char *p;
char check_list[], ret_list[];
{
X register int n, val, i; /* val is return value from regex or re_exec */
X int matches = 0;
X long bytes = 0;
X char buf[HDRSIZ];
X static char *err = (char *)-1;
#ifdef REGCMP
X char *regcmp(), *regex();
#else /* REGCMP */
X char *re_comp();
#endif /* REGCMP */
X
X if (p && *p == '\\')
X p++; /* take care of escaping special cases (`-', `\') */
X
X /* specify what we're looking for */
X if (p && *p) {
X if (icase)
X p = lcase_strcpy(buf, p);
#ifdef REGCMP
X if (err && p)
X xfree(err);
X if (p && !(err = regcmp(p, NULL))) {
X print("regcmp error: %s\n", p);
X clear_msg_list(ret_list);
X return -1;
X }
#else /* REGCMP */
X if (err = re_comp(p)) {
X print("re_comp error: %s\n", err);
X clear_msg_list(ret_list);
X return -1;
X }
#endif /* REGCMP */
X } else if (err == (char *)-1 && mdy[1] <= 0 && match_priority == 0) {
X print("No previous regular expression\n");
X clear_msg_list(ret_list); /* doesn't matter really */
X return -1;
X }
X /* start searching: set bytes, and message number: n */
X for (n = 0; cnt && n < msg_cnt; n++)
X if (msg_bit(check_list, n)) {
X if (match_priority > 0) {
X if (msg[n].m_flags & match_priority)
X ++matches, set_msg_bit(ret_list, n);
X continue;
X }
X if (mdy[1] > 0) {
X int msg_mdy[3];
X if (ison(glob_flags, DATE_RECV))
X p = msg[n].m_date_recv;
X else
X p = msg[n].m_date_sent;
X /* Ick -- fix this mdy thing asap */
X month_day_year(p, &msg_mdy[0], &msg_mdy[1], &msg_mdy[2]);
X Debug("checking %d's date: %d-%d-%d ",
X n+1, msg_mdy[0]+1, msg_mdy[1], msg_mdy[2]);
X /* start at year and wrap around.
X * only when match the day (4), check for == (match)
X */
X for (i = 2; i < 5; i++)
X if (before && msg_mdy[i%3] < mdy[i%3]
X || after && msg_mdy[i%3] > mdy[i%3]
X || i == 4 && (msg_mdy[i%3] == mdy[i%3])) {
X Debug("matched (%s).\n",
X (i == 2)? "year" : (i == 3)? "month" : "day");
X set_msg_bit(ret_list, n);
X cnt--, matches++;
X break;
X } else if (msg_mdy[i%3] != mdy[i%3]) {
X Debug("failed.\n");
X break;
X }
X continue;
X }
X /* we must have the right date -- if we're searching for a
X * string, find it.
X */
X (void) msg_get(n, NULL, 0);
X bytes = 0;
X while (bytes < msg[n].m_size) {
X if (!search_subj && !search_from && !search_to &&
X !*search_hdr && !(p = fgets(buf, sizeof buf, tmpf)))
X break;
X else if (search_subj) {
X if (!(p = header_field(n, "subject")))
X break;
X } else if (search_from) {
X if (!(p = header_field(n, "from"))) {
X /*
X * Check for MSG_SEPARATOR here? Maybe not...
X */
X register char *p2;
X (void) msg_get(n, NULL, 0);
X if (!(p2 = fgets(buf, sizeof buf, tmpf)) ||
X !(p = index(p2, ' ')))
X continue;
X p++;
X if (p2 = any(p, " \t"))
X *p2 = 0;
X }
X } else if (search_to) {
X if (!(p = header_field(n, "to")) &&
X !(p = header_field(n, "apparently-to")))
X break;
X } else if (*search_hdr) {
X if (!(p = header_field(n, search_hdr)))
X break;
X }
X if (icase)
X p = lcase_strcpy(buf, p);
#ifdef REGCMP
X val = !!regex(err, p, NULL); /* convert value to a boolean */
#else /* REGCMP */
X val = re_exec(p);
#endif /* REGCMP */
X if (val == -1) { /* doesn't apply in system V */
X print("Internal error for pattern search.\n");
X clear_msg_list(ret_list); /* it doesn't matter, really */
X return -1;
X }
X if (val) {
X set_msg_bit(ret_list, n);
X cnt--, matches++;
X break;
X }
X if (search_subj || search_from || search_to || *search_hdr)
X break;
X else
X bytes += strlen(p);
X }
X }
X return matches;
}
X
#ifdef CURSES
/*
X * search for a pattern in composed message headers -- also see next function
X * flags == 0 forward search (prompt).
X * flags == -1 continue search (no prompt).
X * flags == 1 backward search (prompt).
X */
search(flags)
register int flags;
{
X register char *p;
X char pattern[128];
X register int this_msg = current_msg, val = 0;
X static char *err = (char *)-1, direction;
X SIGRET (*oldint)(), (*oldquit)();
#ifdef REGCMP
X char *regcmp();
#else /* REGCMP */
X char *re_comp();
#endif /* REGCMP */
X
X if (msg_cnt <= 1) {
X print("Not enough messages to invoke a search.\n");
X return 0;
X }
X pattern[0] = '\0';
X if (flags == -1)
X print("continue %s search...", direction? "forward" : "backward");
X else
X print("%s search: ", flags? "backward" : "forward");
X if (flags > -1)
X if (Getstr(pattern, COLS-18, 0) < 0)
X return 0;
X else
X direction = !flags;
#ifdef REGCMP
X if (err && *pattern)
X xfree(err);
X else if (err == (char *)-1 && !*pattern) {
X print("No previous regular expression.");
X return 0;
X }
X if (*pattern && !(err = regcmp(pattern, NULL))) {
X print("Error in regcmp in %s", pattern);
X return 0;
X }
#else /* REGCMP */
X if (err = re_comp(pattern)) {
X print(err);
X return 0;
X }
#endif /* REGCMP */
X move(LINES-1, 0), refresh();
X on_intr();
X
X do {
X if (direction)
X current_msg = (current_msg+1) % msg_cnt;
X else
X if (--current_msg < 0)
X current_msg = msg_cnt-1;
X p = compose_hdr(current_msg);
#ifdef REGCMP
X val = !!regex(err, p, NULL); /* convert value to a boolean */
#else /* REGCMP */
X val = re_exec(p);
#endif /* REGCMP */
X if (val == -1) /* doesn't apply in system V */
X print("Internal error for pattern search.\n");
X } while (!val && current_msg != this_msg && isoff(glob_flags, WAS_INTR));
X
X if (ison(glob_flags, WAS_INTR)) {
X print("Pattern search interrupted.");
X current_msg = this_msg;
X } else if (val == 0)
X print("Pattern not found.");
X
X off_intr();
X return val;
}
#endif /* CURSES */
X
/*
X * Get just the month, day, and year from a date.
X * This is a temporary measure until the date compares in pick()
X * can be overhauled. It really should be in dates.c, but ...
X */
static
void
month_day_year(date, month, day, year)
char *date;
int *month, *day, *year;
{
X long gmt;
X char unused[4], zone[8];
X struct tm *t;
X extern long getzoff();
X
X (void) sscanf(date, "%ld%3c%s", &gmt, unused, zone);
X gmt += getzoff(zone);
X t = gmtime(&gmt);
X *month = t->tm_mon;
X *day = t->tm_mday;
X *year = t->tm_year;
}
X
/*
X * parse a user given date string and set mdy[] array with correct
X * values. Return 0 on failure.
X */
date1(p)
register char *p;
{
X register char *p2;
X long t;
X int i;
X struct tm *today;
X
X if (*p == '-' || *p == '+') {
X before = !(after = *p == '+');
X skipspaces(1);
X }
X if (!isdigit(*p) && *p != '/') {
X print("syntax error on date: \"%s\"\n", p);
X return 0;
X }
X (void) time (&t);
X today = localtime(&t);
X for (i = 0; i < 3; i++)
X if (!p || !*p || *p == '/') {
X switch(i) { /* default to today's date */
X case 0: mdy[0] = today->tm_mon;
X when 1: mdy[1] = today->tm_mday;
X when 2: mdy[2] = today->tm_year;
X }
X if (p && *p)
X p++;
X } else {
X p2 = (*p)? index(p+1, '/') : NULL;
X mdy[i] = atoi(p); /* atoi will stop at the '/' */
X if (i == 0 && (--(mdy[0]) < 0 || mdy[0] > 11)) {
X print("Invalid month: %s\n", p);
X return 0;
X } else if (i == 1 && (mdy[1] < 1 || mdy[1] > 31)) {
X print("Invalid day: %s\n", p);
X return 0;
X }
X if (p = p2) /* set p to p2 and check to see if it's valid */
X p++;
X }
X return 1;
}
X
/*
X * Parse arguments specifying days/months/years "ago" (relative to today).
X * Legal syntax: -ago [+-][args]
X * where "args" is defined to be:
X * [0-9]+[ ]*[dD][a-Z]*[ ,]*[0-9]+[mM][a-Z]*[ ,]*[0-9]+[ ]*[yY][a-Z]*
X * 1 or more digits, 0 or more spaces, d or D followed by 0 or more chars,
X * 0 or more whitespaces or commas, repeat for months and years...
X * Examples:
X * 1 day, 2 months, 0 years
X * 2 weeks 1 year
X * 10d, 5m
X * 3w
SHAR_EOF
true || echo 'restore of pick.c failed'
fi
echo 'End of part 19'
echo 'File pick.c is continued in part 20'
echo 20 > _shar_seq_.tmp
exit 0
exit 0 # Just in case...
--
Kent Landfield INTERNET: kent at sparky.IMD.Sterling.COM
Sterling Software, IMD UUCP: uunet!sparky!kent
Phone: (402) 291-8300 FAX: (402) 291-4362
Please send comp.sources.misc-related mail to kent at uunet.uu.net.
More information about the Comp.sources.misc
mailing list