📄 dxlpdservercore.pas
字号:
unit DXLPDServerCore;
interface
///////////////////////////////////////////////////////////////////////////////
// Component: TDXLPDServerCore
// Author: G.E. Ozz Nixon Jr. (staff@bpdx.com)
// ========================================================================
// Source Owner: DX, Inc. 1995-2003
// Copyright: All code is the property of DX, Inc. Licensed for
// resell by Brain Patchwork DX (tm) and part of the
// DX (r) product lines, which are (c) 1999-2003
// DX, Inc. Source may not be distributed without
// written permission from both Brain Patchwork DX,
// and DX, Inc.
// License: (Reminder), None of this code can be added to other
// developer products without permission. This includes
// but not limited to DCU's, DCP's, DLL's, OCX's, or
// any other form of merging our technologies. All of
// your products released to a public consumer be it
// shareware, freeware, commercial, etc. must contain a
// license notification somewhere visible in the
// application.
// Example is Internet Explorer - Help->About screen
// shows the licensed code contained in the application.
// Code Version: (4th Generation Code)
// ========================================================================
// Description: implements LPD (Line Printer Daemon) protocol
// ========================================================================
// Tests have shown that HP JetDirect boxes use this protocol. Some people
// refer to this protocol as LPD other refer to it as SPOOLER. The design is
// a print job is sent from remote machines to this service. This service can
// accept or reject the requests. The requests can be to print, to return the
// status of the printer or print job, or delete a print job.
//
// We use this protocol in-house as one router to printers on different
// networks and protocols. All of our machines can see the "Queue", and dump
// output to this service, who in-turn actually spools to the printer. This
// is not a "toy" protocol that you simply through into place. It will require
// a detailed understanding of the protocol, printer output format, and how
// to stream data to the destination printer(s).
//
// RFC: 1179
///////////////////////////////////////////////////////////////////////////////
uses
Classes,
DXServerCore;
{$I DXSock.def}
type
PLPDControlFile=^TLPDControlFile;
TLPDControlFile=Record
ClassStr:String[31]; {31 or less}
Host:String[31]; {31 or less}
Indent:Integer;
Job:String[99]; {99 or less}
UserBanner:String;
MailResultsTo:String;
SourceFileName:String[131]; {131 or less}
UserID:String[31]; {31 or less}
SymbolicLinkData:String;
Title:String[79]; {79 or less}
Unlink:String; // windows uses this if "clear immediate" is enabled.
Width:Integer; {default=132}
// font filenames:
TroffRFont:String;
TroffIFont:String;
TroffBFont:String;
TroffSFont:String;
PlotCIF:String;
PrintDVI:String;
FormattedFile:String;
PlotFile:String;
Kerberized:String;
PrintRAW:String; // windows uses this!
DITroff:String;
PostScript:String;
PRFormat:String;
Fortran:String;
TroffOutput:String;
Raster:String;
Palladium:String;
End;
LPDTControlFileEvent = procedure(ClientThread:TDXClientThread;ControlFile:PLPDControlFile) of object;
LPDTSpoolFileEvent = procedure(ClientThread:TDXClientThread;Size:Integer;PathFileName:String) of object;
LPDTQueueEvent = procedure(ClientThread:TDXClientThread;Queue:String) of object;
LPDTQueueListEvent = procedure(ClientThread:TDXClientThread;Queue,List:String) of object;
LPDTQueueRemoveEvent = procedure(ClientThread:TDXClientThread;Queue,Agent,List:String) of object;
LPDTQueueQueryEvent = procedure(ClientThread:TDXClientThread;Queue:String) of object;
LPDTOtherEvent = procedure(ClientThread:TDXClientThread;Command:string;Parm:string;Var Handled:Boolean) of object;
TDXLPDServerCore = class(TDXServerCore)
private
fOnCommandPrintWaiting:LPDTQueueEvent; //$01
fOnCommandReceiveJob:LPDTQueueEvent; //$02
fOnCommandSendJob:LPDTQueueListEvent; //$03
fOnCommandQueueQuery:LPDTQueueQueryEvent; //$04
fOnCommandRemoveJob:LPDTQueueRemoveEvent; //$05
fOnCommandOther: LPDTOtherEvent;
fOnJobControlFile:LPDTControlFileEvent; //Sub $02
fOnJobSpoolFile:LPDTSpoolFileEvent; //Sub $03
fSpoolPath:String;
fControlPath:String;
protected
Procedure SetOnCommandPrintWaiting(value:LPDTQueueEvent);
Procedure SetOnCommandReceiveJob(value:LPDTQueueEvent);
Procedure SetOnCommandSendJob(value:LPDTQueueListEvent);
Procedure SetOnCommandQueueQuery(value:LPDTQueueQueryEvent);
Procedure SetOnCommandRemoveJob(value:LPDTQueueRemoveEvent);
public
constructor Create(AOwner:TComponent); {$IFNDEF OBJECTS_ONLY} override; {$ENDIF}
destructor Destroy; override;
procedure ProcessSession(ClientThread: TDXClientThread);
Procedure SayOK(ClientThread:TDXClientThread);
procedure ProcessReceiveJobSession(ClientThread:TDXClientThread);
Procedure AddQueueEvent(Command:Char;EventProc:LPDTQueueEvent);
Procedure AddListEvent(Command:Char;EventProc:LPDTQueueListEvent);
Procedure AddRemoveEvent(Command:Char;EventProc:LPDTQueueRemoveEvent);
Procedure AddQueryEvent(Command:Char;EventProc:LPDTQueueQueryEvent);
published
property OnCommandPrintWaiting:LPDTQueueEvent read fOnCommandPrintWaiting
write SetOnCommandPrintWaiting;
property OnCommandReceiveJob:LPDTQueueEvent read fOnCommandReceiveJob
write SetOnCommandReceiveJob;
property OnCommandSendJob:LPDTQueueListEvent read fOnCommandSendJob
write SetOnCommandSendJob;
property OnCommandQueueQuery:LPDTQueueQueryEvent read fOnCommandQueueQuery
write SetOnCommandQueueQuery;
property OnCommandRemoveJob:LPDTQueueRemoveEvent read fOnCommandRemoveJob
write SetOnCommandRemoveJob;
property OnCommandOther: LPDTOtherEvent read fOnCommandOther
write fOnCommandOther;
// usually implemented to store the pointer in fpSessionData,
// and then call SayOk(ClientThread)
property OnJobControlFile:LPDTControlFileEvent read fOnJobControlFile
write fOnJobControlFile;
// must be implemented!
// this is the path/filename for application to push to printer
property OnJobSpoolFile:LPDTSpoolFileEvent read fOnJobSpoolFile
write fOnJobSpoolFile;
property InternalSpoolPath:String read fSpoolPath
write fSpoolPath;
property InternalControlPath:String read fControlPath
write fControlPath;
end;
implementation
Uses
DXSock,
SysUtils,
{$IFNDEF LINUX}
FileCtrl,
{$ENDIF}
DXString;
Type
PLPDQueueEvent=^TLPDQueueEvent;
TLPDQueueEvent=record
Tag:Integer;
Command:Char;
EventProcedure:LPDTQueueEvent;
End;
PLPDListEvent=^TLPDListEvent;
TLPDListEvent=record
Tag:Integer;
Command:Char;
EventProcedure:LPDTQueueListEvent;
End;
PLPDRemoveEvent=^TLPDRemoveEvent;
TLPDRemoveEvent=record
Tag:Integer;
Command:Char;
EventProcedure:LPDTQueueRemoveEvent;
End;
PLPDQueryEvent=^TLPDQueryEvent;
TLPDQueryEvent=record
Tag:Integer;
Command:Char;
EventProcedure:LPDTQueueQueryEvent;
End;
constructor TDXLPDServerCore.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
ServerPort:=515;
ProtocolToBind:=wpTCPOnly;
fSpoolPath:='\default\spoolpath\';
fControlPath:='\default\controlpath\';
end;
destructor TDXLPDServerCore.Destroy;
Var
PQueueEvent:PLPDQueueEvent;
PListEvent:PLPDListEvent;
PRemoteEvent:PLPDRemoveEvent;
PQueryEvent:PLPDQueryEvent;
begin
if Assigned(fEventArray) then Begin
While fEventArray.Count>0 do Begin
Case PLPDQueueEvent(fEventArray[0]).Tag of
1:Begin
PQueueEvent:=fEventArray[0];
Dispose(PQueueEvent);
End;
2:Begin
PListEvent:=fEventArray[0];
Dispose(PListEvent);
End;
3:Begin
PRemoteEvent:=fEventArray[0];
Dispose(PRemoteEvent);
End;
4:Begin
PQueryEvent:=fEventArray[0];
Dispose(PQueryEvent);
End;
End;
fEventArray.Delete(0);
End;
End;
inherited Destroy;
end;
(******************************************************************************
ADDQueueEVENT:
Allows you to dynamically assign a new command to the internal
parser. This allows the servercore to support the 'pre-defined'
OnCommand* events, plus you can add other commands dynamically
at run-time in your application without requiring a source code
modification to our components!
To make support easier for us, we ask that you use the Add*Event
procedures to expand our code, reducing code changes when an
upgrade is released!
See documentation for complete information on how this works.
Example Usage: AddQueueEvent('CDROM',MySpecialEvent);
******************************************************************************)
Procedure TDXLPDServerCore.AddQueueEvent(Command:Char;EventProc:LPDTQueueEvent);
Var
PQueueEvent:PLPDQueueEvent;
Loop:Integer;
Begin
Loop:=0;
While Loop<fEventArray.Count do Begin
If PLPDQueueEvent(fEventArray[Loop]).Command=Command then Begin
PLPDQueueEvent(fEventArray[Loop]).EventProcedure:=EventProc;
Exit;
End
Else Inc(Loop);
End;
New(PQueueEvent);
PQueueEvent.Tag:=1; // Denotes Event in fEventArray is a TSimpleEvent!
PQueueEvent.Command:=Command;
PQueueEvent.EventProcedure:=EventProc;
fEventArray.Add(PQueueEvent);
End;
(******************************************************************************
ADDListEVENT:
Allows you to dynamically assign a new command to the internal
parser. This allows the servercore to support the 'pre-defined'
OnCommand* events, plus you can add other commands dynamically
at run-time in your application without requiring a source code
modification to our components!
To make support easier for us, we ask that you use the Add*Event
procedures to expand our code, reducing code changes when an
upgrade is released!
See documentation for complete information on how this works.
Example Usage: AddListEvent('CDROM',MySpecialEvent);
******************************************************************************)
Procedure TDXLPDServerCore.AddListEvent(Command:Char;EventProc:LPDTQueueListEvent);
Var
PListEvent:PLPDListEvent;
Loop:Integer;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -