
 
PlugIns fr GEMAR 																			 Steffen Engel 1992-94

25.05.94


ALLGEMEINES

	In dieser Datei werden alle ntigen Informationen zu PlugIns gegeben, der 
	aktuelle Stand der von GEMAR installierten PlugIn-Calls, die Liste der aktuell 
	existierenden PlugIns und der aktuelle Stand der PlugIns und ihrer 
	Programmierung.

	Die mit GEMAR gelieferten PlugIns sind grundstzlich alle deaktiviert, indem
	die Namen mit PLX enden.

	Bitte beurteilen Sie selbst, welche PlugIns fr Sie sinnvoll sind.


WAS SIND PLUGINS?

	Um GEMAR mit weiteren Fhigkeiten auszustatten, wurde ein Konzept entworfen, 
	mit dem externe Programme als Erweiterung hinzugeladen werden knnen.

	Dabei wird von GEMAR an bestimmten Stellen einfach kontrolliert, ob ein zu 
	diesem Zweck gehrendes PlugIn existiert, und ruft es gegebenenfalls auf.

	Grundstzlich wurde das Konzept relativ einfach gehalten, da es dadurch 
	einerseits einfach zu verstehen und programmieren ist und andererseits kein 
	vollstndig modulares Programmierungssystem entworfen werden sollte.

	Mit diesem Konzept sind nur kleine Erweiterungen oder Ersetzungen von Teilen 
	von GEMAR mglich.

	PlugIns sind vor allem dann sinnvoll, wenn kleine Erweiterungen an GEMAR 
	gemacht werden sollen, die fr bestimmte Probleme sinnvoll sind, aber zu 
	speziell sind, um allgemein in GEMAR eingebaut zu werden.

	PlugIns werden von GEMAR grundstzlich im Ordner PLUGIN im GEMAR-Pfad
	gesucht.


AUFBAU UND PROGRAMMIERUNG VON PLUGINS

	PlugIns werden grundstzlich als Pozeduren aufgerufen. Als Methode wurde ein
	hnlicher Weg gewhlt wie bei CPX-Modulen.

	Zur Identifikation tragen PlugIns zur Zeit einen 512-Byte langen Kopf:

	TYPE tPlugHead
				= RECORD
						Magic 			: lCARDINAL;							(* 'Plug' *)
						Identify		: ARRAY[0..19] OF CHAR; 	(* Kontrolle fr Programm *)
						SlotIdent 	: ARRAY[0..19] OF CHAR; 	(* Identifikation fr Verwendung *)
						Info				: ARRAY[0..467] OF CHAR;	(* Beschreibung *)
					END;

	Identify dient dabei dazu, zu erkennen, ob dieses Plugin berhaupt fr das
	laufende Programm ist. Bei Gemar mu Identify immer 'Gemar' sein.
	SlotIdent dient zur Erkennung, ob das PlugIn fr den Slot geeignet ist.
	Dies dient als Schutz, da zB ein Plugin fr die Index-Bearbeitung nicht
	fr SCSI-Routinen eingeklinkt wird.


	PlugIns werden geladen und danach wird der Rumpf des PlugIns mit einem Zeiger
	auf folgende Struktur aufgerufen:

	tPlugEnvironment
		= RECORD
				(* aktuelle Parameterversion = 1.00 = 0100H *)
				Version  : sINTEGER;													(* Version zeigt Umfang der Parameter an	 *)
				Private  : ADDRESS; 													(* spezielle Parameter fr den Rumpf			 *)
				ApplId	 : sINTEGER;													(* Applikationsid des rufenden Programmes  *)
				VDIHandle: sINTEGER;													(* Workstation des Hauptprogrammes				 *)
				PlugPath : POINTER TO ARRAY[0..512] OF CHAR;	(* Name und Pfad des PlugIn, kann auch
																												 relativ sein 													 *)
				Alert 	 : PROCEDURE((* def *) sINTEGER, VAR (* msg *) STRING) : sINTEGER;
			END;

	In C sieht das entsprechend so aus:

	typedef struct
		{
			int 	Version;
			void	*private;
			int 	ApplId;
			int 	VDIHandle;
			char	*PlugPath;
			int 	(*Alert) (int defbutt, char *msg);
		} PLUGPARMS;


	Die Struktur wird grundstzlich abwrtskompatibel sein, d.h. bei erweiterten 
	Versionen kommen zustzliche Parameter hinzu und die Versionsnummer wird 
	erhht.

	Nach einer evtl. ntigen Initialisierung (zB Abfragen, ob das Modul berhaupt 
	aktiviert werden soll) mu das PlugIn mit einem Zeiger auf eine Tabelle
	von Funktionen antworten:

	TYPE	tpPlugProcs = POINTER TO tPlugProcs;
				tPlugProc 	= PROCEDURE((* par : *) ADDRESS) : lINTEGER;
				tPlugProcs	= RECORD
												num : SHORTINT; 				(* Anzahl der Funktionen *)
												Procs : ARRAY[0..07FFFH] OF tPlugProc;
											END;

	Ein Null-Zeiger zeigt an, da das PlugIn nicht aktiviert werden soll (oder
	bereits fertig ist).

	Diese Funktionen werden dann zur eigentlichen Verwendung ein- oder mehrmals
	aufgerufen. Als Parameter wird ein Zeiger bergeben, der auf die zu 
	bearbeitenden Daten zeigt.

	Bitte beachten Sie, da UNBEDINGT aller Speicher bei der Deinitialisierung 
	des PlugIns freigegeben wird, da der Speicher nicht durch das Freigeben des
	PlugIn freigeben wird!

	Die Aufforderung zur Deinitialisierung erfolgt durch Aufruf der Funktion 0
	mit -1 (0FFFFFFFFH) als Parameter.

	Als Beispiel sollten Sie sich die beiliegenden PlugIns ansehen, insbesondere
	PLUGPARM.D

PARAMETER IN GEMAR

	Als Standardstruktur wird von GEMAR in private ein Zeiger auf die folgende
	Struktur bergeben:

	TYPE tPlugPrivate = RECORD
											Version : SHORTCARD;		(* = 0200H = 2.00 *)
											special : ADDRESS;			(* Spezielles fr Art des PlugIn *)
											StrHandle : SHORTCARD;
											StrMaxLen : LONGCARD;
											BlockLen: SHORTCARD;		(* Blocklnge des Streamers *)
											ScsiIn	: PROCEDURE ((* ScsiCmd *) tpScsiCmd) : SHORTINT;
											ScsiOut : PROCEDURE ((* ScsiCmd *) tpScsiCmd) : SHORTINT;
											SuperOn 	: PROC;
											SuperOff	: PROC;
										END;
								
										In C sieht das so aus:
								
										typedef struct
											{
												unsigned word version;
												void *special;
												word strhandle;
												long strmaxlen;
												word blocklen;
												word (*ScsiIn)	(SCSIPARMS *Parms);
												word (*ScsiOut) (SCSIPARMS *Parms);
												void (*SuperOn) ();
												void (*SuperOff) ();
											} tScsiCall;

			 tScsiCmd 	= RECORD
											handle			: SHORTCARD;		(* das handle des Gertes *)
											Cmd 				: ADDRESS;			(* Zeiger auf CmdBlock *)
											CmdLen			: SHORTCARD;		(* Lnge des Cmd-Block *)
											Buffer			: ADDRESS;			(* Datenpuffer				 *)
											TransferLen : LONGCARD; 		(* bertragungslnge	 *)
											SenseBuffer : ADDRESS;			(* Puffer fr ReqSense (18 Bytes) *)
											Timeout 		: LONGCARD; 		(* Timeout in 1/200 sec *)
											Flags 			: BITSET; 			(* Bitvektor fr Ablaufwnsche *)
										END;
			 tpScsiCmd	= POINTER TO tScsiCmd;

										Return-Werte fr ScsiIn und ScsiOut sind:
								
										NOSCSIERROR 		= 	0; (* Kein Fehler 																 *)
										SELECTERROR 		=  -1; (* Fehler beim Selektieren 										 *)
										STATUSERROR 		=  -2; (* Default-Fehler															 *)
										PHASEERROR			=  -3; (* ungltige Phase 														 *)
										BSYERROR				=  -4; (* BSY verloren																 *)
										BUSERROR				=  -5; (* Busfehler bei DMA-bertragung 							 *)
										TRANSERROR			=  -6; (* Fehler beim DMA-Transfer (nichts bertragen) *)
										FREEERROR 			=  -7; (* Bus wird nicht mehr freigegeben 						 *)
										TIMEOUTERROR		=  -8; (* Timeout 																		 *)
										DATATOOLONG 		=  -9; (* Daten fr ACSI-Softtransfer zu lang 				 *)
										LINKERROR 			= -10; (* Fehler beim Senden des Linked-Command (ACSI) *)
										TIMEOUTARBIT		= -11; (* Timeout bei der Arbitrierung								 *)
										PENDINGERR			= -12;
								
										Werte > 0 sind das Statusbyte des SCSI-Gertes (siehe SCSI-Norm)

	 ACHTUNG!!!
	 BlockLen kann sich whrend des Betriebes von GEMAR ndern und ist nur gltig,
	 wenn ein Band geladen ist!!

	 special ist dabei ein Spezial-Parameter fr das PlugIn, der von der Art des
	 PlugIn abhngt.
	 Dieser Parameter ist _NUR_ whrend der Initialisierung des PlugIn gltig und
	 mu daher getrennt von der private-Struktur gesichert werden!!

	 Es reicht, den Zeiger zu sichern, da die Struktur auf die special zeigt,
	 nicht flchtig ist.

EXISTIERENDE PLUGINS

	Zur Zeit existieren fnf PlugIn-Slots:
	-REQSENSE przisiert die Fehlermeldungen des Streamers, die in den Request 
						Sense Daten bergeben werden.
	-INDEX		wird nach jedem Backup aufgerufen und kann entweder den Inhalt eines
						Bandes ausdrucken, oder in eine Datei schreiben.
						Darin knnen INDEX.PLG und SCANINDEX.PLG eingesetzt werden.
	-SCANINDE wird beim Indexscanning aufgerufen. Damit kann eine Datei auf einem 
						Band gesucht werden.
						Darin knnen INDEX.PLG und SCANINDEX.PLG eingesetzt werden.
	-SCSI 		Wird bei allen SCSI-Befehlen gerufen und kann damit Anpassungen an
						exotische Streamer durchfhren.
						Darin knnen die folgenden Plugins eingesetzt werden:
						-SPACE.PLG	wird bei Space-Operationen des Streamers gerufen, um
												ein modifziertes Spacing durchzufhren
						-QFA.PLG		wird bei eingeschaltetem Quick File Access fr die
												Funktionen benutzt.
												Dabei ist egal, welche Art eingeschaltet ist (Seek oder
												Locate)
	-Index-Import Wird bei unbekanntem Band-Header gerufen. Damit sind Restores
						von GEMAR-fremden Bndern mglich.

	SCANINDE und INDEX besitzen gleiche Aufrufe, da heit, Sie knnen INDEX.PLG 
	in SCANINDE.PLG umbenennen und damit per 'Scannen' nachtrglich den Inhalt des 
	Bandes in eine Datei schreiben lassen.


EXISTIERENDE PLUGIN-AUFRUFE


	1. Namentliche installierte PlugIns:


	-INDEX.PLG:
		Aufruf		: Nach einem Backup
		Name			: INDEX.PLG
		Anzahl		: 1  (Laden nach Name)
		SlotIdent : 'Index'
		Prozeduren: 2 Prozeduren fr Aufruf
								1. Prozedur : Der Call bekommt Zeiger auf Index-Eintrge,
															jeweils einen Ordner alphabetisch durchlaufen,
															danach den nchsttieferen Ordner.
															Auf dieser Basis wre zB ein Exporter in eine
															Datenbank mglich.
															bergebene Struktur: s. INDEX.M
								2. Prozedur 	Zeiger auf den Index-Header.
															Ein Aufruf zeigt an, da ein neuer Index gelesen
															wurde und der Header mit den Daten gefllt ist.

	-SCANINDEX.PLG:
		Aufruf		: bei Index-Scanning
		Name			: SCANINDE.PLG
		Anzahl		: 1  (Laden nach Name)
		SlotIdent : 'Index'
		Prozeduren: 2 Prozeduren fr Aufruf, wie INDEX
								retour = 1 bricht Scanning ab und whlt den aktuellen Index


	2. Typbasiert installierte PlugIns:

	-REQSENSE:
		Aufruf		: Nach einem Scsi-Fehler (Check Condition auf Streamerzugriff).
		Anzahl		: 1
		SlotIdent : 'REQSENSE'
		Prozeduren: 1 Prozedur fr Aufruf
		Parameter : Zeiger auf Request-Sense-Daten, die vorher vom SCSI-Gert geholt 
								wurden.
		Antwort 	: Zeiger auf einen (nullterminierten) String, der in die Alertbox 
								eingesetzt wird ('Check Condition(%s)')

	-SCSI:
		Aufruf		: Wird bei allen SCSI-Kommandos gerufen
		Anzahl		: 1
		SlotIdent : 'SCSI'
		Prozeduren: 2 Prozeduren fr Aufruf
								1. Prozedur ist SCSIIn
								2. Prozedur ist SCSIOut
		Parameter : Zeiger auf die ScsiStruktur
		Bemerkung : Aufruf im Supervisor-Modus!

	-Index-Import:
		Aufruf		: Wird bei unbekanntem Band-Header gerufen
		Anzahl		: frei
		SlotIdent : 'Index-Import'
		Bemerkung : Dokumentation nur fr Programmierer von Importern.



	Weitere Aufrufe richte ich gerne ein, Ideen sind immer willkommen.



HISTORY

17.07.94
	-Umstellung auf den Header vor dem PlugIn
	-Umstellung der private-Parameter.

20.12.94
	-Umstellung auf Slotbasierte PlugIns

Steffen Engel
		
	
	