123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- {
- $Id$
- This file is part of the Free Pascal run time library.
- Copyright (c) 1999-2000 by Michael Van Canneyt,
- member of the Free Pascal development team.
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- { Change Log
- ----------
- Started by Michael Van Canneyt, 1996
- ([email protected])
- Current version is 0.9
- Date Version Who Comments
- 1999-2000 by 0.8 Michael Initial implementation
- 11/97 0.9 Peter Vreman <[email protected]>
- Unit now depends on the
- linux unit only.
- Cleaned up code.
- ---------------------------------------------------------------------}
- Unit printer;
- Interface
- {.$DEFINE PRINTERDEBUG}
- Const
- DefFile = '/tmp/PID.lst';
- Var
- Lst : Text;
- Procedure AssignLst ( Var F : text; ToFile : string);
- {
- Assigns to F a printing device. ToFile is a string with the following form:
- '|filename options' : This sets up a pipe with the program filename,
- with the given options
- 'filename' : Prints to file filename. Filename can contain the string 'PID'
- (No Quotes), which will be replaced by the PID of your program.
- When closing lst, the file will be sent to lpr and deleted.
- (lpr should be in PATH)
- 'filename|' Idem as previous, only the file is NOT sent to lpr, nor is it
- deleted.
- (useful for opening /dev/printer or for later printing)
- Lst is set up using '/tmp/PID.lst'. You can change this behaviour at
- compile time, setting the DefFile constant.
- }
- Implementation
- Uses Unix,BaseUnix,Strings;
- {
- include definition of textrec
- }
- {$i textrec.inc}
- Const
- P_TOF = 1; { Print to file }
- P_TOFNP = 2; { Print to File, don't spool }
- P_TOP = 3; { Print to Pipe }
- Var
- Lpr : String[255]; { Contains path to lpr binary, including null char }
- SaveExit : pointer;
- Procedure PrintAndDelete (f:string);
- var
- i,j : longint;
- p,pp : ppchar;
- begin
- f:=f+#0;
- if lpr='' then
- exit;
- i:=fpFork;
- if i<0 then
- exit; { No printing was done. We leave the file where it is.}
- if i=0 then
- begin
- { We're in the child }
- getmem(p,12);
- if p=nil then
- halt(127);
- pp:=p;
- pp^:=@lpr[1];
- inc(pp);
- pp^:=@f[1];
- inc(pp);
- pp^:=nil;
- fpExecve(lpr,p,envp);
- { In trouble here ! }
- halt(128)
- end
- else
- begin
- { We're in the parent. }
- fpwaitpid (i,@j,0);
- if j<>0 then
- exit;
- { Erase the file }
- fpUnlink(f);
- end;
- end;
- Procedure OpenLstPipe ( Var F : Text);
- begin
- POpen (f,StrPas(textrec(f).name),'W');
- end;
- Procedure OpenLstFile ( Var F : Text);
- var
- i : longint;
- begin
- {$IFDEF PRINTERDEBUG}
- writeln ('Printer : In OpenLstFile');
- {$ENDIF}
- If textrec(f).mode <> fmoutput then
- exit;
- textrec(f).userdata[15]:=0; { set Zero length flag }
- i:=fpOpen(StrPas(textrec(f).name),(Open_WrOnly or Open_Creat), 438);
- if i<0 then
- textrec(f).mode:=fmclosed
- else
- textrec(f).handle:=i;
- end;
- Procedure CloseLstFile ( Var F : Text);
- begin
- {$IFDEF PRINTERDEBUG}
- writeln ('Printer : In CloseLstFile');
- {$ENDIF}
- fpclose (textrec(f).handle);
- { In case length is zero, don't print : lpr would give an error }
- if (textrec(f).userdata[15]=0) and (textrec(f).userdata[16]=P_TOF) then
- begin
- fpUnlink(StrPas(textrec(f).name));
- exit
- end;
- { Non empty : needs printing ? }
- if (textrec(f).userdata[16]=P_TOF) then
- PrintAndDelete (strpas(textrec(f).name));
- textrec(f).mode:=fmclosed
- end;
- Procedure InOutLstFile ( Var F : text);
- begin
- {$IFDEF PRINTERDEBUG}
- writeln ('Printer : In InOutLstFile');
- {$ENDIF}
- If textrec(f).mode<>fmoutput then
- exit;
- if textrec(f).bufpos<>0 then
- textrec(f).userdata[15]:=1; { Set it is not empty. Important when closing !!}
- fpwrite(textrec(f).handle,textrec(f).bufptr^,textrec(f).bufpos);
- textrec(f).bufpos:=0;
- end;
- Procedure SubstPidInName ( Var s : string);
- var
- i : longint;
- temp : string[8];
- begin
- i:=pos('PID',s);
- if i=0 then
- exit;
- delete (s,i,3);
- str(fpGetPid,temp);
- insert(temp,s,i);
- {$IFDEF PRINTERDEBUG}
- writeln ('Print : Filename became : ',s);
- {$ENDIF}
- end;
- Procedure AssignLst ( Var F : text; ToFile : string);
- begin
- {$IFDEF PRINTERDEBUG}
- writeln ('Printer : In AssignLst');
- {$ENDIF}
- If ToFile='' then
- exit;
- textrec(f).bufptr:=@textrec(f).buffer;
- textrec(f).bufsize:=128;
- SubstPidInName (Tofile);
- if ToFile[1]='|' then
- begin
- Assign(f,Copy(ToFile,2,255));
- textrec(f).userdata[16]:=P_TOP;
- textrec(f).OpenFunc:=@OpenLstPipe;
- end
- else
- begin
- if Tofile[Length(ToFile)]='|' then
- begin
- Assign(f,Copy(ToFile,1,length(Tofile)-1));
- textrec(f).userdata[16]:=P_TOFNP;
- end
- else
- begin
- Assign(f,ToFile);
- textrec(f).userdata[16]:=P_TOF;
- end;
- textrec(f).OpenFunc:=@OpenLstFile;
- textrec(f).CloseFunc:=@CloseLstFile;
- textrec(f).InoutFunc:=@InoutLstFile;
- textrec(f).FlushFunc:=@InoutLstFile;
- end;
- end;
- Procedure PrinterExitProc;
- begin
- close(lst);
- ExitProc:=SaveExit
- end;
- begin
- SaveExit:=ExitProc;
- ExitProc:=@PrinterExitProc;
- AssignLst(Lst,DefFile);
- rewrite(Lst);
- lpr:='/usr/bin/lpr';
- end.
- {
- $Log$
- Revision 1.6 2003-09-20 12:38:29 marco
- * FCL now compiles for FreeBSD with new 1.1. Now Linux.
- Revision 1.5 2003/09/14 20:15:01 marco
- * Unix reform stage two. Remove all calls from Unix that exist in Baseunix.
- Revision 1.4 2002/09/07 16:01:27 peter
- * old logs removed and tabs fixed
- }
|