PAGE 75,128 TITLE LOGIN - USER LOG IN ROUTINES PAGE .XLIST INCLUDE CCBBS.MAC INCLUDE CCBBS.DEF .LIST ;----------------------------------------------- ;SYSTEM DATA SEGMENT ;----------------------------------------------- SYSDATA SEGMENT PARA PUBLIC 'DATA' EXTRN USRLOCK:WORD EXTRN USRCNT:WORD,USERH:WORD PUBLIC USRINXA,USRINXL,SCRIPT2,SNDCF CRCTB1 DW 0,1081H,2102H,3183H DW 4204H,5285H,6306H,7387H DW 8408H,9489H,0A50AH,0B58BH DW 0C60CH,0D68DH,0E70EH,0F78FH CRCTB2 DW 0,1189H,2312H,329BH DW 4624H,57ADH,6536H,74BFH DW 8C48H,9DC1H,0AF5AH,0BED3H DW 0CA6CH,0DBE5H,0E97EH,0F8F7H USRINXA DW -1 ;ADDRESS OF USER INDEX USRINXL DW 0 ;INDEX HIGHEST ENTRY NUMBER DW 3 THESTR DB 'THE' DW 4 ATDT DB 'ATDT' ;FORBIDDEN STRING ;SYSTEM FILE NAMES WELFN DB 'WELCOME',0 ;WELCOME FILE FLASHN DB 'FLASH',0 ;FLASH FILE NAME REGPLCY DB 'REGPLCY',0 ;REGISTRATION POLICY REGDENY DB 'REGDENY',0 ;REGISTRATION DENIED REGPEND DB 'REGPEND',0 ;REGISTRATION PENDING SCRIPT2 DB 'CCREG.SPT',0 ;NEW USER QUESTIONAIRE SYSDATA ENDS ;----------------------------------------------- ;CODE SEGMENT ;----------------------------------------------- CSEG SEGMENT PARA PUBLIC 'CODE' EXTRN ASCBIN:NEAR,BINASC:NEAR,DQTIOA:NEAR EXTRN DOSDAT:NEAR,DOSTIM:NEAR,ERROR:NEAR EXTRN FREBUF:NEAR,FRELBF:NEAR,ILINEB:NEAR EXTRN LOGDSK:NEAR,MOVSTR:NEAR,PADB:NEAR EXTRN PURG1:NEAR,PURGST:NEAR,PUSTAT:NEAR,QMSGNO:NEAR EXTRN CKPTM:NEAR,SENDF:NEAR,STRIP:NEAR,LABWIN:NEAR EXTRN TIMON:NEAR,WRMSG:NEAR,CKPTM:NEAR EXTRN UPDUSR:NEAR,XLATE:NEAR,MVZSTR:NEAR EXTRN BINASP:NEAR,MAILIX:NEAR,GETBUF:NEAR EXTRN TAYSOP:NEAR,YIELD:NEAR,CMPSTR:NEAR,CPCSTA:NEAR EXTRN MMENU1:NEAR,DQCMD:NEAR,CRCXXX:NEAR EXTRN PASSW:NEAR,WMSGNO:NEAR,STM7B:NEAR,RPOST:NEAR EXTRN DISPFM:NEAR,RUNFIL:NEAR,WFBLK:NEAR,SENDHF:NEAR EXTRN GETSBF:NEAR,RFBLK:NEAR,MOVMSG:NEAR,APPBYT:NEAR EXTRN LOCKWT:NEAR,UNLOCK:NEAR,frecmd:near,LALIGN:NEAR EXTRN GETUSR:NEAR,FREUSR:NEAR,ADDUSR:NEAR,BLANKF:NEAR PUBLIC SIGNON,CRCCLC,WELCO,CRCBFR,CRCFIX PUBLIC RDUSER,FNAM ASSUME CS:CSEG,DS:NOTHING,ES:SYSDATA LOGIN PROC NEAR ;--------------------------------------------------------------- ;GET SIGN-ON INFORMATION ; BP-2 LOGIN FLAGS ; 80H - NAME IS A HANDLE ; 40H - NEW USER ; 20H - RESTART REQUEST ; BP-4 USER FLAGS ;--------------------------------------------------------------- SIGNON: PUSH BP ;SAVE CALLER'S FRAME MOV BP,SP ;ESTABLISH LOCAL FRAME SUB SP,4 ;ALLOCATE LOCAL STORAGE XOR AX,AX ;NULL MOV [BP-2],AX ;CLEAR LOGIN FLAGS MOV [BP-4],AX ;CLEAR USER FLAGS MOV AX,145 ;SYSTEM HERALD CALL WMSGNO ;SEND TO USER MOV WORD PTR [BX+USRCT],0 ;CLEAR NUMBER OF TRIES CALL TIMON ;SHOW TIME LOGGED ON ;LOG INCOMING CALL CALL ILINEB ;GET BUFFER MOV AX,251 ;'CALL ANSWERED CALL MOVMSG ;PUT IN BUFFER MOV DX,[BX+DCESTAT] ;COMMUNICATION STATUS OR DX,DX ;EXIST? JNZ SIGN00 ;NO PROBLEM MOV DX,[BX+DTESTAT] ;USE TERMINAL STATUS SIGN00: TEST WORD PTR [BX+CBMDM],MDMKBD ;LOCAL CONNECTION? JNZ SIGN10 ;YES - SKIP BAUD CHECK TEST DX,MSP012 ;1200 BAUD? MOV AX,246 ;ASSUME 1200 JNZ SIGN02 ;YES TEST DX,MSP024 ;2400 BAUD? MOV AX,247 ;ASSUME 2400 JNZ SIGN02 ;2400 IT IS TEST DX,MSP048 ;4800 BAUD? MOV AX,253 ;ASSUME 4800 JNZ SIGN02 ;4800 IT IS TEST DX,MSP096 ;9600 BAUD? MOV AX,394 ;ASSUME 9600 JNZ SIGN02 ;9600 IT IS TEST DX,MSP003 ;300? MOV AX,245 ;ASSUME 300 JZ SIGN03 ;UNKNOWN SPEED SIGN02: CALL MOVMSG ;MOVE SPEED TO BUFFER MOV AX,252 ;'BAUD CALL MOVMSG ;MOVE TO BUFFER ;SHOW ERROR CORRECTION PROTOCOL SIGN03: MOV DX,[BX+DCESTAT] ;RESTORE DCE STATUS TEST DX,MECLAPM ;V.42 ERROR CORRECTION? MOV AX,412 ;ASSUME LAPM JNZ SIGN04 ;YES TEST DX,MECMNP ;MNP ERROR CORRECTION? MOV AX,411 ;ASSUME MNP JZ SIGN05 ;NO SIGN04: CALL MOVMSG ;MOVE TO BUFFER ;SHOW DATA COMPRESSION ACTIVE SIGN05: TEST DX,MDCMNP5 ;MNP DATA COMPRESSION? MOV AX,413 ;MNP JNZ SIGN06 ;YES TEST DX,MDCV42 ;V42 DATA COMPRESSION? MOV AX,414 ;V42 JZ SIGN07 ;NO SIGN06: CALL MOVMSG ;MOVE TO BUFFER SIGN07: MOV SI,WORD PTR [BX+USRLB] ;STRING ADDRESS CALL LOGDSK ;LOG REQUEST SIGN10: INC WORD PTR [BX+USRCT] ;COUNT LOGON ATTEMPT SIGN11: CALL PURGST ;FREE LOGON INFO AND WORD PTR [BP-2],20H ;CLEAR ALL BUT RESTART CMP WORD PTR [BX+USRCT],5 ;MAX ATTEMPTS? JBE SIGN20 ;NO PROBLEM ;LOG INVALID SIGN-ON SIGN12: CALL ILINEB ;GET BUFFER MOV AX,242 ;'INVALID LOGON CALL MOVMSG ;PUT IN BUFFER MOV SI,WORD PTR [BX+USRLB] ;STRING ADDRESS SIGN15: CALL LOGDSK ;LOG ATTEMPT SIGN17: STC ;CANCEL LOGIN EXITF SIGN20: MOV AX,137 ;FIRST NAME? CALL QMSGNO CALL TPOST ;TEST RETURN CODE JNC SIGN21 ;OK JMP SIGN12 ;LOST CARRIER - LOG AS INVALID SIGN21: CALL DQTIOA ;DEQUEUE 1ST TIOA JC SIGN10 ;NONE AVAILABLE MOV WORD PTR [BX+USR1N],SI ;FIRST NAME MOV DI,WORD PTR [SI-2] ;INPUT LENGTH OR DI,DI ;ANYTHING? JNZ SIGN23 ;YES - CONTINUE TEST WORD PTR [BX+CBMDM],MDMKBD ;LOCAL CONNECTION? JZ SIGN11 ;NO - PROMPT AGAIN JMP SIGN17 ;EXIT SIGN23: ADD DI,SI ;POINT TO DELIMITER TEST BYTE PTR [DI],80H ;EVEN PARITY? JZ SIGN26 ;NO PROBLEM CALL STM7B ;SET EVEN PARITY CALL ILINEB ;INITIALIZE BUFFER MOV AX,248 ;7 BIT CALL MOVMSG ;MOVE TO BUFFER CALL LOGDSK ;LOG REQUEST SIGN26: CMP WORD PTR [BX+USRIN],0 ;INPUT ALREADY IN BUFFER? JNZ SIGN30 ;YES MOV WORD PTR [BX+USR2N],0 ;NO 2ND NAME YET CALL BNAM ;VALIDATE USER NAME JNC SIGN32 ;NAME IS VALID CMP WORD PTR [BX+USR2N],0 ;NAME SPLIT? JNZ SIGN31 ;YES MOV AX,138 ;LAST NAME CALL QMSGNO ;ASK USER CALL TPOST ;TEST RETURN CODE JC SIGN12 ;LOST CARRIER - LOG AS INVALID SIGN30: CALL DQTIOA ;DEQUEUE INPUT MOV WORD PTR [BX+USR2N],SI ;LAST NAME CALL BNAM ;BUILD SYSTEM NAME JNC SIGN32 ;NAME IS VALID SIGN31: CALL BADNAM ;SPECIAL CASE? JC SIGN12 ;YES - INVALID LOGIN CALL RAWNAM ;BUILD ERROR STRING MOV AX,144 ;NOT VALID CALL MOVMSG ;MOVE TO BUFFER CALL WRMSG ;DISPLAY MESSAGE MOV AX,141 ;INVALID NAME MENU CALL QMSGNO ;CHECK CHOICES CALL TPOST ;TEST RETURN CODE JNC SIG31A ;OK JMP SIGN12 ;LOST CARRIER - LOG AS INVALID SIG31A: CALL DQCMD ;GET RESPONSE CALL LALIGN ;STRIP LEADING BLANKS CALL XLATE ;MAKE UC CMP BYTE PTR [SI],'G' ;LOGOFF? JZ SIG31G ;YES CMP BYTE PTR [SI],'C' ;RE-ENTER NAME? JZ SIG31J ;YES CMP BYTE PTR [SI],'H' ;HELP? JNZ SIGN31 ;NO - REPEAT PROMPT MOV AX,10 ;HELP FILE NUMBER CALL SENDHF ;INVOKE HELP SCRIPT JMP SIGN31 ;REPEAT PROMPT SIG31G: JMP SIGN12 ;INVALID LOGON SIG31J: JMP SIGN10 ;CORRECT NAME SIGN32: CALL LABWIN ;UPDATE WINDOW LABEL CMP USRCNT,-1 ;FILE LOCKED? JNZ SIG32A ;NO PROBLEM MOV AX,387 ;USER FILE UNAVAILABLE CALL QMSGNO ;GET WAIT RESPONSE CALL TPOST ;TEST RETURN CODE JC SIG33J ;USER HUNG UP CALL DQCMD ;GET RESPONSE CALL LALIGN ;STRIP LEADING BLANKS CALL XLATE ;MAKE UC CMP BYTE PTR [SI],'Y' ;WILL HE WAIT? JNZ SIG33J ;NO MOV SI,OFFSET USRLOCK ;USER FILE LOCK WORD CALL LOCKWT ;WAIT FOR FILE CALL UNLOCK ;CAN SHARE NOW SIG32A: MOV SI,WORD PTR [BX+USR3N] ;USER NAME CALL RDUSER ;CHECK FOR KNOWN USER JC SIGN33 ;NAME NOT FOUND MOV [BX+USRSL],AX ;USER SLOT # MOV [BX+USRST],SI ;RECORD ADDRESS JMP SIGN34 ;EXISTING USER SIGN33: CALL RAWNAM ;BUILD ERROR MSG MOV AX,143 ;NOT REGISTERED CALL MOVMSG ;MOVE TO STRING CALL WRMSG ;DISPLAY STRING MOV AX,140 ;NOT FOUND MENU CALL QMSGNO CALL TPOST ;TEST RETURN CODE JC SIG33J ;LOST CARRIER - LOG AS INVALID CALL DQCMD ;GET RESPONSE CALL LALIGN ;STRIP LEADING BLANKS CALL XLATE ;MAKE UC CMP BYTE PTR [SI],'C' ;CORRECT NAME? JNZ SIG33G ;NO JMP SIGN10 ;YES SIG33G: CMP BYTE PTR [SI],'G' ;LOGOFF? JNZ SIG33R ;NO SIG33J: JMP SIGN12 ;YES - LOG AS INVALID SIG33R: CMP BYTE PTR [SI],'R' ;REGISTER? JNZ SIGN33 ;PROMPT AGAIN CALL FMTNAM ;FORMAT 1ST AND LAST NAMES JMP SIGN60 ;NEW USER ;CHECK FOR RESTRICTED LOGIN SIGN34: CALL FMTNAM ;FORMAT 1ST & LAST NAMES MOV DI,WORD PTR [BX+USRST] ;SIGN-ON ENTRY TEST BYTE PTR [DI+UESTAT],80H ;LOCKED OUT? JZ SIG34A ;NO PROBLEM JMP SIGN31 ;TREAT AS INVALID SIG34A: TEST BYTE PTR [DI+UESTAT],40H ;LOCAL SIGN-IN ONLY? JZ SIGN35 ;NO PROBLEM TEST WORD PTR [BX+CBMDM],MDMKBD ;LOCAL CONSOLE? JNZ SIGN35 ;YES - CHECK PASSWORD JMP SIGN10 ;INVALID NAME SIGN35: CMP WORD PTR [DI+UEPSWD],0 ;PASSWORD REQUIRED? JNZ SIG35B ;YES TEST DS:MSGCKPT+MSOPTS,4000H ;PASSWORDS REQUIRED? JZ SIG35A ;NO PUSH DI ;PASS USER RECORD CALL PASSW ;GET PASSWORD SIG35A: JMP SIGN50 ;SKIP PASSWORD CHECK SIG35B: MOV WORD PTR [BX+USRCT],0 ;CLEAR COUNT CMP WORD PTR [BX+USRIN],0 ;ALREADY IN BUFFER? JNZ SIGN40 ;YES - DON'T PROMPT SIGN36: INC WORD PTR [BX+USRCT] ;COUNT PASSWORD ATTEMPTS CMP WORD PTR [BX+USRCT],4 ;REACHED LIMIT? JBE SIGN38 ;NO PROBLEM ;LOG INVALID PASSWORD SIGN37: CALL ILINEB ;GET BUFFER MOV AX,243 ;INVALID PASSWORD CALL MOVMSG ;PUT IN BUFFER MOV DI,WORD PTR [BX+USR3N] ;LOGON NAME CALL MOVSTR mov al,':' ;delimiter call appbyt ;add to buffer mov di,word ptr [bx+usrcmd] ;password xchg si,di call strip xchg si,di call movstr ;add password to buffer JMP SIGN15 ;LOG ERROR AND EXIT SIGN38: MOV AX,139 ;PASSWORD PROMPT MOV WORD PTR [BX+USRSE],1 ;ECHO WITH DOTS CALL QMSGNO ;ASK USER FOR PASSWORD CALL TPOST ;TEST RETURN CODE JNC SIGN39 ;READ OK JMP SIGN12 ;LOST CARRIER SIGN39: MOV WORD PTR [BX+USRSE],0 ;RESTORE NORMAL ECHO SIGN40: CALL DQCMD ;DEQUEUE INPUT CALL LALIGN ;STRIP LEADING BLANKS CALL XLATE ;MAKE UPPER CASE MOV CX,15 ;PASSWORD LENGTH CALL PADB ;PAD TO TARGET LENGTH MOV DI,WORD PTR [BX+USRST] ;SIGN-ON ENTRY CALL CRCCLC ;ENCRYPT PASSWORD CMP AX,WORD PTR [DI+UEPSWD] ;PASSWORD MATCH? JNZ SIGN36 ;TRY AGAIN ;CLEAR PASSWORD BUFFER CALL BLANKF ;SET ALL BLANKS ;PASSWORD OK OR NOT REQUIRED SIGN50: MOV WORD PTR [BX+USRCT],0 ;CLEAR NEW USER FLAG OR WORD PTR [BX+CBFLG],SFVUR ;SHOW VALID RECORD call frecmd ;free password buffer ;INVOKE SCRIPT FILE XOR DX,DX ;NO PASSED PARMS PUSH DX MOV SI,WORD PTR [BX+USRST] ;USER RECORD PUSH SI CALL ILINEB ;INITIALIZE BUFFER MOV AX,250 ;EXIT NAME CALL MOVMSG ;MOVE TO BUFFER PUSH SI ;PASS AS PARAMETER MOV AX,80 ;WORK BUFFER LENGTH CALL GETBUF ;GET BUFFER MOV DI,OFFSET SCRIPT2 ;SCRIPT FILE NAME CALL MVZSTR ;MOVE TO BUFFER PUSH SI ;PASS PARAMETER CALL RUNFIL ;INVOKE SCRIPT FILE CALL FREBUF ;RELEASE WORK BUFFER CMP AX,16 ;ACCEPT LOGIN? JBE SIGN58 ;YES JMP SIGN12 ;INVALID LOGIN SIGN58: JMP LOGUSR ;UPDATE USER RECORD ;NEW USER SIGN ON SIGN60: OR WORD PTR [BP-2],40H ;NEW USER MOV WORD PTR [BX+USRCT],-1 ;SET NEW USER FLAG MOV WORD PTR [BX+USRSL],-1 ;NOT IN USER FILE MOV AX,USRSIZ ;BUFFER SIZE CALL GETBUF ;GET EMPTY BUFFER MOV WORD PTR [BX+USRST],SI ;SAVE IN TCB MOV DI,SI ;INDEX WITH DI OR WORD PTR [DI+UEOPTS],1 ;SET LF FLAG MOV WORD PTR [DI+UEMARG],72 ;DEFAULT MARGIN MOV WORD PTR [DI+UEXPL],24 ;DEFAULT PAGE LENGTH MOV WORD PTR [DI+UEVERS],0 ;SHOW NEW PASSWORD FORMAT MOV AX,DS:MSGCKPT+MDSECT ;NEW USER DEFAULT SECTIONS MOV WORD PTR [DI+UESECT],AX ;AUTHORIZE MESSAGE SECTIONS MOV AX,[BP-4] ;USER FLAGS MOV BYTE PTR [DI+UEUFLG],AL ;SET FOR SCRIPT TEST DS:MSGCKPT+MSOPTS,8000H ;NEED VALIDATION? JZ SIGN65 ;NO OR BYTE PTR [DI+UESTAT],8 ;REQUIRES VALIDATION SIGN65: TEST WORD PTR [BP-2],80H ;HANDLE? JZ SIGN67 ;NO OR BYTE PTR [DI+UESTAT2],80H ;FLAG AS HANDLE SIGN67: PUSH DI ADD DI,UEGID ;GROUP ID FIELD MOV AL,' ' ;GID DEFAULTS TO BLANK MOV CX,8 ;FIELD LENGTH PUSH ES PUSH DS POP ES REP STOSB ;BLANK GROUP ID FIELD POP ES POP DI ADD DI,UEMEMO ;MEMO FIELD MOV CX,UEUPLD-UEMEMO ;LENGTH PUSH ES PUSH DS POP ES REP STOSB ;BLANK MEMO FIELD POP ES MOV SI,WORD PTR [BX+USR3N] ;LOGON NAME MOV CX,31 ;LENGTH OF NAME FIELD MOV DI,WORD PTR [BX+USRST] ;SIGN-ON RECORD ADD DI,UENAM ;NAME FIELD PUSH ES PUSH DS POP ES REP MOVSB ;PUT NAME IN RECORD POP ES OR WORD PTR [BX+CBFLG],SFVUR ;SHOW VALID RECORD TEST DS:MSGCKPT+MSOPTS,4000H ;PASSWORD REQUIRED? JZ SIGN95 ;NO MOV AX,[BX+USRST] ;USER RECORD PUSH AX ;PASS AS PARM CALL PASSW ;GET PASSWORD ;INVOKE SCRIPT FILE FOR REGISTRATION SIGN95: XOR DX,DX ;NO PASSED PARMS PUSH DX MOV SI,WORD PTR [BX+USRST] ;USER RECORD PUSH SI CALL ILINEB ;INITIALIZE BUFFER MOV AX,249 ;EXIT NAME CALL MOVMSG ;MOVE TO BUFFER TEST WORD PTR [BP-2],20H ;RESTART REQUEST? JZ SIGN97 ;NO MOV AL,'R' ;RESTART INDICATOR CALL APPBYT ;ADD TO EXIT NAME SIGN97: PUSH SI ;PASS AS PARAMETER MOV AX,80 ;WORK BUFFER LENGTH CALL GETBUF ;GET BUFFER MOV DI,OFFSET SCRIPT2 ;SCRIPT FILE NAME CALL MVZSTR ;MOVE TO BUFFER PUSH SI ;PASS PARAMETER CALL RUNFIL ;INVOKE SCRIPT FILE CALL FREBUF ;RELEASE WORK BUFFER CMP AX,8 ;ACCEPT LOGIN? JB SIGN99 ;YES CMP AX,16 ;RETRY LOGIN? JNB SIGN98 ;NO OR WORD PTR [BP-2],20H ;SET RESTART FLAG MOV SI,[BX+USRST] ;USER RECORD MOV AL,BYTE PTR [SI+UEUFLG] ;USER FLAGS SET BY SCRIPT MOV [BP-4],AX ;SAVE FOR RESTART CALL FREBUF ;RELEASE USER RECORD AND WORD PTR [BX+CBFLG],NOT SFVUR ;SHOW NO USER RECORD JMP SIGN10 ;RETRY FROM BEGINNING SIGN98: JMP SIGN12 ;INVALID LOGIN SIGN99: MOV SI,WORD PTR [BX+USRST] ;NEW USER RECORD CALL ADDUSR ;GET NEW USER RECORD MOV [BX+USRSL],AX ;NEW SLOT NUMBER LOGUSR: CALL TAYSOP ;SYSOP? JZ LOGU05 ;NO MOV SI,WORD PTR [BX+USR3N] ;USER NAME CALL STRIP ;TRIM BLANKS MOV AX,184 ;'SYSOP CALL MOVMSG ;APPEND STRING MOV WORD PTR [BX+USR3N],SI ;CAN CHANGE LOGU05: CALL ILINEB ;GET LINE BUFFER MOV AX,254 ;'LOGGING CALL MOVMSG MOV DI,WORD PTR [BX+USR3N] ;NAME CALL MOVSTR MOV AX,255 ;'TO DISK CALL MOVMSG CALL WRMSG CALL ILINEB ;GET LINE BUFFER MOV DI,WORD PTR [BX+USR3N] ;USER NAME CALL MOVSTR MOV AX,244 ;LOGGED ON CALL MOVMSG ;MOVE TO BUFFER LOGU09: CALL LOGDSK ;LOG TO DISK CALL FRELBF ;FREE LINE BUFFER CALL TIMON ;SHOW TIME LOGGED ON MOV DI,WORD PTR [BX+USRST] ;SIGN-ON RECORD MOV AX,WORD PTR [DI+UEHMSG] ;HIGH MESSAGE READ OR AX,AX ;EXIST? JNZ LOGU10 ;YES MOV AX,WORD PTR [DI+UELMSG] ;PREVIOUS HIGH MESSAGE MOV WORD PTR [DI+UEHMSG],AX ;SET AS CURRENT HIGH LOGU10: CMP AX,DS:MSGCKPT+MLASTMN ;HIGH WATER MARK JBE LOGU11 ;NO PROBLEM XOR AX,AX MOV WORD PTR [DI+UELMSG],AX ;RESET TO START MOV WORD PTR [DI+UEHMSG],AX LOGU11: CMP AX,WORD PTR [DI+UELMSG] ;NEW HIGH? JBE LOGU12 ;NO MOV WORD PTR [DI+UELMSG],AX ;SET NEW START POINT LOGU12: MOV SI,DI ;USER RECORD MOV CX,WORD PTR [DI+UELDAT] ;YEAR MOV WORD PTR [DI+UEPDAT],CX ;MOVE TO PREVIOUS MOV CX,WORD PTR [DI+UELDAT+2] ;MONTH & DAY MOV WORD PTR [DI+UEPDAT+2],CX ;MOVE TO PREVIOUS MOV CX,WORD PTR [DI+UELTIM] ;HOUR & MINUTE MOV WORD PTR [DI+UEPTIM],CX ;MOVE TO PREVIOUS MOV CX,WORD PTR [DI+UELTIM+2] ;SECONDS MOV WORD PTR [DI+UELTIM+2],CX ;MOVE TO PREVIOUS CALL DOSDAT MOV WORD PTR [DI+UELDAT],CX ;YEAR MOV WORD PTR [DI+UELDAT+2],DX ;MONTH & DAY CALL DOSTIM MOV WORD PTR [DI+UELTIM],CX ;HOUR & MINUTE MOV WORD PTR [DI+UELTIM+2],DX ;SECONDS INC WORD PTR [DI+UETIMO] ;TIMES LOGGED ON INC USRCNT ;LOGGED-ON USERS MOV AX,[BX+USRSL] ;USER SLOT NUMBER CALL UPDUSR ;RE-WRITE USER RECORD TEST BYTE PTR [DI+UESTAT],12 ;REG PENDING OR DENIED? JZ LOGU15 ;NO PROBLEM MOV AX,5 ;FIVE MINUTES JMP SHORT LOGU24 ;SET TIME LOGU15: TEST BYTE PTR [DI+UESTAT],2 ;FIXED TIME? JZ LOGU17 ;NO MOV AX,WORD PTR [DI+UERTIM] ;TIME ALLOCATION JMP LOGU26 ;SET TIME LOGU17: MOV AX,15 ;BASIC TIME ALLOWANCE CMP WORD PTR [DI+UEMSGR],1 ;READ ANY MESSAGES? JLE LOGU20 ;NO ADD AX,15 LOGU20: CMP WORD PTR [DI+UEMSGE],1 ;ENTERED ANY? JLE LOGU22 ;NOT TO SPEAK OF ADD AX,15 LOGU22: CMP WORD PTR [DI+UEUPLD],1 ;HOW ABOUT UPLOADS? JLE LOGU24 ;NO ADD AX,15 LOGU24: MOV CX,WORD PTR [DI+UEPDAT+2] ;PREVIOUS DATE CMP CX,WORD PTR [DI+UELDAT+2] ;TODAY? JNZ LOGU26 ;NO MOV CX,WORD PTR [DI+UELTIM] ;CURRENT HOURS & MINUTES SUB CX,WORD PTR [DI+UEPTIM] ;PREVIOUS HOURS & MINUTES CMP CL,60 ;CROSS HOUR? JB LOGU25 ;NO PROBLEM ADD CL,60 ;CORRECT MINUTES LOGU25: TEST CH,255 ;ANY HOURS JNZ LOGU26 ;YES SHR CX,1 ;ALLOW HALF CREDIT ADD CX,WORD PTR [DI+UERTIM] ;RESIDUAL TIME CMP CX,AX ;GREATER THAN MAX? JNC LOGU26 ;YES - IGNORE MOV AX,CX ;USE LOWER TIME LOGU26: CMP AX,3 ;MINIMUM TIME ALLOCATION JNB LOGU28 ;NO PROBLEM MOV AX,12 ;HELP TEXT CALL SENDHF ;SEND HELP FILE XOR AX,AX ;SET ZERO TIME LOGU28: MOV WORD PTR [BX+USRLMT],AX ;SET MAXIMUM TIME CALL ILINEB ;GET LINE BUFFER MOV AX,256 ;'YOU HAVE SIGNED ON CALL MOVMSG MOV DI,WORD PTR [BX+USRST] ;USER RECORD MOV AX,WORD PTR [DI+UETIMO] ;TIMES ON CMP AX,1 JZ LOGU30 ;DON'T PRINT 1ST TIME CALL BINASP ;PUT IN STRING MOV AX,257 ;'TIMES CALL MOVMSG CALL WRMSG ;DISPLAY LOGU30: CALL FRELBF ;FREE LINE BUFFER ;UPDATE LAST CALLER INFO INC DS:MSGCKPT+MLASTCN ;COUNT CALLER PUSH SI PUSH DI LEA DI,DS:MSGCKPT+MLCNAM ;LAST CALLER NAME MOV SI,WORD PTR [BX+USRST] ;USER RECORD ADD SI,UENAM ;USER NAME MOV CX,31 ;NAME FIELD LENGTH PUSH ES PUSH DS POP ES REP MOVSB POP ES POP DI POP SI CALL CKPTM ;WRITE RECORD ;WELCOME NEW USER MOV DI,WORD PTR [BX+USRST] ;USER RECORD CMP WORD PTR [DI+UETIMO],1 ;TIMES ON JNZ LOGU80 ;NOT A NEW USER MOV DX,OFFSET WELFN ;WELCOME FILE NAME CALL SNDCF ;DISPLAY FILE ;CHECK FOR REGISTRATION PENDING OR DENIED LOGU80: MOV DI,WORD PTR [BX+USRST] ;USER RECORD TEST BYTE PTR [DI+UESTAT],12 ;PENDING OR DENIED? JZ LOGU83 ;NO PROBLEM MOV DX,OFFSET REGPEND ;ASSUME PENDING TEST BYTE PTR [DI+UESTAT],8 ;CORRECT? JNZ LOGU81 ;YES MOV DX,OFFSET REGDENY ;DENIED LOGU81: CALL SNDCF ;SEND APPROPRIATE FILE ;PRINT FLASH FILE - IF ANY LOGU83: MOV DX,OFFSET FLASHN ;FLASH FILE NAME CALL SNDCF ;SEND IT IF IT EXISTS CALL DISPFM ;DISPLAY FLASH MESSAGES ;CHECK FOR MESSAGES MOV DI,WORD PTR [BX+USRST] ;USER RECORD TEST WORD PTR [DI+UEOPTS],8 ;SKIP MAIL CHECK? JNZ LOGU90 ;YES XOR AX,AX ;ASSUME SCAN FROM ZERO TEST WORD PTR [DI+UEOPTS],16 ;NEW MAIL ONLY? JZ LOGU85 ;NO - GO SCAN MOV AX,WORD PTR [DI+UELMSG] ;LAST MSG READ LOGU85: CALL MAILIX ;CHECK FOR UNREAD MSGS ;ENTER MESSAGE SUBSYSTEM LOGU90: MOV AX,19 ;"ENTERING MSG SYSTEM ... CALL WMSGNO ;DISPLAY MSG ;PRINT CALLER STATISTICS CALL PUSTAT ;USER STATISTICS CLC ;LOGON ACCEPTED EXITF ;--------------------------------------------------------- ;PRINT WELCOME FILE ;--------------------------------------------------------- WELCO: MOV DX,OFFSET WELFN ;WELCOME FILE NAME CALL SNDCF ;TRANSMIT FILE JMP MMENU1 ;MAIN MENU ;--------------------------------------------------------- ;BUILD USER NAME FROM FIRST & LAST NAMES ;SET CARRY IF NAME IS INVALID ;--------------------------------------------------------- BNAM: MOV SI,WORD PTR [BX+USR1N] ;1ST NAME CALL FNAM ;FORMAT NAME JNC BNAM00 ;NAME IS VALID RET ;INVALID NAME BNAM00: CMP WORD PTR [BX+USR2N],0 ;ANY SECOND NAME? JNZ BNAM01 ;NO PROBLEM CALL SNAM ;SPLIT NAME JNC BNAM01 ;OK RET BNAM01: MOV SI,WORD PTR [BX+USR2N] ;LAST NAME CALL FNAM ;FORMAT NAME JNC BNAM02 ;NAME IS VALID RET ;INVALID NAME BNAM02: MOV AX,31 ;MAX NAME SIZE CALL GETBUF ;GET SPACE FOR NAME MOV DX,30 ;MAXIMUM LENGTH MOV WORD PTR [BX+USR3N],SI ;LOGON NAME MOV WORD PTR [SI-2],AX ;LENGTH OF LOGON NAME MOV DI,SI MOV SI,WORD PTR [BX+USR1N] ;FIRST NAME MOV CX,WORD PTR [SI-2] ;DATA LENGTH CMP CX,DX ;OVER LENGTH? JBE BNAM03 ;NO PROBLEM MOV CX,DX ;IMPOSE LIMIT BNAM03: SUB DX,CX ;REMAINING SPACE PUSH ES PUSH DS POP ES REP MOVSB ;COPY DATA MOV AL,' ' ;DELIMITER STOSB POP ES MOV SI,WORD PTR [BX+USR2N] ;LAST NAME MOV CX,WORD PTR [SI-2] ;DATA LENGTH CMP CX,DX ;OVER LENGTH? JBE BNAM04 ;NO PROBLEM MOV CX,DX ;IMPOSE LIMIT BNAM04: SUB DX,CX ;REMAINING SPACE PUSH ES PUSH DS POP ES REP MOVSB ;COPY DATA POP ES BNAM05: MOV CX,DX ;TRAILING SPACE JCXZ BNAM20 ;IF NO SPACE FOR SPACES MOV AL,' ' ;BLANK PUSH ES PUSH DS POP ES REP STOSB ;PAD WITH BLANKS POP ES MOV SI,WORD PTR [BX+USR3N] ;NAME STRING SUB WORD PTR [SI-2],DX ;ELIMINATE BLANKS FROM COUNT BNAM20: CLC RET ;------------------------------------------------------------------- ;TRANSLATE 1ST AND LAST NAMES TO LOWER CASE ;IF FIRST NAME IS 'THE', USE LAST NAME AS FIRST ; AND SET HANDLE FLAG ;------------------------------------------------------------------- FMTNAM: MOV SI,WORD PTR [BX+USR1N] ;FIRST NAME MOV DI,OFFSET THESTR ;'THE' CALL CPCSTA ;EQUAL TO 'THE' JNZ FMTN10 ;NOT EQUAL MOV SI,WORD PTR [BX+USR2N] ;LAST NAME MOV DI,WORD PTR [BX+USR1N] ;1ST NAME MOV WORD PTR [BX+USR1N],SI ;MAKE FIRST MOV WORD PTR [BX+USR2N],DI ;MAKE LAST OR WORD PTR [BP-2],80H ;FLAG AS HANDLE FMTN10: MOV SI,WORD PTR [BX+USR2N] ;LAST NAME CALL LCXL ;LOWER CASE TRANSLATE MOV SI,WORD PTR [BX+USR1N] ;FIRST NAME CALL LCXL ;LOWER CASE TRANSLATE CLC RET ;BUILD ERROR STRING WITH RAW NAME RAWNAM: CALL ILINEB ;INITIALIZE BUFFER MOV AX,142 ;'THE NAME < CALL MOVMSG ;MOVE TO BUFFER MOV DI,WORD PTR [BX+USR1N] ;1ST NAME CALL MOVSTR CMP WORD PTR [BX+USR2N],0 ;ANY SECOND NAME? JZ RAWNAX ;NO - EXIT MOV AL,' ' ;DELIMITER CALL APPBYT ;ADD TO STRING MOV DI,WORD PTR [BX+USR2N] ;LAST NAME CALL MOVSTR ;MOVE TO BUFFER RAWNAX: RET ;FORMAT NAME FIELD FOR UC AND VALID CHARACTERS ;CALLED WITH SI -> STRING HEADER ;RETURNS CARRY IF NAME IS INVALID FNAM: CALL STRIP ;TRUNCATE TRAILING BLANKS CALL LALIGN ;STRIP LEADING BLANKS CALL XLATE ;MAKE UPPER CASE PUSH DX PUSH SI PUSH DI PUSH AX PUSH CX MOV DI,SI ;TARGET FOR STOSB MOV CX,WORD PTR [SI-2] ;LENGTH OF STRING XOR DX,DX ;CLEAR COUNT JCXZ FNAM07 ;EMPTY STRING MOV AH,' ' ;SET INITIAL 'PREVIOUS' FNAM03: LODSB ;GET NEXT CHAR CMP AL,' ' ;BLANK? JNZ FNAM04 ;NO CMP AL,AH ;PREVIOUS ALSO BLANK? JNZ FNAM06 ;ALLOW EMBEDDED BLANK FNAM3A: LOOP FNAM03 ;SKIP CHARACTER JMP SHORT FNAM07 ;END OF STRING FNAM04: CMP AL,'-' JZ FNAM06 ;YES - VALID CMP AL,39 ;SINGLE QUOTE? JZ FNAM06 ;YES - VALID CMP AL,'A' ;ALPHABETIC? JAE FNAM05 ;YES CMP AL,'0' ;NUMERIC? JB FNAM3A ;NOT VALID CMP AL,'9' ;NUMERIC? JA FNAM3A ;NOT VALID OR WORD PTR [BP-2],80H ;FLAG AS HANDLE JMP SHORT FNAM06 ;VALID FNAM05: CMP AL,'Z' ;UPPER CASE? JA FNAM3A ;NO - INVALID FNAM06: MOV AH,AL ;SAVE PREVIOUS MOV [DI],AL ;SAVE IN STRING INC DI INC DX ;COUNT VALID CHARS LOOP FNAM03 ;CHECK NEXT CHAR FNAM07: CMP DX,2 ;MINIMUM LENGTH? FNAMX: POP CX POP AX POP DI POP SI MOV WORD PTR [SI-2],DX ;NEW DATA LENGTH POP DX RET ;SPLIT 1ST NAME STRING INTO 1ST AND 2ND NAMES ; BP-2 ORIGINAL STRING ; BP-4 1ST STRING LENGTH ; BP-6 2ND STRING LENGTH SNAM: PUSH BP ;SAVE CALLER'S FRAME MOV BP,SP ;ESTABLISH LOCAL FRAME SUB SP,6 ;ALLOCATE LOCAL VARIABLES MOV SI,WORD PTR [BX+USR1N] ;1ST NAME MOV [BP-2],SI ;ORIGINAL 1ST NAME MOV CX,[SI-2] ;STRING LENGTH MOV DI,SI ;START OF NAME MOV AL,' ' ;DELIMITER PUSH ES PUSH DS POP ES REPNZ SCASB ;LOOK FOR BLANK POP ES JZ SNAM10 ;FOUND ONE STC ;INVALID JMP SNAM90 ;EXIT SNAM10: MOV AX,[SI-2] ;ORIGINAL LENGTH SUB AX,CX ;1ST NAME LENGTH DEC AX ;DON'T COUNT BLANK MOV [BP-4],AX ;1ST NAME LENGTH MOV [BP-6],CX ;2ND NAME LENGTH CALL GETBUF ;GET NEW 1ST STRING MOV WORD PTR [BX+USR1N],SI ;ALLOCATE TO TASK MOV AX,[BP-6] ;2ND NAME LENGTH CALL GETBUF ;GET NEW 2ND STRING MOV WORD PTR [BX+USR2N],SI ;2ND NAME STRING MOV SI,[BP-2] ;ORIGINAL STRING MOV DI,WORD PTR [BX+USR1N] ;NEW 1ST STRING MOV CX,[BP-4] ;1ST LENGTH MOV WORD PTR [DI-2],CX ;SET LENGTH PUSH ES PUSH DS POP ES REP MOVSB ;MOVE 1ST NAME POP ES INC SI ;SKIP DELIMITER MOV DI,WORD PTR [BX+USR2N] ;NEW 2ND STRING MOV CX,[BP-6] ;2ND LENGTH MOV WORD PTR [DI-2],CX ;SET LENGTH PUSH ES PUSH DS POP ES REP MOVSB ;MOVE 2ND NAME POP ES MOV SI,[BP-2] ;ORIGINAL STRING CALL FREBUF ;FREE STRING CLC ;SHOW GOOD RETURN SNAM90: MOV SP,BP ;FREE LOCAL STORAGE POP BP ;RESTORE CALLER'S FRAME RET ;TRANSLATE ALL EXCEPT 1ST CHAR OF EACH WORD TO LOWER CASE LCXL: PUSH SI PUSH DI PUSH AX PUSH CX PUSH DX MOV CX,WORD PTR [SI-2] ;STRING LENGTH XOR DX,DX ;SHOW START OF WORD MOV DI,SI ;TARGET SAME AS SOURCE LCXL01: LODSB OR DX,DX ;1ST CHAR? JNZ LCXL02 ;NO - GO TRANSLATE INC DX ;NOT START OF WORD JMP SHORT LCXL03 ;DON'T TRANSLATE LCXL02: CMP AL,'A' JB LCXL03 ;NO TRANSLATE IF NOT UC CMP AL,'Z' JA LCXL03 ;NO TRANSLATE IF NOT UC OR AL,20H ;TRANSLATE TO LOWER CASE LCXL03: MOV [DI],AL ;SAVE IN STRING INC DI CMP AL,' ' ;BLANK? JNZ LCXL04 ;NO XOR DX,DX ;SHOW START OF WORD LCXL04: LOOP LCXL01 ;LOOP 'TIL DONE POP DX POP CX POP AX POP DI POP SI RET BADNAM: MOV SI,WORD PTR [BX+USR1N] MOV DI,OFFSET ATDT ;TEST STRING CALL CMPSTR ;MATCH? JNZ BADNOK ;NO STC ;SHOW ERROR RET BADNOK: CLC ;SHOW OK RET TPOST: JC TPOS10 ;SOME EXCEPTION CONDITION RET ;GOOD RETURN TPOS10: TEST BYTE PTR [BX+CBFLG],SFITP ;INTER TASK POST? JNZ TPOS20 ;YES, CHECK WHICH TPOS15: STC ;TIME OUT OR LOST CARRIER RET TPOS20: CALL RPOST ;GET POST CODE CMP AL,1DH ;FORCED OFF? JZ TPOS15 ;YES CLC ;IGNORE OTHER CODES FOR NOW RET ;READ USER SLOT ENTRY ; BP-2 USER NAME ; BP-4 CURRENT BLOCK # ; BP-6 WORK BUFFER RDUSER: PUSH BP ;CALLER'S FRAME MOV BP,SP ;LOCAL FRAME SUB SP,6 ;ALLOCATE LOCAL STORAGE PUSH CX PUSH DX PUSH DI MOV [BP-2],SI ;USER NAME MOV WORD PTR [BP-4],0 ;BEGINNING OF FILE CMP USRINXA,-1 ;NEED INITIALIZATION? JNZ RDUS20 ;NO MOV AX,UESIZE ;USER FILE BLOCK SIZE CALL GETBUF ;GET WORK BUFFER MOV [BP-6],SI ;BUFFER ADDRESS MOV AX,0 ;CONTROL RECORD MOV CX,USERH ;USER FILE HANDLE CALL RFBLK ;READ CONTROL RECORD MOV CX,[SI+UINXSZ] ;NUMBER OF ENTRIES MOV USRINXL,CX ;SAVE LENGTH DEC USRINXL ;USE BASE 0 SHL CX,1 ;LENGTH IN BYTES CALL FREBUF ;FREE CONTROL RECORD MOV AX,CX ;INDEX LENGTH CALL GETSBF ;GET BUFFER MOV USRINXA,SI ;POINT TO INDEX MOV AX,1 ;1ST INDEX BLOCK MOV CX,USERH ;USER FILE HANDLE CALL RFBLK ;READ BLOCK MOV AX,2 ;2ND INDEX BLOCK ADD SI,128 ;LOCATION IN TABLE CALL RFBLK ;READ BLOCK RDUS20: MOV SI,[BP-2] ;LOGON NAME CALL CRCCLC ;HASH LOGON NAME AND AX,USRINXL ;FOLD TO TABLE LENGTH SHL AX,1 ;INDEX IN WORDS MOV SI,AX ;NEED INDEX REG ADD SI,USRINXA ;START OF TABLE MOV AX,WORD PTR [SI] ;GET BLOCK # RDUS25: OR AX,AX ;EXIST? JNZ RDUS30 ;YES STC ;SHOW NOT FOUND JMP RDUS90 ;EXIT RDUS30: MOV [BP-4],AX ;BLOCK TO READ RDUS40: CALL CKUSER ;THIS ENTRY? JNC RDUS50 ;YES CALL YIELD ;LET OTHER USERS RUN JMP RDUS25 ;FOLLOW LINK RDUS50: CMP WORD PTR [BP-4],-1 ;END OF FILE? JNZ RDUS60 ;NO PROBLEM STC ;SHOW NOT FOUND JMP RDUS90 ;EXIT RDUS60: CLC ;SHOW RECORD FOUND RDUS90: POP DI POP DX POP CX MOV AX,[BP-4] ;BLOCK NUMBER MOV SI,[BP-6] ;RECORD ADDRESS MOV SP,BP ;FREE LOCAL STORAGE POP BP ;RESTORE CALLER'S FRAME RET ;CHECK USER FILE ENTRY FOR MATCH ON NAME ;RETURN CARRY SET IF NOT FOUND CKUSER: MOV AX,[BP-4] ;BLOCK NUMBER CALL GETUSR ;READ USER RECORD MOV [BP-6],SI ;RECORD ADDRESS JNC CKUS02 ;NO PROBLEM MOV WORD PTR [BP-4],-1 ;MARK END OF FILE CLC ;SHOW DONE RET CKUS02: MOV SI,[BP-2] ;LOGON NAME MOV DI,[BP-6] ;WORK BUFFER MOV CX,31 ;LENGTH OF NAME FIELD ADD DI,UENAM ;START OF NAME PUSH ES PUSH DS POP ES REPZ CMPSB ;COMPARE POP ES JNZ CKUS04 ;NOT EQUAL CLC RET CKUS04: MOV AX,[BP-4] ;BLOCK NUMBER MOV SI,[BP-6] ;USER RECORD MOV CX,[SI+UELNK] ;LINK POINTER CALL FREUSR ;RELEASE RECORD MOV AX,CX ;NEXT BLOCK NUMBER STC RET ;CALCULATE CRC IN AX FOR STRING POINTER IN SI CRCCLC: PUSH CX MOV CX,WORD PTR [SI-2] ;STRING LENGTH CALL CRCBFR ;CALCULATE CRC POP CX RET ;CALCULATE CRC FOR ADDRESS IN SI, LENGTH IN CX CRCBFR: PUSH BX PUSH CX PUSH DX PUSH SI PUSH DI XOR DX,DX ;CLEAR CRC REG JCXZ CRCB20 ;NULL STRING CRCB10: PUSH CX ;REMAINING LENGTH LODSB ;GET NEXT CHAR XOR AL,DL ;COMBINE WITH CRC LSB MOV AH,AL ;COPY RESULT AND AH,0F0H ;ISOLATE HIGH BITS AND AL,0FH ;ISOLATE LOW BITS MOV CL,4 ;SHIFT FACTOR SHR AH,CL ;RIGHT JUSTIFY BITS MOV DI,OFFSET CRCTB2 ;LOW CRC FACTOR TABLE XOR BX,BX ;INDEX REGISTER MOV BL,AL SHL BX,1 ;WORD INDEX MOV CX,WORD PTR ES:[DI+BX] ;LOW PART OF CRC FACTOR MOV DI,OFFSET CRCTB1 ;HIGH CRC FACTOR TABLE XOR BX,BX ;INDEX REG MOV BL,AH SHL BX,1 ;WORD INDEX MOV BX,WORD PTR ES:[DI+BX] ;HIGH PART CRC FACTOR XOR BX,CX ;COMBINE HIGH & LOW FACTORS MOV CL,8 ;SHIFT FACTOR SHR DX,CL ;SHIFT CRC XOR DX,BX ;COMBINE WITH TABLE VALUE POP CX LOOP CRCB10 ;GET NEXT CHAR CRCB20: MOV AX,DX ;RETURN RESULT IN AX POP DI POP SI POP DX POP CX POP BX RET CRCFIX: PUSH CX MOV CX,16 CRCF10: SHL AX,1 ;SHIFT CRC JNC CRCF20 ;NO OVERFLOW XOR AX,1021H ;CORRECT CRC CRCF20: LOOP CRCF10 ;NEXT BIT POP CX RET ;----------------------------------------------------------------- ;Invoke SENDF to print a file ;----------------------------------------------------------------- SNDCF: PUSH BP MOV BP,SP ;ESTABLISH LOCAL FRAME SUB SP,2 ;ALLOCATE LOCAL STORAGE PUSH AX PUSH DX PUSH SI PUSH DI MOV AX,13 ;STRING LENGTH CALL GETBUF ;STRING BUFFER MOV [BP-2],SI ;BUFFER ADDRESS MOV DI,DX ;FILE NAME STRING CALL MVZSTR ;MOVE TO BUFFER IN DS MOV DX,SI ;BUFFER ADDRESS CALL SENDF ;DISPLAY FILE MOV SI,[BP-2] ;BUFFER ADDRESS CALL FREBUF ;FREE TEMP BUFFER POP DI POP SI POP DX POP AX MOV SP,BP ;FREE LOCAL STORAGE POP BP RET LOGIN ENDP CSEG ENDS END