From 04e68443040c7abad84d66477e98f93bed701760 Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Mon, 4 Feb 2019 13:09:03 +0100 Subject: Initial import --- system/net/1.8.7/src/basic net | 1148 +++++++++++++++++++++++++++ system/net/1.8.7/src/net files-M | 5 + system/net/1.8.7/src/net hardware interface | 389 +++++++++ system/net/1.8.7/src/net inserter | 145 ++++ system/net/1.8.7/src/net manager | 797 +++++++++++++++++++ system/net/1.8.7/src/net report | 41 + system/net/1.8.7/src/netz | 20 + system/net/1.8.7/src/port server | 164 ++++ system/net/1.8.7/src/printer server | 99 +++ system/net/1.8.7/src/spool cmd | 112 +++ system/net/1.8.7/src/spool manager | 915 +++++++++++++++++++++ 11 files changed, 3835 insertions(+) create mode 100644 system/net/1.8.7/src/basic net create mode 100644 system/net/1.8.7/src/net files-M create mode 100644 system/net/1.8.7/src/net hardware interface create mode 100644 system/net/1.8.7/src/net inserter create mode 100644 system/net/1.8.7/src/net manager create mode 100644 system/net/1.8.7/src/net report create mode 100644 system/net/1.8.7/src/netz create mode 100644 system/net/1.8.7/src/port server create mode 100644 system/net/1.8.7/src/printer server create mode 100644 system/net/1.8.7/src/spool cmd create mode 100644 system/net/1.8.7/src/spool manager (limited to 'system/net/1.8.7/src') diff --git a/system/net/1.8.7/src/basic net b/system/net/1.8.7/src/basic net new file mode 100644 index 0000000..c5e9278 --- /dev/null +++ b/system/net/1.8.7/src/basic net @@ -0,0 +1,1148 @@ +PACKET basic net DEFINES (* D. Heinrichs *) + (* Version 10 (!) *) (* 18.02.87 *) + nam, (* 03.06.87 *) + max verbindungsnummer, (* *) + neuer start, + neue routen, + packet eingang, + neue sendung, + zeitueberwachung, + verbindung, + loesche verbindung: + +TEXT PROC nam (TASK CONST t): + IF t = collector THEN name (t) + ELIF station (t) <> station (myself) + THEN "** fremd "+text(station(t))+" **" + ELSE name (t) + FI +END PROC nam; + +INT PROC tasknr (TASK CONST t): + IF t = collector THEN maxtasks + ELSE index (t) + FI +END PROC tasknr; + +LET + maxtasks = 127, + maxstat = 127, + max strom = 20, + max strom 1 = 21, + stx = ""2"", + code stx = 2, + error nak = 2, + seiten groesse = 512, + dr verwaltungslaenge = 8, + dr verwaltungslaenge2=10, + openlaenge = 24, + vorspannlaenge = 14, + ack laenge = 12, + min data length = 64, + (* Codes der Verbindungsebene *) + + task id code = 6, + name code = 7, + task info code = 8, + routen liefern code = 9, + + (* Typen von Kommunikationsströmen *) + + send wait = 0, + zustellung = 1, + call pingpong = 2, + call im wait = 3, + call im abbruch = 4, + call in zustellung = 5, + + (*quittungscodes*) + + ok = 0, + von vorne = 1, + wiederhole = 2, + loesche = 3, + beende = 4; + +LET STEUER = + STRUCT ( + INT head, + zwischenziel, + zielrechner, + quellrechner, + strom, + sequenz, + seitennummer, + TASK quelle,ziel, + INT sende code); + +BOUND STEUER VAR open block; + +BOUND STRUCT (STEUER steuer, INT typ, maxseq) VAR info block; + +BOUND STRUCT ( + INT head, + zwischenziel, + zielrechner, + quellrechner, + strom, + sequenz, + seitennummer) VAR vorspann ; + +LET ACK = STRUCT ( + INT head, + zwischenziel, + zielrechner, + quellrechner, + strom, + code); +BOUND ACK VAR ack packet ; +BOUND ACK VAR transmitted ack packet; + +BOUND STRUCT (ROW maxstat INT port, + ROW maxstat INT zwischen) VAR route; + +INT CONST max verbindungsnummer := max strom; +INT VAR codet,net mode, nutzlaenge := data length, + data len via node := data length via node; + +TEXT VAR buffer first; + +DATASPACE VAR work space := nilspace; +DATASPACE VAR transmitted ack space := nilspace; + + +INT VAR pakete pro seite, + pakete pro seite minus 1, + packets per page via node, + packets per page via node minus 1, + datenpacketlaenge via node, + datenpacketlaenge ; + +INT VAR strom; +INT VAR last data := -1; +INT VAR own:=station (myself) , + quit max := 3, + quit zaehler := 3, + own256 := 256*own; +INT CONST stx open := code stx+256*openlaenge, + stx quit := code stx+256*acklaenge; + + STEUER VAR opti; + ROW maxstrom1 STEUER VAR verbindungen; + ROW maxstrom1 DATASPACE VAR netz dr; + ROW maxstrom1 INT VAR zeit, typ, open try; + FOR strom FROM 1 UPTO maxstrom1 REP vdr := nilspace; forget (vdr) PER; + ROW maxstrom INT VAR dr page ; + ROW maxtasks INT VAR alter call; + +.vx : verbindungen (strom). + +vdr: netz dr (strom). + + via node: + vx.zielrechner <= 0 OR vx.quellrechner <= 0 OR + transmit via node OR receive via node. + + transmit via node: + route.zwischen (vx.zielrechner) <> vx.zielrechner AND vx.zielrechner <> own. + + receive via node: + route.zwischen (vx.quellrechner) <> vx.quellrechner AND vx.quellrechner <> own. + +falsche stromnummer: strom < 1 OR strom > maxstrom. + +zielrechner ok: vorspann.zielrechner > 0 AND vorspann.zielrechner <= maxstat. + +quellrechner ok: vorspann.quellrechner > 0 + AND vorspann.quellrechner <= maxstat. + +call aufruf: typ(strom) >= call pingpong. + +alles raus: vx.seitennummer = -1 AND letztes packet der seite . + +letztes packet der seite : +(vx.sequenz AND packets per page minus 1) = packets per page minus 1. + +neue verbindung: code t = open laenge. + +PROC neue routen: + route := old ("port intern"); +END PROC neue routen; + +PROC neuer start (INT CONST empfangsstroeme, mode): + net mode := mode; + strom := 1; + neue routen; + transmitted ack space := nilspace; + workspace := nilspace; + open block := workspace; + info block := workspace; + nutzlaenge := data length; + data len via node := data length via node; + pakete pro seite:= seitengroesse DIV nutzlaenge; + pakete pro seite minus 1 := pakete pro seite -1; + packets per page via node := seitengroesse DIV data len via node; + packets per page via node minus 1 := packets per page via node - 1; + datenpacketlaenge := vorspannlaenge + nutzlaenge; + datenpacketlaenge via node := vorspannlaenge + data len via node; + vorspann := workspace; + ack packet := workspace; + transmitted ack packet := transmitted ack space; + FOR strom FROM 1 UPTO maxstrom1 REP + vx.strom := 0; forget (vdr) + PER; + INT VAR i; + FOR i FROM 1 UPTO maxtasks REP alter call (i) := 0 PER; + quitmax := empfangsstroeme; + own:=station (myself); + quit zaehler := quit max; + own256 := 256*own; + reset box (net mode); + buffer first := ""; + flush buffers; + INT VAR err; + fehlermeldung ruecksetzen. + + fehlermeldung ruecksetzen: + control (12,0,0,err). + +END PROC neuer start; + +DATASPACE PROC verbindung (INT CONST nr): + INT VAR memory := strom; + strom := nr; + infoblock.steuer := verbindungen (nr); + infoblock.typ := typ (nr); + infoblock.maxseq := dspages (netzdr(nr)) * packets per page; + strom := memory; + workspace +END PROC verbindung; + +PROC neue sendung (TASK CONST q,z, INT CONST cod,z stat, DATASPACE CONST dr): + + naechste verbindung vorbereiten; + forget (vdr); vdr := dr; + sendung starten (q, z, z stat, cod) +END PROC neue sendung; + +PROC zeitueberwachung + (INT VAR snr, TASK VAR q, z, INT VAR ant,DATASPACE VAR dr): + snr INCR 1; + FOR strom FROM snr UPTO maxstrom REP zeitkontrolle PER; + snr := 0. + +zeitkontrolle: + IF vx.strom <> 0 AND zeit(strom) > 0 + THEN + zeit(strom) DECR 1; + IF sendung noch nicht zugestellt + THEN + IF zeit(strom) = 0 + THEN + empfangsreport ("Nicht zustellbar. "); + loesche verbindung (strom) + ELSE + snr := strom; + q := vx.quelle; + z := vx.ziel; + ant := vx.sendecode; + dr := vdr; + LEAVE zeitueberwachung + FI + ELIF zeit(strom) = 0 + THEN wiederholen + FI + FI. + +sendung noch nicht zugestellt: + typ (strom) = zustellung. + +wiederholen: + IF sendeeintrag + THEN + sendung wiederholen + ELSE + empfangseintrag freigeben + FI. + +sendeeintrag : vx.quellrechner = own . + +sendung wiederholen: + IF wiederholung noch sinnvoll + THEN + IF frisch + THEN + time out bei open + ELSE + datenteil wiederholen + FI + ELSE + sendung loeschen + FI. + +wiederholung noch sinnvoll: + task noch da AND bei call noch im call. + +task noch da: vx.quelle = collector OR exists (vx.quelle). + +bei call noch im call: + IF call aufruf + THEN + callee (vx.quelle) = vx.ziel + ELSE + TRUE + FI. + +frisch: vx.sequenz = -1. + +time out bei open: + IF vx.sendecode > -4 OR opentry (strom) > 0 + THEN + open wiederholen ; + opentry (strom) DECR 1 + ELSE + nak an quelle senden + FI. + +nak an quelle senden: + dr := nilspace; + BOUND TEXT VAR erm := dr; + erm := "Station "+text(vx.zielrechner)+" antwortet nicht"; + snr := strom; + q := vx.ziel; + z := vx.quelle; + ant := error nak; + sendung loeschen; + LEAVE zeitueberwachung . + +open wiederholen: + sendereport ("wdh open"); + IF opentry (strom) > 0 THEN zeit(strom) := 4 ELSE zeit(strom) := 40 FI; + openblock := vx; + openblock.head := stx open; + ab die post. + +datenteil wiederholen: + sendereport ("wdh data. sqnr "+text (vx.sequenz)); + senden . + +empfangseintrag freigeben: + IF antwort auf call + THEN + weiter warten + ELSE + empfangsreport ("Empfangseintrag freigegeben"); + loesche verbindung (strom) + FI. +antwort auf call: callee (vx.ziel) = vx.quelle. + +weiter warten: zeit (strom) := 400. + +END PROC zeitueberwachung; + +PROC sendereport (TEXT CONST txt): + report (text (strom)+":"+txt+". Absender: """+nam (vx.quelle)+ + """. Ziel "+text(vx.zielrechner) + " Taskindex: " + + text (index (vx.ziel))); +END PROC sendereport; + +PROC empfangsreport (TEXT CONST txt): + report (text (strom)+":"+txt+". Empfänger: """ + +nam (vx.ziel)+""". Quelle "+text (vx.quellrechner) + + " Taskindex: " + text (index (vx.quelle))); +END PROC empfangsreport ; + +PROC sendung loeschen: + strom loeschen (tasknr (vx.quelle)) +END PROC sendung loeschen; + +PROC strom loeschen (INT CONST tasknr): + IF callaufruf CAND alter call (tasknr ) = strom + THEN + alter call (tasknr ) := 0 + FI; + vx.strom := 0; + forget (vdr) +END PROC strom loeschen; + +PROC empfang loeschen: + quit zaehler INCR 1; + strom loeschen (tasknr (vx.ziel)) +END PROC empfang loeschen; + +PROC loesche verbindung (INT CONST nr): + strom := nr; + IF sendeeintrag + THEN + sendung loeschen + ELSE + gegenstelle zum loeschen auffordern; + empfang loeschen + FI. + +gegenstelle zum loeschen auffordern: + IF verbindung aktiv THEN quittieren (-loesche) FI. + +verbindung aktiv: vx.strom > 0. + +sendeeintrag: vx.quellrechner = own . + +END PROC loesche verbindung; + +PROC weiter senden: + IF NOT alles raus + THEN + sequenz zaehlung; + IF neue seite THEN seitennummer eintragen FI; + senden + FI. + +sequenz zaehlung: + vx.sequenz INCR 1. + +neue seite: + IF via node THEN (vx.sequenz AND packets per page via node minus 1) = 0 + ELSE (vx.sequenz AND pakete pro seite minus 1) = 0 + FI. + +seitennummer eintragen: + dr page (strom) := vx.seiten nummer; + vx.seitennummer := next ds page (vdr, dr page (strom)). + + +END PROC weiter senden; + +.packets per page: + + IF via node THEN packets per page via node + ELSE pakete pro seite + FI. + +packets per page minus 1: + IF via node THEN packets per page via node minus 1 + ELSE pakete pro seite minus 1 + FI. + +used length: + + IF via node THEN data len via node + ELSE nutzlaenge + FI. + +PROC senden: + INT VAR nl; + zeit(strom) := 6; + openblock := vx; + nl := used length; + transmit header (workspace); + vorspann senden; + daten senden; + transmit trailer. + +vorspann senden: + blockout (workspace, 1, dr verwaltungslaenge, vorspannlaenge). + +daten senden: + blockout (vdr,dr page (strom),distanz,nl). + +distanz: nl* (vx.sequenz AND packets per page minus 1). + +END PROC senden; + +PROC naechste verbindung vorbereiten: + FOR strom FROM 1 UPTO maxstrom REP + UNTIL vx.strom = 0 PER; + IF vx.strom <> 0 THEN errorstop ("Verbindungsengpass") FI. +END PROC naechste verbindung vorbereiten; + +PROC sendung starten (TASK CONST quelle, ziel, INT CONST code): + sendung starten (quelle,ziel, station(ziel), code) +END PROC sendung starten; + +PROC sendung starten (TASK CONST quelle, ziel, INT CONST ziel station,code): + IF ziel station = own + THEN + report ("Irrläufer: Sendung an eigene Station. Absender:"""+ + nam (quelle)+"""."); + vx.strom := 0; + forget (vdr) + ELSE + openblock.ziel := ziel; + openblock.quelle :=quelle; + openblock.sendecode := code; + openblock.zielrechner:= ziel station; + openblock.quellrechner :=own; + openblock.zwischenziel := route.zwischen (ziel station)+own256; + alten call loeschen (quelle); + IF call oder ping pong + THEN typ (strom) := call pingpong; call merken + ELSE typ (strom) := send wait FI; + sendung neu starten + FI. + +call oder pingpong: openblock.ziel = callee (openblock.quelle). + +call merken: alter call (tasknr (quelle)) := strom. + +END PROC sendung starten; + +PROC encode packet length (INT VAR val): + + IF val < 96 THEN + ELIF val < 160 THEN val DECR 32 + ELIF val < 288 THEN val DECR 128 + ELIF val < 544 THEN val DECR 352 + ELIF val < 1056 THEN val DECR 832 + ELIF val < 2080 THEN val DECR 1824 + FI; + rotate (val, 8) + +ENDPROC encode packet length; + +PROC sendung neu starten: + INT VAR value; + openblock.head:= stx open; + openblock.sequenz := -1; + openblock.seitennummer:= next ds page (vdr,-1); + openblock.strom := strom; + vx := open block; + schnelles nak bei routen liefern; + ab die post; + value := vorspannlaenge + used length; + encode packet length (value); + vx.head:=code stx+value. + +schnelles nak bei routen liefern: + IF openblock.sendecode = -routen liefern code + THEN + openblock.zwischenziel := openblock.zielrechner+own256; + zeit(strom) := 2; + opentry (strom) := 0 + ELSE + zeit (strom) :=8; + opentry (strom) := 2 + FI. + +END PROC sendung neu starten; . + +ab die post: + transmit header (workspace); + block out (work space,1, dr verwaltungslaenge,open laenge); + transmit trailer. + +PROC alten call loeschen (TASK CONST quelle): + IF alter call aktiv + THEN + INT VAR lstrom := strom; + vx:=openblock; + strom := alter call (tasknr (quelle)); + IF in ausfuehrungsphase + THEN + sendereport ("Call-Löschung vorgemerkt"); + loeschung vormerken + ELSE + report ("Call gelöscht."""+nam(quelle)+""". Strom "+text(strom)); + loesche verbindung (strom) + FI; + strom := lstrom; + openblock := vx + FI. + +in ausfuehrungsphase: + typ(strom) = call im wait OR typ (strom) = call in zustellung. + +loeschung vormerken: + typ(strom) := call im abbruch; + alter call (tasknr (quelle)) := 0. + + + alter call aktiv: + alter call (tasknr (quelle)) > 0. + +END PROC alten call loeschen; + +PROC packet eingang + ( INT VAR snr, TASK VAR q, z, INT VAR ant,DATASPACE VAR dr): + snr := 0; + fehlertest; + vorspann holen; + IF NOT ring logik THEN daten teil FI. + +ring logik: FALSE. + +fehlertest: +# + INT VAR c12; + control (12,0,0,c12); + IF c12 <> 0 + THEN + flush buffers; + report ("E/A-Fehler "+text (c12)); + control (12,0,0,c12); + LEAVE packet eingang + FI. + + #. + +vorspann holen: + sync; + IF NOT blockin (workspace, 1, dr verwaltungslaenge2, block laenge) + THEN LEAVE packeteingang + FI. + + +blocklaenge: IF code t > min data length + THEN + vorspannlaenge-2 + ELSE + code t -2 + FI. + +sync: + IF NOT packet start already inspected + THEN + TEXT VAR skipped, t:= ""; + skipped := next packet start; + IF skipped = "" THEN LEAVE packet eingang FI; + t := incharety (1); + code t := code (t); + ELSE + skipped := buffer first; + buffer first := ""; + t := incharety (1); + code t := code (t); + FI; + decode packet length; +IF skipped=stx AND laenge ok THEN LEAVE sync FI; + REP + skipped CAT t; + t := incharety (1); (* next character *) + IF t = "" THEN + report ("skipped",skipped); + LEAVE packet eingang + FI ; + codet := code (t); + UNTIL blockanfang OR length (skipped) > 200 PER; + decode packet length; + IF skipped <> stx THEN report ("skipped bei sync:", skipped) FI. + +decode packet length: + +IF code t < 96 THEN + ELIF code t < 128 THEN code t INCR 32 + ELIF code t < 160 THEN code t INCR 128 + ELIF code t < 192 THEN code t INCR 352 + ELIF code t < 224 THEN code t INCR 832 + ELIF code t < 256 THEN code t INCR 1824 +FI. + +packet start already inspected: buffer first <> "". + +blockanfang: + (skipped SUB length(skipped)) = stx AND laenge ok. + +laenge ok: + (codet = datenpacketlaenge OR codet = datenpacketlaenge via node + OR codet = ack laenge OR code t = openlaenge). + +zielnummer: vorspann.zielrechner. + +daten teil: + IF zielnummer = own + THEN + ziel erreicht (openblock,snr,q,z,ant,dr) + ELSE + weiter faedeln + FI. + +weiter faedeln: + INT VAR value; + IF zielrechner ok + THEN + IF neue verbindung + THEN + IF (openblock.sendecode = -routenlieferncode) OR NOT route ok + THEN LEAVE packet eingang + FI + FI; + value := code t; + encode packet length (value); + vorspann.head := code stx + value; + vorspann.zwischenziel := own256 + route.zwischen (vorspann.zielrechner); + nutzdaten einlesen; + dr := workspace; + snr := 1000; + ant := zielnummer + FI. + +nutzdaten einlesen: + IF code t > data len via node + THEN + IF NOT blockin (workspace, 1, drverwaltungslaenge+vorspannlaenge, data len via node) + THEN + LEAVE packeteingang + FI; + IF NOT next packet ok THEN LEAVE packeteingang FI + FI. + +END PROC packet eingang; + +PROC ziel erreicht (STEUER CONST prefix, + INT VAR snr, TASK VAR q, z, INT VAR ant,DATASPACE VAR dr): + last data := -1; + IF NOT quellrechner ok + THEN + report ("Quellrechner "+text(prefix.quellrechner)); + LEAVE ziel erreicht + FI; + IF neue verbindung + THEN + IF NOT route ok OR NOT quelltask ok + THEN report ("verbotene Route: " + text (prefix.quellrechner)); + LEAVE ziel erreicht + FI; + verbindung bereitstellen + ELIF quittung + THEN + strom := ack packet.strom; + IF falsche stromnummer THEN report ("Strom falsch in Quittung"); + LEAVE ziel erreicht FI; + IF vx.strom = 0 THEN LEAVE ziel erreicht FI; + IF ackpacket.code >= ok THEN weiter senden + ELIF NOT route ok THEN + sendereport ("verbotene Route bei Quittung"); + LEAVE ziel erreicht + ELIF ackpacket.code = -von vorne THEN + sendereport ("Neustart"); + openblock := vx; + sendung neu starten + ELIF ackpacket.code = -wiederhole THEN back 16 + ELIF ackpacket.code = -loesche THEN fremdloeschung + ELIF ackpacket.code = -beende AND alles raus THEN strom abschliessen + FI + ELIF verbindung festgestellt + THEN + zeit(strom) := 400; + opti := vx; + datenpacket + ELSE + strom := maxstrom1; + vx:=prefix; + report ("Daten ohne Eroeffnung von " +text(prefix.quellrechner) + +" Sequenznr "+text(prefix.sequenz)); + daten entfernen (used length); + IF alles raus THEN quittieren (-beende) ELSE quittieren(-von vorne) FI + FI. + +quelltask ok: + prefix.quelle = collector OR antwort auf routen liefern + OR station (prefix.quelle) = prefix.quellrechner. + +antwort auf routen liefern: prefix.quelle = myself. + +verbindung bereitstellen: + IF (prefix.sendecode < 0 OR station (prefix.ziel) = own) + AND quellrechner ok + THEN + freie verbindungsnummer; + vdr := nilspace; + vx := open block; + zeit(strom) := 30; + quittieren falls genug pufferplatz; + vx.sequenz := 0 ; + opti := vx; + dr page (strom) :=-2; + IF abschluss THEN rueckmeldung FI + FI. + +loeschung vorgemerkt: typ(strom) = call im abbruch. + +strom abschliessen: + IF call aufruf + THEN + wdh data vor ablauf der zustellversuche bei der gegenstation; + ausfuehrungsphase merken + ELSE + wdh data sperren + FI. + +wdh data sperren: + zeit (strom) := 12000. + +wdh data vor ablauf der zustellversuche bei der gegenstation: + zeit (strom) := 80. + +ausfuehrungsphase merken: typ(strom) := call in zustellung. + +back16: + datenraum etwas rueckspulen; + opentry (strom) := 2; + nicht sofort senden (* wegen vagabundierender Quittungen *). + +nicht sofort senden: zeit(strom) := 2. + +datenraum etwas rueckspulen: + INT VAR pps := packets per page ; + sendereport ("etwas rueckgespult"); + INT VAR vs :=-1; + dr page (strom) := -1; + INT VAR i; + FOR i FROM 1 UPTO vx.sequenz DIV pps - etwas REP + vs INCR pps; + dr page (strom) := next ds page (vdr, dr page (strom)) + PER; + vx.seiten nummer := next ds page (vdr, dr page (strom)) ; + vx.sequenz := vs. + +etwas: 3. + +fremdloeschung: + IF fremdrechner ok und sendung + THEN + IF typ (strom) = call in zustellung + THEN + typ (strom) := call im wait + ELSE + IF NOT alles raus + THEN + sendereport ("Sendung von Gegenstelle geloescht") + FI; + sendung loeschen + FI + FI. + +fremdrechner ok und sendung: + ackpacket.quellrechner = vx.zielrechner . + + +quittieren falls genug pufferplatz: + IF quit zaehler > 0 THEN + quit zaehler DECR 1; + open quittieren; + block vorab quittieren + ELSE + quittieren (-wiederhole) + FI. + +open quittieren: quittieren (ok). +block vorab quittieren: + IF prio (myself) < 3 THEN quittieren (ok) FI. + +quittung: code t <= ack laenge. + + +verbindung festgestellt: + FOR strom FROM maxstrom DOWNTO 1 REP + IF bekannter strom + THEN LEAVE verbindung festgestellt WITH TRUE FI + PER; + FALSE. + +bekannter strom: + vx.strom = prefix.strom AND vom selben rechner. + +vom selben rechner: + vx.quellrechner = prefix.quellrechner. + +daten: + IF neue seite da THEN check for valid pagenr; + dr page(strom) := prefix.seitennummer; + ELIF prefix.seitennummer < dr page(strom) + THEN empfangsreport ("Falsche Seitennummer, Soll: " + + text(drpage(strom)) + " ist: " + + text (prefix.seitennummer) + + " bei Sequenznr: " + + text(prefix.sequenz)); + flush buffers; + quittieren (- wiederhole); + LEAVE ziel erreicht + FI; + sequenz zaehlung; + IF neue seite kommt + THEN + vx.seiten nummer := prefix.seiten nummer; + dr page(strom) := prefix.seitennummer; + FI; + quittieren(ok); + IF NOT blockin (vdr, opti.seiten nummer, distanz, nl) + COR NOT next packet ok + THEN quittieren (-wiederhole); + LEAVE ziel erreicht + FI; + last data := strom. + +check for valid pagenr: + IF prefix.seitennummer < dr page(strom) AND prefix.seitennummer > -1 + THEN report ("Absteigende Seitennummern, alt: " + text(drpage(strom))+ + " neu: "+ text(prefix.seitennummer) + " Seq.nr: " + + text(vx.sequenz) ) ; + flush buffers; + quittieren (- von vorne); + LEAVE ziel erreicht; + FI. + +datenpacket: + INT VAR nl := used length; + INT VAR pps1 := packets per page minus 1; + IF sendung wartet auf zustellung THEN auffrischen ELSE daten holen FI. + +sendung wartet auf zustellung: typ (strom) = zustellung. + +auffrischen: zeit (strom) := 200; daten entfernen (nl). + +daten holen: + IF opti.sequenz >= prefix.sequenz AND opti.sequenz < prefix.sequenz+100 + AND prefix.sequenz >= 0 + THEN + IF opti.sequenz <> prefix.sequenz + THEN empfangsreport ("Sequenzreset von "+text(opti.sequenz)+" auf "+ + text (prefix.sequenz)); + vx.sequenz := prefix.sequenz; + IF pagenumber ok + THEN dr page (strom) := prefix.seitennummer + ELSE empfangsreport ("Blocknummer falsch, neu: "+ + text (prefix.seitennummer) + ", alt : " + + text (drpage(strom)) ); + FI; + vorabquittung regenerieren + FI; + daten ; + IF abschluss THEN rueckmeldung FI; + ELSE + empfangsreport ("Sequenzfehler: soll "+text(vx.sequenz)+" ist "+ + text(prefix.sequenz)); + quittieren (-wiederhole); + daten entfernen (nl) + FI. + +pagenumber ok: + dr page (strom) >= prefix.seitennummer . + +rueckmeldung: + snr := strom; + q := vx.quelle; + z := vx.ziel; + ant := vx.sendecode; + dr := vdr; + LEAVE ziel erreicht. + +vorabquittung regenerieren: + IF prio (myself) < 3 + THEN + quittieren (ok) + FI. + +distanz: (opti.sequenz AND pps1 ) * nl. + +sequenz zaehlung: + vx.sequenz INCR 1. + +neue seite da: + neue seite kommt. + +neue seite kommt: +(vx.sequenz AND pps1) = 0. + +freie verbindungsnummer: + INT VAR h strom :=maxstrom1, cstrom := 0; + FOR strom FROM 1 UPTO maxstrom REP + IF vx.strom = 0 THEN h strom := strom ; + typ(strom) := send wait + ELIF bekannter strom + THEN empfangsreport ("Reopen"); + quit zaehler INCR 1; + IF typ (strom) = zustellung THEN typ (strom) := send wait FI; + forget (vdr); + LEAVE freie verbindungsnummer + ELIF antwort auf call + THEN + IF loeschung vorgemerkt + THEN + vx := prefix; + loesche verbindung (strom); + LEAVE ziel erreicht + FI; + cstrom := strom; + typ (strom) := call pingpong; + forget (vdr); + FI + PER; + IF cstrom > 0 THEN strom := cstrom ELSE strom := h strom FI; + IF strom = maxstrom1 THEN + vx:=prefix; + empfangsreport ("Verbindungsengpass"); + quittieren (-wiederhole); + LEAVE ziel erreicht + FI. + +antwort auf call: + prefix.sendecode >= 0 AND + call aufruf AND vx.quelle = prefix.ziel AND vx.ziel = prefix.quelle. + +END PROC ziel erreicht; + +PROC daten entfernen (INT CONST wieviel): + BOOL VAR dummy ; + dummy:=blockin (workspace, 2, 0, wieviel) +END PROC daten entfernen; + +BOOL PROC route ok: + INT VAR zwischenquelle := vorspann.zwischenziel DIV 256, + endquelle := vorspann.quellrechner; + zwischenquelle abgleichen; + endquelle abgleichen; + TRUE. + +zwischenquelle abgleichen: + IF NOT zwischenroute gleich + THEN + IF NOT zwischenabgleich erlaubt THEN LEAVE route ok WITH FALSE FI; + route.port (zwischenquelle) := channel; + route.zwischen (zwischenquelle) := zwischenquelle; + abgleich (zwischenquelle, zwischenquelle) + FI. + +zwischenabgleich erlaubt: route.port (zwischenquelle) < 256. + +endquelle abgleichen: + IF NOT endroute gleich + THEN + IF NOT endabgleich erlaubt THEN LEAVE route ok WITH FALSE FI; + route.port (endquelle) := channel; + route.zwischen (endquelle) := zwischenquelle; + abgleich (endquelle, zwischenquelle) + FI. + +endabgleich erlaubt: route.port (endquelle) < 256. + +zwischenroute gleich: + (route.port (zwischenquelle) AND 255) = channel + AND + route.zwischen (zwischenquelle) = zwischenquelle. + +endroute gleich: + (route.port (endquelle) AND 255) = channel + AND + route.zwischen (endquelle) = zwischenquelle. + +END PROC route ok; + +BOOL PROC abschluss: + + last data := -1; + IF neue seite kommt AND vx.seiten nummer = -1 + THEN + quittieren (-beende); + an ziel weitergeben + ELSE + FALSE + FI. +neue seite kommt: +(vx.sequenz AND packets per page minus 1) = 0. + +an ziel weitergeben: + IF tasknummerfrage THEN taskfrage beantworten ;pufferplatz ; FALSE + ELIF tasknamenfrage THEN name senden ;pufferplatz ; FALSE + ELIF taskinfofrage THEN task info senden;pufferplatz ; FALSE + ELIF routenfrage THEN routen senden; pufferplatz; FALSE + ELSE senden ; TRUE + FI. + +pufferplatz : quitzaehler INCR 1 . + +senden: + IF callaufruf + THEN + ein versuch (* bei Antwort auf Call muß ein Zustellversuch reichen *) + ELSE + max 100 versuche; + typ (strom) := zustellung + FI. + +tasknummerfrage:opti.sendecode = -taskid code. + +tasknamenfrage: opti.sendecode = -name code. + +taskinfofrage: opti.sendecode = -task info code. + +routenfrage: opti.sendecode = -routen liefern code. + +max 100 versuche: zeit(strom) := 100. + +ein versuch: zeit (strom) := 1. + +taskfrage beantworten: + disable stop; + BOUND TEXT VAR tsk := vdr; + TEXT VAR save tsk := tsk; + forget (vdr); vdr := nilspace; + BOUND TASK VAR task id := vdr; + task id := task(save tsk); + IF is error THEN + clear error; enable stop; + forget (vdr); vdr := nilspace; + BOUND TEXT VAR errtxt := vdr; + errtxt := text(own)+"/"""+save tsk+""" gibt es nicht"; + sendung starten (collector, opti.quelle, 2) + ELSE + enable stop; + sendung starten (collector, opti.quelle, 0) + FI. + +name senden: + quittieren (-loesche); + forget (vdr); vdr := nilspace; + tsk := vdr; + tsk := nam (opti.ziel); + sendung starten (collector, opti.quelle, 0). + +routen senden: + forget (vdr); vdr := old ("port intern"); + sendung starten (opti.ziel, opti.quelle, 0). + +task info senden: + disable stop; + BOUND INT VAR ti code := vdr; + INT VAR ti cd := ti code; + forget (vdr); vdr := nilspace; + FILE VAR task inf := sequential file (output,vdr); + head line (task inf,"Station "+text(own)); + task info (ti cd, task inf); + IF is error + THEN + forget (vdr); vdr := nilspace; + errtxt := vdr; + errtxt := errormessage; + clear error; + sendung starten (collector, opti.quelle, 2) + ELSE + sendung starten (collector,opti.quelle,0) + FI; + enable stop +END PROC abschluss ; + +PROC quittieren(INT CONST code) : + INT VAR quell := vx.quellrechner ; + transmitted ackpacket := ACK:(stx quit, route.zwischen (quell)+own256, quell, own, + vx.strom, code); + transmit header (transmitted ack space); + blockout (transmitted ack space,1,dr verwaltungslaenge, ack laenge); + transmit trailer; +END PROC quittieren; + +BOOL PROC next packet ok: + buffer first := next packet start; + buffer first = "" COR normal packet start. + +normal packet start: + IF buffer first = stx + THEN + TRUE + ELSE + buffer first := ""; flush buffers; FALSE + FI. + +END PROC next packet ok; +END PACKET basic net; + + diff --git a/system/net/1.8.7/src/net files-M b/system/net/1.8.7/src/net files-M new file mode 100644 index 0000000..ae6f9f3 --- /dev/null +++ b/system/net/1.8.7/src/net files-M @@ -0,0 +1,5 @@ +net report +net hardware interface +basic net +net manager + diff --git a/system/net/1.8.7/src/net hardware interface b/system/net/1.8.7/src/net hardware interface new file mode 100644 index 0000000..4e3466a --- /dev/null +++ b/system/net/1.8.7/src/net hardware interface @@ -0,0 +1,389 @@ +PACKET net hardware + +(************************************************************************) +(**** Netzprotokoll Anpassung *) +(**** Komplette Version mit BUS Anpassung 10.06.87 *) +(**** mit I/0 Controls fuer integrierte Karten *) +(**** Verschiedene Nutztelegrammgrössen *) +(**** Version: GMD 2.0 A.Reichpietsch *) +(************************************************************************) + + DEFINES + blockin, + blockout, + set net mode, + net address, + mode text, + data length, + data length via node, + decode packet length, + next packet start, + flush buffers, + transmit header, + transmit trailer, + version, + reset box, + max mode, + net mode: + + + + + LET eak prefix laenge = 6, + packet length before stx = 14 (*eth header =14 *), + maximum mode nr = 12, + stx = ""2"", + niltext = "", + null = "0", + hex null = ""0"", + blank = " ", + eak prefix = ""0""0""0""0"", + typefield = "EU", + prefix adresse = "BOX", + second prefix adresse = ""0"BOX", + second address type bound = 90; + + INT CONST data length via node :: 64; + TEXT CONST version :: "GMD 2.0 (10.6.87)"; + + + TEXT VAR own address; + INT VAR paketlaenge, eumel paket laenge, mode, rahmenlaenge, actual data length; + +BOOL PROC blockin (DATASPACE VAR ds, INT CONST seite, abstand, laenge): + INT VAR hilfslaenge:=laenge, code:= abstand+laenge+512; + REAL VAR time out := clock (1) + 10.0; + REP + blockin (ds,seite,code-hilfslaenge, hilfslaenge, hilfslaenge); + UNTIL hilfslaenge = 0 OR clock (1) > time out PER ; + IF hilfslaenge <> 0 + THEN report ("blockin abbruch, fehlende Zeichen: "+text(hilfslaenge)); + FI; + hilfslaenge = 0 +END PROC blockin; + +PROC blockout (DATASPACE CONST ds, INT CONST seite, abstand, laenge): + INT VAR hilfslaenge:=laenge, code:= abstand+laenge+512; + REP + blockout (ds,seite,code-hilfslaenge, hilfslaenge, hilfslaenge); + UNTIL hilfslaenge = 0 PER +END PROC blockout; + +PROC set net mode (INT CONST new mode): + mode := new mode ; + own address := net address (station(myself)); + SELECT mode OF + CASE 1,3 : set data length (64); + CASE 2 : std framelength; set data length (64) + CASE 4,6 : set data length (128) + CASE 5 : std framelength; set data length (128) + CASE 7,9 : set data length (256) + CASE 8 : std framelength; set data length (256) + CASE 10,12 : set data length (512) + CASE 11 : std framelength; set data length (512); + + OTHERWISE + END SELECT. + + std framelength: + rahmenlaenge := eak prefix laenge + packet length before stx. + +ENDPROC set net mode; + +INT PROC max mode: + maximum mode nr +ENDPROC max mode; + +INT PROC net mode: + mode +ENDPROC net mode; + +TEXT PROC mode text: + mode text (mode) +ENDPROC mode text; + +TEXT PROC mode text (INT CONST act mode): + SELECT act mode OF + CASE 1: "Modus: (1) EUMEL-Netz 64 Byte" + CASE 2: "Modus: (2) ETHERNET via V.24 64 Byte" + CASE 3: "Modus: (3) ETHERNET integrated 64 Byte" + CASE 4: "Modus: (4) EUMEL-Netz 128 Byte" + CASE 5: "Modus: (5) ETHERNET via V.24 128 Byte" + CASE 6: "Modus: (6) ETHERNET integrated 128 Byte" + CASE 7: "MODUS: (7) EUMEL-Netz 256 Byte" + CASE 8: "MODUS: (8) ETHERNET via V.24 256 Byte" + CASE 9: "MODUS: (9) ETHERNET integrated 256 Byte" + CASE 10: "MODUS: (10) EUMEL-Netz 512 Byte" + CASE 11: "MODUS: (11) ETHERNET via V.24 512 Byte" + CASE 12: "MODUS: (12) ETHERNET integrated 512 Byte" + OTHERWISE errorstop ("Modus " + text(mode) + " gibt es nicht"); + error message + END SELECT + +ENDPROC mode text; + +PROC set data length (INT CONST new data length): + actual data length := new data length +ENDPROC set data length; + +INT PROC data length: + actual data length +ENDPROC data length; + +PROC reset box (INT CONST net mode): + SELECT net mode OF + CASE 1,4,7,10 : eumel net box reset + CASE 2,5,8,11 : eak reset + OTHERWISE controler reset + END SELECT. + + eumel net box reset: + out (90*""4""); + REP UNTIL incharety (1) = niltext PER. + + eak reset: + out ("E0"13"E0"13""). + + controler reset: + INT VAR dummy; + control (-35, 0,0,dummy); + control (22,0,0,dummy). + +ENDPROC reset box; + +PROC remove frame + (TEXT VAR erstes zeichen vom eumel telegramm, BOOL VAR kein telegramm da): + kein telegramm da := FALSE; + SELECT net mode OF + CASE 2,5,8,11 : remove ethernet frame + (erstes zeichen vom eumel telegramm, kein telegramm da) + OTHERWISE + END SELECT; +ENDPROC remove frame; + +PROC remove ethernet frame (TEXT VAR string, BOOL VAR schrott): + TEXT VAR speicher, t; + INT VAR lg; + + t := string; + speicher := niltext; + WHILE kein stx da REP + lies zeichen ein; + teste auf timeout; + UNTIL textoverflow PER; + melde eingelesene zeichen. + + lies zeichen ein: + speicher CAT t; + t := incharety (1). + + teste auf timeout: + IF t = niltext THEN schrott := (speicher <> niltext) + CAND not only fill characters; + string := niltext; + LEAVE remove ethernet frame + FI. + + not only fill characters: + pos (speicher, ""1"", ""254"",1) <> 0. + + kein stx da : + t <> stx. + + textoverflow: + length (speicher) > 1000. + + melde eingelesene zeichen: + IF kein stx da + THEN kein eumeltelegrammanfang + ELSE untersuche ethernet header + FI. + + kein eumeltelegrammanfang: + report ("skipped ,fehlendes ,letztes Zeichen:", t); + string := t; + schrott := TRUE. + + untersuche ethernet header: + string := t; + IF ethernet header inkorrekt + THEN melde fehler + FI. + + ethernet header inkorrekt: + lg := length (speicher); + packet zu kurz COR adresse falsch. + + packet zu kurz: + lg < packet length before stx. + + adresse falsch: + INT VAR adrpos := pos (speicher, own address); + zieladresse falsch COR adresse nicht an der richtigen pos . + + zieladresse falsch: + adrpos < 1. + + adresse nicht an der richtigen pos: + adrpos <> lg - packet length before stx + 1. + + melde fehler: + report ("Header inkorrekt eingelesen: ", speicher + t); + string := t; + schrott := TRUE. + +ENDPROC remove ethernet frame; + +TEXT PROC next packet start: + + TEXT VAR t := niltext; + BOOL VAR schrott := FALSE; + + t:= incharety (1); + IF t = niltext THEN LEAVE next packet start WITH niltext + ELSE remove frame (t, schrott) + FI; + IF schrott THEN no stx or niltext + ELSE t + FI. + + no stx or niltext: + IF t = stx THEN "2" + ELIF t = niltext THEN "0" + ELSE t + FI. + +ENDPROC next packet start; + +PROC flush buffers: + REP UNTIL incharety (5) = niltext PER; + report ("buffers flushed"); +ENDPROC flush buffers; + +PROC transmit header (DATASPACE CONST w): + BOUND INT VAR laengeninformation := w; + eumel paket laenge := laengeninformation ; + decode packet length (eumel paket laenge); + SELECT net mode OF + CASE 1,4,7,10 : + CASE 2,5,8,11 : eak und eth header senden (w) + OTHERWISE : telegrammanfang melden; + std ethernet header senden (w) + END SELECT; + +ENDPROC transmit header; + +PROC decode packet length (INT VAR decoded length): + + decoded length DECR 2; + rotate (decoded length, 8); + + IF decoded length < 96 THEN + ELIF decoded length < 128 THEN decoded length INCR 32 + ELIF decoded length < 160 THEN decoded length INCR 128 + ELIF decoded length < 192 THEN decoded length INCR 352 + ELIF decoded length < 224 THEN decoded length INCR 832 + ELIF decoded length < 256 THEN decoded length INCR 1824 + FI; + +ENDPROC decode packet length; + +PROC transmit trailer: + INT VAR dummy; + SELECT net mode OF + CASE 3,6,9,12 : control (21,0,0,dummy) + OTHERWISE + END SELECT. + +ENDPROC transmit trailer; + +PROC std ethernet header senden (DATASPACE CONST x): + TEXT VAR eth adresse, ethernet kopf := niltext; + INT VAR adresse; + BOUND STRUCT (INT head, zwischennummern) VAR header := x; + zieladresse holen; + zieladresse senden; + quelladresse senden; + typfeld senden; + ausgeben. + + zieladresse holen: + adresse := header.zwischennummern AND 255; + eth adresse := net address (adresse). + + zieladresse senden: + ethernetkopf CAT eth adresse. + + quelladresse senden: + ethernetkopf CAT own address. + + typfeld senden: + ethernetkopf CAT typefield. + + ausgeben: + out (ethernetkopf). + +ENDPROC std ethernet header senden; + +PROC telegrammanfang melden: + INT VAR dummy; + control (20,eumel paket laenge + packet length before stx,0, dummy). + +ENDPROC telegrammanfang melden; + +PROC eak und eth header senden (DATASPACE CONST x): + TEXT VAR res:= niltext; + + neue laenge berechnen; + eak kopf senden; + std ethernet header senden (x). + + neue laenge berechnen: + paket laenge := rahmenlaenge + eumel paket laenge. + + eak kopf senden: + res := code (paket laenge DIV 256); + res CAT (code (paket laenge AND 255)); + res CAT eak prefix; + out(res). + +ENDPROC eak und eth header senden; + +TEXT PROC net address (INT CONST eumel address): + TEXT VAR res ; + INT VAR low byte; + +SELECT mode OF + CASE 1,4,7,10 : eumel net address + OTHERWISE ethernet address +END SELECT. + +eumel net address: + text(eumel address). + +ethernet address: + IF second adress kind THEN second eth header + ELSE first eth header + FI; + res. + + second adress kind: + eumel address = 34 COR + eumel address > second address type bound. + + second eth header: + low byte := eumel address AND 255; + res := second prefix adresse + code (low byte); + res CAT hex null. + + first eth header: + res := prefix adresse + text (eumel address, 3); + changeall (res, blank, null). + +ENDPROC net address; + +ENDPACKET net hardware; + + + + diff --git a/system/net/1.8.7/src/net inserter b/system/net/1.8.7/src/net inserter new file mode 100644 index 0000000..c89d0f0 --- /dev/null +++ b/system/net/1.8.7/src/net inserter @@ -0,0 +1,145 @@ +(*************************************************************************) +(*** Insertiert alle notwendigen Pakete, die zum Betrieb des Netzes ***) +(*** notwendig sind. ***) +(*** Berücksichtigt nur EUMEL - Versionen ab 1.8.1, sowie ***) +(*** Multi-User-Version ***) +(*** ***) +(*** ***) +(*** 23.05.87 ar ***) +(*************************************************************************) + +LET netfile = "netz", + multi files = "net files/M"; + + +INT CONST version :: id (0); +THESAURUS VAR tesa; + +head; +IF no privileged task + THEN errorstop (name (myself) + " ist nicht privilegiert!") + ELIF station number wrong + THEN errorstop ("'define station' vergessen ") +FI; + +IF version < 181 THEN versionsnummer zu klein + ELSE install net +FI. + +no privileged task: + NOT (myself < supervisor). + +station number wrong: + station (myself) < 1. + +install net : + IF NOT exists (netfile) + THEN errorstop ("Datei " + netfile +" existiert nicht") + FI; + IF is multi THEN insert multi net + ELSE errorstop ("Diese Netzversion ist nur für Multi-user Versionen freigegeben") + FI; + forget ("net install", quiet); + net start. + +net start : + say line (" "); + do ("start"); + do ("global manager (PROC (DATASPACE VAR, INT CONST, INT CONST, TASK CONST) + net manager)"). + +is multi : + (pcb(9) AND 255) > 1. + +insert multi net : + hole dateien vom archiv; + insert say and forget (tesa). + +hole dateien vom archiv : + fetch if necessary (multi files); + tesa := ALL (multi files); + forget (multi files, quiet); + fetch if necessary (tesa - all); + say line (" "); + say line ("Archiv-Floppy kann entnommen werden."); + release (archive). + + +head : + IF online THEN page; + put center (" E U M E L - Netz wird installiert."); + line; + put center ("----------------------------------------"); + line (2) + FI. + +versionsnummer zu klein : + errorstop ("Netzsoftware erst ab Version 1.8.1 insertierbar !"). + +PROC fetch if necessary (TEXT CONST datei) : + IF NOT exists (datei) THEN say line ("Loading """ + datei + """..."); + fetch (datei, archive) + FI. +END PROC fetch if necessary; + +PROC fetch if necessary (THESAURUS CONST tes) : + do (PROC (TEXT CONST) fetch if necessary, tes) +END PROC fetch if necessary; + +PROC insert say and forget (TEXT CONST name of packet): + IF online THEN INT VAR cx, cy; + put ("Inserting """ + name of packet + """..."); + get cursor (cx, cy) + FI; + insert (name of packet); + IF online THEN cl eop (cx, cy); line FI; + forget (name of packet, quiet) +END PROC insert say and forget; + +PROC insert say and forget (THESAURUS CONST tes): + do (PROC (TEXT CONST) insert say and forget, tes) +END PROC insert say and forget; + +PROC put center (TEXT CONST t): + put center (t, xsize); +END PROC put center; + +PROC put center (INT CONST zeile, TEXT CONST t): + put center (zeile, t, xsize); +END PROC put center; + +PROC put center (TEXT CONST t, INT CONST gesamtbreite): + INT VAR cy; + get cursor (cy, cy); + put center (cy, t, gesamtbreite) +END PROC put center; + +PROC put center (INT CONST zeile, TEXT CONST t, INT CONST gesamtbreite): + cursor ((gesamtbreite - length (t)) DIV 2, zeile); + put (t). +END PROC put center; + +PROC cl eol: + out (""5"") +END PROC cl eol; + +PROC cl eop: + out (""4"") +END PROC cl eop; + +PROC cl eol (INT CONST cx, cy): + cursor (cx, cy); + cl eol +END PROC cl eol; + +PROC cl eop (INT CONST cx, cy): + cursor (cx, cy); + cl eop +END PROC cl eop; + +PROC say line (TEXT CONST t): + IF online THEN put line (t) FI +ENDPROC say line; + + + diff --git a/system/net/1.8.7/src/net manager b/system/net/1.8.7/src/net manager new file mode 100644 index 0000000..05f530e --- /dev/null +++ b/system/net/1.8.7/src/net manager @@ -0,0 +1,797 @@ +PACKET net manager DEFINES stop,net manager,frei, routen aufbauen, + (* 175 net manager 8 (!) *) + start, + definiere netz, + aktiviere netz, + list option, + erlaube, sperre, starte kanal, routen: + +TEXT VAR stand := "Netzsoftware vom 10.06.87 "; + (*Heinrichs *) +LET + maxstat = 127, + ack = 0, +(* nak = 1, *) + error nak = 2, +(* zeichen eingang = 4, *) + list code = 15, +(* fetch code = 11, *) + freigabecode = 29, + tabellencode = 500, + continue code = 100, + erase code = 14, + report code = 99, + abgleichcode = 98, + neue routen code = 97, + dr verwaltungslaenge = 8, + + (* Codes der Verbindungsebene *) + + task id code = 6, + name code = 7, + task info code = 8, + routen liefern code = 9, + + (* Weitergabecodes für Netzknoten *) + + route code = 1001, + out code = 1003, + + (* Typen von Kommunikationsströmen *) + + zustellung = 1, + call im wait = 3, + call im abbruch = 4, + call in zustellung = 5; + +LET STEUER = + STRUCT ( + INT head, + zwischenziel, + zielrechner, + quellrechner, + strom, + INT sequenz, + seiten nummer, + TASK quelle,ziel, + INT sende code); + +LET INFO = STRUCT (STEUER steuer, INT typ,maxseq); + +LET PARA = STRUCT (TASK quelle, ziel, INT sendecode, zielstation); + + +TASK VAR sohn; +INT VAR strom,c,kanalmode, rzaehler := 20; +BOUND STRUCT (ROW maxstat INT port, + ROW maxstat INT zwischen) VAR route; + + +TASK PROC netport (INT CONST ziel): + INT VAR kan := route.port (ziel) AND 255; + IF kan < 1 OR kan > 15 + THEN + niltask + ELSE + IF NOT exists (nettask (kan)) + THEN + access catalogue; + nettask (kan) := task (kan); + IF NOT (nettask (kan) < father) THEN nettask (kan) := niltask FI; + FI; + nettask (kan) + FI +END PROC netport; + +PROC frei (INT CONST stat,lvl): + DATASPACE VAR ds := nilspace; + BOUND STRUCT (INT x,y) VAR msg := ds; + msg.x := stat; msg.y := lvl; + INT VAR return; + call (netport (stat), freigabecode, ds, return) ; + forget (ds) +END PROC frei; + +PROC net manager (DATASPACE VAR ds, INT CONST order, phase, TASK CONST + ordertask): + + IF order = report code AND ordertask < myself + THEN + IF storage (old("report")) > 20 THEN forget ("report", quiet) FI; + FILE VAR rp := sequential file (output, "report"); + BOUND TEXT VAR rpt := ds; + putline (rp, rpt); + send (ordertask, ack, ds) + ELIF order = abgleichcode AND ordertask < myself + THEN + BOUND STRUCT (INT ende, zwischen) VAR x := ds; + route.port (x.ende) := channel (ordertask); + route.zwischen (x.ende) := x.zwischen; + send (ordertask, ack, ds) + ELIF order = neue routen code AND ordertask < myself + THEN + forget ("port intern"); + copy (ds,"port intern"); + route := old ("port intern"); + send (ordertask, ack, ds) + ELIF station (ordertask) = station (myself) + THEN + IF ordertask < myself + OR order = list code + OR order > continue code + THEN + IF order = list code + THEN + enable stop; + forget (ds); ds := old ("report"); + FILE VAR ff := sequential file (output,ds); + putline (ff,"bekannte Stationen:"); + stationen; line (ff); putline (ff,"--------"); + putline (ff,"Eingestellte Netzmodi:"); + kanaele ; + paketgroessen; + line (ff); putline (ff,"********"); + putline (ff,stand); + putline (ff,"Rechner "+text(station(myself))+" um "+time of day); + send (ordertask, ack, ds) + ELSE + free manager (ds,order,phase,order task) + FI + ELSE + errorstop ("nur 'list' ist erlaubt") + FI + FI . + +stationen: +INT VAR stat; +INT VAR mystation := station (myself); +FOR stat FROM 1 UPTO maxstat REP + IF route.port (stat) > 0 AND stat <> mystation + THEN + put (ff,text(stat)+"("+text (route.port (stat) AND 255)+","+ + text(route.zwischen(stat))+")") + FI +PER. + +paketgroessen: + + line(ff); + put (ff, "Nutzlaenge bei indirekter Verbindung "+ + text (data length via node) + " Byte "); line (ff). + +kanaele: + INT VAR portnummer; + TASK VAR tsk; + FOR portnummer FROM 1 UPTO 15 REP + tsk := task (portnummer); + IF tsk < myself THEN beschreibe kanal FI; + PER. + +beschreibe kanal: + putline (ff, name (tsk) + " haengt an Kanal " + text (channel (tsk)) + + ", " + mode text (netz mode (portnummer))). + +END PROC net manager; + +TASK VAR cd,stask; +ROW maxstat INT VAR erlaubt; + +PROC communicate: + enable stop; + INT VAR scode, merken :=0; + DATASPACE VAR dr := nilspace; + neuer start (quit max, kanalmode); +REP + forget (dr); + telegrammfreigabe; + wait (dr, scode, stask); + cd := collected destination; + IF weiterleitung steht noch aus + THEN + send (netport (merken), out code, mds, reply); + IF reply <> -2 THEN forget (mds); merken := 0 FI + FI; + IF zeichen da OR zeit abgelaufen + THEN + packet + ELIF cd = myself + THEN + netz info und steuerung + ELSE + sendung untersuchen (stask, cd, scode, dr) + FI +PER. + +telegrammfreigabe: + INT VAR dummy; + control (22,0,0,dummy). + +zeichen da: scode < 0 . + +zeit abgelaufen: scode = ack AND cd = myself. + +packet: + INT VAR snr, ant,err; + TASK VAR quelle, ziel; + snr := 0; + IF NOT zeichen da THEN routen erneuern FI; + REP + IF NOT zeichen da + THEN + forget (dr); + zeitueberwachung (snr, quelle, ziel, ant, dr); + ELIF NOT weiterleitung steht noch aus + THEN + packet eingang (snr, quelle, ziel, ant, dr); + FI; + IF snr = 1000 + THEN + packet weiterleiten + ELIF snr > 0 + THEN + IF ant > 6 AND erlaubt(station (quelle)) < 0 + THEN unerlaubt + ELSE + send (quelle,ziel,ant,dr,err); + fehlerbehandlung ; + FI + FI + UNTIL snr = 0 OR zeichen da PER. + +routen erneuern: + rzaehler DECR 1; + IF rzaehler = 0 + THEN + rzaehler := 20; + neue routen holen + FI. + +weiterleitung steht noch aus: merken <> 0. + +packet weiterleiten: + INT VAR reply; + IF NOT ((route.port (ant) AND 255) = channel OR route.port (ant) < 0) + THEN + send (netport (ant), out code, dr, reply); + IF reply = -2 + THEN + merken := ant; + DATASPACE VAR mds := dr + FI + ELSE + report ("Weiterleitung nicht möglich für "+text(ant)) + FI. + +fehlerbehandlung: + IF ok oder ziel nicht da THEN loesche verbindung (snr) FI. + +ok oder ziel nicht da: err=0 OR err=-1. + +netz info und steuerung: + IF scode = list code THEN list status + ELIF scode = erase code THEN strom beenden + ELIF scode = freigabe code AND stask = father THEN freigabelevel + ELIF scode >= route code THEN weitergaben + ELIF scode > tabellencode THEN routen ausliefern + ELSE forget (dr); ablehnen ("nicht möglich") + FI. + +weitergaben: + IF stask < father + THEN + IF scode = out code + THEN + BOUND INT VAR stx lng := dr; + INT VAR decoded lng := stx lng; + decode packet length (decoded lng); + transmit header (dr); + blockout (dr,1,drverwaltungslaenge,decoded lng); + transmit trailer + ELIF scode = route code + THEN + BOUND PARA VAR parah := dr; + PARA VAR para := parah; + pingpong (stask, ack, dr, reply); + neue sendung (para.quelle, para.ziel, para.sendecode, + para.zielstation, dr); + forget (dr); dr := nilspace; + send (stask, ack, dr) + FI + ELSE + forget (dr); + ablehnen ("nicht Sohn von "+name(father)) + FI. + +routen ausliefern: + neue sendung (stask, myself, -routen liefern code, scode-tabellencode,dr). + +freigabelevel: + BOUND STRUCT (INT stat,lvl) VAR lv := dr; + IF lv.stat > 0 AND lv.stat <= maxstat THEN erlaubt (lv.stat) := lv.lvl FI; + send (stask,ack,dr). + +unerlaubt: + report ("Fremdzugriff von "+text(station (quelle))+" auf "+nam(ziel) + +" code "+text(ant)); + loesche verbindung (snr); + forget (dr); dr := nilspace; + BOUND TEXT VAR errtxt := dr; + errtxt:="Kein Zugriff auf Station "+text (station (myself)); + neue sendung (ziel, quelle, error nak, station (quelle), dr). + +strom beenden: + BOUND TEXT VAR stromtext := dr; + INT VAR erase strom := int (stromtext); + forget (dr); + strom := erase strom; + IF falsche stromnummer THEN ablehnen ("Strom gibt es nicht") + ELSE + BOUND INFO VAR v := verbindung (strom); + IF + stask < supervisor OR stask = vx.quelle OR stask = vx.ziel + THEN + loeschen + ELSE ablehnen ("Nur Empfänger/Absender darf löschen") + FI + FI. + +loeschen: + IF sendeeintrag THEN + IF callee (vx.quelle) = vx.ziel THEN absender warnen FI; + loesche verbindung (strom) + ELSE + IF callee (vx.ziel) = vx.quelle THEN warnen FI; + loesche verbindung (strom) + FI; + dr := nilspace; + send (stask,ack,dr). + +absender warnen: + dr := nilspace; + send(vx.ziel,vx.quelle,1,dr,err) . + +warnen: + dr := nilspace; +errtxt := dr; errtxt:= "Station antwortet nicht"; +send (vx.quelle,vx.ziel,error nak, dr, err). + +falsche stromnummer: strom < 1 OR strom > max verbindungsnummer. +sendeeintrag: vx.quellrechner = station (myself). +vx: v.steuer. +END PROC communicate; + +PROC list option: + begin ("net list",PROC list net, sohn) +END PROC list option; + +PROC list net: + disable stop; + DATASPACE VAR ds ; + INT VAR scode; + REP + wait (ds, scode, stask); + forget (ds); ds := nilspace; + FILE VAR f := sequential file (output, ds); + list (f, father); + list netports; + IF is error THEN clear error; + forget(ds); + ds := nilspace; + f := sequential file (output, ds); + output (f); putline (f,errormessage); + clear error + FI; + send (stask, ack, ds) + PER. + +list netports: + INT VAR k; + FOR k FROM 1 UPTO 15 REP + TASK VAR tsk := task (k); + IF tsk < father + THEN + putline (f, name (tsk)); + list (f,tsk) + FI + PER. + +END PROC list net; + +PROC neue routen holen: + forget ("port intern", quiet); + fetch ("port intern"); + route := old ("port intern"); + neue routen +END PROC neue routen holen; + +PROC sendung untersuchen (TASK CONST q, z, INT CONST cod, DATASPACE VAR dr): + IF z = collector + THEN + verbindungsebene + ELIF station (z) <> 0 + THEN + sendung (q,z,cod,station (z),dr) + ELSE + ablehnen ("Station 0") + FI. + +verbindungsebene: + IF cod = 256 THEN name von fremdstation + ELIF cod > 256 + THEN + taskinfo fremd + ELIF callee (q) = z (* gegen errornak an collector *) + THEN + task id von fremd + FI. + +taskinfo fremd: sendung (q, collector, -task info code,cod-256,dr). + +task id von fremd: sendung (q, collector, -task id code, zielstation, dr) . + +name von fremdstation: + BOUND TASK VAR tsk := dr; + TASK VAR tsk1 := tsk; + forget (dr); + dr := nilspace; + sendung (q, tsk1, -name code, station (tsk1), dr). + +zielstation: cod. +END PROC sendung untersuchen; + +PROC sendung (TASK CONST q, z, INT CONST code, z stat, DATASPACE VAR dr): + IF z stat < 1 OR z stat > maxstat + THEN + ablehnen ("ungültige Stationsnummer"); + LEAVE sendung + FI; + INT VAR reply; + INT VAR rp := route.port (z stat) AND 255; + IF rp = 255 THEN neue routen holen ;rp := route.port (z stat) AND 255 FI; + IF rp = channel + THEN + sendung selbst betreiben + ELIF rp > 0 AND rp < 16 + THEN + sendung weitergeben + ELSE + ablehnen ("Station "+text(z stat)+" gibt es nicht") + FI. + +sendung selbst betreiben: + neue sendung (q, z, code, z stat, dr). + +sendung weitergeben: + DATASPACE VAR ds := nilspace; + BOUND PARA VAR p := ds; + p.quelle := q; + p.ziel := z; + p.zielstation := z stat; + p.sendecode := code; + call (netport (z stat), route code, ds, reply); + forget (ds); + pingpong (netport (z stat), 0, dr, reply); + forget (dr); + IF reply < 0 THEN ablehnen ("netport "+text(route.port(zstat)AND255) + + " fehlt") FI +END PROC sendung; + +PROC ablehnen (TEXT CONST t): + DATASPACE VAR vdr := nilspace; + BOUND TEXT VAR errtxt := vdr; + INT VAR err; + errtxt := t; + send (cd,stask, error nak, vdr,err); + forget (vdr). +END PROC ablehnen; + +PROC stop: + access catalogue; + IF exists task ("net timer") + THEN + TASK VAR nets := father (/"net timer"); + ELSE + nets := myself + FI; + nets := son (nets); + WHILE NOT (nets = niltask) REP + IF text (name (nets),3) = "net" OR name (nets) = "router" + THEN + end (nets) + FI; + nets := brother (nets) + PER +END PROC stop; + +PROC list status: + + DATASPACE VAR ds := nilspace; + FILE VAR f:=sequential file (output, ds); + line(f); + FOR strom FROM 1 UPTO max verbindungsnummer REP + IF strom > 0 THEN + BOUND INFO VAR v := verbindung (strom); + IF vx.strom <> 0 THEN info FI + FI; + PER; + send (stask, ack, ds). + +info: + put (f,"Strom "+text(strom)); + put (f,"(sqnr"+text(vx.sequenz)+"/"+text (v.maxseq)+")"); + IF sendeeintrag THEN sendeinfo ELSE empfangsinfo FI; + line (f). + +sendeeintrag: vx.quellrechner = station(myself) . + +sendeinfo: + IF v.typ = call im wait THEN put (f,"erwartet Antwort von") + ELIF v.typ = call in zustellung THEN put (f,"Ziel busy. Zielstation:") + ELIF v.typ = call im abbruch THEN put (f,"wird gelöscht bei Antwort von") + ELSE put (f,"sendet an") + FI; + put (f,vx.zielrechner); + put (f,". Absender ist """+nam (vx.quelle)+"""."). + +empfangsinfo: + IF v.typ = zustellung THEN + put (f,"Sendung noch nicht zustellbar") + ELSE + put (f,"empfängt von"); + put (f,vx.quellrechner); + FI; + put (f,". Empfaenger ist """+nam (vx.ziel)+"""."). + +vx: v.steuer. +END PROC list status; + +INT VAR quitmax := 3; + +ROW 15 TASK VAR net task; +ROW 15 INT VAR netz mode; + +PROC erlaube (INT CONST von, bis): + IF ein kanal gestartet + THEN + putline ("Warnung: 'erlaube' muß vor 'starte kanal'") + FI; + test (von); test (bis); + INT VAR i; + FOR i FROM von UPTO bis REP erlaubt (i) := 0 PER +END PROC erlaube; + +PROC sperre (INT CONST von, bis): + IF ein kanal gestartet + THEN + putline ("Warnung: 'sperre' muß vor 'starte kanal'") + FI; + test (von); test (bis); + INT VAR i; + FOR i FROM von UPTO bis REP erlaubt (i) :=-1 PER +END PROC sperre ; + +BOOL VAR alte routen, ein kanal gestartet; + +PROC definiere netz: + stop; + INT VAR i; + FOR i FROM 1 UPTO 15 REP net task (i) := niltask PER; + ein kanal gestartet := FALSE; + FILE VAR s := sequential file (output,"report"); + putline (s," N e u e r S t a r t " + date + " " + time of day ); + alte routen := exists ("port intern"); + IF alte routen + THEN + route := old ("port intern") + ELSE + route := new ("port intern"); + initialize routes + FI. + + initialize routes: + FOR i FROM 1 UPTO maxstat REP + route.zwischen(i) := i + PER. + +END PROC definiere netz; + +PROC starte kanal (INT CONST k,modus,stroeme): + ein kanal gestartet := TRUE; + IF exists (canal (k)) THEN end (canal (k)) FI; + IF stroeme <= 0 THEN errorstop ("3.Parameter negativ") FI; + quitmax := stroeme; + c := k; + IF c < 1 OR c > 15 THEN errorstop ("unzulässiger Kanal:"+text(c)) FI; + kanalmode := modus; + IF kanalmode < 1 OR kanalmode > max mode + THEN errorstop ("unzulässiger Netzbetriebsmodus:"+text(kanalmode)) + ELSE netz mode (c) := kanalmode + FI; + IF NOT exists task ("net port") + THEN + begin ("net port",PROC net io, net task (c)); + define collector (/"net port") + ELSE + begin ("net port "+text (c),PROC net io, net task (c)) + FI. +END PROC starte kanal; + +PROC routen (INT CONST von, bis, kanal, zw): + INT VAR i; + IF kanal < 0 OR kanal > 15 THEN errorstop ("Kanal unzulässig") FI; + test (von); test (bis); + FOR i FROM von UPTO bis REP + route.port (i) := kanal+256; + IF zw=0 + THEN + route.zwischen (i) := i + ELSE + test (zw); + route.zwischen (i) := zw + FI + PER. +END PROC routen; + +PROC routen (INT CONST von, bis, kanal): + routen (von, bis, kanal, 0) +END PROC routen; + +PROC test (INT CONST station): + IF station < 1 OR station > maxstat + THEN + errorstop (text (station) + " als Stationsnummer unzulässig") + FI +END PROC test; + +PROC aktiviere netz: +vorgegebene routen pruefen; +IF existstask ("net timer") THEN end (/"net timer") FI; +begin ("net timer",PROC timer,sohn); +IF NOT alte routen +THEN + routen aufbauen +ELSE + IF online THEN break FI +FI. + +vorgegebene routen pruefen: + INT VAR i; + FOR i FROM 1 UPTO maxstat REP + INT VAR s := route.port (i) AND 255; + IF s > 0 AND s <= 15 CAND nettask (s) = niltask + THEN + errorstop ("Kanal "+text(s)+" nicht gestartet, steht aber in Routen") + FI + PER. +END PROC aktiviere netz; + + +PROC routen aufbauen: + alte routen := TRUE; + c := channel; + break (quiet); + begin ("router", PROC rout0, sohn). +END PROC routen aufbauen; + +PROC rout0: + disable stop; + rout; + IF is error + THEN + put error + FI; + end (myself) +END PROC rout0; + +PROC rout: + IF c>0 THEN continue (c) FI; + clear error; enable stop; + fetch ("port intern"); + route := old ("port intern"); + routen aufbauen; + ds := old ("port intern"); + call (father, neue routen code, ds, reply). + +routen aufbauen: + access catalogue; + TASK VAR port := brother (myself); + WHILE NOT (port = niltask) REP + IF text (name (port),8) = "net port" THEN nachbarn FI; + port := brother (port) + PER; + IF online THEN putline ("Fertig. Weiter mit SV !") FI. + +aenderbar: route.port (st) < 256. + +nachbarn: + INT VAR st,reply; + FOR st FROM 1 UPTO maxstat REP + IF erlaubt (st) >= 0 AND st <> station (myself) AND aenderbar + THEN + IF online THEN put (name (port)); put (st) FI; + DATASPACE VAR ds := nilspace; + call (port, tabellencode+st, ds, reply); + IF reply = ack + THEN + BOUND STRUCT (ROW maxstat INT port, + ROW maxstat INT zwischen) VAR fremd := ds; + route.port (st) := channel(port); + route.zwischen (st) := st; + indirekte ziele + ELIF reply < 0 + THEN + errorstop ("netz läuft nicht (Kanalnummer falsch)") + ELSE + BOUND TEXT VAR xt := ds; + IF online THEN put (xt) FI; + FI; + IF online THEN line FI; + forget (ds) + FI + PER. + +indirekte ziele: + INT VAR kanal := fremd.port (station (myself)) AND 255; + INT VAR ind; + FOR ind FROM 1 UPTO maxstat REP + IF ind bei st bekannt AND NOT ((fremd.port (ind) AND 255) = kanal) + AND route.port (ind) < 256 + THEN + route.port (ind) := channel (port); + route.zwischen (ind) := st + FI + PER. + +ind bei st bekannt: NOT (fremd.port (ind) = -1). + +END PROC rout; + + +PROC timer: + disable stop; + access catalogue; + INT VAR old session := 1; + REP + IF session <> old session + THEN + define collector (/"net port"); + old session := session + FI; + clear error; + pause (30); + sende tick an alle ports + PER. + +sende tick an alle ports : + TASK VAR fb := son (father); + REP + IF NOT exists (fb) THEN access catalogue;LEAVE sende tick an alle portsFI; + IF channel (fb) > 0 + THEN + DATASPACE VAR ds := nilspace; + send (fb, ack, ds); + pause (10) + FI; + fb := brother (fb) + UNTIL fb = niltask PER. + +END PROC timer; + +PROC net io: + disable stop; + set net mode (kanalmode); + fetch ("port intern"); + route := old ("port intern"); + commanddialogue (FALSE); + continue (c); + communicate; + TEXT VAR emsg := "++++++ "+error message +" Zeile "+text(errorline); + clear error; + report (emsg); + end (myself) +END PROC net io; + +PROC start: run ("netz") END PROC start; + +END PACKET net manager; + diff --git a/system/net/1.8.7/src/net report b/system/net/1.8.7/src/net report new file mode 100644 index 0000000..ddc19d2 --- /dev/null +++ b/system/net/1.8.7/src/net report @@ -0,0 +1,41 @@ +PACKET net report DEFINES report, abgleich: +(* Version 3 (!) *) + +LET reportcode = 99, abgleichcode = 98; + +PROC abgleich (INT CONST ende, zwischen): + DATASPACE VAR ds := nilspace; + BOUND STRUCT (INT ende, zwischen) VAR x := ds; + x.ende := ende; + x.zwischen := zwischen; + call (father, abgleichcode, ds, rep); + INT VAR rep; + forget (ds) +END PROC abgleich; + +PROC report (TEXT CONST x): + report(x,"") +END PROC report; + +PROC report (TEXT CONST txt, info): + DATASPACE VAR net report := nilspace; + BOUND TEXT VAR rinfo := net report; + rinfo := date; + rinfo CAT " "+time of day +" "; + rinfo CAT name(myself)+":"; + rinfo CAT txt; + INT VAR i; + FOR i FROM 1 UPTO length (info) REP + INT VAR z := code (infoSUBi) ; + IF z < 32 OR z > 126 + THEN rinfo CAT "%"+text(z)+" " + ELSE rinfo CAT (infoSUBi)+" " + FI + PER; + call (father, report code , net report, reply); + INT VAR reply; + forget (net report); +END PROC report; + +END PACKET net report; + diff --git a/system/net/1.8.7/src/netz b/system/net/1.8.7/src/netz new file mode 100644 index 0000000..c237ba2 --- /dev/null +++ b/system/net/1.8.7/src/netz @@ -0,0 +1,20 @@ +IF exists ("port intern") THEN forget ("port intern") FI; +definiere netz; +list option; +erlaube(1,127); +sperre (1,9); +sperre (15,32); +sperre (37,37); +sperre (42,42); +sperre (46,47); +sperre (49,127); +routen (1, 32,8); +routen (33,43, 9); +routen (34,34,8); +routen (35,48,9); +starte kanal (9,11,10); +starte kanal (8,1,10); +aktiviere netz; + + + diff --git a/system/net/1.8.7/src/port server b/system/net/1.8.7/src/port server new file mode 100644 index 0000000..46c647f --- /dev/null +++ b/system/net/1.8.7/src/port server @@ -0,0 +1,164 @@ +PACKET port server: (* Autor : R. Ruland *) + (* Stand : 21.03.86 *) + +INT VAR port station; +TEXT VAR port := "PRINTER"; + +put ("gib Name des Zielspools : "); editget (port); line; +put ("gib Stationsnummer des Zielspools : "); get (port station); + +server channel (15); +spool duty ("Verwalter fuer Task """ + port + + """ auf Station " + text (port station)); + +LET max counter = 10 , + time slice = 300 , + + ack = 0 , + fetch code = 11 , + param fetch code = 21 , + file save code = 22 , + file type = 1003 , + + begin char = ""0"", + end char = ""1""; + + +INT VAR reply, old heap size; +TEXT VAR file name, write pass, read pass, sendername, buffer; +FILE VAR file; + +DATASPACE VAR ds, file ds, send ds; + +BOUND STRUCT (TEXT file name, write pass, read pass, sendername, INT station) VAR msg; +BOUND TEXT VAR error msg ; + +spool manager (PROC save file); + +PROC save file : + + disable stop ; + command dialogue (FALSE); + ds := nilspace; file ds := nilspace; send ds := nil space; + old heap size := heap size; + + REP + execute save file; + + IF is error THEN save error (error message) FI; + + IF heap size > old heap size + 4 + THEN collect heap garbage ; + old heap size := heap size + FI; + + PER + +ENDPROC save file; + + +PROC execute save file : + +enable stop; +forget (file ds) ; file ds := nilspace; +call (father, fetch code, file ds, reply); +IF reply <> ack + THEN error msg := ds; errorstop (error msg); + ELSE save file ds +FI; + +. save file ds : + IF type (file ds) = file type + THEN get file params; + insert file params; + call station (port station, port, file save code, file ds); + ELSE errorstop ("Datenraum hat falschen Typ") + FI; + +. get file params : + forget (ds); ds := nilspace; + call (father, param fetch code, ds, reply); + IF reply <> ack + THEN error msg := ds; errorstop (error msg); + ELSE msg := ds; + file name := msg. file name; + write pass := msg. write pass; + read pass := msg. read pass; + sendername := msg. sender name; + FI; + +. insert file params : + buffer := ""; + in headline (filename); + in headline (write pass); + in headline (read pass); + in headline (sendername); + file := sequential file (input, file ds) ; + headline (file, buffer); + +END PROC execute save file; + + +PROC call station (INT CONST order task station, TEXT CONST order task name, + INT CONST order code, DATASPACE VAR order ds) : + + INT VAR counter := 0; + TASK VAR order task; + disable stop; + REP order task := order task station // order task name; + IF is error CAND pos (error message, "antwortet nicht") > 0 + THEN clear error; + counter := min (max counter, counter + 1); + pause (counter * time slice); + ELSE enable stop; + forget (send ds); send ds := order ds; + call (order task, order code, send ds, reply); + disable stop; + IF reply = ack + THEN forget (order ds); order ds := send ds; + forget (send ds); + LEAVE call station + ELSE error msg := send ds; + errorstop (error msg); + FI; + FI; + PER; + +END PROC call station; + + +TASK OP // (INT CONST station, TEXT CONST name) : + + enable stop; + station / name + +END OP //; + + +PROC in headline (TEXT CONST information) : + IF pos (information, begin char) <> 0 + OR pos (information, end char) <> 0 + THEN errorstop ("Name darf nicht Code 0 oder Code 1 enthalten") FI; + buffer CAT begin char; + buffer CAT information; + buffer CAT end char; +END PROC in headline; + + +PROC save error (TEXT CONST message) : + clear error; + file name CAT "."; + file name CAT sender name; + file name CAT ".ERROR"; + file := sequential file (output, file name); + putline (file, " "); + putline (file, "Uebertragung nicht korrekt beendet "); + putline (file, " "); + put (file, "ERROR :"); put (file, message); + save (file name, public); + clear error; + forget(file name, quiet); +END PROC save error; + +ENDPACKET port server; + diff --git a/system/net/1.8.7/src/printer server b/system/net/1.8.7/src/printer server new file mode 100644 index 0000000..b1a30bc --- /dev/null +++ b/system/net/1.8.7/src/printer server @@ -0,0 +1,99 @@ +PACKET multi user printer : (* Autor : Rudolf Ruland *) + (* Stand : 24.03.86 *) + +INT VAR c; +put ("gib Druckerkanal : "); get (c); + + server channel (c); + station only (FALSE) ; + spool duty ("Ausgabe mit dem Drucker"); + spool control task (myself); + +LET ack = 0 , + + fetch code = 11 , + param fetch code = 21 , + file type = 1003 ; + +INT VAR reply, old heap size, sender station; +TEXT VAR file name, userid, password, sendername; +FILE VAR file ; + +DATASPACE VAR ds, file ds; + +BOUND STRUCT (TEXT file name, userid, password, sendername, INT station) VAR msg; +BOUND TEXT VAR error msg ; + +spool manager (PROC printer); + +PROC printer : + + disable stop ; + command dialogue (FALSE); + ds := nilspace; file ds := nilspace; + continue (server channel) ; + check error ("Kanal belegt"); + + old heap size := heap size ; + REP + execute print ; + + IF is error + THEN put error; + clear error; + FI ; + + IF heap size > old heap size + 4 + THEN collect heap garbage ; + old heap size := heap size + FI + PER + +ENDPROC printer ; + + +PROC execute print : + + enable stop ; + forget (file ds) ; file ds := nilspace ; + call (father, fetch code, file ds, reply) ; + IF reply = ack CAND type (file ds) = file type + THEN get file params; + print file + FI ; + +. get file params : + forget (ds); ds := nilspace; + call (father, param fetch code, ds, reply); + IF reply <> ack + THEN error msg := ds; errorstop (error msg); + ELSE msg := ds; + file name := msg. file name; + userid := msg. userid; + password := msg. password; + sendername := msg. sender name; + sender station := msg. station; + FI; + +. print file : + file := sequential file (input, file ds); + print (file, + PROC (INT CONST, INT VAR, INT VAR) open, + PROC (INT CONST, INT CONST) close, + PROC (INT CONST, TEXT CONST, INT CONST, INT CONST) execute); + +ENDPROC execute print ; + + +PROC check error (TEXT CONST message) : + IF is error + THEN clear error; + rename myself (message); + IF is error THEN clear error; end (myself) FI; + pause (18000); + end (myself); + FI; +END PROC check error; + +ENDPACKET multi user printer ; + diff --git a/system/net/1.8.7/src/spool cmd b/system/net/1.8.7/src/spool cmd new file mode 100644 index 0000000..b44e799 --- /dev/null +++ b/system/net/1.8.7/src/spool cmd @@ -0,0 +1,112 @@ +PACKET spool cmd (* Autor: R. Ruland *) + (* Stand: 01.04.86 *) + DEFINES killer, + first, + start, + stop, + halt, + wait for halt : + +LET error nak = 2 , + + entry line code = 23 , + killer code = 24 , + first code = 25 , + start code = 26 , + stop code = 27 , + halt code = 28 , + wait for halt code = 29 ; + +DATASPACE VAR ds; + +BOUND STRUCT (TEXT entry line, INT index) VAR control msg; +BOUND TEXT VAR error msg ; + +INT VAR reply; + +INITFLAG VAR in this task := FALSE; + + +PROC control spool (TASK CONST spool, INT CONST control code, + TEXT CONST question, BOOL CONST leave) : + + enable stop; + initialize control msg; + WHILE valid spool entry + REP IF control question THEN control spool entry FI PER; + + . initialize control msg : + IF NOT initialized (in this task) THEN ds := nilspace FI; + forget (ds); ds := nilspace; control msg := ds; + control msg. entry line := ""; + control msg. index := 0; + say (""13""10""); + + . valid spool entry : + call (spool, entry line code, ds, reply); + IF reply = error nak + THEN error msg := ds; + errorstop (error msg); + FI; + control msg. index <> 0 + + . control question : + say (control msg. entry line); + yes (question) + + . control spool entry : + call (spool, control code, ds, reply); + IF reply = error nak + THEN error msg := ds; + errorstop (error msg); + FI; + IF leave THEN LEAVE control spool FI; + +END PROC control spool; + + +PROC killer (TASK CONST spool) : + + control spool (spool, killer code, " loeschen", FALSE) + +END PROC killer; + + +PROC first (TASK CONST spool) : + + control spool (spool, first code, " als erstes", TRUE) + +END PROC first; + + +PROC start (TASK CONST spool) : + + call (stop code, "", spool); + call (start code, "", spool); + +END PROC start; + + +PROC stop (TASK CONST spool) : + + call (stop code, "", spool); + +END PROC stop; + + +PROC halt (TASK CONST spool) : + + call (halt code, "", spool); + +END PROC halt; + + +PROC wait for halt (TASK CONST spool) : + + call (wait for halt code, "", spool); + +END PROC wait for halt; + + +END PACKET spool cmd; + diff --git a/system/net/1.8.7/src/spool manager b/system/net/1.8.7/src/spool manager new file mode 100644 index 0000000..e711ab4 --- /dev/null +++ b/system/net/1.8.7/src/spool manager @@ -0,0 +1,915 @@ +PACKET spool manager DEFINES (* Autor: J. Liedtke *) + (* R. Nolting *) + (* R. Ruland *) + (* Stand: 22.07.86 *) + + spool manager , + + server channel , + spool duty, + station only, + spool control task : + +LET que size = 101 , + + ack = 0 , + nak = 1 , + error nak = 2 , + message ack = 3 , + question ack = 4 , + second phase ack = 5 , + false code = 6 , + + fetch code = 11 , + save code = 12 , + exists code = 13 , + erase code = 14 , + list code = 15 , + all code = 17 , + param fetch code = 21 , + file save code = 22 , + entry line code = 23 , + killer code = 24 , + first code = 25 , + start code = 26 , + stop code = 27 , + halt code = 28 , + wait for halt code = 29 , + + continue code = 100 , + + file type = 1003 ; + +LET begin char = ""0"", + end char = ""1""; + +LET PARAMS = STRUCT (TEXT name, userid, password, sendername, INT station), + ENTRY = STRUCT (PARAMS ds params, TEXT entry line, DATASPACE space); + +ROW que size ENTRY VAR que ; + +PARAMS CONST empty params := PARAMS : ("", "", "", "", -1); + +PARAMS VAR save params, file save params; + +ENTRY VAR fetch entry; + +FILE VAR file; + +INT VAR order, last order, phase, reply, old heap size, first, last, list index, + begin pos, end pos, order task station, sp channel, counter; + +TEXT VAR order task name, buffer, sp duty, start time; + +BOOL VAR server is waiting, stop command pending, stat only, valid fetch entry; + +TASK VAR order task, last order task, server, calling parent, task in control; + +INITFLAG VAR in this task := FALSE; + +DATASPACE VAR ds; + +BOUND STRUCT (TEXT name, userid, password) VAR msg; +BOUND STRUCT (TEXT entry line, INT index) VAR control msg; +BOUND PARAMS VAR fetch msg; +BOUND THESAURUS VAR all msg; +BOUND TEXT VAR error msg ; + + +. first entry : que (first) +. list entry : que (list index) +. last entry : que (last) + +. que is empty : first = last +. que is full : first = next (last) +.; + +sp channel := 0; +sp duty := ""; +stat only := FALSE; +task in control := myself; + +PROC server channel (INT CONST channel nr) : + IF channel nr <= 0 OR channel nr >= 33 + THEN errorstop ("falsche Kanalangabe") FI; + sp channel := channel nr; +END PROC server channel; + +INT PROC server channel : + sp channel +END PROC server channel; + + +PROC station only (BOOL CONST flag) : + stat only := flag +END PROC station only; + +BOOL PROC station only : + stat only +END PROC station only; + + +PROC spool duty (TEXT CONST duty) : + sp duty := duty; +END PROC spool duty; + +TEXT PROC spool duty : + sp duty +END PROC spool duty; + + +PROC spool control task (TASK CONST task id): + task in control := task id; +END PROC spool control task; + +TASK PROC spool control task : + task in control +END PROC spool control task; + + +PROC spool manager (PROC server start) : + + spool manager (PROC server start, TRUE) + +END PROC spool manager; + + +PROC spool manager (PROC server start, BOOL CONST with start) : + + set autonom ; + break ; + disable stop ; + initialize spool manager ; + REP forget (ds) ; + wait (ds, order, order task) ; + IF order <> second phase ack + THEN prepare first phase ; + spool (PROC server start); + ELIF order task = last order task + THEN prepare second phase ; + spool (PROC server start); + ELSE send nak + FI ; + send error if necessary ; + collect heap garbage if necessary + PER + + . initialize spool manager : + initialize if necessary; + stop; + erase fetch entry; + IF with start THEN start (PROC server start) FI; + + . initialize if necessary : + IF NOT initialized (in this task) + THEN FOR list index FROM 1 UPTO que size + REP list entry. space := nilspace PER; + fetch entry. space := nilspace; + ds := nilspace; + last order task := niltask; + server := niltask; + calling parent := niltask; + server is waiting := FALSE; + stop command pending := FALSE; + old heap size := 0; + clear spool; + FI; + + . prepare first phase : + IF order = save code OR order = erase code OR order = stop code + THEN phase := 1 ; + last order := order ; + last order task := order task ; + FI; + + . prepare second phase : + phase INCR 1 ; + order := last order + + . send nak : + forget (ds) ; + ds := nilspace ; + send (order task, nak, ds); + + . send error if necessary : + IF is error + THEN forget (ds) ; + ds := nilspace ; + error msg := ds ; + CONCR (error msg) := error message; + clear error; + send (order task, error nak, ds) + FI; + + . collect heap garbage if necessary : + IF heap size > old heap size + 2 + THEN collect heap garbage; + old heap size := heap size; + FI; + +END PROC spool manager; + + +PROC spool (PROC server start): + + command dialogue (FALSE); + enable stop; + IF station only CAND station (ordertask) <> station (myself) + THEN errorstop ("kein Zugriffsrecht auf Task " + text (station(myself)) + + "/""" + name(myself) + """") + FI; + + SELECT order OF + + CASE fetch code : out of que + CASE param fetch code : send fetch params + CASE save code : new que entry + CASE file save code : new file que entry + CASE exists code : exists que entry + CASE erase code : erase que entry + CASE list code : send spool list + CASE all code : send owners ds names + + OTHERWISE : + + IF order >= continue code AND order task = supervisor + THEN forget (ds); + spool command (PROC server start) + + ELIF spool control allowed by order task + THEN SELECT order OF + CASE entry line code : send next entry line + CASE killer code : kill entry + CASE first code : make to first + CASE start code : start server + CASE stop code : stop server + CASE halt code : halt server + CASE wait for halt code : wait for halt + OTHERWISE : errorstop ("falscher Auftrag fuer Task """ + + name(myself) + """") + END SELECT + + ELSE errorstop ("falscher Auftrag fuer Task """ + + name(myself) + """") + FI; + END SELECT; + + +. spool control allowed by order task : + (order task = spool control task OR order task < spool control task + OR spool control task = supervisor) + AND station (order task) = station (myself) +. + out of que : + IF NOT (order task = server) + THEN errorstop ("keine Servertask") + ELIF stop command pending + THEN forget (ds); + stop; + erase fetch entry; + ELIF que is empty + THEN forget (ds) ; + erase fetch entry; + server is waiting := TRUE; + ELSE send first entry; + FI; + +. + send fetch params : + IF order task = server + THEN send params + ELSE errorstop ("keine Servertask") + FI; + + . send params : + forget(ds); ds := nilspace; fetch msg := ds; + fetch msg := fetch entry. ds params; + send (order task, ack, ds); + +. + new que entry : + IF phase = 1 + THEN prepare into que + ELSE into que + FI; + +. + prepare into que : + msg := ds ; + save params. name := msg.name; + save params. userid := msg.userid; + save params. password := msg.password; + save params. sendername := name (order task); + save params. station := station (order task); + forget (ds); ds := nilspace; + send (order task, second phase ack, ds); + +. + new file que entry : + IF type (ds) <> file type + THEN errorstop ("Datenraum hat falschen Typ"); + ELSE get file params; + into que; + FI; + + . get file params : + file := sequential file (input, ds); + end pos := 0; + next headline information (file save params. name); + next headline information (file save params. userid); + next headline information (file save params. password); + next headline information (file save params. sendername); + next headline information (buffer); + file save params. station := int (buffer); + IF NOT last conversion ok + THEN file save params. station := station (order task) FI; + IF file save params. sendername = "" + THEN file save params. sendername := name (order task) FI; + IF file save params. name = "" + THEN IF headline (file) <> "" + THEN file save params. name := headline (file); + ELSE errorstop ("Name unzulaessig") + FI; + ELSE headline (file, file save params. name); + FI; + +. + exists que entry : + msg := ds ; + order task name := name (order task); + order task station := station (order task); + to first que entry; + WHILE next que entry found + REP IF is entry from order task (msg. name) + THEN send ack; + LEAVE exists que entry + FI; + PER ; + forget (ds); ds := nilspace; + send (order task, false code, ds) + +. + erase que entry : + msg := ds ; + order task name := name (order task); + order task station := station (order task); + IF phase = 1 + THEN ask for erase + ELSE erase entry from order task + FI; + + . ask for erase : + to first que entry; + WHILE next que entry found + REP IF is entry from order task (msg. name) + THEN manager question ("""" + msg.name + """ loeschen"); + LEAVE erase que entry + FI; + PER ; + manager message ("""" + msg.name + """ existiert nicht"); + + . erase entry from order task : + IF is entry from order task (msg. name) + THEN delete que entry; + LEAVE erase que entry + ELSE to first que entry; + WHILE next que entry found + REP IF is entry from order task (msg. name) + THEN delete que entry; + LEAVE erase que entry + FI ; + PER ; + manager message ("""" + msg.name + """ existiert nicht"); + FI; + + . delete que entry : + erase entry (list index) ; + send ack; + +. + send owners ds names: + order task name := name (order task); + order task station := station (order task); + forget (ds); ds := nilspace; all msg := ds; + all msg := empty thesaurus; + to first que entry; + WHILE next que entry found + REP IF is entry from order task ("") + THEN insert (all msg, list entry. ds params. name) + FI; + PER; + send (order task, ack, ds) + +. + send spool list : + list spool; + send (order task, ack, ds); + +. + send next entry line : + control msg := ds; + get next entry line (control msg. entry line, control msg. index); + send (order task, ack, ds); + +. + kill entry : + control msg := ds; + list index := control msg. index; + IF is valid que entry (list index) + THEN erase entry (list index) + FI; + send (order task, ack, ds); + +. + make to first : + control msg := ds; + list index := control msg. index; + IF is valid que entry (list index) + THEN new first (list entry); + erase entry (list index); + FI; + send (order task, ack, ds); + +. + start server : + IF exists (server) THEN errorstop ("Spool muß zuerst gestoppt werden") FI; + start (PROC server start); + IF server channel <= 0 OR server channel >= 33 + THEN manager message ("WARNUNG : Serverkanal nicht eingestellt"); + ELSE send ack + FI; + +. + stop server: + IF phase = 1 + THEN stop; + IF valid fetch entry + THEN valid fetch entry := FALSE; + manager question (""13""10"" + + fetch entry. entry line + " neu eintragen"); + ELSE erase fetch entry; + send ack; + FI; + ELSE IF fetch entry. entry line <> "" THEN new first (fetch entry) FI; + erase fetch entry; + send ack; + FI; + +. + halt server : + stop command pending := TRUE; + IF NOT exists (server) OR server is waiting + THEN stop; + erase fetch entry; + FI; + send ack; + +. + wait for halt : + IF exists (calling parent) + THEN errorstop ("Task """ + name (calling parent) + """ wartet schon auf halt") + ELSE calling parent := order task; + stop command pending := TRUE; + forget (ds); + IF NOT exists (server) OR server is waiting + THEN stop; + erase fetch entry; + FI; + FI; + +END PROC spool; + + +PROC send first entry : + + forget (ds); ds := first entry. space; + send (server, ack, ds, reply) ; + IF reply = ack + THEN server is waiting := FALSE; + start time := time of day; + start time CAT " am "; + start time CAT date; + erase fetch entry; + fetch entry := first entry; + erase entry (first); + valid fetch entry := TRUE; + ELSE forget (ds); + FI; + +END PROC send first entry; + + +PROC into que : + + IF que is full + THEN errorstop ("Spool ist voll") + ELSE make new entry; + send ack; + awake server if necessary + FI; + + . make new entry : + IF order = save code + THEN last entry. ds params := save params; + save params := empty params; + ELSE last entry. ds params := file save params; + file save params := empty params; + FI; + last entry. space := ds; + counter INCR 1; + build entry line; + last := next (last) ; + + . build entry line : + IF LENGTH last entry. ds params. sender name > 16 + THEN buffer := subtext (last entry. ds params. sender name, 1, 13); + buffer CAT "..."""; + ELSE buffer := last entry. ds params. sender name; + buffer CAT """"; + buffer := text (buffer, 17); + FI; + last entry. entry line := entry station text; + last entry. entry line CAT "/"""; + last entry. entry line CAT buffer; + last entry. entry line CAT " : """ ; + last entry. entry line CAT last entry. ds params. name; + last entry. entry line CAT """ (" ; + last entry. entry line CAT text (storage (last entry. space)); + last entry. entry line CAT " K)"; + + . entry station text : + IF last entry. ds params. station = 0 + THEN " " + ELSE text (last entry. ds params. station, 3) + FI + + . awake server if necessary : + IF server is waiting THEN send first entry FI; + +END PROC into que; + + +PROC list spool : + + forget (ds); ds := nilspace; + file := sequential file (output, ds) ; + max line length (file, 1000); + headline(file, station text + "/""" + name (myself) + """"); + put spool duty; + put current job; + put spool que; + + . station text : + IF station(myself) = 0 + THEN "" + ELSE text (station(myself)) + FI + + . put spool duty : + IF spool duty <> "" + THEN write (file, "Aufgabe: "); + write (file, spool duty ); + line (file, 2); + FI; + + . put current job : + IF valid fetch entry AND exists (server) + THEN write (file, "In Bearbeitung seit "); + write (file, start time); + write (file, ":"); + line (file, 2); + putline (file, fetch entry. entry line); + IF stop command pending + THEN putline (file, "Spool wird nach diesem Auftrag deaktiviert"); + FI; + line (file); + ELSE write (file, "kein Auftrag in Bearbeitung"); + IF NOT exists (server) + THEN write (file, ", da Spool deaktiviert"); + ELIF que is empty + THEN write (file, ", da Warteschlange leer"); + LEAVE list spool; + FI; + line (file, 2); + FI; + + . put spool que : + IF que is empty + THEN putline (file, "Warteschlange ist leer"); + ELSE write (file, "Warteschlange ("); + write (file, text (counter)); + write (file, " Auftraege):"); + line (file, 2); + to first que entry ; + WHILE next que entry found + REP putline (file, list entry. entry line) PER; + FI; + +END PROC list spool ; + + +PROC clear spool : + + first := 1; + last := 1; + counter := 0; + FOR list index FROM 1 UPTO que size + REP list entry. ds params := empty params; + list entry. entry line := ""; + forget (list entry. space) + PER; + +END PROC clear spool; + +(*********************************************************************) +(* Hilfsprozeduren zum Spoolmanager *) + +BOOL PROC is valid que entry (INT CONST index) : + + que (index). entry line <> "" + +END PROC is valid que entry; + + +INT PROC next (INT CONST index) : + + IF index < que size + THEN index + 1 + ELSE 1 + FI + +END PROC next; + + +PROC to first que entry : + + list index := first - 1; + +ENDPROC to first que entry ; + + +BOOL PROC next que entry found : + + list index := next (list index); + WHILE is not last que entry + REP IF is valid que entry (list index) + THEN LEAVE next que entry found WITH TRUE FI; + list index := next (list index); + PER; + FALSE + + . is not last que entry : + list index <> last + +ENDPROC next que entry found ; + + +PROC get next entry line (TEXT VAR entry line, INT VAR index) : + + IF index = 0 + THEN list index := first - 1 + ELSE list index := index + FI; + IF next que entry found + THEN entry line := list entry. entry line; + index := list index; + ELSE entry line := ""; + index := 0; + FI; + +END PROC get next entry line; + + +PROC new first (ENTRY VAR new first entry) : + + IF que is full + THEN errorstop ("Spool ist voll") + ELSE first DECR 1 ; + IF first = 0 THEN first := que size FI; + first entry := new first entry; + counter INCR 1; + FI; + +END PROC new first; + + +PROC erase entry (INT CONST index) : + + entry. ds params := empty params; + entry. entry line := ""; + forget (entry.space) ; + counter DECR 1; + IF index = first + THEN inc first + FI ; + + . entry : que (index) + + . inc first : + REP first := next (first) + UNTIL que is empty OR is valid que entry (first) PER + +END PROC erase entry; + + +PROC erase fetch entry : + + fetch entry. ds params := empty params; + fetch entry. entry line := ""; + forget (fetch entry. space); + valid fetch entry := FALSE; + +END PROC erase fetch entry; + + +BOOL PROC is entry from order task (TEXT CONST file name) : + + correct order task CAND correct filename + + . correct order task : + order task name = list entry. ds params. sendername + AND order task station = list entry. ds params. station + + . correct file name : + file name = "" OR file name = list entry. ds params. name + +END PROC is entry from order task; + + +PROC start (PROC server start): + + begin (PROC server start, server); + +END PROC start; + + +PROC stop : + + stop server; + send calling parent reply if necessary; + + . stop server: + IF exists (server) THEN end (server) FI; + server := niltask; + server is waiting := FALSE; + stop command pending := FALSE; + + . send calling parent reply if necessary : + IF exists (calling parent) + THEN forget (ds); ds := nilspace; + send (calling parent, ack, ds); + calling parent := niltask; + FI; + +END PROC stop; + + +PROC next headline information (TEXT VAR t): + + begin pos := pos (headline (file), begin char, end pos + 1); + IF begin pos = 0 + THEN begin pos := LENGTH headline (file) + 1; + t := ""; + ELSE end pos := pos (headline (file), end char, begin pos + 1); + IF end pos = 0 + THEN end pos := LENGTH headline (file) + 1; + t := ""; + ELSE t := subtext (headline (file), begin pos+1, end pos-1) + FI + FI + +END PROC next headline information; + + +PROC send ack : + + forget (ds); ds := nilspace; + send (order task, ack, ds) + +END PROC send ack; + + +PROC manager question (TEXT CONST question) : + + forget (ds); ds := nilspace; error msg := ds ; + error msg := question ; + send (order task, question ack, ds) + +ENDPROC manager question ; + + +PROC manager message (TEXT CONST message) : + + forget (ds); ds := nilspace; error msg := ds ; + error msg := message ; + send (order task, message ack, ds) + +ENDPROC manager message ; + +(*********************************************************************) +(* Spool - Kommandos *) + +INT VAR command index , params ; +TEXT VAR command line, param 1, param 2 ; + +LET spool command list = +"break:1.0start:2.01stop:4.0halt:5.0first:6.0killer:7.0listspool:8.0 +clearspool:9.0spoolcontrolby:10.1"; + +PROC spool command (PROC server start) : + + enable stop ; + continue (order - continue code) ; + disable stop ; + REP command dialogue (TRUE) ; + get command ("gib Spool-Kommando:", command line); + analyze command (spool command list, command line, 3, command index, + params, param1, param2); + execute command (PROC server start); + UNTIL NOT online PER; + command dialogue (FALSE); + break (quiet); + set autonom; + +END PROC spool command; + + +PROC execute command (PROC server start) : + + enable stop; + SELECT command index OF + CASE 1 : break + CASE 2 : start server + CASE 3 : start server with new channel + CASE 4 : stop server + CASE 5 : halt server + CASE 6 : first cmd + CASE 7 : killer cmd + CASE 8 : show spool list + CASE 9 : clear spool + CASE 10 : spool control task (task (param1)) + OTHERWISE do (command line) + END SELECT; + + . start server : + IF server channel <= 0 OR server channel >= 33 + THEN line; + putline ("WARNUNG : Serverkanal nicht eingestellt"); + FI; + stop server; + start (PROC server start); + + . start server with new channel: + INT VAR i := int (param1); + IF last conversion ok + THEN server channel (i); + start server; + ELSE errorstop ("falsche Kanalangabe") + FI; + + . stop server : + disable stop; + stop; + IF valid fetch entry CAND + yes (""13""10"" + fetch entry. entry line + " neu eintragen") + THEN new first (fetch entry) FI; + erase fetch entry; + enable stop; + + . halt server : + stop command pending := TRUE; + IF NOT exists (server) OR server is waiting + THEN stop server; + erase fetch entry; + FI; + + . first cmd : + line ; + to first que entry ; + WHILE next que entry found + REP say (list entry. entry line) ; + IF yes (" als erstes") + THEN new first (list entry); + erase entry (list index); + LEAVE first cmd + FI ; + PER; + + . killer cmd : + line ; + to first que entry ; + WHILE next que entry found + REP say (list entry. entry line) ; + IF yes (" loeschen") THEN erase entry (list index) FI ; + PER; + + . show spool list : + list spool; + disable stop; + show (file); + forget (ds); + +ENDPROC execute command ; + +ENDPACKET spool manager; + -- cgit v1.2.3