Fix Pascal quoting
[ohcount] / test / src_dir / pike2.pmod
1 //
2 // LPD.pmod: an implementation of the BSD lpd protocol (RFC 1179).
3 // This is a module for pike.
4 // 3 July 1998 <hww3@riverweb.com> Bill Welliver
5 //
6 // $Id: LPD.pmod,v 1.10 2008/01/13 17:02:43 nilsson Exp $
7 //
8
9 #pike __REAL_VERSION__
10
11 //! A client for communicating with printers and print spoolers that
12 //! support the BSD lpd protocol (RFC 1179).
13 class client {
14   string host;
15   int port;
16   private object conn;
17   int jobnum;
18   string jobtype;
19   string jobname;
20
21   private int connect(string host, int port)
22   {
23     int a=random(10);
24     // try to open one of the "official" local socket ports.
25     // not having one doesn't seem to be a problem with most LPD 
26     // servers, but we should at least try. will probably fail
27     // if two try to open the same local port at once. ymmv.
28     int res=conn->open_socket(721 + a);
29
30     return conn->connect(host, port);
31   }
32
33 //! @decl int set_job_type(string type)
34 //! Set the type of job to be sent to the printer to @i{type@}.
35 //! Valid types are: text, postscript and raw.
36   int set_job_type(string type)
37   {
38     type=lower_case(type);
39     
40     switch (type) { 
41      case "f":
42      case "text":
43       jobtype="f";
44       break;
45
46      case "o":
47      case "postscript":
48      case "ps":
49       jobtype="o";
50       break;
51
52      default:
53      case "l":
54      case "raw":
55       jobtype="l";
56       break;
57     }
58     return 1;
59   }
60
61 //! @decl int set_job_name(string name)
62 //! Sets the name of the print job to @i{name@}.
63   int set_job_name(string name)
64   {
65     jobname=name;
66     return 1;
67   }
68
69 //! @decl int start_queue(string queue)
70 //! Start the queue @i{queue@} if not already printing.
71 //! @returns
72 //! Returns 0 if unable to connect, 1 otherwise. 
73   int start_queue(string queue)
74   {
75     if(!queue) return 0;
76
77     if(!connect(host, port))
78       return 0;
79
80     conn->write(sprintf("%c%s\n", 01, queue));
81     string resp= conn->read();
82     conn->close();
83     return 1;
84   }
85
86 //! @decl string|int send_job(string queue, string job)
87 //! Send print job consisting of data @i{job@} to printer @i{queue@}.
88 //! @returns
89 //! Returns 1 if success, 0 otherwise.
90   int send_job(string queue, string job)
91   {
92     string resp;
93
94     if(!queue) return 0;
95
96     if(!connect(host, port))
97       return 0;
98     // werror("connected to " + host + "\n");
99
100     string control="";
101     control+="H"+gethostname()+"\n";
102 #if constant(getuid) && constant(getpwuid)
103     control+="P"+(getpwuid(getuid())[0]||"nobody")+"\n";
104 #else
105     control+="P-1\n";
106 #endif
107     control+=(jobtype||"l")+"dfA"+ sprintf("%03d%s", jobnum, gethostname())+"\n";
108     if(jobname)
109     {
110       control+="J" + jobname + "\n";
111       control+="N" + jobname + "\n";
112     }
113     else
114     { 
115       control+="JPike LPD Client Job " + jobnum + "\n";
116       control+="NPike LPD Client Job " + jobnum + "\n";
117     }
118     jobnum++;
119 werror("job file:\n\n" + control  + "\n\n");
120
121     conn->write(sprintf("%c%s\n", 02, queue));
122     resp=conn->read(1);
123     if((int)resp !=0)
124     {
125       werror("receive job failed.\n");
126       return 0;
127     }
128
129     conn->write(sprintf("%c%s cfA%03d%s\n", 02, (string)sizeof(control),
130                         jobnum,gethostname()));
131
132     resp=conn->read(1);
133     if((int)resp !=0)
134     {
135       werror("request receive control failed.\n");
136       return 0;
137     }
138
139     conn->write(sprintf("%s%c", control, 0));
140
141     resp=conn->read(1);
142     if((int)resp !=0)
143     {
144       werror("send receive control failed.\n");
145       return 0;
146     }
147
148     conn->write(sprintf("%c%s dfA%03d%s\n", 03, (string)sizeof(job), jobnum,
149                         gethostname()));
150     resp=conn->read(1);
151     if((int)resp !=0)
152     {
153       werror("request receive job failed.\n");
154       return 0;
155     }
156
157
158     conn->write(sprintf("%s%c", job, 0));
159
160     resp=conn->read(1);
161     if((int)resp !=0)
162     {
163       werror("send receive job failed.\n");
164       return 0;
165     }
166
167
168
169     // read the response. 
170
171 //    resp=conn->read();
172     if((int)(resp)!=0) 
173     { 
174       conn->close();
175       return 0;
176     }
177     conn->close();
178 //    start_queue(queue);
179     return 1;
180   }
181
182 //! @decl int delete_job(string queue, int|void job)
183 //! Delete job @i{job@} from printer @i{queue@}.
184 //! @returns
185 //! Returns 1 on success, 0 otherwise.
186   int delete_job(string queue, int|void job)
187   {
188     if(!queue) return 0;
189
190     if(!connect(host, port))
191       return 0;
192
193 #if constant(getpwuid) && constant(getuid)
194     string agent=(getpwuid(getuid())[0]||"nobody");
195 #else
196     string agent="nobody";
197 #endif
198
199     if(job)
200       conn->write(sprintf("%c%s %s %d\n", 05, queue, agent, job));
201     else
202       conn->write(sprintf("%c%s %s\n", 05, queue, agent));
203     string resp= conn->read();
204     conn->close();
205     return 1;
206   }
207
208
209 //! @decl string|int status(string queue)
210 //! Check the status of queue @i{queue@}.
211 //! @returns
212 //! Returns 0 on failure, otherwise returns the status response from the printer.
213   string|int status(string queue)
214   {
215     if(!queue) return 0;
216
217     if(!connect(host, port))
218       return 0;
219
220     conn->write(sprintf("%c%s\n", 04, queue));
221     string resp= conn->read();
222     conn->close();
223     return resp;
224   }
225
226 //! Create a new LPD client connection.
227 //! @param hostname
228 //! Contains the hostname or ipaddress of the print host.
229 //! if not provided, defaults to @i{localhost@}.
230 //! @param portnum
231 //! Contains the port the print host is listening on.
232 //! if not provided, defaults to port @i{515@}, the RFC 1179 standard.
233   void create(string|void hostname, int|void portnum)
234   {
235     host=hostname || "localhost";
236     port=portnum || 515;
237     conn=Stdio.File();
238     jobnum=1;
239   }
240 }
241