home *** CD-ROM | disk | FTP | other *** search
- /* @(#)mail.c (c) copyright 1986 (Dan Heller) */
-
- #include "mush.h"
-
- /*
- * mail.c --
- * do_mail() invoked from within mail. see function for description.
- * abort_mail() suntools specific: resets panel items and so forth.
- * start_file() creates the editing file and reset signal catching.
- * mail_someone() called from do_mail() or from the shell.
- * add_to_letter() adds the next line to letter --determine ~ escapes.
- * finish_up_letter() prompts for Cc:, verifies user really wants to send
- * send_it() invokes mailer, sends to record file, adds signature,
- * fortune, expands aliases, adds own_hdrs.
- * rm_edfile() signals are directed here. remove letter, longjmp
- *
- * The flow of control in this file is NOT obvious to allow for both text
- * and suntools _event driven_ attributes. In text, the flow is far more
- * obvious because it is sequential. In suntools, each function is called
- * from outside this modual. Keystrokes are interpreted individually and
- * queued up in "rite.c". select.c calls add_to_letter when a \n is entered
- * passing the string stored in rite.c. If you're trying to follow the flow
- * of control for suntools, keep the event drivers in mind and follow select.c
- * and rite.c
- */
- #define TO_FIELD 1
- #define SUBJECT 2
- #define CC_FIELD 3
- #define BC_FIELD 4
-
- static char Subject[BUFSIZ],To[BUFSIZ],Cc[BUFSIZ],Bcc[BUFSIZ],in_reply_to[256];
- static int killme;
- static u_long flags;
- static int (*oldterm)(), (*oldint)(), (*oldquit)();
- static void send_it();
- static jmp_buf cntrl_c_buf;
- FILE *ed_fp;
- char *edfile;
-
- /* argc, and argv could be null if coming from compose */
- do_mail(n, argv, list)
- register int n; /* no need for "argc", so use the space for a variable */
- register char **argv, *list;
- {
- char firstchar = (argv)? **argv: 'm';
- register char *to = NULL, *cc = NULL, *subj = NULL;
- u_long flgs = 0;
-
- if (ison(glob_flags, IS_GETTING)) {
- print("You must finish the letter you are editing first.\n");
- return -1;
- }
- if (ison(glob_flags, DO_PIPE)) {
- print("You can't pipe through the mail command.\n");
- return -1;
- }
- turnon(flgs, NO_IGNORE); /* if we include a message, include all hdrs */
-
- if (do_set(set_options, "autoedit"))
- turnon(flgs, EDIT);
- #ifdef VERBOSE_ARG
- if (do_set(set_options, "verbose"))
- turnon(flgs, VERBOSE);
- #endif /* VERBOSE_ARG */
- if (do_set(set_options, "autosign"))
- turnon(flgs, SIGN);
- /* If piped to mail, include the messages piped */
- if (ison(glob_flags, IS_PIPE))
- turnon(flgs, INCLUDE);
- else if (lower(firstchar) == 'r' && do_set(set_options, "autoinclude"))
- turnon(flgs, INCLUDE), set_msg_bit(list, current_msg);
- while (argv && *argv && *++argv && **argv == '-') {
- n = 1;
- while (n && argv[0][n])
- switch (argv[0][n]) {
- #ifdef VERBOSE_ARG
- case 'v': turnon(flgs, VERBOSE); n++; break;
- #endif /* VERBOSE_ARG */
- case 'e': turnon(flgs, EDIT); n++;
- when 'F': turnon(flgs, DO_FORTUNE); n++;
- when 's':
- if (argv[1])
- n = 0, subj = *++argv;
- else
- n++, turnon(flgs, NEW_SUBJECT);
- when 'i': case 'h': case 'f': {
- int m;
- if (!msg_cnt) {
- print("No message to include!\n");
- return -1;
- }
- if (argv[0][n] == 'i') {
- turnon(flgs, INCLUDE);
- turnoff(flgs, INCLUDE_H);
- turnoff(flgs, FORWARD);
- } else if (argv[0][n] == 'h') {
- turnon(flgs, INCLUDE_H);
- turnoff(flgs, INCLUDE);
- turnoff(flgs, FORWARD);
- } else if (argv[0][n] == 'f') {
- turnon(flgs, FORWARD);
- turnoff(flgs, INCLUDE_H);
- turnoff(flgs, INCLUDE);
- }
- /* "-i 3-5" or "-i3-5" Consider the latter case first */
- if (!argv[0][++n])
- argv++, n = 0;
- (*argv) += n;
- m = get_msg_list(argv, list);
- (*argv) -= n;
- if (m == -1)
- return -1;
- /* if there were args, then go back to the first char
- * in the next argv
- */
- if (m)
- n = 0;
- if (!n) /* n may be 0 from above! */
- argv += (m-1);
- }
- otherwise:
- if (argv[0][n] != '?')
- wprint("%c: unknown option\n", argv[0][n]);
- wprint("available options\n");
- #ifdef VERBOSE_ARG
- wprint("v verbose (passed to mail delivery system)\n");
- #endif /* VERBOSE_ARG */
- wprint("e immediately enter editor (autoedit)\n");
- wprint("F add fortune to the end of message.\n");
- wprint("s [subject] prompt for or set subject.\n");
- wprint("i [msg#'s] include msg_list into letter.\n");
- wprint("h [msg#'s] include msg_list with headers.\n");
- wprint("f [msg#'s] forward msg_list (not indented).\n");
- return -1;
- }
- }
- *in_reply_to = *To = *Subject = *Cc = *Bcc = 0;
- if (lower(firstchar) == 'r') {
- char *old_fmt = hdr_format;
- to = reply_to(current_msg, (firstchar == 'R'), To);
- if (firstchar == 'R')
- cc = cc_to(current_msg, Cc);
- if (do_set(set_options, "auto_route"))
- fix_addresses(To, Cc);
- if (hdr_format = do_set(set_options, "in_reply_to"))
- (void) strcpy(in_reply_to, compose_hdr(current_msg)+9); /* magic# */
- hdr_format = old_fmt;
- }
- if (ison(flgs, FORWARD) ||
- lower(firstchar) == 'r' && isoff(flgs, NEW_SUBJECT)) {
- char buf[sizeof(Subject)];
- if (ison(flgs, NEW_SUBJECT))
- print("Forwarded mail can't have subject changed.\n");
- turnoff(flgs, NEW_SUBJECT);
- if (subj = subject_to(current_msg, buf))
- subj = strcpy(Subject, buf + 4*(lower(firstchar) != 'r'));
- } else if (isoff(flgs, NEW_SUBJECT) && do_set(set_options, "ask"))
- turnon(flgs, NEW_SUBJECT);
- if (argv && *argv) {
- char buf[BUFSIZ];
- (void) argv_to_string(buf, argv);
- fix_up_addr(buf);
- to = &To[strlen(To)];
- if (*To)
- to += Strcpy(to-1, ", ") - 1;
- (void) strcpy(to, buf);
- to = To;
- }
- if (do_set(set_options, "fortune"))
- turnon(flgs, DO_FORTUNE);
- #ifdef SUNTOOL
- if (istool) {
- do_clear();
- panel_set(abort_item, PANEL_SHOW_ITEM, TRUE, 0);
- panel_set(comp_item, PANEL_SHOW_ITEM, FALSE, 0);
- panel_set(read_item, PANEL_SHOW_ITEM, FALSE, 0);
- panel_set(respond_item, PANEL_SHOW_ITEM, FALSE, 0);
- }
- #endif /* SUNTOOL */
- return mail_someone(to, subj, cc, flgs, list);
- }
-
- #ifdef SUNTOOL
- /* panel item selection -- it's here because of local (static) variables */
- abort_mail(item, value)
- Panel_item item;
- {
- get_hdr_field = 0;
- if (item == abort_item && value != 2) {
- print("Aborted letter.");
- killme = 1, rm_edfile(SIGINT);
- flags = 0;
- }
- panel_set(comp_item, PANEL_SHOW_ITEM, TRUE, 0);
- panel_set(send_item, PANEL_SHOW_ITEM, FALSE, 0);
- panel_set(edit_item, PANEL_SHOW_ITEM, FALSE, 0);
- panel_set(abort_item, PANEL_SHOW_ITEM, FALSE, 0);
- panel_set(read_item, PANEL_SHOW_ITEM, TRUE, 0);
- panel_set(respond_item, PANEL_SHOW_ITEM, TRUE, 0);
- turnoff(glob_flags, IS_GETTING);
- unlock_cursors();
- }
- #endif /* SUNTOOL */
-
- mail_someone(to, subject, cc, flgs, list)
- register char *to, *subject, *cc, *list;
- u_long flgs;
- {
- register char *p;
-
- flags = flgs;
- #ifdef SUNTOOL
- if (istool)
- rite(_tty.sg_kill), do_clear();
- #endif /* SUNTOOL */
- if (to && *to) {
- if (!*To)
- (void) strncpy(To, to, sizeof(To));
- if (istool)
- wprint("To: %s\n", To);
- } else
- #ifdef SUNTOOL
- if (istool)
- turnon(get_hdr_field, TO_FIELD);
- else
- #endif /* SUNTOOL */
- to = NO_STRING;
- if (subject && *subject) {
- if (!*Subject)
- (void) strncpy(Subject, subject, sizeof(Subject));
- if (istool)
- wprint("Subject: %s\n", Subject);
- } else
- #ifdef SUNTOOL
- if (istool && !*Subject && ison(flags, NEW_SUBJECT))
- turnon(get_hdr_field, SUBJECT);
- else
- #endif /* SUNTOOL */
- subject = NO_STRING;
- if (cc && *cc) {
- if (!*Cc)
- (void) strncpy(Cc, cc, sizeof(Cc));
- if (istool)
- wprint("Cc: %s\n", Cc);
- } else
- #ifdef SUNTOOL /* get_hdr_field -- prevents prompting on reply and forward */
- if (istool && get_hdr_field && do_set(set_options, "askcc"))
- turnon(get_hdr_field, CC_FIELD);
- else
- #endif /* SUNTOOL */
- cc = NO_STRING;
-
- if (ison(glob_flags, REDIRECT)) {
- send_it(); /* doesn't return */
- return 0;
- }
- /* if (!*to) then prompting will be done */
- if (!istool) {
- if (!(p = set_header("To: ", to, !*to)) || !*p) {
- puts("No recipients, can't mail.");
- return -1;
- }
- if (!*to) /* if user typed To-line here, fix up the address line */
- fix_up_addr(p);
- (void) strcpy(To, p);
- /* don't prompt for subject if forwarding mail */
- if (p = set_header("Subject: ", subject,
- !*subject && ison(flags, NEW_SUBJECT)))
- (void) strcpy(Subject, p);
- if (*Cc)
- printf("Cc: %s\n", Cc);
- putchar('\n');
- }
- #ifdef SUNTOOL
- else if (!get_hdr_field) {
- panel_set(send_item, PANEL_SHOW_ITEM, TRUE, 0);
- panel_set(edit_item, PANEL_SHOW_ITEM, TRUE, 0);
- }
- #endif /* SUNTOOL */
- return start_file(list);
- }
-
- start_file(list)
- char *list;
- {
- register char *home;
- register int i;
- char line[MAXPATHLEN];
-
- if (!(home = do_set(set_options, "home")) || !*home)
- alted:
- home = ALTERNATE_HOME;
- (void) mktemp(sprintf(line, "%s/%s", home, EDFILE));
- strdup(edfile, line);
- {
- int omask = umask(077);
- ed_fp = fopen(edfile, "w+");
- (void) umask(omask);
- if (!ed_fp) {
- if (home != ALTERNATE_HOME)
- goto alted;
- #ifdef SUNTOOL
- if (istool)
- abort_mail(NO_ITEM, 0);
- #endif /* SUNTOOL */
- error("can't create %s", edfile);
- return -1;
- }
- }
- if (!istool) {
- oldint = signal(SIGINT, rm_edfile);
- oldquit = signal(SIGQUIT, rm_edfile);
- oldterm = signal(SIGTERM, rm_edfile);
- }
-
- /* if flags call for it, include current message (with header?) */
- if (ison(flags, INCLUDE) || ison(flags,FORWARD) || ison(flags,INCLUDE_H)) {
- long copy_flgs = 0, is_forw = ison(flags, FORWARD);
- char buf[sizeof(To)];
- if (!is_forw)
- turnon(copy_flgs, INDENT);
- if (ison(flags, INCLUDE))
- turnon(copy_flgs, NO_HEADER);
- if (ison(flags, INCLUDE) || ison(flags, FORWARD))
- turnon(copy_flgs, NO_IGNORE);
- #ifdef SUNTOOL
- if (istool)
- lock_cursors();
- #endif /* SUNTOOL */
- for (i = 0; i < msg_cnt; i++)
- if (msg_bit(list, i)) {
- if (is_forw && ison(flags, EDIT)) {
- (void) reply_to(i, FALSE, buf);
- fprintf(ed_fp, "--- Forwarded mail from %s\n\n", buf);
- }
- wprint("%sing message %d ...",
- is_forw? "forward" : "includ", i+1);
- wprint("(%d lines)\n", copy_msg(i, ed_fp, copy_flgs));
- set_isread(i); /* if we included it, we read it, right? */
- if (is_forw && ison(flags, EDIT))
- fprintf(ed_fp,
- "\n--- End of forwarded message from %s\n", buf);
- }
- fflush(ed_fp);
- #ifdef SUNTOOL
- if (istool)
- unlock_cursors();
- #endif /* SUNTOOL */
- }
- if (ison(glob_flags, WARNING)) {
- if (escape && *escape != DEF_ESCAPE[0])
- wprint("(escape character is set to `%c')\n", *escape);
- }
- turnon(glob_flags, IS_GETTING);
- /* enter editor if autoedit and not toolmode */
- if (
- #ifdef SUNTOOL
- (!istool || !get_hdr_field) &&
- #endif /* SUNTOOL */
- /* do an "if" again in case editor not found and EDIT turned off */
- ison(flags, EDIT)) {
- char *argv[3];
- if (!(argv[0] = do_set(set_options, "visual")) || !*argv[0])
- argv[0] = DEF_EDITOR;
- argv[1] = edfile;
- argv[2] = NULL;
- print("Starting \"%s\"...\n", argv[0]);
- fclose(ed_fp);
- ed_fp = NULL_FILE;
- execute(argv);
- turnoff(flags, EDIT);
- turnoff(flags, FORWARD); /* forwarded messages must be unedited */
- /* upon exit of editor, user must now type ^D or "." to send */
- if (istool)
- return 0;
- if (!(ed_fp = fopen(edfile, "r+"))) {
- error("can't reopen %s", edfile);
- return -1;
- }
- (void) fseek(ed_fp, 0L, 2);
- puts("continue editing letter or ^D to send");
- } else if (ison(flags, FORWARD) &&
- #ifdef SUNTOOL
- (!istool || !get_hdr_field) &&
- #endif /* SUNTOOL */
- finish_up_letter())
- return 0; /* if forwarding mail, check to see if tool requires To: */
- #ifdef SUNTOOL
- if (istool) {
- /* If toolmode, we're ready for IO. Give first prompt if not given */
- if (ison(get_hdr_field, TO_FIELD))
- wprint("To: ");
- else if (ison(get_hdr_field, SUBJECT))
- wprint("Subject: ");
- else if (ison(get_hdr_field, CC_FIELD))
- wprint("Cc: ");
- type_cursor(PIX_SRC);
- win_setcursor(msg_sw->ts_windowfd, &write_cursor);
- return 0;
- }
- #endif /* SUNTOOL */
- i = 0;
- do {
- /* If the user hits ^C in cbreak mode, mush will return to
- * Getstr and not clear the buffer. whatever is typed next will
- * be appended to the line. jumping here will force the line to
- * be cleared cuz it's a new call.
- */
- (void) setjmp(cntrl_c_buf);
- while (Getstr(line, sizeof(line), 0) > -1)
- if ((i = add_to_letter(line)) <= 0)
- break;
- } while (i >= 0 && !finish_up_letter());
- return i; /* return -1 if ~x or ~q to terminate letter */
- }
-
- char *tilde_commands[] = {
- "commands: [OPTIONAL argument]",
- "e [editor]\tEnter editor. Editor used: \"set editor\", env EDITOR, vi",
- "v [editor]\tEnter visual editor. \"set visual\", env VISUAL, vi",
- "p [pager]\tPage message; pager used: \"set pager\", env. PAGER, more",
- "i [msg#'s]\tInclude current msg body [msg#'s] indented by \"indent_str\"",
- "H [msg#'s]\tSame, but include the message headers from included messages",
- "f [msg#'s]\tForward mail. Not indented, but marked as \"forwarded mail\"",
- "t [list]\tChange list of recipients",
- "s [subject]\tModify [set] subject header",
- "c [cc list]\tModify [set] carbon copy recipients",
- "b [bcc list]\tModify [set] blind carbon recipients",
- "h\t\tModify all message headers",
- "S[!]\t\tInclude Signature file [suppress file]",
- "F[!]\t\tAdd a fortune at end of letter [don't add]",
- "w file\t\tWrite msg buffer to file name",
- "a file\t\tAppend msg buffer to file name",
- "r file\t\tRead filename into message buffer",
- "q \t\tQuit message; save in dead.letter (unless \"nosave\" is set).",
- "x \t\tQuit message; don't save in dead.letter.",
- "$variable\tInsert the string value for \"variable\" into message.",
- ":cmd\t\tRun the mail command \"cmd\".",
- "u\t\tedit previous line in file.",
- "E[!]\t\tClear contents of letter after saving to dead.letter [unless !].",
- 0
- };
-
- /*
- * Add the line (char *) parameter to the letter. Determine tilde
- * escapes and determine what to do. This function returns 0 to
- * indicate user wants to end the letter, -1 if the letter cannot
- * be sent (~q, ~x no buffer after editor, etc...) or 1 to indicate
- * successful addition of the line to the letter.
- */
- add_to_letter(line)
- register char *line;
- {
- register char *p;
- char buf[BUFSIZ];
-
- killme = 0;
- (void) fseek(ed_fp, 0L, 2);
- #ifdef SUNTOOL
- if (get_hdr_field) {
- /* These are received in order by design! */
- if (ison(get_hdr_field, TO_FIELD)) {
- if (!*line) {
- wprint("There must be a recipient!\nTo: ");
- return 1;
- }
- fix_up_addr(line);
- (void) strcpy(To, line), turnoff(get_hdr_field, TO_FIELD);
- } else if (ison(get_hdr_field, SUBJECT)) {
- (void) strcpy(Subject, line);
- turnoff(get_hdr_field, SUBJECT);
- } else if (ison(get_hdr_field, CC_FIELD)) {
- fix_up_addr(line);
- (void) strcpy(Cc, line);
- turnoff(get_hdr_field, CC_FIELD);
- } else if (ison(get_hdr_field, BC_FIELD)) {
- fix_up_addr(line);
- (void) strcpy(Bcc, line);
- turnoff(get_hdr_field, BC_FIELD);
- }
-
- if (ison(get_hdr_field, SUBJECT))
- (void) set_header("Subject: ", Subject, 1);
- else if (ison(get_hdr_field, CC_FIELD))
- (void) set_header("Cc: ", Cc, 1);
- else if (ison(get_hdr_field, BC_FIELD))
- (void) set_header("Bcc: ", Bcc, 1);
- panel_set(send_item, PANEL_SHOW_ITEM, (get_hdr_field==0), 0);
- panel_set(edit_item, PANEL_SHOW_ITEM, (get_hdr_field==0), 0);
- if (!get_hdr_field) {
- wprint("\n");
- if (ison(flags, EDIT)) {
- (void) add_to_letter(sprintf(line, "%cv", *escape));
- turnoff(flags, EDIT);
- }
- }
- return 1;
- }
- #endif /* SUNTOOL */
- if (!strcmp(line, ".") && (istool || do_set(set_options, "dot")))
- return 0;
- if (*line != *escape) {
- fputs(line, ed_fp), fputc('\n', ed_fp), fflush(ed_fp);
- return 1;
- }
- /* all commands are "~c" (where 'c' is the command). set p = first
- * character after 'c' and skip whitespace
- */
- p = line+2;
- skipspaces(0);
- switch (line[1]) {
- case 'v' : case 'p': case 'e': {
- if (!*p || *p == 'i' && !p[1])
- switch (line[1]) {
- case 'p' :
- if (!(p = do_set(set_options, "pager")))
- p = DEF_PAGER;
- if (!*p || !strcmp(p, "internal"))
- p = NULL;
- when 'v' :
- if (p = do_set(set_options, "visual"))
- break;
- default :
- if (!(p = do_set(set_options, "editor")) || !*p)
- p = DEF_EDITOR;
- }
- if (line[1] == 'p') {
- rewind(ed_fp);
- (void) do_pager(p, TRUE); /* start the pager "p" */
- do_pager(sprintf(buf, "To: %s\n", To), FALSE);
- if (Subject[0])
- do_pager(sprintf(buf, "Subject: %s\n", Subject), FALSE);
- if (Cc[0])
- do_pager(sprintf(buf, "Cc: %s\n", Cc), FALSE);
- if (Bcc[0])
- do_pager(sprintf(buf, "Bcc: %s\n", Bcc), FALSE);
- do_pager(strcpy(buf, "--------\nMessage contains:\n"), FALSE);
- while (fgets(buf, sizeof(buf), ed_fp))
- if (do_pager(buf, FALSE) == EOF)
- break;
- (void) do_pager(NULL, FALSE); /* end pager */
- } else {
- char *argv[3];
- argv[0] = p;
- argv[1] = edfile;
- argv[2] = NULL;
- fclose(ed_fp);
- ed_fp = NULL_FILE;
- execute(argv); /* tool will return even tho editor isn't done */
- if (istool)
- return 1;
- if (!(ed_fp = fopen(edfile, "r+"))) {
- error("can't reopen %s", edfile);
- return -1;
- }
- }
- }
- when '$': {
- register char *p2;
- if (!(p2 = do_set(set_options, p)))
- wprint("(%s isn't set)\n", p);
- else
- fprintf(ed_fp, "%s\n", p2);
- }
- when ':': {
- char new[MAXMSGS_BITS];
- u_long save_flags = glob_flags;
-
- turnon(glob_flags, IGN_SIGS);
- turnon(glob_flags, IGN_BANG);
- turnoff(glob_flags, DO_PIPE);
- turnoff(glob_flags, IS_PIPE);
- (void) cmd_line(p, new);
- glob_flags = save_flags;
- #ifdef SUNTOOL
- if (istool && msg_pix) /* the command was to read a message */
- return 1;
- #endif /* SUNTOOL */
- }
- when 'i': case 'f': case 'H': case 'm': {
- int n;
- long copy_flgs = 0;
- char list[MAXMSGS_BITS];
-
- if (!msg_cnt) {
- print("No messages.\n");
- break;
- }
- clear_msg_list(list);
- if (line[1] != 'f')
- turnon(copy_flgs, INDENT);
- if (line[1] == 'i')
- turnon(copy_flgs, NO_HEADER);
- if (!*p)
- set_msg_bit(list, current_msg);
- else if (!do_range(p, list))
- return 1;
- #ifdef SUNTOOL
- if (istool)
- lock_cursors();
- #endif /* SUNTOOL */
- for (n = 0; n < msg_cnt; n++)
- if (msg_bit(list, n)) {
- if (line[1] == 'f') {
- (void) reply_to(n, FALSE, buf);
- fprintf(ed_fp, "--- Forwarded mail from %s\n\n", buf);
- }
- wprint("Including message %d ... ", n+1);
- wprint("(%d lines)\n", copy_msg(n, ed_fp, copy_flgs));
- set_isread(n);
- if (line[1] == 'f')
- fprintf(ed_fp,"\n--- End of forwarded message from %s\n\n",buf);
- }
- #ifdef SUNTOOL
- if (istool)
- unlock_cursors();
- #endif /* SUNTOOL */
- }
- when 't':
- #ifdef SUNTOOL
- if (!*p && istool) {
- turnon(get_hdr_field, TO_FIELD);
- (void) set_header("To: ", To, 1);
- panel_set(send_item, PANEL_SHOW_ITEM, FALSE, 0);
- panel_set(edit_item, PANEL_SHOW_ITEM, FALSE, 0);
- return 1;
- }
- #endif /* SUNTOOL */
- /* ~t address is a special case ... append to address */
- if (*p) {
- fix_up_addr(p);
- (void) sprintf(To+strlen(To), ", %s", p);
- } else if (p = set_header("To: ", To, 1))
- if (!*p) {
- wprint("There must be a recipient!\n");
- #ifdef SUNTOOL
- turnoff(get_hdr_field, TO_FIELD);
- panel_set(send_item, PANEL_SHOW_ITEM, TRUE, 0);
- panel_set(edit_item, PANEL_SHOW_ITEM, TRUE, 0);
- #endif /* SUNTOOL */
- } else {
- fix_up_addr(p);
- (void) strcpy(To, p);
- }
- when 's':
- #ifdef SUNTOOL
- if (!*p && istool) {
- turnon(get_hdr_field, SUBJECT);
- panel_set(send_item, PANEL_SHOW_ITEM, FALSE, 0);
- panel_set(edit_item, PANEL_SHOW_ITEM, FALSE, 0);
- (void) set_header("Subject: ", Subject, 1);
- return 1;
- }
- #endif /* SUNTOOL */
- if (*p || (p = set_header("Subject: ", Subject, 1)))
- if (!*p)
- Subject[0] = 0;
- else
- (void) strcpy(Subject, p);
- when 'c':
- #ifdef SUNTOOL
- if (!*p && istool) {
- turnon(get_hdr_field, CC_FIELD);
- (void) set_header("Cc: ", Cc, 1);
- panel_set(send_item, PANEL_SHOW_ITEM, FALSE, 0);
- panel_set(edit_item, PANEL_SHOW_ITEM, FALSE, 0);
- return 1;
- }
- #endif /* SUNTOOL */
- if (*p || (p = set_header("Cc: ", Cc, 1)))
- if (!*p)
- Cc[0] = 0;
- else {
- fix_up_addr(p);
- (void) strcpy(Cc, p);
- }
- when 'b':
- #ifdef SUNTOOL
- if (!*p && istool) {
- turnon(get_hdr_field, BC_FIELD);
- (void) set_header("Bcc: ", Bcc, 1);
- panel_set(send_item, PANEL_SHOW_ITEM, FALSE, 0);
- panel_set(edit_item, PANEL_SHOW_ITEM, FALSE, 0);
- return 1;
- }
- #endif /* SUNTOOL */
- if (*p || (p = set_header("Bcc: ", Bcc, 1)))
- if (!*p)
- Bcc[0] = 0;
- else {
- fix_up_addr(p);
- (void) strcpy(Bcc, p);
- }
- when 'h':
- #ifdef SUNTOOL
- if (istool) {
- turnon(get_hdr_field, TO_FIELD);
- turnon(get_hdr_field, SUBJECT);
- turnon(get_hdr_field, CC_FIELD);
- turnon(get_hdr_field, BC_FIELD);
- (void) set_header("To: ", To, 1);
- panel_set(send_item, PANEL_SHOW_ITEM, FALSE, 0);
- panel_set(edit_item, PANEL_SHOW_ITEM, FALSE, 0);
- return 1;
- }
- #endif /* SUNTOOL */
- while ((p = set_header("To: ", To, 1)) && !*p)
- wprint("(There must be a recipient.)\n");
- (void) strcpy(To, p);
- if (p = set_header("Subject: ", Subject, 1))
- if (!*p)
- Subject[0] = 0;
- else
- (void) strcpy(Subject, p);
- if (p = set_header("Cc: ", Cc, 1))
- if (!*p)
- Cc[0] = 0;
- else {
- fix_up_addr(p);
- (void) strcpy(Cc, p);
- }
- if (p = set_header("Bcc: ", Bcc, 1))
- if (!*p)
- Bcc[0] = 0;
- else {
- fix_up_addr(p);
- (void) strcpy(Bcc, p);
- }
- when 'S':
- if (*p == '!')
- turnoff(flags, SIGN), wprint("not ");
- else
- turnon(flags, SIGN);
- wprint("adding signature file at end of message.\n");
- when 'F':
- if (*p == '!')
- turnoff(flags, DO_FORTUNE), wprint("not ");
- else
- turnon(flags, DO_FORTUNE);
- wprint("adding fortune at end of message.\n");
- when 'w': case 'a': case 'r':
- if (!*p) {
- wprint("(you must specify a filename)\n");
- return 1;
- }
- (void) fseek(ed_fp, 0L, 2); /* append */
- file_to_fp(p, ed_fp, (line[1] == 'r')? "r":
- (line[1] == 'w')? "w": "a");
- /* go up one line in the message file and allow the user to edit it */
- when 'u': {
- long newpos, pos = ftell(ed_fp);
- char oldline[256];
- if (istool) {
- wprint("(Not available in tool mode.)\n");
- return 1;
- }
- if (pos <= 0L) { /* pos could be -1 if ftell() failed */
- wprint("(No previous line in file.)\n");
- return 1;
- }
- /* get the last 256 bytes written and read backwards from the
- * current place until '\n' is found. Start by moving past the
- * first \n which is at the end of the line we want to edit
- */
- newpos = max(0, pos - 256L);
- (void) fseek(ed_fp, newpos, L_SET);
- /* don't fgets -- it'll stop at a \n */
- (void) read(fileno(ed_fp), line, (int)(pos-newpos));
- pos--;
- /* the last char in line should be a \n cuz it was last input */
- if (line[(int)(pos-newpos)] != '\n')
- wprint("I don't know how, but your last line ended with %c.\n",
- line[(int)(pos-newpos)]);
- else
- line[(int)(pos-newpos)] = 0; /* null terminate \n for ^H-ing */
- for (pos--; pos > newpos && line[(int)(pos-newpos)] != '\n'; pos--)
- ;
- /* we've gone back to the end of the second previous line. Check
- * to see if the char we're pointing to is a \n. It should be, but
- * if it's not, we moved back to the first line of the file.
- */
- if (line[(int)(pos-newpos)] == '\n')
- ++pos;
- /* save the old line that's there in case the user boo-boo's */
- (void) strcpy(oldline, line+(int)(pos-newpos));
- /* let set header print out the line and get the input */
- if (!(p = set_header("", line+(int)(pos-newpos), TRUE))) {
- wprint("Something bad happened and I don't know what it is.\n");
- p = oldline;
- } else if (*p == *escape && *++p != *escape) {
- wprint("(No %c escapes on %cu lines. Line unchanged.)\n",
- *escape, *escape);
- p = oldline;
- }
- /* seek to to the position where the new line will go */
- (void) fseek(ed_fp, pos, L_SET);
- /* put the newly typed line */
- (void) fputs(p, ed_fp); /* don't add \n. padding may be necessary */
- /* if the new line is less than the old line, we're going to do
- * one of two things. The best thing to do is to truncate the
- * file to the end of the new line. Sys-v can't do that, so we
- * pad the line with blanks. May be messy in some cases, but...
- */
- if ((pos = strlen(p) - strlen(oldline)) < 0) {
- #ifndef SYSV
- /* add the \n, flush the file, truncate to the current pos */
- fputc('\n', ed_fp), fflush(ed_fp);
- (void) ftruncate(fileno(ed_fp), (int)ftell(ed_fp));
- #else
- /* pad with blanks to the length of the old line. add \n */
- while (pos++ < 0)
- fputc(' ', ed_fp);
- fputc('\n', ed_fp), fflush(ed_fp);
- #endif /* SYSV */
- } else
- /* the new line is >= the old line, add \n -- no trunc req. */
- fputc('\n', ed_fp);
- return 1;
- }
- /* break; not here cuz of "return" (lint). */
- case 'E':
- if (*p != '!' && !do_set(set_options, "nosave"))
- dead_letter();
- if (emptyfile(&ed_fp, edfile) == -1)
- error(edfile);
- else
- wprint("Message buffer empty\n");
- when 'q':
- /* save in dead.letter if nosave not set -- rm_edfile(-2). */
- rm_edfile(-2); /* doesn't return out of tool mode */
- return -1;
- /* break; not stated cuz of "return" (lint) */
- case 'x':
- /* don't save dead.letter -- simulate normal rm_edfile() call */
- rm_edfile(0);
- #ifdef SUNTOOL
- if (istool) {
- wprint("*Letter aborted*");
- type_cursor(PIX_CLR);
- }
- #endif /* SUNTOOL */
- return -1;
- /* break; (not specified for lint) */
- default:
- if (line[1] == *escape) {
- fputs(line+1, ed_fp), fputc('\n', ed_fp), fflush(ed_fp);
- return 1;
- } else if (line[1] == '?') {
- register int x;
- for (x = 0; tilde_commands[x]; x++)
- wprint("%s%s\n", escape, tilde_commands[x]);
- wprint("%s%s\t\tbegin a line with a single %s\n",
- escape, escape, escape);
- #ifdef SUNTOOL
- if (istool)
- (void) help(0, "compose", tool_help);
- #endif /* SUNTOOL */
- } else
- wprint("`%c': unknown %c escape. Use %c? for help.\n",
- line[1], *escape, *escape);
- }
- (void) fseek(ed_fp, 0L, 2); /* seek to end of file in case there's more */
- wprint("(continue editing letter)\n");
- return 1;
- }
-
- /*
- * finish up the letter. ask for the cc line, if verify is set, ask to
- * verify sending, continue editing, or to dump the whole idea.
- * Then check for signature and fortune. Finally, pass it to send_it()
- * to actually send it off.
- */
- finish_up_letter()
- {
- register char *p;
- int c;
- char buf[MAXPATHLEN];
-
- /* forwarded mail has no additional peronalized text */
- if (ison(flags, FORWARD)) {
- send_it();
- turnoff(glob_flags, IS_GETTING);
- return 1;
- }
-
- if (isoff(glob_flags, REDIRECT)) {
- if (!istool &&
- do_set(set_options, "askcc") && (p = set_header("Cc: ", Cc, 1)))
- (void) strcpy(Cc, p);
- /* ~v on the Cc line asks for verification, first initialize p! */
- p = NULL;
- if (!strncmp(Cc, "~v", 2) || (p = do_set(set_options, "verify"))) {
- if (!p) /* so we don't Cc to ~v! */
- *Cc = 0;
- for (;;) {
- #ifdef SUNTOOL
- if (istool) {
- type_cursor(PIX_CLR);
- print("Send, Continue, Discard [Left, Middle, Right]?");
- c = confirm(msg_sw->ts_windowfd);
- clr_bot_line(); /* really: clears print window */
- if (isascii(c))
- Lower(c);
- else switch(c) {
- when MS_LEFT : c = 's';
- when MS_MIDDLE : c = 'c';
- when MS_RIGHT : c = 'd';
- otherwise: c = 0;
- }
- } else
- #endif /* SUNTOOL */
- {
- print("send, continue editing, discard [s,c,d]? ");
- c = Getstr(buf, sizeof(buf), 0);
- }
- if (c < 0)
- putchar('\n');
- else if (!istool)
- c = lower(*buf);
- if (c == 'd') {
- rm_edfile(-2);
- return 1;
- } else if (c == 'c') {
- wprint("(continue editing letter)\n");
- #ifdef SUNTOOL
- if (istool)
- type_cursor(PIX_SRC);
- #endif /* SUNTOOL */
- return 0;
- } else if (c == 's')
- break;
- }
- }
- }
-
- #ifdef SUNTOOL
- if (istool)
- lock_cursors();
- #endif /* SUNTOOL */
- send_it();
- turnoff(glob_flags, IS_GETTING);
- return 1;
- }
-
- /*
- * actually send the letter.
- * 1. reset all the signals because of fork.
- * 2. determine recipients (users, address, files, programs)
- * 3. determine mailer, fork and return (if not verbose).
- * 4. popen mailer, $record, and other files specified in step 1.
- * 5. make the headers; this includes To: line, and user set headers, etc...
- * 6. copy the letter right into the array of file pointers (step 1).
- * 7. close the mailer and other files (step 1) and remove the edit-file.
- */
- static void
- send_it()
- {
- register char *p, *b, *addr_list;
- #ifdef MAXFILES
- register int size = MAXFILES - 1;
- FILE *files[MAXFILES];
- #else
- register int size = getdtablesize() - 1;
- FILE *files[30]; /* 30 should be sufficiently large enough */
- #endif /* MAXFILES */
- int next_file = 1; /* reserve files[0] for the mail delivery program */
- char buf[3*BUFSIZ];
- char expand = !do_set(set_options, "no_expand");
-
- if (!istool) {
- (void) signal(SIGINT, oldint);
- (void) signal(SIGQUIT, oldquit);
- (void) signal(SIGTERM, oldterm);
- }
-
- if (!(p = do_set(set_options, "sendmail")))
- p = MAIL_DELIVERY;
-
- #ifdef VERBOSE_ARG
- if (ison(flags, VERBOSE) || do_set(set_options, "verbose"))
- b = &buf[strlen(sprintf(buf, "%s %s", p, VERBOSE_ARG))];
- else
- #endif /* VERBOSE_ARG */
- b = buf + Strcpy(buf, p);
- #ifdef METOO_ARG
- if (!strcmp(p, MAIL_DELIVERY) && do_set(set_options, "metoo"))
- b += strlen(sprintf(b, " %s", METOO_ARG));
- #endif /* METOO_ARG */
- *b++ = ' ', *b = 0; /* strcat(b, " "); */
- addr_list = b; /* save this position to check for addresses later */
-
- /*
- * Build the address lines to give to the mail transfer system. This
- * address line connot contain comment fields! First, expand aliases
- * since they may contain comment fields within addresses. Copy this
- * result back into the Buffer since this will go into the header ...
- * Next, remove all comments so the buffer contains ONLY valid addresses.
- * Next, strip off any filenames/programs which might occur in the list.
- * Finally, add this information to the command line buffer (buf).
- * Remove commas if necessary (see ifdef's). In the event of errors,
- * force a dead letter by rm_edfile(-1). But, rm_edfile will exit with -1
- * arg, so kludge by turning on the VERBOSE bit in "flags".
- */
- if (!(p = alias_to_address(To))) {
- print("address expansion failed for To: line.\n");
- turnon(flags, VERBOSE);
- rm_edfile(-1);
- } else {
- next_file += find_files(p, files+next_file, size - next_file);
- if (expand)
- (void) strcpy(To, p);
- rm_cmts_in_addr(p);
- skipspaces(0);
- if (!*p) {
- print("There must be at least 1 legal recipient on the To line\n");
- while (--next_file > 1)
- fclose(files[next_file]);
- rm_edfile(-2);
- return;
- }
- b += Strcpy(b, p);
- }
- if (*Cc) {
- if (!(p = alias_to_address(Cc))) {
- print("address expansion failed for Cc: line.\n");
- turnon(flags, VERBOSE);
- while (--next_file > 1)
- fclose(files[next_file]);
- rm_edfile(-1);
- } else {
- next_file += find_files(p, files+next_file, size - next_file);
- if (expand)
- (void) strcpy(Cc, p);
- rm_cmts_in_addr(p);
- skipspaces(0);
- if (*p) {
- *b++ = ',', *b++ = ' ';
- b += Strcpy(b, p);
- }
- }
- }
-
- /* Sign the letter before adding the Bcc list since they aren't
- * considered when adding a signature.
- */
- if (ison(flags, SIGN) && isoff(glob_flags, REDIRECT))
- sign_letter(addr_list);
-
- if (*Bcc) {
- if (!(p = alias_to_address(Bcc))) {
- print("address expansion failed for Bcc: line.\n");
- turnon(flags, VERBOSE);
- while (--next_file > 1)
- fclose(files[next_file]);
- rm_edfile(-1);
- } else {
- next_file += find_files(p, files+next_file, size - next_file);
- (void) strcpy(Bcc, p);
- rm_cmts_in_addr(p);
- skipspaces(0);
- if (*p) {
- *b++ = ',', *b++ = ' ';
- b += Strcpy(b, p);
- }
- }
- }
-
- #ifdef OLD_MAILER
- for (p = buf; p = index(p, ','); p++)
- *p = ' ';
- #endif /* OLD_MAILER */
-
- Debug("mail command: %s\n", buf);
-
- #ifdef SUNTOOL
- if (istool)
- abort_mail(NO_ITEM, 0);
- #endif /* SUNTOOL */
-
- if (isoff(flags, VERBOSE) && debug < 3)
- switch (fork()) {
- case 0: /* the child will send the letter. ignore signals */
- #ifdef SYSV
- if (setpgrp() == -1)
- error("setpgrp");
- #endif /* SYSV */
- (void) signal(SIGINT, SIG_IGN);
- (void) signal(SIGHUP, SIG_IGN);
- (void) signal(SIGQUIT, SIG_IGN);
- (void) signal(SIGTERM, SIG_IGN);
- #ifdef SIGTTIN
- (void) signal(SIGTTOU, SIG_IGN);
- (void) signal(SIGTTIN, SIG_IGN);
- #endif /* SIGTTIN */
- #ifdef SIGCONT
- (void) signal(SIGCONT, SIG_IGN);
- (void) signal(SIGTSTP, SIG_IGN);
- #endif /* SIGCONT */
- turnon(glob_flags, IGN_SIGS);
- break;
- case -1:
- error("fork failed trying to send mail");
- default:
- if (isoff(glob_flags, REDIRECT))
- fclose(ed_fp);
- #ifdef SUNTOOL
- if (istool) {
- wprint("Letter sent.");
- print("Letter sent.");
- type_cursor(PIX_CLR);
- }
- #endif /* SUNTOOL */
- while (--next_file > 0)
- fclose(files[next_file]);
- return;
- }
-
- if (debug > 2)
- files[0] = stdout;
- else if (!(files[0] = open_file(buf, TRUE))) {
- rm_edfile(-1); /* force saving of undeliverable mail */
- return;
- }
-
- if (ison(flags, VERBOSE))
- wprint("Sending letter ... ");
-
- /* see if record is set. If so, open that file for appending and add
- * the letter in a format such that mail can be read from it
- */
- if (p = do_set(set_options, "record")) {
- if (!*p)
- p = "~/record";
- (void) strcpy(buf, p);
- next_file += find_files(buf, files+next_file, size - next_file);
- }
-
- /* Make folders conform to RFC-822 by adding From: and Date: headers.
- * Some older mailers (binmail, execmail, delivermail), don't add
- * these headers to the MTA, so add them for OLD_MAIL systems.
- */
- for (size = 0; size < next_file; size++) {
- time_t t;
- #ifndef OLD_MAIL
- if (size == 0)
- continue;
- #endif /* OLD_MAIL */
- (void) time(&t);
- if (size > 0) {
- #ifndef MSG_SEPARATOR
- fprintf(files[size], "From %s %s", login, ctime(&t));
- #else /* MSG_SEPARATOR */
- fprintf(files[size], "%s\n", MSG_SEPARATOR);
- #endif /* MSG_SEPARATOR */
- }
- fprintf(files[size], "From: %s\n", login);
- fprintf(files[size], "Date: %s", ctime(&t));
- }
-
- /* first print users own message headers */
- if (own_hdrs && !do_set(set_options, "no_hdrs")) {
- struct options *opts;
- for (opts = own_hdrs; opts; opts = opts->next)
- for (size = 0; size < next_file; size++)
- fprintf(files[size], "%s %s\n", opts->option, opts->value);
- }
-
- /* send the header stuff to sendmail and end header with a blank line */
- for (size = 0; size < next_file; size++) {
- if (*in_reply_to)
- fprintf(files[size], "In-Reply-To: %s\n", in_reply_to);
- fprintf(files[size], "X-Mailer: %s\n", VERSION);
- fprintf(files[size], "%sTo: %s\n",
- ison(flags, FORWARD) ? "Resent-" : "", To);
- if (*Subject)
- fprintf(files[size], "Subject: %s\n", Subject);
- if (*Cc)
- fprintf(files[size], "%sCc: %s\n",
- ison(flags, FORWARD) ? "Resent-" : "", Cc);
- if (size > 0) {
- /* Do not send these to mail transfer agent */
- if (*Bcc)
- fprintf(files[size], "Bcc: %s\n", Bcc);
- fprintf(files[size], "Status: OR\n");
- }
- fputc('\n', files[size]);
- }
-
- /* if redirection, ed_fp = stdin, else rewind the file just made */
- if (isoff(glob_flags, REDIRECT))
- rewind(ed_fp);
- else
- ed_fp = stdin;
-
- /* read from stdin or the edfile till EOF and send it all to the mailer
- * and other open files/folders/programs. Check for "From " at the
- * beginnings of these lines to prevent creating new messages in folders.
- */
- while (fgets(buf, BUFSIZ, ed_fp))
- for (size = 0; size < next_file; size++) {
- if (!strncmp(buf, "From ", 5))
- fputc('>', files[size]);
- fputs(buf, files[size]);
- }
-
- /* loop thru the open files (except for the first: the mail delivery agent)
- * and append a blank line so that ucb-mail can read these folders.
- * Then close the files. If the file was a popened program, the sigchld
- * that the program generates will close the file.
- */
- for (size = 1; size < next_file; size++)
- if (files[size]) {
- fputc('\n', files[size]);
- fclose(files[size]);
- }
-
- rm_edfile(0);
- if (debug < 3)
- (void) pclose(files[0]);
-
- if ((ison(flags, VERBOSE) || debug > 2) && isoff(glob_flags, REDIRECT))
- wprint("sent.\n");
- else
- exit(0); /* not a user exit -- a child exit */
- }
-
- /* ARGSUSED */
- rm_edfile(sig)
- {
- if (sig > 0 && !killme) {
- if (!istool)
- (void) signal(sig, rm_edfile);
- killme = 1;
- wprint("\n** interrupt -- one more to kill letter **\n");
- #ifdef SUNTOOL
- if (istool) {
- type_cursor(PIX_SRC);
- return;
- }
- #endif /* SUNTOOL */
- longjmp(cntrl_c_buf, 1);
- }
- killme = 0;
- /* if sig == -1, force a save into dead.letter.
- * else, check for nosave not being set and save anyway if it's not set
- * sig == 0 indicates normal exit (or ~x), so don't save a dead letter.
- */
- if (sig == -1 || sig != 0 && !do_set(set_options, "nosave"))
- dead_letter();
- if (isoff(glob_flags, REDIRECT))
- fclose(ed_fp);
- (void) unlink(edfile);
-
- if (sig == -1 && isoff(flags, VERBOSE) && debug < 3)
- exit(-1);
-
- turnoff(glob_flags, IS_GETTING);
- #ifdef SUNTOOL
- if (sig && istool > 1) {
- wprint("*Letter aborted*");
- abort_mail(abort_item, 2);
- }
- #endif /* SUNTOOL */
-
- if (sig == SIGHUP)
- cleanup(0);
- if (!istool) {
- (void) signal(SIGINT, oldint);
- (void) signal(SIGQUIT, oldquit);
- (void) signal(SIGTERM, oldterm);
- }
-
- if (sig == 0)
- return;
- if (istool || sig == -2) /* make sure sigchld is reset first */
- return;
-
- if (isoff(glob_flags, DO_SHELL)) { /* If we're not in a shell, exit */
- puts("exiting");
- echo_on();
- exit(1);
- }
- longjmp(jmpbuf, 1);
- }
-
- /* save letter into dead letter */
- dead_letter()
- {
- char *p, buf[BUFSIZ];
- long t;
- FILE *dead;
-
- if (ison(glob_flags, REDIRECT)) {
- print("input redirected -- can't save dead letter.\n");
- return;
- }
- /* If the file doesn't exist, get outta here. File may not exist if
- * user generated a ^C from a promptable header and catch sent us here.
- */
- if (Access(edfile, R_OK))
- return;
- /* User may have killed mush via a signal while he was in an editor.
- * ed_fp will be NULL in this case. Since the file does exist (above),
- * open it so we can copy it to dead letter.
- */
- if (!ed_fp && !(ed_fp = fopen(edfile, "r"))) {
- error("can't save dead letter from %s", edfile);
- return;
- }
- /* don't save a dead letter if there's nothing to save. */
- if (fseek(ed_fp, 0L, 2) || ftell(ed_fp) == 0L)
- return;
- if (!(p = do_set(set_options, "dead")))
- p = "~/dead.letter";
- if (!(dead = open_file(p, FALSE)))
- return;
- (void) time (&t);
- fflush(ed_fp);
- rewind(ed_fp);
- fprintf(dead, "Unfinished letter from %s", ctime(&t));
- fprintf(dead, "To: %s\nSubject: %s\n", To, Subject);
- if (*Cc)
- fprintf(dead, "Cc: %s\n", Cc);
- while(fgets(buf, sizeof(buf), ed_fp))
- (void) fputs(buf, dead);
- (void) fputc('\n', dead);
- (void) fclose(dead);
- print("Saved unfinished letter in %s.\n", p);
- }
-
- /*
- * Your "signature" is of the type:
- * file_or_path
- * $varaible
- * \ literal string preceded by a backslash.
- * The variable will be expanded into its string value.
- * To sign the letter, the list of addresses is passed to this routine
- * (separated by spaces and/or commas). If "autosign2" is set,
- * then it must be of the form.
- * autosign2 = "user@foo user@bar address...: <signature>"
- * Spaces or tabs separate tokens. If everyone on the list exists in
- * the autosign2 list, the alternate signature is used. In case of
- * syntax error, the alternate signature is used without checks (e.g. if
- * the : is missing). The alternate signature == null is the same as
- * not signing the letter. An empty list forces signature2.
- *
- * If autosign2 is not set at all, then autosign is checked and used.
- * autosign = <signature>
- */
- sign_letter(list)
- register char *list; /* list of addresses -- no comment fields */
- {
- char buf[BUFSIZ];
- register char *p, *p2, *signature, *addr;
- FILE *pp2;
- int lines = 0;
-
- buf[0] = 0;
- while (isspace(*list))
- list++;
- if (p = do_set(set_options, "autosign2")) {
- if (!(signature = index(p, ':')))
- wprint("\"autosign2\" incorrectly set (missing `:').\n");
- else {
- int ret_val = 0;
- *signature = 0;
- /* p now points to a list of addresses and p2 points to the
- * signature format to use. Check that each address contains
- * the stuff in alternate sign.
- */
- skipspaces(0);
- if (!*p)
- /* autosign2 = " : <signature>" send to all recipients */
- ret_val = 1;
- else if (p = alias_to_address(p)) {
- rm_cmts_in_addr(p);
- for (addr = list;;) {
- char c;
- if (p2 = any(addr, ", ")) {
- c = *p2;
- *p2 = 0;
- }
- ret_val = chk_two_lists(addr, p, ", ");
- if (p2)
- for (*p2++ = c; isspace(*p2) || *p2 == ','; p2++)
- ;
- if (!ret_val || !(addr = p2))
- break;
- }
- }
- *signature++ = ':'; /* must reset first! */
- if (ret_val) {
- while (isspace(*signature))
- signature++;
- if (!*strcpy(buf, signature))
- return;
- }
- }
- }
- if (!buf[0]) {
- if (!(p = do_set(set_options, "autosign")) || !*p) {
- char *home;
- if (!(home = do_set(set_options, "home")) || !*home)
- home = ALTERNATE_HOME;
- (void) sprintf(buf, "%s/%s", home, SIGNATURE);
- } else
- (void) strcpy(buf, p);
- wprint("Signing letter... ");
- } else
- wprint("Using alternate signature... ");
- fputc('\n', ed_fp), fflush(ed_fp);
- (void) fseek(ed_fp, 0L, 2); /* guarantee position at end of file */
- if (*buf == '$')
- if (!(p = do_set(set_options, buf)))
- wprint("(%s isn't set -- letter not signed)\n", buf);
- else
- fprintf(ed_fp, "%s\n", p), wprint("\n"), fflush(ed_fp);
- else if (*buf == '\\')
- fprintf(ed_fp, "%s\n", buf+1), wprint("\n"), fflush(ed_fp);
- else
- file_to_fp(buf, ed_fp, "r");
-
- /* if fortune is set, check to see if fortunates is set. If so,
- * check to see if all the recipient are on the fortunates list.
- */
- if (ison(flags, DO_FORTUNE)) {
- if (p = do_set(set_options, "fortunates")) {
- int ret_val;
- if (!(p = alias_to_address(p)))
- return; /* no reason to hang around */
- rm_cmts_in_addr(p);
- for (addr = list;;) {
- char c;
- if (p2 = any(addr, ", ")) {
- c = *p2;
- *p2 = 0;
- }
- if (!(ret_val = chk_two_lists(addr, p, ", ")))
- (void) strcpy(buf, addr);
- if (p2)
- for (*p2++ = c; isspace(*p2) || *p2 == ','; p2++)
- ;
- if (!ret_val || !(addr = p2))
- break;
- }
- if (!ret_val) {
- wprint("\"fortunates\" does not contain \"%s\".\n", buf);
- wprint("No fortune added.\n");
- return;
- }
- }
- wprint("You may be fortunate... ");
- if ((p = do_set(set_options, "fortune")) && *p == '/')
- (void) strcpy(buf, p);
- else
- (void) sprintf(buf, "%s %s", FORTUNE, (p && *p == '-')? p: "-s");
- if (!(pp2 = popen(buf, "r")))
- error(buf);
- else {
- turnon(glob_flags, IGN_SIGS);
- (void) fseek(ed_fp, 0L, 2); /* go to end of file */
- while (fgets(buf, sizeof(buf), pp2))
- fputs(buf, ed_fp), lines++;
- (void) pclose(pp2);
- turnoff(glob_flags, IGN_SIGS);
- fflush(ed_fp);
- wprint("added %d line%s\n", lines, lines == 1? "" : "s");
- }
- }
- }
-