[comp.mail.elm] Elm 2.1 PL1 Part 16 of 22

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