home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume9
/
elm2
/
part17
< prev
next >
Wrap
Text File
|
1987-03-10
|
42KB
|
1,457 lines
Subject: v09i017: ELM Mail System, Part17/19
Newsgroups: mod.sources
Approved: rs@mirror.TMC.COM
Submitted by: Dave Taylor <hplabs!taylor>
Mod.sources: Volume 9, Issue 17
Archive-name: elm2/Part17
#! /bin/sh
# This is a shell archive. Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
# If this archive is complete, you will see the message:
# "End of archive 17 (of 19)."
# Contents: src/elm.c src/mailmsg2.c
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo shar: Extracting \"src/elm.c\" \(19751 characters\)
if test -f src/elm.c ; then
echo shar: Will not over-write existing file \"src/elm.c\"
else
sed "s/^X//" >src/elm.c <<'END_OF_src/elm.c'
X/** elm.c **/
X
X/* Main program of the ELM mail system!
X
X This file and all associated files and documentation:
X (C) Copyright 1986 Dave Taylor
X*/
X
X#include "elm.h"
X
X#ifdef BSD
X# undef toupper
X# undef tolower
X#endif
X
Xlong bytes();
Xchar *format_long();
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X char ch, address[SLEN], to_whom[LONG_SLEN];
X int redraw, /** do we need to rewrite the entire screen? **/
X nuhead, /** or perhaps just the headers section... **/
X nucurr, /** or just the current message pointer... **/
X nufoot; /** clear lines 16 thru bottom and new menu **/
X int i; /** Random counting variable (etc) **/
X int pageon, /** for when we receive new mail... **/
X last_in_mailbox; /** for when we receive new mail too... **/
X
X parse_arguments(argc, argv, to_whom);
X
X if (mail_only) {
X
X initialize(FALSE);
X
X Raw(ON);
X dprint1(3,"Mail-only: mailing to\n-> \"%s\"\n",
X format_long(to_whom, 3));
X (void) send(to_whom, "", TRUE, NO);
X leave(0);
X }
X
X initialize(TRUE);
X
X ScreenSize(&LINES, &COLUMNS);
X
X showscreen();
X
X mailfile_size = bytes(infile);
X
X Raw(ON);
X
X while (1) {
X redraw = 0;
X nuhead = 0;
X nufoot = 0;
X nucurr = 0;
X if ((i = bytes(infile)) != mailfile_size) {
X dprint1(2,"Just received %d bytes more mail (elm)\n",
X i - mailfile_size);
X error("New mail has arrived! Hang on...");
X last_in_mailbox = message_count;
X pageon = header_page;
X newmbox(2, FALSE, TRUE); /* last won't be touched! */
X clear_error();
X header_page = pageon;
X
X if (on_page(current)) /* do we REALLY have to rewrite? */
X showscreen();
X else {
X update_title();
X ClearLine(LINES-1); /* remove reading message... */
X error2("%d new message%s received",
X message_count - last_in_mailbox,
X plural(message_count - last_in_mailbox));
X }
X mailfile_size = i;
X if (cursor_control)
X transmit_functions(ON); /* insurance */
X }
X
X prompt("Command: ");
X
X CleartoEOLN();
X ch = tolower(GetPrompt());
X CleartoEOS();
X dprint1(4, "\nCommand: %c\n\n", ch);
X
X set_error(""); /* clear error buffer */
X
X MoveCursor(LINES-3,strlen("Command: "));
X
X switch (ch) {
X
X case '?' : if (help())
X redraw++;
X else
X nufoot++;
X break;
X
X case '$' : resync(); break;
X
X case ' ' :
X case '+' : header_page++; nuhead++;
X if (move_when_paged && header_page <=
X (message_count / headers_per_page)) {
X current = header_page*headers_per_page + 1;
X if (selected)
X current = visible_to_index(current)+1;
X }
X break;
X
X case '-' : header_page--; nuhead++;
X if (move_when_paged && header_page >= 0) {
X current = header_page*headers_per_page + 1;
X if (selected)
X current = visible_to_index(current)+1;
X }
X break;
X
X case '=' : if (selected)
X current = visible_to_index(1)+1;
X else
X current = 1;
X if (get_page(current))
X nuhead++;
X else
X nucurr++; break;
X
X case '*' : if (selected)
X current = (visible_to_index(selected)+1);
X else
X current = message_count;
X if (get_page(current))
X nuhead++;
X else
X nucurr++; break;
X
X case '|' : Writechar('|');
X softkeys_off();
X redraw = do_pipe();
X softkeys_on(); break;
X
X case '!' : Writechar('!');
X softkeys_off();
X redraw = subshell();
X softkeys_on(); break;
X
X case '%' : get_return(address);
X clear_error();
X PutLine1(LINES,(COLUMNS-strlen(address))/2,
X "%.78s", address);
X break;
X
X case '/' : if (pattern_match()) {
X if (get_page(current))
X nuhead++;
X else
X nucurr++;
X }
X else
X error("pattern not found!");
X break;
X
X case '<' : /* scan current message for calendar information */
X#ifdef ENABLE_CALENDAR
X PutLine0(LINES-3, strlen("Command: "),
X "Scan message for calendar entries...");
X scan_calendar();
X#else
X error("Sorry - calendar function disabled");
X#endif
X break;
X
X case 'a' : alias();
X nufoot++;
X define_softkeys(MAIN); break;
X
X case 'b' : PutLine0(LINES-3, strlen("Command: "),
X "Bounce message");
X fflush(stdout);
X if (message_count < 1)
X error("No mail to bounce!");
X else
X nufoot = remail();
X break;
X
X case 'c' : PutLine0(LINES-3, strlen("Command: "),
X "Change mailbox");
X define_softkeys(CHANGE);
X if ((file_changed = leave_mbox(FALSE)) != -1) {
X redraw = newmbox(0, TRUE, TRUE);
X dprint1(1, "** redraw returned as %d **\n",
X redraw);
X mailfile_size = bytes(infile);
X }
X else {
X file_changed = 0;
X sort_mailbox(message_count, FALSE);
X }
X define_softkeys(MAIN);
X break;
X
X case '^' :
X case 'd' : if (message_count < 1)
X error("No mail to delete!");
X else {
X delete_msg((ch == 'd'));
X if (resolve_mode) /* move after mail resolved */
X if (current < message_count) {
X current++;
X if (get_page(current))
X nuhead++;
X else
X nucurr++;
X }
X }
X break;
X
X case ctrl('D') : if (message_count < 1)
X error("No mail to delete!");
X else
X meta_match(DELETED);
X break;
X
X case 'e' : PutLine0(LINES-3,strlen("Command: "),"Edit mailbox");
X if (current > 0) {
X edit_mailbox();
X if (cursor_control)
X transmit_functions(ON); /* insurance */
X }
X else
X error("Mailbox is empty!");
X break;
X
X case 'f' : PutLine0(LINES-3, strlen("Command: "), "Forward");
X define_softkeys(YESNO);
X if (current > 0)
X redraw = forward();
X else
X error("No mail to forward!");
X define_softkeys(MAIN);
X break;
X
X case 'g' : PutLine0(LINES-3,strlen("Command: "), "Group reply");
X fflush(stdout);
X if (current > 0) {
X if (header_table[current-1].status & FORM_LETTER)
X error("Can't group reply to a Form!!");
X else {
X PutLine0(LINES-3,COLUMNS-40,
X "building addresses...");
X define_softkeys(YESNO);
X redraw = reply_to_everyone();
X define_softkeys(MAIN);
X }
X }
X else
X error("No mail to reply to!");
X break;
X
X case 'h' : if (filter)
X PutLine0(LINES-3, strlen("Command: "),
X "Message with headers...");
X else
X PutLine0(LINES-3, strlen("Command: "),"Read message");
X fflush(stdout);
X i = filter;
X filter = FALSE;
X redraw = show_msg(current);
X filter = i;
X break;
X
X case 'j' : if (selected) {
X if ((current = next_visible(current)) < 0)
X current = visible_to_index(selected)+1;
X }
X else
X current++;
X if (get_page(current))
X nuhead++;
X else
X nucurr++; break;
X
X case 'k' : if (selected)
X current = previous_visible(current);
X else
X current--;
X if (get_page(current))
X nuhead++;
X else
X nucurr++; break;
X
X case 'l' : PutLine0(LINES-3, strlen("Command: "),
X "Limit displayed messages by...");
X if (limit() != 0) {
X nuhead++;
X update_title(); /* poof! */
X }
X else
X nufoot++;
X break;
X
X case 'm' : PutLine0(LINES-3, strlen("Command: "), "Mail");
X redraw = send("", "", TRUE, allow_forms);
X break;
X
X case ctrl('J'):
X case ctrl('M'):PutLine0(LINES-3, strlen("Command: "), "Read Message");
X fflush(stdout);
X define_softkeys(READ);
X redraw = show_msg(current);
X break;
X
X case 'n' : PutLine0(LINES-3, strlen("Command: "), "Next Message");
X fflush(stdout);
X define_softkeys(READ);
X redraw = show_msg(current);
X current += redraw;
X if (current > message_count)
X current = message_count;
X (void) get_page(current); /* rewrites ANYway */
X break;
X
X case 'o' : PutLine0(LINES-3, strlen("Command: "), "Options");
X options();
X redraw++; /* always fix da screen... */
X break;
X
X case 'p' : PutLine0(LINES-3, strlen("Command: "), "Print mail");
X fflush(stdout);
X if (message_count < 1)
X error("No mail to print!");
X else
X printmsg();
X break;
X
X case 'q' : PutLine0(LINES-3, strlen("Command: "), "Quit");
X
X if (mbox_specified == 0) lock(OUTGOING);
X
X if (mailfile_size != bytes(infile)) {
X error("New Mail! Quit cancelled...");
X if (mbox_specified == 0) unlock();
X }
X else
X quit();
X
X break;
X
X case 'r' : PutLine0(LINES-3, strlen("Command: "),
X "Reply to message");
X if (current > 0)
X redraw = reply();
X else
X error("No mail to reply to!");
X softkeys_on();
X break;
X
X case '>' : /** backwards compatibility **/
X
X case 's' : if (message_count < 1)
X error("No mail to save!");
X else {
X PutLine0(LINES-3, strlen("Command: "),
X "Save Message");
X PutLine0(LINES-3,COLUMNS-40,
X "(Use '?' to list your folders)");
X if (save(&redraw) && resolve_mode) {
X if (current < message_count) {
X current++; /* move to next message */
X if (get_page(current))
X nuhead++;
X else
X nucurr++;
X }
X }
X }
X ClearLine(LINES-2);
X break;
X
X case ctrl('T') :
X case 't' : if (message_count < 1)
X error("no mail to tag!");
X else if (ch == 't')
X tag_message();
X else
X meta_match(TAGGED);
X break;
X
X case 'u' : if (message_count < 1)
X error("no mail to mark as undeleted!");
X else {
X undelete_msg();
X if (resolve_mode) /* move after mail resolved */
X if (current < message_count) {
X current++;
X if (get_page(current))
X nuhead++;
X else
X nucurr++;
X }
X }
X break;
X
X case ctrl('U') : if (message_count < 1)
X error("No mail to undelete!");
X else
X meta_match(UNDELETE);
X break;
X
X case ctrl('Q') :
X case ctrl('?') :
X case 'x' : PutLine0(LINES-3, strlen("Command: "), "Exit");
X fflush(stdout); leave();
X
X case ctrl('L') : redraw++; break;
X
X case '@' : debug_screen(); redraw++; break;
X
X case '#' : debug_message(); redraw++; break;
X
X case NO_OP_COMMAND : break; /* noop for timeout loop */
X
X case ESCAPE : if (cursor_control) {
X ch = ReadCh();
X if (ch == up[1]) {
X if (selected)
X current = previous_visible(current);
X else
X current--;
X if (get_page(current))
X nuhead++;
X else
X nucurr++;
X }
X else if (ch == down[1]) {
X if (selected) {
X if ((current = next_visible(current)) < 0)
X current = visible_to_index(selected)+1;
X }
X else
X current++;
X if (get_page(current))
X nuhead++;
X else
X nucurr++;
X }
X else if (hp_terminal) {
X
X switch (ch) {
X case 'U' : /* <NEXT> */
X header_page++;
X nuhead++;
X if (move_when_paged && header_page
X <= (message_count / headers_per_page)) {
X current = header_page*headers_per_page + 1;
X if (selected)
X current = visible_to_index(current)+1;
X }
X break;
X
X case 'V' : /* <PREV> */
X header_page--;
X nuhead++;
X if (move_when_paged && header_page >= 0) {
X current = header_page*headers_per_page + 1;
X if (selected)
X current = visible_to_index(current)+1;
X }
X break;
X
X case 'h' :
X case 'H' : /* <HOME UP> */
X if (selected)
X current = visible_to_index(1)+1;
X else
X current = 1;
X if (get_page(current))
X nuhead++;
X else
X nucurr++;
X break;
X
X case 'F' : /* <HOME DOWN> */
X if (selected)
X current = visible_to_index(selected)+1;
X else
X current = message_count;
X if (get_page(current))
X nuhead++;
X else
X nucurr++;
X break;
X
X /** let's continue, what the heck... **/
X
X case 'A' : /* <UP> */
X case 'D' : /* <BACKTAB> */
X case 'i' : /* <LEFT> */
X if (selected)
X current = previous_visible(current);
X else
X current--;
X if (get_page(current))
X nuhead++;
X else
X nucurr++;
X break;
X
X case 'B' : /* <UP> */
X case 'I' : /* <BACKTAB> */
X case 'C' : /* <LEFT> */
X if (selected) {
X if ((current = next_visible(current)) < 0)
X current = visible_to_index(selected)+1;
X }
X else
X current++;
X if (get_page(current))
X nuhead++;
X else
X nucurr++;
X break;
X
X default: PutLine2(LINES-3, strlen("Command: "),
X "%c%c", ESCAPE, ch);
X }
X }
X else /* false hit - output */
X PutLine2(LINES-3, strlen("Command: "),
X "%c%c", ESCAPE, ch);
X break;
X }
X
X /* else fall into the default error message! */
X
X default : if (ch > '0' && ch <= '9') {
X PutLine0(LINES-3, strlen("Command: "),
X "New Current Message");
X current = read_number(ch);
X if (selected) {
X if ((current = visible_to_index(current)+1) >
X message_count)
X goto too_big;
X }
X if (get_page(current))
X nuhead++;
X else
X nucurr++;
X }
X else
X error("Unknown command: Use '?' for commands");
X }
X
X dprint5(4,"redraw=%s, current=%d, nuhead=%s, nufoot=%s, nucurr=%s\n",
X onoff(redraw), current, onoff(nuhead), onoff(nufoot),
X onoff(nucurr));
X
X if (redraw)
X showscreen();
X
X if (current < 1) {
X if (message_count > 0) {
X error("already at message #1!");
X if (selected)
X current = compute_visible(0); /* get to #0 */
X else
X current = 1;
X }
X else if (current < 0) {
X error("No messages to read!");
X current = 0;
X }
X }
X else if (current > message_count) {
X if (message_count > 0) {
Xtoo_big:
X if (selected) {
X error2("only %d message%s selected!", selected,
X plural(selected));
X current = compute_visible(selected);
X }
X else {
X error2("only %d message%s!", message_count,
X plural(message_count));
X current = message_count;
X }
X }
X else {
X error("No messages to read!");
X current = 0;
X }
X }
X else if (selected && (i=visible_to_index(selected)) > message_count) {
X error2("only %d message%s selected!", selected, plural(selected));
X current = i+1; /* FIXED! Phew! */
X }
X
X if (nuhead)
X show_headers();
X else if (nucurr)
X show_current();
X else if (nufoot) {
X if (mini_menu) {
X MoveCursor(LINES-7, 0);
X CleartoEOS();
X show_menu();
X }
X else {
X MoveCursor(LINES-4, 0);
X CleartoEOS();
X }
X }
X
X } /* the BIG while loop! */
X}
X
Xdebug_screen()
X{
X /**** spit out all the current variable settings and the table
X entries for the current 'n' items displayed. ****/
X
X register int i, j;
X char buffer[SLEN];
X
X ClearScreen();
X Raw(OFF);
X
X PutLine2(0,0,"Current message number = %d\t\t%d message(s) total\n",
X current, message_count);
X PutLine2(2,0,"Header_page = %d \t\t%d possible page(s)\n",
X header_page, (int) (message_count / headers_per_page) + 1);
X
X PutLine1(4,0,"\nCurrent mailfile is %s.\n\n", infile);
X
X i = header_page*headers_per_page; /* starting header */
X
X if ((j = i + (headers_per_page-1)) >= message_count)
X j = message_count-1;
X
X Write_to_screen(
X"Num From Subject Lines Offset\n\n",0);
X
X while (i <= j) {
X sprintf(buffer,
X "%3d %-16.16s %-40.40s %4d %d\n",
X i+1,
X header_table[i].from,
X header_table[i].subject,
X header_table[i].lines,
X header_table[i].offset);
X Write_to_screen(buffer, 0);
X i++;
X }
X
X Raw(ON);
X
X PutLine0(LINES,0,"Press any key to return: ");
X (void) ReadCh();
X}
X
X
Xdebug_message()
X{
X /**** Spit out the current message record. Include EVERYTHING
X in the record structure. **/
X
X char buffer[SLEN];
X
X ClearScreen();
X Raw(OFF);
X
X Write_to_screen("\t\t\t----- Message %d -----\n\n\n\n", 1,
X current);
X
X Write_to_screen("Lines : %-5d\t\t\t\tStatus: N E A P D T V\n", 1,
X header_table[current-1].lines);
X Write_to_screen(" \t\t\t\t e x c r e a i\n", 0);
X Write_to_screen(" \t\t\t\t w p t i l g s\n", 0);
X
X sprintf(buffer,
X "\nOffset: %ld\t\t\t\t %d %d %d %d %d %d %d\n",
X header_table[current-1].offset,
X (header_table[current-1].status & NEW) != 0,
X (header_table[current-1].status & EXPIRED) != 0,
X (header_table[current-1].status & ACTION) != 0,
X (header_table[current-1].status & PRIORITY) != 0,
X (header_table[current-1].status & DELETED) != 0,
X (header_table[current-1].status & TAGGED) != 0,
X (header_table[current-1].status & VISIBLE) != 0);
X Write_to_screen(buffer, 0);
X
X sprintf(buffer, "\nReceived on: %d/%d/%d at %d:%02d\n\n",
X header_table[current-1].received.month+1,
X header_table[current-1].received.day,
X header_table[current-1].received.year,
X header_table[current-1].received.hour,
X header_table[current-1].received.minute);
X Write_to_screen(buffer, 0);
X
X sprintf(buffer, "Message sent on: %s, %s %s, %s at %s\n\n",
X header_table[current-1].dayname,
X header_table[current-1].month,
X header_table[current-1].day,
X header_table[current-1].year,
X header_table[current-1].time);
X Write_to_screen(buffer, 0);
X
X Write_to_screen("\nFrom: %s\n\nSubject: %s", 2,
X header_table[current-1].from,
X header_table[current-1].subject);
X
X Write_to_screen("\nTo: %s\n\nIndex = %d\n", 2,
X header_table[current-1].to,
X header_table[current-1].index_number);
X
X Raw(ON);
X
X PutLine0(LINES,0,"Press any key to return: ");
X (void) ReadCh();
X}
END_OF_src/elm.c
if test 19751 -ne `wc -c <src/elm.c`; then
echo shar: \"src/elm.c\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"src/mailmsg2.c\" \(19017 characters\)
if test -f src/mailmsg2.c ; then
echo shar: Will not over-write existing file \"src/mailmsg2.c\"
else
sed "s/^X//" >src/mailmsg2.c <<'END_OF_src/mailmsg2.c'
X/** mailmsg2.c **/
X
X/** Interface to allow mail to be sent to users. Part of ELM **/
X
X/** (C) Copyright 1986, Dave Taylor **/
X
X#include "headers.h"
X#include <errno.h>
X
Xextern int errno;
X
Xchar *error_name(), *error_description(), *strip_parens();
Xchar *strcat(), *strcpy();
Xchar *format_long(), *strip_commas(), *tail_of_string();
X
Xunsigned long sleep();
X
X#ifdef SITE_HIDING
X char *get_ctime_date();
X#endif
XFILE *write_header_info();
X
Xextern char subject[SLEN], action[SLEN], reply_to[SLEN], expires[SLEN],
X priority [SLEN], to[VERY_LONG_STRING], cc[VERY_LONG_STRING],
X in_reply_to[SLEN], expanded_to[VERY_LONG_STRING],
X expanded_cc[VERY_LONG_STRING], user_defined_header[SLEN];
X#ifdef ALLOW_BCC
Xextern char bcc[VERY_LONG_STRING], expanded_bcc[VERY_LONG_STRING];
X#endif
X
Xint gotten_key = 0;
X
Xchar *bounce_off_remote();
X
Xmail(copy_msg, edit_message, batch, form)
Xint copy_msg, edit_message, batch, form;
X{
X /** Given the addresses and various other miscellany (specifically,
X 'copy-msg' indicates whether a copy of the current message should
X be included, 'edit_message' indicates whether the message should
X be edited and 'batch' indicates that the message should be read
X from stdin) this routine will invoke an editor for the user and
X then actually mail off the message. 'form' can be YES, NO, or
X MAYBE. YES=add "Content-Type: mailform" header, MAYBE=add the
X M)ake form option to last question, and NO=don't worry about it!
X Also, if 'copy_msg' = FORM, then grab the form temp file and use
X that...
X **/
X
X FILE *reply, *real_reply; /* second is post-input buffer */
X char filename[SLEN], filename2[SLEN], fname[SLEN],
X very_long_buffer[VERY_LONG_STRING];
X char ch;
X register int retransmit = FALSE;
X int already_has_text = FALSE; /* we need an ADDRESS */
X
X static int cancelled_msg = 0;
X
X dprint2(4,"\nMailing to '%s'(with%s editing)\n",
X expanded_to, edit_message? "" : "out");
X
X /** first generate the temporary filename **/
X
X sprintf(filename,"%s%d",temp_file, getpid());
X
X /** if possible, let's try to recall the last message? **/
X
X if (! batch && copy_msg != FORM && user_level != 0)
X retransmit = recall_last_msg(filename, copy_msg, &cancelled_msg,
X &already_has_text);
X
X /** if we're not retransmitting, create the file.. **/
X
X if (! retransmit)
X if ((reply = fopen(filename,"w")) == NULL) {
X dprint2(1,
X "Attempt to write to temp file %s failed with error %s (mail)\n",
X filename, error_name(errno));
X error2("Could not create file %s (%s)",filename,
X error_name(errno));
X return(1);
X }
X
X if (batch) {
X Raw(OFF);
X if (isatty(fileno(stdin))) {
X fclose(reply); /* let edit-the-message open it! */
X printf("To: %s\nSubject: %s\n", expanded_to, subject);
X strcpy(editor, "none"); /* force inline editor */
X if (no_editor_edit_the_message(filename)) {
X return(0); /* confused? edit_the_msg returns 1 if bad */
X }
X if (verify_transmission(filename, &form) == 'f')
X return(0);
X }
X else {
X while (gets(very_long_buffer) != NULL)
X fprintf(reply, "%s\n", very_long_buffer);
X }
X }
X
X if (copy_msg == FORM) {
X sprintf(fname, "%s%d", temp_form_file, getpid());
X fclose(reply); /* we can't retransmit a form! */
X if (access(fname,ACCESS_EXISTS) != 0) {
X error("couldn't find forms file!");
X return(0);
X }
X unlink(filename);
X dprint2(4, "-- linking existing file %s to file %s --\n",
X fname, filename);
X link(fname, filename);
X unlink(fname);
X }
X else if (copy_msg && ! retransmit) /* if retransmit we have it! */
X if (edit_message) {
X copy_message(prefixchars, reply, noheader, FALSE);
X already_has_text = TRUE; /* we just added it, right? */
X }
X else
X copy_message("", reply, noheader, FALSE);
X
X if (!batch && ! retransmit && signature && copy_msg != FORM) {
X fprintf(reply, "\n--\n"); /* News 2.11 compatibility? */
X if (chloc(expanded_to, '!') == -1 && chloc(expanded_to, '@') == -1) {
X if (strlen(local_signature) > 0) {
X if (local_signature[0] != '/')
X sprintf(filename2, "%s/%s", home, local_signature);
X else
X strcpy(filename2, local_signature);
X (void) append(reply, filename2);
X already_has_text = TRUE; /* added signature... */
X }
X }
X else {
X if (remote_signature[0] != '/')
X sprintf(filename2, "%s/%s", home, remote_signature);
X else
X strcpy(filename2, remote_signature);
X (void) append(reply, filename2);
X already_has_text = TRUE; /* added signature... */
X }
X }
X
X if (! retransmit && copy_msg != FORM)
X (void) fclose(reply); /* on replies, it won't be open! */
X
X /** Edit the message **/
X
X if (edit_message)
X create_readmsg_file(); /* for "readmsg" routine */
X
X ch = edit_message? 'e' : ' '; /* drop through if needed... */
X
X if (! batch) {
X do {
X switch (ch) {
X case 'e': if (edit_the_message(filename, already_has_text)) {
X cancelled_msg = TRUE;
X return(1);
X }
X break;
X case 'h': edit_headers(); break;
X default : /* do nothing */ ;
X }
X
X /** ask that silly question again... **/
X
X if ((ch = verify_transmission(filename, &form)) == 'f') {
X cancelled_msg = TRUE;
X return(1);
X }
X } while (ch != 's');
X
X if (form == YES)
X if (format_form(filename) < 1) {
X cancelled_msg = TRUE;
X return(1);
X }
X
X if ((reply = fopen(filename,"r")) == NULL) {
X dprint2(1,
X "Attempt to open file %s for reading failed with error %s (mail)\n",
X filename, error_name(errno));
X error1("Could not open reply file (%s)", error_name(errno));
X return(1);
X }
X }
X else if ((reply = fopen(filename,"r")) == NULL) {
X dprint2(1,
X "Attempt to open file %s for reading failed with error %s (mail)\n",
X filename, error_name(errno));
X error1("Could not open reply file (%s)", error_name(errno));
X return(1);
X }
X
X cancelled_msg = FALSE; /* it ain't cancelled, is it? */
X
X /** ask about bounceback if the user wants us to.... **/
X
X if (uucp_hops(to) > bounceback && bounceback > 0 && copy_msg != FORM)
X if (verify_bounceback() == TRUE) {
X if (strlen(cc) > 0) strcat(expanded_cc, ", ");
X strcat(expanded_cc, bounce_off_remote(to));
X }
X
X /** grab a copy if the user so desires... **/
X
X if (auto_cc && !batch)
X save_copy(subject, expanded_to, expanded_cc, filename, to);
X
X /** write all header information into real_reply **/
X
X sprintf(filename2,"%s%d",temp_file, getpid()+1);
X
X /** try to write headers to new temp file **/
X
X dprint2(6, "Composition file='%s' and mail buffer='%s'\n",
X filename, filename2);
X
X if ((real_reply=write_header_info(filename2, expanded_to, expanded_cc,
X#ifdef ALLOW_BCC
X expanded_bcc,
X#endif
X form == YES)) == NULL) {
X
X /** IT FAILED!! MEIN GOTT! Use a dumb mailer instead! **/
X
X dprint1(3,"** write_header failed: %s\n", error_name(errno));
X
X if (cc[0] != '\0') /* copies! */
X sprintf(expanded_to,"%s %s", expanded_to, expanded_cc);
X
X sprintf(very_long_buffer, "( (%s -s \"%s\" %s ; %s %s) & ) < %s",
X mailx, subject, strip_parens(strip_commas(expanded_to)),
X remove, filename, filename);
X
X error1("Message sent using dumb mailer - %s", mailx);
X sleep(2); /* ensure time to see this prompt! */
X
X }
X else {
X copy_message_across(reply, real_reply);
X
X fclose(real_reply);
X
X if (cc[0] != '\0') /* copies! */
X sprintf(expanded_to,"%s %s", expanded_to, expanded_cc);
X
X#ifdef ALLOW_BCC
X if (bcc[0] != '\0') {
X strcat(expanded_to, " ");
X strcat(expanded_to, expanded_bcc);
X }
X#endif
X
X if (access(sendmail, EXECUTE_ACCESS) == 0
X#ifdef SITE_HIDING
X && ! is_a_hidden_user(username))
X#else
X )
X#endif
X sprintf(very_long_buffer,"( (%s %s %s ; %s %s) & ) < %s",
X sendmail, smflags, strip_parens(strip_commas(expanded_to)),
X remove, filename2, filename2);
X else /* oh well, use default mailer... */
X sprintf(very_long_buffer,"( (%s %s ; %s %s) & ) < %s",
X mailer, strip_parens(strip_commas(expanded_to)),
X remove, filename2, filename2);
X }
X
X fclose(reply);
X
X if (mail_only) {
X printf("sending mail...");
X fflush(stdout);
X }
X else {
X PutLine0(LINES,0,"sending mail...");
X CleartoEOLN();
X }
X
X system_call(very_long_buffer, SH);
X
X if (mail_only)
X printf("\rmail sent! \n\r");
X else
X set_error("Mail sent!");
X
X return(TRUE);
X}
X
Xmail_form(address, subj)
Xchar *address, *subj;
X{
X /** copy the appropriate variables to the shared space... */
X
X strcpy(subject, subj);
X strcpy(to, address);
X strcpy(expanded_to, address);
X
X return(mail(FORM, NO, NO, NO));
X}
X
Xint
Xrecall_last_msg(filename, copy_msg, cancelled_msg, already_has_text)
Xchar *filename;
Xint copy_msg, *cancelled_msg, *already_has_text;
X{
X /** If filename exists and we've recently cancelled a message,
X the ask if the user wants to use that message instead! This
X routine returns TRUE if the user wants to retransmit the last
X message, FALSE otherwise...
X **/
X
X register int retransmit = FALSE;
X
X if (access(filename, EDIT_ACCESS) == 0 && *cancelled_msg) {
X Raw(ON);
X CleartoEOLN();
X if (copy_msg)
X PutLine1(LINES-1,0,"Recall last kept message instead? (y/n) y%c",
X BACKSPACE);
X else
X PutLine1(LINES-1,0,"Recall last kept message? (y/n) y%c",
X BACKSPACE);
X fflush(stdout);
X if (tolower(ReadCh()) != 'n') {
X Write_to_screen("Yes",0);
X retransmit++;
X *already_has_text = TRUE;
X }
X else
X Write_to_screen("No",0);
X
X fflush(stdout);
X
X *cancelled_msg = 0;
X }
X
X return(retransmit);
X}
X
Xint
Xverify_transmission(filename, form_letter)
Xchar *filename;
Xint *form_letter;
X{
X /** Ensure the user wants to send this. This routine returns
X the character entered. Modified compliments of Steve Wolf
X to add the'dead.letter' feature.
X Also added form letter support...
X **/
X
X FILE *deadfd, *messagefd;
X char ch, buffer[LONG_SLEN], fname[SLEN];
X
X if (mail_only) {
X if (isatty(fileno(stdin))) {
X printf("\n\rAre you sure you want to send this? (y/n) ");
X CleartoEOLN();
X printf("y%c", BACKSPACE);
X fflush(stdin); /* wait for answer! */
X fflush(stdout);
X if (tolower(ReadCh()) == 'n') { /* >SIGH< */
X printf("No\n\r\n\r");
X /** try to save it as a dead letter file **/
X
X sprintf(fname, "%s/%s", home, dead_letter);
X
X if ((deadfd = fopen(fname,"a")) == NULL) {
X dprint2(1,
X "\nAttempt to append to deadletter file '%s' failed: %s\n\r",
X fname, error_name(errno));
X printf("Message not saved, Sorry.\n\r\n\r");
X return('f');
X }
X else if ((messagefd = fopen(filename, "r")) == NULL) {
X dprint2(1,"\nAttempt to read reply file '%s' failed: %s\n\r",
X filename, error_name(errno));
X printf("Message not saved, Sorry.\n\r\n\r");
X return('f');
X }
X
X /* if we get here we're okay for everything, right? */
X
X while (fgets(buffer, LONG_SLEN, messagefd) != NULL)
X fputs(buffer, deadfd);
X
X fclose(messagefd);
X fclose(deadfd);
X
X printf("Message saved in file \"$HOME/%s\"\n\r\n\r", dead_letter);
X
X return('f'); /* forget it! */
X }
X else
X printf("Yes\n\r\n\r");
X return('s'); /* send this baby! */
X }
X else
X return('s'); /* ditto */
X }
X else if (check_first) { /* used to check strlen(infile) > 0 too? */
Xreprompt:
X MoveCursor(LINES,0);
X CleartoEOLN();
X ClearLine(LINES-1);
X
X if (user_level == 0)
X PutLine1(LINES-1,0, "Are you sure you want to send this? (y/n) y%c",
X BACKSPACE);
X else if (*form_letter == PREFORMATTED)
X PutLine1(LINES-1, 0,
X "Choose: edit H)eaders, S)end, or F)orget : s%c",
X BACKSPACE);
X else if (*form_letter == YES)
X PutLine1(LINES-1, 0,
X "Choose: E)dit form, edit H)eaders, S)end, or F)orget : s%c",
X BACKSPACE);
X else if (*form_letter == MAYBE)
X PutLine1(LINES-1, 0,
X "Choose: E)dit msg, edit H)eaders, M)ake form, S)end, or F)orget : s%c",
X BACKSPACE);
X else
X PutLine1(LINES-1, 0,
X "Please choose: E)dit msg, edit H)eaders, S)end, or F)orget : s%c",
X BACKSPACE);
X
X fflush(stdin); /* wait for answer! */
X fflush(stdout);
X Raw(ON); /* double check... testing only... */
X ch = tolower(ReadCh());
X
X if (user_level == 0) {
X if (ch == 'n') {
X set_error("message cancelled");
X return('f');
X }
X else
X return('s');
X }
X
X /* otherwise someone who knows what's happenin' so... */
X
X switch (ch) {
X case 'f': Write_to_screen("Forget",0);
X set_error(
X "Message kept - Can be restored at next F)orward, M)ail or R)eply ");
X break;
X
X case '\n' :
X case '\r' :
X case 's' : Write_to_screen("Send",0);
X ch = 's'; /* make sure! */
X break;
X
X case 'm' : if (*form_letter == MAYBE) {
X *form_letter = YES;
X switch (check_form_file(filename)) {
X case -1 : return('f');
X case 0 : *form_letter = MAYBE; /* check later!*/
X error("No fields in form!");
X return('e');
X default : goto reprompt;
X }
X }
X else {
X Write_to_screen("%c??", 1, 07); /* BEEP */
X sleep(1);
X goto reprompt; /* yech */
X }
X case 'e' : if (*form_letter != PREFORMATTED) {
X Write_to_screen("Edit",0);
X if (*form_letter == YES)
X *form_letter = MAYBE;
X }
X else {
X Write_to_screen("%c??", 1, 07); /* BEEP */
X sleep(1);
X goto reprompt; /* yech */
X }
X break;
X case 'h' : Write_to_screen("Headers",0);
X break;
X
X default : Write_to_screen("%c??", 1, 07); /* BEEP */
X sleep(1);
X goto reprompt; /* yech */
X }
X
X return(ch);
X }
X else return('s');
X}
X
XFILE *
X#ifdef ALLOW_BCC
X write_header_info(filename, long_to, long_cc, long_bcc, form)
X char *filename, *long_to, *long_cc, *long_bcc;
X#else
X write_header_info(filename, long_to, long_cc, form)
X char *filename, *long_to, *long_cc;
X#endif
Xint form;
X{
X /** Try to open filedesc as the specified filename. If we can,
X then write all the headers into the file. The routine returns
X 'filedesc' if it succeeded, NULL otherwise. Added the ability
X to have backquoted stuff in the users .elmheaders file!
X **/
X
X static FILE *filedesc; /* our friendly file descriptor */
X
X#ifdef SITE_HIDING
X char buffer[SLEN];
X int is_hidden_user; /* someone we should know about? */
X#endif
X
X char *get_arpa_date();
X
X if ((filedesc = fopen(filename, "w")) == NULL) {
X dprint1(1,
X "Attempt to open file %s for writing failed! (write_header_info)\n",
X filename);
X dprint2(1,"** %s - %s **\n\n", error_name(errno),
X error_description(errno));
X error2("Error %s encountered trying to write to %s",
X error_name(errno), filename);
X sleep(2);
X return(NULL); /* couldn't open it!! */
X }
X
X#ifdef SITE_HIDING
X if ((is_hidden_user = is_a_hidden_user(username))) {
X /** this is the interesting part of this trick... **/
X sprintf(buffer, "From %s!%s %s\n", HIDDEN_SITE_NAME,
X username, get_ctime_date());
X fprintf(filedesc, "%s", buffer);
X dprint1(1,"\nadded: %s", buffer);
X /** so is this perverted or what? **/
X }
X#endif
X
X fprintf(filedesc, "To: %s\n", format_long(long_to, strlen("To:")));
X
X fprintf(filedesc,"Date: %s\n", get_arpa_date());
X
X#ifndef DONT_ADD_FROM
X# ifdef SITE_HIDING
X if (is_hidden_user)
X fprintf(filedesc,"From: %s <%s!%s!%s>\n", full_username,
X hostname, HIDDEN_SITE_NAME, username);
X else
X# endif
X# ifdef INTERNET_ADDRESS_FORMAT
X# ifdef USE_DOMAIN
X fprintf(filedesc,"From: %s <%s@%s%s>\n", full_username,
X username, hostname, DOMAIN);
X# else
X fprintf(filedesc,"From: %s <%s@%s>\n", full_username,
X username, hostname);
X# endif
X# else
X fprintf(filedesc,"From: %s <%s!%s>\n", full_username,
X hostname, username);
X# endif
X#endif
X
X fprintf(filedesc, "Subject: %s\n", subject);
X
X if (cc[0] != '\0')
X fprintf(filedesc, "Cc: %s\n", format_long(long_cc, strlen("Cc: ")));
X
X#ifdef ALLOW_BCC
X if (bcc[0] != '\0')
X fprintf(filedesc, "Bcc: %s\n", format_long(long_bcc, strlen("Bcc: ")));
X#endif
X
X if (strlen(action) > 0)
X fprintf(filedesc, "Action: %s\n", action);
X
X if (strlen(priority) > 0)
X fprintf(filedesc, "Priority: %s\n", priority);
X
X if (strlen(expires) > 0)
X fprintf(filedesc, "Expiration-Date: %s\n", expires);
X
X if (strlen(reply_to) > 0)
X fprintf(filedesc, "Reply-To: %s\n", reply_to);
X
X if (strlen(in_reply_to) > 0)
X fprintf(filedesc, "In-Reply-To: %s\n", in_reply_to);
X
X if (strlen(user_defined_header) > 0)
X fprintf(filedesc, "%s\n", user_defined_header);
X
X add_mailheaders(filedesc);
X
X if (form)
X fprintf(filedesc, "Content-Type: mailform\n");
X
X fprintf(filedesc, "X-Mailer: Elm [version %s]\n\n", VERSION);
X
X return((FILE *) filedesc);
X}
X
Xcopy_message_across(source, dest)
XFILE *source, *dest;
X{
X /** copy the message in the file pointed to by source to the
X file pointed to by dest. **/
X
X int crypted = FALSE; /* are we encrypting? */
X int encoded_lines = 0; /* # lines encoded */
X char buffer[LONG_SLEN]; /* file reading buffer */
X
X while (fgets(buffer, LONG_SLEN, source) != NULL) {
X if (buffer[0] == '[') {
X if (strncmp(buffer, START_ENCODE, strlen(START_ENCODE))==0)
X crypted = TRUE;
X else if (strncmp(buffer, END_ENCODE, strlen(END_ENCODE))==0)
X crypted = FALSE;
X else if (strncmp(buffer, DONT_SAVE, strlen(DONT_SAVE)) == 0)
X continue; /* next line? */
X }
X else if (crypted) {
X if (! gotten_key++)
X getkey(ON);
X else if (! encoded_lines++)
X get_key_no_prompt(); /* reinitialize.. */
X
X encode(buffer);
X }
X fputs(buffer, dest);
X }
X}
X
Xint
Xverify_bounceback()
X{
X /** Ensure the user wants to have a bounceback copy too. (This is
X only called on messages that are greater than the specified
X threshold hops and NEVER for non-uucp addresses.... Returns
X TRUE iff the user wants to bounce a copy back....
X **/
X
X if (mail_only) {
X printf("Would you like a copy \"bounced\" off the remote? (y/n) ");
X CleartoEOLN();
X printf("n%c", BACKSPACE);
X fflush(stdin); /* wait for answer! */
X fflush(stdout);
X if (tolower(ReadCh()) != 'y') {
X printf("No\n\r");
X return(FALSE);
X }
X else
X printf("Yes - Bounceback included\n\r");
X }
X else {
X MoveCursor(LINES,0);
X CleartoEOLN();
X PutLine1(LINES,0,
X "\"Bounce\" a copy off the remote machine? (y/n) y%c",
X BACKSPACE);
X fflush(stdin); /* wait for answer! */
X fflush(stdout);
X if (tolower(ReadCh()) != 'y') {
X Write_to_screen("No", 0);
X fflush(stdout);
X return(FALSE);
X }
X Write_to_screen("Yes!", 0);
X fflush(stdout);
X }
X
X return(TRUE);
X}
END_OF_src/mailmsg2.c
if test 19017 -ne `wc -c <src/mailmsg2.c`; then
echo shar: \"src/mailmsg2.c\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: End of archive 17 \(of 19\).
cp /dev/null ark17isdone
DONE=true
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
echo shar: You still need to run archive ${I}.
DONE=false
fi
done
if test "$DONE" = "true" ; then
echo You have unpacked all 19 archives.
echo "See the Instructions file"
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
fi
## End of shell archive.
exit 0