abstract growable arrays somewhat
... and sneak in a C99 requirement on the way. just because.
This commit is contained in:
		
							parent
							
								
									0f24ca31b5
								
							
						
					
					
						commit
						7b567164ff
					
				
					 7 changed files with 93 additions and 76 deletions
				
			
		| 
						 | 
					@ -4,9 +4,9 @@ AM_INIT_AUTOMAKE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
AM_MAINTAINER_MODE
 | 
					AM_MAINTAINER_MODE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
AC_PROG_CC
 | 
					AC_PROG_CC_C99
 | 
				
			||||||
if test "$GCC" = yes; then
 | 
					if test "$GCC" = yes; then
 | 
				
			||||||
    CFLAGS="$CFLAGS -pipe -W -Wall -Wshadow -Wstrict-prototypes -ansi -pedantic -Wno-overlength-strings"
 | 
					    CFLAGS="$CFLAGS -pipe -W -Wall -Wshadow -Wstrict-prototypes -std=c99 -pedantic -Wno-overlength-strings"
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE"
 | 
					CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										31
									
								
								src/common.h
									
										
									
									
									
								
							
							
						
						
									
										31
									
								
								src/common.h
									
										
									
									
									
								
							| 
						 | 
					@ -43,10 +43,12 @@ typedef unsigned int uint;
 | 
				
			||||||
# define ATTR_UNUSED __attribute__((unused))
 | 
					# define ATTR_UNUSED __attribute__((unused))
 | 
				
			||||||
# define ATTR_NORETURN __attribute__((noreturn))
 | 
					# define ATTR_NORETURN __attribute__((noreturn))
 | 
				
			||||||
# define ATTR_PRINTFLIKE(fmt,var) __attribute__((format(printf,fmt,var)))
 | 
					# define ATTR_PRINTFLIKE(fmt,var) __attribute__((format(printf,fmt,var)))
 | 
				
			||||||
 | 
					# define ATTR_PACKED(ref) __attribute__((packed,aligned(sizeof(ref))))
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
# define ATTR_UNUSED
 | 
					# define ATTR_UNUSED
 | 
				
			||||||
# define ATTR_NORETURN
 | 
					# define ATTR_NORETURN
 | 
				
			||||||
# define ATTR_PRINTFLIKE(fmt,var)
 | 
					# define ATTR_PRINTFLIKE(fmt,var)
 | 
				
			||||||
 | 
					# define ATTR_PACKED(ref)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __GNUC__
 | 
					#ifdef __GNUC__
 | 
				
			||||||
| 
						 | 
					@ -137,7 +139,34 @@ char *expand_strdup( const char *s );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int map_name( const char *arg, char **result, int reserve, const char *in, const char *out );
 | 
					int map_name( const char *arg, char **result, int reserve, const char *in, const char *out );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void sort_ints( int *arr, int len );
 | 
					#define DEFINE_ARRAY_TYPE(T) \
 | 
				
			||||||
 | 
						typedef struct T##_array { \
 | 
				
			||||||
 | 
							T *data; \
 | 
				
			||||||
 | 
							int size; \
 | 
				
			||||||
 | 
						} ATTR_PACKED(T *) T##_array_t; \
 | 
				
			||||||
 | 
						typedef struct T##_array_alloc { \
 | 
				
			||||||
 | 
							T##_array_t array; \
 | 
				
			||||||
 | 
							int alloc; \
 | 
				
			||||||
 | 
						} ATTR_PACKED(T *) T##_array_alloc_t; \
 | 
				
			||||||
 | 
						static INLINE T *T##_array_append( T##_array_alloc_t *arr ) \
 | 
				
			||||||
 | 
						{ \
 | 
				
			||||||
 | 
							if (arr->array.size == arr->alloc) { \
 | 
				
			||||||
 | 
								arr->alloc = arr->alloc * 2 + 100; \
 | 
				
			||||||
 | 
								arr->array.data = nfrealloc( arr->array.data, arr->alloc * sizeof(T) ); \
 | 
				
			||||||
 | 
							} \
 | 
				
			||||||
 | 
							return &arr->array.data[arr->array.size++]; \
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ARRAY_INIT(arr) \
 | 
				
			||||||
 | 
						do { (arr)->array.data = 0; (arr)->array.size = (arr)->alloc = 0; } while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ARRAY_SQUEEZE(arr) \
 | 
				
			||||||
 | 
						do { \
 | 
				
			||||||
 | 
							(arr)->data = nfrealloc( (arr)->data, (arr)->size * sizeof((arr)->data[0]) ); \
 | 
				
			||||||
 | 
						} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DEFINE_ARRAY_TYPE(int)
 | 
				
			||||||
 | 
					void sort_int_array( int_array_t array );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void arc4_init( void );
 | 
					void arc4_init( void );
 | 
				
			||||||
uchar arc4_getbyte( void );
 | 
					uchar arc4_getbyte( void );
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -207,7 +207,7 @@ struct driver {
 | 
				
			||||||
	 * and those named in the excs array (smaller than minuid).
 | 
						 * and those named in the excs array (smaller than minuid).
 | 
				
			||||||
	 * The driver takes ownership of the excs array. Messages below newuid do not need
 | 
						 * 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. */
 | 
						 * to have the TUID populated even if OPEN_FIND is set. */
 | 
				
			||||||
	void (*load_box)( store_t *ctx, int minuid, int maxuid, int newuid, int *excs, int nexcs,
 | 
						void (*load_box)( store_t *ctx, int minuid, int maxuid, int newuid, int_array_t excs,
 | 
				
			||||||
	                  void (*cb)( int sts, void *aux ), void *aux );
 | 
						                  void (*cb)( int sts, void *aux ), void *aux );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Fetch the contents and flags of the given message from the current mailbox. */
 | 
						/* Fetch the contents and flags of the given message from the current mailbox. */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2292,7 +2292,7 @@ imap_prepare_load_box( store_t *gctx, int opts )
 | 
				
			||||||
static void imap_submit_load( imap_store_t *, const char *, int, struct imap_cmd_refcounted_state * );
 | 
					static void imap_submit_load( imap_store_t *, const char *, int, struct imap_cmd_refcounted_state * );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
imap_load_box( store_t *gctx, int minuid, int maxuid, int newuid, int *excs, int nexcs,
 | 
					imap_load_box( store_t *gctx, int minuid, int maxuid, int newuid, int_array_t excs,
 | 
				
			||||||
               void (*cb)( int sts, void *aux ), void *aux )
 | 
					               void (*cb)( int sts, void *aux ), void *aux )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	imap_store_t *ctx = (imap_store_t *)gctx;
 | 
						imap_store_t *ctx = (imap_store_t *)gctx;
 | 
				
			||||||
| 
						 | 
					@ -2300,21 +2300,21 @@ imap_load_box( store_t *gctx, int minuid, int maxuid, int newuid, int *excs, int
 | 
				
			||||||
	char buf[1000];
 | 
						char buf[1000];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!ctx->gen.count) {
 | 
						if (!ctx->gen.count) {
 | 
				
			||||||
		free( excs );
 | 
							free( excs.data );
 | 
				
			||||||
		cb( DRV_OK, aux );
 | 
							cb( DRV_OK, aux );
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		struct imap_cmd_refcounted_state *sts = imap_refcounted_new_state( cb, aux );
 | 
							struct imap_cmd_refcounted_state *sts = imap_refcounted_new_state( cb, aux );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		sort_ints( excs, nexcs );
 | 
							sort_int_array( excs );
 | 
				
			||||||
		for (i = 0; i < nexcs; ) {
 | 
							for (i = 0; i < excs.size; ) {
 | 
				
			||||||
			for (bl = 0; i < nexcs && bl < 960; i++) {
 | 
								for (bl = 0; i < excs.size && bl < 960; i++) {
 | 
				
			||||||
				if (bl)
 | 
									if (bl)
 | 
				
			||||||
					buf[bl++] = ',';
 | 
										buf[bl++] = ',';
 | 
				
			||||||
				bl += sprintf( buf + bl, "%d", excs[i] );
 | 
									bl += sprintf( buf + bl, "%d", excs.data[i] );
 | 
				
			||||||
				j = i;
 | 
									j = i;
 | 
				
			||||||
				for (; i + 1 < nexcs && excs[i + 1] == excs[i] + 1; i++) {}
 | 
									for (; i + 1 < excs.size && excs.data[i + 1] == excs.data[i] + 1; i++) {}
 | 
				
			||||||
				if (i != j)
 | 
									if (i != j)
 | 
				
			||||||
					bl += sprintf( buf + bl, ":%d", excs[i] );
 | 
										bl += sprintf( buf + bl, ":%d", excs.data[i] );
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			imap_submit_load( ctx, buf, 0, sts );
 | 
								imap_submit_load( ctx, buf, 0, sts );
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -2333,7 +2333,7 @@ imap_load_box( store_t *gctx, int minuid, int maxuid, int newuid, int *excs, int
 | 
				
			||||||
			imap_submit_load( ctx, buf, (ctx->gen.opts & OPEN_FIND), sts );
 | 
								imap_submit_load( ctx, buf, (ctx->gen.opts & OPEN_FIND), sts );
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	  done:
 | 
						  done:
 | 
				
			||||||
		free( excs );
 | 
							free( excs.data );
 | 
				
			||||||
		imap_refcounted_done( sts );
 | 
							imap_refcounted_done( sts );
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -70,7 +70,8 @@ typedef struct maildir_message {
 | 
				
			||||||
typedef struct maildir_store {
 | 
					typedef struct maildir_store {
 | 
				
			||||||
	store_t gen;
 | 
						store_t gen;
 | 
				
			||||||
	int uvfd, uvok, nuid, is_inbox, fresh[3];
 | 
						int uvfd, uvok, nuid, is_inbox, fresh[3];
 | 
				
			||||||
	int minuid, maxuid, newuid, nexcs, *excs;
 | 
						int minuid, maxuid, newuid;
 | 
				
			||||||
 | 
						int_array_t excs;
 | 
				
			||||||
	char *trash;
 | 
						char *trash;
 | 
				
			||||||
#ifdef USE_DB
 | 
					#ifdef USE_DB
 | 
				
			||||||
	DB *db;
 | 
						DB *db;
 | 
				
			||||||
| 
						 | 
					@ -262,7 +263,7 @@ maildir_cleanup( store_t *gctx )
 | 
				
			||||||
	free( ctx->usedb );
 | 
						free( ctx->usedb );
 | 
				
			||||||
#endif /* USE_DB */
 | 
					#endif /* USE_DB */
 | 
				
			||||||
	free( gctx->path );
 | 
						free( gctx->path );
 | 
				
			||||||
	free( ctx->excs );
 | 
						free( ctx->excs.data );
 | 
				
			||||||
	if (ctx->uvfd >= 0)
 | 
						if (ctx->uvfd >= 0)
 | 
				
			||||||
		close( ctx->uvfd );
 | 
							close( ctx->uvfd );
 | 
				
			||||||
	conf_wakeup( &ctx->lcktmr, -1 );
 | 
						conf_wakeup( &ctx->lcktmr, -1 );
 | 
				
			||||||
| 
						 | 
					@ -446,20 +447,17 @@ typedef struct {
 | 
				
			||||||
	char tuid[TUIDL];
 | 
						char tuid[TUIDL];
 | 
				
			||||||
} msg_t;
 | 
					} msg_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					DEFINE_ARRAY_TYPE(msg_t)
 | 
				
			||||||
	msg_t *ents;
 | 
					 | 
				
			||||||
	int nents, nalloc;
 | 
					 | 
				
			||||||
} msglist_t;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
maildir_free_scan( msglist_t *msglist )
 | 
					maildir_free_scan( msg_t_array_alloc_t *msglist )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (msglist->ents) {
 | 
						if (msglist->array.data) {
 | 
				
			||||||
		for (i = 0; i < msglist->nents; i++)
 | 
							for (i = 0; i < msglist->array.size; i++)
 | 
				
			||||||
			free( msglist->ents[i].base );
 | 
								free( msglist->array.data[i].base );
 | 
				
			||||||
		free( msglist->ents );
 | 
							free( msglist->array.data );
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -821,7 +819,7 @@ maildir_compare( const void *l, const void *r )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
maildir_scan( maildir_store_t *ctx, msglist_t *msglist )
 | 
					maildir_scan( maildir_store_t *ctx, msg_t_array_alloc_t *msglist )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	maildir_store_conf_t *conf = (maildir_store_conf_t *)ctx->gen.conf;
 | 
						maildir_store_conf_t *conf = (maildir_store_conf_t *)ctx->gen.conf;
 | 
				
			||||||
	DIR *d;
 | 
						DIR *d;
 | 
				
			||||||
| 
						 | 
					@ -839,8 +837,7 @@ maildir_scan( maildir_store_t *ctx, msglist_t *msglist )
 | 
				
			||||||
	char buf[_POSIX_PATH_MAX], nbuf[_POSIX_PATH_MAX];
 | 
						char buf[_POSIX_PATH_MAX], nbuf[_POSIX_PATH_MAX];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  again:
 | 
					  again:
 | 
				
			||||||
	msglist->ents = 0;
 | 
						ARRAY_INIT( msglist );
 | 
				
			||||||
	msglist->nents = msglist->nalloc = 0;
 | 
					 | 
				
			||||||
	ctx->gen.count = ctx->gen.recent = 0;
 | 
						ctx->gen.count = ctx->gen.recent = 0;
 | 
				
			||||||
	if (ctx->uvok || ctx->maxuid == INT_MAX) {
 | 
						if (ctx->uvok || ctx->maxuid == INT_MAX) {
 | 
				
			||||||
#ifdef USE_DB
 | 
					#ifdef USE_DB
 | 
				
			||||||
| 
						 | 
					@ -926,17 +923,13 @@ maildir_scan( maildir_store_t *ctx, msglist_t *msglist )
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				if (uid <= ctx->maxuid) {
 | 
									if (uid <= ctx->maxuid) {
 | 
				
			||||||
					if (uid < ctx->minuid) {
 | 
										if (uid < ctx->minuid) {
 | 
				
			||||||
						for (j = 0; j < ctx->nexcs; j++)
 | 
											for (j = 0; j < ctx->excs.size; j++)
 | 
				
			||||||
							if (ctx->excs[j] == uid)
 | 
												if (ctx->excs.data[j] == uid)
 | 
				
			||||||
								goto oke;
 | 
													goto oke;
 | 
				
			||||||
						continue;
 | 
											continue;
 | 
				
			||||||
					  oke: ;
 | 
										  oke: ;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					if (msglist->nalloc == msglist->nents) {
 | 
										entry = msg_t_array_append( msglist );
 | 
				
			||||||
						msglist->nalloc = msglist->nalloc * 2 + 100;
 | 
					 | 
				
			||||||
						msglist->ents = nfrealloc( msglist->ents, msglist->nalloc * sizeof(msg_t) );
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					entry = &msglist->ents[msglist->nents++];
 | 
					 | 
				
			||||||
					entry->base = nfstrdup( e->d_name );
 | 
										entry->base = nfstrdup( e->d_name );
 | 
				
			||||||
					entry->uid = uid;
 | 
										entry->uid = uid;
 | 
				
			||||||
					entry->recent = i;
 | 
										entry->recent = i;
 | 
				
			||||||
| 
						 | 
					@ -992,9 +985,9 @@ maildir_scan( maildir_store_t *ctx, msglist_t *msglist )
 | 
				
			||||||
			tdb->close( tdb, 0 );
 | 
								tdb->close( tdb, 0 );
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
#endif /* USE_DB */
 | 
					#endif /* USE_DB */
 | 
				
			||||||
		qsort( msglist->ents, msglist->nents, sizeof(msg_t), maildir_compare );
 | 
							qsort( msglist->array.data, msglist->array.size, sizeof(msg_t), maildir_compare );
 | 
				
			||||||
		for (uid = i = 0; i < msglist->nents; i++) {
 | 
							for (uid = i = 0; i < msglist->array.size; i++) {
 | 
				
			||||||
			entry = &msglist->ents[i];
 | 
								entry = &msglist->array.data[i];
 | 
				
			||||||
			if (entry->uid != INT_MAX) {
 | 
								if (entry->uid != INT_MAX) {
 | 
				
			||||||
				if (uid == entry->uid) {
 | 
									if (uid == entry->uid) {
 | 
				
			||||||
#if 1
 | 
					#if 1
 | 
				
			||||||
| 
						 | 
					@ -1134,7 +1127,7 @@ maildir_select_box( store_t *gctx, const char *name )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	maildir_cleanup( gctx );
 | 
						maildir_cleanup( gctx );
 | 
				
			||||||
	gctx->msgs = 0;
 | 
						gctx->msgs = 0;
 | 
				
			||||||
	ctx->excs = 0;
 | 
						ctx->excs.data = 0;
 | 
				
			||||||
	ctx->uvfd = -1;
 | 
						ctx->uvfd = -1;
 | 
				
			||||||
#ifdef USE_DB
 | 
					#ifdef USE_DB
 | 
				
			||||||
	ctx->db = 0;
 | 
						ctx->db = 0;
 | 
				
			||||||
| 
						 | 
					@ -1215,9 +1208,9 @@ static int
 | 
				
			||||||
maildir_confirm_box_empty( store_t *gctx )
 | 
					maildir_confirm_box_empty( store_t *gctx )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	maildir_store_t *ctx = (maildir_store_t *)gctx;
 | 
						maildir_store_t *ctx = (maildir_store_t *)gctx;
 | 
				
			||||||
	msglist_t msglist;
 | 
						msg_t_array_alloc_t msglist;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx->nexcs = ctx->minuid = ctx->maxuid = ctx->newuid = 0;
 | 
						ctx->excs.size = ctx->minuid = ctx->maxuid = ctx->newuid = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (maildir_scan( ctx, &msglist ) != DRV_OK)
 | 
						if (maildir_scan( ctx, &msglist ) != DRV_OK)
 | 
				
			||||||
		return DRV_BOX_BAD;
 | 
							return DRV_BOX_BAD;
 | 
				
			||||||
| 
						 | 
					@ -1289,27 +1282,27 @@ maildir_prepare_load_box( store_t *gctx, int opts )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
maildir_load_box( store_t *gctx, int minuid, int maxuid, int newuid, int *excs, int nexcs,
 | 
					maildir_load_box( store_t *gctx, int minuid, int maxuid, int newuid, int_array_t excs,
 | 
				
			||||||
                  void (*cb)( int sts, void *aux ), void *aux )
 | 
					                  void (*cb)( int sts, void *aux ), void *aux )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	maildir_store_t *ctx = (maildir_store_t *)gctx;
 | 
						maildir_store_t *ctx = (maildir_store_t *)gctx;
 | 
				
			||||||
	message_t **msgapp;
 | 
						message_t **msgapp;
 | 
				
			||||||
	msglist_t msglist;
 | 
						msg_t_array_alloc_t msglist;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx->minuid = minuid;
 | 
						ctx->minuid = minuid;
 | 
				
			||||||
	ctx->maxuid = maxuid;
 | 
						ctx->maxuid = maxuid;
 | 
				
			||||||
	ctx->newuid = newuid;
 | 
						ctx->newuid = newuid;
 | 
				
			||||||
	ctx->excs = nfrealloc( excs, nexcs * sizeof(int) );
 | 
						ARRAY_SQUEEZE( &excs );
 | 
				
			||||||
	ctx->nexcs = nexcs;
 | 
						ctx->excs = excs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (maildir_scan( ctx, &msglist ) != DRV_OK) {
 | 
						if (maildir_scan( ctx, &msglist ) != DRV_OK) {
 | 
				
			||||||
		cb( DRV_BOX_BAD, aux );
 | 
							cb( DRV_BOX_BAD, aux );
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	msgapp = &ctx->gen.msgs;
 | 
						msgapp = &ctx->gen.msgs;
 | 
				
			||||||
	for (i = 0; i < msglist.nents; i++)
 | 
						for (i = 0; i < msglist.array.size; i++)
 | 
				
			||||||
		maildir_app_msg( ctx, &msgapp, msglist.ents + i );
 | 
							maildir_app_msg( ctx, &msgapp, msglist.array.data + i );
 | 
				
			||||||
	maildir_free_scan( &msglist );
 | 
						maildir_free_scan( &msglist );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cb( DRV_OK, aux );
 | 
						cb( DRV_OK, aux );
 | 
				
			||||||
| 
						 | 
					@ -1320,37 +1313,37 @@ maildir_rescan( maildir_store_t *ctx )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	message_t **msgapp;
 | 
						message_t **msgapp;
 | 
				
			||||||
	maildir_message_t *msg;
 | 
						maildir_message_t *msg;
 | 
				
			||||||
	msglist_t msglist;
 | 
						msg_t_array_alloc_t msglist;
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx->fresh[0] = ctx->fresh[1] = 0;
 | 
						ctx->fresh[0] = ctx->fresh[1] = 0;
 | 
				
			||||||
	if (maildir_scan( ctx, &msglist ) != DRV_OK)
 | 
						if (maildir_scan( ctx, &msglist ) != DRV_OK)
 | 
				
			||||||
		return DRV_BOX_BAD;
 | 
							return DRV_BOX_BAD;
 | 
				
			||||||
	for (msgapp = &ctx->gen.msgs, i = 0;
 | 
						for (msgapp = &ctx->gen.msgs, i = 0;
 | 
				
			||||||
	     (msg = (maildir_message_t *)*msgapp) || i < msglist.nents; )
 | 
						     (msg = (maildir_message_t *)*msgapp) || i < msglist.array.size; )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (!msg) {
 | 
							if (!msg) {
 | 
				
			||||||
#if 0
 | 
					#if 0
 | 
				
			||||||
			debug( "adding new message %d\n", msglist.ents[i].uid );
 | 
								debug( "adding new message %d\n", msglist.array.data[i].uid );
 | 
				
			||||||
			maildir_app_msg( ctx, &msgapp, msglist.ents + i );
 | 
								maildir_app_msg( ctx, &msgapp, msglist.array.data + i );
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
			debug( "ignoring new message %d\n", msglist.ents[i].uid );
 | 
								debug( "ignoring new message %d\n", msglist.array.data[i].uid );
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
			i++;
 | 
								i++;
 | 
				
			||||||
		} else if (i >= msglist.nents) {
 | 
							} else if (i >= msglist.array.size) {
 | 
				
			||||||
			debug( "purging deleted message %d\n", msg->gen.uid );
 | 
								debug( "purging deleted message %d\n", msg->gen.uid );
 | 
				
			||||||
			msg->gen.status = M_DEAD;
 | 
								msg->gen.status = M_DEAD;
 | 
				
			||||||
			msgapp = &msg->gen.next;
 | 
								msgapp = &msg->gen.next;
 | 
				
			||||||
		} else if (msglist.ents[i].uid < msg->gen.uid) {
 | 
							} else if (msglist.array.data[i].uid < msg->gen.uid) {
 | 
				
			||||||
			/* this should not happen, actually */
 | 
								/* this should not happen, actually */
 | 
				
			||||||
#if 0
 | 
					#if 0
 | 
				
			||||||
			debug( "adding new message %d\n", msglist.ents[i].uid );
 | 
								debug( "adding new message %d\n", msglist.array.data[i].uid );
 | 
				
			||||||
			maildir_app_msg( ctx, &msgapp, msglist.ents + i );
 | 
								maildir_app_msg( ctx, &msgapp, msglist.array.data + i );
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
			debug( "ignoring new message %d\n", msglist.ents[i].uid );
 | 
								debug( "ignoring new message %d\n", msglist.array.data[i].uid );
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
			i++;
 | 
								i++;
 | 
				
			||||||
		} else if (msglist.ents[i].uid > msg->gen.uid) {
 | 
							} else if (msglist.array.data[i].uid > msg->gen.uid) {
 | 
				
			||||||
			debug( "purging deleted message %d\n", msg->gen.uid );
 | 
								debug( "purging deleted message %d\n", msg->gen.uid );
 | 
				
			||||||
			msg->gen.status = M_DEAD;
 | 
								msg->gen.status = M_DEAD;
 | 
				
			||||||
			msgapp = &msg->gen.next;
 | 
								msgapp = &msg->gen.next;
 | 
				
			||||||
| 
						 | 
					@ -1358,7 +1351,7 @@ maildir_rescan( maildir_store_t *ctx )
 | 
				
			||||||
			debug( "updating message %d\n", msg->gen.uid );
 | 
								debug( "updating message %d\n", msg->gen.uid );
 | 
				
			||||||
			msg->gen.status &= ~(M_FLAGS|M_RECENT);
 | 
								msg->gen.status &= ~(M_FLAGS|M_RECENT);
 | 
				
			||||||
			free( msg->base );
 | 
								free( msg->base );
 | 
				
			||||||
			maildir_init_msg( ctx, msg, msglist.ents + i );
 | 
								maildir_init_msg( ctx, msg, msglist.array.data + i );
 | 
				
			||||||
			i++, msgapp = &msg->gen.next;
 | 
								i++, msgapp = &msg->gen.next;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										27
									
								
								src/sync.c
									
										
									
									
									
								
							
							
						
						
									
										27
									
								
								src/sync.c
									
										
									
									
									
								
							| 
						 | 
					@ -938,7 +938,7 @@ static void box_deleted( int sts, void *aux );
 | 
				
			||||||
static void box_created( int sts, void *aux );
 | 
					static void box_created( int sts, void *aux );
 | 
				
			||||||
static void box_opened( int sts, void *aux );
 | 
					static void box_opened( int sts, void *aux );
 | 
				
			||||||
static void box_opened2( sync_vars_t *svars, int t );
 | 
					static void box_opened2( sync_vars_t *svars, int t );
 | 
				
			||||||
static void load_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, int nmexcs );
 | 
					static void load_box( sync_vars_t *svars, int t, int minwuid, int_array_t mexcs );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
sync_boxes( store_t *ctx[], const char *names[], int present[], channel_conf_t *chan,
 | 
					sync_boxes( store_t *ctx[], const char *names[], int present[], channel_conf_t *chan,
 | 
				
			||||||
| 
						 | 
					@ -1138,8 +1138,8 @@ box_opened2( sync_vars_t *svars, int t )
 | 
				
			||||||
	store_t *ctx[2];
 | 
						store_t *ctx[2];
 | 
				
			||||||
	channel_conf_t *chan;
 | 
						channel_conf_t *chan;
 | 
				
			||||||
	sync_rec_t *srec;
 | 
						sync_rec_t *srec;
 | 
				
			||||||
	int opts[2], fails;
 | 
						int_array_alloc_t mexcs;
 | 
				
			||||||
	int *mexcs, nmexcs, rmexcs, minwuid;
 | 
						int opts[2], fails, minwuid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	svars->state[t] |= ST_SELECTED;
 | 
						svars->state[t] |= ST_SELECTED;
 | 
				
			||||||
	if (!(svars->state[1-t] & ST_SELECTED))
 | 
						if (!(svars->state[1-t] & ST_SELECTED))
 | 
				
			||||||
| 
						 | 
					@ -1224,8 +1224,7 @@ box_opened2( sync_vars_t *svars, int t )
 | 
				
			||||||
	svars->drv[M]->prepare_load_box( ctx[M], opts[M] );
 | 
						svars->drv[M]->prepare_load_box( ctx[M], opts[M] );
 | 
				
			||||||
	svars->drv[S]->prepare_load_box( ctx[S], opts[S] );
 | 
						svars->drv[S]->prepare_load_box( ctx[S], opts[S] );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mexcs = 0;
 | 
						ARRAY_INIT( &mexcs );
 | 
				
			||||||
	nmexcs = rmexcs = 0;
 | 
					 | 
				
			||||||
	if (svars->ctx[M]->opts & OPEN_OLD) {
 | 
						if (svars->ctx[M]->opts & OPEN_OLD) {
 | 
				
			||||||
		if (chan->max_messages) {
 | 
							if (chan->max_messages) {
 | 
				
			||||||
			/* When messages have been expired on the slave, the master fetch is split into
 | 
								/* When messages have been expired on the slave, the master fetch is split into
 | 
				
			||||||
| 
						 | 
					@ -1263,16 +1262,12 @@ box_opened2( sync_vars_t *svars, int t )
 | 
				
			||||||
				if (srec->uid[M] > 0 && srec->uid[S] > 0 && minwuid > srec->uid[M] &&
 | 
									if (srec->uid[M] > 0 && srec->uid[S] > 0 && minwuid > srec->uid[M] &&
 | 
				
			||||||
				    (!(svars->ctx[M]->opts & OPEN_NEW) || svars->maxuid[M] >= srec->uid[M])) {
 | 
									    (!(svars->ctx[M]->opts & OPEN_NEW) || svars->maxuid[M] >= srec->uid[M])) {
 | 
				
			||||||
					/* The pair is alive, but outside the bulk range. */
 | 
										/* The pair is alive, but outside the bulk range. */
 | 
				
			||||||
					if (nmexcs == rmexcs) {
 | 
										*int_array_append( &mexcs ) = srec->uid[M];
 | 
				
			||||||
						rmexcs = rmexcs * 2 + 100;
 | 
					 | 
				
			||||||
						mexcs = nfrealloc( mexcs, rmexcs * sizeof(int) );
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					mexcs[nmexcs++] = srec->uid[M];
 | 
					 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			debugn( "  exception list is:" );
 | 
								debugn( "  exception list is:" );
 | 
				
			||||||
			for (t = 0; t < nmexcs; t++)
 | 
								for (t = 0; t < mexcs.array.size; t++)
 | 
				
			||||||
				debugn( " %d", mexcs[t] );
 | 
									debugn( " %d", mexcs.array.data[t] );
 | 
				
			||||||
			debug( "\n" );
 | 
								debug( "\n" );
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			minwuid = 1;
 | 
								minwuid = 1;
 | 
				
			||||||
| 
						 | 
					@ -1281,16 +1276,16 @@ box_opened2( sync_vars_t *svars, int t )
 | 
				
			||||||
		minwuid = INT_MAX;
 | 
							minwuid = INT_MAX;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	sync_ref( svars );
 | 
						sync_ref( svars );
 | 
				
			||||||
	load_box( svars, M, minwuid, mexcs, nmexcs );
 | 
						load_box( svars, M, minwuid, mexcs.array );
 | 
				
			||||||
	if (!check_cancel( svars ))
 | 
						if (!check_cancel( svars ))
 | 
				
			||||||
		load_box( svars, S, (ctx[S]->opts & OPEN_OLD) ? 1 : INT_MAX, 0, 0 );
 | 
							load_box( svars, S, (ctx[S]->opts & OPEN_OLD) ? 1 : INT_MAX, (int_array_t){ 0, 0 } );
 | 
				
			||||||
	sync_deref( svars );
 | 
						sync_deref( svars );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void box_loaded( int sts, void *aux );
 | 
					static void box_loaded( int sts, void *aux );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
load_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, int nmexcs )
 | 
					load_box( sync_vars_t *svars, int t, int minwuid, int_array_t mexcs )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	sync_rec_t *srec;
 | 
						sync_rec_t *srec;
 | 
				
			||||||
	int maxwuid;
 | 
						int maxwuid;
 | 
				
			||||||
| 
						 | 
					@ -1308,7 +1303,7 @@ load_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, int nmexcs )
 | 
				
			||||||
		maxwuid = 0;
 | 
							maxwuid = 0;
 | 
				
			||||||
	info( "Loading %s...\n", str_ms[t] );
 | 
						info( "Loading %s...\n", str_ms[t] );
 | 
				
			||||||
	debug( maxwuid == INT_MAX ? "loading %s [%d,inf]\n" : "loading %s [%d,%d]\n", str_ms[t], minwuid, maxwuid );
 | 
						debug( maxwuid == INT_MAX ? "loading %s [%d,inf]\n" : "loading %s [%d,%d]\n", str_ms[t], minwuid, maxwuid );
 | 
				
			||||||
	svars->drv[t]->load_box( svars->ctx[t], minwuid, maxwuid, svars->newuid[t], mexcs, nmexcs, box_loaded, AUX );
 | 
						svars->drv[t]->load_box( svars->ctx[t], minwuid, maxwuid, svars->newuid[t], mexcs, box_loaded, AUX );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -540,9 +540,9 @@ compare_ints( const void *l, const void *r )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
sort_ints( int *arr, int len )
 | 
					sort_int_array( int_array_t array )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	qsort( arr, len, sizeof(int), compare_ints );
 | 
						qsort( array.data, array.size, sizeof(int), compare_ints );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue