]> git.ipfire.org Git - thirdparty/cups.git/blame - scripting/java/src/com/easysw/cups/Cups.java
Load cups into easysw/current.
[thirdparty/cups.git] / scripting / java / src / com / easysw / cups / Cups.java
CommitLineData
ef416fc2 1package 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
38import java.io.*;
39import java.util.*;
40import java.net.*;
41
42public 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