- instead of having {m,s}foo, we have foo[2] now, so we can do
everything with loops instead of symmetric function calls - added some const
This commit is contained in:
parent
f070f3cd72
commit
4ec56f8cf6
98
src/config.c
98
src/config.c
|
@ -35,7 +35,7 @@
|
||||||
store_conf_t *stores;
|
store_conf_t *stores;
|
||||||
channel_conf_t *channels;
|
channel_conf_t *channels;
|
||||||
group_conf_t *groups;
|
group_conf_t *groups;
|
||||||
int global_mops, global_sops;
|
int global_ops[2];
|
||||||
char *global_sync_state;
|
char *global_sync_state;
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -92,7 +92,7 @@ parse_size( conffile_t *cfile )
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
getopt_helper( conffile_t *cfile, int *cops, int *mops, int *sops, char **sync_state )
|
getopt_helper( conffile_t *cfile, int *cops, int ops[], char **sync_state )
|
||||||
{
|
{
|
||||||
char *arg;
|
char *arg;
|
||||||
|
|
||||||
|
@ -112,56 +112,56 @@ getopt_helper( conffile_t *cfile, int *cops, int *mops, int *sops, char **sync_s
|
||||||
else if (!strcasecmp( "Flags", arg ))
|
else if (!strcasecmp( "Flags", arg ))
|
||||||
*cops |= OP_FLAGS;
|
*cops |= OP_FLAGS;
|
||||||
else if (!strcasecmp( "PullReNew", arg ))
|
else if (!strcasecmp( "PullReNew", arg ))
|
||||||
*sops |= OP_RENEW;
|
ops[S] |= OP_RENEW;
|
||||||
else if (!strcasecmp( "PullNew", arg ))
|
else if (!strcasecmp( "PullNew", arg ))
|
||||||
*sops |= OP_NEW;
|
ops[S] |= OP_NEW;
|
||||||
else if (!strcasecmp( "PullDelete", arg ))
|
else if (!strcasecmp( "PullDelete", arg ))
|
||||||
*sops |= OP_DELETE;
|
ops[S] |= OP_DELETE;
|
||||||
else if (!strcasecmp( "PullFlags", arg ))
|
else if (!strcasecmp( "PullFlags", arg ))
|
||||||
*sops |= OP_FLAGS;
|
ops[S] |= OP_FLAGS;
|
||||||
else if (!strcasecmp( "PushReNew", arg ))
|
else if (!strcasecmp( "PushReNew", arg ))
|
||||||
*mops |= OP_RENEW;
|
ops[M] |= OP_RENEW;
|
||||||
else if (!strcasecmp( "PushNew", arg ))
|
else if (!strcasecmp( "PushNew", arg ))
|
||||||
*mops |= OP_NEW;
|
ops[M] |= OP_NEW;
|
||||||
else if (!strcasecmp( "PushDelete", arg ))
|
else if (!strcasecmp( "PushDelete", arg ))
|
||||||
*mops |= OP_DELETE;
|
ops[M] |= OP_DELETE;
|
||||||
else if (!strcasecmp( "PushFlags", arg ))
|
else if (!strcasecmp( "PushFlags", arg ))
|
||||||
*mops |= OP_FLAGS;
|
ops[M] |= OP_FLAGS;
|
||||||
else if (!strcasecmp( "All", arg ) || !strcasecmp( "Full", arg ))
|
else if (!strcasecmp( "All", arg ) || !strcasecmp( "Full", arg ))
|
||||||
*cops |= XOP_PULL|XOP_PUSH;
|
*cops |= XOP_PULL|XOP_PUSH;
|
||||||
else if (strcasecmp( "None", arg ) && strcasecmp( "Noop", arg ))
|
else if (strcasecmp( "None", arg ) && strcasecmp( "Noop", arg ))
|
||||||
fprintf( stderr, "%s:%d: invalid Sync arg '%s'\n",
|
fprintf( stderr, "%s:%d: invalid Sync arg '%s'\n",
|
||||||
cfile->file, cfile->line, arg );
|
cfile->file, cfile->line, arg );
|
||||||
while ((arg = next_arg( &cfile->rest )));
|
while ((arg = next_arg( &cfile->rest )));
|
||||||
*mops |= XOP_HAVE_TYPE;
|
ops[M] |= XOP_HAVE_TYPE;
|
||||||
} else if (!strcasecmp( "Expunge", cfile->cmd )) {
|
} else if (!strcasecmp( "Expunge", cfile->cmd )) {
|
||||||
arg = cfile->val;
|
arg = cfile->val;
|
||||||
do
|
do
|
||||||
if (!strcasecmp( "Both", arg ))
|
if (!strcasecmp( "Both", arg ))
|
||||||
*cops |= OP_EXPUNGE;
|
*cops |= OP_EXPUNGE;
|
||||||
else if (!strcasecmp( "Master", arg ))
|
else if (!strcasecmp( "Master", arg ))
|
||||||
*mops |= OP_EXPUNGE;
|
ops[M] |= OP_EXPUNGE;
|
||||||
else if (!strcasecmp( "Slave", arg ))
|
else if (!strcasecmp( "Slave", arg ))
|
||||||
*sops |= OP_EXPUNGE;
|
ops[S] |= OP_EXPUNGE;
|
||||||
else if (strcasecmp( "None", arg ))
|
else if (strcasecmp( "None", arg ))
|
||||||
fprintf( stderr, "%s:%d: invalid Expunge arg '%s'\n",
|
fprintf( stderr, "%s:%d: invalid Expunge arg '%s'\n",
|
||||||
cfile->file, cfile->line, arg );
|
cfile->file, cfile->line, arg );
|
||||||
while ((arg = next_arg( &cfile->rest )));
|
while ((arg = next_arg( &cfile->rest )));
|
||||||
*mops |= XOP_HAVE_EXPUNGE;
|
ops[M] |= XOP_HAVE_EXPUNGE;
|
||||||
} else if (!strcasecmp( "Create", cfile->cmd )) {
|
} else if (!strcasecmp( "Create", cfile->cmd )) {
|
||||||
arg = cfile->val;
|
arg = cfile->val;
|
||||||
do
|
do
|
||||||
if (!strcasecmp( "Both", arg ))
|
if (!strcasecmp( "Both", arg ))
|
||||||
*cops |= OP_CREATE;
|
*cops |= OP_CREATE;
|
||||||
else if (!strcasecmp( "Master", arg ))
|
else if (!strcasecmp( "Master", arg ))
|
||||||
*mops |= OP_CREATE;
|
ops[M] |= OP_CREATE;
|
||||||
else if (!strcasecmp( "Slave", arg ))
|
else if (!strcasecmp( "Slave", arg ))
|
||||||
*sops |= OP_CREATE;
|
ops[S] |= OP_CREATE;
|
||||||
else if (strcasecmp( "None", arg ))
|
else if (strcasecmp( "None", arg ))
|
||||||
fprintf( stderr, "%s:%d: invalid Create arg '%s'\n",
|
fprintf( stderr, "%s:%d: invalid Create arg '%s'\n",
|
||||||
cfile->file, cfile->line, arg );
|
cfile->file, cfile->line, arg );
|
||||||
while ((arg = next_arg( &cfile->rest )));
|
while ((arg = next_arg( &cfile->rest )));
|
||||||
*mops |= XOP_HAVE_CREATE;
|
ops[M] |= XOP_HAVE_CREATE;
|
||||||
} else if (!strcasecmp( "SyncState", cfile->cmd ))
|
} else if (!strcasecmp( "SyncState", cfile->cmd ))
|
||||||
*sync_state = expand_strdup( cfile->val );
|
*sync_state = expand_strdup( cfile->val );
|
||||||
else
|
else
|
||||||
|
@ -194,29 +194,29 @@ getcline( conffile_t *cfile )
|
||||||
|
|
||||||
/* XXX - this does not detect None conflicts ... */
|
/* XXX - this does not detect None conflicts ... */
|
||||||
int
|
int
|
||||||
merge_ops( int cops, int *mops, int *sops )
|
merge_ops( int cops, int ops[] )
|
||||||
{
|
{
|
||||||
int aops;
|
int aops;
|
||||||
|
|
||||||
aops = *mops | *sops;
|
aops = ops[M] | ops[S];
|
||||||
if (*mops & XOP_HAVE_TYPE) {
|
if (ops[M] & XOP_HAVE_TYPE) {
|
||||||
if (aops & OP_MASK_TYPE) {
|
if (aops & OP_MASK_TYPE) {
|
||||||
if (aops & cops & OP_MASK_TYPE) {
|
if (aops & cops & OP_MASK_TYPE) {
|
||||||
cfl:
|
cfl:
|
||||||
fprintf( stderr, "Conflicting Sync args specified.\n" );
|
fprintf( stderr, "Conflicting Sync args specified.\n" );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
*mops |= cops & OP_MASK_TYPE;
|
ops[M] |= cops & OP_MASK_TYPE;
|
||||||
*sops |= cops & OP_MASK_TYPE;
|
ops[S] |= cops & OP_MASK_TYPE;
|
||||||
if (cops & XOP_PULL) {
|
if (cops & XOP_PULL) {
|
||||||
if (*sops & OP_MASK_TYPE)
|
if (ops[S] & OP_MASK_TYPE)
|
||||||
goto cfl;
|
goto cfl;
|
||||||
*sops |= OP_MASK_TYPE;
|
ops[S] |= OP_MASK_TYPE;
|
||||||
}
|
}
|
||||||
if (cops & XOP_PUSH) {
|
if (cops & XOP_PUSH) {
|
||||||
if (*mops & OP_MASK_TYPE)
|
if (ops[M] & OP_MASK_TYPE)
|
||||||
goto cfl;
|
goto cfl;
|
||||||
*mops |= OP_MASK_TYPE;
|
ops[M] |= OP_MASK_TYPE;
|
||||||
}
|
}
|
||||||
} else if (cops & (OP_MASK_TYPE|XOP_MASK_DIR)) {
|
} else if (cops & (OP_MASK_TYPE|XOP_MASK_DIR)) {
|
||||||
if (!(cops & OP_MASK_TYPE))
|
if (!(cops & OP_MASK_TYPE))
|
||||||
|
@ -224,26 +224,26 @@ merge_ops( int cops, int *mops, int *sops )
|
||||||
else if (!(cops & XOP_MASK_DIR))
|
else if (!(cops & XOP_MASK_DIR))
|
||||||
cops |= XOP_PULL|XOP_PUSH;
|
cops |= XOP_PULL|XOP_PUSH;
|
||||||
if (cops & XOP_PULL)
|
if (cops & XOP_PULL)
|
||||||
*sops |= cops & OP_MASK_TYPE;
|
ops[S] |= cops & OP_MASK_TYPE;
|
||||||
if (cops & XOP_PUSH)
|
if (cops & XOP_PUSH)
|
||||||
*mops |= cops & OP_MASK_TYPE;
|
ops[M] |= cops & OP_MASK_TYPE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (*mops & XOP_HAVE_EXPUNGE) {
|
if (ops[M] & XOP_HAVE_EXPUNGE) {
|
||||||
if (aops & cops & OP_EXPUNGE) {
|
if (aops & cops & OP_EXPUNGE) {
|
||||||
fprintf( stderr, "Conflicting Expunge args specified.\n" );
|
fprintf( stderr, "Conflicting Expunge args specified.\n" );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
*mops |= cops & OP_EXPUNGE;
|
ops[M] |= cops & OP_EXPUNGE;
|
||||||
*sops |= cops & OP_EXPUNGE;
|
ops[S] |= cops & OP_EXPUNGE;
|
||||||
}
|
}
|
||||||
if (*mops & XOP_HAVE_CREATE) {
|
if (ops[M] & XOP_HAVE_CREATE) {
|
||||||
if (aops & cops & OP_CREATE) {
|
if (aops & cops & OP_CREATE) {
|
||||||
fprintf( stderr, "Conflicting Create args specified.\n" );
|
fprintf( stderr, "Conflicting Create args specified.\n" );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
*mops |= cops & OP_CREATE;
|
ops[M] |= cops & OP_CREATE;
|
||||||
*sops |= cops & OP_CREATE;
|
ops[S] |= cops & OP_CREATE;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -252,12 +252,12 @@ int
|
||||||
load_config( const char *where, int pseudo )
|
load_config( const char *where, int pseudo )
|
||||||
{
|
{
|
||||||
conffile_t cfile;
|
conffile_t cfile;
|
||||||
store_conf_t *store, **storeapp = &stores, **sptarg;
|
store_conf_t *store, **storeapp = &stores;
|
||||||
channel_conf_t *channel, **channelapp = &channels;
|
channel_conf_t *channel, **channelapp = &channels;
|
||||||
group_conf_t *group, **groupapp = &groups;
|
group_conf_t *group, **groupapp = &groups;
|
||||||
string_list_t *chanlist, **chanlistapp;
|
string_list_t *chanlist, **chanlistapp;
|
||||||
char *arg, *p, **ntarg;
|
char *arg, *p;
|
||||||
int err, len, cops, gcops, max_size;
|
int err, len, cops, gcops, max_size, ms;
|
||||||
char path[_POSIX_PATH_MAX];
|
char path[_POSIX_PATH_MAX];
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
|
|
||||||
|
@ -315,12 +315,10 @@ load_config( const char *where, int pseudo )
|
||||||
while ((arg = next_arg( &cfile.rest )));
|
while ((arg = next_arg( &cfile.rest )));
|
||||||
}
|
}
|
||||||
else if (!strcasecmp( "Master", cfile.cmd )) {
|
else if (!strcasecmp( "Master", cfile.cmd )) {
|
||||||
sptarg = &channel->master;
|
ms = M;
|
||||||
ntarg = &channel->master_name;
|
|
||||||
goto linkst;
|
goto linkst;
|
||||||
} else if (!strcasecmp( "Slave", cfile.cmd )) {
|
} else if (!strcasecmp( "Slave", cfile.cmd )) {
|
||||||
sptarg = &channel->slave;
|
ms = S;
|
||||||
ntarg = &channel->slave_name;
|
|
||||||
linkst:
|
linkst:
|
||||||
if (*cfile.val != ':' || !(p = strchr( cfile.val + 1, ':' ))) {
|
if (*cfile.val != ':' || !(p = strchr( cfile.val + 1, ':' ))) {
|
||||||
fprintf( stderr, "%s:%d: malformed mailbox spec\n",
|
fprintf( stderr, "%s:%d: malformed mailbox spec\n",
|
||||||
|
@ -331,7 +329,7 @@ load_config( const char *where, int pseudo )
|
||||||
*p = 0;
|
*p = 0;
|
||||||
for (store = stores; store; store = store->next)
|
for (store = stores; store; store = store->next)
|
||||||
if (!strcmp( store->name, cfile.val + 1 )) {
|
if (!strcmp( store->name, cfile.val + 1 )) {
|
||||||
*sptarg = store;
|
channel->stores[ms] = store;
|
||||||
goto stpcom;
|
goto stpcom;
|
||||||
}
|
}
|
||||||
fprintf( stderr, "%s:%d: unknown store '%s'\n",
|
fprintf( stderr, "%s:%d: unknown store '%s'\n",
|
||||||
|
@ -340,24 +338,24 @@ load_config( const char *where, int pseudo )
|
||||||
continue;
|
continue;
|
||||||
stpcom:
|
stpcom:
|
||||||
if (*++p)
|
if (*++p)
|
||||||
*ntarg = nfstrdup( p );
|
channel->boxes[ms] = nfstrdup( p );
|
||||||
} else if (!getopt_helper( &cfile, &cops, &channel->mops, &channel->sops, &channel->sync_state )) {
|
} else if (!getopt_helper( &cfile, &cops, channel->ops, &channel->sync_state )) {
|
||||||
fprintf( stderr, "%s:%d: unknown keyword '%s'\n",
|
fprintf( stderr, "%s:%d: unknown keyword '%s'\n",
|
||||||
cfile.file, cfile.line, cfile.cmd );
|
cfile.file, cfile.line, cfile.cmd );
|
||||||
err = 1;
|
err = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!channel->master) {
|
if (!channel->stores[M]) {
|
||||||
fprintf( stderr, "channel '%s' refers to no master store\n", channel->name );
|
fprintf( stderr, "channel '%s' refers to no master store\n", channel->name );
|
||||||
err = 1;
|
err = 1;
|
||||||
} else if (!channel->slave) {
|
} else if (!channel->stores[S]) {
|
||||||
fprintf( stderr, "channel '%s' refers to no slave store\n", channel->name );
|
fprintf( stderr, "channel '%s' refers to no slave store\n", channel->name );
|
||||||
err = 1;
|
err = 1;
|
||||||
} else if (merge_ops( cops, &channel->mops, &channel->sops ))
|
} else if (merge_ops( cops, channel->ops ))
|
||||||
err = 1;
|
err = 1;
|
||||||
else {
|
else {
|
||||||
if (max_size >= 0)
|
if (max_size >= 0)
|
||||||
channel->master->max_size = channel->slave->max_size = max_size;
|
channel->stores[M]->max_size = channel->stores[S]->max_size = max_size;
|
||||||
*channelapp = channel;
|
*channelapp = channel;
|
||||||
channelapp = &channel->next;
|
channelapp = &channel->next;
|
||||||
}
|
}
|
||||||
|
@ -400,7 +398,7 @@ load_config( const char *where, int pseudo )
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (!getopt_helper( &cfile, &gcops, &global_mops, &global_sops, &global_sync_state ))
|
else if (!getopt_helper( &cfile, &gcops, global_ops, &global_sync_state ))
|
||||||
{
|
{
|
||||||
fprintf( stderr, "%s:%d: unknown section keyword '%s'\n",
|
fprintf( stderr, "%s:%d: unknown section keyword '%s'\n",
|
||||||
cfile.file, cfile.line, cfile.cmd );
|
cfile.file, cfile.line, cfile.cmd );
|
||||||
|
@ -412,7 +410,7 @@ load_config( const char *where, int pseudo )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose (cfile.fp);
|
fclose (cfile.fp);
|
||||||
err |= merge_ops( gcops, &global_mops, &global_sops );
|
err |= merge_ops( gcops, global_ops );
|
||||||
if (!global_sync_state)
|
if (!global_sync_state)
|
||||||
global_sync_state = expand_strdup( "~/." EXE "/" );
|
global_sync_state = expand_strdup( "~/." EXE "/" );
|
||||||
if (!err && pseudo)
|
if (!err && pseudo)
|
||||||
|
|
32
src/isync.h
32
src/isync.h
|
@ -73,8 +73,8 @@ typedef struct store_conf {
|
||||||
char *name;
|
char *name;
|
||||||
driver_t *driver;
|
driver_t *driver;
|
||||||
const char *path; /* should this be here? its interpretation is driver-specific */
|
const char *path; /* should this be here? its interpretation is driver-specific */
|
||||||
char *map_inbox;
|
const char *map_inbox;
|
||||||
char *trash;
|
const char *trash;
|
||||||
unsigned max_size; /* off_t is overkill */
|
unsigned max_size; /* off_t is overkill */
|
||||||
unsigned trash_remote_new:1, trash_only_new:1;
|
unsigned trash_remote_new:1, trash_only_new:1;
|
||||||
} store_conf_t;
|
} store_conf_t;
|
||||||
|
@ -84,20 +84,23 @@ typedef struct string_list {
|
||||||
char string[1];
|
char string[1];
|
||||||
} string_list_t;
|
} string_list_t;
|
||||||
|
|
||||||
|
#define M 0 /* master */
|
||||||
|
#define S 1 /* slave */
|
||||||
|
|
||||||
typedef struct channel_conf {
|
typedef struct channel_conf {
|
||||||
struct channel_conf *next;
|
struct channel_conf *next;
|
||||||
char *name;
|
const char *name;
|
||||||
store_conf_t *master, *slave;
|
store_conf_t *stores[2];
|
||||||
char *master_name, *slave_name;
|
const char *boxes[2];
|
||||||
char *sync_state;
|
char *sync_state;
|
||||||
string_list_t *patterns;
|
string_list_t *patterns;
|
||||||
int mops, sops;
|
int ops[2];
|
||||||
unsigned max_messages; /* for slave only */
|
unsigned max_messages; /* for slave only */
|
||||||
} channel_conf_t;
|
} channel_conf_t;
|
||||||
|
|
||||||
typedef struct group_conf {
|
typedef struct group_conf {
|
||||||
struct group_conf *next;
|
struct group_conf *next;
|
||||||
char *name;
|
const char *name;
|
||||||
string_list_t *channels;
|
string_list_t *channels;
|
||||||
} group_conf_t;
|
} group_conf_t;
|
||||||
|
|
||||||
|
@ -222,27 +225,24 @@ unsigned char arc4_getbyte( void );
|
||||||
|
|
||||||
/* sync.c */
|
/* sync.c */
|
||||||
|
|
||||||
#define SYNC_OK 0
|
#define SYNC_OK 0
|
||||||
#define SYNC_FAIL 1
|
#define SYNC_FAIL 1
|
||||||
#define SYNC_MASTER_BAD 2
|
#define SYNC_BAD(ms) (2+(ms))
|
||||||
#define SYNC_SLAVE_BAD 3
|
|
||||||
|
|
||||||
int sync_boxes( store_t *, const char *,
|
int sync_boxes( store_t *ctx[], const char *names[], channel_conf_t * );
|
||||||
store_t *, const char *,
|
|
||||||
channel_conf_t * );
|
|
||||||
|
|
||||||
/* config.c */
|
/* config.c */
|
||||||
|
|
||||||
extern channel_conf_t *channels;
|
extern channel_conf_t *channels;
|
||||||
extern group_conf_t *groups;
|
extern group_conf_t *groups;
|
||||||
extern int global_mops, global_sops;
|
extern int global_ops[2];
|
||||||
extern char *global_sync_state;
|
extern char *global_sync_state;
|
||||||
|
|
||||||
int parse_bool( conffile_t *cfile );
|
int parse_bool( conffile_t *cfile );
|
||||||
int parse_int( conffile_t *cfile );
|
int parse_int( conffile_t *cfile );
|
||||||
int parse_size( conffile_t *cfile );
|
int parse_size( conffile_t *cfile );
|
||||||
int getcline( conffile_t *cfile );
|
int getcline( conffile_t *cfile );
|
||||||
int merge_ops( int cops, int *mops, int *sops );
|
int merge_ops( int cops, int ops[] );
|
||||||
int load_config( const char *filename, int pseudo );
|
int load_config( const char *filename, int pseudo );
|
||||||
void parse_generic_store( store_conf_t *store, conffile_t *cfg, int *err );
|
void parse_generic_store( store_conf_t *store, conffile_t *cfg, int *err );
|
||||||
|
|
||||||
|
|
277
src/main.c
277
src/main.c
|
@ -137,20 +137,20 @@ filter_boxes( string_list_t *boxes, string_list_t *patterns )
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
merge_actions( channel_conf_t *chan, int mops, int sops, int have, int mask, int def )
|
merge_actions( channel_conf_t *chan, int ops[], int have, int mask, int def )
|
||||||
{
|
{
|
||||||
if (mops & have) {
|
if (ops[M] & have) {
|
||||||
chan->mops &= ~mask;
|
chan->ops[M] &= ~mask;
|
||||||
chan->mops |= mops & mask;
|
chan->ops[M] |= ops[M] & mask;
|
||||||
chan->sops &= ~mask;
|
chan->ops[S] &= ~mask;
|
||||||
chan->sops |= sops & mask;
|
chan->ops[S] |= ops[S] & mask;
|
||||||
} else if (!(chan->mops & have)) {
|
} else if (!(chan->ops[M] & have)) {
|
||||||
if (global_mops & have) {
|
if (global_ops[M] & have) {
|
||||||
chan->mops |= global_mops & mask;
|
chan->ops[M] |= global_ops[M] & mask;
|
||||||
chan->sops |= global_sops & mask;
|
chan->ops[S] |= global_ops[S] & mask;
|
||||||
} else {
|
} else {
|
||||||
chan->mops |= def;
|
chan->ops[M] |= def;
|
||||||
chan->sops |= def;
|
chan->ops[S] |= def;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,14 +159,15 @@ int
|
||||||
main( int argc, char **argv )
|
main( int argc, char **argv )
|
||||||
{
|
{
|
||||||
channel_conf_t *chan;
|
channel_conf_t *chan;
|
||||||
store_conf_t *mconf, *sconf;
|
store_conf_t *conf[2];
|
||||||
group_conf_t *group;
|
group_conf_t *group;
|
||||||
driver_t *mdriver, *sdriver;
|
driver_t *driver[2];
|
||||||
store_t *mctx, *sctx;
|
store_t *ctx[2];
|
||||||
string_list_t *umboxes, *usboxes, *mboxes, *sboxes, *mbox, *sbox, **mboxp, **sboxp, *cboxes, *chanptr;
|
string_list_t *uboxes[2], *boxes[2], *mbox, *sbox, **mboxp, **sboxp, *cboxes, *chanptr;
|
||||||
char *config = 0, *channame, *boxlist, *opt, *ochar;
|
char *config = 0, *channame, *boxlist, *opt, *ochar;
|
||||||
int all = 0, list = 0, cops = 0, mops = 0, sops = 0, gumboxes, gusboxes;
|
const char *names[2];
|
||||||
int oind, ret, op, multiple, pseudo = 0;
|
int all = 0, list = 0, cops = 0, ops[2] = { 0, 0 }, guboxes[2];
|
||||||
|
int oind, ret, op, multiple, pseudo = 0, t;
|
||||||
|
|
||||||
gethostname( Hostname, sizeof(Hostname) );
|
gethostname( Hostname, sizeof(Hostname) );
|
||||||
if ((ochar = strchr( Hostname, '.' )))
|
if ((ochar = strchr( Hostname, '.' )))
|
||||||
|
@ -213,9 +214,9 @@ main( int argc, char **argv )
|
||||||
if (!Quiet)
|
if (!Quiet)
|
||||||
Quiet = 1;
|
Quiet = 1;
|
||||||
} else if (!strcmp( opt, "pull" ))
|
} else if (!strcmp( opt, "pull" ))
|
||||||
cops |= XOP_PULL, mops |= XOP_HAVE_TYPE;
|
cops |= XOP_PULL, ops[M] |= XOP_HAVE_TYPE;
|
||||||
else if (!strcmp( opt, "push" ))
|
else if (!strcmp( opt, "push" ))
|
||||||
cops |= XOP_PUSH, mops |= XOP_HAVE_TYPE;
|
cops |= XOP_PUSH, ops[M] |= XOP_HAVE_TYPE;
|
||||||
else if (!memcmp( opt, "create", 6 )) {
|
else if (!memcmp( opt, "create", 6 )) {
|
||||||
opt += 6;
|
opt += 6;
|
||||||
op = OP_CREATE|XOP_HAVE_CREATE;
|
op = OP_CREATE|XOP_HAVE_CREATE;
|
||||||
|
@ -223,24 +224,24 @@ main( int argc, char **argv )
|
||||||
if (!*opt)
|
if (!*opt)
|
||||||
cops |= op;
|
cops |= op;
|
||||||
else if (!strcmp( opt, "-master" ))
|
else if (!strcmp( opt, "-master" ))
|
||||||
mops |= op, ochar++;
|
ops[M] |= op, ochar++;
|
||||||
else if (!strcmp( opt, "-slave" ))
|
else if (!strcmp( opt, "-slave" ))
|
||||||
sops |= op, ochar++;
|
ops[S] |= op, ochar++;
|
||||||
else
|
else
|
||||||
goto badopt;
|
goto badopt;
|
||||||
mops |= op & (XOP_HAVE_CREATE|XOP_HAVE_EXPUNGE);
|
ops[M] |= op & (XOP_HAVE_CREATE|XOP_HAVE_EXPUNGE);
|
||||||
} else if (!memcmp( opt, "expunge", 7 )) {
|
} else if (!memcmp( opt, "expunge", 7 )) {
|
||||||
opt += 7;
|
opt += 7;
|
||||||
op = OP_EXPUNGE|XOP_HAVE_EXPUNGE;
|
op = OP_EXPUNGE|XOP_HAVE_EXPUNGE;
|
||||||
goto lcop;
|
goto lcop;
|
||||||
} else if (!strcmp( opt, "no-expunge" ))
|
} else if (!strcmp( opt, "no-expunge" ))
|
||||||
mops |= XOP_HAVE_EXPUNGE;
|
ops[M] |= XOP_HAVE_EXPUNGE;
|
||||||
else if (!strcmp( opt, "no-create" ))
|
else if (!strcmp( opt, "no-create" ))
|
||||||
mops |= XOP_HAVE_CREATE;
|
ops[M] |= XOP_HAVE_CREATE;
|
||||||
else if (!strcmp( opt, "full" ))
|
else if (!strcmp( opt, "full" ))
|
||||||
mops |= XOP_HAVE_TYPE|XOP_PULL|XOP_PUSH;
|
ops[M] |= XOP_HAVE_TYPE|XOP_PULL|XOP_PUSH;
|
||||||
else if (!strcmp( opt, "noop" ))
|
else if (!strcmp( opt, "noop" ))
|
||||||
mops |= XOP_HAVE_TYPE;
|
ops[M] |= XOP_HAVE_TYPE;
|
||||||
else if (!memcmp( opt, "pull", 4 )) {
|
else if (!memcmp( opt, "pull", 4 )) {
|
||||||
op = XOP_PULL;
|
op = XOP_PULL;
|
||||||
lcac:
|
lcac:
|
||||||
|
@ -272,11 +273,11 @@ main( int argc, char **argv )
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
switch (op & XOP_MASK_DIR) {
|
switch (op & XOP_MASK_DIR) {
|
||||||
case XOP_PULL: sops |= op & OP_MASK_TYPE; break;
|
case XOP_PULL: ops[S] |= op & OP_MASK_TYPE; break;
|
||||||
case XOP_PUSH: mops |= op & OP_MASK_TYPE; break;
|
case XOP_PUSH: ops[M] |= op & OP_MASK_TYPE; break;
|
||||||
default: cops |= op; break;
|
default: cops |= op; break;
|
||||||
}
|
}
|
||||||
mops |= XOP_HAVE_TYPE;
|
ops[M] |= XOP_HAVE_TYPE;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -308,14 +309,14 @@ main( int argc, char **argv )
|
||||||
op = OP_CREATE|XOP_HAVE_CREATE;
|
op = OP_CREATE|XOP_HAVE_CREATE;
|
||||||
cop:
|
cop:
|
||||||
if (*ochar == 'm')
|
if (*ochar == 'm')
|
||||||
mops |= op, ochar++;
|
ops[M] |= op, ochar++;
|
||||||
else if (*ochar == 's')
|
else if (*ochar == 's')
|
||||||
sops |= op, ochar++;
|
ops[S] |= op, ochar++;
|
||||||
else if (*ochar == '-')
|
else if (*ochar == '-')
|
||||||
ochar++;
|
ochar++;
|
||||||
else
|
else
|
||||||
cops |= op;
|
cops |= op;
|
||||||
mops |= op & (XOP_HAVE_CREATE|XOP_HAVE_EXPUNGE);
|
ops[M] |= op & (XOP_HAVE_CREATE|XOP_HAVE_EXPUNGE);
|
||||||
break;
|
break;
|
||||||
case 'X':
|
case 'X':
|
||||||
op = OP_EXPUNGE|XOP_HAVE_EXPUNGE;
|
op = OP_EXPUNGE|XOP_HAVE_EXPUNGE;
|
||||||
|
@ -323,7 +324,7 @@ main( int argc, char **argv )
|
||||||
case 'F':
|
case 'F':
|
||||||
cops |= XOP_PULL|XOP_PUSH;
|
cops |= XOP_PULL|XOP_PUSH;
|
||||||
case '0':
|
case '0':
|
||||||
mops |= XOP_HAVE_TYPE;
|
ops[M] |= XOP_HAVE_TYPE;
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
case 'd':
|
case 'd':
|
||||||
|
@ -346,13 +347,13 @@ main( int argc, char **argv )
|
||||||
}
|
}
|
||||||
if (op & OP_MASK_TYPE)
|
if (op & OP_MASK_TYPE)
|
||||||
switch (op & XOP_MASK_DIR) {
|
switch (op & XOP_MASK_DIR) {
|
||||||
case XOP_PULL: sops |= op & OP_MASK_TYPE; break;
|
case XOP_PULL: ops[S] |= op & OP_MASK_TYPE; break;
|
||||||
case XOP_PUSH: mops |= op & OP_MASK_TYPE; break;
|
case XOP_PUSH: ops[M] |= op & OP_MASK_TYPE; break;
|
||||||
default: cops |= op; break;
|
default: cops |= op; break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
cops |= op;
|
cops |= op;
|
||||||
mops |= XOP_HAVE_TYPE;
|
ops[M] |= XOP_HAVE_TYPE;
|
||||||
break;
|
break;
|
||||||
case 'L':
|
case 'L':
|
||||||
op = XOP_PULL;
|
op = XOP_PULL;
|
||||||
|
@ -383,7 +384,7 @@ main( int argc, char **argv )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (merge_ops( cops, &mops, &sops ))
|
if (merge_ops( cops, ops ))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (load_config( config, pseudo ))
|
if (load_config( config, pseudo ))
|
||||||
|
@ -401,11 +402,11 @@ main( int argc, char **argv )
|
||||||
ret = 0;
|
ret = 0;
|
||||||
chan = channels;
|
chan = channels;
|
||||||
chanptr = 0;
|
chanptr = 0;
|
||||||
mctx = sctx = 0;
|
ctx[M] = ctx[S] = 0;
|
||||||
mconf = sconf = 0; /* make-gcc-happy */
|
conf[M] = conf[S] = 0; /* make-gcc-happy */
|
||||||
mdriver = sdriver = 0; /* make-gcc-happy */
|
driver[M] = driver[S] = 0; /* make-gcc-happy */
|
||||||
gumboxes = gusboxes = 0;
|
guboxes[M] = guboxes[S] = 0;
|
||||||
umboxes = usboxes = 0;
|
uboxes[M] = uboxes[S] = 0;
|
||||||
if (all)
|
if (all)
|
||||||
multiple = channels->next != 0;
|
multiple = channels->next != 0;
|
||||||
else if (argv[oind + 1])
|
else if (argv[oind + 1])
|
||||||
|
@ -443,48 +444,31 @@ main( int argc, char **argv )
|
||||||
goto gotnone;
|
goto gotnone;
|
||||||
gotchan: ;
|
gotchan: ;
|
||||||
}
|
}
|
||||||
merge_actions( chan, mops, sops, XOP_HAVE_TYPE, OP_MASK_TYPE, OP_MASK_TYPE );
|
merge_actions( chan, ops, XOP_HAVE_TYPE, OP_MASK_TYPE, OP_MASK_TYPE );
|
||||||
merge_actions( chan, mops, sops, XOP_HAVE_CREATE, OP_CREATE, 0 );
|
merge_actions( chan, ops, XOP_HAVE_CREATE, OP_CREATE, 0 );
|
||||||
merge_actions( chan, mops, sops, XOP_HAVE_EXPUNGE, OP_EXPUNGE, 0 );
|
merge_actions( chan, ops, XOP_HAVE_EXPUNGE, OP_EXPUNGE, 0 );
|
||||||
|
|
||||||
mboxes = sboxes = cboxes = 0;
|
boxes[M] = boxes[S] = cboxes = 0;
|
||||||
/* possible todo: handle master <-> slave swaps */
|
/* possible todo: handle master <-> slave swaps */
|
||||||
if (mctx) {
|
for (t = 0; t < 2; t++) {
|
||||||
if (mconf == chan->master)
|
if (ctx[t]) {
|
||||||
goto gotmctx;
|
if (conf[t] == chan->stores[t])
|
||||||
free_string_list( umboxes );
|
continue;
|
||||||
umboxes = 0;
|
free_string_list( uboxes[t] );
|
||||||
gumboxes = 0;
|
uboxes[t] = 0;
|
||||||
if (mconf->driver != chan->master->driver) {
|
guboxes[t] = 0;
|
||||||
mdriver->close_store( mctx );
|
if (conf[t]->driver != chan->stores[t]->driver) {
|
||||||
mctx = 0;
|
driver[t]->close_store( ctx[t] );
|
||||||
|
ctx[t] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
conf[t] = chan->stores[t];
|
||||||
|
driver[t] = conf[t]->driver;
|
||||||
|
if (!(ctx[t] = driver[t]->open_store( chan->stores[t], ctx[t] ))) {
|
||||||
|
ret = 1;
|
||||||
|
goto next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mconf = chan->master;
|
|
||||||
mdriver = mconf->driver;
|
|
||||||
if (!(mctx = mdriver->open_store( chan->master, mctx ))) {
|
|
||||||
ret = 1;
|
|
||||||
goto next;
|
|
||||||
}
|
|
||||||
gotmctx:
|
|
||||||
if (sctx) {
|
|
||||||
if (sconf == chan->slave)
|
|
||||||
goto gotsctx;
|
|
||||||
free_string_list( usboxes );
|
|
||||||
usboxes = 0;
|
|
||||||
gusboxes = 0;
|
|
||||||
if (sconf->driver != chan->slave->driver) {
|
|
||||||
sdriver->close_store( sctx );
|
|
||||||
sctx = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sconf = chan->slave;
|
|
||||||
sdriver = sconf->driver;
|
|
||||||
if (!(sctx = sdriver->open_store( chan->slave, sctx ))) {
|
|
||||||
ret = 1;
|
|
||||||
goto next;
|
|
||||||
}
|
|
||||||
gotsctx:
|
|
||||||
info( "Channel %s\n", chan->name );
|
info( "Channel %s\n", chan->name );
|
||||||
if (list && multiple)
|
if (list && multiple)
|
||||||
printf( "%s:\n", chan->name );
|
printf( "%s:\n", chan->name );
|
||||||
|
@ -492,49 +476,36 @@ main( int argc, char **argv )
|
||||||
for (boxlist = strtok( boxlist, ",\n" ); boxlist; boxlist = strtok( 0, ",\n" ))
|
for (boxlist = strtok( boxlist, ",\n" ); boxlist; boxlist = strtok( 0, ",\n" ))
|
||||||
if (list)
|
if (list)
|
||||||
puts( boxlist );
|
puts( boxlist );
|
||||||
else
|
else {
|
||||||
switch (sync_boxes( mctx, boxlist, sctx, boxlist, chan )) {
|
names[M] = names[S] = boxlist;
|
||||||
case SYNC_MASTER_BAD: goto screwm;
|
switch (sync_boxes( ctx, names, chan )) {
|
||||||
case SYNC_SLAVE_BAD: goto screws;
|
case SYNC_BAD(M): t = M; goto screwt;
|
||||||
|
case SYNC_BAD(S): t = S; goto screwt;
|
||||||
case SYNC_FAIL: ret = 1;
|
case SYNC_FAIL: ret = 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if (chan->patterns) {
|
} else if (chan->patterns) {
|
||||||
if (!gumboxes) {
|
for (t = 0; t < 2; t++) {
|
||||||
if (mdriver->list( mctx, &umboxes ) != DRV_OK) {
|
if (!guboxes[t]) {
|
||||||
screwm:
|
if (driver[t]->list( ctx[t], &uboxes[t] ) != DRV_OK) {
|
||||||
mdriver->close_store( mctx );
|
screwt:
|
||||||
free_string_list( umboxes );
|
driver[t]->close_store( ctx[t] );
|
||||||
umboxes = 0;
|
free_string_list( uboxes[t] );
|
||||||
gumboxes = 0;
|
uboxes[t] = 0;
|
||||||
mctx = 0;
|
guboxes[t] = 0;
|
||||||
ret = 1;
|
ctx[t] = 0;
|
||||||
goto next;
|
ret = 1;
|
||||||
} else {
|
goto next;
|
||||||
gumboxes = 1;
|
} else {
|
||||||
if (mctx->conf->map_inbox)
|
guboxes[t] = 1;
|
||||||
add_string_list( &umboxes, mctx->conf->map_inbox );
|
if (ctx[t]->conf->map_inbox)
|
||||||
|
add_string_list( &uboxes[t], ctx[t]->conf->map_inbox );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
boxes[t] = filter_boxes( uboxes[t], chan->patterns );
|
||||||
}
|
}
|
||||||
if (!gusboxes) {
|
for (mboxp = &boxes[M]; (mbox = *mboxp); ) {
|
||||||
if (sdriver->list( sctx, &usboxes ) != DRV_OK) {
|
for (sboxp = &boxes[S]; (sbox = *sboxp); sboxp = &sbox->next)
|
||||||
screws:
|
|
||||||
sdriver->close_store( sctx );
|
|
||||||
free_string_list( usboxes );
|
|
||||||
usboxes = 0;
|
|
||||||
gusboxes = 0;
|
|
||||||
sctx = 0;
|
|
||||||
ret = 1;
|
|
||||||
goto next;
|
|
||||||
} else {
|
|
||||||
gusboxes = 1;
|
|
||||||
if (sctx->conf->map_inbox)
|
|
||||||
add_string_list( &usboxes, sctx->conf->map_inbox );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mboxes = filter_boxes( umboxes, chan->patterns );
|
|
||||||
sboxes = filter_boxes( usboxes, chan->patterns );
|
|
||||||
for (mboxp = &mboxes; (mbox = *mboxp); ) {
|
|
||||||
for (sboxp = &sboxes; (sbox = *sboxp); sboxp = &sbox->next)
|
|
||||||
if (!strcmp( sbox->string, mbox->string )) {
|
if (!strcmp( sbox->string, mbox->string )) {
|
||||||
*sboxp = sbox->next;
|
*sboxp = sbox->next;
|
||||||
free( sbox );
|
free( sbox );
|
||||||
|
@ -549,48 +520,42 @@ main( int argc, char **argv )
|
||||||
for (mbox = cboxes; mbox; mbox = mbox->next)
|
for (mbox = cboxes; mbox; mbox = mbox->next)
|
||||||
if (list)
|
if (list)
|
||||||
puts( mbox->string );
|
puts( mbox->string );
|
||||||
else
|
else {
|
||||||
switch (sync_boxes( mctx, mbox->string, sctx, mbox->string, chan )) {
|
names[M] = names[S] = mbox->string;
|
||||||
case SYNC_MASTER_BAD: goto screwm;
|
switch (sync_boxes( ctx, names, chan )) {
|
||||||
case SYNC_SLAVE_BAD: goto screws;
|
case SYNC_BAD(M): t = M; goto screwt;
|
||||||
|
case SYNC_BAD(S): t = S; goto screwt;
|
||||||
case SYNC_FAIL: ret = 1;
|
case SYNC_FAIL: ret = 1;
|
||||||
}
|
}
|
||||||
if ((chan->sops & OP_MASK_TYPE) && (chan->sops & OP_CREATE)) {
|
}
|
||||||
for (mbox = mboxes; mbox; mbox = mbox->next)
|
for (t = 0; t < 2; t++)
|
||||||
if (list)
|
if ((chan->ops[t] & OP_MASK_TYPE) && (chan->ops[t] & OP_CREATE)) {
|
||||||
puts( mbox->string );
|
for (mbox = boxes[t]; mbox; mbox = mbox->next)
|
||||||
else
|
if (list)
|
||||||
switch (sync_boxes( mctx, mbox->string, sctx, mbox->string, chan )) {
|
puts( mbox->string );
|
||||||
case SYNC_MASTER_BAD: goto screwm;
|
else {
|
||||||
case SYNC_SLAVE_BAD: goto screws;
|
names[M] = names[S] = mbox->string;
|
||||||
case SYNC_FAIL: ret = 1;
|
switch (sync_boxes( ctx, names, chan )) {
|
||||||
|
case SYNC_BAD(M): t = M; goto screwt;
|
||||||
|
case SYNC_BAD(S): t = S; goto screwt;
|
||||||
|
case SYNC_FAIL: ret = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((chan->mops & OP_MASK_TYPE) && (chan->mops & OP_CREATE)) {
|
|
||||||
for (mbox = sboxes; mbox; mbox = mbox->next)
|
|
||||||
if (list)
|
|
||||||
puts( mbox->string );
|
|
||||||
else
|
|
||||||
switch (sync_boxes( mctx, mbox->string, sctx, mbox->string, chan )) {
|
|
||||||
case SYNC_MASTER_BAD: goto screwm;
|
|
||||||
case SYNC_SLAVE_BAD: goto screws;
|
|
||||||
case SYNC_FAIL: ret = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
if (list)
|
if (list)
|
||||||
printf( "%s <=> %s\n", chan->master_name, chan->slave_name );
|
printf( "%s <=> %s\n", chan->boxes[M], chan->boxes[S] );
|
||||||
else
|
else
|
||||||
switch (sync_boxes( mctx, chan->master_name, sctx, chan->slave_name, chan )) {
|
switch (sync_boxes( ctx, chan->boxes, chan )) {
|
||||||
case SYNC_MASTER_BAD: goto screwm;
|
case SYNC_BAD(M): t = M; goto screwt;
|
||||||
case SYNC_SLAVE_BAD: goto screws;
|
case SYNC_BAD(S): t = S; goto screwt;
|
||||||
case SYNC_FAIL: ret = 1;
|
case SYNC_FAIL: ret = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
next:
|
next:
|
||||||
free_string_list( cboxes );
|
free_string_list( cboxes );
|
||||||
free_string_list( mboxes );
|
free_string_list( boxes[M] );
|
||||||
free_string_list( sboxes );
|
free_string_list( boxes[S] );
|
||||||
if (all) {
|
if (all) {
|
||||||
if (!(chan = chan->next))
|
if (!(chan = chan->next))
|
||||||
break;
|
break;
|
||||||
|
@ -602,12 +567,12 @@ main( int argc, char **argv )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free_string_list( usboxes );
|
free_string_list( uboxes[S] );
|
||||||
if (sctx)
|
if (ctx[S])
|
||||||
sdriver->close_store( sctx );
|
driver[S]->close_store( ctx[S] );
|
||||||
free_string_list( umboxes );
|
free_string_list( uboxes[M] );
|
||||||
if (mctx)
|
if (ctx[M])
|
||||||
mdriver->close_store( mctx );
|
driver[M]->close_store( ctx[M] );
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
865
src/sync.c
865
src/sync.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user