- 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
					
				
					 4 changed files with 583 additions and 689 deletions
				
			
		
							
								
								
									
										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…
	
	Add table
		
		Reference in a new issue