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; } }
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; } }
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 ); }
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; }
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 )); } }
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; }