package org.cups; /** * @version 1.00 06-NOV-2003 * @author Easy Software Products * * Internet Printing Protocol definitions for the Common UNIX Printing * System (CUPS). * * Copyright 1997-2003 by Easy Software Products. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal * copyright law. Distribution and use rights are outlined in the file * "LICENSE.txt" which should have been included with this file. If this * file is missing or damaged please contact Easy Software Products * at: * * Attn: CUPS Licensing Information * Easy Software Products * 44141 Airport View Drive, Suite 204 * Hollywood, Maryland 20636-3111 USA * * Voice: (301) 373-9603 * EMail: cups-info@cups.org * WWW: http://www.cups.org */ /** * An Cups object is used for connecting to servers, * reading and writing data, and performing common CUPS operations. * * @author TDB * @version 1.0.1 * @since JDK1.3 */ import java.io.*; import java.util.*; import java.net.*; public class Cups { static final int REQ_STATE_CREATE_HTTP = 0; static final int REQ_STATE_WRITE_HTTP_HEADER = 1; static final int REQ_STATE_WRITE_IPP_HEADER = 2; static final int REQ_STATE_WRITE_IPP_ATTRS = 3; static final int REQ_STATE_FINISH_IPP_ATTRS = 4; static final int REQ_STATE_READ_RESPONSE = 5; static final int REQ_STATE_DONE = 6; static final String[] req_state_names = { "Create HTTP", "Write Http Header", "Write IPP Header", "Write IPP Attrs", "Finish IPP Attrs", "Read Response", "Done" }; static final int FILEREQ_STATE_CREATE_HTTP = 0; static final int FILEREQ_STATE_WRITE_HTTP_HEADER = 1; static final int FILEREQ_STATE_WRITE_IPP_HEADER = 2; static final int FILEREQ_STATE_WRITE_IPP_ATTRS = 3; static final int FILEREQ_STATE_FINISH_IPP_ATTRS = 4; static final int FILEREQ_STATE_WRITE_FILE_DATA = 5; static final int FILEREQ_STATE_READ_RESPONSE = 6; static final int FILEREQ_STATE_DONE = 7; static final String[] filereq_state_names = { "Create HTTP", "Write Http Header", "Write IPP Header", "Write IPP Attrs", "Finish IPP Attrs", "Write File Data", "Read Response", "Done" }; IPP ipp; // IPP Request IPPHttp http; // Connection to server String protocol; // Protocol name String address; // address/name of server int port; // Port # String path; // Path .... String dest; // Name of destination printer String instance; // Instance of printer // // encrypt, user, and passwd are not fully implemented! // boolean encrypt; // Open encrypted connection. String user; // User to login as. String passwd; // Password if needed. String site; // URL of site. int last_error; // Last error # String error_text; // Text for error /** * Void constructor. */ public Cups() { http = null; ipp = null; protocol = "http"; address = "localhost"; port = 631; path = "/"; site = "http://localhost:631/"; dest = ""; instance = ""; user = ""; passwd = ""; encrypt = false; } /** * Constructor using a URL. * * @param p_url A URL object. */ public Cups( URL p_url ) { http = null; ipp = null; protocol = p_url.getProtocol() + "://"; address = p_url.getHost(); port = p_url.getPort(); path = p_url.getPath(); site = protocol + address; if (port > 0) site = site + ":" + port; if (path.length() > 0) site = site + path; dest = ""; instance = ""; user = ""; passwd = ""; encrypt = false; } /** * Set the value of the protocol member. Valid values * are ipp or http. * * @param p_protocol String with protocol. */ public void setProtocol( String p_protocol ) { protocol = p_protocol; site = protocol + "://" + address + ":" + port + path; } /** * Set the value of the server member. This is an * IP address or a hostname. * * @param p_server IP address or hostname. */ public void setServer( String p_server ) { address = p_server; site = protocol + "://" + address + ":" + port + path; } /** * Set the value of the port member. * * @param p_port Port number. */ public void setPort( int p_port ) { port = p_port; site = protocol + "://" + address + ":" + port + path; } /** * Set the value of the user member. * * @param p_user User name. */ public void setUser( String p_user ) { user = p_user; } /** * Set the value of the passwd member. * * @param p_passwd Password. */ public void setPasswd( String p_passwd ) { passwd = p_passwd; } /** * Set the value of the dest member. * * @param p_dest Destination. */ public void setDest( String p_dest ) { dest = p_dest; } /** * Set the value of the instance member. * * @param p_instance Instance. */ public void setInstance( String p_instance) { instance = p_instance; } /** * Set the value of the encrypt member. * * @param p_enrypt Yes or no. */ public void setEncrypt( boolean p_encrypt ) { encrypt = p_encrypt; } /** * Get the value of the encrypt member. * * @return boolean Encryption on or off. */ public boolean getEncrypt() { return(encrypt); } /** * Set the value of the path member. This is the * path that will be used in the POST method. * * @param p_path Path on server. */ public void setPath( String p_path ) { path = p_path; site = protocol + "://" + address + ":" + port + path; } public boolean doRequest(String from) throws IOException { // System.out.println("doRequest From: " + from ); return(doRequest()); } /** * Do a CUPS request to the server. * * @param p_dest Destination name. * @return boolean True on success, false otherwise * @throw IOException */ public boolean doRequest() throws IOException { IPPAttribute attr; int state = REQ_STATE_CREATE_HTTP; int errors = 0; while (true) { switch( state ) { case REQ_STATE_CREATE_HTTP: String url_str = site + dest; try { if (user.length() > 0 && passwd.length() > 0) http = new IPPHttp(url_str, "", user, passwd ); else http = new IPPHttp(url_str); state++; } catch (IOException e) { throw(e); } break; case REQ_STATE_WRITE_HTTP_HEADER: // // Send the HTTP header. // switch( http.writeHeader( http.path, ipp.sizeInBytes() )) { case IPPHttp.HTTP_FORBIDDEN: case IPPHttp.HTTP_NOT_FOUND: case IPPHttp.HTTP_BAD_REQUEST: case IPPHttp.HTTP_METHOD_NOT_ALLOWED: case IPPHttp.HTTP_PAYMENT_REQUIRED: case IPPHttp.HTTP_UPGRADE_REQUIRED: case IPPHttp.HTTP_ERROR: case IPPHttp.HTTP_UNAUTHORIZED: errors++; if (errors < 5) { if (!http.reConnect()) { System.out.println("Could not reConnect(0)!"); return(false); } } else { return(false); } break; default: state++; } break; case REQ_STATE_WRITE_IPP_HEADER: // // Send the request header. // byte[] header = new byte[8]; header[0] = (byte)1; header[1] = (byte)1; header[2] = (byte)((ipp.request.operation_id & 0xff00) >> 8); header[3] = (byte)(ipp.request.operation_id & 0xff); header[4] = (byte)((ipp.request.request_id & 0xff000000) >> 24); header[5] = (byte)((ipp.request.request_id & 0xff0000) >> 16); header[6] = (byte)((ipp.request.request_id & 0xff00) >> 8); header[7] = (byte)(ipp.request.request_id & 0xff); http.write( header ); if (http.checkForResponse() >= IPPHttp.HTTP_BAD_REQUEST) { errors++; if (errors < 5) { if (http.reConnect()) state = REQ_STATE_WRITE_HTTP_HEADER; else { System.out.println("Could not reConnect(1)\n"); return(false); } } else { return(false); } } else state++; break; case REQ_STATE_WRITE_IPP_ATTRS: // // Send the attributes list. // byte[] bytes; int sz; int last_group = -1; boolean auth_error = false; for (int i=0; i < ipp.attrs.size() && !auth_error; i++) { attr = (IPPAttribute)ipp.attrs.get(i); sz = attr.sizeInBytes(last_group); bytes = attr.getBytes(sz,last_group); last_group = attr.group_tag; http.write(bytes); // // Check for server response between each attribute. // if (http.checkForResponse() >= IPPHttp.HTTP_BAD_REQUEST) { errors++; if (errors < 5) { if (!http.reConnect()) { System.out.println("Could not reConnect(2)"); return(false); } state = REQ_STATE_WRITE_HTTP_HEADER; auth_error = true; } else { return(false); } } } if (!auth_error) state++; break; case REQ_STATE_FINISH_IPP_ATTRS: // // Send the end of attributes tag. // byte[] footer = new byte[1]; footer[0] = (byte)IPPDefs.TAG_END; http.write( footer ); // // Keep checking ..... // if (http.checkForResponse() >= IPPHttp.HTTP_BAD_REQUEST) { errors++; if (errors < 5) { if (!http.reConnect()) { System.out.println("Could not reConnect(3)"); return(false); } state = REQ_STATE_WRITE_HTTP_HEADER; } else { return(false); } } else state++; break; case REQ_STATE_READ_RESPONSE: // // Now read back response // int read_length; read_length = http.read_header(); switch( http.status ) { case IPPHttp.HTTP_OK: break; case IPPHttp.HTTP_UNAUTHORIZED: http.reConnect(); state = REQ_STATE_WRITE_HTTP_HEADER; errors = 0; break; default: errors++; if (errors < 5) { if (!http.reConnect()) { System.out.println("Could not reConnect(4)"); return(false); } state = REQ_STATE_WRITE_HTTP_HEADER; } else { System.out.println("Too many errors: " + errors ); return(false); } break; } if ((read_length > 0) && (state == REQ_STATE_READ_RESPONSE)) { http.read_buffer = http.read(read_length); ipp = http.processResponse(); state++; } break; case REQ_STATE_DONE: // // success. // http.conn.close(); http = null; return(true); } } } // End of doRequest /** * Send a FILE to the CUPS server. * * @param file File to send. * @return boolean True on success, false otherwise * @throw IOException */ public boolean doRequest(File file) throws IOException { IPPAttribute attr; int state = FILEREQ_STATE_CREATE_HTTP; int errors = 0; FileInputStream fis = null; while (true) { switch( state ) { case FILEREQ_STATE_CREATE_HTTP: String url_str = site + dest; try { if (user.length() > 0 && passwd.length() > 0) http = new IPPHttp(url_str, "", user, passwd ); else http = new IPPHttp(url_str); state++; } catch (IOException e) { throw(e); } break; case FILEREQ_STATE_WRITE_HTTP_HEADER: if (fis != null) { fis.close(); } // // Open an input stream to the file. // try { fis = new FileInputStream(file); } catch (IOException e) { last_error = -1; error_text = "Error opening file input stream."; throw(e); } // // Send the HTTP header. // int ippSz = ipp.sizeInBytes() + (int)file.length(); switch( http.writeHeader( http.path, ippSz )) { case IPPHttp.HTTP_FORBIDDEN: case IPPHttp.HTTP_NOT_FOUND: case IPPHttp.HTTP_BAD_REQUEST: case IPPHttp.HTTP_METHOD_NOT_ALLOWED: case IPPHttp.HTTP_PAYMENT_REQUIRED: case IPPHttp.HTTP_UPGRADE_REQUIRED: case IPPHttp.HTTP_ERROR: case IPPHttp.HTTP_UNAUTHORIZED: errors++; if (errors < 5) { http.reConnect(); } else return(false); break; default: state++; } break; case FILEREQ_STATE_WRITE_IPP_HEADER: // // Send the request header. // byte[] header = new byte[8]; header[0] = (byte)1; header[1] = (byte)1; header[2] = (byte)((ipp.request.operation_id & 0xff00) >> 8); header[3] = (byte)(ipp.request.operation_id & 0xff); header[4] = (byte)((ipp.request.request_id & 0xff000000) >> 24); header[5] = (byte)((ipp.request.request_id & 0xff0000) >> 16); header[6] = (byte)((ipp.request.request_id & 0xff00) >> 8); header[7] = (byte)(ipp.request.request_id & 0xff); http.write( header ); if (http.checkForResponse() >= IPPHttp.HTTP_BAD_REQUEST) { errors++; if (errors < 5) { http.reConnect(); state = FILEREQ_STATE_WRITE_HTTP_HEADER; } else return(false); } else state++; break; case FILEREQ_STATE_WRITE_IPP_ATTRS: // // Send the attributes list. // byte[] bytes; int sz; int last_group = -1; boolean auth_error = false; for (int i=0; i < ipp.attrs.size() && !auth_error; i++) { attr = (IPPAttribute)ipp.attrs.get(i); sz = attr.sizeInBytes(last_group); bytes = attr.getBytes(sz,last_group); last_group = attr.group_tag; http.write(bytes); // // Check for server response between each attribute. // if (http.checkForResponse() >= IPPHttp.HTTP_BAD_REQUEST) { errors++; if (errors < 5) { http.reConnect(); state = FILEREQ_STATE_WRITE_HTTP_HEADER; auth_error = true; } else return(false); } } if (!auth_error) state++; break; case FILEREQ_STATE_FINISH_IPP_ATTRS: // // Send the end of attributes tag. // byte[] footer = new byte[1]; footer[0] = (byte)IPPDefs.TAG_END; http.write( footer ); // // Keep checking ..... // if (http.checkForResponse() >= IPPHttp.HTTP_BAD_REQUEST) { errors++; if (errors < 5) { http.reConnect(); state = FILEREQ_STATE_WRITE_HTTP_HEADER; } else return(false); } else state++; break; case FILEREQ_STATE_WRITE_FILE_DATA: // // Send the file data - this could be improved on ALOT. // int count; byte[] b = new byte[1024]; while ((state == FILEREQ_STATE_WRITE_FILE_DATA) && ((count = fis.read(b)) != -1)) { // // Keep checking ..... // if (http.checkForResponse() >= IPPHttp.HTTP_BAD_REQUEST) { errors++; if (errors < 5) { http.reConnect(); state = FILEREQ_STATE_WRITE_HTTP_HEADER; } else { return(false); } } else { if (count > 0) http.write( b, count ); } } // while if (state == FILEREQ_STATE_WRITE_FILE_DATA) { fis.close(); fis = null; state++; } break; case FILEREQ_STATE_READ_RESPONSE: // // Now read back response // int read_length; read_length = http.read_header(); switch( http.status ) { case IPPHttp.HTTP_OK: break; case IPPHttp.HTTP_UNAUTHORIZED: http.reConnect(); state = FILEREQ_STATE_WRITE_HTTP_HEADER; errors = 0; break; default: errors++; if (errors < 5) { http.reConnect(); state = FILEREQ_STATE_WRITE_HTTP_HEADER; } else { return(false); } break; } if ((read_length > 0) && (state == FILEREQ_STATE_READ_RESPONSE)) { http.read_buffer = http.read(read_length); ipp = http.processResponse(); state++; } break; case FILEREQ_STATE_DONE: // // success. // http.conn.close(); http = null; return(true); } } } // End of doRequest(file) /** * Get a list of jobs. * * @param showMyJobs Show only jobs for user. * @param showCompleted Show completed OR active jobs. * * @return CupsJob[] Array of job objects, or null. * @throw IOException */ public CupsJob[] cupsGetJobs( boolean showMyJobs, boolean showCompleted ) throws IOException { IPPAttribute a; String req_attrs[] = /* Requested attributes */ { "job-id", "job-priority", "job-k-octets", "job-state", "time-at-completed", "time-at-creation", "time-at-processing", "job-printer-uri", "document-format", "job-name", "job-originating-user-name" }; ipp = new IPP(); ipp.request = new IPPRequest( 1, (short)IPPDefs.GET_JOBS ); a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_CHARSET, "attributes-charset" ); a.addString( "", "iso-8859-1" ); ipp.addAttribute(a); a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_LANGUAGE, "attributes-natural-language" ); a.addString( "", "en" ); ipp.addAttribute(a); // // Add the printer uri // a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_URI, "printer-uri" ); if (site != null) a.addString( "", site ); else a.addString( "", "ipp://localhost/jobs" ); // Default ... // a.dump_values(); ipp.addAttribute(a); // // Add the requesting user name // **FIX** This should be fixed to use the user member. // a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_NAME, "requesting-user-name" ); a.addString( "", "root" ); ipp.addAttribute(a); // // Show only my jobs? // if (showMyJobs) { a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_BOOLEAN, "my-jobs" ); a.addBoolean( true ); ipp.addAttribute(a); } // // Show completed jobs? // if (showCompleted) { a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_KEYWORD, "which-jobs" ); a.addString( "", "completed" ); ipp.addAttribute(a); } // // Get ALL attributes - to get only listed ones, // uncomment this and fill in req_attrs. // // a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_KEYWORD, // "requested-attributes" ); // a.addStrings( "", req_attrs ); // ipp.addAttribute(a); // // Do the request and process the response. // if (doRequest("cupsGetJobs")) { // // First we have to figure out how many jobs there are // so we can create the array. // // // Skip past leading attributes // int i = 0; int group_tag = -1; while ((i < ipp.attrs.size()) && (group_tag != IPPDefs.TAG_JOB)) { a = (IPPAttribute)ipp.attrs.get(i); group_tag = a.group_tag; if (group_tag != IPPDefs.TAG_JOB) i++; } int num_jobs = 0; group_tag = IPPDefs.TAG_JOB; while ((i < ipp.attrs.size()) && (group_tag == IPPDefs.TAG_JOB)) { a = (IPPAttribute)ipp.attrs.get(i++); if ((a != null) && (a.name.compareTo("job-id") == 0)) num_jobs++; // a.dump_values(); } if (num_jobs < 1) return(null); // // Now create the array of the proper size. // int n = 0; CupsJob[] jobs = new CupsJob[num_jobs]; for (n=0; n < num_jobs; n++) { jobs[n] = new CupsJob(); } // // Skip past leading attributes // group_tag = -1; i = 0; while ((i < ipp.attrs.size()) && (group_tag != IPPDefs.TAG_JOB)) { a = (IPPAttribute)ipp.attrs.get(i); group_tag = a.group_tag; if (group_tag != IPPDefs.TAG_JOB) i++; } // // Now we actually fill the array with the job data. // n = 0; for (;i < ipp.attrs.size(); i++) { a = (IPPAttribute)ipp.attrs.get(i); if (a.group_tag == IPPDefs.TAG_ZERO) { n++; continue; } else { try { jobs[n].updateAttribute( a ); } catch (ArrayIndexOutOfBoundsException e) { return(jobs); } } } return( jobs ); } return(null); } // End of cupsGetJobs /** * Get a list of printers. * * @return String[] Array of printers, or null. * @throw IOException */ public String[] cupsGetPrinters() throws IOException { IPPAttribute a; ipp = new IPP(); // // Fill in the required attributes // ipp.request = new IPPRequest( 1, (short)IPPDefs.CUPS_GET_PRINTERS ); a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_CHARSET, "attributes-charset" ); a.addString( "", "iso-8859-1" ); ipp.addAttribute(a); a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_LANGUAGE, "attributes-natural-language" ); a.addString( "", "en" ); ipp.addAttribute(a); if (doRequest("cupsGetPrinters")) { int num_printers = 0; for (int i=0; i < ipp.attrs.size(); i++) { a = (IPPAttribute)ipp.attrs.get(i); if ((a.name.compareTo("printer-name") == 0) && (a.value_tag == IPPDefs.TAG_NAME)) { num_printers++; } } if (num_printers < 1) return(null); String[] printers = new String[num_printers]; IPPValue val; int n = 0; for (int i=0; i < ipp.attrs.size(); i++) { a = (IPPAttribute)ipp.attrs.get(i); if (a.group_tag < 2) continue; if ((a.name.compareTo("printer-name") == 0) && (a.value_tag == IPPDefs.TAG_NAME)) { val = (IPPValue)a.values.get(0); if (val != null) { printers[n] = val.text; n++; } } } return( printers ); } // if doRequest ... return(null); } // End of cupsGetPrinters /** * Get default destination. * * @return String Name of default printer, or null. * @throw IOException */ public String cupsGetDefault() throws IOException { IPPAttribute a; ipp = new IPP(); // // Fill in the required attributes // ipp.request = new IPPRequest( 1, (short)IPPDefs.CUPS_GET_DEFAULT); a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_CHARSET, "attributes-charset" ); a.addString( "", "iso-8859-1" ); ipp.addAttribute(a); a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_LANGUAGE, "attributes-natural-language" ); a.addString( "", "en" ); ipp.addAttribute(a); if (doRequest("cupsGetDefault")) { if ((ipp == null) || (ipp.attrs == null)) return(null); int num_printers = 0; for (int i=0; i < ipp.attrs.size(); i++) { a = (IPPAttribute)ipp.attrs.get(i); if ((a.name.compareTo("printer-name") == 0) && (a.value_tag == IPPDefs.TAG_NAME)) { IPPValue val = (IPPValue)a.values.get(0); if (val != null) { return( val.text ); } } } } // if doRequest ... return(null); } // End of cupsGetDefault /** * Get printer attributes * * @param printer_name Name of printer to get info for. * @return List List of attributes. * @throw IOException * * @see CupsPrinter */ public List cupsGetPrinterAttributes( String printer_name ) throws IOException { IPPAttribute a; ipp = new IPP(); // // Fill in the required attributes // ipp.request = new IPPRequest( 1, (short)IPPDefs.GET_PRINTER_ATTRIBUTES ); a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_CHARSET, "attributes-charset" ); a.addString( "", "iso-8859-1" ); ipp.addAttribute(a); a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_LANGUAGE, "attributes-natural-language" ); a.addString( "", "en" ); ipp.addAttribute(a); a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_URI, "printer-uri" ); a.addString( "", site + "/printers/" + printer_name ); ipp.addAttribute(a); if (doRequest("cupsGetPrinterAttributes")) { return(ipp.attrs); } return(null); } // End of cupsGetPrinterAttributes /** * Print a file. * * @param p_filename Path of file to print. * @param p_attrs[] Array of print job attributes. * * @return CupsJob Object with job info. * * @throw IOException * * @see CupsJob */ public CupsJob cupsPrintFile( String p_filename, IPPAttribute p_attrs[] ) throws IOException { CupsJob job; IPPAttribute a; File file; file = new File(p_filename); if (!file.exists()) { last_error = -1; error_text = "File does not exist."; return(null); } if (!file.canRead()) { last_error = -1; error_text = "File cannot be read."; return(null); } ipp = new IPP(); // // Fill in the required attributes // ipp.request = new IPPRequest( 1, (short)IPPDefs.PRINT_JOB ); a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_CHARSET, "attributes-charset" ); a.addString( "", "iso-8859-1" ); ipp.addAttribute(a); // ------------ a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_LANGUAGE, "attributes-natural-language" ); a.addString( "", "en" ); ipp.addAttribute(a); // ------------ a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_URI, "printer-uri" ); a.addString( "", site + dest ); ipp.addAttribute(a); // ------------ // **FIX** Fix this later. /* a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_NAME, "requesting-user-name" ); // a.addString( "", p_username ); a.addString( "", "root"); ipp.addAttribute(a); */ // ------------ a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_NAME, "job-name" ); a.addString( "", file.getName() ); ipp.addAttribute(a); if (p_attrs != null) { for (int i=0; i < p_attrs.length; i++) { a = p_attrs[i]; ipp.addAttribute(a); } } if (doRequest(file)) { job = new CupsJob(); for (int i=0; i < ipp.attrs.size(); i++) { a = (IPPAttribute)ipp.attrs.get(i); job.updateAttribute(a); } return(job); } // if doRequest ... return(null); } // End of cupsPrintFile /** * Cancel a job - send a job cancel request to the server. * * @param printer_name Destination. * @param p_job_id ID of job. * @param p_user_name Requesting user name. * * @throw IOException */ public int cupsCancelJob( String printer_name, int p_job_id, String p_user_name ) throws IOException { IPPAttribute a; ipp = new IPP(); // // Fill in the required attributes // ipp.request = new IPPRequest( 1, (short)IPPDefs.CANCEL_JOB ); a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_CHARSET, "attributes-charset" ); a.addString( "", "iso-8859-1" ); ipp.addAttribute(a); // ------------ a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_LANGUAGE, "attributes-natural-language" ); a.addString( "", "en" ); ipp.addAttribute(a); // ------------ a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_URI, "printer-uri" ); a.addString( "", site + dest ); ipp.addAttribute(a); // ------------ a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_INTEGER, "job-id" ); a.addInteger( p_job_id ); ipp.addAttribute(a); // ------------ a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_NAME, "requesting-user-name" ); a.addString( "", p_user_name ); ipp.addAttribute(a); if (doRequest("cupsCancelJob")) { for (int i=0; i < ipp.attrs.size(); i++) { a = (IPPAttribute)ipp.attrs.get(i); a.dump_values(); } return(0); } // if doRequest ... return(0); } // End of cupsCancelJob public List cupsGetPrinterStatus(String printer_name) throws IOException { IPPAttribute a; String p_uri; ipp = new IPP(); // // Fill in the required attributes // ipp.request = new IPPRequest(1,(short)IPPDefs.GET_PRINTER_ATTRIBUTES); a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_CHARSET, "attributes-charset" ); a.addString( "", "iso-8859-1" ); ipp.addAttribute(a); a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_LANGUAGE, "attributes-natural-language" ); a.addString( "", "en" ); ipp.addAttribute(a); a = new IPPAttribute( IPPDefs.TAG_OPERATION, IPPDefs.TAG_URI, "printer-uri" ); p_uri = "ipp://" + address + ":" + port + "/printers/" + printer_name; a.addString( "", p_uri ); ipp.addAttribute(a); if (doRequest("cupsGetPrinterStatus")) { return(ipp.attrs); } return(null); } } // End of Cups class