commit d12066fb46f960728396efe124aa7c4d592e2366
parent 84c06dab64f6e3821faa4569b21b44e3701579bc
Author: Christoph Lohmann <20h@r-36.net>
Date:   Fri,  7 Dec 2012 10:09:55 +0100
Adding the possibility of different configurations.
Diffstat:
47 files changed, 450 insertions(+), 238 deletions(-)
diff --git a/add.c b/add.c
@@ -26,8 +26,8 @@ char *argv0;
 void
 addusage(void)
 {
-	die("usage: %s [-qh] [-m folder] [-d datetime] [-f flags] file\n",
-			argv0);
+	die("usage: %s [-qh] [-c cfg] [-m folder] [-d datetime] [-f flags]"
+			" file\n", argv0);
 }
 
 int
@@ -35,7 +35,7 @@ addmain(int argc, char *argv[])
 {
 	config_t *cfg;
 	imap_t *imap;
-	char *user, *pass, *netspec, *folder, *flags, *tdate, *filec;
+	char *user, *pass, *netspec, *folder, *flags, *tdate, *filec, *cfgn;
 	int filelen, status;
 	llist_t *flagl;
 	inc_t *incs;
@@ -44,6 +44,7 @@ addmain(int argc, char *argv[])
 	flags = NULL;
 	tdate = NULL;
 	status = 0;
+	cfgn = NULL;
 
 	enum {
 		BEQUIET = 0x01,
@@ -52,6 +53,9 @@ addmain(int argc, char *argv[])
 	};
 
 	ARGBEGIN {
+	case 'c':
+		cfgn = EARGF(addusage());
+		break;
 	case 'd':
 		tdate = EARGF(addusage());
 		break;
@@ -64,7 +68,6 @@ addmain(int argc, char *argv[])
 	case 'q':
 		status |= BEQUIET;
 		break;
-	case 'h':
 	default:
 		addusage();
 	} ARGEND;
@@ -77,6 +80,7 @@ addmain(int argc, char *argv[])
 	} else {
 		filec = readfile(argv[0], &filelen);
 	}
+
 	if (filec == NULL || filelen < 1)
 		die("Given file or input was too short or invalid.\n");
 
@@ -87,7 +91,7 @@ addmain(int argc, char *argv[])
 			die("Flag parameter seems to be invalid.");
 	}
 
-	cfg = config_init();
+	cfg = config_init(cfgn);
 
 	user = config_checkgetstr(cfg, "imapuser");
 	pass = config_checkgetstr(cfg, "imappass");
@@ -110,7 +114,7 @@ addmain(int argc, char *argv[])
 	if (imap_append(imap, folder, flagl, tdate, filec))
 		imap_die(imap, "imap_append");
 
-	incs = inc_init();
+	incs = inc_init(cfgn);
 	inc_updatefolder(imap, folder, incs);
 	if (!(status & BEQUIET)) {
 		free(filec);
diff --git a/barebone.c b/barebone.c
@@ -20,7 +20,8 @@ char *argv0;
 void
 flagusage(void)
 {
-	fprintf(stderr, "usage: %s [-h] [[-s|-d] flag] [msgs]\n", argv0);
+	fprintf(stderr, "usage: %s [-h] [-c cfg] [[-s|-d] flag] [msgs]\n",
+			argv0);
 	exit(1);
 }
 
@@ -30,7 +31,7 @@ flagmain(int argc, char *argv[])
 	config_t *cfg;
 	imap_t *imap;
 	int status;
-	char *user, *pass, *netspec, *selected;
+	char *user, *pass, *netspec, *selected, *cfgn;
 	llist_t *folders, *ffolders, *statusl, *ids;
 	llistelem_t *folder, *elem;
 
@@ -43,8 +44,12 @@ flagmain(int argc, char *argv[])
 	};
 
 	status = 0;
+	cfgn = NULL;
 
 	ARGBEGIN {
+	case 'c':
+		cfgn = EARGF(flagusage());
+		break;
 	case 'q':
 		status |= BEQUIET;
 		break;
@@ -55,14 +60,13 @@ flagmain(int argc, char *argv[])
 		status |= DRYRUN;
 		break;
 	case 'e':
-		addseq = EARGF(pickusage());
+		addseq = EARGF(flagusage());
 		break;
-	case 'h':
 	default:
 		incusage();
 	} ARGEND;
 
-	cfg = config_init();
+	cfg = config_init(cfgn);
 	user = config_checkgetstr(cfg, "imapuser");
 	pass = config_checkgetstr(cfg, "imappass");
 	netspec = config_checkgetstr(cfg, "netspec");
diff --git a/bin/rpcomp b/bin/rpcomp
@@ -1,6 +1,8 @@
 #!/bin/sh
 
-if [ ! -x $HOME/.rohrpost/tmpl/compose.sh ];
+BASE="$(rpcfg -b)"
+
+if [ ! -x $BASE/tmpl/compose.sh ];
 then
 	echo "$HOME/.rohrpost/tmpl/compose.sh does not exist. Will" \
 	       "not proceed."
@@ -15,7 +17,7 @@ trap 'signalh' 3 6 9 15
 
 dfolder=$(rpcfg -v fold_drafts)
 
-$HOME/.rohrpost/tmpl/compose.sh > $tmpfile
+$BASE/tmpl/compose.sh > $tmpfile
 mid=$(rpadd -m $dfolder -f seen $tmpfile)
 signalh
 
diff --git a/bin/rpcountmail b/bin/rpcountmail
@@ -53,7 +53,7 @@
 #set -- `from | wc -l`
 #v=$1
 #v=`from | wc -l`
-v=`rpstats -a`
+v=$(rpstats -a)
 
 #v=0
 #exec 0</var/mail/$USER
diff --git a/bin/rpdownload b/bin/rpdownload
@@ -20,7 +20,7 @@ fi
 
 msgid="$*"
 
-url=`rpview -- $msgid | awk '/URL:/ {print $2}' | tr -d '\r'`
+url=$(rpview -- $msgid | awk '/URL:/ {print $2}' | tr -d '\r')
 cd $DOWNLOADDIR
 for i in $url
 do
diff --git a/bin/rpdrafts b/bin/rpdrafts
@@ -28,14 +28,14 @@ do
 		;;
 	esac
 done
-shift `expr $OPTIND - 1`
+shift $(expr $OPTIND - 1)
 
-dfolder=`rpcfg -v fold_drafts`
+dfolder=$(rpcfg -v fold_drafts)
 
 if [ $# -eq 0 ];
 then
 	rpinc -qnu
-	id=`rpids -m $dfolder : | awk -F' ' '{print $1}'`
+	id=$(rpids -m $dfolder : | awk -F' ' '{print $1}')
 	if [ "$id" = "0" ];
 	then
 		echo "No drafts in draft folder."
@@ -65,7 +65,7 @@ fi
 
 if [ $doedit -eq 1 ];
 then
-	id=`rpids -m $dfolder -- "$@" | awk -F' ' '{print $1}'`
+	id=$(rpids -m $dfolder -- "$@" | awk -F' ' '{print $1}')
 	if [ $? -eq 1 ];
 	then
 		echo "Please specify a valid message id."
diff --git a/bin/rpedit b/bin/rpedit
@@ -1,7 +1,8 @@
 #!/bin/sh
 
 usage() {
-	echo "usage: `basename $1` [-h] [-m folder] id"
+	printf "usage: %s [-h] [-m folder] id\n" "$(basename $1)" 2>&1
+	exit 1
 }
 
 folder=""
@@ -14,11 +15,11 @@ do
 		;;
 	*)
 		usage $0
-		exit 1
 		;;
 	esac
 done
-shift `expr $OPTIND - 1`
+shift $(expr $OPTIND - 1)
+
 if [ "$1" = "--" ];
 then
 	shift 1
@@ -27,36 +28,34 @@ fi
 if [ $# -lt 1 ];
 then
 	usage $0
-	exit 1
 fi
 
 if [ -z "$folder" ];
 then
-	folder=`rpsel`
+	folder=$(rpsel)
 fi
 
-id=`rpids -m $folder -- $* | awk -F' ' '{print $1}'`
+id=$(rpids -m $folder -- $* | awk -F' ' '{print $1}')
 if [ -z "$id" ];
 then
 	usage $0
-	exit 1
 fi
 
-tmpfile=`mktemp /tmp/rpedit.XXXXXXX.eml`
+tmpfile=$(mktemp /tmp/rpedit.XXXXXXX.eml)
 signalh() {
 	rm -f $tmpfile
 }
 trap 'signalh' 3 6 9 15
 
 rpview -m $folder -r $id > $tmpfile
-md5before=`md5sum $tmpfile`
+md5before=$(md5sum $tmpfile)
 eval $EDITOR $tmpfile
-md5after=`md5sum $tmpfile`
+md5after=$(md5sum $tmpfile)
 
 if [ "$md5before" != "$md5after" ];
 then
 	rprm -qm $folder $id
-	mid=`rpadd -m $folder -f seen $tmpfile`
+	mid=$(rpadd -m $folder -f seen $tmpfile)
 	if [ $? -eq 0 ];
 	then
 		rpfscan -m $folder $mid
diff --git a/bin/rpfinc b/bin/rpfinc
@@ -1,4 +1,4 @@
 #!/bin/sh
 
-rpinc "$@" | $HOME/.rohrpost/tmpl/inc.sh
+rpinc "$@" | $(rpcfg -b)/tmpl/inc.sh
 
diff --git a/bin/rpfscan b/bin/rpfscan
@@ -1,4 +1,4 @@
 #!/bin/sh
 
-rpscan "$@" | $HOME/.rohrpost/tmpl/scan.sh
+rpscan "$@" | $(rpcfg -b)/tmpl/scan.sh
 
diff --git a/bin/rpfview b/bin/rpfview
@@ -1,4 +1,4 @@
 #!/bin/sh
 
-rpview "$@" | $HOME/.rohrpost/tmpl/view.sh
+rpview "$@" | $(rpcfg -b)/tmpl/view.sh
 
diff --git a/bin/rpfwd b/bin/rpfwd
@@ -1,7 +1,10 @@
 #!/bin/sh
 
+BASE="$(cfg -b)"
+
 usage() {
-	echo "usage: `basename $1` [-h] msgids"
+	printf "usage. %s [-h] msgids\n" "$(basename $1)" 2>&1
+	exit 1
 }
 
 if [ "$1" = "--" ];
@@ -13,12 +16,11 @@ ids="$@"
 if [ -z "$ids" ];
 then
 	usage $0
-	exit 1
 fi
 
-if [ ! -x $HOME/.rohrpost/tmpl/fwd.sh ];
+if [ ! -x $BASE/tmpl/fwd.sh ];
 then
-	echo "$HOME/.rohrpost/tmpl/fwd.sh does not exist. Will" \
+	echo "$BASE/tmpl/fwd.sh does not exist. Will" \
 	       "not proceed."
 	exit 1
 fi
@@ -29,10 +31,10 @@ signalh() {
 }
 trap 'signalh' 3 6 9 15 
 
-dfolder=`rpcfg -v fold_drafts`
+dfolder=$(rpcfg -v fold_drafts)
 
-$HOME/.rohrpost/tmpl/fwd.sh -- "$ids" > $tmpfile
-mid=`rpadd -m $dfolder -f seen $tmpfile`
+$BASE/tmpl/fwd.sh -- "$ids" > $tmpfile
+mid=$(rpadd -m $dfolder -f seen $tmpfile)
 signalh
 
 if [ $? -eq 0 ];
diff --git a/bin/rpnews b/bin/rpnews
@@ -7,6 +7,6 @@ then
 	args="unseen"
 fi
 
-rpscan $args | $HOME/.rohrpost/tmpl/news.sh \
+rpscan $args | $(rpcfg -b)/tmpl/news.sh \
 	| eval $PAGER
 
diff --git a/bin/rpnext b/bin/rpnext
@@ -1,15 +1,15 @@
 #!/bin/sh
 
-cur=`rpcur`
+cur=$(rpcur)
 if [ $? -gt 0 ];
 then
 	rpcur 1
 	cur=1
 fi
-cursel=`rpsel`
-max=`rpinc $cursel | tail -n 1 | awk '{print $3}'`
+cursel=$(rpsel)
+max=$(rpinc $cursel | tail -n 1 | awk '{print $3}')
 
-cur=`expr $cur + 1`
+cur=$(($cur + 1))
 if [ $cur -gt $max ];
 then
 	echo "We are at the last element."
diff --git a/bin/rpopen b/bin/rpopen
@@ -2,7 +2,7 @@
 
 if [ $# -lt 1 ];
 then
-	echo "usage: `basename $0` msgid"
+	printf "usage. %s msgid\n" "$(basename $0)" 2>&1
 	exit 1
 fi
 
@@ -15,7 +15,7 @@ fi
 
 msgid="$*"
 
-url=`rpview $msgid | awk '/^URL:/ {print $2}' | tr -d '\r'`
+url=$(rpview $msgid | awk '/^URL:/ {print $2}' | tr -d '\r')
 for i in $url
 do
 	echo $i
diff --git a/bin/rppodplay b/bin/rppodplay
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 usage() {
-	printf "usage: %s [-d] msgid\n" "$(basename $1)" >&2
+	printf "usage: %s [-d] msgid\n" "$(basename $1)" 2>&1
 	exit 1
 }
 
@@ -17,7 +17,6 @@ do
 	
 	*)
 		usage $0
-		exit 1
 		;;
 	esac
 done
diff --git a/bin/rppop b/bin/rppop
@@ -1,7 +1,7 @@
 #!/bin/sh
 
-markl=`rpmark -v $1`
-elem=`echo $markl | awk -F' ' '{print $1}'`
+markl=$(rpmark -v $1)
+elem=$(echo $markl | awk -F' ' '{print $1}')
 rpmark -qr $1 $elem
 
 rpview $elem
diff --git a/bin/rpprev b/bin/rpprev
@@ -1,13 +1,13 @@
 #!/bin/sh
 
-cur=`rpcur`
+cur=$(rpcur)
 if [ $? -gt 0 ];
 then
 	rpcur 1
 	cur=1
 fi
 
-cur=`expr $cur - 1`
+cur=$(($cur - 1))
 if [ $cur -lt 1 ];
 then
 	cur=1
diff --git a/bin/rprepl b/bin/rprepl
@@ -1,28 +1,30 @@
 #!/bin/sh
 
-if [ ! -x $HOME/.rohrpost/tmpl/repl.sh ];
+BASE="$(rpcfg -b)"
+
+if [ ! -x $BASE/tmpl/repl.sh ];
 then
-	echo "$HOME/.rohrpost/tmpl/repl.sh does not exist. Will" \
+	echo "$BASE/tmpl/repl.sh does not exist. Will" \
 	       "not proceed."
 	exit 1
 fi
 
-tmpfile=`mktemp`
+tmpfile=$(mktemp)
 signalh() {
 	rm -f $tmpfile
 }
 trap 'signalh' 3 6 9 15 
 
-dfolder=`rpcfg -v fold_drafts`
+dfolder=$(rpcfg -v fold_drafts)
 
-$HOME/.rohrpost/tmpl/repl.sh "$@" > $tmpfile
+$BASE/tmpl/repl.sh "$@" > $tmpfile
 if [ $? -gt 0 ];
 then
 	rm -f $tempfile
 	exit 1
 fi
 
-mid=`rpadd -m $dfolder -f seen $tmpfile`
+mid=$(rpadd -m $dfolder -f seen $tmpfile)
 signalh
 
 if [ $? -eq 0 ];
diff --git a/bin/rpsend b/bin/rpsend
@@ -1,7 +1,9 @@
 #!/bin/sh
 
 usage() {
-	echo "usage: `basename $1` [-hd] [-s sent folder] [-m folder] id"
+	printf "usage: %s [-hd] [-s sent folder] [-m folder] id\n" \
+		"$(basename $1)" 2>&1
+	exit 1
 }
 
 dodelete=0
@@ -22,11 +24,10 @@ do
 		;;
 	*)
 		usage $0
-		exit 1
 		;;
 	esac
 done
-shift `expr $OPTIND - 1`
+shift $(($OPTIND - 1))
 if [ "$1" = "--" ];
 then
 	shift 1
@@ -35,12 +36,11 @@ fi
 if [ $# -lt 1 ];
 then
 	usage $0
-	exit 1
 fi
 
 if [ -z "$folder" ];
 then
-	folder=`rpcfg -v fold_drafts`
+	folder=$(rpcfg -v fold_drafts)
 	if [ $? -eq 1 ];
 	then
 		echo "Please specify fold_drafts in rpcfg."
@@ -50,17 +50,17 @@ fi
 
 if [ -z "$sentfolder" ];
 then
-	sentfolder=`rpcfg -v fold_sent`
+	sentfolder=$(rpcfg -v fold_sent)
 fi
 
-mailer=`rpcfg -v send_cmd`
+mailer=$(rpcfg -v send_cmd)
 if [ $? -eq 1 ];
 then
 	echo "Please specify a send_cmd in rpcfg."
 	exit 1
 fi
 
-for mid in `rpids -m $folder -- "$@"`;
+for mid in $(rpids -m $folder -- "$@");
 do
 	rpview -m $folder -r $mid | eval $mailer
 	[ $? -gt 0 ] && exit 1
diff --git a/bin/rpsyncmail b/bin/rpsyncmail
@@ -6,7 +6,7 @@ then
 else
 	for i in $*;
 	do
-		mailbox=`echo $i | sed "s/^mb://g"`
+		mailbox=$(echo $i | sed "s/^mb://g")
 		dsync -R -m $mailbox -u chrissi mirror chrissi@r-36.net
 	done
 fi
diff --git a/bin/rptailf b/bin/rptailf
@@ -2,7 +2,7 @@
 
 if [ -z "$1" ];
 then
-	echo "usage: `basename $0` folder"
+	printf "usage: %s folder\n" "$(basename $0)" 2>&1
 	exit 1
 fi
 
@@ -10,7 +10,7 @@ folder="$1"
 
 while true;
 do
-	num=`rpinc ${folder} | tail -n 1 | cut -f 3`
+	num=$(rpinc ${folder} | tail -n 1 | cut -f 3)
 
 	if [ $num -gt 0 ];
 	then
diff --git a/capability.c b/capability.c
@@ -19,7 +19,7 @@ char *argv0;
 void
 capabilityusage(void)
 {
-	fprintf(stderr, "usage: %s [-h]\n", argv0);
+	fprintf(stderr, "usage: %s [-h] [-c cfg]\n", argv0);
 	exit(1);
 }
 
@@ -28,16 +28,20 @@ capabilitymain(int argc, char *argv[])
 {
 	config_t *cfg;
 	imap_t *imap;
-	char *user, *pass, *netspec;
+	char *user, *pass, *netspec, *cfgn;
 	llistelem_t *elem;
 
+	cfgn = NULL;
+
 	ARGBEGIN {
-	case 'h':
+	case 'c':
+		cfgn = EARGF(capabilityusage());
+		break;
 	default:
 		capabilityusage();
 	} ARGEND;
 
-	cfg = config_init();
+	cfg = config_init(cfgn);
 	user = (config_checkget(cfg, "imapuser"))->data;
 	pass = (config_checkget(cfg, "imappass"))->data;
 	netspec = (config_checkget(cfg, "imapnet"))->data;
diff --git a/cfg.c b/cfg.c
@@ -19,30 +19,87 @@
 
 char *argv0;
 
+char *
+config_mkcfgpath(char *cfgn)
+{
+	char *prefix, *path;
+
+	if (cfgn == NULL)
+		cfgn = "default";
+
+	prefix = expandhome(CONFIGFILE);
+	path = smprintf(prefix, cfgn);
+	free(prefix);
+
+	return path;
+}
+
+char *
+config_mkbasepath(char *cfgn)
+{
+	char *prefix, *path;
+
+	if (cfgn == NULL)
+		cfgn = "default";
+
+	prefix = expandhome(BASEPREFIX);
+	path = smprintf(prefix, cfgn);
+	free(prefix);
+
+	return path;
+}
+
 config_t *
-config_init(void)
+config_init(char *cfgn)
 {
 	char *path;
 	config_t *cfg;
 
-	path = expandhome(CONFIGFILE);
+	if (cfgn == NULL)
+		cfgn = "default";
+
+	path = config_mkcfgpath(cfgn);
 	cfg = config_read(path);
 	free(path);
 
-	if (cfg == NULL)
-		return config_new();
+	if (cfg == NULL) {
+		if (!strcmp(cfgn, "default")) {
+			die("No default config is set and no cfg was given."
+				" Please use $(rpcfg -e cfg) to set the"
+				" default configuration.\n");
+		}
+
+		cfg = config_new();
+	}
+
+	cfg->name = memdup(cfgn, strlen(cfgn)+1);
 
 	return cfg;
 }
 
 void
+config_default(char *cfgn)
+{
+	char *defaultpath, *cfgpath;
+
+	cfgpath = config_mkbasepath(cfgn);
+	defaultpath = config_mkbasepath("default");
+
+	if (symlink(cfgpath, defaultpath) < 0)
+		edie("symlink");
+
+	free(cfgpath);
+	free(defaultpath);
+}
+
+void
 config_stop(config_t *cfg)
 {
 	char *path;
 
 	if (cfg->changed) {
-		path = expandhome(CONFIGFILE);
-		if (config_write(cfg, path) == NULL)
+		path = config_mkcfgpath(cfg->name);
+		if (config_write(cfg, NULL) == NULL)
 			edie("config_write");
 		free(path);
 	}
@@ -67,21 +124,19 @@ config_getstr(config_t *cfg, char *key)
 {
 	llistelem_t *selitem;
 	char *rstr;
-	config_t *ucfg;
 
 	if (cfg == NULL)
-		ucfg = config_init();
-	else
-		ucfg = cfg;
+		return NULL;
 
-	selitem = config_get(ucfg, key);
-	if (selitem != NULL && selitem->data != NULL)
+	selitem = config_get(cfg, key);
+	if (selitem != NULL && selitem->data != NULL) {
 		rstr = memdup(selitem->data, selitem->datalen+1);
-	else
+	} else {
 		rstr = NULL;
+	}
 
 	if (cfg == NULL)
-		config_free(ucfg);
+		config_free(cfg);
 
 	return rstr;
 }
@@ -101,23 +156,25 @@ config_checkgetstr(config_t *cfg, char *key)
 void
 configprintelem(llistelem_t *elem, int onlydata)
 {
-	if (onlydata)
+	if (onlydata) {
 		llistelem_printdata(elem);
-	else
+	} else {
 		llistelem_print(elem);
+	}
 }
 
 void
 configusage(void)
 {
-	die("usage: %s [-qhv] [-l|key [value]]|-d key|-s regex]\n", argv0);
+	die("usage: %s [-bhqv] [-c cfg] [-e cfg|-l|key"
+			" [value]]|-d key|-s regex]\n", argv0);
 }
 
 int
 configmain(int argc, char *argv[])
 {
 	int status;
-	char *key, *value;
+	char *key, *value, *cfgn, *def, *path;
 	config_t *cfg;
 	llist_t *results;
 	llistelem_t *result, *elem;
@@ -127,17 +184,29 @@ configmain(int argc, char *argv[])
 		ONLYDATA = 0x02,
 		DOLIST = 0x04,
 		DODELETE = 0x08,
-		DOSEARCH = 0x10
+		DOSEARCH = 0x10,
+		DOBASE = 0x20
 	};
 
 	status = 0;
 	key = NULL;
 	value = NULL;
+	cfgn = NULL;
+	def = NULL;
 
 	ARGBEGIN {
+	case 'c':
+		cfgn = EARGF(configusage());
+		break;
+	case 'b':
+		status |= DOBASE;
+		break;
 	case 'd':
 		status |= DODELETE;
 		break;
+	case 'e':
+		def = EARGF(configusage());
+		break;
 	case 'q':
 		status |= BEQUIET;
 		break;
@@ -150,12 +219,27 @@ configmain(int argc, char *argv[])
 	case 's':
 		status |= DOSEARCH;
 		break;
-	case 'h':
 	default:
 		configusage();
 	} ARGEND;
 
-	cfg = config_init();
+	if (def) {
+		config_default(def);
+		if (!(status & BEQUIET)) {
+			printf("Default configuration set to '%s'.\n",
+					def);
+		}
+		return 0;
+	}
+
+	if (status & DOBASE) {
+		path = config_mkbasepath(cfgn);
+		printf("%s\n", path);
+		free(path);
+		return 0;
+	}
+
+	cfg = config_init(cfgn);
 
 	if (status & DOLIST) {
 		forllist(cfg->values, elem)
@@ -167,8 +251,9 @@ configmain(int argc, char *argv[])
 		key = argv[0];
 		if (argc > 1)
 			value = argv[1];
-	} else
+	} else {
 		configusage();
+	}
 
 	if (value != NULL) {
 		result = config_set(cfg, key, value);
diff --git a/cfg.h b/cfg.h
@@ -9,6 +9,8 @@
 #include "llist.h"
 #include "txtdb.h"
 
+/* For CONFIGFILE see ind.h */
+
 #define config_t txtdb_t
 
 #define config_new txtdb_new
@@ -26,8 +28,11 @@ llistelem_t *config_checkget(config_t *cfg, char *key);
 char *config_getstr(config_t *cfg, char *key);
 char *config_checkgetstr(config_t *cfg, char *key);
 
-config_t *config_init(void);
+char *config_mkcfgpath(char *cfgn);
+char *config_mkbasepath(char *cfgn);
+config_t *config_init(char *cfgn);
 void config_stop(config_t *cfg);
+void config_default(char *cfgn);
 
 int configmain(int argc, char *argv[]);
 
diff --git a/config.mk b/config.mk
@@ -13,7 +13,7 @@ INCS = -I. -I/usr/include
 LIBS = -L/usr/lib -lc -lssl -lcrypto -lz -ldl
 
 # flags
-CPPFLAGS = -DVERSION=\"${VERSION}\" -D_XOPEN_SOURCE
+CPPFLAGS = -DVERSION=\"${VERSION}\" -D_XOPEN_SOURCE=600
 CFLAGS = -g -std=gnu99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
 LDFLAGS = -g ${LIBS}
 #LDFLAGS = -s ${LIBS}
diff --git a/copy.c b/copy.c
@@ -22,13 +22,13 @@ char *argv0;
 void
 copyusage(void)
 {
-	die("usage: %s [-hq] [-m folder] folder msgs\n", argv0);
+	die("usage: %s [-hq] [-c cfg] [-m folder] folder msgs\n", argv0);
 }
 
 int
 movemain(int argc, char *argv[])
 {
-	argv[0] = "m";
+	argv[0] = "rpmv";
 	return copymain(argc, argv);
 }
 
@@ -38,7 +38,7 @@ copymain(int argc, char *argv[])
 	config_t *cfg;
 	imap_t *imap;
 	int status;
-	char *user, *pass, *netspec, *selected, *folder;
+	char *user, *pass, *netspec, *selected, *folder, *cfgn;
 	llist_t *ids;
 	inc_t *incs;
 
@@ -50,18 +50,22 @@ copymain(int argc, char *argv[])
 	};
 
 	selected = NULL;
+	cfgn = NULL;
 
 	status = 0;
-	if (argc > 0 && argv[0][0] == 'm')
+	if (argc > 0 && argv[0][2] == 'm')
 		status |= DOMOVE;
 
 	ARGBEGIN {
-	case 'q':
-		status |= BEQUIET;
+	case 'c':
+		cfgn = EARGF(copyusage());
 		break;
 	case 'm':
 		selected = EARGF(copyusage());
 		break;
+	case 'q':
+		status |= BEQUIET;
+		break;
 	case 'h':
 	default:
 		copyusage();
@@ -73,7 +77,7 @@ copymain(int argc, char *argv[])
 	argv++;
 	argc--;
 
-	cfg = config_init();
+	cfg = config_init(cfgn);
 	user = config_checkgetstr(cfg, "imapuser");
 	pass = config_checkgetstr(cfg, "imappass");
 	netspec = config_checkgetstr(cfg, "imapnet");
@@ -94,12 +98,12 @@ copymain(int argc, char *argv[])
 	if (imap_select(imap, selected))
 		imap_die(imap, "imap_select");
 
-	ids = imap_argv2ids(selected, argc, argv);
+	ids = imap_argv2ids(cfgn, selected, argc, argv);
 	if (ids == NULL)
 		die("No msgids selected. Aborting.\n");
 	user = imap_ids2str(ids);
 
-	incs = inc_init();
+	incs = inc_init(cfgn);
 	if (status & DOMOVE) {
 		if (imap_move(imap, ids, folder))
 			imap_die(imap, "imap_move");
diff --git a/cur.c b/cur.c
@@ -21,7 +21,7 @@ char *argv0;
 void
 curusage(void)
 {
-	die("usage: %s [-h] [msgid]\n", argv0);
+	die("usage: %s [-h] [-c cfg] [msgid]\n", argv0);
 }
 
 int
@@ -30,18 +30,23 @@ curmain(int argc, char *argv[])
 	config_t *cfg;
 	mark_t *marks;
 	llistelem_t *curseq;
-	char *msgss, *selected;
+	char *msgss, *selected, *cfgn;
 	int msgs, setn;
 
+	cfgn = NULL;
+
 	ARGBEGIN {
-	case 'h':
+	case 'c':
+		cfgn = EARGF(curusage());
+		break;
 	default:
 		curusage();
 	} ARGEND;
 
-	cfg = config_init();
+	cfg = config_init(cfgn);
 	marks = mark_cfg(cfg);
 	config_free(cfg);
+
 	if (marks == NULL) {
 		fprintf(stderr, "Can not proceed without a selected "
 				"mailbox.\n");
@@ -54,7 +59,7 @@ curmain(int argc, char *argv[])
 			setn = 1;
 
 		selected = config_checkgetstr(cfg, "selected");
-		msgss = inc_getstr(selected, "messages");
+		msgss = inc_getstr(cfgn, selected, "messages");
 		if (msgss != NULL) {
 			msgs = atoi(msgss);
 			if (msgs > 0 && setn > msgs)
diff --git a/flag.c b/flag.c
@@ -76,7 +76,7 @@ flagsyntax(void)
 void
 flagusage(void)
 {
-	die("usage: %s [-fht] [-m folder] [[-s|-d] flag] [msgs]\n"
+	die("usage: %s [-fht] [-c cfg] [-m folder] [[-s|-d] flag] [msgs]\n"
 		"Use -f for displaying the flag syntax.\n", argv0);
 }
 
@@ -86,7 +86,7 @@ flagmain(int argc, char *argv[])
 	config_t *cfg;
 	imap_t *imap;
 	int status;
-	char *user, *pass, *netspec, *selected;
+	char *user, *pass, *netspec, *selected, *cfgn;
 	llist_t *ids, *flagl, *flagrl, *flagel;
 	llistelem_t *elem;
 
@@ -102,33 +102,37 @@ flagmain(int argc, char *argv[])
 	status = 0;
 	flagl = NULL;
 	selected = NULL;
+	cfgn = NULL;
 
 	ARGBEGIN {
-	case 'q':
-		status |= BEQUIET;
+	case 'c':
+		cfgn = EARGF(flagusage());
 		break;
 	case 'd':
 		status |= DODELETE;
 		break;
-	case 's':
-		status |= DOSET;
-		break;
-	case 't':
-		status |= TABSEP;
-		break;
 	case 'f':
 		flagsyntax();
 		break;
 	case 'm':
 		selected = EARGF(flagusage());
 		break;
-	case 'h':
+	case 'q':
+		status |= BEQUIET;
+		break;
+	case 's':
+		status |= DOSET;
+		break;
+	case 't':
+		status |= TABSEP;
+		break;
 	default:
 		flagusage();
 	} ARGEND;
 
 	if (argc < 1)
 		flagusage();
+
 	if (status & DOSET || status & DODELETE) {
 		flagl = flag_sanitize(argv[0]);
 		if (flagl == NULL)
@@ -139,7 +143,7 @@ flagmain(int argc, char *argv[])
 	if (argc < 1)
 		flagusage();
 
-	cfg = config_init();
+	cfg = config_init(cfgn);
 	user = config_checkgetstr(cfg, "imapuser");
 	pass = config_checkgetstr(cfg, "imappass");
 	netspec = config_checkgetstr(cfg, "imapnet");
@@ -160,7 +164,7 @@ flagmain(int argc, char *argv[])
 	if (imap_select(imap, selected))
 		imap_die(imap, "imap_select");
 
-	ids = imap_argv2ids(selected, argc, argv);
+	ids = imap_argv2ids(cfgn, selected, argc, argv);
 	if (ids == NULL)
 		die("No msgids selected. Aborting.\n");
 
diff --git a/folder.c b/folder.c
@@ -19,8 +19,9 @@ char *argv0;
 void
 folderusage(void)
 {
-	die("usage: %s [-qh] [-l [folder|searchterm]|-n folder|-d folder|"
-			"-s [folder]|-u folder|-r old new]\n", argv0);
+	die("usage: %s [-qh] [-c cfg] [-l [folder|searchterm]|-n folder|"
+			"-d folder|-s [folder]|-u folder|-r old new]\n",
+			argv0);
 }
 
 int
@@ -29,7 +30,7 @@ foldermain(int argc, char *argv[])
 	config_t *cfg;
 	imap_t *imap;
 	int status;
-	char *user, *pass, *netspec;
+	char *user, *pass, *netspec, *cfgn;
 	llist_t *folders, *results;
 	llistelem_t *elem;
 
@@ -46,19 +47,26 @@ foldermain(int argc, char *argv[])
 	};
 
 	status = 0;
+	cfgn = NULL;
 
 	ARGBEGIN {
+	case 'c':
+		cfgn = EARGF(folderusage());
+		break;
 	case 'd':
 		status |= DODELETE;
 		break;
-	case 'q':
-		status |= BEQUIET;
+	case 'l':
+		status |= DOLIST;
 		break;
 	case 'n':
 		status |= DOCREATE;
 		break;
-	case 'l':
-		status |= DOLIST;
+	case 'q':
+		status |= BEQUIET;
+		break;
+	case 'r':
+		status |= DORENAME;
 		break;
 	case 's':
 		status |= DOSUBSCRIBE;
@@ -66,15 +74,11 @@ foldermain(int argc, char *argv[])
 	case 'u':
 		status |= DOUNSUBSCRIBE;
 		break;
-	case 'r':
-		status |= DORENAME;
-		break;
-	case 'h':
 	default:
 		folderusage();
 	} ARGEND;
 
-	cfg = config_init();
+	cfg = config_init(cfgn);
 	user = (config_checkget(cfg, "imapuser"))->data;
 	pass = (config_checkget(cfg, "imappass"))->data;
 	netspec = (config_checkget(cfg, "imapnet"))->data;
diff --git a/ids.c b/ids.c
@@ -24,23 +24,26 @@ char *argv0;
 void
 idsusage(void)
 {
-	die("usage: %s [-h] [-m folder] msgs\n", argv0);
+	die("usage: %s [-h] [-c cfg] [-m folder] msgs\n", argv0);
 }
 
 int
 idsmain(int argc, char *argv[])
 {
 	config_t *cfg;
-	char *selected, *idss;
+	char *selected, *idss, *cfgn;
 	llist_t *ids;
 
 	selected = NULL;
+	cfgn = NULL;
 
 	ARGBEGIN {
+	case 'c':
+		cfgn = EARGF(idsusage());
+		break;
 	case 'm':
 		selected = EARGF(idsusage());
 		break;
-	case 'h':
 	default:
 		idsusage();
 	} ARGEND;
@@ -48,7 +51,7 @@ idsmain(int argc, char *argv[])
 	if (argc < 1)
 		idsusage();
 
-	cfg = config_init();
+	cfg = config_init(cfgn);
 	if (selected == NULL) {
 		selected = config_checkgetstr(cfg, "selected");
 	} else {
@@ -56,7 +59,7 @@ idsmain(int argc, char *argv[])
 	}
 	config_free(cfg);
 
-	ids = imap_argv2ids(selected, argc, argv);
+	ids = imap_argv2ids(cfgn, selected, argc, argv);
 	if (ids == NULL)
 		die("No msgsids selected. Aborting.\n");
 
diff --git a/imap.c b/imap.c
@@ -75,7 +75,7 @@ imap_die(imap_t *imap, char *fmt, ...)
 }
 
 llist_t *
-imap_llist2ids(char *mailbox, llist_t *elems)
+imap_llist2ids(char *cfgn, char *mailbox, llist_t *elems)
 {
 	llist_t *ids, *result, *ret;
 	llistelem_t *elem;
@@ -86,13 +86,13 @@ imap_llist2ids(char *mailbox, llist_t *elems)
 	ret = NULL;
 	first = 1;
 
-	rstr = inc_getstr(mailbox, "messages");
+	rstr = inc_getstr(cfgn, mailbox, "messages");
 	if (rstr == NULL)
 		return NULL;
 	last = atoi(rstr);
 	free(rstr);
 
-	marks = mark_init(mailbox);
+	marks = mark_init(cfgn, mailbox);
 	if (marks == NULL)
 		return NULL;
 
@@ -204,21 +204,21 @@ badmarkending:
 }
 
 llist_t *
-imap_str2ids(char *mailbox, char *str)
+imap_str2ids(char *cfgn, char *mailbox, char *str)
 {
 	llist_t *ids, *ssplit;
 
 	ssplit = llist_splitstr(str, " ,");
 	if (ssplit == NULL)
 		return NULL;
-	ids = imap_llist2ids(mailbox, ssplit);
+	ids = imap_llist2ids(cfgn, mailbox, ssplit);
 	llist_free(ssplit);
 
 	return ids;
 }
 
 llist_t *
-imap_argv2ids(char *mailbox, int argc, char *argv[])
+imap_argv2ids(char *cfgn, char *mailbox, int argc, char *argv[])
 {
 	llist_t *allist, *llist, *ids, *nids;
 	llistelem_t *argelem;
@@ -236,7 +236,7 @@ imap_argv2ids(char *mailbox, int argc, char *argv[])
 	}
 	llist_free(allist);
 
-	ids = imap_llist2ids(mailbox, llist);
+	ids = imap_llist2ids(cfgn, mailbox, llist);
 	llist_free(llist);
 
 	return ids;
@@ -268,19 +268,21 @@ imap_ids2str(llist_t *ids)
 		if (ida[i] == nb + nc)
 			continue;
 
-		if (nc > 0)
+		if (nc > 0) {
 			el = smprintf("%d:%d", nb, nb+nc);
-		else
+		} else {
 			el = smprintf("%d", nb);
+		}
 		llist_addraw(seqs, el, NULL, 0);
 		nb = ida[i];
 		nc = 0;
 	}
 
-	if (nc > 0)
+	if (nc > 0) {
 		el = smprintf("%d:%d", nb, nb+nc);
-	else
+	} else {
 		el = smprintf("%d", nb);
+	}
 	free(ida);
 	llist_addraw(seqs, el, NULL, 0);
 
diff --git a/imap.h b/imap.h
@@ -32,9 +32,9 @@ void imap_free(imap_t *imap);
 
 void imap_die(imap_t *imap, char *fmt, ...);
 
-llist_t *imap_llist2ids(char *mailbox, llist_t *ids);
-llist_t *imap_str2ids(char *mailbox, char *str);
-llist_t *imap_argv2ids(char *mailbox, int argc, char *argv[]);
+llist_t *imap_llist2ids(char *cfgn, char *mailbox, llist_t *ids);
+llist_t *imap_str2ids(char *cfgn, char *mailbox, char *str);
+llist_t *imap_argv2ids(char *cfgn, char *mailbox, int argc, char *argv[]);
 char *imap_ids2str(llist_t *ids);
 
 void imap_cmd(imap_t *imap, char *cmd, ...);
diff --git a/inc.c b/inc.c
@@ -22,23 +22,40 @@
 char *argv0;
 
 char *
-inc_mkincfile(void)
+inc_mkincfile(char *cfgn)
 {
-	return expandhome(INCFILE);
+	char *prefix, *path;
+
+	prefix = expandhome(INCFILE);
+	path = smprintf(prefix, cfgn);
+	free(prefix);
+
+	return path;
 }
 
 inc_t *
-inc_init(void)
+inc_init(char *cfgn)
 {
 	inc_t *incs;
 	char *path;
 
-	path = inc_mkincfile();
+	if (cfgn == NULL)
+		cfgn = "default";
+
+	path = inc_mkincfile(cfgn);
 	incs = inc_read(path);
 	free(path);
 
-	if (incs == NULL)
+	if (incs == NULL) {
+		if (!strcmp(cfgn, "default")) {
+			die("No default config is set and no cfg was given."
+				" Please use $(rpcfg -e cfg) to set the"
+				" default configuration.\n");
+		}
 		incs = inc_new();
+	}
+
+	incs->name = memdup(cfgn, strlen(cfgn)+1);
 
 	return incs;
 }
@@ -49,7 +66,7 @@ inc_stop(inc_t *incs)
 	char *path;
 
 	if (incs->changed) {
-		path = inc_mkincfile();
+		path = inc_mkincfile(incs->name);
 		if (inc_write(incs, path) == NULL)
 			edie("inc_write");
 		free(path);
@@ -103,12 +120,12 @@ inc_getstatuselem(inc_t *incs, char *mailbox, char *elem)
 }
 
 char *
-inc_getstr(char *mailbox, char *elem)
+inc_getstr(char *cfgn, char *mailbox, char *elem)
 {
 	inc_t *incs;
 	char *ret;
 
-	incs = inc_init();
+	incs = inc_init(cfgn);
 	if (incs == NULL)
 		return NULL;
 	ret = inc_getstatuselem(incs, mailbox, elem);
@@ -168,15 +185,15 @@ inc_updatefolder(imap_t *imap, char *folder, inc_t *gincs)
 }
 
 void
-inc_mkunseen(imap_t *imap, char *folder)
+inc_mkunseen(imap_t *imap, char *cfgn, char *folder)
 {
 	llist_t *results;
 	mark_t *marks;
 	char *str;
 
-	marks = mark_init(folder);
+	marks = mark_init(cfgn, folder);
 	if (marks == NULL)
-		die("Could not initialize marks for %s.\n", folder);
+		die("Could not initialize marks for '%s'.\n", folder);
 
 	if (imap_select(imap, folder))
 		imap_die(imap, "imap_select");
@@ -201,7 +218,7 @@ inc_print(char *folder, char *msgs, char *unseen, char *recent)
 void
 incusage(void)
 {
-	die("usage: %s [-auqnh] [[-r|] folder]\n", argv0);
+	die("usage: %s [-auqnh] [-c cfg] [[-r|] folder]\n", argv0);
 }
 
 int
@@ -211,7 +228,7 @@ incmain(int argc, char *argv[])
 	imap_t *imap;
 	inc_t *incs;
 	int status;
-	char *user, *pass, *netspec, *msgs, *recent, *unseen, *ncmd;
+	char *user, *pass, *netspec, *msgs, *recent, *unseen, *ncmd, *cfgn;
 	llist_t *folders, *ffolders;
 	llistelem_t *folder;
 
@@ -226,11 +243,15 @@ incmain(int argc, char *argv[])
 	};
 
 	status = 0;
+	cfgn = NULL;
 
 	ARGBEGIN {
 	case 'a':
 		status |= SHOWALL;
 		break;
+	case 'c':
+		cfgn = EARGF(incusage());
+		break;
 	case 'n':
 		status |= RUNNOTIFY;
 		break;
@@ -243,13 +264,11 @@ incmain(int argc, char *argv[])
 	case 'u':
 		status |= GENUNSEEN;
 		break;
-	case 'h':
 	default:
 		incusage();
 	} ARGEND;
 
-	cfg = config_init();
-
+	cfg = config_init(cfgn);
 	user = config_checkgetstr(cfg, "imapuser");
 	pass = config_checkgetstr(cfg, "imappass");
 	netspec = config_checkgetstr(cfg, "imapnet");
@@ -292,7 +311,7 @@ incmain(int argc, char *argv[])
 
 	if (!(status & BEQUIET))
 		inc_print("Folder", "Msgs", "Unseen", "Recent");
-	incs = inc_init();
+	incs = inc_init(cfgn);
 	forllist(ffolders, folder) {
 		if (folder->key == NULL)
 			continue;
@@ -310,7 +329,7 @@ incmain(int argc, char *argv[])
 				inc_print(folder->key, msgs, unseen, recent);
 
 			if (status & GENUNSEEN)
-				inc_mkunseen(imap, folder->key);
+				inc_mkunseen(imap, cfgn, folder->key);
 			if (status & RUNNOTIFY && ncmd) {
 				runcmd(ncmd, NULL, NULL, NULL, 0);
 				wait(NULL);
diff --git a/inc.h b/inc.h
@@ -24,17 +24,17 @@
 #define inc_read txtdb_read
 #define inc_write txtdb_write
 
-char *inc_mkincfile(void);
-inc_t *inc_init(void);
+char *inc_mkincfile(char *cfgn);
+inc_t *inc_init(char *cfgn);
 void inc_stop(inc_t *incs);
 llist_t *inc_getstatus(inc_t *incs, char *mailbox);
 char *inc_getstatuselem(inc_t *incs, char *mailbox, char *elem);
-char *inc_getstr(char *mailbox, char *elem);
+char *inc_getstr(char *cfgn, char *mailbox, char *elem);
 void inc_setstatus(inc_t *incs, char *mailbox, char *msgs, char *unseen,
 		char *recent);
 int inc_updatefolder(imap_t *imap, char *folder, inc_t *gincs);
 
-void inc_mkunseen(imap_t *imap, char *folder);
+void inc_mkunseen(imap_t *imap, char *cfgn, char *folder);
 
 int incmain(int argc, char *argv[]);
 
diff --git a/ind.h b/ind.h
@@ -13,9 +13,12 @@
 #include <time.h>
 
 #define MAXLINESIZE 1048576
-#define CONFIGFILE "~/.rohrpost/config"
-#define MARKPREFIX "~/.rohrpost/marks/"
-#define INCFILE "~/.rohrpost/status"
+
+#define RPPREFIX "~/.rohrpost/"
+#define BASEPREFIX RPPREFIX "%s"
+#define CONFIGFILE BASEPREFIX "/config"
+#define MARKPREFIX BASEPREFIX "/marks/%s"
+#define INCFILE BASEPREFIX "/status"
 
 void die(char *fmt, ...);
 void edie(char *fmt, ...);
diff --git a/mark.c b/mark.c
@@ -22,31 +22,42 @@
 char *argv0;
 
 char *
-mark_mkmarkfile(char *mailbox)
+mark_mkmarkfile(char *cfgn, char *mailbox)
 {
 	char *prefix, *path;
 
 	prefix = expandhome(MARKPREFIX);
-	path = smprintf("%s%s", prefix, mailbox);
+	path = smprintf(prefix, cfgn, mailbox);
 	free(prefix);
 
 	return path;
 }
 
 mark_t *
-mark_init(char *mailbox)
+mark_init(char *cfgn, char *mailbox)
 {
 	char *path;
 	mark_t *marks;
 
-	path = mark_mkmarkfile(mailbox);
+	if (cfgn == NULL)
+		cfgn = "default";
+
+	path = mark_mkmarkfile(cfgn, mailbox);
 	marks = mark_read(path);
 	free(path);
 
-	if (marks == NULL)
+	if (marks == NULL) {
+		if (!strcmp(cfgn, "default")) {
+			die("No default config is set and no cfg was given."
+				" Please use $(rpcfg -e cfg) to set the"
+				" default configuration.\n");
+		}
+
 		marks = mark_new();
+	}
 
 	marks->data = memdup(mailbox, strlen(mailbox)+1);
+	marks->name = memdup(cfgn, strlen(cfgn)+1);
 
 	return marks;
 }
@@ -68,7 +79,7 @@ mark_cfg(config_t *cfg)
 	selected = config_getstr(cfg, "selected");
 	if (selected == NULL)
 		return NULL;
-	marks = mark_init(selected);
+	marks = mark_init(cfg->name, selected);
 	free(selected);
 
 	return marks;
@@ -80,7 +91,7 @@ mark_stop(mark_t *marks)
 	char *path;
 
 	if (marks->changed) {
-		path = mark_mkmarkfile((char *)marks->data);
+		path = mark_mkmarkfile(marks->name, (char *)marks->data);
 		if (mark_write(marks, path) == NULL)
 			edie("mark_write");
 		free(path);
@@ -330,7 +341,7 @@ mark_printelem(llistelem_t *elem, int onlyname, int onlyvalue)
 void
 markusage(void)
 {
-	die("usage: %s [-hnqv] [-m folder] [-l|sequence [value ...]]"
+	die("usage: %s [-hnqv] [-c cfg] [-m folder] [-l|sequence [value ...]]"
 			"|-d sequence|"
 			"-s regex|-a sequence value ...|-r sequence"
 			" value ...]\n", argv0);
@@ -340,7 +351,7 @@ int
 markmain(int argc, char *argv[])
 {
 	int status;
-	char *seqname, *str, *selected;
+	char *seqname, *str, *selected, *cfgn;
 	config_t *cfg;
 	mark_t *marks;
 	llist_t *results, *values, *sequence;
@@ -364,11 +375,15 @@ markmain(int argc, char *argv[])
 	seqname = NULL;
 	values = NULL;
 	selected = NULL;
+	cfgn = NULL;
 
 	ARGBEGIN {
 	case 'a':
 		status |= DOADD;
 		break;
+	case 'c':
+		cfgn = EARGF(markusage());
+		break;
 	case 'd':
 		status |= DODELETE;
 		break;
@@ -399,7 +414,7 @@ markmain(int argc, char *argv[])
 	} ARGEND;
 
 	if (selected == NULL) {
-		cfg = config_init();
+		cfg = config_init(cfgn);
 		selected = config_getstr(cfg, "selected");
 		if (selected == NULL)
 			die("Cannot proceed without any selected mailbox.\n");
@@ -407,7 +422,7 @@ markmain(int argc, char *argv[])
 	} else {
 		selected = memdup(selected, strlen(selected)+1);
 	}
-	marks = mark_init(selected);
+	marks = mark_init(cfgn, selected);
 
 	if (status & DOLIST) {
 		if (marks->values->len > 0) {
@@ -503,7 +518,7 @@ markmain(int argc, char *argv[])
 		markusage();
 	}
 
-	values = imap_argv2ids(selected, argc, argv);
+	values = imap_argv2ids(cfgn, selected, argc, argv);
 	free(selected);
 
 	if (status & DOREMOVE) {
diff --git a/mark.h b/mark.h
@@ -20,8 +20,8 @@
 #define mark_read txtdb_read
 #define mark_write txtdb_write
 
-char *mark_mkmarkfile(char *mailbox);
-mark_t *mark_init(char *mailbox);
+char *mark_mkmarkfile(char *cfgn, char *mailbox);
+mark_t *mark_init(char *cfgn, char *mailbox);
 void mark_free(mark_t *marks);
 mark_t *mark_cfg(config_t *cfg);
 void mark_stop(mark_t *marks);
diff --git a/part.c b/part.c
@@ -116,8 +116,8 @@ part_write(char *id, mime_t *mime, llist_t *partl, char *type,
 void
 partusage(void)
 {
-	die("usage: %s [-hq] [-m folder] [-s|-g|-f filename] "
-			"[-c type|-p part|-a|-l]"
+	die("usage: %s [-hq] [-c cfg] [-m folder] [-s|-g|-f filename] "
+			"[-t type|-p part|-a|-l]"
 			" [msgs]\n", argv0);
 }
 
@@ -128,7 +128,7 @@ partmain(int argc, char *argv[])
 	imap_t *imap;
 	int status, filelen, retc;
 	char *user, *pass, *netspec, *selected, *filename, *type,
-	     *parts, *filec;
+	     *parts, *filec, *cfgn;
 	llist_t *ids, *msgs, *partl;
 	llistelem_t *elem, *msg, *ide;
 	mime_t *mime;
@@ -149,13 +149,14 @@ partmain(int argc, char *argv[])
 	parts = NULL;
 	type = NULL;
 	selected = NULL;
+	cfgn = NULL;
 
 	ARGBEGIN {
 	case 'a':
 		status |= ALLPARTS;
 		break;
 	case 'c':
-		type = EARGF(partusage());
+		cfgn = EARGF(partusage());
 		break;
 	case 'f':
 		filename = EARGF(partusage());
@@ -178,6 +179,9 @@ partmain(int argc, char *argv[])
 	case 's':
 		status |= TOSTDOUT;
 		break;
+	case 't':
+		type = EARGF(partusage());
+		break;
 	case 'h':
 	default:
 		partusage();
@@ -231,7 +235,7 @@ partmain(int argc, char *argv[])
 		return retc;
 	}
 
-	cfg = config_init();
+	cfg = config_init(cfgn);
 	user = config_checkgetstr(cfg, "imapuser");
 	pass = config_checkgetstr(cfg, "imappass");
 	netspec = config_checkgetstr(cfg, "imapnet");
@@ -247,7 +251,7 @@ partmain(int argc, char *argv[])
 	free(pass);
 	free(netspec);
 
-	ids = imap_argv2ids(selected, argc, argv);
+	ids = imap_argv2ids(cfgn, selected, argc, argv);
 	if (ids == NULL)
 		die("No msgsids selected. Aborting.\n");
 
diff --git a/pick.c b/pick.c
@@ -312,7 +312,7 @@ pick_printsyntax(void)
 void
 pickusage(void)
 {
-	die("usage: %s [-sqdht] [-m folder] [-o sort criteria]"
+	die("usage: %s [-sqdht] [-c cfg] [-m folder] [-o sort criteria]"
 			" [-e seq] [search syntax]\n"
 			"See -s for syntax help.\n", argv0);
 }
@@ -324,7 +324,7 @@ pickmain(int argc, char *argv[])
 	imap_t *imap;
 	int status;
 	char *user, *pass, *netspec, *addseq, *sstr, *pstr, *selected,
-	     *sorts, *talg;
+	     *sorts, *talg, *cfgn;
 	llist_t *results, *sortl;
 	mark_t *marks;
 
@@ -341,8 +341,12 @@ pickmain(int argc, char *argv[])
 	addseq = "pseq";
 	sorts = NULL;
 	selected = NULL;
+	cfgn = NULL;
 
 	ARGBEGIN {
+	case 'c':
+		cfgn = EARGF(pickusage());
+		break;
 	case 'd':
 		status |= DRYRUN;
 		break;
@@ -364,7 +368,6 @@ pickmain(int argc, char *argv[])
 	case 't':
 		status |= DOTHREAD;
 		break;
-	case 'h':
 	default:
 		pickusage();
 	} ARGEND;
@@ -377,7 +380,7 @@ pickmain(int argc, char *argv[])
 	if (argc < 1)
 		pickusage();
 
-	cfg = config_init();
+	cfg = config_init(cfgn);
 	user = (config_checkget(cfg, "imapuser"))->data;
 	pass = (config_checkget(cfg, "imappass"))->data;
 	netspec = (config_checkget(cfg, "imapnet"))->data;
@@ -386,7 +389,8 @@ pickmain(int argc, char *argv[])
 	} else {
 		selected = memdup(selected, strlen(selected)+1);
 	}
-	marks = mark_init(selected);
+
+	marks = mark_init(cfg->name, selected);
 	if (marks == NULL)
 		die("Could not initialize marks for %s.\n", addseq);
 
diff --git a/remove.c b/remove.c
@@ -21,7 +21,7 @@ char *argv0;
 void
 removeusage(void)
 {
-	die("usage: %s [-hqde] [-m folder] msgs\n", argv0);
+	die("usage: %s [-hqde] [-c cfg] [-m folder] msgs\n", argv0);
 }
 
 int
@@ -30,7 +30,7 @@ removemain(int argc, char *argv[])
 	config_t *cfg;
 	imap_t *imap;
 	int status;
-	char *user, *pass, *netspec, *selected, *dispose, *dodispose;
+	char *user, *pass, *netspec, *selected, *dispose, *dodispose, *cfgn;
 	llist_t *ids;
 
 	enum {
@@ -43,10 +43,11 @@ removemain(int argc, char *argv[])
 
 	status = 0;
 	selected = NULL;
+	cfgn = NULL;
 
 	ARGBEGIN {
-	case 'q':
-		status |= BEQUIET;
+	case 'c':
+		cfgn = EARGF(removeusage());
 		break;
 	case 'd':
 		status |= DODISPOSE;
@@ -57,7 +58,9 @@ removemain(int argc, char *argv[])
 	case 'm':
 		selected = EARGF(removeusage());
 		break;
-	case 'h':
+	case 'q':
+		status |= BEQUIET;
+		break;
 	default:
 		removeusage();
 	} ARGEND;
@@ -65,7 +68,7 @@ removemain(int argc, char *argv[])
 	if (argc < 1 && !(status & DOEXPUNGE))
 		removeusage();
 
-	cfg = config_init();
+	cfg = config_init(cfgn);
 	user = config_checkgetstr(cfg, "imapuser");
 	pass = config_checkgetstr(cfg, "imappass");
 	netspec = config_checkgetstr(cfg, "imapnet");
@@ -94,7 +97,7 @@ removemain(int argc, char *argv[])
 		if (!(status & BEQUIET))
 			printf("Ran expunge.\n");
 	} else {
-		ids = imap_argv2ids(selected, argc, argv);
+		ids = imap_argv2ids(cfgn, selected, argc, argv);
 		user = imap_ids2str(ids);
 		if (status & DODISPOSE || (dodispose && dodispose[0] == '1')) {
 			if (dispose == NULL) {
diff --git a/scan.c b/scan.c
@@ -30,7 +30,7 @@ scan_print(char *id, char *date, char *from, char *subject)
 void
 scanusage(void)
 {
-	die("usage: %s [-h] [-m folder] msgs\n", argv0);
+	die("usage: %s [-h] [-c cfg] [-m folder] msgs\n", argv0);
 }
 
 int
@@ -40,19 +40,22 @@ scanmain(int argc, char *argv[])
 	imap_t *imap;
 	int filelen;
 	char *user, *pass, *netspec, *selected, *date, *subject, *from,
-	     *id, *filec;
+	     *id, *filec, *cfgn;
 	llist_t *ids, *msgs;
 	llistelem_t *elem, *msg, *datee, *subjecte, *frome, *ide;
 	mime_t *mime;
 	struct tm *tim;
 
 	selected = NULL;
+	cfgn = NULL;
 
 	ARGBEGIN {
+	case 'c':
+		cfgn = EARGF(scanusage());
+		break;
 	case 'm':
 		selected = EARGF(scanusage());
 		break;
-	case 'h':
 	default:
 		scanusage();
 	} ARGEND;
@@ -66,7 +69,7 @@ scanmain(int argc, char *argv[])
 		filec = NULL;
 	}
 
-	cfg = config_init();
+	cfg = config_init(cfgn);
 	if (filec == NULL) {
 		user = config_checkgetstr(cfg, "imapuser");
 		pass = config_checkgetstr(cfg, "imappass");
@@ -139,7 +142,7 @@ scanmain(int argc, char *argv[])
 	if (imap_select(imap, selected))
 		imap_die(imap, "imap_select");
 
-	ids = imap_argv2ids(selected, argc, argv);
+	ids = imap_argv2ids(cfgn, selected, argc, argv);
 	if (ids == NULL)
 		die("No msgids selected. Aborting.\n");
 
diff --git a/select.c b/select.c
@@ -19,7 +19,7 @@ char *argv0;
 void
 selectusage(void)
 {
-	die("usage: %s [-h] [mailbox]\n", argv0);
+	die("usage: %s [-h] [-c cfg] [mailbox]\n", argv0);
 }
 
 int
@@ -27,15 +27,19 @@ selectmain(int argc, char *argv[])
 {
 	config_t *cfg;
 	llistelem_t *result;
+	char *cfgn;
+
+	cfgn = NULL;
 
 	ARGBEGIN {
-	case 'h':
-		selectusage();
+	case 'c':
+		cfgn = EARGF(selectusage());
+		break;
 	default:
 		selectusage();
 	} ARGEND;
 
-	cfg = config_init();
+	cfg = config_init(cfgn);
 
 	if (argc > 0) {
 		config_set(cfg, "selected", argv[0]);
diff --git a/sieve.c b/sieve.c
@@ -413,8 +413,8 @@ sieve_init(sieve_t *sieve)
 void
 sieveusage(void)
 {
-	die("usage: %s [-h] [-b|-l|-d|-v script|-p script [file]|"
-			"-g script [file]|-e script|-c [file]|-a script|"
+	die("usage: %s [-h] [-c cfg] [-b|-l|-d|-v script|-p script [file]|"
+			"-g script [file]|-e script|-t [file]|-a script|"
 			"-s script [name [space]]|-r old new]\n", argv0);
 }
 
@@ -422,7 +422,7 @@ int
 sievemain(int argc, char *argv[])
 {
 	int status, len;
-	char *script, *file, *netspec, *user, *pass, *data;
+	char *script, *file, *netspec, *user, *pass, *data, *cfgn;
 	config_t *cfg;
 	llistelem_t *elem;
 	llist_t *results;
@@ -446,6 +446,7 @@ sievemain(int argc, char *argv[])
 	script = NULL;
 	file = NULL;
 	results = NULL;
+	cfgn = NULL;
 
 	ARGBEGIN {
 	case 'a':
@@ -455,7 +456,7 @@ sievemain(int argc, char *argv[])
 		status |= DOSHOWCAPABILITIES;
 		break;
 	case 'c':
-		status |= DOCHECK;
+		cfgn = EARGF(sieveusage());
 		break;
 	case 'd':
 		status |= DODELETE;
@@ -478,6 +479,9 @@ sievemain(int argc, char *argv[])
 	case 's':
 		status |= DOHAVESPACE;
 		break;
+	case 't':
+		status |= DOCHECK;
+		break;
 	case 'v':
 		status |= DODEACTIVATE;
 		break;
@@ -488,7 +492,7 @@ sievemain(int argc, char *argv[])
 	if (!status)
 		sieveusage();
 
-	cfg = config_init();
+	cfg = config_init(cfgn);
 	netspec = (config_checkget(cfg, "sievenet"))->data;
 	user = (config_checkget(cfg, "sieveuser"))->data;
 	pass = (config_checkget(cfg, "sievepass"))->data;
diff --git a/stats.c b/stats.c
@@ -20,7 +20,7 @@ char *argv0;
 void
 statsusage(void)
 {
-	die("usage: %s [-haru] [-m folder]\n", argv0);
+	die("usage: %s [-haru] [-c cfg] [-m folder]\n", argv0);
 }
 
 int
@@ -29,7 +29,8 @@ statsmain(int argc, char *argv[])
 	config_t *cfg;
 	imap_t *imap;
 	int cmsgs, crecent, cunseen, cfolders, domsgs, dorecent, dounseen;
-	char *user, *pass, *netspec, *msgs, *recent, *unseen, *selected;
+	char *user, *pass, *netspec, *msgs, *recent, *unseen, *selected,
+	     *cfgn;
 	llist_t *folders, *ffolders, *statusl;
 	llistelem_t *folder, *elem;
 
@@ -37,11 +38,15 @@ statsmain(int argc, char *argv[])
 	dorecent = 0;
 	dounseen = 0;
 	selected = NULL;
+	cfgn = NULL;
 
 	ARGBEGIN {
 	case 'a':
 		domsgs = 1;
 		break;
+	case 'c':
+		cfgn = EARGF(statsusage());
+		break;
 	case 'm':
 		selected = EARGF(statsusage());
 		break;
@@ -51,12 +56,11 @@ statsmain(int argc, char *argv[])
 	case 'u':
 		dounseen = 1;
 		break;
-	case 'h':
 	default:
 		statsusage();
 	} ARGEND;
 
-	cfg = config_init();
+	cfg = config_init(cfgn);
 	user = (config_checkget(cfg, "imapuser"))->data;
 	pass = (config_checkget(cfg, "imappass"))->data;
 	netspec = (config_checkget(cfg, "imapnet"))->data;
diff --git a/txtdb.c b/txtdb.c
@@ -32,6 +32,10 @@ void
 txtdb_free(txtdb_t *txtdb)
 {
 	llist_free(txtdb->values);
+	if (txtdb->path != NULL)
+		free(txtdb->path);
+	if (txtdb->name != NULL)
+		free(txtdb->name);
 	free(txtdb);
 }
 
@@ -133,6 +137,9 @@ txtdb_read(char *file)
 		txtdb_free(txtdb);
 		return NULL;
 	}
+
+	txtdb->path = memdup(file, strlen(file)+1);
+
 	return txtdb;
 }
 
@@ -142,6 +149,14 @@ txtdb_write(txtdb_t *txtdb, char *file)
 	FILE *fp;
 	llistelem_t *elem;
 
+	if (file == NULL) {
+		if (txtdb->path != NULL) {
+			file = txtdb->path;
+		} else {
+			return NULL;
+		}
+	}
+
 	fp = fopen(file, "w+");
 	if (fp == NULL)
 		return NULL;
diff --git a/txtdb.h b/txtdb.h
@@ -14,6 +14,9 @@ struct txtdb_t {
 
 	int changed;
 	void *data;
+
+	char *path;
+	char *name;
 };
 
 txtdb_t *txtdb_new(void);
diff --git a/view.c b/view.c
@@ -261,8 +261,8 @@ view_print(char *id, mime_t *mime, llist_t *dhdrs, llist_t *partl,
 void
 viewusage(void)
 {
-	die("usage: %s [-hbdnrv] [-e headers] [-m folder] [-p parts] msgs\n",
-			argv0);
+	die("usage: %s [-hbdnrv] [-c cfg] [-e headers] [-m folder]"
+			" [-p parts] msgs\n", argv0);
 }
 
 int
@@ -272,7 +272,7 @@ viewmain(int argc, char *argv[])
 	imap_t *imap;
 	int status, filelen, printopts, dodebug;
 	char *user, *pass, *netspec, *selected, *mfilter, *parts, *filec,
-	     *headers;
+	     *headers, *cfgn;
 	llist_t *ids, *msgs, *dhdrs, *partl;
 	llistelem_t *elem, *msg, *ide;
 	mime_t *mime;
@@ -292,11 +292,15 @@ viewmain(int argc, char *argv[])
 	headers = NULL;
 	printopts = 0;
 	dodebug = 0;
+	cfgn = NULL;
 
 	ARGBEGIN {
 	case 'b':
 		printopts |= PRINT_BODY;
 		break;
+	case 'c':
+		cfgn = EARGF(viewusage());
+		break;
 	case 'd':
 		dodebug = 1;
 		break;
@@ -318,7 +322,6 @@ viewmain(int argc, char *argv[])
 	case 'v':
 		printopts |= PRINT_VALUE;
 		break;
-	case 'h':
 	default:
 		viewusage();
 	} ARGEND;
@@ -332,7 +335,7 @@ viewmain(int argc, char *argv[])
 		filec = NULL;
 	}
 
-	cfg = config_init();
+	cfg = config_init(cfgn);
 	if (filec == NULL) {
 		user = config_checkgetstr(cfg, "imapuser");
 		pass = config_checkgetstr(cfg, "imappass");
@@ -381,7 +384,7 @@ viewmain(int argc, char *argv[])
 		goto viewcleanup;
 	}
 
-	ids = imap_argv2ids(selected, argc, argv);
+	ids = imap_argv2ids(cfgn, selected, argc, argv);
 	if (ids == NULL)
 		die("No msgids selected. Aborting.\n");
 
@@ -421,7 +424,7 @@ viewmain(int argc, char *argv[])
 		mime_free(mime);
 	}
 	if (ids->last != NULL) {
-		marks = mark_init(selected);
+		marks = mark_init(cfgn, selected);
 		mark_set(marks, "cur", ids->last->key);
 		mark_stop(marks);
 	}