;N
	TITLE	LOGCOPY - NETWORK LOGGING AND COPY LIMITING UTILITY

CODE	SEGMENT PARA PUBLIC 'CODE'
	ASSUME CS:CODE

CSTART:
	JMP	INITIALIZE
;-----------------------------------------------------------------------
EVEN
INT_21		DD
PSP		DW
;-----------------------------------------------------------------------
SAVE_AX		DW
SAVE_SS		DW
SAVE_SP		DW
SAVE_FLAGS	DW
DRVTBL		DD
SERVTBL		DD
;-----------------------------------------------------------------------
REQ		DW	00FFH	; PACKET SIZE INTEL FORMAT
FUNC		DB	0DH	; LOG NETWORK MESSAGE FUNCTION: 0DH (13d)
STRLEN		DB	0
OPCODE		DB	'@'
LETTER		DB	0
FILLER		DB	' '	; WHITE SPACE
DUMMY		DB	0
;-----------------------------------------------------------------------
EVEN
REPLY		DW	0	; PACKET SIZE INTEL FORMAT
;-----------------------------------------------------------------------
SSTART		DB	800H DUP(0)
SEND		DW	0
STACK		DW	OFFSET SEND
;-----------------------------------------------------------------------
REQUEST		DW	0
;-----------------------------------------------------------------------
LOGGED		DB	0
DONTLOG		DB	0
DEFLOGACTION	DB	0FFH
PREFERED	DB	0
;-----------------------------------------------------------------------
FILENAME	DB	'^:LOG&COPY.DAT',00H
PATHREQ		DB	0EH,00,13H,00,'^',0AH,'SYS:PUBLIC'
PATHREPLY	DB	02,00,00,00
;-----------------------------------------------------------------------
MYNAME		DB	00H,02H,0CH,'LOG&COPY.EXE'
EVEN
LIST0		DW	OFFSET MYNAME
LIST		DW	800H DUP(0)
;-----------------------------------------------------------------------
INUSE	DB	0DH,0AH
	DB	'All Copies are currently in use. Press any key to'
	DB	' continue',0DH,0AH,'$'
NAMSG	DB	0DH,0AH
	DB	'Not attached to correct Server for this program.'
	DB	' Press any key to continue',0DH,0AH,'$'
;-----------------------------------------------------------------------
PROGRAM	DB	'LOG&COPY',0
AUTHOR	DB	'by Keith P Robison',0
NOTICE	DB	'Copyright Syracuse University 1988',0
VERSION	DB	'VeRsIoN=LOG&COPY Version 3.00 by Keith P. Robison',0
;=======================================================================

INITIALIZE:

	MOV	AX,DS
	MOV	PSP,AX	; SAVE PSP IN CASE WE NEED IT LATER
;-----------------------------------
	MOV	AX,CS
	MOV	DS,AX
	CALL	LOAD_DATA
;----------------------------------- Get Drive and Server table address
	MOV	AH,0EFH
	MOV	AL,01H
	INT	21H
	MOV	DI,OFFSET DRVTBL
	MOV	[DI],SI
	INC	DI
	INC	DI
	MOV	[DI],ES
	MOV	AH,0EFH
	MOV	AL,04H
	INT	21H
	MOV	DI,OFFSET SERVTBL
	MOV	[DI],SI
	INC	DI
	INC	DI
	MOV	[DI],ES
;----------------------------------- Save current Interupt 21h in INT_21
	MOV	AH,35H
	MOV	AL,21H
	INT	21H
	MOV	DI,OFFSET INT_21
	MOV	[DI],BX
	INC	DI
	INC	DI
	MOV	[DI],ES
;----------------------------------- Set Interupt 21h to INT_PROC
	MOV	DX,OFFSET INT_PROC
	MOV	AH,25H
	MOV	AL,21H
	INT	21H
;----------------------------------- Terminate and Stay Resident
	MOV	AH,31H
	MOV	AL,1
	MOV	DX,OFFSET CEND
	SUB	DX,OFFSET CSTART
	ADD	DX,101H	; 100 FOR PSP 1 FOR ADJUST
	MOV	CX,4
	SHR	DX,CL
	INC	DX
	INT	21H

;=======================================================================

INT_PROC	PROC FAR
	PUSHF
	CMP	AH,4BH
	JZ	EXEC

QUIT:	POPF
	JMP	DWORD PTR [INT_21]

EXEC:
	CMP	AL,0
	JNZ	QUIT
;---------------------------------------
	MOV	DONTLOG,0H
;---------------------------------------
	CLI
	MOV	SAVE_AX,AX
	POP	AX
	MOV	SAVE_FLAGS,AX
	MOV	SAVE_SS,SS
	MOV	SAVE_SP,SP
	MOV	AX,CS
	MOV	SS,AX
	MOV	SP,STACK
	STI
;---------------------------------------
	SUB	SP,004EH
	MOV	REQUEST,SP
	SUB	SP,0002H
;---------------------------------------
	PUSH	SAVE_SS
	PUSH	SAVE_SP
	PUSH    DS
	PUSH	ES
	PUSH	DI
	PUSH	SI
	PUSH	DX
	PUSH	CX
	PUSH	BX
	PUSH	BP
;--------------------------------------- Set up Reply buffer
	XOR	AX,AX
	MOV	REPLY,AX
;--------------------------------------- Set up request buffer
	PUSH	DS		; Save Original DS
	MOV	AX,CS
	MOV	DS,AX
	MOV	ES,AX
	MOV	SI,OFFSET REQ
	MOV	DI,[REQUEST]
	MOV	CX,0004H
	CLD
	REP	MOVSW           ; Copy Setup info to buffer
;--------------------------------------- Set DONTLOG to default value
	MOV	AL,[DEFLOGACTION]
	MOV	DONTLOG,AL
;---------------------------------------
	POP	DS		; Restore Original DS
;--------------------------------------- Store Program to request buffer
	DEC	DI		; DI is one more than start should be
	MOV	SI,DX		; Source Program name in DS:DX
	XOR	CX,CX
LOOP1:  INC	CX
	MOVSB			; Copy until a null is encountered
	CMP	BYTE PTR [SI],0
	JNZ	LOOP1
	DEC	DI
	MOV	BX,DI
	INC	CX		; Take into account extra chars
	INC	CX
	INC	CX
;--------------------------------------- Store String Length to buffer
	MOV	AX,CS
	MOV	DS,AX
	MOV	SI,[REQUEST]
	INC	SI
	INC	SI
	INC	SI
	MOV	[SI],CL
;--------------------------------------- Set drive letter to N if network
	MOV	CX,BX
	MOV	DI,[REQUEST]
	ADD	DI,0008H
	MOV	AL,[DI]
  	CMP	AL,':'		; IS FIRST CHARACTER A DRIVE LETTER ?
	JNZ	NOTNETDRV	; IF NOT DON'T DO SUBSTITUTION
	DEC	DI
	MOV	AL,[DI]
	CLC
	CMP	AL,'a'		; CHECK TO SEE IF IT IS LOWERCASE
	JC	UPPERCASE
	SUB	AL,20H		; MAKE lowercase INTO UPPERCASE
UPPERCASE:
	SUB	AL,'A'
	CLC
	CMP	AL,20H	 	; IS IT OUTSIDE THE BOUNDS OF THE TABLE?
	JNC	NOTNETDRV	; YES SO DON'T DO SUBSTITUTION
	PUSH	DS
	LDS	BX,DRVTBL
	XLAT
	POP	DS
	TEST	AL,03H
	JZ	NOTNETDRV
	MOV	AL,'N'
	MOV	[DI],AL
NOTNETDRV:
	MOV	BX,CX
;--------------------------------------- Search through program list
	MOV	DI,OFFSET LIST0
	PUSH	DI
SLIST:
	POP	DI
	MOV	SI,[DI]
	OR	SI,SI
	JNZ	SSKIP
	JMP	LOGIT		; NO MATCH SO LOGIT !
SSKIP:
	INC	DI
	INC	DI
	PUSH	DI
	XOR	CX,CX
	INC	SI
	INC	SI
	MOV	CL,[SI]
	ADD	SI,CX
	MOV	DI,BX
	STD
SCOMP:
	CMPSB
	JNZ	SLIST
	LOOP	SCOMP
	POP	DI
	DEC	SI
	MOV	AL,[SI]
	DEC	SI
	MOV	DONTLOG,0H
DONTEXECUTCHECK:
	TEST	AL,02H
	JZ	DONTLOGCHECK
	JMP	NOEXEC
DONTLOGCHECK:
	TEST	AL,01H
	JZ	LIMITCHECK
	MOV	DONTLOG,0FFH
LIMITCHECK:
	MOV	AL,[SI]
	OR	AL,AL
	JNZ	FINDSERVER	; NON ZERO --- COPYLIMITED
	JMP	LOGIT		; ZERO NOT COPYLIMITED
;---------------------------------------
FINDSERVER:
	PUSH	AX		; SAVE AX FOR COPYLIMIT
	INC	SI
	INC	SI		; SI points to start of copylimit string
	PUSH	SI		; SAVE SI FOR LATER
	MOV	AL,[SI]
	XOR	AH,AH
	ADD 	SI,AX
	INC	SI
	MOV	AL,[SI]
	OR	AL,AL
	JZ	LIMITED		; NO PREFERED SERVER FOR COPYLIMITING
	XOR	CH,CH
	MOV	CL,AL		; CX HOLDS LENGTH OF TARGET SERVER
	PUSH	ES		; SAVE ES SO WE DON'T HAVE TO SET IT
	LES	DI,SERVTBL
	INC	SI
	MOV	BX,SI		; SAVE SI FOR LOOP
        MOV	AX,DI		; SAVE DI FOR LOOP
	MOV	DX,1		; DX IS SERVER# INITIALLY 1
	CLD
FSLOOP1:
	PUSH	CX
	REPZ	CMPSB
	POP	CX
	JZ	SETSERVER		; A MATCH DX HOLDS SERVER #
	ADD	AX,0030H		; AX POINTS TO NEXT SERVER NAME
	MOV	DI,AX
	MOV	SI,BX
	INC	DX			; INCREMENT SERVER #
	CMP	DL,09H
	JC	FSLOOP1
	MOV	DX,OFFSET NAMSG		; NOT ATTACHED MESSAGE
	POP	ES
	POP	SI
	POP	AX
	JMP	MESSAGE			; ISSUE MESSAGE AND EXIT
SETSERVER:
	POP	ES
	MOV	PREFERED,DL
	MOV	AX,0F000H
	INT	21H
;---------------------------------------
LIMITED:
	POP	SI
	POP	AX
	CALL	COPYLIMIT
	JNC	RESETSERVER
;--------------------------------------- RESET SERVER TO DEFAULT
	MOV	DL,0
	MOV	AX,0F000H
	INT	21H
;--------------------------------------- LOG ALL COPIES IN USE
	MOV	SI,[REQUEST]
	MOV	DI,SI
	ADD	DI,0004H
	MOV	BYTE PTR [DI],'%'
	INC	DI
	MOV	BYTE PTR [DI],'%'
	MOV	DI,OFFSET REPLY
	MOV	AH,0E3H
	INT	21H
;--------------------------------------- SET UP FOR MESSAGE
	MOV	DX,OFFSET INUSE
;--------------------------------------- ISSUE MESSAGE AND WAIT FOR KEY
MESSAGE:
	MOV	AH,09H
	INT	21H
	MOV	AH,08H
	INT	21H
;--------------------------------------- RELOAD DATA FILE AND EXIT
NOEXEC:
	CALL	LOAD_DATA
	MOV	SAVE_AX,0000H           ; set RC to be 0
	PUSH	SAVE_FLAGS
	POPF
        CLC				; signal everthing ok
	PUSHF
        POP	SAVE_FLAGS
	JMP	EXIT2
;---------------------------------------
RESETSERVER:
	MOV	DL,0
	MOV	AX,0F000H
	INT	21H
;---------------------------------------
LOGIT:
	TEST	DONTLOG,0FFH
	JNZ	EXIT
	INC	LOGGED
	CMP	LOGGED,1
	JNZ	EXIT
	MOV	SI,[REQUEST]
	MOV	DI,SI
	ADD	DI,0005H
	MOV	BYTE PTR [DI],'S'
	MOV	DI,OFFSET REPLY
	MOV	AH,0E3H
	INT	21H
;---------------------------------------
EXIT:
	XOR	AH,AH
	MOV	AL,DONTLOG
	PUSH	AX		; SAVE DONTLOG FOR LATER
	PUSH	[REQUEST]
	MOV	CS:STACK,SP
;---------------------------------------
	CLI
	ADD	SP,0004
	POP	BP
	POP	BX
	POP	CX
	POP	DX
	POP	SI
	POP	DI
	POP	ES
	POP	DS
	MOV	SS,SAVE_SS
	MOV	SP,SAVE_SP
	MOV	AX,SAVE_FLAGS
	PUSH	AX			; INSTEAD OF PUSHF ... FOR INT
	MOV	AX,SAVE_AX
;---------------------------------------
	CALL DWORD PTR [INT_21]		; CALL ORIGINAL INT 21 ROUTINE
;---------------------------------------
	CLI
	MOV	SAVE_AX,AX
	PUSHF
	POP	AX
	MOV	SAVE_FLAGS,AX
	MOV	AX,CS
	MOV	SS,AX
	MOV	SP,STACK
	STI
;---------------------------------------
	MOV	AX,CS
	MOV	DS,AX
	MOV	ES,AX
	POP	SI
	POP	AX
	TEST	AL,0FFH
	JNZ	EXIT2
	DEC	LOGGED
	TEST	LOGGED,0FFH
	JNZ	EXIT2
;---------------------------------------
LOGIT2:
	MOV	DI,SI
	ADD	DI,0005H
	MOV	AX,SAVE_FLAGS
	PUSH	AX
	POPF
	JNC	OK
	MOV	BYTE PTR [DI],'F'
	JNZ	DOIT2
OK:	MOV	BYTE PTR [DI],'E'
DOIT2:	MOV	DI,OFFSET REPLY
	MOV	AH,0E3H
	INT	21H
;---------------------------------------
EXIT2:
	POP	BP
	POP	BX
	POP	CX
	POP	DX
	POP	SI
	POP	DI
	POP	ES
	POP	DS
   	POP	SAVE_SP
	POP	SAVE_SS
	ADD	SP,0050H
	MOV	CS:STACK,SP
	MOV	SP,SAVE_SP
	MOV	SS,SAVE_SS
	MOV	AX,SAVE_FLAGS
	PUSH	BP
	MOV	BP,SP
	MOV	[BP+6],AX
	POP	BP
	MOV	AX,SAVE_AX
	IRET
;---------------------------------------

INT_PROC	ENDP

;=======================================================================
COPYLIMIT	PROC	NEAR	; SI POINTS TO SEMAPHORE
	MOV	AH,0
	PUSH    AX		; SAVE NUMBER OF COPIES;
	MOV	DX,SI		; DX POINTS TO SEMAPHORE
	MOV	CL,0		; INITIAL SEMAPHORE VALUE
	MOV	AX,0C500H	; OPEN A SEMPHORE CALL
	INT	21H		; DO IT
	TEST	AL,0FFH
	JNZ	CERROR
	POP	AX
	CMP	AL,BL
	RET
CERROR:				; FOR ERRORS ACT AS IF EVERTHING IS OK
	CLC
	RET
COPYLIMIT	ENDP
;=======================================================================
LOAD_DATA	PROC NEAR

	;-------------------------------- Set up temporary drive letter
        PUSH	ES
	MOV	AX,CS
	MOV	ES,AX
	MOV	SI,OFFSET PATHREQ
	MOV	DI,OFFSET PATHREPLY
	MOV	AH,0E2H
	INT	21H
        TEST	AL,0FFH
	JNZ	FERROR
	;--------------------------------  Open and read file
	MOV	DX,OFFSET FILENAME
	MOV	AL,00000000B		; COMPATIBLITY MODE READ ACCESS
	MOV	AH,03DH
	INT	21H
	JC	FERROR
	MOV	BX,AX		   	; BX HOLDS FILE HANDLE
	MOV	CX,1H			; Read 1 byte for default
	MOV	DX,OFFSET DEFLOGACTION ; loggin action
	MOV	AH,03FH
	INT	21H
	MOV	CX,1000H		; READ MAXIMUM OF 4K BYTES
	MOV	DX,OFFSET LIST
	MOV	AH,03FH
	INT	21H
	JC	FCLOSE
	MOV	SI,OFFSET LIST
	MOV	CX,SI
FLOOP:
	MOV	AX,[SI]
	TEST	AX,0FFFFH
	JZ	FCLOSE
	ADD	AX,CX
	MOV	[SI],AX
	INC	SI
	INC	SI
	JMP	FLOOP
FCLOSE:
	MOV	AH,03EH		; CLOSE THE FILE
	INT	21H
	;-------------------------------- Remove temp drive
	MOV	SI,OFFSET PATHREPLY
	MOV	DI,OFFSET PATHREPLY
	MOV	AL,[SI+2]
	MOV	[SI+3],AL
	MOV	AL,14H
	MOV	[SI+2],AL
	MOV	AL,0E2H
	INT	21H
	;--------------------------------  Exit routine
FERROR:
	POP	ES
	RET

LOAD_DATA	ENDP
;=======================================================================
CEND:

CODE	ENDS

END CSTART
;O
