printer.pp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Michael Van Canneyt,
  5. member of the Free Pascal development team.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. { Change Log
  13. ----------
  14. Started by Michael Van Canneyt, 1996
  15. ([email protected])
  16. Current version is 0.9
  17. Date Version Who Comments
  18. 1999-2000 by 0.8 Michael Initial implementation
  19. 11/97 0.9 Peter Vreman <[email protected]>
  20. Unit now depends on the
  21. linux unit only.
  22. Cleaned up code.
  23. ---------------------------------------------------------------------}
  24. Unit printer;
  25. Interface
  26. {.$DEFINE PRINTERDEBUG}
  27. Const
  28. DefFile = '/tmp/PID.lst';
  29. Var
  30. Lst : Text;
  31. Procedure AssignLst ( Var F : text; ToFile : string);
  32. {
  33. Assigns to F a printing device. ToFile is a string with the following form:
  34. '|filename options' : This sets up a pipe with the program filename,
  35. with the given options
  36. 'filename' : Prints to file filename. Filename can contain the string 'PID'
  37. (No Quotes), which will be replaced by the PID of your program.
  38. When closing lst, the file will be sent to lpr and deleted.
  39. (lpr should be in PATH)
  40. 'filename|' Idem as previous, only the file is NOT sent to lpr, nor is it
  41. deleted.
  42. (useful for opening /dev/printer or for later printing)
  43. Lst is set up using '/tmp/PID.lst'. You can change this behaviour at
  44. compile time, setting the DefFile constant.
  45. }
  46. Implementation
  47. Uses Unix,BaseUnix,Strings;
  48. {
  49. include definition of textrec
  50. }
  51. {$i textrec.inc}
  52. Const
  53. P_TOF = 1; { Print to file }
  54. P_TOFNP = 2; { Print to File, don't spool }
  55. P_TOP = 3; { Print to Pipe }
  56. Var
  57. Lpr : String[255]; { Contains path to lpr binary, including null char }
  58. SaveExit : pointer;
  59. Procedure PrintAndDelete (f:string);
  60. var
  61. i,j : longint;
  62. p,pp : ppchar;
  63. begin
  64. f:=f+#0;
  65. if lpr='' then
  66. exit;
  67. i:=fpFork;
  68. if i<0 then
  69. exit; { No printing was done. We leave the file where it is.}
  70. if i=0 then
  71. begin
  72. { We're in the child }
  73. getmem(p,12);
  74. if p=nil then
  75. halt(127);
  76. pp:=p;
  77. pp^:=@lpr[1];
  78. inc(pp);
  79. pp^:=@f[1];
  80. inc(pp);
  81. pp^:=nil;
  82. fpExecve(lpr,p,envp);
  83. { In trouble here ! }
  84. halt(128)
  85. end
  86. else
  87. begin
  88. { We're in the parent. }
  89. fpwaitpid (i,@j,0);
  90. if j<>0 then
  91. exit;
  92. { Erase the file }
  93. fpUnlink(f);
  94. end;
  95. end;
  96. Procedure OpenLstPipe ( Var F : Text);
  97. begin
  98. POpen (f,StrPas(textrec(f).name),'W');
  99. end;
  100. Procedure OpenLstFile ( Var F : Text);
  101. var
  102. i : longint;
  103. begin
  104. {$IFDEF PRINTERDEBUG}
  105. writeln ('Printer : In OpenLstFile');
  106. {$ENDIF}
  107. If textrec(f).mode <> fmoutput then
  108. exit;
  109. textrec(f).userdata[15]:=0; { set Zero length flag }
  110. i:=fpOpen(StrPas(textrec(f).name),(Open_WrOnly or Open_Creat), 438);
  111. if i<0 then
  112. textrec(f).mode:=fmclosed
  113. else
  114. textrec(f).handle:=i;
  115. end;
  116. Procedure CloseLstFile ( Var F : Text);
  117. begin
  118. {$IFDEF PRINTERDEBUG}
  119. writeln ('Printer : In CloseLstFile');
  120. {$ENDIF}
  121. fpclose (textrec(f).handle);
  122. { In case length is zero, don't print : lpr would give an error }
  123. if (textrec(f).userdata[15]=0) and (textrec(f).userdata[16]=P_TOF) then
  124. begin
  125. fpUnlink(StrPas(textrec(f).name));
  126. exit
  127. end;
  128. { Non empty : needs printing ? }
  129. if (textrec(f).userdata[16]=P_TOF) then
  130. PrintAndDelete (strpas(textrec(f).name));
  131. textrec(f).mode:=fmclosed
  132. end;
  133. Procedure InOutLstFile ( Var F : text);
  134. begin
  135. {$IFDEF PRINTERDEBUG}
  136. writeln ('Printer : In InOutLstFile');
  137. {$ENDIF}
  138. If textrec(f).mode<>fmoutput then
  139. exit;
  140. if textrec(f).bufpos<>0 then
  141. textrec(f).userdata[15]:=1; { Set it is not empty. Important when closing !!}
  142. fpwrite(textrec(f).handle,textrec(f).bufptr^,textrec(f).bufpos);
  143. textrec(f).bufpos:=0;
  144. end;
  145. Procedure SubstPidInName ( Var s : string);
  146. var
  147. i : longint;
  148. temp : string[8];
  149. begin
  150. i:=pos('PID',s);
  151. if i=0 then
  152. exit;
  153. delete (s,i,3);
  154. str(fpGetPid,temp);
  155. insert(temp,s,i);
  156. {$IFDEF PRINTERDEBUG}
  157. writeln ('Print : Filename became : ',s);
  158. {$ENDIF}
  159. end;
  160. Procedure AssignLst ( Var F : text; ToFile : string);
  161. begin
  162. {$IFDEF PRINTERDEBUG}
  163. writeln ('Printer : In AssignLst');
  164. {$ENDIF}
  165. If ToFile='' then
  166. exit;
  167. textrec(f).bufptr:=@textrec(f).buffer;
  168. textrec(f).bufsize:=128;
  169. SubstPidInName (Tofile);
  170. if ToFile[1]='|' then
  171. begin
  172. Assign(f,Copy(ToFile,2,255));
  173. textrec(f).userdata[16]:=P_TOP;
  174. textrec(f).OpenFunc:=@OpenLstPipe;
  175. end
  176. else
  177. begin
  178. if Tofile[Length(ToFile)]='|' then
  179. begin
  180. Assign(f,Copy(ToFile,1,length(Tofile)-1));
  181. textrec(f).userdata[16]:=P_TOFNP;
  182. end
  183. else
  184. begin
  185. Assign(f,ToFile);
  186. textrec(f).userdata[16]:=P_TOF;
  187. end;
  188. textrec(f).OpenFunc:=@OpenLstFile;
  189. textrec(f).CloseFunc:=@CloseLstFile;
  190. textrec(f).InoutFunc:=@InoutLstFile;
  191. textrec(f).FlushFunc:=@InoutLstFile;
  192. end;
  193. end;
  194. Procedure PrinterExitProc;
  195. begin
  196. close(lst);
  197. ExitProc:=SaveExit
  198. end;
  199. begin
  200. SaveExit:=ExitProc;
  201. ExitProc:=@PrinterExitProc;
  202. AssignLst(Lst,DefFile);
  203. rewrite(Lst);
  204. lpr:='/usr/bin/lpr';
  205. end.
  206. {
  207. $Log$
  208. Revision 1.6 2003-09-20 12:38:29 marco
  209. * FCL now compiles for FreeBSD with new 1.1. Now Linux.
  210. Revision 1.5 2003/09/14 20:15:01 marco
  211. * Unix reform stage two. Remove all calls from Unix that exist in Baseunix.
  212. Revision 1.4 2002/09/07 16:01:27 peter
  213. * old logs removed and tabs fixed
  214. }