argv@zipcode.com (Dan Heller) (04/22/91)
Submitted-by: Dan Heller <argv@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@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@uunet.uu.net.