diff --git a/src/sbbs3/text_defaults.c b/src/sbbs3/text_defaults.c
new file mode 100644
index 0000000000000000000000000000000000000000..a313a31a808123a644230bbaa2ee491938737d56
--- /dev/null
+++ b/src/sbbs3/text_defaults.c
@@ -0,0 +1,745 @@
+/* text_defaults.c */
+
+/* Synchronet default text strings */
+
+/* $Id$ */
+
+/****************************************************************************
+ * @format.tab-size 4		(Plain Text/Source Code File Header)			*
+ * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
+ *																			*
+ * Auto-generated from CTRL\TEXT.DAT										*
+ ****************************************************************************/
+
+#include "text_defaults.h"
+
+const char * const text_defaults[TOTAL_TEXT]={
+	 "\x01n\x01h\x01c\xda\xc4\xc4\xc4\xc4\xc4\xc4\x01n\xc4\xc4\xc4\xc4\xc4\xc4\x01h\x01k\xc4\xc4\xc4\xc4\xc4\xc4\xc4\x01n\x01c\xc4\xc4\xc4\xc4\xc4\xfa\xfa\xfa\xfa\x0d\x0a\x01h\xb3 \x01bSubj\x01n\x01b: \x01h\x01c%.70s\x0d\x0a"
+	,"\xb3 \x01bAttr\x01n\x01b: \x01h\x01c%s%s%s%s%s%s%s%s%s%s\x0d\x0a"
+	,"\xb3 \x01bTo  \x01n\x01b: \x01h\x01c%.70s"
+	," #%s"
+	," (%s)"
+	,"\x0d\x0a\x01w\xb3 \x01bFrom\x01n\x01b: \x01h\x01c%.70s"
+	," #%s"
+	," (%s)"
+	,"\x0d\x0a\x01w\xb3 \x01bDate\x01n\x01b: \x01h\x01c%.24s %s\x0d\x0a\x01w\xc0\xc4\xc4\xc4\xc4\xc4\xc4\x01c\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\x01n\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\x01h\x01k\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\x01n\x01c\xc4\xc4\xc4\xc4\xc4\xc4\xc4\x01b\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xfa\xfa\xfa\xfa\xfa\xfa\x01n"
+	,"\x01_\x0d\x0a\x01b\x01hE-mail (User name or number): \x01w"
+	,"\x0d\x0aPost on %s %s"
+	,"\x01r\x01h\x0d\x0a\x07You have sent too many E-mails today.\x0d\x0a"
+	,"\x01r\x01h\x0d\x0a\x07You have posted too many times today.\x0d\x0a"
+	,"\x0d\x07\x01n\x01r\x01hCannot add \x01w%s\x01r to queue - \x01n"
+	,"\x01n\x0d\x0aThe sending of mail is beyond your ability.\x0d\x0a"
+	,"\x01n\x0d\x0aYou can't post messages.\x0d\x0a"
+	,"\x01n\x0d\x0aYou can't send E-mail to %s.\x0d\x0a"
+	,"\x01n\x01m\x0d\x0aSending E-mail to \x01h%s \x01n\x01m#%u\x01n\x0d\x0a"
+	,"\x01n\x01m\x0d\x0aPosting on \x01h%s\x01n\x01m %s\x0d\x0a"
+	,"\x0d\x0aNew file.\x0d\x0a"
+	,"\x01_\x0d\x0a\x01y\x01hSubject: "
+	,"\x01n\x01g\x0d\x0aEnter message now (\x01h%d\x01n\x01g lines max). Type \x01h/?\x01n\x01g on a new line for menu.\x0d\x0a\x01n"
+	,"\x01n\x01g\x0d\x0aRaw message input (\x01h%u\x01n\x01g bytes max). \x01hCtrl-Z\x01n\x01g to save, \x01hCtrl-C\x01n\x01g to abort.\x01n\x0d\x0a\x0d\x0a"
+	,"No more lines. Type /? for menu.\x0d\x0a"
+	,"Only %d lines left.\x0d\x0a"
+	,"\x0d\x0a\x0d\x0a\x01n\x01r\x01h\x01iOut of bytes.\x01n\x0d\x0a"
+	,"Invalid line number\x0d\x0a"
+	,"\x01nMessage cleared.\x0d\x0a"
+	,"With line numbers"
+	,"\x0d\x0a\x01r\x01h\x01iAborted.\x01n\x0d\x0a"
+	,"\x0d\x0aAnonymous"
+	,"ANONYMOUS"
+	,"\x01n\x01h\x0d\x0aSaving..."
+	,"\x0d\x01bSaved \x01w%u\x01b characters (\x01w%u\x01b lines).\x01n\x0d\x0a"
+	,"\x01n\x0d\x0aWriting Index..."
+	,"\x0d\x01n\x01mE-mail sent to \x01h%s \x01n\x01m#%d.\x01n\x0d\x0a"
+	,"\x0d\x01n\x01mPosted on \x01h%s\x01n\x01m %s.\x0d\x0a"
+	,"\x07\x01_\x01w\x01hNode %2d: \x01g%s\x01n\x01g sent you E-mail.\x0d\x0a"
+	,"\x01n\x0d\x0aYou can't forward mail.\x0d\x0a"
+	,"\x01n\x01m\x0d\x0aForwarded by \x01h%s\x01n\x01m on \x01h%s\x01n\x0d\x0a"
+	,"\x01n\x01m\x0d\x0aMail forwarded to \x01h%s \x01n\x01m#%d.\x01n\x0d\x0a"
+	,"\x01b\x01hAuto message by: \x01c%s\x01b on %s\x01n\x0d\x0a\x0d\x0a"
+	,"\x0d\x0aAuto Message - ~Read, ~Write, or ~Quit: "
+	,"\x01n\x0d\x0aYou can't write to the auto-message.\x0d\x0a"
+	,"\x01n\x0d\x0aYou have no mail.\x0d\x0a"
+	,"\x01_\x0d\x0a\x01g\x01hMail Waiting:\x0d\x0a\x0d\x0a"
+	,"\x01g\x01h%3d: \x01n\x01g%-25.25s \x01h%c\x01n\x01g %.46s\x0d\x0a"
+	,"\x01_\x0d\x0a\x01y\x01hStart with number [\x01w%u\x01y]: \x01w"
+	,"\x0d\x0a\x01n\x01c\xfe \x01b\x01hReading E-mail \x01n\x01c\xfe \x01b\x01h(\x01w?\x01b=Menu) (\x01w%u\x01b of \x01w%u\x01b): \x01n"
+	,"\x01n\x0d\x0aYou can't reply to an anonymous message.\x0d\x0a"
+	,"  \x01h\x01bRe\x01n\x01b: \x01h\x01c%s\x01n\x0d\x0a\x0d\x0a"
+	,"  \x01h\x01bRe\x01n\x01b: \x01h\x01c%s\x0d\x0a  \x01bBy\x01n\x01b: \x01h\x01c%s \x01bon \x01c%s\x01n\x0d\x0a\x0d\x0a"
+	,"  \x01h\x01bRe\x01n\x01b: \x01h\x01c%s\x0d\x0a  \x01bBy\x01n\x01b: \x01h\x01c%s \x01bto \x01c%s \x01bon \x01c%s\x01n\x0d\x0a\x0d\x0a"
+	,"Delete %s's mail"
+	,"OK"
+	,"\x0d\x0a\x01_\x01b\x01hForward mail to: \x01w"
+	,"Save/Append messsage to another file"
+	,"\x01_\x01y\x01hPath/Filename to write to: \x01n"
+	,"\x01n\x0d\x0aYou have no sent messages pending.\x0d\x0a"
+	,"\x0d\x0a\x01g\x01hMail that you've sent still pending:\x0d\x0a\x0d\x0a\x01n"
+	,"\x01n\x0d\x0a\x01c\xfe \x01h\x01bReading Sent E-mail \x01n\x01c\xfe \x01h\x01b(\x01w?\x01b=Menu) (\x01w%u\x01b of \x01w%u\x01b): \x01n"
+	,"\x01h\x01m\x0d\x0aSending Internet Mail To: \x01w%s\x01m\x0d\x0a                    From: \x01w%s\x0d\x0a"
+	,"\x01n\x0d\x0aNo mail on system.\x0d\x0a"
+	,"\x01n\x0d\x0a\x01c\xfe \x01h\x01bReading All E-mail \x01n\x01c\xfe \x01h\x01b(\x01w%u \x01bof \x01w%u\x01b): \x01n"
+	,"\x01_\x0d\x0a\x01g\x01h      From                   To                     Subject\x0d\x0a\x01n"
+	,"\x01g\x01h%4d:\x01n\x01g %-22.22s %-22.22s \x01h%c\x01n\x01g %.25s\x0d\x0a"
+	,"\x01-\x0d\x0a\x01c%-15.15s \x01y\x01h%-40.40s       \x01n\x01cNew:\x01h%4u \x01n\x01cof\x01h %-u"
+	,"\x01-\x0d\x0a\x01c%-15.15s \x01y\x01h%-40.40s        \x01w%u"
+	,"\x0d\x0aNo messages have been posted on %s %s\x0d\x0a"
+	,"\x0d\x0a\x01n\x01cPost : [\x01h%u\x01n\x01c][\x01h%u\x01n\x01c] \x01h%u\x01n\x01c/\x01h%u"
+	,"\x01n\x0d\x0a\x01c\xfe \x01h\x01bReading \x01n\x01c\xfe [\x01h%u\x01n\x01c] %s [\x01h%u\x01n\x01c] %s (\x01h?\x01n\x01c=Menu) (\x01h%u\x01n\x01c of \x01h%u\x01n\x01c): \x01n"
+	,"\x0d\x0aYou didn't post message #%d\x0d\x0a"
+	,"\x0d\x0aDelete message #%u '%s'"
+	,"\x01n\x01b[\x01h\x01wI\x01n\x01b] \x01hAutoLogon via IP address      \x01n\x01b: \x01c%s\x0d\x0a"
+	,"\x01n\x0d\x0a\x01m%s sent to \x01h%s #%u\x0d\x0a"
+	,"\x01_\x0d\x0a\x01y\x01hString to search for: "
+	,"\x01w\x01h\xc4\xc4\xc4\xc4\xc4[\x01i\x01r%c\x01n\x01h]\xc4\xc4\xc4\xc4\xb4 \x01yPrivate Chat - \x01rCtrl-C to Quit \x01y- Time Left: \x01g%-8s\x01w \xc3\xc4\xc4\xc4\xc4[\x01i\x01b%c\x01n\x01h]\xc4\xc4\xc4\xc4\xc4"
+	,"\x01g\x01h%4u:\x01n\x01g %-22.22s %-22.22s \x01h%c\x01n\x01g %.25s\x0d\x0a"
+	,"\x01w\x01h\xc4\xc4\xc4\xc4\xc4[\x01i\x01r%c\x01n\x01h]\xc4\xc4\xc4\xc4\xb4 \x01rSplit-Screen \x01cSysop\x01r Chat          \x01yTime Left: \x01g%-8s\x01w \xc3\xc4\xc4\xc4\xc4[\x01i\x01b%c\x01n\x01h]\xc4\xc4\xc4\xc4\xc4"
+	,"\x0d\x0a\x0d\x0aNo text file sections available.\x0d\x0a"
+	,"\x01l\x01_\x01c\x01hGeneral Text File Sections:\x0d\x0a\x0d\x0a"
+	,"\x01n\x01c<\x01h%d\x01n\x01c> %s\x0d\x0a"
+	,"\x01_\x0d\x0a\x01cWhich or \x01h~Q\x01n\x01cuit: \x01h"
+	,"\x01l\x01_\x01c\x01h%s Files:\x0d\x0a\x0d\x0a"
+	,"\x01c\x01h%3d: \x01n\x01c%s"
+	,"\x0d\x0aWhich, ~Add, ~Remove, ~Edit, or ~Quit: "
+	,"\x01_\x0d\x0a\x01n\x01cWhich or \x01h~Q\x01n\x01cuit: \x01h"
+	,"\x01_\x0d\x0a\x01y\x01hBefore which file: \x01n"
+	,"\x0d\x0aPath and filename (no path indicates %stext/%s/filename):\x0d\x0a"
+	,"Description:\x0d\x0a"
+	,"\x01_\x0d\x0a\x01y\x01hRemove which: \x01n"
+	,"Delete %s"
+	,"\x01_\x0d\x0a\x01y\x01hEdit which: \x01n"
+	,"\x0d\x0aSearch all groups for new messages"
+	,"\x0d\x0aSearch all groups for un-read messages to you"
+	,"\x0d\x0aAre you sure"
+	,"\x0d\x0a\x0d\x0aYou can't chat.\x0d\x0a"
+	,"RE: Feedback\x0d\x0a\x0d\x0a"
+	,"\x0d\x0a\x01g\x01hSystem Information:\x0d\x0a\x0d\x0a\x01h"
+	,"\x01b\x01hSystem          : \x01c%s\x0d\x0a"
+	,"\x01bQWK ID          : \x01c%s\x0d\x0a"
+	,"\x01bFidoNet Address : \x01c%s\x0d\x0a"
+	,"\x01bPostLink Site   : \x01c%s %u\x0d\x0a"
+	,"\x01bLocation        : \x01c%s\x0d\x0a"
+	,"\x01bOperator        : \x01c%s\x0d\x0a"
+	,"\x01bNodes           : \x01c%u\x0d\x0a"
+	,"\x01bNode #\x01c%-3d       \x01b: \x01c%s\x0d\x0a"
+	,"\x01bNode Phone      : \x01c%s\x0d\x0a"
+	,"\x01bTotal Logons    : \x01c%s\x0d\x0a"
+	,"\x01bLogons Today    : \x01c%s\x0d\x0a"
+	,"\x01bTotal Time      : \x01c%s minutes\x0d\x0a"
+	,"\x01bTime Today      : \x01c%s minutes\x0d\x0a"
+	,"\x0d\x0aView system information file"
+	,"View logon message"
+	,"\x0d\x0a\x0d\x0aYou can't read mail you've sent.\x0d\x0a"
+	,"\x0d\x0a\x01w\x01hMessage Scan "
+	,"\x01n\x01c(\x01h%u \x01n\x01csub-boards)\x01h\x01w complete.\x0d\x0a"
+	,"\x01r\x01iaborted.\x01n\x0d\x0a"
+	,"\x0d\x0aLog off"
+	,"\x0d\x0aYou can't post on this sub.\x0d\x0a"
+	,"\x0d\x0a\x01n\x01mSending message to \x01h%s\x0d\x0a"
+	,"\x0d\x0a\x01r\x01hNo other active nodes.\x01n\x0d\x0a"
+	,"\x0d\x0a\x0d\x0aYou can't use the external programs.\x0d\x0a"
+	,"\x0d\x0a\x01-\x01gUsage Statistics for \x01h%s #%d\x01n\x0d\x0a\x0d\x0a"
+	,"\x01-\x01gSub-boards of \x01h%-40s      \x01n\x01gPosts\x0d\x0a\x0d\x0a\x01h"
+	,"\x01n\x01g[\x01h%u\x01n\x01g] %-40s %12s \x01h%4u\x0d\x0a"
+	,"\x0d\x0a\x01_\x01g\x01hMessage Groups\x01n\x01g                                            Sub-boards\x0d\x0a\x0d\x0a\x01h"
+	,"\x01n\x01g[\x01h%u\x01n\x01g] %-40s %12s \x01h%4u\x0d\x0a"
+	,"\x0d\x0aGroup to configure new message scan or ~Quit: "
+	,"\x0d\x0aGroup to configure your message scan or ~Quit: "
+	,"\x01l\x01-\x01gSub-boards of \x01h%s:\x0d\x0a\x0d\x0a\x01h"
+	,"\x01n\x01g[\x01h%d\x01n\x01g] %-40.40s  \x01h%s\x0d\x0a"
+	,"\x01l\x01_\x01g\x01hMessage Groups:\x0d\x0a\x0d\x0a"
+	,"\x01n\x01g[\x01h%d\x01n\x01g] %s\x01h\x0d\x0a"
+	,"\x0d\x0aSub-board to toggle new message scan, ~All, or ~Quit: "
+	,"\x0d\x0aSub-board to toggle your message scan, ~All, or ~Quit: "
+	,"\x01n\x01g[\x01h%d\x01n\x01g] %-40.40s  \x01h\x01c%s\x0d\x0a"
+	,"\x0d\x0aSet new-scan pointer for which, ~All, or ~Quit: "
+	,"\x0d\x0aRaw message input mode is now "
+	,"OFF"
+	,"ON"
+	,"\x0d\x0a\x01n\x01mPaging \x01h%s #%u\x01n\x01m for private chat\x0d\x0a"
+	,"\x0d\x0a\x01-\x01gSystem Statistics:\x0d\x0a\x0d\x0a\x01n"
+	,"\x0d\x0a\x01-\x01gNode #%d Statistics:\x0d\x0a\x0d\x0a\x01n"
+	,"Total Logons    : %s\x0d\x0a"
+	,"Logons Today    : %s\x0d\x0a"
+	,"Total Time      : %s minutes\x0d\x0a"
+	,"Time Today      : %s minutes\x0d\x0a"
+	,"Uploads Today   : %s bytes in %u files\x0d\x0a"
+	,"Downloads Today : %s bytes in %u files\x0d\x0a"
+	,"Posts Today     : %s\x0d\x0a"
+	,"E-mails Today   : %s\x0d\x0a"
+	,"Feedback Today  : %s\x0d\x0a"
+	,"\x01_\x0d\x0a\x01y\x01hChange to (User Name or Number): \x01n"
+	,"PW: "
+	,"<UNUSED156>"
+	,"\x0d\x0aError log:\x0d\x0a"
+	,"Delete error log"
+	,"\x0d\x0a\x01n\x01r\x01hDirectory does not exist: \x01c%s\x01n\x0d\x0a"
+	,"\x0d\x0aClear critical error counters on all nodes"
+	,"\x0d\x0aInvalid node.\x0d\x0a"
+	,"\x01n\x0d\x0a\x01mSending telegram to \x01h%s #%u\x01n\x01m (Max 5 lines, Blank line ends):\x0d\x0a\x0d\x0a\x01g\x01h"
+	,"Delete Guru file"
+	,"\x01n\x01g\x07Telegram from \x01n\x01h%s\x01n\x01g on %s:\x0d\x0a\x01h"
+	,"\x0d\x0a\x0d\x0aYou can't download.\x0d\x0a"
+	,"\x0d\x0a\x01w\x01hSearching all directories...\x0d\x0a"
+	,"\x01w\x01hSearching all libraries...\x0d\x0a"
+	,"\x0d\x0a\x01w\x01h%u Files Listed.\x0d\x0a"
+	,"\x0d\x0a\x01w\x01hEmpty directory.\x0d\x0a"
+	,"\x0d\x0a\x01n\x01cSearching for files uploaded after \x01h%s\x01n\x0d\x0a"
+	,"\x0d\x0a\x0d\x0aYou can't remove files.\x0d\x0a"
+	,"\x0d\x0a\x0d\x0aThis directory is full.\x0d\x0a"
+	,"\x0d\x0a\x0d\x0aYou can't upload.\x0d\x0a"
+	,"\x0d\x0a\x0d\x0aYou can't upload here.\x0d\x0a"
+	,"\x01_\x0d\x0a\x0d\x0a\x01y\x01hFilespec: \x01n"
+	,"SY: "
+	,"\x0d\x0a\x0d\x0aNo sysop directory specified.\x0d\x0a"
+	,"\x0d\x0a\x0d\x0aYou can't upload to sysop.\x0d\x0a"
+	,"\x01-\x01gDirectories of \x01h%-40.40s     \x01n\x01gFiles\x0d\x0a\x0d\x0a\x01h"
+	,"\x01n\x01g(\x01h%u\x01n\x01g) %-40.40s %12.12s \x01h%4u\x0d\x0a"
+	,"\x0d\x0a\x01_\x01g\x01hFile Libraries \x01n\x01g                                          Directories\x0d\x0a\x0d\x0a\x01h"
+	,"\x01n\x01g(\x01h%u\x01n\x01g) %-40.40s %12.12s \x01h%4u\x0d\x0a"
+	,"\x01n\x0d\x0aInvalid NetMail address.\x0d\x0a"
+	,"\x01_\x0d\x0a\x01g\x01h%s \x01n\x01gTransfer Policy\x0d\x0a\x0d\x0a\x01n"
+	,"\x01n\x01h[\x01y%c\x01w] \x01b%-25s  "
+	,"Initial uploads are rewarded with %d%% of the credit value\x0d\x0a"
+	,"All downloads are rewarded with %d%% of the credit value\x0d\x0a"
+	,"\x0d\x0a\x0d\x0aNo user directory specified.\x0d\x0a"
+	,"\x0d\x0aThere are no files for you.\x0d\x0a"
+	,"\x0d\x0a\x0d\x0aUser transfer directory is full.\x0d\x0a"
+	,"\x0d\x0a\x0d\x0aYou can't send files to users.\x0d\x0a"
+	,"\x01n\x01cLibrary   : (%u) %s\x01y\x01h"
+	,"\x01n\x01cDirectory : (%u) %s\x01y\x01h"
+	,"\x01n\x01cFiles     : %u\x01y\x01h"
+	,"\x01n\x01c(\x01h%u\x01n\x01c) %s "
+	,"\x01n\x01c(\x01h%u\x01n\x01c) %s"
+	,"\x01r\x01hFilenames, specs, or flags [None]: \x01m\x01h"
+	,"\x0d\x0a\x07\x01r\x01h\x01iBatch download queue is full.\x01n\x0d\x0a"
+	,"\x01_\x0d\x0a\x01y\x01hFilespec [\x01wAll Files\x01y]: \x01n"
+	,"\x0d\x0a\x0d\x0a\x01r\x01h\x01iNot enough free disk space.\x01n\x0d\x0a\x0d\x0a\x01hThe sysop has been notified.\x01n\x0d\x0a"
+	,"\x0d\x0a%s kilobytes free\x0d\x0a\x0d\x0a"
+	,"\x01_\x01y\x01hFilename: \x01n"
+	,"\x0d\x0a\x01r\x01hBad filename.\x0d\x0a"
+	,"Upload '%s' to Sysop directory"
+	,"Upload '%s' to User directory"
+	,"Upload '%s' to %s %s"
+	,"\x0d\x0a\x01r\x01h\x01iThat file is already there!\x01n\x0d\x0a"
+	,"That file is already on disk. Add to data base"
+	,"\x0d\x0a\x01r\x01h\x01iThat file is not on disk!\x01n\x0d\x0a"
+	,"\x0d\x0a\x01r\x01h\x01iPlease upload files with the following extensions only:\x01n\x0d\x0a\x01w\x01h"
+	,"\x0d\x0a\x01r\x01h\x01i%s has already been uploaded!\x01n\x0d\x0a"
+	,"\x0d\x0a\x01w\x01hHit [ENTER] after last destination user.\x0d\x0a\x0d\x0a"
+	,"\x01_\x01y\x01hSend file to (User name or number): \x01n"
+	,"\x0d\x0a\x01r\x01h\x01iDuplicate user\x01n\x0d\x0a\x0d\x0a"
+	,"\x07\x0d\x0a\x01r\x01h\x01i%s wouldn't be able to download it!\x01n\x0d\x0a\x0d\x0a"
+	,"\x07\x0d\x0a\x01r\x01h\x01iYou can't send yourself files.\x01n\x0d\x0a\x0d\x0a"
+	,"\x0d\x0a\x01-\x01gAdded to destination user list: \x01w\x01h%s\x0d\x0a\x0d\x0a\x01n"
+	,"\x0d\x0a\x01-\x01gHow do you rate the content of this file (\x01h\x01wG\x01n\x01g, \x01h\x01wR\x01n\x01g, or \x01h\x01wX\x01n\x01g): \x01n"
+	,"[%c] "
+	,"Is this upload part of a set (multiple files)"
+	,"\x01_\x01y\x01hHow many files total: \x01n"
+	,"\x01_\x01y\x01hWhich file number is your upload: \x01n"
+	," [%2.2d/%2.2d]"
+	," [%d/%d]"
+	,"\x0d\x0a\x01-\x01gEnter a description now.\x0d\x0a: "
+	,"No description given."
+	,"\x0d\x0aProtocol or ~Quit: "
+	,"\x0d\x0aProtocol, ~Batch or ~Quit: "
+	,"\x0d\x0a\x07\x01r\x01h\x01iBatch upload queue is full.\x01n\x0d\x0a"
+	,"\x0d\x0a\x01n\x01m\x01h%s \x01n\x01madded to batch upload queue\x01c - Files: \x01h%u \x01n\x01c(\x01h%u\x01n\x01c Max)\x0d\x0a"
+	,"\x07\x01_\x01w\x01hNode %2d: \x01g%s\x01n\x01g sent you a file.\x0d\x0a"
+	,"\x01n\x01g\x01h%s\x01y: \x01w~B\x01yatch download, \x01w~E\x01yxtended info, \x01w~V\x01yiew file, \x01w~Q\x01yuit or [Next]: \x01w"
+	,"\x0d\x0a~Quit or [Next]: "
+	,"~Remove, ~Move, ~Edit, ~View, ~Quit, or [Next]: "
+	,"\x01n(%d) %s\x0d\x0a"
+	,"\x01_\x0d\x0a\x01y\x01hLibrary [%d]: \x01n"
+	,"\x01n(%d) %s\x0d\x0a"
+	,"\x01_\x0d\x0a\x01y\x01hDirectory [%d]: \x01n"
+	,"%s moved to %s %s.\x0d\x0a"
+	,"\x0d\x0aClose file record"
+	,"~Remove, ~Credits only, ~File only, ~Move, ~Edit, ~View, ~Quit, or [Next]: "
+	,"~Remove, ~Edit, ~View, ~Quit, or [Next]: "
+	,"\x0d\x0a\x01n\x01r\x01hFile does not exist: \x01c%s\x01n\x0d\x0a"
+	,"\x07\x0d\x0a\x01r\x01h\x01iCouldn't remove '%s'.\x01n\x0d\x0a"
+	,"Delete file"
+	,"Add %s to %s %s"
+	,"Remove credits"
+	,"\x0d\x0aUser not available.\x0d\x0a"
+	,"\x01_\x01y\x01hCredits to remove: \x01n"
+	,"\x01_\x01w\x01h%s was removed.\x0d\x0a\x01n\x01gYou lost %s credits.\x0d\x0a"
+	,"\x01_\x0d\x0a\x01y\x01hFilename         : \x01n"
+	,"\x0d\x0a\x01r\x01h\x01iError renaming %s to %s\x01n\x0d\x0a"
+	,"%s renamed to %s\x0d\x0a"
+	,"\x01_\x01y\x01hDescription      : \x01n"
+	,"Delete extended description"
+	,"\x01_\x01y\x01hUploader         : \x01n"
+	,"\x01_\x01y\x01hCredit value     : \x01n"
+	,"\x01_\x01y\x01hTimes downloaded : \x01n"
+	,"\x01_\x01y\x01hOpen count       : \x01n"
+	,"\x01_\x01y\x01hAlternate Path   : \x01n"
+	,"\x0d\x0a\x01w\x01hYou only have %s credits.\x0d\x0a"
+	,"\x0d\x0aYou don't have enough credits.\x0d\x0a"
+	,"\x0d\x0a\x01w\x01hNot enough time left to transfer.\x0d\x0a"
+	,"\x0d\x0aProtocol, ~Batch, ~Quit, or [Next]: "
+	,"\x0d\x0aBulk Upload %s %s Directory:\x0d\x0a"
+	,"\x01_\x01y\x01h%s\x01w%7uk\x01b:"
+	,"\x0d\x0a\x01r\x01h\x01iNo files in batch queue.\x01n\x0d\x0a\x0d\x0a\x01mUse \x01hD\x01n\x01m or \x01hU\x01n\x01m to add files to the queue.\x0d\x0a"
+	,"\x01_\x0d\x0a\x01y\x01hBatch: \x01n"
+	,"\x0d\x0aClear upload queue"
+	,"\x0d\x0aUpload queue cleared.\x0d\x0a"
+	,"\x0d\x0aClear download queue"
+	,"\x0d\x0aDownload queue cleared.\x0d\x0a"
+	,"\x0d\x0aDownload queue is empty.\x0d\x0a"
+	,"\x0d\x0a\x01-\x01g\x01hUpload Queue:\x01n\x01g        Description\x0d\x0a\x0d\x0a\x01n"
+	,"\x01g\x01h%2d: \x01n\x01g%s     %s\x0d\x0a"
+	,"\x0d\x0a\x01-\x01g\x01hDownload Queue:\x01n\x01g      Credits      Bytes        Time\x0d\x0a\x0d\x0a\x01n"
+	,"\x01g\x01h%2d: \x01n\x01g%s %11.11s %11.11s     %s\x0d\x0a"
+	,"\x0d\x0a\x01w\x01h         Totals: %11.11s %11.11s     %s\x0d\x0a"
+	,"\x0d\x0a\x01-\x01gRemove which file from upload queue (1-%d): \x01n"
+	,"\x0d\x0a\x01-\x01gRemove which file from download queue (1-%d): \x01n"
+	,"\x0d\x0aUpload queue is empty\x0d\x0a"
+	,"\x0d\x0aHang up after transfer"
+	,"\x0d\x0a\x01w\x01hStart transfer now (Ctrl-X to abort):\x0d\x0a\x01n"
+	,"\x01_\x0d\x0a\x01b\x01hDisconnecting... \x01wH\x01bang up or \x01wA\x01bbort "
+	,"\x0d\x01w\x01hGood-bye!  (Time Used: @TUSED@)\x01>"
+	,"\x01r\x01h\x01i%s NOT SENT!\x01n\x0d\x0a"
+	,"Deleting files in temp directory...\x0d\x0a"
+	,"\x01_\x01y\x01hExtract from: \x01n"
+	,"\x0d\x0aUnextractable file type.\x0d\x0a"
+	,"\x0d\x0aFile not found.\x0d\x0a"
+	,"\x0d\x0a~Extract file(s), ~View archive, or ~Quit: "
+	,"\x01_\x0d\x0a\x01y\x01hTemp Directory: \x01n"
+	,"\x01n\x0d\x0a%s not created yet.\x0d\x0a\x0d\x0aUse the \x01hA\x01n command to create it.\x0d\x0a"
+	,"\x0d\x0aUploader: %s\x0d\x0aFilename: %s\x0d\x0a"
+	,"\x0d\x0a%s bytes in %u files\x0d\x0a"
+	,"\x0d\x0a%u files removed.\x0d\x0a"
+	,"\x01r\x01h\x01iAll other nodes should NOT be in use during resort/compression.\x01n\x0d\x0a"
+	,"\x01-\x01c%-15.15s \x01y\x01h%-25.25s "
+	,"\x01bEmpty\x01n\x0d\x0a"
+	,"\x01wSorting..."
+	,"\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x01bSorted    \x01n\x0d\x0a"
+	,"\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x01bCompressed %u slots (%s bytes)\x01n\x0d\x0a"
+	,"\x01w\x01h\x0d\x0a%s is already in the queue.\x0d\x0a"
+	,"\x01w\x01h\x0d\x0aFile is not online.\x0d\x0a"
+	,"\x01n\x0d\x0a\x01m\x01h%s \x01n\x01madded to batch download queue -\x0d\x0a\x01cFiles: \x01h%u\x01n\x01c (\x01h%u\x01n\x01c Max)  Credits: \x01h%s\x01n\x01c  Bytes: \x01h%s\x01n\x01c  Time: \x01h%s\x0d\x0a"
+	,"\x0d\x0a\x01n\x01r\x01hThe sysop has not configured \x01w%s\x01r as a viewable file type.\x0d\x0a"
+	,"\x01r\x01h\x01i%s NOT RECEIVED!\x01n\x0d\x0a"
+	,"\x0d\x0a\x07\x01r\x01h\x01i%s HAD ERRORS - NOT UPLOADED!\x01n\x0d\x0a"
+	,"\x01r\x01h\x01i%s IS ZERO LENGTH - NOT UPLOADED!\x01n\x0d\x0a"
+	,"\x01_\x01w\x01h%s (%s bytes) received.\x0d\x0a"
+	,"\x01_\x01w\x01h%s (%s bytes) sent.\x0d\x0a"
+	,"\x01_\x01h\x01w%s was %sdownloaded by %s\x0d\x0a\x01n\x01gYou were awarded %s credits.\x0d\x0a"
+	,"partially "
+	,"\x0d\x0a\x01n\x01gLibrary          :\x01h (%u) %s"
+	,"\x0d\x0a\x01n\x01gDirectory        :\x01h (%u) %s"
+	,"\x0d\x0a\x01n\x01gFilename         :\x01h %s"
+	,"\x0d\x0a\x01n\x01gFile size        :\x01h %s"
+	,"\x0d\x0a\x01n\x01gCredit value     :\x01h %s"
+	,"\x0d\x0a\x01n\x01gDescription      :\x01h %s"
+	,"\x0d\x0a\x01n\x01gUploaded by      :\x01h %s"
+	,"\x0d\x0a\x01n\x01gFile date        :\x01h %s"
+	,"\x0d\x0a\x01n\x01gUploaded on      :\x01h %s"
+	,"\x0d\x0a\x01n\x01gLast downloaded  :\x01h %s"
+	,"\x0d\x0a\x01n\x01gTimes downloaded :\x01h %u"
+	,"\x0d\x0a\x01n\x01gTime to download :\x01h %s"
+	,"\x0d\x0a\x01n\x01gAlternate Path   :\x01h %s"
+	,"\x0d\x0a\x01r\x01h\x01iInvalid Alternate Path Number: %u\x01n"
+	,"\x01_\x0d\x0a\x01w\x01hFile is currently open by %d user%s.\x0d\x0a"
+	,"\x07\x07\x0d\x0a\x01h\x01rH\x01ba\x01gp\x01yp\x01cy \x01mB\x01wi\x01rr\x01gt\x01bh\x01cd\x01ma\x01yy \x01wt\x01ro \x01gy\x01bo\x01cu\x0d\x0a\x07\x07\x01mH\x01ya\x01wp\x01rp\x01gy \x01bB\x01ci\x01mr\x01yt\x01wh\x01rd\x01ga\x01by \x01ct\x01mo \x01yy\x01wo\x01ru\x01g.\x01b.\x01c.\x0d\x0a\x0d\x0a"
+	,"\x01w\x01hYou haven't changed your password in more than %d days.\x0d\x0a\x0d\x0a"
+	,"\x0d\x0aEnter a different password"
+	,"\x01_\x0d\x0a\x01y\x01hNew password (4-8 chars): "
+	,"\x01_\x01y\x01hVerify (enter again): \x01n"
+	,"\x07\x01r\x01hWrong!"
+	,"\x01w\x01hPassword changed.\x0d\x0a"
+	,"Sorry, you have no more logons allowed today.\x0d\x0a"
+	,"You can only logon once a day.\x0d\x0a"
+	,"\x01_\x01b\x01h[\x01c\xfb\x01b] \x01yEnter your full name or alias: \x01w"
+	,"\x01_\x01b\x01h[\x01c\xfb\x01b] \x01yEnter your full real name: \x01w"
+	,"\x01_\x01b\x01h[\x01c\xfb\x01b] \x01yEnter your company name: \x01w"
+	,"\x01_\x01b\x01h[\x01c\xfb\x01b] \x01yEnter your chat handle: \x01w"
+	,"\x01_\x01b\x01h[\x01c\xfb\x01b] \x01yEnter your sex (M/F): \x01w"
+	,"\x01_\x01b\x01h[\x01c\xfb\x01b] \x01yEnter your street address: \x01w"
+	,"\x01_\x01b\x01h[\x01c\xfb\x01b] \x01yEnter your voice phone number: \x01w"
+	,"\x01_\x01b\x01h[\x01c\xfb\x01b] \x01yEnter your birthday (%s): \x01w"
+	,"\x01_\x01b\x01h[\x01c\xfb\x01b] \x01yEnter your city, state: \x01w"
+	,"\x01_\x01b\x01h[\x01c\xfb\x01b] \x01yEnter your zip (or postal) code: \x01w"
+	,"\x01_\x01y\x01hEnter a description of your computer: \x01w"
+	,"Are you calling from North America"
+	,"Is the above information correct"
+	,"\x01bUser #\x01c%-4d      \x01b: \x01c%s\x0d\x0a"
+	,"\x01bLogons Today    : \x01c%-5u \x01b(Max \x01c%u\x01b)\x0d\x0a"
+	,"\x01bTime on Today   : \x01c%-5u \x01b(Max \x01c%u\x01b)\x0d\x0a"
+	,"\x01bMail Waiting    : \x01c%u\x0d\x0a"
+	,"\x01bSysop is        : \x01c"
+	,"Available"
+	,"Not Available"
+	,"\x01r\x01h\x01iYou can't possibly be in two places at the same time.\x01n\x0d\x0a"
+	,"\x07\x01r\x01h\x01i%d critical errors have occurred. Type ;ERR at main menu.\x01n\x0d\x0a"
+	,"\x01_\x01w\x01hYou have %d User to User Transfer%s waiting for you\x0d\x0a"
+	,"\x01_\x01w\x01hYou have sent %d unreceived User to User Transfer%s\x0d\x0a"
+	,"Read your mail now"
+	,"Sorry, the system is closed to new users.\x0d\x0a"
+	,"New User Password: "
+	,"Use automatic terminal type detection"
+	,"Does your terminal support ANSI"
+	,"Do you have a color terminal"
+	,"\x01n\x01gAre you using \x01hRIPterm\x01n\x01g or a \x01hRIPscrip \x01n\x01gcompatible terminal program?\x0d\x0a\x01h\x01wIMPORTANT:\x01n\x01g If you are not absolutely sure, hit \x01h\x01w\x01iN\x01n\x01b\x01h"
+	,"Does your terminal support IBM extended ASCII"
+	,"\x01nYou can't use that name (duplicate or invalid).\x0d\x0a"
+	,"\x01l\x01-\x01gYour password is \x01h%s\x0d\x0a"
+	,"\x0d\x0a\x01_\x01w\x01hWrite down your password and keep it confidential.\x0d\x0a\x0d\x0a\x01y\x01hEnter this password for verification: \x01w"
+	,"\x07\x0d\x0a\x01r\x01hIncorrect, try again.\x0d\x0a"
+	,"\x01_\x0d\x0a\x01y\x01hMagic word: \x01w"
+	,"\x0d\x0aSorry, that was not the magic word.\x0d\x0a"
+	,"Sorry, the system is full."
+	,"*NEW USER*  %-30.30s  Age/Sex/BD   : %-2d %c %s\x0d\x0aReal name : %-30.30s  Phone number : %s\x0d\x0aComputer  : %-30.30s  Modem type   : %s\x0d\x0a\x0d\x0a"
+	,"\x07\x0d\x0a\x01r\x01h\x01iYou must leave %s mail in order to be validated!\x01n\x0d\x0a"
+	,"\x0d\x0a\x0d\x0aNo external programs available.\x0d\x0a"
+	,"\x01l\x01n\x01c\x01h%s \x01n\x01cExternal Programs:\x0d\x0a\x0d\x0a"
+	,"\x01n\x01cNum \x01h\xb3\x01n\x01c Name                           "
+	,"\x01h\xc4\xc4\xc4\xc4\xc5\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4      "
+	,"\x01h\x01c%3u \xb3 \x01n\x01c%-25.25s\x01h      "
+	,"\x0d\x0a\x01-\x01cWhich or \x01h~Q\x01n\x01cuit: \x01h"
+	,"\x0d\x0a%s is currently running %s on node %d.\x0d\x0a\x0d\x0aTry again later.\x0d\x0a\x0d\x0a"
+	,"Remove node lock"
+	,"The minimum modem speed for this node is %ubps."
+	,"You do not have sufficient access for this node."
+	,"\x01n\x01r\x01h\x0d\x0aSorry, this node is temporarily closed for maintenance.\x01n\x0d\x0a"
+	,"\x0d\x0aUnknown user\x0d\x0a"
+	,"\x07Invalid Logon\x0d\x0a"
+	,"%2.2d/%2.2d/%2.2d T:%5u   L:%3u   P:%3u   E:%3u   F:%3u   U:%6uk %3u  D:%6uk %3u\x0d\x0a"
+	,"Locally"
+	,"\x0d\x0aSort alphabetically"
+	,"\x0d\x0a\x01m\x01hChecking Slots..."
+	,"\x01n\x01h%-32.32s\x01n\x01m%-30.30s\x01h%-8.8s \x01n\x01m%-8.8s\x0d\x0a"
+	,"\x0d\x01h\x01w%d\x01b total users.        \x0d\x0a"
+	,"\x01w%d \x01busers with access to current sub-board.\x0d\x0a"
+	,"\x01w%d \x01busers with access to current directory.\x0d\x0a"
+	,"\x0d\x0a\x01-\x01cCurrent New-Scan date/time: \x01h"
+	,"\x01y\x01hYear: \x01w"
+	,"  \x01yMonth: \x01w"
+	,"  \x01yDay: \x01w"
+	,"  \x01yHour: \x01w"
+	,"  \x01yMinute: \x01w"
+	," pm"
+	," am"
+	,"\x01r\x01h\x01iNot long enough!\x01n"
+	,"\x01r\x01h\x01iThat's your current password!\x01n"
+	,"\x01r\x01h\x01iYou call that a password?\x01n"
+	,"\x01r\x01h\x01iThat password is too obvious!\x01n"
+	,"\x0d\x0a\x01nA) IBM (or compatible)\x0d\x0aB) Apple\x0d\x0aC) Macintosh\x0d\x0aD) Amiga\x0d\x0aE) Other\x0d\x0a\x0d\x0a"
+	,"\x01_\x01y\x01hPrimary Computer: \x01n"
+	,"Apple"
+	,"Macintosh"
+	,"Amiga"
+	,"Other"
+	,"\x07\x0d\x0aNo user data defined.\x0d\x0a"
+	,"\x01r\x01h\xae\xae\xae \x01iDELETED\x01n\x01r\x01h \xaf\xaf\xaf\x0d\x0a"
+	,"\x01b\x01h\xae\xae\xae \x01iINACTIVE\x01n\x01b\x01h \xaf\xaf\xaf\x0d\x0a"
+	,"\x01n\x01cAlias     : \x01h%-30.30s  \x01n\x01cPassword     : \x01h%-8.8s  %s\x0d\x0a"
+	,"\x01n\x01cReal Name : \x01h%-30.30s  \x01n\x01cPhone number : \x01h%s\x0d\x0a"
+	,"\x01n\x01cAddress   : \x01h%-30.30s  \x01n\x01cAge/Sex/BD   : \x01h%2d %c %s\x0d\x0a"
+	,"\x01n\x01cLocation  : \x01h%-30.30s  \x01n\x01cZip Code     : \x01h%s\x0d\x0a"
+	,"\x01n\x01cNote      : \x01h%-30.30s  \x01n\x01cHandle       : \x01h%s\x0d\x0a"
+	,"\x01n\x01cComputer  : \x01h%-30.30s  \x01n\x01cModem type   : \x01h%s\x0d\x0a"
+	,"\x01n\x01cComment %c : \x01h%s\x0d\x0a"
+	,"\x01n\x01cFirst on  : \x01h%-8.8s  \x01n\x01cExpire    : \x01h%-8.8s  \x01n\x01cLast on   : \x01h%-8.8s  %02u:%02u\x0d\x0a"
+	,"\x01n\x01cTime on   : \x01h%-5u     \x01n\x01cToday     : \x01h%-5u%-5u\x01n\x01cLast call : \x01h%-5u%-5u\x01n\x01cExtra : \x01h%u\x0d\x0a"
+	,"\x01n\x01cLogons    : \x01h%-5u     \x01n\x01cToday     : \x01h%-5u%-5u\x01n\x01cPosts     : \x01h%-5u%-5u\x01n\x01cToday : \x01h%u\x0d\x0a"
+	,"\x01n\x01cE-mails   : \x01h%-5u     \x01n\x01cTo sysop  : \x01h%-5u     \x01n\x01cWaiting   : \x01h%-5u     \x01n\x01cToday : \x01h%u\x0d\x0a"
+	,"\x01n\x01cNetMail   : \x01h%s\x0d\x0a"
+	,"\x01n\x01cUploads   : \x01h%13.13s \x01n\x01cbytes in \x01h%u \x01n\x01cfiles\x0d\x0a"
+	,"\x01n\x01cDownloads : \x01h%13.13s \x01n\x01cbytes in \x01h%u \x01n\x01cfiles %s\x0d\x0a"
+	,"- Leech: \x01r\x01h\x01i%u\x01n"
+	,"\x01n\x01cCredits   : \x01h%13.13s \x01n\x01cfree: \x01h%s \x01n\x01c(\x01h%s \x01n\x01cper day)\x0d\x0a"
+	,"\x01n\x01cMinutes   : \x01h%13.13s\x0d\x0a"
+	,"\x0d\x0a\x01n\x01cSec Level : \x01h%d\x0d\x0a"
+	,"\x01n\x01cFlags #1  : \x01h%-26s   \x01n\x01cFlags #3  : \x01h%s\x0d\x0a\x01n\x01cFlags #2  : \x01h%-26s   \x01n\x01cFlags #4  : \x01h%s\x0d\x0a"
+	,"\x01n\x01cExemption : \x01h%-26s   \x01n\x01cRestricts : \x01h%s\x0d\x0a"
+	,"\x0d\x0a\x01_\x01y\x01hUser edit (\x01w?\x01y=Menu) (\x01w%u\x01y of \x01w%u\x01y): \x01n"
+	,"Restore User"
+	,"Activate User"
+	,"Delete User"
+	,"User has mail waiting. Read/Delete it"
+	,"User has sent mail. Read/Delete it"
+	,"Deactivate User"
+	,"Change Exemptions"
+	,"        \x01n%s\x0d\x0aToggle: "
+	,"\x01_\x01y\x01hGo to Name or Number: \x01n"
+	,"\x01_\x01y\x01hLast on: \x01w"
+	,"\x01_\x01y\x01hFirst on: \x01w"
+	,"\x01_\x01y\x01hExpire: \x01w"
+	,"\x01_\x01y\x01hPassword Last Modified: \x01w"
+	,"\x01_\x01y\x01hLevel: \x01w"
+	,"\x01_\x01y\x01hNote: \x01w"
+	,"\x01_\x01y\x01hComment: \x01w"
+	,"\x01_\x01y\x01hUpload Bytes: \x01w"
+	,"\x01_\x01y\x01hTotal Uploads: \x01w"
+	,"\x01_\x01y\x01hDownload Bytes: \x01w"
+	,"\x01_\x01y\x01hTotal Downloads: \x01w"
+	,"\x01_\x01y\x01hLeech Downloads: \x01w"
+	,"%d: L: %2d  F: %s  EX: %s\x0d\x0a  RE: %s\x0d\x0a"
+	,"\x0d\x0a\x01_\x01y\x01hValidate: \x01n"
+	,"\x01_\x01y\x01hPassword: \x01w"
+	,"\x01_\x01y\x01hCredits: \x01w"
+	,"\x01_\x01y\x01hMinutes: \x01w"
+	,"Copy user"
+	,"\x01_\x01y\x01hTo slot #: \x01n"
+	,"Change Restrictions"
+	,"\x01_\x01y\x01hAdjust Credits (- to subtract, M or K = Mega/Kilobytes, or $): \x01n"
+	,"\x01_\x01y\x01hAdjust Minutes (- to subtract, H = Hours): \x01n"
+	,"\x0d\x0aDelete Questionaire"
+	,"\x01h\x01bDefault settings for \x01w%s #%d\x0d\x0a\x0d\x0a"
+	,"\x01n\x01b[\x01h\x01wT\x01n\x01b] \x01hTerminal Mode                 \x01n\x01b: \x01c%s\x0d\x0a"
+	,"\x01n\x01b[\x01h\x01wE\x01n\x01b] \x01hExternal Editor               \x01n\x01b: \x01c%s\x0d\x0a"
+	,"\x01n\x01b[\x01h\x01wL\x01n\x01b] \x01hScreen Length                 \x01n\x01b: \x01c%s\x0d\x0a"
+	,"\x01n\x01b[\x01h\x01wX\x01n\x01b] \x01hExpert Menu Mode              \x01n\x01b: \x01c%s\x0d\x0a"
+	,"\x01n\x01b[\x01h\x01wP\x01n\x01b] \x01hScreen Pause                  \x01n\x01b: \x01c%s\x0d\x0a"
+	,"\x01n\x01b[\x01h\x01wH\x01n\x01b] \x01hHot Keys                      \x01n\x01b: \x01c%s\x0d\x0a"
+	,"\x01n\x01b[\x01h\x01wS\x01n\x01b] \x01hSpinning Cursor               \x01n\x01b: \x01c%s\x0d\x0a"
+	,"\x01n\x01b[\x01h\x01wC\x01n\x01b] \x01hClear Screen Between Messages \x01n\x01b: \x01c%s\x0d\x0a"
+	,"\x01n\x01b[\x01h\x01wN\x01n\x01b] \x01hAsk For New Message/File Scan \x01n\x01b: \x01c%s\x0d\x0a"
+	,"\x01n\x01b[\x01h\x01wY\x01n\x01b] \x01hAsk For Your Un-read Msg Scan \x01n\x01b: \x01c%s\x0d\x0a"
+	,"\x01n\x01b[\x01h\x01wF\x01n\x01b] \x01hAutomatic New File Scan       \x01n\x01b: \x01c%s\x0d\x0a"
+	,"\x01n\x01b[\x01h\x01wR\x01n\x01b] \x01hRemember Current Sub-board    \x01n\x01b: \x01c%s\x0d\x0a"
+	,"\x01n\x01b[\x01h\x01wB\x01n\x01b] \x01hBatch Download File Flagging  \x01n\x01b: \x01c%s\x0d\x0a"
+	,"\x01n\x01b[\x01h\x01wM\x01n\x01b] \x01hForward E-mail to NetMail     \x01n\x01b: \x01c%s\x0d\x0a"
+	,"\x01n\x01b[\x01h\x01wK\x01n\x01b] \x01hCommand Shell                 \x01n\x01b: \x01c%s\x0d\x0a"
+	,"\x01n\x01b[\x01h\x01wD\x01n\x01b] \x01hDefault to Quiet Mode         \x01n\x01b: \x01c%s\x0d\x0a"
+	,"\x01n\x01b[\x01h\x01wW\x01n\x01b] \x01hChange Password or Signature\x0d\x0a"
+	,"\x01n\x01b[\x01h\x01wA\x01n\x01b] \x01hTemporary/QWK Archive Type    \x01n\x01b: \x01c%s\x0d\x0a"
+	,"\x01n\x01b[\x01h\x01wZ\x01n\x01b] \x01hDefault Download Protocol     \x01n\x01b: \x01c%s \x01b%s\x0d\x0a"
+	,"\x0d\x0a\x01n\x01h\x01bWhich or [\x01wQ\x01b]uit: \x01c"
+	,"On"
+	,"Off"
+	,"\x0d\x0a\x01_\x01b\x01h[\x01c\xfb\x01b] \x01yHow many rows on your monitor [\x01wAuto Detect\x01y]: "
+	,"\x0d\x0a\x01_\x01y\x01hCurrent Password: \x01w"
+	,"Forward personal e-mail to network mail address"
+	,"\x01_\x01b\x01h[\x01c\xfb\x01b] \x01yNetwork mail address (Example: user@domain)\x0d\x0a: "
+	,"\x01n\x01l\x01gSelect \x01h%s\x01n\x01g:\x0d\x0a\x0d\x0a"
+	,"\x01g\x01h%3d: \x01n\x01g%s\x0d\x0a"
+	,"\x0d\x0aWhich, ~Quit or [%u]: "
+	,"\x01_\x01w\x01h\x0d\x0a\x0d\x0a%s is here...\x0d\x0a\x0d\x0a\x01n"
+	,"\x0d\x0a\x01_\x01w\x01hEnd of chat.\x0d\x0a\x0d\x0a\x01n"
+	,"\x0d\x0a\x01_\x01y\x01hChat: \x01n"
+	,"????"
+	,"\x0d\x0a\x01n\x01-\x01gMultinode Chat - Type \x01h/?\x01n\x01g for menu.\x0d\x0a"
+	,"\x0d\x0a\x01w\x01hWelcome to Channel %d (\x01c%s\x01w)\x0d\x0a\x0d\x0a\x01n"
+	,"\x01_\x01w\x01h%3d  \x01g%s\x01n\x01g in multinode chat channel %d locally.\x0d\x0a"
+	,"\x0d\x0a\x01n\x01m\x01hYou're on the Air!\x0d\x0a\x0d\x0a\x01n"
+	,"\x01_\x01w\x01hNode %2d: \x01g%s\x01n\x01g joined multinode chat channel %u.\x0d\x0a\x01n"
+	,"\x01_\x01w\x01hNode %2d: \x01g%s\x01n\x01g left multinode chat channel %u.\x0d\x0a"
+	,"\x01_\x01y\x01hCommand: \x01n"
+	,"%s has password protected this channel\x0d\x0aPassword: "
+	,"\x0d\x0aCorrect.\x0d\x0a"
+	,"\x01r\x01h\x0d\x0aWrong password.\x0d\x0a"
+	,"Password protect this channel"
+	,"\x0d\x0a\x01_\x01y\x01hPassword: "
+	,"\x01_\x01g\x01h%-8.8s \x01w%2d%c \x01n\x01g%s"
+	,"\x0d\x0aSysop page is now %s\x0d\x0a"
+	,"\x0d\x0a%s is not available.\x0d\x0a"
+	,"Chat with %s instead"
+	,"\x0d\x0a\x01b\x01hPrivate: \x01g~T\x01n\x01gelegram, \x01h~M\x01n\x01gessage, \x01h~C\x01n\x01ghat, or \x01h~Q\x01n\x01guit: \x01c\x01h"
+	,"\x0d\x0a\x01h\x01yNode, User name, \x01w#\x01yNumber, \x01w'\x01yHandle, or \x01w^U\x01yser list: \x01w\x01h"
+	,"\x0d\x0a\x01_\x01w\x01hNode %d is in private chat with another node.\x0d\x0a"
+	,"\x0d\x0a\x01_\x01w\x01hNode %d is not in use.\x0d\x0a"
+	,"\x0d\x0aThere's no need to page yourself.\x0d\x0a"
+	,"\x0d\x0a\x01r\x01h\x01iDon't bug %s.\x01n\x0d\x0a"
+	,"\x07\x01_\x01w\x01hNode %2d: \x01g%s\x01n\x01g is paging you to chat.\x0d\x0a"
+	,"\x07\x01_\x01w\x01hNode %2d: \x01g%s\x01n\x01g is paging all nodes to chat.\x0d\x0a"
+	,"\x07\x01_\x01w\x01hNode %2d: \x01g%s\x01n\x01g is paging you for private chat.\x0d\x0a"
+	,"\x0d\x0aYou can't send messages.\x0d\x0a"
+	,"\x0d\x0a\x01h\x01yNode, Name, \x01w#\x01yNumber, \x01w'\x01yHandle, \x01w^U\x01yser list, or \x01wAll\x01y: \x01w\x01h"
+	,"\x0d\x0aThere's no need to send a message to yourself.\x0d\x0a"
+	,"\x01_\x01y\x01h\x0d\x0aMessage: "
+	,"\x07\x01_\x01w\x01hNode %2d: \x01g%s\x01n\x01g sent you a message:\x0d\x0a\x01w\x01h\x014%s\x01n\x0d\x0a"
+	,"\x07\x01_\x01w\x01hNode %2d: \x01g%s\x01n\x01g sent all nodes a message:\x0d\x0a\x01w\x01h\x014%s\x01n\x0d\x0a"
+	,"\x0d\x0aPaging %s..."
+	,"\x01n\x0d\x0a\x01cWaiting for \x01hNode %d \x01n\x01cto join private chat. Hit \x01h\x01iCtrl-C\x01n\x01c to abort.\x01n\x0d\x0a\x0d\x0a"
+	,"\x01_\x01w\x01hNode %2d: \x01g%s\x01n\x01g joined private chat.\x01n\x0d\x0a"
+	,"\x0d\x0a\x01_\x01w\x01hNode %2d: \x01g%s\x01n\x01g left private chat.\x01n\x0d\x0a"
+	,"No one has logged on today.\x0d\x0a"
+	,"\x01g\x01hLast few callers:\x0d\x0a\x01n\x01g"
+	,"\x0d\x0a\x01n\x01h\x01m%-2d \x01n\x01m%-6u \x01w\x01h%-25.25s \x01m%-25.25s\x01n\x01m%02u:%02u \x01h%-8.8s \x01n\x01m%-3.3d"
+	,"\x0d\x0a\x01g\x01hCallers Today:\x01n\x01g"
+	,"\x01_\x01b\x01hDo you mean %s #%u (\x01cY\x01bes, \x01cN\x01bo, or \x01cQ\x01buit) ? \x01n"
+	,"UNKNOWN USER"
+	,"\x0d\x0aTime's up.\x0d\x0a"
+	,"\x01_\x01w\x01hNode %2d: \x01g%s\x01n\x01g logged off\x0d\x0a\x01n"
+	,"\x01_\x01w\x01hNode %2d: \x01g%s\x01n\x01g logged on %s\x0d\x0a\x01n"
+	,"\x01n\x0d\x0a\x0d\x0aLogon     : %s"
+	,"\x0d\x0aNow       : %s"
+	,"\x0d\x0aTime on   : %s"
+	,"\x0d\x0aTime left : %s\x0d\x0a\x0d\x0a"
+	,"\x0d\x0a\x0d\x0a\x01nCtrl-Key Commands (From Anywhere)\x0d\x0a\x0d\x0aCtrl-S  Pause Current Process\x0d\x0aCtrl-Q  Continue Current Process\x0d\x0aCtrl-C  Abort Current Process\x0d\x0aCtrl-O  Toggle Pause Temporarily\x0d\x0aCtrl-Z  Toggle Raw Input Mode\x0d\x0aCtrl-U  List Users Online\x0d\x0aCtrl-P  Send Private Message to Another Node\x0d\x0aCtrl-T  Time Information\x0d\x0a\x0d\x0a"
+	,"\x0d\x0a\x01nYou've taken too long to log on.\x0d\x0a"
+	,"\x0d\x0a\x01nYou've been inactive too long.\x0d\x0a"
+	,"@EXEC:yesnobar@"
+	,"Yes"
+	,"No"
+	,"@EXEC:noyesbar@"
+	,"\x01_\x01r\x01h[Hit a key] "
+	,"Continue"
+	,"\x01-\x01g\x0d\x0aSystem Statistics Log:\x0d\x0a\x0d\x0a\x01n"
+	,"\x01-\x01g\x0d\x0aNode #%d Statistics Log:\x0d\x0a\x0d\x0a\x01n"
+	,"\x01_\x01r\x01hYour time has been reduced due to an upcoming event on \x01w%s\x0d\x0a\x0d\x0a"
+	,"\x01n\x0d\x0aTimed Event - Node: %d   Time: %02d:%02d   Last Ran: %s\x0d\x0a"
+	,"\x01_\x01r\x01h\x01i\x0d\x0a\x0d\x0aCarrier will be dropped in %d minutes due to upcoming event.\x01n"
+	,"\x01_\x01y\x01h\x0d\x0aQWK: \x01n"
+	,"\x0d\x0aCtrl-A codes: ~Expand to ANSI, ~Leave in, or [Strip]: "
+	,"\x0d\x0a\x01_\x01h\x01wPacking Sub-board...      "
+	,"\x0d\x01bPacked:\x01w%4u \x01bof\x01w %u\x01>"
+	,"\x0d\x0a\x01_\x01h\x01wPacking E-mail...            "
+	,"\x0d\x01bPacked \x01w%u\x01b E-mail messages.\x01>"
+	,"\x0d\x0a\x01_\x01h\x01wUnpacking..."
+	,"\x0d\x01_\x01h\x01bUnpacked.\x01>"
+	,"\x01_\x01w\x01hNo new messages.\x0d\x0a"
+	,"\x0d\x0a\x01r\x01h\x01iPacket Compression Failed!\x01n\x0d\x0a"
+	,"\x0d\x0a\x01r\x01h\x01iCan't Extract!\x01n\x0d\x0a"
+	,"\x0d\x0a\x01r\x01h\x01iReply not received!\x01n\x0d\x0a"
+	,"\x01_\x01w\x01hInvalid Conference %d\x0d\x0a"
+	,"\x0d\x0a\x01_\x01h\x01wCreating %s..."
+	,"\x0d\x01bCreated %s\x01>"
+	,"\x0d\x01bNo Files.\x01>"
+	,"\x0d\x0aMessage pointers reset to initial values.\x0d\x0a"
+	,"\x01-\x0d\x0a\x01gThe current conversion rate is \x01h%u \x01n\x01gminutes for \x01h100k\x01n\x01g credits.\x0d\x0a\x0d\x0a\x01n"
+	,"\x0d\x0a\x01_\x01b\x01hHow many \x01w100k \x01bcredit blocks to convert to minutes (\x01w%u Max\x01b): \x01n"
+	,"\x01-\x01r\x01h\x01iYou have too many minutes.\x01n\x0d\x0a"
+	,"\x0d\x0aYou are connected to a billing node for %s BBS.\x0d\x0aYour phone number will be charged $%d if you do not hang up within 30 seconds.\x0d\x0a\x0d\x0aPlease wait, or hit any key to hang up now..."
+	,"Convert 100k credits to %u minutes"
+	,"\x0d\x0a%u credits have been added to your account.\x0d\x0a"
+	,"\x0d\x0aANSI Capture is now %s\x0d\x0a"
+	,"\x01n\x01m\x0d\x0aRetrieving \x01h%s\x01n\x01m..."
+	,"\x01n\x0d\x0aAlternate upload path now: %s\x0d\x0a"
+	,"\x0d\x0aPrivate"
+	,"\x0d\x0a\x01_\x01y\x01hPost to: "
+	,"\x0d\x0aPrivate posts require a destination user name.\x0d\x0a"
+	,"\x0d\x0a\x01_\x01w\x01hUsing your real name...\x0d\x0a"
+	,"\x0d\x0a\x01_\x01w\x01hPosting Privately...\x0d\x0a"
+	,"\x0d\x0a\x01_\x01w\x01hPosting anonymously...\x0d\x0a"
+	,"\x0d\x0aCan't delete posts on this sub-board.\x0d\x0a"
+	,"\x0d\x0a\x01h\x01gSub-board Information:\x0d\x0a\x0d\x0a\x01n"
+	,"Long Name  : %s\x0d\x0a"
+	,"Short Name : %s\x0d\x0a"
+	,"QWK Name   : %s\x0d\x0a"
+	,"Max Msgs   : %u\x0d\x0a"
+	,"\x0d\x0aQWK packet network using the tagline:\x0d\x0a%s\x01n\x0d\x0a"
+	,"\x0d\x0a\x01nFidoNet EchoMail Conference:\x0d\x0a%s (%s)\x0d\x0a"
+	,"View sub-board information file"
+	,"\x0d\x0a\x01g\x01hDirectory Information:\x0d\x0a\x0d\x0a\x01n"
+	,"Long Name               : %s\x0d\x0a"
+	,"Short Name              : %s\x0d\x0a"
+	,"Allowed File Extensions : %s\x0d\x0a"
+	,"Maximum Files           : %u\x0d\x0a"
+	,"View directory information file"
+	,"\x01n\x0d\x0aNo NetMail allowed.\x0d\x0a"
+	,"\x0d\x0aIt will cost you %u credits to send NetMail. Continue"
+	,"\x01n\x01m\x0d\x0aSending NetMail To: \x01h%s\x01n\x01m (\x01h%s\x01n\x01m)\x0d\x0a              From: \x01h%s\x01n\x01m (\x01h%s\x01n\x01m)\x0d\x0a"
+	,"Remove this sub-board from your new-scan list"
+	,"\x0d\x0a~Sub-board, ~Group, or ~All: "
+	,"\x0d\x0a~Directory, ~Library, or ~All: "
+	,"\x0d\x0a\x01_\x01y\x01hEnter path: "
+	,"\x0d\x0aSearch and display extended information"
+	,"\x0d\x0aDisplay Subjects Only"
+	,"\x0d\x0aEcho is now %s \x0d\x0a"
+	,"\x0d\x0a\x01n\x01y\x01hPrivate Chat - \x01bCtrl-C to Quit\x01n\x0d\x0a\x0d\x0a"
+	,"\x0d\x0a\x01n\x01gUploading \x01h%s.REP\x0d\x0a"
+	,"\x01n\x01gReceived \x01n\x01h%s\x01n\x01g from \x01h%s\x01n\x01g via QWK.\x0d\x0a"
+	,"\x01r\x01h\x01i\x0dQWK packet message limit reached.\x01n\x01h\x0d\x0a"
+	,"\x0d\x0a\x01nPrivate posts not allowed on this sub.\x0d\x0a"
+	,"\x01_\x01w\x01hLoading message pointers..."
+	,"\x0d                               \x0d"
+	,"\x0d\x0aQuote original message"
+	,"\x0d\x0a\x01b\x01hLine numbers (#,#), Range (#-#), \x01w~L\x01bist or [%s]: \x01w"
+	,"\x0d\x0a\x01_\x01c\x01hMultinode Chat Channels:\x0d\x0a\x0d\x0a"
+	,"\x01n\x01cNum Name                         Cost"
+	,"\x01h\xc4\xc4\xc4 \xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4    \xc4\xc4\xc4\xc4"
+	,"\x01h\x01c%3u \x01n\x01c%-25.25s\x01h%8u"
+	,"\x0d\x0aYou can't access that channel.\x0d\x0a"
+	,"\x0d\x0aYou can't download from this directory.\x0d\x0a"
+	,"\x01_\x01w\x01hSearching for duplicates..."
+	,"\x0d\x01n                                 \x0d"
+	,"\x01n\x01hYour account will expire in \x01r\x01i%d\x01n\x01h days.\x0d\x0a"
+	,"\x01n\x01r\x01h\x01iYour account has expired!\x01n\x0d\x0a"
+	,"\x0d\x0aDownload files in batch queue now"
+	,"\x01_\x01r\x01h\x0d\x0aWaiting for Slow Media Device #%u..."
+	,"\x07\x01n\x01y\x01h%s\x01n\x01c sent you E-mail.\x0d\x0a"
+	,"\x07\x01n\x01y\x01h%s\x01n\x01c sent you a file.\x0d\x0a"
+	,"\x01n\x01y\x01h%s\x01n\x01c read your E-mail on %s.\x0d\x0a"
+	,"\x07\x01_\x01w\x01hNode %2d: \x01g%s\x01n\x01g read your E-mail.\x0d\x0a"
+	,"\x0d\x0aWhich, ~Quit, or [%u]: "
+	,"\x0d\x0aWhich, ~Quit, or [%u]: "
+	,"\x0d\x0aWhich, ~Quit, or [%u]: "
+	,"\x0d\x0aWhich, ~Quit, or [%u]: "
+	,"\x01l\x01-\x01gDirectories of \x01h%s:\x0d\x0a\x0d\x0a\x01h"
+	," \x01n\x01g(\x01h%d\x01n\x01g) %s\x01h\x0d\x0a"
+	,"\x01l\x01_\x01g\x01hFile Libraries:\x0d\x0a\x0d\x0a"
+	,"\x01n\x01g(\x01h%d\x01n\x01g) %s\x01h\x0d\x0a"
+	,"\x01_\x01c\x01hListing \x01n\x01c(\x01h%u\x01n\x01c) %s (\x01h%u\x01n\x01c) %s (\x01h?\x01n\x01c=Menu) (\x01h%u\x01n\x01c Files\x01n\x01c): \x01n"
+	,"\x01n\x01l\x014  \x01h\x01y[\x01wB\x01y]atch Download  [\x01wV\x01y]iew Content  [\x01wE\x01y]xtended Info  [\x01wP\x01y]revious Files  [\x01wQ\x01y]uit  \x01n\x0d\x0a"
+	,"\x0d\x0aDownload attached file: \x01w%s\x01b (%s bytes)"
+	,"\x0d\x0a\x0d\x0a\x01nTime left : %13u\x0d\x0a"
+	,"\x01b\x01h\x0d\x0aTime left to deposit in minute bank (\x01w%u Max\x01b): \x01n"
+	,"\x0d\x0aE-mail file attachments not allowed.\x0d\x0a"
+	,"\x0d\x0a\x01nSorry, you have insufficient access to run that program.\x0d\x0a\x0d\x0a\x01p"
+	,"\x01n\x01h\x0d\x0a\x07\x0d\x0aYou only have \x01r\x01i%u\x01n\x01h minute%s left.\x0d\x0a\x0d\x0a"
+	,"\x0d\x01n\x01r\x01h\x01i\x07\x07@NAME@! \x01n\x01hAre you really there? \x01n\x01>"
+	,"Level %u"
+	,"Age %u"
+	,"BPS %u"
+	,"Credits %u"
+	,"Node %u"
+	,"User %u"
+	,"Days till expire %u"
+	,"Time Left %u"
+	,"Time Used %u"
+	,"Time of day %02d:%02d"
+	,"Post/Call Ratio %u"
+	,"Upload/Download Ratio %u"
+	,"Upload/Download File Ratio %u"
+	,"Flag 1 %c"
+	,"Flag 2 %c"
+	,"Flag 3 %c"
+	,"Flag 4 %c"
+	,"Sex %c"
+	,"Exemption %c"
+	,"Restriction %c"
+	,"Day of week %s"
+	,"Group %u"
+	,"Sub-board %u"
+	,"Library %u"
+	,"Directory %u"
+	,"\x01n\x01hNode Status\x0d\x0a\x01c\xc4\xc4\xc4\xc4 \xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\x0d\x0a"
+	,""
+	,""
+	,""
+	,""
+	,""
+	,""
+	,""
+	,""
+	,""
+	,""
+	,""
+	,""
+	,""
+	,""
+	,""
+	,""
+	,""
+	,"\x01h%s\x01n\x01g \x01(%u\x01) %u %c in multinode chat%.0s%.0s%.0s channel %u"
+	,""
+	,""
+	,""
+	,""
+	,""
+	,""
+	,""
+	,"YNQ*"
+	,"View signature"
+	,"Delete signature"
+	,"Create/Edit signature"
+	,"Spinning cursor on pause prompts"
+	,"Use an external editor"
+	,"External Editor"
+	,"Command Shell"
+	,"Archive Type"
+};
diff --git a/src/sbbs3/text_defaults.h b/src/sbbs3/text_defaults.h
new file mode 100644
index 0000000000000000000000000000000000000000..15d3e51b3448d7a2c09aa493f4c9a3c0bef3550e
--- /dev/null
+++ b/src/sbbs3/text_defaults.h
@@ -0,0 +1,20 @@
+/* text_defaults.h */
+
+/* Synchronet default text strings */
+
+/* $Id$ */
+
+/****************************************************************************
+ * @format.tab-size 4		(Plain Text/Source Code File Header)			*
+ * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
+ *																			*
+ * Auto-generated from CTRL\TEXT.DAT										*
+/****************************************************************************
+
+#ifndef _TEXT_DEFAULTS_H_
+#define _TEXT_DEFAULTS_H_
+
+#include "text.h"
+extern const char * const text_defaults[TOTAL_TEXT]
+
+#endif
diff --git a/src/sbbs3/textgen.c b/src/sbbs3/textgen.c
new file mode 100644
index 0000000000000000000000000000000000000000..f7d540e2b3829d3abcaa277c8ce0332923946d01
--- /dev/null
+++ b/src/sbbs3/textgen.c
@@ -0,0 +1,348 @@
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "gen_defs.h"
+
+/****************************************************************************/
+/* Converts an ASCII Hex string into an ulong                               */
+/* by Steve Deppe (Ille Homine Albe)										*/
+/****************************************************************************/
+/* Copied from str_util.c */
+ulong ahtoul(char *str)
+{
+    ulong l,val=0;
+
+	while((l=(*str++)|0x20)!=0x20)
+		val=(l&0xf)+(l>>6&1)*9+val*16;
+	return(val);
+}
+
+/****************************************************************************/
+/* Reads special TEXT.DAT printf style text lines, splicing multiple lines, */
+/* replacing escaped characters, and allocating the memory					*/
+/****************************************************************************/
+/* Copied from load_cfg.c with comment pointer added */
+char *readtext(FILE *stream, char **comment_ret)
+{
+	char buf[2048],str[2048],tmp[256],*p,*p2;
+	char comment[2048], *cp;
+	int i,j,k;
+
+	if(!fgets(buf,256,stream))
+		return(NULL);
+	if(buf[0]=='#')
+		return(NULL);
+	p=strrchr(buf,'"');
+	if(!p) {
+		return(NULL); 
+	}
+	comment[0]=0;
+	if(*(p+1)=='\\') {	/* merge multiple lines */
+		for(cp=p+2; *cp && isspace(*cp); cp++);
+		strcat(comment, cp);
+		while(strlen(buf)<2000) {
+			if(!fgets(str,255,stream))
+				return(NULL);
+			p2=strchr(str,'"');
+			if(!p2)
+				continue;
+			strcpy(p,p2+1);
+			p=strrchr(p,'"');
+			if(p && *(p+1)=='\\') {
+				for(cp=p+2; *cp && isspace(*cp); cp++);
+				strcat(comment, cp);
+				continue;
+			}
+			break; 
+		}
+	}
+	for(cp=p+2; *cp && isspace(*cp); cp++);
+	strcat(comment, cp);
+	cp=strchr(comment, 0);
+	if(cp && cp > comment) {
+		cp--;
+		while(cp > comment && isspace(*cp)) {
+			*(cp--)=0;
+		}
+	}
+
+	*(p)=0;
+	k=strlen(buf);
+	for(i=1,j=0;i<k;j++) {
+		if(buf[i]=='\\')	{ /* escape */
+			i++;
+			if(isdigit(buf[i])) {
+				str[j]=atoi(buf+i); 	/* decimal, NOT octal */
+				if(isdigit(buf[++i]))	/* skip up to 3 digits */
+					if(isdigit(buf[++i]))
+						i++;
+				continue; 
+			}
+			switch(buf[i++]) {
+				case '\\':
+					str[j]='\\';
+					break;
+				case '?':
+					str[j]='?';
+					break;
+				case 'x':
+					tmp[0]=buf[i++];        /* skip next character */
+					tmp[1]=0;
+					if(isxdigit(buf[i])) {  /* if another hex digit, skip too */
+						tmp[1]=buf[i++];
+						tmp[2]=0; 
+					}
+					str[j]=(char)ahtoul(tmp);
+					break;
+				case '\'':
+					str[j]='\'';
+					break;
+				case '"':
+					str[j]='"';
+					break;
+				case 'r':
+					str[j]=CR;
+					break;
+				case 'n':
+					str[j]=LF;
+					break;
+				case 't':
+					str[j]=TAB;
+					break;
+				case 'b':
+					str[j]=BS;
+					break;
+				case 'a':
+					str[j]=BEL;
+					break;
+				case 'f':
+					str[j]=FF;
+					break;
+				case 'v':
+					str[j]=11;	/* VT */
+					break;
+				default:
+					str[j]=buf[i];
+					break; 
+			}
+			continue; 
+		}
+		str[j]=buf[i++]; 
+	}
+	str[j]=0;
+	if((p=(char *)calloc(1,j+2))==NULL) { /* +1 for terminator, +1 for YNQX line */
+		fprintf(stderr,"Error allocating %u bytes of memory from text.dat",j);
+		return(NULL); 
+	}
+	strcpy(p,str);
+	if(comment_ret)
+		*comment_ret=strdup(comment);
+	return(p);
+}
+
+char *format_as_cstr(char *orig)
+{
+	int		len=0;
+	int		outpos=0;
+	char	*ret=NULL;
+	char	*in;
+	char	*tmp;
+	char	hex[32];
+
+	if(!orig)
+		return(NULL);
+	for(in=orig; *in; in++) {
+		if(outpos >= len-5) {
+			len += strlen(in)+5;
+			tmp=realloc(ret, len);
+			if(tmp==NULL) {
+				free(ret);
+				return(NULL);
+			}
+			ret=tmp;
+		}
+		if(*in < ' ' || *in > '~') {
+			sprintf(hex, "%02x", (unsigned char)*in);
+			ret[outpos++]='\\';
+			ret[outpos++]='x';
+			ret[outpos++]=hex[0];
+			ret[outpos++]=hex[1];
+		}
+		else
+			ret[outpos++]=*in;
+	}
+	if(in==orig) {
+		ret=(char *)malloc(1);
+	}
+	if(ret)
+		ret[outpos]=0;
+	return(ret);
+}
+
+int main(int argc, char **argv)
+{
+	FILE			*text_dat;
+	char			*p;
+	char			*cstr;
+	char			*comment;
+	char			*macro;
+	unsigned long	lno;
+	int				i=0;
+	FILE			*text_h;
+	FILE			*text_js;
+	FILE			*text_defaults_c;
+
+	if((text_dat=fopen("../../ctrl/text.dat","r"))==NULL) {
+		fprintf(stderr,"Can't open text.dat!\n");
+		return(1);
+	}
+	if((text_h=fopen("text.h", "w"))==NULL) {
+		fprintf(stderr,"Can't open text.h!\n");
+		return(1);
+	}
+	fputs("/* text.h */\n",text_h);
+	fputs("\n",text_h);
+	fputs("/* Synchronet static text string constants */\n",text_h);
+	fputs("\n",text_h);
+	fputs("/* $Id$ */\n",text_h);
+	fputs("\n",text_h);
+	fputs("/****************************************************************************\n",text_h);
+	fputs(" * @format.tab-size 4		(Plain Text/Source Code File Header)			*\n",text_h);
+	fputs(" * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*\n",text_h);
+	fputs(" *																			*\n",text_h);
+	fputs(" * Copyright 2008 Rob Swindell - http://www.synchro.net/copyright.html		*\n",text_h);
+	fputs(" *																			*\n",text_h);
+	fputs(" * This program is free software; you can redistribute it and/or			*\n",text_h);
+	fputs(" * modify it under the terms of the GNU General Public License				*\n",text_h);
+	fputs(" * as published by the Free Software Foundation; either version 2			*\n",text_h);
+	fputs(" * of the License, or (at your option) any later version.					*\n",text_h);
+	fputs(" * See the GNU General Public License for more details: gpl.txt or			*\n",text_h);
+	fputs(" * http://www.fsf.org/copyleft/gpl.html										*\n",text_h);
+	fputs(" *																			*\n",text_h);
+	fputs(" * Anonymous FTP access to the most recent released source is available at	*\n",text_h);
+	fputs(" * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net	*\n",text_h);
+	fputs(" *																			*\n",text_h);
+	fputs(" * Anonymous CVS access to the development source and modification history	*\n",text_h);
+	fputs(" * is available at cvs.synchro.net:/cvsroot/sbbs, example:					*\n",text_h);
+	fputs(" * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login			*\n",text_h);
+	fputs(" *     (just hit return, no password is necessary)							*\n",text_h);
+	fputs(" * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src		*\n",text_h);
+	fputs(" *																			*\n",text_h);
+	fputs(" * For Synchronet coding style and modification guidelines, see				*\n",text_h);
+	fputs(" * http://www.synchro.net/source.html										*\n",text_h);
+	fputs(" *																			*\n",text_h);
+	fputs(" * You are encouraged to submit any modifications (preferably in Unix diff	*\n",text_h);
+	fputs(" * format) via e-mail to mods@synchro.net									*\n",text_h);
+	fputs(" *																			*\n",text_h);
+	fputs(" * Note: If this box doesn't appear square, then you need to fix your tabs.	*\n",text_h);
+	fputs(" ****************************************************************************/\n",text_h);
+	fputs("\n",text_h);
+	fputs("/****************************************************************************/\n",text_h);
+	fputs("/* Macros for elements of the array of pointers (text[]) to static text		*/\n",text_h);
+	fputs("/* Auto-generated from CTRL\\TEXT.DAT										*/\n",text_h);
+	fputs("/****************************************************************************/\n",text_h);
+	fputs("\n",text_h);
+	fputs("#ifndef _TEXT_H\n",text_h);
+	fputs("#define _TEXT_H\n",text_h);
+	fputs("\n",text_h);
+	fputs("enum {\n",text_h);
+	if((text_js=fopen("../../exec/text.js", "w"))==NULL) {
+		fprintf(stderr,"Can't open text.js!\n");
+		return(1);
+	}
+	fputs("/* text.js */\n",text_js);
+	fputs("\n",text_js);
+	fputs("/* Synchronet static text string constants */\n",text_js);
+	fputs("\n",text_js);
+	fputs("/* $Id$ */\n",text_js);
+	fputs("\n",text_js);
+	fputs("/****************************************************************************\n",text_js);
+	fputs(" * @format.tab-size 4		(Plain Text/Source Code File Header)			*\n",text_js);
+	fputs(" * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*\n",text_js);
+	fputs(" *																			*\n",text_js);
+	fputs(" * Copyright 2008 Rob Swindell - http://www.synchro.net/copyright.html		*\n",text_js);
+	fputs(" *																			*\n",text_js);
+	fputs(" * This program is free software; you can redistribute it and/or			*\n",text_js);
+	fputs(" * modify it under the terms of the GNU General Public License				*\n",text_js);
+	fputs(" * as published by the Free Software Foundation; either version 2			*\n",text_js);
+	fputs(" * of the License, or (at your option) any later version.					*\n",text_js);
+	fputs(" * See the GNU General Public License for more details: gpl.txt or			*\n",text_js);
+	fputs(" * http://www.fsf.org/copyleft/gpl.html										*\n",text_js);
+	fputs(" *																			*\n",text_js);
+	fputs(" * Anonymous FTP access to the most recent released source is available at	*\n",text_js);
+	fputs(" * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net	*\n",text_js);
+	fputs(" *																			*\n",text_js);
+	fputs(" * Anonymous CVS access to the development source and modification history	*\n",text_js);
+	fputs(" * is available at cvs.synchro.net:/cvsroot/sbbs, example:					*\n",text_js);
+	fputs(" * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login			*\n",text_js);
+	fputs(" *     (just hit return, no password is necessary)							*\n",text_js);
+	fputs(" * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src		*\n",text_js);
+	fputs(" *																			*\n",text_js);
+	fputs(" * For Synchronet coding style and modification guidelines, see				*\n",text_js);
+	fputs(" * http://www.synchro.net/source.html										*\n",text_js);
+	fputs(" *																			*\n",text_js);
+	fputs(" * You are encouraged to submit any modifications (preferably in Unix diff	*\n",text_js);
+	fputs(" * format) via e-mail to mods@synchro.net									*\n",text_js);
+	fputs(" *																			*\n",text_js);
+	fputs(" * Note: If this box doesn't appear square, then you need to fix your tabs.	*\n",text_js);
+	fputs(" ****************************************************************************/\n",text_js);
+	fputs("\n",text_js);
+	fputs("/****************************************************************************/\n",text_js);
+	fputs("/* Values for elements of the array of pointers (bbs.text()) to static text	*/\n",text_js);
+	fputs("/* Auto-generated from CTRL\\TEXT.DAT										*/\n",text_js);
+	fputs("/****************************************************************************/\n",text_js);
+	fputs("\n",text_js);
+	if((text_defaults_c=fopen("text_defaults.c","w"))==NULL) {
+		fprintf(stderr,"Can't open text_defaults.c!\n");
+		return(1);
+	}
+	fputs("/* text_defaults.c */\n",text_defaults_c);
+	fputs("\n",text_defaults_c);
+	fputs("/* Synchronet default text strings */\n",text_defaults_c);
+	fputs("\n",text_defaults_c);
+	fputs("/* $Id$ */\n",text_defaults_c);
+	fputs("\n",text_defaults_c);
+	fputs("/****************************************************************************\n",text_defaults_c);
+	fputs(" * @format.tab-size 4		(Plain Text/Source Code File Header)			*\n",text_defaults_c);
+	fputs(" * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*\n",text_defaults_c);
+	fputs(" *																			*\n",text_defaults_c);
+	fputs(" * Auto-generated from CTRL\\TEXT.DAT										*\n",text_defaults_c);
+	fputs(" ****************************************************************************/\n",text_defaults_c);
+	fputs("\n",text_defaults_c);
+	fputs("#include \"text_defaults.h\"\n",text_defaults_c);
+	fputs("\n",text_defaults_c);
+	fputs("const char * const text_defaults[TOTAL_TEXT]={\n",text_defaults_c);
+	do {
+		i++;
+		p=readtext(text_dat, &comment);
+		if(p!=NULL) {
+			cstr=format_as_cstr(p);
+			if(cstr==NULL) {
+				fprintf(stderr,"Error creating C string! for %d\n", i+1);
+			}
+			lno=strtoul(comment, &macro, 10);
+			while(isspace(*macro))
+				macro++;
+			if(lno != i) {
+				fprintf(stderr,"Mismatch! %s has %d... should be %d\n", comment, lno, i);
+			}
+			fprintf(text_h, "\t%c%s\n", i==1?' ':',', macro);
+			fprintf(text_js, "var %s=%d;\n", macro, i);
+			fprintf(text_defaults_c, "\t%c\"%s\"\n", i==1?' ':',', cstr);
+		}
+	} while(p != NULL);
+	fclose(text_dat);
+	
+	fputs("\n",text_h);
+	fputs("\t,TOTAL_TEXT\n",text_h);
+	fputs("};\n",text_h);
+	fputs("\n",text_h);
+	fputs("#endif\n",text_h);
+	fclose(text_h);
+	fputs("\n",text_h);
+	fprintf(text_h, "var TOTAL_TEXT=%d;\n",i);
+	fclose(text_js);
+	fputs("};\n",text_defaults_c);
+	fclose(text_defaults_c);
+}