[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