예제 #1
0
파일: config.c 프로젝트: seanvk/isync
void
parse_generic_store( store_conf_t *store, conffile_t *cfg )
{
	if (!strcasecmp( "Trash", cfg->cmd ))
		store->trash = nfstrdup( cfg->val );
	else if (!strcasecmp( "TrashRemoteNew", cfg->cmd ))
		store->trash_remote_new = parse_bool( cfg );
	else if (!strcasecmp( "TrashNewOnly", cfg->cmd ))
		store->trash_only_new = parse_bool( cfg );
	else if (!strcasecmp( "MaxSize", cfg->cmd ))
		store->max_size = parse_size( cfg );
	else if (!strcasecmp( "MapInbox", cfg->cmd ))
		store->map_inbox = nfstrdup( cfg->val );
	else if (!strcasecmp( "Flatten", cfg->cmd )) {
		const char *p;
		for (p = cfg->val; *p; p++)
			if (*p == '/') {
				error( "%s:%d: flattened hierarchy delimiter cannot contain the canonical delimiter '/'\n", cfg->file, cfg->line );
				cfg->err = 1;
				return;
			}
		store->flat_delim = nfstrdup( cfg->val );
	} else {
		error( "%s:%d: unknown keyword '%s'\n", cfg->file, cfg->line, cfg->cmd );
		cfg->err = 1;
	}
}
예제 #2
0
파일: config.c 프로젝트: mback2k/isync
void
parse_generic_store( store_conf_t *store, conffile_t *cfg )
{
	if (!strcasecmp( "Trash", cfg->cmd ))
		store->trash = nfstrdup( cfg->val );
	else if (!strcasecmp( "TrashRemoteNew", cfg->cmd ))
		store->trash_remote_new = parse_bool( cfg );
	else if (!strcasecmp( "TrashNewOnly", cfg->cmd ))
		store->trash_only_new = parse_bool( cfg );
	else if (!strcasecmp( "MaxSize", cfg->cmd ))
		store->max_size = parse_size( cfg );
	else if (!strcasecmp( "MapInbox", cfg->cmd ))
		store->map_inbox = nfstrdup( cfg->val );
	else if (!strcasecmp( "Flatten", cfg->cmd )) {
		int sl = strlen( cfg->val );
		if (sl != 1) {
			error( "%s:%d: malformed flattened hierarchy delimiter\n", cfg->file, cfg->line );
			cfg->err = 1;
		} else if (cfg->val[0] == '/') {
			error( "%s:%d: flattened hierarchy delimiter cannot be the canonical delimiter '/'\n", cfg->file, cfg->line );
			cfg->err = 1;
		} else {
			store->flat_delim = cfg->val[0];
		}
	} else {
		error( "%s:%d: unknown keyword '%s'\n", cfg->file, cfg->line, cfg->cmd );
		cfg->err = 1;
	}
}
예제 #3
0
파일: util.c 프로젝트: xaiki/isync
char *
expand_strdup( const char *s )
{
	struct passwd *pw;
	const char *p, *q;
	char *r;

	if (*s == '~') {
		s++;
		if (!*s) {
			p = 0;
			q = Home;
		} else if (*s == '/') {
			p = s;
			q = Home;
		} else {
			if ((p = strchr( s, '/' ))) {
				r = my_strndup( s, (int)(p - s) );
				pw = getpwnam( r );
				free( r );
			} else
				pw = getpwnam( s );
			if (!pw)
				return 0;
			q = pw->pw_dir;
		}
		nfasprintf( &r, "%s%s", q, p ? p : "" );
		return r;
	} else
		return nfstrdup( s );
}
예제 #4
0
파일: sync.c 프로젝트: leifwalsh/isync
static char *
clean_strdup( const char *s )
{
	char *cs;
	int i;

	cs = nfstrdup( s );
	for (i = 0; cs[i]; i++)
		if (cs[i] == '/')
			cs[i] = '!';
	return cs;
}
예제 #5
0
파일: sync.c 프로젝트: leifwalsh/isync
void
sync_boxes( store_t *ctx[], const char *names[], channel_conf_t *chan,
            void (*cb)( int sts, void *aux ), void *aux )
{
	sync_vars_t *svars;
	int t;

	svars = nfcalloc( sizeof(*svars) );
	svars->t[1] = 1;
	svars->ref_count = 1;
	svars->cb = cb;
	svars->aux = aux;
	svars->ctx[0] = ctx[0];
	svars->ctx[1] = ctx[1];
	svars->chan = chan;
	svars->uidval[0] = svars->uidval[1] = -1;
	svars->srecadd = &svars->srecs;

	for (t = 0; t < 2; t++) {
		ctx[t]->orig_name =
			(!names[t] || (ctx[t]->conf->map_inbox && !strcmp( ctx[t]->conf->map_inbox, names[t] ))) ?
				"INBOX" : names[t];
		ctx[t]->name = nfstrdup( ctx[t]->orig_name );
		if (ctx[t]->conf->flat_delim && map_name( ctx[t]->name, '/', ctx[t]->conf->flat_delim ) < 0) {
			error( "Error: canonical mailbox name '%s' contains flattened hierarchy delimiter\n", ctx[t]->name );
			svars->ret = SYNC_FAIL;
			sync_bail3( svars );
			return;
		}
		ctx[t]->uidvalidity = -1;
		set_bad_callback( ctx[t], store_bad, AUX );
		svars->drv[t] = ctx[t]->conf->driver;
	}
	/* Both boxes must be fully set up at this point, so that error exit paths
	 * don't run into uninitialized variables. */
	for (t = 0; t < 2; t++) {
		info( "Selecting %s %s...\n", str_ms[t], ctx[t]->orig_name );
		DRIVER_CALL(select( ctx[t], (chan->ops[t] & OP_CREATE) != 0, box_selected, AUX ));
	}
}
예제 #6
0
파일: config.c 프로젝트: sineer/isync
int
load_config( const char *where, int pseudo )
{
	conffile_t cfile;
	store_conf_t *store, **storeapp = &stores;
	channel_conf_t *channel, **channelapp = &channels;
	group_conf_t *group, **groupapp = &groups;
	string_list_t *chanlist, **chanlistapp;
	char *arg, *p;
	int len, cops, gcops, max_size, ms, i;
	char path[_POSIX_PATH_MAX];
	char buf[1024];

	if (!where) {
		assert( !pseudo );
		nfsnprintf( path, sizeof(path), "%s/." EXE "rc", Home );
		cfile.file = path;
	} else
		cfile.file = where;

	if (!pseudo)
		info( "Reading configuration file %s\n", cfile.file );

	if (!(cfile.fp = fopen( cfile.file, "r" ))) {
		sys_error( "Cannot open config file '%s'", cfile.file );
		return 1;
	}
	buf[sizeof(buf) - 1] = 0;
	cfile.buf = buf;
	cfile.bufl = sizeof(buf) - 1;
	cfile.line = 0;
	cfile.err = 0;
	cfile.rest = 0;

	gcops = 0;
	global_conf.expire_unread = -1;
  reloop:
	while (getcline( &cfile )) {
		if (!cfile.cmd)
			continue;
		for (i = 0; i < N_DRIVERS; i++)
			if (drivers[i]->parse_store( &cfile, &store )) {
				if (store) {
					if (!store->max_size)
						store->max_size = INT_MAX;
					*storeapp = store;
					storeapp = &store->next;
					*storeapp = 0;
				}
				goto reloop;
			}
		if (!strcasecmp( "Channel", cfile.cmd ))
		{
			channel = nfcalloc( sizeof(*channel) );
			channel->name = nfstrdup( cfile.val );
			channel->max_messages = global_conf.max_messages;
			channel->expire_unread = global_conf.expire_unread;
			channel->use_internal_date = global_conf.use_internal_date;
			cops = 0;
			max_size = -1;
			while (getcline( &cfile ) && cfile.cmd) {
				if (!strcasecmp( "MaxSize", cfile.cmd ))
					max_size = parse_size( &cfile );
				else if (!strcasecmp( "Pattern", cfile.cmd ) ||
				         !strcasecmp( "Patterns", cfile.cmd ))
				{
					arg = cfile.val;
					do
						add_string_list( &channel->patterns, arg );
					while ((arg = get_arg( &cfile, ARG_OPTIONAL, 0 )));
				}
				else if (!strcasecmp( "Master", cfile.cmd )) {
					ms = M;
					goto linkst;
				} else if (!strcasecmp( "Slave", cfile.cmd )) {
					ms = S;
				  linkst:
					if (*cfile.val != ':' || !(p = strchr( cfile.val + 1, ':' ))) {
						error( "%s:%d: malformed mailbox spec\n",
						       cfile.file, cfile.line );
						cfile.err = 1;
						continue;
					}
					*p = 0;
					for (store = stores; store; store = store->next)
						if (!strcmp( store->name, cfile.val + 1 )) {
							channel->stores[ms] = store;
							goto stpcom;
						}
					error( "%s:%d: unknown store '%s'\n",
					       cfile.file, cfile.line, cfile.val + 1 );
					cfile.err = 1;
					continue;
				  stpcom:
					if (*++p)
						channel->boxes[ms] = nfstrdup( p );
				} else if (!getopt_helper( &cfile, &cops, channel )) {
					error( "%s:%d: unknown keyword '%s'\n", cfile.file, cfile.line, cfile.cmd );
					cfile.err = 1;
				}
			}
			if (!channel->stores[M]) {
				error( "channel '%s' refers to no master store\n", channel->name );
				cfile.err = 1;
			} else if (!channel->stores[S]) {
				error( "channel '%s' refers to no slave store\n", channel->name );
				cfile.err = 1;
			} else if (merge_ops( cops, channel->ops ))
				cfile.err = 1;
			else {
				if (max_size >= 0) {
					if (!max_size)
						max_size = INT_MAX;
					channel->stores[M]->max_size = channel->stores[S]->max_size = max_size;
				}
				*channelapp = channel;
				channelapp = &channel->next;
			}
		}
		else if (!strcasecmp( "Group", cfile.cmd ))
		{
			group = nfmalloc( sizeof(*group) );
			group->name = nfstrdup( cfile.val );
			*groupapp = group;
			groupapp = &group->next;
			*groupapp = 0;
			chanlistapp = &group->channels;
			*chanlistapp = 0;
			while ((arg = get_arg( &cfile, ARG_OPTIONAL, 0 ))) {
			  addone:
				len = strlen( arg );
				chanlist = nfmalloc( sizeof(*chanlist) + len );
				memcpy( chanlist->string, arg, len + 1 );
				*chanlistapp = chanlist;
				chanlistapp = &chanlist->next;
				*chanlistapp = 0;
			}
			while (getcline( &cfile )) {
				if (!cfile.cmd)
					goto reloop;
				if (!strcasecmp( "Channel", cfile.cmd ) ||
				    !strcasecmp( "Channels", cfile.cmd ))
				{
					arg = cfile.val;
					goto addone;
				}
				else
				{
					error( "%s:%d: unknown keyword '%s'\n",
					       cfile.file, cfile.line, cfile.cmd );
					cfile.err = 1;
				}
			}
			break;
		}
		else if (!strcasecmp( "FSync", cfile.cmd ))
		{
			UseFSync = parse_bool( &cfile );
		}
		else if (!strcasecmp( "FieldDelimiter", cfile.cmd ))
		{
			if (strlen( cfile.val ) != 1) {
				error( "%s:%d: Field delimiter must be exactly one character long\n", cfile.file, cfile.line );
				cfile.err = 1;
			} else {
				FieldDelimiter = cfile.val[0];
				if (!ispunct( FieldDelimiter )) {
					error( "%s:%d: Field delimiter must be a punctuation character\n", cfile.file, cfile.line );
					cfile.err = 1;
				}
			}
		}
		else if (!strcasecmp( "BufferLimit", cfile.cmd ))
		{
			BufferLimit = parse_size( &cfile );
			if (BufferLimit <= 0) {
				error( "%s:%d: BufferLimit must be positive\n", cfile.file, cfile.line );
				cfile.err = 1;
			}
		}
		else if (!getopt_helper( &cfile, &gcops, &global_conf ))
		{
			error( "%s:%d: unknown section keyword '%s'\n",
			       cfile.file, cfile.line, cfile.cmd );
			cfile.err = 1;
			while (getcline( &cfile ))
				if (!cfile.cmd)
					goto reloop;
			break;
		}
	}
	fclose (cfile.fp);
	cfile.err |= merge_ops( gcops, global_conf.ops );
	if (!global_conf.sync_state)
		global_conf.sync_state = expand_strdup( "~/." EXE "/" );
	if (!cfile.err && pseudo)
		unlink( where );
	return cfile.err;
}