isync

mailbox synchronization program
git clone https://git.code.sf.net/p/isync/isync
Log | Files | Refs | README | LICENSE

commit bc39f10a1e4c6007f5948f70544459170dd36962
parent 7726ce3e0f57f39f9040de4f85dc04f99b859f29
Author: Oswald Buddenhagen <ossi@users.sf.net>
Date:   Sat, 11 Feb 2006 20:28:45 +0000

lock the sync state open the journal before opening the master. this is
a bit ugly for the "SyncState *" case, as we have to create a directory
without making it a maildir right away. however, this makes the code
quite a bit simpler to understand and simpler to parallelize.

Diffstat:
Msrc/sync.c | 69+++++++++++++++++++++++++++++++--------------------------------------
1 file changed, 31 insertions(+), 38 deletions(-)

diff --git a/src/sync.c b/src/sync.c @@ -394,6 +394,18 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan ) } free( csname ); } + if (!(s = strrchr( dname, '/' ))) { + fprintf( stderr, "Error: invalid SyncState '%s'\n", dname ); + free( dname ); + return SYNC_BAD(S); + } + *s = 0; + if (mkdir( dname, 0700 ) && errno != EEXIST) { + fprintf( stderr, "Error: cannot create SyncState directory '%s': %s\n", dname, strerror(errno) ); + free( dname ); + return SYNC_BAD(S); + } + *s = '/'; nfasprintf( &jname, "%s.journal", dname ); nfasprintf( &nname, "%s.new", dname ); nfasprintf( &lname, "%s.lock", dname ); @@ -405,18 +417,12 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan ) #if F_WRLCK != 0 lck.l_type = F_WRLCK; #endif - line = 0; if ((lfd = open( lname, O_WRONLY|O_CREAT, 0666 )) < 0) { - if (errno != ENOENT) { - lferr: - fprintf( stderr, "Error: cannot create lock file %s: %s\n", lname, strerror(errno) ); - ret = SYNC_FAIL; - goto bail2; - } - goto skiprd; + fprintf( stderr, "Error: cannot create lock file %s: %s\n", lname, strerror(errno) ); + ret = SYNC_FAIL; + goto bail2; } if (fcntl( lfd, F_SETLK, &lck )) { - lckerr: fprintf( stderr, "Error: channel :%s:%s-:%s:%s is locked\n", chan->stores[M]->name, ctx[M]->name, chan->stores[S]->name, ctx[S]->name ); ret = SYNC_FAIL; @@ -477,6 +483,7 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan ) goto bail; } } + line = 0; if ((jfp = fopen( jname, "r" ))) { if (!stat( nname, &st ) && fgets( buf, sizeof(buf), jfp )) { debug( "recovering journal ...\n" ); @@ -618,7 +625,20 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan ) goto bail; } } - skiprd: + if (!(nfp = fopen( nname, "w" ))) { + fprintf( stderr, "Error: cannot write new sync state %s\n", nname ); + ret = SYNC_FAIL; + goto bail; + } + if (!(jfp = fopen( jname, "a" ))) { + fprintf( stderr, "Error: cannot write journal %s\n", jname ); + fclose( nfp ); + ret = SYNC_FAIL; + goto bail; + } + setlinebuf( jfp ); + if (!line) + Fprintf( jfp, JOURNAL_VERSION "\n" ); opts[M] = opts[S] = 0; for (t = 0; t < 2; t++) { @@ -687,35 +707,9 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan ) if (suidval && suidval != ctx[S]->uidvalidity) { fprintf( stderr, "Error: UIDVALIDITY of slave changed\n" ); ret = SYNC_FAIL; - goto bail; + goto finish; } info( "%d messages, %d recent\n", ctx[S]->count, ctx[S]->recent ); - - s = strrchr( dname, '/' ); - *s = 0; - mkdir( dname, 0700 ); - *s = '/'; - if (lfd < 0) { - if ((lfd = open( lname, O_WRONLY|O_CREAT, 0666 )) < 0) - goto lferr; - if (fcntl( lfd, F_SETLK, &lck )) - goto lckerr; - } - if (!(nfp = fopen( nname, "w" ))) { - fprintf( stderr, "Error: cannot write new sync state %s\n", nname ); - ret = SYNC_FAIL; - goto bail; - } - if (!(jfp = fopen( jname, "a" ))) { - fprintf( stderr, "Error: cannot write journal %s\n", jname ); - fclose( nfp ); - ret = SYNC_FAIL; - goto bail; - } - setlinebuf( jfp ); - if (!line) - Fprintf( jfp, JOURNAL_VERSION "\n" ); - if ((ret = findmsgs( recs, ctx, S, line ? jfp : 0 )) != SYNC_OK) goto finish; @@ -799,7 +793,6 @@ sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan ) goto finish; } info( "%d messages, %d recent\n", ctx[M]->count, ctx[M]->recent ); - if ((ret = findmsgs( recs, ctx, M, line ? jfp : 0 )) != SYNC_OK) goto finish;