diff --git a/exec/addfiles.js b/exec/addfiles.js
index 901db0f22a196f3180eb29ca610a6370f092adce..37da051ee8ce66218367251822c75ebab23651b3 100644
--- a/exec/addfiles.js
+++ b/exec/addfiles.js
@@ -3,7 +3,7 @@
 
 require("sbbsdefs.js", 'LEN_FDESC');
 
-var lib = load({}, "filelist_lib.js");
+const lib = load({}, "filelist_lib.js");
 
 "use strict";
 
diff --git a/src/conio/cterm.c b/src/conio/cterm.c
index 2ff39d654a7a0c3884b71fbcdba8c402157a40a4..ee36379feee5cdb90aed77a76175d95d2a4ad416 100644
--- a/src/conio/cterm.c
+++ b/src/conio/cterm.c
@@ -836,7 +836,7 @@ prestel_apply_ctrl_before(struct cterminal *cterm, uint8_t ch)
 		case 73: // Steady
 			cterm->attr &= 0x7f;
 			attr2palette(cterm->attr, &cterm->fg_color, &cterm->bg_color);
-			if (CTERM_EXTATTR_PRESTEL_DOUBLE_HEIGHT)
+			if (cterm->extattr & CTERM_EXTATTR_PRESTEL_DOUBLE_HEIGHT)
 				cterm->bg_color |= 0x01000000;
 			break;
 		case 76: // Normal Height
@@ -868,49 +868,46 @@ prestel_apply_ctrl_before(struct cterminal *cterm, uint8_t ch)
 	}
 }
 
+static void
+prestel_colour(struct cterminal *cterm, bool alpha, int colour)
+{
+	cterm->attr &= 0xF7;
+	set_fgattr(cterm, colour);
+	cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_CONCEAL);
+	if (alpha)
+		cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_MOSAIC);
+	else
+		cterm->extattr |= CTERM_EXTATTR_PRESTEL_MOSAIC;
+	cterm->prestel_last_mosaic = 32;
+}
+
 static void
 prestel_apply_ctrl_after(struct cterminal *cterm, uint8_t ch)
 {
 	switch(ch) {
 		case 64: // Alphanumeric Black
-			set_fgattr(cterm, BLACK);
-			cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_MOSAIC | CTERM_EXTATTR_PRESTEL_CONCEAL);
-			cterm->prestel_last_mosaic = 32;
+			prestel_colour(cterm, true, BLACK);
 			break;
 		case 65: // Alphanumeric Red
-			set_fgattr(cterm, RED);
-			cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_MOSAIC | CTERM_EXTATTR_PRESTEL_CONCEAL);
-			cterm->prestel_last_mosaic = 32;
+			prestel_colour(cterm, true, RED);
 			break;
 		case 66: // Alphanumeric Green
-			set_fgattr(cterm, GREEN);
-			cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_MOSAIC | CTERM_EXTATTR_PRESTEL_CONCEAL);
-			cterm->prestel_last_mosaic = 32;
+			prestel_colour(cterm, true, GREEN);
 			break;
 		case 67: // Alphanumeric Yellow
-			set_fgattr(cterm, BROWN);
-			cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_MOSAIC | CTERM_EXTATTR_PRESTEL_CONCEAL);
-			cterm->prestel_last_mosaic = 32;
+			prestel_colour(cterm, true, YELLOW);
 			break;
 		case 68: // Alphanumeric Blue
-			set_fgattr(cterm, BLUE);
-			cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_MOSAIC | CTERM_EXTATTR_PRESTEL_CONCEAL);
-			cterm->prestel_last_mosaic = 32;
+			prestel_colour(cterm, true, BLUE);
 			break;
 		case 69: // Alphanumeric Magenta
-			set_fgattr(cterm, MAGENTA);
-			cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_MOSAIC | CTERM_EXTATTR_PRESTEL_CONCEAL);
-			cterm->prestel_last_mosaic = 32;
+			prestel_colour(cterm, true, MAGENTA);
 			break;
 		case 70: // Alphanumeric Cyan
-			set_fgattr(cterm, CYAN);
-			cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_MOSAIC | CTERM_EXTATTR_PRESTEL_CONCEAL);
-			cterm->prestel_last_mosaic = 32;
+			prestel_colour(cterm, true, CYAN);
 			break;
 		case 71: // Alphanumeric White
-			set_fgattr(cterm, LIGHTGRAY);
-			cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_MOSAIC | CTERM_EXTATTR_PRESTEL_CONCEAL);
-			cterm->prestel_last_mosaic = 32;
+			prestel_colour(cterm, true, WHITE);
 			break;
 		case 72: // Flash
 			cterm->attr |= 0x80;
@@ -924,52 +921,28 @@ prestel_apply_ctrl_after(struct cterminal *cterm, uint8_t ch)
 			cterm->prestel_last_mosaic = 32;
 			break;
 		case 80: // Mosaic Black
-			set_fgattr(cterm, BLACK);
-			cterm->extattr |= CTERM_EXTATTR_PRESTEL_MOSAIC;
-			cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_CONCEAL);
-			cterm->prestel_last_mosaic = 32;
+			prestel_colour(cterm, false, BLACK);
 			break;
 		case 81: // Mosaic Red
-			set_fgattr(cterm, RED);
-			cterm->extattr |= CTERM_EXTATTR_PRESTEL_MOSAIC;
-			cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_CONCEAL);
-			cterm->prestel_last_mosaic = 32;
+			prestel_colour(cterm, false, RED);
 			break;
 		case 82: // Mosaic Green
-			set_fgattr(cterm, GREEN);
-			cterm->extattr |= CTERM_EXTATTR_PRESTEL_MOSAIC;
-			cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_CONCEAL);
-			cterm->prestel_last_mosaic = 32;
+			prestel_colour(cterm, false, GREEN);
 			break;
 		case 83: // Mosaic Yellow
-			set_fgattr(cterm, BROWN);
-			cterm->extattr |= CTERM_EXTATTR_PRESTEL_MOSAIC;
-			cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_CONCEAL);
-			cterm->prestel_last_mosaic = 32;
+			prestel_colour(cterm, false, YELLOW);
 			break;
 		case 84: // Mosaic Blue
-			set_fgattr(cterm, BLUE);
-			cterm->extattr |= CTERM_EXTATTR_PRESTEL_MOSAIC;
-			cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_CONCEAL);
-			cterm->prestel_last_mosaic = 32;
+			prestel_colour(cterm, false, BLUE);
 			break;
 		case 85: // Mosaic Magenta
-			set_fgattr(cterm, MAGENTA);
-			cterm->extattr |= CTERM_EXTATTR_PRESTEL_MOSAIC;
-			cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_CONCEAL);
-			cterm->prestel_last_mosaic = 32;
+			prestel_colour(cterm, false, MAGENTA);
 			break;
 		case 86: // Mosaic Cyan
-			set_fgattr(cterm, CYAN);
-			cterm->extattr |= CTERM_EXTATTR_PRESTEL_MOSAIC;
-			cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_CONCEAL);
-			cterm->prestel_last_mosaic = 32;
+			prestel_colour(cterm, false, CYAN);
 			break;
 		case 87: // Mosaic White
-			set_fgattr(cterm, LIGHTGRAY);
-			cterm->extattr |= CTERM_EXTATTR_PRESTEL_MOSAIC;
-			cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_CONCEAL);
-			cterm->prestel_last_mosaic = 32;
+			prestel_colour(cterm, false, WHITE);
 			break;
 		case 95: // Release Mosaics
 			cterm->extattr &= ~(CTERM_EXTATTR_PRESTEL_HOLD);
@@ -4921,7 +4894,7 @@ struct cterminal* cterm_init(int height, int width, int xpos, int ypos, int back
 	if (cterm->emulation == CTERM_EMULATION_PRESTEL) {
 		cterm->cursor = _NOCURSOR;
 		SETCURSORTYPE(cterm->cursor);
-		memcpy(cterm->prestel_data[0], "0000000000??????", PRESTEL_MEM_SLOT_SIZE);
+		memcpy(cterm->prestel_data[0], "????????????????", PRESTEL_MEM_SLOT_SIZE);
 		memcpy(cterm->prestel_data[1], ":2:?4967?89:1???", PRESTEL_MEM_SLOT_SIZE);
 		memcpy(cterm->prestel_data[2], ":1632?123?456???", PRESTEL_MEM_SLOT_SIZE);
 		memcpy(cterm->prestel_data[3], ";???????????????", PRESTEL_MEM_SLOT_SIZE);
diff --git a/src/sbbs3/answer.cpp b/src/sbbs3/answer.cpp
index d2952b9e85d60ef64b958c31d71ceb0a2d222adf..34ea886662c5dd19d403b081bb127bbe7adda544 100644
--- a/src/sbbs3/answer.cpp
+++ b/src/sbbs3/answer.cpp
@@ -452,7 +452,7 @@ bool sbbs_t::answer()
 								SAFECOPY(useron.ipaddr, client_ipaddr);
 								SAFECOPY(useron.comp, client_name);
 								useron.logons++;
-								putuserdat(&cfg,&useron);
+								putuserdat(&useron);
 								snprintf(str, sizeof(str), "(%04u)  %-25s  %s Logon"
 									,useron.number, useron.alias, client.protocol);
 								logline("++", str);
diff --git a/src/sbbs3/data_ovl.cpp b/src/sbbs3/data_ovl.cpp
index 6fd173ac2abb69d5f8294e278230bc62597bdc1c..d6cf70d0fc2cd306f1f9e4cb965d94f2b7d4c6a2 100644
--- a/src/sbbs3/data_ovl.cpp
+++ b/src/sbbs3/data_ovl.cpp
@@ -89,6 +89,20 @@ uint sbbs_t::finduserstr(uint usernumber, enum user_field fnum, const char* str
 	return(i);
 }
 
+/****************************************************************************/
+/* An error checking/logging wrapper for userdat.c putuserdat()				*/
+/****************************************************************************/
+bool sbbs_t::putuserdat(user_t* user)
+{
+	int result = ::putuserdat(&cfg, user);
+	if(result != 0) {
+		lprintf(LOG_ERR, "!Error %d writing user data for user #%d"
+			,result, user->number);
+		return false;
+	}
+	return true;
+}
+
 bool sbbs_t::putuserstr(int usernumber, enum user_field fnum, const char *str)
 {
 	int result = ::putuserstr(&cfg, usernumber, fnum, str);
diff --git a/src/sbbs3/findstr.c b/src/sbbs3/findstr.c
index 4f85a1e8af2fb62e99835e4875914d1dd67d265c..62778ecccd603fc42f9c4c6b6d86609c1e16a000 100644
--- a/src/sbbs3/findstr.c
+++ b/src/sbbs3/findstr.c
@@ -240,6 +240,7 @@ bool find2strs(const char* str1, const char* str2, const char* fname, char* meta
 static char* process_findstr_item(size_t index, char *str, void* cbdata)
 {
 	SKIP_WHITESPACE(str);
+	truncnl(str);
 	return c_unescape_str(str);
 }
 
diff --git a/src/sbbs3/ftpsrvr.c b/src/sbbs3/ftpsrvr.c
index 8115f23d819209648aa77dec9268b0b72c4eae3c..216752481fb3e99bbc89810a84a9f4a9306684a8 100644
--- a/src/sbbs3/ftpsrvr.c
+++ b/src/sbbs3/ftpsrvr.c
@@ -2628,7 +2628,9 @@ static void ctrl_thread(void* arg)
 			SAFECOPY(user.comp,host_name);
 			SAFECOPY(user.ipaddr,host_ip);
 			user.logontime=(time32_t)logintime;
-			putuserdat(&scfg, &user);
+			if((result = putuserdat(&scfg, &user)) != 0)
+				lprintf(LOG_ERR, "%04d [%s] <%s> !Error %d writing user data for user #%d"
+					,sock, host_ip, user.alias, result, user.number);
 			mqtt_user_login(&mqtt, &client);
 
 #ifdef _WIN32
diff --git a/src/sbbs3/logon.cpp b/src/sbbs3/logon.cpp
index 711fbefbd0f01f099a0ee4b27d02202bc83fed5e..41721fe5c9021e3ed3d629ad2df9091f04dbdbd2 100644
--- a/src/sbbs3/logon.cpp
+++ b/src/sbbs3/logon.cpp
@@ -443,7 +443,7 @@ bool sbbs_t::logon()
 	SAFECOPY(useron.ipaddr, client_ipaddr);
 	SAFECOPY(useron.comp, client_name);
 	useron.logons++;
-	putuserdat(&cfg,&useron);
+	putuserdat(&useron);
 	getmsgptrs();
 	sys_status|=SS_USERON;          /* moved from further down */
 
diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h
index 3ef8e9faf67a38b49d1b46febd0f3a78ac34c085..1f7a5c343342b4c2c8e2b782bda599f0be6b6b5d 100644
--- a/src/sbbs3/sbbs.h
+++ b/src/sbbs3/sbbs.h
@@ -805,6 +805,7 @@ public:
 	bool	putusermisc(int usernumber, uint32_t value);
 	bool	putuserchat(int usernumber, uint32_t value);
 	bool	putuserqwk(int usernumber, uint32_t value);
+	bool	putuserdat(user_t*);
 
 	uint	finduserstr(uint usernumber, enum user_field, const char* str
 				,bool del=false, bool next=false);
diff --git a/src/sbbs3/sbbs3.sln b/src/sbbs3/sbbs3.sln
index 1e97065384e81c1c107fe6b12ce6c83d2304c4cf..9d4275eee20e94413f072534370707c837e8fcfb 100644
--- a/src/sbbs3/sbbs3.sln
+++ b/src/sbbs3/sbbs3.sln
@@ -102,6 +102,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "conio_gdi", "..\conio\conio
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sftp", "..\sftp\sftp.vcxproj", "{4C69A1D2-182A-45D3-AD33-54A8A91B387D}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "trashman", "trashman.vcxproj", "{2BE1C8F2-50CE-44B0-A341-92B24E2D3DB4}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Win32 = Debug|Win32
@@ -275,6 +277,10 @@ Global
 		{4C69A1D2-182A-45D3-AD33-54A8A91B387D}.Debug|Win32.Build.0 = Debug|Win32
 		{4C69A1D2-182A-45D3-AD33-54A8A91B387D}.Release|Win32.ActiveCfg = Release|Win32
 		{4C69A1D2-182A-45D3-AD33-54A8A91B387D}.Release|Win32.Build.0 = Release|Win32
+		{2BE1C8F2-50CE-44B0-A341-92B24E2D3DB4}.Debug|Win32.ActiveCfg = Debug|Win32
+		{2BE1C8F2-50CE-44B0-A341-92B24E2D3DB4}.Debug|Win32.Build.0 = Debug|Win32
+		{2BE1C8F2-50CE-44B0-A341-92B24E2D3DB4}.Release|Win32.ActiveCfg = Release|Win32
+		{2BE1C8F2-50CE-44B0-A341-92B24E2D3DB4}.Release|Win32.Build.0 = Release|Win32
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/src/sbbs3/services.c b/src/sbbs3/services.c
index 2cff60677b6aa859af3784094ba2c5b26fdc8c26..bc8a3540acccd3dba3fe3b6a39f44aebff84ca77 100644
--- a/src/sbbs3/services.c
+++ b/src/sbbs3/services.c
@@ -475,7 +475,12 @@ js_login(JSContext *cx, uintN argc, jsval *arglist)
 		client->user.ltoday++;
 	}
 
-	putuserdat(&scfg,&client->user);
+	int result = putuserdat(&scfg,&client->user);
+	if(result != 0) {
+		lprintf(LOG_ERR, "%04d %s !Error %d writing user data for user #%d"
+			,client->socket,client->service->protocol
+			,result, client->user.number);
+	}
 	if(client->subscan==NULL) {
 		client->subscan=(subscan_t*)calloc(scfg.total_subs, sizeof(subscan_t));
 		if(client->subscan==NULL)
diff --git a/src/sbbs3/trashman.c b/src/sbbs3/trashman.c
index e2b7b5e7817f93854814494105795bb569d1962f..ad730262d9b23f6a8a8892561700d625e7d5d79e 100644
--- a/src/sbbs3/trashman.c
+++ b/src/sbbs3/trashman.c
@@ -20,14 +20,15 @@
  ****************************************************************************/
 
 #include "trash.h"
-//#include "datewrap.h"
-//#include "xpdatetime.h"
-//#include "ini_file.h"
-//#include "scfglib.h"
 #include "findstr.h"
 #include "nopen.h"
+#include "git_branch.h"
+#include "git_hash.h"
 
+bool test = false;
 int verbosity = 0;
+int max_age = 0;
+const char* prot = NULL;
 
 int maint(const char* fname)
 {
@@ -37,46 +38,69 @@ int maint(const char* fname)
 		perror(fname);
 		return -1;
 	}
-	FILE* fp = fnopen(NULL, fname, O_WRONLY|O_TRUNC);
+	FILE* fp;
+	if(test)
+		fp = fopen(_PATH_DEVNULL, "w");
+	else
+		fp = fnopen(NULL, fname, O_WRONLY|O_TRUNC);
 	if(fp == NULL) {
-		perror(fname);
+		perror(test ? _PATH_DEVNULL : fname);
 		return -2;
 	}
 	time_t now = time(NULL);
 	for(int i = 0; list[i] != NULL; ++i) {
 		struct trash trash;
 		char item[256];
-		if(!trash_parse_details(list[i], &trash, item, sizeof item)) {
-			fputs(list[i], fp);
+		if(!trash_parse_details(list[i], &trash, item, sizeof item)
+			|| (prot != NULL && stricmp(trash.prot, prot) != 0)) {
+			fprintf(fp, "%s\n", list[i]);
 			continue;
 		}
 		if(verbosity > 1) {
 			char details[256];
-			printf("%s %s\n", item, trash_details(&trash, details, sizeof details));
+			printf("%s: %s %s\n", fname, item, trash_details(&trash, details, sizeof details));
 		}
 		if(trash.expires && trash.expires < now) {
 			if(verbosity > 0)
-				printf("%s expired %s", item, ctime(&trash.expires));
+				printf("%s: %s expired %s", fname, item, ctime(&trash.expires));
 			++removed;
 			continue;
 		}
-		fputs(list[i], fp);
+		if(max_age != 0 && trash.added != 0) {
+			int age = (int)(now - trash.added);
+			if(age > 0 && (age/=(24*60*60)) > max_age) {
+				if(verbosity > 0)
+					printf("%s: %s is %d days old\n", fname, item, age);
+				++removed;
+				continue;
+			}
+		}
+		fprintf(fp, "%s\n", list[i]);
 	}
 	fclose(fp);
 	strListFree(&list);
+	if(removed || verbosity > 0)
+		printf("%s: %d items %sremoved\n"
+			,fname, removed, test ? "would have been " : "");
 	return removed;
 }
 
 int usage(const char* prog)
 {
-	printf("usage: %s [-v][...] /path/to/file1.can [/path/to/file2.can][...]\n"
+	printf("\nusage: %s [-opt][...] /path/to/file1.can [/path/to/file2.can][...]\n"
 		,getfname(prog));
+	printf("\noptions:\n");
+	printf("     -a<days> specify maximum age of filter items, in days\n");
+	printf("     -p<prot> only manage filters for specified protocol\n");
+	printf("     -t       run in test (read-only) mode\n");
+	printf("     -v       increase verbosity of output\n");
 	return EXIT_SUCCESS;
 }
 
 int main(int argc, const char** argv)
 {
-	printf("\nSynchronet trash/filter file manager v1.0\n");
+	printf("\nSynchronet Trash Can (Filter File) Manager  v1.0  %s/%s\n"
+		,GIT_BRANCH, GIT_HASH);
 
 	if(argc < 2)
 		return usage(argv[0]);
@@ -84,15 +108,28 @@ int main(int argc, const char** argv)
 		const char* arg = argv[i];
 		if(*arg != '-')
 			continue;
-		switch(arg[1]) {
+		++arg;
+		switch(*arg) {
+			case 't':
+				test = true;
+				break;
 			case 'v':
-				++verbosity;
+				do {
+					++verbosity;
+				} while(*(++arg) == 'v');
+				break;
+			case 'a':
+				max_age = atoi(++arg);
+				break;
+			case 'p':
+				prot = ++arg;
 				break;
 			default:
 				return usage(argv[0]);
 		}
 	}
 	int total = 0;
+	int files = 0;
 	for(int i = 1; i < argc; ++i) {
 		const char* arg = argv[i];
 		if(*arg == '-')
@@ -101,7 +138,9 @@ int main(int argc, const char** argv)
 		if(removed < 0)
 			return EXIT_FAILURE;
 		total += removed;
+		++files;
 	}
-	printf("%d total items removed\n", total);
+	if(files > 1)
+		printf("%d total items %sremoved from %d files\n", total, test ? "would have been " : "", files);
 	return EXIT_SUCCESS;
 }
diff --git a/src/sbbs3/trashman.vcxproj b/src/sbbs3/trashman.vcxproj
new file mode 100644
index 0000000000000000000000000000000000000000..d8ce360fa5766b7602ec7c4514344f392fcf5a06
--- /dev/null
+++ b/src/sbbs3/trashman.vcxproj
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{2BE1C8F2-50CE-44B0-A341-92B24E2D3DB4}</ProjectGuid>
+    <RootNamespace>trashman</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v141_xp</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v141_xp</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
+    <Import Project="..\build\target_ia32.props" />
+    <Import Project="..\smblib\smblib.props" />
+    <Import Project="..\xpdev\xpdev.props" />
+    <Import Project="..\hash\hash.props" />
+    <Import Project="..\build\undeprecate.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
+    <Import Project="..\build\target_ia32.props" />
+    <Import Project="..\smblib\smblib.props" />
+    <Import Project="..\xpdev\xpdev.props" />
+    <Import Project="..\hash\hash.props" />
+    <Import Project="..\build\undeprecate.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\msvc.win32.exe.release\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\msvc.win32.release\trashman\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\msvc.win32.exe.debug\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\msvc.win32.debug\trashman\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Midl>
+      <TypeLibraryName>.\msvc.win32.exe.release/trashman.tlb</TypeLibraryName>
+      <HeaderFileName>
+      </HeaderFileName>
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>NDEBUG;WRAPPER_EXPORTS;WIN32;_CONSOLE;SBBS_EXPORTS;NO_SOCKET_SUPPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeaderOutputFile>.\msvc.win32.release\trashman/trashman.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>.\msvc.win32.release\trashman/</AssemblerListingLocation>
+      <ObjectFileName>.\msvc.win32.release\trashman/</ObjectFileName>
+      <ProgramDataBaseFileName>.\msvc.win32.release\trashman/</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Link>
+      <OutputFile>.\msvc.win32.exe.release/trashman.exe</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <ProgramDatabaseFile>.\msvc.win32.exe.release/trashman.pdb</ProgramDatabaseFile>
+      <GenerateMapFile>true</GenerateMapFile>
+      <MapFileName>.\msvc.win32.release\trashman/trashman.map</MapFileName>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+      <IgnoreSpecificDefaultLibraries>libcd.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+      <AdditionalDependencies>netapi32.lib;wsock32.lib;setargv.obj;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+    <Bscmake>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <OutputFile>.\msvc.win32.exe.release/trashman.bsc</OutputFile>
+    </Bscmake>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Midl>
+      <TypeLibraryName>.\msvc.win32.exe.debug/trashman.tlb</TypeLibraryName>
+      <HeaderFileName>
+      </HeaderFileName>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_DEBUG;WRAPPER_EXPORTS;WIN32;_CONSOLE;SBBS_EXPORTS;NO_SOCKET_SUPPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <PrecompiledHeaderOutputFile>.\msvc.win32.debug\trashman/trashman.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>.\msvc.win32.debug\trashman/</AssemblerListingLocation>
+      <ObjectFileName>.\msvc.win32.debug\trashman/</ObjectFileName>
+      <ProgramDataBaseFileName>.\msvc.win32.debug\trashman/</ProgramDataBaseFileName>
+      <BrowseInformation>true</BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Link>
+      <OutputFile>.\msvc.win32.exe.debug/trashman.exe</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>.\msvc.win32.exe.debug/trashman.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+      <IgnoreSpecificDefaultLibraries>libcd.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+      <AdditionalDependencies>netapi32.lib;wsock32.lib;setargv.obj;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+    <Bscmake>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <OutputFile>.\msvc.win32.exe.debug/trashman.bsc</OutputFile>
+    </Bscmake>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="findstr.c" />
+    <ClCompile Include="nopen.c" />
+    <ClCompile Include="trash.c" />
+    <ClCompile Include="trashman.c">
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\xpdev\xpdev.vcxproj">
+      <Project>{7428a1e8-56b7-4868-9c0e-29d031689feb}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/src/sbbs3/userdat.c b/src/sbbs3/userdat.c
index 42d8a3f68c45e3a1e05358456f6ba13566d5e2a7..6169e7f2004725c67fa48b20fce5e6041f979e7a 100644
--- a/src/sbbs3/userdat.c
+++ b/src/sbbs3/userdat.c
@@ -279,8 +279,6 @@ bool lockuserdat(int file, unsigned user_number)
 
 	off_t offset = userdatoffset(user_number);
 
-	if(lseek(file, offset, SEEK_SET) != offset)
-		return false;
 	unsigned attempt=0;
 	while(attempt < LOOP_USERDAT && lock(file, offset, USER_RECORD_LINE_LEN) == -1) {
 		attempt++;
@@ -783,7 +781,10 @@ int putuserdat(scfg_t* cfg, user_t* user)
 		return(-4);
 	}
 
-	seekuserdat(file, user->number);
+	if(!seekuserdat(file, user->number)) {
+		close(file);
+		return -5;
+	}
 	if(!lockuserdat(file, user->number)) {
 		close(file);
 		return(-2);
@@ -2612,7 +2613,8 @@ int putuserstr(scfg_t* cfg, int usernumber, enum user_field fnum, const char *st
 		unlockuserdat(file, usernumber);
 	}
 	close(file);
-	dirtyuserdat(cfg, usernumber);
+	if(retval == 0)
+		dirtyuserdat(cfg, usernumber);
 	return retval;
 }
 
diff --git a/src/sbbs3/useredit.cpp b/src/sbbs3/useredit.cpp
index 768f8ad1b64e8e20a76fd1332849e09540f84bec..0e971907fb5bcf16ba919a6fd1726f78aa84a94d 100644
--- a/src/sbbs3/useredit.cpp
+++ b/src/sbbs3/useredit.cpp
@@ -78,7 +78,7 @@ void sbbs_t::useredit(int usernumber)
 		if(strcmp(str,tmp) && user.ltoday) {
 			user.ltoday=user.ttoday=user.ptoday=user.etoday=user.textra=0;
 			user.freecdt=cfg.level_freecdtperday[user.level];
-			putuserdat(&cfg,&user); 	/* Leave alone */
+			putuserdat(&user); 	/* Leave alone */
 		}
 		char user_pass[LEN_PASS + 1];
 		SAFECOPY(user_pass, user.pass);
@@ -494,7 +494,7 @@ void sbbs_t::useredit(int usernumber)
 					else
 						user.expire+=((long)cfg.val_expire[i]*24L*60L*60L); 
 				}
-				putuserdat(&cfg,&user);
+				putuserdat(&user);
 				break;
 			case 'W':
 				bputs(text[UeditPassword]);
@@ -516,7 +516,7 @@ void sbbs_t::useredit(int usernumber)
 					if((int)i>0) {
 						user.number=i;
 						putusername(&cfg,user.number,user.alias);
-						putuserdat(&cfg,&user); 
+						putuserdat(&user);
 					} 
 				}
 				break;
diff --git a/src/sbbs3/websrvr.c b/src/sbbs3/websrvr.c
index f7fc816aeb41a63e0eb07b60c6417994d3758161..9783a8af95f9fa038d29ec50d31bb6aea450a53a 100644
--- a/src/sbbs3/websrvr.c
+++ b/src/sbbs3/websrvr.c
@@ -1654,7 +1654,12 @@ void http_logon(http_session_t * session, user_t *usr)
 		SAFECOPY(session->user.comp, session->host_name);
 		SAFECOPY(session->user.ipaddr, session->host_ip);
 		session->user.logontime = (time32_t)session->logon_time;
-		putuserdat(&scfg, &session->user);
+		int result = putuserdat(&scfg, &session->user);
+		if(result != 0)
+			lprintf(LOG_ERR, "%04d %s [%s] <%s> !Error %d writing user data for user #%d"
+				,session->socket, session->client.protocol, session->host_ip
+				,session->username, session->user.number);
+
 	}
 	SAFECOPY(session->client.user, session->username);
 	session->client.usernum = session->user.number;
diff --git a/src/syncterm/CHANGES b/src/syncterm/CHANGES
index 26004e6e6ee874b04ff711baca8f0c50611af4cd..5e79bb67fe1b5e85feca70308beeef1a4f41cec1 100644
--- a/src/syncterm/CHANGES
+++ b/src/syncterm/CHANGES
@@ -1,3 +1,8 @@
+Version 1.2rc6
+--------------
+Prestel fixes for Steady and Concealed modes
+Set default prestel ID to zero characters for CCl4
+
 Version 1.2rc5
 --------------
 Fix RIP parsing when passed fragmented ANSI sequences