[Allegro] srch32 und includes im Datenbankverzeichnis - und Nachladungen

Thomas Berger ThB at Gymel.com
Mi Okt 17 12:42:15 CEST 2012


Lieber Herr Eversberg, lieber Herr Eger, liebe Liste,

Am 17.10.2012 09:27, schrieb Bernhard Eversberg:
> Am 17.10.2012 09:02, schrieben A. Eger und T. Berger:
>>
>>> Und fuer /alle/ Faelle solcherart mit
>>> explizitem Pfad angegebener Parameterdateien sollte ein sinnvolles
>>> Verhalten fuer die (implizite) Suche nach Includetabellen definiert
>>> und dann auch implementiert werden, sonst bleibt das an sich gute
>>> neue Feature ein unbewohnbarer Rohbau.
>>> ...
> Ja gut, aber wer definiert das jetzt mal? Damit wir nicht am Bedarf vorbei
> programmieren.

Ich will einmal versuchen das zu analysieren:

Das bisherige Verhalten ist, dass in der Reihenfolge Datenverzeichnis (D),
Arbeitsverzeichnis (W) und dann Programmverzeichnis (P) gesucht wird.

Und seit es die "universellen" Parameterdateien gibt, wird zuerst nach
Includes mit passender Extension .cPT gesucht, anschliessend in einer zweiten
Runde nach den universellen mit Extension . at PT. Korrekt?

Es gibt fuer gewisse Dateiarten Abweichungen von dieser Regel (fuer welche?),
fuer Export- oder Indexparameterdateien und -tabellen gilt sie aber m.W.
uneingeschraenkt, allerdings ist die gestern wieder in Erinnerung gerufene
Irritation zu beachten, dass das in Aufrufen genutzten Datenbankverzeichnis
nicht unbedingt das Datenverzeichnis (D) ist: Das war bei zweistufigen
Exporten ("Cockpit-Listenproduktion") schon immer ein Problem, denn die
erste Stufe exportiert aus der Datenbank und in deren Verzeichnis (D) liegende
Parameterdateien sind die staerksten, die zweite Stufe exportiert aus der
typischerweise im Arbeitsverzeichnis liegenden Zwischendatei, dabei ist dann
(D') = (W) und statt in (D) liegenden Includetabellen werden solche aus (P)
genommen.

SRCH.EXE bzw. srch32.exe unterscheiden sich hier zwangslaeufig im Verhalten
von acon bzw. a99: Letztere benoetigen stets eine existierende Datenbank
um ueberhaupt zu starten, daraus (bei acon also doch implizit aus dem mit
Schalter -b uebergebenen Pfad!) ergibt sich m.E., dass (D) invariant ist
und nicht dem Pfad einer Offlinedatei entspricht (Export erfolgt ohnehin
entweder aus der Datenbank oder anhand eines Einzelsatzes im Arbeitsspeicher,
wie der zustande kam ist aufgrund der feineren Steuerung in Flex- und Job-
sprache eher egal. Man /koennte/ also darueber nachdenken, ob srch das
Datenverzeichnis (D) nicht doch primaer ueber den optionalen Parameter
-b bestimmen sollte, das wuerde aber den Unterschied zu index, qrix und
import vergroessern und m.E. auch inkompatibel zu frueheren Nutzungen sein
(m.E. hat srch32 in V32.7 "direkt" das 16bit SRCH.EXE ersetzt: Win64-
Nutzer mussten zwar schon seit Jahren auf acon -jsrch.job ausweichen,
das war dann aber eher individuell und womoeglich mit entsprechenden
Tests verbunden, jedenfalls sind mir keine Meldungen hier erinnerlich,
die auf den gerade herausgearbeiteten fundamentalen Unterschied bezueglich
(D) beim Uebergang /auf/ die acon-Loesung hindeuteten. Herrn Egers Meldung
scheint ja eher dem Uebergang zurueck zu srch geschuldet zu sein?)

N.B.: Srch.exe greift - wenn ueberhaupt - nur wegen einiger weniger
Parameter (il, i0, i5? und i6) auf die zur per -b angegebenen Datenbank
gehoerende Indexparamteterdatei zu, und m.W. ohne irgendwelche
t-Befehle auszuwerten. Daher ist es fuer srch egal, dass ein vollstaendiges
Laden der .cPI-Datei eine Festlegung bezueglich (D) benoetigen wuerde.


Ein in einem acon-Job in der ersten Zeile mit "& ..." angegebenes "Virtuelles
Aufrufverzeichnis" tritt anstelle des Programmverzeichnisses (P), [warum auch
immer: Namensnennung sowie Nutzung von "WorkDir" in den acon-Quellen zeigen
m.E., dass es einmal anders war oder zumindest anders intendiert. Das ist hier
aber nicht interessant]

Das eigentliche Arbeitsverzeichnis ist im avanti-Kontext der acon-Nutzung
oft eher unklar, aber invariant und typischerweise ohne Schreiberlaubnis.
In a99 (acon wohl nicht?) laesst es sich allerdings mittels "set W" waehrend
der Sitzung (ggfls. auch mehrfach) aendern.

Anforderungen:

1. Angabe eines expliziten Pfads von Parameterdateien auf der Kommandozeile
   ist sinnvoll, sowohl absolut als auch relativ.

1a. Da der Pfadtrenner sowohl "\" als auch "/" sein kann (sein duerfen soll ;-)
   (fuer Win32. Unter U**X nur "/") gibt es bei den traditinellen Schaltern -e
   einen Konflikt, da (optional?) mit "/" (bzw. "+", da ist dann kein Konflikt)
   die Ausgabedatei benannt wird (da sind auch Pfade erlaubt, mit Ruecksicht
   auf die Aufrufzeilenbegrenzung auf 126 Zeichen in 16bit-Umgebungen wurde
   das aber immer sehr sparsam gehandhabt).
   Abhilfe sollte durch Einfuehrung eines Alternativzeichens ("!", "=", ...)
   einfach moeglich sein

1b. wie relative Pfade aufzufassen sind, muesste definiert werden. "Kein Pfad"
   als Extremfall unterlag ganz klar der klassischen Reihenfolge (D), (W), (P),

2. Unter Flex/Job-Kontrolle mit "export param" geladene Parameterdateien
   sollten analogen Regeln unterliegen (bei srch.job und update.job stammen
   die Angaben zu Parameterdateien ja aus srch.exe bzw. update.exe
   nachgebildeten Schaltern).
   [xexport.rtf spricht noch vom "Namen" der Parameterdatei, m.W. sind hier
   aber durchaus bereits Pfade erlaubt]

2a. /Denkbar/ waere allerdings, Pfade (auch) als relativ zu dem Verzeichnis (J)
   aufzufassen, aus dem die gerade abgearbeitete Flex- bzw. Jobdatei geladen
   wurde: Der Fall, dass aufeinander abgestimmte Flex- und Parameterdateien
   eine funktionale Einheit bilden, ist ja nicht selten und durch Isolation
   ein einem eigenen Verzeichnis spart man sich Klimmzuege beim Finden
   von Namen, die auch zukuenftig nie in Konflikt stehen werden mit Namen,
   die sich irgendjemand anderes ausdenken wird...
   [Bei Jobuebergabe per STDIN wie insbesondere im Avanti-Kontext entfaellt
   das natuerlich bzw. es sollten Arbeits- bzw. Programmverzeichnis hilfsweise
   eintreten?]

2b. Aufgepasst: Flex- und Jobdateien haben selber Includes (bei deren Suche
   aehnliche Regeln gelten bzw. gelten sollten), und es kann vorkommen,
   dass eine Parameterdatei geladen wird in einem Abschnitt, der aus einem
   in einem anderen Verzeichnis als der Original-Flex residierenden Include
   stammt. Die Parameterdatei wird aber - und da ist der Unterschied zu
   den Flex-Includes - zur Laufzeit geladen und selbst bei Buchfuehrung
   darueber, woher welche Zeile der Flexdatei stammt wissen wir nicht, ob
   Pfad und oder Name der zu ladenden Parameterdatei nicht in einem ganz
   anderen Abschnitt grundlegend bestimmt wurde. Die genauere Buchfuehrung
   macht also nicht in allen Situationen mehr Sinn und daher meinte ich
   bei 2a. auch wirklich nur *die* (Haupt-)Flex- oder Jobdatei die
   beim Aufruf angegeben wurde.

2c. Bei vorgegebener Reihenfolge (D), (W), (C) gibt es also vier Moeglichkeiten,
   solch einen relativen Wurzelpfad (J) mit ins Spiel zu bringen


3. Ueber t-Befehle in Parameterdateien eingebundene "Parameterabellen"
   erlauben m.W. inzwischen auch
   i. die Angabe von Pfaden
   ii. die Angabe von Extensions
   iii. Schachtelung
   ich habe das allerdings nie selbst getestet und weiss auch nicht, ob das
   in den diversen Modulen so einheitlich ist, dass Nutzung verlaesslich wird.

3a. Bei 1. und 2. werden Aufrufe / Einbindungen dynamisch aus Umgebungen (Shell
   bzw. Flex/Jobsprache) getaetigt, die Kenntnis ueber die Rahmenbedingungen
   erlangen koennen (vorzugsweise durch Zugriff aufs Environment oder Auslesen
   irgendwelcher Dateien). Da koennen durchaus absolute Pfade von Parameter-
   dateien entstehen, die haargenau passen. Bei Include-Tabellen (und auch
   den include-Befehlen der Flex-/Jobsprache) ist der Fall fundamental anders:
   Die Dateien werden nicht umgeschrieben, die Einbindung erfolgt vorab zur
   Ladezeit des "Eltern"-Objekts. Absolute Pfade machen da m.E. ueberhaupt
   keinen Sinn, es sei denn, es gaebe elaborierte Installationsroutinen,
   die beim Abwerfen der Dateien ins Dateisystem irgendwelche Pfade im
   Quelltext der Parameter- und Flexdateien fixieren.

3b. Relative Pfade machen natuerlich umso mehr Sinn, auch hier wieder die
   Ueberlegung, ob nicht das Verzeichnis (T) der einbindenden Parameterdatei
   als eine Alternative fuer die Verankerung relativer Pfade mit ins Spiel
   soll, und - anders als bei Parameterdateien, die aus Jobs geladen werden -
   dabei ist (T) im Fall von Verschachtelungen jeweils der tatsaechliche
   Ort, von dem die /unmittelbar einbindende/ Parameterdatei oder -tabelle
   gerade geladen wird (fuer diese einfache Rekursion zur Ladezeit muss man
   kein Array preallozieren, das geht mit einem rekursiven Unterprogramm-
   aufruf, Limit ist da die Stackgroesse der Laufzeitumgebung oder evtl. die
   maximale Anzahl gleichzeitig offener Dateideskriptoren, ueber eine
   Konstante kann man da ein Soft-Limit definieren, ab dem kurz vor dem
   Crash eine Warnung ausgegeben wird: Wenn die Rekursion Level 1000 erreicht
   hat, wird es allmaehlich unwahrscheinlich, dass sie je zu einem Ende kommt
   ;-)

3c wie 2c: Bei vorgegebener Reihenfolge (D), (W), (C) gibt es also vier
   Moeglichkeiten, solch einen relativen Wurzelpfad (T) mit ins Spiel zu bringen

4. Klar ist, dass es nie Konflikte gibt, wenn ein gewisser Parameterdatei-
   name ohnehin nur ein einziges Mal in den relevanten Verzeichnissen
   vorkommt: Da geht es "nur" darum, diese Datei auch zuverlaessig zu
   finden.

5. These: Ein vernuenftiger Mechanismus, der solche Einbindungswurzelpfade
   (J) und (T) unterstuetzt, reduziert die Notwendigkeit, Kopien von
   Parameterdateien (unter gleichem oder anderen Namen) anzulegen.


Kompatiblitaetsueberlegungen:

Der "Cockpit-Listendruck"-Mechanismus beruht darauf, gewisse Dateien (aus
dem Programmverzeichnis) unter fixem Namen ins Arbeitsverzeichnis zu
kopieren. Also p-xy.apr bindet printer.apt ein, das ist aber eine kurz
zuvor (?) erzeugte Kopie von p-blabla.apt. Es gibt "im Feld" aber
moeglicherweise auch Varianten, die direkt p-xy.apr laden und dadurch
auf printer.apt /in einem anderen Verzeichnis/ angewiesen sind. Und
es gibt vermutlich auch Installationen, die im Programmverzeichnis
eine "harmlose" printer.apt als Fallback anbieten, falls der Anwender
vergessen hat, im Arbeitsverzeichnis eine printer.apt abzuwerfen: Hier
muesste also (W) Praeferenz vor dem Einbindungswurzelverzeichnis (T)
bzw. (J) haben.

In Installationen mit mehreren Datenbanken sind oft datenbankspezifische
Teile (Ueberschriftszeilen, bestimmte Vorgabetexte) in Includetabellen
ausgelagert, die sich unter einem standardisierten Namen im Datenbank-
verzeichnis befinden. Eingebunden werden sie jedoch von Parameterdateien,
die sich im Programmverzeichnis befinden (etwa d-wrtf.apr). Konflikte
koennen auch hier entstehen, wenn eine "Default"-Version der Tabellen
im Programmverzeichnis vorgehalten wird. Umgekehrt ist die .api-Datei
typischerweise oft identisch (nur mit anderem Namen) und wird im
Daten(bank)verzeichnis (D) vorgehalten, nutzt aber fuer Umcodierungs-
tabellen Includes, die nur im Programmverzeichnis liegen.

Damit scheinen mir nur die Varianten
A: (D), (W), (T/J), (P)
B: (D), (W), (P), (T/J)
eine kompatible Erweiterungsmoeglichkeit des Bestehenden darzustellen,
es sei denn,
a) man will eine kompliziertere Logik einfuehren, die untersucht, ob (T)
   bzw. (J) irgendwie identisch mit (D), (W), (P) ist und sich dann
   "konventioneller" verhaelt [Pfadvergleiche sind i.A. extrem schwierig,
   in diesem Fall jedoch machbar, weil (T) und (J) ja irgendwo bestimmt
   wurden und zu dem Zeitpunkt gewusst wird, ob auf (D), (W), (P)
   zurueckgegriffen wird. Andererseits: "../demo2/cat" trifft in der
   Standardinstallation (D) auf wenig offensichtliche Weise...
b) man realisiert eine "Weiche": Direkte Einbindungen des Namens
   verhalten sich absolut konventionell, erst Notation mit mindestens
   einem Pfadtrenner, also etwa
t./foo
   bringt (T) ins Spiel. (Aber wie kommt (J) ins Spiel, also Pfade
   von Includedateien relativ zum im Aufruf explizit angegebenen Pfad der
   Parameterdatei?)

Umgekehrt scheint mir, dass (T) bzw. (J) eine sehr hohe Praeferenz
haben sollten (genau so funktioniert das Web: da beziehen sich *alle*
relativen Pfade *nur* auf die URL der bereits erfolgreich lokalisierten
unmittelbaren Ueberordnung), d.h. ein "Paket" zusammengehoerender
Dateien sitzt in einem Verzeichnis fuer sich, Einbindung/Lokalisierung
einer "Master"-Datei fuehrt dazu, dass die "zugehoerenden" automatisch
und zweifelsfrei von dort genommen werden, nur fuer fehlende (wie etwa
o.apt oder ggfls. nur . at pt-Dateien) gibt es Fallback-Orte. Nach dieser
Logik waeren eigentlich nur die oben bereits ausgeschlossenen Faelle
C: (T/J), (D), (W), (P)
D: (D), (T/J), (W), (P)
akzeptabel, da nuetzlich.


Sicherheit:
Wir hatten das vor einigen Jahren diskutiert, anschliessend war a99 mit
access <= 3 kaum noch benutzbar ;-): Eine (eigentlich sinnlose) Einbindung
include /etc/passwd
oder
t../../../var/log/irgendwas
kann einem Angreifer in Form von Fehlermeldungen alles moegliche "leaken",
was er eigentlich nicht zu sehen bekommen sollte. Ich stelle mir vor,
dass das allerdings nur acon betrifft (solange wir keine remote-Version
von a99 oder flex.exe haben) und hier in der .conf-Datei ein Filter
definiert werden sollte: Da wird ein (oder mehrere?) Wurzelpfade
definiert und jeglicher Versuch, eine Datei ausserhalb der dadurch
angegebenen Teilbaeume zu oeffnen wird abgeschmettert. (D) kann ja
implizit dazu genommen werden, (P) und (W) nicht, da ueber "&" oder
sonstwie im Job tendenziell setzbar.


Zwischenstand:
Die Anforderungen Kompatibilitaet (erlaubt nur Varianten A und B) und
Zusatznutzen (Varianten C und D sind zu praeferieren) stehen arg im
Widerspruch. Wer weiss eine Loesung?

viele Gruesse
Thomas Berger









Mehr Informationen über die Mailingliste Allegro