NeXTnet: Das Verzeichnis für NeXT-Rechner und sein Plan

NeXTnet
2. November 2026
PAP-032

NeXTnet ist ein Verzeichnis für NeXT-Rechner: Eine App auf der Maschine registriert sie und meldet Modell, Ausstattung und Laufzeit, eine Website zeigt jede registrierte Maschine mit Online-Zustand und, wenn angegeben, Standort, und eine Weltkarte zeigt, wo sie stehen. Dieses Paper ist der Plan: NeXTSTEP 3.3 und OPENSTEP 4.2 auf schwarzer Hardware, ein Inventar aus Mach-Aufrufen und dem Start-Protokoll des Kernels, eine Registrierung und ein Protokoll mit signierten Anfragen über Klartext-HTTP, ein freiwilliger Standort, ein Rust-Backend mit PostgreSQL und eine Astro-Website als Container, die sich zwischen Hosts nur in Umgebungsvariablen unterscheiden, ein Client in Objective-C aus AppKit-App, Meldeprozess und dem Terminal-Befehl hinv, ein Repository für alles und vier Lieferphasen.

Inhalt

  1. Was NeXTnet ist
  2. Gegenstand und Grenzen
  3. Zielplattformen
  4. Hardware-Inventar unter NeXTSTEP
  5. Werkzeugkette und Entwicklungsumgebung
  6. Protokoll und Sicherheit
  7. Datenmodell und Datenschutz
  8. Backend, Website und Betrieb
  9. Der Globus
  10. Der Client: AppKit-App, Meldeprozess und hinv
  11. Repository und Lieferphasen
  12. Quellennachweis

Anhang

  1. Fundstellen zu NeXTSTEP
  2. Prüfpunkte für den ersten Build

1. Was NeXTnet ist

NeXTnet ist ein Verzeichnis für NeXT-Rechner. Die Maschine registriert sich selbst: Die AppKit-App auf der NeXT meldet sie beim Server an, der ihr eine Key-ID und ein Secret gibt. Ein Meldeprozess sendet von da an die Ausstattung der Maschine und alle zehn Minuten ein Lebenszeichen, signiert mit dem Secret. Im Terminal zeigt der Befehl hinv dieselbe Ausstattung, lesbar gruppiert oder als strukturierte Daten, sagt eindeutig, ob die Maschine echte Hardware ist oder in einem Emulator läuft, und nennt beim Emulator das Host-System. Die Website zeigt jede registrierte Maschine: welches Modell es ist, wie es ausgestattet ist, wo es steht, ob es online ist und wie lange es läuft. Den Standort gibt der Nutzer freiwillig an. Eine Weltkarte zeigt die Standorte. Auf der Website steht der Hinweis „Dieses Verzeichnis zeigt, was Maschinen selbst melden. Ob eine echte NeXT dahintersteht, wird nicht geprüft.“

Der Client läuft unter NeXTSTEP 3.3 und OPENSTEP 4.2 auf der Hardware von NeXT. Backend und Website laufen als Container und sind so zugeschnitten, dass dieselben Dienste ohne Änderung des Codes auf jedem Host laufen, der Container ausführt.

2. Gegenstand und Grenzen

Dieses Paper plant NeXTnet. Jede Aussage über NeXTSTEP und OPENSTEP nennt ihre Quelle: die Entwicklerdokumentation von NeXTSTEP 3.3, das Support-Archiv NeXTanswers, Handbuchseiten, einen Kernel-Quelltext von NeXT oder den Quelltext des Emulators Previous. Kein Programm wurde auf einem NeXTSTEP-System ausgeführt. Was sich nur dort klären lässt, steht als offen im Text und als Prüfpunkt in Anhang B. Die Rohnotizen der Recherche liegen unter sources/ neben diesem Dokument.

3. Zielplattformen

Der Client, die AppKit-App mit Meldeprozess und hinv, unterstützt NeXTSTEP 3.3 und OPENSTEP 4.2 auf der schwarzen Hardware von NeXT, also den 68040-Maschinen NeXTcube, NeXTstation und ihren Turbo- und Color-Varianten sowie dem 68030-Cube. NeXTSTEP 3.3 wird zuerst gebaut, weil es auf jeder dieser Maschinen läuft1 und der Stand ist, den der Emulator Previous und das Projekt Previously vorbereiten.2 OPENSTEP 4.2 für Mach folgt im selben Schritt, weil es auf derselben Hardware läuft und die letzte gefundene Ausgabe für sie ist.3

Die beiden Systeme haben eine Schnittstelle gemeinsam und unterscheiden sich in einer zweiten. Foundation ist auf beiden da: in 3.3 als statische Bibliothek mit 22 Klassen, die NeXT als OpenStep-konform bezeichnet, in 4.2 als Framework nach dem Foundation-Teil der OpenStep-Spezifikation. Code gegen die 3.3-Bibliothek muss für 4.x neu übersetzt werden, läuft dann aber gegen dieselben Klassen.45 Das Application Kit ist auf beiden ein anderes: Das von 3.3 steht auf der Wurzel Object, das von OpenStep auf NSObject mit neuen Namen, und NeXT beschreibt den Weg vom einen zum anderen als Konvertierung des Quelltexts mit tops-Skripten in sechs Stufen, nicht als Schicht, die beides ausführt.5

Daraus folgt der Zuschnitt. Alles, was nicht Oberfläche ist, also Protokoll, Signatur, Inventar, Dateien und die Steuerung der App, ist eine Quelle in Objective-C auf Foundation und wird zweimal übersetzt: auf dem 3.3-Abbild gegen die statische Bibliothek, auf dem 4.2-Abbild gegen das Framework. Der Meldeprozess besteht nur aus dieser Quelle, der Befehl hinv aus ihr und einem Bildschirmmodul je System. Die AppKit-App hat darüber zwei dünne Oberflächenschichten, eine gegen das Application Kit von 3.3 und eine gegen das OpenStep Application Kit, jede mit ihren Nib-Dateien aus dem Interface Builder des jeweiligen Systems. Beide rufen denselben Controller in der Bibliothek, so dass jede Entscheidung genau einmal existiert und die Schichten nichts enthalten als die Verbindung von Control und Aufruf. Das kostet zwei Entwicklungsabbilder in Previous, zwei Build-Ziele im Makefile, zwei Nib-Sätze, zwei Installer-Pakete je Ausgabe, weil die Binaries je System gegen eine andere Foundation gelinkt sind, und einen Testlauf auf jedem System vor jedem Release. Ob ein 3.3-Binary auf 4.2 unverändert läuft, ist offen (Anhang B). Läuft es, reicht für den Meldeprozess ein Build für beide Systeme, und die 4.2-Schicht der App bleibt für das native Aussehen.

NeXTSTEP 3.3 lief auch auf Intel-PCs, auf HP 9000 der Serien 712 bis 755 und auf SPARCstation 5, 10 und 20.1 Das Verzeichnis nimmt solche Maschinen an und führt die Architektur als Feld, weil sich NeXTSTEP auf einem HP 712 genauso zeigen lässt und der Client dafür nur ein Fat Binary mehr braucht. In der Liste und auf dem Globus sind sie standardmäßig sichtbar und als Fremdhardware gekennzeichnet, weil eine Maschine registriert wird, damit man sie sieht; in der Bestenliste zählen sie nicht. Emulatoren werden ebenfalls angenommen, sind genauso sichtbar und als solche gekennzeichnet, mit der Klasse aus Abschnitt 4. Gebaut wird der Client zuerst für m68k; die Fat Binaries für Intel, PA-RISC und SPARC stehen im Backlog, und Maschinen dieser Architekturen erscheinen, sobald es sie gibt.

4. Hardware-Inventar unter NeXTSTEP

NeXTSTEP hat kein Werkzeug, das die Hardware einer Maschine als Liste zeigt. Was ein Programm über die eigene Maschine erfährt, kommt aus Mach-Aufrufen, aus dem Kernel-Protokoll des Starts und aus wenigen Werkzeugen. Tabelle 1 ist der Plan: Welche Angabe der Client sammelt, woher, und wie sicher die Quelle ist.

Tabelle 1 Die Angaben des Inventars und ihre Quelle unter NeXTSTEP 3.3
AngabeQuelleStand
CPU-Familie und -Typ (68030, 68040, i486, PA-RISC, SPARC), Anzahl CPUshost_info() mit HOST_BASIC_INFO: cpu_type, cpu_subtype, max_cpus, avail_cpus6belastbar
ArbeitsspeicherDasselbe, Feld memory_size in Bytes6belastbar
Kernel und Betriebssystemhost_kernel_version() liefert die Zeile NeXT Mach 3.3: ..., die auch hostinfo als erste Zeile druckt67belastbar
Lastwerteprocessor_set_info() mit PROCESSOR_SET_BASIC_INFO: load_average und mach_factor, skaliert mit LOAD_SCALE6belastbar
CPU-Takt, Systemtyp, Board-RevisionDrei Zeilen der Ausgabe von hostinfo auf 3.3 (Processor speed: 33 MHz, System type: 5, Board revision: 0xf); der Aufruf dahinter ist in keiner Dokumentation beschrieben, der Client parst deshalb die Ausgabe7schwach
Modell (NeXTcube, NeXTstation, Color, Turbo)Der Kernel kennt den Maschinentyp aus einem Steuerregister, veröffentlicht aber nur den CPU-Typ8; der Nutzer wählt das Modell bei der Registrierung aus einer Liste, die der Server liefertbelastbar
PlattenZeilen des Start-Protokolls in /usr/adm/messages, etwa MAXTOR XT-8360S as sd0 at sc0 target 1 lun 0 und Disk capacity: 660MB9; als zweiter Weg die ioctls DKIOCINFO und SDIOCGETCAP des Treibers sd(4)10schwach
BildschirmGrenzen, Farbtiefe und Anzahl der Bildschirme über NXScreen und getScreens:count: des Application Kit, also nur mit Verbindung zum Window Server; die Bildschirmdatensätze in NetInfo unter /localconfig/screens sind von der Shell lesbar, aber nicht immer vollständig11; die App gibt die Werte über den Spool an nextnetd weiter, der sie sendet (Abschnitt 10)schwach
Ethernet-AdresseDie Zeile en0: Ethernet address des Start-Protokolls9; gethostid() liefert nur die unteren drei Bytes, der Präfix 00:00:0f gehört NeXT1012schwach
UptimeKein dokumentierter Aufruf; w und uptime zeigen sie, der Client parst die Kopfzeile von w10schwach
SeriennummerWeder der NVRAM-Datensatz noch die Struktur des ROM-Monitors noch Mach kennen eine8keine
Klasse (NeXT-Hardware, Fremdhardware, Emulator)Die INQUIRY-Antwort des Boot-Laufwerks, als Superuser über SDIOCSRQ des Treibers sd(4) gelesen10: Hersteller Previous oder der Marker PREVIOUS-EMULATOR in den herstellerspezifischen Bytes 36 bis 53 bedeutet Emulator2; sonst entscheidet cpu_type aus host_info() zwischen NeXT-Hardware (68k) und Fremdhardwarebelastbar
Host-System (nur Emulator)Die herstellerspezifische INQUIRY-Seite 0xC0 desselben Laufwerks mit Emulator, Version, Betriebssystem, Modell und Architektur des Hosts, die Previous nach der Änderung aus diesem Abschnitt liefertoffen

Die Ethernet-Adresse ist das einzige hardwaregebundene Merkmal einer schwarzen Maschine. Sie erscheint in der Ausgabe von hinv und in der App und wird nie gesendet. Die Identität einer Maschine ist allein ihre Key-ID aus Abschnitt 6.

Ob die Maschine echte NeXT-Hardware ist oder in einem Emulator läuft, sagt das Inventar eindeutig, und das Signal kommt aus der emulierten Hardware, nicht aus dem Netz. Previous beantwortet die SCSI-Anfrage INQUIRY für jedes Plattenabbild, dessen Größe nicht genau einem der zwei bekannten Laufwerke entspricht, mit dem Hersteller Previous, dem Produkt HDD und der Revision B als festen Konstanten; die zwei bekannten Größen bekommen die Kennungen der originalen MAXTOR-Laufwerke, und keine Einstellung ändert diese Strings.2 Ein echtes Laufwerk hat nie den Hersteller Previous, dieser Wert ist also eindeutig, aber er fehlt bei den zwei bekannten Größen. Darum bekommt Previous eine kleine Änderung, als eigenes Issue in phrancks Fork und als Pull Request an Previous: Die INQUIRY-Antwort jedes emulierten Laufwerks, auch der bekannten, enthält in den herstellerspezifischen Bytes 36 bis 53 den Marker PREVIOUS-EMULATOR, und die herstellerspezifische INQUIRY-Seite 0xC0 liefert das Host-System als Zeilen der Form name=value mit emulator, version, host_os, host_os_version, host_model und host_arch, die Previous beim Start aus uname, aus /etc/os-release oder der Versionsabfrage von macOS, aus /proc/device-tree/model oder hw.model und aus seiner eigenen Versionskonstante füllt. Hersteller und Produkt der bekannten Laufwerke bleiben, wie sie sind, damit NeXTSTEP sie weiter behandelt wie bisher. Für sich allein eindeutig ist von allem, was Previous dem Gast zeigt, nur dieser Hersteller, und nach der Änderung der Marker. Die Ethernet-Adressen stammen aus den ROM-Abbildern echter Maschinen, das NVRAM wird bei jedem Reset ohne Marker aus der Konfiguration gebaut, die Systemregister folgen den Werten echter Maschinen, und den Hostnamen previous, den NetInfo-Datensatz /machines/previous mit seinem system_type, den Namen des Hosts in NetInfo und DNS, den NTP-Dienst und die Adressen des emulierten Netzes gibt es nur mit SLiRP; zusammen sind sie ein Hinweis, und der Plan nutzt keinen davon.213 Marker und Host-Seite liegen in der INQUIRY und nicht in den NetInfo-Datensätzen, die Previous für den Gast baut, weil diese nur mit SLiRP und gebundener NetInfo-Domäne da sind und im Bridge-Betrieb fehlen, die INQUIRY-Antwort aber in jeder Konfiguration.

Der Client liest die INQUIRY-Antwort des Boot-Laufwerks über SDIOCSRQ des Treibers sd(4), das den Superuser verlangt; nextnetd tut das beim Start und schreibt Klasse und Host-Block in seinen Zustand, aus dem hinv und die App sie lesen. Die Klasse hat vier Werte: emulator, wenn der Hersteller Previous oder der Marker gefunden wurde; sonst next-hardware, wenn host_info() einen 68k-Prozessor meldet, und foreign-hardware bei jeder anderen CPU; undetermined, wenn kein Prozess mit Root die INQUIRY gelesen hat. Der Host-Block steht nur bei emulator; liefert das Laufwerk die Seite 0xC0 nicht, weil Previous älter ist als die Änderung, steht er als nicht geliefert da. Ein Previous ohne die Änderung mit einem Abbild einer der zwei bekannten Größen erscheint bis zum Update als NeXT-Hardware; das ist die eine Lücke, und sie schließt sich mit dem Paket, das Previously installiert.

Alles in Tabelle 1 mit dem Stand schwach rechnet mit Quellen, die aus Handbuch und Kernel-Quelltext belegt sind, aber nicht auf einem laufenden 3.3 geprüft. Die Prüfung ist der erste Schritt des ersten Builds (Anhang B).

Eine Angabe in Tabelle 1 erreicht nur ein Programm mit Verbindung zum Window Server: der Bildschirm. Grenzen und Farbtiefe jedes angeschlossenen Bildschirms liefert NXScreen, und die Liste aller Bildschirme liefert getScreens:count: der Klasse Application; beides sind Antworten des Window Servers.11 Jede NeXTSTEP-Anwendung baut diese Verbindung beim Start auf, und jedes Programm, das sie braucht, hat dafür ein Application-Objekt.14 Wer sich verbinden darf, regelt der Window Server: Solange ein Benutzer angemeldet ist und PublicWindowServer nicht gesetzt hat, nimmt er nur Prozesse an, die vom Workspace abstammen, und wenige Systemprozesse wie den Druckdienst.10 Ein Befehl aus einem Terminal-Fenster der angemeldeten Sitzung stammt vom Workspace ab und erreicht den Window Server; eine Shell über telnet oder rlogin stammt nicht von ihm ab und wird abgewiesen. Ein Prozess aus /etc/rc.local läuft beim Systemstart, bevor init den Mehrbenutzerbetrieb beginnt und die Programme aus /etc/ttys startet, darunter loginwindow auf der Konsole; vor der Anmeldung stammt kein Prozess vom Workspace ab.10 Der NetInfo-Datensatz unter /localconfig/screens ist von der Shell aus lesbar, aber der Window Server ersetzt fehlende Angaben darin durch Vorgaben, so dass der Datensatz unvollständig sein kann.11 Alle anderen Angaben kommen aus Mach, aus dem Start-Protokoll und aus Werkzeugen, die jeder Prozess gleich erreicht. Abschnitt 10 zieht daraus die Folge für die Form des Clients: Die App und der Befehl hinv in der angemeldeten Sitzung sehen den Bildschirm, der Meldeprozess nicht, und die App reicht ihm die Werte über den Spool weiter.

5. Werkzeugkette und Entwicklungsumgebung

Entwickelt wird mit den Werkzeugen, die NeXTSTEP 3.3 Developer mitbringt. Tabelle 2 nennt sie.

Tabelle 2 Die Werkzeugkette für den Client
WasWerkzeug unter NeXTSTEP 3.3Unter OPENSTEP 4.2
Projekt und BuildProject Builder mit dem Projekttyp Tool für den Meldeprozess und hinv, Application für die AppKit-App; er erzeugt PB.project und ruft make mit den Makefiles aus /NextDeveloper/Makefiles, Eigenes steht in Makefile.preamble1516Project Builder mit den Makefiles unter pb_makefiles, wählbar über MAKEFILEDIR5
OberflächeInterface Builder, Nib-Dateien als Pakete1Interface Builder
Compilercc, NeXTs GNU C auf Basis von GCC 2.5.8, ANSI C, Objective-C mit Protokollen, Kategorien, @selector und @encode; ohne @try171819cc auf Basis von GCC 2.7.2.15
Fat Binarycc -arch m68k -arch i386 ..., in 3.1 nur diese beiden Werte dokumentiert17; ob 3.3 auch sparc und hppa annimmt, ist offenm68k, i386, sparc, hppa5
FrameworksFoundation als libFoundation_s.a mit 22 Klassen, darunter NSObject, NSString, NSData, NSDictionary, NSArray, NSDate und NSException204; daneben die Common Classes mit der Wurzel Object, die das Application Kit von 3.3 verwendet21Foundation und Application Kit als Frameworks nach der OpenStep-Spezifikation5
NetzBSD-Sockets und select; gethostbyname fragt über lookupd NetInfo und DNS22; keine HTTP-Klasse in Foundation, kein TLS von NeXT4Dasselbe; NSFileHandle für Sockets ab 4.25
PaketInstaller-Paket, ein Verzeichnis mit .tar.Z, .bom, .info und .sizes, gebaut mit /NextAdmin/Installer.app/package, mit post_install für Verzeichnis und Starteintrag23Dasselbe Format
Start beim BootenEine Zeile in /etc/rc.local, dem Ort für lokale Ergänzungen des Starts2425Dasselbe

Der Client wird in Objective-C geschrieben, mit Foundation als Grundlage, weil Foundation auf 3.3 und 4.2 vorhanden ist und so Protokoll, Inventar und Zustand in beiden Builds dieselbe Quelle haben. Das Application Kit kommt nur in der AppKit-App und im Bildschirmmodul von hinv vor. Netzcode ist BSD-Sockets in C, in eine Objective-C-Klasse gefasst.

Entwickelt wird in NeXTSTEP 3.3 und OPENSTEP 4.2 im Emulator Previous auf phrancks Mac, mit den beiden Plattenabbildern, die Previously vorbereitet. Previous teilt mit SLiRP und seinem NetInfo-Server automatisch einen Ordner des Mac unter /Net in das Gastsystem, so dass der Quelltext auf dem Mac liegt und im Gast gebaut wird.13 Das Gastsystem erreicht das Netz über das Gateway 10.0.2.2 und den DNS 10.0.2.3 des Emulators, der Client kann also aus Previous heraus gegen den Server getestet werden.13 Ob die Abbilder die Developer-Werkzeuge unter /NextDeveloper enthalten, ist der erste Prüfpunkt; falls nicht, werden sie von der Developer-CD des jeweiligen Systems nachinstalliert.

Auf eine echte NeXT-Maschine kommt das Paket über das Netz. Der Nutzer lädt den Tarball mit dem Paket auf einem heutigen Rechner herunter und kopiert ihn per FTP oder NFS auf die NeXT; beide gehören zum System, und ein HTTP-Client wie lynx ist Zusatzsoftware aus dem Peanuts-Archiv.26 Dort öffnet der Nutzer das Paketsymbol, und der Installer installiert es.23

Der erste Build soll sechs Dinge klären: ob der Compiler von 3.3 die geplante Objective-C-Form und ANSI-Prototypen so annimmt, wie der Quelltext sie schreibt; welche Werte host_info, hostinfo und das Start-Protokoll in Previous liefern und wo sie von einer echten Maschine abweichen; ob ein Prozess ohne Root /usr/adm/messages lesen darf; wie groß das gelinkte Binary ist und was es an Speicher braucht, bei 16 MB als kleinster und 24 MB als empfohlener Ausstattung der NeXT-Rechner27; ob die Verbindung aus dem Gast über SLiRP den Server erreicht; und ob das 3.3-Binary auf dem 4.2-Abbild startet.

6. Protokoll und Sicherheit

Ein NeXTSTEP ohne Zusatzsoftware kann kein TLS. Die Ports von OpenSSL, die es für 3.3 und 4.2 gibt, sind Stände der Serien 0.9 und 1.0.2; bei einem Test der RSA-Prüfung auf 68k schlug die Signaturprüfung fehl, und ein weiterer Bericht nennt fehlende Zufallsquellen.32829 Der Client spricht deshalb Klartext-HTTP, und die Sicherheit liegt in der Nachricht, nicht im Transport: Jede Anfrage nach der Registrierung ist mit dem Secret signiert, das der Server der Maschine bei der Registrierung gibt, und das Secret verlässt die Maschine danach nie.

Registrierung

Die Maschine registriert sich selbst. Das Registrieren-Panel der AppKit-App zeigt den Hostnamen, unter dem die Maschine veröffentlicht werden soll, lässt das Modell aus der Liste des Servers wählen und holt die Einwilligung ein (Abschnitt 7). Die App übergibt die Eingaben dem Meldeprozess (Abschnitt 10), und der sendet sie mit dem Inventar an POST /v1/register. Diese Nachricht ist nicht signiert, weil die Maschine noch kein Secret hat.

Der Server prüft die Eingaben und gibt der Maschine eine Key-ID und ein Secret. Die Key-ID ist eine zufällige Kennung aus 80 Bit, in Base32 sechzehn Zeichen in vier Gruppen, die der Server auf Eindeutigkeit prüft; über sie ist jede Maschine zu erkennen, und nichts anderes ist ihre Identität. Das Secret sind 256 Bit aus dem Zufallsgenerator des Betriebssystems des Servers. Beide stehen in der Antwort. Der Meldeprozess legt sie nach /etc/nextnet/machine.key mit Rechten nur für Root, und kein anderes Programm liest die Datei. Das Secret ist der Schlüssel K der Signaturen. Der Server speichert es, weil er die Signaturen prüft.

Signierte Anfragen

Jede weitere Anfrage hat vier Kopfzeilen: die Key-ID, einen Zähler, eine Nonce und die Signatur HMAC-SHA-256(K, Methode || Pfad || Zähler || Nonce || SHA-256(Body)). Der Zähler steigt mit jeder Anfrage und steht auf der Maschine in /etc/nextnet/counter; der Server nimmt nur einen Zähler an, der größer ist als der letzte gesehene, und merkt sich die Nonce der letzten Stunde. Damit ist eine Wiederholung erkannt, ohne dass die Uhr der Maschine stimmen muss, und das ist wichtig, weil die Pufferbatterien dieser Maschinen oft leer sind. Die Zeit im Body ist Information, nicht Prüfmerkmal. SHA-256 und HMAC sind wenige hundert Zeilen C und laufen auf einem 68040 ohne Mühe.

Tabelle 3 Die Nachrichten des Client-Protokolls unter dem Pfad /v1 der konfigurierten Basisadresse
NachrichtSigniertInhaltAntwort
GET /v1/modelsneinkeinerDie Modellliste zur Auswahl bei der Registrierung
GET /v1/timeneinkeinerDie Serverzeit, damit der Client eine falsche Uhr erkennt und meldet
GET /v1/placesneinEin Ortsname als q oder der Name einer Zeitzone als zoneBis zu zehn Orte mit Name, Land, Verwaltungsgebiet und Koordinaten, bei zone der Punkt der Zone
POST /v1/registerneinHostname, gewähltes Modell, Inventar, Version des Clients, Fassung des EinwilligungstextesKey-ID und Secret
POST /v1/inventorymit KDas Inventar aus Tabelle 1Bestätigung
POST /v1/statusmit KUptime, Lastwerte, Version, Zeit der Maschine; alle zehn Minuten vom MeldeprozessBestätigung, auf Wunsch die Bitte um ein frisches Inventar
POST /v1/locationmit KBreite und Länge in Dezimalgrad und die Genauigkeit approximate oder exact; ohne Koordinaten entfernt die Nachricht den StandortDer Standort, wie er veröffentlicht wird
POST /v1/withdrawmit Kkeiner; widerruft die EinwilligungBestätigung
POST /v1/offlinemit Kkeiner; beim HerunterfahrenBestätigung

Anfragen und Antworten sind JSON. Antworten sind flach und klein, damit der Client sie mit einem kleinen eigenen Parser liest. Online ist eine Maschine, deren letzter Status höchstens 25 Minuten alt ist, also zwei Meldungen plus Reserve.

Was der Server glaubt

Der Server glaubt der Signatur, dass die Anfrage von der Maschine kommt, deren Key-ID sie nennt. Dem Inhalt glaubt er nicht: Jedes Feld wird auf Typ, Länge und erlaubte Zeichen geprüft, das Inventar auf höchstens 200 Einträge, der Body auf höchstens 32 KB. Tabelle 4 nennt die Grenzen.

Tabelle 4 Grenzen und Prüfungen des Client-Endpunkts
GegenMaßnahme
WiederholungSteigender Zähler je Maschine und Nonce-Speicher über eine Stunde
MassenregistrierungHöchstens fünf Registrierungen je Adresse und Tag und höchstens 100 am Tag insgesamt; darüber antwortet der Server mit der Bitte, später wiederzukommen
Unplausibles InventarDer CPU-Typ aus host_info() muss zu den CPU-Typen des gewählten Modells passen (Tabelle 5), und der Host-Block steht genau bei der Klasse emulator; was nicht passt, lehnt der Server ab. Die Wertemengen für Takt, Systemtyp und Board-Revision folgen aus dem ersten Build (Anhang B).
Erfundene UptimeZwischen zwei Statusmeldungen muss die Uptime um die vergangene Serverzeit wachsen, mit einer Toleranz von fünf Prozent und einer Minute; ein Rückgang gilt als Neustart. Weicht die Uptime anders ab, zählt die Strecke seit der letzten stimmigen Meldung nicht. Gesamt-Uptime und längste Uptime rechnet der Server aus den Meldungen, die er beobachtet hat, und nicht aus der gemeldeten Zahl; die Uptime bis zur ersten Meldung hat er nie beobachtet.
Fälschung in Statistik und BestenlisteEine Maschine zählt in der Statistik und in der Bestenliste erst nach sieben Tagen beobachteter Meldungen ohne Lücke von mehr als 25 Minuten; inaktive Maschinen zählen in der Bestenliste und in der Modellverteilung nicht
FlutHöchstens eine Statusmeldung je Maschine in fünf Minuten, höchstens ein Inventar je Stunde, Body bis 32 KB, 200 Inventareinträge
Ausprobieren von KennungenUnbekannte Kennung und falsche Signatur antworten gleich und knapp; Fehlversuche je Adresse werden gezählt und gebremst
Missbrauch der OrtssucheHöchstens 30 Anfragen je Adresse und Stunde, höchstens zehn Treffer je Antwort

Der Betreiber kann einen Eintrag als Fälschung entfernen. Das ist ein Betriebsbefehl des Backends, remove-machine mit der Key-ID. Er läuft nie automatisch.

Wer welche Maschine fälschen kann

Das Secret geht bei der Registrierung einmal im Klartext über die Leitung, weil die NeXT keinen verschlüsselten Weg hat. Daraus folgt:

Ein Relay mit TLS im eigenen Netz (nächster Unterabschnitt) verschlüsselt den Weg ins Internet. Das Secret kreuzt dann nur das eigene Netz.

Trennung von Client-API und öffentlicher API

Der Client-Endpunkt und die Website haben zwei Hostnamen und zwei Ports im Backend. Die Website liegt hinter HTTPS und liefert unter /api/v1 die öffentliche Lese-API für Listen, Details und Karte. Der Client-Host antwortet ausschließlich auf die Nachrichten aus Tabelle 3 über Klartext-HTTP, ohne Zertifikat und ohne Umleitung auf HTTPS, weil die NeXT beidem nicht folgen könnte; der Reverse Proxy vor dem Backend muss diesen einen Host unverschlüsselt durchreichen. Der Client löst den Namen bei jedem Lauf auf und enthält keine feste Adresse, weil der Host hinter dem Namen wechseln kann und sich Adressen über die Lebensdauer eines Projekts ändern.

Der Client nimmt die Basisadresse des Servers aus seiner Konfigurationsdatei /etc/nextnet/nextnet.conf. Wer die Strecke aus seinem LAN zusätzlich verschlüsseln will, schreibt dort die Adresse eines Reverse Proxy im eigenen Netz hinein, der mit TLS an den Server weiterreicht; das Repository liefert dafür eine Beispielkonfiguration eines Reverse Proxy mit. Die Signaturen bleiben dieselben, der Server behandelt beide Wege gleich.

7. Datenmodell und Datenschutz

Tabelle 5 Die Entitäten des Verzeichnisses
EntitätFelder
MaschineKey-ID, Hostname, Modell aus der Liste, Klasse aus dem letzten Inventar (NeXT-Hardware, Fremdhardware, Emulator), Architektur, Betriebssystem, Registrierdatum, zuletzt gesehen, Secret K, letzter Zähler, Zeitpunkt und Fassung der Einwilligung, Standort mit seiner Genauigkeit (approximate oder exact)
InventarMaschine, Zeitpunkt, die Angaben aus Tabelle 1 als Felder, die Klasse als Aufzählung mit den vier Werten aus Abschnitt 4, der Host-Block als strukturiertes JSON-Feld (JSONB) mit den sechs Angaben der Seite 0xC0, nur bei Emulatoren
StatusprobeMaschine, Eingang, Uptime, Lastwerte, Client-Version; roh 90 Tage, danach zu Tageswerten verdichtet, aus denen der Server Gesamt-Uptime und längste Uptime aus den beobachteten Meldungen ableitet (Tabelle 4)
OrtslisteKennung, Name, Land, Verwaltungsgebiet, Koordinaten und Einwohnerzahl der Orte aus den GeoNames-Daten cities5000, dazu die Zeitzonen der IANA mit Name, Land und einem Punkt; ein Unterbefehl des Backends lädt beides in die Datenbank
ModelllisteName, Klasse, Hersteller, CPU-Typen, zu denen er passt; gepflegt im Backend, geliefert an Client und Website

Der Standort ist freiwillig. Eine Maschine ohne Standort steht in der Liste und fehlt auf dem Globus. Der Nutzer setzt ihn im Client und entscheidet, auf welchem von drei Wegen:

Veröffentlicht wird der Standort auf ein Zehntelgrad gerundet, in Nord-Süd-Richtung rund elf Kilometer, weil diese Genauigkeit die Weltkarte füllt und die Wohnung nicht verrät. Der Nutzer kann stattdessen die genaue Veröffentlichung wählen. Bei der gerundeten Veröffentlichung speichert der Server nur den gerundeten Wert. Mit einer signierten Nachricht lässt sich der Standort jederzeit ändern oder entfernen (Tabelle 3).

Tabelle 6 Was die Website standardmäßig zeigt und was privat bleibt
ÖffentlichPrivat
Hostname (bei inaktiven Maschinen und nach einem Widerruf die Key-ID), Key-ID, Modell, Klasse, Architektur, Betriebssystem, Inventar der Hardware, bei Emulatoren Emulator, Version und Host-System, Online-Zustand, Uptime und Gesamt-Uptime, Registrierdatum, Standort in der gewählten Genauigkeit, sofern gesetzt und die Maschine nicht inaktiv istSecret K, Zähler, Einwilligung mit Zeitpunkt und Fassung, IP-Adressen, Fehlversuche, der Standort einer inaktiven Maschine

Hostname und Standort sind personenbezogene Daten nach Art. 4 Nr. 1 DSGVO, sobald sie einer Person zugeordnet werden können: Die Vorschrift nennt Standortdaten ausdrücklich als Kennung, und ein Hostname kann einen Namen enthalten. Ein genauer Standort ist die Wohnung, wenn die Maschine zu Hause steht. Die Verordnung gilt in Österreich unmittelbar, ergänzt durch das Datenschutzgesetz.3334 Verantwortlicher ist phranck in Bregenz.

Rechtsgrundlage für die Veröffentlichung ist die Einwilligung nach Art. 6 Abs. 1 lit. a.33 Der Client holt sie beim Registrieren ein: Das Panel zeigt den Hostnamen, der veröffentlicht wird, neben einem Häkchen, und der Nutzer bestätigt ihn oder gibt einen anderen Namen ein. Die Einwilligung gilt genau für diesen Namen und für einen Standort, den der Nutzer später setzt; das Panel für den Standort zeigt vor dem Senden den Punkt, der veröffentlicht wird. Für Screenshots (Abschnitt 11) gibt der Nutzer die Einwilligung für jedes Bild einzeln, in der Vorschau. Der Server speichert zur Key-ID den Zeitpunkt und die Fassung des Einwilligungstextes und keine Angabe zu einer Person. Die Informationen nach Art. 13 stehen auf einer Datenschutzseite der Website in Deutsch und Englisch, und Name, Anschrift und Kontaktadresse des Verantwortlichen setzt die Website beim Aufruf aus drei Umgebungsvariablen ein (Tabelle 8), so dass das Repository keine personenbezogenen Daten enthält.

Die Einwilligung lässt sich so einfach widerrufen, wie sie erteilt wird (Art. 7 Abs. 3): Das Panel hat einen Button Einwilligung widerrufen, und der Meldeprozess sendet POST /v1/withdraw. Der Server löscht dann den Standort der Maschine und, wenn es eines gibt, ihr Screenshot-Bild und ersetzt den Hostnamen durch die Key-ID (Art. 17 Abs. 1 lit. b).33 Den Standort allein entfernt der Button Standort entfernen mit POST /v1/location ohne Koordinaten, und die Einwilligung für den Hostnamen bleibt. Wer sein Secret verliert, kann nicht mehr widerrufen; Hostname und Standort werden spätestens 90 Tage nach der letzten Meldung nicht mehr veröffentlicht.

Für die Speicherdauer gilt Art. 5 Abs. 1 lit. e.33 Eine Maschine, die 90 Tage nichts gemeldet hat, gilt als inactive und steht in einer eigenen Liste, ohne Standort, ohne Bild und mit der Key-ID statt des Hostnamens. Ihr Standort bleibt gespeichert und wird nicht mehr veröffentlicht. Sie zählt in der Bestenliste und in der Modellverteilung nicht. Meldet sich die Maschine wieder, gilt sie wieder als aktiv, und Hostname und Standort erscheinen wie zuvor. Der Betreiber kann einen Eintrag als Fälschung entfernen (Abschnitt 6); das ist ein Betriebsbefehl, kein Löschweg für Personen und keine automatische Löschung.

IP-Adressen stehen nur in den Logs des Reverse Proxy und werden nach sieben Tagen gelöscht; die Zähler gegen Missbrauch rechnen mit gesalzenen Hashes der Adresse. Aufsichtsbehörde ist die österreichische Datenschutzbehörde.35

8. Backend, Website und Betrieb

Das Backend wird in Rust geschrieben, das Frontend in TypeScript. Jeder Dienst ist ein Container-Image, seine Konfiguration kommt ausschließlich aus Umgebungsvariablen, und eine Beschreibung des Deployments im Ordner deploy/ legt die Dienste an. So läuft derselbe Stand auf jedem Host, der Container ausführt, und ein Wechsel des Hosts ändert nichts am Code.

Tabelle 7 Die Dienste von NeXTnet und ihre Technik
DienstTechnikContainer und Konfiguration
backendRust 1.99 stabil, axum 0.8 auf tokio, sqlx 0.9 mit eingebetteten Migrationen, tower-http, serde, hmac und sha2, utoipa für die OpenAPI-Beschreibung, tracing3637; ein Prozess mit zwei Listenern, Port 3000 für die Website-API, Port 3001 nur für den Client-EndpunktMulti-Stage-Dockerfile rust:1-alpine nach alpine; die Migrationen laufen als Unterbefehl des Binarys vor dem Start
webAstro 7 mit SSR über @astrojs/node, React 19 nur als Insel für den Globus, UnoCSS, TypeScript 5, oxlint und oxfmt, vitest, TSDoc mit typedoc, knip38Container node:22-alpine, Build mit astro build, Start node dist/server/entry.mjs, erreicht das Backend als http://backend:3000
dbPostgreSQLContainer postgres:18-alpine mit eigenem Volume; den Verbindungsstring bekommt das Backend aus seiner Umgebung
edgeReverse Proxy des HostsBeendet TLS für die Website und leitet /api/* auf backend:3000 und alles andere auf web:3000; reicht den Client-Host unverschlüsselt und ohne Umleitung auf backend:3001 durch

axum wird verwendet, weil es die Bibliothek des tokio-Ökosystems ist, Middleware aus Tower übernimmt und damit Ratenbegrenzung, Logging und Zeitlimits ohne eigenen Unterbau liefert. sqlx wird verwendet, weil es Abfragen beim Kompilieren gegen das Schema prüft und Migrationen in das Binary einbettet. Astro mit React-Inseln, UnoCSS, oxlint und oxfmt sind die Konventionen, die phrancks andere Web-Projekte schon verwenden; der Globus braucht WebGL und bekommt die eine React-Insel.

Die Migrationen laufen vor dem Start des Dienstes als Unterbefehl des eigenen Binarys, in das sqlx sie einbettet; der Datenbankstand reist so mit dem Binary. Vor der ersten Migration prüft das Binary die Rolle: Es liest current_user und rolsuper, bricht bei einem Superuser oder einer anderen Rolle als DB_MIGRATION_ROLE ab und läuft auf jedem Host gleich. Die Ortsliste lädt der Unterbefehl import-places in die Datenbank, aus den GeoNames-Daten cities500032 und der Tabelle zone.tab mit der Datei backward der IANA.31 Der Unterbefehl remove-machine entfernt einen Eintrag als Fälschung (Abschnitt 6).

Ein Stand für jeden Host

Von den Ordnern des Repositorys (Abschnitt 11) zählen für die Serverseite drei: backend/ (Cargo-Projekt), web/ (Astro-Projekt, npm) und deploy/ mit der Compose-Datei für die drei Dienste, den Anforderungen an den Reverse Proxy als Text und je einer Beschreibung des Deployments für jeden Host, auf dem der Stand laufen soll. Zwischen den Hosts unterscheidet sich nichts im Code, nur die Umgebungsvariablen aus Tabelle 8, die jeder Host auf seine Weise setzt.

Tabelle 8 Die Umgebungsvariablen, in denen sich die Hosts unterscheiden
VariableDienstInhalt
DATABASE_URLbackendVerbindung als Anwendungsrolle, vom Host gesetzt
DB_MIGRATION_ROLEbackendErwartete Rolle vor der Migration, kein Superuser
NEXTNET_WEB_PORTbackendPort für die Website-API, 3000
NEXTNET_CLIENT_PORTbackendPort für den Client-Endpunkt, 3001
NEXTNET_PUBLIC_URLwebÖffentliche Adresse der Website mit https://, für Links in Seiten
API_URLwebhttp://backend:3000/api/v1, weil die Dienste sich intern unter ihrem Namen erreichen
PRIVACY_CONTROLLER_NAMEwebName des Verantwortlichen für die Datenschutzseite, beim Aufruf eingesetzt
PRIVACY_CONTROLLER_ADDRESSwebAnschrift des Verantwortlichen für die Datenschutzseite, beim Aufruf eingesetzt
PRIVACY_CONTACT_EMAILwebKontaktadresse für Datenschutzanfragen, beim Aufruf eingesetzt
RUST_LOGbackendLogstufe

Der Reverse Proxy gehört zum Host, und das Repository nennt in deploy/ nur die Anforderungen an ihn: Er beendet TLS für den Website-Host und leitet dort HTTP auf HTTPS um, gibt /api/* an den öffentlichen Port des Backends und alles andere an die Website, reicht den Client-Host unverschlüsselt und ohne Umleitung an Port 3001 durch, setzt keine Diagnose-Header in die Antworten und behält seine Logs sieben Tage. Die konkrete Konfiguration ist Teil des Deployments und steht nicht im öffentlichen Repository. Kann ein Host den Klartext-Host nicht durchreichen, bekommt der Endpunkt einen eigenen Port, und die Basisadresse in der Konfiguration des Clients nennt ihn.

Gates vor jedem Deploy: cargo fmt --check, cargo clippy ohne Warnungen, cargo test; im Web oxlint, astro check, vitest und ein Build. Die CI des Repositorys führt sie bei jedem Pull Request aus.

9. Der Globus

Der Globus ist eine Seite der Website unter /globe, gebaut mit three-globe auf Three.js als React-Insel.39 Er zeigt jede Maschine mit Standort als Marker in der Genauigkeit, in der der Standort veröffentlicht ist, Fremdhardware und Emulatoren eingeschlossen und mit ihrer Klasse gekennzeichnet, grün für online und grau für offline, mit Hostname und Modell beim Zeigen. Inaktive Maschinen erscheinen nicht. Die Daten kommen aus GET /api/v1/markers, das nur die öffentlichen Felder aus Tabelle 6 liefert. Eine native Globus-App für NeXTSTEP steht im Backlog.

10. Der Client: AppKit-App, Meldeprozess und hinv

Der Client ist die AppKit-App NeXTnet.app, im Workspace laufend; sie ist die Oberfläche: Sie nimmt die Eingaben für Registrierung und Standort entgegen, zeigt Inventar und Zustand und reicht an den Meldeprozess weiter, was nur sie sehen kann. Neben ihr stehen zwei Programme ohne Oberfläche auf derselben Bibliothek: der Meldeprozess nextnetd, der als einziges Programm den Schlüssel hält, signiert und sendet, und der Befehl hinv, der das Inventar im Terminal zeigt und nie sendet. Alle drei sind eine Neuentwicklung in Objective-C für NeXTSTEP; Namen, Protokoll, Datenformat und Paket sind eigene Entwürfe. Der Client besteht aus vier Teilen, in dieser Reihenfolge gebaut:

  1. Die Bibliothek libnextnet kommt zuerst. Sie enthält das Inventar nach Tabelle 1, SHA-256 und HMAC, den JSON-Schreiber und den kleinen Leser, den HTTP-Client über BSD-Sockets, die Schlüssel- und Zählerdatei, die Konfigurationsdatei, den Spool-Verkehr zwischen App und Meldeprozess, das Lesen der Zeitzone und den Controller der App. Sie ist eine Quelle auf Foundation und wird für 3.3 und 4.2 übersetzt. Sie hat keine Abhängigkeit zum Application Kit, damit sie im Meldeprozess und in hinv ohne Window Server läuft.
  2. Der Meldeprozess nextnetd kommt als zweites. Er hat keine Oberfläche und keine Befehle für den Nutzer, nur den Schalter -once für eine einzelne Meldung beim Testen. Er startet aus /etc/rc.local, lange vor einer Anmeldung, und läuft als Root, weil Start-Protokoll, Platten-ioctls und Schlüsseldatei Root verlangen. Er sendet den Status alle zehn Minuten, nach dem Start ein Inventar ohne Bildschirmwerte, bestimmt dabei über die INQUIRY des Boot-Laufwerks die Klasse der Maschine und liest bei einem Emulator die Host-Seite (Abschnitt 4), öffnet nur ausgehende Verbindungen und schreibt seinen Zustand mit Klasse und Host-Block nach /etc/nextnet/state, lesbar für alle und ohne Schlüssel. Er ist der einzige Halter von K und das einzige Programm, das signiert und sendet. Anfragen der App nimmt er aus dem Spool-Verzeichnis /usr/spool/nextnet/requests, das er alle drei Sekunden in seinem Schleifentakt liest: register mit Hostname, Modell und Einwilligung, location und withdraw für Standort und Widerruf, lookup für die Modellliste, die Serverzeit und die Ortssuche, display mit den Bildschirmwerten, status für eine sofortige Meldung. Jede Anfrage prüft er auf Form und Grenzen wie der Server, löscht sie und legt die Antwort unter der Kennung der Anfrage nach /usr/spool/nextnet/replies, wo sie eine Minute liegt. Ohne Schlüsseldatei sendet er nichts und wartet auf eine Anfrage register.
  3. Der Befehl hinv kommt als drittes. Er liest nur, den Zustand des Meldeprozesses und die Hardware, und sendet nie. Er ist ein natives Programm auf libnextnet und kein Skript, weil das Inventar so in einem Codepfad existiert und ein Skript ein zweiter wäre, der dieselben Dateien noch einmal liest und mit der Zeit abweicht; ein Skript käme außerdem nicht an den Window Server. Ohne Schalter schreibt er das Inventar für das Terminal: in Gruppen für Modell, Klasse, CPU, Speicher, Platten, Bildschirm, Netz, System und Laufzeit, bei einem Emulator dazu die Gruppe Host, eine Angabe je Zeile, die Werte in einer bündigen Spalte, dahinter die Quelle des Werts, wo sie nicht selbstverständlich ist. Mit -json schreibt er das Inventar als JSON, und zwar genau das Dokument, das nextnetd und die App als Body von POST /v1/inventory senden, so dass die Struktur einmal in der Bibliothek definiert ist und drei Programme sie nutzen. Die Ethernet-Adresse gehört nicht zum Inventar und erscheint nur in der Terminal-Ausgabe. Den Bildschirm erhebt hinv in einem Kindprozess, der ein Application-Objekt anlegt, die Bildschirme liest und es wieder freigibt; dieses Bildschirmmodul ist je System eine Datei, gegen das Application Kit von 3.3 und gegen das von OpenStep. Aus einem Terminal-Fenster der angemeldeten Sitzung gelingt das, weil der Prozess vom Workspace abstammt (Abschnitt 4). Aus einer Shell über telnet oder rlogin, aus /etc/rc.local oder wenn das Kind den Window Server aus einem anderen Grund nicht erreicht, endet nur das Kind, und hinv schreibt in die Gruppe Bildschirm die Zeile not determined: no access to the Window Server; im JSON steht dort "display": {"state": "unavailable", "reason": "no-window-server"} und nie ein geratener Wert. Klasse und Host-Block nimmt hinv aus /etc/nextnet/state, weil die INQUIRY den Superuser verlangt; als Root fragt er das Laufwerk selbst. Fehlt beides, schreibt er Class not determined: needs root for the SCSI inquiry, im JSON "class": "undetermined". Das JSON hat das Feld "class" mit genau den vier Werten aus Abschnitt 4 und bei emulator den Block "host" mit "state", read oder unavailable samt "reason": "not-provided", und den sechs Angaben der Seite 0xC0. Dieselbe Kennzeichnung bekommt jede Angabe aus Tabelle 1, deren Quelle fehlt oder nicht lesbar ist, etwa das Start-Protokoll ohne Root. Die Beschriftungen sind Englisch, wie bei den Werkzeugen des Systems.
  4. Die AppKit-App NeXTnet.app, im Workspace laufend, kommt als viertes. Sie zeigt im Dock-Icon den Online-Zustand, hat ein Panel zum Registrieren, ein Panel für den Standort, ein Fenster mit Inventar und Zustand und ein Info-Panel. Sie hält keinen Schlüssel und sendet nichts: Die Eingaben aus dem Registrieren-Panel legt sie als Anfrage register in den Spool, die Eingaben aus dem Panel für den Standort als Anfrage location, einen Widerruf als Anfrage withdraw, die Bildschirmwerte aus dem Window Server als Anfrage display, einen Klick auf den Button Jetzt melden als Anfrage status, und sie zeigt, was der Meldeprozess in seinen Zustand und in die Antwort schreibt. Das Registrieren-Panel zeigt den Hostnamen, der veröffentlicht wird, neben dem Häkchen der Einwilligung und lässt ihn ändern, und hat den Button Registrieren. Das Panel für den Standort bietet die Zeitzone als Vorschlag, den Ortsnamen mit der Liste der Treffer und die Koordinaten, dazu die Wahl zwischen gerundeter und genauer Veröffentlichung und die Buttons Standort setzen, Standort entfernen und Einwilligung widerrufen. Sie besteht aus zwei Oberflächenschichten über demselben Controller, einer gegen das Application Kit von 3.3 und einer gegen das OpenStep Application Kit von 4.2, mit je eigenen Nib-Dateien. Ihre Oberfläche folgt den Regeln der NeXTSTEP-3.3-Interface-Dokumentation, mit Verben auf den Buttons und der Return-Taste auf dem Standard-Button.

Die Übergabe zwischen App und Meldeprozess läuft über Dateien in einem Spool-Verzeichnis unter /usr/spool, wo NeXTSTEP 3.3 auch Druckaufträge und Post ablegt.10 post_install legt /usr/spool/nextnet/requests an, Root gehört es, Modus 1733, so dass jeder Benutzer eine Datei ablegen, aber weder das Verzeichnis noch eine fremde Datei lesen kann, und /usr/spool/nextnet/replies mit Modus 755, in das nur der Meldeprozess schreibt. Eine Anfrage ist eine kleine JSON-Datei mit action, einer Kennung aus Prozessnummer und Zähler und den Daten der Aktion; die App legt sie mit Modus 600 an, so dass Hostname und Standort darin nur sie und Root lesen, und die Antwort hat dieselbe Kennung. Dateien eignen sich dafür, weil der Meldeprozess sie mit einem stat() in seinem vorhandenen Takt sieht, die App sie mit den Dateiaufrufen von Foundation schreibt, beide Systeme sie gleich behandeln und der erste Build sie mit ls prüft. Distributed Objects wären der native Weg: Der Meldeprozess registriert ein Objekt beim Network Name Server, und die App ruft es über NXConnection.40 Das brächte dem Meldeprozess aber eine Mach-Nachrichtenschleife neben seiner Socket-Schleife.

So sieht die Ausgabe von hinv im Terminal aus, mit Werten, wie sie Tabelle 1 für eine NeXTstation Turbo Color nennt:

NeXTnet hinv 0.1

Model     NeXTstation Turbo Color        chosen at registration
Class     NeXT hardware                  SCSI inquiry via nextnetd
CPU       68040, 33 MHz, 1 processor     speed from hostinfo
Memory    32 MB
Disks     sd0  MAXTOR XT-8360S  660 MB   from the boot log
Display   1120 x 832, 2-bit gray, 1 screen
Network   en0  00:00:0f:01:23:45          from the boot log
System    NeXTSTEP 3.3, NeXT Mach 3.3
Uptime    3 days 04:12, load 0.12 0.08 0.03

Bei einem Emulator steht in der Zeile Class emulator, und unter den Gruppen folgt die Gruppe Host mit Emulator, Version, Betriebssystem, Modell und Architektur des Hosts aus der Seite 0xC0; fehlt die Seite, steht dort not provided by the emulator.

Je System ein Paket, NeXTnet-3.3.pkg und NeXTnet-4.2.pkg, installiert alle vier: die Bibliothek wird statisch gelinkt, der Meldeprozess nach /usr/local/libexec/nextnetd, der Befehl nach /usr/local/bin/hinv, die App nach /LocalApps/NeXTnet.app, und post_install legt /etc/nextnet und das Spool-Verzeichnis /usr/spool/nextnet mit requests und replies an und schreibt die Zeile in /etc/rc.local. Liegt /usr/local/bin nicht im Suchpfad der Shells, ergänzt post_install ihn in den systemweiten Startdateien der Shells, damit hinv in jedem Terminal-Fenster sofort gefunden wird; ob das nötig ist, klärt Anhang B. Der Meldeprozess sendet erst, wenn die Maschine registriert ist: Ohne Schlüsseldatei meldet nichts.

Die Aufteilung in App und Meldeprozess folgt aus zwei Grenzen. Eine App im Workspace läuft nur, solange ein Benutzer angemeldet ist und sie gestartet hat; eine NeXT, die am Anmeldefenster steht oder als Server läuft, wäre mit ihr allein nie online. Ein Prozess aus rc.local läuft immer, sieht aber den Bildschirm nicht. Darum meldet der Prozess Status und Inventar, die App gibt einmal pro Sitzung über den Spool weiter, was nur sie sehen kann, und hinv zeigt im Terminal, was die Maschine meldet. Der Preis sind zwei weitere Binaries im Paket; der Gewinn ist, dass die Maschine unabhängig von der Anmeldung online ist, das Inventar trotzdem den Bildschirm kennt und man es ohne die App prüfen kann.

11. Repository und Lieferphasen

Ein Repository für alles: NeXTnet auf phrancks eigener Gitea-Instanz, mit backend/ (Rust), web/ (Astro), client/ mit libnextnet, nextnetd, hinv, NeXTnet.app und dem Paketbau, deploy/ für die Dienste und docs/ mit der Protokollbeschreibung, die Server- und Client-Seite gemeinsam lesen. Ein Repository, weil Protokoll und Datenformat an einer Stelle definiert sind und eine Änderung beide Seiten im selben Commit erreicht; der Client-Teil wird auf einer NeXTSTEP-Maschine gebaut und braucht dafür nur seinen Ordner. Issues und Projekt-Board liegen in derselben Gitea-Instanz, und die Phasen werden dort als Issues angelegt. Der Code für Papers ist NXN.

Tabelle 9 Die vier Phasen, ihre Issues und was jede für sich liefert
PhaseIssuesLiefertBraucht
1 Server(1) Backend mit Schema, Migrationen, Client-Endpunkt nach Tabelle 3 für Registrierung, Inventar, Status und Abmeldung, Signaturprüfung, Grenzen und Prüfungen nach Tabelle 4, Lese-API mit der Regel für inaktive Maschinen und dem Unterbefehl remove-machine. (2) Website mit Liste, Detail, Liste der inaktiven Maschinen, dem Hinweis auf die Selbstauskunft und Datenschutzseite. (3) Betrieb: Container-Images und Compose-Datei für die drei Dienste, die Anforderungen an den Reverse Proxy, Beschreibung des Deployments in deploy/, CI mit den Gates.Ein laufendes Verzeichnis, in dem eine Maschine mit einem Testskript vom Mac registriert und gemeldet wird und in der Liste mit Inventar und Online-Zustand erscheintnichts
2 AppKit-App(1) libnextnet mit Inventar, Klasse und Host-Block, Signatur, HTTP, Dateien und Controller, der Meldeprozess nextnetd mit dem Spool-Verzeichnis und den Anfragen register, lookup, display und status, und der Befehl hinv mit Terminal- und JSON-Ausgabe, gebaut auf dem 3.3- und dem 4.2-Abbild, mit den Prüfpunkten aus Anhang B als erstem Schritt, darunter der Nachweis, ob das 3.3-Binary auf 4.2 läuft. Voraussetzung ist die Änderung in Previous aus Abschnitt 4, Marker und Host-Seite in der INQUIRY-Antwort, als eigenes Issue in phrancks Fork vor diesem Issue und als Pull Request an Previous, damit das Paket, das Previously installiert, sie bekommt. (2) NeXTnet.app für 3.3 mit Dock-Icon, Registrieren-Panel, das Hostname, Modell und Einwilligung über den Spool an den Meldeprozess übergibt, Inventarfenster mit Bildschirmwerten, die es ebenso übergibt, Button Jetzt melden und Info-Panel. (3) Die 4.2-Schicht gegen das OpenStep Application Kit mit eigenen Nib-Dateien über demselben Controller, dazu NeXTnet-3.3.pkg und NeXTnet-4.2.pkg mit post_install, Installationsanleitung und der Beispielkonfiguration für ein Relay im eigenen Netz.Die erste echte NeXT in der Liste, registriert aus dem Workspace, gemeldet von ihrem Meldeprozess und mit hinv im Terminal geprüft, unter 3.3 wie unter 4.2Phase 1
3 Standort und Statistik(1) Server: die Ortsliste mit dem Unterbefehl import-places, GET /v1/places für Ortssuche und Zeitzone, POST /v1/location mit Rundung auf ein Zehntelgrad oder genauer Veröffentlichung und POST /v1/withdraw. (2) Client: das Panel für den Standort mit Zeitzone als Vorschlag, Ortsname mit Trefferliste und Koordinaten, die Anfragen location und withdraw im Meldeprozess und das Lesen der Zeitzone in libnextnet. (3) Klassenfilter in der Liste. (4) Statistik: Gesamt-Uptime, längste Uptime aus der beobachteten Kette, Modellverteilung, Bestenliste über NeXT-Hardware; eine Maschine zählt erst nach sieben beobachteten Tagen und nicht mehr, wenn sie inaktiv ist.Maschinen mit Standort und eine Website mit Filter und StatistikPhase 2
4 Globus(1) /api/v1/markers und die React-Insel mit three-globe. (2) Die Seite /globe mit Legende und Verweis auf die Maschine.Die Weltkarte der MaschinenPhase 3

Backlog, je ein Issue, sobald die Phase davor steht: Fat Binaries für Intel, PA-RISC und SPARC, die native Globus-App, Screenshots der Maschinen.

Die Screenshots der Maschinen laufen so: Der Nutzer löst eine Aufnahme nur mit einem Button in der App aus. Die App liest den Bildschirm, zeigt eine Vorschau mit dem Button Bestätigen und übergibt das Bild erst nach der Bestätigung über den Spool an den Meldeprozess, der es als signiertes POST /v1/screenshot sendet. Die Einwilligung gilt damit für jedes Bild einzeln, und die Vorschau zeigt genau das, was gesendet wird, weil ein Bild des Desktops Personendaten enthalten kann. Ein bestätigtes Bild ist öffentlich auf der Seite der Maschine. Nur die Maschine selbst entfernt es, mit einem signierten POST /v1/screenshot ohne Bild, wie beim Standort. Der Widerruf der Einwilligung löscht es ebenfalls, und eine inaktive Maschine zeigt es nicht.

Der Client schreibt das Bild als TIFF mit 8 Bit je Wert und LZW-Kompression. Die Klasse NXBitmapImageRep liest Bilddaten aus einem gerenderten Bild und schreibt TIFF mit LZW und PackBits;41 sie liest dabei nur das aktuelle Fenster, und wie die App den ganzen Desktop liest, ist offen (Anhang B). Der Client erweitert die Bildpunkte vor dem Schreiben auf 8 Bit je Wert, weil die TIFF-Bibliothek des Servers Graustufen und Farbe nur mit gleichen Tiefen ab 8 Bit liest und LZW und PackBits dekodiert.42 Der Server liest die Maße aus dem Kopf der Datei, lehnt Bilder über 2 MiB oder über 2048 mal 1536 Bildpunkte ab, dekodiert mit der Bibliothek image 0.25.1037 und liefert nur das PNG aus, das er selbst daraus schreibt, nie die gesendeten Bytes. Die Maße prüft er vorab, weil die Grenzen der Bibliothek nicht für jeden Decoder strikt gelten.43 Die 2 MiB liegen über dem, was zu erwarten ist: Ein Bild von 1120 mal 832 Bildpunkten mit 3 Byte je Bildpunkt hat rund 2,8 MB roh,11 und LZW erreicht 2:1 bis 3:1, also rund 0,9 bis 1,4 MB.41 Je Maschine gibt es höchstens ein Bild, ein neues ersetzt das alte, und der Server nimmt höchstens eines je Stunde an.

Quellennachweis

45 Quellen, in der Reihenfolge ihres Auftretens. Die Seiten der NeXTSTEP-Dokumentation und der Archive sind an den genannten Stellen gelesen, die lokalen Dateien vollständig.

  1. NeXT: NEXTSTEP 3.3 Release Notes: What’s New in Release 3.3, Abschnitte Platforms und Interface Builder. Spiegel bei nextop.de. Abschnitte gelesen Quelle↩↩↩
  2. Grabher, A., Schubiger, S., Fétis, G.: Previous 4.5, Stand a8e4b20 vom 28. Oktober 2026, readme.previous.txt und die Quelldateien src/rom.c, src/rtcnvram.c, src/sysReg.c, src/scsi.c, src/configuration.c, src/includes/main.h, src/slirp/ctl.h, src/slirp/ntp.h, src/slirp/slirp.c, src/slirp/rpc/netinfo.c, src/slirp/rpc/vfs.c im Quellbaum unter ~/Developer/Projects/previous. Genannte Dateien gelesen Quelle↩↩↩↩
  3. Peanuts-Archiv: SSLeay Framework 0.9.0 für OPENSTEP 4.2 for Mach, README. Volltext gelesen Quelle↩↩
  4. NeXT/Apple: NeXTanswers 1905, Foundation in NEXTSTEP 3.3. Volltext gelesen Quelle↩↩↩
  5. NeXT/Apple: NeXTanswers 2504, Release Notes OPENSTEP 4.2: Compiler GCC 2.7.2.1, Konvertierung mit tops, Makefiles, NSFileHandle, Architekturen. Abschnitte gelesen Quelle↩↩↩↩↩↩↩
  6. NeXT: Operating System Software, Teil 1 Mach, Kapitel 4: Mach Functions, Einträge host_info(), host_kernel_version(), processor_set_info(). Einträge gelesen Quelle↩↩↩↩
  7. jrra: NeXTstation Color, Protokoll einer Installation von NeXTSTEP 3.3 mit der Ausgabe von hostinfo und des ROM-Monitors. Volltext gelesen Quelle↩↩
  8. NeXT: NeXT Mach kernel, Quelltextstand mk-108.1 (Release 2.0), Spiegel johnsonjh/NeXTMach: next/next_init.c, next/autoconf.c, next/scr.h, mon/nvram.h, mon/global.h, nextif/if_en.c, bsd/kern_xxx.c. Älter als der 3.3-Kernel mk-171.9. Genannte Dateien gelesen Quelle↩↩
  9. NeXT: NEXTSTEP 3.3 Network and System Administration, Kapitel 3 Setting Up the Network, 7 Peripherals, 9 Starting Up and Shutting Down, 15 Troubleshooting. Spiegel bei cilinder.be. Abschnitte gelesen Quelle↩↩
  10. NeXT: NeXTSTEP 3.3 Manual Pages bei man.FreeBSD.org, manpath=NeXTSTEP+3.3: gethostid(2), hostinfo(1), sd(4), sg(4), scsimodes(8), w(1), if(4N), uname(2P), arch(3), loginwindow(8), ttys(5), init(8), lpd(8), mail(1). Seiten gelesen Quelle↩↩↩↩↩↩↩
  11. NeXT: NEXTSTEP 3.3 Developer Documentation, Release Notes Window Server, Eintrag setframebuffertransfer; Application Kit, Types and Constants, Einträge NXScreen und NXWindowDepth; Klassenübersicht des Application Kit, Abschnitt Managing Screens. Einträge gelesen Quelle↩↩↩↩
  12. IEEE: MA-L Public Listing, Eintrag 00000F NEXT, INC. Eintrag geprüft Quelle↩
  13. Grabher, A. u. a.: Previous, networking.howto.txt und filesharing.howto.txt im Quellbaum unter ~/Developer/Projects/previous. Volltext gelesen Quelle↩↩↩
  14. NeXT: Object-Oriented Programming and the Objective C Language, Kapitel 5: Programming in Objective C, Abschnitte The Window Server und The Application Object. Abschnitte gelesen Quelle↩
  15. NeXT: Development Tools, Kapitel 2: The Project Builder Application. Abschnitte gelesen Quelle↩
  16. NeXT: NEXTSTEP 3.3 Release Notes: Project Builder, Projekttyp Tool. Volltext gelesen Quelle↩
  17. NeXT: NEXTSTEP 3.3 Release Notes: Compiler und Fat Files. Volltext gelesen Quelle↩↩
  18. NeXT: Development Tools, Kapitel 11: The GNU C Compiler. Volltext gelesen Quelle↩
  19. NeXT: Object-Oriented Programming and the Objective C Language, Anhang A: Objective C Language Summary. Volltext gelesen Quelle↩
  20. NeXT: Foundation Kit, Introduction. Volltext gelesen Quelle↩
  21. NeXT: Foundation Kit: Living in a Hybrid World. Volltext gelesen Quelle↩
  22. Marcum, A. M.: The NetInfo Lookup Server: lookupd, NEXTSTEP In Focus, Sommer 1993, im Archiv NeXTanswers als Nummer 1275. Abschnitte gelesen Quelle↩
  23. NeXT: Preparing an Application for Installation by the Installer. Volltext gelesen Quelle↩↩
  24. NeXT: NeXTanswers 1987, Ablauf von /etc/rc und /etc/rc.net in 3.3. Volltext gelesen Quelle↩
  25. NeXT: NeXTanswers 1849, Ergänzungen in /etc/rc.local. Abschnitt gelesen Quelle↩
  26. NiCE: Peanuts-Archiv, Verzeichnisse mit lynx, gnumake und gzip für NeXTSTEP, gelesen am 2. November 2026. Verzeichnisse gelesen Quelle↩
  27. NeXT Computer, Inc.: NEXTSTEP, Produktdatenblatt, Spalte „NEXTSTEP for NeXT Computers“ mit CPU- und Speicherangaben, Copyright 1988 bis 1995, Spiegel bei levenez.com. Abschnitt gelesen Quelle↩
  28. rjbrown99: NeXTStep Software Ports, Wiki, OpenSSL 0.9.6m und wget auf NeXTSTEP 3.3. Volltext gelesen Quelle↩
  29. rooprob: OS42ssl, OpenSSL 1.0.2 auf OPENSTEP 4.2, README mit dem fehlgeschlagenen RSA-Test auf m68k. Volltext gelesen Quelle↩
  30. NeXT: NEXTSTEP 3.3 Developer Documentation, Foundation Kit, NSTimeZone Class Cluster, Klassenbeschreibung mit defaultTimeZone, timeZoneName und timeZoneArray. Volltext gelesen Quelle↩
  31. IANA: Time Zone Database, die Dateien zone.tab und backward. Kopf und genannte Einträge gelesen Quelle↩↩
  32. GeoNames: Readme der Datenexporte, die Datei cities5000.zip und die Felder der Tabelle geoname, gelesen am 2. November 2026. Abschnitte gelesen Quelle↩↩
  33. Europäische Union: Verordnung (EU) 2016/679 (Datenschutz-Grundverordnung), Art. 4, 5, 6, 7, 13, 17. Artikel gelesen Quelle↩↩↩↩
  34. Republik Österreich: Datenschutzgesetz (DSG), geltende Fassung im RIS. Fassung geöffnet Quelle↩
  35. Österreichische Datenschutzbehörde. Startseite geöffnet Quelle↩
  36. tokio-rs: axum, Dokumentation auf docs.rs. Startseite gelesen Quelle↩
  37. crates.io: Stände am 2. November 2026: axum 0.8.9, sqlx 0.9.0, tokio 1.54.1, tower-http 0.7.1, hmac 0.13.0, sha2 0.11.1, utoipa 6.0.0, image 0.25.10, tiff 0.11.3; Rust 1.99.1 vom 16. Oktober 2026. Versionen abgefragt Quelle↩↩
  38. Astro: astro.build, Version 7.4.4 auf npm am 2. November 2026. Version geprüft Quelle↩
  39. Turiano, V.: three-globe, Version 2.45.6 auf npm am 2. November 2026. Version geprüft Quelle↩
  40. NeXT: NEXTSTEP 3.3 General Reference, Distributed Objects, Klasse NXConnection, Klassenbeschreibung und die Methoden registerRoot:withName: und connectToName:. Abschnitte gelesen Quelle↩
  41. NeXT: NEXTSTEP 3.3 General Reference, Application Kit, Klasse NXBitmapImageRep, Klassenbeschreibung, initData:fromRect:, initData:pixelsWide:... und writeTIFF:usingCompression:. Volltext gelesen Quelle↩↩
  42. image-rs: image-tiff 0.11.3, README mit den Tabellen der Formate und Kompressionen. Volltext gelesen Quelle↩
  43. image-rs: image 0.25.10, Dokumentation auf docs.rs, Struktur Limits und die Features des Crates. Abschnitte gelesen Quelle↩
  44. NeXT: Development Tools, Kapitel 14: Mach Object Files, CPU-Konstanten. Abschnitt gelesen Quelle
  45. comp.sys.next.hardware: Attempt to setup NeXTstation Color under NS3.2, Boot-Protokoll von NeXT Mach 3.2. Thread gelesen Quelle

Anhang

Fundstellen zu NeXTSTEP und die Prüfpunkte für den ersten Build. Für die Aussagen oben braucht man das hier nicht.

A. Fundstellen zu NeXTSTEP

Tabelle 10 Aussagen über NeXTSTEP und OPENSTEP und ihre Fundstellen
AussageFundstelle
host_info liefert max_cpus, avail_cpus, memory_size, cpu_type, cpu_subtype; nur HOST_BASIC_INFO, HOST_PROCESSOR_SLOTS und HOST_SCHED_INFO sind implementiert; die CPU-Konstanten stehen im Mach-O-KapitelQuelle 6, Eintrag host_info(); Quelle 44
Der Kernel setzt nur CPU_SUBTYPE_MC68030 oder CPU_SUBTYPE_MC68040, obwohl er den Maschinentyp aus dem Steuerregister liestQuelle 8, next/next_init.c:153-154, next/autoconf.c:80-92, next/scr.h:34-61
hostinfo auf 3.3 druckt Processor speed, System type, Board revision; die Handbuchseite von 1989 kennt diese Zeilen nichtQuelle 7, Abschnitt After install; Quelle 10, hostinfo(1)
Boot-Protokoll mit physical memory, SCSI-Zeilen und en0: Ethernet addressQuelle 9, Kapitel 3 und 7; Quelle 45; Quelle 8, next/machdep.c:828-835, nextif/if_en.c:173-182
gethostid() ist 0x01 und die unteren drei Bytes der Ethernet-Adresse; Root kann den Wert mit sethostid ändernQuelle 10, gethostid(2); Quelle 8, next/next_init.c:200-202, bsd/kern_xxx.c:91-98
Kein Ioctl für die Link-Layer-Adresse im Kernel-Quelltext (AF_LINK, sockaddr_dl, SIOCGIFHWADDR fehlen)Quelle 8, net/if.c:309-394
Der NVRAM-Datensatz enthält Ethernet-Adresse, SIMM-Konfiguration, Boot-Kommando und Prüfsumme, aber keine SeriennummerQuelle 8, mon/nvram.h:14-47, mon/global.h:51-121
Platten: DKIOCINFO, DKIOCGLABEL, SDIOCGETCAP; SDIOCSRQ sendet jeden SCSI-Befehl als Superuser; INQUIRY auch über sg(4) als SuperuserQuelle 10, sd(4), sg(4), scsimodes(8)
Bildschirm: NXScreen mit Grenzen und Tiefe; getScreens:count:; Datensätze in NetInfo /localconfig/screensQuelle 11
Jede Anwendung baut beim Start die Verbindung zum Window Server auf; jedes Programm braucht dafür ein Application-ObjektQuelle 14, Abschnitte The Window Server und The Application Object
Spool-Verzeichnisse unter /usr/spool: Druckaufträge in /usr/spool/*, Post in /usr/spool/mailQuelle 10, lpd(8), mail(1)
NXConnection registriert ein Wurzelobjekt mit registerRoot:withName: beim Network Name Server, connectToName: liefert einen Proxy; Wurzel Object, deklariert in remote/NXConnection.hQuelle 40
Ohne PublicWindowServer nimmt der Window Server nur Prozesse an, die vom Workspace abstammen, und wenige Systemprozesse; loginwindow ist das Konsolenprogramm aus /etc/ttys; init startet die Programme aus /etc/ttys erst im Mehrbenutzerbetrieb nach /etc/rcQuelle 10, loginwindow(8), ttys(5), init(8)
Lastwerte aus processor_set_info; w zeigt Uptime und nennt /dev/kmemQuelle 6, Eintrag processor_set_info(); Quelle 10, w(1)
3.3 läuft auf SPARCstation 5, 10, 20, HP 9000 712 bis 755, Intel und NeXTQuelle 1, Abschnitt Platforms
Foundation A’ liegt 3.3 Intel, Motorola, RISC und Developer bei; 3.2 hat keinesQuelle 4
22 Foundation-Klassen in 3.3, libFoundation_s.a, Header unter /NextDeveloper/Headers/foundationQuelle 20; Index der Dokumentation
Zwei Wurzelklassen in 3.3, Object und NSObjectQuelle 21
GCC 2.5.8 in 3.3, GCC 2.7.2.1 in 4.2; Konvertierung von 3.x-Quelltext mit tops in sechs Stufen; Foundation-Code von 3.3 muss für 4.0 neu übersetzt werdenQuelle 17; Quelle 5
cc ist ANSI C mit -ansi, -traditional, -ObjC; Objective-C mit Protokollen, Kategorien, @selector, @encodeQuelle 18; Quelle 19
Fat Binaries mit wiederholbarem -arch; 3.1 nennt m68k und i386Quelle 17, Fat Files
Project Builder ruft make; Makefile.preamble; Projekttyp Tool seit 3.2Quelle 15; Quelle 16
Installer-Paket: .tar.Z, .bom, .info, .sizes; package; post_install; Doppelklick installiertQuelle 23
/etc/rc startet nmserver, rc.net; /etc/rc.local für lokale ErgänzungenQuelle 24; Quelle 25
gethostbyname() ruft lookupd, das NetInfo, DNS, NIS und die Systemdateien in dieser Reihenfolge fragtQuelle 22
NeXT-Rechner mit 68030 und 68040 (25 und 33 MHz): 16 MB Speicher mindestens, 24 MB empfohlenQuelle 27
Die Zeitzone, die der Nutzer in Preferences wählt, ist der Standardwert von NSTimeZone; timeZoneName liefert ihren Namen; die Zeitzonen liegen als Dateien in /etc/zoneinfo; die Namen in der Dokumentation sind US/Pacific und Canada/PacificQuelle 30
zone.tab nennt je Zone einen Punkt, etwa Europe/Vienna +4813+01620; die Datei backward führt alte Namen auf neue zurück, etwa GB-Eire auf Europe/London und MET auf Europe/BrusselsQuelle 31
GeoNames cities5000: Orte mit mehr als 5000 Einwohnern oder dem Merkmal PPLA, rund 50.000 Einträge, mit Name, Koordinaten und LandQuelle 32
NXBitmapImageRep liest Bilddaten aus einem gerenderten Bild im aktuellen Fenster (initData:fromRect:) und schreibt TIFF mit LZW oder PackBits (writeTIFF:usingCompression:); LZW erreicht 2:1 bis 3:1Quelle 41
Die TIFF-Bibliothek tiff 0.11.3 liest Graustufen und Farbe mit gleichen Tiefen ab 8 Bit und dekodiert LZW und PackBitsQuelle 42
Die Bibliothek image 0.25.10 hat die Grenzen max_image_width, max_image_height und max_alloc, die nicht jeder Decoder strikt einhältQuelle 43
Kein TLS von NeXT; SSLeay 0.9.0 für 4.2; OpenSSL 0.9.6m auf 3.3; RSA-Prüfung mit OpenSSL 1.0.2 auf m68k fehlgeschlagenQuelle 3; Quelle 28; Quelle 29
lynx, gnumake und gzip als Fremdpakete; kein curl gefundenQuelle 26
Previous: INQUIRY-Antwort von 54 Bytes; Hersteller Previous, Produkt HDD, Revision B für jedes Abbild, dessen Größe keinem bekannten Laufwerk entspricht; bekannte Laufwerke MAXTOR XT-8380S und XT-8760S, SONY CD-ROM CDU-541, PLI SUPER FLOPPY; keine Einstellung für diese StringsQuelle 2, src/scsi.c:148, :158-161, :188-194, :198-216, :626-636; src/configuration.c:189-233
Previous: ROM-Abbilder mit den Adressen 00:00:0f:00:1a:3d, 00:00:0f:00:30:90, 00:00:0f:00:f3:02, 00:00:0f:12:34:56; eine eigene Adresse nur in den unteren drei BytesQuelle 2, readme.previous.txt:41-49, src/rom.c:19-39, src/configuration.c:526-539
Previous: NVRAM bei jedem Reset ohne Marker aus der Konfiguration gebaut; Systemregister nach den Werten echter MaschinenQuelle 2, src/rtcnvram.c:951-1074, src/sysReg.c:31-82, :180-279
Previous: Hostname previous in der Domain home, NTP-Kennung PREV auf 10.0.2.2, SLiRP-Adressen 52:54:00:12:35:xx, NetInfo-Mount nfs:/ auf /Net; der NFS-Server liefert nur echte Dateien des Hosts; die Versionskonstante Previous 4.5 erreicht keinen emulierten BausteinQuelle 2, src/slirp/ctl.h:1-21, src/slirp/ntp.h:13, src/slirp/slirp.c:17-19, src/slirp/rpc/netinfo.c:424-429, src/slirp/rpc/vfs.c:461-467, src/includes/main.h:16
Previous: Netz ohne Einrichtung ab 3.3, NFS-Freigabe unter /Net, Gateway 10.0.2.2, DNS 10.0.2.3Quelle 13, networking.howto.txt:12-14, :199-226; filesharing.howto.txt:1-3

B. Prüfpunkte für den ersten Build

Jeder Punkt ist auf einem laufenden NeXTSTEP 3.3 zu klären, zuerst im Emulator, dann auf einer echten Maschine. Die Spalte Folge sagt, was im Plan davon abhängt.

Tabelle 11 Prüfpunkte, Prüfung und Folge für den Plan
PrüfpunktPrüfungFolge
Enthalten die Plattenabbilder /NextDeveloper mit Project Builder und cc?ls /NextDeveloper/Apps, cc -vSonst Developer-CD nachinstallieren
Woher nimmt hostinfo Takt, Systemtyp und Board-Revision?hostinfo, dann otool -tv /usr/etc/hostinfo; Vergleich Previous gegen echte Maschine (Previous baut Typ 4 und Revision 0, die echte Turbo meldet 5 und 0xf)Ob der Client den Aufruf nutzt oder die Ausgabe parst
Welche Werte für Takt, Systemtyp und Board-Revision melden echte Maschinen je Modell, und welche Emulatoren?hostinfo auf echten Maschinen und in Previous, je ModellWertemengen der Plausibilitätsprüfung des Servers (Tabelle 4)
Darf ein Prozess ohne Root /usr/adm/messages lesen, und stehen die Boot-Zeilen noch darin?ls -l /usr/adm/messages, erste Zeilen lesenOb der Meldeprozess Root braucht
Welche Werte haben utsname.release, version, machine, und linkt uname() ohne -posix?Testprogramm mit und ohne cc -posixOb uname das Betriebssystem liefert
Gibt es uptime, getloadavg, sysctl, gzip, gnutar?ls /usr/bin /usr/ucb /usr/etc, grep -l sysctl /usr/include/bsd/sys/*.hUptime-Quelle und Form des Downloads
Liefert SIOCGARP oder arp -a die eigene Ethernet-Adresse?TestprogrammEthernet-Adresse ohne Boot-Protokoll
Welche Zahlenwerte haben die Subtypen für Intel, HP und SPARC?/NextDeveloper/Headers/bsd/sys/machine.hArchitekturfeld des Inventars
Was steht in /localconfig/screens einer echten Maschine mit MegaPixel oder Farbmonitor?niutil -read . /localconfig/screensBildschirmfeld des Inventars
Nimmt der 3.3-Compiler die geplante Objective-C-Form und ANSI-Prototypen an, und wie groß wird das Binary?Build der Bibliothek, size und ps im MeldeprozessSpeicherbedarf bei 16 MB
Erreicht der Client aus Previous den Server?nextnetd -once gegen die konfigurierte Basisadresse über SLiRPTestweg vor der echten Maschine
Startet das 3.3-Binary des Meldeprozesses auf dem 4.2-Abbild?Kopieren und ausführenOb ein Build des Meldeprozesses für beide Systeme reicht
Übersetzt die Foundation-Quelle unverändert auf beiden Abbildern?Build von libnextnet gegen libFoundation_s.a und gegen das FrameworkOb die 3.3-Foundation A’ Methoden anders benennt als die von 4.2
Welchen Namen liefert timeZoneName des Standard-Zeitzonenobjekts, und enthält /etc/zoneinfo die Namen aus zone.tab oder backward?Testprogramm mit [[NSTimeZone defaultTimeZone] timeZoneName] nach der Wahl in Preferences, ls /etc/zoneinfoOb der Server die Zeitzone einem Punkt zuordnen kann
Startet /etc/rc.local den Meldeprozess, und überlebt er die Abmeldung?Neustart, ps nach AbmeldungStartmechanismus des Meldeprozesses
Zeigt das Application-Objekt, das hinv kurz anlegt, ein Icon oder einen Eintrag im Workspace?hinv aus dem Terminal, Workspace und Dock beobachtenOb hinv den Bildschirm selbst erhebt oder den letzten Stand der App aus /etc/nextnet/state zeigt
Wie weist der Window Server hinv aus einer telnet-Shell ab, und was schreibt das Application Kit dabei?hinv über telnet auf die MaschineOb das Kind sauber endet oder hinv dessen Ausgabe unterdrücken muss
Liegt /usr/local/bin im Suchpfad der Shells einer frischen Anmeldung?echo $path in der csh eines neuen Terminal-FenstersOb post_install den Pfad ergänzt
Lässt SDIOCSRQ auf dem Boot-Laufwerk als Root eine INQUIRY mit 54 Bytes und die Seite 0xC0 mit EVPD zu?Testprogramm auf dem 3.3-Abbild gegen /dev/rsd0aOb die Klasse über sd(4) kommt oder über sg(4)
Was steht in den Bytes 36 bis 53 der INQUIRY einer echten Platte, und liefert DKIOCINFO den Herstellernamen ohne Root?Testprogramm auf einer echten MaschineOb hinv die Klasse auch ohne Root und ohne nextnetd sieht
Nimmt nextnetd eine Anfrage aus /usr/spool/nextnet/requests binnen drei Sekunden an, und kann der Benutzer me dort ablegen, ohne fremde Dateien zu sehen?Datei als me ablegen, ls -l auf beide Verzeichnisse, Zustand und Antwort lesenModus der Spool-Verzeichnisse und Takt des Meldeprozesses
Wie liest die App den ganzen Desktop, wenn initData:fromRect: nur das aktuelle Fenster liest, und mit welcher Tiefe?Testprogramm in der App, Bild als TIFF schreiben und auf dem Mac öffnenAufnahmeverfahren und Erweiterung auf 8 Bit je Wert für Screenshots