sources-request@mirror.UUCP (03/12/87)
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