printer.pp 5.6 KB

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