home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-05-06 | 54.9 KB | 1,868 lines |
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # If this archive is complete, you will see the following message at the end:
- # "End of archive 9 (of 19)."
- # Contents: mush/doproc.c mush/mail.c.a
- # Wrapped by argv@turnpike on Wed May 2 13:59:29 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'mush/doproc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mush/doproc.c'\"
- else
- echo shar: Extracting \"'mush/doproc.c'\" \(21819 characters\)
- sed "s/^X//" >'mush/doproc.c' <<'END_OF_FILE'
- X/* @(#)doproc.c (c) copyright 10/18/86 (Dan Heller) */
- X
- X/* do main panel item procedures */
- X#include "mush.h"
- X
- Xextern void start_textsw_edit();
- Xvoid set_comp_items();
- X
- Xextern Panel_item
- X file_item, folder_text_item, folder_item, msg_num_item, read_item,
- X reply_item, save_item, sub_hdr_item[6];
- X
- X/* following macro is for the next two procedures */
- X#define hdr_item(item) \
- X (item == sub_hdr_item[0] || item == sub_hdr_item[1] || \
- X item == sub_hdr_item[2] || item == sub_hdr_item[3] || \
- X item == sub_hdr_item[4] || item == sub_hdr_item[5])
- X
- Xvoid
- Xdelete_mail(item, value, event)
- Xregister Panel_item item;
- Xint value;
- Xregister Event *event;
- X{
- X int val = value; /* save cuz we reset value immediately */
- X u_long bang = ison(glob_flags, IGN_BANG);
- X char buf[128];
- X
- X (void) panel_set(item, PANEL_VALUE, 0, 0);
- X if (hdr_item(item) && event_id(event) != MS_LEFT || val == 2) {
- X help(0, "delete", tool_help);
- X return;
- X }
- X /* delete current message */
- X wprint(sprintf(buf, "\\%sdelete %s\n",
- X ((event_id(event) == MS_LEFT || val == 0)? "" : "un"),
- X panel_get_value(msg_num_item)) + 1); /* +1 skips the backslash */
- X turnon(glob_flags, IGN_BANG);
- X (void) cmd_line(buf, msg_list);
- X if (!bang)
- X turnoff(glob_flags, IGN_BANG);
- X}
- X
- Xvoid
- Xread_mail(item, value, event)
- XPanel_item item;
- XEvent *event;
- X{
- X int this_msg = current_msg;
- X
- X /* check "event" in case we were called from hdr_sw.c
- X * in which case event would be NULL
- X */
- X if (event && event_id(event) == MS_RIGHT && item &&
- X (item == read_item ||
- X (item == sub_hdr_item[0] || item == sub_hdr_item[1]))) {
- X (void) help(0, "next", tool_help);
- X return;
- X }
- X if (item && (item == sub_hdr_item[4] || item == sub_hdr_item[5])) {
- X (void) help(0, "Menu Read", tool_help);
- X return;
- X }
- X if (!msg_cnt) {
- X wprint ("No Mail.\n");
- X return;
- X }
- X if (item && item == read_item || ison(msg[current_msg].m_flags, DELETE))
- X (void) next_msg();
- X if (this_msg != current_msg || ison(msg[current_msg].m_flags, UNREAD) ||
- X (current_msg < n_array[0] || current_msg > n_array[screen])) {
- X set_isread(current_msg);
- X (void) do_hdrs(0, DUBL_NULL, NULL);
- X }
- X if (isoff(msg[current_msg].m_flags, DELETE))
- X display_msg(current_msg, (u_long)0);
- X}
- X
- X/* the panel button that says "filename" and "directory", etc... text item */
- XPanel_setting
- Xfile_dir(item, event)
- XPanel_item item;
- XEvent *event;
- X{
- X register char *p;
- X u_long bang = ison(glob_flags, IGN_BANG);
- X char buf[MAXPATHLEN];
- X
- X if (event_id(event) == ESC) {
- X /* file expansion request */
- X int n;
- X char **files;
- X p = panel_get_value(item);
- X (void) sprintf(buf, "%s*", p);
- X timeout_cursors(1);
- X if ((n = filexp(buf, &files)) > 0) {
- X Debug("%d: ",n), print_argv(files);
- X if (n > 1) {
- X n = lcprefix(files, 0);
- X files[0][n] = 0;
- X }
- X panel_set_value(item, trim_filename(files[0]));
- X free_vec(files);
- X } else
- X errbell(n); /* see curs_io.c */
- X timeout_cursors(0);
- X return PANEL_NONE;
- X }
- X
- X if (item == folder_text_item) {
- X (void) sprintf(buf, "folder %s %s",
- X (ison(glob_flags, READ_ONLY) || ison(glob_flags, DO_UPDATE) &&
- X !ask("Folder has been modified. Update changes?"))? "!" : "",
- X panel_get_value(folder_text_item));
- X }
- X else if (item == file_item) {
- X register char *b = buf;
- X char msgstr[BUFSIZ];
- X
- X if (event_id(event) == '\n' || event_id(event) == '\r')
- X b += Strcpy(buf, "save ");
- X else
- X b += Strcpy(buf, "write ");
- X if ((p = panel_get_value(msg_num_item)) && *p)
- X b += Strcpy(b, p);
- X else {
- X if (ison(msg[current_msg].m_flags, DELETE) &&
- X !do_set(set_options, "show_deleted")) {
- X (void) sprintf(msgstr, "Message %d deleted -- save anyway?",
- X current_msg+1);
- X if (ask(msgstr) != TRUE) {
- X wprint("Message not saved\n");
- X return PANEL_NONE;
- X }
- X }
- X b += strlen(sprintf(b, "%d", current_msg+1));
- X }
- X *b++ = ' ', *b = 0;
- X if (!(p = panel_get_value(item)) || !*p &&
- X (!(p = do_set(set_options, "mbox")) || !*p))
- X p = DEF_MBOX;
- X (void) sprintf(msgstr, "%s in \"%s\"?", buf, trim_filename(p));
- X if (ask(msgstr) != TRUE) {
- X wprint("Message not saved\n");
- X return PANEL_NONE;
- X }
- X (void) strcpy(b, p); /* now add to command */
- X }
- X turnon(glob_flags, IGN_BANG);
- X (void) cmd_line(buf, msg_list);
- X if (!bang)
- X turnoff(glob_flags, IGN_BANG);
- X return PANEL_NONE;
- X}
- X
- X/*
- X * callback routine for the panel items that need filename input.
- X * (folder and save)
- X */
- Xvoid
- Xdo_file_dir(item, value, event)
- XPanel_item item;
- Xint value;
- XEvent *event;
- X{
- X char buf[BUFSIZ];
- X u_long bang = ison(glob_flags, IGN_BANG);
- X
- X if (item == folder_item) {
- X (void) sprintf(buf, "folder %s ",
- X (ison(glob_flags, READ_ONLY) || ison(glob_flags, DO_UPDATE) &&
- X !ask("Folder has been modified. Update changes?"))? "!" : "");
- X if (event_id(event) == MS_LEFT) {
- X char *p = panel_get_value(folder_text_item);
- X if (!*p) {
- X ok_box("Enter folder name.");
- X return;
- X }
- X (void) strcat(buf, p);
- X } else if (!value)
- X (void) strcat(buf, "%");
- X else if (value == 1)
- X (void) strcat(buf, "&");
- X else if (value == 2)
- X (void) strcat(buf, "#");
- X else
- X (void) strcat(buf, panel_get(item, PANEL_CHOICE_STRING, value));
- X } else if (item == save_item) {
- X char msgstr[BUFSIZ], *p;
- X (void) strcpy(buf, "save ");
- X if (event_id(event) == MS_LEFT) {
- X if (!strcmp("Filename:", panel_get(file_item,PANEL_LABEL_STRING))) {
- X event_id(event) = '\n'; /* let file_dir think it got a \n */
- X file_dir(file_item, event);
- X return;
- X }
- X } else if (value == 0) {
- X register char *p2 = (char *)panel_get_value(msg_num_item);
- X
- X if (!(p = do_set(set_options, "mbox")) || !*p)
- X p = DEF_MBOX;
- X if (p2 && *p2) {
- X (void) strcat(buf, p2);
- X (void) strcat(buf, " ");
- X }
- X (void) strcat(buf, p);
- X } else
- X (void) strcat(buf, p = panel_get(item, PANEL_CHOICE_STRING, value));
- X (void) sprintf(msgstr, "Save in %s? ", trim_filename(p));
- X if (ask(msgstr) != TRUE) {
- X wprint("Message not saved\n");
- X return;
- X }
- X }
- X turnon(glob_flags, IGN_BANG);
- X (void) cmd_line(buf, msg_list);
- X if (!bang)
- X turnoff(glob_flags, IGN_BANG);
- X (void) panel_set(item, PANEL_VALUE, 0, NULL); /* remove last value */
- X}
- X
- X/*ARGSUSED*/
- Xvoid
- Xdo_help(item, value, event)
- XPanel_item item;
- Xregister int value;
- XEvent *event;
- X{
- X register char *p, *helpfile = tool_help;
- X if (!event || event_id(event) == MS_LEFT)
- X value = 0;
- X switch(value) {
- X case 1: p = "help";
- X when 2: p = "mouse";
- X when 3: p = "windows";
- X when 4: p = "hdr_format", helpfile = cmd_help;
- X when 5: p = "msg_list", helpfile = cmd_help;
- X when 6: p = "folder";
- X otherwise: p = "general";
- X }
- X (void) help(0, p, helpfile);
- X}
- X
- X/*ARGSUSED*/
- Xvoid
- Xdo_update(item, value, event)
- XPanel_item item;
- Xint value;
- XEvent *event;
- X{
- X char *argv[2];
- X if (event && event_id(event) != MS_LEFT) {
- X if (value == 0) {
- X if (check_new_mail() == 0)
- X print("No new mail.\n");
- X } else
- X (void) help(0, "update", tool_help);
- X return;
- X }
- X argv[0] = "update";
- X argv[1] = NULL;
- X timeout_cursors(TRUE);
- X (void) folder(0, argv, NULL);
- X timeout_cursors(FALSE);
- X}
- X
- X/*ARGSUSED*/
- Xvoid
- Xtoolquit(item, value, event)
- XPanel_item item;
- Xint value;
- XEvent *event;
- X{
- X void wmgr_changestate(), wmgr_changelevel();
- X register int which;
- X
- X if (!value || event_id(event) == MS_LEFT) {
- X if (ison(glob_flags, DO_UPDATE)) {
- X do_update(NO_ITEM, 0, NO_EVENT);
- X turnoff(glob_flags, NEW_MAIL);
- X }
- X check_icons();
- X mail_status(0); /* lower flag (if up) print current num of msgs */
- X /* wmgr_changestate (window_get(tool, WIN_FD), rootfd, TRUE); */
- X /* wmgr_changelevel (window_get(tool, WIN_FD), parentfd, TRUE); */
- X window_set(tool, FRAME_CLOSED, TRUE, NULL);
- X is_iconic = ((int) window_get(tool, FRAME_CLOSED));
- X return;
- X } else if (value == 2) {
- X (void) help(0, "quit", tool_help);
- X return;
- X }
- X /* modify this to check for "abort" choice when ternary return values
- X * are possible!
- X */
- X if (isoff(glob_flags, DO_UPDATE) ||
- X ask("Folder has been modified -- update?")) {
- X if (!copyback("Quit anyway?"))
- X return;
- X }
- X cleanup(0);
- X}
- X
- X/*ARGSUSED*/
- Xvoid
- Xdo_lpr(item, value, event)
- XPanel_item item;
- Xint value;
- XEvent *event;
- X{
- X char buf[128];
- X
- X if (event && (event_id(event) == MS_LEFT || value == 1)) {
- X wprint("Sending message %d to printer...\n", current_msg+1);
- X (void) strcpy(buf, "lpr ");
- X if (value)
- X (void) sprintf(buf, "lpr \"%s\"", panel_get_value(msg_num_item));
- X timeout_cursors(TRUE);
- X (void) cmd_line(buf, msg_list);
- X timeout_cursors(FALSE);
- X } else
- X (void) help(0, "printer", tool_help);
- X}
- X
- X/* panel selection button pressed to send a letter.
- X * we've attached the sign panel item to this item to 1) avoid
- X * using a global and 2) make it general enough so that multiple
- X * compose windows can have multiple send_items and we can
- X * identify which sign/fortune items are associated with this
- X * particular letter. The fortune item is attached to the sign
- X * item.
- X */
- X/*ARGSUSED*/
- Xvoid
- Xdo_send(item, value, event)
- XPanel_item item;
- Xint value;
- Xregister Event *event;
- X{
- X Panel panel = (Panel)panel_get(item, PANEL_PARENT_PANEL);
- X Panel_item sign_item = (Panel_item)panel_get(item, PANEL_CLIENT_DATA);
- X Panel_item fortune_item =
- X (Panel_item)panel_get(sign_item, PANEL_CLIENT_DATA);
- X Textsw textsw = (Textsw)panel_get(panel, PANEL_CLIENT_DATA);
- X char *argv[5], buf[64];
- X char *file = (char *)window_get(textsw, TEXTSW_CLIENT_DATA);
- X char *p, *oldsign = NULL, *oldfortune = NULL;
- X Textsw save_sw = wprint_sw;
- X
- X if (textsw_store_file(textsw, file, 0, 0)) {
- X error("Can't save to %s", file);
- X return;
- X }
- X /* check if user changed variables before sending */
- X if (p = do_set(set_options, "autosign"))
- X oldsign = savestr(p);
- X if (panel_get_value(sign_item) && !oldsign)
- X cmd_line(strcpy(buf, "\\set autosign"), NULL);
- X else if (!panel_get_value(sign_item) && oldsign)
- X cmd_line(strcpy(buf, "\\unset autosign"), NULL);
- X if (p = do_set(set_options, "fortune"))
- X oldfortune = savestr(p);
- X if (panel_get_value(fortune_item) && !oldfortune)
- X (void) cmd_line(strcpy(buf, "set fortune"), NULL);
- X else if (!panel_get_value(fortune_item) && oldfortune)
- X (void) cmd_line(strcpy(buf, "\\unset fortune"), NULL);
- X wprint_sw = NULL;
- X wprint_sw = save_sw;
- X turnoff(glob_flags, IS_GETTING);
- X argv[0] = "mail";
- X argv[1] = "-Uh";
- X argv[2] = file;
- X argv[3] = NULL;
- X clear_msg_list(msg_list);
- X timeout_cursors(TRUE);
- X if (do_mail(3, argv, msg_list) == 0) {
- X (void) unlink(file);
- X set_comp_items(panel);
- X }
- X if (panel_get_value(sign_item) && !oldsign)
- X (void) cmd_line(strcpy(buf, "\\unset autosign"), NULL);
- X else if (!panel_get_value(sign_item) && oldsign) {
- X argv[0] = "set";
- X argv[1] = "autosign";
- X if (*oldsign) {
- X argv[2] = "=";
- X argv[3] = oldsign;
- X argv[4] = NULL;
- X (void) set(4, argv, NULL);
- X } else {
- X argv[2] = NULL;
- X (void) set(2, argv, NULL);
- X }
- X }
- X if (panel_get_value(fortune_item) && !oldfortune)
- X cmd_line(strcpy(buf, "\\unset fortune"), NULL);
- X else if (!panel_get_value(fortune_item) && oldfortune) {
- X argv[0] = "set";
- X argv[1] = "fortune";
- X if (*oldfortune) {
- X argv[2] = "=";
- X argv[3] = oldfortune;
- X argv[4] = NULL;
- X (void) set(4, argv, NULL);
- X } else {
- X argv[2] = NULL;
- X (void) set(2, argv, NULL);
- X }
- X }
- X xfree(oldsign), xfree(oldfortune);
- X timeout_cursors(FALSE);
- X}
- X
- X/*ARGSUSED*/
- Xvoid
- Xdo_include(item, value, event)
- XPanel_item item;
- Xint value;
- XEvent *event;
- X{
- X extern FILE *ed_fp;
- X char *p, buf[64], *file;
- X Textsw textsw = (Textsw)panel_get(panel_get(item, PANEL_PARENT_PANEL),
- X PANEL_CLIENT_DATA);
- X
- X if (event && event_id(event) == MS_LEFT)
- X value = 0;
- X if (value == 2) {
- X (void) help(0, "include", tool_help);
- X return;
- X }
- X p = panel_get_value(msg_num_item);
- X (void) sprintf(buf, "%c%c%s", *escape, value == 0? 'i' : 'f', p? p : "");
- X
- X file = (char *)window_get(textsw, TEXTSW_CLIENT_DATA);
- X if (textsw_store_file(textsw, file, 0, 0)) {
- X (void) ask("Something's wrong... Click anything.");
- X return;
- X }
- X if (ed_fp) {
- X (void) ask("tmpfile already in use... Click anything.");
- X (void) fclose(ed_fp);
- X }
- X if (!(ed_fp = mask_fopen(file, "a"))) {
- X error("Cannot open %s to append msg.", file);
- X return;
- X }
- X (void) add_to_letter(buf);
- X (void) fclose(ed_fp), ed_fp = NULL_FILE;
- X#ifdef SUN_4_0 /* SunOS 4.0+ */
- X window_set(textsw, TEXTSW_FILE_CONTENTS, file, NULL);
- X#else /* SUN_4_0 */
- X textsw_load_file(textsw, file, 1, 0, 0);
- X#endif /* SUN_4_0 */
- X window_set(textsw, TEXTSW_UPDATE_SCROLLBAR, NULL);
- X (void) unlink(file);
- X}
- X
- X/*ARGSUSED*/
- Xvoid
- Xdo_compose(item, value, event)
- XPanel_item item;
- Xint value;
- XEvent *event;
- X{
- X char buf[5];
- X Textsw textsw;
- X
- X if (event && event_id(event) != MS_LEFT) {
- X (void) help(0, "compose", tool_help);
- X return;
- X }
- X open_compose();
- X clear_msg_list(msg_list);
- X if (do_mail(0, DUBL_NULL, msg_list) == 0) {
- X#ifdef SUN_4_0
- X Panel panel = (Panel)window_get(compose_frame, FRAME_NTH_WINDOW, 1);
- X#else
- X Panel panel = (Panel)window_get(compose_frame, FRAME_NTH_WINDOW, 0);
- X#endif /* SUN_4_0 */
- X Textsw textsw = (Textsw)panel_get(panel, PANEL_CLIENT_DATA);
- X start_textsw_edit(textsw, TRUE);
- X set_comp_items(panel);
- X }
- X}
- X
- X/*
- X * notify proc for reply button -- also called from select.c (do_menu()) ,
- X * in which case "event" is null and "value" contains the message
- X * number of the message to reply to.
- X */
- X/*ARGSUSED*/
- Xvoid
- Xrespond_mail(item, value, event)
- XPanel_item item;
- Xint value;
- XEvent *event;
- X{
- X int tmp = current_msg;
- X char buf[256];
- X
- X if (event && event_id(event) == MS_LEFT)
- X value = 0;
- X if (event && value == 4) {
- X (void) help(0, "respond", tool_help);
- X return;
- X }
- X if (!msg_cnt) {
- X wprint("No messages to respond to.\n");
- X return;
- X }
- X if (ison(glob_flags, IS_GETTING)) {
- X wprint("Finish editing current message first.\n");
- X return;
- X }
- X if (!event)
- X tmp = value, value = 0;
- X open_compose();
- X (void) sprintf(buf, "%s %s %d",
- X (value == 2 || value == 3)? "\\replyall" : "\\replysender",
- X (value == 1 || value == 3)? "-i": NO_STRING, tmp+1);
- X if (cmd_line(buf, NULL) != -1) {
- X#ifdef SUN_4_0
- X Panel panel = (Panel)window_get(compose_frame, FRAME_NTH_WINDOW, 1);
- X#else
- X Panel panel = (Panel)window_get(compose_frame, FRAME_NTH_WINDOW, 0);
- X#endif /* SUN_4_0 */
- X Textsw textsw = (Textsw)panel_get(panel, PANEL_CLIENT_DATA);
- X wprint("Responding to message %d\n", tmp+1);
- X start_textsw_edit(textsw, FALSE);
- X set_comp_items(panel);
- X }
- X}
- X
- X/*ARGSUSED*/
- Xvoid
- Xload_from_file(item, value, event)
- XPanel_item item;
- Xint value;
- XEvent *event;
- X{
- X int x = 0;
- X Textsw textsw;
- X Panel_item filename_item = (Panel_item)panel_get(item, PANEL_CLIENT_DATA);
- X char *file, *p = panel_get_value(filename_item);
- X#ifndef SUN_4_0 /* SunOS 4.0+ */
- X char *sfile, buf[128];
- X extern FILE *ed_fp;
- X#endif /* SUN_4_0 */
- X
- X if (!*p) {
- X wprint("Specify Filename.\n");
- X return;
- X }
- X file = getpath(p, &x);
- X if (x == 1)
- X wprint("%s: is a directory.\n", p);
- X else if (x == -1)
- X wprint("%s: %s\n", p, file);
- X if (x)
- X return;
- X timeout_cursors(TRUE);
- X textsw = (Textsw)panel_get(panel_get(item, PANEL_PARENT_PANEL),
- X PANEL_CLIENT_DATA);
- X if (event_id(event) != MS_LEFT && value == 1)
- X /* replace */
- X textsw_load_file(textsw, file, 1, 0, 0);
- X else {
- X /* insert */
- X#ifdef SUN_4_0 /* SunOS 4.0+ */
- X window_set(textsw, TEXTSW_INSERT_FROM_FILE, file, NULL);
- X#else /* SUN_4_0 */
- X /* best we can do with pre 4.0 is save the current file
- X * and append the new file onto the end.
- X */
- X sfile = (char *)window_get(textsw, TEXTSW_CLIENT_DATA);
- X if (textsw_store_file(textsw, sfile, 0, 0)) {
- X (void) ask("Can't save file... Click anything.");
- X return;
- X }
- X if (ed_fp) {
- X (void) ask("tmpfile already in use... Click anything.");
- X fclose(ed_fp);
- X }
- X if (!(ed_fp = mask_fopen(sfile, "a"))) {
- X error("Cannot open %s.", sfile);
- X return;
- X }
- X (void) sprintf(buf, "%c%c%s", *escape, 'r', trim_filename(p));
- X (void) add_to_letter(buf);
- X (void) fclose(ed_fp), ed_fp = NULL_FILE;
- X textsw_load_file(textsw, sfile, 1, 0, 0);
- X (void) unlink(sfile);
- X#endif /* SUN_4_0 */
- X }
- X window_set(textsw, TEXTSW_UPDATE_SCROLLBAR, NULL);
- X panel_set_value(item, 0);
- X timeout_cursors(FALSE);
- X}
- X
- X/*ARGSUSED*/
- Xvoid
- Xsave_to_file(item, value, event)
- XPanel_item item;
- XEvent *event;
- X{
- X Panel_item filename_item = panel_get(item, PANEL_CLIENT_DATA);
- X char *file = panel_get_value(filename_item);
- X FILE *fp;
- X Textsw textsw = (Textsw)panel_get(panel_get(item, PANEL_PARENT_PANEL),
- X PANEL_CLIENT_DATA);
- X
- X if (!*file) {
- X wprint("Specify Filename\n");
- X return;
- X }
- X timeout_cursors(TRUE);
- X /* append to file -- no confirmation necessary */
- X if (fp = open_file(file, FALSE, TRUE)) {
- X char buf[BUFSIZ];
- X Textsw_index next_pos = 0, tmp;
- X Textsw_index length =
- X (Textsw_index)window_get(textsw, TEXTSW_LENGTH);
- X do {
- X tmp = next_pos;
- X next_pos = (Textsw_index) window_get(textsw, TEXTSW_CONTENTS,
- X next_pos, buf, sizeof(buf));
- X if (fwrite(buf, sizeof(char), (int)(next_pos - tmp), fp) == 0)
- X error("%s may be incomplete", file);
- X } while (next_pos < length);
- X (void) close_lock(file, fp);
- X wprint("Wrote %d bytes to %s\n", length, trim_filename(file));
- X }
- X timeout_cursors(FALSE);
- X}
- X
- Xvoid
- Xabort_mail(item, event)
- XPanel_item item;
- XEvent *event;
- X{
- X Panel panel = (Panel)panel_get(item, PANEL_PARENT_PANEL);
- X Textsw textsw = (Textsw)panel_get(panel, PANEL_CLIENT_DATA);
- X wprint("Aborted letter.\n");
- X textsw_reset(textsw, 0, 0);
- X rm_edfile(0);
- X set_comp_items(panel);
- X}
- X
- X/* set the compose panel items */
- Xvoid
- Xset_comp_items(panel)
- XPanel panel;
- X{
- X Panel_item item, next;
- X Textsw textsw = (Textsw)panel_get(panel, PANEL_CLIENT_DATA);
- X int getting = ison(glob_flags, IS_GETTING) != 0;
- X int i = 0;
- X
- X window_set(textsw, TEXTSW_READ_ONLY, !getting, NULL);
- X /* remove next line when multiple composes become a reality */
- X (void) panel_set(reply_item, PANEL_SHOW_ITEM, !getting, NULL);
- X /* skip "close" item */
- X item = (Panel_item) panel_get(panel, PANEL_FIRST_ITEM);
- X for (item = (Panel_item) panel_get(item, PANEL_NEXT_ITEM);
- X item; item = next) {
- X next = (Panel_item) panel_get(item, PANEL_NEXT_ITEM);
- X (void) panel_set(item,
- X PANEL_SHOW_ITEM, (i++ < 1)? !getting : getting, NULL);
- X }
- X}
- X
- X/*
- X * Ask a yes/no question and return an answer: TRUE or FALSE.
- X */
- Xask(question)
- Xchar *question;
- X{
- X#ifdef SUN_4_0 /* SunOS 4.0+ */
- X return alert_prompt(tool, (Event *)NULL,
- X ALERT_MESSAGE_STRINGS, question, NULL,
- X ALERT_BUTTON_YES, "Yes",
- X ALERT_BUTTON_NO, "No",
- X NULL) == ALERT_YES;
- X#else /* SUN_4_0 */
- X Event event;
- X struct prompt prompt;
- X Rect *rect = (Rect *)window_get(tool, WIN_RECT);
- X char buf[MAXPATHLEN];
- X
- X (void) sprintf(buf,
- X "%s \nPress LEFT Button to Confirm. Anything else to cancel.",
- X question);
- X prompt.prt_rect.r_left = rect->r_left + (rect->r_width / 3);
- X prompt.prt_rect.r_top = rect->r_top + (rect->r_height / 3);
- X prompt.prt_rect.r_width = prompt.prt_rect.r_height = PROMPT_FLEXIBLE;
- X prompt.prt_font = mush_font;
- X prompt.prt_text = buf;
- X
- X menu_prompt(&prompt, &event, window_get(tool, WIN_FD));
- X return event_id(&event) == MS_LEFT;
- X#endif /* SUN_4_0 */
- X}
- X
- Xvoid
- Xok_box(buf)
- Xchar *buf;
- X{
- X#ifdef SUN_4_0
- X (void) alert_prompt(tool, (Event *)NULL,
- X ALERT_MESSAGE_STRINGS, buf, NULL,
- X ALERT_BUTTON_YES, "Ok",
- X NULL);
- X#else /* SUN_4_0 */
- X Event event;
- X struct prompt prompt;
- X Rect *rect = (Rect *)window_get(tool, WIN_RECT);
- X (void) strcat(buf, " \nPress LEFT Button to Continue.");
- X prompt.prt_rect.r_left = rect->r_left + (rect->r_width / 3);
- X prompt.prt_rect.r_top = rect->r_top + (rect->r_height / 3);
- X prompt.prt_rect.r_width = prompt.prt_rect.r_height = PROMPT_FLEXIBLE;
- X prompt.prt_font = mush_font;
- X prompt.prt_text = buf;
- X menu_prompt(&prompt, &event, window_get(tool, WIN_FD));
- X#endif /* SUN_4_0 */
- X}
- X
- XPanel_setting
- Xmsg_num_done(item, event)
- XPanel_item item;
- XEvent *event;
- X{
- X char buf[82];
- X u_long bang = ison(glob_flags, IGN_BANG);
- X register char *p;
- X int n;
- X
- X if (event_id(event) != '\n' && event_id(event) != '\r') {
- X (void) help(0, "message range", tool_help);
- X return PANEL_NONE;
- X }
- X (void) sprintf(buf, "headers %s", (p = (char *)panel_get_value(item)));
- X (void) panel_set(item, PANEL_VALUE, NO_STRING, NULL);
- X if (!(n = chk_msg(p)))
- X return PANEL_NONE;
- X current_msg = --n;
- X turnon(glob_flags, IGN_BANG);
- X (void) cmd_line(buf, msg_list);
- X if (!bang)
- X turnoff(glob_flags, IGN_BANG);
- X (void) display_msg(n, (u_long)0);
- X return PANEL_NONE;
- X}
- X
- Xvoid
- Xdo_sort(item, value, event)
- XPanel_item item;
- Xint value;
- XEvent *event;
- X{
- X char *argv[3], list[MAXMSGS_BITS];
- X char *p = (char *)panel_get_value(msg_num_item);
- X int n = 0;
- X
- X if (p && *p) {
- X argv[0] = p;
- X argv[1] = NULL;
- X n = get_msg_list(argv, list);
- X }
- X argv[0] = "sort";
- X argv[2] = NULL;
- X
- X if (event_id(event) == MS_LEFT)
- X argv[1] = do_set(set_options, "sort");
- X else switch(value) {
- X case 0: argv[1] = "d";
- X when 1: argv[1] = "a";
- X when 2: argv[1] = "l";
- X when 3: argv[1] = "R";
- X when 4: argv[1] = "s";
- X when 5: argv[1] = "S";
- X when 6: (void) help(0, "sort", tool_help);
- X }
- X if (value != 6) {
- X if (n > 0) {
- X turnon(glob_flags, IS_PIPE);
- X (void) sort(2, argv, list);
- X turnoff(glob_flags, IS_PIPE);
- X } else
- X (void) sort(2, argv, NULL);
- X (void) do_hdrs(0, DUBL_NULL, NULL);
- X }
- X (void) panel_set(item, PANEL_VALUE, 0, NULL);
- X}
- X
- Xvoid
- Xdo_options(item, value, event)
- XPanel_item item;
- Xint value;
- XEvent *event;
- X{
- X if (event_id(event) == MS_LEFT) {
- X view_options();
- X return;
- X }
- X switch (value) {
- X case 0:
- X view_options();
- X when 1:
- X do_ignore();
- X when 2:
- X do_aliases();
- X }
- X}
- END_OF_FILE
- if test 21819 -ne `wc -c <'mush/doproc.c'`; then
- echo shar: \"'mush/doproc.c'\" unpacked with wrong size!
- fi
- # end of 'mush/doproc.c'
- fi
- if test -f 'mush/mail.c.a' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mush/mail.c.a'\"
- else
- echo shar: Extracting \"'mush/mail.c.a'\" \(30778 characters\)
- sed "s/^X//" >'mush/mail.c.a' <<'END_OF_FILE'
- X/* @(#)mail.c (c) copyright 1986 (Dan Heller) */
- X
- X#include "mush.h"
- X
- X/*
- X * mail.c --
- X * do_mail() external interface to these functions; parses options.
- X * mail_someone() called from do_mail() to begin composing the message.
- X * start_file() creates the editing file and reset signal catching.
- X * add_to_letter() adds the next line to letter --determine ~ escapes.
- X * finish_up_letter() prompts for Cc:, verifies send, adds signatures.
- X * send_it() expands aliases, invokes mailer, sends to record file.
- X * add_headers() adds all headers to a FILE *, reads draft files
- X * rm_edfile() signals are directed here. remove letter, longjmp
- X * dead_letter() make a dead.letter if mail failed.
- X */
- X
- Xstatic char Subject[BUFSIZ],To[HDRSIZ],Cc[HDRSIZ],Bcc[HDRSIZ],in_reply_to[256];
- Xstatic int killme;
- Xstatic u_long flags;
- Xstatic SIGRET (*oldterm)(), (*oldint)(), (*oldquit)();
- Xstatic int finish_up_letter(), send_it(), start_file();
- Xstatic long add_headers();
- Xstatic jmp_buf cntrl_c_buf;
- Xstatic char *Hfile, *edfile;
- XFILE *ed_fp;
- Xchar *hfile, *mktemp();
- X
- X/* argc and argv could be null if coming from tool mode compose */
- Xdo_mail(n, argv, list)
- Xregister int n; /* no need for "argc", so use the space for a variable */
- Xregister char **argv, *list;
- X{
- X char firstchar = (argv)? **argv: 'm';
- X char *to = NULL, *cc = NULL, *addcc = NULL, *bcc = NULL, *subj = NULL;
- X char *route = NULL;
- X char inc_list[MAXMSGS_BITS], buf[HDRSIZ];
- X u_long flgs = 0;
- X
- X if (ison(glob_flags, IS_GETTING)) {
- X wprint("You must finish the letter you are editing first.\n");
- X return -1;
- X }
- X if (ison(glob_flags, DO_PIPE)) {
- X wprint("You can't pipe through the mail command.\n");
- X return -1;
- X }
- X clear_msg_list(inc_list);
- X hfile = Hfile = NULL;
- X
- X /* If piped to mail, include the messages piped */
- X if (ison(glob_flags, IS_PIPE) ||
- X (lower(firstchar) == 'r' && do_set(set_options, "autoinclude"))) {
- X turnon(flgs, INCLUDE);
- X bitput(list, inc_list, msg_cnt, =);
- X }
- X /* Set SIGN and DO_FORTUNE now so we can turn them off later */
- X if (do_set(set_options, "autosign"))
- X turnon(flgs, SIGN);
- X if (do_set(set_options, "fortune"))
- X turnon(flgs, DO_FORTUNE);
- X while (argv && *argv && *++argv && **argv == '-') {
- X n = 1;
- X while (n && argv[0][n])
- X switch (argv[0][n]) {
- X#ifdef VERBOSE_ARG
- X case 'v': turnon(flgs, VERBOSE); n++; break;
- X#endif /* VERBOSE_ARG */
- X case 'H':
- X if (argv[1]) {
- X n = 0;
- X Hfile = *++argv;
- X } else {
- X wprint("Must specify a file\n");
- X return -1;
- X }
- X when 'h':
- X if (argv[1]) {
- X n = -1; /* it gets incremented below */
- X hfile = savestr(*++argv);
- X if (ison(glob_flags, REDIRECT)) {
- X turnoff(glob_flags, REDIRECT);
- X turnon(flgs, SEND_NOW);
- X }
- X } else {
- X wprint("Must specify a file containing headers\n");
- X return -1;
- X }
- X /* Fall through */
- X case 'E': turnon(flgs, EDIT_HDRS); n++;
- X when 'e': turnon(flgs, EDIT); n++;
- X when 'F': turnon(flgs, DO_FORTUNE); n++;
- X when 'b':
- X if (argv[1]) {
- X n = 0, bcc = *++argv;
- X fix_up_addr(bcc);
- X } else {
- X wprint("Must specify blind-carbon list\n");
- X return -1;
- X }
- X when 'c':
- X if (argv[1]) {
- X n = 0, addcc = *++argv;
- X fix_up_addr(addcc);
- X } else {
- X wprint("Must specify carbon-copy list\n");
- X return -1;
- X }
- X when 's':
- X if (argv[1])
- X n = 0, subj = *++argv;
- X else
- X n++, turnon(flgs, NEW_SUBJECT);
- X when 'i': case 'I': case 'f': {
- X int m;
- X if (!msg_cnt) {
- X wprint("No message to include!\n");
- X return -1;
- X }
- X if (argv[0][n] == 'i') {
- X turnon(flgs, INCLUDE);
- X turnoff(flgs, INCLUDE_H);
- X turnoff(flgs, FORWARD);
- X } else if (argv[0][n] == 'I') {
- X turnon(flgs, INCLUDE_H);
- X turnoff(flgs, INCLUDE);
- X turnoff(flgs, FORWARD);
- X } else if (argv[0][n] == 'f') {
- X turnon(flgs, FORWARD);
- X turnon(flgs, SEND_NOW);
- X turnoff(flgs, INCLUDE_H);
- X turnoff(flgs, INCLUDE);
- X }
- X /* "-i 3-5" or "-i3-5" Consider the latter case first */
- X if (!argv[0][++n])
- X argv++, n = 0;
- X (*argv) += n;
- X m = get_msg_list(argv, inc_list);
- X (*argv) -= n;
- X if (m == -1)
- X return -1;
- X /* if there were args, then go back to the first char
- X * in the next argv
- X */
- X if (m)
- X n = 0;
- X if (!n) /* n may be 0 from above! */
- X argv += (m-1);
- X }
- X when 'U':
- X turnon(flgs, SEND_NOW);
- X n++;
- X when 'u':
- X turnoff(flgs, SIGN);
- X turnoff(flgs, DO_FORTUNE);
- X n++;
- X when 'r':
- X if (lower(firstchar) == 'r') {
- X route = *++argv;
- X n = 0;
- X break;
- X }
- X /* fall thru */
- X default:
- X if (argv[0][n] != '?') {
- X wprint("%c: unknown option\n\n", argv[0][n]);
- X return -1;
- X } else
- X return help(0, "mail", cmd_help);
- X }
- X }
- X if (isoff(flgs, FORWARD)) {
- X if (ison(flgs, SEND_NOW)) {
- X if (!hfile && !Hfile) {
- X wprint("Can't send immediately without draft file.\n");
- X return -1;
- X }
- X turnoff(flgs, EDIT); /* -U overrides -e */
- X } else if (do_set(set_options, "autoedit"))
- X turnon(flgs, EDIT);
- X } else if (ison(flgs, EDIT)) /* -e modifies -f */
- X turnoff(flgs, SEND_NOW);
- X#ifdef VERBOSE_ARG
- X if (do_set(set_options, "verbose"))
- X turnon(flgs, VERBOSE);
- X#endif /* VERBOSE_ARG */
- X *in_reply_to = *To = *Subject = *Cc = *Bcc = 0;
- X if (lower(firstchar) == 'r') {
- X char *in_reply_fmt, *pcc = NULL;
- X to = To, cc = Cc;
- X /*
- X * Generate a reply to all the messages passed to respond(). This
- X * list is different than the include-msg list above. Get info about
- X * whom the messages were sent to for reply-all.
- X * BUG: currently, redundant addresses aren't pruned from Bcc list!
- X */
- X for (n = 0; n < msg_cnt; n++)
- X if (msg_bit(list, n)) {
- X if (to != To)
- X *to++ = ',', *to++ = ' ';
- X (void) reply_to(n, (firstchar == 'R'), buf);
- X if (strlen(buf) + (to - To) > sizeof(To) - 1) {
- X wprint("# recipients exceeded at msg %d\n", n);
- X break;
- X }
- X to += Strcpy(to, buf);
- X if (firstchar == 'R') {
- X if (pcc = cc_to(n, buf)) {
- X /* if there was a previous cc, append ", " */
- X if (cc != Cc)
- X *cc++ = ',', *cc++ = ' ';
- X if (strlen(pcc) + (cc - Cc) > sizeof(Cc) - 1)
- X wprint("# Cc's exceeded at msg %d\n", n);
- X else
- X cc += Strcpy(cc, pcc);
- X }
- X }
- X /* remove redundant addresses now, or headers could get too
- X * long before the list runs out (it still might)
- X */
- X rm_redundant_addrs(To, Cc);
- X to = To + strlen(To);
- X cc = Cc + strlen(Cc);
- X }
- X /* clean up end of Cc line for replyall's */
- X while (*cc == ' ' || *cc == ',')
- X *cc-- = '\0';
- X if (firstchar == 'R' && !do_set(set_options, "metoo")) {
- X /* Each reply_to() call above will leave at least
- X * one person in To. If that one person was us,
- X * we need to get removed from the complete list.
- X */
- X (void) take_me_off(to);
- X }
- X to = To, cc = Cc;
- X if (route || (route = do_set(set_options, "auto_route")))
- X /* careful! This routine could add lots-o-bytes and lose addresses
- X * to avoid writing out of segment.
- X */
- X route_addresses(To, Cc, route);
- X if (in_reply_fmt = do_set(set_options, "in_reply_to"))
- X /* "9" here is a magic # --see compose_hdr() */
- X (void) strcpy(in_reply_to,
- X format_hdr(current_msg, in_reply_fmt, FALSE)+9);
- X }
- X if (ison(flgs, FORWARD) && ison(flgs, EDIT) ||
- X lower(firstchar) == 'r' && isoff(flgs, NEW_SUBJECT)) {
- X turnoff(flgs, NEW_SUBJECT);
- X if (subj && *subj && (isoff(flgs, FORWARD) || ison(flgs, EDIT)))
- X subj = strcpy(Subject, subj);
- X else if (subj = subject_to(current_msg, buf))
- X subj = strcpy(Subject, buf + 4*(lower(firstchar) != 'r'));
- X } else if (isoff(flgs, NEW_SUBJECT) && isoff(flgs, FORWARD) &&
- X (do_set(set_options, "ask") || do_set(set_options, "asksub")))
- X turnon(flgs, NEW_SUBJECT);
- X if (argv && *argv) {
- X char buf[HDRSIZ];
- X (void) argv_to_string(buf, argv);
- X fix_up_addr(buf);
- X to = &To[strlen(To)];
- X if (*To)
- X *to++ = ',', *to++ = ' ';
- X (void) strcpy(to, buf);
- X to = To;
- X }
- X if (addcc && *addcc) {
- X cc = &Cc[strlen(Cc)];
- X if (*Cc)
- X *cc++ = ',', *cc++ = ' ';
- X (void) strcpy(cc, addcc); /* addcc has already been fixed up */
- X cc = Cc;
- X }
- X /* remove any redundant addresses that just got added */
- X rm_redundant_addrs(To, Cc);
- X if (bcc && *bcc)
- X (void) strncpy(Bcc, bcc, sizeof(Bcc)); /* bcc already fixed up */
- X bcc = Bcc;
- X
- X return mail_someone(to, subj, cc, bcc, flgs, inc_list);
- X}
- X
- Xstatic
- Xmail_someone(to, subject, cc, bcc, flgs, list)
- Xregister char *to, *subject, *cc, *bcc, *list;
- Xu_long flgs;
- X{
- X register char *p;
- X
- X flags = flgs;
- X if (to && *to) {
- X if (!*To)
- X (void) strncpy(To, to, sizeof(To));
- X } else
- X to = NO_STRING;
- X if (subject && *subject) {
- X if (!*Subject)
- X (void) strncpy(Subject, subject, sizeof(Subject));
- X } else
- X subject = NO_STRING;
- X if (cc && *cc) {
- X if (!*Cc)
- X (void) strncpy(Cc, cc, sizeof(Cc));
- X } else
- X Cc[0] = '\0';
- X if (bcc && *bcc) {
- X if (!*Bcc)
- X (void) strncpy(Bcc, bcc, sizeof(Bcc));
- X } else
- X Bcc[0] = '\0';
- X
- X if (ison(glob_flags, REDIRECT)) {
- X /*
- X * NOTE: Could change this to finish_up_letter() to allow
- X * signatures to be appended. The -U! option to mush would
- X * be extended to suppress signing when redirection is on.
- X */
- X int sent = send_it();
- X if (sent == -1) {
- X wprint("Message not sent!\n");
- X rm_edfile(-1);
- X }
- X return sent;
- X }
- X /* if (!*to) then prompting will be done */
- X if (!istool && !hfile) {
- X if (p = set_header("To: ", to, !*to)) {
- X if (!*to) /* if user typed To-line here, fix up the addresses */
- X fix_up_addr(p);
- X (void) strcpy(To, p);
- X }
- X if (!*To && ison(flags, FORWARD) && ison(flags, SEND_NOW)) {
- X turnoff(flags, SEND_NOW); /* user must edit To: line or do again */
- X print("(You must add a To: address.)\n");
- X }
- X /* don't prompt for subject if forwarding mail */
- X if (isoff(flags, FORWARD) && (*subject || ison(flags, NEW_SUBJECT)) &&
- X (p = set_header("Subject: ", subject,
- X !*subject && ison(flags, NEW_SUBJECT))))
- X (void) strcpy(Subject, p);
- X if (*Cc || ison(flags, EDIT_HDRS) && do_set(set_options, "askcc")) {
- X if ((p = set_header("Cc: ", cc, !*Cc)) && *p) {
- X fix_up_addr(p);
- X (void) strcpy(Cc, p);
- X }
- X }
- X if (*Bcc)
- X print("Bcc: %s\n", Bcc);
- X putchar('\n');
- X }
- X
- X /* If forwarding w/o editing, start a new file for each. */
- X if (ison(flags, FORWARD) && ison(flags, SEND_NOW)) {
- X char fwd[MAXMSGS_BITS];
- X register int i;
- X clear_msg_list(fwd);
- X for (i = 0; i < msg_cnt; i++)
- X if (msg_bit(list, i)) {
- X set_msg_bit(fwd, i);
- X if (start_file(fwd) < 0)
- X return -1;
- X turnon(msg[i].m_flags, FORWARD);
- X if (isoff(glob_flags, READ_ONLY))
- X turnon(glob_flags, DO_UPDATE);
- X clear_msg_list(fwd);
- X }
- X } else
- X return start_file(list);
- X return 0;
- X}
- X
- Xstatic
- Xstart_file(list)
- Xchar *list;
- X{
- X register char *dir;
- X register int i;
- X char line[MAXPATHLEN];
- X int had_hfile = FALSE;
- X
- X /* getdir() uses the home directory if no tmpdir */
- X if (!(dir = getdir(do_set(set_options, "tmpdir"))))
- Xalted:
- X dir = ALTERNATE_HOME;
- X (void) mktemp(sprintf(line, "%s/%s", dir, EDFILE));
- X strdup(edfile, line);
- X if (!(ed_fp = mask_fopen(edfile, "w+"))) {
- X if (strcmp(dir, ALTERNATE_HOME))
- X goto alted;
- X error("can't create %s", edfile);
- X return -1;
- X }
- X if (!istool) {
- X oldint = signal(SIGINT, rm_edfile);
- X oldquit = signal(SIGQUIT, rm_edfile);
- X oldterm = signal(SIGTERM, rm_edfile);
- X }
- X
- X if (istool && isoff(flags, SEND_NOW) ||
- X (isoff(flags, FORWARD) || isoff(flags, SEND_NOW)) &&
- X (ison(flags, EDIT_HDRS) || do_set(set_options, "edit_hdrs"))) {
- X turnon(flags, EDIT_HDRS);
- X if (hfile)
- X had_hfile = TRUE;
- X if (add_headers(NULL_FILE, &ed_fp, 1, flags) == (long) -1)
- X return -1;
- X }
- X if (Hfile) {
- X (void) file_to_fp(Hfile, ed_fp, "r");
- X Hfile = NULL;
- X had_hfile = TRUE;
- X }
- X if (istool && isoff(flags, SEND_NOW))
- X strdup(hfile, edfile);
- X
- X /* if flags call for it, include current message (with header?) */
- X if (ison(flags, INCLUDE|FORWARD|INCLUDE_H)) {
- X long copy_flgs = 0, is_forw = ison(flags, FORWARD);
- X char buf[sizeof(To)];
- X if (!is_forw) {
- X turnon(copy_flgs, INDENT);
- X if (ison(flags, INCLUDE_H) &&
- X !chk_option("alwaysignore", "include"))
- X turnon(copy_flgs, NO_IGNORE);
- X else if (ison(flags, INCLUDE))
- X turnon(copy_flgs, NO_HEADER);
- X } else if (ison(flags, SEND_NOW) ||
- X !chk_option("alwaysignore", "forward"))
- X turnon(copy_flgs, FORWARD); /* FORWARD implies NO_IGNORE */
- X#ifdef MSG_SEPARATOR
- X turnon(copy_flgs, NO_SEPARATOR);
- X#endif /* MSG_SEPARATOR */
- X for (i = 0; i < msg_cnt; i++)
- X if (msg_bit(list, i)) {
- X if (is_forw && isoff(flags, SEND_NOW)) {
- X (void) reply_to(i, FALSE, buf);
- X (void) fprintf(ed_fp,"--- Forwarded mail from %s\n\n",buf);
- X }
- X wprint("%sing message %d ...",
- X is_forw? "forward" : "includ", i+1);
- X wprint("(%d lines)\n",
- X copy_msg(i, ed_fp, (u_long) copy_flgs, NULL));
- X set_isread(i); /* if we included it, we read it, right? */
- X if (is_forw && isoff(flags, SEND_NOW))
- X (void) fprintf(ed_fp,
- X "\n--- End of forwarded message from %s\n", buf);
- X if (!is_forw || isoff(flags, SEND_NOW))
- X (void) fputc('\n', ed_fp);
- X }
- X (void) fflush(ed_fp);
- X }
- X if (!istool && ison(glob_flags, WARNING)) {
- X if (escape && strncmp(escape, DEF_ESCAPE, 1))
- X print("(escape character is set to `%c')\n", *escape);
- X if (wrapcolumn && wrapcolumn < 20)
- X print("(warning: wrapping only %d columns from the left!)\n",
- X wrapcolumn);
- X }
- X
- X /* do an "if" again in case editor not found and EDIT turned off */
- X if (!istool && ison(flags, EDIT)) {
- X char **argv, *edit;
- X int argc;
- X if ((!(edit = do_set(set_options, "visual")) || !*edit) &&
- X (!(edit = do_set(set_options, "editor")) || !*edit))
- X edit = DEF_EDITOR;
- X (void) sprintf(line, "%s %s", edit, edfile);
- X if ((argv = mk_argv(line, &argc, FALSE)) && argc > 0) {
- X print("Starting \"%s\"...\n", argv[0]);
- X (void) fclose(ed_fp);
- X ed_fp = NULL_FILE;
- X execute(argv);
- X free_vec(argv);
- X turnoff(flags, EDIT);
- X turnoff(flags, FORWARD); /* forwarded messages must be unedited */
- X /* upon exit of editor, user must now type eofc or "." to send */
- X if (!(ed_fp = fopen(edfile, "r+"))) {
- X error("can't reopen %s", edfile);
- X return -1;
- X }
- X (void) fseek(ed_fp, 0L, 2);
- X } else
- X print("Unable to start \"%s\"\n", edit);
- X wprint("(continue editing letter or ^%c to send)\n", eofc + '@');
- X } else if (ison(flags, SEND_NOW)) {
- X /* if finish_up_letter() was successful, file was successfully sent. */
- X if (!setjmp(cntrl_c_buf) && finish_up_letter() == 0) {
- X rm_edfile(0);
- X return 0;
- X }
- X } else if (had_hfile) {
- X /* it's not obvious what's going on -- enlighten user */
- X wprint("(continue editing or ^%c to send)\n", eofc + '@');
- X }
- X
- X#ifdef SUNTOOL
- X if (istool) {
- X /* toolmode doesn't care if SEND_NOW -- user continues to edit file.
- X * if SEND_NOW is not set, then the editor file has just been started,
- X * so again, just return so user can edit file.
- X */
- X if (ed_fp)
- X fclose(ed_fp), ed_fp = NULL_FILE;
- X turnon(glob_flags, IS_GETTING);
- X return 0;
- X }
- X#endif /* SUNTOOL */
- X if (ison(flags, SEND_NOW)) {
- X /* editing couldn't have been on -- finish_up_letter() failed */
- X rm_edfile(0 - ison(flags, FORWARD));
- X return -1;
- X }
- X
- X i = 0;
- X turnon(glob_flags, IS_GETTING);
- X do {
- X /* If the user hits ^C in cbreak mode, mush will return to
- X * Getstr and not clear the buffer. whatever is typed next will
- X * be appended to the line. jumping here will force the line to
- X * be cleared cuz it's a new call.
- X */
- X (void) setjmp(cntrl_c_buf);
- X while (Getstr(line, sizeof(line), 0) > -1) {
- X if (!istool) /* toolmode checks on a timer -- don't do it here */
- X (void) check_new_mail(); /* if new mail comes in, get it */
- X if ((i = add_to_letter(line)) <= 0)
- X break;
- X }
- X } while (i >= 0 && finish_up_letter() == -1);
- X turnoff(glob_flags, IS_GETTING);
- X return i; /* return -1 if ~x or ~q to terminate letter */
- X}
- X
- Xchar *tilde_commands[] = {
- X "commands: [OPTIONAL argument]",
- X "t [list]\tChange list of recipients",
- X "s [subject]\tModify [set] subject header",
- X "c [cc list]\tModify [set] carbon copy recipients",
- X "b [bcc list]\tModify [set] blind carbon recipients",
- X "h\t\tModify all message headers",
- X "e [editor]\tEnter editor. Editor used: \"set editor\", env EDITOR, vi",
- X "v [editor]\tEnter visual editor. \"set visual\", env VISUAL, vi",
- X "u\t\tEdit previous (last) line in file.",
- X "p [pager]\tPage message; pager used: \"set pager\", env. PAGER, more",
- X "i [msg#'s]\tInclude current msg body [msg#'s] indented by \"indent_str\"",
- X "I [msg#'s]\tSame, but include the message headers from included messages",
- X "f [msg#'s]\tForward mail. Not indented, but marked as \"forwarded mail\"",
- X "S[!]\t\tInclude Signature file [suppress file]",
- X "F[!]\t\tAdd a fortune at end of letter [don't add]",
- X "w file\t\tWrite msg buffer to file name",
- X "a file\t\tAppend msg buffer to file name",
- X "r file\t\tRead filename into message buffer",
- X "q \t\tQuit message; save in dead.letter (unless \"nosave\" is set).",
- X "x \t\tQuit message; don't save in dead.letter.",
- X "$variable\tInsert the string value for \"variable\" into message.",
- X ":cmd\t\tRun the mail command \"cmd\".",
- X "|cmd\t\tPipe the message through the unix command \"cmd\".",
- X "E[!]\t\tClear contents of letter after saving to dead.letter [unless !].",
- X 0
- X};
- X
- X/*
- X * TC_EDIT(tc) returns TRUE if tilde_command[tc] involves message
- X * editing operations. Used when EDIT_HDRS is active.
- X */
- X#define TC_EDIT(tc) ((tc) && ((tc) < 6 || !tilde_commands[(tc)+1]))
- X
- X/*
- X * Add the line (char *) parameter to the letter. Determine tilde
- X * escapes and determine what to do. This function returns 0 to
- X * indicate user wants to end the letter, -1 if the letter cannot
- X * be sent (~q, ~x no buffer after editor, etc...) or 1 to indicate
- X * successful addition of the line to the letter.
- X * This function may be called by toolmode just to change certain mush
- X * internal variables via tilde escapes. Thus, ed_fp might be null.
- X */
- Xadd_to_letter(line)
- Xchar line[];
- X{
- X register char *p;
- X char buf[HDRSIZ > MAXPATHLEN ? HDRSIZ : MAXPATHLEN];
- X
- X killme = 0;
- X if (ed_fp) /* may be null if istool */
- X (void) fseek(ed_fp, 0L, 2);
- X
- X if (!strcmp(line, ".") && do_set(set_options, "dot"))
- X return 0;
- X if (line[0] != *escape) {
- X (void) fputs(line, ed_fp);
- X (void) fputc('\n', ed_fp);
- X (void) fflush(ed_fp);
- X return 1;
- X }
- X /* all commands are "~c" (where 'c' is the command). set p = first
- X * character after 'c' and skip whitespace
- X */
- X p = &line[2];
- X skipspaces(0);
- X switch (line[1]) {
- X case 'v' : case 'p': case 'e' : case '|' : {
- X if (!*p || *p == 'i')
- X switch (line[1]) {
- X case 'p' :
- X if (!*p && !(p = do_set(set_options, "pager")))
- X p = DEF_PAGER;
- X if (!*p || !strcmp(p, "internal"))
- X p = NULL;
- X when 'v' :
- X if (*p && p[1] || (p = do_set(set_options, "visual")))
- X break;
- X /* else fall through */
- X default :
- X if (!(p = do_set(set_options, "editor")) || !*p)
- X p = DEF_EDITOR;
- X when '|' :
- X print("No command for pipe\n");
- X return 1;
- X }
- X if (line[1] == 'p' || line[1] == '|')
- X rewind(ed_fp);
- X if (line[1] == 'p') {
- X (void) do_pager(p, TRUE); /* start the pager "p" */
- X if (isoff(flags, EDIT_HDRS)) {
- X (void) do_pager(sprintf(buf, "To: %s\n", To), FALSE);
- X if (Subject[0])
- X (void) do_pager(sprintf(buf, "Subject: %s\n", Subject),
- X FALSE);
- X if (Cc[0])
- X (void) do_pager(sprintf(buf, "Cc: %s\n", Cc), FALSE);
- X if (Bcc[0])
- X (void) do_pager(sprintf(buf, "Bcc: %s\n", Bcc), FALSE);
- X (void) do_pager(strcpy(buf,
- X "--------\nMessage contains:\n"),
- X FALSE);
- X }
- X while (fgets(buf, sizeof(buf), ed_fp))
- X if (do_pager(buf, FALSE) == EOF)
- X break;
- X (void) do_pager(NULL, FALSE); /* end pager */
- X } else if (line[1] == '|') {
- X FILE *pipe_fp;
- X (void) sprintf(buf, "( %s ) > %s", p, edfile);
- X if (unlink(edfile) < 0) {
- X error("Can't unlink %s:", edfile);
- X break; /* Drop out of switch */
- X }
- X if ((pipe_fp = popen(buf, "w")) == NULL_FILE) {
- X error("Can't run \"%s\":", p);
- X (void) file_to_fp(edfile, ed_fp, "w");
- X } else {
- X while (fgets(buf, sizeof(buf), ed_fp))
- X if (fputs(buf, pipe_fp) == EOF) {
- X print("Broken pipe\n");
- X break;
- X }
- X (void) pclose(pipe_fp);
- X }
- X pipe_fp = ed_fp; /* save ed_fp until we can reopen it */
- X if (!(ed_fp = fopen(edfile, "r+"))) {
- X error("can't reopen %s", edfile);
- X (void) rewind(pipe_fp);
- X if (file_to_fp(edfile, pipe_fp, "w") < 0 ||
- X !(ed_fp = fopen(edfile, "r+"))) {
- X error("can't restore old contents of %s", edfile);
- X ed_fp = pipe_fp;
- X dead_letter(0);
- X return -1;
- X }
- X }
- X (void) fclose(pipe_fp);
- X } else {
- X char **argv;
- X int argc;
- X (void) sprintf(buf, "%s %s", p, edfile);
- X if ((argv = mk_argv(buf, &argc, FALSE)) && argc > 0) {
- X (void) fclose(ed_fp);
- X ed_fp = NULL_FILE;
- X execute(argv);
- X free_vec(argv);
- X /* tool will return even tho editor isn't done */
- X if (!(ed_fp = fopen(edfile, "r+"))) {
- X error("can't reopen %s", edfile);
- X return -1;
- X }
- X } else
- X print("Unable to start \"%s\"\n", p);
- X }
- X }
- X when '$': {
- X register char *p2;
- X if (!(p2 = do_set(set_options, p)))
- X print("(%s isn't set)\n", p);
- X else
- X putstring(p2, ed_fp);
- X }
- X when ':': {
- X char new[MAXMSGS_BITS];
- X u_long save_flags = glob_flags;
- X
- X turnon(glob_flags, IGN_SIGS);
- X turnoff(glob_flags, DO_PIPE);
- X turnoff(glob_flags, IS_PIPE);
- X (void) cmd_line(p, new);
- X glob_flags = save_flags;
- X }
- X when 'i': case 'f': case 'I': case 'm': {
- X int n;
- X u_long copy_flgs = 0;
- X char list[MAXMSGS_BITS];
- X
- X if (!msg_cnt) {
- X wprint("No messages.\n");
- X break;
- X }
- X clear_msg_list(list);
- X if (line[1] != 'f') {
- X turnon(copy_flgs, INDENT);
- X if (line[1] == 'i')
- X turnon(copy_flgs, NO_HEADER);
- X else if (!chk_option("alwaysignore", "include"))
- X turnon(copy_flgs, NO_IGNORE);
- X } else if (!chk_option("alwaysignore", "forward"))
- X turnon(copy_flgs, NO_IGNORE);
- X#ifdef MSG_SEPARATOR
- X turnon(copy_flgs, NO_SEPARATOR);
- X#endif /* MSG_SEPARATOR */
- X if (!*p)
- X set_msg_bit(list, current_msg);
- X else if (!do_range(p, list))
- X return 1;
- X for (n = 0; n < msg_cnt; n++)
- X if (msg_bit(list, n)) {
- X if (line[1] == 'f') {
- X (void) reply_to(n, FALSE, buf);
- X (void) fprintf(ed_fp,
- X "--- Forwarded mail from %s\n\n", buf);
- X }
- X wprint("Including message %d ... ", n+1);
- X wprint("(%d lines)\n", copy_msg(n, ed_fp, copy_flgs, NULL));
- X set_isread(n);
- X if (line[1] == 'f')
- X (void) fprintf(ed_fp,
- X "\n--- End of forwarded message from %s\n\n", buf);
- X else
- X (void) fputc('\n', ed_fp);
- X }
- X }
- X /* To: Cc: and Bcc: headers */
- X when 'b':
- X case 't':
- X case 'c': {
- X char *h = (line[1] == 't')? To : (line[1] == 'c')? Cc : Bcc;
- X char *Prompt = line[1] == 't'? "To: " :
- X line[1] == 'c'? "Cc: " : "Bcc: ";
- X if (ison(flags, EDIT_HDRS)) {
- X print("You must use an editor to change your headers.\n");
- X break;
- X }
- X
- X if (*p) {
- X fix_up_addr(p);
- X if (*h)
- X (void) sprintf(h+strlen(h), ", %s", p);
- X else
- X (void) strcpy(h, p);
- X } else if (!(p = set_header(Prompt, h, TRUE)) || !*p)
- X *h = 0;
- X else {
- X fix_up_addr(p);
- X (void) strcpy(h, p);
- X }
- X }
- X when 's':
- X if (ison(flags, EDIT_HDRS)) {
- X print("You must use an editor to change your headers.\n");
- X break;
- X }
- X if (*p || (p = set_header("Subject: ", Subject, 1)))
- X if (!*p)
- X Subject[0] = 0;
- X else
- X (void) strcpy(Subject, p);
- X when 'h':
- X if (ison(flags, EDIT_HDRS)) {
- X print("You must use an editor to change your headers.\n");
- X break;
- X }
- X while ((p = set_header("To: ", To, 1)) && !*p)
- X print("(There must be a recipient.)\n");
- X (void) strcpy(To, p);
- X if (p = set_header("Subject: ", Subject, 1))
- X if (!*p)
- X Subject[0] = 0;
- X else
- X (void) strcpy(Subject, p);
- X if (p = set_header("Cc: ", Cc, 1))
- X if (!*p)
- X Cc[0] = 0;
- X else {
- X fix_up_addr(p);
- X (void) strcpy(Cc, p);
- X }
- X if (p = set_header("Bcc: ", Bcc, 1))
- X if (!*p)
- X Bcc[0] = 0;
- X else {
- X fix_up_addr(p);
- X (void) strcpy(Bcc, p);
- X }
- X when 'F': case 'S' : {
- X if (*p == '!')
- X turnoff(flags, line[1] == 'F'? DO_FORTUNE : SIGN);
- X else
- X turnon(flags, line[1] == 'F'? DO_FORTUNE : SIGN);
- X wprint("%sadding %s at end of message.\n", *p == '!'? "not " : "",
- X line[1] == 'F'? "fortune" : "signature");
- X }
- X when 'w': case 'a': case 'r':
- X if (!*p) {
- X print("(you must specify a filename)\n");
- X return 1;
- X }
- X (void) fseek(ed_fp, 0L, 2); /* append */
- X (void) file_to_fp(p, ed_fp, (line[1] == 'r')? "r":
- X (line[1] == 'w')? "w": "a");
- X /* go up one line in the message file and allow the user to edit it */
- X when 'u': {
- X long newpos, pos = ftell(ed_fp);
- X char oldline[256];
- X if (pos <= 0L) { /* pos could be -1 if ftell() failed */
- X print("(No previous line in file.)\n");
- X return 1;
- X }
- X /* get the last 256 bytes written and read backwards from the
- X * current place until '\n' is found. Start by moving past the
- X * first \n which is at the end of the line we want to edit
- X */
- X newpos = max(0, pos - 256L);
- X (void) fseek(ed_fp, newpos, L_SET);
- X /* don't fgets -- it'll stop at a \n */
- X (void) fread(line, sizeof(char), (int)(pos-newpos), ed_fp);
- X pos--;
- X /* the last char in line should be a \n cuz it was last input */
- X if (line[(int)(pos-newpos)] != '\n')
- X print("I don't know how, but your last line ended with %c.\n",
- X line[(int)(pos-newpos)]);
- X else
- X line[(int)(pos-newpos)] = 0; /* null terminate \n for ^H-ing */
- X for (pos--; pos > newpos && line[(int)(pos-newpos)] != '\n'; pos--)
- X ;
- X /* we've gone back to the end of the second previous line. Check
- X * to see if the char we're pointing to is a \n. It should be, but
- X * if it's not, we moved back to the first line of the file.
- X */
- X if (line[(int)(pos-newpos)] == '\n')
- X ++pos;
- X /* save the old line that's there in case the user boo-boos */
- X (void) strcpy(oldline, &line[(int)(pos-newpos)]);
- X /* let set header print out the line and get the input */
- X if (!(p = set_header("", &line[(int)(pos-newpos)], TRUE))) {
- X print("Something bad happened and I don't know what it is.\n");
- X p = oldline;
- X } else if (*p == *escape)
- X print("(Warning: %c escapes ignored on %cu lines.)\n",
- X *escape, *escape);
- X /* seek to to the position where the new line will go */
- X (void) fseek(ed_fp, pos, L_SET);
- X /* put the newly typed line */
- X (void) fputs(p, ed_fp); /* don't add \n. padding may be necessary */
- X /* if the new line is less than the old line, we're going to do
- X * one of two things. The best thing to do is to truncate the
- X * file to the end of the new line. Sys-v can't do that, so we
- X * pad the line with blanks. May be messy in some cases, but...
- X */
- X if ((pos = strlen(p) - strlen(oldline)) < 0) {
- X#ifndef SYSV
- X /* add the \n, flush the file, truncate to the current pos */
- X (void) fputc('\n', ed_fp);
- X (void) fflush(ed_fp);
- X (void) ftruncate(fileno(ed_fp), (off_t) ftell(ed_fp));
- X#else /* SYSV */
- X /* pad with blanks to the length of the old line. add \n */
- X while (pos++ < 0)
- X (void) fputc(' ', ed_fp);
- X (void) fputc('\n', ed_fp), (void) fflush(ed_fp);
- X#endif /* SYSV */
- X } else {
- X /* the new line is >= the old line, add \n -- no trunc req. */
- X (void) fputc('\n', ed_fp);
- X (void) fflush(ed_fp);
- X }
- X return 1;
- X }
- X /* break; not here cuz of "return" (lint). */
- X case 'E':
- X if (ison(flags, EDIT_HDRS)) {
- X print("You must use an editor to empty the message buffer.\n");
- X break;
- X }
- X if (*p != '!' && !do_set(set_options, "nosave"))
- X dead_letter(0);
- X if (emptyfile(&ed_fp, edfile) == -1)
- X error(edfile);
- X else
- X print("Message buffer empty\n");
- X when 'q':
- X /* save in dead.letter if nosave not set -- rm_edfile(-2). */
- X rm_edfile(-2); /* doesn't return out of tool mode */
- X return -1;
- X /* break; not stated cuz of "return" (lint) */
- X case 'x':
- X /* don't save dead.letter -- simulate normal rm_edfile() call */
- X rm_edfile(0);
- X return -1;
- X /* break; (not specified for lint) */
- X default:
- X if (line[1] == *escape) {
- X (void) fputs(&line[1], ed_fp);
- X (void) fputc('\n', ed_fp);
- X (void) fflush(ed_fp);
- X return 1;
- X } else if (line[1] == '?') {
- X register int x;
- X (void) do_pager(NULL, TRUE); /* start pager */
- X for (x = 0; tilde_commands[x]; x++) {
- X if (ison(flags, EDIT_HDRS) && TC_EDIT(x))
- X continue;
- X (void) sprintf(buf, "%s%s\n", escape, tilde_commands[x]);
- X if (do_pager(buf, FALSE) == EOF)
- X break;
- X }
- X if (tilde_commands[x] == NULL) {
- X (void) sprintf(buf,
- X "%s%s\t\tBegin a line with a single %s\n",
- X escape, escape, escape);
- X (void) do_pager(buf, FALSE);
- X }
- X (void) do_pager(NULL, FALSE); /* end pager */
- X } else
- X print("`%c': unknown %c escape. Use %c? for help.\n",
- X line[1], *escape, *escape);
- X return 1;
- X }
- X if (ed_fp)
- X (void) fseek(ed_fp, 0L, 2);
- X if (!istool)
- X wprint("(continue editing letter)\n");
- X return 1;
- X}
- X
- X/*
- X * finish up the letter. ask for the cc line, if verify is set, ask to
- X * verify sending, continue editing, or to dump the whole idea.
- X * Then check for signature and fortune. Finally, pass it to send_it()
- X * to actually send it off.
- X * Return 0 on success, -1 on failure.
- X */
- Xstatic int
- Xfinish_up_letter()
- X{
- X register char *p;
- X int c;
- X char buf[MAXPATHLEN];
- X
- X /* forwarded mail has no additional personalized text */
- X if (ison(flags, FORWARD)) {
- X if (send_it() == -1) {
- X wprint("Message not sent!\n");
- X return -1;
- X }
- X turnoff(glob_flags, IS_GETTING);
- X return 0;
- X }
- X
- X /* REDIRECT should never be on here, but just in case */
- X if (isoff(glob_flags, REDIRECT)) {
- X if (!istool) {
- X if (isoff(flags, EDIT_HDRS) && do_set(set_options, "askcc")) {
- X if (p = set_header("Cc: ", Cc, 1))
- X (void) strcpy(Cc, p);
- X }
- X }
- X /* ~v on the Cc line asks for verification, first initialize p! */
- X p = NULL;
- X if (!strncmp(Cc, "~v", 2) || (p = do_set(set_options, "verify"))) {
- X if (!p) /* so we don't Cc to ~v! */
- X *Cc = 0;
- X for (;;) {
- X#ifdef SUNTOOL
- X if (istool)
- X c = (ask("Send Message?") == TRUE)? 's' : 'c';
- X else
- X#endif /* SUNTOOL */
- X {
- X print("send, continue editing, discard [s,c,d]? ");
- X c = Getstr(buf, sizeof(buf), 0);
- X if (c < 0)
- X putchar('\n');
- X else if (!istool)
- X c = lower(*buf);
- END_OF_FILE
- if test 30778 -ne `wc -c <'mush/mail.c.a'`; then
- echo shar: \"'mush/mail.c.a'\" unpacked with wrong size!
- fi
- # end of 'mush/mail.c.a'
- fi
- echo shar: End of archive 9 \(of 19\).
- cp /dev/null ark9isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 19 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-
-
-