diff --git a/exec/imapservice.js b/exec/imapservice.js
index 12b24bcc4226eed0fbf30f6eb9497f502ba48277..db476ef28d83dc8d07e829b5afa05589fd795bac 100644
--- a/exec/imapservice.js
+++ b/exec/imapservice.js
@@ -30,6 +30,7 @@ var msg_ptrs={};
 var curr_status={exists:0,recent:0,unseen:0,uidnext:0,uidvalidity:0};
 var saved_config={mail:{scan_ptr:0}};
 var scan_ptr;
+var cfgfile;
 
 /**********************/
 /* Encoding functions */
@@ -285,6 +286,8 @@ function send_fetch_response(msgnum, fmat, uid)
 			}
 		}
 		else {
+			lock_cfg();
+			read_cfg(index.code, false);
 			if(saved_config[index.code] == undefined)
 				saved_config[index.code] = {};
 			if(saved_config[index.code].Seen == undefined)
@@ -292,6 +295,9 @@ function send_fetch_response(msgnum, fmat, uid)
 			if(saved_config[index.code].Seen[msgnum] != 1)
 				seen_changed=true;
 			saved_config[index.code].Seen[msgnum]=1;
+			save_cfg(false);
+			apply_seen();
+			unlock_cfg();
 			idx.attr |= MSG_READ;
 		}
 	}
@@ -536,8 +542,6 @@ function send_fetch_response(msgnum, fmat, uid)
 			}
 		}
 	}
-	if(seen_changed)
-		save_cfg();
 	if(seen_changed && !sent_flags) {
 		get_header();
 		resp += "FLAGS ("+calc_msgflags(idx.attr, hdr.netattr, base.subnum, msgnum, readonly)+") ";
@@ -794,7 +798,6 @@ var any_state_command_handlers = {
 			var elapsed=0;
 
 			client.socket.send("+ Ooo, Idling... my favorite.\r\n");
-			save_cfg();
 			while(1) {
 				line=client.socket.recvline(10240, 5);
 				if(line==null) {
@@ -844,6 +847,11 @@ var unauthenticated_command_handlers = {
 					tagged(tag, "NO", "No AUTH for you.");
 					return;
 				}
+				cfgfile=new File(format(system.data_dir+"user/%04d.imap", user.number));
+				if (!cfgfile.open(cfgfile.exists ? 'r+':'w+', true)) {
+					tagged(tag, "NO", "Can't open imap state file");
+					return;
+				}
 				tagged(tag, "OK", "Howdy.");
 				state=Authenticated;
 			}
@@ -1211,6 +1219,18 @@ function send_updates()
 	}
 }
 
+function get_base_code()
+{
+	var base_code;
+
+	if (base.cfg !== undefined)
+		base_code = base.cfg.code;
+	else
+		base_code = 'mail';
+
+	return base_code;
+}
+
 function read_index(base)
 {
 	var i;
@@ -1224,10 +1244,7 @@ function read_index(base)
 	index.subnum=base.subnum;
 	index.total=base.total_msgs;
 
-	if(base.cfg != undefined)
-		index.code=base.cfg.code;
-	else
-		index.code='mail';
+	index.code = get_base_code();
 	for(i=0; i<index.total; i++) {
 		idx=base.get_msg_index(true,i);
 		if(idx==null)
@@ -1252,30 +1269,58 @@ function read_index(base)
 	return(index);
 }
 
+function apply_seen()
+{
+	var i;
+
+	if (index.code == 'mail')
+		return;
+	for(i in index.idx) {
+		// Fake \Seen
+		index.idx[i].attr &= ~MSG_READ;
+		if(saved_config[index.code].Seen != undefined && saved_config[index.code].Seen[index.idx[i].number] == 1)
+			index.idx[i].attr |= MSG_READ;
+	}
+}
+
+function lock_cfg()
+{
+	while(!cfgfile.lock(0, 1))
+		mswait(10);
+}
+
+function unlock_cfg()
+{
+	cfgfile.unlock(0, 1);
+}
+
 function exit_func()
 {
 	close_sub();
-	save_cfg();
+	unlock_cfg();
+	save_cfg(true);
 }
 
-function save_cfg()
+function save_cfg(lck)
 {
 	var cfg;
 	var s;
 
 	if(user.number > 0) {
-		cfg=new File(format(system.data_dir+"user/%04d.imap", user.number));
-		if(cfg.open()) {
-			for(sub in saved_config) {
-				s=saved_config[sub].Seen;
-				delete saved_config[sub].Seen;
-				cfg.iniSetObject(sub,saved_config[sub]);
-				if(s != undefined)
-					cfg.iniSetObject(sub+'.seen',s);
-				saved_config[sub].Seen=s;
-			}
-			cfg.close();
+		if (lck)
+			lock_cfg();
+		cfgfile.rewind();
+		for(sub in saved_config) {
+			s=saved_config[sub].Seen;
+			delete saved_config[sub].Seen;
+			cfgfile.iniSetObject(sub,saved_config[sub]);
+			if(s != undefined)
+				cfgfile.iniSetObject(sub+'.seen',s);
+			saved_config[sub].Seen=s;
 		}
+		cfgfile.flush();
+		if (lck)
+			unlock_cfg();
 	}
 }
 
@@ -1285,7 +1330,10 @@ function close_sub()
 		msg_ptrs[base.subnum]=scan_ptr;
 		if(msg_ptrs[base.subnum]!=orig_ptrs[base.subnum]) {
 			if(base.subnum==-1) {
-				saved_config.mail.scan_ptr=scan_ptr;
+				if (saved_config.mail.scan_ptr!=scan_ptr) {
+					saved_config.mail.scan_ptr=scan_ptr;
+					save_cfg(true);
+				}
 			}
 			else
 				msg_area.sub[base.cfg.code].scan_ptr=scan_ptr;
@@ -1311,7 +1359,7 @@ function open_sub(sub)
 			msg_ptrs[base.subnum]=msg_area.sub[base.cfg.code].scan_ptr;
 		}
 	}
-	read_cfg(sub);
+	read_cfg(sub, true);
 
 	scan_ptr=orig_ptrs[base.subnum];
 	update_status();
@@ -1490,15 +1538,12 @@ var authenticated_command_handlers = {
 			}
 			if(base.cfg != undefined && orig_ptrs[base.subnum]==undefined)
 				orig_ptrs[base.subnum]=msg_area.sub[base.cfg.code].scan_ptr;
-			
-			if(base.cfg != undefined)
-				base_code=base.cfg.code;
-			else
-				base_code='mail';
+
+			base_code = get_base_code();
 			if (saved_config[base_code] != undefined)
 				old_saved = saved_config[base_code];
-			read_cfg(base_code);
-			index=read_index(base);
+			read_cfg(base_code, true);
+			apply_seen();
 			delete saved_config[base_code];
 			if (old_saved != undefined)
 				saved_config[base_code] = old_saved;
@@ -1593,23 +1638,26 @@ function do_store(seq, uid, item, data)
 			}
 		}
 		if(mod_seen && base.cfg != undefined) {
-			if(saved_config[base.cfg.code] == undefined)
+			lock_cfg();
+			read_cfg(base.cfg.code, false);
+			if(saved_config[base.cfg.code] == undefined) {
 				saved_config[base.cfg.code] = {};
+			}
 			if(saved_config[base.cfg.code].Seen == undefined) {
 				saved_config[base.cfg.code].Seen = {};
 				saved_config[base.cfg.code].Seen[header.number]=0;
 			}
 			saved_config[base.cfg.code].Seen[seq[i]] ^= 1;
-			changed=true;
+			save_cfg(false);
+			apply_seen();
+			unlock_cfg();
 		}
 		if(!silent)
 			send_fetch_response(seq[i], ["FLAGS"], uid);
 	}
 	js.gc();
-	if(changed) {
-		save_cfg();
+	if(changed)
 		index=read_index(base);
-	}
 }
 
 function datestr(date)
@@ -1963,6 +2011,8 @@ var selected_command_handlers = {
 			var data_items=parse_data_items(args[2]);
 			var i;
 
+			read_cfg(get_base_code(), true);
+			apply_seen();
 			for(i in seq) {
 				send_fetch_response(seq[i], data_items, false);
 			}
@@ -2012,6 +2062,8 @@ var selected_command_handlers = {
 					}
 					seq=parse_seq_set(args[2],true);
 					data_items=parse_data_items(args[3]);
+					read_cfg(get_base_code(), true);
+					apply_seen();
 					for(i in seq) {
 						send_fetch_response(seq[i], data_items, true);
 					}
@@ -2046,9 +2098,8 @@ var selected_command_handlers = {
 	},
 };
 
-function read_cfg(sub)
+function read_cfg(sub, lck)
 {
-	var cfg=new File(format(system.data_dir+"user/%04d.imap",user.number));
 	var secs;
 	var sec;
 	var seen;
@@ -2057,30 +2108,32 @@ function read_cfg(sub)
 	if(saved_config[sub]==undefined)
 		saved_config[sub]={};
 
-	if(cfg.open("r+")) {
-		secs=cfg.iniGetSections();
-		for(sec in secs) {
-			if(secs[sec].search(/\.seen$/)!=-1) {
-				this_sec = secs[sec].replace(/(?:\.seen)+$/,'');
-				if(saved_config[this_sec]==undefined)
-					saved_config[this_sec]={};
-				saved_config[this_sec].Seen=cfg.iniGetObject(secs[sec]);
-				if(saved_config[this_sec].Seen==null)
-					saved_config[this_sec].Seen={};
-			}
-			else {
-				if(saved_config[secs[sec]] != undefined && saved_config[secs[sec]].Seen != undefined)
-					seen = saved_config[secs[sec]].Seen;
-				else
-					seen = {};
-				saved_config[secs[sec]]=cfg.iniGetObject(secs[sec]);
-				if(saved_config[secs[sec]]==null)
-					saved_config[secs[sec]]={};
-				saved_config[secs[sec]].Seen=seen;
-			}
+	if (lck)
+		lock_cfg();
+	cfgfile.rewind();
+	secs=cfgfile.iniGetSections();
+	for(sec in secs) {
+		if(secs[sec].search(/\.seen$/)!=-1) {
+			this_sec = secs[sec].replace(/(?:\.seen)+$/,'');
+			if(saved_config[this_sec]==undefined)
+				saved_config[this_sec]={};
+			saved_config[this_sec].Seen=cfgfile.iniGetObject(secs[sec]);
+			if(saved_config[this_sec].Seen==null)
+				saved_config[this_sec].Seen={};
+		}
+		else {
+			if(saved_config[secs[sec]] != undefined && saved_config[secs[sec]].Seen != undefined)
+				seen = saved_config[secs[sec]].Seen;
+			else
+				seen = {};
+			saved_config[secs[sec]]=cfgfile.iniGetObject(secs[sec]);
+			if(saved_config[secs[sec]]==null)
+				saved_config[secs[sec]]={};
+			saved_config[secs[sec]].Seen=seen;
 		}
-		cfg.close();
 	}
+	if (lck)
+		unlock_cfg();
 
 	if(sub == 'mail') {
 		msg_ptrs[-1]=saved_config.mail.scan_ptr;