diff --git a/src/sbbs3/makeuser.c b/src/sbbs3/makeuser.c
new file mode 100644
index 0000000000000000000000000000000000000000..9884c4e1afc59e08e8b17dd6af81f9737cd45d63
--- /dev/null
+++ b/src/sbbs3/makeuser.c
@@ -0,0 +1,239 @@
+/* makeuser.c */
+
+/* Program to add a user to a Synchronet user database */
+
+/* $Id$ */
+
+/****************************************************************************
+ * @format.tab-size 4		(Plain Text/Source Code File Header)			*
+ * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
+ *																			*
+ * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html		*
+ *																			*
+ * This program is free software; you can redistribute it and/or			*
+ * modify it under the terms of the GNU General Public License				*
+ * as published by the Free Software Foundation; either version 2			*
+ * of the License, or (at your option) any later version.					*
+ * See the GNU General Public License for more details: gpl.txt or			*
+ * http://www.fsf.org/copyleft/gpl.html										*
+ *																			*
+ * Anonymous FTP access to the most recent released source is available at	*
+ * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net	*
+ *																			*
+ * Anonymous CVS access to the development source and modification history	*
+ * is available at cvs.synchro.net:/cvsroot/sbbs, example:					*
+ * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login			*
+ *     (just hit return, no password is necessary)							*
+ * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src		*
+ *																			*
+ * For Synchronet coding style and modification guidelines, see				*
+ * http://www.synchro.net/source.html										*
+ *																			*
+ * You are encouraged to submit any modifications (preferably in Unix diff	*
+ * format) via e-mail to mods@synchro.net									*
+ *																			*
+ * Note: If this box doesn't appear square, then you need to fix your tabs.	*
+ ****************************************************************************/
+
+#include "sbbs.h"
+
+scfg_t scfg;
+
+/****************************************************************************/
+/* Performs printf() through local assembly routines                        */
+/* Called from everywhere                                                   */
+/****************************************************************************/
+int lprintf(char *fmat, ...)
+{
+	va_list argptr;
+	char sbuf[512];
+	int chcount;
+
+	va_start(argptr,fmat);
+	chcount=vsprintf(sbuf,fmat,argptr);
+	va_end(argptr);
+	printf("%s",sbuf);
+	return(chcount);
+}
+
+
+char *usage="\nusage: makeuser name [-param value] [...]\n"
+	"\nparams:\n"
+	"\t-P\tPassword\n"
+	"\t-R\tReal name\n"
+	"\t-H\tChat handle\n"
+	"\t-G\tGender (M or F)\n"
+	"\t-B\tBirth date (in MM/DD/YY or DD/MM/YY format)\n"
+	"\t-T\tTelephone number\n"
+	"\t-N\tNetmail (Internet e-mail) address\n"
+	"\t-A\tStreet address\n"
+	"\t-L\tLocation (city, state)\n"
+	"\t-Z\tZip/Postal code\n"
+	"\t-S\tSecurity level\n"
+	"\t-E\tExpiration days\n"
+	"\t-C\tComment\n"
+	"\nNOTE: multi-word user name and param values must be enclosed in \"quotes\"\n"
+	;
+
+/*********************/
+/* Entry point (duh) */
+/*********************/
+int main(int argc, char **argv)
+{
+	char*	p;
+	char	error[512];
+	char	revision[16];
+	int		i;
+	time_t	now;
+	user_t	user;
+
+	sscanf("$Revision$" + 11, "%s", revision);
+
+	fprintf(stderr,"\nMAKEUSER v%s-%s - Adds User to Synchronet User Database\n"
+		,revision
+		,PLATFORM_DESC
+		);
+
+	if(argc<2) {
+		printf("%s",usage);
+		return(1); 
+	}
+
+	p=getenv("SBBSCTRL");
+	if(p==NULL) {
+		printf("\nSBBSCTRL environment variable not set.\n");
+		printf("\nExample: SET SBBSCTRL=/sbbs/ctrl\n");
+		exit(1); 
+	}
+
+	memset(&scfg,0,sizeof(scfg));
+	scfg.size=sizeof(scfg);
+	SAFECOPY(scfg.ctrl_dir,p);
+
+	if(chdir(scfg.ctrl_dir)!=0)
+		fprintf(stderr,"!ERROR changing directory to: %s", scfg.ctrl_dir);
+
+	printf("\nLoading configuration files from %s\n",scfg.ctrl_dir);
+	if(!load_cfg(&scfg,NULL,TRUE,error)) {
+		fprintf(stderr,"!ERROR loading configuration files: %s\n",error);
+		exit(1);
+	}
+
+	if(!(scfg.sys_misc&SM_LOCAL_TZ))
+		putenv("TZ=UTC0");
+
+	now=time(NULL);
+
+	memset(&user,0,sizeof(user));
+
+	/****************/
+	/* Set Defaults */
+	/****************/
+
+	/* security */
+	user.level=scfg.new_level;
+	user.flags1=scfg.new_flags1;
+	user.flags2=scfg.new_flags2;
+	user.flags3=scfg.new_flags3;
+	user.flags4=scfg.new_flags4;
+	user.rest=scfg.new_rest;
+	user.exempt=scfg.new_exempt; 
+
+	user.cdt=scfg.new_cdt;
+	user.min=scfg.new_min;
+	user.freecdt=scfg.level_freecdtperday[user.level];
+
+	if(scfg.total_fcomps)
+		strcpy(user.tmpext,scfg.fcomp[0]->ext);
+	else
+		strcpy(user.tmpext,"ZIP");
+	for(i=0;i<scfg.total_xedits;i++)
+		if(!stricmp(scfg.xedit[i]->code,scfg.new_xedit))
+			break;
+	if(i<scfg.total_xedits)
+		user.xedit=i+1;
+
+	user.shell=scfg.new_shell;
+	user.misc=(scfg.new_misc&~(DELETED|INACTIVE|QUIET|NETMAIL));
+	user.qwk=QWK_DEFAULT;
+	user.firston=now;
+	user.laston=now;	/* must set this or user may be purged prematurely */
+	user.pwmod=now;
+	user.sex=' ';
+	user.prot=scfg.new_prot;
+
+	if(scfg.new_expire)
+		user.expire=now+((long)scfg.new_expire*24L*60L*60L); 
+
+	for(i=1;i<argc;i++) {
+		if(argv[i][0]=='-') {
+			switch(toupper(argv[i++][1])) {
+			case 'A':
+				SAFECOPY(user.address,argv[i]);
+				break;
+			case 'B':
+				SAFECOPY(user.birth,argv[i]);
+				break;
+			case 'L':
+				SAFECOPY(user.location,argv[i]);
+				break;
+			case 'C':
+				SAFECOPY(user.comment,argv[i]);
+				break;
+			case 'E':
+				user.expire=now+((long)atoi(argv[i])*24L*60L*60L); 
+				break;
+			case 'G':
+				user.sex=toupper(argv[i][0]);
+				break;
+			case 'H':
+				SAFECOPY(user.handle,argv[i]);
+				break;
+			case 'N':
+				SAFECOPY(user.netmail,argv[i]);
+				break;
+			case 'P':
+				SAFECOPY(user.pass,argv[i]);
+				strupr(user.pass);
+				break;
+			case 'R':
+				SAFECOPY(user.name,argv[i]);
+				break;
+			case 'S':
+				user.level=atoi(argv[i]);
+				break;
+			case 'T':
+				SAFECOPY(user.phone,argv[i]);
+				break;
+			case 'Z':
+				SAFECOPY(user.zipcode,argv[i]);
+				break;
+			default:
+				printf("%s",usage);
+				return(1); 
+			}
+		}
+		else
+			SAFECOPY(user.alias,argv[i]);
+	}
+
+	if(user.alias[0]==0) {
+		printf("%s",usage);
+		return(1);
+	}
+
+	if(user.handle[0]==0)
+		SAFECOPY(user.handle,user.alias);
+	if(user.name[0]==0)
+		SAFECOPY(user.name,user.alias);
+
+	if((i=newuserdat(&scfg, &user))!=0) {
+		fprintf(stderr,"!ERROR %d adding new user record\n",i);
+		return(i);
+	}
+
+	printf("User record #%d (%s) created successfully.\n",user.number,user.alias);
+
+	return(0);
+}
+
diff --git a/src/sbbs3/makeuser.dsp b/src/sbbs3/makeuser.dsp
new file mode 100644
index 0000000000000000000000000000000000000000..7c2be1a0e881359fb9eaf56ca6fdd22027b38431
--- /dev/null
+++ b/src/sbbs3/makeuser.dsp
@@ -0,0 +1,136 @@
+# Microsoft Developer Studio Project File - Name="makeuser" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=makeuser - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "makeuser.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "makeuser.mak" CFG="makeuser - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "makeuser - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "makeuser - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "makeuser - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "msvc.win32.exe.release"
+# PROP Intermediate_Dir "msvc.win32.exe.release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\xpdev" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "SBBS_EXPORTS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF  "$(CFG)" == "makeuser - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "makeuser___Win32_Debug"
+# PROP BASE Intermediate_Dir "makeuser___Win32_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "msvc.win32.exe.debug"
+# PROP Intermediate_Dir "msvc.win32.exe.debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ  /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\xpdev" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "SBBS_EXPORTS" /YX /FD /GZ  /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "makeuser - Win32 Release"
+# Name "makeuser - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\makeuser.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ars.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\dat_rec.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\date_str.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\xpdev\dirwrap.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\xpdev\filewrap.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\xpdev\genwrap.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\load_cfg.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\nopen.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\scfglib1.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\scfglib2.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\str_util.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\userdat.c
+# End Source File
+# End Target
+# End Project