diff --git a/exec/load/sbbslist_lib.js b/exec/load/sbbslist_lib.js
index 756ce0288373748edc456e48c539ff6eeede1f63..9b88ee4a73f77c87d087619911fe5758a6f7cddf 100644
--- a/exec/load/sbbslist_lib.js
+++ b/exec/load/sbbslist_lib.js
@@ -1,4 +1,5 @@
 // $Id$
+// @format.tab-size 4
 
 // Synchronet BBS List (SBL) v4 Library
 
@@ -402,39 +403,78 @@ function parse(f)
 	return list;
 }
 
+function lock_fname()
+{
+	return list_fname + '.lock';
+}
+
+function lock(op, timeout /* in seconds */, max)
+{
+	var start = time();
+	if(timeout === undefined)
+		timeout = 60;
+	if(max === undefined)
+		max = 24 * 60 * 60;
+
+	while(!file_mutex(lock_fname(), op, max)) {
+		if(time() - start >= timeout) {
+        		log(LOG_ERR, "SBBSLIST: Timeout locking " + list_fname + " for " + op);
+			return false;
+		}
+		sleep(1000);
+	}
+	return true;
+}
+
+function unlock()
+{
+	return file_remove(lock_fname());
+}
+
 function read_list()
 {
+	if(!lock("read"))
+		return false;
     var f = new File(list_fname);
     log(LOG_DEBUG, "Opening list file: " + f.name);
     if(!f.open("r")) {
         log(LOG_ERR, "SBBSLIST: Error " + f.error + " opening " + f.name);
+		unlock();
         return [];
     }
 	var list = parse(f);
     f.close();
+	unlock();
     return list;
 }
 
 function write_list(list)
 {
+	if(!lock("write"))
+		return false;
     var out = new File(list_fname);
     log(LOG_DEBUG, "SBBSLIST: Opening / creating list file: " + list_fname);
     if(!out.open("w+")) {
         log(LOG_ERR, "SBBSLIST: Error " + out.error + " creating " + out.name);
+		unlock();
         return false;
     }
     log(LOG_DEBUG, "SBBSLIST: Writing list file: " + out.name + " (" + list.length + " BBS entries)");
     out.write(JSON.stringify(list, null, 4));
     out.close();
+	unlock();
     return true;
 }
 
 function append(bbs)
 {
+	if(!lock("append"))
+		return false;
     var f = new File(list_fname);
     log(LOG_DEBUG, "SBBSLIST: Opening / creating list file: " + list_fname);
     if(!f.open(f.exists ? 'r+':'w+')) {
         log(LOG_ERR, "SBBSLIST: Error " + f.error + " creating " + f.name);
+		unlock();
         return false;
     }
 	var list = parse(f);
@@ -443,21 +483,26 @@ function append(bbs)
 	f.truncate();
     f.write(JSON.stringify(list, null, 4));
     f.close();
+	unlock();
     return true;
 }
 
 function remove(bbs)
 {
+	if(!lock("remove"))
+		return false;
     var f = new File(list_fname);
     log(LOG_INFO, "SBBSLIST: Opening / creating list file: " + list_fname);
     if(!f.open('r+')) {
         log(LOG_ERR, "SBBSLIST: Error " + f.error + " opening " + f.name);
+		unlock();
         return false;
     }
     var list = parse(f);
 	var index = find_value(list, "name", bbs.name); 
 	if(index < 0 ) {
 		f.close();
+		unlock();
 		return false;
 	}
 	list.splice(index, 1);
@@ -465,21 +510,26 @@ function remove(bbs)
 	f.truncate();
     f.write(JSON.stringify(list, null, 4));
     f.close();
+	unlock();
     return true;
 }
 
 function replace(bbs)
 {
+	if(!lock("replace"))
+		return false;
     var f = new File(list_fname);
     log(LOG_INFO, "SBBSLIST: Opening / creating list file: " + list_fname);
     if(!f.open('r+')) {
         log(LOG_ERR, "SBBSLIST: Error " + f.error + " opening " + f.name);
+		unlock();
         return false;
     }
     var list = parse(f);
 	var index = find_value(list, "name", bbs.name); 
 	if(index < 0 ) {
 		f.close();
+		unlock();
 		return false;
 	}
 	list[index] = bbs;
@@ -487,6 +537,7 @@ function replace(bbs)
 	f.truncate();
     f.write(JSON.stringify(list, null, 4));
     f.close();
+	unlock();
     return true;
 }