syd@dsinc.UUCP (Syd Weinstein) (12/13/88)
---- Cut Here and unpack ----
#!/bin/sh
# this is part 16 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file src/options.c continued
#
CurArch=16
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/options.c"
sed 's/^X//' << 'SHAR_EOF' >> src/options.c
X Centerline(0,"-- Elm Options Editor --");
X
X#ifdef ENABLE_CALENDAR
X PutLine1(2, 0, "C)alendar file : %s", calendar_file);
X#endif
X PutLine1(3, 0, "D)isplay mail using : %s", pager);
X PutLine1(4, 0, "E)ditor : %s", editor);
X PutLine1(5, 0, "F)older directory : %s", folders);
X PutLine1(6, 0, "S)orting criteria : %s", sort_name(FULL));
X PutLine1(7, 0, "O)utbound mail saved : %s", savefile);
X PutLine1(8, 0, "P)rint mail using : %s", printout);
X PutLine1(9, 0, "Y)our full name : %s", full_username);
X
X PutLine1(12,0, "A)rrow cursor : %s", onoff(arrow_cursor));
X PutLine1(13,0, "M)enu display : %s", onoff(mini_menu));
X
X PutLine1(15,0, "U)ser level : %s", level_name(user_level));
X PutLine1(16,0, "N)ames only : %s", onoff(names_only));
X}
X
Xon_or_off(var, x, y)
Xint *var, x,y;
X{
X /** 'var' field at x.y toggles between on and off... **/
X
X char ch;
X
X PutLine0(x, y+6,
X "(use <space> to toggle, any other key to leave)");
X
X MoveCursor(x,y+3); /* at end of value... */
X
X do {
X ch = ReadCh();
X
X if (ch == SPACE) {
X *var = ! *var;
X PutLine0(x,y, onoff(*var));
X }
X } while (ch == SPACE);
X
X MoveCursor(x,y+4); CleartoEOLN(); /* remove help prompt */
X}
X
X
Xswitch_user_level(ulevel, x, y)
Xint *ulevel, x, y;
X{
X /** step through possible user levels... **/
X
X PutLine0(x, y+20, "<space> to change");
X
X MoveCursor(x,y); /* at end of value... */
X
X while (ReadCh() == ' ') {
X *ulevel = (*ulevel == 2? 0 : *ulevel + 1);
X PutLine1(x,y, "%s", level_name(*ulevel));
X }
X
X MoveCursor(x,y+20); CleartoEOLN(); /* remove help prompt */
X}
X
Xchange_sort(x, y)
Xint x,y;
X{
X /** change the sorting scheme... **/
X
X int last_sortby, /* so we know if it changes... */
X sign = 1; /* are we reverse sorting?? */
X int ch; /* character typed in ... */
X
X last_sortby = sortby; /* remember current ordering */
X
X PutLine0(x, COLUMNS-29, "(SPACE for next, or R)everse)");
X sort_one_liner(sortby);
X MoveCursor(x, y);
X
X do {
X ch = ReadCh();
X ch = tolower(ch);
X switch (ch) {
X case SPACE : if (sortby < 0) {
X sign = -1;
X sortby = - sortby;
X }
X else sign = 1; /* insurance! */
X sortby = sign * ((sortby + 1) % (STATUS+2));
X if (sortby == 0) sortby = sign; /* snicker */
X PutLine0(x, y, sort_name(PAD));
X sort_one_liner(sortby);
X MoveCursor(x, y);
X break;
X
X case 'r' : sortby = - sortby;
X PutLine0(x, y, sort_name(PAD));
X sort_one_liner(sortby);
X MoveCursor(x, y);
X }
X } while (ch == SPACE || ch == 'r');
X
X MoveCursor(x, COLUMNS-30); CleartoEOLN();
X
X if (sortby != last_sortby) {
X error("resorting mailbox...");
X sleep(1);
X sort_mailbox(message_count, 0);
X }
X ClearLine(LINES-2); /* clear sort_one_liner()! */
X}
X
Xone_liner(string)
Xchar *string;
X{
X /** A single-line description of the selected item... **/
X
X ClearLine(LINES-4);
X Centerline(LINES-4, string);
X}
X
Xsort_one_liner(sorting_by)
Xint sorting_by;
X{
X /** A one line summary of the particular sorting scheme... **/
X
X ClearLine(LINES-2);
X
X switch (sorting_by) {
X
X case -SENT_DATE : Centerline(LINES-2,
X"This sort will order most-recently-sent to least-recently-sent"); break;
X case -RECEIVED_DATE : Centerline(LINES-2,
X"This sort will order most-recently-received to least-recently-received");
X break;
X case -MAILBOX_ORDER : Centerline(LINES-2,
X"This sort will order most-recently-added-to-mailbox to least-recently");
X break;
X case -SENDER : Centerline(LINES-2,
X"This sort will order by sender name, in reverse alphabetical order"); break;
X case -SIZE : Centerline(LINES-2,
X"This sort will order messages by longest to shortest"); break;
X case -SUBJECT : Centerline(LINES-2,
X"This sort will order by subject, in reverse alphabetical order"); break;
X case -STATUS : Centerline(LINES-2,
X"This sort will order by reverse status - Deleted through Tagged..."); break;
X
X case SENT_DATE : Centerline(LINES-2,
X"This sort will order least-recently-sent to most-recently-sent"); break;
X case RECEIVED_DATE : Centerline(LINES-2,
X"This sort will order least-recently-received to most-recently-received");
X break;
X case MAILBOX_ORDER : Centerline(LINES-2,
X"This sort will order least-recently-added-to-mailbox to most-recently");
X break;
X case SENDER : Centerline(LINES-2,
X "This sort will order by sender name"); break;
X case SIZE : Centerline(LINES-2,
X "This sort will order messages by shortest to longest");
X break;
X case SUBJECT : Centerline(LINES-2,
X "This sort will order messages by subject"); break;
X case STATUS : Centerline(LINES-2,
X"This sort will order by status - Tagged through Deleted..."); break;
X }
X}
X
Xchar *one_liner_for(c)
Xchar c;
X{
X /** returns the one-line description of the command char... **/
X
X switch (c) {
X case 'c' : return(
X"This is the file where calendar entries from messages are saved.");
X
X case 'd' : return(
X"This is the program invoked to display individual messages (try 'builtin')");
X
X case 'e' : return(
X"This is the editor that will be used for sending messages, etc.");
X
X case 'f' : return(
X"This is the folders directory used when '=' (etc) is used in filenames");
X
X case 'm' : return(
X"This determines if you have the mini-menu displayed or not");
X
X case 'n' : return(
X"Whether to display the names and addresses on mail, or names only");
X case 'o' : return(
X"This is where copies of outbound messages are saved automatically.");
X
X case 'p' : return(
X"This is how printouts are generated. \"%s\" will be replaced by the filename.");
X
X case 's' : return(
X"This is used to specify the sorting criteria for the mailboxes");
X
X case 'y' : return(
X"When mail is sent out, this is what your full name will be recorded as.");
X
X case 'a' : return(
X"This defines whether the ELM cursor is an arrow or a highlight bar.");
X
X case 'u' : return(
X"The level of knowledge you have about the Elm mail system.");
X
X default : return(""); /* nothing if we don't know! */
X }
X}
X
Xoptions_help()
X{
X /** help menu for the options screen... **/
X
X char c, *ptr;
X
X Centerline(LINES-3,
X "Enter the key you want help on, '?' for a list, or '.' to exit help");
X
X lower_prompt("Key : ");
X
X while ((c = ReadCh()) != '.') {
X c = tolower(c);
X if (c == '?') {
X display_helpfile(OPTIONS_HELP);
X display_options();
X return;
X }
X if ((ptr = one_liner_for(c)) != NULL)
X error2("%c = %s", c, ptr);
X else
X error1("%c isn't used in this section", c);
X lower_prompt("Key : ");
X }
X}
X
Xchar *level_name(n)
Xint n;
X{
X /** return the 'name' of the level... **/
X
X switch (n) {
X case 0 : return("Beginning User ");
X case 1 : return("Intermediate User");
X default: return("Expert User ");
X }
X}
SHAR_EOF
echo "File src/options.c is complete"
chmod 0444 src/options.c || echo "restore of src/options.c fails"
echo "x - extracting src/out_utils.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/out_utils.c &&
X
Xstatic char rcsid[] = "@(#)$Id: out_utils.c,v 2.1 88/07/21 09:59:11 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: out_utils.c,v $
X * Revision 2.1 88/07/21 09:59:11 edc
X * checked in with -k by syd at 88.09.15.20.29.12.
X *
X * Revision 2.1 88/07/21 09:59:11 edc
X * Final hacks and cleanup to the 2.1 alpha test release.
X *
X * Revision 2.0 88/06/27 17:25:24 edc
X * The original 2.0 gamma sources as leaked from HP
X *
X *
X *
X ******************************************************************************/
X
X/** This file contains routines used for output in the ELM program.
X
X**/
X
X#include "headers.h"
X
X
Xstatic char err_buffer[SLEN]; /* store last error message */
X
Xstatic char central_message_buffer[SLEN];
X
Xchar *strcpy();
X
Xshow_last_error()
X{
X /** rewrite last error message! **/
X
X error(err_buffer);
X}
X
Xclear_error()
X{
X MoveCursor(LINES,0);
X CleartoEOLN();
X err_buffer[0] = '\0';
X}
X
Xset_error(s)
Xchar *s;
X{
X strcpy(err_buffer, s);
X}
X
Xerror(s)
Xchar *s;
X{
X /** outputs error 's' to screen at line 22, centered! **/
X
X MoveCursor(LINES,0);
X CleartoEOLN();
X PutLine0(LINES,(COLUMNS-strlen(s))/2,s);
X fflush(stdout);
X strcpy(err_buffer, s); /* save it too! */
X}
X
X/*VARARGS1*/
X
Xerror1(s, a)
Xchar *s, *a;
X{
X /** same as error, but with a 'printf' argument **/
X char buffer[SLEN];
X
X sprintf(buffer,s,a);
X error(buffer);
X}
X
X/*VARARGS1*/
X
Xerror2(s, a1, a2)
Xchar *s, *a1, *a2;
X{
X /** same as error, but with two 'printf' arguments **/
X char buffer[SLEN];
X
X sprintf(buffer,s, a1, a2);
X error(buffer);
X}
X
X/*VARARGS1*/
X
Xerror3(s, a1, a2, a3)
Xchar *s, *a1, *a2, *a3;
X{
X /** same as error, but with three 'printf' arguments **/
X char buffer[SLEN];
X
X sprintf(buffer,s, a1, a2, a3);
X error(buffer);
X}
X
Xlower_prompt(s)
Xchar *s;
X{
X /** prompt user for input on LINES-1 line, left justified **/
X
X PutLine0(LINES-1,0,s);
X CleartoEOLN();
X}
X
Xprompt(s)
Xchar *s;
X{
X /** prompt user for input on LINES-3 line, left justified **/
X
X PutLine0(LINES-3,0,s);
X CleartoEOLN();
X}
X
X
Xset_central_message(string, arg)
Xchar *string, *arg;
X{
X /** set up the given message to be displayed in the center of
X the current window **/
X
X sprintf(central_message_buffer, string, arg);
X}
X
Xdisplay_central_message()
X{
X /** display the message if set... **/
X
X if (central_message_buffer[0] != '\0') {
X ClearLine(LINES-15);
X Centerline(LINES-15, central_message_buffer);
X fflush(stdout);
X }
X}
X
Xclear_central_message()
X{
X /** clear the central message buffer **/
X
X central_message_buffer[0] = '\0';
X}
SHAR_EOF
chmod 0444 src/out_utils.c || echo "restore of src/out_utils.c fails"
echo "x - extracting src/pattern.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/pattern.c &&
X
Xstatic char rcsid[] = "@(#)$Id: pattern.c,v 2.1 88/09/15 20:29:15 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: pattern.c,v $
X * Revision 2.1 88/09/15 20:29:15 syd
X * checked in with -k by syd at 88.09.15.20.29.15.
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:12 edc
X * Final hacks and cleanup to the 2.1 alpha test release.
X *
X * Revision 2.0 88/06/27 17:25:24 edc
X * The original 2.0 gamma sources as leaked from HP
X *
X *
X *
X ******************************************************************************/
X
X/** General pattern matching for the ELM mailer.
X
X**/
X
X#include <errno.h>
X
X#include "headers.h"
X
Xstatic char pattern[SLEN] = { "" };
Xstatic char alt_pattern[SLEN] = { "" };
X
Xextern int errno;
X
Xchar *error_name(), *shift_lower(), *strcpy();
X
Xmeta_match(function)
Xint function;
X{
X char ch;
X
X /** Perform specific function based on whether an entered string
X matches either the From or Subject lines..
X **/
X
X register int i, tagged=0, count=0;
X static char meta_pattern[SLEN];
X
X PutLine1(LINES-3, strlen("Command: "),
X "%s messages that match pattern...",
X function==TAGGED?"Tag": function==DELETED?"Delete":"Undelete");
X
X if (function == TAGGED) { /* are messages already tagged??? */
X for (i=0; i < message_count; i++)
X if (ison(header_table[i].status,TAGGED))
X tagged++;
X
X if (tagged) {
X if (tagged > 2)
X PutLine0(LINES-2,0, "Some messages are already tagged");
X else
X PutLine0(LINES-2,0, "A message is already tagged");
X
X Write_to_screen("- Remove tag%s? y%c", 2, plural(tagged),BACKSPACE);
X
X ch = ReadCh();
X if (tolower(ch) != 'n') { /* remove tags... */
X for (i=0; i < message_count; i++) {
X clearit(header_table[i].status,TAGGED);
X show_new_status(i);
X }
X }
X }
X }
X
X PutLine0(LINES-2,0, "Enter pattern: "); CleartoEOLN();
X
X optionally_enter(meta_pattern, LINES-2,strlen("Enter pattern: "),FALSE);
X
X if (strlen(meta_pattern) == 0) {
X ClearLine(LINES-2);
X return(0);
X }
X
X strcpy(meta_pattern, shift_lower(meta_pattern)); /* lowercase it */
X
X for (i = 0; i < message_count; i++) {
X if (from_matches(i, meta_pattern)) {
X if ((selected && header_table[i].status & VISIBLE) || ! selected) {
X if (function == UNDELETE)
X clearit(header_table[i].status, DELETED);
X else
X setit(header_table[i].status, function);
X show_new_status(i);
X count++;
X }
X }
X else if (subject_matches(i, meta_pattern)) {
X if ((selected && header_table[i].status & VISIBLE) || ! selected) {
X if (function == UNDELETE)
X clearit(header_table[i].status, DELETED);
X else
X setit(header_table[i].status, function);
X show_new_status(i);
X count++;
X }
X }
X }
X
X ClearLine(LINES-2); /* remove "pattern: " prompt */
X
X if (count > 0)
X error3("%s %d messsage%s",
X function==TAGGED? "tagged" :
X function==DELETED? "marked for deletion" : "undeleted",
X count, plural(count));
X else
X error1("no matches - no messages %s",
X function==TAGGED? "tagged" :
X function==DELETED? "marked for deletion": "undeleted");
X
X return(0);
X}
X
Xint
Xpattern_match()
X{
X /** Get a pattern from the user and try to match it with the
X from/subject lines being displayed. If matched (ignoring
X case), move current message pointer to that message, if
X not, error and return ZERO **/
X
X register int i;
X
X PutLine0(LINES-3,40,"/ = match anywhere in messages");
X
X PutLine0(LINES-1,0, "Match Pattern:");
X
X if (pattern_enter(pattern, alt_pattern, LINES-1, 16,
X "Match Pattern (in entire mailbox):"))
X if (strlen(alt_pattern) > 0) {
X strcpy(alt_pattern, shift_lower(alt_pattern));
X return(match_in_message(alt_pattern));
X }
X else
X return(1);
X
X if (strlen(pattern) == 0)
X return(0);
X else
X strcpy(pattern, shift_lower(pattern));
X
X for (i = current; i < message_count; i++) {
X if (from_matches(i, pattern)) {
X if (!selected || (selected && header_table[i].status & VISIBLE)) {
X current = ++i;
X return(1);
X }
X }
X else if (subject_matches(i, pattern)) {
X if (!selected || (selected && header_table[i].status & VISIBLE)) {
X current = ++i;
X return(1);
X }
X }
X }
X
X return(0);
X}
X
Xint
Xfrom_matches(message_number, pat)
Xint message_number;
Xchar *pat;
X{
X /** Returns true iff the pattern occurs in it's entirety
X in the from line of the indicated message **/
X
X return( in_string(shift_lower(header_table[message_number].from),
X pat) );
X}
X
Xint
Xsubject_matches(message_number, pat)
Xint message_number;
Xchar *pat;
X{
X /** Returns true iff the pattern occurs in it's entirety
X in the subject line of the indicated message **/
X
X return( in_string(shift_lower(header_table[message_number].subject),
X pat) );
X}
X
Xmatch_in_message(pat)
Xchar *pat;
X{
X /** Match a string INSIDE a message...starting at the current
X message read each line and try to find the pattern. As
X soon as we do, set current and leave!
X Returns 1 if found, 0 if not
X **/
X
X char buffer[LONG_STRING];
X int message_number, lines, line;
X
X message_number = current-1;
X
X error("searching mailbox for pattern...");
X
X while (message_number < message_count) {
X
X if (fseek(mailfile, header_table[message_number].offset, 0L) == -1) {
X
X dprint(1, (debugfile,
X "Error: seek %ld bytes into file failed. errno %d (%s)\n",
X header_table[message_number].offset, errno,
X "match_in_message"));
X error2("ELM [match] failed looking %ld bytes into file (%s)",
X header_table[message_number].offset, error_name(errno));
X return(1); /* fake it out to avoid replacing error message */
X }
X
X line = 0;
X lines = header_table[message_number].lines;
X
X while (fgets(buffer, LONG_STRING, mailfile) != NULL && line < lines) {
X
X line++;
X
X if (in_string(shift_lower(buffer), pat)) {
X current = message_number+1;
X clear_error();
X return(1);
X }
X }
X
X /** now we've passed the end of THIS message...increment and
X continue the search with the next message! **/
X
X message_number++;
X }
X
X return(0);
X}
SHAR_EOF
chmod 0444 src/pattern.c || echo "restore of src/pattern.c fails"
echo "x - extracting src/pmalloc.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/pmalloc.c &&
X
Xstatic char rcsid[] = "@(#)$Id: pmalloc.c,v 2.1 88/07/21 09:59:13 edc Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 2.1 $ $State: Exp $
X *
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: pmalloc.c,v $
X * Revision 2.1 88/07/21 09:59:13 edc
X * checked in with -k by syd at 88.09.15.20.29.17.
X *
X * Revision 2.1 88/07/21 09:59:13 edc
X * Final hacks and cleanup to the 2.1 alpha test release.
X *
X * Revision 2.0 88/06/27 17:25:25 edc
X * The original 2.0 gamma sources as leaked from HP
X *
X *
X *
X ******************************************************************************/
X
X/** This routine contains a cheap permanent version of the malloc call to
X speed up the initial allocation of the weedout headers and the uuname
X data.
X
X This routine is originally from Jim Davis of HP Labs, with some
X mods by me.
X**/
X
X#include <stdio.h>
X#include "defs.h"
X
X/*VARARGS0*/
X
Xchar *pmalloc(size)
Xint size;
X{
X /** return the address of a specified block **/
X
X static char *our_block = NULL;
X static int free_mem = 0;
X
X char *return_value, *malloc();
X
X /** if bigger than our threshold, just do the real thing! **/
X
X if (size > PMALLOC_THRESHOLD)
X return(malloc(size));
X
X /** if bigger than available space, get more, tossing what's left **/
X
X if (size > free_mem) {
X if ((our_block = malloc(PMALLOC_BUFFER_SIZE)) == NULL) {
X fprintf(stderr, "\n\r\n\rCouldn't malloc %d bytes!!\n\r\n\r",
X PMALLOC_BUFFER_SIZE);
X leave();
X }
X our_block += 4; /* just for safety, don't give back true address */
X free_mem = PMALLOC_BUFFER_SIZE-4;
X }
X
X return_value = our_block; /* get the memory */
X size = ((size+3)/4)*4; /* Go to quad byte boundary */
X our_block += size; /* use it up */
X free_mem -= size; /* and decrement */
X
X return( (char *) return_value);
X}
SHAR_EOF
chmod 0444 src/pmalloc.c || echo "restore of src/pmalloc.c fails"
echo "x - extracting src/quit.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/quit.c &&
X
Xstatic char rcsid[] = "@(#)$Id: quit.c,v 2.1 88/07/21 09:59:15 edc Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 2.1 $ $State: Exp $
X *
X * Copyright (c) 1985 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: quit.c,v $
X * Revision 2.1 88/07/21 09:59:15 edc
X * checked in with -k by syd at 88.09.15.20.29.19.
X *
X * Revision 2.1 88/07/21 09:59:15 edc
X * Final hacks and cleanup to the 2.1 alpha test release.
X *
X * Revision 2.0 88/06/27 17:25:26 edc
X * The original 2.0 gamma sources as leaked from HP
X *
X *
X *
X ******************************************************************************/
X
X/** quit: leave the current mailbox and quit the program.
X
X**/
X
X#include "headers.h"
X
Xlong bytes();
X
Xquit()
X{
X /* a wonderfully short routine!! */
X
X if (leave_mbox(1) == -1)
X return; /* new mail! (damn it) resync */
X
X leave();
X}
X
Xresync()
X{
X /** Resync on the current mailbox... This is simple: simply call
X 'newmbox' to read the file in again, set the size (to avoid
X confusion in the main loop) and refresh the screen!
X **/
X
X if (leave_mbox(0) ==-1) /* new mail...can't resync yet! */
X return;
X
X newmbox(3, TRUE, TRUE);
X mailfile_size = bytes(infile);
X showscreen();
X}
SHAR_EOF
chmod 0444 src/quit.c || echo "restore of src/quit.c fails"
echo "x - extracting src/read_rc.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/read_rc.c &&
X
Xstatic char rcsid[] = "@(#)$Id: read_rc.c,v 2.1 88/09/15 20:29: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: read_rc.c,v $
X * Revision 2.1 88/09/15 20:29:23 syd
X * checked in with -k by syd at 88.09.15.20.29.23.
X *
X * 88/09/13 Rob Bernardo <gatech!pbhyf.PacBell.COM!rob>
X * fixes problem in converting the old style elm alias and elmrc files
X * to the new style. The user's input to the prompt is now displayed
X * along with an English sentence indicating whether such action is
X * about to occur.
X *
X * 88/09/01 Rob Bernardo <gatech!pbhyf.PacBell.COM!rob>
X * Resend: exiting in cooked mode fix
X *
X * Revision 2.1 88/07/21 09:59:16 edc
X * Final hacks and cleanup to the 2.1 alpha test release.
X *
X * Revision 2.0 88/06/27 17:25:27 edc
X * The original 2.0 gamma sources as leaked from HP
X *
X *
X *
X ******************************************************************************/
X
X/** This file contains programs to allow the user to have a .elm/elmrc file
X in their home directory containing any of the following:
X
X fullname= <username string>
X maildir = <directory>
X mailbox = <file>
X editor = <editor>
X savemail= <savefile>
X calendar= <calendar file name>
X shell = <shell>
X print = <print command>
X weedout = <list of headers to weed out>
X prefix = <copied message prefix string>
X pager = <command to use for displaying messages>
X
X escape = <single character escape, default = '~' >
X
X--
X signature = <.signature file for all outbound mail>
XOR:
X localsignature = <.signature file for local mail>
X remotesignature = <.signature file for non-local mail>
X--
X
X bounceback= <hop count threshold, or zero to disable>
X timeout = <seconds for main menu timeout or zero to disable>
X userlevel = <0=amateur, 1=okay, 2 or greater = expert!>
X
X sortby = <sent, received, from, size, subject, mailbox>
X
X alternatives = <list of addresses that forward to us>
X
X and/or the logical arguments:
X
X autocopy [on|off]
X askcc [on|off]
X copy [on|off]
X resolve [on|off]
X weed [on|off]
X noheader [on|off]
X titles [on|off]
X savebyname [on|off]
X movepage [on|off]
X pointnew [on|off]
X hpkeypad [on|off]
X hpsoftkeys [on|off]
X alwaysleave [on|off]
X alwaysdel [on|off]
X arrow [on|off]
X menus [on|off]
X forms [on|off]
X warnings [on|off]
X names [on|off]
X ask [on|off]
X keepempty [on|off]
X
X
X Lines starting with '#' are considered comments and are not checked
X any further!
X
X Modified 10/85 to know about "Environment" variables..
X Modified 12/85 for the 'prefix' option
X Modified 2/86 for the new 3.3 flags
X Modified 8/86 (was I supposed to be keeping this up to date?)
X**/
X
X#include <stdio.h>
X#include <ctype.h>
X
X#ifdef BSD
X#undef tolower
X#endif
X
X#include "headers.h"
X
Xextern char *pmalloc();
Xchar *shift_lower(), *strtok(), *getenv(), *strcpy();
Xvoid exit();
X
X#define NOTWEEDOUT 0
X#define WEEDOUT 1
X#define ALTERNATIVES 2
X
Xread_rc_file()
X{
X /** this routine does all the actual work of reading in the
X .rc file... **/
X
X FILE *file;
X char buffer[SLEN], filename[SLEN];
X char word1[SLEN], word2[SLEN];
X register int i, errors = 0,
X last = NOTWEEDOUT, lineno = 0, ch;
X
X sprintf(filename,"%s/%s", home, elmrcfile);
X
X default_weedlist();
X
X alternative_addresses = NULL; /* none yet! */
X
Xtop_of_this_routine:
X
X if ((file = fopen(filename, "r")) == NULL) {
X dprint(2, (debugfile,
X "Warning: User has no \".elm/elmrc\" file\n\n"));
X /** look for old-style .elmrc file too: in $HOME **/
X sprintf(filename, "%s/.elmrc", home);
X if (access(filename, 00) != -1) {
X printf("\n\rWarning:\n\r");
X printf(
X"All the Elm 'dot' files are expected to have been moved into their own\n\r");
X printf(
X"directory -- $HOME/.elm -- by now. Would you like me to move them all\n\r");
X printf(
X"for you [if you choose not to, the files will be ignored] (y/n) ? n%c",
X BACKSPACE);
X fflush(stdout);
X ch=getchar();
X if (ch == 'y' || ch == 'Y') {
X putchar((int)'y');
X printf("\n\rVery well, I'll move them.\n\r");
X move_old_files_to_new();
X goto top_of_this_routine;
X }
X printf("\n\rVery well, I won't move them.\n\r");
X sleep(3);
X }
X return; /* we're done with this bit, at least! */
X }
X
X while (fgets(buffer, SLEN, file) != NULL) {
X lineno++;
X no_ret(buffer); /* remove return */
X if (buffer[0] == '#') { /* comment */
X last = NOTWEEDOUT;
X continue;
X }
X if (strlen(buffer) < 2) { /* empty line */
X last = NOTWEEDOUT;
X continue;
X }
X
X breakup(buffer, word1, word2, FALSE);
X
X strcpy(word1, shift_lower(word1)); /* to lower case */
X
X if (word2[0] == 0 && (last != WEEDOUT || last != ALTERNATIVES)) {
X dprint(2, (debugfile,
X "Error: Bad .elm/elmrc entry in users file;\n-> \"%s\"\n",
X buffer));
X fprintf(stderr,
X "Line %d of your \".elm/elmrc\" is badly formed:\n> %s\n",
X lineno, buffer);
X errors++;
X continue;
X }
X
X if (equal(word1,"maildir") || equal(word1,"folders")) {
X expand_env(folders, word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "fullname") || equal(word1,"username") ||
X equal(word1, "name")) {
X strcpy(full_username, word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "prefix")) {
X for (i=0; i < strlen(word2); i++)
X prefixchars[i] = (word2[i] == '_' ? ' ' : word2[i]);
X prefixchars[i] = '\0';
X
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "shell")) {
X expand_env(shell, word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "sort") || equal(word1, "sortby")) {
X strcpy(word2, shift_lower(word2));
X if (equal(word2, "sent"))
X sortby = SENT_DATE;
X else if (equal(word2, "received") || equal(word2,"recieved"))
X sortby = RECEIVED_DATE;
X else if (equal(word2, "from") || equal(word2, "sender"))
X sortby = SENDER;
X else if (equal(word2, "size") || equal(word2, "lines"))
X sortby = SIZE;
X else if (equal(word2, "subject"))
X sortby = SUBJECT;
X else if (equal(word2, "mailbox") || equal(word2, "folder"))
X sortby = MAILBOX_ORDER;
X else if (equal(word2, "reverse-sent") || equal(word2,"rev-sent"))
X sortby = - SENT_DATE;
X else if (strncmp(word2, "reverse-rec",11) == 0 ||
X strncmp(word2,"rev-rec",7) == 0)
X sortby = - RECEIVED_DATE;
X else if (equal(word2, "reverse-from") || equal(word2, "rev-from")
X || equal(word2,"reverse-sender")|| equal(word2,"rev-sender"))
X sortby = - SENDER;
X else if (equal(word2, "reverse-size") || equal(word2, "rev-size")
X || equal(word2, "reverse-lines")|| equal(word2,"rev-lines"))
X sortby = - SIZE;
X else if (equal(word2, "reverse-subject") ||
X equal(word2, "rev-subject"))
X sortby = - SUBJECT;
X else if (equal(word2, "reverse-mailbox") ||
X equal(word2, "rev-mailbox") ||
X equal(word2, "reverse-folder") ||
X equal(word2, "rev-folder"))
X sortby = - MAILBOX_ORDER;
X else {
X if (! errors)
X printf("Error reading '.elm/elmrc' file;\n");
X printf("Line %d: Don't know what sort key '%s' specifies!\n",
X lineno, word2);
X errors++;
X continue;
X }
X }
X else if (equal(word1, "mailbox")) {
X expand_env(mailbox, word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "editor") || equal(word1,"mailedit")) {
X expand_env(editor, word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "savemail") || equal(word1, "saveto")) {
X expand_env(savefile, word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "calendar")) {
X expand_env(calendar_file, word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "print") || equal(word1, "printmail")) {
X expand_env(printout, word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "pager") || equal(word1, "page")) {
X expand_env(pager, word2);
X if (equal(pager,"builtin+") || equal(pager,"internal+"))
X clear_pages++;
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "signature")) {
X if (equal(shift_lower(word2), "on") ||
X equal(shift_lower(word2), "off")) {
X fprintf(stderr,
X "\"signature\" used in obsolete way in .elm/elmrc file - ignored!\n\r");
X fprintf(stderr,
X "\t(signature should specify the filename to use rather than on/off)\n\r\n");
X }
X else {
X expand_env(local_signature, word2);
X strcpy(remote_signature, local_signature);
X signature = TRUE;
X }
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "localsignature")) {
X expand_env(local_signature, word2);
X signature = TRUE;
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "remotesignature")) {
X expand_env(remote_signature, word2);
X signature = TRUE;
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "escape")) {
X escape_char = word2[0];
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "autocopy")) {
X auto_copy = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "copy") || equal(word1, "auto_cc")) {
X auto_cc = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "names")) {
X names_only = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "resolve")) {
X resolve_mode = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "weed")) {
X filter = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "noheader")) {
X noheader = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "titles")) {
X title_messages = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "savebyname") || equal(word1, "savename")) {
X save_by_name = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "movepage") || equal(word1, "page") ||
X equal(word1, "movewhenpaged")) {
X move_when_paged = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "pointnew") || equal(word1, "pointtonew")) {
X point_to_new = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "keypad") || equal(word1, "hpkeypad")) {
X hp_terminal = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "softkeys") || equal(word1, "hpsoftkeys")) {
X if (hp_softkeys = is_it_on(word2))
X hp_terminal = TRUE; /* must be set also! */
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "arrow")) {
X arrow_cursor = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (strncmp(word1, "form", 4) == 0) {
X allow_forms = (is_it_on(word2)? MAYBE : NO);
X last = NOTWEEDOUT;
X }
X else if (strncmp(word1, "menu", 4) == 0) {
X mini_menu = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (strncmp(word1, "warning", 7) == 0) {
X warnings = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "alwaysleave") || equal(word1, "leave")) {
X always_leave = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "alwaysdelete") || equal(word1, "delete")) {
X always_del = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "askcc") || equal(word1, "cc")) {
X prompt_for_cc = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "ask") || equal(word1, "question")) {
X question_me = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "keep") || equal(word1, "keepempty")) {
X keep_empty_files = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "bounce") || equal(word1, "bounceback")) {
X bounceback = atoi(word2);
X if (bounceback > MAX_HOPS) {
X fprintf(stderr,
X "Warning: bounceback is set to greater than %d (max-hops) - Ignored.\n",
X MAX_HOPS);
X bounceback = 0;
X }
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "userlevel")) {
X user_level = atoi(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "timeout")) {
X timeout = atoi(word2);
X if (timeout < 10) {
X fprintf(stderr,
X "Warning: timeout is set to less than 10 seconds - Ignored.\n");
X timeout = 0;
X }
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "weedout")) {
X weedout(word2);
X last = WEEDOUT;
X }
X else if (equal(word1, "alternatives")) {
X alternatives(word2);
X last = ALTERNATIVES;
X }
X else if (last == WEEDOUT) /* could be multiple line weedout */
X weedout(buffer);
X else if (last == ALTERNATIVES) /* multi-line addresses */
X alternatives(buffer);
X else {
X fprintf(stderr,
X "I can't understand line %d in your \".elm/elmrc\" file:\n> %s\n",
X lineno, buffer);
X /* no error flagged -- let use continue, ok? */
X sleep(2);
X }
X }
X
X if (debug > 10) /** only do this if we REALLY want debug! **/
X dump_rc_results();
X
X if (errors) {
X Raw(OFF);
X exit(errors);
X }
X}
X
Xweedout(string)
Xchar *string;
X{
X /** This routine is called with a list of headers to weed out. **/
X
X char *strptr, *header;
X register int i;
X
X strptr = string;
X
X while ((header = strtok(strptr, "\t ,\"'")) != NULL) {
X if (strlen(header) > 0) {
X if (! strcmp(header, "*end-of-user-headers*")) break;
X if (weedcount > MAX_IN_WEEDLIST) {
X fprintf(stderr, "Too many weed headers! Leaving...\n");
X exit(1);
X }
X if ((weedlist[weedcount] = pmalloc(strlen(header) + 1))
X == NULL) {
X fprintf(stderr,
X "Too many weed headers - out of memory! Leaving...\n");
X exit(1);
X }
X
X for (i=0; i< strlen(header); i++)
X if (header[i] == '_') header[i] = ' ';
X
X strcpy(weedlist[weedcount], header);
X weedcount++;
X }
X strptr = NULL;
X }
X}
X
Xalternatives(string)
Xchar *string;
X{
X /** This routine is called with a list of alternative addresses
X that you may receive mail from (forwarded) **/
X
X char *strptr, *address;
X struct addr_rec *current_record, *previous_record;
X
X previous_record = alternative_addresses; /* start 'er up! */
X /* move to the END of the alternative addresses list */
X
X if (previous_record != NULL)
X while (previous_record->next != NULL)
X previous_record = previous_record->next;
X
X strptr = (char *) string;
X
X while ((address = strtok(strptr, "\t ,\"'")) != NULL) {
X if (previous_record == NULL) {
X previous_record = (struct addr_rec *) pmalloc(sizeof
X *alternative_addresses);
X
X strcpy(previous_record->address, address);
X previous_record->next = NULL;
X alternative_addresses = previous_record;
X }
X else {
X current_record = (struct addr_rec *) pmalloc(sizeof
X *alternative_addresses);
X
X strcpy(current_record->address, address);
X current_record->next = NULL;
X previous_record->next = current_record;
X previous_record = current_record;
X }
X strptr = (char *) NULL;
X }
X}
X
Xdefault_weedlist()
X{
X /** Install the default headers to weed out! Many gracious
X thanks to John Lebovitz for this dynamic method of
X allocation!
X **/
X
X static char *default_list[] = { ">From", "In-Reply-To:",
X "References:", "Newsgroups:", "Received:",
X "Apparently-To:", "Message-Id:", "Content-Type:",
X "From", "X-Mailer:", "*end-of-defaults*", NULL
X };
X
X for (weedcount = 0; default_list[weedcount] != (char *) 0;weedcount++){
X if ((weedlist[weedcount] =
X pmalloc(strlen(default_list[weedcount]) + 1)) == NULL) {
X fprintf(stderr,
X "\n\rNot enough memory for default weedlist. Leaving.\n\r");
X leave(1);
X }
X strcpy(weedlist[weedcount], default_list[weedcount]);
X }
X}
X
Xint
Xmatches_weedlist(buffer)
Xchar *buffer;
X{
X /** returns true iff the first 'n' characters of 'buffer'
X match an entry of the weedlist **/
X
X register int i;
X
X for (i=0;i < weedcount; i++)
X if (strncmp(buffer, weedlist[i], strlen(weedlist[i])) == 0)
X return(1);
X
X return(0);
X}
X
Xbreakup(buffer, word1, word2, no_multiword_values)
Xchar *buffer, *word1, *word2;
Xint no_multiword_values;
X{
X /** This routine breaks buffer down into word1, word2 where
X word1 is alpha characters only, and there is an equal
X sign delimiting the two...
X alpha = beta
X For lines with more than one 'rhs', word2 is set to the
X entire string...(if no_multiword_values, however, word2
X will end at the first whitespace encountered)
X **/
X
X register int i;
X
X for (i=0;buffer[i] != '\0' && ok_char(buffer[i]); i++)
X if (buffer[i] == '_')
X word1[i] = '-';
X else if (isupper(buffer[i]))
X word1[i] = tolower(buffer[i]);
X else
X word1[i] = buffer[i];
X
X word1[i++] = '\0'; /* that's the first word! */
X
X /** spaces before equal sign? **/
X
X while (whitespace(buffer[i])) i++;
X if (buffer[i] == '=') i++;
X
X /** spaces after equal sign? **/
X
X while (whitespace(buffer[i])) i++;
X
X if (buffer[i] != '\0')
X strcpy(word2, (char *) (buffer + i));
X else
X word2[0] = '\0';
X
X if (no_multiword_values) { /* remove trailing spaces from word2! */
X for (i=0; word2[i] != '\0'; i++)
X if (whitespace(word2[i]) || word2[i] == '\n') word2[i] = '\0';
X }
X
X}
X
Xexpand_env(dest, buffer)
Xchar *dest, *buffer;
X{
X /** expand possible metacharacters in buffer and then copy
X to dest...
X This routine knows about "~" being the home directory,
X and "$xxx" being an environment variable.
X **/
X
X char *word, *string, next_word[SLEN];
X
X if (buffer[0] == '/') {
X dest[0] = '/';
X dest[1] = '\0';
X }
X else
X dest[0] = '\0';
X
X string = (char *) buffer;
X
X while ((word = strtok(string, "/")) != NULL) {
X if (word[0] == '$') {
X next_word[0] = '\0';
X if (getenv((char *) (word + 1)) != NULL)
X strcpy(next_word, getenv((char *) (word + 1)));
X if (strlen(next_word) == 0)
X leave(fprintf(stderr,
X "\n\rCan't expand environment variable '%s'\n\r",
X word));
X }
X else if (word[0] == '~' && word[1] == '\0')
X strcpy(next_word, home);
X else
X strcpy(next_word, word);
X
X sprintf(dest, "%s%s%s", dest,
X (strlen(dest) > 0 && lastch(dest) != '/' ? "/":""),
X next_word);
X
X string = (char *) NULL;
X }
X}
X
X#define on_off(s) (s == 1? "ON " : "OFF")
Xdump_rc_results()
X{
X
X register int i, len;
X
X fprintf(debugfile, "folders = %s ", folders);
X fprintf(debugfile, "mailbox = %s ", mailbox);
X fprintf(debugfile, "editor = %s\n", editor);
X fprintf(debugfile, "printout = %s ", printout);
X fprintf(debugfile, "savefile = %s ", savefile);
X fprintf(debugfile, "calendar_file = %s\n", calendar_file);
X fprintf(debugfile, "prefixchars = %s ", prefixchars);
X fprintf(debugfile, "shell = %s ", shell);
X fprintf(debugfile, "pager = %s\n", pager);
X fprintf(debugfile, "\n");
X fprintf(debugfile, "escape = %c\n", escape_char);
X fprintf(debugfile, "\n");
X
X fprintf(debugfile, "mini_menu = %s ", on_off(mini_menu));
X fprintf(debugfile, "mbox_specified = %s ", on_off(mbox_specified));
X fprintf(debugfile, "check_first = %s ", on_off(check_first));
X fprintf(debugfile, "auto_copy = %s\n", on_off(auto_copy));
X
X fprintf(debugfile, "filter_hdrs = %s ", on_off(filter));
X fprintf(debugfile, "resolve_mode = %s ", on_off(resolve_mode));
X fprintf(debugfile, "auto_save_copy = %s ", on_off(auto_cc));
X fprintf(debugfile, "noheader = %s\n", on_off(noheader));
X
X fprintf(debugfile, "title_msgs = %s ", on_off(title_messages));
X fprintf(debugfile, "hp_terminal = %s ", on_off(hp_terminal));
X fprintf(debugfile, "hp_softkeys = %s ", on_off(hp_softkeys));
X fprintf(debugfile, "save_by_name = %s\n", on_off(save_by_name));
X
X fprintf(debugfile, "move_paged = %s ", on_off(move_when_paged));
X fprintf(debugfile, "point_to_new = %s ", on_off(point_to_new));
X fprintf(debugfile, "bounceback = %s ", on_off(bounceback));
X fprintf(debugfile, "signature = %s\n", on_off(signature));
X
X fprintf(debugfile, "always_leave = %s ", on_off(always_leave));
X fprintf(debugfile, "always_delete = %s ", on_off(always_del));
X fprintf(debugfile, "arrow_cursor = %s ", on_off(arrow_cursor));
X fprintf(debugfile, "names = %s\n", on_off(names_only));
X
X fprintf(debugfile, "warnings = %s ", on_off(warnings));
X fprintf(debugfile, "question_me = %s ", on_off(question_me));
X fprintf(debugfile, "keep_nil_files = %s\n\n",
X on_off(keep_empty_files));
X
X fprintf(debugfile, "Userlevel is set to %s user: %d\n",
X user_level == 0 ? "beginning" :
X user_level > 1 ? "expert" : "intermediate", user_level);
X
X fprintf(debugfile, "\nAnd we're skipping the following headers:\n\t");
X
X for (len=8, i=0; i < weedcount; i++) {
X if (weedlist[i][0] == '*') continue; /* skip '*end-of-defaults*' */
X if (len + strlen(weedlist[i]) > 80) {
X fprintf(debugfile, " \n\t");
X len = 8;
X }
X fprintf(debugfile, "%s ", weedlist[i]);
X len += strlen(weedlist[i]) + 3;
X }
X
X fprintf(debugfile, "\n\n");
X}
X
Xis_it_on(word)
Xchar *word;
X{
X /** Returns TRUE if the specified word is either 'ON', 'YES'
X or 'TRUE', and FALSE otherwise. We explicitly translate
X to lowercase here to ensure that we have the fastest
X routine possible - we really DON'T want to have this take
X a long time or our startup will be major pain each time.
X **/
X
X static char mybuffer[NLEN];
X register int i, j;
X
X for (i=0, j=0; word[i] != '\0'; i++)
X mybuffer[j++] = isupper(word[i]) ? tolower(word[i]) : word[i];
X mybuffer[j] = '\0';
X
X return( (strncmp(mybuffer, "on", 2) == 0) ||
X (strncmp(mybuffer, "yes", 3) == 0) ||
X (strncmp(mybuffer, "true", 4) == 0)
X );
X}
SHAR_EOF
chmod 0444 src/read_rc.c || echo "restore of src/read_rc.c fails"
echo "x - extracting src/remail.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/remail.c &&
X
Xstatic char rcsid[] = "@(#)$Id: remail.c,v 2.1 88/09/15 20:29:27 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: remail.c,v $
X * Revision 2.1 88/09/15 20:29:27 syd
X * checked in with -k by syd at 88.09.15.20.29.27.
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:19 edc
X * Final hacks and cleanup to the 2.1 alpha test release.
X *
X * Revision 2.0 88/06/27 17:25:28 edc
X * The original 2.0 gamma sources as leaked from HP
X *
X *
X *
X ******************************************************************************/
X
X/** For those cases when you want to have a message continue along
X to another person in such a way as they end up receiving it with
X the return address the person YOU received the mail from (does
X this comment make any sense yet??)...
X
X**/
X
X#include "headers.h"
X#include <errno.h>
X
Xextern int errno;
X
Xchar *error_name(), *error_description();
X
Xint
Xremail()
X{
X /** remail a message... returns TRUE if new foot needed ... **/
X
X FILE *mailfd;
X char entered[VERY_LONG_STRING], expanded[VERY_LONG_STRING];
X char filename[SLEN], buffer[VERY_LONG_STRING], ch;
X
X entered[0] = '\0';
X
X get_to(entered, expanded);
X if (strlen(entered) == 0)
X return(0);
X
X display_to(expanded);
X
X /** now the munge... **/
X
X sprintf(filename, "%s%d", temp_file, getpid());
X
X if ((mailfd = fopen(filename, "w")) == NULL) {
X dprint(1, (debugfile, "couldn't open temp file %s! (remail)\n",
X filename));
X dprint(1, (debugfile, "** %s - %s **\n", error_name(errno),
X error_description(errno)));
X sprintf(buffer, "Sorry - couldn't open file %s for writing (%s)",
X error_name(errno));
X set_error(buffer);
X return(1);
X }
X
X /** now let's copy the message into the newly opened
X buffer... **/
X
X chown (filename, userid, groupid);
X
X copy_message("", mailfd, FALSE, TRUE);
X
X fclose(mailfd);
X
X /** Got the messsage, now let's ensure the person really wants to
X remail it... **/
X
X ClearLine(LINES-1);
X ClearLine(LINES);
X PutLine1(LINES-1,0,
X "Are you sure you want to remail this message (y/n) ? y%c",
X BACKSPACE);
X fflush(stdin);
X fflush(stdout);
X ch = ReadCh();
X if (tolower(ch) == 'n') { /* another day, another No... */
X Write_to_screen("No", 0);
X set_error("Bounce of message cancelled");
X return(1);
X }
X Write_to_screen("Yes!", 0);
X
X sprintf(buffer, "%s %s < %s", mailer, strip_parens(expanded), filename);
X
X PutLine0(LINES,0,"resending mail...");
X
X if ((errno = system_call(buffer, SH)) != 0) {
X sprintf(buffer, "Remail failed with error %d!", errno);
X set_error(buffer);
X }
X else
X set_error("mail resent");
X
X return(1);
X}
SHAR_EOF
chmod 0444 src/remail.c || echo "restore of src/remail.c fails"
echo "x - extracting src/reply.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/reply.c &&
X
Xstatic char rcsid[] = "@(#)$Id: reply.c,v 2.1 88/09/15 20:29:30 syd Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 2.1 $ $State: Exp $
X *
X * Copyright (c) 1985 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: reply.c,v $
X * Revision 2.1 88/09/15 20:29:30 syd
X * checked in with -k by syd at 88.09.15.20.29.30.
X *
X * 88/09/13 Rob Bernardo <rob@pbhyf.PacBell.COM >
X * fixes how elm knows when to repaint the screen or not.
X *
X * 88/09/01 Rob Bernardo <gatech!pbhyf.PacBell.COM!rob>
X * forward a message without editing it, fix redraw after no edit
X *
X * Revision 2.1 88/07/21 09:59:21 edc
X * Final hacks and cleanup to the 2.1 alpha test release.
X *
X * Revision 2.0 88/06/27 17:25:29 edc
X * The original 2.0 gamma sources as leaked from HP
X *
X *
X *
X ******************************************************************************/
X
X/*** routine allows replying to the sender of the current message
X
X***/
X
X#include "headers.h"
X#include <errno.h>
X
X#ifndef BSD
X# include <sys/types.h>
X# include <sys/utsname.h>
X#endif
X
X/** Note that this routine generates automatic header information
X for the subject and (obviously) to lines, but that these can
X be altered while in the editor composing the reply message!
X**/
X
Xchar *strip_parens(), *get_token();
X
Xextern int errno;
X
Xchar *error_name(), *strcat(), *strcpy();
X
Xint
Xreply()
X{
X /** Reply to the current message. Returns non-zero iff
X the screen has to be rewritten. **/
X
X char return_address[LONG_SLEN], subject[SLEN];
SHAR_EOF
echo "End of part 16"
echo "File src/reply.c is continued in part 17"
echo "17" > 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