/* $Id: mbx_imp.h,v 1.74 2006/07/01 07:37:48 hurtta Exp $ */

/******************************************************************************
 *  The Elm (ME+) Mail System  -  $Revision: 1.74 $   $State: Exp $
 *
 *  Author: Kari Hurtta <hurtta+elm@posti.FMI.FI> (was hurtta+elm@ozone.FMI.FI)
 *****************************************************************************/

#ifdef REMOTE_MBX
struct imap_uid_ref {
    int last_mbx_index;        /* Not necessary valid -- just chache */
    int uid_number;
};
#endif

#define RF_magic        0xFA00
struct read_folder_state {
    unsigned short magic;
    long    fbytes;
    int     linecounter;
    long    fbytes_body;
    enum prepare_mode mode;
    int     skipping;   /*  0 == reading, 1 = skipping, -1 == end of message */
    int     skip_count;
    long    skip_bytes;

    union {
	struct FILE_rs {
	    char    * next_line;
	    int     next_line_len;
	} file;
#ifdef REMOTE_MBX
	struct POP_MBX_rs {
	    int msg_num;              /* Current msg_num */
	    int data_idx;
	    char **uidl_vector;
	    int uidl_count;
	    int *rfc822_size_vector;
	    int rfc822_size_count;
	} pop_mbx;
	struct IMAP_MBX_rs {
	    struct imap_uid_ref  current_message;
	    int                  data_idx;
	} imap_mbx;
#endif
    } a;
};

typedef void mbx_close_folder P_((struct folder_info *folder,
				  enum close_mode mode));
typedef int  mbx_lock_folder  P_((int direction,struct folder_info *folder));
typedef int  mbx_unlock_folder P_((int interrupt, struct folder_info *folder));
typedef void mbx_flush_folder P_((struct folder_info *folder));
typedef void mbx_init_folder P_((struct folder_info *folder));
typedef void mbx_free_folder P_((struct folder_info *folder));
typedef int mbx_sessionlock_folder P_((struct folder_info *folder,
				       enum sessionlock_mode mode));
typedef int mbx_ferror_folder P_((struct folder_info *folder, int clean));
typedef int mbx_prepare_read_folder P_((struct folder_info *folder,
					enum prepare_mode mode,
					READ_STATE read_state_ptr));
typedef int mbx_end_read_folder P_((struct folder_info *folder,
				    READ_STATE read_state_ptr,
				    int silent));
typedef int mbx_copy_envelope_folder P_((struct folder_info *folder,
					 READ_STATE read_state_ptr,
					 struct header_rec *entry,
					 int force));
typedef CONST char * mbx_is_forwarded_folder P_((struct folder_info *folder,
						 READ_STATE read_state_ptr));
typedef int mbx_copy_header_folder P_((struct folder_info *folder,
				       READ_STATE read_state_ptr,
				       char **buffer, int *len));
typedef int mbx_copy_body_folder P_((struct folder_info *folder,
				     READ_STATE read_state_ptr,
				     char **buffer, int *len,
				     long *content_remaining));
typedef int mbx_copy_envelope_end_folder P_((struct folder_info *folder,
					     READ_STATE read_state_ptr));
typedef int mbx_copy_envelope_reset_body P_((struct folder_info *folder,
					     READ_STATE read_state_ptr));
typedef FILE * mbx_folder_to_fd P_((struct folder_info *folder,long offset));
typedef int mbx_new_mail_on_folder P_((struct folder_info *folder,int *bytes));
typedef int mbx_consider_remove_folder P_((struct folder_info *folder));
typedef int mbx_prepare_keep_folder P_((struct folder_info *folder,
					KEEP_STATE keep_state_ptr));
typedef int mbx_end_keep_folder P_((struct folder_info *folder,
				    KEEP_STATE keep_state_ptr));
typedef void mbx_mark_keep_folder P_((struct folder_info *folder,
				      KEEP_STATE keep_state_ptr,
				      struct header_rec *entry,
				      int keep));
typedef CONST char * mbx_folder_type P_((struct folder_info *folder));
typedef int mbx_start_edit_folder P_((struct folder_info *folder, 
				      CONST char **buffer));
typedef int mbx_end_edit_folder P_((struct folder_info *folder));
typedef void mbx_zero_rs_fields_folder P_((struct read_folder_state *rs));
typedef void mbx_free_rs_fields_folder P_((struct read_folder_state *rs));
typedef void mbx_zero_ks_fields_folder P_((struct keep_folder_state *rs));
typedef void mbx_free_ks_fields_folder P_((struct keep_folder_state *rs));
typedef int mbx_get_folder_mode P_((struct folder_info *folder));


struct folder_type {
    CONST char                   * type_name;
    mbx_close_folder             * close_it;
    mbx_lock_folder              * lock_it;
    mbx_init_folder              * init_it;
    mbx_sessionlock_folder       * sessionlock_it;
    mbx_unlock_folder            * unlock_it;
    mbx_flush_folder             * flush_it;
    mbx_ferror_folder            * ferror_it;
    mbx_prepare_read_folder      * prepare_read_it;
    mbx_end_read_folder          * end_read_it;
    mbx_copy_envelope_folder     * copy_envelope_it;
    mbx_is_forwarded_folder      * is_forwarded_it;
    mbx_copy_header_folder       * copy_header_it;
    mbx_copy_body_folder         * copy_body_it;
    mbx_copy_envelope_end_folder * copy_envelope_end_it;
    mbx_copy_envelope_reset_body * copy_envelope_reset_it;
    mbx_folder_to_fd             * xxx_to_fd;
    mbx_new_mail_on_folder       * new_mail_on_it;
    mbx_consider_remove_folder   * consider_remove_it;
    mbx_prepare_keep_folder      * prepare_keep_it;
    mbx_end_keep_folder          * end_keep_it;
    mbx_mark_keep_folder         * mark_keep_it;
    mbx_folder_type              * type;
    mbx_start_edit_folder        * start_edit_it;
    mbx_end_edit_folder          * end_edit_it;
    mbx_free_folder              * free_it;
    mbx_zero_rs_fields_folder    * zero_rs_fields_it;
    mbx_free_rs_fields_folder    * free_rs_fields_it;
    mbx_zero_ks_fields_folder    * zero_ks_fields_it;  
    mbx_free_ks_fields_folder    * free_ks_fields_it;
    mbx_get_folder_mode          * get_it_mode;
};

extern int mbx_copy_line_to_temp P_((struct folder_info *folder,
				     char *buffer, int len));
extern void append_buffer P_((char **buffer, int *len,
			      char *buffer1, int len1));
extern void mbx_flush_temp P_((struct folder_info *folder));

#define KS_magic        0xF000

struct keep_folder_state {
    unsigned short     magic;
    union {
	struct FILE_ks {
	    char * temp_keep_file;
	    FILE * keep_file;
	} file;
    } a;
};

int remote_folder_type P_((struct folder_info *fh));

extern struct folder_type read_only, non_spool, spool;


#ifdef REMOTE_MBX
extern struct folder_type pop_mbx, imap_mbx;



typedef enum { POP_error = 0,
	       POP_idle, POP_simple_command, POP_simple_response,
	       POP_multiline_command, POP_multiline_response, 
	       POP_multiline_data,
	       POP_command_ready, 
	       POP_not_logged } pop_states;



extern void set_remote_tempmbox P_((struct folder_info *fh,
				    struct remote_account *X));

struct imap_token {
    enum token_type { imap_atom, imap_number, 
		      imap_continue, imap_notag,
		      imap_status_keyword,
		      imap_other_keyword,
		      imap_list_begin, imap_list_end,
		      imap_code_begin,  imap_code_end,
		      imap_string, imap_literal ,
		      imap_zero
    }          imap_token;
    long       len_or_value;
    char     * str;
};


struct imap_reference {
    long uid_number;       /* used correlate with Elm mailbox structure */
    long imap_flags;       /* imap \Flag bits                           */

    int    rfc822_size;
    char * internaldate;

    int     header_len;
    char  * header;

    int     body_len;
    char  * body;
};

struct Imap_Token_Buffer {
    struct imap_token * tokens;
    int                 token_count;
};

extern CONST folder_type_p POP_MBX ;
extern CONST folder_type_p IMAP_MBX ;

#define IMAP_writable     1
#define IMAP_flusherr     2
#define IMAP_folder_open  4
#define IMAP_can_CLOSE   16 

#define  POP_disable_skip    1



extern struct connection_type IMAP_connection;


extern void set_imap_connection_state P_((struct connection_cache  *Ch, 
					  imap_states st));


#endif
extern CONST folder_type_p NO_NAME;


struct private_data {
    FILE *fh_temp;		   /* current folder 	     */
    FILE *fh_folder;               /* current folder 	     */

#define FLAG1_CHECKNEW            0x01
    int   flags1;                  /* Set by sessionlock_folder() */

    union {
	struct SPOOL {
	    int  lock_state;
#ifdef	USE_DOTLOCK_LOCKING
	    char *lockfile;
#endif  /* USE_DOTLOCK_LOCKING */
	} spool;
#ifdef REMOTE_MBX
	struct POP_MBX {
	    struct remote_account  C;

	    struct Read_Buffer read_buffer;

	    pop_states pop_state;
	    long       pop_flags;

	    struct Write_Buffer write_buffer;

	    /* Last command */
	    char      command[4];

	    /* parsed response */
	    char      *command_status;
	    char      *command_data;
	    int       data_len;

	    /* size from STAT */
	    int       stat_size;
	    int       stat_count;

	    struct uidl_entry  * uidl_root; /* Binary tree -- not balanced! */
	} pop_mbx;

	struct IMAP_MBX {
	    struct connection_cache  *Ch;

	    char      * folder;       /* IMAP folder, for example INBOX */
	    struct string * folder_name_cache;

	    int       folder_status;
	    long      flag_bits;

	    int       num_recent;
	    
	    struct imap_reference  *references;   /* references[0] not used */
	    int                     reference_count; /* actual number of
							messages +1 */

	    int last_uid_number;    /* uid of last message parsed */
	    
	} imap_mbx;

#endif /* REMOTE_MBX */
    } a;
};

struct mbx_hdr_info {
    struct info_type * type_code;

    union {
	int dummy;
#ifdef REMOTE_MBX
	struct POP_MBX_if {
	    int msg_num;
	    char * uidl;   
	} pop_mbx;
	struct imap_uid_ref imap_mbx;
#endif
    } a;
};

typedef void info_zero_routine P_((struct mbx_hdr_info *info));
typedef void info_free_routine P_((struct mbx_hdr_info *info));
typedef void info_status_routine P_((struct mbx_hdr_info *info,
				     char status_buffer[3]));

typedef struct info_type {
    info_zero_routine    * zero_it;
    info_free_routine    * free_it;
    info_status_routine  * it_status;
}  * info_type_t;

void change_rec_mbx_info P_((struct header_rec *entry,
			     info_type_t t));


typedef void browser_zero_dir P_((struct folder_browser *dir));
typedef void browser_free_dir P_((struct folder_browser *dir));

/* rel_dirname is relative to type -- not include user@hostname */
typedef int browser_change_dir P_((struct folder_browser *dir,
				   struct string *rel_dirname,
				   struct string **dispname));
typedef int browser_select_dir P_((struct folder_browser *dir,
				   const struct string *rel_itemname,
				   struct string **dispname));
#if ANSI_C
struct name_vector;
#endif
typedef int browser_change_v_dir P_((struct folder_browser *dir,
				     struct name_vector *X,
				     struct string **dispname));
typedef int browser_change_up_dir P_((struct folder_browser *dir,
				      struct string **dispname));

typedef struct string * browser_give_title_dir P_((struct folder_browser *dir));

typedef char browser_separator_dir P_((struct folder_browser *dir));
typedef struct string * browser_name_dir P_((struct folder_browser *dir));
typedef struct string * browser_cat_dir P_((struct folder_browser *dir,
					    struct string * item));

typedef struct folder_info * 
browser_folder_from_dir P_((struct folder_browser *dir));
			
typedef int browser_create_selection_dir P_((struct folder_browser *dir));

typedef void zero_ws_fields_browser P_((WRITE_STATE ptr));
typedef void free_ws_fields_browser P_((WRITE_STATE ptr));
typedef int browser_prepare_write_dir P_((struct folder_browser *dir,
					  WRITE_STATE ptr));
typedef int browser_end_write_dir P_((struct folder_browser *dir,
				      WRITE_STATE ptr));

typedef int browser_sync_write_dir P_((struct folder_browser *dir,
				      WRITE_STATE ptr));

typedef long browser_tell_dir_ws P_((struct folder_browser *dir,
				     WRITE_STATE write_state_ptr));
typedef int browser_seek_dir_ws P_((struct folder_browser *dir,
				    WRITE_STATE write_state_ptr,
				    long pos));
typedef int browser_write_dir_ws P_((struct folder_browser *dir,
				     WRITE_STATE write_state_ptr,
				     int l, const char *buffer));

typedef int browser_start_we_dir P_((struct folder_browser *dir,
				     WRITE_STATE write_state_ptr,
				     int write_envelope,
				     struct header_rec *current_header,
				     int *env_flags));

typedef int browser_end_we_dir P_((struct folder_browser *dir,
				   WRITE_STATE write_state_ptr,
				   int write_envelope,
				   struct header_rec *current_header));

typedef int browser_selection_is_folder P_((struct folder_browser *dir,
					    struct folder_info *folder));

typedef int browser_make_ref_folder P_((struct folder_browser *dir,
					char **refname, int *iscopy,
					int is_text));

typedef void browser_update_dir P_((struct folder_browser *dir));

/* Call only if BROWSER_NEEDSTAT is set */
typedef void browser_do_stat P_((struct folder_browser *dir,
				 int idx));
				 
typedef void browser_folder_sort_dir P_((struct folder_browser *dir,
					print_sort_message * print));

#define WS_magic        0xFE00

struct browser_write_state {
    unsigned short magic;
    union {
	struct LOCAL_ws {
	    int     save_fd;
	    FILE *  save_file;
	} local;
#ifdef REMOTE_MBX
	struct IMAP_ws {
	    int    literal_len;
	    char * literal;
	} imap;
#endif
    } a;
};

struct browser_type {
    browser_zero_dir             * browser_zero_it;
    browser_free_dir             * browser_free_it;
    browser_change_dir           * browser_change_it;
    browser_give_title_dir       * browser_give_title_it;
    browser_separator_dir        * browser_separator_it;
    browser_name_dir             * browser_name_it;
    browser_cat_dir              * browser_cat_it;
    browser_select_dir           * browser_select_it;
    browser_folder_from_dir      * browser_folder_from_it;
    browser_change_v_dir         * browser_change_v_it;
    browser_change_up_dir        * browser_change_up_it;
    browser_create_selection_dir * browser_create_selection_it;
    zero_ws_fields_browser       * zero_ws_fields_it;
    free_ws_fields_browser       * free_ws_fields_it;
    browser_prepare_write_dir    * browser_prepare_write_it;
    browser_end_write_dir        * browser_end_write_it;
    browser_tell_dir_ws          * browser_tell_it_ws;
    browser_seek_dir_ws          * browser_seek_it_ws;
    browser_write_dir_ws         * browser_write_it_ws;
    browser_start_we_dir         * browser_start_we_it;
    browser_end_we_dir           * browser_end_we_it;
    browser_selection_is_folder  * browser_selection_is_it;
    browser_make_ref_folder      * browser_make_ref_it;
    browser_update_dir           * browser_update_it;
    browser_do_stat              * browser_stat_routine;
    browser_sync_write_dir       * browser_sync_write_it;
    browser_folder_sort_dir      * browser_folder_sort_it;
};

#ifdef REMOTE_MBX
extern struct browser_type imap_browser;
#endif
#ifdef DIROPS
extern struct browser_type local_browser;

#if DIROPS == USE_DIRENT
#include <dirent.h>
#endif /* DIROPS == USE_DIRENT */
#if DIROPS == USE_SYSDIR
#include <sys/dir.h>
#endif /* DIROPS == USE_SYSDIR */

#endif /* DIROPS */
        
struct folder_browser {
    struct browser_type    * type;

    /* NOTE: sys_dir does not include possible user@host
     *  but  dirname includes possible user@host !
     */
    char                   * sys_dir;     /* Unspecified character set! */
    struct string          * dirname;     /* Display name               */
    

    enum selection_type    sel_type;

    int     vector_len;       /* -1 indicates that browser_update_it
				 should be called ...
			      */
    struct name_vector {
	char           *  sys_name;
	struct string  *  disp_name;
	int               flags;
	time_t            mtime;      /* modify time  for local files */
    }  * vector, *selection;

    struct string * filter;          /*  name filter */

    union {
	struct DUMMY_BROWSER {
	    char *remote;
	} dummy_browser;

#ifdef REMOTE_MBX
	struct IMAP_BROWSER {
	    struct connection_cache * Ch;

	    struct string           * dir_name_cache;

	    /* Assumed that current separator is ASCII here ... */
	    char cur_sep;

	    struct imap_dir_entry {
		char                   * imap_name;
		struct string          * translated_name;
		char                   sep;
		int flags;
	    }       * dir_entries;
	    int     dir_entry_count;

	} imap_browser;
#endif /* REMOTE_MBX */

#ifdef DIROPS
	struct LOCAL_BROWSER {
	    DIR *   handle;
	} local_browser;
#endif

    } a;
};

extern void clear_dir_vector P_((struct folder_browser *dir));
extern void add_dir_vector P_((struct folder_browser *dir,
			       char *sys_name,
			       struct string * disp_name,
			       int flags));
extern void clear_dir_selection P_((struct folder_browser *dir));
extern void set_dir_selection P_((struct folder_browser *dir,
				  char *sys_name,
				  struct string * disp_name,
				  int flags));

enum folder_place { in_none = 0, in_folders = 1, in_home = 2 };

extern struct folder_info *mbx_new_folder P_((void));
extern folder_type_p get_folder_type P_((CONST char *filename, 
					 enum folder_place *in_mail));

extern int in_directory P_((struct stat *buf1, const char *name,
			    const char * dir));
extern int create_as_user P_((const char *name));
extern void zero_ws_fields_local P_((WRITE_STATE ptr));
extern void free_ws_fields_local P_((WRITE_STATE ptr));
extern int real_prepare_write_local P_((struct folder_browser *dir,
					WRITE_STATE ptr,
					const char *filename));
extern int real_end_write_local P_((struct folder_browser *dir,
				    WRITE_STATE ptr,
				    const char *filename));
extern int real_sync_write_local P_((struct folder_browser *dir,
				    WRITE_STATE ptr,
				    const char *filename));
extern long real_browser_tell_ws P_((struct folder_browser *dir,
				     WRITE_STATE write_state_ptr));
extern int real_browser_seek_ws P_((struct folder_browser *dir,
				    WRITE_STATE write_state_ptr,
				    long pos));
extern int real_browser_write_ws P_((struct folder_browser *dir,
				     WRITE_STATE ptr,
				     int l, const char *buffer));
extern int real_select_local P_((struct folder_browser *dir,
				 const struct string *rel_itemname,
				 struct string * relative));

extern int real_start_we_local P_((struct folder_browser *dir,
				   WRITE_STATE write_state_ptr,
				   struct header_rec *current_header,
				   int *env_flags));
extern int real_end_we_local P_((struct folder_browser *dir,
				 WRITE_STATE write_state_ptr,
				 struct header_rec *current_header));

extern int browser_select_generic P_((struct folder_browser *dir,
				      struct string * relative_path,
				      const struct string * rel_dirname,
				      struct string * relative,
				      struct string ** Lstr,
				      char          ** str,
				      int sep,
				      charset_t default_charset));
extern struct folder_info * real_folder_from_local 
P_((struct folder_browser *dir));
extern int real_selection_is_local P_((struct folder_browser *dir,
				       struct folder_info *folder));

extern int real_make_ref_local P_((struct folder_browser *dir,
				   char **refname, int *iscopy,
				   int is_text));

extern int browser_vector_len P_((struct folder_browser *dir));


#ifdef REMOTE_MBX

extern int make_remote_mbox P_((struct folder_info *fh, 
				struct remote_account *X,
				struct service_entry *se, 
				char * rest,
				int rewrite));

typedef uint16 url_default_port_f P_((
	 const struct browser_url_method  *schema));

/* May not be 
      uin16 port
   because this is promoted to int
*/

typedef struct connection_cache * url_make_connection_f P_((
	 const struct browser_url_method  *schema,
	 const struct string              *user   /* May be NULL */,
	 const struct string              *password /* May be NULL */,
	 const char                       *host   /* May be NULL */,
	 int                      port   /* May be NULL */));

/* This is always absolute path -- from root as defined for URL */
typedef int url_select_item_from_URL_f P_((
	const struct browser_url_method  *schema,
	struct folder_browser *dir,
	int elems_count,
	const struct string **elems));


#define BROWSER_URL_method_magic 0xEC09

struct browser_url_method {
    unsigned short         magic;

    struct browser_type    *type;

    url_default_port_f          * url_default_port_it;
    url_make_connection_f       * url_make_it;
    url_select_item_from_URL_f  * url_select_item_from_it_URL;
};

#endif

/* result MALLOCED */
extern char * return_path_to_env_from_1 P_((const char *value));

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


syntax highlighted by Code2HTML, v. 0.9.1