syd@dsinc.UUCP (Syd Weinstein) (12/13/88)
---- Cut Here and unpack ----
#!/bin/sh
# this is part 15 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file src/mailmsg2.c continued
#
CurArch=15
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
X sprintf(fname, "%s/%s", home, dead_letter);
X
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 printf("Message not saved, Sorry.\n\r\n\r");
X return('f');
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 printf("Message not saved, Sorry.\n\r\n\r");
X return('f');
X }
X
X chown (fname, userid, groupid);
X
X /* if we get here we're okay for everything, right? */
X
X while (fgets(buffer, LONG_SLEN, messagefd) != NULL)
X fputs(buffer, deadfd);
X
X fclose(messagefd);
X fclose(deadfd);
X
X printf("Message saved in file \"$HOME/%s\"\n\r\n\r", dead_letter);
X
X return('f'); /* forget it! */
X }
X else switch (ch) {
X case '\r':
X case '\n': ch = 's';
X case 's' : printf("Send\n\r"); break;
X case 'e' : printf("Edit the message\n\r"); break;
X case 'h' : printf("Edit the headers\n\r"); break;
X default : printf("\n\rI'm afraid I don't understand that - please answer again...\n\r");
X goto batch_reprompt;
X }
X
X return(ch); /* send this baby or whatever! */
X }
X else
X return('s'); /* SEND! Yow!! */
X }
X else if (check_first) { /* used to check strlen(infile) > 0 too? */
Xreprompt:
X MoveCursor(LINES,0);
X CleartoEOLN();
X ClearLine(LINES-1);
X
X if (user_level == 0) {
X PutLine0(LINES-2,0, "Please choose one of the following options by capitalized letter");
X PutLine1(LINES-1,0, "E)dit the message, edit the H)eaders, S)end it, or F)orget it: s%c",
X BACKSPACE);
X }
X else if (*form_letter == PREFORMATTED)
X PutLine1(LINES-1, 0,
X "Choose: edit H)eaders, S)end, or F)orget : s%c",
X BACKSPACE);
X else if (*form_letter == YES)
X PutLine1(LINES-1, 0,
X "Choose: E)dit form, edit H)eaders, S)end, or F)orget : s%c",
X BACKSPACE);
X else if (*form_letter == MAYBE)
X PutLine1(LINES-1, 0,
X "Choose: E)dit msg, edit H)eaders, M)ake form, S)end, or F)orget : s%c",
X BACKSPACE);
X else
X PutLine1(LINES-1, 0,
X "Please choose: E)dit msg, edit H)eaders, S)end, or F)orget : s%c",
X BACKSPACE);
X
X fflush(stdin); /* wait for answer! */
X fflush(stdout);
X Raw(ON); /* double check... testing only... */
X ch = ReadCh();
X ch = tolower(ch);
X
X switch (ch) {
X case 'f': Write_to_screen("Forget",0);
X set_error(
X "Message kept - Can be restored at next F)orward, M)ail or R)eply ");
X break;
X
X case '\n' :
X case '\r' :
X case 's' : Write_to_screen("Send",0);
X ch = 's'; /* make sure! */
X break;
X
X case 'm' : if (*form_letter == MAYBE) {
X *form_letter = YES;
X switch (check_form_file(filename)) {
X case -1 : return('f');
X case 0 : *form_letter = MAYBE; /* check later!*/
X error("No fields in form!");
X return('e');
X default : goto reprompt;
X }
X }
X else {
X Write_to_screen("%c??", 1, 07); /* BEEP */
X sleep(1);
X goto reprompt; /* yech */
X }
X case 'e' : if (*form_letter != PREFORMATTED) {
X Write_to_screen("Edit",0);
X if (*form_letter == YES)
X *form_letter = MAYBE;
X }
X else {
X Write_to_screen("%c??", 1, 07); /* BEEP */
X sleep(1);
X goto reprompt; /* yech */
X }
X break;
X case 'h' : Write_to_screen("Headers",0);
X break;
X
X default : Write_to_screen("%c??", 1, 07); /* BEEP */
X sleep(1);
X goto reprompt; /* yech */
X }
X
X return(ch);
X }
X else return('s');
X}
X
XFILE *
X#ifdef ALLOW_BCC
X write_header_info(filename, long_to, long_cc, long_bcc, form)
X char *filename, *long_to, *long_cc, *long_bcc;
X#else
X write_header_info(filename, long_to, long_cc, form)
X char *filename, *long_to, *long_cc;
X#endif
Xint form;
X{
X /** Try to open filedesc as the specified filename. If we can,
X then write all the headers into the file. The routine returns
X 'filedesc' if it succeeded, NULL otherwise. Added the ability
X to have backquoted stuff in the users .elmheaders file!
X **/
X
X static FILE *filedesc; /* our friendly file descriptor */
X
X#ifdef SITE_HIDING
X char buffer[SLEN];
X int is_hidden_user; /* someone we should know about? */
X#endif
X
X char *get_arpa_date();
X
X if ((filedesc = fopen(filename, "w")) == NULL) {
X 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 chown (filename, userid, groupid);
X
X#ifdef SITE_HIDING
X if ((is_hidden_user = is_a_hidden_user(username))) {
X /** this is the interesting part of this trick... **/
X sprintf(buffer, "From %s!%s %s\n", HIDDEN_SITE_NAME,
X username, get_ctime_date());
X fprintf(filedesc, "%s", buffer);
X 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# endif
X# ifdef INTERNET_ADDRESS_FORMAT
X# ifdef USE_DOMAIN
X fprintf(filedesc,"From: %s <%s@%s%s>\n", full_username,
X username, hostname, DOMAIN);
X# else
X fprintf(filedesc,"From: %s <%s@%s>\n", full_username,
X username, hostname);
X# endif
X# else
X fprintf(filedesc,"From: %s <%s!%s>\n", full_username,
X hostname, username);
X# endif
X#endif
X
X if (cc[0] != '\0')
X fprintf(filedesc, "Cc: %s\n", format_long(long_cc, strlen("Cc: ")));
X
X#ifdef ALLOW_BCC
X if (bcc[0] != '\0')
X fprintf(filedesc, "Bcc: %s\n",
X format_long(long_bcc, strlen("Bcc: ")));
X#endif
X
X if (strlen(action) > 0)
X fprintf(filedesc, "Action: %s\n", action);
X
X if (strlen(priority) > 0)
X fprintf(filedesc, "Priority: %s\n", priority);
X
X if (strlen(expires) > 0)
X fprintf(filedesc, "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 fprintf(filedesc, "X-Mailer: Elm [version %s]\n\n", version_buff);
X
X return((FILE *) filedesc);
X}
X
Xcopy_message_across(source, dest)
XFILE *source, *dest;
X{
X /** copy the message in the file pointed to by source to the
X file pointed to by dest. **/
X
X int crypted = FALSE; /* are we encrypting? */
X int encoded_lines = 0; /* # lines encoded */
X char buffer[LONG_SLEN]; /* file reading buffer */
X
X while (fgets(buffer, LONG_SLEN, source) != NULL) {
X if (buffer[0] == '[') {
X if (strncmp(buffer, START_ENCODE, strlen(START_ENCODE))==0)
X crypted = TRUE;
X else if (strncmp(buffer, END_ENCODE, strlen(END_ENCODE))==0)
X crypted = FALSE;
X else if (strncmp(buffer, DONT_SAVE, strlen(DONT_SAVE)) == 0)
X continue; /* next line? */
X }
X else if (crypted) {
X if (! gotten_key++)
X getkey(ON);
X else if (! encoded_lines++)
X get_key_no_prompt(); /* reinitialize.. */
X
X encode(buffer);
X }
X fputs(buffer, dest);
X }
X}
X
Xint
Xverify_bounceback()
X{
X 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 if (mail_only) {
X printf("Would you like a copy \"bounced\" off the remote? (y/n) ");
X CleartoEOLN();
X printf("n%c", BACKSPACE);
X fflush(stdin); /* wait for answer! */
X fflush(stdout);
X ch = ReadCh();
X if (tolower(ch) != 'y') {
X printf("No\n\r");
X return(FALSE);
X }
X else
X printf("Yes - Bounceback included\n\r");
X }
X else {
X MoveCursor(LINES,0);
X CleartoEOLN();
X PutLine1(LINES,0,
X "\"Bounce\" a copy off the remote machine? (y/n) y%c",
X BACKSPACE);
X fflush(stdin); /* wait for answer! */
X fflush(stdout);
X 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
X return(TRUE);
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 2.1 88/07/21 09:58:59 edc Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 2.1 $ $State: Exp $
X *
X * Copyright (c) 1986 Dave Taylor
X *******************************************************************************
X * Bug reports, patches, comments, suggetions should be sent to:
X *
X * Syd Weinstein, Elm Corrdinator
X * syd@dsinc.UUCP dsinc!syd
X *
X *******************************************************************************
X * $Log: mailtime.c,v $
X * Revision 2.1 88/07/21 09:58:59 edc
X * checked in with -k by syd at 88.09.15.20.28.59.
X *
X * Revision 2.1 88/07/21 09:58:59 edc
X * Final hacks and cleanup to the 2.1 alpha test release.
X *
X * Revision 2.0 88/06/27 17:25:18 edc
X * The original 2.0 gamma sources as leaked from HP
X *
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 BSD
X# ifndef BSD4_1
X# include <sys/time.h>
X# else
X# include <time.h>
X# include <sys/timeb.h>
X# endif
X#else
X# include <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}
X
Xget_mailtime()
X{
X /** Instantiate the values of the last_read_mail stat
X variable based on the file access time/date of the
X file mailtime_file. IF the file doesn't exist,
X then assume all mail is new. **/
X
X struct stat buffer;
X struct tm *timebuf;
X char filename[SLEN];
X#ifdef BSD
X extern struct tm *localtime();
X#endif
X
X sprintf(filename, "%s/%s", home, mailtime_file);
X
X if (stat(filename, &buffer) == -1) {
X last_read_mail.month = 0;
X last_read_mail.day = 0;
X last_read_mail.year = 0;
X last_read_mail.hour = 0;
X last_read_mail.minute = 0;
X }
X else { /* stat okay... */
X timebuf = (struct tm *) localtime(&(buffer.st_mtime));
X
X last_read_mail.month = timebuf->tm_mon;
X last_read_mail.day = timebuf->tm_mday;
X last_read_mail.year = timebuf->tm_year;
X last_read_mail.hour = timebuf->tm_hour;
X last_read_mail.minute = timebuf->tm_min;
X }
X}
X
Xupdate_mailtime()
X{
X /** This routine updates the last modified time of the
X .last_read_mail file in the users home directory.
X If the file doesn't exist, it creates it!! **/
X
X char filename[SLEN];
X
X#ifdef BSD
X# ifdef BSD4_1
X struct timeb loc_time;
X time_t tval;
X# else
X struct timeval tval[2];
X struct timezone tzone;
X# endif
X#endif
X
X sprintf(filename, "%s/%s", home, mailtime_file);
X
X#ifdef BSD
X# ifdef BSD4_1
X tval = (time_t) time((long *) 0);
X if (utime(filename, &tval) == -1)
X# else
X gettimeofday(&tval[0], &tzone);
X gettimeofday(&tval[1], &tzone);
X
X if (utimes(filename, tval) == -1) /* note the "S" */
X# endif
X#else
X if (utime(filename, (char *) NULL) == -1) /* note no "S" */
X#endif
X /** That's what I like about programming for BSD & USG - the easy
X portability between 'em. Especially the section 2 calls!! **/
X
X (void) creat(filename, 0777);
X}
X
Xnew_msg(entry)
Xstruct header_rec entry;
X{
X /** Return true if the current message is NEW. This can be
X easily tested by seeing 1) if we're reading the incoming
X mailbox and then, if so, 2) if the received_on_machine
X date is more recent than the last_read_mail date.
X **/
X
X if (mbox_specified != 0) return(FALSE); /* not incoming */
X
X /** Two tests - if received is OLDER than last read mail, then
X immediately return FALSE. If received is NEWER than last
X read mail then immediately return TRUE **/
X
X if (entry.received.year < last_read_mail.year)
X return(FALSE);
X
X if (entry.received.year > last_read_mail.year)
X return(TRUE);
X
X if (entry.received.month < last_read_mail.month)
X return(FALSE);
X
X if (entry.received.month > last_read_mail.month)
X return(TRUE);
X
X if (entry.received.day < last_read_mail.day)
X return(FALSE);
X
X if (entry.received.day > last_read_mail.day)
X return(TRUE);
X
X if (entry.received.hour < last_read_mail.hour)
X return(FALSE);
X
X if (entry.received.hour > last_read_mail.hour)
X return(TRUE);
X
X if (entry.received.minute < last_read_mail.minute)
X return(FALSE);
X
X return(TRUE);
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 2.1 88/07/21 09:59:01 edc Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 2.1 $ $State: Exp $
X *
X * Copyright (c) 1986 Dave Taylor
X *******************************************************************************
X * Bug reports, patches, comments, suggetions should be sent to:
X *
X * Syd Weinstein, Elm Corrdinator
X * syd@dsinc.UUCP dsinc!syd
X *
X *******************************************************************************
X * $Log: mkhdrs.c,v $
X * Revision 2.1 88/07/21 09:59:01 edc
X * checked in with -k by syd at 88.09.15.20.29.01.
X *
X * Revision 2.1 88/07/21 09:59:01 edc
X * Final hacks and cleanup to the 2.1 alpha test release.
X *
X * Revision 2.0 88/06/27 17:25:20 edc
X * The original 2.0 gamma sources as leaked from HP
X *
X *
X *
X ******************************************************************************/
X
X/** This contains all the header generating routines for the ELM
X program.
X
X**/
X
X#include <stdio.h>
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(header_table[msg].from, '!') != -1)
X tail_of(header_table[msg].from, buffer, FALSE);
X else
X strcpy(buffer, header_table[msg].from);
X sprintf(in_reply_to, "%s; from \"%s\" at %s %s, %s %s",
X header_table[msg].messageid,
X buffer,
X header_table[msg].month,
X header_table[msg].day,
X header_table[msg].year,
X header_table[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[LONG_SLEN];
X
X sprintf(filename, "%s/%s", home, mailheaders);
X
X if ((fd = fopen(filename, "r")) != NULL) {
X while (fgets(buffer, LONG_SLEN, fd) != NULL)
X if (strlen(buffer) < 2) {
X dprint(2, (debugfile,
X "Strlen of line from .elmheaders is < 2 (write_header_info)"));
X if (mail_only)
X printf("Warning: blank line in %s ignored!\r\n", filename);
X else {
X error1("Warning: blank line in %s ignored!", filename);
X sleep(2);
X }
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%d", temp_print, getpid());
X
X sprintf(command_buffer, "%s > %s", command, fname);
X
X system_call(command_buffer, SH);
X
X if ((fd = fopen(fname, "r")) == NULL) {
X if (mail_only)
X printf("\nbackquoted command \"%s\" in .elmheaders failed\n",
X command);
X else
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 2.1.1.2 88/09/23 syd Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 2.1 $ $State: Exp $
X *
X * Copyright (c) 1986 Dave Taylor
X *******************************************************************************
X * Bug reports, patches, comments, suggetions should be sent to:
X *
X * Syd Weinstein, Elm Corrdinator
X * syd@dsinc.UUCP dsinc!syd
X *
X *******************************************************************************
X * $Log: newmbox.c,v $
X * Revision 2.1 88/09/15 20:29:04 syd
X * checked in with -k by syd at 88.09.15.20.29.04.
X *
X * 88/09/01 Rob Bernardo <gatech!pbhyf.PacBell.COM!rob>
X * Resend: exiting in cooked mode fix
X * fix alignment when new mail arrives in existing and in empty box
X *
X * 88/08/27 ssw
X * add deluth patches
X *
X * Revision 2.1 88/07/21 09:59:02 edc
X * Final hacks and cleanup to the 2.1 alpha test release.
X *
X * Revision 2.0 88/06/27 17:25:21 edc
X * The original 2.0 gamma sources as leaked from HP
X *
X *
X *
X ******************************************************************************/
X
X/** read new mailbox file **/
X
X#include <ctype.h>
X
X#ifdef BSD
X#undef tolower /* we have our own "tolower" routine instead! */
X#endif
X
X#include "headers.h"
X
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <errno.h>
X
X#ifdef BSD /* Berkeley has library elsewhere... */
X# ifndef BSD4_1
X# include <sys/time.h>
X# else
X# include <time.h>
X# endif
X#else
X# include <time.h>
X#endif
X
Xextern int errno;
X
Xchar *error_name(), *error_description(), *strcpy(), *strncpy();
Xunsigned long sleep();
Xvoid rewind();
Xvoid exit();
Xlong bytes();
X
Xstruct header_rec *realloc();
X
Xint
Xnewmbox(stat, resync, main_screen)
Xint stat, resync, main_screen;
X{
X /** Read a new mailbox file or resync on current file.
X
X Values of stat and what they mean;
X
X stat = 0 - changing mailboxes from within program
X stat = 1 - read default mailbox or infile for the
X first time
X stat = 2 - read existing mailbox, new mail arrived
X stat = 3 - resync on existing mailbox...
X
X resync is TRUE iff we know the current mailbox has changed. If
X it's set to true this means that we MUST READ SOMETHING, even
X if it's the current mailbox again!!
X
X main_screen simply tells where the counting line should be.
X
X **/
X
X int switching_to_default = 0, switching_from_default = 0;
X int iterations = 0, redraw = 0; /* for dealing with the '?' answer */
X int old_raw;
X char buff[SLEN];
X
X if (mbox_specified == 0 && stat == 0)
X switching_from_default++;
X
X if (stat > 0) {
X if (stat == 1 && strlen(infile) == 0) {
X
X /* Subtlety - check to see if there's another instantiation
X of Elm (e.g. if the /tmp file is in use). If so, DIE! */
X
X sprintf(infile, "%s%s", temp_mbox, username);
X if (access(infile, ACCESS_EXISTS) != -1) {
X error(
X "Hey! An instantiation of Elm is already reading this mail!\n\r");
X fprintf(stderr,
X"\n\r [if this is in error then you'll need to remove '%s%s']\n\r",
X temp_mbox, username);
X Raw(OFF);
X exit(1);
X }
X sprintf(infile, "%s%s", mailhome, username);
X }
X if (strlen(infile) == 0) /* no filename yet?? */
X sprintf(infile,"%s%s",mailhome, username);
X if ((errno = can_access(infile, READ_ACCESS))) {
X if (strncmp(infile, mailhome, strlen(mailhome)) == 0) {
X /* oh wow. incoming mailbox with no messages... */
X return(1);
X }
X error2("Can't open mailbox '%s' for reading [%s]", infile,
X error_name(errno));
X Raw(OFF);
X exit(1);
X }
X }
X else { /* get name of new mailbox! */
X MoveCursor(LINES-3, 30);
X CleartoEOS();
X PutLine0(LINES-3, 40, "(Use '?' to list your folders)");
X show_last_error();
Xask_again:
X buff[0] = '\0';
X if (iterations++ == 0) {
X PutLine0(LINES-2,0,"Name of new mailbox: ");
X (void) optionally_enter(buff, LINES-2, 21, FALSE);
X ClearLine(LINES-2);
X }
X else {
X printf("\n\rName of new mailbox: ");
X (void) optionally_enter(buff, -1, -1, FALSE);
X }
X if (strlen(buff) == 0) {
X if (resync && file_changed)
X strcpy(buff, infile);
X else
X return(redraw);
X }
X if (strcmp(buff, "?") == 0) {
X redraw = 1; /* we'll need to clean the screen */
X if (( old_raw = RawState()) == ON)
X Raw(OFF);
X list_folders();
X if (old_raw == ON)
X Raw(ON);
X goto ask_again;
X }
X if (strcmp(buff, "!") == 0 ||
X strcmp(buff, "%") == 0) /* go to mailbox */
X sprintf(buff,"%s%s", mailhome, username);
X else if (! expand_filename(buff)) {
X error1("can't expand file %s", buff);
X if (resync && file_changed)
X strcpy(buff, infile);
X else
X return(FALSE);
X }
X
X if (strcmp(buff, infile) == 0 && ! resync) {
X error("already reading that mailbox!");
X return(FALSE);
X }
X
X if ((errno = can_access(buff, READ_ACCESS))) {
X dprint(2, (debugfile,
X "Error: attempt to open %s as mailbox denied (%s)!\n",
X buff, "newmbox"));
X error1("Permission to open file %s denied", buff);
X if (resync && file_changed)
X strcpy(buff, infile);
X else
X return(FALSE);
X }
X
X if (first_word(buff, mailhome)) { /* a mail file! */
X mbox_specified = 0; /* fake program to think that */
X stat = 1; /* we're the default file */
X switching_to_default++; /* remember this act! */
X }
X
X if (resync && file_changed && strcmp(buff, infile) == 0)
X PutLine0(LINES-3,COLUMNS-40,"Resynchronizing file");
X else
X PutLine1(LINES-3,COLUMNS-40,"Mailbox: %s", buff);
X CleartoEOLN();
X strcpy(infile,buff);
X if (! switching_to_default) mbox_specified = 1;
X
X }
X
X if (stat == 3)
X switching_from_default = TRUE;
X
X if (switching_from_default) { /* we need to remove the tmp file */
X sprintf(buff, "%s%s", temp_mbox, username);
X if (access(buff, ACCESS_EXISTS) != -1) /* is it there at all? */
X if (unlink(buff) != 0) {
X error1(
X "Sorry, but I can't seem to unlink your temp mail file [%s]\n\r",
X error_name(errno));
X silently_exit();
X }
X }
X
X clear_error();
X clear_central_message();
X
X header_page = 0;
X
X if (mailfile != NULL)
X (void) fclose(mailfile); /* close it first, to avoid too many open */
X
X if ((mailfile = fopen(infile,"r")) == NULL)
X message_count = 0;
X else if (stat != 2) { /* new mail file! */
X current = 1;
X save_file_stats(infile);
X message_count = read_headers(FALSE, main_screen);
X if (! message_count) current = 0;
X }
X else { /* resync with current mail file */
X save_file_stats(infile);
X message_count = read_headers(TRUE, main_screen);
X }
X
X if (stat != 2)
X selected = 0; /* we don't preselect new mailboxes, boss! */
X
X return(TRUE);
X}
X
Xint
Xread_headers(rereading, main_screen)
Xint rereading, main_screen;
X{
X /** Reads the headers into the header_table structure and leaves
X the file rewound for further I/O requests. If the file being
X read is the default mailbox (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 'rereading' is set, the program will copy
X the status flags from the previous data structure to the new
X one if possible. This is (obviously) for re-reading a mailfile!
X **/
X
X FILE *temp;
X struct header_rec *temp_struct;
X char buffer[LONG_STRING], temp_filename[SLEN];
X long fbytes = 0L, line_bytes = 0L;
X register int line = 0, count = 0, subj = 0, copyit = 0, in_header = 1;
X int count_x, count_y = 17, new_messages = 0, err;
X int in_to_list = FALSE, forwarding_mail = FALSE, first_line = TRUE;
X
X static int first_read = 0;
X
X if (! first_read++) {
X ClearLine(LINES-1);
X ClearLine(LINES);
X if (rereading)
X PutLine2(LINES, 0, "Reading in %s, message: %d", infile,
X message_count);
X else
X PutLine1(LINES, 0, "Reading in %s, message: 0", infile);
X count_x = LINES;
X count_y = 22 + strlen(infile);
X }
X else {
X count_x = LINES-2;
X if (main_screen)
X PutLine0(LINES-2, 0, "Reading message: 0");
X else {
X PutLine0(LINES, 0, "\n");
X PutLine0(LINES, 0, "Reading message: 0");
X count_x = LINES;
X }
X }
X
X if (mbox_specified == 0) {
X lock(INCOMING); /* ensure no mail arrives while we do this! */
X sprintf(temp_filename,"%s%s",temp_mbox, username);
X if (! rereading) {
X if (access(temp_filename, 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 mailbox already exists??");
X sleep(2);
X error("Ahhhh.....I give up");
X silently_exit(); /* leave without tampering with it! */
X }
X if ((temp = fopen(temp_filename,"w")) == NULL) {
X err = errno;
X unlock(); /* remove lock file! */
X Raw(OFF);
X Write_to_screen(
X "\nCouldn't open file %s for use as temp mailbox;\n", 1,
X temp_filename);
X Write_to_screen("** %s - %s **\n", 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 temp_filename, error_name(err), "read_headers"));
X leave();
X }
X get_mailtime();
X copyit++;
X chown(temp_filename, userid, groupid);
X chmod(temp_filename, 0700); /* shut off file for other people! */
X }
X else {
X if ((temp = fopen(temp_filename,"a")) == NULL) {
X err = errno;
X unlock(); /* remove lock file! */
X Raw(OFF);
X Write_to_screen(
X "\nCouldn't reopen file %s for use as temp mailbox;\n", 1,
X temp_filename);
X Write_to_screen("** %s - %s **\n", 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 temp_filename, error_name(err), "read_headers"));
X emergency_exit();
X }
X copyit++;
X }
X }
X
X if (rereading) {
X if (fseek(mailfile, mailfile_size, 0) == -1) {
X err = errno;
X Write_to_screen(
X "\nCouldn't seek to %ld (end of mailbox) in %s!\n", 2,
X mailfile_size, infile);
X Write_to_screen("** %s - %s **\n", 2,
X error_name(err), error_description(err));
X dprint(1, (debugfile,
X "Error: Couldn't seek to end of mailbox %s: (offset %ld) Errno %s (%s)\n",
X infile, 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 mailbox then unlock the file **/
X
X mailfile_size = bytes(infile);
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 (fbytes == 0L || first_line) { /* first line of file... */
X if (! mbox_specified) {
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 if (! first_word(buffer, "From ") && !forwarding_mail) {
X PutLine0(LINES, 0,
X "\n\rMail file 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 if (copyit) fputs(buffer, temp);
X line_bytes = (long) strlen(buffer);
X line++;
X if (first_word(buffer,"From ")) {
X
X /** try to allocate new headers, if needed... **/
X
X if (count >= max_headers) {
X max_headers += KLICK;
X if ((temp_struct = realloc(header_table, max_headers *
X sizeof(struct header_rec))) == NULL) {
X error1(
X "\n\r\n\rCouldn't allocate enough memory! Failed on message #%d\n\r\n\r",
X count);
X leave();
X }
X header_table = temp_struct;
X }
X
X if (real_from(buffer, &header_table[count])) {
X header_table[count].offset = (long) fbytes;
X header_table[count].index_number = count+1;
X if (! rereading || count >= message_count)
X header_table[count].status = VISIBLE; /* default status! */
X strcpy(header_table[count].subject, ""); /* clear subj */
X strcpy(header_table[count].to, ""); /* clear to */
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) && (!rereading || count > message_count))
X header_table[count-1].lines = line;
X if (new_msg(header_table[count])) {
X header_table[count].status |= NEW; /* new message! */
X
X if (! new_messages++ && point_to_new && ! rereading &&
X sortby == RECEIVED_DATE) {
X current = count+1;
X get_page(current); /* make sure we're ON that page! */
X }
X
X /* Quick comment on that last conditional test...
X
X We want to move the current pointer to the first new
X message IF this is the first of the new messages, the
X user requested this feature, we're not rereading the
X mailbox (imagine how THAT could screw the user up!),
X and we're not in some funky sorting mode (received-date is
X the default). As always, I'm open to suggestions on
X other ways to have this work intelligently.
X */
X
X }
X count++;
X subj = 0;
X line = 0;
X in_header = 1;
X PutLine1(count_x, count_y, "%d", count);
X }
X }
X else if (in_header) {
X if (first_word(buffer,">From:"))
X parse_arpa_from(buffer, header_table[count-1].from);
X else if (first_word(buffer,">From"))
X forwarded(buffer, &header_table[count-1]); /* 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(header_table[count-1].subject, buffer, STRING);
X remove_possible_trailing_spaces(header_table[count-1].subject);
X }
X }
X else if (first_word(buffer,"From:"))
X parse_arpa_from(buffer, header_table[count-1].from);
X
X else if (first_word(buffer, "Message-Id:") ||
X first_word(buffer, "Message-ID:")) {
X buffer[strlen(buffer)-1] = '\0';
X strcpy(header_table[count-1].messageid,
X (char *) buffer + 12);
X }
X
X else if (first_word(buffer, "Expires:"))
X process_expiration_date((char *) buffer + 9,
X &(header_table[count-1].status));
X
X /** when it was sent... **/
X
X else if (first_word(buffer, "Date:"))
X parse_arpa_date(buffer, &header_table[count-1]);
X
X /** some status things about the message... **/
X
X else if (first_word(buffer, "Priority:") ||
X first_word(buffer, "Importance: 2"))
X header_table[count-1].status |= URGENT;
X else if (first_word(buffer, "Sensitivity: 2"))
X header_table[count-1].status |= PRIVATE;
X else if (first_word(buffer, "Sensitivity: 3"))
X header_table[count-1].status |= CONFIDENTIAL;
X else if (first_word(buffer, "Content-Type: mailform"))
X header_table[count-1].status |= FORM_LETTER;
X else if (first_word(buffer, "Action:"))
X header_table[count-1].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 header_table[count-1].to[0] = '\0'; /* nothing yet */
X figure_out_addressee((char *) buffer +3,
X header_table[count-1].to);
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(&header_table[count-1]);
X }
X }
X else if (in_to_list == TRUE) {
X if (whitespace(buffer[0]))
X figure_out_addressee(buffer, header_table[count-1].to);
X else in_to_list = FALSE;
X }
X }
X fbytes += (long) line_bytes;
X }
X
X header_table[count > 0? count-1:count].lines = line + 1;
X if(count && ! current) current = 1;
X
X if (mbox_specified == 0) {
X unlock(); /* remove lock file! */
X fclose(mailfile);
X fclose(temp);
X if ((mailfile = fopen(temp_filename,"r")) == NULL) {
X err = errno;
X MoveCursor(LINES,0);
X Raw(OFF);
X Write_to_screen("\nAugh! Couldn't reopen %s as temp mail file;\n",
X 1, temp_filename);
X Write_to_screen("** %s - %s **\n", 2, error_name(err),
X error_description(err));
X dprint(1, (debugfile,
X "Error: Reopening %s as temp mail file failed! errno %s (%s)\n",
X temp_filename, error_name(errno), "read_headers"));
X leave();
X }
X }
X else
X rewind(mailfile);
X
X sort_mailbox(count, 1); /* let's sort this baby now! */
X
X return(count);
X}
SHAR_EOF
chmod 0444 src/newmbox.c || echo "restore of src/newmbox.c fails"
echo "x - extracting src/opt_utils.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/opt_utils.c &&
X
Xstatic char rcsid[] = "@(#)$Id: opt_utils.c,v 2.1.1.2 88/09/23 edc Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 2.1 $ $State: Exp $
X *
X * Copyright (c) 1986 Dave Taylor
X *******************************************************************************
X * Bug reports, patches, comments, suggetions should be sent to:
X *
X * Syd Weinstein, Elm Corrdinator
X * syd@dsinc.UUCP dsinc!syd
X *
X *******************************************************************************
X * $Log: opt_utils.c,v $
X * Revision 2.1 88/07/21 09:59:07 edc
X * checked in with -k by syd at 88.09.15.20.29.07.
X *
X * Revision 2.1 88/07/21 09:59:07 edc
X * Final hacks and cleanup to the 2.1 alpha test release.
X *
X * Revision 2.0 88/06/27 17:25:22 edc
X * The original 2.0 gamma sources as leaked from HP
X *
X *
X *
X ******************************************************************************/
X
X/** This file contains routines that might be needed for the various
X machines that the mailer can run on. Please check the Makefile
X for more help and/or information.
X
X**/
X
X#include <stdio.h>
X#include "headers.h"
X
X#ifdef BSD
X# include <pwd.h>
X#endif
X
X#ifdef NEED_GETHOSTNAME
X# include <sys/types.h>
X# include <sys/utsname.h>
X#endif
X
X#ifdef NEED_GETHOSTNAME
X
Xgethostname(hostname,size) /* get name of current host */
Xint size;
Xchar *hostname;
X{
X /** Return the name of the current host machine. **/
X
X /** This routine compliments of Scott McGregor at the HP
X Corporate Computing Center **/
X
X int uname();
X struct utsname name;
X
X (void) uname(&name);
X (void) strncpy(hostname,name.nodename,size-1);
X hostname[size - 1] = '\0';
X
X}
X
X#endif
X
X#ifdef NEED_CUSERID
X
Xchar *cuserid(uname)
X char *uname;
X{
X /** Added for compatibility with Bell systems, this is the last-ditch
X attempt to get the users login name, after getlogin() fails. It
X instantiates "uname" to the name of the user...(it also tries
X to use "getlogin" again, just for luck)
X **/
X /** This wasn't really compatible. According to our man page,
X ** It was inconsistent. If the parameter is NULL then you return
X ** the name in a static area. Else the ptr is supposed to be a
X ** pointer to l_cuserid bytes of memory [probally 9 bytes]...
X ** It's not mention what it should return if you copy the name
X ** into the array, so I chose NULL.
X ** Sept 20, 1988
X ** **WJL**
X **/
X
X struct passwd *password_entry, *getpwuid();
X char *name, *getlogin();
X static char buf[10];
X register returnonly = 0;
X
X if (uname == NULL) ++returnonly;
X
X if ((name = getlogin()) != NULL) {
X if (returnonly) {
X return(name);
X } else {
X strcpy(uname, name);
X return name;
X }
X }
X else
X if (( password_entry = getpwuid(getuid())) != NULL)
X {
X if (returnonly)
X {
X return(password_entry->pw_name);
X }
X else
X {
X strcpy(uname, password_entry->pw_name);
X return name;
X }
X }
X else
X {
X return NULL;
X }
X}
X
X#endif
X
X#ifdef BSD
X
X/** some supplementary string functions for Berkeley Unix systems **/
X
Xstrspn(source, keys)
Xchar *source, *keys;
X{
X /** This function returns the length of the substring of
X 'source' (starting at zero) that consists ENTIRELY of
X characters from 'keys'. This is used to skip over a
X defined set of characters with parsing, usually.
X **/
X
X register int loc = 0, key_index = 0;
X
X while (source[loc] != '\0') {
X key_index = 0;
X while (keys[key_index] != source[loc])
X if (keys[key_index++] == '\0')
X return(loc);
X loc++;
X }
X
X return(loc);
X}
X
Xstrcspn(source, keys)
Xchar *source, *keys;
X{
X /** This function returns the length of the substring of
X 'source' (starting at zero) that consists entirely of
X characters NOT from 'keys'. This is used to skip to a
X defined set of characters with parsing, usually.
X NOTE that this is the opposite of strspn() above
X **/
X
X register int loc = 0, key_index = 0;
X
X while (source[loc] != '\0') {
X key_index = 0;
X while (keys[key_index] != '\0')
X if (keys[key_index++] == source[loc])
X return(loc);
X loc++;
X }
X
X return(loc);
X}
X
Xchar *strtok(source, keys)
Xchar *source, *keys;
X{
X /** This function returns a pointer to the next word in source
X with the string considered broken up at the characters
X contained in 'keys'. Source should be a character pointer
X when this routine is first called, then NULL subsequently.
X When strtok has exhausted the source string, it will
X return NULL as the next word.
X
X WARNING: This routine will DESTROY the string pointed to
X by 'source' when first invoked. If you want to keep the
X string, make a copy before using this routine!!
X **/
X
X register int last_ch;
X static char *sourceptr;
X char *return_value;
X
X if (source != NULL)
X sourceptr = source;
X
X if (*sourceptr == '\0')
X return(NULL); /* we hit end-of-string last time!? */
X
X sourceptr += strspn(sourceptr, keys); /* skip leading crap */
X
X if (*sourceptr == '\0')
X return(NULL); /* we've hit end-of-string */
X
X last_ch = strcspn(sourceptr, keys); /* end of good stuff */
X
X return_value = sourceptr; /* and get the ret */
X
X sourceptr += last_ch; /* ...value */
X
X if (*sourceptr != '\0') /* don't forget if we're at END! */
X sourceptr++; /* and skipping for next time */
X
X return_value[last_ch] = '\0'; /* ..ending right */
X
X return((char *) return_value); /* and we're outta here! */
X}
X
Xchar *strpbrk(source, keys)
Xchar *source, *keys;
X{
X /** Returns a pointer to the first character of source that is any
X of the specified keys, or NULL if none of the keys are present
X in the source string.
X **/
X
X register int loc = 0, key_index = 0;
X
X while (source[loc] != '\0') {
X key_index = 0;
X while (keys[key_index] != '\0')
X if (keys[key_index++] == source[loc])
X return((char *) (source + loc));
X loc++;
X }
X
X return(NULL);
X}
X
Xchar *strchr(buffer, ch)
Xchar *buffer, ch;
X{
X /** Returns a pointer to the first occurance of the character
X 'ch' in the specified string or NULL if it doesn't occur **/
X
X char *address;
X
X address = buffer;
X
X while (*address != ch) {
X if (*address == '\0')
X return (NULL);
X address++;
X }
X
X return ( (char *) address);
X}
X
X#endif
SHAR_EOF
chmod 0444 src/opt_utils.c || echo "restore of src/opt_utils.c fails"
echo "x - extracting src/options.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/options.c &&
X
Xstatic char rcsid[] = "@(#)$Id: options.c,v 2.1 88/09/15 20:29:10 syd Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 2.1 $ $State: Exp $
X *
X * Copyright (c) 1986 Dave Taylor
X *******************************************************************************
X * Bug reports, patches, comments, suggetions should be sent to:
X *
X * Syd Weinstein, Elm Corrdinator
X * syd@dsinc.UUCP dsinc!syd
X *
X *******************************************************************************
X * $Log: options.c,v $
X * Revision 2.1 88/09/15 20:29:10 syd
X * checked in with -k by syd at 88.09.15.20.29.10.
X *
X * 88/08/27 ssw
X * add deluth patches
X *
X * 88/08/27 ssw
X * split tolower and ReadCh due to macro calls
X *
X * Revision 2.1 88/07/21 09:59:08 edc
X * Final hacks and cleanup to the 2.1 alpha test release.
X *
X * Revision 2.0 88/06/27 17:25:23 edc
X * The original 2.0 gamma sources as leaked from HP
X *
X *
X *
X ******************************************************************************/
X
X/** This set of routines allows the alteration of a number of paramaters
X in the Elm mailer, including the following;
X
X calendar-file <where to put calendar entries>
X display pager <how to page messages>
X editor <name of composition editor>
X folder-dir <folder directory>
X sort-by <how to sort mailboxes>
X savefile <file to save outbound message copies to>
X printmail <how to print messages>
X full_username <your full user name for outgoing mail>
X
X arrow-cursor <on or off>
X menu-display <on or off>
X
X user-level <BEGINNER|INTERMEDIATE|EXPERT>
X names-only <on or off>
X
X And others as they seem useful.
X
X**/
X
X#include "headers.h"
X
X#ifdef BSD
X#undef tolower
X#endif
X
X#undef onoff
X#define onoff(n) (n == 1? "ON ":"OFF")
X
Xchar *one_liner_for(), *level_name();
Xunsigned long sleep();
X
Xoptions()
X{
X /** change options... **/
X
X int ch;
X
X display_options();
X
X clearerr(stdin);
X
X do {
X ClearLine(LINES-4);
X
X Centerline(LINES-4,
X "Select first letter of Option line, '>' to Save, or R)eturn");
X
X PutLine0(LINES-2, 0, "Command: ");
X
X ch = ReadCh();
X ch = tolower(ch);
X
X clear_error(); /* remove possible "sorting" message etc... */
X
X one_liner(one_liner_for(ch));
X
X switch (ch) {
X case 'c' : optionally_enter(calendar_file, 2, 23, FALSE); break;
X case 'd' : optionally_enter(pager, 3, 23, FALSE);
X clear_pages = (equal(pager, "builtin+") ||
X equal(pager, "internal+")); break;
X case 'e' : optionally_enter(editor, 4, 23, FALSE); break;
X case 'f' : optionally_enter(folders, 5, 23, FALSE); break;
X case 's' : change_sort(6,23); break;
X case 'o' : optionally_enter(savefile, 7, 23, FALSE); break;
X case 'p' : optionally_enter(printout, 8, 23, FALSE); break;
X case 'y' : optionally_enter(full_username, 9, 23, FALSE); break;
X case 'a' : on_or_off(&arrow_cursor, 12, 23); break;
X case 'm' : on_or_off(&mini_menu, 13, 23);
X headers_per_page = LINES - (mini_menu ? 13 : 8); break;
X
X case 'u' : switch_user_level(&user_level,15, 23); break;
X case 'n' : on_or_off(&names_only, 16, 23); break;
X
X case '?' : options_help();
X PutLine0(LINES-2,0,"Command: "); break;
X
X case '>' : printf("Save options in .elm/elmrc...");
X fflush(stdout); save_options(); break;
X
X case 'x' :
X case 'r' :
X case ctrl('D'):
X case ctrl('M'):
X case ctrl('J'): return;
X case ctrl('L'): display_options(); break;
X default: error("Command unknown!");
X }
X
X } while (ch != 'r');
X}
X
Xdisplay_options()
X{
X /** Display all the available options.. **/
X
X char *sort_name();
X
X ClearScreen();
SHAR_EOF
echo "End of part 15"
echo "File src/options.c is continued in part 16"
echo "16" > s2_seq_.tmp
exit 0
--
=====================================================================
Sydney S. Weinstein, CDP, CCP Elm Coordinator
Datacomp Systems, Inc. Voice: (215) 947-9900
{allegra,bellcore,bpa,vu-vlsi}!dsinc!syd FAX: (215) 938-0235