commit c2209c8470769a6166db14ce3856f57e44e9a3da
parent 556dfabc38ec0c615c26a528711ed75336a2730d
Author: Oswald Buddenhagen <ossi@users.sf.net>
Date: Sat, 13 Nov 2004 09:19:36 +0000
cope with out-of-disk-space halfways gracefully (that is, don't clobber
the sync state including the journal, but exit immediately).
Diffstat:
M | src/sync.c | | | 90 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------- |
1 file changed, 62 insertions(+), 28 deletions(-)
diff --git a/src/sync.c b/src/sync.c
@@ -33,6 +33,22 @@
#include <errno.h>
#include <sys/stat.h>
+void
+Fprintf( FILE *f, const char *msg, ... )
+{
+ int r;
+ va_list va;
+
+ va_start( va, msg );
+ r = vfprintf( f, msg, va );
+ va_end( va );
+ if (r < 0) {
+ perror( "cannot write file" );
+ exit( 1 );
+ }
+}
+
+
static const char Flags[] = { 'D', 'F', 'R', 'S', 'T' };
static int
@@ -256,10 +272,10 @@ sync_old( int tops, store_t *sctx, store_t *tctx, store_conf_t *tconf, FILE *jfp
default: /* ok */ break;
case DRV_OK:
if (pull) {
- fprintf( jfp, "< %d %d 0\n", srec->muid, srec->suid );
+ Fprintf( jfp, "< %d %d 0\n", srec->muid, srec->suid );
srec->muid = 0;
} else {
- fprintf( jfp, "> %d %d 0\n", srec->muid, srec->suid );
+ Fprintf( jfp, "> %d %d 0\n", srec->muid, srec->suid );
srec->suid = 0;
}
}
@@ -290,10 +306,10 @@ sync_old( int tops, store_t *sctx, store_t *tctx, store_conf_t *tconf, FILE *jfp
case DRV_OK:
if (pull) {
srec->suid = uid;
- fprintf( jfp, "> %d -1 %d\n", srec->muid, srec->suid );
+ Fprintf( jfp, "> %d -1 %d\n", srec->muid, srec->suid );
} else {
srec->muid = uid;
- fprintf( jfp, "< -1 %d %d\n", srec->suid, srec->muid );
+ Fprintf( jfp, "< -1 %d %d\n", srec->suid, srec->muid );
}
*nflags = smsg->flags;
}
@@ -344,7 +360,7 @@ sync_old( int tops, store_t *sctx, store_t *tctx, store_conf_t *tconf, FILE *jfp
if (unex) {
debug( "unexpiring pair(%d,%d)\n", srec->muid, srec->suid );
/* log last, so deletion can't be misinterpreted! */
- fprintf( jfp, "~ %d %d 0\n", srec->muid, srec->suid );
+ Fprintf( jfp, "~ %d %d 0\n", srec->muid, srec->suid );
srec->status &= ~S_EXPIRED;
}
}
@@ -407,10 +423,10 @@ sync_new( int tops, store_t *sctx, store_t *tctx, store_conf_t *tconf, FILE *jfp
srec->next = 0;
**srecadd = srec;
*srecadd = &srec->next;
- fprintf( jfp, "+ %d %d %u\n", srec->muid, srec->suid, srec->flags );
+ Fprintf( jfp, "+ %d %d %u\n", srec->muid, srec->suid, srec->flags );
if (*smaxuid < msg->uid) {
*smaxuid = msg->uid;
- fprintf( jfp, pull ? "( %d\n" : ") %d\n", msg->uid );
+ Fprintf( jfp, pull ? "( %d\n" : ") %d\n", msg->uid );
}
}
} else
@@ -522,7 +538,13 @@ sync_boxes( store_t *mctx, const char *mname,
}
if ((dfp = fopen( dname, "r" ))) {
debug( "reading sync state %s ...\n", dname );
- if (fscanf( dfp, "%d:%d %d:%d:%d\n", &muidval, &mmaxuid, &suidval, &smaxxuid, &smaxuid) != 5) {
+ if (!fgets( buf, sizeof(buf), dfp ) || !(i = strlen( buf )) || buf[i - 1] != '\n') {
+ fprintf( stderr, "Error: incomplete sync state header in %s\n", dname );
+ fclose( dfp );
+ ret = SYNC_FAIL;
+ goto bail;
+ }
+ if (sscanf( buf, "%d:%d %d:%d:%d", &muidval, &mmaxuid, &suidval, &smaxxuid, &smaxuid) != 5) {
fprintf( stderr, "Error: invalid sync state header in %s\n", dname );
fclose( dfp );
ret = SYNC_FAIL;
@@ -531,8 +553,14 @@ sync_boxes( store_t *mctx, const char *mname,
line = 1;
while (fgets( buf, sizeof(buf), dfp )) {
line++;
+ if (!(i = strlen( buf )) || buf[i - 1] != '\n') {
+ fprintf( stderr, "Error: incomplete sync state entry at %s:%d\n", dname, line );
+ fclose( dfp );
+ ret = SYNC_FAIL;
+ goto bail;
+ }
fbuf[0] = 0;
- if (sscanf( buf, "%d %d %15s\n", &t1, &t2, fbuf ) < 2) {
+ if (sscanf( buf, "%d %d %15s", &t1, &t2, fbuf ) < 2) {
fprintf( stderr, "Error: invalid sync state entry at %s:%d\n", dname, line );
fclose( dfp );
ret = SYNC_FAIL;
@@ -568,14 +596,20 @@ sync_boxes( store_t *mctx, const char *mname,
srec = recs;
while (fgets( buf, sizeof(buf), jfp )) {
line++;
+ if (!(i = strlen( buf )) || buf[i - 1] != '\n') {
+ fprintf( stderr, "Error: incomplete journal entry at %s:%d\n", jname, line );
+ fclose( jfp );
+ ret = SYNC_FAIL;
+ goto bail;
+ }
if (buf[0] == '^')
srec = recs;
else {
if (buf[0] == '(' || buf[0] == ')' ?
- (sscanf( buf + 2, "%d\n", &t1 ) != 1) :
+ (sscanf( buf + 2, "%d", &t1 ) != 1) :
buf[0] == '-' || buf[0] == '|' ?
- (sscanf( buf + 2, "%d %d\n", &t1, &t2 ) != 2) :
- (sscanf( buf + 2, "%d %d %d\n", &t1, &t2, &t3 ) != 3))
+ (sscanf( buf + 2, "%d %d", &t1, &t2 ) != 2) :
+ (sscanf( buf + 2, "%d %d %d", &t1, &t2, &t3 ) != 3))
{
fprintf( stderr, "Error: malformed journal entry at %s:%d\n", jname, line );
fclose( jfp );
@@ -719,7 +753,7 @@ sync_boxes( store_t *mctx, const char *mname,
minwuid = srec->muid;
}
debug( " min non-orphaned master uid is %d\n", minwuid );
- fprintf( jfp, "^\n" ); /* if any S_EXP_SLAVE */
+ Fprintf( jfp, "^\n" ); /* if any S_EXP_SLAVE */
for (srec = recs; srec; srec = srec->next) {
if (srec->status & S_DEAD)
continue;
@@ -727,10 +761,10 @@ sync_boxes( store_t *mctx, const char *mname,
if (minwuid > srec->muid && mmaxuid >= srec->muid) {
debug( " -> killing (%d,%d)\n", srec->muid, srec->suid );
srec->status = S_DEAD;
- fprintf( jfp, "- %d %d\n", srec->muid, srec->suid );
+ Fprintf( jfp, "- %d %d\n", srec->muid, srec->suid );
} else if (srec->suid) {
debug( " -> orphaning (%d,[%d])\n", srec->muid, srec->suid );
- fprintf( jfp, "> %d %d 0\n", srec->muid, srec->suid );
+ Fprintf( jfp, "> %d %d 0\n", srec->muid, srec->suid );
srec->suid = 0;
}
} else if (minwuid > srec->muid) {
@@ -738,7 +772,7 @@ sync_boxes( store_t *mctx, const char *mname,
if (mmaxuid >= srec->muid) {
debug( " -> killing (%d,%d)\n", srec->muid, srec->suid );
srec->status = S_DEAD;
- fprintf( jfp, "- %d %d\n", srec->muid, srec->suid );
+ Fprintf( jfp, "- %d %d\n", srec->muid, srec->suid );
}
} else if (srec->muid > 0 && srec->suid && (mctx->opts & OPEN_OLD) &&
(!(mctx->opts & OPEN_NEW) || mmaxuid >= srec->muid)) {
@@ -785,12 +819,12 @@ sync_boxes( store_t *mctx, const char *mname,
if (!muidval || !suidval) {
muidval = mctx->uidvalidity;
suidval = sctx->uidvalidity;
- fprintf( jfp, "| %d %d\n", muidval, suidval );
+ Fprintf( jfp, "| %d %d\n", muidval, suidval );
}
info( "Synchronizing\n" );
debug( "synchronizing old entries\n" );
- fprintf( jfp, "^\n" );
+ Fprintf( jfp, "^\n" );
for (srec = recs; srec; srec = srec->next) {
if (srec->status & S_DEAD)
continue;
@@ -803,7 +837,7 @@ sync_boxes( store_t *mctx, const char *mname,
debug( " vanished\n" );
/* d.1) d.5) d.6) d.10) d.11) */
srec->status = S_DEAD;
- fprintf( jfp, "- %d %d\n", srec->muid, srec->suid );
+ Fprintf( jfp, "- %d %d\n", srec->muid, srec->suid );
} else {
delm = nom && (srec->muid > 0);
dels = nos && (srec->suid > 0);
@@ -816,7 +850,7 @@ sync_boxes( store_t *mctx, const char *mname,
if (srec->flags != nflags) {
debug( " updating flags (%u -> %u)\n", srec->flags, nflags );
srec->flags = nflags;
- fprintf( jfp, "* %d %d %u\n", srec->muid, srec->suid, nflags );
+ Fprintf( jfp, "* %d %d %u\n", srec->muid, srec->suid, nflags );
}
if (mmsg && (mmsg->flags & F_DELETED))
srec->status |= S_DEL_MASTER;
@@ -849,7 +883,7 @@ sync_boxes( store_t *mctx, const char *mname,
}
}
if (delt) {
- fprintf( jfp, "^\n" );
+ Fprintf( jfp, "^\n" );
for (srec = recs; srec; srec = srec->next) {
if (srec->status & (S_DEAD|S_EXPIRED))
continue;
@@ -857,7 +891,7 @@ sync_boxes( store_t *mctx, const char *mname,
if (smsg && (smsg->status & M_EXPIRED)) {
debug( " expiring pair(%d,%d)\n", srec->muid, srec->suid );
/* log first, so deletion can't be misinterpreted! */
- fprintf( jfp, "~ %d %d 1\n", srec->muid, srec->suid );
+ Fprintf( jfp, "~ %d %d 1\n", srec->muid, srec->suid );
if (smaxxuid < srec->suid)
smaxxuid = srec->suid;
srec->status |= S_EXPIRED;
@@ -914,7 +948,7 @@ sync_boxes( store_t *mctx, const char *mname,
debug( " min non-orphaned master uid is %d\n", minwuid );
}
- fprintf( jfp, "^\n" );
+ Fprintf( jfp, "^\n" );
for (srec = recs; srec; srec = srec->next) {
if (srec->status & S_DEAD)
continue;
@@ -922,15 +956,15 @@ sync_boxes( store_t *mctx, const char *mname,
if (srec->muid <= 0 || ((srec->status & S_DEL_MASTER) && mex)) {
debug( " -> killing (%d,%d)\n", srec->muid, srec->suid );
srec->status = S_DEAD;
- fprintf( jfp, "- %d %d\n", srec->muid, srec->suid );
+ Fprintf( jfp, "- %d %d\n", srec->muid, srec->suid );
} else if (srec->status & S_EXPIRED) {
if (mmaxuid >= srec->muid && minwuid > srec->muid) {
debug( " -> killing (%d,%d)\n", srec->muid, srec->suid );
srec->status = S_DEAD;
- fprintf( jfp, "- %d %d\n", srec->muid, srec->suid );
+ Fprintf( jfp, "- %d %d\n", srec->muid, srec->suid );
} else if (srec->suid) {
debug( " -> orphaning (%d,[%d])\n", srec->muid, srec->suid );
- fprintf( jfp, "> %d %d 0\n", srec->muid, srec->suid );
+ Fprintf( jfp, "> %d %d 0\n", srec->muid, srec->suid );
srec->suid = 0;
}
}
@@ -939,12 +973,12 @@ sync_boxes( store_t *mctx, const char *mname,
}
finish:
- fprintf( nfp, "%d:%d %d:%d:%d\n", muidval, mmaxuid, suidval, smaxxuid, smaxuid );
+ Fprintf( nfp, "%d:%d %d:%d:%d\n", muidval, mmaxuid, suidval, smaxxuid, smaxuid );
for (srec = recs; srec; srec = srec->next) {
if (srec->status & S_DEAD)
continue;
make_flags( srec->flags, fbuf );
- fprintf( nfp, "%d %d %s%s\n", srec->muid, srec->suid,
+ Fprintf( nfp, "%d %d %s%s\n", srec->muid, srec->suid,
srec->status & S_EXPIRED ? "X" : "", fbuf );
}