static char rcsid[] = "@(#)$Id: newmail.c,v 1.43 2006/05/30 16:33:21 hurtta Exp $";

/******************************************************************************
 *  The Elm (ME+) Mail System  -  $Revision: 1.43 $   $State: Exp $
 *
 *  Modified by: Kari Hurtta <hurtta+elm@posti.FMI.FI> 
 *                           (was hurtta+elm@ozone.FMI.FI)
 ******************************************************************************
 *  The Elm Mail System 
 *
 * 			Copyright (c) 1988-1992 USENET Community Trust
 * 			Copyright (c) 1986,1987 Dave Taylor
 *****************************************************************************/

/** This is actually two programs folded into one - 'newmail()' and
    'wnewmail()'.  They perform essentially the same function, to
    monitor the mail arriving in a set of/a mailbox or folder, but
    newmail is designed to run in background on a terminal, and
    wnewmail is designed to have a window of its own to run in.

    The main difference is that wnewmail checks for mail more often.

    The usage parameters are:

	-i <interval>  		how often to check for mail
				(default: 60 secs if newmail,
					  10 secs if wnewmail)

	<filename>		name of a folder to monitor
				(can prefix with '+'/'=', or can
			 	default to the incoming mailbox)

	<filename>=prefix	file to monitor, output with specified
				prefix when mail arrives.

    If we're monitoring more than one mailbox the program will prefix
    each line output (if 'newmail') or each cluster of mail (if 'wnewmail')
    with the basename of the folder the mail has arrived in.  In the 
    interest of exhaustive functionality, you can also use the "=prefix"
    suffix (eh?) to specify your own strings to prefix messages with.

    The output format is either:

	  newmail:
	     >> New mail from <user> - <subject>
	     >> Priority mail from <user> - <subject>

	     >> <folder>: from <user> - <subject>
	     >> <folder>: Priority from <user> - <subject>

	  wnewmail:
	     <user> - <subject>
	     Priority: <user> - <subject>

	     <folder>: <user> - <subject>
	     <folder>: Priority: <user> - <subject>\fR

**/

#include "elmutil.h"
#include "mboxlib.h"
#include "s_newmail.h"

DEBUG_VAR(Debug,__FILE__,"util");

#ifdef PWDINSYS
#  include <sys/pwd.h>
#else
#  include <pwd.h>
#endif
#include <sys/stat.h>

#ifdef BSD_TYPE
#  include <sys/timeb.h>
#endif

#ifdef I_UTIME
#  include <utime.h>
#endif
#ifdef I_SYSUTIME
#  include <sys/utime.h>
#endif

/**********
   Since a number of machines don't seem to bother to define the utimbuf
   structure for some *very* obscure reason.... 

   Suprise, though, BSD has a different utime() entirely...*sigh*
**********/

#define LINEFEED		(char) 10
#define BEGINNING		0			/* seek fseek(3S) */
#define DEFAULT_INTERVAL	60

#define MAX_FOLDERS		25		/* max we can keep track of */



/*
 * The "read_headers()" and "show_header()" routines use a (struct header_rec)
 * to hold the header information.  This structure does not have a flag to
 * save the message priority status.  We don't need the "encrypted" flag in
 * the structure, so we will use that instead.
 */
#define priority encrypted

#define metachar(c)	(c == '+' || c == '=' || c == '%')

struct folder_struct {
    struct folder_info *F;
    char	prefix[NLEN];	
    int		access_error;
} folder_list[MAX_FOLDERS] = {0};

static int read_headers P_((register struct folder_struct *cur_folder,
			    struct read_folder_state * read_state_ptr));

static void add_folder P_((char *name));
static void add_default_folder P_((void));
static void show_header P_((struct header_rec *hdr,
			    struct folder_struct *cur_folder));
static void usage P_((char *name));
static void pad_prefixes P_((void));

int  interval_time,		/* how long to sleep between checks */
     in_window = 0,		/* are we running as 'wnewmail'?    */
     total_folders = 0,		/* # of folders we're monitoring    */
     print_prefix = 0,		/* force printing of prefix	    */
     current_folder = 0;	/* struct pointer for looping       */

#ifdef PIDCHECK
int  parent_pid;		/* See if sucide should be attempt  */
#endif /* PIDCHECK */

#include <errno.h>
#ifndef ANSI_C
extern int errno;
#endif       

#if defined(BSD_TYPE) && !defined(UTIMBUF)
        time_t utime_buffer[2];         /* utime command */

#else
        struct utimbuf utime_buffer;    /* utime command */
#endif

static char	*priority_to,	/* pointer to Priority to text	*/
		*priority_text,	/* pointer to priority text	*/
		*To_text,	/* pointer To to text		*/
		*priority_mail,	/* pointer to priority mail	*/
		*mail_text,	/* pointer to mail text		*/
		*to_text,	/* pointer to to text		*/
		*from_text;	/* pointer to from text		*/

static void expand_filename P_((char *, char *, int)); /* Prototype */

#ifndef	ANSI_C
extern struct passwd *getpwuid();
#endif

static void save_acc P_((char *name));


int main P_((int argc, char *argv[]));
int main(argc, argv)
     int argc;
     char *argv[];
{
	extern char *optarg;
	extern int   optind;
	char *ptr;
	int c, i;
	struct folder_struct *cur_folder;

	locale_init();

#if DEBUG
	init_debugfile("NEWMAIL");
#endif
	user_init();

	init_mboxlib();
	init_defaults();
	read_rc_file(0);

	/* Get the No subject string */

	priority_to = catgets(elm_msg_cat, NewmailSet,
	   NewmailInWinPriorityTo, "Priority to ");
	priority_text = catgets(elm_msg_cat, NewmailSet,
	      NewmailInWinPriority, "Priority ");
	To_text = catgets(elm_msg_cat, NewmailSet, NewmailInWinTo, "To ");
	priority_mail = catgets(elm_msg_cat, NewmailSet,
	   NewmailPriorityMail, "Priority mail ");
	mail_text = catgets(elm_msg_cat, NewmailSet, NewmailMail, "Mail ");
	to_text = catgets(elm_msg_cat, NewmailSet, NewmailTo, "to ");
	from_text = catgets(elm_msg_cat, NewmailSet, NewmailFrom, "from ");

#ifdef PIDCHECK				/* This will get the pid that         */
	parent_pid = getppid();		/* started the program, ie: /bin/sh   */
					/* If it dies for some reason (logout)*/
#endif /* PIDCHECK */			/* Then exit the program if PIDCHECK  */

	interval_time = DEFAULT_INTERVAL;

	/** let's see if the first character of the basename of the
	    command invoked is a 'w' (e.g. have we been called as
	    'wnewmail' rather than just 'newmail'?)
	**/

	for (i=0, ptr=(argv[0] + strlen(argv[0])-1); !i && ptr > argv[0]; ptr--)
	  if (*ptr == '/') {
	    in_window = (*(ptr+1) == 'w');
	    i++;
	  }

	if (ptr == argv[0] && i == 0 && argv[0][0] == 'w')
	  in_window = 1;

	while ((c = getopt(argc, argv, "d:i:wX:")) != EOF) {
	  switch (c) {
       	  case 'd' : 
#if DEBUG
	      set_debugging(optarg);	   
#else
	      lib_error(CATGETS(elm_msg_cat, NewmailSet, 
				NewmailArgsIngoringDebug,
				"Warning: system created without debugging enabled - request ignored\n"));
#endif
	      break;
	  case 'i' : interval_time = atoi(optarg);		break;
	  case 'w' : in_window = 1;				break;
	  case 'X' : 
#ifdef REMOTE_MBX	    
	      if (!set_transaction_file(optarg))
		  exit(1);
#endif
	      break;
	      
	  default  : usage(argv[0]);				exit(1);
	  }
	}

    elm_sfprintf(version_buff, sizeof version_buff,
		 FRM("%s PL%s"), VERSION, PATCHLEVEL);

#ifdef DEBUG	  	 
	{ 
	    int d = panic_dprint("\n\
======================================================\n\
Debug output of the NEWMAIL program (version %s).\n",
			     version_buff);
	    
	    if (d >= 50) {
		printf("WARNING: Debug file may include passwords -- edit it!\n");
		panic_dprint("WARNING: Edit manually out sensitive information from that file!");
	    }
	}
#endif
	
	if (interval_time < 10)
	    if (interval_time == 1)
		lib_error(CATGETS(elm_msg_cat, NewmailSet, NewmailShort,
"Warning: interval set to 1 second.  I hope you know what you're doing!\n"));
	    else
		lib_error(CATGETS(elm_msg_cat, NewmailSet, NewmailShortPlur,
"Warning: interval set to %d seconds.  I hope you know what you're doing!\n"),
			  interval_time);

	/* now let's parse the foldernames, if any are given */

	if (optind >= argc) /* get default */
	    add_default_folder();
	else {
	  while (optind < argc)
	      add_folder(argv[optind++]);
	  pad_prefixes();			/* for nice output...*/
	}
	if (total_folders > 1)
		print_prefix = 1;

#ifdef AUTO_BACKGROUND
	if (! in_window) {
	    if (fork())	    /* automatically puts this task in background! */
		exit(0);

	    (void) signal(SIGINT, SIG_IGN);
	    (void) signal(SIGQUIT, SIG_IGN);
	}
#endif
	(void) signal(SIGHUP, SIG_DFL);

	if (in_window)
	     elm_fprintf(stdout,
			 CATGETS(elm_msg_cat, NewmailSet, NewmailIncommingMail,
				 "Incoming mail:\n"));

	while (1) {
	    int bytes;

#ifdef PIDCHECK
	    if ( kill(parent_pid,0))
		exit(0);
#else
#ifndef AUTO_BACKGROUND		/* won't work if we're nested this deep! */
	    if (getppid() == 1) 	/* we've lost our shell! */
		exit(0);
#endif /* AUTO_BACKGROUND */
#endif /* PIDCHECK */

	    if (! isatty(1))  /* we're not sending output to a tty any more */
		goto clean_exit;

	    DPRINT(Debug,1,(&Debug,			    
			    "\n----\n"));

	    for (i = 0; i < total_folders; i++) {

		cur_folder = &folder_list[i];
		DPRINT(Debug,1,(&Debug,			    
				"[checking folder #%d: %s]\n",
				i, cur_folder->F->cur_folder_sys));

		if (0 != (get_folder_mode(cur_folder->F) & FOLDER_FILE)) {
		    save_acc(cur_folder->F->cur_folder_sys);
		}

		if (new_mail_on_folder(cur_folder->F,&bytes)) {
		    struct read_folder_state * read_state_ptr = NULL;

		    if (!sessionlock_folder(cur_folder->F,SESSIONLOCK_NONE)) {
			if (errno == EACCES) {
			    cur_folder->access_error++;
			    if (cur_folder->access_error > 5) {
				lib_error(CATGETS(elm_msg_cat, 
						  NewmailSet,
						  NewmailErrNoPerm,
						  "Permission to monitor \"%S\" denied!"),
					  cur_folder->F->cur_folder_disp);
#if POLL_METHOD
				wait_for_timeout(5);
#else
				sleep(5);
#endif
				exit(1);
			    }
			}
			continue;
		    }

		    DPRINT(Debug,1,(&Debug,			    
				    "\tnew mail has arrived!  bytes %d\n",
				    bytes));

		    /* skip what we've read already... */

		    if (!prepare_read_folder(cur_folder->F,
					     PREPARE_NEW_ONLY_NOLOCK,
					     &read_state_ptr)) {
			goto clean;
		    }

		    /* read and display new mail! */
		    if (read_headers(cur_folder,read_state_ptr) && ! in_window)
			printf("\n\r");

		    end_read_folder(cur_folder->F,&read_state_ptr,1);

		clean:
		    /* try to set the file access times back, ignore
		       failures */

		    if (0 != (get_folder_mode(cur_folder->F) & FOLDER_FILE)) {
			close_folder(cur_folder->F,CLOSE_NORMAL);
	    
#if defined(BSD_TYPE) && !defined(UTIMBUF)
			utime(cur_folder->F->cur_folder_sys, utime_buffer);
#else
			utime(cur_folder->F->cur_folder_sys, &utime_buffer);
#endif
		    }
		} 
		else if (bytes < 0) {	/* file SHRUNK! */
		    int last = bytes;
		    int done     = 0;

		    while (! done) {
			int temp;
#if POLL_METHOD
			wait_for_timeout(1);
#else
			sleep(1);	/* wait for the size to stabilize */
#endif
			new_mail_on_folder(cur_folder->F,&temp);

			if (temp != last)
			    last = temp;
			else
			    done++;
		    } 
	 
		    if (sessionlock_folder(cur_folder->F,SESSIONLOCK_NONE)) { 
			struct read_folder_state * read_state_ptr = NULL;
			if (prepare_read_folder(cur_folder->F,PREPARE_NOLOCK,
						 &read_state_ptr)) {
			    end_read_folder(cur_folder->F,&read_state_ptr,1);
			}
		    }
		}
	    }

#if POLL_METHOD
	    wait_for_timeout(interval_time);
#else
	    sleep(interval_time);
#endif
	}
 clean_exit:
	for (i = 0; i < total_folders; i++) {
	    close_folder(folder_list[i].F,CLOSE_NORMAL);
	}
	return 0;
}

static int parse_header_routine P_((struct folder_info *folder,
				    READ_STATE read_state_ptr,
				    struct header_rec *entry,
				    header_list_ptr parsed_headers ));
static int parse_header_routine(folder,read_state_ptr,entry,parsed_headers)
     struct folder_info *folder;
     READ_STATE read_state_ptr;
     struct header_rec *entry;
     header_list_ptr parsed_headers;
{
    header_list_ptr tmphdr;

    /* copy_envelope_folder() may have set entry->content_length */
    /* copy_envelope_folder() have set entry->header_charset */


    if (NULL != (tmphdr = locate_header_by_name(parsed_headers,
						"From"))) {	    
	if (entry->from)
	    free_addr_items(entry->from);
	entry->from = 
	    break_down_address(tmphdr->body, 
			       !(entry->status & NOHDRENCODING),
			       entry->header_charset);	    
    }
        
    if (NULL != (tmphdr = locate_header_by_name(parsed_headers,
						"To"))) {	    
	if (entry->to)
	    free_addr_items(entry->to);
	entry->to = 
	    break_down_address(tmphdr->body, 
			       !(entry->status & NOHDRENCODING),
				   entry->header_charset);	    
    }
        
    if (NULL != (tmphdr = locate_header_by_name(parsed_headers,
						"Cc"))) {	    
	if (entry->cc)
	    free_addr_items(entry->cc);
	entry->cc = 
	    break_down_address(tmphdr->body, 
			       !(entry->status & NOHDRENCODING),
			       entry->header_charset);	    
    }
        
    if (NULL != (tmphdr = locate_header_by_name(parsed_headers,
						"Status"))) {	    
	if (index(tmphdr->body, 'R') != NULL)
	    entry->status &= ~(NEW | UNREAD);
	else if (index(tmphdr->body,'O') != NULL) {
	    entry->status &= ~NEW;
	    entry->status |= UNREAD;
	}
	if (index(tmphdr->body, 'r') != NULL)
	    entry->status |= REPLIED;
    }
    
    if (NULL != (tmphdr = locate_header_by_name(parsed_headers,
						"Subject"))) {	    
	
	if (entry->subject)
	    free_string(&(entry->subject));
	
	entry->subject = 
	    hdr_to_string(HDR_TEXT,
			  tmphdr->body,
			  entry->header_charset,
			  !(entry->status & NOHDRENCODING));	  
    } else if (!entry->subject)
	entry->subject = 
	    format_string(CATGETS(elm_msg_cat, NewmailSet, 
				  NewmailNoSubject,
				  "(No Subject Specified)"));
    
    if (NULL != (tmphdr = locate_header_by_name(parsed_headers,
						"Importance"))) {	    
	if (atoi(tmphdr->body) >= 2)
	    entry->priority = TRUE;
    }

    if (NULL != (tmphdr = locate_header_by_name(parsed_headers,
						"Priority"))) {	    
	
	if (strincmp(tmphdr->body, "normal", 6) != 0 &&
	    strincmp(tmphdr->body, "non-urgent", 10) != 0)
	    entry->priority = TRUE;		
    }
    return 1;
}


static int parse_body_routine P_((struct folder_info *folder,
			   READ_STATE read_state_ptr,
			   struct header_rec *entry,
			   header_list_ptr parsed_headers,
			   struct counter_data *counter
			   ));
static int parse_body_routine(folder,read_state_ptr,entry,parsed_headers,
			      counter)
     struct folder_info *folder;
     READ_STATE read_state_ptr;
     struct header_rec *entry;
     header_list_ptr parsed_headers;
     struct counter_data *counter;
{
    char * buffer;
    int len;
    long content_remaining                = -1L;

    content_remaining = entry->content_length;


 reset_body:

    while (copy_body_folder(folder,read_state_ptr,
			    &buffer,&len,&content_remaining)) {
	if (buffer)
	    free(buffer);
    }

    if (!copy_envelope_end_folder(folder,read_state_ptr)) {	
	if (entry->content_length >= 0L) {
	    entry->content_length = -1L;
	    
	    if (copy_envelope_reset_body(folder,read_state_ptr,
					 &content_remaining))
		goto reset_body;
	}
	DPRINT(Debug,10,(&Debug,			    
			 "-- Message parsing FAILED.\n"));
	return 0;
    }
    DPRINT(Debug,10,(&Debug,			    
		     "-- Message parsed.\n"));

    entry->body_parsed = 1;

    return 1;
}

static int read_headers(cur_folder,read_state_ptr)
     struct folder_struct *cur_folder;
     struct read_folder_state * read_state_ptr;
{
    /** read the headers, output as found given current_folder,
	the prefix of that folder, and whether we're in a window
	or not.
    **/

    struct header_rec hdr;		/* holds header info on curr mssg */
    int count;			/* count of messages done	  */

    count = 0;
    
    bzero((void *)&hdr, sizeof hdr);
    hdr.mbx_info    = NULL;
    hdr.binary      = 0;
    /*
     * Go through every line of the mailbox.
     */

    while(copy_envelope_folder(cur_folder->F,read_state_ptr,
			       &hdr,parse_header_routine,parse_body_routine,
			       NULL) > 0) {
        		
	if (hdr.status & NEW) {
	    show_header(&hdr, cur_folder);
	} else {
	    DPRINT(Debug,10,(&Debug,			    
			     "-- Message %d is not new...\n",count));
	}
	count++;
	
	free_rec_mbx_info(&hdr);
	if (hdr.header_error)
	    free_header_errors(& (hdr.header_error));
	bzero((void *)&hdr, sizeof hdr);   /* memory leak ... */
	hdr.binary      = 0;
    }
    
    return(count);
}

static void add_folder(name)
     char *name;
{
    /* add the specified folder to the list of folders...ignore any
       problems we may having finding it (user could be monitoring
       a mailbox that doesn't currently exist, for example)
    */

    char *cp, buf[SLEN];
    
    struct read_folder_state * read_state_ptr = NULL;


    if (current_folder >= MAX_FOLDERS) {
	lib_error(CATGETS(elm_msg_cat, NewmailSet, NewmailErrMaxFolders,
			   "Sorry, but I can only keep track of %d folders.\n"), 
		   MAX_FOLDERS);
	exit(1);
    }

    /* now let's rip off the suffix "=<string>" if it's there... */

    for (cp = name + strlen(name); cp > name+1 && *cp != '=' ; cp--)
	/* just keep stepping backwards */ ;

    /* if *cp isn't pointing to the first character we'e got something! */

    if (cp > name+1) {

	*cp++ = '\0';		/* null terminate the filename & get prefix */

	if (metachar(*cp)) cp++;
	
	strfcpy(folder_list[current_folder].prefix, cp,
		sizeof folder_list[current_folder].prefix);
	print_prefix = 1;
    }
    else {			/* nope, let's get the basename of the file */
	for (cp = name + strlen(name); cp > name && *cp != '/'; cp--)
	    /* backing up a bit... */ ;
	
	if (metachar(*cp)) cp++;
	if (*cp == '/') cp++;

	strfcpy(folder_list[current_folder].prefix, cp,
		sizeof folder_list[current_folder].prefix);
    }

    /* and next let's see what kind of weird prefix chars this user
       might be testing us with.  We can have '+'|'='|'%' to expand
       or a file located in the incoming mail dir...
    */

    if (metachar(name[0])) {
	expand_filename(name, buf, sizeof buf);
	folder_list[current_folder].F = enter_new_folder(buf);
    }
    else if (access(name, ACCESS_EXISTS) == -1) {
	/* let's try it in the mail home directory */
	elm_sfprintf(buf, sizeof buf,
		     FRM("%s%s"), 
		     mailhome, name);
	if (access(buf,ACCESS_EXISTS) != -1) 		/* aha! */
	    folder_list[current_folder].F = enter_new_folder(buf);
	else
	    folder_list[current_folder].F = enter_new_folder(name);
    }
    else
	folder_list[current_folder].F = enter_new_folder(name);
    
    if (!folder_list[current_folder].F) {
	DPRINT(Debug,1,(&Debug,			    
			"failed to add folder %s\n",name));
	return;
    }
    /* now let's try to actually open the file descriptor and grab
       a size... */

    if (!sessionlock_folder(folder_list[current_folder].F,SESSIONLOCK_NONE)) {
	if (errno == EACCES) {
	    lib_error(CATGETS(elm_msg_cat, NewmailSet, NewmailErrNoPerm,
			      "Permission to monitor \"%S\" denied!"),
		      folder_list[current_folder].F->cur_folder_sys);
	    exit(1);
	}
	goto clean;
    }

    if (!prepare_read_folder(folder_list[current_folder].F,PREPARE_NOLOCK,
			     &read_state_ptr)) {
			     
	goto clean;
    }

    end_read_folder(folder_list[current_folder].F,&read_state_ptr,1);

/* and increment current-folder please! */
 clean:

    DPRINT(Debug,1,(&Debug,			    
		    "folder %d: \"%s\" <%s>\n",
		    current_folder,
		    folder_list[current_folder].F->cur_folder_sys,
		    folder_list[current_folder].prefix));

    current_folder++;
    total_folders++;
}

static void add_default_folder()
{
    struct read_folder_state * read_state_ptr;
    char * default_val = give_dt_estr_as_str(&defaultfile_e,"incoming-mailbox");

    if (!default_val)
	return;

    folder_list[0].F = enter_new_folder(default_val);

    if (!folder_list[0].F) {
	DPRINT(Debug,1,(&Debug,			    
			"failed to add folder %s\n",
			default_val));
	return;
    }
         
    if (!sessionlock_folder(folder_list[0].F,SESSIONLOCK_NONE)) {
	if (errno == EACCES) {
	    lib_error(CATGETS(elm_msg_cat, NewmailSet, NewmailErrNoPerm,
			      "Permission to monitor \"%S\" denied!"),
		      folder_list[0].F->cur_folder_disp);
	    exit(1);
	}
	goto clean;
    }

    if (!prepare_read_folder(folder_list[0].F,PREPARE_NOLOCK,
			     &read_state_ptr)) {
	
	goto clean;
    }
    
    end_read_folder(folder_list[0].F,&read_state_ptr,1);

 clean:

    DPRINT(Debug,1,(&Debug,			    
		    "default folder: \"%s\" <%s>\n",
		    folder_list[0].F->cur_folder_sys,
		    folder_list[0].prefix));
    total_folders = 1;
    
}

static void show_header(hdr, cur_folder)
     struct header_rec *hdr;
     struct folder_struct *cur_folder;
{
    struct string * from_line = NULL;
    char prefix[SLEN];
    int used_to_line;
    
    used_to_line = DisplayAddress(hdr,&from_line);

    prefix[0] = '\0';

    if (! in_window)
	strfcat(prefix, ">> ", sizeof prefix);

    if (print_prefix) {
	strfcat(prefix, cur_folder->prefix, sizeof prefix);
	strfcat(prefix, ": ", sizeof prefix);
    }

    if (in_window) {
	if (hdr->priority && used_to_line)
	    strfcat(prefix, priority_to, sizeof prefix);
	else if (hdr->priority)
	    strfcat(prefix, priority_text, sizeof prefix);
	else if (used_to_line)
	    strfcat(prefix, To_text, sizeof prefix);
	elm_fprintf(stdout,FRM("\007%s%S -- %S\n"), 
		    prefix, from_line, hdr->subject);
    } else {
	if (hdr->priority)
	    strfcat(prefix, priority_mail, sizeof prefix);
	else
	    strfcat(prefix, mail_text, sizeof prefix);
	if (used_to_line)
	    strfcat(prefix, to_text, sizeof prefix);
	else
	    strfcat(prefix, from_text, sizeof prefix);
	elm_fprintf(stdout,FRM("\n\r%s%S - %S\n\r"), 
		    prefix, from_line, hdr->subject);
    }
}

static void save_acc(name)
     char *name;
{
    /** return the number of bytes in the specified file.  This
	is to check to see if new mail has arrived....  **/

    struct stat buffer;

    if (stat(name, &buffer) != 0)
	if (errno != ENOENT) {
	    lib_error(CATGETS(elm_msg_cat, NewmailSet, NewmailErrFstat,
			      "Error %d attempting fstat on %s"), errno, name);
	    exit(1);
	}
	
	/* retain the access times for later use */

#if defined(BSD_TYPE) && !defined(UTIMBUF)
    utime_buffer[0]     = buffer.st_atime;
    utime_buffer[1]     = buffer.st_mtime;
#else
    utime_buffer.actime = buffer.st_atime;
    utime_buffer.modtime= buffer.st_mtime;
#endif

}

static void usage(name)
     char *name;
{
	/* print a nice friendly usage message */

	lib_error(CATGETS(elm_msg_cat, NewmailSet, NewmailArgsHelp1,
"\nUsage: %s [-d] [-i interval] [-w] {folders}\n\
\targ\t\t\tMeaning\n\r\
\t -d  \tturns on debugging output\n\
\t -i D\tsets the interval checking time to 'D' seconds\n\
\t -w  \tforces 'window'-style output, and bypasses auto-background\n\n"),
	name);

	lib_error(CATGETS(elm_msg_cat, NewmailSet, NewmailArgsHelp2,
"folders can be specified by relative or absolute path names, can be the name\n\
of a mailbox in the incoming mail directory to check, or can have one of the\n\
standard Elm mail directory prefix chars (e.g. '+', '=' or '%%').\n\
Furthermore, any folder can have '=string' as a suffix to indicate a folder\n\
identifier other than the basename of the file\n\n"));

}

static void expand_filename(name, store_space,size)
     char *name, *store_space;
     int size;
{
    strfcpy(store_space, name, size);
    if (expand(store_space, size) == 0) {
	lib_error(CATGETS(elm_msg_cat, NewmailSet, NewmailErrExpand,
			  "Sorry, but I couldn't expand \"%s\"\n"),name);
	exit(1);
    }
}

static void pad_prefixes()
{
	/** This simple routine is to ensure that we have a nice
	    output format.  What it does is whip through the different
	    prefix strings we've been given, figures out the maximum
	    length, then space pads the other prefixes to match.
	**/

	register int i, j, len = 0;

	for (i=0; i < total_folders; i++)
	  if (len < (j=strlen(folder_list[i].prefix)))
	    len = j;
	
	for (i=0; i < total_folders; i++)
	  for (j = strlen(folder_list[i].prefix); j < len; j++)
	    strfcat(folder_list[i].prefix, " ", sizeof folder_list[i].prefix);
}

/*
 * Local Variables:
 *  mode:c
 *  c-basic-offset:4
 *  buffer-file-coding-system: iso-8859-1
 * End:
 */


syntax highlighted by Code2HTML, v. 0.9.1