
*FileTypes
*written by Sebastian Leske November 1989
 

	incdir ":Include/"
	include "libraries/dos_lib.i"
	include "exec/exec_lib.i"

*Anfangskram

	move.l	d0,ParZL		
	move.l	a0,ParZAdr		

	move.l	#0,OldCD		

	move.l	#DOSName,a1		
	moveq	#0,d0
	move.l	4,a6
	jsr	_LVOOpenLibrary(a6)
	tst.l	d0
	beq	Ende
	move.l	d0,DOSBase

	move.l	DOSBase,a6		
	jsr	_LVOOutput(a6)
	move.l	d0,CurrOut		

	jsr	PZAusw			
	tst.l	d0			;error while processing command line?
	bne	KAuswF			
	moveq.l	#3,d0			;yes, error #3
	jsr	Fehler			;report error and end prg
	rts				

KAuswF	jsr	EtwasAusg		;no key character set?
					;if so, set all

KEAnf	
*Info requested?
	cmpi.l	#2,ParZL		
	bne	DateiZugr	
	move.l	ParZAdr,a0	
	cmpi.b	#"?",(a0)
	bne	DateiZugr	
	bra	Auskunft		;yes, give info and exit
					
DateiZugr
*Access file/directory
	lea	Par1,a0			;Par1=adress of 1st parameter
	move.l	Par1L,d0		;on command line (set by my comm.
	move.b	#0,0(a0,d0.l)		;line processor (PZAusw))
	move.l	a0,DatName		
	move.l	a0,d1			
	moveq	#-2,d2			
	move.l	DOSBase,a6		
	jsr	_LVOLock(a6)		
	tst.l	d0			;entry found?
	bne	VzGef			
	moveq	#0,d0			
	jsr	Fehler			;no: report error
	bra	DOSzu			;& exit
VzGef
*entry found
	move.l	d0,DirLock		
	move.l	d0,d1			
	move.l	#InfoBlock,d2		
	jsr	_LVOExamine(a6)		
	tst.l	d0			;check for error etc.
	bne	ÜbOK		
	moveq	#0,d0		
	jsr	Fehler		
	bra	DOSzu			
ÜbOK	lea	InfoBlock,a0		
	tst.l	4(a0)			
	bpl	Dir			;type positive=directory

Datei1
*1st parameter is a file
	move.l	DatName,d1		
	jsr	DatPrüf			;check type of file&print it
	bra	DOSzu			;exit

Dir
*1st parameter is a directory
	move.l	DirLock,d1		
	jsr	_LVOCurrentDir(a6)	;set specified directory as CD
	move.l	d0,OldCD		
DirLoop	move.l	DirLock,d1		
	move.l	#InfoBlock,d2		
	jsr	_LVOExNext(a6)		;next entry
	tst.l	d0			
	beq	DirEnde			;none left -> exit
	lea	InfoBlock,a0		
	tst.l	4(a0)			;a subdirectory?
	bmi	Datei2			
	tst.b	DirS			
	beq	VznAusg			;if Dir-switch not set, skip dir
	jsr	NamAusg			;print name of dir
	move.l	CurrOut,d1		
	move.l	#DirText,d2		
	move.l	#12,d3			
	jsr	_LVOWrite(a6)		;write "*Directory*"
VznAusg	bra	DirLoop			;go get next entry

Datei2
*we've found a file
	move.l	#InfoBlock,d1		
	add.l	#8,d1			
	jsr	DatPrüf			;check type of file & print it
	bra	DirLoop			;next entry

DirEnde	jsr	_LVOIoErr(a6)
	cmpi.l	#232,d0			;error No_More_Entries ?
	beq	DOSzu			
	moveq	#2,d0			
	jsr	Fehler			
	bra	DOSzu			

DOSzu	move.l	DOSBase,a6
	move.l	OldCD,d1		;set old CD if it was changed
	tst.l	d1			
	beq	KOldCD			
	jsr	_LVOCurrentDir(a6)	
KOldCD	move.l	DirLock,d1		
	tst.l	d1			
	beq	DZ			
	jsr	_LVOUnLock(a6)		
DZ	move.l	DOSBase,a1		
	move.l	4,a6
	jsr	_LVOCloseLibrary(a6)
Ende	rts				;THE END


*give Info (quick reference)
Auskunft
	move.l	DOSBase,a6		
	move.l	CurrOut,d1		
	move.l	#AuskunftText,d2	
	move.l	AuskunftTextL,d3	
	jsr	_LVOWrite(a6)		
	bra	DOSzu			

*report error
Fehler
	asl.l	#3,d0			
	lea	FTabelle,a0		
	move.l	0(a0,d0.l),d2		
	move.l	4(a0,d0.l),d3		
	move.l	DOSBase,a6		
	move.l	CurrOut,d1		
	jsr	_LVOWrite(a6)		
	rts				

*Test: if no key characters are set, print all types (set switches
*for all types)
EtwasAusg
	tst.b	DirS			
	bne	EtwGes			
	tst.b	UnbS			
	bne	EtwGes			
	tst.b	IFFS
	bne	EtwGes
	lea	PrüfTabelle,a0		
PrüSchl
*test loop
	tst.l	20(a0)			;switch set to output?
	bne	EtwGes			
	adda.l	#24,a0			
	tst.l	0(a0)			;end of table?
	bne	PrüSchl			

	move.b	#1,DirS			
	move.b	#1,UnbS
	move.b	#1,IFFS
	lea	PrüfTabelle,a0		
SetSchl
*loop to set all output switches to output
	move.l	#1,20(a0)		;set switch to output
	adda.l	#24,a0	
	tst.l	0(a0)	
	bne	SetSchl	
EtwGes
*at least one key character was found to be set
	rts				;und zurück

*open file and check type
DatPrüf
	move.l	#1005,d2		
	jsr	_LVOOpen(a6)	
	tst.l	d0		
	bne	ÖffnOK		
	moveq	#1,d0		
	jsr	Fehler		
	rts			
ÖffnOK
*no error while opening
	move.l	d0,DatHand		;read first 50 bytes of file
	move.l	d0,d1			
	move.l	#DateiPuffer,d2		
	move.l	#50,d3			
	jsr	_LVORead(a6)		
	tst.l	d0		
	bpl	LesOK		
	jsr	NamAusg		
	moveq	#1,d0		
	jsr	Fehler		
	move.l	DatHand,d1	
	jsr	_LVOClose(a6)	
	rts			
LesOK	lea	DateiPuffer,a0		
	jsr	CheckDat		;check first 50 bytes
	move.l	DOSBase,a6
	move.l	DatHand,d1	
	jsr	_LVOClose(a6)	
DatEnd	rts			

*check: are contents of buffer an IFF file?
CheckIFF
	moveq	#1,d0			;
	cmpi.b	#"F",0(a0)		;
	bne	NoIFF			;
	cmpi.b	#"O",1(a0)		;
	bne	NoIFF			;
	cmpi.b	#"R",2(a0)		;
	bne	NoIFF			;
	cmpi.b	#"M",3(a0)		;
	bne	NoIFF			;
	rts				;
NoIFF	moveq	#0,d0			;return value for "no IFF"
IFFDat	rts				;
	
*check for known types
CheckDat
	lea	PrüfTabelle,a1		
PrüLoop	move.l	(a1),a2			
	cmp.l	#0,a2			;end of table of known types?
	beq	TestIFF			;if so, maybe it's an IFF
	move.l	4(a1),d1	
	move.l	a0,a3		
	add.l	8(a1),a3		
Vergl
*loop: compare one known type with file contents
	move.b	0(a3,d1.l),d0		
	cmp.b	0(a2,d1.l),d0
	bne	Ungl		
	sub.l	#1,d1		
	tst.l	d1		
	bne	Vergl			

	tst.l	20(a1)			;switch for type set?
	beq	TnAusg			;no, don't print anything
	move.l	a1,-(sp)	
	jsr	NamAusg			;print file name
	move.l	(sp)+,a1	
	move.l	CurrOut,d1	
	move.l	12(a1),d2	
	move.l	16(a1),d3		
	jsr	_LVOWrite(a6)		;print type description
TnAusg	rts				

Ungl	add.l	#24,a1			;next entry from table of known
					;types
	bra	PrüLoop			

TestIFF	bsr	CheckIFF		;is it an IFF?
	tst.l	d0			
	beq	Unbek			;no, then we don't know it
	tst.b	IFFS			;if switch for IFF not set,
	beq	kIFF			;don't print anything
IFFTest	move.l	a0,a1			
	add.l	#12,a1			
	lea	IFFLücke,a2		
	moveq	#3,d0			
IFFloop	move.b	-(a1),-(a2)		;copy IFF type (ILBM, 8SVX etc.)
	dbra	d0,IFFloop		;into type description
	jsr	NamAusg			
	move.l	CurrOut,d1		
	move.l	#IFFText,d2		
	move.w	#IFFTextE-IFFText,d3	
	jsr	_LVOWrite(a6)		;print type description
kIFF	rts			

Unbek
*couldn't identify file
	tst.b	UnbS			;switch for unknown files set?
	beq	KUnbek		
	jsr	NamAusg		
	move.l	CurrOut,d1	
	move.l	#UnbekText,d2	
	move.l	#20,d3			
	jsr	_LVOWrite(a6)		;print "Filetype unknown."
KUnbek
*don't mention unknown file
	rts				

*print name of file/directory and pad with spaces upto column 30
NamAusg	lea.l	InfoBlock,a5		
	add.l	#8,a5			
	move.l	a5,a0			
LZähl	tst.b	(a0)+			
	bne	LZähl			
	sub.l	#1,a0			
	suba.l	a5,a0			
	move.l	a0,d4			
	move.l	CurrOut,d1		
	move.l	a0,d3			
	move.l	a5,d2			
	move.l	DOSBase,a6
	jsr	_LVOWrite(a6)		;print name of file/directory
	move.l	#30,d3			;how many spaces to pad upto
	sub.l	d4,d3			;column 30?
	move.l	#LeerZ,d2		
	move.l	CurrOut,d1		
	jsr	_LVOWrite(a6)		;print pad spaces
	rts				


*CLI command line processing V1.0
*command line must be:Command Parameter1 aParameter2 bParameter3
*cParameter4 dParameter5 etc. aus
*written by Sebastian Leske August/September 1990

PZAusw	move.l	ParZAdr,a6		;Zeiger auf Anf d. P.zeile in a6
	move.l	a6,d7
	add.l	ParZL,d7		;Endadresse d. Zeile ausrechnen
	subq.l	#1,d7			;Endadresse korr. (wg. CR am Ende)

* 1. Parameter kopieren (ggf. diesen Teil streichen)
*copy 1st parameter (1st parameter has no key character)
LZSpr1	cmpi.b	#32,(a6)+		;Leerzeichen?
	beq	LZSpr1			;ja: weiterlesen
	subq	#1,a6			;Anf.adresse korrigieren
	cmp.l	d7,a6			;Ende der Eingabe erreicht ?
	bge	AEnde			;ja, dann beenden
	lea	Par1,a0			;Pufferadresse holen
	jsr	ParKop			;Parameter in Puffer kopieren
	move.l	d0,Par1L		;Länge des 1. Parameters speichern
**??**	jsr	Par1Bearb		;1. Par. bearbeiten lassen
	cmp.l	d7,a6			;Ende der Eingabe erreicht ?
	bge	AEnde			;ja, dann beenden
	
* restliche Parameter (mit Kennbuchstaben) holen
* get the other parameters
ParSu
LZSpr2	cmpi.b	#32,(a6)+		;Leerzeichen ?
	beq	LZSpr2			;ja: weiterlesen
	subq	#1,a6			;Anf.adresse korrigieren
	cmp.l	d7,a6			;Ende der Eingabe erreicht ?
	bge	AEnde			;ja, dann beenden
	move.b	(a6),d0			;gefundenes Zeichen nach d0
**??**	bclr.l	#5,d0			;Umwandlung in Großbuchstaben
	lea	KennLis,a0		;Adr. d. Kennbuchstabenliste holen
SuchAP	tst.w	(a0)			;Listenende erreicht?
	beq	PZFehler		;ja -> Fehler
	cmp.w	(a0)+,d0		;Zeichen aus Liste vergleichen
	beq	KennGef			;Kennbuchstabe gefunden
	addq.l	#4,a0			;Zeiger auf nächstes Zeichen setzen
	bra	SuchAP			;weitersuchen
KennGef	move.l	(a0),a5			;Adresse d. zuständigen UPs holen
	lea	Par,a0			;Pufferadresse holen
	jsr	ParKop			;Parameter kopieren
	move.l	d0,ParL			;Länge des Parameters speichern
	jsr	(a5)			;AuswertungsUP aufrufen
	cmp.l	d7,a6			;Ende der Eingabe erreicht ?
	bge	AEnde			;ja, dann beenden
	bra	ParSu			;und nächstes Parameter suchen

AEnde	moveq.l	#-1,d0			;kein Fehler aufgetreten (für's HP)
	rts				;und ENDE


***subprogrammes***
*for command line processing

ParKop	move.l	#" ",d5			;Standardtrennzeichen=Leerzeichen
	cmpi.b	#34,(a6)		;1. Zeichen=Anführungszeichen?
	bne	KAnfz			;Nein
	move.l	#34,d5			;ja, Trennzeichen=Anführungszeichen
	addq.l	#1,a6			;und Zeiger auf nächstes Zeichen
KAnfz	moveq	#-1,d0			;Längenz. auf 0 (-1 wg. Aufbau d. Schleife)
KopP	move.b	(a6),(a0)+		;Byte in Puffer kopieren
	addq.l	#1,d0			;mitzählen...
	cmp.l	d7,a6			;Ende der Eingabe erreicht?
	bge	ParAE			;ja, dann Ende
	cmp.b	(a6)+,d5		;Trennzeichen erreicht?
	bne	KopP			;nein, dann weiter kopieren		
ParAE	rts				;und wieder zurück

PZFehler
	clr.l	d0			;0 nach d0 heißt Fehler (für's HP)
	rts				;und ENDE

PZDir	move.b	#1,DirS
	rts

PZaP	move.l	#1,PrüfTabelle+20
	rts

PZUnb	move.b	#1,UnbS
	rts

PZIFF	move.b	#1,IFFS
	rts

***Daten-Bereich***
	SECTION DATA,DATA

DOSName	dc.b "dos.library",0

FT1	dc.b "Could not access directory/file.",10
	dc.b "Is the pathname correct?",10
FT2	dc.b "Can't read from this file!",10
FT3	dc.b "Error while examining directory!",10
FT4	dc.b "Unknown key character in command line!",10
FTEnde
	cnop 0,4
FTabelle
	dc.l FT1,FT2-FT1
	dc.l FT2,FT3-FT2
	dc.l FT3,FT4-FT3
	dc.l FT4,FTEnde-FT4

AuskunftText
	dc.b "FileTypes [Directoryname|Dateiname] [e i d u]",10
	dc.b "FileTypes V2.1",10
	dc.b "© by Sebastian Leske",10
	dc.b "Bergerhauserstr.17a, D-4300 Essen 1",10
	dc.b "This programme may be freely distributed.",10
	dc.b "Length of this executable: 2436 Bytes.",10
	cnop 0,4
AuskunftTextL	dc.l *-AuskunftText

DirText		dc.b "*Directory*",10

	cnop 0,4
PrüfTabelle	dc.l	aP,3,0,aPText,aPTE-aPText,0
		dc.l	0			;Endkennung

;format of table (only LWs): 
;pointer to data that must be compared to recognize type
;lenght of that data, its position in the file (0=at the very beginning)
;pointer to text with type description, length of that text,
;switch for output or no output (set by prg, must be zero)

aP	dc.l $3F3

aPText	dc.b $9B,"0;32;40m"
	dc.b "Executable file.",10
	dc.b $9B,"0;31;40m"
aPTE

IFFText	dc.b "IFF file, type ",$9B,"0;33;40m" 	
	ds.b 4					
IFFLücke dc.b ".",$9B,"0;31;40m",10
IFFTextE

UnbekText	dc.b "Filetype unknown.",10

	cnop 0,4

KennLis	
	dc.w "d"			;key character
	dc.l PZDir			;subprg to be called if it's speci-
	dc.w "e"			;fied in the command line
	dc.l PZaP
	dc.w "u"
	dc.l PZUnb
	dc.w "i"
	dc.l PZIFF
	dc.w 0				; end of list

LeerZ	dc.b "                             "

***Platzbedarfs-Bereich***
	SECTION SPACE,BSS
DOSBase	ds.l 1
ParZAdr	ds.l 1
ParZL	ds.l 1
CurrOut	ds.l 1
DirLock	ds.l 1
OldCD	ds.l 1
DatName	ds.l 1
DatHand	ds.l 1
TestFl	ds.l 1

InfoBlock	ds.l 260

DateiPuffer	ds.b 50

Par1	ds.b 256		;Speicher für erstes Parameter
Par1L	ds.l 1			;dessen Länge

Par	ds.b 256		;Zwischenspeicher für sonstige Parameter
ParL	ds.l 1			;deren jeweilige Länge
		
*switches for print type/don't print type
DirS	ds.b 1
UnbS	ds.b 1
IFFS	ds.b 1

