diff --git a/CTRL/TEXT.DAT b/CTRL/TEXT.DAT
index fe86f053bc18a8596f4b8505365a6992f1fa12bd..d7b18a8d1393a2c166bba0a9ec4980bcc5c624e2 100644
--- a/CTRL/TEXT.DAT
+++ b/CTRL/TEXT.DAT
@@ -322,7 +322,7 @@
 "\r\nHang up after transfer"				HangUpAfterXferQ
 "\r\nwhStart transfer now (Ctrl-X to abort):\r\nn"	StartXferNow
 "_\r\nbhDisconnecting... wHbang up or wAbbort "	Disconnecting
-"\rwhGood-bye!                        "\		Disconnected
+"\rwhGood-bye!  (Time Used: @TUSED@)               "\	Disconnected
 	"             \r\n"	
 "rhi%s NOT SENT!n\r\n"				FileNotSent
 "Deleting files in temp directory...\r\n"		RemovingTmpFiles
@@ -832,3 +832,24 @@
 "\r\nE-mail file attachments not allowed.\r\n"		EmailFileNotAllowed
 "\r\nnSorry, you have insufficient access to run "\	CantRunThatProgram
 	"that program.\r\n\r\np"
+"nh\r\n\7\r\nYou only have ri%unh minute%s "\     OnlyXminutesLeft
+	"left.\r\n\r\n"
+"Level %u"                                              NoAccessLevel
+"Age %u"                                                NoAccessAge
+"BPS %u"                                                NoAccessBPS
+"Credits %lu"                                           NoAccessCredit
+"Node %u"                                               NoAccessNode
+"User %u"                                               NoAccessUser
+"Days till expire %u"                                   NoAccessExpire
+"Time Left %u"                                          NoAccessTimeLeft
+"Time Used %u"                                          NoAccessTimeUsed
+"Time of day %02d:%02d"                                 NoAccessTime
+"Post/Call Ratio %u"                                    NoAccessPCR
+"Upload/Download Ratio %u"                              NoAccessUDR
+"Upload/Download File Ratio %u"                         NoAccessUDFR
+"Flag 1 %c"                                             NoAccessFlag1
+"Flag 2 %c"                                             NoAccessFlag2
+"Flag 3 %c"                                             NoAccessFlag3
+"Flag 4 %c"                                             NoAccessFlag4
+"Sex %c"                                                NoAccessSex
+
diff --git a/SRC/BBS_OVL.C b/SRC/BBS_OVL.C
index 9aaee2ad3cc5a19f18c37d1cc4675c29ca169281..9da02886e3a1e536b7613a6f70fe3cff3a273408 100644
--- a/SRC/BBS_OVL.C
+++ b/SRC/BBS_OVL.C
@@ -180,7 +180,7 @@ while(online && !done) {
 								strcat(str3,tmp); }
 						ch=getkeys(str3,0);
 						for(i=0;i<total_prots;i++)
-							if(ch==prot[i]->mnemonic)
+							if(prot[i]->dlcmd[0] && ch==prot[i]->mnemonic)
 								break;
 						if(i<total_prots) {
 							j=protocol(cmdstr(prot[i]->dlcmd,str2,nulstr));
@@ -455,6 +455,8 @@ while(curmsg<MAX_MAILS && !ferror(instream)) {
 		if((piece[curmsg]=(mail_t *)MALLOC(sizeof(mail_t)))==NULL) {
 			fclose(instream);
 			errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(mail_t));
+			for(i=0;i<curmsg;i++)
+				FREE(piece[i]);
 			FREE(piece);
 			return; }
 		piece[curmsg]->mode=(str[8]-SP);
@@ -633,6 +635,8 @@ while(!ferror(instream) && curmsg<MAX_SYSMAIL) {
 	if((piece[curmsg]=(mail_t *)MALLOC(sizeof(mail_t)))==NULL) {
 		fclose(instream);
 		errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(mail_t));
+		for(i=0;i<curmsg;i++)
+			FREE(piece[i]);
 		FREE(piece);
 		FREE(flag);
 		return; }
diff --git a/SRC/COMIO.C b/SRC/COMIO.C
index ded9ca35304748cd4400b4d23d0aa5d8b516ed09..6c1b17117da72f7b7b5d5a96adc4736a414c0452 100644
--- a/SRC/COMIO.C
+++ b/SRC/COMIO.C
@@ -8,6 +8,7 @@
 
 #include "sbbs.h"
 
+extern mswtyp;
 extern uint riobp;
 extern char term_ret;
 
@@ -296,15 +297,9 @@ if(mdm_misc&MDM_RTS)
 if(i)
 	rioctl(IOSM|i); /* set cts checking if hardware flow control */
 
-i=0;
-if(node_misc&NM_INT28)
-	i|=TS_INT28;
-if(i&NM_WINOS2)
-	i|=TS_WINOS2;
-if(i&NM_NODV)
-	i|=TS_NODV;
-i|=TS_NODV;
-rioctl(TSTYPE|i);	/* set time-slice API type */
+rioctl(TSTYPE|mswtyp);	 /* set time-slice API type */
+
+rioctl(CPTON);			/* ctrl-p translation */
 
 sys_status|=SS_COMISR;
 #endif
diff --git a/SRC/CONIO.C b/SRC/CONIO.C
index aad389d904cdd818901866c156d2bd55693453d2..5977ae53e94105deb569b8a7e04872ea2f876d0a 100644
--- a/SRC/CONIO.C
+++ b/SRC/CONIO.C
@@ -220,7 +220,7 @@ if(lncntr==rows-1 && ((useron.misc&UPAUSE && !(sys_status&SS_PAUSEOFF))
 /****************************************************************************/
 char getkey(int mode)
 {
-	char ch,c=0,spin=random(5),warn=0;
+	char ch,c=0,spin=random(5);
 
 if(!online)
 	return(0);
@@ -229,6 +229,7 @@ if((sys_status&SS_USERON || action==NODE_DFLT) && !(mode&K_GETSTR))
 	mode|=(useron.misc&SPIN);
 lncntr=0;
 timeout=time(NULL);
+inactive_warn=0;
 if(mode&K_SPIN)
 	outchar(' ');
 do {
@@ -415,8 +416,15 @@ do {
 		console|=(CON_R_ECHO|CON_L_ECHO);
 		bputs(text[TakenTooLongToLogon]);
 		hangup(); }
-	if(now-timeout>=SEC_WARN && !warn)	  /* warning */
-		for(warn=0;warn<5;warn++)
+	if((timeleft/60)<(5-timeleft_warn)) {
+		timeleft_warn=5-(timeleft/60);
+		SAVELINE;
+		bprintf(text[OnlyXminutesLeft]
+			,(timeleft/60)+1,(timeleft/60) ? "s" : nulstr);
+		RESTORELINE; }
+
+	if(now-timeout>=SEC_WARN && !inactive_warn)    /* warning */
+		for(inactive_warn=0;inactive_warn<5;inactive_warn++)
 			outchar(7); }
 	while(now-timeout<SEC_HANGUP && online);
 if(!online)
@@ -1170,6 +1178,7 @@ while((ch=getkey(mode|K_GETSTR))!=CR && online && !(sys_status&SS_ABORT)) {
 		case 22:	/* Ctrl-V 	Center line */
 			str1[l]=0;
 			l=bstrlen(str1);
+			if(!l) break;
 			for(x=0;x<(maxlen-l)/2;x++)
 				str2[x]=SP;
 			str2[x]=0;
@@ -2460,7 +2469,7 @@ switch(node.status) {
                 else hour=node.aux/60;
                 strcpy(mer,"am"); }
             bprintf(" ETA %02d:%02d %s"
-                ,hour,node.aux-((node.aux/60)*60),mer); }
+				,hour,node.aux%60,mer); }
         break; }
 if(node.misc&(NODE_LOCK|NODE_POFF|NODE_AOFF|NODE_MSGW|NODE_NMSG)) {
     bputs(" (");
@@ -2888,6 +2897,9 @@ else if(!strcmp(sp,"DL"))
 else if(!strcmp(sp,"DR"))
 	bprintf("%4u",curdir[curlib]+1);
 
+else if(!strcmp(sp,"NOACCESS"))
+	bputs(noaccess);
+
 else return(0);
 
 return(len);
diff --git a/SRC/DEFS.H b/SRC/DEFS.H
index 3691b4eb5733fc1983f6ab30589de524ec92d509..69715be37ead82c1c31ae976b28e6288507d7bb1 100644
--- a/SRC/DEFS.H
+++ b/SRC/DEFS.H
@@ -16,7 +16,7 @@
 /*************/
 
 #define DEBUG		0		/* Set to zero to stop DEBUG LOG writes 	*/
-#define INHOUSE 	0		/* Set to non-zero for In-house devlopement */
+#define INHOUSE 	1		/* Set to non-zero for In-house devlopement */
 
 #define VERSION 	"1c"    /* Version, Major number, Minor letter */
 #define REVISION	1		/* Revision number */
@@ -270,6 +270,10 @@ enum {								/* Access requirement binaries */
 	,AR_FLAG3
 	,AR_FLAG4
     ,AR_SEX
+	,AR_UDR
+	,AR_UDFR
+	,AR_EXPIRE
+	,AR_CREDIT
     };
 
 #define SBBS_MAIN_CMDS "ABCDEFGINOPQRSTUXZ&*JM"
@@ -830,6 +834,11 @@ enum {						/* Values of mode for userlist function     */
 #define IOSM 1          	/* i/o set mode flags */
 #define IOCM 2          	/* i/o clear mode flags */
 
+#define GVERS 0x007 		/* get version */
+#define GUART 0x107 		/* get uart */
+#define GIRQN 0x207 		/* get IRQ number */
+#define GBAUD 0x307 		/* get baud */
+
 							/* the following return state in high 8 bits */
 #define IOSTATE 4       	/* no operation */
 #define IOSS 5          	/* i/o set state flags */
@@ -845,16 +854,31 @@ enum {						/* Values of mode for userlist function     */
 
 							/* return count (16bit)	*/
 #define RXBC	0x000a		/* get receive buffer count */
+#define RXBS	0x010a		/* get receive buffer size */
 #define TXBC	0x000b		/* get transmit buffer count */
+#define TXBS	0x010b		/* get transmit buffer size */
+#define TXBF	0x020b		/* get transmit buffer free space */
 #define TXSYNC	0x000c		/* sync transmition (seconds<<8|0x0c) */
 #define IDLE	0x000d		/* suspend communication routines */
 #define RESUME	0x010d		/* return from suspended state */
 #define RLERC	0x000e		/* read line error count and clear */
 #define CPTON	0x0110		/* set input translation flag for ctrl-p on */
 #define CPTOFF	0x0010		/* set input translation flag for ctrl-p off */
+#define GETCPT	0x8010		/* return the status of ctrl-p translation */
 #define MSR 	0x0011		/* read modem status register */
 #define FIFOCTL 0x0012		/* FIFO UART control */
 #define TSTYPE	0x0013		/* Time-slice API type */
+#define GETTST	0x8013		/* Get Time-slice API type */
+
+#define SMSMK	0x0014		/* set modem status mask */
+#define SMLCR	0x0015		/* set modem line control register */
+#define LFN81	0x0315		/* set line format N81 */
+#define LFE71	0x1A15		/* set line format E71 */
+#define SRXHL	0x001E		/* set receive flow control high limit */
+#define SRXLL	0x001F		/* set receive flow control low limit */
+#define IGCLS	0x0020		/* input gate close */
+#define IGOPN	0xFF20		/* input gate open */
+
 
 							/* ivhctl() arguments */
 #define INT29R 1         	/* copy int 29h output to remote */
diff --git a/SRC/LOGONOFF.C b/SRC/LOGONOFF.C
index 6fbcaa2a82b9f292a688d95dc3b7efe9d238ee54..c94775ac04299a38fa8cba8cccca925593268f0c 100644
--- a/SRC/LOGONOFF.C
+++ b/SRC/LOGONOFF.C
@@ -247,7 +247,7 @@ strcpy(str,text[LiSysopIs]);
 #else
 	i=peekb(0,0x417);		/* Check scroll lock */
 #endif
-	if(i&16)
+	if(i&16 || (sys_chat_ar[0] && chk_ar(sys_chat_ar,useron)))
 		strcat(str,text[LiSysopAvailable]);
 	else
 		strcat(str,text[LiSysopNotAvailable]);
diff --git a/SRC/MAIN_OVL.C b/SRC/MAIN_OVL.C
index 4a0127353cdded909daa61f41aa9ee3e384de39c..43b912678f42ba1ad14ebfc9072e4d1d49cb61ac 100644
--- a/SRC/MAIN_OVL.C
+++ b/SRC/MAIN_OVL.C
@@ -76,7 +76,7 @@ max_nodes=MAX_NODES;
 setcbrk(0);
 
 #ifndef __OS2__
-if((asmrev=*(&riobp-1))!=17) {
+if((asmrev=*(&riobp-1))!=19) {
     printf("Wrong rciol.obj\n");
     exit(1); }
 #endif
@@ -124,7 +124,7 @@ if(!strstr(str,"[SBBS]")) {
 	sprintf(prompt,"PROMPT=[SBBS] %s",str);
 	putenv(prompt); }
 
-/******** Old protection scheme
+/******** Old protection scheme *
 
 #define CSF1 *(s+vcom1)     /* putlch C3h retn -> CBh retf */
 #define CSF2 *(s+vcom2)     /* putls 0Fh pop cs -> CBh retf */
diff --git a/SRC/MAIN_SEC.C b/SRC/MAIN_SEC.C
index d726e09712112bf7b3741e135eea9c1584cc2d80..2aba52c309c921f7e236ab931cebbf8031c9ad78 100644
--- a/SRC/MAIN_SEC.C
+++ b/SRC/MAIN_SEC.C
@@ -895,7 +895,7 @@ if(SYSOP) {
 		return; }
 	if(!strcmp(str,"EVENT")) {
 		bprintf(text[EventInfo],sys_eventnode,sys_eventtime/60
-			,sys_eventtime-((sys_eventtime/60)*60)
+			,sys_eventtime%60
 			,timestr(&lastevent));
 		return; }
 	if(!strcmp(str,"MAIL")) {      /* Read all mail on system */
diff --git a/SRC/MAIN_WFC.C b/SRC/MAIN_WFC.C
index 3f2c4d620585265eb4ad974137721b9ba7bcbcb3..4a533905e1c140ec4c7996ae21919c4345d9a5e1 100644
--- a/SRC/MAIN_WFC.C
+++ b/SRC/MAIN_WFC.C
@@ -456,6 +456,7 @@ if(sys_status&SS_RETURN) {
     read(file,&logon_emails,sizeof(logon_emails));
     read(file,&logon_fbacks,sizeof(logon_fbacks));
 	read(file,&logon_ml,sizeof(logon_ml));
+	read(file,&timeleft_warn,sizeof(timeleft_warn));
     read(file,&curgrp,sizeof(curgrp));
     for(i=0;i<total_grps;i++)
         read(file,&cursub[i],sizeof(cursub[0]));
@@ -517,7 +518,7 @@ if(term_ret)
 if(com_port)
     rioctl(0x10f);  /* for blanking debug line */
 ***/
-keybufbot=keybuftop=online=console=lbuflen=slcnt=altul=0;
+keybufbot=keybuftop=online=console=lbuflen=slcnt=altul=timeleft_warn=0;
 sys_status&=~(SS_USERON|SS_TMPSYSOP|SS_LCHAT|SS_ABORT
 	|SS_PAUSEON|SS_PAUSEOFF|SS_EVENT|SS_NEWUSER);
 if(qoc && calls) {
@@ -795,7 +796,7 @@ while(!gotcaller) {
 			gm=localtime(&now);
 			lprintf("%-3u ",node_num);
 			lclatr(GREEN);
-			lprintf("%-3.3s %02u  Space: ",mon[gm->tm_mon],gm->tm_mday);
+			lprintf("%-3.3s %-2u  Space: ",mon[gm->tm_mon],gm->tm_mday);
 			if(temp_dir[1]==':')
 				k=temp_dir[0]-'A'+1;
 			else k=0;
diff --git a/SRC/MISC.C b/SRC/MISC.C
index 1aedf8f80f053b5ea88a3aef073c669b272851e9..89a796417bd75f31594ac1e09b1dc1158cfbfc0f 100644
--- a/SRC/MISC.C
+++ b/SRC/MISC.C
@@ -41,10 +41,11 @@ int bstrlen(char *str)
 	int i=0;
 
 while(*str) {
-	if(*str==1)	/* ctrl-a */
+	if(*str==1) /* ctrl-a */
 		str++;
 	else
 		i++;
+	if(!(*str)) break;
 	str++; }
 return(i);
 }
@@ -553,6 +554,7 @@ else return(NULL);
 int ar_exp(char **ptrptr, user_t user)
 {
 	uint len,true=1,not,or,equal,artype=AR_LEVEL,n,i,age;
+	ulong l;
 
 for(;(**ptrptr);(*ptrptr)++) {
 
@@ -599,6 +601,8 @@ for(;(**ptrptr);(*ptrptr)++) {
 				true=not;
 			else
 				true=!not;
+			if(!true)
+				sprintf(noaccess,text[NoAccessLevel],n);
 			break;
 		case AR_AGE:
 			age=getage(user.birth);
@@ -606,6 +610,8 @@ for(;(**ptrptr);(*ptrptr)++) {
 				true=not;
 			else
 				true=!not;
+			if(!true)
+				sprintf(noaccess,text[NoAccessAge],n);
 			break;
 		case AR_BPS:
 			if((equal && cur_rate!=i) || (!equal && cur_rate<i))
@@ -613,12 +619,27 @@ for(;(**ptrptr);(*ptrptr)++) {
 			else
 				true=!not;
 			(*ptrptr)++;
+			if(!true)
+				sprintf(noaccess,text[NoAccessBPS],i);
+			break;
+		case AR_CREDIT:
+			l=(long)i*1024L;
+			if((equal && user.cdt+user.freecdt!=l)
+				|| (!equal && user.cdt+user.freecdt<l))
+				true=not;
+			else
+				true=!not;
+			(*ptrptr)++;
+			if(!true)
+				sprintf(noaccess,text[NoAccessCredit],l);
 			break;
 		case AR_NODE:
 			if((equal && node_num!=n) || (!equal && node_num<n))
 				true=not;
 			else
 				true=!not;
+			if(!true)
+				sprintf(noaccess,text[NoAccessNode],n);
 			break;
 		case AR_USER:
 			if((equal && user.number!=i) || (!equal && user.number<i))
@@ -626,18 +647,35 @@ for(;(**ptrptr);(*ptrptr)++) {
 			else
 				true=!not;
 			(*ptrptr)++;
+			if(!true)
+				sprintf(noaccess,text[NoAccessUser],i);
+			break;
+		case AR_EXPIRE:
+			now=time(NULL);
+			l=now-user.expire;
+			if(!user.expire || !l || l/(24L*60L*60L)<i)
+				true=not;
+			else
+				true=!not;
+			(*ptrptr)++;
+			if(!true)
+				sprintf(noaccess,text[NoAccessExpire],i);
 			break;
 		case AR_TLEFT:
 			if(timeleft/60<n)
 				true=not;
 			else
 				true=!not;
+			if(!true)
+				sprintf(noaccess,text[NoAccessTimeLeft],n);
 			break;
 		case AR_TUSED:
 			if((time(NULL)-logontime)/60<n)
 				true=not;
 			else
 				true=!not;
+			if(!true)
+				sprintf(noaccess,text[NoAccessTimeUsed],n);
 			break;
 		case AR_TIME:
 			now=time(NULL);
@@ -647,6 +685,8 @@ for(;(**ptrptr);(*ptrptr)++) {
 			else
 				true=!not;
 			(*ptrptr)++;
+			if(!true)
+				sprintf(noaccess,text[NoAccessTime],i/60,i%60);
 			break;
 		case AR_PCR:
 			if(!user.posts || !(user.logons/user.posts) ||
@@ -654,13 +694,37 @@ for(;(**ptrptr);(*ptrptr)++) {
 				true=not;
 			else
 				true=!not;
+			if(!true)
+				sprintf(noaccess,text[NoAccessPCR],n);
+			break;
+		case AR_UDR:	/* up/download byte ratio */
+			l=user.dlb;
+			if(!l) l=1;
+			if(!user.ulb || !(l/user.ulb) || 100/(l/user.ulb)<n)
+				true=not;
+			else
+				true=!not;
+			if(!true)
+				sprintf(noaccess,text[NoAccessUDR],n);
 			break;
+		case AR_UDFR:	/* up/download file ratio */
+			i=user.dls;
+			if(!i) i=1;
+			if(!user.uls || !(i/user.uls) || 100/(i/user.uls)<n)
+				true=not;
+			else
+				true=!not;
+			if(!true)
+				sprintf(noaccess,text[NoAccessUDFR],n);
+            break;
 		case AR_FLAG1:
 			if((!equal && !(user.flags1&FLAG(n)))
 				|| (equal && user.flags1!=FLAG(n)))
 				true=not;
 			else
 				true=!not;
+			if(!true)
+				sprintf(noaccess,text[NoAccessFlag1],n);
 			break;
 		case AR_FLAG2:
 			if((!equal && !(user.flags2&FLAG(n)))
@@ -668,6 +732,8 @@ for(;(**ptrptr);(*ptrptr)++) {
 				true=not;
 			else
 				true=!not;
+			if(!true)
+				sprintf(noaccess,text[NoAccessFlag2],n);
             break;
 		case AR_FLAG3:
 			if((!equal && !(user.flags3&FLAG(n)))
@@ -675,6 +741,8 @@ for(;(**ptrptr);(*ptrptr)++) {
 				true=not;
 			else
 				true=!not;
+			if(!true)
+				sprintf(noaccess,text[NoAccessFlag3],n);
             break;
 		case AR_FLAG4:
 			if((!equal && !(user.flags4&FLAG(n)))
@@ -682,12 +750,16 @@ for(;(**ptrptr);(*ptrptr)++) {
 				true=not;
 			else
 				true=!not;
+			if(!true)
+				sprintf(noaccess,text[NoAccessFlag4],n);
             break;
 		case AR_SEX:
 			if(user.sex!=n)
 				true=not;
 			else
 				true=!not;
+			if(!true)
+				sprintf(noaccess,text[NoAccessSex],n);
 			break; } }
 return(true);
 }
diff --git a/SRC/MSG_OVL.C b/SRC/MSG_OVL.C
index 64f76828da7587918db6110d0ef0b1c257e62ad2..700943b02b38838f01308b4cdc3bdc140b7100ee 100644
--- a/SRC/MSG_OVL.C
+++ b/SRC/MSG_OVL.C
@@ -17,7 +17,9 @@ void quotestr(char *str)
 	char tmp[512];
 	int i,j;
 
-truncsp(str);
+j=strlen(str);
+while(j && (str[j-1]==SP || str[j-1]==LF || str[j-1]==CR)) j--;
+str[j]=0;
 if(!(useron.exempt&FLAG('E'))) {
 	for(i=j=0;str[i];i++) {    /* Remove elite text if applicable */
 		if(str[i]==1 && toupper(str[i+1])=='E') {
@@ -407,7 +409,7 @@ if(mode&WM_FILE) {
 			remove(msgpath);
 			return; }
 		for(x=0;x<total_prots;x++)
-			if(prot[x]->mnemonic==ch)
+			if(prot[x]->ulcmd[0] && prot[x]->mnemonic==ch)
 				break;
 		if(x<total_prots)	/* This should be always */
 			protocol(cmdstr(prot[x]->ulcmd,str2,nulstr)); }
diff --git a/SRC/QWK.C b/SRC/QWK.C
index 4396df515c1556226168828e5364697dd64bea6a..c045dd94c7a2e66b83ec57b2e5678c4a8df93b41 100644
--- a/SRC/QWK.C
+++ b/SRC/QWK.C
@@ -284,7 +284,7 @@ else
 	i=level_linespermsg[useron.level];
 for(l=128;l<length*128L && lines<i;l++) {
 	if(qwkbuf[l]==0)
-		break;
+		continue;
 	if(qwkbuf[l]==0xE3) {		/* expand 0xe3 to crlf */
 		fwrite(crlf,2,1,stream);
 		lines++;
@@ -382,7 +382,7 @@ while(online) {
 				sub[i]->ptr=sav_ptr[i];   /* re-load saved pointers */
             continue; }
 		for(i=0;i<total_prots;i++)
-			if(prot[i]->mnemonic==ch)
+			if(prot[i]->bicmd[0] && prot[i]->mnemonic==ch)
 				break;
 		if(i<total_prots) {
 			batup_total=1;
@@ -476,7 +476,7 @@ while(online) {
 				sub[i]->ptr=sav_ptr[i];   /* re-load saved pointers */
 			continue; }
 		for(i=0;i<total_prots;i++)
-			if(prot[i]->mnemonic==ch)
+			if(prot[i]->dlcmd[0] && prot[i]->mnemonic==ch)
 				break;
 		if(i<total_prots) {
 			sprintf(str,"%s%s.QWK",temp_dir,sys_id);
@@ -546,7 +546,7 @@ while(online) {
 		if(ch=='Q' || sys_status&SS_ABORT)
 			continue;
 		for(i=0;i<total_prots;i++)
-			if(prot[i]->mnemonic==ch)
+			if(prot[i]->ulcmd[0] && prot[i]->mnemonic==ch)
 				break;
 		if(i>=total_prots)	/* This shouldn't happen */
 			continue;
@@ -1491,13 +1491,16 @@ for(l=128;l<size;l+=i*128) {
 		lseek(file,0L,SEEK_SET);
 		write(file,str,17); /* Write back new total posts and time stamp */
 		lseek(file,0L,SEEK_END);
-		if(useron.rest&FLAG('Q')) {
-			sprintf(tmp,"%-25.25s",block+46);   /* from */
+										   /* Author */
+		if(useron.rest&FLAG('Q')) {        /* get from packet if net */
+			sprintf(tmp,"%-25.25s",block+46);
 			truncsp(tmp);
 			sprintf(str,"@%s",useron.alias);
 			strcat(tmp,strupr(str)); }
 		else {
-			if(sub[usrsub[j][k]]->misc&SUB_NAME)
+			if(sub[usrsub[j][k]]->misc&SUB_AONLY)
+				strcpy(tmp,text[Anonymous]);
+			else if(sub[usrsub[j][k]]->misc&SUB_NAME)
 				strcpy(tmp,useron.name);
 			else
 				strcpy(tmp,useron.alias); }
diff --git a/SRC/SCFG/SCFG.C b/SRC/SCFG/SCFG.C
index 8af6f6e5637b73dc9a30f43df806d62065d8d0d4..a416de70f4e5d40ec04b242852cd9955fb1c1a53 100644
--- a/SRC/SCFG/SCFG.C
+++ b/SRC/SCFG/SCFG.C
@@ -752,8 +752,8 @@ of the name.
 				FREE(txtsec[i]);
 			read_text_cfg(txt); }
 		return; }
-	if((i&0xff00)==MSK_INS) {
-		i&=0xff;
+	if((i&0xf000)==MSK_INS) {
+		i&=0xfff;
 		strcpy(str,"ANSI Artwork");
 		SETHELP(WHERE);
 /*
@@ -793,20 +793,20 @@ abreviation of the name.
 		total_txtsecs++;
 		changes=1;
 		continue; }
-	if((i&0xff00)==MSK_DEL) {
-		i&=0xff;
+	if((i&0xf000)==MSK_DEL) {
+		i&=0xfff;
 		FREE(txtsec[i]);
 		total_txtsecs--;
 		for(j=i;j<total_txtsecs;j++)
 			txtsec[j]=txtsec[j+1];
 		changes=1;
 		continue; }
-	if((i&0xff00)==MSK_GET) {
-		i&=0xff;
+	if((i&0xf000)==MSK_GET) {
+		i&=0xfff;
 		savtxtsec=*txtsec[i];
 		continue; }
-	if((i&0xff00)==MSK_PUT) {
-		i&=0xff;
+	if((i&0xf000)==MSK_PUT) {
+		i&=0xfff;
 		*txtsec[i]=savtxtsec;
 		changes=1;
         continue; }
@@ -1034,6 +1034,12 @@ while(!done) {
 			else if(!strncmp(ar+i,"SEX",3)) {
 				strcat(str,"$S");
 				i+=2; }
+			else if(!strncmp(ar+i,"UDR",3)) {
+				strcat(str,"$K");
+				i+=2; }
+			else if(!strncmp(ar+i,"UDFR",4)) {
+				strcat(str,"$D");
+				i+=3; }
 			else if(!strncmp(ar+i,"FLAG",4)) {
 				strcat(str,"$F");
 				i+=3; }
@@ -1055,6 +1061,12 @@ while(!done) {
 			else if(!strncmp(ar+i,"TUSED",5)) {
 				strcat(str,"$O");
 				i+=4; }
+			else if(!strncmp(ar+i,"EXPIRE",6)) {
+				strcat(str,"$E");
+				i+=5; }
+			else if(!strncmp(ar+i,"CREDIT",6)) {
+				strcat(str,"$C");
+                i+=5; }
 			else if(!strncmp(ar+i,":00",3)) {
 				i+=2; }
 			else
@@ -1077,10 +1089,14 @@ while(!done) {
 	strcpy(opt[i++],"Set Required Sex");
 	strcpy(opt[i++],"Set Required Connect Rate");
 	strcpy(opt[i++],"Set Required Post/Call Ratio");
+	strcpy(opt[i++],"Set Required Number of Credits");
+	strcpy(opt[i++],"Set Required Upload/Download Ratio");
+	strcpy(opt[i++],"Set Required Upload/Download File Ratio");
 	strcpy(opt[i++],"Set Required Time of Day");
 	strcpy(opt[i++],"Set Required Node Number");
 	strcpy(opt[i++],"Set Required User Number");
 	strcpy(opt[i++],"Set Required Time Remaining");
+	strcpy(opt[i++],"Set Required Days Till Expiration");
 	opt[i][0]=NULL;
 	SETHELP(WHERE);
 /*
@@ -1156,7 +1172,7 @@ Otherwise, select No.
 You are being prompted to enter the security level to be used in this
 requirement evaluation. The valid range is 0 (zero) through 99.
 */
-			uinput(WIN_MID,0,0,"Level",str,2,K_NUMBER);
+			uinput(WIN_MID|WIN_SAV,0,0,"Level",str,2,K_NUMBER);
 			if(!str[0])
 				break;
 			if(ar[0]) {
@@ -1236,7 +1252,7 @@ requirement evaluation. The valid range is A through Z.
 You are being prompted to enter the user's age to be used in this
 requirement evaluation. The valid range is 0 through 255.
 */
-			uinput(WIN_MID,0,0,"Age",str,3,K_NUMBER);
+			uinput(WIN_MID|WIN_SAV,0,0,"Age",str,3,K_NUMBER);
 			if(!str[0])
 				break;
 			if(ar[0]) {
@@ -1303,9 +1319,13 @@ female).
 You are being prompted to enter the connect rate to be used in this
 requirement evaluation. The valid range is 300 through 57600.
 */
-			uinput(WIN_MID,0,0,"Connect Rate (BPS)",str,5,K_NUMBER);
+			uinput(WIN_MID|WIN_SAV,0,0,"Connect Rate (BPS)",str,5,K_NUMBER);
 			if(!str[0])
 				break;
+			j=atoi(str);
+			if(j>=300 && j<30000) {
+				j/=100;
+				sprintf(str,"%d",j); }
 			if(ar[0]) {
 				j=whichcond();
 				if(j==-1)
@@ -1342,7 +1362,8 @@ requirement evaluation. The valid range is 300 through 57600.
 You are being prompted to enter the post/call ratio to be used in this
 requirement evaluation (percentage). The valid range is 0 through 100.
 */
-			uinput(WIN_MID,0,0,"Post/Call Ratio (Percentage)",str,3,K_NUMBER);
+			uinput(WIN_MID|WIN_SAV,0,0,"Post/Call Ratio (Percentage)"
+				,str,3,K_NUMBER);
 			if(!str[0])
 				break;
 			if(ar[0]) {
@@ -1369,6 +1390,131 @@ requirement evaluation (percentage). The valid range is 0 through 100.
 		case 8:
 			if(strlen(ar)>=30) {
 				umsg("Maximum string length reached");
+                break; }
+			i=whichlogic();
+			if(i==-1)
+				break;
+			str[0]=0;
+			SETHELP(WHERE);
+/*
+Required Number of Credits:
+
+You are being prompted to enter the number of credits (in kilobytes) to
+be used in this requirement evaluation. The valid range is 0 through
+65535.
+*/
+			uinput(WIN_MID|WIN_SAV,0,0,"Required Credits",str,5,K_NUMBER);
+			if(!str[0])
+				break;
+			if(ar[0]) {
+				j=whichcond();
+				if(j==-1)
+					break;
+				if(!j)
+					strcat(ar," AND ");
+				else
+                    strcat(ar," OR "); }
+			strcat(ar,"CREDIT ");
+			switch(i) {
+				case 1:
+					strcat(ar,"= ");
+					break;
+				case 2:
+					strcat(ar,"NOT = ");
+					break;
+				case 3:
+					strcat(ar,"NOT ");
+					break; }
+			strcat(ar,str);
+            break;
+		case 9:
+			if(strlen(ar)>=30) {
+				umsg("Maximum string length reached");
+                break; }
+			i=whichlogic();
+			if(i==-1)
+				break;
+			str[0]=0;
+			SETHELP(WHERE);
+/*
+Required Upload/Download Ratio:
+
+You are being prompted to enter the upload/download ratio to be used in
+this requirement evaluation (percentage). The valid range is 0 through
+100. This ratio is based on the number of bytes uploaded by the user
+divided by the number of bytes downloaded.
+*/
+			uinput(WIN_MID|WIN_SAV,0,0,"Upload/Download Ratio (Percentage)"
+				,str,3,K_NUMBER);
+			if(!str[0])
+				break;
+			if(ar[0]) {
+				j=whichcond();
+				if(j==-1)
+					break;
+				if(!j)
+					strcat(ar," AND ");
+				else
+                    strcat(ar," OR "); }
+			strcat(ar,"UDR ");
+			switch(i) {
+				case 1:
+					strcat(ar,"= ");
+					break;
+				case 2:
+					strcat(ar,"NOT = ");
+					break;
+				case 3:
+					strcat(ar,"NOT ");
+					break; }
+			strcat(ar,str);
+            break;
+		case 10:
+			if(strlen(ar)>=30) {
+				umsg("Maximum string length reached");
+                break; }
+			i=whichlogic();
+			if(i==-1)
+				break;
+			str[0]=0;
+			SETHELP(WHERE);
+/*
+Required Upload/Download File Ratio:
+
+You are being prompted to enter the upload/download ratio to be used in
+this requirement evaluation (percentage). The valid range is 0 through
+100. This ratio is based on the number of files uploaded by the user
+divided by the number of files downloaded.
+*/
+			uinput(WIN_MID|WIN_SAV,0,0
+				,"Upload/Download File Ratio (Percentage)"
+				,str,3,K_NUMBER);
+			if(!str[0])
+				break;
+			if(ar[0]) {
+				j=whichcond();
+				if(j==-1)
+					break;
+				if(!j)
+					strcat(ar," AND ");
+				else
+                    strcat(ar," OR "); }
+			strcat(ar,"UDFR ");
+			switch(i) {
+				case 1:
+					strcat(ar,"= ");
+					break;
+				case 2:
+					strcat(ar,"NOT = ");
+					break;
+				case 3:
+					strcat(ar,"NOT ");
+					break; }
+			strcat(ar,str);
+            break;
+		case 11:
+			if(strlen(ar)>=30) {
+				umsg("Maximum string length reached");
                 break; }
 			i=0;
 			strcpy(opt[0],"Before");
@@ -1390,7 +1536,7 @@ You are being prompted to enter the time of day to be used in this
 requirement evaluation (military format). The valid range is 0 through
 23:59.
 */
-			uinput(WIN_MID,0,0,"Time of Day (Military)",str,5,K_UPPER);
+			uinput(WIN_MID|WIN_SAV,0,0,"Time of Day (Military)",str,5,K_UPPER);
 			if(!str[0])
 				break;
 			if(ar[0]) {
@@ -1406,7 +1552,7 @@ requirement evaluation (military format). The valid range is 0 through
 				strcat(ar,"NOT ");
 			strcat(ar,str);
 			break;
-		case 9:
+		case 12:
 			if(strlen(ar)>=30) {
 				umsg("Maximum string length reached");
                 break; }
@@ -1421,7 +1567,7 @@ requirement evaluation (military format). The valid range is 0 through
 You are being prompted to enter the number of a node to be used in this
 requirement evaluation. The valid range is 1 through 250.
 */
-			uinput(WIN_MID,0,0,"Node Number",str,3,K_NUMBER);
+			uinput(WIN_MID|WIN_SAV,0,0,"Node Number",str,3,K_NUMBER);
 			if(!str[0])
 				break;
 			if(ar[0]) {
@@ -1445,7 +1591,7 @@ requirement evaluation. The valid range is 1 through 250.
 					break; }
 			strcat(ar,str);
             break;
-		case 10:
+		case 13:
 			if(strlen(ar)>=30) {
 				umsg("Maximum string length reached");
                 break; }
@@ -1460,7 +1606,7 @@ requirement evaluation. The valid range is 1 through 250.
 You are being prompted to enter the user's number to be used in this
 requirement evaluation.
 */
-			uinput(WIN_MID,0,0,"User Number",str,3,K_NUMBER);
+			uinput(WIN_MID|WIN_SAV,0,0,"User Number",str,3,K_NUMBER);
 			if(!str[0])
 				break;
 			if(ar[0]) {
@@ -1485,7 +1631,7 @@ requirement evaluation.
 			strcat(ar,str);
             break;
 
-		case 11:
+		case 14:
 			if(strlen(ar)>=30) {
 				umsg("Maximum string length reached");
                 break; }
@@ -1498,9 +1644,9 @@ requirement evaluation.
 Required Time Remaining:
 
 You are being prompted to enter the time remaining to be used in this
-requirement evaluation (in minutes). The valid range is 0 through 255.
+requirement evaluation (in minutes). The valid range is 0 through 255.
 */
-			uinput(WIN_MID,0,0,"Time Remaining (minutes)"
+			uinput(WIN_MID|WIN_SAV,0,0,"Time Remaining (minutes)"
 				,str,3,K_NUMBER);
 			if(!str[0])
 				break;
@@ -1524,7 +1670,49 @@ requirement evaluation (in minutes). The valid range is 0 through 255.
 					strcat(ar,"NOT ");
 					break; }
 			strcat(ar,str);
-			break; } }
+			break;
+
+		case 15:
+			if(strlen(ar)>=30) {
+				umsg("Maximum string length reached");
+                break; }
+			i=whichlogic();
+			if(i==-1)
+				break;
+			str[0]=0;
+			SETHELP(WHERE);
+/*
+Required Days Till User Account Expiration:
+
+You are being prompted to enter the required number of days till the
+user's account will expire.
+*/
+			uinput(WIN_MID|WIN_SAV,0,0,"Days Till Expiration"
+				,str,5,K_NUMBER);
+			if(!str[0])
+				break;
+			if(ar[0]) {
+				j=whichcond();
+				if(j==-1)
+					break;
+				if(!j)
+					strcat(ar," AND ");
+				else
+                    strcat(ar," OR "); }
+			strcat(ar,"EXPIRE ");
+			switch(i) {
+				case 1:
+					strcat(ar,"= ");
+					break;
+				case 2:
+					strcat(ar,"NOT = ");
+					break;
+				case 3:
+					strcat(ar,"NOT ");
+					break; }
+			strcat(ar,str);
+            break;
+			} }
 sprintf(inar,"%.*s",LEN_ARSTR,ar);
 }
 
diff --git a/SRC/SCFG/SCFGMISC.C b/SRC/SCFG/SCFGMISC.C
index 95d5b9ddaff95065412cf125ac5dd7cfd65f2aed..0990492606d1b7e4db84215a78d257412758fe64 100644
--- a/SRC/SCFG/SCFGMISC.C
+++ b/SRC/SCFG/SCFGMISC.C
@@ -183,8 +183,7 @@ write_cfg_line(file,sys_daily,"Daily Event");
 write_cfg_line(file,sys_timed,"Timed Event");
 sprintf(str,"%c %u",sys_misc&SM_TIMED_SH ? 'Y':'N',sys_lastnode);
 write_cfg_line(file,str,"Timed Event Shrink & Last Node");
-sprintf(str,"%2.2d:%2.2d",sys_eventtime/60
-    ,sys_eventtime-((sys_eventtime/60)*60));
+sprintf(str,"%2.2d:%2.2d",sys_eventtime/60,sys_eventtime%60);
 write_cfg_line(file,str,"Timed Event Start Time (Military)");
 sprintf(str,"%u %u",sys_eventnode,sys_autonode);
 write_cfg_line(file,str,"Timed Event Node and Auto-Node");
@@ -413,8 +412,7 @@ for(i=0;i<total_qhubs;i++) {
 			? 1440/qhub[i]->freq : 0);
 		write_cfg_line(file,str,"Call-outs Per Day"); }
 	else {
-		sprintf(str,"%2.2d:%2.2d",qhub[i]->time/60
-			,qhub[i]->time-((qhub[i]->time/60)*60));
+		sprintf(str,"%2.2d:%2.2d",qhub[i]->time/60,qhub[i]->time%60);
 		write_cfg_line(file,str,"Call-out Time (military)"); }
 	write_cfg_line(file,itoa(qhub[i]->days,str,10),"Call-out Days");
 	write_cfg_line(file,itoa(qhub[i]->node,str,10),"Call-out Node");
@@ -460,8 +458,7 @@ for(i=0;i<total_phubs;i++) {
 			? 1440/phub[i]->freq : 0);
 		write_cfg_line(file,str,"Call-outs Per Day"); }
 	else {
-		sprintf(str,"%2.2d:%2.2d",phub[i]->time/60
-			,phub[i]->time-((phub[i]->time/60)*60));
+		sprintf(str,"%2.2d:%2.2d",phub[i]->time/60,phub[i]->time%60);
 		write_cfg_line(file,str,"Call-out Time (military)"); }
 	write_cfg_line(file,itoa(phub[i]->days,str,10),"Call-out Days");
 	write_cfg_line(file,itoa(phub[i]->node,str,10),"Call-out Node");
diff --git a/SRC/SCFG/SCFGMSG.C b/SRC/SCFG/SCFGMSG.C
index 5d84bb2638fa992007a8f2e3d833dddeb3b157b1..2bbb3fa3e011a09cc252d9102919346474d22bdd 100644
--- a/SRC/SCFG/SCFGMSG.C
+++ b/SRC/SCFG/SCFGMSG.C
@@ -125,8 +125,8 @@ should be descriptive of the sub-boards that belong to it.
 				FREE(sub[i]);
 			read_subs_cfg(txt); }
 		return; }
-	if((i&0xff00)==MSK_INS) {
-		i&=0xff;
+	if((i&0xf000)==MSK_INS) {
+		i&=0xfff;
 		SETHELP(WHERE);
 /*
 Group Long Name:
@@ -163,8 +163,8 @@ main menu and reading message prompts.
 		total_grps++;
 		changes=1;
 		continue; }
-	if((i&0xff00)==MSK_DEL) {
-		i&=0xff;
+	if((i&0xf000)==MSK_DEL) {
+		i&=0xfff;
 		SETHELP(WHERE);
 /*
 Delete All Data in Group:
@@ -205,12 +205,12 @@ select Yes.
 			i++; }
 		changes=1;
 		continue; }
-	if((i&0xff00)==MSK_GET) {
-		i&=0xff;
+	if((i&0xf000)==MSK_GET) {
+		i&=0xfff;
 		savgrp=*grp[i];
 		continue; }
-	if((i&0xff00)==MSK_PUT) {
-		i&=0xff;
+	if((i&0xf000)==MSK_PUT) {
+		i&=0xfff;
 		*grp[i]=savgrp;
 		changes=1;
 		continue; }
@@ -369,11 +369,12 @@ and change one of them.
 It is helpful if the internal code for a sub-board is an abreviation
 of the name.
 */
+			savnum=0;
 			umsg(str);
 			continue; }
 		return; }
-	if((i&0xff00)==MSK_INS) {
-		i&=0xff;
+	if((i&0xf000)==MSK_INS) {
+		i&=0xfff;
 		strcpy(str,"General");
 		SETHELP(WHERE);
 /*
@@ -453,8 +454,8 @@ usually an abreviation of the sub-board's name.
 		total_subs++;
 		changes=1;
 		continue; }
-	if((i&0xff00)==MSK_DEL) {
-		i&=0xff;
+	if((i&0xf000)==MSK_DEL) {
+		i&=0xfff;
 		SETHELP(WHERE);
 /*
 Delete Data in Sub-board:
@@ -482,13 +483,15 @@ If you want to delete all the messages for this sub-board, select Yes.
 			sub[j]=sub[j+1];
 		changes=1;
 		continue; }
-	if((i&0xff00)==MSK_GET) {
-		i&=0xff;
+	if((i&0xf000)==MSK_GET) {
+		i&=0xfff;
 		savsub=*sub[subnum[i]];
 		continue; }
-	if((i&0xff00)==MSK_PUT) {
-		i&=0xff;
+	if((i&0xf000)==MSK_PUT) {
+		i&=0xfff;
+		ptridx=sub[subnum[i]]->ptridx;
 		*sub[subnum[i]]=savsub;
+		sub[subnum[i]]->ptridx=ptridx;
 		sub[subnum[i]]->grp=grpnum;
 		changes=1;
         continue; }
diff --git a/SRC/SCFG/SCFGNET.C b/SRC/SCFG/SCFGNET.C
index c245d6655543ea91af9f3e063d6d26ba969c0662..453f82370b171fee21883ad6969a9cb7c82703d2 100644
--- a/SRC/SCFG/SCFGNET.C
+++ b/SRC/SCFG/SCFGNET.C
@@ -135,8 +135,8 @@ To configure a hub, select it and hit  ENTER .
 							,"QWK Network Hubs",opt);
 						if(i==-1)
 							break;
-						if((i&0xff00)==MSK_INS) {
-							i&=0xff;
+						if((i&0xf000)==MSK_INS) {
+							i&=0xfff;
 							for(j=total_qhubs;j>i;j--)
 								qhub[j]=qhub[j-1];
 							savnum=1;
@@ -187,8 +187,8 @@ outgoing network packets and must be accurate.
 							total_qhubs++;
 							changes=1;
 							continue; }
-						if((i&0xff00)==MSK_DEL) {
-							i&=0xff;
+						if((i&0xf000)==MSK_DEL) {
+							i&=0xfff;
 							FREE(qhub[i]->mode);
 							FREE(qhub[i]->conf);
 							FREE(qhub[i]->sub);
@@ -543,8 +543,8 @@ To configure a hub, select it and hit  ENTER .
 							,"PostLink and PCRelay Hubs",opt);
 						if(i==-1)
 							break;
-						if((i&0xff00)==MSK_INS) {
-							i&=0xff;
+						if((i&0xf000)==MSK_INS) {
+							i&=0xfff;
 							for(j=total_phubs;j>i;j--)
 								phub[j]=phub[j-1];
 							savnum=1;
@@ -569,8 +569,8 @@ This is the Site Name of this hub. It is used for only for reference.
 							total_phubs++;
 							changes=1;
 							continue; }
-						if((i&0xff00)==MSK_DEL) {
-							i&=0xff;
+						if((i&0xf000)==MSK_DEL) {
+							i&=0xfff;
 							FREE(phub[i]);
 							total_phubs--;
 							while(i<total_phubs) {
@@ -601,8 +601,7 @@ while(!done) {
 		sprintf(str,"%u times a day",1440/qhub[num]->freq);
 		sprintf(opt[i++],"%-27.27s%s","Call-out Frequency",str); }
 	else {
-		sprintf(str,"%2.2d:%2.2d",qhub[num]->time/60
-			,qhub[num]->time-((qhub[num]->time/60)*60));
+		sprintf(str,"%2.2d:%2.2d",qhub[num]->time/60,qhub[num]->time%60);
 		sprintf(opt[i++],"%-27.27s%s","Call-out Time",str); }
 	strcpy(opt[i++],"Networked Sub-boards...");
 	opt[i][0]=0;
@@ -720,7 +719,7 @@ hub more than once a day at predetermined intervals, set this option to
 				,"Perform Call-out at a Specific Time",opt);
 			if(i==0) {
 				sprintf(str,"%2.2d:%2.2d",qhub[num]->time/60
-					,qhub[num]->time-((qhub[num]->time/60)*60));
+					,qhub[num]->time%60);
 				SETHELP(WHERE);
 /*
 Time to Perform Call-out:
@@ -801,8 +800,8 @@ To configure a sub-board for this QWK network hub, select it and hit
 		,"Networked Sub-boards",opt);
 	if(j==-1)
 		break;
-	if((j&0xff00)==MSK_INS) {
-		j&=0xff;
+	if((j&0xf000)==MSK_INS) {
+		j&=0xfff;
 		savnum=3;
 		if((l=getsub())==-1)
 			continue;
@@ -859,8 +858,8 @@ this option to Strip out.
 		qhub[num]->conf[j]=atoi(str);
 		qhub[num]->subs++;
 		continue; }
-	if((j&0xff00)==MSK_DEL) {
-		j&=0xff;
+	if((j&0xf000)==MSK_DEL) {
+		j&=0xfff;
 		qhub[num]->subs--;
 		while(j<qhub[num]->subs) {
 			qhub[num]->sub[j]=qhub[num]->sub[j+1];
@@ -969,7 +968,7 @@ while(!done) {
 		sprintf(opt[i++],"%-27.27s%s","Call-out Frequency",str); }
 	else {
 		sprintf(str,"%2.2d:%2.2d",phub[num]->time/60
-			,phub[num]->time-((phub[num]->time/60)*60));
+			,phub[num]->time%60);
 		sprintf(opt[i++],"%-27.27s%s","Call-out Time",str); }
 	opt[i][0]=0;
 	sprintf(str,"%s Network Hub",phub[num]->name);
@@ -1061,7 +1060,7 @@ once a day at predetermined intervals, set this option to No.
 				,"Perform Call-out at a Specific Time",opt);
 			if(i==0) {
 				sprintf(str,"%2.2d:%2.2d",phub[num]->time/60
-					,phub[num]->time-((phub[num]->time/60)*60));
+					,phub[num]->time%60);
 				SETHELP(WHERE);
 /*
 Time to Perform Call-out:
diff --git a/SRC/SCFG/SCFGNODE.C b/SRC/SCFG/SCFGNODE.C
index bf1986a0b4166eceaf09c61e5832e8ee83e44bfc..78295bc86b75e57e935d674cb1da7cd9bf8c2593 100644
--- a/SRC/SCFG/SCFGNODE.C
+++ b/SRC/SCFG/SCFGNODE.C
@@ -48,7 +48,7 @@ node and hit  F6 .
 			savnode=0; }
 		return; }
 
-	if((i&0xff00)==MSK_DEL) {
+	if((i&0xf000)==MSK_DEL) {
 		strcpy(opt[0],"Yes");
 		strcpy(opt[1],"No");
 		opt[2][0]=NULL;
@@ -68,7 +68,7 @@ select No or hit  ESC .
 			remove(str);
 			write_main_cfg(); }
 		continue; }
-	if((i&0xff00)==MSK_INS) {
+	if((i&0xf000)==MSK_INS) {
 		strcpy(node_dir,node_path[sys_nodes-1]);
 		i=sys_nodes+1;
 		read_node_cfg(txt);
@@ -106,17 +106,17 @@ If you want to abort the creation of this new node, hit  ESC .
 		for(i=0;i<mdm_results;i++)
 			FREE(mdm_result[i]);
 		continue; }
-	if((i&0xff00)==MSK_GET) {
+	if((i&0xf000)==MSK_GET) {
 		if(savnode)
 			for(j=0;j<mdm_results;j++)
 				FREE(mdm_result[j]);
-		i&=0xff;
+		i&=0xfff;
 		strcpy(node_dir,node_path[i]);
 		read_node_cfg(txt);
 		savnode=1;
 		continue; }
-	if((i&0xff00)==MSK_PUT) {
-		i&=0xff;
+	if((i&0xf000)==MSK_PUT) {
+		i&=0xfff;
 		strcpy(node_dir,node_path[i]);
 		node_num=i+1;
 		write_node_cfg();
@@ -1241,8 +1241,8 @@ To delete a result code, select it using the arrow keys and hit  DEL .
 							i=ulist(i,0,0,33,&dflt,"Result Codes",opt);
 							if(i==-1)
 								break;
-							if((i&0xff00)==MSK_DEL) {
-								i&=0xff;
+							if((i&0xf000)==MSK_DEL) {
+								i&=0xfff;
 								FREE(mdm_result[i]);
 								mdm_results--;
 								while(i<mdm_results) {
@@ -1250,8 +1250,8 @@ To delete a result code, select it using the arrow keys and hit  DEL .
 									i++; }
 								changes=1;
 								continue; }
-							if((i&0xff00)==MSK_INS) {
-								i&=0xff;
+							if((i&0xf000)==MSK_INS) {
+								i&=0xfff;
 								for(j=mdm_results;j>i;j--)
 									mdm_result[j]=mdm_result[j-1];
 								if((mdm_result[i]=(mdm_result_t *)MALLOC(
diff --git a/SRC/SCFG/SCFGSYS.C b/SRC/SCFG/SCFGSYS.C
index 647861fd25e897e779f765a1bbc67a0b53424773..22d083cf2eb6da4faa52f9b2581384f1d7611861 100644
--- a/SRC/SCFG/SCFGSYS.C
+++ b/SRC/SCFG/SCFGSYS.C
@@ -1705,8 +1705,8 @@ hit  ENTER .
 					if(i!=-1)
 						break;
 					continue; }
-				if((i&0xff00)==MSK_INS) {
-					i&=0xff;
+				if((i&0xf000)==MSK_INS) {
+					i&=0xfff;
 					sprintf(str,"Command Set %d",i+1);
 					SETHELP(WHERE);
 /*
@@ -1747,8 +1747,8 @@ used for this subdirectory.
 					total_altcmds++;
 					changes=1;
 					continue; }
-				if((i&0xff00)==MSK_DEL) {
-					i&=0xff;
+				if((i&0xf000)==MSK_DEL) {
+					i&=0xfff;
 					FREE(altcmds[i]);
 					total_altcmds--;
 					for(j=i;j<total_altcmds;j++)
diff --git a/SRC/SCFG/SCFGXFER.C b/SRC/SCFG/SCFGXFER.C
index 812efa3e100261a8485d3a655b1e2c0cdeab783e..96082dcd6d5793b6145f446e7851dbf09a3dc8ca 100644
--- a/SRC/SCFG/SCFGXFER.C
+++ b/SRC/SCFG/SCFGXFER.C
@@ -266,8 +266,8 @@ command line examples for a few file types.
 				i=ulist(i,0,0,50,&dflt,"Viewable File Types",opt);
 				if(i==-1)
 					break;
-				if((i&0xff00)==MSK_DEL) {
-					i&=0xff;
+				if((i&0xf000)==MSK_DEL) {
+					i&=0xfff;
 					FREE(fview[i]);
 					total_fviews--;
 					while(i<total_fviews) {
@@ -275,8 +275,8 @@ command line examples for a few file types.
 						i++; }
 					changes=1;
 					continue; }
-				if((i&0xff00)==MSK_INS) {
-					i&=0xff;
+				if((i&0xf000)==MSK_INS) {
+					i&=0xfff;
 					if(!total_fviews) {
 						if((fview[0]=(fview_t *)MALLOC(
 							sizeof(fview_t)))==NULL) {
@@ -295,12 +295,12 @@ command line examples for a few file types.
 					total_fviews++;
 					changes=1;
 					continue; }
-				if((i&0xff00)==MSK_GET) {
-					i&=0xff;
+				if((i&0xf000)==MSK_GET) {
+					i&=0xfff;
 					savfview=*fview[i];
 					continue; }
-				if((i&0xff00)==MSK_PUT) {
-					i&=0xff;
+				if((i&0xf000)==MSK_PUT) {
+					i&=0xfff;
 					*fview[i]=savfview;
 					changes=1;
 					continue; }
@@ -343,8 +343,8 @@ listed.
 				i=ulist(i,0,0,50,&dflt,"Testable File Types",opt);
 				if(i==-1)
 					break;
-				if((i&0xff00)==MSK_DEL) {
-					i&=0xff;
+				if((i&0xf000)==MSK_DEL) {
+					i&=0xfff;
 					FREE(ftest[i]);
 					total_ftests--;
 					while(i<total_ftests) {
@@ -352,8 +352,8 @@ listed.
 						i++; }
 					changes=1;
 					continue; }
-				if((i&0xff00)==MSK_INS) {
-					i&=0xff;
+				if((i&0xf000)==MSK_INS) {
+					i&=0xfff;
 					if(!total_ftests) {
 						if((ftest[0]=(ftest_t *)MALLOC(
 							sizeof(ftest_t)))==NULL) {
@@ -373,12 +373,12 @@ listed.
 					total_ftests++;
 					changes=1;
 					continue; }
-				if((i&0xff00)==MSK_GET) {
-					i&=0xff;
+				if((i&0xf000)==MSK_GET) {
+					i&=0xfff;
 					savftest=*ftest[i];
 					continue; }
-				if((i&0xff00)==MSK_PUT) {
-					i&=0xff;
+				if((i&0xf000)==MSK_PUT) {
+					i&=0xfff;
 					*ftest[i]=savftest;
 					changes=1;
 					continue; }
@@ -442,8 +442,8 @@ extract the file(s).
                 i=ulist(i,0,0,50,&dflt,"Extractable File Types",opt);
                 if(i==-1)
                     break;
-                if((i&0xff00)==MSK_DEL) {
-                    i&=0xff;
+				if((i&0xf000)==MSK_DEL) {
+					i&=0xfff;
                     FREE(fextr[i]);
                     total_fextrs--;
                     while(i<total_fextrs) {
@@ -451,8 +451,8 @@ extract the file(s).
                         i++; }
                     changes=1;
                     continue; }
-                if((i&0xff00)==MSK_INS) {
-                    i&=0xff;
+				if((i&0xf000)==MSK_INS) {
+					i&=0xfff;
                     if(!total_fextrs) {
                         if((fextr[0]=(fextr_t *)MALLOC(
                             sizeof(fextr_t)))==NULL) {
@@ -471,12 +471,12 @@ extract the file(s).
                     total_fextrs++;
                     changes=1;
                     continue; }
-                if((i&0xff00)==MSK_GET) {
-                    i&=0xff;
+				if((i&0xf000)==MSK_GET) {
+					i&=0xfff;
                     savfextr=*fextr[i];
                     continue; }
-                if((i&0xff00)==MSK_PUT) {
-                    i&=0xff;
+				if((i&0xf000)==MSK_PUT) {
+					i&=0xfff;
                     *fextr[i]=savfextr;
                     changes=1;
                     continue; }
@@ -519,8 +519,8 @@ directory accordingly.
 				i=ulist(i,0,0,50,&dflt,"File Transfer Protocols",opt);
 				if(i==-1)
 					break;
-				if((i&0xff00)==MSK_DEL) {
-					i&=0xff;
+				if((i&0xf000)==MSK_DEL) {
+					i&=0xfff;
 					FREE(prot[i]);
 					total_prots--;
 					while(i<total_prots) {
@@ -528,8 +528,8 @@ directory accordingly.
 						i++; }
 					changes=1;
 					continue; }
-				if((i&0xff00)==MSK_INS) {
-					i&=0xff;
+				if((i&0xf000)==MSK_INS) {
+					i&=0xfff;
 					if(!total_prots) {
 						if((prot[0]=(prot_t *)MALLOC(
 							sizeof(prot_t)))==NULL) {
@@ -556,12 +556,12 @@ directory accordingly.
 					total_prots++;
 					changes=1;
 					continue; }
-				if((i&0xff00)==MSK_GET) {
-					i&=0xff;
+				if((i&0xf000)==MSK_GET) {
+					i&=0xfff;
 					savprot=*prot[i];
 					continue; }
-				if((i&0xff00)==MSK_PUT) {
-					i&=0xff;
+				if((i&0xf000)==MSK_PUT) {
+					i&=0xfff;
 					*prot[i]=savprot;
 					changes=1;
 					continue; }
@@ -666,8 +666,8 @@ multiple CD-ROMs or hard disks.
 				i=ulist(i,0,0,50,&dflt,"Alternate File Paths",opt);
 				if(i==-1)
 					break;
-				if((i&0xff00)==MSK_DEL) {
-					i&=0xff;
+				if((i&0xf000)==MSK_DEL) {
+					i&=0xfff;
 					FREE(altpath[i]);
 					altpaths--;
 					while(i<altpaths) {
@@ -675,8 +675,8 @@ multiple CD-ROMs or hard disks.
 						i++; }
 					changes=1;
 					continue; }
-				if((i&0xff00)==MSK_INS) {
-					i&=0xff;
+				if((i&0xf000)==MSK_INS) {
+					i&=0xfff;
 					if(!altpaths) {
 						if((altpath[0]=(char *)MALLOC(42))==NULL) {
 							errormsg(WHERE,ERR_ALLOC,nulstr,42);
@@ -692,12 +692,12 @@ multiple CD-ROMs or hard disks.
 					altpaths++;
 					changes=1;
 					continue; }
-				if((i&0xff00)==MSK_GET) {
-					i&=0xff;
+				if((i&0xf000)==MSK_GET) {
+					i&=0xfff;
 					strcpy(savaltpath,altpath[i]);
 					continue; }
-				if((i&0xff00)==MSK_PUT) {
-					i&=0xff;
+				if((i&0xf000)==MSK_PUT) {
+					i&=0xfff;
 					strcpy(altpath[i],savaltpath);
 					changes=1;
 					continue; }
@@ -801,8 +801,8 @@ should be descriptive of the directories that belong to it.
 			read_dirs_cfg(txt); }
 		changes=savchanges;
 		return; }
-	if((i&0xff00)==MSK_INS) {
-		i&=0xff;
+	if((i&0xf000)==MSK_INS) {
+		i&=0xfff;
 		strcpy(str,"Main");
 		SETHELP(WHERE);
 /*
@@ -840,8 +840,8 @@ file transfer menu prompt.
 		total_libs++;
 		changes=1;
 		continue; }
-	if((i&0xff00)==MSK_DEL) {
-		i&=0xff;
+	if((i&0xf000)==MSK_DEL) {
+		i&=0xfff;
 		FREE(lib[i]);
 		for(j=0;j<total_dirs;) {
 			if(dir[j]->lib==i) {
@@ -861,12 +861,12 @@ file transfer menu prompt.
 			i++; }
 		changes=1;
 		continue; }
-	if((i&0xff00)==MSK_GET) {
-		i&=0xff;
+	if((i&0xf000)==MSK_GET) {
+		i&=0xfff;
 		savlib=*lib[i];
 		continue; }
-	if((i&0xff00)==MSK_PUT) {
-		i&=0xff;
+	if((i&0xf000)==MSK_PUT) {
+		i&=0xfff;
 		*lib[i]=savlib;
 		changes=1;
         continue; }
@@ -1029,8 +1029,8 @@ the internal code is an abreviation of the name of the directory.
 			umsg(str);
             continue; }
 		return; }
-	if((i&0xff00)==MSK_INS) {
-		i&=0xff;
+	if((i&0xf000)==MSK_INS) {
+		i&=0xfff;
 		strcpy(str,"Games");
 		SETHELP(WHERE);
 /*
@@ -1103,20 +1103,20 @@ this directory will be stored. Example: C:\XFER\GAMES
 		total_dirs++;
 		changes=1;
 		continue; }
-	if((i&0xff00)==MSK_DEL) {
-		i&=0xff;
+	if((i&0xf000)==MSK_DEL) {
+		i&=0xfff;
 		FREE(dir[dirnum[i]]);
 		total_dirs--;
 		for(j=dirnum[i];j<total_dirs;j++)
 			dir[j]=dir[j+1];
 		changes=1;
 		continue; }
-	if((i&0xff00)==MSK_GET) {
-		i&=0xff;
+	if((i&0xf000)==MSK_GET) {
+		i&=0xfff;
 		savdir=*dir[dirnum[i]];
 		continue; }
-	if((i&0xff00)==MSK_PUT) {
-		i&=0xff;
+	if((i&0xf000)==MSK_PUT) {
+		i&=0xfff;
 		*dir[dirnum[i]]=savdir;
 		dir[dirnum[i]]->lib=libnum;
 		changes=1;
diff --git a/SRC/SCFG/SCFGXTRN.C b/SRC/SCFG/SCFGXTRN.C
index 07c6a3854e0a63f20b6997525569d42abcb25576..e66604da91adb24abb96a83a5f86aa4f33e6a2b8 100644
--- a/SRC/SCFG/SCFGXTRN.C
+++ b/SRC/SCFG/SCFGXTRN.C
@@ -52,8 +52,7 @@ while(1) {
 	sprintf(str,"Timed Event %s",sys_misc&SM_TIMED_SH ?
 		"(Shrink)" : "");
 	sprintf(opt[i++],"%-27.27s%s",str,sys_timed);
-	sprintf(str,"%2.2d:%2.2d",sys_eventtime/60
-		,sys_eventtime-((sys_eventtime/60)*60));
+	sprintf(str,"%2.2d:%2.2d",sys_eventtime/60,sys_eventtime%60);
 	sprintf(opt[i++],"%-27.27s%s","Event Time",str);
 	sprintf(str,"Event Node %s",sys_misc&SM_TIMED_EX ?
 		"(Exclusive)" : "");
@@ -157,8 +156,7 @@ If this event requires a lot of free memory, set this option to Yes.
 
 This is the time (in 24hour format) of the time to run the timed event.
 */
-			sprintf(str,"%2.2d:%2.2d",sys_eventtime/60
-				,sys_eventtime-((sys_eventtime/60)*60));
+			sprintf(str,"%2.2d:%2.2d",sys_eventtime/60,sys_eventtime%60);
 			if(uinput(WIN_MID|WIN_SAV,0,0
 				,"Time to Execute Event (military)"
 				,str,5,K_UPPER|K_EDIT)>0) {
@@ -246,8 +244,8 @@ To configure a program, select it with the arrow keys and hit  ENTER .
 				FREE(xtrn[i]);
 			read_xtrn_cfg(txt); }
 		return; }
-	if((i&0xff00)==MSK_INS) {
-		i&=0xff;
+	if((i&0xf000)==MSK_INS) {
+		i&=0xfff;
 		sprintf(str,"External Program Number %d",i+1);
 		SETHELP(WHERE);
 /*
@@ -270,20 +268,20 @@ This is the name or description of the external program (door).
 		total_xtrns++;
 		changes=1;
 		continue; }
-	if((i&0xff00)==MSK_DEL) {
-		i&=0xff;
+	if((i&0xf000)==MSK_DEL) {
+		i&=0xfff;
 		FREE(xtrn[i]);
 		total_xtrns--;
 		for(j=i;j<total_xtrns;j++)
 			xtrn[j]=xtrn[j+1];
 		changes=1;
 		continue; }
-	if((i&0xff00)==MSK_GET) {
-		i&=0xff;
+	if((i&0xf000)==MSK_GET) {
+		i&=0xfff;
 		savxtrn=*xtrn[i];
 		continue; }
-	if((i&0xff00)==MSK_PUT) {
-		i&=0xff;
+	if((i&0xf000)==MSK_PUT) {
+		i&=0xfff;
 		*xtrn[i]=savxtrn;
 		changes=1;
         continue; }
@@ -772,8 +770,8 @@ To configure an editor, select it and hit  ENTER .
 				FREE(xtrn[i]);
 			read_xtrn_cfg(txt); }
 		return; }
-	if((i&0xff00)==MSK_INS) {
-		i&=0xff;
+	if((i&0xf000)==MSK_INS) {
+		i&=0xfff;
 		sprintf(str,"External Editor Number %d",i+1);
 		SETHELP(WHERE);
 /*
@@ -795,20 +793,20 @@ This is the name or description of the external editor.
 		total_xedits++;
 		changes=1;
 		continue; }
-	if((i&0xff00)==MSK_DEL) {
-		i&=0xff;
+	if((i&0xf000)==MSK_DEL) {
+		i&=0xfff;
 		FREE(xedit[i]);
 		total_xedits--;
 		for(j=i;j<total_xedits;j++)
 			xedit[j]=xedit[j+1];
 		changes=1;
 		continue; }
-	if((i&0xff00)==MSK_GET) {
-		i&=0xff;
+	if((i&0xf000)==MSK_GET) {
+		i&=0xfff;
 		savxedit=*xedit[i];
 		continue; }
-	if((i&0xff00)==MSK_PUT) {
-		i&=0xff;
+	if((i&0xf000)==MSK_PUT) {
+		i&=0xfff;
 		*xedit[i]=savxedit;
 		changes=1;
         continue; }
@@ -953,8 +951,8 @@ To configure a channel, select it with the arrow keys and hit  ENTER .
 				FREE(chan[i]);
 			read_chan_cfg(txt); }
 		return; }
-	if((i&0xff00)==MSK_INS) {
-		i&=0xff;
+	if((i&0xf000)==MSK_INS) {
+		i&=0xfff;
 		strcpy(str,"Open");
 		SETHELP(WHERE);
 /*
@@ -976,20 +974,20 @@ This is the name or description of the chat channel.
 		total_chans++;
 		changes=1;
 		continue; }
-	if((i&0xff00)==MSK_DEL) {
-		i&=0xff;
+	if((i&0xf000)==MSK_DEL) {
+		i&=0xfff;
 		FREE(chan[i]);
 		total_chans--;
 		for(j=i;j<total_chans;j++)
 			chan[j]=chan[j+1];
 		changes=1;
 		continue; }
-	if((i&0xff00)==MSK_GET) {
-		i&=0xff;
+	if((i&0xf000)==MSK_GET) {
+		i&=0xfff;
 		savchan=*chan[i];
 		continue; }
-	if((i&0xff00)==MSK_PUT) {
-		i&=0xff;
+	if((i&0xf000)==MSK_PUT) {
+		i&=0xfff;
 		*chan[i]=savchan;
 		changes=1;
         continue; }
diff --git a/SRC/SCFGLIB.C b/SRC/SCFGLIB.C
index 7c70e35dbb43f493d0ebdb77bf5fa1a723c5be17..fc62ccf48a18d12927ff6985af88c8561cfcb120 100644
--- a/SRC/SCFGLIB.C
+++ b/SRC/SCFGLIB.C
@@ -2200,6 +2200,12 @@ for(i=j=0;i<len;i++) {
             case 'B':
                 artype=AR_BPS;
                 break;
+			case 'C':
+				artype=AR_CREDIT;
+				break;
+			case 'E':
+				artype=AR_EXPIRE;
+				break;
 			case 'T':
 				artype=AR_TIME;
                 break;
@@ -2224,6 +2230,12 @@ for(i=j=0;i<len;i++) {
 			case 'R':
                 artype=AR_TLEFT;
                 break;
+			case 'K':
+				artype=AR_UDR;
+				break;
+			case 'D':
+				artype=AR_UDFR;
+				break;
             case 'U':
                 artype=AR_USER;
                 break;
@@ -2245,6 +2257,12 @@ for(i=j=0;i<len;i++) {
         else if(!strncmp(str+i,"SEX",3)) {
             artype=AR_SEX;
             i+=2; }
+		else if(!strncmp(str+i,"UDR",3)) {
+			artype=AR_UDR;
+			i+=2; }
+		else if(!strncmp(str+i,"UDFR",4)) {
+			artype=AR_UDFR;
+			i+=3; }
         else if(!strncmp(str+i,"FLAG",4)) {
 			artype=AR_FLAG1;
             i+=3; }
@@ -2266,6 +2284,12 @@ for(i=j=0;i<len;i++) {
         else if(!strncmp(str+i,"TUSED",5)) {
             artype=AR_TUSED;
             i+=4; }
+		else if(!strncmp(str+i,"EXPIRE",6)) {
+			artype=AR_EXPIRE;
+			i+=5; }
+		else if(!strncmp(str+i,"CREDIT",6)) {
+			artype=AR_CREDIT;
+			i+=5; }
 		if(n!=i)			/* one of the above */
 			continue; }
 
@@ -2303,13 +2327,19 @@ for(i=j=0;i<len;i++) {
         switch(artype) {
             case AR_AGE:   /* byte operands */
             case AR_PCR:
+			case AR_UDR:
+			case AR_UDFR:
             case AR_NODE:
 			case AR_LEVEL:
             case AR_TLEFT:
             case AR_TUSED:
                 ar[j++]=n;
                 break;
-            case AR_BPS:
+			case AR_BPS:	/* int operands */
+				if(n<300)
+					n*=100;
+			case AR_EXPIRE:
+			case AR_CREDIT:
             case AR_USER:
 				*((int *)(ar+j))=n;
 				j+=2;
diff --git a/SRC/TEXT.H b/SRC/TEXT.H
index 7b22d26a0146d8ea1f8ad3434149db4f5674784c..2a8ff0eca732874bb42e8bfdf1029f08317f9444 100644
--- a/SRC/TEXT.H
+++ b/SRC/TEXT.H
@@ -723,6 +723,26 @@ enum {
 ,FreeMinToDeposit
 ,EmailFilesNotAllowed
 ,CantRunThatProgram
+,OnlyXminutesLeft
+,NoAccessLevel
+,NoAccessAge
+,NoAccessBPS
+,NoAccessCredit
+,NoAccessNode
+,NoAccessUser
+,NoAccessExpire
+,NoAccessTimeLeft
+,NoAccessTimeUsed
+,NoAccessTime
+,NoAccessPCR
+,NoAccessUDR
+,NoAccessUDFR
+,NoAccessFlag1
+,NoAccessFlag2
+,NoAccessFlag3
+,NoAccessFlag4
+,NoAccessSex
+
 ,TOTAL_TEXT };
 
 #endif
diff --git a/SRC/USEREDIT.C b/SRC/USEREDIT.C
index 3f482fc713114a9794be85a1accc6493178a15a7..f08aea5555706a5852cea371038be9485bd94b06 100644
--- a/SRC/USEREDIT.C
+++ b/SRC/USEREDIT.C
@@ -8,9 +8,14 @@
 
 #include "sbbs.h"
 
+#define SEARCH_TXT 0
+#define SEARCH_ARS 1
+
 int searchup(char *search,int usernum);
 int searchdn(char *search,int usernum);
 
+char *arstr(char *str);
+
 /****************************************************************************/
 /* Edits user data. Can only edit users with a Main Security Level less 	*/
 /* than or equal to the current user's Main Security Level					*/
@@ -18,9 +23,9 @@ int searchdn(char *search,int usernum);
 /****************************************************************************/
 void useredit(int usernumber)
 {
-	uchar str[256],tmp2[256],tmp3[256],c;
-	uchar search[256]={""};
-	int i;
+	uchar str[256],tmp2[256],tmp3[256],c,stype=SEARCH_TXT;
+	uchar search[256]={""},artxt[128]={""},*ar=NULL;
+	int i,j,k;
 	long l;
 	user_t user;
 
@@ -361,6 +366,8 @@ while(online) {
 		case 'Q':
 			CLS;
 			sys_status&=~SS_INUEDIT;
+			if(ar)
+				FREE(ar);
 			return;
 		case 'R':
 			bputs(text[EnterYourRealName]);
@@ -372,6 +379,11 @@ while(online) {
 			if(getstr(str,1,K_UPPER|K_LINE))
 				putuserrec(user.number,U_SEX,1,str);
 			break;
+		case 'T':   /* Text Search */
+			bputs(text[SearchStringPrompt]);
+			if(getstr(search,30,K_UPPER|K_LINE))
+				stype=SEARCH_TXT;
+			break;
 		case 'U':
 			bputs(text[UeditUlBytes]);
 			ultoa(user.ulb,str,10);
@@ -515,13 +527,44 @@ while(online) {
             break;
 		case '/':
 			bputs(text[SearchStringPrompt]);
-			getstr(search,30,K_UPPER|K_LINE);
-			break;
+			if(getstr(artxt,40,K_UPPER|K_LINE))
+				stype=SEARCH_ARS;
+			if(ar)
+				FREE(ar);
+			ar=arstr(artxt);
+            break;
 		case '{':
-			user.number=searchdn(search,user.number);
+			if(stype==SEARCH_TXT)
+				user.number=searchdn(search,user.number);
+			else {
+				if(!ar)
+					break;
+				k=user.number;
+				for(i=k-1;i;i--) {
+					user.number=i;
+					getuserdat(&user);
+					if(chk_ar(ar,user)) {
+						outchar(7);
+						break; } }
+				if(!i)
+					user.number=k; }
 			break;
 		case '}':
-			user.number=searchup(search,user.number);
+			if(stype==SEARCH_TXT)
+				user.number=searchup(search,user.number);
+			else {
+				if(!ar)
+					break;
+				j=lastuser();
+				k=user.number;
+				for(i=k+1;i<=j;i++) {
+					user.number=i;
+					getuserdat(&user);
+					if(chk_ar(ar,user)) {
+						outchar(7);
+						break; } }
+				if(i>j)
+                    user.number=k; }
 			break;
 		case ']':
 			if(user.number==lastuser())
diff --git a/SRC/VARS.C b/SRC/VARS.C
index b71b7a3fd80c1fe453f9dc5a952a42cfb9e9af4f..b355a46676d95c51a05859a3de15980b1d77515e 100644
--- a/SRC/VARS.C
+++ b/SRC/VARS.C
@@ -55,6 +55,8 @@ GLOBAL uint 	cur_rate;		/* Current Connection (DCE) Rate */
 GLOBAL uint 	cur_cps;		/* Current Average Transfer CPS */
 GLOBAL uint 	dte_rate;		/* Current COM Port (DTE) Rate */
 GLOBAL time_t 	timeout;		/* User inactivity timeout reference */
+GLOBAL char 	inactive_warn;	/* Inactivity warning flag */
+GLOBAL char 	timeleft_warn;	/* low timeleft warning flag */
 GLOBAL time_t 	lastevent;		/* Date/time last timed event ran */
 GLOBAL char 	curatr; 		/* Current Text Attributes Always */
 GLOBAL char 	lncntr; 		/* Line Counter - for PAUSE */
@@ -139,3 +141,4 @@ GLOBAL uint 	emshandle;		/* EMS handle for overlay swap */
 GLOBAL char 	emsver; 		/* Version of EMS installed */
 GLOBAL ulong	regnum[2];		/* Registration number (encrypted) */
 GLOBAL uint 	max_nodes;		/* Maximum number of nodes allowed */
+GLOBAL char 	noaccess[512];	/* Why access was denied via ARS */
diff --git a/SRC/VER.C b/SRC/VER.C
index 9897b7faac414a2fcf9229a9abfba8121c3e0c24..646a59ac8b018aa90410d454838bd9c1265ed66d 100644
--- a/SRC/VER.C
+++ b/SRC/VER.C
@@ -19,7 +19,7 @@ void ver()
 {
 	int i;
 
-i=rioctl(0x12);
+i=rioctl(FIFOCTL);
 bputs("\r\n");
 bprintf(decrypt(LogonNotice,0),max_nodes);
 
diff --git a/SRC/XFER_OVL.C b/SRC/XFER_OVL.C
index 7888efa671eb6ba51650fef62c6358bb6a4565d0..02889b502ee49631848670d19c5336e428a3ad5b 100644
--- a/SRC/XFER_OVL.C
+++ b/SRC/XFER_OVL.C
@@ -459,7 +459,7 @@ while(online && !done && m<l) {
                 break; } }
         else if(ch!=CR) {
             for(i=0;i<total_prots;i++)
-                if(prot[i]->mnemonic==ch)
+				if(prot[i]->dlcmd[0] && prot[i]->mnemonic==ch)
                     break;
             if(i<total_prots) {
 				if(online==ON_LOCAL) {
@@ -501,8 +501,9 @@ while(online && !done && m<l) {
 					else {
 						if(!j)
 							downloadfile(f);
-						   else
-							notdownloaded(f.size,start,end); }
+						else {
+							bprintf(text[FileNotSent],f.name);
+							notdownloaded(f.size,start,end); } }
 					delfiles(temp_dir,"*.*");
 					autohangup(); } } }
         closefile(f); }
@@ -643,7 +644,7 @@ while(online && !done && (batdn_total || batup_total)) {
 			if(ch=='Q')
 				break;
 			for(i=0;i<total_prots;i++)
-				if(prot[i]->mnemonic==ch)
+				if(prot[i]->bicmd[0] && prot[i]->mnemonic==ch)
 					break;
 			if(i<total_prots) {
 				xfrprot=i;
@@ -796,7 +797,7 @@ while(online && !done && (batdn_total || batup_total)) {
 			if(ch=='Q')
 				break;
 			for(i=0;i<total_prots;i++)
-				if(prot[i]->mnemonic==ch)
+				if(prot[i]->batulcmd[0] && prot[i]->mnemonic==ch)
 					break;
 			if(i<total_prots) {
 				sprintf(str,"%sBATCHUP.LST",node_dir);
@@ -901,7 +902,7 @@ ch=getkeys(tmp2,0);
 if(ch=='Q' || sys_status&SS_ABORT)
 	return;
 for(i=0;i<total_prots;i++)
-	if(prot[i]->mnemonic==ch)
+	if(prot[i]->batdlcmd[0] && prot[i]->mnemonic==ch)
 		break;
 if(i<total_prots) {
 	xfrprot=i;
@@ -1064,7 +1065,7 @@ while(online && !done) {
 					strcat(tmp2,tmp); }
 			ch=getkeys(tmp2,0);
 			for(i=0;i<total_prots;i++)
-				if(prot[i]->mnemonic==ch)
+				if(prot[i]->dlcmd[0] && prot[i]->mnemonic==ch)
 					break;
 			if(i<total_prots) {
                 getnodedat(node_num,&thisnode,1);
@@ -1087,8 +1088,9 @@ while(online && !done) {
 				else {
 					if(!j)
 						downloadfile(f);
-					else
-						notdownloaded(f.size,start,end); }
+					else {
+						bprintf(text[FileNotSent],f.name);
+						notdownloaded(f.size,start,end); } }
 				autohangup(); }
 			removefiledat(f);
 			break;
@@ -1451,7 +1453,7 @@ else {
                 ,f.name,batup_total,max_batup); } }
     else {
         for(i=0;i<total_prots;i++)
-            if(prot[i]->mnemonic==ch)
+			if(prot[i]->ulcmd[0] && prot[i]->mnemonic==ch)
                 break;
         if(i<total_prots) {
             start=time(NULL);
diff --git a/SRC/XTRN.C b/SRC/XTRN.C
index 7d262a083dd8b298df9fd8e6294660e17f0bbfb2..f239fa4f80477ee574c9137832cd5a15cb49246a 100644
--- a/SRC/XTRN.C
+++ b/SRC/XTRN.C
@@ -10,6 +10,7 @@
 
 #ifndef __OS2__
 extern uint riobp;
+extern mswtyp;
 #endif
 
 #ifndef __OS2__
@@ -147,6 +148,9 @@ for(i=j=0;i<len && j<128;i++) {
             case 'V':   /* Synchronet Version */
                 sprintf(str,"%s%d",VERSION,REVISION);
                 break;
+			case 'W':   /* Time-slice API type (mswtype) */
+				strcat(cmd,itoa(mswtyp,str,10));
+				break;
             case '&':   /* Address of msr */
 #ifndef __OS2__
 				sprintf(str,"%lu",sys_status&SS_DCDHIGH ? &fakeriobp
@@ -232,7 +236,8 @@ if(rmode)
 	ivhctl(rmode);	/* set DOS output interception vectors */
 
 #ifndef __OS2__
-if(mode&EX_WWIV) { /* WWIV code expansion */
+if(mode&EX_WWIV) {	/* WWIV code expansion */
+	rioctl(CPTOFF); /* turn off ctrl-p translation */
 	oldfunc=getvect(0x29);
 	setvect(0x29,wwiv_expand); }
 #endif
@@ -240,6 +245,7 @@ if(mode&EX_WWIV) { /* WWIV code expansion */
 #ifndef __OS2__
 if(com_port && sys_status&SS_COMISR && !(mode&(EX_OUTR|EX_INR))
 	&& online==ON_REMOTE) {
+	riosync(0);
 	rioini(0,0);
 	sys_status&=~SS_COMISR; }
 #endif
@@ -256,6 +262,8 @@ if(com_port && !(mode&(EX_OUTR|EX_INR)) && online==ON_REMOTE) {
 	setrate();
 	rioctl(IOSM|PAUSE|ABORT); }
 
+rioctl(CPTON);	/* turn on ctrl-p translation */
+
 #ifndef __OS2__
 if(mode&EX_WWIV)
 	setvect(0x29,oldfunc);
diff --git a/SRC/XTRN_OVL.C b/SRC/XTRN_OVL.C
index 3ac7975695f1f439e9108be7a06388683ac3d782..0140c419a5a4ee67babdffdf0e0f4afe10da43b9 100644
--- a/SRC/XTRN_OVL.C
+++ b/SRC/XTRN_OVL.C
@@ -292,7 +292,7 @@ else if(xtrn[xtrnnum]->type==XTRN_GAP) {   /* Gap DOOR.SYS File */
 		,sys_op 							/* Sysop name */
 		,nulstr 							/* Alias name */
 		,sys_eventtime/60					/* Event time HH:MM */
-		,sys_eventtime-((sys_eventtime/60)*60)
+		,sys_eventtime%60
 		,'Y');                              /* Error correcting connection */
 	write(file,str,strlen(str));
 
@@ -606,7 +606,7 @@ else if(xtrn[xtrnnum]->type==XTRN_PCBOARD) { /* PCBoard Files */
 		,0									/* Printer on/off */
 		,sys_status&SS_SYSPAGE ? -1:0		/* Page Bell on/off */
 		,node_misc&NM_ANSALARM ? -1:0		/* Caller Alarm on/off */
-		,SP 								/* Sysop flag */
+		,SP 								/* Sysop next flag */
 		,0									/* Error corrected */
 		,useron.misc&NO_EXASCII ? '7'       /* Graphics mode */
 			: useron.misc&(COLOR|ANSI)==(COLOR|ANSI) ? 'Y':'N'
@@ -664,7 +664,7 @@ else if(xtrn[xtrnnum]->type==XTRN_PCBOARD) { /* PCBoard Files */
 
 	sprintf(str,"%02d:%02d%2d%2d"           /* Scheduled Event time */
 		,sys_eventtime/60
-		,sys_eventtime-((sys_eventtime/60)*60)
+		,sys_eventtime%60
 		,sys_timed[0] ? -1:0				/* Event active ? */
 		,0									/* Slide event ? */
 		);
@@ -808,34 +808,42 @@ else if(xtrn[xtrnnum]->type==XTRN_SPITFIRE) {	/* SpitFire SFDOORS.DAT File */
 		,tmp								/* User's first name */
 		,dte_rate							/* DTE Rate */
 		,com_port							/* COM Port */
-		,0									/* ??? */
-		,l									/* Seconds since midnight */
+		,timeleft/60						/* Time left in minutes */
+		,l									/* Seconds since midnight (now) */
 		);
 	write(file,str,strlen(str));
 
+	unixtodos(logontime,&date,&curtime);
+    l=(((curtime.ti_hour*60)+curtime.ti_min)*60)+curtime.ti_sec;
+
 	sprintf(str,"%s\r\n%s\r\n%u\r\n%u\r\n%u\r\n%u\r\n%lu\r\n%u\r\n%s\r\n"
 		"%s\r\n%s\r\n%u\r\n%s\r\n%u\r\n%u\r\n%u\r\n%u\r\n%u\r\n%lu\r\n%u\r\n"
+		"%lu\r\n%lu\r\n%s\r\n%s\r\n"
 		,xtrn[xtrnnum]->misc&STARTUPDIR 	/* Start-up directory */
 			? startup : node_dir
 		,useron.misc&ANSI ? "TRUE":"FALSE"  /* ANSI ? True or False */
 		,useron.level						/* Security level */
 		,useron.uls 						/* Total uploads */
 		,useron.dls 						/* Total downloads */
-		,0									/* ??? */
-		,l									/* Seconds since midnight */
-		,0									/* ??? */
-		,"FALSE"                            /* ??? */
-		,"FALSE"                            /* ??? */
-		,"FALSE"                            /* ??? */
+		,level_timepercall[useron.level]	/* Minutes allowed this call */
+		,l									/* Secs since midnight (logon) */
+		,starttime-logontime				/* Extra time in seconds */
+		,"FALSE"                            /* Sysop next? */
+		,"FALSE"                            /* From Front-end? */
+		,"FALSE"                            /* Software Flow Control? */
 		,dte_rate							/* DTE Rate */
-		,"FALSE"                            /* ??? */
+		,"FALSE"                            /* Error correcting connection? */
 		,0									/* Current conference */
-		,1									/* ??? */
+		,0									/* Current file dir */
 		,node_num							/* Node number */
-		,15 								/* ??? */
-		,0									/* ??? */
-		,100000 							/* ??? */
-		,0									/* ??? */
+		,15 								/* Downloads allowed per day */
+		,0									/* Downloads already this day */
+		,100000 							/* Download bytes allowed/day */
+		,0									/* Downloaded bytes already today */
+		,useron.ulb/1024L					/* Kbytes uploaded */
+		,useron.dlb/1024L					/* Kbytes downloaded */
+		,useron.phone						/* Phone Number */
+		,useron.location					/* City, State */
 		);
 	write(file,str,strlen(str));
 
@@ -1240,6 +1248,7 @@ if(xtrn[xtrnnum]->misc&SHRINK) { /* Exec over bbs */
 	write(file,&logon_emails,sizeof(logon_emails));
 	write(file,&logon_fbacks,sizeof(logon_fbacks));
 	write(file,&logon_ml,sizeof(logon_ml));
+	write(file,&timeleft_warn,sizeof(timeleft_warn));
 	write(file,&curgrp,sizeof(curgrp));
 	for(i=0;i<total_grps;i++)
 		write(file,&cursub[i],sizeof(cursub[0]));
@@ -1307,8 +1316,9 @@ if(online==ON_REMOTE) {
 			,timestr(&now));
 		write(file,str,strlen(str));
 		close(file); } }
-if(xtrn[xtrnnum]->misc&MODUSERDAT)	   /* Modify user data */
+if(xtrn[xtrnnum]->misc&MODUSERDAT) {	/* Modify user data */
 	moduserdat(xtrnnum);
+	statusline(); }
 
 }