
*FileTypes
*erkennt einige File-Typen in einem bestimmten Verzeichnis
*geschrieben von Sebastian Leske im November 1989
*V1.2 12./13./23. Dezember 1989
*Farbmarkierung bei Erkannt-Meldungen, Prg. arbeitet mit CD
*V1.21 30. Dezember 1989
*Arbeitet jetzt anders mit CD (keine Sonderbehandlung f. leere
*Kommandozeile), entfernt angefordertes Lock auch wieder
*V2.0 September 1990
*es können nach Wahl nur bestimmte Dateitypen ausgegeben werden,
*die Typangabe steht jetzt hinter dem Dateinamen,
*bei einem Lesefehler bricht das Programm nicht mehr ab,
*es wird die Unterroutine Kommandozeilenauswertung verwendet
*verschiedene interne Änderungen, einige Kleinigkeiten
*V2.1 1.-3. Dezember 1990
*Angabe der Programmdateilänge als Virusschutz
*Fehlerkorrektur: CurrOut v. erster Fehlermöglichkeit (unbek.
*Schlüsselbuchstabe) holen, sonst Absturz bei Fehlermeldung
*Programm an Fred FISH geschickt
 

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

*Anfangskram

	move.l	d0,ParZL		;Parameterzeile sichern...
	move.l	a0,ParZAdr		

	move.l	#0,OldCD		;Speicher f. altes CD auf Null

	move.l	#DOSName,a1		;DOS-Lib öffnen...
	moveq	#0,d0
	move.l	4,a6
	jsr	_LVOOpenLibrary(a6)
	tst.l	d0
	beq	Ende
	move.l	d0,DOSBase

	move.l	DOSBase,a6		;Output-Handle holen...
	jsr	_LVOOutput(a6)
	move.l	d0,CurrOut		;...und speichern

	jsr	PZAusw			;Parameterzeile auswerten lassen
	tst.l	d0			;Fehler bei der Auswertung ?
	bne	KAuswF			;nein, dann weiter	
	moveq.l	#3,d0			;Fehler Nr. 3...
	jsr	Fehler			;melden
	rts				;und Programm beenden

KAuswF	jsr	EtwasAusg		;testen: kein Schalter auf Ausgabe?

KEAnf	
*Auskunft gewünscht ?
	cmpi.l	#2,ParZL		;Länge der Parmzeile gleich 1 ?
	bne	DateiZugr		;nein, dann normaler Zugriff
	move.l	ParZAdr,a0		;Anfangsadresse d. Parz. holen
	cmpi.b	#"?",(a0)
	bne	DateiZugr		;nein, dann normaler Zugriff
	bra	Auskunft		;ja, dann Auskunft geben
					
DateiZugr
	lea	Par1,a0			;Adresse d. ersten Parameters holen
	move.l	Par1L,d0		;Länge holen (1. Par.=Dateiname)
	move.b	#0,0(a0,d0.l)		;Leerzeichen hinters Namensende(f.DOS)
	move.l	a0,DatName		;Zeiger auf Namen speichern
	move.l	a0,d1			;Zeiger auf Namen nach d1
	moveq	#-2,d2			;Lesezugriff
	move.l	DOSBase,a6		;DOSBase nach a6
	jsr	_LVOLock(a6)		;und auf Verzeichnis zugreifen
	tst.l	d0			;gefunden ?
	bne	VzGef			;ja, dann weiter
	moveq	#0,d0			;sonst Fehlermeldung nach d0
	jsr	Fehler			;Fehler melden
	bra	DOSzu			;und Programm beenden
VzGef	move.l	d0,DirLock		;Directory-Lock speichern
	move.l	d0,d1			;Lock nach d1
	move.l	#InfoBlock,d2		;Zeiger auf Block f. Daten nach d2
	jsr	_LVOExamine(a6)		;und Infos holen
	tst.l	d0			;Fehler aufgetreten ?
	bne	ÜbOK			;nein, dann weiter
	moveq	#0,d0			;sonst Fehlermeldung nach d0
	jsr	Fehler			;Fehler melden
	bra	DOSzu			;und Programm beenden
ÜbOK	lea	InfoBlock,a0		;Adresse d. InfoBlocks holen
	tst.l	4(a0)			;und Eintragstyp prüfen
	bpl	Dir			;Typ positiv=Unterverzeichnis

Datei1	move.l	DatName,d1		;Zeiger auf Dateinamen nach d1
	jsr	DatPrüf			;Dateityp prüfen
	bra	DOSzu			;und Programm beenden

Dir	move.l	DirLock,d1		;Directory-Lock nach d1
	jsr	_LVOCurrentDir(a6)	;und Unterdirectory=aktuelles Dir
	move.l	d0,OldCD		;vorheriges akt. Directory speichern
DirLoop	move.l	DirLock,d1		;Directory-Lock nach d1
	move.l	#InfoBlock,d2		;Adresse d. InfoBlocks holen
	jsr	_LVOExNext(a6)		;und nächsten Eintrag laden
	tst.l	d0			;noch Einträge da ?
	beq	DirEnde			;nein, dann Überprüfung beenden
	lea	InfoBlock,a0		;Adresse d. InfoBlocks holen
	tst.l	4(a0)			;und auf Unterverzeichnis prüfen
	bmi	Datei2			;kein Unterverzeichnis, dann weiter
	tst.b	DirS			;Schalter prüfen: U.verz. ausgeben?
	beq	VznAusg			;nein, dann zum Schleifenende
	jsr	NamAusg			;Namen ausgeben lassen
	move.l	CurrOut,d1		;Ausgabe-Handle nach d1
	move.l	#DirText,d2		;zu schreibender Text nach d2
	move.l	#12,d3			;Textlänge nach d3
	jsr	_LVOWrite(a6)		;und Verzeichnis-Kennung ausgeben
VznAusg	bra	DirLoop			;und weiter lesen

Datei2	move.l	#InfoBlock,d1		;Adresse d. InfoBlocks holen
	add.l	#8,d1			;Zeiger auf Eintragsnamen nach d1,
	jsr	DatPrüf			;Dateityp prüfen
	bra	DirLoop			;und nächsten Eintrag lesen

DirEnde	jsr	_LVOIoErr(a6)		;Fehlernummer holen
	cmpi.l	#232,d0			;Fehler No_More_Entries ?
	beq	DOSzu			;ja, dann weiter
	moveq	#2,d0			;sonst Fehlermeldung nach d0
	jsr	Fehler			;Fehler melden
	bra	DOSzu			;und Programm beenden

DOSzu	move.l	DOSBase,a6
	move.l	OldCD,d1		;altes aktuelles Verzeichnis holen
	tst.l	d1			;wurde es überhaupt abgespeichert?
	beq	KOldCD			;nein, dann weiter
	jsr	_LVOCurrentDir(a6)	;sonst wieder setzen
KOldCD	move.l	DirLock,d1		;Lock holen
	tst.l	d1			;Lock da ?
	beq	DZ			;nein, dann weiter
	jsr	_LVOUnLock(a6)		;sonst Lock entfernen	
DZ	move.l	DOSBase,a1		;DOS-Library schließen...
	move.l	4,a6
	jsr	_LVOCloseLibrary(a6)
Ende	rts				;und ENDE


*Auskunft über das Programm geben
Auskunft
	move.l	DOSBase,a6		;DOSBase nach a6
	move.l	CurrOut,d1		;Ausgabe-Handle nach d1
	move.l	#AuskunftText,d2	;zu schreibender Text nach d2
	move.l	AuskunftTextL,d3	;Textlänge nach d3
	jsr	_LVOWrite(a6)		;und Auskunfts-Text ausgeben
	bra	DOSzu			;Programm beenden

*Fehler melden
Fehler
	asl.l	#3,d0			;Fehlernr. *8 (wg. Offsetgebrauch)
	lea	FTabelle,a0		;Adresse der Tabelle f. FMeldungen
	move.l	0(a0,d0.l),d2		;Fehlertextadresse nach d2
	move.l	4(a0,d0.l),d3		;Textlänge nach d3
	move.l	DOSBase,a6		;DOSBase nach a6
	move.l	CurrOut,d1		;Ausgabe-Handle nach d1
	jsr	_LVOWrite(a6)		;und Fehlermeldung ausgeben
	rts				;wieder zurück

*Prüfen, ob kein Typ ausgegeben werden soll; wenn ja, alle auf
*Ausgabe setzen
EtwasAusg
	tst.b	DirS			;die drei Schalter für Verzeichnisse,
	bne	EtwGes			;unbekannte Dateien und IFF-Dateien
	tst.b	UnbS			;prüfen; wenn einer auf Ausgeben
	bne	EtwGes			;steht, beenden
	tst.b	IFFS
	bne	EtwGes
	lea	PrüfTabelle,a0		;Adresse d. Prüftabelle holen
PrüSchl	tst.l	20(a0)			;Schalter f. Ausgabe auf 1?
	bne	EtwGes			;ja, dann beenden
	adda.l	#24,a0			;Zeiger auf nächsten Eintrag
	tst.l	0(a0)			;Tabelle zu Ende?
	bne	PrüSchl			;nein, dann nächsten Eintrag bearbeiten

	move.b	#1,DirS			;Alle Schalter auf Ausgabe:
	move.b	#1,UnbS
	move.b	#1,IFFS
	lea	PrüfTabelle,a0		;Adresse d. Prüftabelle holen
SetSchl	move.l	#1,20(a0)		;Schalter f. Ausgabe auf 1
	adda.l	#24,a0			;Zeiger auf nächsten Eintrag
	tst.l	0(a0)			;Tabelle zu Ende?
	bne	SetSchl			;nein, dann nächsten Eintrag bearbeiten
EtwGes	rts				;und zurück

*Datei öffnen und Typ prüfen
DatPrüf
	move.l	#1005,d2		;Modus=Lesen aus bestehender Datei
	jsr	_LVOOpen(a6)		;und Datei öffnen
	tst.l	d0			;Fehler aufgetreten ?
	bne	ÖffnOK			;nein, dann weiter	
	moveq	#1,d0			;Fehlermeldung nach d0
	jsr	Fehler			;und Fehler melden...
	rts				;und Auswertung abbrechen
ÖffnOK	move.l	d0,DatHand		;Handle der Datei speichern
	move.l	d0,d1			;Datei-Handle nach d1
	move.l	#DateiPuffer,d2		;Zeiger auf Puffer nach d2
	move.l	#50,d3			;Anzahl der zu lesenden Zeichen
	jsr	_LVORead(a6)		;und in den Puffer lesen
	tst.l	d0			;Fehler aufgetreten ?
	bpl	LesOK			;nein, dann weiter
	jsr	NamAusg			;Dateinamen ausgeben
	moveq	#1,d0			;Fehlermeldung nach d0
	jsr	Fehler			;und Fehler melden...
	move.l	DatHand,d1		;Datei-Handle nach d1
	jsr	_LVOClose(a6)		;und Datei wieder schließen
	rts				;und Auswertung abbrechen
LesOK	lea	DateiPuffer,a0		;Zeiger auf Puffer nach a0
	jsr	CheckDat		;prüfen auf bekanntes Format
	move.l	DOSBase,a6
	move.l	DatHand,d1		;Datei-Handle nach d1
	jsr	_LVOClose(a6)		;und Datei wieder schließen
DatEnd	rts				;und Rückkehr

*Prüfen, ob Dateianfang im Puffer zu einer IFF-Datei gehört
CheckIFF
	moveq	#1,d0			;Rückgabewert für "IFF-Datei"
	cmpi.b	#"F",0(a0)		;Beginnt die Datei mit "FORM" ?
	bne	NoIFF			;Nein, dann ist es keine IFF-Datei
	cmpi.b	#"O",1(a0)		;
	bne	NoIFF			;
	cmpi.b	#"R",2(a0)		;
	bne	NoIFF			;
	cmpi.b	#"M",3(a0)		;
	bne	NoIFF			;
	rts				;Es ist eine IFF-Datei; zurück
NoIFF	moveq	#0,d0			;Rückgabewert für "keine IFF-Datei"
IFFDat	rts				;und zurück
	
*Auf bekannte Dateitypen (incl. IFF) prüfen
CheckDat
	lea	PrüfTabelle,a1		;Zeiger auf Tabelle nach a1
PrüLoop	move.l	(a1),a2			;Zeiger auf gesp. Daten nach a2
	cmp.l	#0,a2			;nichts mehr zu vergleichen ?
	beq	TestIFF			;dann abbrechen
	move.l	4(a1),d1		;Länge der gesp. Daten nach d1 
	move.l	a0,a3			;Anfang des Dateipuffers nach a3
	add.l	8(a1),a3		;Lage der zu vergl. Daten nach a3
Vergl	move.b	0(a3,d1.l),d0		;Byte aus Puffer nach d0
	cmp.b	0(a2,d1.l),d0		;mit gesp. Daten vergleichen
	bne	Ungl			;falls ungleich, Vergleichen beenden
	sub.l	#1,d1			;nächstes Byte
	tst.l	d1			;Fertig ?
	bne	Vergl			;nein, dann weiter vergleichen

	tst.l	20(a1)			;soll Typ ausgegeben werden?
	beq	TnAusg			;nein, dann Ausgabe überspringen
	move.l	a1,-(sp)		;a1 zwischenspeichern
	jsr	NamAusg			;Dateinamen ausgeben
	move.l	(sp)+,a1		;a1 zurückholen
	move.l	CurrOut,d1		;gefundenen Typ ausgeben:
	move.l	12(a1),d2		;Zeiger auf Text
	move.l	16(a1),d3		;Textlänge
	jsr	_LVOWrite(a6)		;und Typ ausgeben
TnAusg	rts				;Rückkehr

Ungl	add.l	#24,a1			;nächster Eintrag
	bra	PrüLoop			;und vergleichen
TestIFF	bsr	CheckIFF		;auf IFF-Datei testen
	tst.l	d0			;Rückgabewert=0 ?
	beq	Unbek			;ja, dann auch keine IFF-Datei
	tst.b	IFFS			;IFF-Dateien aufführen?
	beq	kIFF			;nein, dann nichts ausgeben
IFFTest	move.l	a0,a1			;Zeiger auf Dateipufferanf. kopieren
	add.l	#12,a1			;Zeiger +12 (Ende der Typkennung)
	lea	IFFLücke,a2		;Zeiger auf Lücke im Ausgabetext
	moveq	#3,d0			;Schleifenzähler auf 3
IFFloop	move.b	-(a1),-(a2)		;und Kennung...
	dbra	d0,IFFloop		;...kopieren
	jsr	NamAusg			;Dateinamen ausgeben
	move.l	CurrOut,d1		;gefundenen Typ ausgeben:
	move.l	#IFFText,d2		;Zeiger auf Text
	move.w	#IFFTextE-IFFText,d3	;Textlänge
	jsr	_LVOWrite(a6)		;und Typ ausgeben
kIFF	rts				;Rückkehr

Unbek	tst.b	UnbS			;unbekannte Dateien aufführen?
	beq	KUnbek			;nein, dann nichts ausgeben
	jsr	NamAusg			;Dateinamen ausgeben
	move.l	CurrOut,d1		;Ausgabe-Handle nach d1
	move.l	#UnbekText,d2		;zu schreibender Text nach d2
	move.l	#20,d3			;Textlänge nach d3
	jsr	_LVOWrite(a6)		;und Auskunfts-Text ausgeben
KUnbek	rts				;und Rückkehr

*Eintragsnamen ausgeben und Zeile bis in Spalte 30 auffüllen
NamAusg	lea.l	InfoBlock,a5		;Adresse d. InfoBlocks holen
	add.l	#8,a5			;Zeiger auf Eintragsnamen nach a5,
	move.l	a5,a0			;und nach a0
LZähl	tst.b	(a0)+			;End-Nullbyte gefunden ?
	bne	LZähl			;nein, dann weiterzählen
	sub.l	#1,a0			;Zähler korrigieren
	suba.l	a5,a0			;und Namenslänge ausrechnen
	move.l	a0,d4			;Namenslänge zwischenspeichern
	move.l	CurrOut,d1		;aktuelle Ausgabe setzen
	move.l	a0,d3			;Textlänge setzen
	move.l	a5,d2			;Textadresse setzen
	move.l	DOSBase,a6
	jsr	_LVOWrite(a6)		;und Eintragsnamen ausgeben
	move.l	#30,d3			;so viele Leerzeichen fehlen noch...
	sub.l	d4,d3			;bis Spalte 30
	move.l	#LeerZ,d2		;Textadresse setzen
	move.l	CurrOut,d1		;aktuelle Ausgabe setzen
	jsr	_LVOWrite(a6)		;und Zeile auffüllen
	rts				;und zurück


*CLI-Parameterzeilen-Auswertung V1.0
*wertet CLI-Parameter im Format Befehl Parameter1 aParameter2  
*bParameter3 cParameter4 etc. aus
*geschrieben von Sebastian Leske im 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)
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
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


***Unterprogramme***
*der PZ-Auswertung

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 "Konnte nicht auf Directory/Datei zugreifen.",10
	dc.b "Stimmt der Pfadname?",10
FT2	dc.b "Kann nicht aus dieser Datei lesen!",10
FT3	dc.b "Fehler aufgetreten beim Auslesen des Directory!",10
FT4	dc.b "Unbekannter Kennbuchstabe in der Parameterzeile!",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] [a 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 "Dieses Programm ist frei kopierbar!",10
	dc.b "Länge der Programmdatei: 2476 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

;Tabellenformat (alles LW): 
;Zeiger auf zu vergleichende Daten,
;Länge derselben minus 1, Lage derselben in der Datei,
;Zeiger auf auszugebenden Text mit Typbeschreibung, Länge des Textes,
;Langwort das entscheidet, ob Typ ausgegeben wird

aP	dc.l $3F3

aPText	dc.b $9B,"0;32;40m"
	dc.b "Ausführbares Programm.",10
	dc.b $9B,"0;31;40m"
aPTE

IFFText	dc.b "IFF-Datei, Typ ",$9B,"0;33;40m" 	;4 Bytes Lücke zum Ein-
	ds.b 4					;setzen der Typkennung
IFFLücke dc.b ".",$9B,"0;31;40m",10
IFFTextE

UnbekText	dc.b "Dateityp unbekannt.",10

	cnop 0,4

KennLis	
	dc.w "d"			;Kennbuchstabe
	dc.l PZDir			;Adresse des entsprechenden UPs
	dc.w "a"
	dc.l PZaP
	dc.w "u"
	dc.l PZUnb
	dc.w "i"
	dc.l PZIFF
	dc.w 0				;Ende der Liste

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
		
*Schalter für ausgeben/nicht ausgeben
DirS	ds.b 1
UnbS	ds.b 1
IFFS	ds.b 1

