Das Cookie-Jar-Prinzip

Neben dem mittlerweile etablierten XBRA-Protokoll, das wir Ihnen im vorherigen Artikel vorgestellt haben, existiert seit TOS 1.6 (STE) der Cookie-Jar (die Keksdose). Dabei handelt es sich um eine Informationsstruktur. Mit ihrer Hilfe kann man verschiedene rechnerabhängige Informationen erhalten bzw. Informationen mit anderen Programmen austauschen.

Der Cookie-Jar befindet sich irgendwo im Speicher des Rechners. Auf seine Startadresse zeigt die Systemvariable _p_cookies (Adresse: $5A0). Die einzelnen Kekse (Cookies) bestehen aus zwei 32-Bit-Werten (Im ATARI-Slang ist Cookie ein gebräuchlicher Terminus für eine 32 Bits große Codenummer). Der erste Wert stellt die Cookie-Kennung (cookie_id\ siehe Bild 1) dar. Der zweite Wert ist abhängig vom jeweiligen Cookie (siehe Tabelle 1).

Da der Cookie-Jar erst ab TOS 1.6 vom Betriebssystem automatisch installiert (und beim Reset wieder gelöscht) wird, muß er bei früheren Versionen von einem residenten Programm installiert werden.

Die Theorie

Wenn man mit Cookies arbeiten will, muß man als erstes einmal nachsehen, ob es sie überhaupt gibt. Steht in der Systemvariablen j>_cookies ein NULL-Zeiger, bedeutet dies, daß (noch) kein Cookie-Jar installiert ist. Hat man einen Zeiger bekommen, kann man die Tabelle gezielt nach einem Cookie durchsuchen, um entsprechende Informationen zu erhalten, einen neuen Cookie einzutragen oder einen Eintrag zu löschen.

Sie fragen sich, was für einen Sinn solch eine Tabelle hat? Nun, zum einen erhält man einige wichtige Informationen über die Rechnerkonfiguration (siehe nochmal Tabelle 1), und zum zweiten kann man anderen Programmen mitteilen, ob ein bestimmtes Programm installiert ist. Dazu sollte, wie beim XBRA-Verfahren, dieCookie-ID individuell sein. Bei der Namensgebung sind drei Punkte zu beachten:

  1. Die Kennung darf nicht mitbeginnen; dies hat sich ATARI für eigene Cookies reserviert.
  2. Die vier Zeichen müssen ASCII-Zeichen (Code zwischen 32 und 126; keine Sonderzeichen) sein.
  3. Die Kennung sollte eine Abkürzung ergeben, mit deren Hilfe man auf das Programm schließen kann.

Wie bereits bei der XBRA-Bezeichnung, wird auch beim Cookie-Jar von Julian Reschke eine Liste der bereits verwendeten IDs geführt.

Im Langwort cookie_value kann eine beliebige Information abgelegt werden, z.B. ein Zeiger auf eine interne Programmstruktur [über die andere Programme beispielsweise bestimmte Betriebsparameter verstellen können (dies ist beim Mausbeschleuniger MACCEL3 der Fall)], auf einen Text oder sonst etwas; der Phantasie sind hier keine Grenzen gesetzt!

Es versteht sich natürlich von selbst, daß die Bedeutung von cookie_value irgendwo dokumentiert sein sollte! (Was nützt schon ein Eintrag, wenn man nicht weiß, wozu er zu gebrauchen ist?)

Die Aufmerksamen unter Ihnen werden jetzt wahrscheinlich fragen, wieviele Cookies denn eigentlich in den Jar hineinpassen? Diese Frage kann nicht pauschal beantwortet werden, da der Speicherbereich, auf den _p_cookies verweist, ja an beliebiger Stelle im Speicher steht und somit irgendwann mittels Malloc (oder einer ähnlichen Funktion) angefordert wurde - die Größe des Jars ist also variabel!

Um aber trotzdem das Ende der Tabelle erkennen zu können, existiert ein sogenannter NULL-Cookie (ID: $00000000), der als Wert die maximale Anzahl der in den Jar reinpassenden Cookies enthält. Außerdem ist er der letzte der aktuellen Cookie-Liste.

Die Praxis

Soweit die Theorie. Schauen wir uns einige Beispiele an, die die Nützlichkeit dieses Verfahrens noch einmal unterstreichen sollen. Besonders wichtig (im Hinblick auf portable Programmierung) ist es z.B., festzustellen, ob ein bestimmtes Programm auf einem normalen ST, einem getuneten Rechner (etwa mit einem 68020-Prozessor) oder gar auf dem TT läuft. Dank der vom BIOS installierten System-Cookies [erst ab TOS 1.6; vorher muß selbst installiert werden (siehe Programm auf der Diskette)] ist es nun kein Problem mehr, festzustellen, auf welchem Rechner-Typ und mit welchem Prozessor das Programm läuft.

Aufgrund der außerordentlichen Nützlichkeit dieses Verfahrens bot es sich an, einige Hilfsroutinen zu schreiben, die den Umgang mit Cookies erleichtern sollen. Diese finden Sie, neben einem Beispiel, auf den Disketten zum Heft. Das Beispiel demonstriert einen Anwendungsfall von Cookies: Wie kann ein Programm feststellen, ob es sich bereits installiert hat? Einige der im Listing verwendeten Funktionen stammen aus dem Cookie-Modul; in der Praxis dürfte es sich als nützlich erweisen, dieses Modul getrennt zu übersetzen und in einer ‘LIB’-Datei festzuhalten. Bei einer Programmentwicklung wird dann diese Datei automatisch vom Projektmanager an den Linker weitergereicht...

Die Implementierung

Kommen wir aber zu den eigentlichen Hilfroutinen des Moduls. Sie übernehmen die wichtigsten Operationen, die beim Umgang mit Cookies auftreten können (Erzeugen, Einträgen, Abfragen, Löschen etc.).

Ein neuer Cookie kann ganz einfach mit Hilfe der Funktion create_cookie() erstellt werden; man übergibt dieser dazu lediglich einen Zeiger auf eine COOKIE-Struktur, die Programmmkennung (cookiejd) sowie den Wert des Cookies (longl). Der so erzeugte Cookie kann mittels new_cookie in den hoffentlich vorhandenen Cookie-Jar eingetragen werden.

Mit Hilfe von get_cookieQ kann überprüft werden, ob ein bestimmter Cookie bereits im System vorhanden ist (Return-Wert = TRUE); in diesem Fall wird auch gleich der zugehörige Wert in der Variablen value mitgeliefert.

Das Löschen von Cookies (das kann beispielsweise dann notwendig sein, wenn das Programm, das diesen installiert hat, sich wieder aus dem Speicher entfernen will) übernimmt die Funktion remove_cookie(). Gelöscht wird übrigens einfach dadurch, daß - nachdem die Cookie-ID gefunden wurde, alle folgenden Cookies (einschließlich des abschließenden NULL-Cookies) eine Position nach oben verrückt werden.

move_cookiejar() ermöglicht es, den kompletten Jar an eine neue Speicherstelle zu kopieren (der zweite Parameter gibt dabei die evtl, neue Größe des Jars an), und cookie_size() liefert die Größe des Jars, d.h. die Anzahl der maximal in ihn hineinpassenden Cookies. Zu guter Letzt kann der Inhalt des gesamten Cookie Jars noch mittels print_cookie() auf die Standardausgabeeinheit ausgegeben werden.

Aufruf: create_cookie(cookie, id, value)

Funktion: initialisiert einen Cookie

Parameter: cookie: Zeiger auf COOKIE-Struktur
id: (ASCII-)Kennzeichnung des Cookies (vier Zeichen)
value: Wert des Cookies

Rückgabewert: keiner

Aufruf: new_cookie (entry)

Funktion: trägt neuen Cookie in den Jar ein

Parameter: entry: Zeiger auf einzutragenden Cookie

Rückgabewert: TRUE, wenn ok: FALSE im Fehlerfall

Aufruf: get_cookie(id, value)

Funktion: liefert den Wert eines Cookies

Parameter: id: (ASCII-)Kennzeichnung des Cookies (vier Zeichen)
value: Zeiger für Wert des Cookies

Rückgabewert: TRUE, wenn ok; FALSE, wenn Cookie nicht existiert

Aufruf: remove_cookie(id)

Funktion: entfernt einen Cookie

Parameter: id: (ASCII-)Kennzeichnung des Cookies (vier Zeichen)

Rückgabewert: TRUE, wenn ok; FALSE, wenn Cookie nicht existiert

Aufruf: move_cookiejar(dest, size)

Funktion: verschiebt kompletten Jar an neue Speicherstelle; evtl. Vergrößerung der Anzahl der möglichen Einträge

Parameter: dest: neue Adresse für Jar
size: neue Größe des Jars

Rückgabewert: keiner

Aufruf: cookie_size()

Funktion: liefert die Anzahl der maximal möglichen Einträge in den installierten Jar

Parameter: keine

Rückgabewert: Anzahl der maximal möglichen Cookies

Aufruf: print_size()

Funktion: gibt Inhalt des Jars aus Standardausgabe aus

Parameter: keine

Rückgabewert: keiner

typedef struct {
	char cookie_id[4];	/*	Cookie-Kennung	- 4 ASCII-Zeichen */ 
	long cookie_value; /* Wert des Cookies */ 
} COOKIE;

Bild 1: Die Cookie-Struktur in C

ID Bedeutung
_CPU Prozessortyp: Die Werte 0,10, 20, 30 und 40 stehen für die Prozessoren 68000,68010,68020,68030 und 68040.
_FPU FPU-Typ: das obere Wort gibt Auskunft über das Vorhandensein eines Floating-Point-Koprozessors und über die Unterstützungsart des Betriebssystems bei Fließkommazahlenrechnung:

Bit 0: gesetzt wenn FPU-Zusatzkarte (z.B. SFP 004 von ATARI) vorhanden ist; 68881 als Peripheriebaustein (ST und STE)

Bit 1+2: Koprozessortyp (68881 oder 68882):

0: weder noch

1: 68881 oder 68882 (Typ unbekannt)

2:68881 3: 68882 Bit 3: gesetzt wenn 68040

__FRB Fast-RAM-Buffer (TT): Zeiger auf einen 64-KByte-Puffer im ST-RAM, der als Zwischenspeicher beim normalen ACSI-DMA-Transfer dient.

_MCH Maschinentyp; das obere Wort bezeichnet die Rechnerfamilie

0: ST (520ST, 1040ST oder Mega ST)

1: STE (1040 STE und Mega STE)

2: TT

_SND Soundhardware:

Bit 0 gesetzt, wenn ‘normaler’ Soundchip (Gl/Yamaha) vorhanden

Bit 1 gesetzt, wenn Stereo-DMA-Chip vorhanden (STE und TT)

_SWI DIP-Switch: Werte des internen DIP-Schalters, sofern vorhanden

_VDO Video-Hardware: Das obere Wort beschreibt die Art der Video-Hardware:

0: ST 1: STE 2: TT

Außer den bisher aufgeführten Cookies, die ab TOS1.6 automatisch installiert werden, verwendet ATARI folgende weitere Cookies:

_FDC Informationen über Floppy-Controiler. Oberstes Byte erteilt Auskunft über die maximale Schreibdichte:

0: normal (720 KB) 1: High-Density (1,44 MB) 2: Extra High Density (2,88 MB)

Die unteren drei Bytes sind eine Herstellerkennung.

_FLK GEMDOS verfügt über FILE-LOCKING-Erweiterungen; Wert ist Versionsnummer der Erweiterung

JNF STEFIX (Patch-Programm für TOS 1.06) ist installiert

_NET GEMDOS-Netzwerkerweiterung; Wert ist ein Zeiger auf die Herstellerkennung und -versionsnummer

_OOL POOLFIX3 (Patch-Programm für GEMDOS 0.15) ist installiert

_SLM Diablo-Treiber für SLM-Laserdrucker ist installiert

Tabelle 1: Die System-Cookies


Rolf Kotzian
Aus: ST-Computer SH / 1992, Seite 16

Links

Copyright-Bestimmungen: siehe Über diese Seite