home *** CD-ROM | disk | FTP | other *** search
- Subject: v06i036: Elm mail system (elm), Part11/14
- Newsgroups: mod.sources
- Approved: rs@mirror.UUCP
-
- Submitted by: Dave Taylor <pyramid!hplabs!hpldat!taylor>
- Mod.sources: Volume 6, Issue 36
- Archive-name: elm/Part11
-
- # Continuation of Shell Archive, created by hpldat!taylor
-
- # This is part 11
-
- # To unpack the enclosed files, please use this file as input to the
- # Bourne (sh) shell. This can be most easily done by the command;
- # sh < thisfilename
-
-
- if [ ! -d src ]
- then
- echo creating directory src
- mkdir src
- fi
-
- # ---------- file src/options.c ----------
-
- filename="src/options.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/options.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** options.c **/
-
- /** This set of routines allows the alteration of a number of paramaters
- in the Elm mailer, including the following;
-
- printmail <how to print messages>
- default-shell <what shell to use for "!" and "|">
- full_username <your full user name for outgoing mail>
- folder-dir <folder directory>
- editor <name of composition editor>
- savefile <file to save outbound message copies to>
- calendar-file <where to put calendar entries>
- sort-by <how to sort mailboxes>
- pager <how to page messages>
-
- arrow-cursor <on or off>
-
- lines-on-screen <count>
- columns-on-screen <count>
-
- And others as they seem useful.
-
- (C) Copyright 1986, Dave Taylor
- **/
-
- #include "headers.h"
-
- #undef onoff
- #define onoff(n) (n == 1? "ON ":"OFF")
-
- options()
- {
- /** change options... **/
-
- char ch;
-
- display_options();
-
- do {
- MoveCursor(LINES-1, strlen("Command: "));
-
- ch = tolower(ReadCh());
-
- clear_error(); /* remove possible "sorting" message etc... */
-
- switch (ch) {
- case 'c' : one_liner(
- "This is the file where calendar entries from messages are saved.");
- optionally_enter(calendar_file, 2, 23, FALSE); break;
-
- case 'd' : one_liner(
- "This is the program invoked to display individual messages");
- optionally_enter(pager, 3, 23, FALSE);
- break;
- case 'e' : one_liner(
- "This is the editor that will be used for sending messages, etc.");
- optionally_enter(editor, 4, 23, FALSE); break;
-
- case 'f' : one_liner(
- "This is the folders directory used when '=' (etc) is used in filenames");
- optionally_enter(folders, 5, 23, FALSE); break;
-
- case 'm' : one_liner(
- "How mailboxes are sorted;");
- change_sort(6,23); break;
-
- case 'o' : one_liner(
- "This is where copies of outbound messages are saved automatically.");
- optionally_enter(savefile, 7, 23, FALSE); break;
-
- case 'p' : one_liner(
- "This is how printouts are generated. \"%s\" will be replaced by the filename.");
- optionally_enter(printout, 8, 23, FALSE); break;
-
- case 's' : one_liner(
- "This is what shell to use for Pipe and System calls...");
- optionally_enter(shell, 9, 23, FALSE); break;
-
- case 'y' : one_liner(
- "When mail is sent out, this is what your full name will be recorded as.");
- optionally_enter(full_username, 10, 23, FALSE); break;
-
- case 'a' : one_liner(
- "This defines whether the ELM cursor is an arrow or a highlight bar.");
- on_or_off(&arrow_cursor, 12, 23); break;
-
- case 'l' : one_liner(
- "The number of lines on the screen (alter with care...)");
- num_enter(&LINES, 14, 23); break;
-
- case 'w' : one_liner(
- "The number of characters that can go on one line (alter with care...)");
- num_enter(&COLUMNS,15,23); break;
-
- case 'r' :
- case ctrl('M'):
- case ctrl('J'): return;
-
- case ctrl('L'): display_options(); break;
-
- default: error("Command unknown!");
- }
- ClearLine(LINES-3);
- } while (ch != 'r');
- }
-
- display_options()
- {
- /** Display all the available options.. **/
-
- char *sort_name();
-
- ClearScreen();
- Centerline(0,"-- Elm Options Editor --");
-
- #ifdef ENABLE_CALENDAR
- PutLine1(2, 0, "C)alendar file : %s", calendar_file);
- #endif
- PutLine1(3, 0, "D)isplay mail using : %s", pager);
- PutLine1(4, 0, "E)ditor : %s", editor);
- PutLine1(5, 0, "F)older directory : %s", folders);
- PutLine1(6, 0, "M)ailboxes sorted by : %s", sort_name(FALSE));
- PutLine1(7, 0, "O)utbound mail saved : %s", savefile);
- PutLine1(8, 0, "P)rint mail using : %s", printout);
- PutLine1(9, 0, "S)ystem shell : %s", shell);
- PutLine1(10,0, "Y)our full name : %s", full_username);
-
- PutLine1(12,0, "A)rrow cursor : %s", onoff(arrow_cursor));
-
- PutLine1(14,0, "L)ines on screen : %d", LINES);
- PutLine1(15,0, "W)idth of screen : %d", COLUMNS);
-
- Centerline(LINES-5,"Select first letter of Option line or R)eturn");
-
- PutLine1(LINES-1,0,"Command: ");
- }
-
- on_or_off(var, x, y)
- int *var, x,y;
- {
- /** 'var' field at x.y toggles between on and off... **/
-
- char ch;
-
- PutLine0(x, y+6,
- "(use <space> to toggle, any other key to leave)");
-
- MoveCursor(x,y+3); /* at end of value... */
-
- do {
- ch = ReadCh();
-
- if (ch == SPACE) {
- *var = ! *var;
- PutLine0(x,y, onoff(*var));
- }
- } while (ch == SPACE);
-
- MoveCursor(x,y+4); CleartoEOLN(); /* remove help prompt */
- }
-
- num_enter(var, x, y)
- int *var, x, y;
- {
- /** Enter a new value for the specified number. For ease, we'll
- use a string entry routine then convert it internally... **/
-
- char buffer[NLEN];
-
- sprintf(buffer,"%d", *var); /* current value... */
-
- optionally_enter(buffer, x, y, FALSE);
-
- *var = atoi(buffer);
-
- PutLine1(x,y, "%d", *var); CleartoEOLN();
- }
-
- change_sort(x, y)
- int x,y;
- {
- /** change the sorting scheme... **/
-
- int last_sortby, /* so we know if it changes... */
- sign = 1; /* are we reverse sorting?? */
- char ch; /* character typed in ... */
-
- last_sortby = sortby; /* remember current ordering */
-
- PutLine0(x, COLUMNS-29, "(SPACE for next, or R)everse)");
- sort_one_liner(sortby);
- MoveCursor(x, y);
-
- do {
- ch = tolower(ReadCh());
- switch (ch) {
- case SPACE : if (sortby < 0) {
- sign = -1;
- sortby = - sortby;
- }
- else sign = 1; /* insurance! */
- sortby = sign * ((sortby + 1) % (STATUS+1));
- if (sortby == 0) sortby = sign; /* snicker */
- PutLine0(x, y, sort_name(TRUE));
- sort_one_liner(sortby);
- MoveCursor(x, y);
- break;
-
- case 'r' : sortby = - sortby;
- PutLine0(x, y, sort_name(TRUE));
- sort_one_liner(sortby);
- MoveCursor(x, y);
- }
- } while (ch == SPACE || ch == 'r');
-
- MoveCursor(x, COLUMNS-30); CleartoEOLN();
-
- if (sortby != last_sortby) {
- error("resorting mailbox...");
- sleep(1);
- sort_mailbox(message_count);
- }
- ClearLine(LINES-2); /* clear sort_one_liner()! */
- }
-
- one_liner(string)
- char *string;
- {
- /** A single-line description of the selected item... **/
-
- Centerline(LINES-3, string);
- }
-
- sort_one_liner(sorting_by)
- int sorting_by;
- {
- /** A one line summary of the particular sorting scheme... **/
-
- ClearLine(LINES-2);
-
- switch (sorting_by) {
-
- case -SENT_DATE : Centerline(LINES-2,
- "This sort will order most-recently-sent to least-recently-sent"); break;
- case -RECEIVED_DATE : Centerline(LINES-2,
- "This sort will order most-recently-received to least-recently-received");
- break;
- case -SENDER : Centerline(LINES-2,
- "This sort will order by sender name, in reverse alphabetical order"); break;
- case -SIZE : Centerline(LINES-2,
- "This sort will order messages by longest to shortest"); break;
- case -SUBJECT : Centerline(LINES-2,
- "This sort will order by subject, in reverse alphabetical order"); break;
- case -STATUS : Centerline(LINES-2,
- "This sort will order by reverse status - Deleted through Tagged..."); break;
-
- case SENT_DATE : Centerline(LINES-2,
- "This sort will order least-recently-sent to most-recently-sent"); break;
- case RECEIVED_DATE : Centerline(LINES-2,
- "This sort will order least-recently-received to most-recently-received");
- break;
- case SENDER : Centerline(LINES-2,
- "This sort will order by sender name"); break;
- case SIZE : Centerline(LINES-2,
- "This sort will order messages by shortest to longest");
- break;
- case SUBJECT : Centerline(LINES-2,
- "This sort will order messages by subject"); break;
- case STATUS : Centerline(LINES-2,
- "This sort will order by status - Tagged through Deleted..."); break;
- }
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 7702 ]
- then
- echo $filename changed - should be 7702 bytes, not $size bytes
- fi
-
- chmod 666 $filename
- fi
-
- # ---------- file src/showmsg.old ----------
-
- filename="src/showmsg.old"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/showmsg.old...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** showmsg.c **/
-
- /** This file contains all the routines needed to display the specified
- message.
-
- These routines (C) Copyright 1986 Dave Taylor
- **/
-
-
- #include "headers.h"
- #include <ctype.h>
- #include <errno.h>
-
- #ifdef BSD
- #undef tolower
- #endif
-
- extern int errno;
-
- char *error_name();
-
- int memory_lock = FALSE; /* is it available?? */
-
- int
- show_msg(number)
- int number;
- {
- /*** display number'th message. Get starting and ending lines
- of message from headers data structure, then fly through
- the file, displaying only those lines that are between the
- two!
- Returns non-zero iff screen was changed
- ***/
-
- dprint0(8, "show_msg called\n");
-
- if (number > message_count) {
- error1("Only %d messages!", message_count);
- return(0);
- }
- else if (number < 1) {
- error("you can't read THAT message!");
- return(0);
- }
-
- clearit(header_table[number-1].status, NEW); /* it's been read now! */
-
- memory_lock = (HasMemlock() && scrolling);
-
- /* some explaination for that last one - We COULD use memory locking
- to speed up the paging, but the action of "ClearScreen" on a screen
- with memory lock turned on seems to vary considerably (amazingly so)
- so it's safer to only allow memory lock to be a viable bit of
- trickery when dumping text to the screen in scroll mode.
- Philosophical arguments should be forwarded to Bruce at the
- University of Walamazoo, Australia, via ACSNet *wry chuckle* */
-
- return(show_message(header_table[number-1].lines,
- header_table[number-1].offset,number));
- }
-
- int
- show_message(lines, file_loc, msgnumber)
- int lines, msgnumber;
- long file_loc;
- {
- /*** Show the indicated range of lines from mailfile
- for message 'msgnumber' by using 'display'
- Returns non-zero iff screen was altered.
- ***/
-
- dprint3(9,"show_message(%d,%ld,%d)\n", lines, file_loc, msgnumber);
-
- if (fseek(mailfile, file_loc, 0) != 0) {
- dprint2(1,"Error: seek %d bytes into file, errno %s (show_message)\n",
- file_loc, error_name(errno));
- error1("ELM failed seeking %d bytes into file (%s)",
- file_loc, error_name(errno));
- return(0);
- }
-
- /* next read will get 'this' line so must be at end of previous */
-
- Raw(OFF);
- display(lines, msgnumber);
- Raw(ON);
- if (memory_lock) EndMemlock(); /* turn it off!! */
-
- return(1); /* we did it boss! */
- }
-
-
- /** these two variables are used iff the variable 'title_message' is
- set, and are buffers for output of message title... **/
-
- static char top_of_screen_left [LONG_STRING],
- top_of_screen_right[LONG_STRING],
- second_line[SLEN];
-
- int
- display(lines, msgnum)
- int lines, msgnum;
- {
- /** Display specified number of lines from file mailfile.
- Note: This routine MUST be placed at the first line
- of the input file!
- Returns the same as the routine above (namely zero or one)
- **/
-
- char buffer[VERY_LONG_STRING], *full_month();
-
- int lines_displayed = 0;
- int lines_on_screen = 0; /* display */
- int crypted = 0, gotten_key = 0; /* encryption */
- int weed_header, weeding_out = 0; /* weeding */
- int mail_sent; /* misc use */
-
- dprint2(4,"displaying %d lines from message %d\n",
- lines, msgnum);
-
- second_line[0] = '\0'; /* must start as NULL */
-
- if (title_messages) {
-
- mail_sent = (strncmp(header_table[msgnum-1].from, "To:", 3) == 0);
-
- tail_of(header_table[msgnum-1].from, buffer, FALSE);
- sprintf(top_of_screen_left, "%s #%d %s %s",
- notesfile? "Note" : "Message", msgnum,
- mail_sent? "to" : "from", buffer);
- sprintf(top_of_screen_right," %s %s %s, %d at %s\n\r%s",
- notesfile? "Posted" : "Mailed",
- full_month(header_table[msgnum-1].month),
- header_table[msgnum-1].day,
- atoi(header_table[msgnum-1].year) + 1900,
- header_table[msgnum-1].time,
- filter? "": "\n\r\n\r");
-
- if (! mail_sent && matches_weedlist("To:") && filter &&
- strcmp(header_table[current-1].to,username) != 0 &&
- strlen(header_table[current-1].to) > 0)
- sprintf(second_line, "\n\r(message addressed to %s)\n\r\n\r",
- header_table[current-1].to);
-
- /** The test above is: if we didn't originally send the mail
- (e.g. we're not reading "mail.sent") AND the user is currently
- weeding out the "To:" line (otherwise they'll get it twice!)
- AND the user is actually weeding out headers AND the message
- wasn't addressed to the user AND the 'to' address is non-zero
- (consider what happens when the message doesn't HAVE a "To:"
- line...the value is NULL but it doesn't match the username
- either. We don't want to display something ugly like
- "(message addressed to )" which will just clutter up the
- display!).
-
- And you thought programming was EASY!!!!
- **/
- }
-
- weed_header = filter; /* allow us to change it after header */
-
- ClearScreen();
-
- if (cursor_control) transmit_functions(OFF);
-
- while (lines > 0) {
-
- if (fgets(buffer, VERY_LONG_STRING, mailfile) == NULL) {
- if (lines_displayed == 0) {
-
- /* AUGH! Why do we get this occasionally??? */
-
- dprint0(1,
- "\n\n** Out of Sync!! EOF with nothing read (display) **\n");
- dprint0(1,"\nLeaving with all temp files intact!\n");
- error("Internal error: out of sync!");
- emergency_exit();
-
- }
- if (scrolling)
- Write_to_screen("\n\r\n\r\n\r\n\r", 0);
- PutLine0(LINES-1, 0, "Please press <return> to return: ");
- (void) tolower(ReadCh());
- if (cursor_control) transmit_functions(ON);
- return(TRUE);
- }
-
- if (strlen(buffer) > 0)
- no_ret(buffer);
-
- if (strlen(buffer) == 0) {
- weed_header = 0; /* past header! */
- weeding_out = 0;
- }
-
- lines--;
- lines_displayed++;
-
- if (notesfile) { /* treat notes differently! */
-
- if (filter && (first_word(buffer, NOTES_HEADER) ||
- first_word(buffer, NOTES_FOOTER)) )
-
- /*** weed this line out of the display! ***/;
-
- else if (show_line(buffer, &lines_on_screen, &lines,
- lines_displayed)) {
- if (cursor_control) transmit_functions(ON);
- return(TRUE);
- }
- }
-
- else { /* "normal" message */
-
- if (weed_header && matches_weedlist(buffer))
- weeding_out = 1; /* aha! We don't want to see this! */
- else if (buffer[0] == '[') {
- if (strcmp(buffer, START_ENCODE)==0)
- crypted++;
- else if (strcmp(buffer, END_ENCODE)==0)
- crypted--;
- else if (crypted) {
- encode(buffer);
- if (show_line(buffer, &lines_on_screen, &lines,
- lines_displayed)) {
- if (cursor_control) transmit_functions(ON);
- return(TRUE);
- }
- }
- else
- if (show_line(buffer, &lines_on_screen, &lines,
- lines_displayed)) {
- if (cursor_control) transmit_functions(ON);
- return(TRUE);
- }
- }
- else if (crypted) {
- if (! gotten_key++) getkey(OFF);
- encode(buffer);
- if (show_line(buffer, &lines_on_screen, &lines,
- lines_displayed)) {
- if (cursor_control) transmit_functions(ON);
- return(TRUE);
- }
- }
- else if (weeding_out) {
- weeding_out = (whitespace(buffer[0])); /* 'n' line weed */
- if (! weeding_out) /* just turned on! */
- if (show_line(buffer, &lines_on_screen, &lines,
- lines_displayed)) {
- if (cursor_control) transmit_functions(ON);
- return(TRUE);
- }
- }
- else
- if (show_line(buffer, &lines_on_screen, &lines,
- lines_displayed)) {
- if (cursor_control) transmit_functions(ON);
- return(TRUE);
- }
- }
- }
-
-
- if (scrolling)
- Write_to_screen("\n\r\n\r\n\r", 0);
-
- PutLine0(LINES-1, 0, "Please press <return> to return: ");
- Raw(ON);
- tolower(ReadCh());
- if (cursor_control) transmit_functions(ON);
- return(TRUE);
- }
-
- int
- show_line(buffer, lines_on_screen, total, lines_displayed)
- char *buffer;
- int *lines_on_screen, *total, lines_displayed;
- {
- /** Displays the given line if it can. if not, it will put the
- 'ole 'space to continue' prompt on the bottom of the screen
- and wait for either a 'space' or 'return'. This function
- returns 0 if '<space>' is hit, or the character pressed.
- **/
-
- static char overlap [LONG_SLEN];
- char ch;
- int last_line_loc;
-
- last_line_loc = *lines_on_screen; /* one back... */
-
- *lines_on_screen += ((strlen(buffer) / COLUMNS) + 1);
-
- if (last_line_loc == 0 && title_messages) {
- display_title(lines_on_screen);
- last_line_loc = *lines_on_screen;
- }
-
- if (*lines_on_screen > LINES-2) {
-
- if (*total > 0) {
-
- if (scrolling) {
-
- if (lines_displayed > LINES+5) /* are we past screen 1? */
- Write_to_screen("\n\r\n\r\n\r\n\r", 0); /* don't ask */
-
- PutLine2(LINES, COLUMNS-20, "%d line%s left",
- *total, plural(*total));
- PutLine0(LINES, 0,
- "Press <space> to continue, <return> to return: ", 0);
- }
- else {
- PutLine0(LINES-1, 0,
- "Press <space> to continue, <return> to return: ");
- PutLine2(LINES-1, COLUMNS-20, "%d line%s left",
- *total, plural(*total));
- }
- }
-
- else if (scrolling)
- Write_to_screen("\n\r\n\rPlease press <return> to return: ");
- else
- PutLine0(LINES-1, 0, "Please press <return> to return: ");
-
- Raw(ON);
- ch = tolower(ReadCh());
- if (ch != ' ' || *total == 0)
- return(ch);
- Raw(OFF);
- if (scrolling) {
- MoveCursor(LINES-2, 0);
- CleartoEOS();
- }
- else {
- ClearScreen();
- }
- *lines_on_screen = 1;
-
- if (title_messages && ! scrolling) {
- display_title(lines_on_screen);
- dprint1(2,"displayed title, lines-on-screen = %d\n",
- *lines_on_screen);
- }
-
- if (! scrolling) {
- PutLine1(*lines_on_screen, 0, "%s\n\r", overlap);
- *lines_on_screen += ((strlen(overlap) / COLUMNS) + 1);
- }
-
- last_line_loc = *lines_on_screen;
- *lines_on_screen += ((strlen(buffer) / COLUMNS) + 1);
-
- /* resync terminal from write... */
- Write_to_screen("%c%c", 2, '\0', '\0');
- Write_to_screen("%c%c", 2, '\0', '\0');
- }
-
- Write_to_screen("%s\n\r", 1, buffer);
-
- if (*lines_on_screen > LINES-6) /* in case next is too LONG */
- strcpy(overlap, buffer);
-
- return(0);
- }
-
- display_title(lines_on_screen)
- int *lines_on_screen;
- {
- /** Display top title, including "Page N" **/
-
- *lines_on_screen = 2; /* the title */
-
- PutLine0(0,1,top_of_screen_left);
-
- PutLine0(0, COLUMNS-strlen(top_of_screen_right)+(filter?1:3),
- top_of_screen_right);
-
- if (memory_lock)
- StartMemlock(); /* start up! */
-
- if (strlen(second_line) > 0) {
- PutLine0(1, 0, second_line);
- *lines_on_screen = 5;
- }
-
- dprint1(2,"Display_title set lines-on-screen to %d\n",
- *lines_on_screen);
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 10887 ]
- then
- echo $filename changed - should be 10887 bytes, not $size bytes
- fi
-
- chmod 666 $filename
- fi
-
- # ---------- file src/string2.c ----------
-
- filename="src/string2.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/string2.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** string2.c **/
-
- /** This file contains string functions that are shared throughout the
- various ELM utilities...
-
- (C) Copyright 1986 Dave Taylor
- **/
-
- #ifndef TRUE
- #define TRUE 1
- #define FALSE 0
- #endif
-
- int
- in_string(buffer, pattern)
- char *buffer, *pattern;
- {
- /** Returns TRUE iff pattern occurs IN IT'S ENTIRETY in buffer. **/
-
- register int i = 0, j = 0;
-
- while (buffer[i] != '\0') {
- while (buffer[i++] == pattern[j++])
- if (pattern[j] == '\0')
- return(TRUE);
- i = i - j + 1;
- j = 0;
- }
- return(FALSE);
- }
-
- int
- chloc(string, ch)
- char *string, ch;
- {
- /** returns the index of ch in string, or -1 if not in string **/
- register int i;
-
- for (i=0; i<strlen(string); i++)
- if (string[i] == ch) return(i);
- return(-1);
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 757 ]
- then
- echo $filename changed - should be 757 bytes, not $size bytes
- fi
-
- chmod 644 $filename
- fi
-
- # ---------- file src/calendar.c ----------
-
- filename="src/calendar.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/calendar.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** calendar.c **/
-
- /** This routine implements a rather snazzy idea suggested by Warren
- Carithers of the Rochester Institute of Technology that allows
- mail to contain entries formatted in a manner that will allow direct
- copying into a users calendar program.
-
- Never able to leave good-enough alone, I've extended this idea to a
- further one - the knowledge of a different type of calendar program
- too. Specifically, the current message can contain either of;
-
- -> Mon 04/21 1:00p meet with chairman candidate
-
- or
-
- - >April 21
- -
- - 1:00 pm: Meet with Chairman Candidate
- -
-
- The first type will have the leading '->' removed and all subsequent
- white space, creating a simple one-line entry in the users calendar
- file. The second type will remove the '-' and the leading white
- spaces and leave everything else intact (that is, the file in the
- second example would be appended with ">April 21" followed by a
- blank line, the 1:00 pm meeting info, and another blank line.
-
- The file to include this in is either the default as defined in the
- sysdefs.h file (see CALENDAR_FILE) or a filename contained in the
- users ".elmrc" file, "calendar= <filename>".
-
- (C) Copyright 1986 Dave Taylor
- **/
-
- #include "headers.h"
-
- #ifdef ENABLE_CALENDAR /* if not defined, this will be an empty file */
-
- #include <errno.h>
-
- extern int errno;
-
- char *error_name(), *error_number();
-
- scan_calendar()
- {
- FILE *calendar;
- int count;
-
- /* First step is to open the celendar file for appending... **/
-
- if ((calendar = fopen(calendar_file,"a")) == NULL) {
- dprint1(2, "Error: couldn't append to calendar file %s (save)\n",
- calendar_file);
- dprint2(2, "** %s - %s **\n",
- error_name(errno), error_description(errno));
- error1("Couldn't append to file %s!", calendar_file);
- return;
- }
-
- count = extract_info(calendar);
-
- fclose(calendar);
-
- chown(calendar_file, userid, groupid); /* ensure owned by user */
-
- if (count > 0)
- error2("%d entr%s saved in calendar file",
- count, count > 1 ? "ies" : "y");
- else
- error("No calendar entries found in that message");
-
- return;
- }
-
- int
- extract_info(save_to_fd)
- FILE *save_to_fd;
- {
- /** Save the relevant parts of the current message to the given
- calendar file. The only parameter is an opened file
- descriptor, positioned at the end of the existing file **/
-
- register int entries = 0, ok = 1, lines, index, in_entry = FALSE;
- char buffer[SLEN];
-
- /** get to the first line of the message desired **/
-
- if (fseek(mailfile, header_table[current-1].offset, 0) == -1) {
- dprint2(1,"ERROR: Attempt to seek %d bytes into file failed (%s)",
- header_table[current-1].offset, "extract_info");
- error1("ELM [seek] failed trying to read %d bytes into file",
- header_table[current-1].offset);
- return(0);
- }
-
- /* how many lines in message? */
-
- lines = header_table[current-1].lines;
-
- /* now while not EOF & still in message... scan it! */
-
- while (ok && lines--) {
- ok = (int) (fgets(buffer, LONG_SLEN, mailfile) != NULL);
-
- /* now let's see if it matches the basic pattern... */
-
- if ((index = calendar_line(buffer)) > -1) {
-
- if (buffer[index] == '>') { /* single line entry */
- if (remove_through_ch(buffer, '>')) {
- fprintf(save_to_fd,"%s", buffer);
- entries++;
- }
- }
- else { /* multi-line entry */
- fprintf(save_to_fd, "%s", (char *) (buffer + index + 1));
- in_entry = TRUE;
- }
- }
- else if (in_entry) {
- in_entry = FALSE;
- entries++;
- }
- }
-
- dprint2(4,"Got %d calender entr%s.\n", entries, entries > 1? "ies":"y");
-
- return(entries);
- }
-
- int
- calendar_line(string)
- char *string;
- {
- /** Iff the input line is of the form;
-
- {white space} <one or more '-'>
-
- this routine will return the index of the NEXT character
- after the dashed sequence...If this pattern doesn't occur,
- or if any other problems are encountered, it'll return "-1"
- **/
-
- register int loc = 0;
-
- if (chloc(string,'-') == -1) /* no dash??? */
- return(-1); /* that was easy! */
-
- /** skip leading white space... **/
-
- while (whitespace(string[loc])) loc++; /* MUST have '-' too! */
-
- if (string[loc] != '-') return(-1); /* nice try, sleazo! */
-
- while (string[loc] == '-') loc++;
-
- if (loc >= strlen(string)) return(-1); /* Empty line... */
-
- /* otherwise.... */
-
- return(loc);
- }
-
-
- int
- remove_through_ch(string, ch)
- char *string;
- char ch;
- {
- /** removes all characters from zero to ch in the string, and
- any 'white-space' following the 'n'th char... if it hits a
- NULL string, it returns FALSE, otherwise it'll return TRUE!
- **/
-
- char buffer[SLEN];
- register int index = 0, i = 0;
-
- while (string[index] != ch && string[index] != '\0')
- index++;
-
- if (index >= strlen(string))
- return(FALSE); /* crash! burn! */
-
- index++; /* get past the 'ch' character... */
-
- while (whitespace(string[index])) index++;
-
- while (index < strlen(string))
- buffer[i++] = string[index++];
-
- buffer[i] = '\0';
-
- strcpy(string, buffer);
-
- return(TRUE);
- }
-
- #endif
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 5189 ]
- then
- echo $filename changed - should be 5189 bytes, not $size bytes
- fi
-
- chmod 666 $filename
- fi
-
- # ---------- file src/elm.c ----------
-
- filename="src/elm.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/elm.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** elm.c **/
-
- /* main program of the ELM mail system!
-
- This file and all associated files and documentation:
- (C) Copyright 1986 Dave Taylor
- */
-
- #include "elm.h"
-
- long bytes();
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- char ch, address[SLEN], to_whom[LONG_SLEN];
- int redraw, /** do we need to rewrite the entire screen? **/
- nuhead, /** or perhaps just the headers section... **/
- nucurr, /** or just the current message pointer... **/
- nufoot; /** clear lines 16 thru bottom and new menu **/
- int i; /** Random counting variable (etc) **/
- int pageon, /** for when we receive new mail... **/
- last_in_mailbox; /** for when we receive new mail too... **/
-
- parse_arguments(argc, argv, to_whom);
-
- if (mail_only) {
-
- initialize(FALSE);
-
- Raw(ON);
- dprint1(3,"Mail-only: mailing to\n-> \"%s\"\n",
- format_long(to_whom));
- (void) send(to_whom, "", TRUE);
- leave(0);
- }
-
- initialize(TRUE);
-
- ScreenSize(&LINES, &COLUMNS);
-
- showscreen();
-
- mailfile_size = bytes(infile);
-
- Raw(ON);
-
- while (1) {
- redraw = 0;
- nuhead = 0;
- nufoot = 0;
- nucurr = 0;
- if ((i = bytes(infile)) != mailfile_size) {
- dprint1(2,"Just received %d bytes more mail (elm)\n",
- i - mailfile_size);
- error("New mail has arrived! Hang on...");
- last_in_mailbox = message_count;
- pageon = header_page;
- newmbox(2, FALSE, TRUE);
- clear_error();
- header_page = pageon;
-
- if (on_page(current)) /* do we REALLY have to rewrite? */
- showscreen();
- else {
- update_title();
- ClearLine(LINES-1); /* remove reading message... */
- error2("%d new message%s received",
- message_count - last_in_mailbox,
- plural(message_count - last_in_mailbox));
- }
- mailfile_size = i;
- if (cursor_control)
- transmit_functions(ON); /* insurance */
- }
-
- prompt("Command: ");
-
- CleartoEOLN();
- ch = tolower(GetPrompt());
- CleartoEOS();
- dprint1(4, "\nCommand: %c\n\n", ch);
-
- set_error(""); /* clear error buffer */
-
- MoveCursor(LINES-3,strlen("Command: "));
-
- switch (ch) {
-
- case '?' : if (help())
- redraw++;
- else
- nufoot++;
- break;
-
- case ' ' :
- case '+' : header_page++; nuhead++;
- if (move_when_paged &&
- header_page < (message_count / headers_per_page))
- current = header_page*headers_per_page + 1;
- break;
-
- case '-' : header_page--; nuhead++;
- if (move_when_paged && header_page > 0)
- current = header_page*headers_per_page + 1;
- break;
-
- case '=' : if (current != 1) {
- current = 1;
- if (get_page(current))
- nuhead++;
- else
- nucurr++;
- } break;
-
- case '*' : if (current != message_count) {
- current = message_count;
- if (get_page(current))
- nuhead++;
- else
- nucurr++;
- } break;
-
- case '|' : Writechar('|');
- softkeys_off();
- redraw = do_pipe();
- softkeys_on(); break;
-
- case '!' : Writechar('!');
- softkeys_off();
- redraw = subshell();
- softkeys_on(); break;
-
- case '%' : get_return(address);
- clear_error();
- PutLine1(LINES,(COLUMNS-strlen(address))/2,
- "%.78s", address);
- break;
-
- case '/' : if (pattern_match()) {
- if (get_page(current))
- nuhead++;
- else
- nucurr++;
- }
- else
- error("pattern not found!");
- break;
-
- case '<' : /* scan current message for calendar information */
- #ifdef ENABLE_CALENDAR
- PutLine0(LINES-3, strlen("Command: "),
- "Scan message for calendar entries...");
- scan_calendar();
- #else
- error("Sorry - calendar function disabled");
- #endif
- break;
-
- case 'a' : alias();
- nufoot++;
- define_softkeys(MAIN); break;
-
- case 'b' : PutLine0(LINES-3, strlen("Command: "),
- "Bounce message");
- fflush(stdout);
- if (message_count < 1)
- error("No mail to bounce!");
- else
- nufoot = remail();
- break;
-
- case 'c' : PutLine0(LINES-3, strlen("Command: "),
- "Change mailbox");
- define_softkeys(CHANGE);
- if ((file_changed = leave_mbox(FALSE)) != -1) {
- redraw = newmbox(0, TRUE, TRUE);
- mailfile_size = bytes(infile);
- }
- else {
- file_changed = 0;
- sort_mailbox(message_count, FALSE);
- }
- define_softkeys(MAIN);
- break;
-
- case '^' :
- case 'd' : if (message_count < 1)
- error("No mail to delete!");
- else {
- delete((ch == 'd'));
- if (resolve_mode) /* move after mail resolved */
- if (current < message_count) {
- current++;
- if (get_page(current))
- nuhead++;
- else
- nucurr++;
- }
- }
- break;
-
- case ctrl('D') : if (message_count < 1)
- error("No mail to delete!");
- else
- meta_match(DELETED);
- break;
-
- case 'e' : PutLine0(LINES-3, strlen("Command: "), "Edit mailbox");
- if (current > 0)
- edit_mailbox();
- else
- error("Mailbox is empty!");
- break;
-
- case 'f' : PutLine0(LINES-3, strlen("Command: "), "Forward");
- define_softkeys(YESNO);
- if (current > 0)
- redraw = forward();
- else
- error("No mail to forward!");
- define_softkeys(MAIN);
- break;
-
- case 'g' : PutLine0(LINES-3, strlen("Command: "), "Group reply");
- define_softkeys(YESNO);
- fflush(stdout);
- if (current > 0) {
- PutLine0(LINES-3,COLUMNS-40,
- "building addresses...");
- redraw = reply_to_everyone();
- }
- else
- error("No mail to reply to!");
- define_softkeys(MAIN);
- break;
-
- case 'h' : if (filter)
- PutLine0(LINES-3, strlen("Command: "),
- "Message with headers...");
- else
- PutLine0(LINES-3, strlen("Command: "),"Read message");
- fflush(stdout);
- i = filter;
- filter = FALSE;
- redraw = show_msg(current);
- filter = i;
- break;
-
- case 'j' : current++;
- if (get_page(current))
- nuhead++;
- else
- nucurr++; break;
-
- case 'k' : current--;
- if (get_page(current))
- nuhead++;
- else
- nucurr++; break;
-
- case 'm' : PutLine0(LINES-3, strlen("Command: "), "Mail");
- redraw = send("", "", TRUE);
- break;
-
- case ctrl('J'):
- case ctrl('M'):PutLine0(LINES-3, strlen("Command: "), "Read Message");
- fflush(stdout);
- define_softkeys(READ);
- redraw = show_msg(current);
- break;
-
- case 'n' : PutLine0(LINES-3, strlen("Command: "), "Next Message");
- fflush(stdout);
- define_softkeys(READ);
- redraw = show_msg(current);
- current += redraw;
- (void) get_page(current); /* rewrites ANYway */
- if (current > message_count)
- current = message_count;
- break;
-
- case 'o' : PutLine0(LINES-3, strlen("Command: "), "Options");
- options();
- redraw++; /* always fix da screen... */
- break;
-
- case 'p' : PutLine0(LINES-3, strlen("Command: "), "Print mail");
- fflush(stdout);
- if (message_count < 1)
- error("No mail to print!");
- else
- printmsg();
- break;
-
- case 'q' : PutLine0(LINES-3, strlen("Command: "), "Quit");
-
- if (mbox_specified == 0) lock(OUTGOING);
-
- if (mailfile_size != bytes(infile)) {
- error("New Mail! Quit cancelled...");
- if (mbox_specified == 0) unlock();
- }
- else
- quit();
-
- break;
-
- case 'r' : PutLine0(LINES-3, strlen("Command: "),
- "Reply to message");
- if (current > 0)
- redraw = reply();
- else
- error("No mail to reply to!");
- softkeys_on();
- break;
-
- case '>' : /** backwards compatibility **/
-
- case 's' : if (message_count < 1)
- error("No mail to save!");
- else {
- PutLine0(LINES-3, strlen("Command: "),"Save Message");
- if (save() && resolve_mode) {
- if (current < message_count) {
- current++; /* move to next message */
- if (get_page(current))
- nuhead++;
- else
- nucurr++;
- }
- }
- }
- ClearLine(LINES-2);
- break;
-
- case ctrl('T') :
- case 't' : if (message_count < 1)
- error("no mail to tag!");
- else if (ch == 't')
- tag_message();
- else
- meta_match(TAGGED);
- break;
-
- case 'u' : if (message_count < 1)
- error("no mail to mark as undeleted!");
- else {
- undelete();
- if (resolve_mode) /* move after mail resolved */
- if (current < message_count) {
- current++;
- if (get_page(current))
- nuhead++;
- else
- nucurr++;
- }
- }
- break;
-
- case ctrl('Q') :
- case ctrl('?') :
- case 'x' : PutLine0(LINES-3, strlen("Command: "), "Exit");
- fflush(stdout); leave();
-
- case ctrl('L') : redraw++; break;
-
- case '@' : debug_screen(); redraw++; break;
-
- case '#' : debug_message(); redraw++; break;
-
- case NO_OP_COMMAND : break; /* noop for timeout loop */
-
- case ESCAPE : if (cursor_control) {
- ch = ReadCh();
- if (ch == up[1]) {
- current--;
- if (get_page(current))
- nuhead++;
- else
- nucurr++;
- }
- else if (ch == down[1]) {
- current++;
- if (get_page(current))
- nuhead++;
- else
- nucurr++;
- }
- else if (hp_terminal) { /* kludge! */
- if (ch == 'U') { /* <NEXT> */
- header_page++;
- nuhead++;
- if (move_when_paged)
- current = header_page*headers_per_page + 1;
- }
- else if (ch == 'V') { /* <PREV> */
- header_page--;
- nuhead++;
- if (move_when_paged)
- current = header_page*headers_per_page + 1;
- }
- else if (ch == 'h' || ch == 'H') { /* <HOME UP> */
- current = 1;
- if (get_page(current))
- nuhead++;
- else
- nucurr++;
- }
- else if (ch == 'F') { /* <HOME DOWN> */
- current = message_count;
- if (get_page(current))
- nuhead++;
- else
- nucurr++;
- }
- else /* what DID they hit??? */
- PutLine2(LINES-3, strlen("Command: "),
- "%c%c", ESCAPE, ch);
- }
- else /* false hit - output */
- PutLine2(LINES-3, strlen("Command: "),
- "%c%c", ESCAPE, ch);
- break;
- }
- /* else fall into default.. */
-
- default : if (ch > '0' && ch <= '9') {
- PutLine0(LINES-3, strlen("Command: "),
- "New Current Message");
- current = read_number(ch, message_count);
- if (get_page(current))
- nuhead++;
- else
- nucurr++;
- }
- else
- error("Unknown command: Use '?' for commands");
- }
-
- dprint5(4,"redraw=%s, current=%d, nuhead=%s, nufoot=%s, nucurr=%s\n",
- onoff(redraw), current, onoff(nuhead), onoff(nufoot),
- onoff(nucurr));
-
- if (redraw)
- showscreen();
-
- if (current < 1) {
- if (message_count > 0) {
- error("already at message #1!");
- current = 1;
- }
- else if (current < 0) {
- error("No messages to read!");
- current = 0;
- }
- }
- else if (current > message_count) {
- if (message_count > 0) {
- error2("only %d message%s!", message_count,
- plural(message_count));
- current = message_count;
- }
- else {
- error("No messages to read!");
- current = 0;
- }
- }
-
- if (nuhead)
- show_headers();
- else if (nucurr)
- show_current();
- else if (nufoot) {
- MoveCursor(LINES-7, 0);
- CleartoEOS();
- if (mini_menu)
- show_menu();
- }
-
- } /* the BIG while loop! */
- }
-
- debug_screen()
- {
- /**** spit out all the current variable settings and the table
- entries for the current 'n' items displayed. ****/
-
- register int i, j;
- char buffer[SLEN];
-
- ClearScreen();
- Raw(OFF);
-
- PutLine2(0,0,"Current message number = %d\t\t%d message(s) total\n",
- current, message_count);
- PutLine2(2,0,"Header_page = %d \t\t%d possible page(s)\n",
- header_page, (int) (message_count / headers_per_page) + 1);
-
- PutLine1(4,0,"\nCurrent mailfile is %s.\n\n", infile);
-
- i = header_page*headers_per_page; /* starting header */
-
- if ((j = i + (headers_per_page-1)) >= message_count)
- j = message_count-1;
-
- Write_to_screen(
- "Num From Subject Lines Offset\n\n",0);
-
- while (i <= j) {
- sprintf(buffer,
- "%3d %-16.16s %-40.40s %4d %d\n",
- i+1,
- header_table[i].from,
- header_table[i].subject,
- header_table[i].lines,
- header_table[i].offset);
- Write_to_screen(buffer, 0);
- i++;
- }
-
- Raw(ON);
-
- PutLine0(LINES,0,"Press any key to return: ");
- (void) ReadCh();
- }
-
-
- debug_message()
- {
- /**** Spit out the current message record. Include EVERYTHING
- in the record structure. **/
-
- char buffer[SLEN];
-
- ClearScreen();
- Raw(OFF);
-
- Write_to_screen("\t\t\t----- Message %d -----\n\n\n\n", 1,
- current);
-
- Write_to_screen("Lines : %-5d\t\t\t\tStatus: N E A P D T\n", 1,
- header_table[current-1].lines);
- Write_to_screen(" \t\t\t\t e x c r e a\n", 0);
- Write_to_screen(" \t\t\t\t w p t i l g\n\n", 0);
-
- sprintf(buffer, "Offset: %ld\t\t\t\t %d %d %d %d %d %d\n\n",
- header_table[current-1].offset,
- (header_table[current-1].status & NEW) != 0,
- (header_table[current-1].status & EXPIRED) != 0,
- (header_table[current-1].status & ACTION) != 0,
- (header_table[current-1].status & PRIORITY) != 0,
- (header_table[current-1].status & DELETED) != 0,
- (header_table[current-1].status & TAGGED) != 0);
- Write_to_screen(buffer, 0);
-
- sprintf(buffer, "Received on: %d/%d/%d at %d:%02d\n\n",
- header_table[current-1].received.month+1,
- header_table[current-1].received.day,
- header_table[current-1].received.year,
- header_table[current-1].received.hour,
- header_table[current-1].received.minute);
- Write_to_screen(buffer, 0);
-
- sprintf(buffer, "Message sent on: %s, %s %s, %s at %s\n\n",
- header_table[current-1].dayname,
- header_table[current-1].month,
- header_table[current-1].day,
- header_table[current-1].year,
- header_table[current-1].time);
- Write_to_screen(buffer, 0);
-
- Write_to_screen("\nFrom: %s\n\nSubject: %s", 2,
- header_table[current-1].from,
- header_table[current-1].subject);
-
- Write_to_screen("\nTo: %s\n\nIndex = %d\n", 2,
- header_table[current-1].to,
- header_table[current-1].index_number);
-
- Raw(ON);
-
- PutLine0(LINES,0,"Press any key to return: ");
- (void) ReadCh();
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 15852 ]
- then
- echo $filename changed - should be 15852 bytes, not $size bytes
- fi
-
- chmod 644 $filename
- fi
-
- # ---------- file src/replyc ----------
-
- filename="src/replyc"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/replyc...
- fi
-
- cat << 'END-OF-FILE' > $filename
-
- /** reply.c **/
-
- /*** routine allows replying to the sender of the current message
-
- (C) Copyright 1985, Dave Taylor
- ***/
-
- #include "headers.h"
- #include <errno.h>
-
- #ifndef BSD
- # include <sys/utsname.h>
- #endif
-
- /** Note that this routine generates automatic header information
- for the subject and (obviously) to lines, but that these can
- be altered while in the editor composing the reply message!
- **/
-
- char *strip_parens(), *get_token(), *notes_machine();
-
- extern int errno;
-
- char *error_name();
-
- int
- reply()
- {
- /** Reply to the current message. Returns non-zero iff
- the screen has to be rewritten. **/
-
- char return_address[LONG_SLEN], subject[SLEN];
- int return_value;
-
- get_return(return_address);
-
- if (first_word(header_table[current-1].from, "To:")) {
- strcpy(subject, header_table[current-1].subject);
- return_value = send(return_address, subject, TRUE);
- }
- else if (header_table[current-1].subject[0] != '\0') {
- if ((strncmp("Re:", header_table[current-1].subject, 3) == 0) ||
- (strncmp("RE:", header_table[current-1].subject, 3) == 0) ||
- (strncmp("re:", header_table[current-1].subject, 3) == 0))
- strcpy(subject, header_table[current-1].subject);
- else {
- strcpy(subject,"Re: ");
- strcat(subject,header_table[current-1].subject);
- }
- return_value = send(return_address, subject, TRUE);
- }
- else
- return_value = send(return_address, "Re: your mail", TRUE);
-
- return(return_value);
- }
-
- int
- reply_to_everyone()
- {
- /** Reply to everyone who received the current message.
- This includes other people in the 'To:' line and people
- in the 'Cc:' line too. Returns non-zero iff the screen
- has to be rewritten. **/
-
- char return_address[LONG_SLEN], subject[SLEN];
- char full_address[VERY_LONG_STRING];
- int return_value;
-
- get_return(return_address);
-
- strcpy(full_address, return_address); /* sender gets copy */
-
- get_and_expand_everyone(return_address, full_address);
-
- if (header_table[current-1].subject[0] != '\0') {
- if ((strncmp("Re:", header_table[current-1].subject, 3) == 0) ||
- (strncmp("RE:", header_table[current-1].subject, 3) == 0) ||
- (strncmp("re:", header_table[current-1].subject, 3) == 0))
- strcpy(subject, header_table[current-1].subject);
- else {
- strcpy(subject,"Re: ");
- strcat(subject,header_table[current-1].subject);
- }
- return_value = send(full_address, subject, TRUE);
- }
- else
- return_value = send(full_address, "Re: your mail", TRUE);
-
- return(return_value);
-
- }
-
- int
- forward()
- {
- /** Forward the current message. What this actually does is
- to set auto_copy to true, then call 'send' to get the
- address and route the mail.
- **/
-
- char subject[SLEN], address[VERY_LONG_STRING];
- int original_cc, results, edit_msg;
-
- original_cc = auto_copy;
- address[0] = '\0';
-
- edit_msg = (want_to("Edit outgoing message (y/n) ? ",'y',FALSE) != 'n');
- Write_to_screen("%s", 1, edit_msg? "Yes" : "No");
-
- auto_cc = TRUE; /* we want a copy */
-
- if (strlen(header_table[current-1].subject) > 0) {
- strcpy(subject,header_table[current-1].subject);
- results = send(address, subject, edit_msg);
- }
- else
- results = send(address, "Forwarded Mail...", edit_msg);
-
- auto_copy = original_cc;
-
- return(results);
- }
-
- get_and_expand_everyone(return_address, full_address)
- char *return_address, *full_address;
- {
- /** Read the current message, extracting addresses from the 'To:'
- and 'Cc:' lines. As each address is taken, ensure that it
- isn't to the author of the message NOR to us. If neither,
- prepend with current return address and append to the
- 'full_address' string.
- **/
-
- char ret_address[LONG_SLEN], buf[LONG_SLEN], new_address[LONG_SLEN];
- char *bufptr, *address;
- int in_message = 1, first_pass = 0;
-
- /** First off, get to the first line of the message desired **/
-
- if (fseek(mailfile, header_table[current-1].offset, 0) == -1) {
- dprint3(1,"Error: seek %ld resulted in errno %s (%s)\n",
- header_table[current-1].offset, error_name(errno),
- "get_and_expand_everyone");
- error2("ELM [seek] couldn't read %d bytes into file (%s)",
- header_table[current-1].offset, error_name(errno));
- return;
- }
-
- /** okay! Now we're there! **/
-
- /** let's fix the ret_address to reflect the return address of this
- message with '%s' instead of the persons login name... **/
-
- translate_return(return_address, ret_address);
-
- /** now let's parse the actual message! **/
-
- while (in_message) {
- in_message = (int) (fgets(buf, LONG_SLEN, mailfile) != NULL);
- if (first_word(buf, "From ") && first_pass++ != 0)
- in_message = FALSE;
- else if (first_word(buf, "To:") || first_word(buf, "Cc:") ||
- first_word(buf, "CC:") || first_word(buf, "cc:")) {
- do {
- no_ret(buf);
-
- bufptr = (char *) (strip_parens(buf) + 3); /* 3 = strlen of prompt */
-
- while ((address = get_token(bufptr, "\t, ", 0)) != NULL) {
- if (okay_address(address, return_address)) {
- sprintf(new_address, ret_address, address);
- optimize_and_add(new_address, full_address);
- }
- bufptr = NULL;
- }
-
- in_message = (int) (fgets(buf, LONG_SLEN, mailfile) != NULL);
-
- } while (in_message && whitespace(buf[0]));
-
- }
- else if (strlen(buf) < 2) /* done with header */
- in_message = FALSE;
- }
- }
-
- int
- okay_address(address, return_address)
- char *address, *return_address;
- {
- /** This routine checks to ensure that the address we just got
- from the "To:" or "Cc:" line isn't us AND isn't the person
- who sent the message. Returns true iff neither is the case **/
-
- char our_address[SLEN];
- struct addr_rec *alternatives;
-
- if (in_string(address, return_address))
- return(FALSE);
-
- sprintf(our_address, "%s!%s", hostname, username);
-
- if (in_string(address, our_address))
- return(FALSE);
-
- sprintf(our_address, "%s@%s", username, hostname);
-
- if (in_string(address, our_address))
- return(FALSE);
-
- alternatives = alternative_addresses;
-
- while (alternatives != NULL) {
- if (in_string(address, alternatives->address))
- return(FALSE);
- alternatives = alternatives->next;
- }
-
- return(TRUE);
- }
-
- optimize_and_add(new_address, full_address)
- char *new_address, *full_address;
- {
- /** This routine will add the new address to the list of addresses
- in the full address buffer IFF it doesn't already occur. It
- will also try to fix dumb hops if possible, specifically hops
- of the form ...a!b...!a... and hops of the form a@b@b etc
- **/
-
- register int len, host_count = 0, i;
- char hosts[MAX_HOPS][SLEN]; /* array of machine names */
- char *host, *addrptr;
-
- if (in_string(full_address, new_address))
- return(1); /* duplicate address */
-
- /** optimize **/
- /* break down into a list of machine names, checking as we go along */
-
- addrptr = (char *) new_address;
-
- while ((host = get_token(addrptr, "!", 1)) != NULL) {
- for (i = 0; i < host_count && ! equal(hosts[i], host); i++)
- ;
-
- if (i == host_count) {
- strcpy(hosts[host_count++], host);
- if (host_count == MAX_HOPS) {
- dprint1(2,
- "Error: hit max_hops limit trying to build return address (%s)\n",
- "optimize_and_add");
- error("Can't build return address - hit MAX_HOPS limit!");
- return(1);
- }
- }
- else
- host_count = i + 1;
- addrptr = NULL;
- }
-
- /** fix the ARPA addresses, if needed **/
-
- if (chloc(hosts[host_count-1], '@') > -1)
- fix_arpa_address(hosts[host_count-1]);
-
- /** rebuild the address.. **/
-
- new_address[0] = '\0';
-
- for (i = 0; i < host_count; i++)
- sprintf(new_address, "%s%s%s", new_address,
- new_address[0] == '\0'? "" : "!",
- hosts[i]);
-
- if (full_address[0] == '\0')
- strcpy(full_address, new_address);
- else {
- len = strlen(full_address);
- full_address[len ] = ',';
- full_address[len+1] = ' ';
- full_address[len+2] = '\0';
- strcat(full_address, new_address);
- }
-
- return(0);
- }
-
- get_return_name(address, name, shift_lower)
- char *address, *name;
- int shift_lower;
- {
- /** Given the address (either a single address or a combined list
- of addresses) extract the login name of the first person on
- the list and return it as 'name'. Modified to stop at
- any non-alphanumeric character. **/
-
- /** An important note to remember is that it isn't vital that this
- always returns just the login name, but rather that it always
- returns the SAME name. If the persons' login happens to be,
- for example, joe.richards, then it's arguable if the name
- should be joe, or the full login. It's really immaterial, as
- indicated before, so long as we ALWAYS return the same name! **/
-
- /** Another note: modified to return the argument as all lowercase
- always, unless "shift_lower" isn't TRUE... **/
-
- char single_address[LONG_SLEN];
- register int i, loc, index = 0;
-
- dprint2(6,"get_return_name called with (%s, %s)\n",
- address, name);
-
- /* First step - copy address up to a comma, space, or EOLN */
-
- for (i=0; address[i] != ',' && ! whitespace(address[i]) &&
- address[i] != '\0'; i++)
- single_address[i] = address[i];
- single_address[i] = '\0';
-
- /* Now is it an ARPA address?? */
-
- if ((loc = chloc(single_address, '@')) != -1) { /* Yes */
-
- /* At this point the algorithm is to keep shifting our copy
- window left until we hit a '!'. The login name is then
- located between the '!' and the first metacharacter to
- it's right (ie '%', ':' or '@'). */
-
- dprint0(3,"Breaking down ARPA address...(get_return_name)\n");
-
- for (i=loc; single_address[i] != '!' && i > -1; i--)
- if (single_address[i] == '%' ||
- single_address[i] == ':' ||
- single_address[i] == '.' || /* no domains */
- single_address[i] == '@') loc = i-1;
-
- if (i < 0 || single_address[i] == '!') i++;
-
- dprint3(3,"\tgetting from %d to %d out of '%s'\n",
- i, loc - i + 1, single_address);
-
- for (index = 0; index < loc - i + 1; index++)
- if (shift_case)
- name[index] = tolower(single_address[index+i]);
- else
- name[index] = single_address[index+i];
- name[index] = '\0';
-
- dprint1(3,"\tfor a return name of '%s'\n", name);
- }
- else { /* easier - standard USENET address */
-
- /* This really is easier - we just cruise left from the end of
- the string until we hit either a '!' or the beginning of the
- line. No sweat. */
-
- loc = strlen(single_address)-1; /* last char */
-
- for (i = loc; single_address[i] != '!' && single_address[i] != '.'
- && i > -1; i--)
- name[index++] = tolower(single_address[i]);
- name[index] = '\0';
- reverse(name);
- }
-
- dprint2(6,"get_return_name leaves with (%s, %s)\n",
- address, name);
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 10750 ]
- then
- echo $filename changed - should be 10750 bytes, not $size bytes
- fi
-
- chmod 666 $filename
- fi
-
- echo end of this archive file....
- exit 0
-
-