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

syd@dsinc.UUCP (Syd Weinstein) (12/13/88)

---- Cut Here and unpack ----
#!/bin/sh
# this is part 13 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file src/forms.c continued
#
CurArch=13
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/forms.c"
sed 's/^X//' << 'SHAR_EOF' >> src/forms.c
X
X	dprint(7, (debugfile, "prompt-for-sized-entry \"%s\" %d chars\n", 
X		prompt, field_size));
X
X	printf("%s : ", prompt);
X	
X	for (i=0;i<field_size; i++)
X	  putchar('_');
X	for (i=0;i<field_size; i++)
X	  putchar(BACKSPACE);
X	fflush(stdout);
X
X	gets(buffer);
X
X	if (strlen(buffer) > field_size) buffer[field_size-1] = '\0';
X}
SHAR_EOF
echo "File src/forms.c is complete"
chmod 0444 src/forms.c || echo "restore of src/forms.c fails"
echo "x - extracting src/getopt.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/getopt.c &&
X
Xstatic char rcsid[] = "@(#)$Id: getopt.c,v 2.1 88/07/21 09:58:34 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:	getopt.c,v $
X * Revision 2.1  88/07/21  09:58:34  edc
X * checked in with -k by syd at 88.09.15.20.28.31.
X * 
X * Revision 2.1  88/07/21  09:58:34  edc
X * Final hacks and cleanup to the 2.1 alpha test release.
X * 
X * Revision 2.0  88/06/27  17:25:06  edc
X * The original 2.0 gamma sources as leaked from HP
X * 
X *
X *
X ******************************************************************************/
X
X/** starting argument parsing routine... 
X
X**/
X
X#include "defs.h"
X
X#ifndef NULL
X# define NULL		0
X#endif
X
X#define DONE		0
X#define ERROR		-1
X
Xchar *optional_arg;			/* optional argument as we go */
Xint   opt_index = 0;			/* argnum + 1 when we leave   */
X
X/***********************
X
X   Typical usage of this routine is exemplified by;
X
X	register int c;
X
X	while ((c = get_options(argc, argv, "ad:f:")) > 0) {
X	   switch (c) {
X	     case 'a' : arrow_cursor++;		break;
X	     case 'd' : debug = atoi(optional_arg);	break;
X	     case 'f' : strcpy(infile, optional_arg); 
X	                mbox_specified = 2;  break;
X	    }
X	 }
X
X	 if (c == ERROR) {
X	   printf("Usage: %s [a] [-d level] [-f file] <names>\n\n", argv[0]);
X	   exit(1);
X	}
X
X***********************/
X
Xint  _indx = 1, _argnum = 1;
X
Xint
Xget_options(argc, argv, options)
Xint argc;
Xchar *argv[], *options;
X{
X	/** Returns the character argument next, and optionally instantiates 
X	    "argument" to the argument associated with the particular option 
X	**/
X	
X	char        *word, *strchr();
X
X	if (_argnum >= argc) {	/* quick check first - no arguments! */
X	  opt_index = argc;
X	  return(DONE);
X	}
X
X	if (_indx >= strlen(argv[_argnum]) && _indx > 1) {
X	  _argnum++;
X	  _indx = 1;		/* zeroeth char is '-' */
X	}
X
X	if (_argnum >= argc) {
X	  opt_index = _argnum; /* no more args */
X	  return(DONE);
X	}
X
X	if (argv[_argnum][0] != '-') {
X	  opt_index = _argnum;
X	  return(DONE);
X	}
X
X        word = strchr(options, argv[_argnum][_indx++]);
X
X	if (word == NULL)
X	  return(ERROR);		/* Sun compatibility */
X
X	if (word == NULL || strlen(word) == 0) 
X	  return(ERROR);
X	
X	if (word[1] == ':') {
X
X	  /** Two possibilities - either tailing end of this argument or the 
X	      next argument in the list **/
X
X	  if (_indx < strlen(argv[_argnum])) { /* first possibility */
X	    optional_arg = (char *) (argv[_argnum] + _indx);
X	    _argnum++;
X	    _indx = 1;
X	  }
X	  else {				/* second choice     */
X	    if (++_argnum >= argc) 
X	      return(ERROR);			/* no argument!!     */
X
X	    optional_arg = (char *) argv[_argnum++];
X	    _indx = 1;
X	  }
X	}
X
X	return((int) word[0]);
X}
SHAR_EOF
chmod 0444 src/getopt.c || echo "restore of src/getopt.c fails"
echo "x - extracting src/hdrcfg_b.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/hdrcfg_b.c &&
X
Xstatic char rcsid[] = "@(#)$Id: hdrcfg_b.c,v 2.1 88/09/15 20:28:33 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:	hdrcfg_b.c,v $
X * Revision 2.1  88/09/15  20:28:33  syd
X * checked in with -k by syd at 88.09.15.20.28.33.
X * 
X * 88/08/27 ssw
X *	add deluth patches
X *
X * Revision 2.1  88/07/21  09:58:38  edc
X * Final hacks and cleanup to the 2.1 alpha test release.
X * 
X * Revision 2.0  88/06/27  17:25:09  edc
X * The original 2.0 gamma sources as leaked from HP
X * 
X *
X *
X ******************************************************************************/
X
X/**   This file contains the routines necessary to be able to modify
X      the mail headers of messages on the way off the machine for 
X      users that are in 'batch' mode (e.g. the system has no knowledge
X      of the termtype or anything, so needs to use dump printf calls)
X
X      Headers currently supported for modification are:
X
X	To:
X	Cc:
X	Bcc:			(depending on #ifdef BCC_ALLOWED)
X	Subject:
X	Reply-To:
X	Expires:
X	Priority:
X        In-Reply-To:
X	Action:
X	<user defined>
X
X**/
X
X#include <stdio.h>
X#include "headers.h"
X
X#include <ctype.h>
X
X#ifdef BSD
X#undef toupper
X#endif
X
X/* these are all defined in the mailmsg file! */
X
Xextern char subject[SLEN], in_reply_to[SLEN], expires[SLEN], 
X            action[SLEN], priority[SLEN], reply_to[SLEN], to[VERY_LONG_STRING], 
X	    cc[VERY_LONG_STRING], expanded_to[VERY_LONG_STRING], 
X	    expanded_cc[VERY_LONG_STRING], user_defined_header[SLEN];
X
X#ifdef ALLOW_BCC
Xextern char bcc[VERY_LONG_STRING], expanded_bcc[VERY_LONG_STRING];
X#endif
X
Xchar *strip_commas(), *strcpy();
X
Xbatch_header_editor()
X{
X	/** Edit headers.  **/
X
X	char ch;
X	int  first_time_through = 0; 
X	
X	printf("\n\rElm Header Editor.  Please choose from the following:\n\n\r");
X
Xreprompt:
X	if (first_time_through++ == 0) {
X#ifdef ALLOW_BCC
X  printf("   V)iew headers  T)o:  C)c:  B)cc:  S)ubject:  R)eply-To:  E)xpires:\n\r");
X#else
X  printf("   V)iew headers  T)o:  C)c:  S)ubject:  R)eply-To:  E)xpires:\n\r");
X#endif
X	  printf(
X	  "   P)riority:  I)n-reply-to:  A)ction:  or  Q)uit editing\n\n\r");
X	  printf("Choice? q%c", BACKSPACE);
X	}
X	else 
X	  printf("\n\rHeader to edit ('?' for choices) : q%c", BACKSPACE);
X
X	fflush(stdout);
X
X	ch = ReadCh();
X	if (isupper(ch))
X	  ch = tolower(ch);
X
X	switch (ch) {
X	  case 'v' : printf("View Headers:\n\n\r");
X
X		     printf("To: "); 
X		     if (strlen(expanded_to) > 0)
X			printf("%s\n\r", format_long(expanded_to, 4));
X		     else if (strlen(to) > 0)
X		        printf("%s\n\r", format_long(to, 4));
X		     else printf("\n\r");
X
X		     printf("Cc: "); 
X		     if (strlen(expanded_cc) > 0)
X			printf("%s\n\r", format_long(expanded_cc, 4));
X		     else if (strlen(cc) > 0)
X			printf("%s\n\r", format_long(cc, 4));
X		     else printf("\n\r");
X
X#ifdef ALLOW_BCC
X		     if (strlen(bcc) > 0) {
X			printf("Bcc: "); 
X		        if (strlen(expanded_bcc) > 0)
X			   printf("%s\n\r", format_long(expanded_bcc, 4));
X		        else if (strlen(bcc) > 0)
X			   printf("%s\n\r", format_long(bcc, 4));
X		        else printf("\n\r");
X		     }
X#endif
X		     if (strlen(subject) > 0) 
X			printf("Subject: %s\n\r", subject);
X		     if (strlen(reply_to) > 0) 
X			printf("Reply-To: %s\n\r", reply_to);
X		     if (strlen(expires) > 0) 
X			printf("Expires: %s\n\r", expires);
X	   	     if (strlen(priority) > 0)
X		       printf("Priority: %s\n\r", priority);
X		     if (strlen(in_reply_to) > 0)
X	   	       printf("In-Reply-To: %s\n\r", in_reply_to);
X		     if (strlen(action) > 0)
X	   	       printf("Action: %s\n\r", action);
X		     printf("\n");
X		     break;
X
X	  case 't' : printf("To\n\n\rTo: ");
X		     if (optionally_enter(to, -1, -1, TRUE) == -1)
X	               return;
X	    	     if (build_address(strip_commas(to), expanded_to))
X		       printf("\rTo: %s\n\r", format_long(expanded_to, 4));
X		     break;
X	  case 'c' : printf("Cc\n\n\rCc: ");
X		     if (optionally_enter(cc, -1, -1, TRUE) == -1)
X	               return;
X	    	     if (build_address(strip_commas(cc), expanded_cc));
X		       printf("\rCc: %s\n\r", format_long(expanded_cc, 4));
X		     break;
X#ifdef ALLOW_BCC
X	  case 'b' : printf("Bcc\n\n\rBcc: ");
X		     if (optionally_enter(bcc, -1, -1, TRUE) == -1)
X	               return;
X	    	     if (build_address(strip_commas(bcc), expanded_bcc))
X		       printf("\rBcc: %s\n\r", format_long(expanded_bcc, 5));
X		     break;
X#endif
X	  case 's' : printf("Subject\n\n\rSubject: ");
X		     if (optionally_enter(subject, -1, -1, TRUE) == -1)
X	               return;
X		     break;
X	  case 'r' : printf("Reply-To\n\n\rReply-To: ");
X		     if (optionally_enter(reply_to, -1, -1, TRUE) == -1)
X	               return;
X		     break;
X
X	  case 'e' : printf("Expires\n\n\rExpires: ");
X		     batch_enter_date(expires);
X		     break;
X	  case 'p' : printf("Priority\n\n\rPriority: ");
X		     if (optionally_enter(priority, -1, -1, TRUE) == -1)
X	               return;
X		     break;
X	  case 'i' : printf("In-Reply-To\n\n\rIn-Reply-To: ");
X		     if (optionally_enter(in_reply_to, -1, -1, TRUE) == -1)
X	               return;
X		     break;
X	  case 'a' : printf("Action\n\n\rAction: ");
X		     if (optionally_enter(action, -1, -1, TRUE) == -1)
X	               return;
X		     break;
X	  case '\n':
X	  case '\r':
X	  case 'q' : printf("Quit Header Editor\n\r"); return;
X
X	  case '?': 
X		     printf("Help\n\n\r"); 
X		     first_time_through = 0;
X		     break;
X
X	  default  : printf("%c\r\nI don't understand that choice!\n\r", ch);
X		     first_time_through == 0;
X	}
X
X	goto reprompt;
X}
X
Xbatch_enter_date(buffer)
Xchar *buffer;
X{
X	/** Enter the number of days this message is valid for, then
X	    display the actual date of expiration.  This routine relies 
X	    heavily on the routine 'days_ahead()' in the file date.c
X	**/
X
X	int days;
X	int old_raw;
X
X	printf(
X	    "How many days in the future should this message expire? ");
X	fflush(stdout);
X	if (( old_raw = RawState()) == ON)
X	    Raw(OFF);
X	gets(buffer);
X	if ( old_raw == ON)
X	   Raw(ON);
X	sscanf(buffer, "%d", &days);
X	if (days < 1)
X	  printf("You can't send messages that have already expired!\n");
X	else if (days > 56)
X	  printf(
X	  "The expiration date must be within eight weeks of today\n");
X	else {
X	  days_ahead(days, buffer);
X	  printf("Expires on: %s\n", buffer);
X	}
X}
SHAR_EOF
chmod 0444 src/hdrcfg_b.c || echo "restore of src/hdrcfg_b.c fails"
echo "x - extracting src/hdrconfg.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/hdrconfg.c &&
X
Xstatic char rcsid[] = "@(#)$Id: hdrconfg.c,v 2.1 88/09/15 20:28:35 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:	hdrconfg.c,v $
X * Revision 2.1  88/09/15  20:28:35  syd
X * checked in with -k by syd at 88.09.15.20.28.35.
X * 
X * 88/09/12 Chip Rosenthal <chip@vector>
X * couple of additional toupper()/tolower() side effect instances.
X *
X * 88/08/27 ssw
X *	add deluth patches
X *
X * 88/08/27 Rob Bernardo <gatech!pbhyf.PacBell.COM!rob>
X * fix header edit code
X *
X * Revision 2.1  88/07/21  09:58:36  edc
X * Final hacks and cleanup to the 2.1 alpha test release.
X * 
X * Revision 2.0  88/06/27  17:25:08  edc
X * The original 2.0 gamma sources as leaked from HP
X * 
X *
X *
X ******************************************************************************/
X
X/**   This file contains the routines necessary to be able to modify
X      the mail headers of messages on the way off the machine.  The
X      headers currently supported for modification are:
X
X	Subject:
X	To:
X	Cc:
X	Bcc:
X	Reply-To:
X	Expires:
X	Priority:
X        In-Reply-To:
X	Action:
X
X	<user defined>
X**/
X
X#include <stdio.h>
X#include "headers.h"
X
X#include <ctype.h>
X
X#ifdef BSD
X#undef toupper
X#endif
X
X/* these are all defined in the mailmsg file! */
X
Xextern char subject[SLEN], in_reply_to[SLEN], expires[SLEN], 
X            action[SLEN], priority[SLEN], reply_to[SLEN], to[VERY_LONG_STRING], 
X	    cc[VERY_LONG_STRING], expanded_to[VERY_LONG_STRING], 
X	    expanded_cc[VERY_LONG_STRING], user_defined_header[SLEN],
X	    bcc[VERY_LONG_STRING], expanded_bcc[VERY_LONG_STRING];
X
Xchar *strip_commas(), *strcpy();
X
Xedit_headers()
X{
X	/** Edit headers.  **/
X
X	int unexpanded_to = TRUE, unexpanded_cc = TRUE, unexpanded_bcc = TRUE;
X	int c;
X	
X	if (mail_only) goto outta_here;		/* how did we get HERE??? */
X
X	display_headers();
X
X	clearerr(stdin);
X
X	clearerr(stdin);
X
X	while (TRUE) {	/* forever */
X	  PutLine0(LINES-2,0,"Choice: ");
X	  CleartoEOLN();
X	  c = getchar();
X	  c = toupper(c);
X	  MoveCursor(LINES-1,0); CleartoEOLN();
X	  clear_error();
X	  if (c == EOF)
X		break;
X	  switch (c) {
X	    case RETURN:
X	    case LINE_FEED:
X	    case 'Q' : goto outta_here;
X	    case ctrl('L') : display_headers();
X		       break;
X	    case 'T' : if (optionally_enter(to, 2, 4, TRUE) == -1)
X	                 goto outta_here;
X	    	       (void) build_address(strip_commas(to), expanded_to);
X		       unexpanded_to = FALSE; 
X		       break;
X	    case 'S' : if (optionally_enter(subject, 7, 9, FALSE) == -1)
X			 goto outta_here;
X		       break;
X	    case 'B' : if (optionally_enter(bcc, 4, 5, TRUE) == -1)
X			 goto outta_here;
X	  	       (void) build_address(strip_commas(bcc), expanded_bcc);
X		       unexpanded_bcc = FALSE;
X		       break;
X	    case 'C' : if (optionally_enter(cc, 3, 4, TRUE) == -1)
X			 goto outta_here;
X	  	       (void) build_address(strip_commas(cc), expanded_cc);
X		       unexpanded_cc = FALSE;
X		       break;
X	    case 'R' : if (optionally_enter(reply_to, 5, 10, FALSE) == -1)
X			 goto outta_here;
X		       break;
X
X	    case 'A' : if (optionally_enter(action, 9, 8, FALSE) == -1)
X			 goto outta_here;
X		       break;
X
X	    case 'P' : if (optionally_enter(priority, 11, 10, FALSE) == -1)
X			 goto outta_here;
X		       break;
X
X	    case 'E' : enter_date(10, 9, expires);
X		       break;
X
X	    case 'U' : if (optionally_enter(user_defined_header,14,0,FALSE)==-1)
X			 goto outta_here;
X		       else
X		         check_user_header(user_defined_header);
X		       break;
X
X	    case 'I' : if (strlen(in_reply_to) > 0) {
X	                 if (optionally_enter(in_reply_to, 12,13, FALSE) == -1)
X			   goto outta_here;
X			 break;		
X		       }
X		       /** else fall through as an error **/
X	    default  : Centerline(LINES-1, "Unknown header being specified!");
X	  }
X	} 
X
Xoutta_here:	/* this section re-expands aliases before we leave... */
X
X	if (unexpanded_to)
X	  (void) build_address(strip_commas(to), expanded_to);
X	if (unexpanded_cc)
X	  (void) build_address(strip_commas(cc), expanded_cc);
X	if (unexpanded_bcc)
X	  (void) build_address(strip_commas(bcc), expanded_bcc);
X}
X
Xdisplay_headers()
X{
X	ClearScreen();
X
X	Centerline(0,"Message Header Edit Screen");
X
X	PutLine1(2,0,"To: %s", to);
X	PutLine1(3,0,"Cc: %s", cc); CleartoEOLN();
X	PutLine1(4,0,"Bcc: %s", bcc); CleartoEOLN();
X	PutLine1(5,0,"Reply-To: %s", reply_to); CleartoEOS();
X
X	PutLine1(7,0,"Subject: %s", subject);
X	PutLine1(9,0,"Action: %s", action);
X	PutLine1(10,0,"Expires: %s", expires);
X	PutLine1(11,0,"Priority: %s", priority);
X	if (strlen(in_reply_to) > 0)
X	  PutLine1(12,0,"In-Reply-To: %s", in_reply_to);
X
X	if (strlen(user_defined_header) > 0)
X	  PutLine1(14,0, "%s", user_defined_header);
X
X	Centerline(LINES-5, 
X    "Choose first letter of existing header, U)ser defined header, or <return>");
X}
X
Xenter_date(x, y, buffer)
Xint x, y;
Xchar *buffer;
X{
X	/** Enter the number of days this message is valid for, then
X	    display at (x,y) the actual date of expiration.  This 
X	    routine relies heavily on the routine 'days_ahead()' in
X	    the file date.c
X	**/
X
X	int days;
X	int old_raw;
X
X	PutLine0(LINES-2,0, 
X	    "How many days in the future should this message expire? ");
X	CleartoEOLN();
X	if (( old_raw = RawState()) == ON)
X	    Raw(OFF);
X	gets(buffer);
X	if (old_raw == ON)
X	  Raw(ON);
X	sscanf(buffer, "%d", &days);
X	if (days < 1)
X	  Centerline(LINES-1, "That doesn't make sense!");
X	else if (days > 56)
X	  Centerline(LINES-1, 
X	     "Expiration date must be within eight weeks of today");
X	else {
X	  days_ahead(days, buffer);
X	  PutLine0(x, y, buffer);
X	}
X}
X
X
Xcheck_user_header(header)
Xchar *header;
X{
X	/** check the header format...if bad print error and erase! **/
X
X	register int i = -1;
X
X	if (strlen(header) == 0)
X	   return;
X
X	if (whitespace(header[0])) {
X	  error ("you can't have leading white space in a header!");
X	  header[0] = '\0';
X	  ClearLine(14);
X	  return;
X	}
X
X	if (header[0] == ':') {
X	  error ("you can't have a colon as the first character!");
X	  header[0] = '\0';
X	  ClearLine(14);
X	  return;
X	}
X
X	while (header[++i] != ':') {
X	  if (header[i] == '\0') {
X	    Centerline(LINES-1, "You need to have a colon ending the field name!");
X	    header[0] = '\0';
X	    ClearLine(14);
X	    return;
X	  }
X	  else if (whitespace(header[i])) {
X	    Centerline(LINES-1, "You can't have white space imbedded in the header name!");
X	    header[0] = '\0';
X	    ClearLine(14);
X	    return;
X	  }
X	}
X	
X	return;
X}
SHAR_EOF
chmod 0444 src/hdrconfg.c || echo "restore of src/hdrconfg.c fails"
echo "x - extracting src/help.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/help.c &&
X
Xstatic char rcsid[] = "@(#)$Id: help.c,v 2.1 88/09/15 20:28:37 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:	help.c,v $
X * Revision 2.1  88/09/15  20:28:37  syd
X * checked in with -k by syd at 88.09.15.20.28.37.
X * 
X * 88/08/27 ssw
X *	split tolower and ReadCh due to macro calls
X *
X * Revision 2.1  88/07/21  09:58:40  edc
X * Final hacks and cleanup to the 2.1 alpha test release.
X * 
X * Revision 2.0  88/06/27  17:25:10  edc
X * The original 2.0 gamma sources as leaked from HP
X * 
X *
X *
X ******************************************************************************/
X
X/*** help routine for ELM program 
X
X***/
X
X#include <ctype.h>
X
X#ifdef BSD
X# undef tolower
X#endif
X
X#include "headers.h"
X
Xhelp()
X{
X	/** Process the request for help [section] from the user **/
X
X	char ch;		/* character buffer for input */
X	char *s;		/* string pointer...	      */
X
X	MoveCursor(LINES-7,0);
X	CleartoEOS();
X
X	Centerline(LINES-7, "ELM Help System");
X	Centerline(LINES-5,
X           "Press keys you want help for, '?' for a list, or '.' to end");
X
X	PutLine0(LINES-3, 0, "Help on key: ");
X
X	do {
X	  MoveCursor(LINES-3, strlen("Help on key: "));
X	  ch = ReadCh();
X	  ch = tolower(ch);
X	  
X	  if (ch == '.') return(0);	/* zero means footer rewrite only */
X
X	  s = "Unknown command.  Use '?' for a list of commands...";
X
X	  switch (ch) {
X
X	    case '?': display_helpfile(MAIN_HELP);	return(1);
X
X	    case '$': s =
X  "$ = Force a resync of the current mailbox.  This will 'purge' deleted mail";
X		break;
X
X	    case '!': s = 
X   "! = Escape to the Unix shell of your choice, or just to enter commands";
X	       break;
X	    case '@': s = 
X       "@ = Debug - display a summary of the messages on the header page";
X	       break;
X	    case '|': s = 
X "| = Pipe the current message or tagged messages to the command specified";
X	       break;
X	    case '#': s = 
X      "# = Debug - display all information known about current message";
X	      break;
X	    case '%': s = 
X   "% = Debug - display the computed return address of the current message";
X	       break;
X	    case '*': s = "* = Go to the last message in the current mailbox";
X	       break;
X	    case '-': s = 
X	       "- = Go to the previous page of messages in the current mailbox";
X	       break;
X	    case '=': s = 
X                  "'=' = Go to the first message in the current mailbox";
X	       break;
X	    case ' ': 
X	    case '+': s = 
X		"+ = Go to the next page of messages in the current mailbox";
X	       break;
X	    case '/': s = "/ = Search for specified pattern in mailbox";
X	       break;
X	    case '<': s = 
X	       "< = Scan current message for calendar entries (if enabled)";
X	       break;
X	    case '>': s = 
X	       "> = Save current message or tagged messages to specified file";
X	       break;
X	    case '^': s = 
X	       "^ = Toggle the Delete/Undelete status of the current message";
X	       break;
X	    case 'a': s = 
X       "a = Enter the alias sub-menu section.  Create and display aliases";
X	       break;
X	    case 'b': s = 
X    "b = Bounce (remail) a message to someone as if you have never seen it";
X	       break;
X	    case 'c': s = 
X       "c = Change mailboxes, leaving the current mailbox as if 'quitting'";
X	       break;
X	    case 'd': s = "d = Mark the current message for future deletion";
X	       break;
X	    case ctrl('D') :
X	s = "^D = Mark for deletion all messages with the specified pattern";
X		break;
X	    case 'e': s = 
X       "e = Invoke the editor on the entire mailbox, resync'ing when done";
X	       break;
X	    case 'f': s = 
X      "f = Forward the current message to someone, return address is yours";
X	       break;
X	    case 'g': s = 
X "g = Group reply not only to the sender, but to everyone who received msg";
X	       break;
X	    case 'h': s = 
X	       "h = Display message with all Headers (ignore weedout list)";
X	       break;
X	    case 'j': s = 
X       "j = Go to the next message.  This is the same as the DOWN arrow";
X	       break;
X	    case 'k': s = 
X       "k = Go to the previous message.  This is the same as the UP arrow";
X	       break;
X	    case 'l': s =
X               "l = Limit displayed messages based on the specified criteria";
X	       break;
X	    case 'm': s = 
X               "m = Create and send mail to the specified person or persons";
X	       break;
X	    case 'n': s = 
X               "n = Read the current message, then move current to next messge";
X	       break;
X	    case 'o': s = "o = Go to the options submenu";
X	       break;
X	    case 'p': s = 
X		"p = Print the current message or the tagged messages";
X	       break;
X	    case 'q': s = 
X		"q = Quit the mailer, asking about deletion, saving, etc";
X	       break;
X	    case 'r': s = 
X  "r = Reply to the message.  This only sends to the originator of the message";
X	       break;
X	    case 's': s = 
X               "s = Save current message or tagged messages to specified file";
X	       break;
X	    case 't': s = 
X               "t = Tag a message for further operations (or untag if tagged)";
X	       break;
X	    case ctrl('T') :
X		s = "^T = tag all messages with the specified pattern";
X		break;
X	    case 'u': 
X		s = "u = Undelete - remove the deletion mark on the message";
X	       break;
X	    case 'x': s = "x = Exit the mail system quickly";
X	       break;
X    	
X	    case '\n':
X	    case '\r': s = "<return> = Read the current message";
X	       break;
X    
X	    case ctrl('L'): s = "^L = Rewrite the screen";	
X	       break;
X            case ctrl('?'):					    /* DEL */
X	    case ctrl('Q'): s = "Exit the mail system quickly";
X	       break;
X	    default : if (isdigit(ch)) 
X	            s = "<number> = Make specified number the current message";
X	  }
X
X	  ClearLine(LINES-1);
X	  Centerline(LINES-1, s);
X
X	} while (ch != '.');
X	
X	/** we'll never actually get here, but that's okay... **/
X
X	return(0);
X}
X
Xdisplay_helpfile(section)
Xint section;
X{
X	/*** Help me!  Read file 'helpfile.<section>' and echo to screen ***/
X
X	FILE *hfile;
X	char buffer[SLEN];
X	int  lines=0;
X
X	sprintf(buffer, "%s/%s.%d", helphome, helpfile, section);
X
X	if ((hfile = fopen(buffer,"r")) == NULL) {
X	  dprint(1, (debugfile,
X		 "Error: Couldn't open helpfile %s (help)\n", buffer));
X	  error1("couldn't open helpfile %s",buffer);
X	  return(FALSE);
X	}
X	
X	ClearScreen();
X
X	while (fgets(buffer, SLEN, hfile) != NULL) {
X	  if (lines > LINES-3) {
X	    PutLine0(LINES,0,"Press any key to continue: ");
X	    (void) ReadCh();
X	    lines = 0;
X	    ClearScreen();
X	    Write_to_screen("%s\r", 1, buffer);
X	  }
X	  else 
X	    Write_to_screen("%s\r", 1, buffer);
X
X	  lines++;
X	}
X
X        PutLine0(LINES,0,"Press any key to return: ");
X
X	(void) ReadCh();
X	clear_error();
X
X	return(TRUE);
X}
SHAR_EOF
chmod 0444 src/help.c || echo "restore of src/help.c fails"
echo "x - extracting src/in_utils.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/in_utils.c &&
X
Xstatic char rcsid[] = "@(#)$Id: in_utils.c,v 2.1 88/09/15 20:28:40 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:	in_utils.c,v $
X * Revision 2.1  88/09/15  20:28:40  syd
X * checked in with -k by syd at 88.09.15.20.28.40.
X * 
X * 88/09/12 Chip Rosenthal <chip@vector>
X * couple of additional toupper()/tolower() side effect instances.
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:58:42  edc
X * Final hacks and cleanup to the 2.1 alpha test release.
X * 
X * Revision 2.0  88/06/27  17:25:11  edc
X * The original 2.0 gamma sources as leaked from HP
X * 
X *
X *
X ******************************************************************************/
X
X/** Mindless I/O routines for ELM 
X	
X**/
X
X#include "headers.h"
X#include <errno.h>
X#include <ctype.h>
X
X#ifdef BSD
X#  undef tolower
X#endif
X
Xextern int errno;		/* system error number */
X
Xunsigned alarm();
X
X#define isstopchar(c)		(c == ' ' || c == '\t' || c == '/')
X#define isslash(c)		(c == '/')
X#define erase_a_char()		{ Writechar(BACKSPACE); Writechar(' '); \
X			          Writechar(BACKSPACE); fflush(stdout); }
X
Xint
Xwant_to(question, dflt, echo_answer)
Xchar *question, dflt;
Xint  echo_answer;
X{
X	/** Ask 'question' at LINES-2, COLUMNS-40, returning the answer in 
X	    lower case.  If 'echo_answer', then echo answer.  'dflt' is the 
X	    default answer if <return> is pressed. (Note: 'dflt' is also what 
X	    will be returned if <return> is pressed!)
X	**/
X	register int ch, cols;
X
X	cols = (strlen(question) < 30)? COLUMNS-40 : COLUMNS-50;
X
X	PutLine3(LINES-3, cols,"%s%c%c", question, dflt, BACKSPACE);
X	fflush(stdout);
X	fflush(stdin);
X
X	ch = ReadCh();
X	ch = tolower(ch);
X
X        if ( dflt == 'y' || dflt == 'n')
X        {
X                while (!( ch == 'y' || ch == 'n' || ch == '\n' || ch == '\r')) {
X		  ch = ReadCh();
X                  ch = tolower(ch);
X		}
X        }
X  
X	if (echo_answer && ch > (char) ' ') {
X	  Writechar(ch);
X	  fflush(stdout);
X	}
X
X	return(ch == '\n' || ch == '\r' ? dflt : ch);
X}
X
Xint
Xread_number(ch)
Xchar ch;
X{
X	/** Read a number, where 'ch' is the leading digit! **/
X	
X	char buff[SHORT_SLEN];
X	int  num;
X
X	buff[0] = ch;
X	buff[1] = '\0';
X
X	PutLine0(LINES-3, COLUMNS-40,"Set current message to :");
X	if (optionally_enter(buff, LINES-3, COLUMNS-15, TRUE) == -1)
X	  return(current);
X
X	sscanf(buff,"%d", &num);
X	return(num);
X}
X
Xint
Xoptionally_enter(string, x, y, append_current)
Xchar *string;
Xint  x,y, append_current;
X{
X	/** This will display the string on the screen and allow the user to
X	    either accept it (by pressing RETURN) or alter it according to
X	    what the user types.   The various flags are:
X	         string    is the buffer to use (with optional initial value)
X	 	 x,y	   is the location we're at on the screen (-1,-1 means
X			   that we can't use this info and need to explicitly
X			   use backspace-space-backspace sequences)
X		 append_current  means that we have an initial string and that
X			   the cursor should be placed at the END of the line,
X			   not the beginning (the default).
X	      
X	    If we hit an interrupt or EOF we'll return non-zero.
X	**/
X
X	int ch;
X	register int ch_count = 0, index = 0, use_cursor_control;
X
X	clearerr(stdin);
X
X	if ((use_cursor_control = (! mail_only && x >= 0 && y >= 0)))
X	  PutLine1(x, y, "%s", string);	
X	else
X	  printf("%s", string);	
X
X	CleartoEOLN();
X
X	if (! append_current) {
X	  if (use_cursor_control)
X	    MoveCursor(x,y);
X	  else
X	    non_destructive_back_up(strlen(string));
X	}
X	else
X	  index = strlen(string);
X
X	if (cursor_control)
X	  transmit_functions(OFF);
X
X	/** now we have the screen as we want it and the cursor in the 
X	    right place, we can loop around on the input and return the
X	    string as soon as the user presses <RETURN>
X	**/
X
X	do {
X	  ch = getchar();
X
X	  if (ch == ctrl('D') || ch == EOF) {		/* we've hit EOF */
X	    if (cursor_control)
X	      transmit_functions(ON);
X	    return(1);
X	  }
X
X	  if (ch_count++ == 0) {
X	    if (ch == '\n' || ch == '\r') {
X	      if (cursor_control)
X	        transmit_functions(ON);
X	      return(0);
X	    }
X	    else if (! append_current) {
X	      CleartoEOLN();
X	      index = (append_current? strlen(string) : 0);
X	    }
X	  }
X
X	  /* the following is converted from a case statement to
X	     allow the variable characters (backspace, kill_line
X	     and break) to be processed.  Case statements in
X	     C require constants as labels, so it failed ...
X	  */
X
X	  if (ch == backspace) {
X	    if (index > 0) {
X	      Writechar(BACKSPACE);
X  	      index--;
X	    }
X	    Writechar(' ');
X	    Writechar(BACKSPACE);
X            fflush(stdout);
X	  }
X	  else if (ch == EOF || ch == '\n' || ch == '\r') {
X	    string[index] = '\0';
X	    if (cursor_control)
X	      transmit_functions(ON);
X	    return(0);
X	  }
X	  else if (ch == ctrl('W')) {		/* back up a word! */
X	    if (index == 0)
X	      continue;		/* no point staying here.. */
X	    index--;
X	    if (isslash(string[index])) {
X	      erase_a_char();
X	    }
X	    else {
X	      while (index >= 0 && isspace(string[index])) {
X	        index--;
X	        erase_a_char();
X	      }
X
X	      while (index >= 0 && ! isstopchar(string[index])) {
X	        index--;
X	        erase_a_char();
X	      }
X	      index++;	/* and make sure we point at the first AVAILABLE slot */
X	    }
X	  }
X	  else if (ch == ctrl('R')) {
X	    string[index] = '\0';
X	    if (use_cursor_control) {
X	      PutLine1(x,y, "%s", string);	
X	      CleartoEOLN();
X	    }
X	    else
X	      printf("\n\r%s", string);	
X	  }
X	  else if (ch == kill_line) {
X	    if (use_cursor_control)
X	       MoveCursor(x,y);
X	    else
X	       back_up(index+1);
X            CleartoEOLN();
X	    index = 0;
X	  }
X	  else if (ch == '\0') {
X	    if (cursor_control)
X	      transmit_functions(ON);
X	    fflush(stdin); 	/* remove extraneous chars, if any */
X	    string[0] = '\0'; /* clean up string, and... */
X	    return(-1);
X	  }
X	  else {  /* default case */
X		        
X	      string[index++] = ch;
X	      Writechar(ch);
X	  }
X	} while (index < SLEN);
X
X	string[index] = '\0';
X
X	if (cursor_control)
X	  transmit_functions(ON);
X
X	return(0);
X}
X
Xint
Xpattern_enter(string, alt_string, x, y, alternate_prompt)
Xchar *string, *alt_string, *alternate_prompt;
Xint  x,y;
X{
X	/** This function is functionally similar to the routine
X	    optionally-enter, but if the first character pressed
X	    is a '/' character, then the alternate prompt and string
X	    are used rather than the normal one.  This routine 
X	    returns 1 if alternate was used, 0 if not
X	**/
X
X	int ch;
X	register index = 0;
X
X	PutLine1(x, y, "%s", string);	
X	CleartoEOLN();
X	MoveCursor(x,y);
X
X	if (cursor_control)
X	  transmit_functions(OFF);
X
X	ch = getchar();
X
X	if (ch == '\n' || ch == '\r') {
X	  if (cursor_control)
X	    transmit_functions(ON);
X	  return(0);	/* we're done.  No change needed */
X	}
X	
X	if (ch == '/') {
X	  PutLine1(x, 0, "%s", alternate_prompt);
X	  CleartoEOLN();
X	  (void) optionally_enter(alt_string, x, strlen(alternate_prompt)+1,
X		 FALSE);
X	  return(1);
X	}
X
X	CleartoEOLN();
X
X	index = 0;
X
X	if (ch == kill_line) {
X	  MoveCursor(x,y);
X          CleartoEOLN();
X	  index = 0;
X	}
X	else if (ch != backspace) {
X	  Writechar(ch);
X	  string[index++] = ch;
X	}
X	else if (index > 0) {
X	  index--;
X	  erase_a_char();
X	}
X	else {
X	  Writechar(' ');
X	  Writechar(BACKSPACE);
X	}
X
X	do {
X	  fflush(stdout);
X	  ch = getchar();
X
X	  /* the following is converted from a case statement to
X	     allow the variable characters (backspace, kill_line
X	     and break) to be processed.  Case statements in
X	     C require constants as labels, so it failed ...
X	  */
X
X	    if (ch == backspace) {
X              if (index > 0) {
X		index--;
X		erase_a_char();
X	      }
X	      else {
X		Writechar(' ');
X		Writechar(BACKSPACE);
X	      }
X	    }
X	    else if (ch == '\n' || ch == '\r') {
X	      string[index] = '\0';
X	      if (cursor_control)
X	        transmit_functions(ON);
X	      return(0);
X	    }
X	    else if (ch == ctrl('W')) {
X	      if (index == 0)
X	        continue;		/* no point staying here.. */
X	      index--;
X	      if (isslash(string[index])) {
X	        erase_a_char();
X	      }
X	      else {
X	        while (index >= 0 && isspace(string[index])) {
X	          index--;
X	          erase_a_char();
X	        }
X
X	        while (index >= 0 && ! isstopchar(string[index])) {
X	          index--;
X	          erase_a_char();
X	        }
X	        index++;/* and make sure we point at the first AVAILABLE slot */
X	      }
X	    }
X	    else if (ch == ctrl('R')) {
X	      string[index] = '\0';
X	      if (!mail_only) {
X	        PutLine1(x,y, "%s", string);	
X	        CleartoEOLN();
X	      }
X	      else
X	        printf("\n\r%s", string);	
X	    }
X	    else if (ch == kill_line) {
X	      MoveCursor(x,y);
X              CleartoEOLN();
X	      index = 0;
X	    }
X	    else if (ch == '\0') {
X	      if (cursor_control)
X	        transmit_functions(ON);
X	      fflush(stdin); 	/* remove extraneous chars, if any */
X	      string[0] = '\0'; /* clean up string, and... */
X	      return(-1);
X	    }
X	    else {  /* default case */
X		        
X	      string[index++] = ch;
X	      Writechar(ch);
X	   }
X	} while (index < SLEN);
X
X	string[index] = '\0';
X
X	if (cursor_control)
X	  transmit_functions(ON);
X	return(0);
X}
X
Xback_up(spaces)
Xint spaces;
X{
X	/** this routine is to replace the goto x,y call for when sending
X	    mail without starting the entire "elm" system up... **/
X	
X	while (spaces--) {
X	  erase_a_char();
X	}
X}
X
Xnon_destructive_back_up(spaces)
Xint spaces;
X{
X	/** same as back_up() but doesn't ERASE the characters on the screen **/
X
X	while (spaces--)
X	  Writechar(BACKSPACE); 
X        fflush(stdout); 
X}
X
Xint
XGetPrompt()
X{
X	/** This routine does a read/timeout for a single character.
X	    The way that this is determined is that the routine to
X	    read a character is called, then the "errno" is checked
X	    against EINTR (interrupted call).  If they match, this
X	    returns NO_OP_COMMAND otherwise it returns the normal
X	    command.	
X	**/
X
X	int ch;
X
X	if (timeout > 0) {
X	  alarm((unsigned) timeout);
X	  errno = 0;	/* we actually have to do this.  *sigh*  */
X	  ch = ReadCh();
X	  if (errno == EINTR) ch = NO_OP_COMMAND;
X	  alarm((unsigned) 0);
X	}
X	else
X	  ch = ReadCh();
X
X	return(ch);
X}
SHAR_EOF
chmod 0444 src/in_utils.c || echo "restore of src/in_utils.c fails"
echo "x - extracting src/init.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/init.c &&
X
Xstatic char rcsid[] = "@(#)$Id: init.c,v 2.1 88/09/15 20:28:42 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:	init.c,v $
X * Revision 2.1  88/09/15  20:28:42  syd
X * checked in with -k by syd at 88.09.15.20.28.42.
X * 
X * 88/09/02 Syd Weinstein
X *	added version buffer init and expansion
X *
X * 88/09/01 Rob Bernardo <gatech!pbhyf.PacBell.COM!rob>
X *	1. It allows the user to use the -z flags and -f [filename] flag
X *	2. Puts elm in raw mode earlier on than before so that any commands
X *
X * 88/08/27 ssw
X *	add deluth patches
X *
X * Revision 2.1  88/07/21  09:58:45  edc
X * Final hacks and cleanup to the 2.1 alpha test release.
X * 
X * Revision 2.0  88/06/27  17:25:12  edc
X * The original 2.0 gamma sources as leaked from HP
X * 
X *
X *
X ******************************************************************************/
X
X/***** Initialize - read in all the defaults etc etc 
X*****/
X
X#include "headers.h"
X#include "patchlevel.h"
X
X#ifdef BSD
X#  include <sgtty.h>
X#else
X#  include <termio.h>
X#endif
X
X#include <pwd.h>
X
X#ifdef BSD
X#  include <sys/time.h>
X#else
X#  include <time.h>
X#endif
X
X#include <signal.h>
X#include <ctype.h>
X#include <errno.h>
X
X#ifdef BSD
X#undef toupper
X#undef tolower
X#endif
X
Xextern int errno;		/* system error number on failure */
Xextern char version_buff[];
X
Xchar *error_name(), *error_description();
X
Xchar *expand_logname(), *getenv(), *getlogin(), *strcpy(), *strcat();
Xunsigned short getgid(), getuid(); 
Xvoid exit();
X
Xchar   *malloc();
X
Xinitialize(initscreen_too)
Xint initscreen_too;
X{
X	/** initialize the whole ball of wax.   If "initscreen_too" then
X	    call init_screen where appropriate..
X	**/
X	struct passwd *pass, *getpwnam();
X
X	register int i, j; 
X	int      quit_signal(), term_signal(), ill_signal(),
X		 fpe_signal(),  bus_signal(),  segv_signal(),
X	         alarm_signal(), pipe_signal(), hup_signal();
X#ifdef SIGTSTP
X	int sig_user_stop(), sig_return_from_user_stop();
X#endif
X	char     buffer[SLEN], *cp;
X	
X	sprintf(version_buff, "%s PL%d", VERSION, PATCHLEVEL);
X	Raw(ON);
X
X	userid  = getuid();
X	groupid = getgid();	
X
X	(void)umask(077);	/* make all newly created files private */
X
X	strcpy(home, ((cp = getenv("HOME")) == NULL)? "" : cp);
X	strcpy(shell,((cp = getenv("SHELL")) == NULL)? default_shell : cp);
X	strcpy(pager,((cp = getenv("PAGER")) == NULL)? default_pager : cp);
X
X#ifdef DEBUG
X	if (debug) {		/* setup for dprint() statements! */
X	  char newfname[SLEN], filename[SLEN];
X
X	  sprintf(filename, "%s/%s", home, DEBUGFILE);
X	  if (access(filename, ACCESS_EXISTS) == 0) {	/* already one! */
X	    sprintf(newfname,"%s/%s", home, OLDEBUG);
X	    (void) unlink(newfname);
X	    (void) link(filename, newfname);
X	    (void) unlink(filename);
X	  }
X
X	  /* Note what we just did up there: we always save the old
X	     version of the debug file as OLDEBUG, so users can mail
X	     copies of bug files without trashing 'em by starting up
X	     the mailer.  Dumb, subtle, but easy enough to do!
X 	  */
X
X	  if ((debugfile = fopen(filename, "w")) == NULL) {
X	    debug = 0;	/* otherwise 'leave' will try to log! */
X	    leave(fprintf(stderr,"Could not open file %s for debug output!\n",
X		  filename));
X	  }
X	  chown(filename, userid, groupid); /* file owned by user */
X
X	  fprintf(debugfile, 
X     "Debug output of the ELM program (at debug level %d).  Version %s\n\n",
X		  debug, version_buff);
X	}
X#endif
X
X	if (initscreen_too)	/* don't set up unless we need to! */
X	  if ((i = InitScreen()) < 0) {
X	    if (i == -1) {
X	      printf( 
X"Sorry, but you must specify what type of terminal you're on if you want to\n");
X	      printf( 
X"run the \"elm\" program...(you need your environment variable \"TERM\" set)\n"
X	             );
X	      dprint(1,(debugfile,"No $TERM variable in environment!\n"));
X	    }
X	    else if (i == -2) {
X	      printf(
X"You need a cursor-addressable terminal to run \"elm\" and I can't find any\n");
X	      printf(
X"kind of termcap entry for \"%s\" - check your \"TERM\" setting...\n",
X		     getenv("TERM"));
X	      dprint(1,
X		  (debugfile,"$TERM variable is an unknown terminal type!\n"));
X	    }
X	    else {
X	     printf("Failed trying to initialize your terminal entry: unknown return code %d\n", i);
X	     dprint(1, (debugfile, "Initscreen returned unknown code: %d\n",
X		    i));
X	    }
X	    Raw(OFF);
X	    exit(1);	/* all the errors share this exit statement */
X	  }
X
X	if (debug < 5) {	/* otherwise let the system trap 'em! */
X	  signal(SIGINT,  SIG_IGN);
X	  signal(SIGQUIT, quit_signal);		/* Quit signal 	            */
X	  signal(SIGTERM, term_signal); 	/* Terminate signal         */
X	  signal(SIGILL,  ill_signal);		/* Illegal instruction      */
X	  signal(SIGFPE,  fpe_signal);		/* Floating point exception */
X	  signal(SIGBUS,  bus_signal);		/* Bus error  		    */
X	  signal(SIGSEGV, segv_signal);		/* Segmentation Violation   */
X	  signal(SIGHUP,  hup_signal);		/* HangUp (line dropped)    */
X	}
X	else {
X	  dprint(3,(debugfile,
X  "\n*** Elm-Internal Signal Handlers Disabled due to debug level %d ***\n\n",
X		    debug));
X	}
X	
X	signal(SIGALRM, alarm_signal);		/* Process Timer Alarm	    */
X	signal(SIGPIPE, pipe_signal);		/* Illegal Pipe Operation   */
X#ifdef SIGTSTP
X	signal(SIGTSTP, sig_user_stop);		/* Suspend signal from tty  */
X	signal(SIGCONT, sig_return_from_user_stop);	/* Continue Process */
X#endif
X
X	get_term_chars();
X	
X	gethostname(hostname, sizeof(hostname));
X
X#ifdef BSD
X	if ((cp = getenv("USER")) == NULL)
X#else
X	if ((cp = getenv("LOGNAME")) == NULL)
X#endif
X	  if ((cp = getlogin()) == NULL)
X	    cuserid(username);
X	  else
X	    strcpy(username, cp);
X	else
X	  strcpy(username, cp);
X
X	/* now let's get the full username.. */
X
X	if ((pass = getpwnam(username)) == NULL) {
X	  error("Couldn't read password entry??");
X	  strcpy(full_username, username);
X	}
X	else {
X	  /* fix for this section from Don Joslyn of Nova University */
X	  for (i=0,j=0; pass->pw_gecos[i] != '\0' && pass->pw_gecos[i] != ',';
X	       i++)
X	      if (pass->pw_gecos[i] == '&') {
X	        full_username[j] = '\0';
X	        strcat(full_username, expand_logname());
X	        j = strlen(full_username);
X	      }
X	      else
X	        full_username[j++] = pass->pw_gecos[i];
X	  full_username[j] = '\0'; 
X	}
X
X	if ((cp = getenv("EDITOR")) == NULL)
X	  strcpy(editor,default_editor);
X	else
X	  strcpy(editor, cp);
X	strcpy(alternative_editor, editor);	/* this one can't be changed! */
X
X	if (! mail_only) {
X	  mailbox[0] = '\0';
X	  strcpy(prefixchars, "> "); 	/* default message prefix */
X	  sprintf(calendar_file, "%s/%s", home, dflt_calendar_file);
X	}
X
X	local_signature[0] = remote_signature[0] = '\0';	/* NULL! */
X
X	read_rc_file();		/* reading the .elm/elmrc next... */
X
X	/** now try to expand the specified filename... **/
X
X	if (strlen(infile) > 0) {
X	  (void) expand_filename(infile);
X	  if (check_size)
X	    if(check_mailfile_size() != 0) {
X		Raw(OFF);
X		exit(0);
X	    }
X	  if ((errno = can_access(infile, READ_ACCESS))) {
X	    dprint(1, (debugfile,
X		  "Error: given file %s as mailbox - unreadable (%s)!\n", 
X		  infile, error_name(errno)));
X	    fprintf(stderr,"Can't open mailbox '%s' for reading!\n", infile);
X	    Raw(OFF);
X	    exit(1);
X	  }
X	} else {
X	  if (check_size) {
X	    if(check_mailfile_size() != 0) {
X		Raw(OFF);
X		exit(0);
X	    }
X	  }
X	}
X
X	/** check to see if the user has defined a LINES or COLUMNS
X	    value different to that in the termcap entry (for
X	    windowing systems, of course!) **/
X
X	ScreenSize(&LINES, &COLUMNS);
X
X	if ((cp = getenv("LINES")) != NULL && isdigit(*cp)) {
X	  sscanf(cp, "%d", &LINES);
X	  LINES -= 1;	/* kludge for HP Window system? ... */
X	}
X
X	if ((cp = getenv("COLUMNS")) != NULL && isdigit(*cp))
X	  sscanf(cp, "%d", &COLUMNS);
X
X	/** fix the shell if needed **/
X
X	if (shell[0] != '/') {
X	   sprintf(buffer, "/bin/%s", shell);
X	   strcpy(shell, buffer);
X	}
X
X	if (! mail_only) {
X	  mailbox_defined = (mailbox[0] != '\0'); 
X
X	  /* get the cursor control keys... */
X
X	  cursor_control = FALSE;
X
X	  if ((cp = return_value_of("ku")) != NULL)
X	    {
X	    strcpy(up, cp);
X	    if ((cp = return_value_of("kd")) == NULL)
X	      cursor_control = FALSE;
X	    else
X	    {
X	      strcpy(down, cp);
X	      cursor_control = TRUE;
X	      transmit_functions(ON);
X	    }
X	  }
X
X	  strcpy(start_highlight, "->");
X	  end_highlight[0] = '\0';
X
X	  if (!arrow_cursor) {	/* try to use inverse bar instead */
X	    if ((cp = return_value_of("so")) != NULL) {
X	      strcpy(start_highlight, cp);
X	      if ((cp = return_value_of("se")) == NULL)
X	        strcpy(start_highlight, "->");
X	      else {
X	        strcpy(end_highlight, cp);
X	        has_highlighting = TRUE;
X	      }
X	    }
X	  }
X	}
X
X	/** allocate the first KLICK headers... **/
X
X	if ((header_table = (struct header_rec *) malloc(KLICK * 
X	     sizeof(struct header_rec))) == NULL) {
X	   fprintf(stderr,"\n\r\n\rCouldn't allocate initial headers!\n\r\n");
X	   leave();
X	}
X	max_headers = KLICK;		/* we have those preallocated */
X
X	/** now cruise along... **/
X
X	if (! mail_only) {
X	  if (mini_menu)
X	    headers_per_page = LINES - 13;
X	  else
X	    headers_per_page = LINES -  8;	/* 5 more headers! */
X
X	  newmbox(1,FALSE, TRUE);	/* read in the mailbox! */
X	}
X
X#ifdef DEBUG
X	if (debug >= 2 && debug < 10) {
X	  fprintf(debugfile,
X"hostname = %-20s \tusername = %-20s \tfullname = %-20s\n",
X	         hostname, username, full_username);
X
X	  fprintf(debugfile,
X"home     = %-20s \teditor   = %-20s \tmailbox  = %-20s\n",
X		 home, editor, mailbox);
X
X	  fprintf(debugfile,
X"infile   = %-20s \tfolders  = %-20s \tprintout = %-20s\n",
X		 infile, folders, printout);
X	
X	  fprintf(debugfile,
X"savefile = %-20s \tprefix   = %-20s \tshell    = %-20s\n\n",
X		savefile, prefixchars, shell);
X	
X	  if (signature)
X	    fprintf(debugfile,
X		 "local-signature = \"%s\" and \tremote-signature = \"%s\"\n\n",
X	  	  local_signature, remote_signature);
X	}
X#endif
X}
X
Xget_term_chars()
X{
X	/** This routine sucks out the special terminal characters
X	    ERASE and KILL for use in the input routine.  The meaning 
X            of the characters are (dare I say it?) fairly obvious... **/
X
X#ifdef BSD
X	struct sgttyb term_buffer;
X
X# define TCGETA	TIOCGETP
X
X#else 
X	struct termio term_buffer;
X#endif
X
X	if (ioctl(STANDARD_INPUT, TCGETA, &term_buffer) == -1) {
X	  dprint(1, (debugfile,
X		   "Error: %s encountered on ioctl call (get_term_chars)\n", 
X		   error_name(errno)));
X	  /* set to defaults for terminal driver */
X	  backspace = BACKSPACE;
X	  kill_line = ctrl('U');
X	}
X	else {
X#ifdef BSD
X	  backspace = term_buffer.sg_erase;
X	  kill_line = term_buffer.sg_kill;
X#else
X	  backspace = term_buffer.c_cc[VERASE];
X	  kill_line = term_buffer.c_cc[VKILL];
X#endif
X	}
X}
X
Xchar *expand_logname()
X{
X	/** Return logname in a nice format (for expanding "&" in the
X	    /etc/passwd file) **/
X
X	static char buffer[SLEN];
X	register int i;
X
X	if (strlen(username) == 0)
X	  buffer[0] = '\0';
X	else {
X	  buffer[0] = toupper(username[0]);
X
X	  for (i=1; username[i] != '\0'; i++)
X	    buffer[i] = tolower(username[i]);
X
X	  buffer[i] = '\0';
X	}
X
X	return( (char *) buffer);	
X}
SHAR_EOF
chmod 0444 src/init.c || echo "restore of src/init.c fails"
echo "x - extracting src/leavembox.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/leavembox.c &&
X
Xstatic char rcsid[] = "@(#)$Id: leavembox.c,v 2.2 88/09/15 20:28:45 syd Exp $";
X
X/*******************************************************************************
X *  The Elm Mail System  -  $Revision: 2.2 $   $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:	leavembox.c,v $
X * Revision 2.2  88/09/15  20:28:45  syd
X * checked in with -k by syd at 88.09.15.20.28.45.
X * 
X * 14 Sep 88 Chip Rosenthal <chip@vector>
X * This file contains the patches for Elm 2.1b to run on XENIX System V.
X * The general issues with running Elm on such a machine are:
X *
X * 88/09/01 Rob Bernardo <gatech!pbhyf.PacBell.COM!rob>
SHAR_EOF
echo "End of part 13"
echo "File src/leavembox.c is continued in part 14"
echo "14" > 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