static char rcsid[] = "@(#)$Id: file_util.c,v 1.28 2006/04/09 07:37:18 hurtta Exp $";

/*****************************************************************************
 *  The Elm (ME+) Mail System  -  $Revision: 1.28 $   $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
 *****************************************************************************/

/** File oriented utility routines for ELM 

**/

#include "def_elm.h"
#include "s_elm.h"

DEBUG_VAR(Debug,__FILE__,"mbox");

#include <errno.h>
#ifndef ANSI_C
extern int errno;               /* system error number */
#endif         

long bytes(name)
     char *name;
{

    /** return the number of bytes in the specified file.  This
	is to check to see if new mail has arrived....  (also
	see "fsize()" to see how we can get the same information
	on an opened file descriptor slightly more quickly)
    **/
    
    long result = file_bytes(name);
    if (-1 == result) {
	int err = errno;
	Raw(OFF);
	
	lib_error(CATGETS(elm_msg_cat, ElmSet, ElmErrorFstat,
			  "\nError attempting fstat on file %s!\n"),
		  name);
	lib_error(FRM("** %s. **\n"), 
		  error_description(err));
	emergency_exit(0);
    }
    return(result);
}

int append(fd, filename, prefix_str, page)
     FILE *fd;
     char *filename;
     char *prefix_str;
     struct menu_context *page;
{
	/** This routine appends the specified file to the already
	    open file descriptor.. Returns non-zero if fails.  **/

	FILE *my_fd;
	char buffer[VERY_LONG_STRING];
	int  len;
	
	int err = can_open(filename, "r");
	
    int LINES, COLUMNS;

    menu_get_sizes(page, &LINES, &COLUMNS);   


	if (err) {
	    DPRINT(Debug,1,(&Debug,
			    "Error: could not open %s for reading (append) -- can_open\n", 
			    filename));
	    return(1);

	}

	if ((my_fd = fopen(filename, "r")) == NULL) {
	    DPRINT(Debug,1,(&Debug,
			    "Error: could not open %s for reading (append)\n", filename));
	  return(1);
	}

	if (prefix_str != NULL && fputs(prefix_str, fd) == EOF) {
	    MoveCursor(LINES-1, 0);
	  Raw(OFF);
	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmWriteFailedAppend,
			    "\nWrite failed to temp file in append\n"));
	  perror(filename);
	  rm_temps_exit();     
	}

	while (0 < (len = 
		    fread(buffer, 1, VERY_LONG_STRING, my_fd)))
	  if (fwrite(buffer, 1, len, fd) != len) {
	      MoveCursor(LINES-1, 0);
	      Raw(OFF);
	      lib_error(CATGETS(elm_msg_cat, ElmSet, ElmWriteFailedAppend,
				"\nWrite failed to temp file in append\n"));
	      perror(filename);
	      rm_temps_exit();   
	  }

	if (fclose(my_fd) == EOF) {
	    MoveCursor(LINES-1, 0);
	  Raw(OFF);
	  lib_error(CATGETS(elm_msg_cat, ElmSet, ElmCloseFailedAppend,
			    "\nClose failed on temp file in append\n"));
	  perror(filename);
	  rm_temps_exit();      /* ??? global reference */
	}

	return(0);
}

int check_mailfile_size(mfile)
     struct folder_info *mfile;
{
    /** Check to ensure we have mail.  Only used with the '-z'
	starting option. So we output a diagnostic if there is
	no mail to read (including  forwarding).
	Return 0 if there is mail,
	<0 if no permission to check,
	1 if no mail,
	2 if no mail because mail is being forwarded.
    **/

    int retcode;
    READ_STATE state;

    if (prepare_read_folder(mfile,PREPARE_NOLOCK,&state)) {
	CONST char * FORWARD = NULL;

	if (NULL != (FORWARD = is_forwarded_folder(mfile,state))) {
	    lib_error(CATGETS(elm_msg_cat, ElmSet,ElmMailBeingForwarded,
			      "Your mail is being forwarded to %s.\n\r"),
		      FORWARD);
	    retcode = 2;
	} else if (mfile->mailfile_size < 2) {
	    lib_error(CATGETS(elm_msg_cat, ElmSet, ElmNoMail,
			   "You have no mail."));
	    retcode = 1;
	} else
	    retcode = 0;

	end_read_folder(mfile,&state,1);
    } else
	retcode = -1;					/* no perm */

    if (-1 == retcode) {
	lib_error(CATGETS(elm_msg_cat, ElmSet, ElmNoPermRead,
			  "You have no permission to read %s!\n\r"),
		  mfile);
    }
    
    return(retcode);
}

long fsize(fd)
     FILE *fd;
{
	/** return the size of the current file pointed to by the given
	    file descriptor - see "bytes()" for the same function with
	    filenames instead of open files...
	**/

	struct stat buffer;

	/*
	 *  Make sure there is nothing in the stdio buffer
	 *  that is not also on the disk!!!!
	 */

	fflush (fd);			

	(void) fstat(fileno(fd), &buffer);

	return( (long) buffer.st_size );
}

/* Open and possible creates file for updates and seeks end of file. */
FILE *open_end_update(name)
     char *name;
{
  
  FILE *fp = open_or_create(name);
  if (!fp) {
    int err = errno;
    DPRINT(Debug,1,
	   (&Debug, 
	    "open_end_update: could not open file %s\n\tError: %s\n", 
	    name, error_description(err)));
    
    return NULL;
  }
  
  if (0 != fseek(fp,0,SEEK_END)) {
    int err = errno;
    
    DPRINT(Debug,1,(&Debug,
		    "open_end_update: could not seek to EOF %s\n\tError: %s\n", 
		    name, error_description(err)));
    
    fclose(fp);
    return NULL;
  }
  
  return fp;
}

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


syntax highlighted by Code2HTML, v. 0.9.1