MODULE LPR;
IMPORT Files, Streams, TCP, DNS, IP, Configuration, Strings;
CONST
DefConPort = 515;
BegLocPort = 721;
EndLocPort = 731;
LF = 0AX;
CR = 0DX;
DefaultEmail = "oberonuser@ethz.ch";
OK = 0;
FILENOTFOUND = -1;
HOSTNOTFOUND = -2;
READERNIL = -3;
SENDCONTROLFILEFAILED = -4;
RECEIVECONTROLFILEFAILED = -5;
SENDDATAFILEFAILED= -6;
RECEIVEDATAFILEFAILED= -7;
RECEIVEPRINTJOBFAILED= -8;
NOTCONNECTED=-9;
VAR
jobNr: INTEGER;
PROCEDURE Print*(CONST host, queue, docName, email: ARRAY OF CHAR; banner, mail: BOOLEAN; data : Streams.Reader; size: LONGINT; VAR res : LONGINT);
VAR
dataFile, controlFile: ARRAY 64 OF CHAR;
nrStr: ARRAY 8 OF CHAR;
state: CHAR;
controlfile : Strings.Buffer;
controlfileWriter : Streams.Writer;
reader: Streams.Reader;
writer: Streams.Writer;
fadr: IP.Adr;
locport: INTEGER;
connres, len : LONGINT;
conn: TCP.Connection;
buf : ARRAY 10000 OF CHAR;
BEGIN
DNS.HostByName(host, fadr, connres);
IF connres = DNS.Ok THEN
locport := BegLocPort;
REPEAT
NEW(conn); conn.Open(locport, fadr, DefConPort, connres);
INC(locport)
UNTIL (connres = TCP.Ok) OR (locport > EndLocPort);
IF connres = TCP.Ok THEN
IF data # NIL THEN
Streams.OpenReader(reader, conn.Receive);
Streams.OpenWriter(writer, conn.Send);
INC(jobNr);
IF jobNr >= 1000 THEN
jobNr := 100
END;
Strings.IntToStr(jobNr, nrStr);
COPY("dfA",dataFile);
Strings.Append(dataFile, nrStr);
Strings.Append(dataFile, host);
COPY("cfA", controlFile);
Strings.Append(controlFile, nrStr);
Strings.Append(controlFile, host);
writer.Char(02X); writer.String(queue);writer.Char(LF);
writer.Update();
state := 0FFX; state := reader.Get();
IF (state = 0X) & (reader.res = Streams.Ok) THEN
Strings.IntToStr(size + 1, nrStr);
writer.Char( 03X); writer.String(nrStr); writer.Char(" "); writer.String(dataFile); writer.Char(LF);
writer.Update();
state := 0FFX; state := reader.Get();
IF (state = 0X) & (reader.res = Streams.Ok) THEN
WHILE data.res = Streams.Ok DO
data.Bytes(buf, 0, LEN(buf), len);
writer.Bytes(buf, 0, len);
END;
writer.Char(LF); writer.Char(0X);
writer.Update();
state := 0FFX; state := reader.Get();
IF (state = 0X)& (reader.res = Streams.Ok) THEN
NEW(controlfile,100000);
controlfileWriter := controlfile.GetWriter();
controlfileWriter.Char("H");controlfileWriter.String(host); controlfileWriter.Char(LF);
controlfileWriter.Char("P"); controlfileWriter.String(email); controlfileWriter.Char(LF);
IF mail THEN
controlfileWriter.Char("M"); controlfileWriter.String(email); controlfileWriter.Char(LF);
END;
IF docName # "" THEN
controlfileWriter.Char("J");controlfileWriter.String(docName);controlfileWriter.Char(LF);
END;
IF banner THEN
controlfileWriter.Char("L"); controlfileWriter.String(email); controlfileWriter.Char(LF);
END;
controlfileWriter.Char("l");controlfileWriter.String(dataFile);controlfileWriter.Char(LF);
controlfileWriter.Char("U");controlfileWriter.String(dataFile);controlfileWriter.Char(LF);
controlfileWriter.Char("N");controlfileWriter.String(docName);controlfileWriter.Char(LF);
Strings.IntToStr(controlfile.GetLength(), nrStr);
writer.Char( 02X); writer.String(nrStr); writer.Char( " "); writer.String(controlFile);writer.Char( LF);
writer.Update();
state := 0FFX; state := reader.Get();
IF (state = 0X) & (reader.res = Streams.Ok) THEN
controlfile.Write(writer); writer.Char(0X);
writer.Update();
conn.Close();
state := 0FFX; state := reader.Get();
IF (state = 0X) THEN
res := OK;
ELSE
res := SENDCONTROLFILEFAILED;
END
ELSE
res := RECEIVECONTROLFILEFAILED;
END
ELSE
res := SENDDATAFILEFAILED;
END
ELSE
res := RECEIVEDATAFILEFAILED;
END
ELSE
res := RECEIVEPRINTJOBFAILED
END;
ELSE
res := READERNIL;
END;
ELSE
res := NOTCONNECTED;
END;
ELSE
res := HOSTNOTFOUND;
END;
END Print;
PROCEDURE ShowJobs*(out: Streams.Writer; CONST host, queue : ARRAY OF CHAR; VAR res: LONGINT);
VAR
job: ARRAY 64 OF CHAR;
connres: LONGINT;
conn: TCP.Connection;
reader: Streams.Reader;
writer: Streams.Writer;
fadr: IP.Adr;
locport: INTEGER;
BEGIN
DNS.HostByName(host, fadr, connres);
IF connres = DNS.Ok THEN
locport := BegLocPort;
REPEAT
NEW(conn); conn.Open(locport, fadr, DefConPort, connres);
INC(locport)
UNTIL (connres = TCP.Ok) OR (locport > EndLocPort);
IF connres = TCP.Ok THEN
Streams.OpenReader(reader, conn.Receive);
Streams.OpenWriter(writer, conn.Send);
writer.Char(04X); writer.String(queue);writer.Char(LF);
writer.Update();
WHILE reader.res = Streams.Ok DO
reader.Ln(job);
out.String(job);
END;
res := OK;
conn.Close();
ELSE
res := NOTCONNECTED;
END;
ELSE
res := HOSTNOTFOUND;
END;
END ShowJobs;
PROCEDURE RemoveJob*(CONST host, queue, email, job: ARRAY OF CHAR; VAR res : LONGINT);
VAR
connres: LONGINT;
conn: TCP.Connection;
reader: Streams.Reader;
writer : Streams.Writer;
fadr: IP.Adr;
locport: INTEGER;
BEGIN
DNS.HostByName(host, fadr, connres);
IF connres = DNS.Ok THEN
locport := BegLocPort;
REPEAT
NEW(conn); conn.Open(locport, fadr, DefConPort, connres);
INC(locport)
UNTIL (connres = TCP.Ok) OR (locport > EndLocPort);
IF connres = TCP.Ok THEN
Streams.OpenReader(reader, conn.Receive);
Streams.OpenWriter(writer, conn.Send);
writer.Char(05X);writer.String(queue); writer.Char(" "); writer.String(email);
IF job # "" THEN
writer.Char(" ");
writer.String(job)
END;
writer.Char(LF);
writer.Update();
res := OK;
conn.Close();
ELSE
res := NOTCONNECTED;
END;
ELSE
res := HOSTNOTFOUND;
END;
END RemoveJob;
PROCEDURE PrintFile*(CONST fn : ARRAY OF CHAR; VAR res : LONGINT);
VAR
file : Files.File;
fileReader : Files.Reader;
host, queue, email: ARRAY 100 OF CHAR;
banner, mail : BOOLEAN;
BEGIN
file := Files.Old(fn);
IF (file # NIL) THEN
Configuration.Get("LPR.host", host, res);
Configuration.Get("LPR.queue", queue, res);
Configuration.Get("LPR.email", email, res);
banner := FALSE;
mail := FALSE;
Files.OpenReader(fileReader, file, 0);
Print(host, queue, "Oberon Document", email, banner, mail, fileReader, file.Length(), res);
ELSE
res := FILENOTFOUND;
END;
END PrintFile;
BEGIN
jobNr := 99;
END LPR.
Usage:
PROCEDURE PrintTest*;
VAR
res : LONGINT;
BEGIN
KernelLog.String("Printing....");
LPR.PrintFile("test.ps", res);
KernelLog.Int(res, 5); KernelLog.Ln;
END PrintTest;
PROCEDURE PrintTest2*();
VAR
file : Files.File;
fileReader : Files.Reader;
host, queue, email: ARRAY 100 OF CHAR;
banner, mail : BOOLEAN;
res : LONGINT;
BEGIN
file := Files.Old("test.ps");
IF (file # NIL) THEN
Files.OpenReader(fileReader, file, 0);
COPY("129.132.134.122", host);
COPY("dummyQueue", queue);
COPY("daniel.keller@inf.ethz.ch", email);
banner := FALSE;
mail := FALSE;
Files.OpenReader(fileReader, file, 0);
KernelLog.String("Printing....");
LPR.Print(host, queue, "Oberon Document", email, banner, mail, fileReader, file.Length(), res);
KernelLog.Int(res, 5); KernelLog.Ln;
END;
END PrintTest2;
PROCEDURE ShowJobTest*;
VAR
out : Streams.Writer;
host, queue: ARRAY 100 OF CHAR;
res : LONGINT;
BEGIN
Streams.OpenWriter(out, KernelLog.Send);
Configuration.Get("LPR.host", host);
Configuration.Get("LPR.queue", queue);
LPR.ShowJobs(out, host, queue, res);
KernelLog.Int(res, 5); KernelLog.Ln;
END ShowJobTest;