home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume22
/
elm2.3
/
part18
< prev
next >
Wrap
Text File
|
1990-06-07
|
50KB
|
1,606 lines
Subject: v22i077: ELM mail syste, release 2.3, Part18/26
Newsgroups: comp.sources.unix
Approved: rsalz@uunet.UU.NET
X-Checksum-Snefru: 7997dd7c f2ed2d5a 0a47a0a8 5821681e
Submitted-by: Syd Weinstein <syd@dsinc.dsi.com>
Posting-number: Volume 22, Issue 77
Archive-name: elm2.3/part18
---- Cut Here and unpack ----
#!/bin/sh
# this is part 18 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file src/mailmsg2.c continued
#
CurArch=18
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
exit 1; fi
( read Scheck
if test "$Scheck" != $CurArch
then echo "Please unpack part $Scheck next!"
exit 1;
else exit 0; fi
) < s2_seq_.tmp || exit 1
echo "x - Continuing file src/mailmsg2.c"
sed 's/^X//' << 'SHAR_EOF' >> src/mailmsg2.c
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 (*copy_file) /* i.e. if copy_file contains a name */
X save_copy(expanded_to, expanded_cc, expanded_bcc,
X filename, copy_file, form);
X
X /** write all header information into whole_msg_file **/
X
X if((whole_msg_file=tempnam(temp_dir, "snd.")) == NULL) {
X dprint(1, (debugfile, "couldn't make temp file nam! (mail)\n"));
X if(batch_only)
X printf("Sorry - couldn't make temp file name!\n");
X else if(mail_only)
X error("Sorry - couldn't make temp file name.");
X else
X set_error("Sorry - couldn't make temp file name.");
X return(need_redraw);
X }
X
X /** try to write headers to new temp file **/
X
X dprint(6, (debugfile, "Composition file='%s' and mail buffer='%s'\n",
X filename, whole_msg_file));
X
X dprint(2,(debugfile,"--\nTo: %s\nCc: %s\nBcc: %s\nSubject: %s\n---\n",
X expanded_to, expanded_cc, expanded_bcc, subject));
X
X if ((real_reply=
X write_header_info(whole_msg_file, expanded_to,
X expanded_cc, expanded_bcc, form == YES, FALSE)) == NULL) {
X
X /** IT FAILED!! MEIN GOTT! Use a dumb mailer instead! **/
X
X dprint(3, (debugfile, "** write_header failed: %s\n",
X error_name(errno)));
X
X if (cc[0] != '\0') /* copies! */
X sprintf(expanded_to,"%s %s", expanded_to, expanded_cc);
X
X quote_args(very_long_buffer, strip_parens(strip_commas(expanded_to)));
X strcpy(expanded_to, very_long_buffer);
X
X sprintf(very_long_buffer, "( (%s -s \"%s\" %s ; %s %s) & ) < %s",
X mailx, subject, expanded_to, remove_cmd, filename, filename);
X
X if(batch_only)
X printf("Message sent using dumb mailer %s.\n", mailx);
X else
X error1("Message sent using dumb mailer %s.", mailx);
X sleep(2); /* ensure time to see this prompt! */
X
X }
X else {
X
X copy_message_across(reply, real_reply, FALSE);
X
X /* Append signature if not done earlier */
X
X if (!signature_done && !retransmit && copy_msg != FORM)
X append_sig(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 if (bcc[0] != '\0') {
X strcat(expanded_to, " ");
X strcat(expanded_to, expanded_bcc);
X }
X
X remove_hostbang(expanded_to);
X
X if (strcmp(sendmail, mailer) == 0
X#ifdef SITE_HIDING
X && ! is_a_hidden_user(username))
X#else
X )
X#endif
X
X strcpy(mailerflags, (sendmail_verbose ? smflagsv : smflags));
X else
X mailerflags[0] ='\0';
X
X quote_args(very_long_buffer, strip_parens(strip_commas(expanded_to)));
X strcpy(expanded_to, very_long_buffer);
X
X sprintf(very_long_buffer,"( (%s %s %s ; %s %s) & ) < %s",
X mailer, mailerflags, expanded_to,
X remove_cmd, whole_msg_file, whole_msg_file);
X }
X
X fclose(reply);
X
X if(batch_only)
X printf("Sending mail...\n");
X else {
X PutLine0(LINES,0,"Sending mail...");
X CleartoEOLN();
X }
X
X /* Take note of mailer return value */
X
X if ( sys_status = system_call(very_long_buffer, SH, FALSE, FALSE) ) {
X /* problem case: */
X if (mail_only || batch_only)
X printf("\r\nmailer returned error status %d\r\n", sys_status);
X else {
X sprintf(very_long_buffer, "mailer returned error status %d", sys_status);
X set_error(very_long_buffer);
X }
X } else {
X /* Success case: */
X if(batch_only)
X printf("Mail sent!\n");
X else if(mail_only)
X error("Mail sent!");
X else
X set_error("Mail sent!");
X }
X
X /* Unlink temp file now.
X * This is a precaution in case the message was encrypted.
X * I.e. even though this file is readable by the owner only,
X * encryption is supposed to hide things even from someone
X * with root privelges. The best we can do is not let this
X * file just hang after we're finished with it.
X */
X (void)unlink(filename);
X
X return(need_redraw);
X}
X
X/*
X * remove_hostbang - Given an expanded list of addresses, remove all
X * occurrences of "thishost!" at the beginning of addresses.
X * This hack is useful in itself, but it is required now because of the
X * kludge disallowing alias expansion on return addresses.
X */
X
Xremove_hostbang(addrs)
Xchar *addrs;
X{
X int i, j, hlen, flen;
X
X if ((hlen = strlen(hostname)) < 1)
X return;
X
X flen = strlen(hostfullname);
X i = j = 0;
X
X while (addrs[i]) {
X if (i == 0 || isspace(addrs[i - 1])) {
X if (strncmp(&addrs[i], hostname, hlen) == 0 &&
X addrs[i + hlen] == '!') {
X i += hlen + 1;
X continue;
X }
X if (strncmp(&addrs[i], hostfullname, flen) == 0 &&
X addrs[i + flen] == '!') {
X i += flen + 1;
X continue;
X }
X }
X addrs[j++] = addrs[i++];
X }
X addrs[j] = 0;
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));
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 char ch;
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 ch = ReadCh();
X if (tolower(ch) != '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[SLEN], fname[SLEN];
X int x_coord, y_coord;
X
X while(1) {
X /* clear bottom part of screen */
X MoveCursor(LINES-2,0);
X CleartoEOS();
X
X /* display prompt and menu according to
X * user level and what's available on the menu */
X if (user_level == 0) {
X PutLine0(LINES-2,0,
X "Please choose one of the following options by parenthesized letter: s");
X GetXYLocation(&x_coord, &y_coord);
X y_coord--; /* backspace over default answer */
X Centerline(LINES-1,
X "e)dit message, edit h)eaders, s)end it, or f)orget it.");
X } else {
X PutLine0(LINES-2, 0, "And now: s");
X GetXYLocation(&x_coord, &y_coord);
X y_coord--; /* backspace over default answer */
X if (*form_letter == PREFORMATTED) {
X strcpy(buffer, "Choose ");
X } else if (*form_letter == YES) {
X strcpy(buffer, "Choose e)dit form, ");
X } else if (*form_letter == MAYBE) {
X strcpy(buffer, "Choose e)dit msg, m)ake form, ");
X } else {
X strcpy(buffer, "Choose e)dit message, ");
X }
X#ifdef ALLOW_SUBSHELL
X strcat(buffer, "!)shell, ");
X#endif
X strcat(buffer, "h)eaders, c)opy file, s)end, or f)orget.");
X Centerline(LINES-1, buffer);
X }
X
X /* wait for answer */
X fflush(stdin);
X fflush(stdout);
X Raw(ON); /* double check... testing only... */
X MoveCursor(x_coord, y_coord);
X ch = ReadCh();
X ch = tolower(ch);
X
X /* process answer */
X switch (ch) {
X case 'f': Write_to_screen("Forget",0);
X if (mail_only) {
X /** try to save it as a dead letter file **/
X save_file_stats(fname);
X sprintf(fname, "%s/%s", home, dead_letter);
X if ((deadfd = fopen(fname,"a")) == NULL) {
X dprint(1, (debugfile,
X "\nAttempt to append to deadletter file '%s' failed: %s\n\r",
X fname, error_name(errno)));
X error("Message not saved, Sorry.");
X }
X else if ((messagefd = fopen(filename, "r")) == NULL) {
X dprint(1, (debugfile,
X "\nAttempt to read reply file '%s' failed: %s\n\r",
X filename, error_name(errno)));
X error("Message not saved, Sorry.");
X } else {
X /* if we get here we're okay for everything */
X while (fgets(buffer, SLEN, messagefd) != NULL)
X fputs(buffer, deadfd);
X
X fclose(messagefd);
X fclose(deadfd);
X restore_file_stats(fname);
X
X error1("Message saved in file \"$HOME/%s\".",
X dead_letter);
X
X }
X } else if (user_level != 0)
X set_error("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 : continue;
X }
X }
X else {
X Write_to_screen("%c??", 1, 07); /* BEEP */
X sleep(1);
X continue;
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 continue;
X }
X break;
X
X case 'h' : Write_to_screen("Headers",0);
X break;
X
X case 'c' : Write_to_screen("Copy file",0);
X break;
X
X case '!' : break;
X
X default : Write_to_screen("%c??", 1, 07); /* BEEP */
X sleep(1);
X continue;
X }
X
X return(ch);
X }
X}
X
XFILE *
Xwrite_header_info(filename, long_to, long_cc, long_bcc, form, copy)
Xchar *filename, *long_to, *long_cc, *long_bcc;
Xint form, copy;
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 If copy is TRUE, then treat this as the saved copy of outbound
X mail.
X **/
X
X char opentype[2];
X long time(), thetime;
X char *ctime();
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(copy)
X strcpy(opentype, "a");
X else
X strcpy(opentype, "w");
X
X save_file_stats(filename);
X if ((filedesc = fopen(filename, opentype)) == NULL) {
X dprint(1, (debugfile,
X "Attempt to open file %s for writing failed! (write_header_info)\n",
X filename));
X dprint(1, (debugfile, "** %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 restore_file_stats(filename);
X
X if(copy) { /* Add top line that mailer would add */
X#ifdef MMDF
X fprintf(filedesc, MSG_SEPERATOR);
X#endif /* MMDF */
X thetime = time((long *) 0);
X fprintf(filedesc,"From %s %s", username, ctime(&thetime));
X }
X
X#ifdef SITE_HIDING
X if ( !copy && (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 dprint(1,(debugfile, "\nadded: %s", buffer));
X /** so is this perverted or what? **/
X }
X#endif
X
X
X /** Subject moved to top of headers for mail because the
X pure System V.3 mailer, in its infinite wisdom, now
X assumes that anything the user sends is part of the
X message body unless either:
X 1. the "-s" flag is used (although it doesn't seem
X to be supported on all implementations??)
X 2. the first line is "Subject:". If so, then it'll
X read until a blank line and assume all are meant
X to be headers.
X So the gory solution here is to move the Subject: line
X up to the top. I assume it won't break anyone elses program
X or anything anyway (besides, RFC-822 specifies that the *order*
X of headers is irrelevant). Gahhhhh....
X **/
X
X fprintf(filedesc, "Subject: %s\n", subject);
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# else
X# ifdef INTERNET
X# ifdef USE_DOMAIN
X fprintf(filedesc,"From: %s <%s@%s>\n", full_username,
X username, hostfullname);
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#endif
X
X if (cc[0] != '\0')
X fprintf(filedesc, "Cc: %s\n", format_long(long_cc, strlen("Cc: ")));
X
X if (copy && (bcc[0] != '\0'))
X fprintf(filedesc, "Bcc: %s\n", format_long(long_bcc, strlen("Bcc: ")));
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, "Expires: %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#ifndef NOXHEADER
X fprintf(filedesc, "X-Mailer: ELM [version %s]\n\n", version_buff);
X#endif /* !NOXHEADER */
X
X return((FILE *) filedesc);
X}
X
Xcopy_message_across(source, dest, copy)
XFILE *source, *dest;
Xint copy;
X{
X /** Copy the message in the file pointed to by source to the
X file pointed to by dest.
X If copy is TRUE, treat as a saved copy of outbound mail. **/
X
X int crypted = FALSE; /* are we encrypting? */
X int encoded_lines = 0; /* # lines encoded */
X char buffer[SLEN]; /* file reading buffer */
X
X while (fgets(buffer, 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 || (strncmp(buffer, DONT_SAVE2, strlen(DONT_SAVE2)) == 0)) {
X if(copy) break; /* saved copy doesn't want anything after this */
X else continue; /* next line? */
X }
X }
X else if (crypted) {
X if (batch_only) {
X printf(
X "Sorry. Cannot send encrypted mail in \"batch mode\".\n\r");
X leave();
X } else if (! gotten_key++)
X getkey(ON);
X else if (! encoded_lines)
X get_key_no_prompt(); /* reinitialize.. */
X encode(buffer);
X encoded_lines++;
X }
X
X if (copy && (strncmp(buffer, "From ", 5) == 0))
X /* Add in the > to a From on our copy */
X fprintf(dest, ">%s", buffer);
X
X else if (!copy && strcmp(buffer, ".\n") == 0)
X /* Because some mail transport agents take a lone period to
X * mean EOF, we add a blank space on outbound message.
X */
X fputs(". \n", dest);
X else
X if (fputs(buffer, dest) == EOF) {
X Write_to_screen("\n\rWrite failed in copy_message_across\n\r", 0);
X emergency_exit();
X }
X }
X#ifdef MMDF
X if (copy) fputs(MSG_SEPERATOR, dest);
X#else
X if (copy) fputs("\n", dest); /* ensure a blank line at the end */
X#endif /* MMDF */
X}
X
Xint
Xverify_bounceback()
X{
X char ch;
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 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 ch = ReadCh();
X if (tolower(ch) != '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 return(TRUE);
X}
X
X
Xint
Xappend_sig(file)
XFILE *file;
X{
X /* Append the correct signature file to file. Return TRUE if
X we append anything. */
X
X /* Look at the to and cc list to determine which one to use */
X
X /* We could check the bcc list too, but we don't want people to
X know about bcc, even indirectly */
X
X /* Some people claim that user@anything.same_domain should be
X considered local. Since it's not the same machine, better be
X safe and use the remote sig (presumably it has more complete
X information). You can't necessarily finger someone in the
X same domain. */
X
X if (!batch_only && (local_signature[0] || remote_signature[0])) {
X
X char filename2[SLEN];
X char *sig;
X
X if (index(expanded_to, '!') || index(expanded_cc,'!'))
X sig = remote_signature; /* ! always means remote */
X else {
X /* check each @ for @thissite.domain */
X /* if any one is different than this, then use remote sig */
X int len;
X char *ptr;
X char sitename[SLEN];
X sprintf(sitename,"@%s",hostfullname);
X len = strlen(sitename);
X sig = local_signature;
X for (ptr = index(expanded_to,'@'); ptr; /* check To: list */
X ptr = index(ptr+1,'@')) {
X if (strncmp(ptr,sitename,len) != 0
X || (*(ptr+len) != ',' && *(ptr+len) != 0
X && *(ptr+len) != ' ')) {
X sig = remote_signature;
X break;
X }
X }
X if (sig == local_signature) /* still local? */
X for (ptr = index(expanded_cc,'@'); ptr; /* check Cc: */
X ptr = index(ptr+1,'@')) {
X if (strncmp(ptr,sitename,len) != 0
X || (*(ptr+len) != ',' && *(ptr+len) != 0
X && *(ptr+len) != ' ')) {
X sig = remote_signature;
X break;
X }
X }
X }
X
X if (sig[0]) { /* if there is a signature file */
X if (sig_dashes) /* dashes are optional */
X fprintf(file, "\n-- \n"); /* News 2.11 compatibility? */
X if (sig[0] != '/')
X sprintf(filename2, "%s/%s", home, sig);
X else
X strcpy(filename2, sig);
X (void) append(file, filename2);
X
X return TRUE;
X }
X }
X
Xreturn FALSE;
X
X}
SHAR_EOF
echo "File src/mailmsg2.c is complete"
chmod 0444 src/mailmsg2.c || echo "restore of src/mailmsg2.c fails"
echo "x - extracting src/mailtime.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/mailtime.c &&
X
Xstatic char rcsid[] = "@(#)$Id: mailtime.c,v 4.1 90/04/28 22:43:31 syd Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
X *
X * Copyright (c) 1986, 1987 Dave Taylor
X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
X *******************************************************************************
X * Bug reports, patches, comments, suggestions should be sent to:
X *
X * Syd Weinstein, Elm Coordinator
X * elm@DSI.COM dsinc!elm
X *
X *******************************************************************************
X * $Log: mailtime.c,v $
X * Revision 4.1 90/04/28 22:43:31 syd
X * checkin of Elm 2.3 as of Release PL0
X *
X *
X ******************************************************************************/
X
X/** This set of routines is used to figure out when the user last read
X their mail and to also figure out if a given message is new or not.
X
X**/
X
X#include "headers.h"
X
X#include <sys/types.h>
X#include <sys/stat.h>
X#ifdef I_TIME
X# include <time.h>
X#endif
X#ifdef I_SYSTIME
X# include <sys/time.h>
X#endif
X
Xresolve_received(entry)
Xstruct header_rec *entry;
X{
X /** Entry has the data for computing the time and date the
X message was received. Fix it and return **/
X
X switch (tolower(entry->month[0])) {
X case 'j' : if (tolower(entry->month[1]) == 'a')
X entry->received.month = JANUARY;
X else if (tolower(entry->month[2]) == 'n')
X entry->received.month = JUNE;
X else
X entry->received.month = JULY;
X break;
X case 'f' : entry->received.month = FEBRUARY;
X break;
X case 'm' : if (tolower(entry->month[2]) == 'r')
X entry->received.month = MARCH;
X else
X entry->received.month = MAY;
X break;
X case 'a' : if (tolower(entry->month[1]) == 'p')
X entry->received.month = APRIL;
X else
X entry->received.month = AUGUST;
X break;
X case 's' : entry->received.month = SEPTEMBER;
X break;
X case 'o' : entry->received.month = OCTOBER;
X break;
X case 'n' : entry->received.month = NOVEMBER;
X break;
X case 'd' : entry->received.month = DECEMBER;
X break;
X }
X
X sscanf(entry->day, "%d", &(entry->received.day));
X
X sscanf(entry->year, "%d", &(entry->received.year));
X if (entry->received.year > 100) entry->received.year -= 1900;
X
X sscanf(entry->time, "%d:%d", &(entry->received.hour),
X &(entry->received.minute));
X}
SHAR_EOF
chmod 0444 src/mailtime.c || echo "restore of src/mailtime.c fails"
echo "x - extracting src/mkhdrs.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/mkhdrs.c &&
X
Xstatic char rcsid[] = "@(#)$Id: mkhdrs.c,v 4.1 90/04/28 22:43:32 syd Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
X *
X * Copyright (c) 1986, 1987 Dave Taylor
X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
X *******************************************************************************
X * Bug reports, patches, comments, suggestions should be sent to:
X *
X * Syd Weinstein, Elm Coordinator
X * elm@DSI.COM dsinc!elm
X *
X *******************************************************************************
X * $Log: mkhdrs.c,v $
X * Revision 4.1 90/04/28 22:43:32 syd
X * checkin of Elm 2.3 as of Release PL0
X *
X *
X ******************************************************************************/
X
X/** This contains all the header generating routines for the ELM
X program.
X
X**/
X
X#include "headers.h"
X
Xextern char in_reply_to[SLEN];
X
Xchar *strcpy();
Xunsigned long sleep();
X
Xgenerate_reply_to(msg)
Xint msg;
X{
X /** Generate an 'in-reply-to' message... **/
X char buffer[SLEN];
X
X
X if (msg == -1) /* not a reply! */
X in_reply_to[0] = '\0';
X else {
X if (chloc(headers[msg]->from, '!') != -1)
X tail_of(headers[msg]->from, buffer, 0);
X else
X strcpy(buffer, headers[msg]->from);
X sprintf(in_reply_to, "%s; from \"%s\" at %s %s, %s %s",
X headers[msg]->messageid[0] == '\0'? "<no.id>":
X headers[msg]->messageid,
X buffer,
X headers[msg]->month,
X headers[msg]->day,
X headers[msg]->year,
X headers[msg]->time);
X }
X}
X
Xadd_mailheaders(filedesc)
XFILE *filedesc;
X{
X /** Add the users .mailheaders file if available. Allow backquoting
X in the file, too, for fortunes, etc...*shudder*
X **/
X
X FILE *fd;
X char filename[SLEN], buffer[SLEN];
X
X sprintf(filename, "%s/%s", home, mailheaders);
X
X if ((fd = fopen(filename, "r")) != NULL) {
X while (fgets(buffer, SLEN, fd) != NULL)
X if (strlen(buffer) < 2) {
X dprint(2, (debugfile,
X "Strlen of line from .elmheaders is < 2 (write_header_info)"));
X error1("Warning: blank line in %s ignored!", filename);
X sleep(2);
X }
X else if (occurances_of(BACKQUOTE, buffer) >= 2)
X expand_backquote(buffer, filedesc);
X else
X fprintf(filedesc, "%s", buffer);
X
X fclose(fd);
X }
X}
X
Xexpand_backquote(buffer, filedesc)
Xchar *buffer;
XFILE *filedesc;
X{
X /** This routine is called with a line of the form:
X Fieldname: `command`
X and is expanded accordingly..
X **/
X
X FILE *fd;
X char command[SLEN], command_buffer[SLEN], fname[SLEN],
X prefix[SLEN];
X register int i, j = 0;
X
X for (i=0; buffer[i] != BACKQUOTE; i++)
X prefix[j++] = buffer[i];
X prefix[j] = '\0';
X
X j = 0;
X
X for (i=chloc(buffer, BACKQUOTE)+1; buffer[i] != BACKQUOTE;i++)
X command[j++] = buffer[i];
X command[j] = '\0';
X
X sprintf(fname,"%s%s%d", temp_dir, temp_print, getpid());
X
X sprintf(command_buffer, "%s > %s", command, fname);
X
X system_call(command_buffer, SH, FALSE, FALSE);
X
X if ((fd = fopen(fname, "r")) == NULL) {
X error1("Backquoted command \"%s\" in elmheaders failed.", command);
X return;
X }
X
X /* If we get a line that is less than 80 - length of prefix then we
X can toss it on the same line, otherwise, simply prepend each line
X *starting with this line* with a leading tab and cruise along */
X
X if (fgets(command_buffer, SLEN, fd) == NULL)
X fprintf(filedesc, prefix);
X else {
X if (strlen(command_buffer) + strlen(prefix) < 80)
X fprintf(filedesc, "%s%s", prefix, command_buffer);
X else
X fprintf(filedesc, "%s\n\t%s", prefix, command_buffer);
X
X while (fgets(command_buffer, SLEN, fd) != NULL)
X fprintf(filedesc, "\t%s", command_buffer);
X
X fclose(fd);
X }
X
X unlink(fname); /* don't leave the temp file laying around! */
X}
SHAR_EOF
chmod 0444 src/mkhdrs.c || echo "restore of src/mkhdrs.c fails"
echo "x - extracting src/newmbox.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/newmbox.c &&
X
Xstatic char rcsid[] = "@(#)$Id: newmbox.c,v 4.1 90/04/28 22:43:34 syd Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
X *
X * Copyright (c) 1988, USENET Community Trust
X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
X *******************************************************************************
X * Bug reports, patches, comments, suggestions should be sent to:
X *
X * Syd Weinstein, Elm Coordinator
X * elm@DSI.COM dsinc!elm
X *
X *******************************************************************************
X * $Log: newmbox.c,v $
X * Revision 4.1 90/04/28 22:43:34 syd
X * checkin of Elm 2.3 as of Release PL0
X *
X *
X ******************************************************************************/
X
X/** read new folder **/
X
X#include <ctype.h>
X#include "headers.h"
X
X#ifdef BSD
X#undef tolower /* we have our own "tolower" routine instead! */
X#endif
X
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <errno.h>
X
X#ifdef I_TIME
X# include <time.h>
X#endif
X#ifdef I_SYSTIME
X# include <sys/time.h>
X#endif
X
Xextern int errno;
X
Xchar *error_name(), *error_description();
Xchar *malloc(), *realloc(), *strcpy(), *strncpy(), *rindex(), *index();
Xunsigned long sleep();
Xvoid rewind();
Xvoid exit();
Xlong bytes();
X
Xint
Xnewmbox(new_file, adds_only)
Xchar *new_file;
Xint adds_only;
X{
X /** Read a folder.
X
X new_file - name of folder to read. It is up to the calling
X function to make sure that the file can be
X read by the user. This is not checked in this
X function. The reason why it is not checked here
X is due to the situation where the user wants to
X change folders: the new folder must be checked
X for access *before* leaving the old one, which
X is before this function gets called.
X adds_only - set if we only want to read newly added messages to
X same old folder.
X
X **/
X
X int same_file;
X int new_folder_type;
X int err;
X char new_tempfile[SLEN];
X
X /* determine type of new mailfile and calculate temp file name */
X if((new_folder_type = get_folder_type(new_file)) == SPOOL)
X mk_temp_mail_fn(new_tempfile, new_file);
X else
X *new_tempfile = '\0';
X
X /* determine whether we are changing files */
X same_file = !(strcmp(new_file, cur_folder));
X
X /* If we are changing files and we are changing to a spool file,
X * make sure there isn't a temp file for it, because if
X * there is, someone else is using ELM to read the new file,
X * and we don't want to be reading it at the same time.
X */
X if((new_folder_type == SPOOL) && (!same_file)) {
X if (access(new_tempfile, ACCESS_EXISTS) != -1) {
X if(folder_type != NO_NAME) ClearScreen();
X Centerline(15,
X "Hey! An instantiation of ELM is already reading this mail!");
X Centerline(17,
X "If this is in error, then you'll need to save a copy of the");
X Centerline(18, "the following file then remove it:");
X Centerline(19, new_tempfile);
X MoveCursor(LINES, 0); /* so shell prompt upon exit is on newline */
X silently_exit();
X }
X }
X
X /* If we were reading a spool file and we are not just reading
X * in the additional new messages to the same file, we need to
X * remove the corresponding tempfile.
X */
X
X if((folder_type == SPOOL) && !adds_only) {
X if (access(cur_tempfolder, ACCESS_EXISTS) != -1) {
X if (unlink(cur_tempfolder) != 0) {
X error2("Sorry, can't unlink the temp file %s [%s]!\n\r",
X cur_tempfolder, error_name(errno));
X silently_exit();
X }
X }
X }
X
X /* Okay! Now establish this new file as THE file */
X strcpy(cur_folder, new_file);
X folder_type = new_folder_type;
X strcpy(cur_tempfolder, new_tempfile);
X
X clear_error();
X clear_central_message();
X
X if (mailfile != NULL)
X (void) fclose(mailfile); /* close it first, to avoid too many open */
X
X if ((mailfile = fopen(cur_folder,"r")) == NULL) {
X if (errno != ENOENT ) { /* error on anything but file not exist */
X err = errno;
X Write_to_screen("\n\rfail on open in newmbox, open %s failed!!\n\r", 1,
X cur_folder);
X Write_to_screen("** %s - %s. **\n\r", 2,
X error_name(err), error_description(err));
X dprint(1, (debugfile, "fail on open in newbox, file %s!!\n",
X cur_folder));
X rm_temps_exit();
X }
X else {
X mailfile_size = 0; /* must non-existant folder */
X message_count = 0;
X selected = 0;
X }
X } else { /* folder exists, read headers */
X read_headers(adds_only);
X }
X
X if(!same_file) /* limit mode off if this is a new file */
X selected = 0;
X if (!adds_only) /* limit mode off if recreating headers */
X selected = 0; /* because we loose the 'Visible' flag */
X
X dprint(1, (debugfile,
X "New folder %s type %s temp file %s (%s)\n", cur_folder,
X (folder_type == SPOOL ? "spool" : "non-spool"),
X (*cur_tempfolder ? cur_tempfolder : "none"), "newmbox"));
X
X return(0);
X}
X
Xint
Xget_folder_type(filename)
Xchar *filename;
X{
X /** returns the type of mailfile filename is
X NO_NAME = no name
X SPOOL = consisting only of mailhome plus base file name
X (no intervening directory name)
X NON_SPOOL = a name that is not SPOOL type above
X **/
X
X char *last_slash;
X
X /* if filename is null or is of zero length */
X if((filename == NULL) || (*filename == '\0'))
X return(NO_NAME);
X
X /* if filename begins with mailhome,
X * and there is a slash in filename,
X * and there is a filename after it (i.e. last slash is not last char),
X * and the last character of mailhome is last slash in filename,
X * it's a spool file .
X */
X if((first_word(filename, mailhome)) &&
X ((last_slash = rindex(filename, '/')) != NULL) &&
X (*(last_slash+1) != '\0') &&
X (filename + strlen(mailhome) - 1 == last_slash))
X return(SPOOL);
X /* if file name == default mailbox, its a spool file also
X * even if its not in the spool directory. (SVR4)
X */
X if (strcmp(filename, defaultfile) == 0)
X return(SPOOL);
X
X return(NON_SPOOL);
X}
X
Xmk_temp_mail_fn(tempfn, mbox)
Xchar *tempfn, *mbox;
X{
X /** create in tempfn the name of the temp file corresponding to
X mailfile mbox. Mbox is presumed to be a file in mailhome;
X Strangeness may result if it is not!
X **/
X
X char *cp;
X
X sprintf(tempfn, "%s%s", default_temp, temp_mbox);
X if((cp = rindex(mbox, '/')) != NULL) {
X cp++;
X if (strcmp(cp, "mbox") == 0 || strcmp(cp, "mailbox") == 0 ||
X *cp == '.')
X strcat(tempfn, username);
X else
X strcat(tempfn, cp);
X }
X}
X
Xint
Xread_headers(add_new_only)
Xint add_new_only;
X{
X /** Reads the headers into the headers[] array and leaves the
X file rewound for further I/O requests. If the file being
X read is a mail spool file (ie incoming) then it is copied to
X a temp file and closed, to allow more mail to arrive during
X the elm session. If 'add_new_only' is set, the program will copy
X the status flags from the previous data structure to the new
X one if possible and only read in newly added messages.
X **/
X
X FILE *temp;
X struct header_rec *current_header = NULL;
X char buffer[LONG_STRING], *c;
X long fbytes = 0L, line_bytes = 0L;
X register int line = 0, count = 0, another_count,
X subj = 0, copyit = 0, in_header = 0;
X int count_x, count_y = 17, err;
X int in_to_list = FALSE, forwarding_mail = FALSE, first_line = TRUE;
X
X static int first_read = 0;
X#ifdef MMDF
X int newheader = 0;
X#endif /* MMDF */
X
X if (folder_type == SPOOL) {
X lock(INCOMING); /* ensure no mail arrives while we do this! */
X if (! add_new_only) {
X if (access(cur_tempfolder, ACCESS_EXISTS) != -1) {
X /* Hey! What the hell is this? The temp file already exists? */
X /* Looks like a potential clash of processes on the same file! */
X unlock(); /* so remove lock file! */
X error("What's this? The temp folder already exists??");
X sleep(2);
X error("Ahhhh... I give up.");
X silently_exit(); /* leave without tampering with it! */
X }
X if ((temp = fopen(cur_tempfolder,"w")) == NULL) {
X err = errno;
X unlock(); /* remove lock file! */
X Raw(OFF);
X Write_to_screen(
X "\n\rCouldn't open file %s for use as temp file.\n\r",
X 1, cur_tempfolder);
X Write_to_screen("** %s - %s. **\n\r", 2,
X error_name(err), error_description(err));
X dprint(1, (debugfile,
X "Error: Couldn't open file %s as temp mbox. errno %s (%s)\n",
X cur_tempfolder, error_name(err), "read_headers"));
X rm_temps_exit();
X }
X copyit++;
X chown(cur_tempfolder, userid, groupid);
X chmod(cur_tempfolder, 0700); /* shut off file for other people! */
X }
X else {
X if ((temp = fopen(cur_tempfolder,"a")) == NULL) {
X err = errno;
X unlock(); /* remove lock file! */
X Raw(OFF);
X Write_to_screen(
X "\n\rCouldn't reopen file %s for use as temp file.\n\r",
X 1, cur_tempfolder);
X Write_to_screen("** %s - %s. **\n\r", 2,
X error_name(err), error_description(err));
X dprint(1, (debugfile,
X "Error: Couldn't reopen file %s as temp mbox. errno %s (%s)\n",
X cur_tempfolder, error_name(err), "read_headers"));
X rm_temps_exit();
X }
X copyit++;
X }
X }
X
X if (! first_read++) {
X ClearLine(LINES-1);
X ClearLine(LINES);
X if (add_new_only)
X PutLine2(LINES, 0, "Reading in %s, message: %d", cur_folder,
X message_count);
X else
X PutLine1(LINES, 0, "Reading in %s, message: 0", cur_folder);
X count_x = LINES;
X count_y = 22 + strlen(cur_folder);
X }
X else {
X count_x = LINES-2;
X PutLine0(LINES-2, 0, "Reading message: 0");
X }
X
X if (add_new_only) {
X if (fseek(mailfile, mailfile_size, 0) == -1) {
X err = errno;
X Write_to_screen(
X "\n\rCouldn't seek to %ld (end of folder) in %s!\n\r", 2,
X mailfile_size, cur_folder);
X Write_to_screen("** %s - %s. **\n\r", 2,
X error_name(err), error_description(err));
X dprint(1, (debugfile,
X "Error: Couldn't seek to end of folder %s: (offset %ld) Errno %s (%s)\n",
X cur_folder, mailfile_size, error_name(err), "read_headers"));
X emergency_exit();
X }
X count = message_count; /* next available */
X fbytes = mailfile_size; /* start correctly */
X }
X
X /** find the size of the folder then unlock the file **/
X
X mailfile_size = bytes(cur_folder);
X unlock();
X
X /** now let's copy it all across accordingly... **/
X
X while (fbytes < mailfile_size) {
X
X if (fgets(buffer, LONG_STRING, mailfile) == NULL) break;
X
X if (copyit)
X if (fputs(buffer, temp) == EOF) {
X err = errno;
X Write_to_screen("\n\rWrite to tempfile %s failed!!\n\r", 1,
X cur_tempfolder);
X Write_to_screen("** %s - %s. **\n\r", 2,
X error_name(err), error_description(err));
X dprint(1, (debugfile, "Can't write to tempfile %s!!\n",
X cur_tempfolder));
X rm_temps_exit();
X }
X line_bytes = (long) strlen(buffer);
X
X /* Fix below to increment line count ONLY if we got a full line.
X * Input lines longer than the fgets buffer size would
X * get counted each time a subsequent part of them was
X * read in. This meant that when the faulty line count was used
X * to display the message, part of the next message
X * was displayed at the end of the message.
X */
X if(buffer[strlen(buffer)-1] == '\n') line++;
X
X if (fbytes == 0L || first_line) { /* first line of file... */
X if (folder_type == SPOOL) {
X if (first_word(buffer, "Forward to ")) {
X set_central_message("Mail being forwarded to %s",
X (char *) (buffer + 11));
X forwarding_mail = TRUE;
X }
X }
X
X /** flush leading blank lines before next test... **/
X if (strlen(buffer) == 1) {
X fbytes++;
X continue;
X }
X else
X first_line = FALSE;
X
X#ifdef MMDF
X if (!forwarding_mail && strcmp(buffer, MSG_SEPERATOR) != 0 ) {
X#else
X if (! first_word(buffer, "From ") && !forwarding_mail) {
X#endif /* MMDF */
X PutLine0(LINES, 0,
X "\n\rFolder is corrupt!! I can't read it!!\n\r\n\r");
X fflush(stderr);
X dprint(1, (debugfile,
X "\n\n**** First mail header is corrupt!! ****\n\n"));
X dprint(1, (debugfile, "Line is;\n\t%s\n\n", buffer));
X mail_only++; /* to avoid leave() cursor motion */
X leave();
X }
X }
X
X#ifdef MMDF
X if (strcmp(buffer, MSG_SEPERATOR) == 0) {
X newheader = !newheader;
X#else
X if (first_word(buffer,"From ")) {
X#endif /* MMDF */
X /** allocate new header pointers, if needed... **/
X
X if (count >= max_headers) {
X struct header_rec **new_headers;
X int new_max;
X
X new_max = max_headers + KLICK;
X if (max_headers == 0) {
X new_headers = (struct header_rec **)
X malloc(new_max * sizeof(struct header_rec *));
X }
X else {
X new_headers = (struct header_rec **)
X realloc(headers, new_max * sizeof(struct header_rec *));
X }
X if (new_headers == NULL) {
X error1(
X "\n\r\n\rCouldn't allocate enough memory! Message #%d.\n\r\n\r",
X count);
X leave();
X }
X headers = new_headers;
X while (max_headers < new_max)
X headers[max_headers++] = NULL;
X }
X
X /** allocate new header structure, if needed... **/
X
X if (headers[count] == NULL) {
X struct header_rec *h;
X
X if ((h = (struct header_rec *)
X malloc(sizeof(struct header_rec))) == NULL) {
X error1(
X "\n\r\n\rCouldn't allocate enough memory! Message #%d.\n\r\n\r",
X count);
X leave();
X }
X headers[count] = h;
X }
X
X if (real_from(buffer, headers[count])) {
X current_header = headers[count];
X
X current_header->offset = (long) fbytes;
X current_header->index_number = count+1;
X /* set default status - always 'visible' - and
X * if a spool file, presume 'new', otherwise
X * 'read', for the time being until overridden
X * by a Status: header.
X * We presume 'read' for nonspool mailfile messages
X * to be compatible messages stored with older versions of elm,
X * which didn't support a Status: header.
X */
X if(folder_type == SPOOL)
X current_header->status = VISIBLE | NEW | UNREAD;
X else
X current_header->status = VISIBLE;
X
X strcpy(current_header->subject, ""); /* clear subj */
X strcpy(current_header->to, ""); /* clear to */
X strcpy(current_header->mailx_status, ""); /* clear status flags */
X strcpy(current_header->messageid, "<no.id>"); /* set no id into message id */
X current_header->encrypted = 0; /* clear encrypted */
X current_header->exit_disposition = UNSET;
X current_header->status_chgd = FALSE;
X
X /* Set the number of lines for the _preceding_ message,
X * but only if there was a preceding message and
X * only if it wasn't calculated already. It would
X * have been calculated already if we are only
X * reading headers of new messages that have just arrived,
X * and the preceding message was one of the old ones.
X */
X if ((count) && (!add_new_only || count > message_count))
X headers[count-1]->lines = line;
X
X count++;
X subj = 0;
X line = 0;
X in_header = 1;
X PutLine1(count_x, count_y, "%d", count);
X#ifdef MMDF
X } else if (newheader) {
X current_header = headers[count];
X
X current_header->offset = (long) fbytes;
X current_header->index_number = count+1;
X
X /* set default status - always 'visible' - and
X * if a spool file, presume 'new', otherwise
X * 'read', for the time being until overridden
X * by a Status: header.
X * We presume 'read' for nonspool mailfile messages
X * to be compatible messages stored with older versions of elm,
X * which didn't support a Status: header.
X */
X if(folder_type == SPOOL)
X current_header->status = VISIBLE | NEW | UNREAD;
X else
X current_header->status = VISIBLE;
X
X strcpy(current_header->from, ""); /* clear from */
X strcpy(current_header->dayname, ""); /* clear dayname */
X strcpy(current_header->month, ""); /* clear month */
X strcpy(current_header->day, ""); /* clear day */
X strcpy(current_header->time, ""); /* clear time */
X strcpy(current_header->year, ""); /* clear year */
X strcpy(current_header->subject, ""); /* clear subj */
X strcpy(current_header->to, ""); /* clear to */
X strcpy(current_header->mailx_status, ""); /* clear status flags */
X strcpy(current_header->messageid, "<no.id>"); /* set no id into message id */
X current_header->encrypted = 0; /* clear encrypted */
X current_header->exit_disposition = UNSET;
X current_header->status_chgd = FALSE;
X
X /* Set the number of lines for the _preceding_ message,
X * but only if there was a preceding message and
X * only if it wasn't calculated already. It would
X * have been calculated already if we are only
X * reading headers of new messages that have just arrived,
X * and the preceding message was one of the old ones.
X */
X if ((count) && (!add_new_only || count > message_count))
X headers[count-1]->lines = line;
X
X count++;
X subj = 0;
X line = 0;
X in_header = 1;
X PutLine1(count_x, count_y, "%d", count);
X dprint(1, (debugfile,
X "\n\n**** Added header record ****\n\n"));
X#endif /* MMDF */
X } else if (count == 0) {
X /* if this is the first "From" in file but the "From" line is
X * not of the proper format, we've got a corrupt folder.
X */
X PutLine0(LINES, 0,
X "\n\rFolder is corrupt!! I can't read it!!\n\r\n\r");
X fflush(stderr);
X dprint(1, (debugfile,
X "\n\n**** First mail header is corrupt!! ****\n\n"));
X dprint(1, (debugfile, "Line is;\n\t%s\n\n", buffer));
X mail_only++; /* to avoid leave() cursor motion */
X leave();
X }
X }
X else if (in_header) {
X#ifdef MMDF
X if (first_word(buffer,"From "))
X real_from(buffer, current_header);
X#endif /* MMDF */
X if (first_word(buffer,">From:"))
X parse_arpa_who(buffer, current_header->from, FALSE);
X else if (first_word(buffer,">From"))
X forwarded(buffer, current_header); /* return address */
X else if (first_word(buffer,"Subject:") ||
X first_word(buffer,"Subj:") ||
X first_word(buffer,"Re:")) {
X if (! subj++) {
X remove_first_word(buffer);
X copy_sans_escape(current_header->subject, buffer, STRING);
X remove_possible_trailing_spaces(current_header->subject);
X }
X }
X else if (first_word(buffer,"From:")) {
X#ifdef MMDF
X parse_arpa_who(buffer, current_header->from, TRUE);
X dprint(1, (debugfile,
X "\n\n**** Calling parse_arpa_who for from ****\n\n"));
X#else
X parse_arpa_who(buffer, current_header->from, FALSE);
X#endif /* MMDF */
X
X }
X else if (first_word(buffer, "Message-Id:") ||
X first_word(buffer, "Message-ID:")) {
X buffer[strlen(buffer)-1] = '\0';
X strcpy(current_header->messageid,
X (char *) buffer + 12);
X }
X
X else if (first_word(buffer, "Expires:"))
X process_expiration_date((char *) buffer + 9,
X &(current_header->status));
X
X /** when it was sent... **/
X
X else if (first_word(buffer, "Date:")) {
X dprint(1, (debugfile,
X "\n\n**** Calling parse_arpa_date ****\n\n"));
X remove_first_word(buffer);
X parse_arpa_date(buffer, current_header);
X }
X
X /** some status things about the message... **/
X
X else if (first_word(buffer, "Priority:") ||
X first_word(buffer, "Importance: 2"))
X current_header->status |= URGENT;
X else if (first_word(buffer, "Sensitivity: 2"))
X current_header->status |= PRIVATE;
X else if (first_word(buffer, "Sensitivity: 3"))
X current_header->status |= CONFIDENTIAL;
X else if (first_word(buffer, "Content-Type: mailform"))
X current_header->status |= FORM_LETTER;
X else if (first_word(buffer, "Action:"))
X current_header->status |= ACTION;
X
X /** next let's see if it's to us or not... **/
X
X else if (first_word(buffer, "To:")) {
X in_to_list = TRUE;
X current_header->to[0] = '\0'; /* nothing yet */
X figure_out_addressee((char *) buffer +3,
X current_header->to);
X }
X else if (first_word(buffer, "Status:")) {
X remove_first_word(buffer);
X strncpy(current_header->mailx_status, buffer, WLEN-1);
X current_header->mailx_status[WLEN-1] ='\0';
X
X c = index(current_header->mailx_status, '\n');
X if (c != NULL)
X *c = '\0';
X remove_possible_trailing_spaces(current_header->mailx_status);
X
X /* Okay readjust the status. If there's an 'R', message
X * is read; if there is no 'R' but there is an 'O', message
X * is unread. In any case it isn't new because a new message
X * wouldn't have a Status: header.
X */
X if (index(current_header->mailx_status, 'R') != NULL)
X current_header->status &= ~(NEW | UNREAD);
X else if (index(current_header->mailx_status, 'O') != NULL) {
X current_header->status &= ~NEW;
X current_header->status |= UNREAD;
X }
X }
X
X else if (buffer[0] == LINE_FEED || buffer[0] == '\0') {
X if (in_header) {
X in_header = 0; /* in body of message! */
X fix_date(current_header);
X }
X }
X else if (in_header) {
X if ((!whitespace(buffer[0])) && index(buffer, ':') == NULL) {
X in_header = 0; /* in body of message! */
X fix_date(current_header);
X }
X }
X else if (in_to_list == TRUE) {
X if (whitespace(buffer[0]))
X figure_out_addressee(buffer, current_header->to);
SHAR_EOF
echo "End of part 18"
echo "File src/newmbox.c is continued in part 19"
echo "19" > s2_seq_.tmp
exit 0
exit 0 # Just in case...