2004-03-27 16:07:20 +00:00
|
|
|
/*
|
|
|
|
* mbsync - mailbox synchronizer
|
2002-12-28 15:31:20 +00:00
|
|
|
* Copyright (C) 2000-2002 Michael R. Elkins <me@mutt.org>
|
2006-03-20 20:16:22 +00:00
|
|
|
* Copyright (C) 2002-2006 Oswald Buddenhagen <ossi@users.sf.net>
|
2000-12-20 21:41:21 +00:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2011-04-10 17:34:36 +00:00
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2002-10-30 02:31:20 +00:00
|
|
|
*
|
2004-03-27 16:07:20 +00:00
|
|
|
* As a special exception, mbsync may be linked with the OpenSSL library,
|
2002-10-30 02:31:20 +00:00
|
|
|
* despite that library's more restrictive license.
|
2000-12-20 21:41:21 +00:00
|
|
|
*/
|
|
|
|
|
2003-05-07 00:06:37 +00:00
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
2004-09-20 11:28:33 +00:00
|
|
|
#include <stdarg.h>
|
2004-03-27 16:07:20 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
#define as(ar) (sizeof(ar)/sizeof(ar[0]))
|
|
|
|
|
2006-02-03 21:33:43 +00:00
|
|
|
#define __stringify(x) #x
|
|
|
|
#define stringify(x) __stringify(x)
|
|
|
|
|
2004-03-27 16:07:20 +00:00
|
|
|
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
|
|
|
|
# define ATTR_UNUSED __attribute__((unused))
|
|
|
|
# define ATTR_NORETURN __attribute__((noreturn))
|
|
|
|
# define ATTR_PRINTFLIKE(fmt,var) __attribute__((format(printf,fmt,var)))
|
|
|
|
#else
|
|
|
|
# define ATTR_UNUSED
|
|
|
|
# define ATTR_NORETURN
|
|
|
|
# define ATTR_PRINTFLIKE(fmt,var)
|
2000-12-21 06:27:05 +00:00
|
|
|
#endif
|
2000-12-20 21:41:21 +00:00
|
|
|
|
2012-07-15 10:55:04 +00:00
|
|
|
#ifdef __GNUC__
|
|
|
|
# define INLINE __inline__
|
|
|
|
#else
|
|
|
|
# define INLINE
|
|
|
|
#endif
|
|
|
|
|
2004-03-27 16:07:20 +00:00
|
|
|
#define EXE "mbsync"
|
|
|
|
|
2011-01-23 12:43:00 +00:00
|
|
|
typedef struct ssl_st SSL;
|
|
|
|
typedef struct ssl_ctx_st SSL_CTX;
|
|
|
|
typedef struct x509_store_st X509_STORE;
|
|
|
|
|
|
|
|
typedef struct server_conf {
|
|
|
|
char *tunnel;
|
|
|
|
char *host;
|
|
|
|
int port;
|
|
|
|
#ifdef HAVE_LIBSSL
|
|
|
|
char *cert_file;
|
|
|
|
unsigned use_imaps:1;
|
|
|
|
unsigned use_sslv2:1;
|
|
|
|
unsigned use_sslv3:1;
|
|
|
|
unsigned use_tlsv1:1;
|
|
|
|
|
|
|
|
/* these are actually variables and are leaked at the end */
|
|
|
|
SSL_CTX *SSLContext;
|
|
|
|
X509_STORE *cert_store;
|
|
|
|
#endif
|
|
|
|
} server_conf_t;
|
|
|
|
|
2012-08-25 16:26:23 +00:00
|
|
|
typedef struct buff_chunk {
|
|
|
|
struct buff_chunk *next;
|
|
|
|
char *data;
|
|
|
|
int len;
|
|
|
|
char buf[1];
|
|
|
|
} buff_chunk_t;
|
|
|
|
|
2011-01-23 12:43:00 +00:00
|
|
|
typedef struct {
|
2012-08-25 16:26:23 +00:00
|
|
|
/* connection */
|
2011-01-23 12:43:00 +00:00
|
|
|
int fd;
|
2012-08-25 16:26:23 +00:00
|
|
|
int state;
|
|
|
|
const server_conf_t *conf; /* needed during connect */
|
2011-04-10 13:32:25 +00:00
|
|
|
char *name;
|
2011-01-23 12:43:00 +00:00
|
|
|
#ifdef HAVE_LIBSSL
|
|
|
|
SSL *ssl;
|
|
|
|
#endif
|
|
|
|
|
2011-03-27 14:50:32 +00:00
|
|
|
void (*bad_callback)( void *aux ); /* async fail while sending or listening */
|
2012-08-25 16:26:23 +00:00
|
|
|
void (*read_callback)( void *aux ); /* data available for reading */
|
|
|
|
int (*write_callback)( void *aux ); /* all *queued* data was sent */
|
|
|
|
union {
|
|
|
|
void (*connect)( int ok, void *aux );
|
|
|
|
void (*starttls)( int ok, void *aux );
|
|
|
|
} callbacks;
|
2011-03-27 14:50:32 +00:00
|
|
|
void *callback_aux;
|
|
|
|
|
2012-08-25 16:26:23 +00:00
|
|
|
/* writing */
|
|
|
|
buff_chunk_t *write_buf, **write_buf_append; /* buffer head & tail */
|
|
|
|
int write_offset; /* offset into buffer head */
|
|
|
|
|
|
|
|
/* reading */
|
2011-04-03 16:47:37 +00:00
|
|
|
int offset; /* start of filled bytes in buffer */
|
|
|
|
int bytes; /* number of filled bytes in buffer */
|
|
|
|
int scanoff; /* offset to continue scanning for newline at, relative to 'offset' */
|
2011-03-27 15:50:13 +00:00
|
|
|
char buf[100000];
|
2011-01-23 13:06:03 +00:00
|
|
|
} conn_t;
|
2011-01-23 12:43:00 +00:00
|
|
|
|
2004-03-27 16:07:20 +00:00
|
|
|
typedef struct {
|
|
|
|
const char *file;
|
|
|
|
FILE *fp;
|
|
|
|
char *buf;
|
|
|
|
int bufl;
|
|
|
|
int line;
|
|
|
|
char *cmd, *val, *rest;
|
|
|
|
} conffile_t;
|
|
|
|
|
|
|
|
#define OP_NEW (1<<0)
|
|
|
|
#define OP_RENEW (1<<1)
|
|
|
|
#define OP_DELETE (1<<2)
|
|
|
|
#define OP_FLAGS (1<<3)
|
|
|
|
#define OP_MASK_TYPE (OP_NEW|OP_RENEW|OP_DELETE|OP_FLAGS) /* asserted in the target ops */
|
|
|
|
#define OP_EXPUNGE (1<<4)
|
|
|
|
#define OP_CREATE (1<<5)
|
|
|
|
#define XOP_PUSH (1<<6)
|
|
|
|
#define XOP_PULL (1<<7)
|
|
|
|
#define XOP_MASK_DIR (XOP_PUSH|XOP_PULL)
|
|
|
|
#define XOP_HAVE_TYPE (1<<8)
|
|
|
|
#define XOP_HAVE_EXPUNGE (1<<9)
|
|
|
|
#define XOP_HAVE_CREATE (1<<10)
|
|
|
|
|
|
|
|
typedef struct driver driver_t;
|
|
|
|
|
|
|
|
typedef struct store_conf {
|
|
|
|
struct store_conf *next;
|
|
|
|
char *name;
|
|
|
|
driver_t *driver;
|
|
|
|
const char *path; /* should this be here? its interpretation is driver-specific */
|
2005-12-28 10:02:22 +00:00
|
|
|
const char *map_inbox;
|
|
|
|
const char *trash;
|
2004-03-27 16:07:20 +00:00
|
|
|
unsigned max_size; /* off_t is overkill */
|
|
|
|
unsigned trash_remote_new:1, trash_only_new:1;
|
2012-08-18 11:58:14 +00:00
|
|
|
char flat_delim;
|
2004-03-27 16:07:20 +00:00
|
|
|
} store_conf_t;
|
|
|
|
|
|
|
|
typedef struct string_list {
|
|
|
|
struct string_list *next;
|
|
|
|
char string[1];
|
|
|
|
} string_list_t;
|
|
|
|
|
2005-12-28 10:02:22 +00:00
|
|
|
#define M 0 /* master */
|
|
|
|
#define S 1 /* slave */
|
|
|
|
|
2004-03-27 16:07:20 +00:00
|
|
|
typedef struct channel_conf {
|
|
|
|
struct channel_conf *next;
|
2005-12-28 10:02:22 +00:00
|
|
|
const char *name;
|
|
|
|
store_conf_t *stores[2];
|
|
|
|
const char *boxes[2];
|
2004-03-27 16:07:20 +00:00
|
|
|
char *sync_state;
|
|
|
|
string_list_t *patterns;
|
2005-12-28 10:02:22 +00:00
|
|
|
int ops[2];
|
2004-03-27 16:07:20 +00:00
|
|
|
unsigned max_messages; /* for slave only */
|
|
|
|
} channel_conf_t;
|
|
|
|
|
|
|
|
typedef struct group_conf {
|
|
|
|
struct group_conf *next;
|
2005-12-28 10:02:22 +00:00
|
|
|
const char *name;
|
2004-03-27 16:07:20 +00:00
|
|
|
string_list_t *channels;
|
|
|
|
} group_conf_t;
|
|
|
|
|
|
|
|
/* For message->flags */
|
|
|
|
/* Keep the mailbox driver flag definitions in sync! */
|
|
|
|
/* The order is according to alphabetical maildir flag sort */
|
|
|
|
#define F_DRAFT (1<<0) /* Draft */
|
|
|
|
#define F_FLAGGED (1<<1) /* Flagged */
|
|
|
|
#define F_ANSWERED (1<<2) /* Replied */
|
|
|
|
#define F_SEEN (1<<3) /* Seen */
|
|
|
|
#define F_DELETED (1<<4) /* Trashed */
|
|
|
|
#define NUM_FLAGS 5
|
|
|
|
|
|
|
|
/* For message->status */
|
|
|
|
#define M_RECENT (1<<0) /* unsyncable flag; maildir_* depend on this being 1<<0 */
|
|
|
|
#define M_DEAD (1<<1) /* expunged */
|
|
|
|
#define M_FLAGS (1<<2) /* flags fetched */
|
|
|
|
|
2011-04-10 11:06:07 +00:00
|
|
|
#define TUIDL 12
|
|
|
|
|
2004-03-27 16:07:20 +00:00
|
|
|
typedef struct message {
|
|
|
|
struct message *next;
|
2006-01-30 10:26:04 +00:00
|
|
|
struct sync_rec *srec;
|
2004-03-27 16:07:20 +00:00
|
|
|
/* string_list_t *keywords; */
|
|
|
|
size_t size; /* zero implies "not fetched" */
|
|
|
|
int uid;
|
|
|
|
unsigned char flags, status;
|
2011-04-10 11:06:07 +00:00
|
|
|
char tuid[TUIDL];
|
2004-03-27 16:07:20 +00:00
|
|
|
} message_t;
|
|
|
|
|
|
|
|
/* For opts, both in store and driver_t->select() */
|
|
|
|
#define OPEN_OLD (1<<0)
|
|
|
|
#define OPEN_NEW (1<<1)
|
|
|
|
#define OPEN_FLAGS (1<<2)
|
|
|
|
#define OPEN_SIZE (1<<3)
|
|
|
|
#define OPEN_EXPUNGE (1<<5)
|
|
|
|
#define OPEN_SETFLAGS (1<<6)
|
|
|
|
#define OPEN_APPEND (1<<7)
|
2006-02-03 21:33:43 +00:00
|
|
|
#define OPEN_FIND (1<<8)
|
2004-03-27 16:07:20 +00:00
|
|
|
|
|
|
|
typedef struct store {
|
2006-03-20 19:38:20 +00:00
|
|
|
struct store *next;
|
2004-03-27 16:07:20 +00:00
|
|
|
store_conf_t *conf; /* foreign */
|
2006-03-20 19:27:38 +00:00
|
|
|
string_list_t *boxes; /* _list results - own */
|
|
|
|
unsigned listed:1; /* was _list already run? */
|
2004-03-27 16:07:20 +00:00
|
|
|
|
2012-07-15 10:55:04 +00:00
|
|
|
void (*bad_callback)( void *aux );
|
|
|
|
void *bad_callback_aux;
|
|
|
|
|
2004-03-27 16:07:20 +00:00
|
|
|
/* currently open mailbox */
|
2012-08-18 11:58:14 +00:00
|
|
|
const char *orig_name; /* foreign! maybe preset? */
|
|
|
|
char *name; /* foreign! maybe preset? */
|
2004-03-27 16:07:20 +00:00
|
|
|
char *path; /* own */
|
|
|
|
message_t *msgs; /* own */
|
|
|
|
int uidvalidity;
|
2011-04-10 11:06:07 +00:00
|
|
|
int uidnext; /* from SELECT responses */
|
2006-02-03 21:33:43 +00:00
|
|
|
unsigned opts; /* maybe preset? */
|
2004-03-27 16:07:20 +00:00
|
|
|
/* note that the following do _not_ reflect stats from msgs, but mailbox totals */
|
|
|
|
int count; /* # of messages */
|
|
|
|
int recent; /* # of recent messages - don't trust this beyond the initial read */
|
|
|
|
} store_t;
|
|
|
|
|
2011-04-03 16:21:46 +00:00
|
|
|
/* When the callback is invoked (at most once per store), the store is fubar;
|
|
|
|
* call the driver's cancel_store() to dispose of it. */
|
2012-07-15 10:55:04 +00:00
|
|
|
static INLINE void
|
|
|
|
set_bad_callback( store_t *ctx, void (*cb)( void *aux ), void *aux )
|
|
|
|
{
|
|
|
|
ctx->bad_callback = cb;
|
|
|
|
ctx->bad_callback_aux = aux;
|
|
|
|
}
|
|
|
|
|
2004-03-27 16:07:20 +00:00
|
|
|
typedef struct {
|
|
|
|
char *data;
|
|
|
|
int len;
|
|
|
|
unsigned char flags;
|
|
|
|
} msg_data_t;
|
|
|
|
|
|
|
|
#define DRV_OK 0
|
2011-04-03 16:21:46 +00:00
|
|
|
/* Message went missing, or mailbox is full, etc. */
|
2006-03-21 20:03:21 +00:00
|
|
|
#define DRV_MSG_BAD 1
|
2011-04-03 16:21:46 +00:00
|
|
|
/* Something is wrong with the current mailbox - probably it is somehow inaccessible. */
|
2006-03-21 20:03:21 +00:00
|
|
|
#define DRV_BOX_BAD 2
|
2011-04-03 16:21:46 +00:00
|
|
|
/* The command has been cancel()ed or cancel_store()d. */
|
2012-07-15 10:55:04 +00:00
|
|
|
#define DRV_CANCELED 3
|
2006-03-21 20:03:21 +00:00
|
|
|
|
2011-04-03 16:21:46 +00:00
|
|
|
/* All memory belongs to the driver's user, unless stated otherwise. */
|
2004-03-27 16:07:20 +00:00
|
|
|
|
2010-02-06 09:34:41 +00:00
|
|
|
/*
|
|
|
|
This flag says that the driver CAN store messages with CRLFs,
|
|
|
|
not that it must. The lack of it OTOH implies that it CANNOT,
|
|
|
|
and as CRLF is the canonical format, we convert.
|
|
|
|
*/
|
2006-02-03 21:33:43 +00:00
|
|
|
#define DRV_CRLF 1
|
|
|
|
|
2012-08-11 16:34:46 +00:00
|
|
|
#define LIST_PATH 1
|
|
|
|
#define LIST_INBOX 2
|
|
|
|
|
2004-03-27 16:07:20 +00:00
|
|
|
struct driver {
|
2006-02-03 21:33:43 +00:00
|
|
|
int flags;
|
2011-04-03 16:21:46 +00:00
|
|
|
|
|
|
|
/* Parse configuration. */
|
2004-03-27 16:07:20 +00:00
|
|
|
int (*parse_store)( conffile_t *cfg, store_conf_t **storep, int *err );
|
2011-04-03 16:21:46 +00:00
|
|
|
|
|
|
|
/* Close remaining server connections. All stores must be disowned first. */
|
2006-03-20 19:38:20 +00:00
|
|
|
void (*cleanup)( void );
|
2011-04-03 16:21:46 +00:00
|
|
|
|
|
|
|
/* Open a store with the given configuration. This may recycle existing
|
|
|
|
* server connections. Upon failure, a null store is passed to the callback. */
|
2006-03-21 20:03:21 +00:00
|
|
|
void (*open_store)( store_conf_t *conf,
|
|
|
|
void (*cb)( store_t *ctx, void *aux ), void *aux );
|
2011-04-03 16:21:46 +00:00
|
|
|
|
|
|
|
/* Mark the store as available for recycling. Server connection may be kept alive. */
|
2006-03-20 19:38:20 +00:00
|
|
|
void (*disown_store)( store_t *ctx );
|
2011-04-03 16:21:46 +00:00
|
|
|
|
|
|
|
/* Try to recycle a store with the given configuration. */
|
2006-03-20 19:38:20 +00:00
|
|
|
store_t *(*own_store)( store_conf_t *conf );
|
2011-04-03 16:21:46 +00:00
|
|
|
|
|
|
|
/* Discard the store after a bad_callback. The server connections will be closed.
|
|
|
|
* Pending commands will have their callbacks synchronously invoked with DRV_CANCELED. */
|
2006-03-20 19:38:20 +00:00
|
|
|
void (*cancel_store)( store_t *ctx );
|
2011-04-03 16:21:46 +00:00
|
|
|
|
2012-08-11 16:34:46 +00:00
|
|
|
/* List the mailboxes in this store. Flags are ORed LIST_* values. */
|
|
|
|
void (*list)( store_t *ctx, int flags,
|
2006-03-21 20:03:21 +00:00
|
|
|
void (*cb)( int sts, void *aux ), void *aux );
|
2011-04-03 16:21:46 +00:00
|
|
|
|
|
|
|
/* Invoked before select(), this informs the driver which operations (OP_*)
|
|
|
|
* will be performed on the mailbox. The driver may extend the set by implicitly
|
|
|
|
* needed or available operations. */
|
2006-01-29 11:22:45 +00:00
|
|
|
void (*prepare_opts)( store_t *ctx, int opts );
|
2011-04-03 16:21:46 +00:00
|
|
|
|
|
|
|
/* Open the mailbox ctx->name. Optionally create missing boxes.
|
|
|
|
* As a side effect, this should resolve ctx->path if applicable. */
|
2011-07-23 14:06:32 +00:00
|
|
|
void (*select)( store_t *ctx, int create,
|
|
|
|
void (*cb)( int sts, void *aux ), void *aux );
|
2011-04-03 16:21:46 +00:00
|
|
|
|
|
|
|
/* Load the message attributes needed to perform the requested operations.
|
|
|
|
* Consider only messages with UIDs between minuid and maxuid (inclusive)
|
|
|
|
* and those named in the excs array (smaller than minuid).
|
2011-04-10 11:06:07 +00:00
|
|
|
* The driver takes ownership of the excs array. Messages below newuid do not need
|
|
|
|
* to have the TUID populated even if OPEN_FIND is set. */
|
|
|
|
void (*load)( store_t *ctx, int minuid, int maxuid, int newuid, int *excs, int nexcs,
|
2011-07-23 14:06:32 +00:00
|
|
|
void (*cb)( int sts, void *aux ), void *aux );
|
2011-04-03 16:21:46 +00:00
|
|
|
|
|
|
|
/* Fetch the contents and flags of the given message from the current mailbox. */
|
2012-07-29 21:14:48 +00:00
|
|
|
void (*fetch_msg)( store_t *ctx, message_t *msg, msg_data_t *data,
|
|
|
|
void (*cb)( int sts, void *aux ), void *aux );
|
2011-04-03 16:21:46 +00:00
|
|
|
|
|
|
|
/* Store the given message to either the current mailbox or the trash folder.
|
|
|
|
* If the new copy's UID can be immediately determined, return it, otherwise -1. */
|
2012-07-29 21:14:48 +00:00
|
|
|
void (*store_msg)( store_t *ctx, msg_data_t *data, int to_trash,
|
|
|
|
void (*cb)( int sts, int uid, void *aux ), void *aux );
|
2011-04-03 16:21:46 +00:00
|
|
|
|
2011-04-10 11:06:07 +00:00
|
|
|
/* Index the messages which have newly appeared in the mailbox, including their
|
|
|
|
* temporary UID headers. This is needed if store_msg() does not guarantee returning
|
|
|
|
* a UID; otherwise the driver needs to implement only the OPEN_FIND flag. */
|
|
|
|
void (*find_new_msgs)( store_t *ctx,
|
|
|
|
void (*cb)( int sts, void *aux ), void *aux );
|
2011-04-03 16:21:46 +00:00
|
|
|
|
|
|
|
/* Add/remove the named flags to/from the given message. The message may be either
|
|
|
|
* a pre-fetched one (in which case the in-memory representation is updated),
|
|
|
|
* or it may be identifed by UID only. The operation may be delayed until commit()
|
|
|
|
* is called. */
|
2012-07-29 21:14:48 +00:00
|
|
|
void (*set_flags)( store_t *ctx, message_t *msg, int uid, int add, int del, /* msg can be null, therefore uid as a fallback */
|
|
|
|
void (*cb)( int sts, void *aux ), void *aux );
|
2011-04-03 16:21:46 +00:00
|
|
|
|
|
|
|
/* Move the given message from the current mailbox to the trash folder.
|
|
|
|
* This may expunge the original message immediately, but it needn't to. */
|
2012-07-29 21:14:48 +00:00
|
|
|
void (*trash_msg)( store_t *ctx, message_t *msg, /* This may expunge the original message immediately, but it needn't to */
|
|
|
|
void (*cb)( int sts, void *aux ), void *aux );
|
2011-04-03 16:21:46 +00:00
|
|
|
|
|
|
|
/* Expunge deleted messages from the current mailbox and close it.
|
|
|
|
* There is no need to explicitly close a mailbox if no expunge is needed. */
|
2012-07-29 21:14:48 +00:00
|
|
|
void (*close)( store_t *ctx, /* IMAP-style: expunge inclusive */
|
|
|
|
void (*cb)( int sts, void *aux ), void *aux );
|
2011-04-03 16:21:46 +00:00
|
|
|
|
|
|
|
/* Cancel queued commands which are not in flight yet; they will have their
|
|
|
|
* callbacks invoked with DRV_CANCELED. Afterwards, wait for the completion of
|
|
|
|
* the in-flight commands. If the store is canceled before this command completes,
|
|
|
|
* the callback will *not* be invoked. */
|
|
|
|
void (*cancel)( store_t *ctx,
|
2012-07-22 15:32:32 +00:00
|
|
|
void (*cb)( void *aux ), void *aux );
|
2011-04-03 16:21:46 +00:00
|
|
|
|
|
|
|
/* Commit any pending set_flags() commands. */
|
2006-03-21 20:03:21 +00:00
|
|
|
void (*commit)( store_t *ctx );
|
2000-12-20 21:41:21 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2004-03-27 16:07:20 +00:00
|
|
|
/* main.c */
|
2000-12-20 21:41:21 +00:00
|
|
|
|
2004-03-27 16:07:20 +00:00
|
|
|
extern int Pid;
|
|
|
|
extern char Hostname[256];
|
|
|
|
extern const char *Home;
|
2000-12-21 10:24:53 +00:00
|
|
|
|
|
|
|
|
2011-01-23 12:43:00 +00:00
|
|
|
/* socket.c */
|
|
|
|
|
2011-03-27 14:50:32 +00:00
|
|
|
/* call this before doing anything with the socket */
|
|
|
|
static INLINE void socket_init( conn_t *conn,
|
2012-08-25 16:26:23 +00:00
|
|
|
const server_conf_t *conf,
|
2011-03-27 14:50:32 +00:00
|
|
|
void (*bad_callback)( void *aux ),
|
2012-08-25 16:26:23 +00:00
|
|
|
void (*read_callback)( void *aux ),
|
|
|
|
int (*write_callback)( void *aux ),
|
2011-03-27 14:50:32 +00:00
|
|
|
void *aux )
|
|
|
|
{
|
2012-08-25 16:26:23 +00:00
|
|
|
conn->conf = conf;
|
2011-03-27 14:50:32 +00:00
|
|
|
conn->bad_callback = bad_callback;
|
2012-08-25 16:26:23 +00:00
|
|
|
conn->read_callback = read_callback;
|
|
|
|
conn->write_callback = write_callback;
|
2011-03-27 14:50:32 +00:00
|
|
|
conn->callback_aux = aux;
|
|
|
|
conn->fd = -1;
|
2011-04-10 13:32:25 +00:00
|
|
|
conn->name = 0;
|
2012-08-25 16:26:23 +00:00
|
|
|
conn->write_buf_append = &conn->write_buf;
|
2011-03-27 14:50:32 +00:00
|
|
|
}
|
2012-08-25 16:26:23 +00:00
|
|
|
void socket_connect( conn_t *conn, void (*cb)( int ok, void *aux ) );
|
|
|
|
void socket_start_tls(conn_t *conn, void (*cb)( int ok, void *aux ) );
|
2011-01-23 13:06:03 +00:00
|
|
|
void socket_close( conn_t *sock );
|
2011-04-03 16:47:37 +00:00
|
|
|
int socket_read( conn_t *sock, char *buf, int len ); /* never waits */
|
|
|
|
char *socket_read_line( conn_t *sock ); /* don't free return value; never waits */
|
2011-03-13 13:12:54 +00:00
|
|
|
typedef enum { KeepOwn = 0, GiveOwn } ownership_t;
|
|
|
|
int socket_write( conn_t *sock, char *buf, int len, ownership_t takeOwn );
|
2011-01-23 12:43:00 +00:00
|
|
|
|
|
|
|
void cram( const char *challenge, const char *user, const char *pass,
|
|
|
|
char **_final, int *_finallen );
|
|
|
|
|
|
|
|
|
2004-03-27 16:07:20 +00:00
|
|
|
/* util.c */
|
2000-12-21 10:24:53 +00:00
|
|
|
|
2006-01-29 14:46:16 +00:00
|
|
|
#define DEBUG 1
|
|
|
|
#define VERBOSE 2
|
2010-02-06 09:40:36 +00:00
|
|
|
#define XVERBOSE 4
|
|
|
|
#define QUIET 8
|
|
|
|
#define VERYQUIET 16
|
|
|
|
#define KEEPJOURNAL 32
|
2012-08-25 13:29:16 +00:00
|
|
|
#define ZERODELAY 64
|
2006-01-29 14:46:16 +00:00
|
|
|
|
2011-06-02 08:14:54 +00:00
|
|
|
extern int DFlags;
|
2004-01-31 01:01:07 +00:00
|
|
|
|
2011-04-11 08:46:25 +00:00
|
|
|
void ATTR_PRINTFLIKE(1, 2) debug( const char *, ... );
|
|
|
|
void ATTR_PRINTFLIKE(1, 2) debugn( const char *, ... );
|
|
|
|
void ATTR_PRINTFLIKE(1, 2) info( const char *, ... );
|
|
|
|
void ATTR_PRINTFLIKE(1, 2) infon( const char *, ... );
|
|
|
|
void ATTR_PRINTFLIKE(1, 2) warn( const char *, ... );
|
|
|
|
void ATTR_PRINTFLIKE(1, 2) error( const char *, ... );
|
|
|
|
void ATTR_PRINTFLIKE(1, 2) sys_error( const char *, ... );
|
2011-04-11 08:45:46 +00:00
|
|
|
void flushn( void );
|
2000-12-20 21:41:21 +00:00
|
|
|
|
2004-03-27 16:07:20 +00:00
|
|
|
char *next_arg( char ** );
|
2001-11-20 18:06:09 +00:00
|
|
|
|
2004-03-27 16:07:20 +00:00
|
|
|
void add_string_list( string_list_t **list, const char *str );
|
|
|
|
void free_string_list( string_list_t *list );
|
2004-01-12 01:24:47 +00:00
|
|
|
|
2004-03-27 16:07:20 +00:00
|
|
|
void free_generic_messages( message_t * );
|
2004-01-12 01:24:47 +00:00
|
|
|
|
2012-08-11 16:34:46 +00:00
|
|
|
#ifndef HAVE_MEMRCHR
|
|
|
|
void *memrchr( const void *s, int c, size_t n );
|
|
|
|
#endif
|
|
|
|
|
2004-03-27 16:07:20 +00:00
|
|
|
void *nfmalloc( size_t sz );
|
|
|
|
void *nfcalloc( size_t sz );
|
|
|
|
void *nfrealloc( void *mem, size_t sz );
|
|
|
|
char *nfstrdup( const char *str );
|
|
|
|
int nfvasprintf( char **str, const char *fmt, va_list va );
|
2011-04-11 08:46:25 +00:00
|
|
|
int ATTR_PRINTFLIKE(2, 3) nfasprintf( char **str, const char *fmt, ... );
|
|
|
|
int ATTR_PRINTFLIKE(3, 4) nfsnprintf( char *buf, int blen, const char *fmt, ... );
|
2004-03-27 16:07:20 +00:00
|
|
|
void ATTR_NORETURN oob( void );
|
2000-12-20 21:41:21 +00:00
|
|
|
|
2004-03-27 16:07:20 +00:00
|
|
|
char *expand_strdup( const char *s );
|
2000-12-23 00:02:42 +00:00
|
|
|
|
2012-08-11 16:34:46 +00:00
|
|
|
int map_name( char *arg, char in, char out );
|
|
|
|
|
2004-03-27 16:07:20 +00:00
|
|
|
void sort_ints( int *arr, int len );
|
|
|
|
|
|
|
|
void arc4_init( void );
|
|
|
|
unsigned char arc4_getbyte( void );
|
|
|
|
|
2012-08-26 11:36:12 +00:00
|
|
|
int bucketsForSize( int size );
|
|
|
|
|
2011-03-13 13:29:12 +00:00
|
|
|
#ifdef HAVE_SYS_POLL_H
|
|
|
|
# include <sys/poll.h>
|
|
|
|
#else
|
|
|
|
# define POLLIN 1
|
|
|
|
# define POLLOUT 4
|
|
|
|
# define POLLERR 8
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void add_fd( int fd, void (*cb)( int events, void *aux ), void *aux );
|
|
|
|
void conf_fd( int fd, int and_events, int or_events );
|
|
|
|
void fake_fd( int fd, int events );
|
|
|
|
void del_fd( int fd );
|
|
|
|
void main_loop( void );
|
|
|
|
|
2004-03-27 16:07:20 +00:00
|
|
|
/* sync.c */
|
|
|
|
|
2006-03-21 10:30:45 +00:00
|
|
|
extern const char *str_ms[2], *str_hl[2];
|
|
|
|
|
2006-03-21 20:03:21 +00:00
|
|
|
#define SYNC_OK 0 /* assumed to be 0 */
|
|
|
|
#define SYNC_FAIL 1
|
2012-08-18 10:48:08 +00:00
|
|
|
#define SYNC_FAIL_ALL 2
|
|
|
|
#define SYNC_BAD(ms) (4<<(ms))
|
|
|
|
#define SYNC_NOGOOD 16 /* internal */
|
|
|
|
#define SYNC_CANCELED 32 /* internal */
|
2004-03-27 16:07:20 +00:00
|
|
|
|
2006-03-21 20:03:21 +00:00
|
|
|
/* All passed pointers must stay alive until cb is called. */
|
|
|
|
void sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan,
|
|
|
|
void (*cb)( int sts, void *aux ), void *aux );
|
2004-03-27 16:07:20 +00:00
|
|
|
|
|
|
|
/* config.c */
|
|
|
|
|
2006-03-20 18:36:49 +00:00
|
|
|
#define N_DRIVERS 2
|
|
|
|
extern driver_t *drivers[N_DRIVERS];
|
|
|
|
|
2004-03-27 16:07:20 +00:00
|
|
|
extern channel_conf_t *channels;
|
|
|
|
extern group_conf_t *groups;
|
2005-12-28 10:02:22 +00:00
|
|
|
extern int global_ops[2];
|
2004-03-27 16:07:20 +00:00
|
|
|
extern char *global_sync_state;
|
|
|
|
|
|
|
|
int parse_bool( conffile_t *cfile );
|
|
|
|
int parse_int( conffile_t *cfile );
|
|
|
|
int parse_size( conffile_t *cfile );
|
|
|
|
int getcline( conffile_t *cfile );
|
2005-12-28 10:02:22 +00:00
|
|
|
int merge_ops( int cops, int ops[] );
|
2004-03-27 16:07:20 +00:00
|
|
|
int load_config( const char *filename, int pseudo );
|
|
|
|
void parse_generic_store( store_conf_t *store, conffile_t *cfg, int *err );
|
2000-12-21 06:27:05 +00:00
|
|
|
|
2004-03-27 16:07:20 +00:00
|
|
|
/* drv_*.c */
|
|
|
|
extern driver_t maildir_driver, imap_driver;
|