Metropoli BBS
VIEWER: last.asm MODE: TEXT (ASCII)
;
; $Id: last.asm 1.7 1994/12/12 17:13:55 rthomas Exp rthomas $
;
; The Press-Enterprise Co.
; 3512 Fourteenth Street
; Riverside, California 92501-3878
; (c) Copyright 1994
;
; Author: Randolph Thomas
;         rthomas@pe.com
;
; LICENCE INFORMATION
;        This program is free software; you may redistribute it and/or
;        modify it under the terms of the GNU General Public Licence
;        as published by the Free Software Foundation; either version 1
;        or (at your option) any later version.
;
;        This program is distributed in the hope that it will be useful,
;        but WITHOUT ANY WARRANTY; with even the implied warranty of
;        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;        GNU General Public Licence for more details.
;
;        You should have received a copy of the GNU General Public Licence
;        along with this program; if not, write to the Free Software
;        Foundation, Inc., 675 Mass Ave., Cambridge, MA 02139, USA.
;
; $Log: last.asm $
; Revision 1.7  1994/12/12  17:13:55  rthomas
; Added the -w option.  Fixed a bug associated with EOF.
;
; Revision 1.6  1994/12/10  00:39:57  rthomas
; Corrected the FileError reporting.
;
; Revision 1.5  1994/12/10  00:15:19  rthomas
; Added the -f option and the SkipWord() usage.
;
; Revision 1.4  1994/12/01  18:48:00  rthomas
; Recovered the source.
;
; Revision 1.3  1992/09/04  23:19:07  rthomas
; Added the -h option.
;
; Revision 1.2  1992/09/04  23:07:23  rthomas
; Added ReadToEnd on reading the end of file.
;
; Revision 1.1  1992/04/01  19:50:29  rthomas
; Initial revision
;

.MODEL	small

include	ascii.inc
include	filei.inc

LoginNote	struct
	Net	dd	?
	NodeH	dd	?
	NodeL	dw	?
LoginNote	ends

LogoutNote	struct
	Net	dd	?
	NodeH	dd	?
	NodeL	dw	?
LogoutNote	ends

E3h36h_GetBindObjName_req	struct
			dw	5
			db	036h
	ObjectID	dd	?
E3h36h_GetBindObjName_req	ends

E3h36h_GetBindObjName_rep	struct
			dw	4+2+48
	ObjectID	dd	?
	ObjectType	dw	?
	ObjectName	db	48 dup(?)
E3h36h_GetBindObjName_rep	ends

.STACK
.DATA
RcsId	db	"$Id: last.asm 1.7 1994/12/12 17:13:55 rthomas Exp rthomas $"

Warranty	db	"last - a Unix-like last program for the Novell Network",10,13
	db	"Copyright (C) 1994  Press-Enterprise Co.",10,13
	db	10,13
	db	"This program is free software; you can redistribute it and/or modify",10,13
	db	"it under the terms of the GNU General Public License as published by",10,13
	db	"the Free Software Foundation; either version 1, or (at your option)",10,13
	db	"any later version.",10,13
	db	10,13
	db	"This program is distributed in the hope that it will be useful,",10,13
	db	"but WITHOUT ANY WARRANTY; without even the implied warranty of",10,13
	db	"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the",10,13
	db	"GNU General Public License for more details.",10,13
	db	10,13
	db	"You should have received a copy of the GNU General Public License",10,13
	db	"along with this program; if not, write to the Free Software",10,13
	db	"Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.",10,13,"$"

NoteRecord	dw	?
ServerID	dd	?
TimeStamp	db	6 dup(?)
RecordType	db	?
		db	?
ServiceType	dw	?
ClientID	dd	?
CommentType	dw	?
CommentField	db	300 dup(?)

ClientIDtoMatch	dd	?		;these are used when looking for
NetToMatch	dd	?		;the matching logout record
NodeHtoMatch	dd	?
NodeLtoMatch	dw	?

NameToMatchLength	dw	0
NameToMatch		db	47 dup(0),0	;yes, login names can be 47 long

GetName_req	E3h36h_GetBindObjName_req	<>
GetName_rep	E3h36h_GetBindObjName_rep	<>

FileError	db	"last: Error opening "
FileName	db	"SYS:SYSTEM/NET$ACCT.DAT",256 dup(0)
HexTable	db	"0123456789ABCDEF"
Months		db	"Jan","Feb","Mar","Apr","May","Jun"
		db	"Jul","Aug","Sep","Oct","Nov","Dec"
LineOut		db	80 dup(0)
IllegalOption	db	"last: bad option",10,13
ErrorWithObject	db	"last: error in GetBinderyObjectName",10,13
Usage		db	"Usage:",10,13,9,"last [-f file] [-h] [-v] [-w] [name]"

.CODE
.STARTUP

	mov	ax,seg DGROUP
	mov	es,ax
	call	CheckCmdLine
	lea	si,FileName
	call	OpenFile
	jnc	ALoop
	mov	ax,seg DGROUP
	mov	es,ax
	mov	ds,ax
	mov	ah,40h
	mov	bx,1
	mov	cx,LENGTHOF FileError
	lea	si,FileName
@@:
	lodsb
	cmp	al,0
	je	@F
	inc	cx
	jmp	@B
@@:
	lea	dx,FileError
	int	21h
	.EXIT	1
ALoop:
	call	ReadRecord
	jc	DoneH
	cmp	[RecordType],02h
	jne	@F
	cmp	[CommentType],0300h	;remember, Motorola format
	jne	@F
	call	ObjectID2Name
	mov	cx,[NameToMatchLength]
	jcxz	NoCheck
	lea	si,GetName_rep.ObjectName
	lea	di,NameToMatch
	repe	cmpsb
	jne	@F
	cmp	cx,0
	jne	@F
NoCheck:
	call	PrintRecord
@@:
	jmp	ALoop
DoneH:
	call	CloseFile
.EXIT	0

;-----------------------------------------------------------------------
;Given:
;Returns:
;	Carry Set	- End of File (or perhaps an error)
;-----------------------------------------------------------------------
ReadRecord	proc USES ax bx cx di

	call	ReadNextByte
	cmp	ax,-1
	je	ReadToEnd
	mov	bh,al
	call	ReadNextByte
	cmp	ax,-1
	je	ReadToEnd
	mov	ah,bh
	mov	[NoteRecord],ax
	cmp	ax,01Eh		; is it the right length?
	je	@F
	call	SkipWord
	mov	[RecordType],0
	clc
	jmp	OuttaHere
@@:
	lea	di,ServerID
	mov	cx,ax
@@:
	call	ReadNextByte
	cmp	ax,-1
	je	ReadToEnd
	stosb
	loop	@B
	clc
	jmp	OuttaHere
ReadToEnd:
	stc
OuttaHere:
	ret

ReadRecord	endp
;-----------------------------------------------------------------------
;Given:
;Returns:
;-----------------------------------------------------------------------
PrintRecord	proc

	lea	si,GetName_rep.ObjectName
	lea	di,LineOut
	xor	cx,cx
@@:
	lodsb
	cmp	al,0
	je	@F
	inc	cx
	stosb
	jmp	@B
@@:
	cmp	cx,11
	jnb	@F
	neg	cx
	add	cx,11
	mov	al,' '
	rep	stosb
@@:
	lea	si,CommentField
	lodsw
	xchg	ah,al
	call	Bin2Hex
	lodsw
	xchg	ah,al
	call	Bin2Hex
	mov	al,':'
	stosb
	lodsw
	xchg	ah,al
	call	Bin2Hex
	lodsw
	xchg	ah,al
	call	Bin2Hex
	lodsw
	xchg	ah,al
	call	Bin2Hex
	mov	al,' '
	stosb
	lea	si,TimeStamp
	lodsb				;get year
	mov	ah,al
	cmp	al,99
	ja	@F
	mov	al,'1'
	stosb
	mov	al,'9'
	stosb
	jmp	Not19
@@:
	mov	al,'2'
	stosb
	mov	al,'0'
	stosb
Not19:
	mov	al,ah
	xor	ah,ah
	aam
	or	ax,03030h
	xchg	al,ah
	stosw
	mov	al,' '
	stosb
	lodsb				;get month
	dec	al
	xor	ah,ah
	lea	si,Months
	add	si,ax
	shl	ax,1
	add	si,ax
	lodsb
	stosb
	lodsb
	stosb
	lodsb
	stosb
	mov	al,' '
	stosb
	mov	si,offset TimeStamp + 2
	lodsb				;get day
	cmp	al,27
	jne	ToHere
	nop
ToHere:
	aam
	or	ax,03030h
	xchg	al,ah
	stosw
	mov	al,' '
	stosb
	lodsb				;get hour
	aam
	or	ax,03030h
	xchg	al,ah
	stosw
	mov	al,':'
	stosb
	lodsb				;get minute
	aam
	or	ax,03030h
	xchg	al,ah
	stosw
	call	FindLogout
	mov	al,Ascii_CR
	stosb
	mov	al,Ascii_LF
	stosb
	mov	cx,di
	sub	cx,offset LineOut
	mov	ah,040h
	mov	bx,1
	lea	dx,LineOut
	int	21h
	ret

PrintRecord	endp
;-----------------------------------------------------------------------
;Given:
;Returns:
;	Carry set	- no logout found
;	Carry clear	- logout found
;-----------------------------------------------------------------------
FindLogout	proc USES ax si
	LOCAL	DoneHere:word

	mov	DoneHere,0
	mov	ax,word ptr [ClientID]		; store the ID we'll look for
	mov	word ptr [ClientIDtoMatch],ax
	mov	ax,word ptr [ClientID+2]
	mov	word ptr [ClientIDtoMatch+2],ax
	lea	si,CommentField
	mov	ax,word ptr [si.LogoutNote.NodeH]	; store the Host too
	mov	word ptr [NodeHtoMatch],ax
	mov	ax,word ptr [si.LogoutNote.NodeH+2]
	mov	word ptr [NodeHtoMatch+2],ax
	mov	ax,word ptr [si.LogoutNote.NodeL]
	mov	[NodeLtoMatch],ax
	call	FileSetMark
BLoop:
	call	ReadRecord
	jnc	@F
	mov	DoneHere,1
@@:
	cmp	[RecordType],02h
	jne	@F
	cmp	[CommentType],0300h	;login note?
	je	CmpID
	cmp	[CommentType],0400h	;logout note?
	jne	@F
CmpID:
	mov	ax,word ptr [ClientIDtoMatch]
	cmp	ax,word ptr [ClientID]
	jne	@F
	mov	ax,word ptr [ClientIDtoMatch+2]
	cmp	ax,word ptr [ClientID+2]
	jne	@F
	lea	si,CommentField			; good, it matched the ID
	mov	ax,word ptr [NodeHtoMatch]	; now check the Host
	cmp	ax,word ptr [si.LogoutNote.NodeH]
	jne	@F
	mov	ax,word ptr [NodeHtoMatch+2]
	cmp	ax,word ptr [si.LogoutNote.NodeH+2]
	jne	@F
	mov	ax,word ptr [NodeLtoMatch]
	cmp	ax,word ptr [si.LogoutNote.NodeL]
	jne	@F
	cmp	[CommentType],0400h	;logout note?
	je	FoundLogout
	mov	DoneHere,1
	jmp	@F
FoundLogout:
	mov	al,' '
	stosb
	mov	al,'-'
	stosb
	mov	al,' '
	stosb
	lea	si,TimeStamp
	lodsb				;get year
	mov	ah,al
	cmp	al,99
	ja	Is20
	mov	al,'1'
	stosb
	mov	al,'9'
	stosb
	jmp	Not19
Is20:
	mov	al,'2'
	stosb
	mov	al,'0'
	stosb
Not19:
	mov	al,ah
	xor	ah,ah
	aam
	or	ax,03030h
	xchg	al,ah
	stosw
	mov	al,' '
	stosb
	lodsb				;get month
	dec	al
	xor	ah,ah
	lea	si,Months
	add	si,ax
	shl	ax,1
	add	si,ax
	lodsb
	stosb
	lodsb
	stosb
	lodsb
	stosb
	mov	al,' '
	stosb
	mov	si,offset TimeStamp + 2
	lodsb				;get day
	aam
	or	ax,03030h
	xchg	al,ah
	stosw
	mov	al,' '
	stosb
	lodsb				;get hour
	aam
	or	ax,03030h
	xchg	al,ah
	stosw
	mov	al,':'
	stosb
	lodsb				;get minute
	aam
	or	ax,03030h
	xchg	al,ah
	stosw
	call	FileGotoMark
	clc
	jmp	OuttaHere
@@:
	cmp	DoneHere,1
	jne	BLoop
	call	FileGotoMark
	stc
OuttaHere:
	ret

FindLogout	endp
;-----------------------------------------------------------------------
;Given:
;	ES:DI	=place to put it
;Returns:
;-----------------------------------------------------------------------
Bin2Hex	proc USES bx cx dx

	mov	dx,ax
	mov	cx,4
	xchg	al,ah
	lea	bx,HexTable
	shr	al,cl
	xlat
	stosb
	mov	ax,dx
	xchg	al,ah
	and	al,0Fh
	xlat
	stosb
	mov	ax,dx
	clc
	shr	al,cl
	xlat
	stosb
	mov	ax,dx
	and	al,0Fh
	xlat
	stosb
	ret

Bin2Hex	endp
;-----------------------------------------------------------------------
;Given:
;Returns:
;-----------------------------------------------------------------------
CheckCmdLine	proc USES ds

	mov	ah,062h			;Get PSP
	int	21h
	mov	ds,bx
	mov	si,80h
	lodsb				;get the # of characters in cmdline
	mov	cl,al
	xor	ch,ch
	jcxz	OuttaHere1
	jmp	CLoop
OuttaHere1:
	jmp	OuttaHere
CLoop:
	lodsb
	cmp	al,0Dh		;end of line?
	je	OuttaHere1
	cmp	al,' '
	jne	@F			;skip over spaces
	loop	CLoop
	jmp	OuttaHere
@@:
	cmp	al,'-'			;check if a dash option
	jne	NoDash
	dec	cx
	jcxz	ShowUsage
	lodsb
	cmp	al,'h'
	jne	@F
	jmp	ShowUsage
@@:
	cmp	al,'f'		; file option ?
	jne	@F
	jmp	FileOption
@@:
	cmp	al,'v'		; version option?
	jne	@F
	jmp	VersionOption
@@:
	cmp	al,'w'		; warranty option?
	jne	@F
	jmp	WarrantyOption
@@:
	mov	ax,seg DGROUP
	mov	ds,ax
	mov	ah,40h
	mov	bx,1
	mov	cx,LENGTHOF IllegalOption
	lea	dx,IllegalOption
	int	21h
ShowUsage:
	mov	ax,seg DGROUP
	mov	ds,ax
	mov	ah,40h
	mov	bx,1
	mov	cx,LENGTHOF Usage
	lea	dx,Usage
	int	21h
	.EXIT	2
WarrantyOption:
	mov	ax,seg DGROUP
	mov	ds,ax
	mov	ah,9
	lea	dx,Warranty
	int	21h
	.EXIT	0
VersionOption:
	mov	ax,seg DGROUP
	mov	ds,ax
	mov	ah,40h
	mov	bx,1
	mov	cx,LENGTHOF RcsId
	lea	dx,RcsId
	int	21h
	.EXIT	0
FileOption:
	lea	di,FileName
@@:
	dec	cx		;check to make sure there are more characters
	jcxz	ShowUsage
	lodsb
	cmp	al,' '
	je	@B
@@:
	call	CapAL
	stosb
	lodsb
	dec	cx
	cmp	al,' '
	je	@F
	cmp	al,Ascii_CR
	je	@F
	jcxz	OuttaHere
	jmp	@B
@@:
	mov	al,0
	stosb
	jcxz	OuttaHere
	jmp	CLoop
NoDash:
	lea	di,NameToMatch
@@:
	inc	es:[NameToMatchLength]
	call	CapAL
	stosb
	lodsb
	cmp	al,' '
	je	@F
	cmp	al,Ascii_CR
	je	@F
	loop	@B
@@:
	mov	al,0
	stosb
OuttaHere:
	ret

CheckCmdLine	endp
;-----------------------------------------------------------------------
;Given:
;Returns:
;-----------------------------------------------------------------------
ObjectID2Name	proc USES ax si di

	mov	ax,word ptr [ClientID]
	mov	word ptr [GetName_req.ObjectID],ax
	mov	ax,word ptr [ClientID+2]
	mov	word ptr [GetName_req.ObjectID+2],ax
	mov	ah,0E3h
	xor	al,al
	lea	si,GetName_req
	lea	di,GetName_rep
	int	21h
	cmp	al,0
	je	OuttaHere
	cmp	al,0FCh		; no such object?
	jne	@F
	lea	di,GetName_rep.ObjectName
	mov	al,'0'
	stosb
	mov	al,'x'
	stosb
	mov	ax,word ptr [ClientID+2]
	call	Bin2Hex
	mov	ax,word ptr [ClientID]
	call	Bin2Hex
	jmp	OuttaHere
@@:
	mov	ah,40h
	mov	bx,1
	mov	cx,LENGTHOF ErrorWithObject
	lea	dx,ErrorWithObject
	int	21h
	.EXIT	4
OuttaHere:
	ret

ObjectID2Name	endp

CapAL	proc
	cmp	al,'a'
	jb	@F
	cmp	al,'z'
	ja	@F
	and	al,0DFh			;capitalize it
@@:
	ret
CapAL	endp

END

[ RETURN TO DIRECTORY ]