/*
 * Copyright (c) 1999 Ian Freislich
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *      $Id: poputil.h,v 1.14 2003/01/24 09:35:19 ianf Exp $
 */

#define GOT_SIGNAL	-2
enum cmd {INVALCMD = -1, APOP, AUTH, PASS, USER, DELE, LIST, NOOP, QUIT, RETR,
    RSET, STAT, TOP, UIDL, LAST, TIMEDOUT, SESSION_START, SESSION_END, BUL_SIZE,
    BUL_MSGS};

#define IDX_OPEN	1
#define IDX_EXTEND	2
#define IDX_CLOSE	3
#define IDX_O_READ	0x0001
#define IDX_O_MODIFY	0x0002
#define IDX_O_APPEND	0x0004
#define IDX_O_IGNORE	0x0008
#define IDX_NONBLOCK	0x0010

#define IDX_F_NULL	0x0000
#define IDX_F_NOSUCH	0x0001
#define IDX_F_DELETE	0x0002
#define IDX_F_EXPIRE	0x0004
#define IDX_F_REMOVE	0x0008
#define IDX_F_READ	0x0010
#define IDX_F_TOP	0x0020
#define IDX_F_STAT	0x0040

#define MAGIC_HDR	0x6470253c
#define MAGIC_MSG	0x179b137c

struct idx_hdr
{
	int	magic;
	int	max;
	int	count;
	size_t	bytes;
	int	flags;
	int	remove;
	int	expire;
};

struct idx_msg
{
	int	magic;
	off_t	offset;
	char	uidl[33];
	size_t	bytes;
	time_t	d_time;
	int	flags;
};

struct mail_idx
{
	int		file_fd;
	int		last;
	size_t		st_size;
	struct idx_hdr	*hdr;
	struct idx_msg	*msg;
};

/* Mailbox config data */
#define MAILBOX_F_AUTODELETE	0x0001
#define MAILBOX_F_FALSEUIDL	0x0002
#define MAILBOX_F_ENABLETOP	0x0004
#define MAILBOX_F_ENABLEUIDL	0x0008
#define MAILBOX_F_WIREFORMAT	0x0010
#define MAILBOX_F_SORT_TIME	0x0100
#define MAILBOX_F_SORT_SIZE	0x0200
#define MAILBOX_F_FASCIST_LOG	0x0400
#define MAILBOX_F_CMD_LOG	0x0800
#define MAILBOX_F_MAILBOX	0x1000
#define MAILBOX_F_MAILDIR	0x2000
#define MAILBOX_F_MAILDIRCOMPAT	0x4000
#define MAILBOX_F_MAILIDX	0x8000

#define MAILBOX_F_SORTMASK	0x0300
#define MAILBOX_F_MAILMASK	0xf000
#define MAILBOX_F_DEFAULT	0x110c

struct connection {
	int	flags;

	time_t	expire;
	time_t	remove;
	time_t	timeout;

	char	*username;
	char	*password;
	char	*auth_string;
	char	*realm;
	char	*bulletinpath;
	char	*mailpath;

	uid_t	uid;
	uid_t	euid;
};
/* End of mailbox config data */

int     mbox_op(struct connection *, int, char *, char *);

int	mbf_mbox_op(struct connection *, enum cmd, ...);
int	maildir_mbox_op(struct connection *, enum cmd, ...);
int	mailidx_mbox_op(struct connection *, enum cmd, ...);
int	bulletin_mbox_op(struct connection *, enum cmd, ...);

int	mailidx_ctl(struct mail_idx *, char *, int, ...);
int	mailidx_compact(struct connection *);
int	mailidx_check_reindex(char *);

time_t		atosec(const char *tstring);
void		*xmalloc(size_t);
void		*xcalloc(size_t, size_t);
void		*xrealloc(void *, size_t);
size_t		xwrite(const void *, size_t);
size_t		xread(void *, size_t);
char		*binhex (const void *pointer, size_t length);
void		exit_error(int exit, char *format, ...);
void		freeconnection(struct connection *);
char		*make_timestamp (void);
enum cmd	recvcmd(char **arg1, char **arg2);
enum send {SEND_BUF, SEND_FLUSH};
void		sendline(enum send, const char *format, ...);
int		cxndetails(struct connection *, char *, char *, char *, char *, int, int);
void		poputil_init(FILE *, FILE *, time_t, int);
#ifdef USE_SSL
void		ssl_init(int, char *, char *, char *);
void		ssl_accept(int);
#endif
void		poputil_end(void);
int		openlock(const char *path, int flags, ...);
void		log_stats(char *, int, int, int, int, int, int, int, int, int);
enum msg {NOSUCH, BADNUM, BADARG, ALREADYDELETED, MSGINVAL, CMDISABLE, CMDINVAL,
    OUTOFRANGE, CHALLENGEINVAL, TOOFEWARGUMENTS, NEEDUSERNAME, BADPASSWORD,
    NEEDPASSWORD};
void		message(enum msg);
char		*ntocmd(enum cmd);
