split out drv->load() from drv->select()
This commit is contained in:
		
							parent
							
								
									c741d5ffb5
								
							
						
					
					
						commit
						05fd0b9970
					
				
					 4 changed files with 121 additions and 85 deletions
				
			
		|  | @ -1541,13 +1541,6 @@ imap_open_store( store_conf_t *conf, | |||
| 	cb( 0, aux ); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| imap_prepare_paths( store_t *gctx ) | ||||
| { | ||||
| 	free_generic_messages( gctx->msgs ); | ||||
| 	gctx->msgs = 0; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| imap_prepare_opts( store_t *gctx, int opts ) | ||||
| { | ||||
|  | @ -1555,15 +1548,15 @@ imap_prepare_opts( store_t *gctx, int opts ) | |||
| } | ||||
| 
 | ||||
| static void | ||||
| imap_select( store_t *gctx, int minuid, int maxuid, int *excs, int nexcs, | ||||
| imap_select( store_t *gctx, int create, | ||||
|              void (*cb)( int sts, void *aux ), void *aux ) | ||||
| { | ||||
| 	imap_store_t *ctx = (imap_store_t *)gctx; | ||||
| 	struct imap_cmd *cmd = new_imap_cmd(); | ||||
| 	const char *prefix; | ||||
| 	int ret, i, j, bl; | ||||
| 	char buf[1000]; | ||||
| 
 | ||||
| 	free_generic_messages( gctx->msgs ); | ||||
| 	gctx->msgs = 0; | ||||
| 
 | ||||
| 	if (!strcmp( gctx->name, "INBOX" )) { | ||||
| 		prefix = ""; | ||||
|  | @ -1573,10 +1566,18 @@ imap_select( store_t *gctx, int minuid, int maxuid, int *excs, int nexcs, | |||
| 
 | ||||
| 	ctx->uidnext = -1; | ||||
| 
 | ||||
| 	cmd->param.create = (gctx->opts & OPEN_CREATE) != 0; | ||||
| 	cmd->param.create = create; | ||||
| 	cmd->param.trycreate = 1; | ||||
| 	if ((ret = imap_exec_b( ctx, cmd, "SELECT \"%s%s\"", prefix, gctx->name )) != DRV_OK) | ||||
| 		goto bail; | ||||
| 	cb( imap_exec_b( ctx, cmd, "SELECT \"%s%s\"", prefix, gctx->name ), aux ); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| imap_load( store_t *gctx, int minuid, int maxuid, int *excs, int nexcs, | ||||
|            void (*cb)( int sts, void *aux ), void *aux ) | ||||
| { | ||||
| 	imap_store_t *ctx = (imap_store_t *)gctx; | ||||
| 	int ret, i, j, bl; | ||||
| 	char buf[1000]; | ||||
| 
 | ||||
| 	if (gctx->count) { | ||||
| 		ctx->msgapp = &gctx->msgs; | ||||
|  | @ -1907,9 +1908,9 @@ struct driver imap_driver = { | |||
| 	imap_own_store, | ||||
| 	imap_cancel_store, | ||||
| 	imap_list, | ||||
| 	imap_prepare_paths, | ||||
| 	imap_prepare_opts, | ||||
| 	imap_select, | ||||
| 	imap_load, | ||||
| 	imap_fetch_msg, | ||||
| 	imap_store_msg, | ||||
| 	imap_find_msg, | ||||
|  |  | |||
|  | @ -745,9 +745,12 @@ maildir_app_msg( maildir_store_t *ctx, message_t ***msgapp, msg_t *entry ) | |||
| } | ||||
| 
 | ||||
| static void | ||||
| maildir_prepare_paths( store_t *gctx ) | ||||
| maildir_select( store_t *gctx, int create, | ||||
|                 void (*cb)( int sts, void *aux ), void *aux ) | ||||
| { | ||||
| 	maildir_store_t *ctx = (maildir_store_t *)gctx; | ||||
| 	int ret; | ||||
| 	char uvpath[_POSIX_PATH_MAX]; | ||||
| 
 | ||||
| 	maildir_cleanup( gctx ); | ||||
| 	gctx->msgs = 0; | ||||
|  | @ -759,37 +762,8 @@ maildir_prepare_paths( store_t *gctx ) | |||
| 		gctx->path = nfstrdup( ((maildir_store_conf_t *)gctx->conf)->inbox ); | ||||
| 	else | ||||
| 		nfasprintf( &gctx->path, "%s%s", gctx->conf->path, gctx->name ); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| maildir_prepare_opts( store_t *gctx, int opts ) | ||||
| { | ||||
| 	if (opts & OPEN_SETFLAGS) | ||||
| 		opts |= OPEN_OLD; | ||||
| 	if (opts & OPEN_EXPUNGE) | ||||
| 		opts |= OPEN_OLD|OPEN_NEW|OPEN_FLAGS; | ||||
| 	gctx->opts = opts; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| maildir_select( store_t *gctx, int minuid, int maxuid, int *excs, int nexcs, | ||||
|                 void (*cb)( int sts, void *aux ), void *aux ) | ||||
| { | ||||
| 	maildir_store_t *ctx = (maildir_store_t *)gctx; | ||||
| 	message_t **msgapp; | ||||
| 	msglist_t msglist; | ||||
| 	int i; | ||||
| #ifdef USE_DB | ||||
| 	int ret; | ||||
| #endif /* USE_DB */ | ||||
| 	char uvpath[_POSIX_PATH_MAX]; | ||||
| 
 | ||||
| 	ctx->minuid = minuid; | ||||
| 	ctx->maxuid = maxuid; | ||||
| 	ctx->excs = nfrealloc( excs, nexcs * sizeof(int) ); | ||||
| 	ctx->nexcs = nexcs; | ||||
| 
 | ||||
| 	if ((ret = maildir_validate( gctx->path, "", ctx->gen.opts & OPEN_CREATE, ctx )) != DRV_OK) { | ||||
| 	if ((ret = maildir_validate( gctx->path, "", create, ctx )) != DRV_OK) { | ||||
| 		cb( ret, aux ); | ||||
| 		return; | ||||
| 	} | ||||
|  | @ -854,9 +828,43 @@ maildir_select( store_t *gctx, int minuid, int maxuid, int *excs, int nexcs, | |||
| 			ctx->nuid = ((int *)value.data)[1]; | ||||
| 			ctx->uvok = 1; | ||||
| 		} | ||||
| 		cb( DRV_OK, aux ); | ||||
| 		return; | ||||
| 	} | ||||
|   fnok: | ||||
| #endif /* USE_DB */ | ||||
| 	if ((ret = maildir_uidval_lock( ctx )) != DRV_OK) { | ||||
| 		cb( ret, aux ); | ||||
| 		return; | ||||
| 	} | ||||
| 	maildir_uidval_unlock( ctx ); | ||||
| 
 | ||||
| 	cb( DRV_OK, aux ); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| maildir_prepare_opts( store_t *gctx, int opts ) | ||||
| { | ||||
| 	if (opts & OPEN_SETFLAGS) | ||||
| 		opts |= OPEN_OLD; | ||||
| 	if (opts & OPEN_EXPUNGE) | ||||
| 		opts |= OPEN_OLD|OPEN_NEW|OPEN_FLAGS; | ||||
| 	gctx->opts = opts; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| maildir_load( store_t *gctx, int minuid, int maxuid, int *excs, int nexcs, | ||||
|               void (*cb)( int sts, void *aux ), void *aux ) | ||||
| { | ||||
| 	maildir_store_t *ctx = (maildir_store_t *)gctx; | ||||
| 	message_t **msgapp; | ||||
| 	msglist_t msglist; | ||||
| 	int i; | ||||
| 
 | ||||
| 	ctx->minuid = minuid; | ||||
| 	ctx->maxuid = maxuid; | ||||
| 	ctx->excs = nfrealloc( excs, nexcs * sizeof(int) ); | ||||
| 	ctx->nexcs = nexcs; | ||||
| 
 | ||||
| 	if (maildir_scan( ctx, &msglist ) != DRV_OK) { | ||||
| 		cb( DRV_BOX_BAD, aux ); | ||||
|  | @ -1302,9 +1310,9 @@ struct driver maildir_driver = { | |||
| 	maildir_own_store, | ||||
| 	maildir_disown_store, /* _cancel_, but it's the same */ | ||||
| 	maildir_list, | ||||
| 	maildir_prepare_paths, | ||||
| 	maildir_prepare_opts, | ||||
| 	maildir_select, | ||||
| 	maildir_load, | ||||
| 	maildir_fetch_msg, | ||||
| 	maildir_store_msg, | ||||
| 	maildir_find_msg, | ||||
|  |  | |||
|  | @ -142,7 +142,6 @@ typedef struct message { | |||
| #define OPEN_NEW        (1<<1) | ||||
| #define OPEN_FLAGS      (1<<2) | ||||
| #define OPEN_SIZE       (1<<3) | ||||
| #define OPEN_CREATE     (1<<4) | ||||
| #define OPEN_EXPUNGE    (1<<5) | ||||
| #define OPEN_SETFLAGS   (1<<6) | ||||
| #define OPEN_APPEND     (1<<7) | ||||
|  | @ -208,10 +207,11 @@ struct driver { | |||
| 	void (*cancel_store)( store_t *ctx ); | ||||
| 	void (*list)( store_t *ctx, | ||||
| 	              void (*cb)( int sts, void *aux ), void *aux ); | ||||
| 	void (*prepare_paths)( store_t *ctx ); | ||||
| 	void (*prepare_opts)( store_t *ctx, int opts ); | ||||
| 	void (*select)( store_t *ctx, int minuid, int maxuid, int *excs, int nexcs, | ||||
| 	                void (*cb)( int sts, void *aux ), void *aux ); | ||||
| 	void (*select)( store_t *ctx, int create, | ||||
| 	               void (*cb)( int sts, void *aux ), void *aux ); | ||||
| 	void (*load)( store_t *ctx, int minuid, int maxuid, int *excs, int nexcs, | ||||
| 	              void (*cb)( int sts, void *aux ), void *aux ); | ||||
| 	void (*fetch_msg)( store_t *ctx, message_t *msg, msg_data_t *data, | ||||
| 	                   void (*cb)( int sts, void *aux ), void *aux ); | ||||
| 	void (*store_msg)( store_t *ctx, msg_data_t *data, int to_trash, | ||||
|  |  | |||
							
								
								
									
										97
									
								
								src/sync.c
									
										
									
									
									
								
							
							
						
						
									
										97
									
								
								src/sync.c
									
										
									
									
									
								
							|  | @ -207,6 +207,7 @@ static int check_cancel( sync_vars_t *svars ); | |||
| #define ST_CLOSED          (1<<5) | ||||
| #define ST_SENT_CANCEL     (1<<6) | ||||
| #define ST_CANCELED        (1<<7) | ||||
| #define ST_SELECTED        (1<<8) | ||||
| 
 | ||||
| #define ST_DID_EXPUNGE     (1<<16) | ||||
| 
 | ||||
|  | @ -452,9 +453,13 @@ cancel_done( void *aux ) | |||
| 
 | ||||
| 	svars->state[t] |= ST_CANCELED; | ||||
| 	if (svars->state[1-t] & ST_CANCELED) { | ||||
| 		Fclose( svars->nfp ); | ||||
| 		Fclose( svars->jfp ); | ||||
| 		sync_bail( svars ); | ||||
| 		if (svars->lfd) { | ||||
| 			Fclose( svars->nfp ); | ||||
| 			Fclose( svars->jfp ); | ||||
| 			sync_bail( svars ); | ||||
| 		} else { | ||||
| 			sync_bail2( svars ); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -537,21 +542,14 @@ clean_strdup( const char *s ) | |||
| 
 | ||||
| #define JOURNAL_VERSION "2" | ||||
| 
 | ||||
| static int select_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, int nmexcs ); | ||||
| static void box_selected( int sts, void *aux ); | ||||
| 
 | ||||
| void | ||||
| sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan, | ||||
|             void (*cb)( int sts, void *aux ), void *aux ) | ||||
| { | ||||
| 	sync_vars_t *svars; | ||||
| 	sync_rec_t *srec, *nsrec; | ||||
| 	char *s, *cmname, *csname; | ||||
| 	FILE *jfp; | ||||
| 	int opts[2], line, t1, t2, t3, t; | ||||
| 	struct stat st; | ||||
| 	struct flock lck; | ||||
| 	char fbuf[16]; /* enlarge when support for keywords is added */ | ||||
| 	char buf[64]; | ||||
| 	int t; | ||||
| 
 | ||||
| 	svars = nfcalloc( sizeof(*svars) ); | ||||
| 	svars->t[1] = 1; | ||||
|  | @ -571,15 +569,44 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan, | |||
| 		ctx[t]->uidvalidity = -1; | ||||
| 		set_bad_callback( ctx[t], store_bad, AUX ); | ||||
| 		svars->drv[t] = ctx[t]->conf->driver; | ||||
| 		svars->drv[t]->prepare_paths( ctx[t] ); | ||||
| 		info( "Selecting %s %s...\n", str_ms[t], ctx[t]->name ); | ||||
| 		DRIVER_CALL(select( ctx[t], (chan->ops[t] & OP_CREATE) != 0, box_selected, AUX )); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static int load_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, int nmexcs ); | ||||
| 
 | ||||
| static void | ||||
| box_selected( int sts, void *aux ) | ||||
| { | ||||
| 	DECL_SVARS; | ||||
| 	sync_rec_t *srec, *nsrec; | ||||
| 	char *s, *cmname, *csname; | ||||
| 	store_t *ctx[2]; | ||||
| 	channel_conf_t *chan; | ||||
| 	FILE *jfp; | ||||
| 	int opts[2], line, t1, t2, t3; | ||||
| 	struct stat st; | ||||
| 	struct flock lck; | ||||
| 	char fbuf[16]; /* enlarge when support for keywords is added */ | ||||
| 	char buf[64]; | ||||
| 
 | ||||
| 	if (check_ret( sts, aux )) | ||||
| 		return; | ||||
| 	INIT_SVARS(aux); | ||||
| 	ctx[0] = svars->ctx[0]; | ||||
| 	ctx[1] = svars->ctx[1]; | ||||
| 	svars->state[t] |= ST_SELECTED; | ||||
| 	if (!(svars->state[1-t] & ST_SELECTED)) | ||||
| 		return; | ||||
| 
 | ||||
| 	chan = svars->chan; | ||||
| 	if (!strcmp( chan->sync_state ? chan->sync_state : global_sync_state, "*" )) { | ||||
| 		if (!ctx[S]->path) { | ||||
| 			error( "Error: store '%s' does not support in-box sync state\n", chan->stores[S]->name ); | ||||
| 		  sbail: | ||||
| 			free( svars ); | ||||
| 			cb( SYNC_BAD(S), aux ); | ||||
| 			svars->ret = SYNC_BAD(S); | ||||
| 			sync_bail2( svars ); | ||||
| 			return; | ||||
| 		} | ||||
| 		nfasprintf( &svars->dname, "%s/." EXE "state", ctx[S]->path ); | ||||
|  | @ -597,13 +624,11 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan, | |||
| 	} | ||||
| 	if (!(s = strrchr( svars->dname, '/' ))) { | ||||
| 		error( "Error: invalid SyncState '%s'\n", svars->dname ); | ||||
| 		free( svars->dname ); | ||||
| 		goto sbail; | ||||
| 	} | ||||
| 	*s = 0; | ||||
| 	if (mkdir( svars->dname, 0700 ) && errno != EEXIST) { | ||||
| 		error( "Error: cannot create SyncState directory '%s': %s\n", svars->dname, strerror(errno) ); | ||||
| 		free( svars->dname ); | ||||
| 		goto sbail; | ||||
| 	} | ||||
| 	*s = '/'; | ||||
|  | @ -810,6 +835,17 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan, | |||
| 			goto bail; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	t1 = 0; | ||||
| 	for (t = 0; t < 2; t++) | ||||
| 		if (svars->uidval[t] >= 0 && svars->uidval[t] != ctx[t]->uidvalidity) { | ||||
| 			error( "Error: UIDVALIDITY of %s changed (got %d, expected %d)\n", | ||||
| 			       str_ms[t], ctx[t]->uidvalidity, svars->uidval[t] ); | ||||
| 			t1++; | ||||
| 		} | ||||
| 	if (t1) | ||||
| 		goto bail; | ||||
| 
 | ||||
| 	if (!(svars->nfp = fopen( svars->nname, "w" ))) { | ||||
| 		error( "Error: cannot write new sync state %s\n", svars->nname ); | ||||
| 		goto bail; | ||||
|  | @ -851,8 +887,6 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan, | |||
| 			} else if (chan->stores[1-t]->trash && chan->stores[1-t]->trash_remote_new) | ||||
| 				opts[t] |= OPEN_NEW|OPEN_FLAGS; | ||||
| 		} | ||||
| 		if (chan->ops[t] & OP_CREATE) | ||||
| 			opts[t] |= OPEN_CREATE; | ||||
| 	} | ||||
| 	if ((chan->ops[S] & (OP_NEW|OP_RENEW)) && chan->max_messages) | ||||
| 		opts[S] |= OPEN_OLD|OPEN_NEW|OPEN_FLAGS; | ||||
|  | @ -873,15 +907,15 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan, | |||
| 	svars->drv[S]->prepare_opts( ctx[S], opts[S] ); | ||||
| 
 | ||||
| 	svars->find = line != 0; | ||||
| 	if (!svars->smaxxuid && select_box( svars, M, (ctx[M]->opts & OPEN_OLD) ? 1 : INT_MAX, 0, 0 )) | ||||
| 	if (!svars->smaxxuid && load_box( svars, M, (ctx[M]->opts & OPEN_OLD) ? 1 : INT_MAX, 0, 0 )) | ||||
| 		return; | ||||
| 	select_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, 0, 0 ); | ||||
| } | ||||
| 
 | ||||
| static void box_selected( int sts, void *aux ); | ||||
| static void box_loaded( int sts, void *aux ); | ||||
| 
 | ||||
| static int | ||||
| select_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, int nmexcs ) | ||||
| load_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, int nmexcs ) | ||||
| { | ||||
| 	sync_rec_t *srec; | ||||
| 	int maxwuid; | ||||
|  | @ -897,9 +931,9 @@ select_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, int nmexcs ) | |||
| 				maxwuid = srec->uid[t]; | ||||
| 	} else | ||||
| 		maxwuid = 0; | ||||
| 	info( "Selecting %s %s...\n", str_ms[t], svars->ctx[t]->name ); | ||||
| 	debug( maxwuid == INT_MAX ? "selecting %s [%d,inf]\n" : "selecting %s [%d,%d]\n", str_ms[t], minwuid, maxwuid ); | ||||
| 	DRIVER_CALL_RET(select( svars->ctx[t], minwuid, maxwuid, mexcs, nmexcs, box_selected, AUX )); | ||||
| 	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 ); | ||||
| 	DRIVER_CALL_RET(load( svars->ctx[t], minwuid, maxwuid, mexcs, nmexcs, box_loaded, AUX )); | ||||
| } | ||||
| 
 | ||||
| typedef struct { | ||||
|  | @ -911,19 +945,12 @@ static void msg_found_sel( int sts, int uid, void *aux ); | |||
| static void msgs_found_sel( sync_vars_t *svars, int t ); | ||||
| 
 | ||||
| static void | ||||
| box_selected( int sts, void *aux ) | ||||
| box_loaded( int sts, void *aux ) | ||||
| { | ||||
| 	find_vars_t *fv; | ||||
| 	sync_rec_t *srec; | ||||
| 
 | ||||
| 	SVARS_CHECK_RET; | ||||
| 	if (svars->uidval[t] >= 0 && svars->uidval[t] != svars->ctx[t]->uidvalidity) { | ||||
| 		error( "Error: UIDVALIDITY of %s changed (got %d, expected %d)\n", | ||||
| 		         str_ms[t], svars->ctx[t]->uidvalidity, svars->uidval[t] ); | ||||
| 		svars->ret |= SYNC_FAIL; | ||||
| 		cancel_sync( svars ); | ||||
| 		return; | ||||
| 	} | ||||
| 	info( "%s: %d messages, %d recent\n", str_ms[t], svars->ctx[t]->count, svars->ctx[t]->recent ); | ||||
| 
 | ||||
| 	if (svars->find) { | ||||
|  | @ -1100,7 +1127,7 @@ msgs_found_sel( sync_vars_t *svars, int t ) | |||
| 		for (t = 0; t < nmexcs; t++) | ||||
| 			debugn( " %d", mexcs[t] ); | ||||
| 		debug( "\n" ); | ||||
| 		select_box( svars, M, minwuid, mexcs, nmexcs ); | ||||
| 		load_box( svars, M, minwuid, mexcs, nmexcs ); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue