/* $Id: mboxlib.h,v 1.10 2006/07/01 08:40:52 hurtta Exp $ */

/******************************************************************************
 *  The Elm (ME+) Mail System  -  $Revision: 1.10 $   $State: Exp $
 *
 *  Author: Kari Hurtta <hurtta+elm@posti.FMI.FI>
 *      or  Kari Hurtta <elm@elmme-mailer.org>
 *****************************************************************************/

/* declarations */

typedef struct read_folder_state * READ_STATE;

/* init.c */

extern void init_mboxlib P_((void));

/* expires.c */

extern void process_expiration_date P_((char *date,
					int  *message_status));

/* forwarded.c */

extern void forwarded P_((char *buffer, struct header_rec *entry));

/* getword.c */

extern int get_word P_((const char *buffer,int start,
			char *word,int wordlen));

/* header_cmp.c */

extern char * header_cmp P_((char *header, char *prefix, char *suffix));

/* headers.c */

extern void read_folder_headers_helper P_((struct header_rec *entry,
					   header_list_ptr result));

extern header_list_ptr read_folder_headers P_((READ_STATE read_state_ptr,
					       struct folder_info *folder,
					       struct header_rec *entry));

/* localmbx.c */

extern void remove_possible_trailing_spaces P_((char *string));
extern void mailbox_2_status P_((char * status, struct header_rec *entry));
extern int status_2_mailbox P_((struct header_rec *entry, char *buffer, 
				int size));

extern int Release_the_file P_((int flock_fd));
extern int Grab_the_file P_((int flock_fd));

/* mbox.c */

extern int same_file P_((char *,char *)); 


enum sessionlock_mode { SESSIONLOCK_NORMAL   = 0,
			SESSIONLOCK_REOPEN   = 1,
			SESSIONLOCK_TRUNCATE = 2,
			SESSIONLOCK_CHECK    = 3,
			SESSIONLOCK_NONE     = 4,
	SESSIONLOCK_NONE_CHECKNEW    =  0x80 + 4 /* not actually mode */ 
};


typedef struct folder_type * folder_type_p;

struct folder_info {
    char             * cur_folder_sys;	 /* name of current folder         */
    struct string    * cur_folder_disp;  /* Display name of current folder */

    char cur_tempfolder[SLEN];  /* name of temp folder open for a mailbox */

    folder_type_p folder_type;	 /* flag: type of folder     */
    long mailfile_size;	         /* size of current mailfile */

    struct private_data * p;
};

enum close_mode { CLOSE_NORMAL = 0,
		  CLOSE_LEAVE_LOCKED = 1 };

extern void close_folder P_((struct folder_info *folder,
			     enum close_mode mode));
extern void flush_folder P_((struct folder_info *folder));

extern struct folder_info *enter_new_folder P_((const char 
						*new_file)); /* create */
extern void leave_old_folder P_((struct folder_info **folder,
				 enum close_mode mode));    /* free   */

#define FOLDER_MBOX          0x001         /* Folder is mbox */
#define FOLDER_RDONLY        0x002         /* Folder is read-only */
#define FOLDER_FILE          0x004         /* Folder is file */

extern int get_folder_mode P_((struct folder_info *folder));

/* Opens folder -- Return 1 on succeed */
extern int sessionlock_folder P_((struct folder_info *folder,
				  enum sessionlock_mode mode));
/* Return 1 on succeed */
extern int lock_folder P_((int direction,struct folder_info *folder));
extern int unlock_folder P_((int interrupt, struct folder_info *folder));
extern int ferror_folder P_((struct folder_info *folder, int clean));

enum prepare_mode { PREPARE_NORMAL = 0, PREPARE_NEW_ONLY = 1,
		    PREPARE_NOLOCK = 2, PREPARE_NEW_ONLY_NOLOCK = 3,
		    PREPARE_ACCESS = 4 };

extern int prepare_read_folder P_((struct folder_info *folder,
				   enum prepare_mode mode,
				   READ_STATE * read_state_ptr));
extern int end_read_folder P_((struct folder_info *folder,
			       READ_STATE * read_state_ptr,
			       int silent));

#ifdef ANSI_C
struct counter_data;
#endif

/* 0 = Error, 1 = OK */
typedef int parse_header_callback P_((struct folder_info *folder,
				      READ_STATE read_state_ptr,
				      struct header_rec *entry,
				      header_list_ptr parsed_headers ));
typedef int parse_body_callback P_((struct folder_info *folder,
				    READ_STATE read_state_ptr,
				    struct header_rec *entry,
				    header_list_ptr parsed_headers,
				    struct counter_data *counter
				    ));

/* Returns:  0 = End of folder
             1 = OK
	    -1 = format error
*/
extern int copy_envelope_folder P_((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));

extern CONST char * is_forwarded_folder P_((struct folder_info *folder,
					    READ_STATE read_state_ptr));
extern long copy_fbytes_folder P_((struct folder_info *folder,
				   READ_STATE read_state_ptr));
extern int copy_lines_folder P_((struct folder_info *folder,
				   READ_STATE read_state_ptr));
extern void copy_skipcount_folder P_((struct folder_info *folder,
				      READ_STATE read_state_ptr,
				      int *skipcount,
				      long *skipbytes));

/* Gives header including continuation lines */
extern int copy_header_folder P_((struct folder_info *folder,
				  READ_STATE read_state_ptr,
				  char **buffer, int *len));

/* Unfolds line returned by copy_header_folder */
extern void unfold_header P_((char *buffer, int *len, 
			    struct header_rec *current_header));

extern void mbx_status_hook P_((struct header_rec *hdr, char *buffer));

extern int copy_body_folder P_((struct folder_info *folder,
				READ_STATE read_state_ptr,
				char **buffer, int *len,
				long *content_remaining));

/* Returns 0 if not end of message (needs resync without content-length) */
extern int copy_envelope_end_folder P_((struct folder_info *folder,
					READ_STATE read_state_ptr));

extern int copy_envelope_reset_body P_((struct folder_info *folder,
                                        READ_STATE read_state_ptr,
					long *content_remaining));

typedef int parse_mime_callback P_((struct folder_info *folder,
				   struct header_rec *entry,
				   FILE *fp));
extern int NO_mime_parse P_((struct folder_info *folder,
                                   struct header_rec *entry,
                                   FILE *fp));


extern int prepare_message_access P_((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
				      ));

extern FILE * folder_to_fd P_((struct folder_info *folder,long offset));

extern int new_mail_on_folder P_((struct folder_info *folder,int *bytes));

/* possible removes file and closes folder -- 
   returns 1 if removed  and closed */
extern int consider_remove_folder P_((struct folder_info *folder));

typedef struct keep_folder_state * KEEP_STATE;

extern int prepare_keep_folder P_((struct folder_info *folder,
				   KEEP_STATE * keep_state_ptr));
extern int end_keep_folder P_((struct folder_info *folder,
			       KEEP_STATE * keep_state_ptr));
extern void mark_keep_folder P_((struct folder_info *folder,
				 KEEP_STATE keep_state_ptr,
				 struct header_rec *entry,
				 int keep));

extern CONST char * folder_type P_((struct folder_info *folder));
extern int start_edit_folder P_((struct folder_info *folder, 
				 CONST char **buffer));
extern int end_edit_folder P_((struct folder_info *folder));
extern void write_folder_info P_((FILE *F, struct folder_info *folder));

extern void free_rec_mbx_info P_((struct header_rec *entry));

extern void return_path_to_env_from P_((struct header_rec *entry,
					const char *value));

/* mk_lockname.c */
     
extern char * mk_lockname P_((char *));

/* parsarpdat.c */

extern int parse_date_time P_((const char *str, 
			       char *time_zone, int size_time_zone,
			       time_t *tz_offset, time_t *time_result));

extern int parse_arpa_date P_((char *str,
			       struct header_rec *entry));

/* realfrom.c */

extern int real_from P_((char *buffer, struct header_rec *entry));

/* savefolder.c */

enum selection_type { selection_file, selection_folder, 
		      selection_url };

typedef struct folder_browser  *folder_dir;

extern void free_dir P_((struct folder_browser **dir));
extern struct folder_browser *new_browser P_((enum selection_type  sel_type));


#ifdef REMOTE_MBX

extern CONST struct browser_url_method  URL_imap;   

/* 0 == no port */
extern uint16 browser_URL_default_port P_((const struct browser_url_method  *schema));

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

extern struct folder_browser * browser_connect_URL 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 0 */));

/* Returns 1 on succeed */
/* This is always absolute path -- from root as defined for URL */
extern int select_item_from_URL P_((
	const struct browser_url_method  *schema,
	struct folder_browser *browser,
	int elems_count,
	const struct string **elems));

#endif

/* Returns 1 if succesfully, and may canonify argument
   may change type of dir
 */

extern int change_dir P_((struct folder_browser *dir, 
			  struct string **buffer));
extern int select_dir_item P_((struct folder_browser *dir, 
			       struct string **buffer));
extern int change_dir_to_entry P_((struct folder_browser *dir, 
				   int entry,
				   struct string **buffer));
extern int change_dir_up P_((struct folder_browser *dir, 
			     struct string **buffer));


extern struct string * give_title_dir P_((struct folder_browser *dir,
					  int *entry_count));


/* NULL == clear message */
typedef void print_sort_message P_((struct string *message));
extern void  folder_sort_dir P_((struct folder_browser *dir,
				 print_sort_message * print));

extern int give_edit_buffer P_((struct folder_browser *dir,
				int entry, struct string **buffer,
				int fill_with_entry));

extern int dir_is_wildcard P_((struct folder_browser *dir,
			       struct string **buffer));


#define BROWSER_NODIR              1          /* Not a directory */         
#define BROWSER_NOFOLDER           2          /* Not a folder  */
#define BROWSER_MARKED             4          /* New mails ?   */
#define BROWSER_NEEDSTAT           8          /* Internal only ... */

/* return reference to array -- do not free_string !!! */
extern struct string * give_line_dir P_((struct folder_browser *dir,
					 int idx,
					 int *flags));

/* Operations for selection */

#define BROWSER_MAILFILE            64

#define BROWSER_SELECTED           128
#define BROWSER_EXIST              256
#define BROWSER_DIRPREFIX          512    /* Selection is dir prefix */

extern int give_dir_flags P_((struct folder_browser *dir));
extern struct folder_info * 
folder_from_dir_item P_((struct folder_browser *dir));

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

typedef struct browser_write_state * WRITE_STATE;
extern int prepare_write_folder P_((struct folder_browser *dir,
				    WRITE_STATE * write_state_ptr));
extern int end_write_folder P_((struct folder_browser *dir,
				    WRITE_STATE * write_state_ptr));
extern int sync_write_folder P_((struct folder_browser *dir,
				 WRITE_STATE write_state_ptr));

extern struct string * selection_name_dir P_((struct folder_browser *dir));
extern void clear_selection_dir P_((struct folder_browser *dir));

/* Returns -1 if not seekable, else position */
extern long tell_dir_write_state P_((struct folder_browser *dir,
				    WRITE_STATE write_state_ptr));
/* Returns 0 on failure! */
extern int seek_dir_write_state P_((struct folder_browser *dir,
                                    WRITE_STATE write_state_ptr,
				    long pos));
/* Return 0 on failure */

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

#define WE_ADD_RETURN_PATH           1
#define WE_USE_CRLF                  2

extern int write_dir_write_state P_((struct folder_browser *dir,
				     WRITE_STATE write_state_ptr,
				     int l, const char *buffer));
extern int write_envelope_start P_((struct folder_browser *dir,
				    WRITE_STATE write_state_ptr,
				    int write_envelope,
				    struct header_rec *current_header,
				    int *env_flags));
extern int write_envelope_end P_((struct folder_browser *dir,
				    WRITE_STATE write_state_ptr,
				    int write_envelope,
				    struct header_rec *current_header));

extern int selection_is_folder P_((struct folder_browser *dir,
				   struct folder_info *folder));

/* helper routines for fileio.c */
extern void start_fd_write_state P_((FILE *fd, 
				     struct folder_browser **dir,
				     WRITE_STATE *write_state_ptr));
extern void end_fd_write_state P_((struct folder_browser **dir,
				   WRITE_STATE *write_state_ptr));


/* state.c */

/* STATE_out_dir */
extern void set_out_state_dir   P_((struct folder_browser *,
				    WRITE_STATE,
				    out_state_t *));  

#define   STATE_out_dir      0xEB04   /* _magic */


/* shared_mbox.c */


#ifdef REMOTE_MBX
#ifdef ANSI_C
struct POP_capa_libs;
#endif

extern void probe_pop_capa_lib P_((struct POP_capa_libs * *pop_capa_libs,
				   int                  * pop_capa_libcount,
				   const char *capa,
				   const char *capa_args));


/* Also frees pop_capa_libs list ... */
extern int handle_pop_capa_libs P_((struct folder_info *folder,
				    struct POP_capa_libs * *pop_capa_libs,
				    int                  * pop_capa_libcount,
				    enum CAPA_phase      * phase,
				    struct pop_callbacks *commands));

extern void probe_imap_capa_lib P_((struct IMAP_capa_libs * *imap_capa_libs,
				   int                  * imap_capa_libcount,
				   const char *capa));


enum imap_phase { IMAP_prelogin = 0, IMAP_logged = 1 };
/* Also frees imap_capa_libs list ... */
extern int handle_imap_capa_libs P_((struct connection_cache *con,
				    struct IMAP_capa_libs * *imap_capa_libs,
				    int                  * imap_capa_libcount,
				    enum CAPA_phase      * phase,
				    struct imap_callbacks *commands));

extern void free_only_imap_capa_libs P_((struct IMAP_capa_libs * *imap_capa_libs,
					 int                  * imap_capa_libcount));

#endif

/* error.c */

extern void free_header_errors P_((struct header_errors **error));

extern void process_header_error P_((struct header_errors **error,
				     const char * format, const char *msg, 
				     ...));

extern int get_header_errors_count P_((struct header_errors *error));
extern CONST struct string * get_header_errors_msg P_((struct header_errors *
						       error, int idx));

extern void print_header_errors P_((struct header_errors *error));


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


syntax highlighted by Code2HTML, v. 0.9.1