]>
Commit | Line | Data |
---|---|---|
ef416fc2 | 1 | package com.easysw.cups; |
2 | ||
3 | /** | |
b423cd4c | 4 | * @version 1.2 26-FEB-2006 |
ef416fc2 | 5 | * @author Easy Software Products |
6 | * | |
7 | * Internet Printing Protocol definitions for the Common UNIX Printing | |
8 | * System (CUPS). | |
9 | * | |
b423cd4c | 10 | * Copyright 1997-2006 by Easy Software Products. |
ef416fc2 | 11 | * |
12 | * These coded instructions, statements, and computer programs are the | |
13 | * property of Easy Software Products and are protected by Federal | |
14 | * copyright law. Distribution and use rights are outlined in the file | |
15 | * "LICENSE.txt" which should have been included with this file. If this | |
16 | * file is missing or damaged please contact Easy Software Products | |
17 | * at: | |
18 | * | |
19 | * Attn: CUPS Licensing Information | |
20 | * Easy Software Products | |
21 | * 44141 Airport View Drive, Suite 204 | |
b423cd4c | 22 | * Hollywood, Maryland 20636 USA |
ef416fc2 | 23 | * |
b423cd4c | 24 | * Voice: (301) 373-9600 |
ef416fc2 | 25 | * EMail: cups-info@cups.org |
b423cd4c | 26 | * WWW: http://www.cups.org/ |
ef416fc2 | 27 | */ |
28 | ||
29 | /** | |
30 | * An <code>Cups</code> object is used for connecting to servers, | |
31 | * reading and writing data, and performing common CUPS operations. | |
32 | * | |
33 | * @author TDB | |
b423cd4c | 34 | * @version 1.2 |
ef416fc2 | 35 | * @since JDK1.3 |
36 | */ | |
37 | ||
38 | import java.io.*; | |
39 | import java.util.*; | |
40 | import java.net.*; | |
41 | ||
42 | public class Cups | |
43 | { | |
44 | ||
45 | static final int REQ_STATE_CREATE_HTTP = 0; | |
46 | static final int REQ_STATE_WRITE_HTTP_HEADER = 1; | |
47 | static final int REQ_STATE_WRITE_IPP_HEADER = 2; | |
48 | static final int REQ_STATE_WRITE_IPP_ATTRS = 3; | |
49 | static final int REQ_STATE_FINISH_IPP_ATTRS = 4; | |
50 | static final int REQ_STATE_READ_RESPONSE = 5; | |
51 | static final int REQ_STATE_DONE = 6; | |
52 | static final String[] req_state_names = | |
53 | { "Create HTTP", | |
54 | "Write Http Header", | |
55 | "Write IPP Header", | |
56 | "Write IPP Attrs", | |
57 | "Finish IPP Attrs", | |
58 | "Read Response", | |
59 | "Done" | |
60 | }; | |
61 | ||
62 | ||
63 | static final int FILEREQ_STATE_CREATE_HTTP = 0; | |
64 | static final int FILEREQ_STATE_WRITE_HTTP_HEADER = 1; | |
65 | static final int FILEREQ_STATE_WRITE_IPP_HEADER = 2; | |
66 | static final int FILEREQ_STATE_WRITE_IPP_ATTRS = 3; | |
67 | static final int FILEREQ_STATE_FINISH_IPP_ATTRS = 4; | |
68 | static final int FILEREQ_STATE_WRITE_FILE_DATA = 5; | |
69 | static final int FILEREQ_STATE_READ_RESPONSE = 6; | |
70 | static final int FILEREQ_STATE_DONE = 7; | |
71 | static final String[] filereq_state_names = | |
72 | { "Create HTTP", | |
73 | "Write Http Header", | |
74 | "Write IPP Header", | |
75 | "Write IPP Attrs", | |
76 | "Finish IPP Attrs", | |
77 | "Write File Data", | |
78 | "Read Response", | |
79 | "Done" | |
80 | }; | |
81 | ||
82 | ||
83 | IPP ipp; // IPP Request | |
84 | IPPHttp http; // Connection to server | |
85 | ||
86 | ||
87 | String protocol; // Protocol name | |
88 | String address; // address/name of server | |
89 | int port; // Port # | |
90 | String path; // Path .... | |
91 | String dest; // Name of destination printer | |
92 | String instance; // Instance of printer | |
93 | ||
94 | // | |
95 | // encrypt, user, and passwd are not fully implemented! | |
96 | // | |
97 | boolean encrypt; // Open encrypted connection. | |
98 | String user; // User to login as. | |
99 | String passwd; // Password if needed. | |
100 | ||
101 | String site; // URL of site. | |
102 | ||
103 | int last_error; // Last error # | |
104 | String error_text; // Text for error | |
105 | ||
106 | /** | |
107 | * Void constructor. | |
108 | */ | |
109 | public Cups() | |
110 | { | |
111 | http = null; | |
112 | ipp = null; | |
113 | ||
114 | protocol = "http"; | |
115 | address = "localhost"; | |
116 | port = 631; | |
117 | path = "/"; | |
118 | site = "http://localhost:631/"; | |
119 | dest = ""; | |
120 | instance = ""; | |
121 | user = ""; | |
122 | passwd = ""; | |
123 | encrypt = false; | |
124 | } | |
125 | ||
126 | /** | |
127 | * Constructor using a <code>URL</code>. | |
128 | * | |
129 | * @param <code>p_url</code> A <code>URL</code> object. | |
130 | */ | |
131 | public Cups( URL p_url ) | |
132 | { | |
133 | http = null; | |
134 | ipp = null; | |
135 | ||
136 | protocol = p_url.getProtocol() + "://"; | |
137 | address = p_url.getHost(); | |
138 | port = p_url.getPort(); | |
139 | path = p_url.getPath(); | |
140 | ||
141 | site = protocol + address; | |
142 | if (port > 0) | |
143 | site = site + ":" + port; | |
144 | ||
145 | if (path.length() > 0) | |
146 | site = site + path; | |
147 | ||
148 | dest = ""; | |
149 | instance = ""; | |
150 | user = ""; | |
151 | passwd = ""; | |
152 | encrypt = false; | |
153 | } | |
154 | ||
155 | ||
156 | /** | |
157 | * Set the value of the <code>protocol</code> member. Valid values | |
158 | * are ipp or http. | |
159 | * | |
160 | * @param <code>p_protocol</code> String with protocol. | |
161 | */ | |
162 | public void setProtocol( String p_protocol ) | |
163 | { | |
164 | protocol = p_protocol; | |
165 | site = protocol + "://" + address + ":" + port + path; | |
166 | } | |
167 | ||
168 | /** | |
169 | * Set the value of the <code>server</code> member. This is an | |
170 | * IP address or a hostname. | |
171 | * | |
172 | * @param <code>p_server</code> IP address or hostname. | |
173 | */ | |
174 | public void setServer( String p_server ) | |
175 | { | |
176 | address = p_server; | |
177 | site = protocol + "://" + address + ":" + port + path; | |
178 | } | |
179 | ||
180 | ||
181 | /** | |
182 | * Set the value of the <code>port</code> member. | |
183 | * | |
184 | * @param <code>p_port</code> Port number. | |
185 | */ | |
186 | public void setPort( int p_port ) | |
187 | { | |
188 | port = p_port; | |
189 | site = protocol + "://" + address + ":" + port + path; | |
190 | } | |
191 | ||
192 | ||
193 | /** | |
194 | * Set the value of the <code>user</code> member. | |
195 | * | |
196 | * @param <code>p_user</code> User name. | |
197 | */ | |
198 | public void setUser( String p_user ) | |
199 | { | |
200 | user = p_user; | |
201 | } | |
202 | ||
203 | ||
204 | /** | |
205 | * Set the value of the <code>passwd</code> member. | |
206 | * | |
207 | * @param <code>p_passwd</code> Password. | |
208 | */ | |
209 | public void setPasswd( String p_passwd ) | |
210 | { | |
211 | passwd = p_passwd; | |
212 | } | |
213 | ||
214 | ||
215 | /** | |
216 | * Set the value of the <code>dest</code> member. | |
217 | * | |
218 | * @param <code>p_dest</code> Destination. | |
219 | */ | |
220 | public void setDest( String p_dest ) | |
221 | { | |
222 | dest = p_dest; | |
223 | } | |
224 | ||
225 | ||
226 | /** | |
227 | * Set the value of the <code>instance</code> member. | |
228 | * | |
229 | * @param <code>p_instance</code> Instance. | |
230 | */ | |
231 | public void setInstance( String p_instance) | |
232 | { | |
233 | instance = p_instance; | |
234 | } | |
235 | ||
236 | ||
237 | /** | |
238 | * Set the value of the <code>encrypt</code> member. | |
239 | * | |
240 | * @param <code>p_enrypt</code> Yes or no. | |
241 | */ | |
242 | public void setEncrypt( boolean p_encrypt ) | |
243 | { | |
244 | encrypt = p_encrypt; | |
245 | } | |
246 | ||
247 | ||
248 | /** | |
249 | * Get the value of the <code>encrypt</code> member. | |
250 | * | |
251 | * @return <code>boolean</code> Encryption on or off. | |
252 | */ | |
253 | public boolean getEncrypt() | |
254 | { | |
255 | return(encrypt); | |
256 | } | |
257 | ||
258 | ||
259 | /** | |
260 | * Set the value of the <code>path</code> member. This is the | |
261 | * path that will be used in the POST method. | |
262 | * | |
263 | * @param <code>p_path</code> Path on server. | |
264 | */ | |
265 | public void setPath( String p_path ) | |
266 | { | |
267 | path = p_path; | |
268 | site = protocol + "://" + address + ":" + port + path; | |
269 | } | |
270 | ||
271 | ||
272 | ||
273 | public boolean doRequest(String from) throws IOException | |
274 | { | |
275 | // System.out.println("doRequest From: " + from ); | |
276 | return(doRequest()); | |
277 | } | |
278 | ||
279 | ||
280 | ||
281 | /** | |
282 | * Do a CUPS request to the server. | |
283 | * | |
284 | * @param <code>p_dest</code> Destination name. | |
285 | * @return <code>boolean</code> True on success, false otherwise | |
286 | * @throw <code>IOException</code> | |
287 | */ | |
288 | public boolean doRequest() throws IOException | |
289 | { | |
290 | IPPAttribute attr; | |
291 | int state = REQ_STATE_CREATE_HTTP; | |
292 | int errors = 0; | |
293 | ||
294 | while (true) | |
295 | { | |
296 | switch( state ) | |
297 | { | |
298 | ||
299 | case REQ_STATE_CREATE_HTTP: | |
300 | String url_str = site + dest; | |
301 | ||
302 | try | |
303 | { | |
304 | if (user.length() > 0 && passwd.length() > 0) | |
305 | http = new IPPHttp(url_str, "", user, passwd ); | |
306 | else | |
307 | http = new IPPHttp(url_str); | |
308 | state++; | |
309 | } | |
310 | catch (IOException e) | |
311 | { | |
312 | throw(e); | |
313 | } | |
314 | break; | |
315 | ||
316 | ||
317 | ||
318 | case REQ_STATE_WRITE_HTTP_HEADER: | |
319 | // | |
320 | // Send the HTTP header. | |
321 | // | |
322 | switch( http.writeHeader( http.path, ipp.sizeInBytes() )) | |
323 | { | |
324 | case IPPHttp.HTTP_FORBIDDEN: | |
325 | case IPPHttp.HTTP_NOT_FOUND: | |
326 | case IPPHttp.HTTP_BAD_REQUEST: | |
327 | case IPPHttp.HTTP_METHOD_NOT_ALLOWED: | |
328 | case IPPHttp.HTTP_PAYMENT_REQUIRED: | |
329 | case IPPHttp.HTTP_UPGRADE_REQUIRED: | |
330 | case IPPHttp.HTTP_ERROR: | |
331 | case IPPHttp.HTTP_UNAUTHORIZED: | |
332 | errors++; | |
333 | if (errors < 5) | |
334 | { | |
335 | if (!http.reConnect()) | |
336 | { | |
337 | System.out.println("Could not reConnect(0)!"); | |
338 | return(false); | |
339 | } | |
340 | } | |
341 | else | |
342 | { | |
343 | return(false); | |
344 | } | |
345 | break; | |
346 | ||
347 | default: state++; | |
348 | } | |
349 | break; | |
350 | ||
351 | ||
352 | ||
353 | case REQ_STATE_WRITE_IPP_HEADER: | |
354 | // | |
355 | // Send the request header. | |
356 | // | |
357 | byte[] header = new byte[8]; | |
358 | header[0] = (byte)1; | |
359 | header[1] = (byte)1; | |
360 | header[2] = (byte)((ipp.request.operation_id & 0xff00) >> 8); | |
361 | header[3] = (byte)(ipp.request.operation_id & 0xff); | |
362 | header[4] = (byte)((ipp.request.request_id & 0xff000000) >> 24); | |
363 | header[5] = (byte)((ipp.request.request_id & 0xff0000) >> 16); | |
364 | header[6] = (byte)((ipp.request.request_id & 0xff00) >> 8); | |
365 | header[7] = (byte)(ipp.request.request_id & 0xff); | |
366 | http.write( header ); | |
367 | if (http.checkForResponse() >= IPPHttp.HTTP_BAD_REQUEST) | |
368 | { | |
369 | errors++; | |
370 | if (errors < 5) | |
371 | { | |
372 | if (http.reConnect()) | |
373 | state = REQ_STATE_WRITE_HTTP_HEADER; | |
374 | else | |
375 | { | |
376 | System.out.println("Could not reConnect(1)\n"); | |
377 | return(false); | |
378 | } | |
379 | } | |
380 | else | |
381 | { | |
382 | return(false); | |
383 | } | |
384 | } | |
385 | else state++; | |
386 | break; | |
387 | ||
388 | ||
389 | case REQ_STATE_WRITE_IPP_ATTRS: | |
390 | // | |
391 | // Send the attributes list. | |
392 | // | |
393 | byte[] bytes; | |
394 | int sz; | |
395 | int last_group = -1; | |
396 | boolean auth_error = false; | |
397 | for (int i=0; i < ipp.attrs.size() && !auth_error; i++) | |
398 | { | |
399 | attr = (IPPAttribute)ipp.attrs.get(i); | |
400 | sz = attr.sizeInBytes(last_group); | |
401 | bytes = attr.getBytes(sz,last_group); | |
402 | last_group = attr.group_tag; | |
403 | http.write(bytes); | |
404 | ||
405 | // | |
406 | // Check for server response between each attribute. | |
407 | // | |
408 | if (http.checkForResponse() >= IPPHttp.HTTP_BAD_REQUEST) | |
409 | { | |
410 | errors++; | |
411 | if (errors < 5) | |
412 | { | |
413 | if (!http.reConnect()) | |
414 | { | |
415 | System.out.println("Could not reConnect(2)"); | |
416 | return(false); | |
417 | } | |
418 | state = REQ_STATE_WRITE_HTTP_HEADER; | |
419 | auth_error = true; | |
420 | } | |
421 | else | |
422 | { | |
423 | return(false); | |
424 | } | |
425 | } | |
426 | ||
427 | } | |
428 | if (!auth_error) | |
429 | state++; | |
430 | break; | |
431 | ||
432 | ||
433 | ||
434 | case REQ_STATE_FINISH_IPP_ATTRS: | |
435 | // | |
436 | // Send the end of attributes tag. | |
437 | // | |
438 | byte[] footer = new byte[1]; | |
439 | footer[0] = (byte)IPPDefs.TAG_END; | |
440 | http.write( footer ); | |
441 | ||
442 | // | |
443 | // Keep checking ..... | |
444 | // | |
445 | if (http.checkForResponse() >= IPPHttp.HTTP_BAD_REQUEST) | |
446 | { | |
447 | errors++; | |
448 | if (errors < 5) | |
449 | { | |
450 | if (!http.reConnect()) | |
451 | { | |
452 | System.out.println("Could not reConnect(3)"); | |
453 | return(false); | |
454 | } | |
455 | state = REQ_STATE_WRITE_HTTP_HEADER; | |
456 | } | |
457 | else | |
458 | { | |
459 | return(false); | |
460 | } | |
461 | } | |
462 | else state++; | |
463 | break; | |
464 | ||
465 | ||
466 | ||
467 | case REQ_STATE_READ_RESPONSE: | |
468 | // | |
469 | // Now read back response | |
470 | // | |
471 | int read_length; | |
472 | read_length = http.read_header(); | |
473 | switch( http.status ) | |
474 | { | |
475 | case IPPHttp.HTTP_OK: | |
476 | break; | |
477 | ||
478 | case IPPHttp.HTTP_UNAUTHORIZED: | |
479 | http.reConnect(); | |
480 | state = REQ_STATE_WRITE_HTTP_HEADER; | |
481 | errors = 0; | |
482 | break; | |
483 | ||
484 | default: | |
485 | errors++; | |
486 | if (errors < 5) | |
487 | { | |
488 | if (!http.reConnect()) | |
489 | { | |
490 | System.out.println("Could not reConnect(4)"); | |
491 | return(false); | |
492 | } | |
493 | state = REQ_STATE_WRITE_HTTP_HEADER; | |
494 | } | |
495 | else | |
496 | { | |
497 | System.out.println("Too many errors: " + errors ); | |
498 | return(false); | |
499 | } | |
500 | break; | |
501 | } | |
502 | ||
503 | if ((read_length > 0) && (state == REQ_STATE_READ_RESPONSE)) | |
504 | { | |
505 | http.read_buffer = http.read(read_length); | |
506 | ipp = http.processResponse(); | |
507 | state++; | |
508 | } | |
509 | break; | |
510 | ||
511 | case REQ_STATE_DONE: | |
512 | // | |
513 | // success. | |
514 | // | |
515 | http.conn.close(); | |
516 | http = null; | |
517 | return(true); | |
518 | } | |
519 | } | |
520 | ||
521 | } // End of doRequest | |
522 | ||
523 | ||
524 | ||
525 | /** | |
526 | * Send a FILE to the CUPS server. | |
527 | * | |
528 | * @param <code>file</code> File to send. | |
529 | * @return <code>boolean</code> True on success, false otherwise | |
530 | * @throw <code>IOException</code> | |
531 | */ | |
532 | public boolean doRequest(File file) throws IOException | |
533 | { | |
534 | IPPAttribute attr; | |
535 | int state = FILEREQ_STATE_CREATE_HTTP; | |
536 | int errors = 0; | |
537 | FileInputStream fis = null; | |
538 | ||
539 | while (true) | |
540 | { | |
541 | switch( state ) | |
542 | { | |
543 | ||
544 | case FILEREQ_STATE_CREATE_HTTP: | |
545 | String url_str = site + dest; | |
546 | try | |
547 | { | |
548 | if (user.length() > 0 && passwd.length() > 0) | |
549 | http = new IPPHttp(url_str, "", user, passwd ); | |
550 | else | |
551 | http = new IPPHttp(url_str); | |
552 | state++; | |
553 | } | |
554 | catch (IOException e) | |
555 | { | |
556 | throw(e); | |
557 | } | |
558 | break; | |
559 | ||
560 | ||
561 | ||
562 | case FILEREQ_STATE_WRITE_HTTP_HEADER: | |
563 | ||
564 | if (fis != null) | |
565 | { | |
566 | fis.close(); | |
567 | } | |
568 | ||
569 | // | |
570 | // Open an input stream to the file. | |
571 | // | |
572 | try | |
573 | { | |
574 | fis = new FileInputStream(file); | |
575 | } | |
576 | catch (IOException e) | |
577 | { | |
578 | last_error = -1; | |
579 | error_text = "Error opening file input stream."; | |
580 | throw(e); | |
581 | } | |
582 | ||
583 | // | |
584 | // Send the HTTP header. | |
585 | // | |
586 | int ippSz = ipp.sizeInBytes() + (int)file.length(); | |
587 | switch( http.writeHeader( http.path, ippSz )) | |
588 | { | |
589 | case IPPHttp.HTTP_FORBIDDEN: | |
590 | case IPPHttp.HTTP_NOT_FOUND: | |
591 | case IPPHttp.HTTP_BAD_REQUEST: | |
592 | case IPPHttp.HTTP_METHOD_NOT_ALLOWED: | |
593 | case IPPHttp.HTTP_PAYMENT_REQUIRED: | |
594 | case IPPHttp.HTTP_UPGRADE_REQUIRED: | |
595 | case IPPHttp.HTTP_ERROR: | |
596 | case IPPHttp.HTTP_UNAUTHORIZED: | |
597 | errors++; | |
598 | if (errors < 5) | |
599 | { | |
600 | http.reConnect(); | |
601 | } | |
602 | else | |
603 | return(false); | |
604 | break; | |
605 | ||
606 | default: state++; | |
607 | } | |
608 | break; | |
609 | ||
610 | ||
611 | ||
612 | case FILEREQ_STATE_WRITE_IPP_HEADER: | |
613 | // | |
614 | // Send the request header. | |
615 | // | |
616 | byte[] header = new byte[8]; | |
617 | header[0] = (byte)1; | |
618 | header[1] = (byte)1; | |
619 | header[2] = (byte)((ipp.request.operation_id & 0xff00) >> 8); | |
620 | header[3] = (byte)(ipp.request.operation_id & 0xff); | |
621 | header[4] = (byte)((ipp.request.request_id & 0xff000000) >> 24); | |
622 | header[5] = (byte)((ipp.request.request_id & 0xff0000) >> 16); | |
623 | header[6] = (byte)((ipp.request.request_id & 0xff00) >> 8); | |
624 | header[7] = (byte)(ipp.request.request_id & 0xff); | |
625 | http.write( header ); | |
626 | if (http.checkForResponse() >= IPPHttp.HTTP_BAD_REQUEST) | |
627 | { | |
628 | errors++; | |
629 | if (errors < 5) | |
630 | { | |
631 | http.reConnect(); | |
632 | state = FILEREQ_STATE_WRITE_HTTP_HEADER; | |
633 | } | |
634 | else | |
635 | return(false); | |
636 | } | |
637 | else state++; | |
638 | break; | |
639 | ||
640 | ||
641 | case FILEREQ_STATE_WRITE_IPP_ATTRS: | |
642 | // | |
643 | // Send the attributes list. | |
644 | // | |
645 | byte[] bytes; | |
646 | int sz; | |
647 | int last_group = -1; | |
648 | boolean auth_error = false; | |
649 | for (int i=0; i < ipp.attrs.size() && !auth_error; i++) | |
650 | { | |
651 | attr = (IPPAttribute)ipp.attrs.get(i); | |
652 | sz = attr.sizeInBytes(last_group); | |
653 | bytes = attr.getBytes(sz,last_group); | |
654 | last_group = attr.group_tag; | |
655 | http.write(bytes); | |
656 | ||
657 | // | |
658 | // Check for server response between each attribute. | |
659 | // | |
660 | if (http.checkForResponse() >= IPPHttp.HTTP_BAD_REQUEST) | |
661 | { | |
662 | errors++; | |
663 | if (errors < 5) | |
664 | { | |
665 | http.reConnect(); | |
666 | state = FILEREQ_STATE_WRITE_HTTP_HEADER; | |
667 | auth_error = true; | |
668 | } | |
669 | else | |
670 | return(false); | |
671 | } | |
672 | ||
673 | } | |
674 | if (!auth_error) | |
675 | state++; | |
676 | break; | |
677 | ||
678 | ||
679 | ||
680 | case FILEREQ_STATE_FINISH_IPP_ATTRS: | |
681 | // | |
682 | // Send the end of attributes tag. | |
683 | // | |
684 | byte[] footer = new byte[1]; | |
685 | footer[0] = (byte)IPPDefs.TAG_END; | |
686 | http.write( footer ); | |
687 | ||
688 | // | |
689 | // Keep checking ..... | |
690 | // | |
691 | if (http.checkForResponse() >= IPPHttp.HTTP_BAD_REQUEST) | |
692 | { | |
693 | errors++; | |
694 | if (errors < 5) | |
695 | { | |
696 | http.reConnect(); | |
697 | state = FILEREQ_STATE_WRITE_HTTP_HEADER; | |
698 | } | |
699 | else | |
700 | return(false); | |
701 | } | |
702 | else state++; | |
703 | break; | |
704 | ||
705 | ||
706 | ||
707 | case FILEREQ_STATE_WRITE_FILE_DATA: | |
708 | // | |
709 | // Send the file data - this could be improved on ALOT. | |
710 | // | |
711 | int count; | |
712 | byte[] b = new byte[1024]; | |
713 | while ((state == FILEREQ_STATE_WRITE_FILE_DATA) && | |
714 | ((count = fis.read(b)) != -1)) | |
715 | { | |
716 | // | |
717 | // Keep checking ..... | |
718 | // | |
719 | if (http.checkForResponse() >= IPPHttp.HTTP_BAD_REQUEST) | |
720 | { | |
721 | errors++; | |
722 | if (errors < 5) | |
723 | { | |
724 | http.reConnect(); | |
725 | state = FILEREQ_STATE_WRITE_HTTP_HEADER; | |
726 | } | |
727 | else | |
728 | { | |
729 | return(false); | |
730 | } | |
731 | } | |
732 | else | |
733 | { | |
734 | if (count > 0) | |
735 | http.write( b, count ); | |
736 | } | |
737 | ||
738 | } // while | |
739 | ||
740 | if (state == FILEREQ_STATE_WRITE_FILE_DATA) | |
741 | { | |
742 | fis.close(); | |
743 | fis = null; | |
744 | state++; | |
745 | } | |
746 | break; | |
747 | ||
748 | ||
749 | ||
750 | case FILEREQ_STATE_READ_RESPONSE: | |
751 | // | |
752 | // Now read back response | |
753 | // | |
754 | int read_length; | |
755 | read_length = http.read_header(); | |
756 | switch( http.status ) | |
757 | { | |
758 | case IPPHttp.HTTP_OK: | |
759 | break; | |
760 | ||
761 | case IPPHttp.HTTP_UNAUTHORIZED: | |
762 | http.reConnect(); | |
763 | state = FILEREQ_STATE_WRITE_HTTP_HEADER; | |
764 | errors = 0; | |
765 | break; | |
766 | ||
767 | default: | |
768 | errors++; | |
769 | if (errors < 5) | |
770 | { | |
771 | http.reConnect(); | |
772 | state = FILEREQ_STATE_WRITE_HTTP_HEADER; | |
773 | } | |
774 | else | |
775 | { | |
776 | return(false); | |
777 | } | |
778 | break; | |
779 | } | |
780 | ||
781 | if ((read_length > 0) && (state == FILEREQ_STATE_READ_RESPONSE)) | |
782 | { | |
783 | http.read_buffer = http.read(read_length); | |
784 | ipp = http.processResponse(); | |
785 | state++; | |
786 | } | |
787 | break; | |
788 | ||
789 | case FILEREQ_STATE_DONE: | |
790 | // | |
791 | // success. | |
792 | // | |
793 | http.conn.close(); | |
794 | http = null; | |
795 | return(true); | |
796 | } | |
797 | } | |
798 | ||
799 | } // End of doRequest(file) | |
800 | ||
801 | ||
802 | ||
803 | ||
804 | ||
805 | ||
806 | ||
807 | /** | |
808 | * Get a list of jobs. | |
809 | * | |
810 | * @param <code>showMyJobs</code> Show only jobs for user. | |
811 | * @param <code>showCompleted</code> Show completed OR active jobs. | |
812 | * | |
813 | * @return <code>CupsJob[]</code> Array of job objects, or null. | |
814 | * @throw <code>IOException</code> | |
815 | */ | |
816 | public CupsJob[] cupsGetJobs( boolean showMyJobs, boolean showCompleted ) | |
817 | throws IOException | |
818 | { | |
819 | ||
820 | IPPAttribute a; | |
821 | ||
822 | String req_attrs[] = /* Requested attributes */ | |
823 | { | |
824 | "job-id", | |
825 | "job-priority", | |
826 | "job-k-octets", | |
827 | "job-state", | |
828 | "time-at-completed", | |
829 | "time-at-creation", | |
830 | "time-at-processing", | |
831 | "job-printer-uri", | |
832 | "document-format", | |
833 | "job-name", | |
834 | "job-originating-user-name" | |
835 | }; | |
836 | ||
837 | ||
838 | ipp = new IPP(); | |
839 | ipp.request = new IPPRequest( 1, (short)IPPDefs.GET_JOBS ); | |
840 | ||
841 | a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_CHARSET, | |
842 | "attributes-charset" ); | |
843 | a.addString( "", "iso-8859-1" ); | |
844 | ipp.addAttribute(a); | |
845 | ||
846 | ||
847 | a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_LANGUAGE, | |
848 | "attributes-natural-language" ); | |
849 | a.addString( "", "en" ); | |
850 | ipp.addAttribute(a); | |
851 | ||
852 | ||
853 | // | |
854 | // Add the printer uri | |
855 | // | |
856 | a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_URI, | |
857 | "printer-uri" ); | |
858 | ||
859 | if (site != null) | |
860 | a.addString( "", site ); | |
861 | else | |
862 | a.addString( "", "ipp://localhost/jobs" ); // Default ... | |
863 | // a.dump_values(); | |
864 | ipp.addAttribute(a); | |
865 | ||
866 | ||
867 | // | |
868 | // Add the requesting user name | |
869 | // **FIX** This should be fixed to use the user member. | |
870 | // | |
871 | a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_NAME, | |
872 | "requesting-user-name" ); | |
873 | a.addString( "", "root" ); | |
874 | ipp.addAttribute(a); | |
875 | ||
876 | // | |
877 | // Show only my jobs? | |
878 | // | |
879 | if (showMyJobs) | |
880 | { | |
881 | a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_BOOLEAN, | |
882 | "my-jobs" ); | |
883 | a.addBoolean( true ); | |
884 | ipp.addAttribute(a); | |
885 | } | |
886 | ||
887 | // | |
888 | // Show completed jobs? | |
889 | // | |
890 | if (showCompleted) | |
891 | { | |
892 | a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_KEYWORD, | |
893 | "which-jobs" ); | |
894 | a.addString( "", "completed" ); | |
895 | ipp.addAttribute(a); | |
896 | } | |
897 | ||
898 | // | |
899 | // Get ALL attributes - to get only listed ones, | |
900 | // uncomment this and fill in req_attrs. | |
901 | // | |
902 | // a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_KEYWORD, | |
903 | // "requested-attributes" ); | |
904 | // a.addStrings( "", req_attrs ); | |
905 | // ipp.addAttribute(a); | |
906 | ||
907 | // | |
908 | // Do the request and process the response. | |
909 | // | |
910 | if (doRequest("cupsGetJobs")) | |
911 | { | |
912 | ||
913 | ||
914 | // | |
915 | // First we have to figure out how many jobs there are | |
916 | // so we can create the array. | |
917 | // | |
918 | ||
919 | // | |
920 | // Skip past leading attributes | |
921 | // | |
922 | int i = 0; | |
923 | int group_tag = -1; | |
924 | while ((i < ipp.attrs.size()) && (group_tag != IPPDefs.TAG_JOB)) | |
925 | { | |
926 | a = (IPPAttribute)ipp.attrs.get(i); | |
927 | group_tag = a.group_tag; | |
928 | if (group_tag != IPPDefs.TAG_JOB) | |
929 | i++; | |
930 | } | |
931 | ||
932 | int num_jobs = 0; | |
933 | group_tag = IPPDefs.TAG_JOB; | |
934 | while ((i < ipp.attrs.size()) && (group_tag == IPPDefs.TAG_JOB)) | |
935 | { | |
936 | a = (IPPAttribute)ipp.attrs.get(i++); | |
937 | if ((a != null) && (a.name.compareTo("job-id") == 0)) | |
938 | num_jobs++; | |
939 | // a.dump_values(); | |
940 | } | |
941 | ||
942 | if (num_jobs < 1) | |
943 | return(null); | |
944 | ||
945 | ||
946 | // | |
947 | // Now create the array of the proper size. | |
948 | // | |
949 | int n = 0; | |
950 | CupsJob[] jobs = new CupsJob[num_jobs]; | |
951 | for (n=0; n < num_jobs; n++) | |
952 | { | |
953 | jobs[n] = new CupsJob(); | |
954 | } | |
955 | ||
956 | ||
957 | ||
958 | ||
959 | // | |
960 | // Skip past leading attributes | |
961 | // | |
962 | group_tag = -1; | |
963 | i = 0; | |
964 | while ((i < ipp.attrs.size()) && (group_tag != IPPDefs.TAG_JOB)) | |
965 | { | |
966 | a = (IPPAttribute)ipp.attrs.get(i); | |
967 | group_tag = a.group_tag; | |
968 | if (group_tag != IPPDefs.TAG_JOB) | |
969 | i++; | |
970 | } | |
971 | ||
972 | // | |
973 | // Now we actually fill the array with the job data. | |
974 | // | |
975 | n = 0; | |
976 | for (;i < ipp.attrs.size(); i++) | |
977 | { | |
978 | a = (IPPAttribute)ipp.attrs.get(i); | |
979 | ||
980 | if (a.group_tag == IPPDefs.TAG_ZERO) | |
981 | { | |
982 | n++; | |
983 | continue; | |
984 | } | |
985 | else | |
986 | { | |
987 | try | |
988 | { | |
989 | jobs[n].updateAttribute( a ); | |
990 | } | |
991 | catch (ArrayIndexOutOfBoundsException e) | |
992 | { | |
993 | return(jobs); | |
994 | } | |
995 | } | |
996 | } | |
997 | return( jobs ); | |
998 | } | |
999 | return(null); | |
1000 | ||
1001 | } // End of cupsGetJobs | |
1002 | ||
1003 | ||
1004 | ||
1005 | /** | |
1006 | * Get a list of printers. | |
1007 | * | |
1008 | * @return <code>String[]</code> Array of printers, or null. | |
1009 | * @throw <code>IOException</code> | |
1010 | */ | |
1011 | public String[] cupsGetPrinters() | |
1012 | throws IOException | |
1013 | { | |
1014 | ||
1015 | IPPAttribute a; | |
1016 | ||
1017 | ipp = new IPP(); | |
1018 | ||
1019 | // | |
1020 | // Fill in the required attributes | |
1021 | // | |
1022 | ipp.request = new IPPRequest( 1, (short)IPPDefs.CUPS_GET_PRINTERS ); | |
1023 | ||
1024 | a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_CHARSET, | |
1025 | "attributes-charset" ); | |
1026 | a.addString( "", "iso-8859-1" ); | |
1027 | ipp.addAttribute(a); | |
1028 | ||
1029 | ||
1030 | a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_LANGUAGE, | |
1031 | "attributes-natural-language" ); | |
1032 | a.addString( "", "en" ); | |
1033 | ipp.addAttribute(a); | |
1034 | ||
1035 | ||
1036 | if (doRequest("cupsGetPrinters")) | |
1037 | { | |
1038 | int num_printers = 0; | |
1039 | for (int i=0; i < ipp.attrs.size(); i++) | |
1040 | { | |
1041 | a = (IPPAttribute)ipp.attrs.get(i); | |
1042 | if ((a.name.compareTo("printer-name") == 0) && | |
1043 | (a.value_tag == IPPDefs.TAG_NAME)) | |
1044 | { | |
1045 | num_printers++; | |
1046 | } | |
1047 | } | |
1048 | if (num_printers < 1) | |
1049 | return(null); | |
1050 | ||
1051 | String[] printers = new String[num_printers]; | |
1052 | IPPValue val; | |
1053 | int n = 0; | |
1054 | for (int i=0; i < ipp.attrs.size(); i++) | |
1055 | { | |
1056 | a = (IPPAttribute)ipp.attrs.get(i); | |
1057 | if (a.group_tag < 2) | |
1058 | continue; | |
1059 | ||
1060 | if ((a.name.compareTo("printer-name") == 0) && | |
1061 | (a.value_tag == IPPDefs.TAG_NAME)) | |
1062 | { | |
1063 | val = (IPPValue)a.values.get(0); | |
1064 | if (val != null) | |
1065 | { | |
1066 | printers[n] = val.text; | |
1067 | n++; | |
1068 | } | |
1069 | } | |
1070 | } | |
1071 | return( printers ); | |
1072 | ||
1073 | } // if doRequest ... | |
1074 | ||
1075 | return(null); | |
1076 | ||
1077 | } // End of cupsGetPrinters | |
1078 | ||
1079 | ||
1080 | ||
1081 | ||
1082 | /** | |
1083 | * Get default destination. | |
1084 | * | |
1085 | * @return <code>String</code> Name of default printer, or null. | |
1086 | * @throw <code>IOException</code> | |
1087 | */ | |
1088 | public String cupsGetDefault() | |
1089 | throws IOException | |
1090 | { | |
1091 | ||
1092 | IPPAttribute a; | |
1093 | ||
1094 | ||
1095 | ipp = new IPP(); | |
1096 | // | |
1097 | // Fill in the required attributes | |
1098 | // | |
1099 | ipp.request = new IPPRequest( 1, (short)IPPDefs.CUPS_GET_DEFAULT); | |
1100 | ||
1101 | a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_CHARSET, | |
1102 | "attributes-charset" ); | |
1103 | a.addString( "", "iso-8859-1" ); | |
1104 | ipp.addAttribute(a); | |
1105 | ||
1106 | ||
1107 | a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_LANGUAGE, | |
1108 | "attributes-natural-language" ); | |
1109 | a.addString( "", "en" ); | |
1110 | ipp.addAttribute(a); | |
1111 | ||
1112 | ||
1113 | if (doRequest("cupsGetDefault")) | |
1114 | { | |
1115 | if ((ipp == null) || (ipp.attrs == null)) | |
1116 | return(null); | |
1117 | ||
1118 | int num_printers = 0; | |
1119 | for (int i=0; i < ipp.attrs.size(); i++) | |
1120 | { | |
1121 | a = (IPPAttribute)ipp.attrs.get(i); | |
1122 | if ((a.name.compareTo("printer-name") == 0) && | |
1123 | (a.value_tag == IPPDefs.TAG_NAME)) | |
1124 | { | |
1125 | IPPValue val = (IPPValue)a.values.get(0); | |
1126 | if (val != null) | |
1127 | { | |
1128 | return( val.text ); | |
1129 | } | |
1130 | } | |
1131 | } | |
1132 | } // if doRequest ... | |
1133 | ||
1134 | return(null); | |
1135 | ||
1136 | } // End of cupsGetDefault | |
1137 | ||
1138 | ||
1139 | ||
1140 | ||
1141 | ||
1142 | ||
1143 | /** | |
1144 | * Get printer attributes | |
1145 | * | |
1146 | * @param <code>printer_name</code> Name of printer to get info for. | |
1147 | * @return <code>List</code> List of attributes. | |
1148 | * @throw <code>IOException</code> | |
1149 | * | |
1150 | * @see <code>CupsPrinter</code> | |
1151 | */ | |
1152 | public List cupsGetPrinterAttributes( String printer_name ) | |
1153 | throws IOException | |
1154 | { | |
1155 | ||
1156 | IPPAttribute a; | |
1157 | ||
1158 | ipp = new IPP(); | |
1159 | ||
1160 | // | |
1161 | // Fill in the required attributes | |
1162 | // | |
1163 | ipp.request = new IPPRequest( 1, (short)IPPDefs.GET_PRINTER_ATTRIBUTES ); | |
1164 | ||
1165 | a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_CHARSET, | |
1166 | "attributes-charset" ); | |
1167 | a.addString( "", "iso-8859-1" ); | |
1168 | ipp.addAttribute(a); | |
1169 | ||
1170 | ||
1171 | a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_LANGUAGE, | |
1172 | "attributes-natural-language" ); | |
1173 | a.addString( "", "en" ); | |
1174 | ipp.addAttribute(a); | |
1175 | ||
1176 | a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_URI, | |
1177 | "printer-uri" ); | |
b423cd4c | 1178 | String p_uri = "ipp://" + address + ":" + |
1179 | port + "/printers/" + printer_name; | |
1180 | a.addString( "", p_uri ); | |
ef416fc2 | 1181 | ipp.addAttribute(a); |
1182 | ||
1183 | if (doRequest("cupsGetPrinterAttributes")) | |
1184 | { | |
1185 | return(ipp.attrs); | |
1186 | } | |
1187 | ||
1188 | return(null); | |
1189 | ||
1190 | } // End of cupsGetPrinterAttributes | |
1191 | ||
1192 | ||
1193 | ||
1194 | ||
1195 | /** | |
1196 | * Print a file. | |
1197 | * | |
1198 | * @param <code>p_filename</code> Path of file to print. | |
1199 | * @param <code>p_attrs[]</code> Array of print job attributes. | |
1200 | * | |
1201 | * @return <code>CupsJob</code> Object with job info. | |
1202 | * | |
1203 | * @throw <code>IOException</code> | |
1204 | * | |
1205 | * @see <code>CupsJob</code> | |
1206 | */ | |
1207 | public CupsJob cupsPrintFile( String p_filename, | |
1208 | IPPAttribute p_attrs[] ) | |
1209 | throws IOException | |
1210 | { | |
1211 | ||
1212 | CupsJob job; | |
1213 | IPPAttribute a; | |
1214 | File file; | |
1215 | ||
1216 | ||
1217 | file = new File(p_filename); | |
1218 | if (!file.exists()) | |
1219 | { | |
1220 | last_error = -1; | |
1221 | error_text = "File does not exist."; | |
1222 | return(null); | |
1223 | } | |
1224 | ||
1225 | if (!file.canRead()) | |
1226 | { | |
1227 | last_error = -1; | |
1228 | error_text = "File cannot be read."; | |
1229 | return(null); | |
1230 | } | |
1231 | ||
1232 | ||
1233 | ipp = new IPP(); | |
1234 | // | |
1235 | // Fill in the required attributes | |
1236 | // | |
1237 | ipp.request = new IPPRequest( 1, (short)IPPDefs.PRINT_JOB ); | |
1238 | ||
1239 | a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_CHARSET, | |
1240 | "attributes-charset" ); | |
1241 | a.addString( "", "iso-8859-1" ); | |
1242 | ipp.addAttribute(a); | |
1243 | ||
1244 | // ------------ | |
1245 | a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_LANGUAGE, | |
1246 | "attributes-natural-language" ); | |
1247 | a.addString( "", "en" ); | |
1248 | ipp.addAttribute(a); | |
1249 | ||
1250 | // ------------ | |
1251 | a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_URI, | |
1252 | "printer-uri" ); | |
1253 | a.addString( "", site + dest ); | |
1254 | ipp.addAttribute(a); | |
1255 | ||
1256 | // ------------ | |
1257 | // **FIX** Fix this later. | |
1258 | /* | |
1259 | a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_NAME, | |
1260 | "requesting-user-name" ); | |
1261 | // a.addString( "", p_username ); | |
1262 | a.addString( "", "root"); | |
1263 | ipp.addAttribute(a); | |
1264 | */ | |
1265 | ||
1266 | // ------------ | |
1267 | a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_NAME, | |
1268 | "job-name" ); | |
1269 | a.addString( "", file.getName() ); | |
1270 | ipp.addAttribute(a); | |
1271 | ||
1272 | if (p_attrs != null) | |
1273 | { | |
1274 | for (int i=0; i < p_attrs.length; i++) | |
1275 | { | |
1276 | a = p_attrs[i]; | |
1277 | ipp.addAttribute(a); | |
1278 | } | |
1279 | } | |
1280 | ||
1281 | if (doRequest(file)) | |
1282 | { | |
1283 | job = new CupsJob(); | |
1284 | for (int i=0; i < ipp.attrs.size(); i++) | |
1285 | { | |
1286 | a = (IPPAttribute)ipp.attrs.get(i); | |
1287 | job.updateAttribute(a); | |
1288 | } | |
1289 | return(job); | |
1290 | ||
1291 | } // if doRequest ... | |
1292 | ||
1293 | return(null); | |
1294 | ||
1295 | } // End of cupsPrintFile | |
1296 | ||
1297 | ||
1298 | ||
1299 | ||
1300 | ||
1301 | /** | |
1302 | * Cancel a job - send a job cancel request to the server. | |
1303 | * | |
1304 | * @param <code>printer_name</code> Destination. | |
1305 | * @param <code>p_job_id</code> ID of job. | |
1306 | * @param <code>p_user_name</code> Requesting user name. | |
1307 | * | |
1308 | * @throw <code>IOException</code> | |
1309 | */ | |
1310 | public int cupsCancelJob( String printer_name, | |
1311 | int p_job_id, | |
1312 | String p_user_name ) | |
1313 | throws IOException | |
1314 | { | |
1315 | ||
1316 | IPPAttribute a; | |
1317 | ||
1318 | ipp = new IPP(); | |
1319 | ||
1320 | // | |
1321 | // Fill in the required attributes | |
1322 | // | |
1323 | ipp.request = new IPPRequest( 1, (short)IPPDefs.CANCEL_JOB ); | |
1324 | ||
1325 | a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_CHARSET, | |
1326 | "attributes-charset" ); | |
1327 | a.addString( "", "iso-8859-1" ); | |
1328 | ipp.addAttribute(a); | |
1329 | ||
1330 | // ------------ | |
1331 | a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_LANGUAGE, | |
1332 | "attributes-natural-language" ); | |
1333 | a.addString( "", "en" ); | |
1334 | ipp.addAttribute(a); | |
1335 | ||
1336 | // ------------ | |
1337 | a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_URI, | |
1338 | "printer-uri" ); | |
1339 | a.addString( "", site + dest ); | |
1340 | ipp.addAttribute(a); | |
1341 | ||
1342 | // ------------ | |
1343 | a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_INTEGER, | |
1344 | "job-id" ); | |
1345 | a.addInteger( p_job_id ); | |
1346 | ipp.addAttribute(a); | |
1347 | ||
1348 | // ------------ | |
1349 | a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_NAME, | |
1350 | "requesting-user-name" ); | |
1351 | a.addString( "", p_user_name ); | |
1352 | ipp.addAttribute(a); | |
1353 | ||
1354 | if (doRequest("cupsCancelJob")) | |
1355 | { | |
1356 | for (int i=0; i < ipp.attrs.size(); i++) | |
1357 | { | |
1358 | a = (IPPAttribute)ipp.attrs.get(i); | |
1359 | a.dump_values(); | |
1360 | } | |
1361 | return(0); | |
1362 | ||
1363 | } // if doRequest ... | |
1364 | ||
1365 | return(0); | |
1366 | ||
1367 | } // End of cupsCancelJob | |
1368 | ||
1369 | ||
1370 | ||
1371 | ||
1372 | public List cupsGetPrinterStatus(String printer_name) | |
1373 | throws IOException | |
1374 | { | |
1375 | IPPAttribute a; | |
1376 | String p_uri; | |
1377 | ||
1378 | ipp = new IPP(); | |
1379 | ||
1380 | // | |
1381 | // Fill in the required attributes | |
1382 | // | |
1383 | ipp.request = new IPPRequest(1,(short)IPPDefs.GET_PRINTER_ATTRIBUTES); | |
1384 | ||
1385 | a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_CHARSET, | |
1386 | "attributes-charset" ); | |
1387 | a.addString( "", "iso-8859-1" ); | |
1388 | ipp.addAttribute(a); | |
1389 | ||
1390 | ||
1391 | a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_LANGUAGE, | |
1392 | "attributes-natural-language" ); | |
1393 | a.addString( "", "en" ); | |
1394 | ipp.addAttribute(a); | |
1395 | ||
1396 | a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_URI, | |
1397 | "printer-uri" ); | |
1398 | p_uri = "ipp://" + address + ":" + | |
1399 | port + "/printers/" + printer_name; | |
1400 | a.addString( "", p_uri ); | |
1401 | ipp.addAttribute(a); | |
1402 | ||
1403 | if (doRequest("cupsGetPrinterStatus")) | |
1404 | { | |
1405 | return(ipp.attrs); | |
1406 | } | |
1407 | return(null); | |
1408 | } | |
1409 | ||
1410 | ||
1411 | ||
1412 | ||
1413 | ||
1414 | } // End of Cups class | |
1415 |