Przeglądaj źródła

keep the result of driver->list() and a flag whether it is valid in the store.

Oswald Buddenhagen 19 lat temu
rodzic
commit
47e592b603
4 zmienionych plików z 23 dodań i 32 usunięć
  1. 9 8
      src/drv_imap.c
  2. 4 3
      src/drv_maildir.c
  3. 3 1
      src/isync.h
  4. 7 20
      src/main.c

+ 9 - 8
src/drv_imap.c

@@ -113,7 +113,6 @@ typedef struct imap_store {
 	unsigned /*currentnc:1,*/ trashnc:1;
 	int uidnext; /* from SELECT responses */
 	list_t *ns_personal, *ns_other, *ns_shared; /* NAMESPACE info */
-	string_list_t *boxes; /* LIST results */
 	message_t **msgapp; /* FETCH results */
 	unsigned caps, rcaps; /* CAPABILITY results */
 	/* command queue */
@@ -898,7 +897,7 @@ parse_list_rsp( imap_store_t *ctx, char *cmd )
 	arg += l;
 	if (!memcmp( arg + strlen( arg ) - 5, ".lock", 5 )) /* workaround broken servers */
 		return;
-	add_string_list( &ctx->boxes, arg );
+	add_string_list( &ctx->gen.boxes, arg );
 }
 
 static int
@@ -1042,6 +1041,7 @@ imap_close_store( store_t *gctx )
 	imap_store_t *ctx = (imap_store_t *)gctx;
 
 	free_generic_messages( gctx->msgs );
+	free_string_list( ctx->gen.boxes );
 	if (ctx->buf.sock.fd != -1) {
 		imap_exec( ctx, 0, "LOGOUT" );
 		close( ctx->buf.sock.fd );
@@ -1180,6 +1180,9 @@ imap_open_store( store_conf_t *conf, store_t *oldctx )
 
 	if (ctx) {
 		if (((imap_store_conf_t *)(ctx->gen.conf))->server == cfg->server) {
+			free_string_list( ctx->gen.boxes );
+			ctx->gen.boxes = 0;
+			ctx->gen.listed = 0;
 			ctx->gen.conf = conf;
 			goto final;
 		}
@@ -1586,16 +1589,14 @@ imap_find_msg( store_t *gctx, const char *tuid, int *uid )
 }
 
 static int
-imap_list( store_t *gctx, string_list_t **retb )
+imap_list( store_t *gctx )
 {
 	imap_store_t *ctx = (imap_store_t *)gctx;
 	int ret;
 
-	ctx->boxes = 0;
-	if ((ret = imap_exec_b( ctx, 0, "LIST \"\" \"%s%%\"", ctx->prefix )) != DRV_OK)
-		return ret;
-	*retb = ctx->boxes;
-	return DRV_OK;
+	if ((ret = imap_exec_b( ctx, 0, "LIST \"\" \"%s%%\"", ctx->prefix )) == DRV_OK)
+		gctx->listed = 1;
+	return ret;
 }
 
 static int

+ 4 - 3
src/drv_maildir.c

@@ -147,11 +147,12 @@ static void
 maildir_close_store( store_t *gctx )
 {
 	maildir_cleanup( gctx );
+	free_string_list( gctx->boxes );
 	free( gctx );
 }
 
 static int
-maildir_list( store_t *gctx, string_list_t **retb )
+maildir_list( store_t *gctx )
 {
 	DIR *dir;
 	struct dirent *de;
@@ -160,7 +161,6 @@ maildir_list( store_t *gctx, string_list_t **retb )
 		error( "%s: %s\n", gctx->conf->path, strerror(errno) );
 		return DRV_STORE_BAD;
 	}
-	*retb = 0;
 	while ((de = readdir( dir ))) {
 		struct stat st;
 		char buf[PATH_MAX];
@@ -170,9 +170,10 @@ maildir_list( store_t *gctx, string_list_t **retb )
 		nfsnprintf( buf, sizeof(buf), "%s%s/cur", gctx->conf->path, de->d_name );
 		if (stat( buf, &st ) || !S_ISDIR(st.st_mode))
 			continue;
-		add_string_list( retb, de->d_name );
+		add_string_list( &gctx->boxes, de->d_name );
 	}
 	closedir (dir);
+	gctx->listed = 1;
 
 	return DRV_OK;
 }

+ 3 - 1
src/isync.h

@@ -144,6 +144,8 @@ typedef struct message {
 
 typedef struct store {
 	store_conf_t *conf; /* foreign */
+	string_list_t *boxes; /* _list results - own */
+	unsigned listed:1; /* was _list already run? */
 
 	/* currently open mailbox */
 	const char *name; /* foreign! maybe preset? */
@@ -176,7 +178,7 @@ struct driver {
 	int (*parse_store)( conffile_t *cfg, store_conf_t **storep, int *err );
 	store_t *(*open_store)( store_conf_t *conf, store_t *oldctx );
 	void (*close_store)( store_t *ctx );
-	int (*list)( store_t *ctx, string_list_t **boxes );
+	int (*list)( store_t *ctx );
 	void (*prepare_paths)( store_t *ctx );
 	void (*prepare_opts)( store_t *ctx, int opts );
 	int (*select)( store_t *ctx, int minuid, int maxuid, int *excs, int nexcs );

+ 7 - 20
src/main.c

@@ -194,10 +194,10 @@ main( int argc, char **argv )
 	group_conf_t *group;
 	driver_t *driver[2];
 	store_t *ctx[2];
-	string_list_t *uboxes[2], *boxes[2], *mbox, *sbox, **mboxp, **sboxp, *cboxes, *chanptr;
+	string_list_t *boxes[2], *mbox, *sbox, **mboxp, **sboxp, *cboxes, *chanptr;
 	char *config = 0, *channame, *boxlist, *opt, *ochar;
 	const char *names[2];
-	int all = 0, list = 0, cops = 0, ops[2] = { 0, 0 }, guboxes[2];
+	int all = 0, list = 0, cops = 0, ops[2] = { 0, 0 };
 	int oind, ret, op, multiple, pseudo = 0, t;
 
 	gethostname( Hostname, sizeof(Hostname) );
@@ -444,8 +444,6 @@ main( int argc, char **argv )
 	ctx[M] = ctx[S] = 0;
 	conf[M] = conf[S] = 0;	/* make-gcc-happy */
 	driver[M] = driver[S] = 0;	/* make-gcc-happy */
-	guboxes[M] = guboxes[S] = 0;
-	uboxes[M] = uboxes[S] = 0;
 	if (all)
 		multiple = channels->next != 0;
 	else if (argv[oind + 1])
@@ -493,9 +491,6 @@ main( int argc, char **argv )
 			if (ctx[t]) {
 				if (conf[t] == chan->stores[t])
 					continue;
-				free_string_list( uboxes[t] );
-				uboxes[t] = 0;
-				guboxes[t] = 0;
 				if (conf[t]->driver != chan->stores[t]->driver) {
 					driver[t]->close_store( ctx[t] );
 					ctx[t] = 0;
@@ -525,23 +520,17 @@ main( int argc, char **argv )
 				}
 		} else if (chan->patterns) {
 			for (t = 0; t < 2; t++) {
-				if (!guboxes[t]) {
-					if (driver[t]->list( ctx[t], &uboxes[t] ) != DRV_OK) {
+				if (!ctx[t]->listed) {
+					if (driver[t]->list( ctx[t] ) != DRV_OK) {
 					  screwt:
 						driver[t]->close_store( ctx[t] );
-						free_string_list( uboxes[t] );
-						uboxes[t] = 0;
-						guboxes[t] = 0;
 						ctx[t] = 0;
 						ret = 1;
 						goto next;
-					} else {
-						guboxes[t] = 1;
-						if (ctx[t]->conf->map_inbox)
-							add_string_list( &uboxes[t], ctx[t]->conf->map_inbox );
-					}
+					} else if (ctx[t]->conf->map_inbox)
+						add_string_list( &ctx[t]->boxes, ctx[t]->conf->map_inbox );
 				}
-				boxes[t] = filter_boxes( uboxes[t], chan->patterns );
+				boxes[t] = filter_boxes( ctx[t]->boxes, chan->patterns );
 			}
 			for (mboxp = &boxes[M]; (mbox = *mboxp); ) {
 				for (sboxp = &boxes[S]; (sbox = *sboxp); sboxp = &sbox->next)
@@ -606,10 +595,8 @@ main( int argc, char **argv )
 				break;
 		}
 	}
-	free_string_list( uboxes[S] );
 	if (ctx[S])
 		driver[S]->close_store( ctx[S] );
-	free_string_list( uboxes[M] );
 	if (ctx[M])
 		driver[M]->close_store( ctx[M] );