static char rcsid[] = "@(#)$Id: mbox.c,v 1.6 2006/05/01 09:18:57 hurtta Exp $";
/******************************************************************************
* The Elm (ME+) Mail System - $Revision: 1.6 $ $State: Exp $
*
* Author: Kari Hurtta <hurtta+elm@posti.FMI.FI> (was hurtta+elm@ozone.FMI.FI)
*****************************************************************************
* Based on code ../src/newmbox.c and ../src/lock.c.
* That code was following copyright:
*
* The Elm Mail System
*
* Copyright (c) 1988-1992 USENET Community Trust
* Copyright (c) 1986,1987 Dave Taylor
*****************************************************************************/
#include "def_mbox.h"
#ifdef USE_DLOPEN
#include "shared_imp.h"
#endif
#include "s_me.h"
#include "s_elm.h"
DEBUG_VAR(Debug,__FILE__,"mbox");
#include <errno.h>
#ifndef ANSI_C
extern int errno;
#endif
CONST static unsigned char *cs2us P_((const char *str));
CONST static unsigned char *cs2us(str)
CONST char *str;
{
return (CONST unsigned char *)str;
}
/* Folder type dependent routines ------------------------------------------ */
static void mbx_close_no_name P_((struct folder_info *folder,
enum close_mode mode));
static void mbx_close_no_name(folder,mode)
struct folder_info *folder;
enum close_mode mode;
{
DPRINT(Debug,11,(&Debug,
"mbx_close_no_name (dummy): folder=%p (%s)\n",
folder,folder->cur_folder_sys));
return;
}
static int mbx_lock_no_name P_((int direction,struct folder_info *folder));
static int mbx_lock_no_name(direction,folder)
int direction;
struct folder_info *folder;
{
DPRINT(Debug,11,(&Debug,
"mbx_lock_no_name=0 (dummy): folder=%p (%s)\n",
folder,folder->cur_folder_sys));
return 0;
}
static int mbx_unlock_no_name P_((int interrupt, struct folder_info *folder));
static int mbx_unlock_no_name(interrupt,folder)
int interrupt;
struct folder_info *folder;
{
DPRINT(Debug,11,(&Debug,
"mbx_unlock_no_name=0 (dummy): folder=%p (%s)\n",
folder,folder->cur_folder_sys));
return 0;
}
static void mbx_init_null P_((struct folder_info *folder));
static void mbx_init_null(folder)
struct folder_info *folder;
{
DPRINT(Debug,11,(&Debug,
"mbx_init_null: folder=%p (%s)\n",
folder,folder->cur_folder_sys));
folder -> cur_tempfolder[0] = '\0';
folder -> p = NULL;
}
static void mbx_free_null P_((struct folder_info *folder));
static void mbx_free_null(folder)
struct folder_info *folder;
{
DPRINT(Debug,11,(&Debug,
"mbx_free_null: folder=%p (%s)\n",
folder,folder->cur_folder_sys));
}
static int mbx_sessionlock_no_name P_((struct folder_info *folder,
enum sessionlock_mode mode));
static int mbx_sessionlock_no_name(folder,mode)
struct folder_info *folder;
enum sessionlock_mode mode;
{
DPRINT(Debug,11,(&Debug,
"mbx_sessionlock_no_name=0 (dummy): folder=%p (%s)\n",
folder,folder->cur_folder_sys));
return 0;
}
static void mbx_flush_null P_((struct folder_info *folder));
static void mbx_flush_null(folder)
struct folder_info *folder;
{
DPRINT(Debug,11,(&Debug,
"mbx_flush_null: folder=%p (%s)\n",
folder,folder->cur_folder_sys));
}
static int mbx_ferror_no_name P_((struct folder_info *folder, int clean));
static int mbx_ferror_no_name(folder,clean)
struct folder_info *folder;
int clean;
{
DPRINT(Debug,11,(&Debug,
"mbx_ferror_no_name=1 (dummy): folder=%p (%s)\n",
folder,folder->cur_folder_sys));
return 1;
}
static void malloc_read_folder_state P_((struct read_folder_state **ptr));
static void malloc_read_folder_state(ptr)
struct read_folder_state **ptr;
{
*ptr = safe_malloc(sizeof (struct read_folder_state));
DPRINT(Debug,11,(&Debug,
"malloc_read_folder_state: (*ptr)=%p\n",
*ptr));
/* bzero is defined hdrs/defs.h */
bzero((void *)*ptr,sizeof (struct read_folder_state));
(*ptr) -> magic = RF_magic;
(*ptr) -> fbytes = 0;
/* (*ptr) -> count = 0; */
(*ptr) -> linecounter = 0;
(*ptr) -> fbytes_body = 0;
(*ptr) -> skipping = -1; /* 0 == reading, 1 = skipping, -1 == end of message */
(*ptr) -> skip_count = 0;
(*ptr) -> skip_bytes = 0;
}
static void free_read_folder_state P_((struct read_folder_state **ptr));
static void free_read_folder_state(ptr)
struct read_folder_state **ptr;
{
DPRINT(Debug,11,(&Debug,
"free_read_folder_state: (*ptr)=%p\n",
*ptr));
/* bzero is defined hdrs/defs.h */
bzero((void *)*ptr,sizeof (struct read_folder_state));
free(*ptr);
*ptr = NULL;
}
static int mbx_prepare_read_no_name P_((struct folder_info *folder,
enum prepare_mode mode,
READ_STATE read_state_ptr));
static int mbx_prepare_read_no_name(folder,mode,read_state_ptr)
struct folder_info *folder;
enum prepare_mode mode;
READ_STATE read_state_ptr;
{
DPRINT(Debug,11,(&Debug,
"mbx_prepare_read_no_name: folder=%p (%s)\n",
folder,folder->cur_folder_sys));
DPRINT(Debug,11,(&Debug,
" : read_state_ptr=%p\n",
read_state_ptr));
DPRINT(Debug,11,(&Debug,
"mbx_prepare_read_no_name=0\n"));
return 0;
}
static int mbx_end_read_null P_((struct folder_info *folder,
READ_STATE read_state_ptr,
int silent));
static int mbx_end_read_null(folder,read_state_ptr,silent)
struct folder_info *folder;
READ_STATE read_state_ptr;
int silent;
{
DPRINT(Debug,11,(&Debug,
"mbx_end_read_null: folder=%p (%s)\n",
folder,folder->cur_folder_sys));
DPRINT(Debug,11,(&Debug,
" : read_state_ptr=%p\n",
read_state_ptr));
DPRINT(Debug,11,(&Debug,
"mbx_end_read_null=1\n"));
return 1;
}
static int mbx_copy_envelope_no_name P_((struct folder_info *folder,
READ_STATE read_state_ptr,
struct header_rec *entry,
int force));
static int mbx_copy_envelope_no_name(folder,read_state_ptr,entry,force)
struct folder_info *folder;
READ_STATE read_state_ptr;
struct header_rec *entry;
int force;
{
DPRINT(Debug,11,(&Debug,
"mbx_copy_envelope_no_name: folder=%p (%s)\n",
folder,folder->cur_folder_sys));
DPRINT(Debug,11,(&Debug,
" : read_state_ptr=%p\n",
read_state_ptr));
entry->offset = 0;
entry->status = VISIBLE;
DPRINT(Debug,11,(&Debug,
"mbx_copy_envelope_no_name=0\n"));
return 0;
}
static CONST char * mbx_is_forwarded_null P_((struct folder_info *folder,
READ_STATE read_state_ptr));
static CONST char * mbx_is_forwarded_null(folder,read_state_ptr)
struct folder_info *folder;
READ_STATE read_state_ptr;
{
DPRINT(Debug,11,(&Debug,
"mbx_is_forwarded_null: folder=%p (%s)\n",
folder,folder->cur_folder_sys));
DPRINT(Debug,11,(&Debug,
" : read_state_ptr=%p\n",
read_state_ptr));
DPRINT(Debug,11,(&Debug,
"mbx_is_forwarded_null=NULL\n"));
return NULL;
}
static int mbx_copy_header_no_name P_((struct folder_info *folder,
READ_STATE read_state_ptr,
char **buffer, int *len));
static int mbx_copy_header_no_name(folder,read_state_ptr,buffer,len)
struct folder_info *folder;
READ_STATE read_state_ptr;
char **buffer;
int *len;
{
DPRINT(Debug,11,(&Debug,
"mbx_copy_header_no_name: folder=%p (%s)\n",
folder,folder->cur_folder_sys));
DPRINT(Debug,11,(&Debug,
" : read_state_ptr=%p\n",
read_state_ptr));
DPRINT(Debug,11,(&Debug,
"mbx_copy_header_no_name=0\n"));
return 0;
}
static int mbx_copy_body_no_name P_((struct folder_info *folder,
READ_STATE read_state_ptr,
char **buffer, int *len,
long *content_remaining));
static int mbx_copy_body_no_name(folder,read_state_ptr,buffer,len,
content_remaining)
struct folder_info *folder;
READ_STATE read_state_ptr;
char **buffer;
int *len;
long *content_remaining;
{
DPRINT(Debug,11,(&Debug,
"mbx_copy_body_no_name: folder=%p (%s)\n",
folder,folder->cur_folder_sys));
DPRINT(Debug,11,(&Debug,
" : read_state_ptr=%p\n",
read_state_ptr));
DPRINT(Debug,11,(&Debug,
"mbx_copy_body_no_name=0\n"));
return 0;
}
static int mbx_copy_envelope_end_no_name P_((struct folder_info *folder,
READ_STATE read_state_ptr));
static int mbx_copy_envelope_end_no_name(folder,read_state_ptr)
struct folder_info *folder;
READ_STATE read_state_ptr;
{
DPRINT(Debug,11,(&Debug,
"mbx_copy_envelope_end_no_name: folder=%p (%s)\n",
folder,folder->cur_folder_sys));
DPRINT(Debug,11,(&Debug,
" : read_state_ptr=%p\n",
read_state_ptr));
DPRINT(Debug,11,(&Debug,
"mbx_copy_envelope_end_no_name=1\n"));
return 1; /* Always end of message */
}
static int mbx_copy_envelope_reset_body_no_name P_((struct folder_info *folder,
READ_STATE
read_state_ptr));
static int mbx_copy_envelope_reset_body_no_name(folder,read_state_ptr)
struct folder_info *folder;
READ_STATE read_state_ptr;
{
DPRINT(Debug,11,(&Debug,
"mbx_copy_envelope_reset_body_no_name: folder=%p (%s)\n",
folder,folder->cur_folder_sys));
DPRINT(Debug,11,(&Debug,
" : read_state_ptr=%p\n",
read_state_ptr));
DPRINT(Debug,11,(&Debug,
"mbx_copy_envelope_reset_body_no_name=0\n"));
return 0;
}
static FILE * mbx_no_name_to_fd P_((struct folder_info *folder,long offset));
static FILE * mbx_no_name_to_fd(folder,offset)
struct folder_info *folder;
long offset;
{
DPRINT(Debug,11,(&Debug,
"mbx_no_name_to_fd: folder=%p (%s)\n",
folder,folder->cur_folder_sys));
DPRINT(Debug,11,(&Debug,
"mbx_no_name_to_fd=NULL\n"));
return NULL;
}
static int mbx_new_mail_on_no_name P_((struct folder_info *folder,int *bytes));
static int mbx_new_mail_on_no_name(folder,bytes)
struct folder_info *folder;
int *bytes;
{
DPRINT(Debug,11,(&Debug,
"mbx_new_mail_on_no_name: folder=%p (%s)\n",
folder,folder->cur_folder_sys));
DPRINT(Debug,11,(&Debug,
"mbx_new_mail_on_no_name=0\n"));
return 0;
}
static int mbx_consider_remove_null P_((struct folder_info *folder));
static int mbx_consider_remove_null(folder)
struct folder_info *folder;
{
DPRINT(Debug,11,(&Debug,
"mbx_consider_remove_null=0 (dummy): folder=%p (%s)\n",
folder,folder->cur_folder_sys));
return 0;
}
static void malloc_keep_folder_state P_((struct keep_folder_state **ptr));
static void malloc_keep_folder_state(ptr)
struct keep_folder_state **ptr;
{
*ptr = safe_malloc(sizeof (struct keep_folder_state));
bzero((void *)*ptr,sizeof (struct keep_folder_state));
(*ptr)->magic = KS_magic;
}
static void free_keep_folder_state P_((struct keep_folder_state **ptr));
static void free_keep_folder_state(ptr)
struct keep_folder_state **ptr;
{
bzero((void *)*ptr,sizeof (struct keep_folder_state));
free(*ptr);
*ptr = NULL;
}
static int mbx_prepare_keep_no_name P_((struct folder_info *folder,
KEEP_STATE keep_state_ptr));
static int mbx_prepare_keep_no_name(folder,keep_state_ptr)
struct folder_info *folder;
KEEP_STATE keep_state_ptr;
{
DPRINT(Debug,11,(&Debug,
"mbx_prepare_keep_no_name=0 (dummy): folder=%p (%s)\n",
folder,folder->cur_folder_sys));
return 0;
}
static int mbx_end_keep_no_name P_((struct folder_info *folder,
KEEP_STATE keep_state_ptr));
static int mbx_end_keep_no_name(folder,keep_state_ptr)
struct folder_info *folder;
KEEP_STATE keep_state_ptr;
{
DPRINT(Debug,11,(&Debug,
"mbx_end_keep_no_name=1 (dummy): folder=%p (%s)\n",
folder,folder->cur_folder_sys));
return 1;
}
static void mbx_mark_keep_no_name P_((struct folder_info *folder,
KEEP_STATE keep_state_ptr,
struct header_rec *entry,
int keep));
static void mbx_mark_keep_no_name(folder,keep_state_ptr,entry,keep)
struct folder_info *folder;
KEEP_STATE keep_state_ptr;
struct header_rec *entry;
int keep;
{
DPRINT(Debug,11,(&Debug,
"mbx_mark_keep_no_name (dummy): folder=%p (%s)\n",
folder,folder->cur_folder_sys));
}
CONST char * mbx_no_name_type P_((struct folder_info *folder));
CONST char * mbx_no_name_type(folder)
struct folder_info *folder;
{
char * status = "NULL";
DPRINT(Debug,11,(&Debug,
"mbx_no_name_type: folder=%p (%s)\n",
folder,folder->cur_folder_sys));
DPRINT(Debug,11,(&Debug,
"mbx_no_name_type=%s\n",
status));
return status;
}
static int mbx_start_edit_no_name P_((struct folder_info *folder,
CONST char **buffer));
static int mbx_start_edit_no_name(folder,buffer)
struct folder_info *folder;
CONST char **buffer;
{
DPRINT(Debug,11,(&Debug,
"mbx_start_edit_no_name=0 (dummy): folder=%p (%s)\n",
folder,folder->cur_folder_sys));
return 0;
}
static int mbx_end_edit_no_name P_((struct folder_info *folder));
static int mbx_end_edit_no_name(folder)
struct folder_info *folder;
{
DPRINT(Debug,11,(&Debug,
"mbx_end_edit_no_name=0 (dummy): folder=%p (%s)\n",
folder,folder->cur_folder_sys));
return 0;
}
static int mbx_get_no_name_mode P_((struct folder_info *folder));
static int mbx_get_no_name_mode(folder)
struct folder_info *folder;
{
DPRINT(Debug,11,(&Debug,
"mbx_get_no_name_mode=0 (dummy): folder=%p (%s)\n",
folder,folder->cur_folder_sys));
return 0;
}
static void mbx_zero_rs_fields_null P_((struct read_folder_state *rs));
static void mbx_zero_rs_fields_null(rs)
struct read_folder_state *rs;
{
DPRINT(Debug,11,(&Debug,
"mbx_zero_rs_fields_null (dummy): rs=%p\n",
rs));
}
static void mbx_free_rs_fields_null P_((struct read_folder_state *rs));
static void mbx_free_rs_fields_null(rs)
struct read_folder_state *rs;
{
DPRINT(Debug,11,(&Debug,
"mbx_free_rs_fields_null (dummy): rs=%p\n",
rs));
}
static void mbx_zero_ks_fields_null P_((struct keep_folder_state *rs));
static void mbx_zero_ks_fields_null(rs)
struct keep_folder_state *rs;
{
DPRINT(Debug,11,(&Debug,
"mbx_zero_ks_fields_null (dummy): rs=%p\n",
rs));
}
static void mbx_free_ks_fields_null P_((struct keep_folder_state *rs));
static void mbx_free_ks_fields_null(rs)
struct keep_folder_state *rs;
{
DPRINT(Debug,11,(&Debug,
"mbx_free_ks_fields_null (dummy): rs=%p\n",
rs));
}
static struct folder_type no_name = { "(none)",
mbx_close_no_name,
mbx_lock_no_name,
mbx_init_null,
mbx_sessionlock_no_name,
mbx_unlock_no_name,
mbx_flush_null,
mbx_ferror_no_name,
mbx_prepare_read_no_name,
mbx_end_read_null,
mbx_copy_envelope_no_name,
mbx_is_forwarded_null,
mbx_copy_header_no_name,
mbx_copy_body_no_name,
mbx_copy_envelope_end_no_name,
mbx_copy_envelope_reset_body_no_name,
mbx_no_name_to_fd,
mbx_new_mail_on_no_name,
mbx_consider_remove_null,
mbx_prepare_keep_no_name,
mbx_end_keep_no_name,
mbx_mark_keep_no_name,
mbx_no_name_type,
mbx_start_edit_no_name,
mbx_end_edit_no_name,
mbx_free_null,
mbx_zero_rs_fields_null,
mbx_free_rs_fields_null,
mbx_zero_ks_fields_null,
mbx_free_ks_fields_null,
mbx_get_no_name_mode};
CONST folder_type_p NO_NAME = &no_name;
CONST folder_type_p NON_SPOOL = &non_spool; /* mailfile -- not mailbox */
CONST folder_type_p SPOOL = &spool; /* normal mailbox */
CONST folder_type_p READ_ONLY = &read_only; /* read only mailfile */
#ifdef REMOTE_MBX
CONST folder_type_p POP_MBX = &pop_mbx; /* POP mailbox */
CONST folder_type_p IMAP_MBX = &imap_mbx; /* IMAP mailbox */
#endif
static int valid_magic P_((folder_type_p magic));
static int valid_magic(magic)
folder_type_p magic;
{
int i;
if (magic == &no_name ||
magic == &non_spool ||
magic == &spool ||
#ifdef REMOTE_MBX
magic == &pop_mbx ||
magic == &imap_mbx ||
#endif
magic == &read_only)
return 1;
#ifdef USE_DLOPEN
for (i = 0; i < shared_folder_type_count; i++)
if (magic == shared_folder_types[i].T)
return 1;
#endif
return 0;
}
/* General routines -------------------------------------------------------- */
folder_type_p get_folder_type(filename, in_mail)
CONST char *filename;
enum folder_place *in_mail;
{
/** returns the type of mailfile filename is
NO_NAME = no name
SPOOL = consisting only of mailhome plus base file name
(no intervening directory name)
NON_SPOOL = a name that is not SPOOL type above
READ_ONLY = open this read-only
**/
struct stat bufX, *buf = NULL; /* stat command */
char *mbx_dir = NULL;
if (in_mail)
*in_mail = in_none;
/* if filename is null or is of zero length */
if((filename == NULL) || (*filename == '\0')) {
DPRINT(Debug,8,(&Debug,
"get_folder_type=NO_NAME: no filename\n"));
return(NO_NAME);
}
DPRINT(Debug,8,(&Debug,
"get_folder_type: filename=%s\n",filename));
if (stat(filename, &bufX) != 0) {
int err = errno;
DPRINT(Debug,8,(&Debug,
"get_folder_type: errno %d (%s) attempting to stat file %s\n",
err, error_description(err), filename));
} else
buf = &bufX;
if (in_directory(buf,filename,mailhome)) {
DPRINT(Debug,8,(&Debug,
"get_folder_type=SPOOL\n"));
return(SPOOL);
}
mbx_dir = give_dt_estr_as_str(&extra_mailbox_dir_e,
"extra-mailbox-dir");
if (mbx_dir) {
if (in_directory(buf,filename,mbx_dir)) {
DPRINT(Debug,8,(&Debug,
"get_folder_type=SPOOL (is on %s)\n",
mbx_dir));
return(SPOOL);
}
}
if (in_mail) {
/* give_dt_estr_as_str adds / to end */
char * str = give_dt_estr_as_str(&folders_e,"maildir");
if (str) {
if (in_directory(buf,filename,str)) {
DPRINT(Debug,8,(&Debug,
"get_folder_type: On folders directory: %s\n",
str));
*in_mail = in_folders;
}
}
if (home[0]) {
if (in_directory(buf,filename,home)) {
DPRINT(Debug,8,(&Debug,
"get_folder_type: On home directory: %s\n",
home));
*in_mail = in_home;
}
}
}
/* if file name == default mailbox, its a spool file also
* even if its not in the spool directory. (SVR4)
*/
{
char * default_val = give_dt_estr_as_str(&defaultfile_e,"incoming-mailbox");
if (default_val &&
strcmp(filename, default_val) == 0) {
DPRINT(Debug,8,(&Debug,
"get_folder_type=SPOOL\n"));
return(SPOOL);
}
}
if (buf) {
if (buf->st_mode & 07000) {
/* is 'SPOOL' file if special modes set */
DPRINT(Debug,8,(&Debug,
"get_folder_type=SPOOL; mode=%05o\n",
buf->st_mode));
return(SPOOL);
}
/* If owner do not have write permission, open it read-only */
if (0 == (buf->st_mode & 00200)) {
DPRINT(Debug,8,(&Debug,
"get_folder_type=READ_ONLY; mode=%05o\n",
buf->st_mode));
return(READ_ONLY);
}
}
/* Open read only if we have no write access ...
* This also detects (at least on Linux) cases where filesystem is
* mounted read-only
*/
if (0 != access(filename,WRITE_ACCESS)) {
int err = errno;
DPRINT(Debug,8,(&Debug,
"get_folder_type=READ_ONLY; no write access: %s (errno %d)\n",
error_description(err),err));
return(READ_ONLY);
}
DPRINT(Debug,8,(&Debug,
"get_folder_type=NON_SPOOL\n"));
return(NON_SPOOL);
}
int in_directory(buf1,name,dir)
struct stat *buf1;
CONST char *name;
CONST char * dir;
{
CONST char * ptr = strrchr(name,'/');
CONST char * X = name;
int l1 = strlen(dir);
if (buf1) {
DPRINT(Debug,8,(&Debug,
"in_directory: buf1=%p ",buf1));
} else {
DPRINT(Debug,8,(&Debug,
"in_directory: buf1=NULL "));
}
DPRINT(Debug,8,(&Debug,
"name=%s dir=%s\n",name,dir));
if (l1 > 0 && '/' == dir[l1-1]) {
l1--;
DPRINT(Debug,8,(&Debug,
"in_directory: Last char / on dir=%s (using len=%d)\n",
dir,l1));
}
if (ptr) {
int L = ptr-X;
X = ptr+1;
if (l1 == L &&
0 == strncmp(dir,name,L)) {
DPRINT(Debug,8,(&Debug,
"in_directory=1 same base=%.*s\n",
L,dir));
return 1;
}
}
if (buf1) {
char * cmp = elm_message(FRM("%.*s/%s"),l1,dir,X);
struct stat buf2;
if (stat(cmp, &buf2) != 0) {
int err = errno;
DPRINT(Debug,8,(&Debug,
"in_directory=1: %s (errno=%d) attempting to stat file %s\n",
error_description(err), err, cmp));
free(cmp);
return 0;
}
if (buf1->st_ino == buf2.st_ino && buf1->st_dev == buf2.st_dev) {
DPRINT(Debug,8,(&Debug,
"in_directory=1 (same dev=%ld and ino=%d as %s)\n",
(long)buf1->st_dev,(long)buf1->st_ino,cmp));
free(cmp);
return 1;
}
free(cmp);
}
DPRINT(Debug,8,(&Debug,
"in_directory=0\n"));
return 0;
}
int same_file(name1,name2)
char *name1, *name2;
{
struct stat buf1, buf2;
if (0 == strcmp(name1,name2)) {
DPRINT(Debug,8,(&Debug,
"same_file(%s,%s)=TRUE\n",name1,name2));
return TRUE;
}
if (stat(name1, &buf1) != 0) {
int err = errno;
DPRINT(Debug,8,(&Debug,
"same_file(%s,%s)=FALSE: %s (errno=%d) attempting to stat file %s\n",
name1,name2,error_description(err), err, name1));
return FALSE;
}
if (stat(name2, &buf2) != 0) {
int err = errno;
DPRINT(Debug,8,(&Debug,
"same_file(%s,%s)=FALSE: %s (errno=%d) attempting to stat file %s\n",
name1,name2,error_description(err), err, name2));
return FALSE;
}
if (buf1.st_ino == buf2.st_ino && buf1.st_dev == buf2.st_dev) {
DPRINT(Debug,8,(&Debug,
"same_file(%s,%s)=TRUE\n",name1,name2));
return TRUE;
}
DPRINT(Debug,8,(&Debug,
"same_file(%s,%s)=FALSE\n",name1,name2));
return FALSE;
}
void close_folder(folder,mode)
struct folder_info *folder;
enum close_mode mode;
{
DPRINT(Debug,10,(&Debug,
"close_folder: folder=%p (%s), type=%p\n",
folder,folder->cur_folder_sys,folder -> folder_type));
folder -> folder_type->close_it(folder,mode);
if (folder -> p) {
if (folder -> p->fh_folder != NULL)
fclose(folder -> p->fh_folder);
folder -> p->fh_folder = NULL;
if (folder -> p->fh_temp != NULL)
fclose(folder -> p->fh_temp);
folder -> p->fh_temp = NULL;
}
}
struct folder_info *mbx_new_folder()
{
struct folder_info *new_folder = NULL;
new_folder = safe_malloc(sizeof (struct folder_info));
/* defined in hdrs/defs.h */
bzero((void *)new_folder,sizeof (struct folder_info));
new_folder -> p = NULL;
new_folder -> cur_folder_sys = NULL;
new_folder -> cur_folder_disp = NULL;
new_folder -> cur_tempfolder[0] = '\0';
new_folder -> mailfile_size = 0;
return new_folder;
}
struct folder_info *enter_new_folder(new_file)
CONST char *new_file;
{
struct folder_info *new_folder = NULL;
DPRINT(Debug,10,(&Debug,
"enter_new_folder(%s)\n",
new_file));
new_folder = mbx_new_folder();
new_folder -> cur_folder_sys = safe_strdup(new_file);
new_folder -> cur_folder_disp = new_string2(display_charset,
cs2us(new_file));
/* determine type of new mailfile and calculate temp file name
remote_folder_type calls folder's init_it routine if
succees
*/
if (!remote_folder_type(new_folder)) {
new_folder -> folder_type = get_folder_type(new_file,NULL);
new_folder -> folder_type->init_it(new_folder);
}
/* HACK */
if (new_folder->p)
new_folder->p->flags1 = 0;
#if 0
DPRINT(Debug,1,(&Debug,
"New folder %s type %s temp file %s (%s)\n",
current_folder->cur_folder_sys,
(current_folder -> folder_type == SPOOL ?
"spool" : "non-spool"),
(*current_folder-> cur_tempfolder ?
current_folder -> cur_tempfolder : "none"), "newmbox"));
#endif
DPRINT(Debug,10,(&Debug,
"enter_new_folder=%p (%s), type=%p (%s)\n",
new_folder,new_folder->cur_folder_sys,
new_folder->folder_type,
new_folder->folder_type->type_name));
return new_folder;
}
void leave_old_folder(folder,mode)
struct folder_info **folder;
enum close_mode mode;
{
if (!valid_magic((*folder)->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"leave_old_folder",
"Bad magic number (folder type)",0);
DPRINT(Debug,10,(&Debug,
"leave_old_folder: *folder=%p (%s), type=%p (%s)\n",
folder,
(*folder)->cur_folder_sys,
(*folder)->folder_type,
(*folder)->folder_type->type_name));
close_folder(*folder, mode);
(*folder)->folder_type->free_it(*folder);
if ((*folder) -> cur_folder_sys) {
free((*folder) -> cur_folder_sys);
(*folder) -> cur_folder_sys = NULL;
}
if ((*folder) -> cur_folder_disp)
free_string(&((*folder) -> cur_folder_disp));
free(*folder);
*folder = NULL;
}
int lock_folder(direction, folder)
int direction;
struct folder_info *folder;
{
int ret;
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"lock_folder",
"Bad magic number (folder type)",0);
DPRINT(Debug,10,(&Debug,
"lock_folder: folder=%p (%s), type=%p (%s)\n",
folder,folder->cur_folder_sys,folder -> folder_type,
folder->folder_type->type_name));
ret = folder -> folder_type->lock_it(direction,folder);
DPRINT(Debug,10,(&Debug,
"lock_folder=%d\n",
ret));
return ret;
}
int unlock_folder(interrupt, folder)
int interrupt;
struct folder_info *folder;
{
int ret;
/* If interrupt is set, avoid calling no-reentrant routines ... */
/** Flush the mailfile buffer if necessary before removing the lock.
**/
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"unlock_folder",
"Bad magic number (folder type)",interrupt);
DPRINT(Debug,10,(&Debug,
"unlock_folder: folder=%p (%s), type=%p (%s)\n",
folder,folder->cur_folder_sys,folder -> folder_type,
folder->folder_type->type_name));
if (!interrupt)
flush_folder(folder);
ret = folder -> folder_type->unlock_it(interrupt,folder);
DPRINT(Debug,10,(&Debug,
"unlock_folder=%d\n",
ret));
return ret;
}
/* Return 1 on succeed */
int sessionlock_folder(folder,mode)
struct folder_info *folder;
enum sessionlock_mode mode;
{
int ret;
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"sessionlock_folder",
"Bad magic number (folder type)",0);
DPRINT(Debug,10,(&Debug,
"sessionlock_folder: folder=%p (%s), type=%p (%s)\n",
folder,folder->cur_folder_sys,folder -> folder_type,
folder->folder_type->type_name));
/* HACK */
if (folder->p)
folder->p->flags1 = 0;
switch (mode) {
case SESSIONLOCK_NONE_CHECKNEW:
if (folder->p)
folder->p->flags1 |= FLAG1_CHECKNEW;
else {
DPRINT(Debug,10,(&Debug,
"sessionlock_folder: SESSIONLOCK_NONE_CHECKNEW unsupported\n"));
}
mode = SESSIONLOCK_NONE;
break;
}
ret = folder->folder_type->sessionlock_it(folder,mode);
DPRINT(Debug,10,(&Debug,
"sessionlock_folder=%d\n",
ret));
return ret;
}
void flush_folder(folder)
struct folder_info *folder;
{
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"flush_folder",
"Bad magic number (folder type)",0);
DPRINT(Debug,10,(&Debug,
"flush_folder: folder=%p (%s), type=%p (%s)\n",
folder,folder->cur_folder_sys,folder -> folder_type,
folder->folder_type->type_name));
folder->folder_type->flush_it(folder);
}
int ferror_folder(folder,clean)
struct folder_info *folder;
int clean;
{
int ret;
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"ferror_folder",
"Bad magic number (folder type)",0);
DPRINT(Debug,10,(&Debug,
"ferror_folder: folder=%p (%s), type=%p (%s)\n",
folder,folder->cur_folder_sys,folder -> folder_type,
folder->folder_type->type_name));
ret = folder->folder_type->ferror_it(folder,clean);
DPRINT(Debug,10,(&Debug,
"ferror_folder=%d\n",
ret));
return ret;
}
int prepare_read_folder(folder,mode,read_state_ptr)
struct folder_info *folder;
enum prepare_mode mode;
READ_STATE * read_state_ptr;
{
int status;
READ_STATE ptr = NULL;
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"prepare_read_folder",
"Bad magic number (folder type)",0);
DPRINT(Debug,10,(&Debug,
"prepare_read_folder: folder=%p (%s), type=%p (%s)\n",
folder,folder->cur_folder_sys,folder -> folder_type,
folder->folder_type->type_name));
malloc_read_folder_state(&ptr);
folder->folder_type->zero_rs_fields_it(ptr);
ptr->mode = mode;
status = folder->folder_type->prepare_read_it(folder,mode,ptr);
if (!status) {
folder->folder_type->free_rs_fields_it(ptr);
free_read_folder_state(&ptr);
}
*read_state_ptr = ptr;
DPRINT(Debug,10,(&Debug,
"prepare_read_folder=%d\n",
status));
return status;
}
int end_read_folder(folder,read_state_ptr,silent)
struct folder_info *folder;
READ_STATE * read_state_ptr;
int silent;
{
int status;
READ_STATE ptr = *read_state_ptr;
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"end_read_folder",
"Bad magic number (folder type)",0);
if (RF_magic != ptr -> magic)
panic("MBX PANIC",__FILE__,__LINE__,"end_read_folder",
"Bad magic number (read state)",0);
DPRINT(Debug,10,(&Debug,
"end_read_folder: folder=%p (%s), type=%p (%s)\n",
folder,folder->cur_folder_sys,folder -> folder_type,
folder->folder_type->type_name));
status = folder->folder_type->end_read_it(folder,ptr,silent);
folder->folder_type->free_rs_fields_it(ptr);
free_read_folder_state(&ptr);
*read_state_ptr = ptr;
DPRINT(Debug,10,(&Debug,
"end_read_folder=%d\n",
status));
return status;
}
void copy_skipcount_folder(folder,read_state_ptr,skipcount,skipbytes)
struct folder_info *folder;
READ_STATE read_state_ptr;
int *skipcount;
long *skipbytes;
{
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"copy_skipcount_folder",
"Bad magic number (folder type)",0);
if (RF_magic != read_state_ptr -> magic)
panic("MBX PANIC",__FILE__,__LINE__,"copy_skipcount_folder",
"Bad magic number (read state)",0);
*skipcount = read_state_ptr -> skip_count;
*skipbytes = read_state_ptr -> skip_bytes;
}
/* Returns: 0 = End of folder
1 = OK
-1 = format error
*/
int copy_envelope_folder(folder,read_state_ptr,entry,parse_header,parse_body,
counter)
struct folder_info *folder;
READ_STATE read_state_ptr;
struct header_rec *entry;
parse_header_callback *parse_header;
parse_body_callback *parse_body;
struct counter_data *counter;
{
int status;
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"copy_envelope_folder",
"Bad magic number (folder type)",0);
if (RF_magic != read_state_ptr -> magic)
panic("MBX PANIC",__FILE__,__LINE__,"copy_envelope_folder",
"Bad magic number (read state)",0);
DPRINT(Debug,10,(&Debug,
"copy_envelope_folder: folder=%p (%s), type=%p (%s)\n",
folder,folder->cur_folder_sys,folder -> folder_type,
folder->folder_type->type_name));
DPRINT(Debug,10,(&Debug,
" : entry=%p",entry));
if (!entry->mbx_info) {
DPRINT(Debug,10,(&Debug,
", { mbx_info=NULL }\n"));
} else {
DPRINT(Debug,10,(&Debug,
", { mbx_info=%p, type=%p }\n",
entry->mbx_info,entry->mbx_info->type_code));
}
read_state_ptr ->skipping = 0; /* 0 == reading, 1 = skipping, -1 == end of message */
entry->body_parsed = 0;
entry->mime_parsed = 0;
status = folder->folder_type->copy_envelope_it(folder,read_state_ptr,
entry,0);
read_state_ptr -> fbytes_body = read_state_ptr -> fbytes;
entry->mime_rec.begin_offset = read_state_ptr -> fbytes;;
DPRINT(Debug,12,(&Debug,
"copy_envelope_folder: {mime} begin_offset = %ld\n",
entry->mime_rec.begin_offset));
/* TEMPORARY? */
if (status > 0) {
int s;
header_list_ptr parsed_headers;
DPRINT(Debug,12,(&Debug,
"copy_envelope_folder: hdr %ld body %ld\n",
entry->offset,read_state_ptr -> fbytes_body));
entry->binary = TRUE;
/* read_folder_headers() -- actually unfold_header()
resets binary flags if LF is seend without CR
*/
entry->header_charset = display_charset;
/* read_folder_headers() will re-set header_charset
if it sees X-ELM-OSV header with parameter
hdr-charset
*/
entry->content_length = -1; /* not found yet */
/* read_folder_headers() will re-set content_length
if it sees Content-Length header
*/
parsed_headers =
read_folder_headers(read_state_ptr,folder,entry);
if (entry->binary) {
DPRINT(Debug,10,(&Debug,
"copy_envelope_folder: binary flag was preserved\n"));
}
if (entry->header_charset != display_charset) {
DPRINT(Debug,10,(&Debug,
"copy_envelope_folder: header charset was modified: %s\n",
entry->header_charset->MIME_name ?
entry->header_charset->MIME_name :
"<no MIME name>"
));
}
if (-1 != entry->content_length) {
DPRINT(Debug,10,(&Debug,
"copy_envelope_folder: content_length set: %ld\n",
entry->content_length
));
}
s = parse_header(folder,read_state_ptr,entry,parsed_headers);
if (s <= 0) {
DPRINT(Debug,10,(&Debug,
"copy_envelope_folder: parse_header callback failed (%d)\n",
s));
status = -1;
} else {
if (read_state_ptr ->skipping) {
DPRINT(Debug,10,(&Debug,
"copy_envelope_folder: Body skipped\n"));
} else {
s = parse_body(folder,read_state_ptr,entry,parsed_headers,counter);
if (s <= 0) {
DPRINT(Debug,10,(&Debug,
"copy_envelope_folder: parse_body callback failed (%d)\n",
s));
status = -1;
}
}
delete_headers(&parsed_headers);
}
}
if (-1 != read_state_ptr ->skipping &&
status > 0) {
int s;
DPRINT(Debug,10,(&Debug,
"copy_envelope_folder: copy_envelope_end_folder not called or succeed (skipping=%d)\n",
read_state_ptr ->skipping));
s = folder->folder_type->copy_envelope_end_it(folder,read_state_ptr);
if (s <= 0) {
DPRINT(Debug,10,(&Debug,
"copy_envelope_folder: copy_envelope_end_it failed (%d)\n",
s));
status = -1;
} else
read_state_ptr ->skipping = -1;
}
DPRINT(Debug,10,(&Debug,
"copy_envelope_folder=%d\n",
status));
return status;
}
#if ANSI_C
extern parse_mime_callback NO_mime_parse;
#endif
int NO_mime_parse(folder,entry,fp)
struct folder_info *folder;
struct header_rec *entry;
FILE *fp;
{
return 1; /* OK, but not set parsed flag */
}
int prepare_message_access(folder,entry,parse_header,
parse_body,counter,parse_mime)
struct folder_info *folder;
struct header_rec *entry;
parse_header_callback *parse_header;
parse_body_callback *parse_body;
struct counter_data *counter;
parse_mime_callback *parse_mime;
{
int status = 1;
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"prepare_message_access",
"Bad magic number (folder type)",0);
DPRINT(Debug,10,(&Debug,
"prepare_message_access: folder=%p (%s), type=%p (%s)\n",
folder,folder->cur_folder_sys,folder -> folder_type,
folder->folder_type->type_name));
DPRINT(Debug,10,(&Debug,
" : entry=%p",entry));
if (!entry->mbx_info) {
DPRINT(Debug,10,(&Debug,
", { mbx_info=NULL }\n"));
} else {
DPRINT(Debug,10,(&Debug,
", { mbx_info=%p, type=%p }\n",
entry->mbx_info,entry->mbx_info->type_code));
}
if (! entry->body_parsed) {
READ_STATE read_state_ptr;
DPRINT(Debug,10,(&Debug,
"prepare_message_access: Need read message\n",
folder,folder->cur_folder_sys));
malloc_read_folder_state(&read_state_ptr);
folder->folder_type->zero_rs_fields_it(read_state_ptr);
if (!folder->p->fh_temp) {
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"folder_to_message",
"Internal error -- no temp file",0);
}
read_state_ptr->mode = PREPARE_ACCESS;
status = folder->folder_type->prepare_read_it(folder,PREPARE_ACCESS,
read_state_ptr);
if (!status)
goto fail2;
/* 0 == reading, 1 = skipping, -1 == end of message */
read_state_ptr ->skipping = 0;
status = folder->folder_type->copy_envelope_it(folder,read_state_ptr,
entry,1 /*force */);
read_state_ptr -> fbytes_body = read_state_ptr -> fbytes;
entry->mime_rec.begin_offset = read_state_ptr -> fbytes;
DPRINT(Debug,12,(&Debug,
"prepare_message_access: {mime} begin_offset = %ld\n",
entry->mime_rec.begin_offset));
if (status > 0) {
header_list_ptr parsed_headers = NULL;
DPRINT(Debug,12,(&Debug,
"prepare_message_access: hdr %ld body %ld\n",
entry->offset,read_state_ptr -> fbytes_body));
parsed_headers =
read_folder_headers(read_state_ptr,folder,entry);
status = parse_header(folder,read_state_ptr,entry,parsed_headers);
if (status <= 0) {
DPRINT(Debug,10,(&Debug,
"prepare_message_access: parse_header callback failed (%d)\n",
status));
goto fail3;
}
status = parse_body(folder,read_state_ptr,entry,parsed_headers,counter);
if (status <= 0) {
DPRINT(Debug,10,(&Debug,
"prepare_message_access: parse_body callback failed (%d)\n",
status));
}
fail3:
if (parsed_headers) {
delete_headers(&parsed_headers);
}
}
fail2:
folder->folder_type->end_read_it(folder,read_state_ptr,1);
folder->folder_type->free_rs_fields_it(read_state_ptr);
free_read_folder_state(&read_state_ptr);
if (!status)
goto fail;
}
if (! entry->mime_parsed && parse_mime == NO_mime_parse) {
DPRINT(Debug,10,(&Debug,
"prepare_message_access: mime structure not needed\n"));
} else if (! entry->mime_parsed) {
FILE * F;
DPRINT(Debug,10,(&Debug,
"prepare_message_access: Need parsing of mime structure (offset %ld)\n",
entry->offset
));
/* Offset of current message */
F = folder->folder_type->xxx_to_fd(folder,entry->offset);
if (!F) {
status = 0;
goto fail;
}
status = parse_mime(folder,entry,F);
if (status <= 0) {
DPRINT(Debug,10,(&Debug,
"prepare_message_access: parse_mime callback failed (%d)\n",
status));
}
}
fail:
DPRINT(Debug,10,(&Debug,
"prepare_message_access=%d\n",status));
return status;
}
CONST char * is_forwarded_folder(folder,read_state_ptr)
struct folder_info *folder;
READ_STATE read_state_ptr;
{
CONST char *ret;
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"is_forwarded_folder",
"Bad magic number (folder type)",0);
if (RF_magic != read_state_ptr -> magic)
panic("MBX PANIC",__FILE__,__LINE__,"is_forwarded_folder",
"Bad magic number (read state)",0);
DPRINT(Debug,10,(&Debug,
"is_forwarded_folder: folder=%p (%s), type=%p (%s)\n",
folder,folder->cur_folder_sys,folder -> folder_type,
folder->folder_type->type_name));
ret=folder->folder_type->is_forwarded_it(folder,read_state_ptr);
DPRINT(Debug,10,(&Debug,
"is_forwarded_folder=%s\n",
ret ? ret : "<NULL>"));
return ret;
}
long copy_fbytes_folder(folder,read_state_ptr)
struct folder_info *folder;
READ_STATE read_state_ptr;
{
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"copy_fbytes_folder",
"Bad magic number (folder type)",0);
if (RF_magic != read_state_ptr -> magic)
panic("MBX PANIC",__FILE__,__LINE__,"copy_fbytes_folder",
"Bad magic number (read state)",0);
DPRINT(Debug,10,(&Debug,
"copy_fbytes_folder=%ld: folder=%p (%s), type=%p (%s)\n",
read_state_ptr->fbytes,
folder,folder->cur_folder_sys,folder -> folder_type,
folder->folder_type->type_name));
return read_state_ptr->fbytes;
}
int copy_lines_folder(folder,read_state_ptr)
struct folder_info *folder;
READ_STATE read_state_ptr;
{
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"copy_lines_folder",
"Bad magic number (folder type)",0);
if (RF_magic != read_state_ptr -> magic)
panic("MBX PANIC",__FILE__,__LINE__,"copy_lines_folder",
"Bad magic number (read state)",0);
DPRINT(Debug,10,(&Debug,
"copy_lines_folder=%d: folder=%p (%s), type=%p (%s)\n",
read_state_ptr -> linecounter,
folder,folder->cur_folder_sys,folder -> folder_type,
folder->folder_type->type_name));
return read_state_ptr -> linecounter;
}
/* Gives header including continuation lines */
int copy_header_folder(folder,read_state_ptr,buffer,len)
struct folder_info *folder;
READ_STATE read_state_ptr;
char **buffer;
int *len;
{
int status;
*buffer = NULL;
*len = 0;
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"copy_header_folder",
"Bad magic number (folder type)",0);
if (RF_magic != read_state_ptr -> magic)
panic("MBX PANIC",__FILE__,__LINE__,"copy_header_folder",
"Bad magic number (read state)",0);
DPRINT(Debug,10,(&Debug,
"copy_header_folder: folder=%p (%s), type=%p (%s)\n",
folder,folder->cur_folder_sys,folder -> folder_type,
folder->folder_type->type_name));
status = folder->folder_type->copy_header_it(folder,read_state_ptr,
buffer,len);
read_state_ptr -> fbytes_body = read_state_ptr -> fbytes;
DPRINT(Debug,10,(&Debug,
"copy_header_folder=%d\n",
status));
return status;
}
int copy_body_folder(folder,read_state_ptr,buffer,len,content_remaining)
struct folder_info *folder;
READ_STATE read_state_ptr;
char **buffer;
int *len;
long *content_remaining;
{
int ret;
*buffer = NULL;
*len = 0;
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"copy_body_folder",
"Bad magic number (folder type)",0);
if (RF_magic != read_state_ptr -> magic)
panic("MBX PANIC",__FILE__,__LINE__,"copy_body_folder",
"Bad magic number (read state)",0);
DPRINT(Debug,10,(&Debug,
"copy_body_folder: folder=%p (%s), type=%p (%s)\n",
folder,folder->cur_folder_sys,folder -> folder_type,
folder->folder_type->type_name));
if (*content_remaining == 0L) {
/* If content remining has gone 0, let
let routine copy_envelope_end_folder()
check end of message
-1 indicates no content-length given;
*/
DPRINT(Debug,10,(&Debug,
"copy_body_folder=0 (*content_remaining == 0)\n"));
return 0;
}
ret=folder->folder_type->copy_body_it(folder,read_state_ptr,
buffer,len,
content_remaining);
DPRINT(Debug,10,(&Debug,
"copy_body_folder=%d\n",
ret));
return ret;
}
/* Returns 0 if not end of message (needs resync without content-length) */
int copy_envelope_end_folder(folder,read_state_ptr)
struct folder_info *folder;
READ_STATE read_state_ptr;
{
int ret;
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"copy_envelope_end_folder",
"Bad magic number (folder type)",0);
if (RF_magic != read_state_ptr -> magic)
panic("MBX PANIC",__FILE__,__LINE__,"copy_envelope_end_folder",
"Bad magic number (read state)",0);
DPRINT(Debug,10,(&Debug,
"copy_envelope_end_folder: folder=%p (%s), type=%p (%s)\n",
folder,folder->cur_folder_sys,folder -> folder_type,
folder->folder_type->type_name));
ret=folder->folder_type->copy_envelope_end_it(folder,read_state_ptr);
if (ret) {
/* 0 == reading, 1 = skipping, -1 == end of message */
read_state_ptr ->skipping = -1;
}
DPRINT(Debug,10,(&Debug,
"copy_envelope_end_folder=%d\n",
ret));
return ret;
}
int copy_envelope_reset_body(folder,read_state_ptr,content_remaining)
struct folder_info *folder;
READ_STATE read_state_ptr;
long *content_remaining;
{
int ret;
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"copy_envelope_reset_body",
"Bad magic number (folder type)",0);
if (RF_magic != read_state_ptr -> magic)
panic("MBX PANIC",__FILE__,__LINE__,"copy_envelope_reset_body",
"Bad magic number (read state)",0);
DPRINT(Debug,10,(&Debug,
"copy_envelope_reset_body: folder=%p (%s), type=%p (%s)\n",
folder,folder->cur_folder_sys,folder -> folder_type,
folder->folder_type->type_name));
if (*content_remaining < 0L) {
panic("MBX PANIC",__FILE__,__LINE__,"copy_envelope_reset_body",
"*content_remaining < 0",0);
}
*content_remaining = -1L;
ret=folder->folder_type->copy_envelope_reset_it(folder,read_state_ptr);
DPRINT(Debug,10,(&Debug,
"copy_envelope_reset_body=%d\n",
ret));
return ret;
}
FILE * folder_to_fd(folder,offset)
struct folder_info *folder;
long offset;
{
FILE *ret;
DPRINT(Debug,10,(&Debug,
"folder_to_fd: folder=%p (%s), type=%p (%s)\n",
folder,folder->cur_folder_sys,folder -> folder_type,
folder->folder_type->type_name));
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"folder_to_fd",
"Bad magic number (folder type)",0);
ret=folder->folder_type->xxx_to_fd(folder,offset);
DPRINT(Debug,10,(&Debug,
"folder_to_fd=%s (%p)\n",
ret ? "NON-NULL" : "NULL",
ret));
return ret;
}
int new_mail_on_folder(folder,bytes)
struct folder_info *folder;
int *bytes;
{
int ret;
DPRINT(Debug,10,(&Debug,
"new_mail_on_folder: folder=%p (%s), type=%p (%s)\n",
folder,folder->cur_folder_sys,folder -> folder_type,
folder->folder_type->type_name));
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"new_mail_on_folder",
"Bad magic number (folder type)",0);
ret=folder->folder_type->new_mail_on_it(folder,bytes);
DPRINT(Debug,10,(&Debug,
"new_mail_on_folder=%d\n",
ret));
return ret;
}
int consider_remove_folder(folder)
struct folder_info *folder;
{
DPRINT(Debug,10,(&Debug,
"consider_remove_folder: folder=%p (%s), type=%p (%s)\n",
folder,folder->cur_folder_sys,folder -> folder_type,
folder->folder_type->type_name));
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"consider_remove_folder",
"Bad magic number (folder type)",0);
if (!keep_empty_files) {
if(folder->folder_type->consider_remove_it(folder)) {
close_folder(folder,CLOSE_NORMAL);
DPRINT(Debug,10,(&Debug,
"consider_remove_folder=1\n"));
return 1;
}
}
DPRINT(Debug,10,(&Debug,
"consider_remove_folder=0 (keep_empty_files=%d)\n",
keep_empty_files));
return 0;
}
int prepare_keep_folder(folder,keep_state_ptr)
struct folder_info *folder;
KEEP_STATE * keep_state_ptr;
{
int status;
KEEP_STATE ptr = NULL;
DPRINT(Debug,10,(&Debug,
"prepare_keep_folder: folder=%p (%s), type=%p (%s)\n",
folder,folder->cur_folder_sys,folder -> folder_type,
folder->folder_type->type_name));
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"prepare_keep_folder",
"Bad magic number (folder type)",0);
malloc_keep_folder_state(&ptr);
folder->folder_type->zero_ks_fields_it(ptr);
status = folder->folder_type->prepare_keep_it(folder,ptr);
if (!status) {
folder->folder_type->free_ks_fields_it(ptr);
free_keep_folder_state(&ptr);
}
*keep_state_ptr = ptr;
DPRINT(Debug,10,(&Debug,
"prepare_keep_folder=%d\n",
status));
return status;
}
int end_keep_folder(folder,keep_state_ptr)
struct folder_info *folder;
KEEP_STATE * keep_state_ptr;
{
int status = 0;
KEEP_STATE ptr = *keep_state_ptr;
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"end_keep_folder",
"Bad magic number (folder type)",0);
if (KS_magic != ptr->magic)
panic("MBX PANIC",__FILE__,__LINE__,"end_keep_folder",
"Bad magic number (keep state)",0);
DPRINT(Debug,10,(&Debug,
"end_keep_folder: folder=%p (%s), type=%p (%s)\n",
folder,folder->cur_folder_sys,folder -> folder_type,
folder->folder_type->type_name));
status = folder->folder_type->end_keep_it(folder,ptr);
folder->folder_type->free_ks_fields_it(ptr);
free_keep_folder_state(&ptr);
*keep_state_ptr = ptr;
DPRINT(Debug,10,(&Debug,
"end_keep_folder=%d\n",
status));
return status;
}
void mark_keep_folder(folder,keep_state_ptr,entry,keep)
struct folder_info *folder;
KEEP_STATE keep_state_ptr;
struct header_rec *entry;
int keep;
{
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"mark_keep_folder",
"Bad magic number (folder type)",0);
if (KS_magic != keep_state_ptr->magic)
panic("MBX PANIC",__FILE__,__LINE__,"mark_keep_folder",
"Bad magic number (keep state)",0);
DPRINT(Debug,10,(&Debug,
"mark_keep_folder: folder=%p (%s), type=%p (%s)\n",
folder,folder->cur_folder_sys,folder -> folder_type,
folder->folder_type->type_name));
DPRINT(Debug,10,(&Debug,
" : entry=%p",entry));
if (!entry->mbx_info) {
DPRINT(Debug,10,(&Debug,
", { mbx_info=NULL }\n"));
} else {
DPRINT(Debug,10,(&Debug,
", { mbx_info=%p, type=%p }\n",
entry->mbx_info,entry->mbx_info->type_code));
}
folder->folder_type->mark_keep_it(folder,keep_state_ptr,entry,keep);
}
CONST char * folder_type(folder)
struct folder_info *folder;
{
CONST char *ret;
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"folder_type",
"Bad magic number (folder type)",0);
DPRINT(Debug,10,(&Debug,
"folder_type: folder=%p (%s), type=%p (%s)\n",
folder,folder->cur_folder_sys,folder -> folder_type,
folder->folder_type->type_name));
ret=folder->folder_type->type(folder);
DPRINT(Debug,10,(&Debug,
"folder_type=%s\n",
ret ? ret : "<NULL>"));
return ret;
}
int get_folder_mode(folder)
struct folder_info *folder;
{
int ret = 0;
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"get_folder_mode",
"Bad magic number (folder type)",0);
DPRINT(Debug,10,(&Debug,
"get_folder_mode: folder=%p (%s), type=%p (%s)\n",
folder,folder->cur_folder_sys,folder -> folder_type,
folder->folder_type->type_name));
ret = folder->folder_type->get_it_mode(folder);
DPRINT(Debug,10,(&Debug,
"get_folder_mode=%d\n",ret));
return ret;
}
int start_edit_folder(folder,buffer)
struct folder_info *folder;
CONST char **buffer;
{
int ret;
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"start_edit_folder",
"Bad magic number (folder type)",0);
DPRINT(Debug,10,(&Debug,
"start_edit_folder: folder=%p (%s), type=%p (%s)\n",
folder,folder->cur_folder_sys,folder -> folder_type,
folder->folder_type->type_name));
ret=folder->folder_type->start_edit_it(folder,buffer);
DPRINT(Debug,10,(&Debug,
"start_edit_folder=%d\n",
ret));
return ret;
}
int end_edit_folder(folder)
struct folder_info *folder;
{
int ret;
DPRINT(Debug,10,(&Debug,
"end_edit_folder: folder=%p (%s), type=%p (%s)\n",
folder,folder->cur_folder_sys,folder -> folder_type,
folder->folder_type->type_name));
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"end_edit_folder",
"Bad magic number (folder type)",0);
ret=folder->folder_type->end_edit_it(folder);
DPRINT(Debug,10,(&Debug,
"end_edit_folder=%d\n",
ret));
return ret;
}
void write_folder_info(F,folder)
FILE *F;
struct folder_info *folder;
{
DPRINT(Debug,10,(&Debug,
"write_folder_info: folder=%p (%s), type=%p (%s)\n",
folder,folder->cur_folder_sys,folder -> folder_type,
folder->folder_type->type_name));
if (!valid_magic(folder->folder_type))
panic("MBX PANIC",__FILE__,__LINE__,"write_folder_info",
"Bad magic number (folder type)",0);
fprintf(F, "F%s\n",
(folder->folder_type == NON_SPOOL ?
folder->cur_folder_sys :
folder->cur_tempfolder));
}
void change_rec_mbx_info(entry, t)
struct header_rec *entry;
info_type_t t;
{
DPRINT(Debug,14,(&Debug,
"change_rec_mbx_info: entry=%p, (new)t=%p\n",
entry,t));
/* Make new mbx_info */
if (entry->mbx_info) {
DPRINT(Debug,14,(&Debug,
" : mbx_info=%p, type=%p\n",
entry->mbx_info,entry->mbx_info->type_code));
DPRINT(Debug,14,(&Debug,
"change_rec_mbx_info: resetting current mbx_info...\n"));
entry->mbx_info->type_code->free_it(entry->mbx_info);
} else {
DPRINT(Debug,14,(&Debug,
" : mbx_info=NULL\n"));
}
entry->mbx_info = safe_realloc(entry->mbx_info,
sizeof (struct mbx_hdr_info));
bzero((void *)entry->mbx_info,sizeof (struct mbx_hdr_info));
entry->mbx_info->type_code = t;
entry->mbx_info->type_code->zero_it(entry->mbx_info);
}
void mbx_status_hook(hdr,buffer)
struct header_rec *hdr;
char *buffer;
{
/* buffer[0] interim status of the message
buffer[1] permanent attributes of the message
*/
if (hdr->mbx_info)
hdr->mbx_info->type_code->it_status(hdr->mbx_info,
buffer);
}
void free_rec_mbx_info(entry)
struct header_rec *entry;
{
DPRINT(Debug,10,(&Debug,
"free_rec_mbx_info: entry=%p\n",
entry));
if (!entry->mbx_info) {
DPRINT(Debug,10,(&Debug,
" : mbx_info=NULL\n"));
return;
}
if (entry->mbx_info) {
DPRINT(Debug,10,(&Debug,
" : mbx_info=%p, type=%p\n",
entry->mbx_info,entry->mbx_info->type_code));
entry->mbx_info->type_code->free_it(entry->mbx_info);
free(entry->mbx_info);
entry->mbx_info = NULL;
}
}
void unfold_header(buffer,len,current_header)
char *buffer;
int *len;
struct header_rec *current_header;
{
char *c, *p;
enum tag { t_NORMAL, t_CR, t_LF } tag = t_NORMAL;
DPRINT(Debug,65,(&Debug,
"fold_header- len=%d,buffer=%.*s",*len,*len,buffer));
if (*len < 1 || !(buffer) || (buffer)[*len -1] != '\n') {
DPRINT(Debug,65,(&Debug,
"\nfold_header- NO NEWLINE\n"));
}
/* Unfold and remove newline ... */
for (c = buffer, p = buffer; c < buffer + *len; c++) {
switch(*c) {
case '\n':
if (tag != t_CR && current_header && current_header->binary) {
current_header->binary = 0;
DPRINT(Debug,12,(&Debug,
"-- Not a binary message\n"));
}
tag = t_LF;
break;
case '\r':
tag = t_CR;
break;
case ' ':
case '\t':
if (tag == t_LF) {
*(p++) = ' ';
tag = t_NORMAL;
break;
}
default:
*(p++) = *c;
case '\0':
tag = t_NORMAL;
}
}
*p = '\0';
*len = p-buffer;
DPRINT(Debug,65,(&Debug,
"fold_header: len=%d,buffer=%.*s\n",*len,*len,buffer));
}
/* result MALLOCED */
char * return_path_to_env_from_1(value)
CONST char *value;
{
char * temp = NULL;
char ** tokens = rfc822_tokenize(value);
remove_space_tokenized(tokens);
if (tokens[0] && 0 == strcmp(tokens[0],"<")) {
int start = 1,i;
/* Strip source path */
for (i = 1; tokens[i]; i++) {
if (0 == strcmp(":",tokens[i]))
start = i+1;
if (0 == strcmp(">",tokens[i]))
break;
}
if (!tokens[i]) {
DPRINT(Debug,20,(&Debug,
"Bad Return-Path: %s\n",value));
} else {
int j;
temp = safe_strdup("");
if (0 != strcmp(tokens[1],"@"))
start = 1;
else if (start > 1) {
DPRINT(Debug,20,(&Debug,
" (stripping source path)\n"));
}
for (j = start; j < i; j++)
temp = strmcat(temp,tokens[j]);
}
} else {
DPRINT(Debug,20,(&Debug,
"Bad Return-Path: %s\n",value));
}
free_rfc822tokenized(tokens);
return temp;
}
void return_path_to_env_from(entry,value)
struct header_rec *entry;
CONST char *value;
{
int ef = give_dt_enumerate_as_int(&env_from_source);
DPRINT(Debug,20,(&Debug,
"return_path_to_env_from- value=%s\n",value));
DPRINT(Debug,20,(&Debug,
"env_from_source=%d\n",ef));
/* env_from_source:
0 == forward-from,
1 == from,
2 == return-path
*/
if (ef <3) {
char * temp = return_path_to_env_from_1(value);
if (temp) {
strfcpy(entry->env_from, temp, sizeof(entry->env_from));
DPRINT(Debug,20,(&Debug,
" user=%s\n", temp));
free(temp);
}
}
}
/*
* Local Variables:
* mode:c
* c-basic-offset:4
* buffer-file-coding-system: iso-8859-1
* End:
*/
syntax highlighted by Code2HTML, v. 0.9.1