[comp.sources.unix] v18i096: Elm mail system, release 2.2, Part17/24

rsalz@uunet.uu.net (Rich Salz) (04/13/89)

Submitted-by: dsinc!syd@uunet.UU.NET (Syd Weinstein)
Posting-number: Volume 18, Issue 96
Archive-name: elm2.2/part17

#!/bin/sh
# this is part 17 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file src/mailmsg2.c continued
#
CurArch=17
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
     exit 1; fi
( read Scheck
  if test "$Scheck" != $CurArch
  then echo "Please unpack part $Scheck next!"
       exit 1;
  else exit 0; fi
) < s2_seq_.tmp || exit 1
echo "x - Continuing file src/mailmsg2.c"
sed 's/^X//' << 'SHAR_EOF' >> src/mailmsg2.c
X	    that...
X	    Return TRUE if the main part of the screen has been changed
X	    (useful for knowing whether a redraw is needed.
X	**/
X
X	FILE *reply, *real_reply; /* second is post-input buffer */
X	char *whole_msg_file, *tempnam();
X	char filename[SLEN], filename2[SLEN], fname[SLEN], copy_file[SLEN],
X             very_long_buffer[VERY_LONG_STRING], mailerflags[NLEN];
X	int ch;
X	register int retransmit = FALSE; 
X	int      already_has_text = FALSE;		/* we need an ADDRESS */
X	int	 need_redraw = 0;
X
X	static int cancelled_msg = 0;
X
X	dprint(4, (debugfile, "\nMailing to \"%s\" (with%s editing)\n",
X		  expanded_to, edit_message? "" : "out"));
X	
X	gotten_key = 0;		/* ignore previously gotten encryption key */
X
X	/** first generate the temporary filename **/
X
X	sprintf(filename,"%s%d",temp_file, getpid());
X
X	/** if possible, let's try to recall the last message? **/
X
X	if (! batch_only && copy_msg != FORM && user_level != 0)
X	  retransmit = recall_last_msg(filename, copy_msg, &cancelled_msg, 
X		       &already_has_text);
X
X	/** if we're not retransmitting, create the file.. **/
X
X	if (! retransmit)
X	  if ((reply = fopen(filename,"w")) == NULL) {
X	    dprint(1, (debugfile, 
X               "Attempt to write to temp file %s failed with error %s (mail)\n",
X		 filename, error_name(errno)));
X	    if(batch_only)
X	      printf("Could not create file %s (%s).\n",filename,
X		 error_name(errno));
X	    else
X	      error2("Could not create file %s (%s).",filename,
X		 error_name(errno));
X	    return(need_redraw);
X	  }
X
X	chown (filename, userid, groupid);
X
X	/* copy the message from standard input */
X	if (batch_only) {
X	  while (fgets(very_long_buffer, VERY_LONG_STRING, stdin) != NULL) 
X	    fprintf(reply, "%s", very_long_buffer);
X	}
X
X	if (copy_msg == FORM) {
X	  sprintf(fname, "%s%d", temp_form_file, getpid());
X	  fclose(reply);	/* we can't retransmit a form! */
X	  if (access(fname,ACCESS_EXISTS) != 0) {
X	    if(batch_only)
X	      printf("Couldn't find forms file!\n");
X	    else
X	      error("Couldn't find forms file!");
X	    return(need_redraw);
X	  }
X	  dprint(4, (debugfile, "-- renaming existing file %s to file %s --\n",
X		  fname, filename));
X	  rename(fname, filename);
X	}
X	else if (copy_msg && ! retransmit)    /* if retransmit we have it! */
X	  if (edit_message) {
X	    copy_message(prefixchars, reply, noheader, FALSE, FALSE);
X	    already_has_text = TRUE;	/* we just added it, right? */
X	  }
X	  else
X	    copy_message("", reply, noheader, FALSE, FALSE);
X
X	if (!batch_only && !retransmit && copy_msg != FORM) {
X	  char *sig;
X
X	  if (chloc(expanded_to, '!') == -1 && chloc(expanded_to, '@') == -1)
X	    sig = local_signature;
X	  else
X	    sig = remote_signature;
X
X	  if (sig[0]) {
X	    fprintf(reply, "\n-- \n");  /* News 2.11 compatibility? */
X	    if (sig[0] != '/')
X	      sprintf(filename2, "%s/%s", home, sig);
X	    else
X	      strcpy(filename2, sig);
X	    (void) append(reply, filename2);
X	    already_has_text = TRUE;  /* added signature... */
X	  }
X	}
X
X	if (! retransmit && copy_msg != FORM)
X	  if (reply != NULL)
X	    (void) fclose(reply);	/* on replies, it won't be open! */
X
X	/** Edit the message **/
X
X	if (edit_message)
X	  create_readmsg_file();	/* for "readmsg" routine */
X
X	ch = edit_message? 'e' : ' ';	/* drop through if needed... */
X
X	/* calculate default save_file name */
X	if(auto_cc) {
X	  if(save_by_name)
X	    strcpy(copy_file, "=");	/* signals save by 'to' logname */
X	  else
X	    strcpy(copy_file, "<");	/* signals save to sentmail */
X	} else *copy_file = '\0';	/* signals to not save a copy */
X
X
X	if (! batch_only) {
X	  do {
X	    switch (ch) {
X	      case 'e': if (edit_the_message(filename, already_has_text)) {
X			  cancelled_msg = TRUE;
X			  return(need_redraw);
X			}
X			need_redraw++;
X			break;
X
X	      case 'c': need_redraw += name_copy_file(copy_file);
X			break;
X
X	      case 'h': edit_headers();
X			need_redraw++;
X			break;
X
X	      default : /* do nothing */ ;
X	    }
X
X	    /** ask that silly question again... **/
X  
X	    if ((ch = verify_transmission(filename, &form)) == 'f') {
X	      cancelled_msg = TRUE;
X	      return(need_redraw);
X	    }
X
X	  } while (ch != 's');
X
X	  if (form == YES) 
X	    if (format_form(filename) < 1) {
X	      cancelled_msg = TRUE;
X	      return(need_redraw);
X	    }
X
X	  if ((reply = fopen(filename,"r")) == NULL) {
X	      dprint(1, (debugfile,
X	    "Attempt to open file %s for reading failed with error %s (mail)\n",
X                filename, error_name(errno)));
X	      error1("Could not open reply file (%s).", error_name(errno));
X	      return(need_redraw);
X	  }
X	}
X	else if ((reply = fopen(filename,"r")) == NULL) {
X	  dprint(1, (debugfile, 
X	    "Attempt to open file %s for reading failed with error %s (mail)\n",
X             filename, error_name(errno)));
X	  printf("Could not open reply file (%s).\n", error_name(errno));
X	  return(need_redraw);
X	}
X
X	cancelled_msg = FALSE;	/* it ain't cancelled, is it? */
X
X	/** ask about bounceback if the user wants us to.... **/
X
X	if (uucp_hops(to) > bounceback && bounceback > 0 && copy_msg != FORM) 
X	  if (verify_bounceback() == TRUE) {
X	    if (strlen(cc) > 0) strcat(expanded_cc, ", ");
X	    strcat(expanded_cc, bounce_off_remote(to));
X	  }
X
X	/** grab a copy if the user so desires... **/
X
X	if (*copy_file) /* i.e. if copy_file contains a name */
X	  save_copy(expanded_to, expanded_cc, expanded_bcc,
X	       filename, copy_file, form);
X
X	/** write all header information into whole_msg_file **/
X
X	if((whole_msg_file=tempnam(temp_dir, "snd.")) == NULL) {
X	  dprint(1, (debugfile, "couldn't make temp file nam! (mail)\n"));
X	  if(batch_only)
X	    printf("Sorry - couldn't make temp file name!\n");
X	  else if(mail_only)
X	    error("Sorry - couldn't make temp file name.");
X	  else
X	    set_error("Sorry - couldn't make temp file name.");
X	  return(need_redraw);
X	}
X
X	/** try to write headers to new temp file **/
X
X	dprint(6, (debugfile, "Composition file='%s' and mail buffer='%s'\n", 
X		    filename, whole_msg_file));
X
X	dprint(2,(debugfile,"--\nTo: %s\nCc: %s\nBcc: %s\nSubject: %s\n---\n", 
X		  expanded_to, expanded_cc, expanded_bcc, subject));
X
X	if ((real_reply=
X	   write_header_info(whole_msg_file, expanded_to,
X	     expanded_cc, expanded_bcc, form == YES, FALSE)) == NULL) {
X
X	  /** IT FAILED!!  MEIN GOTT!  Use a dumb mailer instead! **/
X
X	  dprint(3, (debugfile, "** write_header failed: %s\n", 
X		 error_name(errno)));
X
X	  if (cc[0] != '\0')  		/* copies! */
X	    sprintf(expanded_to,"%s %s", expanded_to, expanded_cc);
X
X	  sprintf(very_long_buffer, "( (%s -s \"%s\" %s ; %s %s) & ) < %s",
X                  mailx, subject, strip_parens(strip_commas(expanded_to)), 
X		  remove_cmd, filename, filename);
X
X	  if(batch_only)
X	    printf("Message sent using dumb mailer %s.\n", mailx);
X	  else
X	    error1("Message sent using dumb mailer %s.", mailx);
X	  sleep(2);	/* ensure time to see this prompt! */
X
X	}
X	else {
X	  copy_message_across(reply, real_reply, FALSE);
X
X	  fclose(real_reply);
X
X	  if (cc[0] != '\0')  				         /* copies! */
X	    sprintf(expanded_to,"%s %s", expanded_to, expanded_cc);
X
X	  if (bcc[0] != '\0') {
X	    strcat(expanded_to, " ");
X	    strcat(expanded_to, expanded_bcc);
X	  }
X
X	  if (strcmp(sendmail, mailer) == 0
X#ifdef SITE_HIDING
X	      && ! is_a_hidden_user(username))
X#else
X	     					)
X#endif
X		
X	     strcpy(mailerflags, (sendmail_verbose ? smflagsv : smflags));
X	  else
X	     mailerflags[0] ='\0';
X
X	  sprintf(very_long_buffer,"( (%s %s %s ; %s %s) & ) < %s", 
X		mailer, mailerflags, strip_parens(strip_commas(expanded_to)), 
X		remove_cmd, whole_msg_file, whole_msg_file);
X	}
X	
X	fclose(reply);
X
X	if(batch_only)
X	  printf("Sending mail...\n");
X	else {
X	  PutLine0(LINES,0,"Sending mail...");
X	  CleartoEOLN();
X	}
X
X	system_call(very_long_buffer, SH, FALSE);
X
X	/* Unlink temp file now.
X	 * This is a precaution in case the message was encrypted.
X	 * I.e. even though this file is readable by the owner only,
X	 * encryption is supposed to hide things even from someone
X	 * with root privelges. The best we can do is not let this
X	 * file just hang after we're finished with it.
X	 */
X	(void)unlink(filename);
X
X	if(batch_only)
X	  printf("Mail sent!\n");
X	else if(mail_only)
X	  error("Mail sent!");
X	else
X	  set_error("Mail sent!");
X
X	return(need_redraw);
X}
X
Xmail_form(address, subj)
Xchar *address, *subj;
X{
X	/** copy the appropriate variables to the shared space... */
X
X	strcpy(subject, subj);
X	strcpy(to, address);
X	strcpy(expanded_to, address);
X
X	return(mail(FORM, NO, NO));
X}
X
Xint
Xrecall_last_msg(filename, copy_msg, cancelled_msg, already_has_text)
Xchar *filename;
Xint  copy_msg, *cancelled_msg, *already_has_text;
X{
X	char ch;
X
X	/** If filename exists and we've recently cancelled a message,
X	    the ask if the user wants to use that message instead!  This
X	    routine returns TRUE if the user wants to retransmit the last
X	    message, FALSE otherwise...
X	**/
X
X	register int retransmit = FALSE;
X
X	if (access(filename, EDIT_ACCESS) == 0 && *cancelled_msg) {
X	  Raw(ON);
X	  CleartoEOLN();
X	  if (copy_msg)
X	    PutLine1(LINES-1,0,"Recall last kept message instead? (y/n) y%c",
X		     BACKSPACE);
X	  else
X	    PutLine1(LINES-1,0,"Recall last kept message? (y/n) y%c", 
X		     BACKSPACE);
X	  fflush(stdout);
X	  ch = ReadCh();
X	  if (tolower(ch) != 'n') {
X	    Write_to_screen("Yes.",0);	
X            retransmit++;
X	    *already_has_text = TRUE;
X	  }
X	  else 
X	    Write_to_screen("No.",0);	
X
X	  fflush(stdout);
X
X	  *cancelled_msg = 0;
X	}
X
X	return(retransmit);
X}
X
Xint
Xverify_transmission(filename, form_letter)
Xchar *filename;
Xint  *form_letter;
X{
X	/** Ensure the user wants to send this.  This routine returns
X	    the character entered.  Modified compliments of Steve Wolf 
X	    to add the'dead.letter' feature.
X	    Also added form letter support... 
X	**/
X
X	FILE *deadfd, *messagefd;
X	char ch, buffer[SLEN], fname[SLEN];
X	int x_coord, y_coord;
X
X	while(1) {
X	  /* clear bottom part of screen */
X	  MoveCursor(LINES-2,0);
X	  CleartoEOS();
X
X	  /* display prompt and menu according to
X	   * user level and what's available on the menu */
X	  if (user_level == 0) {
X	    PutLine0(LINES-2,0,
X      "Please choose one of the following options by parenthesized letter: s");
X	    GetXYLocation(&x_coord, &y_coord);
X	    y_coord--;	/* backspace over default answer */
X	    Centerline(LINES-1,
X	      "e)dit message, edit h)eaders, s)end it, or f)orget it.");
X	  } else {
X	    PutLine0(LINES-2, 0, "And now: s");
X	    GetXYLocation(&x_coord, &y_coord);
X	    y_coord--;	/* backspace over default answer */
X	    if (*form_letter == PREFORMATTED)  {
X	Centerline(LINES-1, "Choose h)eaders, s)end, c)opy file, or f)orget.");
X	    } else if (*form_letter == YES) {
X	      Centerline(LINES-1,
X		"Choose e)dit form, h)eaders, s)end, c)opy file, or f)orget.");
X	    } else if (*form_letter == MAYBE)  {
X	      Centerline(LINES-1,
X  "Choose e)dit message, h)eaders, m)ake form, s)end, c)opy file, or f)orget.");
X	    } else {
X	      Centerline(LINES-1,
X	      "Choose e)dit message, h)eaders, s)end, c)opy file, or f)orget.");
X	    }
X	  }
X
X	  /* wait for answer */
X	  fflush(stdin);
X	  fflush(stdout);
X	  Raw(ON);	/* double check... testing only... */
X	  MoveCursor(x_coord, y_coord);
X	  ch = ReadCh();
X	  ch = tolower(ch);
X
X	  /* process answer */
X	  switch (ch) {
X	     case 'f': Write_to_screen("Forget",0);
X		       if (mail_only) {
X			 /** try to save it as a dead letter file **/
X			 save_file_stats(fname);
X			 sprintf(fname, "%s/%s", home, dead_letter);
X			 if ((deadfd = fopen(fname,"a")) == NULL) {
X			   dprint(1, (debugfile,
X		   "\nAttempt to append to deadletter file '%s' failed: %s\n\r",
X			       fname, error_name(errno)));
X			   error("Message not saved, Sorry.");
X			 }
X			 else if ((messagefd = fopen(filename, "r")) == NULL) {
X			   dprint(1, (debugfile,
X			     "\nAttempt to read reply file '%s' failed: %s\n\r",
X				   filename, error_name(errno)));
X			   error("Message not saved, Sorry.");
X			 } else {
X			   /* if we get here we're okay for everything */
X			   while (fgets(buffer, SLEN, messagefd) != NULL)
X			     fputs(buffer, deadfd);
X
X			   fclose(messagefd);
X			   fclose(deadfd);
X			   restore_file_stats(fname);
X
X			   error1("Message saved in file \"$HOME/%s\".",
X			     dead_letter);
X
X			}
X		       } else set_error(
X          "Message kept. Can be restored at next f)orward, m)ail or r)eply.");
X		       break;
X
X	     case '\n' :
X	     case '\r' :
X	     case 's'  : Write_to_screen("Send",0);
X			 ch = 's';		/* make sure! */
X			 break;
X
X	     case 'm'  : if (*form_letter == MAYBE) {
X			   *form_letter = YES;
X		           switch (check_form_file(filename)) {
X			     case -1 : return('f');
X			     case 0  : *form_letter = MAYBE;  /* check later!*/
X				       error("No fields in form!");
X				       return('e');
X			     default : continue;
X	                   }
X			 }
X			 else {
X	                    Write_to_screen("%c??", 1, 07);	/* BEEP */
X			    sleep(1);
X		            continue;
X	                 }
X	     case 'e'  :  if (*form_letter != PREFORMATTED) {
X			    Write_to_screen("Edit",0);
X	 	            if (*form_letter == YES) 
X			      *form_letter = MAYBE;
X	                  }
X			  else {
X	                    Write_to_screen("%c??", 1, 07);	/* BEEP */
X			    sleep(1);
X		            continue;
X	                 }
X			 break;
X
X	     case 'h'  : Write_to_screen("Headers",0);
X			 break;
X
X	     case 'c'  : Write_to_screen("Copy file",0);
X			 break;
X
X	     default   : Write_to_screen("%c??", 1, 07);	/* BEEP */
X			 sleep(1);
X		         continue;
X	   }
X
X	   return(ch);
X	}
X}
X
XFILE *
Xwrite_header_info(filename, long_to, long_cc, long_bcc, form, copy)
Xchar *filename, *long_to, *long_cc, *long_bcc;
Xint   form, copy;
X{
X	/** Try to open filedesc as the specified filename.  If we can,
X	    then write all the headers into the file.  The routine returns
X	    'filedesc' if it succeeded, NULL otherwise.  Added the ability
X	    to have backquoted stuff in the users .elmheaders file!
X	    If copy is TRUE, then treat this as the saved copy of outbound
X	    mail.
X	**/
X
X	char opentype[2];
X	long time(), thetime;
X	char *ctime();
X	static FILE *filedesc;		/* our friendly file descriptor  */
X
X#ifdef SITE_HIDING
X	char  buffer[SLEN];
X	int   is_hidden_user;		/* someone we should know about?  */
X#endif
X
X	char  *get_arpa_date();
X
X	if(copy)
X	    strcpy(opentype, "a");
X	else
X	    strcpy(opentype, "w");
X
X	save_file_stats(filename);
X	if ((filedesc = fopen(filename, opentype)) == NULL) {
X	  dprint(1, (debugfile,
X	    "Attempt to open file %s for writing failed! (write_header_info)\n",
X	     filename));
X	  dprint(1, (debugfile, "** %s - %s **\n\n", error_name(errno),
X		 error_description(errno)));
X	  error2("Error %s encountered trying to write to %s.", 
X		error_name(errno), filename);
X	  sleep(2);
X	  return(NULL);		/* couldn't open it!! */
X	}
X
X	restore_file_stats(filename);
X
X	if(copy) {	/* Add top line that mailer would add */
X	  thetime = time((long *) 0);
X	  fprintf(filedesc,"From %s %s", username, ctime(&thetime));
X	}
X
X#ifdef SITE_HIDING
X	if ( !copy && (is_hidden_user = is_a_hidden_user(username))) {
X	  /** this is the interesting part of this trick... **/
X	  sprintf(buffer, "From %s!%s %s\n",  HIDDEN_SITE_NAME,
X		  username, get_ctime_date());
X	  fprintf(filedesc, "%s", buffer);
X	  dprint(1,(debugfile, "\nadded: %s", buffer));
X	  /** so is this perverted or what? **/
X	}
X#endif
X
X
X	/** Subject moved to top of headers for mail because the
X	    pure System V.3 mailer, in its infinite wisdom, now
X	    assumes that anything the user sends is part of the 
X	    message body unless either:
X		1. the "-s" flag is used (although it doesn't seem
X		   to be supported on all implementations??)
X		2. the first line is "Subject:".  If so, then it'll
X		   read until a blank line and assume all are meant
X		   to be headers.
X	    So the gory solution here is to move the Subject: line
X	    up to the top.  I assume it won't break anyone elses program
X	    or anything anyway (besides, RFC-822 specifies that the *order*
X	    of headers is irrelevant).  Gahhhhh....
X	**/
X
X	fprintf(filedesc, "Subject: %s\n", subject);
X
X	  fprintf(filedesc, "To: %s\n", format_long(long_to, strlen("To:")));
X
X	fprintf(filedesc,"Date: %s\n", get_arpa_date());
X
X#ifndef DONT_ADD_FROM
X# ifdef SITE_HIDING
X	if (is_hidden_user)
X	  fprintf(filedesc,"From: %s <%s!%s!%s>\n", full_username,
X		  hostname, HIDDEN_SITE_NAME, username);
X	else
X# else
X#  ifdef  INTERNET
X#   ifdef  USE_DOMAIN
X	fprintf(filedesc,"From: %s <%s@%s%s>\n", full_username, 
X		username, hostname, hostdomain);
X#   else
X	fprintf(filedesc,"From: %s <%s@%s>\n", full_username,
X		username, hostname);
X#   endif
X#  else
X	fprintf(filedesc,"From: %s <%s!%s>\n", full_username,
X		hostname, username);
X#  endif
X# endif
X#endif
X
X	if (cc[0] != '\0')
X	    fprintf(filedesc, "Cc: %s\n", format_long(long_cc, strlen("Cc: ")));
X
X	if (copy && (bcc[0] != '\0'))
X	    fprintf(filedesc, "Bcc: %s\n", format_long(long_bcc, strlen("Bcc: ")));
X
X	if (strlen(action) > 0)
X	    fprintf(filedesc, "Action: %s\n", action);
X	
X	if (strlen(priority) > 0)
X	    fprintf(filedesc, "Priority: %s\n", priority);
X	
X	if (strlen(expires) > 0)
X	    fprintf(filedesc, "Expires: %s\n", expires);
X	
X	if (strlen(reply_to) > 0)
X	    fprintf(filedesc, "Reply-To: %s\n", reply_to);
X
X	if (strlen(in_reply_to) > 0)
X	    fprintf(filedesc, "In-Reply-To: %s\n", in_reply_to);
X
X	if (strlen(user_defined_header) > 0)
X	    fprintf(filedesc, "%s\n", user_defined_header);
X
X	add_mailheaders(filedesc);
X
X	if (form)
X	  fprintf(filedesc, "Content-Type: mailform\n");
X
X	fprintf(filedesc, "X-Mailer: ELM [version %s]\n\n", version_buff);
X
X	return((FILE *) filedesc);
X}
X
Xcopy_message_across(source, dest, copy)
XFILE *source, *dest;
Xint copy;
X{
X	/** Copy the message in the file pointed to by source to the
X	    file pointed to by dest.
X	    If copy is TRUE, treat as a saved copy of outbound mail. **/
X
X	int  crypted = FALSE;			/* are we encrypting?  */
X	int  encoded_lines = 0;			/* # lines encoded     */
X	char buffer[SLEN];			/* file reading buffer */
X
X	while (fgets(buffer, SLEN, source) != NULL) {
X	  if (buffer[0] == '[') {
X	    if (strncmp(buffer, START_ENCODE, strlen(START_ENCODE))==0)
X	      crypted = TRUE;
X	    else if (strncmp(buffer, END_ENCODE, strlen(END_ENCODE))==0)
X	      crypted = FALSE;
X	    else if ((strncmp(buffer, DONT_SAVE, strlen(DONT_SAVE)) == 0)
X	          || (strncmp(buffer, DONT_SAVE2, strlen(DONT_SAVE2)) == 0)) {
X	      if(copy) break;  /* saved copy doesn't want anything after this */
X	      else continue;   /* next line? */
X	    }
X	  }
X	  else if (crypted) {
X	    if (batch_only) {
X	      printf(
X		"Sorry. Cannot send encrypted mail in \"batch mode\".\n\r");
X	      leave();
X	    } else if (! gotten_key++)
X	      getkey(ON);
X	    else if (! encoded_lines)
X	      get_key_no_prompt();		/* reinitialize.. */
X	    encode(buffer);
X	    encoded_lines++;
X	  }
X
X	  if (copy && (strncmp(buffer, "From ", 5) == 0))
X	    /* Add in the > to a From on our copy */
X	    fprintf(dest, ">%s", buffer);
X
X	  else if (!copy && strcmp(buffer, ".\n") == 0)
X	    /* Because some mail transport agents take a lone period to
X	     * mean EOF, we add a blank space on outbound message.
X	     */
X	    fputs(". \n", dest);
X  	  else
X  	    fputs(buffer, dest);
X	} 
X	if (copy) fputs("\n", dest);	/* ensure a blank line at the end */
X}
X
Xint
Xverify_bounceback()
X{
X	char	ch;
X
X	/** Ensure the user wants to have a bounceback copy too.  (This is
X	    only called on messages that are greater than the specified 
X	    threshold hops and NEVER for non-uucp addresses.... Returns
X	    TRUE iff the user wants to bounce a copy back.... 
X	 **/
X
X	MoveCursor(LINES,0);
X	CleartoEOLN();
X	PutLine1(LINES,0, 
X	      "\"Bounce\" a copy off the remote machine? (y/n) y%c",
X	      BACKSPACE);
X	fflush(stdin);	/* wait for answer! */
X	fflush(stdout);
X	ch = ReadCh();
X	if (tolower(ch) != 'y') { 
X	  Write_to_screen("No.", 0);
X	  fflush(stdout);
X	  return(FALSE);
X	}
X	Write_to_screen("Yes.", 0);
X	fflush(stdout);
X
X	return(TRUE);
X}
SHAR_EOF
echo "File src/mailmsg2.c is complete"
chmod 0444 src/mailmsg2.c || echo "restore of src/mailmsg2.c fails"
echo "x - extracting src/mailtime.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/mailtime.c &&
X
Xstatic char rcsid[] = "@(#)$Id: mailtime.c,v 2.6 89/03/25 21:46:46 syd Exp $";
X
X/*******************************************************************************
X *  The Elm Mail System  -  $Revision: 2.6 $   $State: Exp $
X *
X * 			Copyright (c) 1986, 1987 Dave Taylor
X * 			Copyright (c) 1988, 1989 USENET Community Trust
X *******************************************************************************
X * Bug reports, patches, comments, suggestions should be sent to:
X *
X *	Syd Weinstein, Elm Coordinator
X *	elm@dsinc.UUCP			dsinc!elm
X *
X *******************************************************************************
X * $Log:	mailtime.c,v $
X * Revision 2.6  89/03/25  21:46:46  syd
X * Initial 2.2 Release checkin
X * 
X *
X ******************************************************************************/
X
X/** This set of routines is used to figure out when the user last read
X    their mail and to also figure out if a given message is new or not.
X
X**/
X
X#include "headers.h"
X
X#include <sys/types.h>
X#include <sys/stat.h>
X#ifdef BSD
X#  ifdef TMINSYS
X#    include <sys/time.h>
X#  else
X#    include <time.h>
X#    include <sys/timeb.h>
X#  endif
X#else
X#  include <time.h>
X#endif
X
Xresolve_received(entry)
Xstruct header_rec *entry;
X{
X	/** Entry has the data for computing the time and date the 
X	    message was received.  Fix it and return **/
X
X	switch (tolower(entry->month[0])) {
X	  case 'j' : if (tolower(entry->month[1]) == 'a')
X		       entry->received.month = JANUARY;
X		     else if (tolower(entry->month[2]) == 'n')
X	               entry->received.month = JUNE;
X		     else
X	               entry->received.month = JULY;
X	             break;
X	  case 'f' : entry->received.month = FEBRUARY;
X	 	     break;
X	  case 'm' : if (tolower(entry->month[2]) == 'r')
X	               entry->received.month = MARCH;
X		     else
X		       entry->received.month = MAY;
X	             break;
X	  case 'a' : if (tolower(entry->month[1]) == 'p')
X	               entry->received.month = APRIL;
X	             else
X	               entry->received.month = AUGUST;
X		     break;
X	  case 's' : entry->received.month = SEPTEMBER;
X		     break;
X	  case 'o' : entry->received.month = OCTOBER;
X		     break;
X	  case 'n' : entry->received.month = NOVEMBER;
X	  	     break;
X	  case 'd' : entry->received.month = DECEMBER;
X		     break;
X	}
X
X	sscanf(entry->day, "%d", &(entry->received.day));
X
X	sscanf(entry->year, "%d", &(entry->received.year));
X	if (entry->received.year > 100) entry->received.year -= 1900;
X
X	sscanf(entry->time, "%d:%d", &(entry->received.hour),
X	       &(entry->received.minute));
X}
SHAR_EOF
chmod 0444 src/mailtime.c || echo "restore of src/mailtime.c fails"
echo "x - extracting src/mkhdrs.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/mkhdrs.c &&
X
Xstatic char rcsid[] = "@(#)$Id: mkhdrs.c,v 2.7 89/03/25 21:46:48 syd Exp $";
X
X/*******************************************************************************
X *  The Elm Mail System  -  $Revision: 2.7 $   $State: Exp $
X *
X * 			Copyright (c) 1986, 1987 Dave Taylor
X * 			Copyright (c) 1988, 1989 USENET Community Trust
X *******************************************************************************
X * Bug reports, patches, comments, suggestions should be sent to:
X *
X *	Syd Weinstein, Elm Coordinator
X *	elm@dsinc.UUCP			dsinc!elm
X *
X *******************************************************************************
X * $Log:	mkhdrs.c,v $
X * Revision 2.7  89/03/25  21:46:48  syd
X * Initial 2.2 Release checkin
X * 
X *
X ******************************************************************************/
X
X/** This contains all the header generating routines for the ELM
X    program.
X
X**/
X
X#include "headers.h"
X
Xextern char in_reply_to[SLEN];
X
Xchar *strcpy();
Xunsigned long sleep();
X
Xgenerate_reply_to(msg)
Xint msg;
X{
X	/** Generate an 'in-reply-to' message... **/
X	char buffer[SLEN];
X
X
X	if (msg == -1)		/* not a reply! */
X	  in_reply_to[0] = '\0';
X	else {
X	  if (chloc(headers[msg]->from, '!') != -1)
X	    tail_of(headers[msg]->from, buffer, 0);
X	  else
X	    strcpy(buffer, headers[msg]->from);
X	  sprintf(in_reply_to, "%s; from \"%s\" at %s %s, %s %s",
X		  headers[msg]->messageid,
X		  buffer,
X		  headers[msg]->month,
X		  headers[msg]->day,
X		  headers[msg]->year,
X		  headers[msg]->time);
X	}
X}
X
Xadd_mailheaders(filedesc)
XFILE *filedesc;
X{
X	/** Add the users .mailheaders file if available.  Allow backquoting 
X	    in the file, too, for fortunes, etc...*shudder*
X	**/
X
X	FILE *fd;
X	char filename[SLEN], buffer[SLEN];
X
X	sprintf(filename, "%s/%s", home, mailheaders);
X
X	if ((fd = fopen(filename, "r")) != NULL) {
X	  while (fgets(buffer, SLEN, fd) != NULL)
X	    if (strlen(buffer) < 2) {
X	      dprint(2, (debugfile,
X	         "Strlen of line from .elmheaders is < 2 (write_header_info)"));
X	      error1("Warning: blank line in %s ignored!", filename);
X	      sleep(2);
X	    }
X	    else if (occurances_of(BACKQUOTE, buffer) >= 2) 
X	      expand_backquote(buffer, filedesc);
X	    else 
X	      fprintf(filedesc, "%s", buffer);
X
X	    fclose(fd);
X	}
X}
X
Xexpand_backquote(buffer, filedesc)
Xchar *buffer;
XFILE *filedesc;
X{
X	/** This routine is called with a line of the form:
X		Fieldname: `command`
X	    and is expanded accordingly..
X	**/
X
X	FILE *fd;
X	char command[SLEN], command_buffer[SLEN], fname[SLEN],
X	     prefix[SLEN];
X	register int i, j = 0;
X
X	for (i=0; buffer[i] != BACKQUOTE; i++)
X	  prefix[j++] = buffer[i];
X	prefix[j] = '\0';
X
X	j = 0;
X
X	for (i=chloc(buffer, BACKQUOTE)+1; buffer[i] != BACKQUOTE;i++)
X	  command[j++] = buffer[i];
X	command[j] = '\0';
X
X	sprintf(fname,"%s%d", temp_print, getpid());
X
X	sprintf(command_buffer, "%s > %s", command, fname);
X
X	system_call(command_buffer, SH, FALSE);
X
X	if ((fd = fopen(fname, "r")) == NULL) {
X	  error1("Backquoted command \"%s\" in elmheaders failed.", command);
X	  return;	
X	}
X
X	/* If we get a line that is less than 80 - length of prefix then we
X	   can toss it on the same line, otherwise, simply prepend each line
X	   *starting with this line* with a leading tab and cruise along */
X
X	if (fgets(command_buffer, SLEN, fd) == NULL) 
X	  fprintf(filedesc, prefix);
X	else {
X	  if (strlen(command_buffer) + strlen(prefix) < 80) 
X	    fprintf(filedesc, "%s%s", prefix, command_buffer);
X	  else
X	    fprintf(filedesc, "%s\n\t%s", prefix, command_buffer);
X	  
X	  while (fgets(command_buffer, SLEN, fd) != NULL) 
X	    fprintf(filedesc, "\t%s", command_buffer);
X	
X	  fclose(fd);
X	}
X
X	unlink(fname);	/* don't leave the temp file laying around! */
X}
SHAR_EOF
chmod 0444 src/mkhdrs.c || echo "restore of src/mkhdrs.c fails"
echo "x - extracting src/newmbox.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/newmbox.c &&
X
Xstatic char rcsid[] = "@(#)$Id: newmbox.c,v 2.35 89/03/29 09:07:09 syd Exp $";
X
X/*******************************************************************************
X *  The Elm Mail System  -  $Revision: 2.35 $   $State: Exp $
X *
X * 			Copyright (c) 1988, USENET Community Trust
X * 			Copyright (c) 1988, 1989 USENET Community Trust
X *******************************************************************************
X * Bug reports, patches, comments, suggestions should be sent to:
X *
X *	Syd Weinstein, Elm Coordinator
X *	elm@dsinc.UUCP			dsinc!elm
X *
X *******************************************************************************
X * $Log:	newmbox.c,v $
X * Revision 2.35  89/03/29  09:07:09  syd
X * Fix problem with assuming headers start file
X * From: Rob
X * 
X * Revision 2.34  89/03/25  21:46:49  syd
X * Initial 2.2 Release checkin
X * 
X *
X ******************************************************************************/
X
X/**  read new folder **/
X
X#include <ctype.h>
X#include "headers.h"
X
X#ifdef BSD
X#undef tolower		/* we have our own "tolower" routine instead! */
X#endif
X
X#include <sys/types.h>		
X#include <sys/stat.h>
X#include <errno.h>
X
X#ifdef BSD			/* Berkeley has library elsewhere... */
X#  ifdef TMINSYS
X#    include <sys/time.h>
X#  else
X#    include <time.h>
X#  endif
Xchar *malloc(), *realloc();
X#else
X#  include <time.h>
X#endif
X
Xextern int errno;
X
Xchar *error_name(), *error_description();
Xchar *malloc(), *realloc(), *strcpy(), *strncpy(), *strrchr(), *strchr();
Xunsigned long sleep();
Xvoid rewind();
Xvoid exit();
Xlong bytes();
X
Xint
Xnewmbox(new_file, adds_only)
Xchar *new_file;
Xint adds_only;
X{
X	/** Read a folder.
X
X	    new_file	- name of folder  to read. It is up to the calling
X			  function to make sure that the file can be
X			  read by the user. This is not checked in this
X			  function. The reason why it is not checked here
X			  is due to the situation where the user wants to
X			  change folders: the new folder must be checked
X			  for access *before* leaving the old one, which
X			  is before this function gets called.
X	    adds_only	- set if we only want to read newly added messages to
X				same old folder.
X
X	**/
X
X	int  same_file;
X	int  new_folder_type;
X	char new_tempfile[SLEN], buffer[SLEN];
X
X	/* determine type of new mailfile and calculate temp file name */
X	if((new_folder_type = get_folder_type(new_file)) == SPOOL)
X	  mk_temp_mail_fn(new_tempfile, new_file);
X	else
X	  *new_tempfile = '\0';
X
X	/* determine whether we are changing files */
X	same_file = !(strcmp(new_file, cur_folder));
X
X	/* If we are changing files and we are changing to a spool file,
X	 * make sure there isn't a temp file for it, because if
X	 * there is, someone else is using ELM to read the new file,
X	 * and we don't want to be reading it at the same time.
X	 */
X	if((new_folder_type == SPOOL) && (!same_file)) {
X	  if (access(new_tempfile, ACCESS_EXISTS) != -1) {
X	    if(folder_type != NO_NAME) ClearScreen();
X	    Centerline(15,
X	      "Hey! An instantiation of ELM is already reading this mail!");
X	    Centerline(17,
X	      "If this is in error, then you'll need to remove the file:");
X	    Centerline(18, new_tempfile);
X	    MoveCursor(LINES, 0);  /* so shell prompt upon exit is on newline */
X	    silently_exit();
X	  }
X	}
X
X	/* If we were reading a spool file and we are not just reading
X	 * in the additional new messages to the same file, we need to
X	 * remove the corresponding tempfile.
X	 */
X
X	if((folder_type == SPOOL) && !adds_only) {
X	  if (access(cur_tempfolder, ACCESS_EXISTS) != -1) {
X	    if (unlink(cur_tempfolder) != 0) {
X	      error2("Sorry, can't unlink the temp file %s [%s]!\n\r",
X	        cur_tempfolder, error_name(errno));
X	      silently_exit();
X	    }
X	  }
X	}
X
X	/* Okay! Now establish this new file as THE file */
X	strcpy(cur_folder, new_file);
X	folder_type = new_folder_type;
X	strcpy(cur_tempfolder, new_tempfile);
X
X	clear_error();
X	clear_central_message();
X
X	if (mailfile != NULL)
X	  (void) fclose(mailfile);  /* close it first, to avoid too many open */
X
X	if ((mailfile = fopen(cur_folder,"r")) == NULL)  {
X	  mailfile_size = 0;		/* must be empty folder */
X	  message_count = 0;
X	} else {
X	  read_headers(adds_only);
X	}
X
X	if(!same_file)		/* limit mode off if this is a new file */
X	  selected = 0;
X
X	dprint(1, (debugfile,
X	  "New folder %s type %s temp file %s (%s)\n", cur_folder, 
X	  (folder_type == SPOOL ? "spool" : "non-spool"),
X	  (*cur_tempfolder ? cur_tempfolder : "none"), "newmbox"));
X
X	return(0);
X}
X
Xint
Xget_folder_type(filename)
Xchar *filename;
X{
X	/** returns the type of mailfile filename is
X	    NO_NAME = no name
X	    SPOOL = consisting only of mailhome plus base file name
X		    (no intervening directory name)
X	    NON_SPOOL = a name that is not SPOOL type above
X	 **/
X
X	char *last_slash;
X
X	/* if filename is null or is of zero length */
X	if((filename == NULL) || (*filename == '\0'))
X	  return(NO_NAME);
X
X	/* if filename begins with mailhome,
X	 * and there is a slash in filename,
X	 * and there is a filename after it (i.e. last slash is not last char),
X	 * and the last character of mailhome is last slash in filename,
X	 * it's a spool file .
X	 */
X	if((first_word(filename, mailhome)) &&
X	  ((last_slash = strrchr(filename, '/')) != NULL) &&
X	  (*(last_slash+1) != '\0') &&
X	  (filename + strlen(mailhome) - 1 == last_slash))
X	    return(SPOOL);
X	/* if file name == default mailbox, its a spool file also
X	 * even if its not in the spool directory. (SVR4)
X	 */
X	if (strcmp(filename, defaultfile) == 0)
X	    return(SPOOL);
X
X	return(NON_SPOOL);
X}
X
Xmk_temp_mail_fn(tempfn, mbox)
Xchar *tempfn, *mbox;
X{
X	/** create in tempfn the name of the temp file corresponding to
X	    mailfile mbox. Mbox is presumed to be a file in mailhome;
X	    Strangeness may result if it is not!
X	 **/
X
X	char *cp;	/* will point to '/' preceding filename part of mbox */
X	strcpy(tempfn, temp_mbox);
X	if((cp = strrchr(mbox, '/')) != NULL)
X	  strcat(tempfn, cp+1);
X}
X
Xint
Xread_headers(add_new_only)
Xint add_new_only;
X{
X	/** Reads the headers into the headers[] array and leaves the
X	    file rewound for further I/O requests.   If the file being
X	    read is a mail spool file (ie incoming) then it is copied to
X	    a temp file and closed, to allow more mail to arrive during 
X	    the elm session.  If 'add_new_only' is set, the program will copy
X	    the status flags from the previous data structure to the new 
X	    one if possible and only read in newly added messages.
X	**/
X
X	FILE *temp;
X	struct header_rec *current_header = NULL;
X	char buffer[LONG_STRING], *c;
X	long fbytes = 0L, line_bytes = 0L;
X	register int line = 0, count = 0, another_count,
X	  subj = 0, copyit = 0, in_header = 0;
X	int count_x, count_y = 17, new_messages = 0, err;
X	int in_to_list = FALSE, forwarding_mail = FALSE, first_line = TRUE;
X
X	static int first_read = 0;
X
X	if (folder_type == SPOOL) {
X	  lock(INCOMING);	/* ensure no mail arrives while we do this! */
X	  if (! add_new_only) {
X	    if (access(cur_tempfolder, ACCESS_EXISTS) != -1) {
X	      /* Hey!  What the hell is this?  The temp file already exists? */
X	      /* Looks like a potential clash of processes on the same file! */
X	      unlock();				     /* so remove lock file! */
X	      error("What's this?  The temp folder already exists??");
X	      sleep(2);
X	      error("Ahhhh... I give up.");
X	      silently_exit();	/* leave without tampering with it! */
X	    }
X	    if ((temp = fopen(cur_tempfolder,"w")) == NULL) {
X	     err = errno;
X	     unlock();	/* remove lock file! */
X	     Raw(OFF);
X	     Write_to_screen(
X		     "\n\rCouldn't open file %s for use as temp file.\n\r",
X		     1, cur_tempfolder);
X	     Write_to_screen("** %s - %s. **\n\r", 2,
X		     error_name(err), error_description(err));
X	     dprint(1, (debugfile,
X                "Error: Couldn't open file %s as temp mbox.  errno %s (%s)\n",
X	         cur_tempfolder, error_name(err), "read_headers"));
X	     leave();
X	    }
X	   copyit++;
X	   chown(cur_tempfolder, userid, groupid);
X	   chmod(cur_tempfolder, 0700);	/* shut off file for other people! */
X	 }
X	 else {
X	   if ((temp = fopen(cur_tempfolder,"a")) == NULL) {
X	     err = errno;
X	     unlock();	/* remove lock file! */
X	     Raw(OFF);
X	     Write_to_screen(
X		     "\n\rCouldn't reopen file %s for use as temp file.\n\r",
X		     1, cur_tempfolder);
X	     Write_to_screen("** %s - %s. **\n\r", 2,
X		     error_name(err), error_description(err));
X	     dprint(1, (debugfile, 
X                "Error: Couldn't reopen file %s as temp mbox.  errno %s (%s)\n",
X	         cur_tempfolder, error_name(err), "read_headers"));
X	     emergency_exit();
X	    }
X	   copyit++;
X	  }
X	}
X
X	if (! first_read++) {
X	  ClearLine(LINES-1);
X	  ClearLine(LINES);
X	  if (add_new_only)
X	    PutLine2(LINES, 0, "Reading in %s, message: %d", cur_folder, 
X		     message_count);
X	  else
X	    PutLine1(LINES, 0, "Reading in %s, message: 0", cur_folder);
X	  count_x = LINES;
X          count_y = 22 + strlen(cur_folder);
X	}
X	else {
X	  count_x = LINES-2;
X	  PutLine0(LINES-2, 0, "Reading message: 0");
X	}
X
X	if (add_new_only) {
X	   if (fseek(mailfile, mailfile_size, 0) == -1) {
X	     err = errno;
X	     Write_to_screen(
X		"\n\rCouldn't seek to %ld (end of folder) in %s!\n\r", 2,
X	     	mailfile_size, cur_folder);	
X	     Write_to_screen("** %s - %s. **\n\r", 2,
X		     error_name(err), error_description(err));
X	     dprint(1, (debugfile,
X     "Error: Couldn't seek to end of folder %s: (offset %ld) Errno %s (%s)\n",
X	        cur_folder, mailfile_size, error_name(err), "read_headers"));
X	     emergency_exit();
X	   }
X	   count = message_count;		/* next available  */
X	   fbytes = mailfile_size;		/* start correctly */
X	}
X
X	/** find the size of the folder then unlock the file **/
X
X	mailfile_size = bytes(cur_folder);
X	unlock();
X
X	/** now let's copy it all across accordingly... **/
X
X	while (fbytes < mailfile_size) {
X
X	  if (fgets(buffer, LONG_STRING, mailfile) == NULL) break;
X
X	  if (copyit) fputs(buffer, temp);
X	  line_bytes = (long) strlen(buffer); 
X
X	  /* Fix below to increment line count ONLY if we got a full line.
X	   * Input lines longer than the fgets buffer size would
X	   * get counted each time a subsequent part of them was
X	   * read in. This meant that when the faulty line count was used
X	   * to display the message, part of the next message
X	   * was displayed at the end of the message.
X	   */
X	  if(buffer[strlen(buffer)-1] == '\n') line++;
X
X	  if (fbytes == 0L || first_line) { 	/* first line of file... */	
X	    if (folder_type == SPOOL) {
X	      if (first_word(buffer, "Forward to ")) {
X	        set_central_message("Mail being forwarded to %s", 
X                   (char *) (buffer + 11));
X	        forwarding_mail = TRUE;
X	      }
X	    }
X
X	    /** flush leading blank lines before next test... **/
X	    if (strlen(buffer) == 1) {
X	      fbytes++;
X	      continue;	
X	    }
X	    else
X	      first_line = FALSE;
X	      	
X	    if (! first_word(buffer, "From ") && !forwarding_mail) {
X	      PutLine0(LINES, 0,
X		  "\n\rFolder is corrupt!!  I can't read it!!\n\r\n\r");
X	      fflush(stderr);
X	      dprint(1, (debugfile, 
X			   "\n\n**** First mail header is corrupt!! ****\n\n"));
X	      dprint(1, (debugfile, "Line is;\n\t%s\n\n", buffer));
X              mail_only++;	/* to avoid leave() cursor motion */
X              leave();
X	    }
X	  }
X
X	  if (first_word(buffer,"From ")) {
X	
X	    /** allocate new header pointers, if needed... **/
X
X	    if (count >= max_headers) {
X	      struct header_rec **new_headers;
X	      int new_max;
X
X	      new_max = max_headers + KLICK;
X	      if (max_headers == 0) {
X		new_headers = (struct header_rec **)
X		  malloc(new_max * sizeof(struct header_rec *));
X	      }
X	      else {
X		new_headers = (struct header_rec **)
X		  realloc(headers, new_max * sizeof(struct header_rec *));
X	      }
X	      if (new_headers == NULL) {
X	        error1(
X      "\n\r\n\rCouldn't allocate enough memory! Message #%d.\n\r\n\r",
X			count);
X	        leave();
X	      }
X	      headers = new_headers;
X	      while (max_headers < new_max)
X		headers[max_headers++] = NULL;
X	    }
X	      
X	    /** allocate new header structure, if needed... **/
X
X	    if (headers[count] == NULL) {
X	      struct header_rec *h;
X
X	      if ((h = (struct header_rec *)
X			malloc(sizeof(struct header_rec))) == NULL) {
X	        error1(
X      "\n\r\n\rCouldn't allocate enough memory! Message #%d.\n\r\n\r",
X			count);
X	        leave();
X	      }
X	      headers[count] = h;
X	    }
X
X	    if (real_from(buffer, headers[count])) {
X	      current_header = headers[count];
X
X	      current_header->offset = (long) fbytes;
X	      current_header->index_number = count+1;
X	      if (! add_new_only || count >= message_count)  {
X		/* set default status - always 'visible'  - and
X		 * if a spool file, presume 'new', otherwise
X		 * 'read', for the time being until overridden
X		 * by a Status: header.
X		 * We presume 'read' for nonspool mailfile messages
X		 * to be compatible messages stored with older versions of elm,
X		 * which didn't support a Status: header.
X		 */
X		if(folder_type == SPOOL)
X		  current_header->status = VISIBLE | NEW | UNREAD;
X		else
X		  current_header->status = VISIBLE;
X	      }
X
X	      strcpy(current_header->subject, "");	/* clear subj    */
X	      strcpy(current_header->to, "");		/* clear to    */
X	      strcpy(current_header->mailx_status, "");	/* clear status flags    */
X	      current_header->encrypted = 0;		/* clear encrypted */
X	      current_header->exit_disposition = UNSET;
X	      current_header->status_chgd = FALSE;
X
X	      /* Set the number of lines for the _preceding_ message,
X	       * but only if there was a preceding message and
X	       * only if it wasn't calculated already. It would
X	       * have been calculated already if we are only
X	       * reading headers of new messages that have just arrived,
X	       * and the preceding message was one of the old ones.
X	       */
X	      if ((count) && (!add_new_only || count > message_count))
X	        headers[count-1]->lines = line;
X
X	      count++;
X	      subj = 0;
X	      line = 0;
X	      in_header = 1;
X	      PutLine1(count_x, count_y, "%d", count);
X	    } else if (count == 0) {
X	      /* if this is the first "From" in file but the "From" line is
X	       * not of the proper format, we've got a corrupt folder.
X	       */
X	      PutLine0(LINES, 0,
X		  "\n\rFolder is corrupt!!  I can't read it!!\n\r\n\r");
X	      fflush(stderr);
X	      dprint(1, (debugfile, 
X			   "\n\n**** First mail header is corrupt!! ****\n\n"));
X	      dprint(1, (debugfile, "Line is;\n\t%s\n\n", buffer));
X              mail_only++;	/* to avoid leave() cursor motion */
X              leave();
X	    }
X	  }
X	  else if (in_header) {
X	    if (first_word(buffer,">From:"))
X	      parse_arpa_who(buffer, current_header->from, FALSE);
X	    else if (first_word(buffer,">From")) 
X	      forwarded(buffer, current_header); /* return address */
X	    else if (first_word(buffer,"Subject:") ||
X		     first_word(buffer,"Subj:") ||
X		     first_word(buffer,"Re:")) {
X	      if (! subj++) {
X	        remove_first_word(buffer);
X	        copy_sans_escape(current_header->subject, buffer, STRING);
X		remove_possible_trailing_spaces(current_header->subject);
X	      }
X	    }
X	    else if (first_word(buffer,"From:"))
X	      parse_arpa_who(buffer, current_header->from, FALSE);
X
X	    else if (first_word(buffer, "Message-Id:") ||
X		     first_word(buffer, "Message-ID:")) {
X	      buffer[strlen(buffer)-1] = '\0';
X	      strcpy(current_header->messageid,
X		     (char *) buffer + 12);
X	    }
X
X	    else if (first_word(buffer, "Expires:"))
X	      process_expiration_date((char *) buffer + 9, 
X				      &(current_header->status));
X	    
X	    /** when it was sent... **/
X
X	    else if (first_word(buffer, "Date:")) 
X	      parse_arpa_date(buffer, current_header);
X
X	    /** some status things about the message... **/
X
X	    else if (first_word(buffer, "Priority:") || 
X		     first_word(buffer, "Importance: 2"))
X	      current_header->status |= URGENT;
X	    else if (first_word(buffer, "Sensitivity: 2"))
X	      current_header->status |= PRIVATE;
X	    else if (first_word(buffer, "Sensitivity: 3"))
X	      current_header->status |= CONFIDENTIAL;
X	    else if (first_word(buffer, "Content-Type: mailform"))
X	      current_header->status |= FORM_LETTER;
X	    else if (first_word(buffer, "Action:"))
X	      current_header->status |= ACTION;
X
X	    /** next let's see if it's to us or not... **/
X
X	    else if (first_word(buffer, "To:")) {
X	      in_to_list = TRUE;
X	      current_header->to[0] = '\0';	/* nothing yet */
X	      figure_out_addressee((char *) buffer +3, 
X				   current_header->to);
X	    }
X	    else if (first_word(buffer, "Status:")) {
X	      remove_first_word(buffer);
X	      strncpy(current_header->mailx_status, buffer, WLEN-1);
X	      current_header->mailx_status[WLEN-1] ='\0';
X
X	      c = strchr(current_header->mailx_status, '\n');
X	      if (c != NULL)
X		*c = '\0';
X	      remove_possible_trailing_spaces(current_header->mailx_status);
X
X	      /* Okay readjust the status. If there's an 'R', message
X	       * is read; if there is no 'R' but there is an 'O', message
X	       * is unread. In any case it isn't new because a new message
X	       * wouldn't have a Status: header.
X	       */
X	      if (strchr(current_header->mailx_status, 'R') != NULL)
X		current_header->status = VISIBLE;
X	      else if (strchr(current_header->mailx_status, 'O') != NULL)
X		current_header->status = VISIBLE | UNREAD;
X	    }
X
X	    else if (buffer[0] == LINE_FEED || buffer[0] == '\0') {
X	      if (in_header) {
X	        in_header = 0;	/* in body of message! */
X	        fix_date(current_header);
X	      }
X	    }
X	    else if (in_header) {
X	       if ((!whitespace(buffer[0])) && strchr(buffer, ':') == NULL) {
X	        in_header = 0;	/* in body of message! */
X	        fix_date(current_header);
X	      }
X	    }
X	    else if (in_to_list == TRUE) {
X	      if (whitespace(buffer[0]))
X	        figure_out_addressee(buffer, current_header->to);
X	      else in_to_list = FALSE;
X	    }
X	  }
X	  if (!in_header && first_word(buffer, START_ENCODE))
X	    current_header->encrypted = 1;
X	  fbytes += (long) line_bytes;
X	}
X
X	if (count)
X	  headers[count-1]->lines = line + 1;
X
X	if (folder_type == SPOOL) {
X	  unlock();	/* remove lock file! */
X	  fclose(mailfile);
X	  fclose(temp);
X	  if ((mailfile = fopen(cur_tempfolder,"r")) == NULL) {
X	    err = errno;
X	    MoveCursor(LINES,0);
X	    Raw(OFF);
X	    Write_to_screen(
X		   "\n\rAugh! Couldn't reopen %s as temp file.\n\r",
X	           1, cur_tempfolder);
X	    Write_to_screen("** %s - %s. **\n\r", 2, error_name(err),
X		   error_description(err));
X	    dprint(1, (debugfile,
X		  "Error: Reopening %s as temp file failed!  errno %s (%s)\n",
X	           cur_tempfolder, error_name(errno), "read_headers"));
X	    leave();
X	  }
X	}
X	else 
X          rewind(mailfile);
X
X	/* Sort folder *before* we establish the current message, so that
X	 * the current message is based on the post-sort order.
X	 * Note that we have to set the global variable message_count
X	 * before the sort for the sort to correctly keep the correct
X	 * current message if we are only adding new messages here. */
X
X	message_count = count;
X	sort_mailbox(count, 1);
X
X	/* Now lets figure what the current message should be.
X	 * If we are only reading in newly added messages from a mailfile
X	 * that already had some messages, current should remain the same.
X	 * If we have a folder of no messages, current should be zero.
X	 * Otherwise, if we have point_to_new on then the current message
X	 * is the first message of status NEW if there is one.
X	 * If we don't have point_to_new on or if there are no messages of
X	 * of status NEW, then the current message is the first message.
X	 */
X	if(!(add_new_only && current != 0)) {
X	  if(count == 0)
X	    current = 0;
X	  else {
X	    current = 1;
X	    if (point_to_new) {
X	      for(another_count = 0; another_count < count; another_count++) {
X		if(ison(headers[another_count]->status, NEW)) {
X		  current = another_count+1;
X		  break;	/* first one found give up */
X		}
X	      }
X	    }
X	  }
X	}
X        get_page(current);
X	return(count);
X}
SHAR_EOF
chmod 0444 src/newmbox.c || echo "restore of src/newmbox.c fails"
echo "x - extracting src/opt_utils.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/opt_utils.c &&
X
Xstatic char rcsid[] = "@(#)$Id: opt_utils.c,v 2.16 89/03/25 21:46:52 syd Exp $";
X
X/*******************************************************************************
X *  The Elm Mail System  -  $Revision: 2.16 $   $State: Exp $
X *
X * 			Copyright (c) 1986, 1987 Dave Taylor
X * 			Copyright (c) 1988, 1989 USENET Community Trust
X *******************************************************************************
X * Bug reports, patches, comments, suggestions should be sent to:
X *
X *	Syd Weinstein, Elm Coordinator
X *	elm@dsinc.UUCP			dsinc!elm
X *
X *******************************************************************************
X * $Log:	opt_utils.c,v $
X * Revision 2.16  89/03/25  21:46:52  syd
X * Initial 2.2 Release checkin
X * 
X *
X ******************************************************************************/
X
X/** This file contains routines that might be needed for the various
X     machines that the mailer can run on.  Please check the Makefile
X     for more help and/or information. 
X
X**/
X
X#include "headers.h"
X#include <ctype.h>
X
X#ifdef BSD
X# include <pwd.h>
X#undef tolower
X#undef toupper
X#endif
X
X#ifndef GETHOSTNAME
X#  include <sys/types.h>
X#  include <sys/utsname.h>
X#endif
X
X#ifndef GETHOSTNAME
X
Xgethostname(hostname,size) /* get name of current host */
Xchar *hostname;
SHAR_EOF
echo "End of part 17"
echo "File src/opt_utils.c is continued in part 18"
echo "18" > s2_seq_.tmp
exit 0

-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.