server_jreason_t /* O - Bits */ serverGetJobStateReasonsBits( ipp_attribute_t *attr) /* I - "job-state-reasons" attribute */ { int i, j, /* Looping vars */ count; /* Number of "job-state-reasons" values */ const char *keyword; /* "job-state-reasons" value */ server_jreason_t jreasons = SERVER_JREASON_NONE; /* Bits for "job-state-reasons" values */ count = ippGetCount(attr); for (i = 0; i < count; i ++) { keyword = ippGetString(attr, i, NULL); for (j = 0; j < (int)(sizeof(server_jreasons) / sizeof(server_jreasons[0])); j ++) { if (!strcmp(keyword, server_jreasons[j])) { jreasons |= (server_jreason_t)(1 << j); break; } } } return (jreasons); }
void serverCreateJobFilename( server_printer_t *printer, /* I - Printer */ server_job_t *job, /* I - Job */ const char *format, /* I - Format or NULL */ char *fname, /* I - Filename buffer */ size_t fnamesize) /* I - Size of filename buffer */ { char name[256], /* "Safe" filename */ *nameptr; /* Pointer into filename */ const char *ext, /* Filename extension */ *job_name; /* job-name value */ ipp_attribute_t *job_name_attr; /* job-name attribute */ /* * Make a name from the job-name attribute... */ if ((job_name_attr = ippFindAttribute(job->attrs, "job-name", IPP_TAG_NAME)) != NULL) job_name = ippGetString(job_name_attr, 0, NULL); else job_name = "untitled"; for (nameptr = name; *job_name && nameptr < (name + sizeof(name) - 1); job_name ++) if (isalnum(*job_name & 255) || *job_name == '-') *nameptr++ = (char)tolower(*job_name & 255); else *nameptr++ = '_'; *nameptr = '\0'; /* * Figure out the extension... */ if (!format) format = job->format; if (!strcasecmp(format, "image/jpeg")) ext = "jpg"; else if (!strcasecmp(format, "image/png")) ext = "png"; else if (!strcasecmp(format, "image/pwg-raster")) ext = "ras"; else if (!strcasecmp(format, "image/urf")) ext = "urf"; else if (!strcasecmp(format, "application/pdf")) ext = "pdf"; else if (!strcasecmp(format, "application/postscript")) ext = "ps"; else ext = "prn"; /* * Create a filename with the job-id, job-name, and document-format (extension)... */ snprintf(fname, fnamesize, "%s/%s/%d-%s.%s", SpoolDirectory, printer->name, job->id, name, ext); }
/////////////////////////////////////////////////////////////////////////////////////////// // // CS : PUBLIC gint getPrinterStatus(gchar *pDestName, gchar *pStatus, gint bufSize) // IN : gchar *pDestName : Printer name. // gint bufSize : Size of output buffer. // OUT : gchar *pStatus : Printer status string. // RETURN : ID_ERR_NO_ERROR : No error. // ID_ERR_CUPS_API_FAILED : Error occured in CUPS API. // PUBLIC gint getPrinterStatus(gchar *pDestName, gchar *pStatus, gint bufSize) { /*** Parameters start ***/ http_t *pHTTP; // Pointer to HTTP connection. ipp_t *pRequest, // Pointer to CUPS IPP request. *pResponse; // Pointer to CUPS IPP response. ipp_attribute_t *pAttribute; // Pointer to CUPS attributes. cups_lang_t *pLanguage; // Pointer to language. gchar printerURI[HTTP_MAX_URI]; // Printer URI. gchar serverName[HTTP_MAX_URI]; // CUPS server name. gint retVal = ID_ERR_NO_ERROR; // Return value. /*** Parameters end ***/ // Initialize buffer. memset(printerURI, 0, sizeof(printerURI)); memset(serverName, 0, sizeof(serverName)); // Get printer URI and CUPS server name. retVal = getPrinterURI(pDestName, printerURI, serverName, HTTP_MAX_URI); if (retVal == ID_ERR_NO_ERROR) { // CUPS http connect. if ((pHTTP = httpConnectEncrypt(serverName, ippPort(), cupsEncryption())) == NULL) { retVal = ID_ERR_CUPS_API_FAILED; } else { pRequest = ippNew(); ippSetOperation(pRequest, IPP_GET_PRINTER_ATTRIBUTES); ippSetRequestId(pRequest, 1); pLanguage = bjcupsLangDefault(); // cupsLangDefault() -> bjcupsLangDefault() for cups-1.1.19 ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, cupsLangEncoding(pLanguage)); ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, pLanguage->language); ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, printerURI); if ((pResponse = cupsDoRequest(pHTTP, pRequest, "/")) != NULL) { if (ippGetStatusCode(pResponse) > IPP_OK_CONFLICT) { retVal = ID_ERR_CUPS_API_FAILED; } else { pAttribute = ippFindAttribute(pResponse, "printer-state-message", IPP_TAG_TEXT); if (pAttribute != NULL) { strncpy(pStatus, ippGetString(pAttribute, 0, NULL), bufSize); } } ippDelete(pResponse); } else { retVal = ID_ERR_CUPS_API_FAILED; } cupsLangFree(pLanguage); httpClose(pHTTP); } } return(retVal); }// End getPrinterStatus
const char * gtk_cups_request_ipp_get_string (GtkCupsRequest *request, ipp_tag_t tag, const char *name) { ipp_attribute_t *attribute = NULL; if (request != NULL && request->ipp_request != NULL) attribute = ippFindAttribute (request->ipp_request, name, tag); if (attribute != NULL && ippGetCount (attribute) > 0) return ippGetString (attribute, 0, NULL); else return NULL; }
server_job_t * /* O - Job or NULL */ serverFindJob( server_client_t *client, /* I - Client */ int job_id) /* I - Job ID to find or 0 to lookup */ { ipp_attribute_t *attr; /* job-id or job-uri attribute */ server_job_t key, /* Job search key */ *job; /* Matching job, if any */ if (job_id > 0) { key.id = job_id; } else if ((attr = ippFindAttribute(client->request, "job-uri", IPP_TAG_URI)) != NULL) { const char *uri = ippGetString(attr, 0, NULL); /* job-uri value */ char scheme[32], /* URI scheme */ userpass[256], /* username:password */ host[256], /* Hostname/IP */ resource[1024]; /* Resource path */ int port; /* Port number */ if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource)) >= HTTP_URI_STATUS_OK && !strncmp(resource, client->printer->resource, client->printer->resourcelen) && resource[client->printer->resourcelen] == '/') key.id = atoi(resource + client->printer->resourcelen + 1); else return (NULL); } else if ((attr = ippFindAttribute(client->request, "job-id", IPP_TAG_INTEGER)) != NULL) { key.id = ippGetInteger(attr, 0); } _cupsRWLockRead(&(client->printer->rwlock)); job = (server_job_t *)cupsArrayFind(client->printer->jobs, &key); _cupsRWUnlock(&(client->printer->rwlock)); return (job); }
std::unordered_set<std::string> destination_implObj::supported_options() const { std::unordered_set<std::string> s; info_t::lock lock{*this}; auto attrs=cupsFindDestSupported(lock->http, lock->dest, lock->info, "job-creation-attributes"); if (!attrs) return s; auto count=ippGetCount(attrs); for (decltype (count) i=0; i<count; i++) { s.insert(ippGetString(attrs, i, nullptr)); } return s; }
static int iprint_get_server_version(http_t *http, char* serviceUri) { ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ ipp_attribute_t *attr; /* Current attribute */ cups_lang_t *language = NULL; /* Default language */ char *ver; /* server version pointer */ char *vertmp; /* server version tmp pointer */ int serverVersion = 0; /* server version */ char *os; /* server os */ int osFlag = 0; /* 0 for NetWare, 1 for anything else */ char *temp; /* pointer for string manipulation */ /* * Build an OPERATION_NOVELL_MGMT("get-server-version") request, * which requires the following attributes: * * attributes-charset * attributes-natural-language * operation-name * service-uri */ request = ippNew(); ippSetOperation(request, (ipp_op_t)OPERATION_NOVELL_MGMT); ippSetRequestId(request, 1); language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "service-uri", NULL, serviceUri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "operation-name", NULL, "get-server-version"); /* * Do the request and get back a response... */ if (((response = cupsDoRequest(http, request, "/ipp/")) == NULL) || (ippGetStatusCode(response) >= IPP_OK_CONFLICT)) goto out; if (((attr = ippFindAttribute(response, "server-version", IPP_TAG_STRING)) != NULL)) { if ((ver = strstr(ippGetString(attr, 0, NULL), NOVELL_SERVER_VERSION_STRING)) != NULL) { ver += strlen(NOVELL_SERVER_VERSION_STRING); /* * Strangely, libcups stores a IPP_TAG_STRING (octet * string) as a null-terminated string with no length * even though it could be binary data with nulls in * it. Luckily, in this case the value is not binary. */ serverVersion = strtol(ver, &vertmp, 10); /* Check for not found, overflow or negative version */ if ((ver == vertmp) || (serverVersion < 0)) serverVersion = 0; } if ((os = strstr(ippGetString(attr, 0, NULL), NOVELL_SERVER_SYSNAME)) != NULL) { os += strlen(NOVELL_SERVER_SYSNAME); if ((temp = strchr(os,'<')) != NULL) *temp = '\0'; if (strcmp(os,NOVELL_SERVER_SYSNAME_NETWARE)) osFlag = 1; /* 1 for non-NetWare systems */ } } out: if (response) ippDelete(response); if (language) cupsLangFree(language); if (osFlag == 0) serverVersion *= -1; return serverVersion; }
/////////////////////////////////////////////////////////////////////////////////////////// // // CS : PRIVATE gint getPrinterURI(gchar *pDestName, gchar *pURI, gchar *pServerName, gint bufSize) // IN : gchar *pDestName : Printer name. // gint bufSize : Size of output buffer. // OUT : gchar *pURI : Printer URI. // gchar *pServerName : Server name. // RETURN : ID_ERR_NO_ERROR : No error. // ID_ERR_CUPS_API_FAILED : Error occured in CUPS API. // PRIVATE gint getPrinterURI(gchar *pDestName, gchar *pURI, gchar *pServerName, gint bufSize) { /*** Parameters start ***/ http_t *pHTTP; // Pointer to HTTP connection. ipp_t *pRequest, // Pointer to CUPS IPP request. *pResponse; // Pointer to CUPS IPP response. ipp_attribute_t *pAttribute; // Pointer to CUPS attributes. cups_lang_t *pLanguage; // Pointer to language. gchar *pPrinter = NULL; // Pointer to printer name. gchar *pUri = NULL; // Pointer to printer uri. gchar *pTemp = NULL; // Temporary pointer. gint i; // Counter. gint retVal = ID_ERR_NO_ERROR; // Return value. const char *attributes[] = { // Attributes name set. "printer-name", "printer-uri-supported", }; /*** Parameters end ***/ // CUPS http connect. if ((pHTTP = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption())) == NULL) { retVal = ID_ERR_CUPS_API_FAILED; } else { pRequest = ippNew(); ippSetOperation(pRequest, CUPS_GET_PRINTERS); ippSetRequestId(pRequest, 1); pLanguage = bjcupsLangDefault(); // cupsLangDefault() -> bjcupsLangDefault() for cups-1.1.19 ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, cupsLangEncoding(pLanguage)); ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, pLanguage->language); ippAddStrings(pRequest, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", sizeof(attributes) / sizeof(attributes[0]), NULL, attributes); if ((pResponse = cupsDoRequest(pHTTP, pRequest, "/")) != NULL) { if (ippGetStatusCode(pResponse) > IPP_OK_CONFLICT) { retVal = ID_ERR_CUPS_API_FAILED; } else { pAttribute = ippFirstAttribute(pResponse); while (pAttribute != NULL) { while (pAttribute != NULL && ippGetGroupTag(pAttribute) != IPP_TAG_PRINTER) { pAttribute = bjcups_ippNextAttribute(pRequest, pAttribute); } if (pAttribute == NULL) { break; } while (pAttribute != NULL && ippGetGroupTag(pAttribute) == IPP_TAG_PRINTER) { if (strcmp(ippGetName(pAttribute), "printer-name") == 0 && ippGetValueTag(pAttribute) == IPP_TAG_NAME) { pPrinter = ippGetString(pAttribute, 0, NULL); } if (strcmp(ippGetName(pAttribute), "printer-uri-supported") == 0 && ippGetValueTag(pAttribute) == IPP_TAG_URI) { pUri = ippGetString(pAttribute, 0, NULL); } pAttribute = bjcups_ippNextAttribute(pRequest, pAttribute); } // Tora 020418: Compare two printer names ignoring the character case. if (strcasecmp(pDestName, pPrinter) == 0) { strncpy(pURI, pUri, bufSize); pTemp = strstr(pURI, "//"); pTemp += 2; for (i = 0; *pTemp != '/' && *pTemp != ':'; i++, pTemp++) { pServerName[i] = *pTemp; } break; } if (pAttribute != NULL) pAttribute = bjcups_ippNextAttribute(pRequest, pAttribute); } } ippDelete(pResponse); } else { retVal = ID_ERR_CUPS_API_FAILED; } cupsLangFree(pLanguage); httpClose(pHTTP); } if (pURI[0] == '\0') { snprintf(pURI, bufSize, "ipp://localhost/printers/%s", pDestName); } if (pServerName[0] == '\0') { strncpy(pServerName, "localhost", strlen("localhost")); } return(retVal); }// End getPrinterURI
/////////////////////////////////////////////////////////////////////////////////////////// // // CS : PRIVATE gint getJobID(gchar *pDestName, gchar *pURI, gchar *pServerName, gint *pJobID) // IN : gchar *pDestName : Printer name. // gchar *pURI : Printer URI. // gchar *pServerName : CUPS server name. // OUT : gint *pJobID : Job ID. // RETURN : ID_ERR_NO_ERROR : No error. // ID_ERR_CUPS_API_FAILED : Error occured in CUPS API. // PRIVATE gint getJobID(gchar *pDestName, gchar *pURI, gchar *pServerName, gint *pJobID) { /*** Parameters start ***/ http_t *pHTTP; // Pointer to HTTP connection. ipp_t *pRequest, // Pointer to CUPS IPP request. *pResponse; // Pointer to CUPS IPP response. ipp_attribute_t *pAttribute; // Pointer to CUPS attributes. cups_lang_t *pLanguage; // Pointer to language. ipp_jstate_t jobState = 0; // Job state. gint jobID = 0; // Job ID. gchar *pJobUserName = NULL; // User name of print job. uid_t userID; // User ID. struct passwd *pPasswd; // Pointer to password structure. gint retVal = ID_ERR_PRINT_JOB_NOT_EXIST; // Return value. /*** Parameters end ***/ // Get login name. userID = getuid(); pPasswd = getpwuid(userID); // CUPS http connect. if ((pHTTP = httpConnectEncrypt(pServerName, ippPort(), cupsEncryption())) == NULL) { retVal = ID_ERR_CUPS_API_FAILED; } else { pRequest = ippNew(); ippSetOperation(pRequest, IPP_GET_JOBS); ippSetRequestId(pRequest, 1); pLanguage = bjcupsLangDefault(); // cupsLangDefault() -> bjcupsLangDefault() for cups-1.1.19 ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, cupsLangEncoding(pLanguage)); ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, pLanguage->language); ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, pURI); ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); if ((pResponse = cupsDoRequest(pHTTP, pRequest, "/")) != NULL) { int statusCode = ippGetStatusCode(pResponse); if (statusCode > IPP_OK_CONFLICT) { retVal = ID_ERR_CUPS_API_FAILED; } else { pAttribute = ippFirstAttribute(pResponse); while (pAttribute != NULL) { while (pAttribute != NULL && ippGetGroupTag(pAttribute) != IPP_TAG_JOB) { pAttribute = bjcups_ippNextAttribute(pResponse, pAttribute); } if (pAttribute == NULL) { break; } while (pAttribute != NULL && ippGetGroupTag(pAttribute) == IPP_TAG_JOB) { if (strcmp(ippGetName(pAttribute), "job-id") == 0 && ippGetValueTag(pAttribute) == IPP_TAG_INTEGER) { jobID = ippGetInteger(pAttribute, 0); } if (strcmp(ippGetName(pAttribute), "job-uri") == 0 && ippGetValueTag(pAttribute) == IPP_TAG_URI) { pJobUserName=getJobState(pDestName,ippGetString(pAttribute, 0, NULL),pServerName,&jobState,pJobUserName); } pAttribute = bjcups_ippNextAttribute(pRequest, pAttribute); } if (jobState == IPP_JOB_PROCESSING) { if (pJobUserName != NULL) { if (strcmp(pPasswd->pw_name, pJobUserName) == 0) { retVal = ID_ERR_NO_ERROR; } else if (pJobUserName[0] == '\0') { retVal = ID_ERR_NO_ERROR; } } break; } if (pAttribute != NULL) pAttribute = bjcups_ippNextAttribute(pRequest, pAttribute); } } ippDelete(pResponse); } else { retVal = ID_ERR_CUPS_API_FAILED; } cupsLangFree(pLanguage); httpClose(pHTTP); } if (retVal == ID_ERR_NO_ERROR && pJobID != NULL) { *pJobID = jobID; } return(retVal); }// End getJobID
PRIVATE gchar * getJobState(gchar *pDestName, const gchar *pURI, gchar *pServerName, ipp_jstate_t *pJobState, gchar *pJobUserName) { /*** Parameters start ***/ http_t *pHTTP; // Pointer to HTTP connection. ipp_t *pRequest, // Pointer to CUPS IPP request. *pResponse; // Pointer to CUPS IPP response. ipp_attribute_t *pAttribute; // Pointer to CUPS attributes. cups_lang_t *pLanguage; // Pointer to language. // ipp_jstate_t jobState = 0; // Job state. // gint jobID = 0; // Job ID. // gchar *pJobUserName = NULL; // User name of print job. uid_t userID; // User ID. struct passwd *pPasswd; // Pointer to password structure. gint retVal = ID_ERR_PRINT_JOB_NOT_EXIST; // Return value. /*** Parameters end ***/ // Get login name. userID = getuid(); pPasswd = getpwuid(userID); // CUPS http connect. if ((pHTTP = httpConnectEncrypt(pServerName, ippPort(), cupsEncryption())) == NULL) { retVal = ID_ERR_CUPS_API_FAILED; } else { pRequest = ippNew(); ippSetOperation(pRequest, IPP_GET_JOB_ATTRIBUTES); ippSetRequestId(pRequest, 1); pLanguage = bjcupsLangDefault(); // cupsLangDefault() -> bjcupsLangDefault() for cups-1.1.19 ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, cupsLangEncoding(pLanguage)); ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, pLanguage->language); ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, pURI); ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, pPasswd->pw_name); if ((pResponse = cupsDoRequest(pHTTP, pRequest, "/")) != NULL) { if (ippGetStatusCode(pResponse) > IPP_OK_CONFLICT) { retVal = ID_ERR_CUPS_API_FAILED; } else { pAttribute = ippFirstAttribute(pResponse); while (pAttribute != NULL) { while (pAttribute != NULL && ippGetGroupTag(pAttribute) != IPP_TAG_JOB) { pAttribute = bjcups_ippNextAttribute(pResponse, pAttribute); } if (pAttribute == NULL) { break; } while (pAttribute != NULL && ippGetGroupTag(pAttribute) == IPP_TAG_JOB) { if (strcmp(ippGetName(pAttribute), "job-state") == 0 && ippGetValueTag(pAttribute) == IPP_TAG_ENUM) { *pJobState = (ipp_jstate_t)ippGetInteger(pAttribute, 0); } if (strcmp(ippGetName(pAttribute), "job-originating-user-name") == 0 && ippGetValueTag(pAttribute) == IPP_TAG_NAME) { //pJobUserName = pAttribute->values[0].string.text; pJobUserName=malloc(20*sizeof(gchar)); strncpy(pJobUserName,ippGetString(pAttribute, 0, NULL), 19); pJobUserName[19]='\0'; } pAttribute = bjcups_ippNextAttribute(pResponse, pAttribute); } if (pAttribute != NULL) pAttribute = bjcups_ippNextAttribute(pResponse, pAttribute); } } ippDelete(pResponse); } else { retVal = ID_ERR_CUPS_API_FAILED; } cupsLangFree(pLanguage); httpClose(pHTTP); } return(pJobUserName); }// End getJobState
static gboolean _pp_maintenance_command_is_supported (const gchar *printer_name, const gchar *command) { ipp_attribute_t *attr = NULL; gboolean is_supported = FALSE; ipp_t *request; ipp_t *response = NULL; gchar *printer_uri; gchar *command_lowercase; GPtrArray *available_commands = NULL; int i; printer_uri = g_strdup_printf ("ipp://localhost/printers/%s", printer_name); request = ippNewRequest (IPP_GET_PRINTER_ATTRIBUTES); ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, printer_uri); ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", NULL, "printer-commands"); response = cupsDoRequest (CUPS_HTTP_DEFAULT, request, "/"); if (response != NULL) { if (ippGetStatusCode (response) <= IPP_OK_CONFLICT) { int commands_count; attr = ippFindAttribute (response, "printer-commands", IPP_TAG_ZERO); commands_count = attr != NULL ? ippGetCount (attr) : 0; if (commands_count > 0 && ippGetValueTag (attr) != IPP_TAG_NOVALUE && (ippGetValueTag (attr) == IPP_TAG_KEYWORD)) { available_commands = g_ptr_array_new_full (commands_count, g_free); for (i = 0; i < commands_count; ++i) { /* Array gains ownership of the lower-cased string */ g_ptr_array_add (available_commands, g_ascii_strdown (ippGetString (attr, i, NULL), -1)); } } } ippDelete (response); } if (available_commands != NULL) { command_lowercase = g_ascii_strdown (command, -1); for (i = 0; i < available_commands->len; ++i) { const gchar *available_command = g_ptr_array_index (available_commands, i); if (g_strcmp0 (available_command, command_lowercase) == 0) { is_supported = TRUE; break; } } g_free (command_lowercase); g_ptr_array_free (available_commands, TRUE); } g_free (printer_uri); return is_supported; }
static int iprint_queue_get(const char *sharename, enum printing_types printing_type, char *lpq_command, print_queue_struct **q, print_status_struct *status) { fstring printername; http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ ipp_attribute_t *attr = NULL; /* Current attribute */ cups_lang_t *language = NULL; /* Default language */ char uri[HTTP_MAX_URI]; /* printer-uri attribute */ char serviceUri[HTTP_MAX_URI]; /* service-uri attribute */ char httpPath[HTTP_MAX_URI]; /* path portion of the uri */ int jobUseUnixTime = 0; /* Whether job times should * be assumed to be Unix time */ int qcount = 0, /* Number of active queue entries */ qalloc = 0; /* Number of queue entries allocated */ print_queue_struct *queue = NULL, /* Queue entries */ *temp; /* Temporary pointer for queue */ const char *user_name, /* job-originating-user-name attribute */ *job_name; /* job-name attribute */ int job_id; /* job-id attribute */ int job_k_octets; /* job-k-octets attribute */ time_t job_time; /* time-at-creation attribute */ time_t printer_up_time = 0; /* printer's uptime */ ipp_jstate_t job_status; /* job-status attribute */ int job_priority; /* job-priority attribute */ static const char *jattrs[] = /* Requested job attributes */ { "job-id", "job-k-octets", "job-name", "job-originating-user-name", "job-priority", "job-state", "time-at-creation", }; static const char *pattrs[] = /* Requested printer attributes */ { "printer-state", "printer-state-message", "printer-current-time", "printer-up-time" }; *q = NULL; /* HACK ALERT!!! The porblem with support the 'printer name' option is that we key the tdb off the sharename. So we will overload the lpq_command string to pass in the printername (which is basically what we do for non-cups printers ... using the lpq_command to get the queue listing). */ fstrcpy( printername, lpq_command ); DEBUG(5,("iprint_queue_get(%s, %p, %p)\n", printername, q, status)); /* * Make sure we don't ask for passwords... */ cupsSetPasswordCB(iprint_passwd_cb); /* * Try to connect to the server... */ if ((http = httpConnect(iprint_server(), ippPort())) == NULL) { DEBUG(0,("Unable to connect to iPrint server %s - %s\n", iprint_server(), strerror(errno))); goto out; } /* * Generate the printer URI and the service URI that goes with it... */ slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), printername); slprintf(serviceUri, sizeof(serviceUri) - 1, "ipp://%s/ipp/", iprint_server()); /* * For Linux iPrint servers from OES SP1 on, the iPrint server * uses Unix time for job start times unless it detects the iPrint * client in an http User-Agent header. (This was done to accomodate * CUPS broken behavior. According to RFC 2911, section 4.3.14, job * start times are supposed to be relative to how long the printer has * been up.) Since libcups doesn't allow us to set that header before * the request is sent, this ugly hack allows us to detect the server * version and decide how to interpret the job time. */ if (iprint_get_server_version(http, serviceUri) >= NOVELL_SERVER_VERSION_OES_SP1) jobUseUnixTime = 1; request = ippNew(); ippSetOperation(request, IPP_GET_PRINTER_ATTRIBUTES); ippSetRequestId(request, 2); language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (sizeof(pattrs) / sizeof(pattrs[0])), NULL, pattrs); /* * Do the request and get back a response... */ slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", printername); if ((response = cupsDoRequest(http, request, httpPath)) == NULL) { DEBUG(0,("Unable to get printer status for %s - %s\n", printername, ippErrorString(cupsLastError()))); *q = queue; goto out; } if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) { DEBUG(0,("Unable to get printer status for %s - %s\n", printername, ippErrorString(ippGetStatusCode(response)))); *q = queue; goto out; } /* * Get the current printer status and convert it to the SAMBA values. */ if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL) { if (ippGetInteger(attr, 0) == IPP_PRINTER_STOPPED) status->status = LPSTAT_STOPPED; else status->status = LPSTAT_OK; } if ((attr = ippFindAttribute(response, "printer-state-message", IPP_TAG_TEXT)) != NULL) fstrcpy(status->message, ippGetString(attr, 0, NULL)); if ((attr = ippFindAttribute(response, "printer-up-time", IPP_TAG_INTEGER)) != NULL) printer_up_time = ippGetInteger(attr, 0); ippDelete(response); response = NULL; /* * Build an IPP_GET_JOBS request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * requested-attributes * printer-uri */ request = ippNew(); ippSetOperation(request, IPP_GET_JOBS); ippSetRequestId(request, 3); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (sizeof(jattrs) / sizeof(jattrs[0])), NULL, jattrs); /* * Do the request and get back a response... */ slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", printername); if ((response = cupsDoRequest(http, request, httpPath)) == NULL) { DEBUG(0,("Unable to get jobs for %s - %s\n", uri, ippErrorString(cupsLastError()))); goto out; } if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) { DEBUG(0,("Unable to get jobs for %s - %s\n", uri, ippErrorString(ippGetStatusCode(response)))); goto out; } /* * Process the jobs... */ qcount = 0; qalloc = 0; queue = NULL; for (attr = ippFirstAttribute(response); attr != NULL; attr = ippNextAttribute(response)) { /* * Skip leading attributes until we hit a job... */ while (attr != NULL && ippGetGroupTag(attr) != IPP_TAG_JOB) attr = ippNextAttribute(response); if (attr == NULL) break; /* * Allocate memory as needed... */ if (qcount >= qalloc) { qalloc += 16; queue = SMB_REALLOC_ARRAY(queue, print_queue_struct, qalloc); if (queue == NULL) { DEBUG(0,("iprint_queue_get: Not enough memory!")); qcount = 0; goto out; } } temp = queue + qcount; memset(temp, 0, sizeof(print_queue_struct)); /* * Pull the needed attributes from this job... */ job_id = 0; job_priority = 50; job_status = IPP_JOB_PENDING; job_time = 0; job_k_octets = 0; user_name = NULL; job_name = NULL; while (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_JOB) { if (ippGetName(attr) == NULL) { attr = ippNextAttribute(response); break; } if (strcmp(ippGetName(attr), "job-id") == 0 && ippGetValueTag(attr) == IPP_TAG_INTEGER) job_id = ippGetInteger(attr, 0); if (strcmp(ippGetName(attr), "job-k-octets") == 0 && ippGetValueTag(attr) == IPP_TAG_INTEGER) job_k_octets = ippGetInteger(attr, 0); if (strcmp(ippGetName(attr), "job-priority") == 0 && ippGetValueTag(attr) == IPP_TAG_INTEGER) job_priority = ippGetInteger(attr, 0); if (strcmp(ippGetName(attr), "job-state") == 0 && ippGetValueTag(attr) == IPP_TAG_ENUM) job_status = (ipp_jstate_t)ippGetInteger(attr, 0); if (strcmp(ippGetName(attr), "time-at-creation") == 0 && ippGetValueTag(attr) == IPP_TAG_INTEGER) { /* * If jobs times are in Unix time, the accuracy of the job * start time depends upon the iPrint server's time being * set correctly. Otherwise, the accuracy depends upon * the Samba server's time being set correctly */ if (jobUseUnixTime) job_time = ippGetInteger(attr, 0); else job_time = time(NULL) - printer_up_time + ippGetInteger(attr, 0); } if (strcmp(ippGetName(attr), "job-name") == 0 && (ippGetValueTag(attr) == IPP_TAG_NAMELANG || ippGetValueTag(attr) == IPP_TAG_NAME)) job_name = ippGetString(attr, 0, NULL); if (strcmp(ippGetName(attr), "job-originating-user-name") == 0 && (ippGetValueTag(attr) == IPP_TAG_NAMELANG || ippGetValueTag(attr) == IPP_TAG_NAME)) user_name = ippGetString(attr, 0, NULL); attr = ippNextAttribute(response); } /* * See if we have everything needed... */ if (user_name == NULL || job_name == NULL || job_id == 0) { if (attr == NULL) break; else continue; } temp->sysjob = job_id; temp->size = job_k_octets * 1024; temp->status = job_status == IPP_JOB_PENDING ? LPQ_QUEUED : job_status == IPP_JOB_STOPPED ? LPQ_PAUSED : job_status == IPP_JOB_HELD ? LPQ_PAUSED : LPQ_PRINTING; temp->priority = job_priority; temp->time = job_time; strncpy(temp->fs_user, user_name, sizeof(temp->fs_user) - 1); strncpy(temp->fs_file, job_name, sizeof(temp->fs_file) - 1); qcount ++; if (attr == NULL) break; } /* * Return the job queue... */ *q = queue; out: if (response) ippDelete(response); if (language) cupsLangFree(language); if (http) httpClose(http); return qcount; }
server_job_t * /* O - Job */ serverCreateJob(server_client_t *client) /* I - Client */ { server_job_t *job; /* Job */ ipp_attribute_t *attr; /* Job attribute */ char uri[1024], /* job-uri value */ uuid[64]; /* job-uuid value */ server_listener_t *lis = (server_listener_t *)cupsArrayFirst(Listeners); /* First listener */ _cupsRWLockWrite(&(client->printer->rwlock)); /* * Allocate and initialize the job object... */ if ((job = calloc(1, sizeof(server_job_t))) == NULL) { perror("Unable to allocate memory for job"); return (NULL); } job->printer = client->printer; job->attrs = ippNew(); job->state = IPP_JSTATE_HELD; job->fd = -1; /* * Copy all of the job attributes... */ serverCopyAttributes(job->attrs, client->request, NULL, IPP_TAG_JOB, 0); /* * Get the requesting-user-name, document format, and priority... */ if ((attr = ippFindAttribute(client->request, "job-priority", IPP_TAG_INTEGER)) != NULL) job->priority = ippGetInteger(attr, 0); else job->priority = 50; if ((attr = ippFindAttribute(client->request, "requesting-user-name", IPP_TAG_NAME)) != NULL) job->username = ippGetString(attr, 0, NULL); else job->username = "******"; ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, "job-originating-user-name", NULL, job->username); if (ippGetOperation(client->request) != IPP_OP_CREATE_JOB) { if ((attr = ippFindAttribute(job->attrs, "document-format-detected", IPP_TAG_MIMETYPE)) != NULL) job->format = ippGetString(attr, 0, NULL); else if ((attr = ippFindAttribute(job->attrs, "document-format-supplied", IPP_TAG_MIMETYPE)) != NULL) job->format = ippGetString(attr, 0, NULL); else job->format = "application/octet-stream"; } if ((attr = ippFindAttribute(client->request, "job-impressions", IPP_TAG_INTEGER)) != NULL) job->impressions = ippGetInteger(attr, 0); if ((attr = ippFindAttribute(client->request, "job-name", IPP_TAG_NAME)) != NULL) job->name = ippGetString(attr, 0, NULL); /* * Add job description attributes and add to the jobs array... */ job->id = client->printer->next_job_id ++; snprintf(uri, sizeof(uri), "%s/%d", client->printer->default_uri, job->id); httpAssembleUUID(lis->host, lis->port, client->printer->name, job->id, uuid, sizeof(uuid)); ippAddDate(job->attrs, IPP_TAG_JOB, "date-time-at-creation", ippTimeToDate(time(&job->created))); ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-id", job->id); ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-uri", NULL, uri); ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-uuid", NULL, uuid); if ((attr = ippFindAttribute(client->request, "printer-uri", IPP_TAG_URI)) != NULL) ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-printer-uri", NULL, ippGetString(attr, 0, NULL)); else ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-printer-uri", NULL, client->printer->default_uri); ippAddInteger(job->attrs, IPP_TAG_JOB, IPP_TAG_INTEGER, "time-at-creation", (int)(job->created - client->printer->start_time)); cupsArrayAdd(client->printer->jobs, job); cupsArrayAdd(client->printer->active_jobs, job); _cupsRWUnlock(&(client->printer->rwlock)); return (job); }
option_values_t destination_implObj::parse_attribute_values(info_t::lock &lock, ipp_attribute_t *attrs, const char *option_s, bool unicode_flag) { if (!attrs) return {}; auto count=ippGetCount(attrs); auto tag_value=ippGetValueTag(attrs); switch (tag_value) { case IPP_TAG_NOVALUE: return {}; case IPP_TAG_RANGE: { std::vector<std::tuple<int, int>> v; v.reserve(count); for (decltype (count) i=0; i<count; i++) { int upper; int lower=ippGetRange(attrs, i, &upper); v.emplace_back(lower, upper); } return v; } case IPP_TAG_RESOLUTION: { std::vector<resolution> v; v.reserve(count); for (decltype (count) i=0; i<count; i++) { resolution res; ipp_res_t units; res.xres=ippGetResolution(attrs, i, &res.yres, &units); switch (units) { case IPP_RES_PER_INCH: res.units=res.per_inch; break; case IPP_RES_PER_CM: res.units=res.per_cm; break; default: res.units=res.unknown; } v.push_back(res); } return v; } case IPP_TAG_INTEGER: { std::unordered_set<int> v; for (decltype (count) i=0; i<count; i++) { v.insert(ippGetInteger(attrs, i)); } return v; } case IPP_TAG_BOOLEAN: { std::unordered_set<bool> v; for (decltype (count) i=0; i<count; i++) { v.insert(ippGetBoolean(attrs, i)); } return v; } case IPP_TAG_ENUM: if (unicode_flag) { auto l=locale::base::global(); std::unordered_map<int, std::u32string> v; for (decltype (count) i=0; i<count; i++) { auto value=ippGetInteger(attrs, i); auto s=enum_string(option_s, value); auto us=unicode::iconvert::tou ::convert(s, l->charset()).first; v.emplace(value, us); } return v; } else { std::unordered_map<int, std::string> v; for (decltype (count) i=0; i<count; i++) { auto value=ippGetInteger(attrs, i); v.emplace(value, enum_string(option_s, value)); } return v; } case IPP_TAG_BEGIN_COLLECTION: { std::vector<const_collection> v; v.reserve(count); for (decltype (count) i=0; i<count; i++) { auto ippc=ippGetCollection(attrs, i); auto c=collection::create(); for (auto attr=ippFirstAttribute(ippc); attr; attr=ippNextAttribute(ippc)) { std::string n=ippGetName(attr); c->emplace(n, parse_attribute_values (lock, attr, n.c_str(), unicode_flag)); } v.push_back(c); } return v; } default: break; } std::unordered_map<std::string, std::string> v; bool is_media=strcmp(option_s, CUPS_MEDIA) == 0; auto localizer=strcmp(option_s, CUPS_SIDES) == 0 ? sides : strcmp(option_s, CUPS_PRINT_COLOR_MODE) == 0 ? print_color_mode : no_localizer; for (decltype (count) i=0; i<count; i++) { const char *lang=0; auto val=ippGetString(attrs, i, &lang); if (!val) { std::ostringstream o; o << "{unknown tag " << ippTagString(ippGetValueTag(attrs)) << "}"; v.emplace(o.str(), ""); continue; } std::string lang_s; if (is_media) { cups_size_t size; lang_s=val; if (cupsGetDestMediaByName(lock->http, lock->dest, lock->info, val, CUPS_MEDIA_FLAGS_DEFAULT, &size)) { auto l=cupsLocalizeDestMedia (lock->http, lock->dest, lock->info, CUPS_MEDIA_FLAGS_DEFAULT, &size); if (l) lang_s=l; } } else { auto c=cupsLocalizeDestValue(lock->http, lock->dest, lock->info, option_s, val); if (c && strcmp(c, val)) { lang_s=c; } else { lang_s=localizer(val); } } v.emplace(val, lang_s); } if (!unicode_flag) return v; auto l=locale::base::global(); std::unordered_map<std::string, std::u32string> uv; for (const auto &s:v) { auto n=s.first; uv.emplace(s.first, unicode::iconvert::tou::convert(s.second, l->charset()) .first); } return uv; }
static int iprint_cache_add_printer(http_t *http, int reqId, char* url) { ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ ipp_attribute_t *attr; /* Current attribute */ cups_lang_t *language = NULL; /* Default language */ char *name, /* printer-name attribute */ *info, /* printer-info attribute */ smb_enabled, /* smb-enabled attribute */ secure; /* security-enabled attrib. */ char *httpPath; /* path portion of the printer-uri */ static const char *pattrs[] = /* Requested printer attributes */ { "printer-name", "security-enabled", "printer-info", "smb-enabled" }; request = ippNew(); ippSetOperation(request, IPP_GET_PRINTER_ATTRIBUTES); ippSetRequestId(request, reqId); language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, url); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (sizeof(pattrs) / sizeof(pattrs[0])), NULL, pattrs); /* * Do the request and get back a response... */ if ((httpPath = strstr(url,"://")) == NULL || (httpPath = strchr(httpPath+3,'/')) == NULL) { ippDelete(request); request = NULL; goto out; } if ((response = cupsDoRequest(http, request, httpPath)) == NULL) { ipp_status_t lastErr = cupsLastError(); /* * Ignore printers that cannot be queried without credentials */ if (lastErr == IPP_FORBIDDEN || lastErr == IPP_NOT_AUTHENTICATED || lastErr == IPP_NOT_AUTHORIZED) goto out; DEBUG(0,("Unable to get printer list - %s\n", ippErrorString(lastErr))); goto out; } for (attr = ippFirstAttribute(response); attr != NULL;) { /* * Skip leading attributes until we hit a printer... */ while (attr != NULL && ippGetGroupTag(attr) != IPP_TAG_PRINTER) attr = ippNextAttribute(response); if (attr == NULL) break; /* * Pull the needed attributes from this printer... */ name = NULL; info = NULL; smb_enabled= 1; secure = 0; while (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_PRINTER) { if (strcmp(ippGetName(attr), "printer-name") == 0 && ippGetValueTag(attr) == IPP_TAG_NAME) name = ippGetString(attr, 0, NULL); if (strcmp(ippGetName(attr), "printer-info") == 0 && (ippGetValueTag(attr) == IPP_TAG_TEXT || ippGetValueTag(attr) == IPP_TAG_TEXTLANG)) info = ippGetString(attr, 0, NULL); /* * If the smb-enabled attribute is present and the * value is set to 0, don't show the printer. * If the attribute is not present, assume that the * printer should show up */ if (!strcmp(ippGetName(attr), "smb-enabled") && ((ippGetValueTag(attr) == IPP_TAG_INTEGER && !ippGetInteger(attr, 0)) || (ippGetValueTag(attr) == IPP_TAG_BOOLEAN && !ippGetBoolean(attr, 0)))) smb_enabled = 0; /* * If the security-enabled attribute is present and the * value is set to 1, don't show the printer. * If the attribute is not present, assume that the * printer should show up */ if (!strcmp(ippGetName(attr), "security-enabled") && ((ippGetValueTag(attr) == IPP_TAG_INTEGER && ippGetInteger(attr, 0)) || (ippGetValueTag(attr) == IPP_TAG_BOOLEAN && ippGetBoolean(attr, 0)))) secure = 1; attr = ippNextAttribute(response); } /* * See if we have everything needed... * Make sure the printer is not a secure printer * and make sure smb printing hasn't been explicitly * disabled for the printer */ if (name != NULL && !secure && smb_enabled) pcap_cache_add(name, info, NULL); } out: if (response) ippDelete(response); return(0); }
bool iprint_cache_reload(void) { http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ ipp_attribute_t *attr; /* Current attribute */ cups_lang_t *language = NULL; /* Default language */ int i; bool ret = False; DEBUG(5, ("reloading iprint printcap cache\n")); /* * Make sure we don't ask for passwords... */ cupsSetPasswordCB(iprint_passwd_cb); /* * Try to connect to the server... */ if ((http = httpConnect(iprint_server(), ippPort())) == NULL) { DEBUG(0,("Unable to connect to iPrint server %s - %s\n", iprint_server(), strerror(errno))); goto out; } /* * Build a OPERATION_NOVELL_LIST_PRINTERS request, which requires the following attributes: * * attributes-charset * attributes-natural-language */ request = ippNew(); ippSetOperation(request, (ipp_op_t)OPERATION_NOVELL_LIST_PRINTERS); ippSetRequestId(request, 1); language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "ipp-server", NULL, "ippSrvr"); /* * Do the request and get back a response... */ if ((response = cupsDoRequest(http, request, "/ipp")) == NULL) { DEBUG(0,("Unable to get printer list - %s\n", ippErrorString(cupsLastError()))); goto out; } for (attr = ippFirstAttribute(response); attr != NULL;) { /* * Skip leading attributes until we hit a printer... */ while (attr != NULL && ippGetGroupTag(attr) != IPP_TAG_PRINTER) attr = ippNextAttribute(response); if (attr == NULL) break; /* * Pull the needed attributes from this printer... */ while (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_PRINTER) { if (strcmp(ippGetName(attr), "printer-name") == 0 && (ippGetValueTag(attr) == IPP_TAG_URI || ippGetValueTag(attr) == IPP_TAG_NAME || ippGetValueTag(attr) == IPP_TAG_TEXT || ippGetValueTag(attr) == IPP_TAG_NAMELANG || ippGetValueTag(attr) == IPP_TAG_TEXTLANG)) { for (i = 0; i<ippGetCount(attr); i++) { char *url = ippGetString(attr, i, NULL); if (!url || !strlen(url)) continue; iprint_cache_add_printer(http, i+2, url); } } attr = ippNextAttribute(response); } } ret = True; out: if (response) ippDelete(response); if (language) cupsLangFree(language); if (http) httpClose(http); return ret; }
static void show_supported(http_t *http, /* I - Connection to destination */ cups_dest_t *dest, /* I - Destination */ cups_dinfo_t *dinfo, /* I - Destination information */ const char *option, /* I - Option, if any */ const char *value) /* I - Value, if any */ { ipp_attribute_t *attr; /* Attribute */ int i, /* Looping var */ count; /* Number of values */ if (!option) { attr = cupsFindDestSupported(http, dest, dinfo, "job-creation-attributes"); if (attr) { count = ippGetCount(attr); for (i = 0; i < count; i ++) show_supported(http, dest, dinfo, ippGetString(attr, i, NULL), NULL); } else { static const char * const options[] = { /* List of standard options */ CUPS_COPIES, CUPS_FINISHINGS, CUPS_MEDIA, CUPS_NUMBER_UP, CUPS_ORIENTATION, CUPS_PRINT_COLOR_MODE, CUPS_PRINT_QUALITY, CUPS_SIDES }; puts("No job-creation-attributes-supported attribute, probing instead."); for (i = 0; i < (int)(sizeof(options) / sizeof(options[0])); i ++) if (cupsCheckDestSupported(http, dest, dinfo, options[i], NULL)) show_supported(http, dest, dinfo, options[i], NULL); } } else if (!value) { printf("%s (%s)\n", option, cupsCheckDestSupported(http, dest, dinfo, option, NULL) ? "supported" : "not-supported"); if ((attr = cupsFindDestSupported(http, dest, dinfo, option)) != NULL) { count = ippGetCount(attr); switch (ippGetValueTag(attr)) { case IPP_TAG_INTEGER : for (i = 0; i < count; i ++) printf(" %d\n", ippGetInteger(attr, i)); break; case IPP_TAG_ENUM : for (i = 0; i < count; i ++) printf(" %s\n", ippEnumString(option, ippGetInteger(attr, i))); break; case IPP_TAG_RANGE : for (i = 0; i < count; i ++) { int upper, lower = ippGetRange(attr, i, &upper); printf(" %d-%d\n", lower, upper); } break; case IPP_TAG_RESOLUTION : for (i = 0; i < count; i ++) { int xres, yres; ipp_res_t units; xres = ippGetResolution(attr, i, &yres, &units); if (xres == yres) printf(" %d%s\n", xres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm"); else printf(" %dx%d%s\n", xres, yres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm"); } break; case IPP_TAG_TEXTLANG : case IPP_TAG_NAMELANG : case IPP_TAG_TEXT : case IPP_TAG_NAME : case IPP_TAG_KEYWORD : case IPP_TAG_URI : case IPP_TAG_URISCHEME : case IPP_TAG_CHARSET : case IPP_TAG_LANGUAGE : case IPP_TAG_MIMETYPE : for (i = 0; i < count; i ++) printf(" %s\n", ippGetString(attr, i, NULL)); break; case IPP_TAG_STRING : for (i = 0; i < count; i ++) { int j, len; unsigned char *data = ippGetOctetString(attr, i, &len); fputs(" ", stdout); for (j = 0; j < len; j ++) { if (data[j] < ' ' || data[j] >= 0x7f) printf("<%02X>", data[j]); else putchar(data[j]); } putchar('\n'); } break; case IPP_TAG_BOOLEAN : break; default : printf(" %s\n", ippTagString(ippGetValueTag(attr))); break; } } } else if (cupsCheckDestSupported(http, dest, dinfo, option, value)) puts("YES"); else puts("NO"); }
static void _pp_maintenance_command_execute_thread (GSimpleAsyncResult *res, GObject *object, GCancellable *cancellable) { PpMaintenanceCommand *command = (PpMaintenanceCommand *) object; PpMaintenanceCommandPrivate *priv = command->priv; static const char *attrs[] = {"printer-commands"}; ipp_attribute_t *attr = NULL; gboolean success = FALSE; GError *error = NULL; ipp_t *request; ipp_t *response = NULL; gchar *printer_uri; gchar *printer_commands = NULL; gchar *printer_commands_lowercase = NULL; gchar *command_lowercase; gchar *file_name = NULL; int fd = -1; printer_uri = g_strdup_printf ("ipp://localhost/printers/%s", priv->printer_name); request = ippNewRequest (IPP_GET_PRINTER_ATTRIBUTES); ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, printer_uri); ippAddStrings (request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", 1, NULL, attrs); response = cupsDoRequest (CUPS_HTTP_DEFAULT, request, "/"); if (response) { if (ippGetStatusCode (response) <= IPP_OK_CONFLICT) { attr = ippFindAttribute (response, "printer-commands", IPP_TAG_ZERO); if (attr && ippGetCount (attr) > 0 && ippGetValueTag (attr) != IPP_TAG_NOVALUE) { if (ippGetValueTag (attr) == IPP_TAG_KEYWORD) { printer_commands = g_strdup (ippGetString (attr, 0, NULL)); } } else { success = TRUE; } } ippDelete (response); } if (printer_commands) { command_lowercase = g_ascii_strdown (priv->command, -1); printer_commands_lowercase = g_ascii_strdown (printer_commands, -1); if (g_strrstr (printer_commands_lowercase, command_lowercase)) { request = ippNewRequest (IPP_PRINT_JOB); ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, printer_uri); ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, priv->title); ippAddString (request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, "document-format", NULL, "application/vnd.cups-command"); fd = g_file_open_tmp ("ccXXXXXX", &file_name, &error); if (fd != -1) { FILE *file; file = fdopen (fd, "w"); fprintf (file, "#CUPS-COMMAND\n"); fprintf (file, "%s\n", priv->command); fclose (file); response = cupsDoFileRequest (CUPS_HTTP_DEFAULT, request, "/", file_name); g_unlink (file_name); if (response) { if (ippGetStatusCode (response) <= IPP_OK_CONFLICT) { success = TRUE; } ippDelete (response); } } g_free (file_name); } else { success = TRUE; } g_free (command_lowercase); g_free (printer_commands_lowercase); g_free (printer_commands); } g_free (printer_uri); if (!success) { g_simple_async_result_set_error (res, G_IO_ERROR, G_IO_ERROR_FAILED, "Execution of maintenance command failed."); } g_simple_async_result_set_op_res_gboolean (res, success); }
static bool process_cups_printers_response(TALLOC_CTX *mem_ctx, ipp_t *response, struct pcap_data *pcap_data) { ipp_attribute_t *attr; char *name; char *info; char *location = NULL; struct pcap_printer *printer; bool ret_ok = false; for (attr = ippFirstAttribute(response); attr != NULL;) { /* * Skip leading attributes until we hit a printer... */ while (attr != NULL && ippGetGroupTag(attr) != IPP_TAG_PRINTER) attr = ippNextAttribute(response); if (attr == NULL) break; /* * Pull the needed attributes from this printer... */ name = NULL; info = NULL; while (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_PRINTER) { size_t size; if (strcmp(ippGetName(attr), "printer-name") == 0 && ippGetValueTag(attr) == IPP_TAG_NAME) { if (!pull_utf8_talloc(mem_ctx, &name, ippGetString(attr, 0, NULL), &size)) { goto err_out; } } if (strcmp(ippGetName(attr), "printer-info") == 0 && ippGetValueTag(attr) == IPP_TAG_TEXT) { if (!pull_utf8_talloc(mem_ctx, &info, ippGetString(attr, 0, NULL), &size)) { goto err_out; } } if (strcmp(ippGetName(attr), "printer-location") == 0 && ippGetValueTag(attr) == IPP_TAG_TEXT) { if (!pull_utf8_talloc(mem_ctx, &location, ippGetString(attr, 0, NULL), &size)) { goto err_out; } } attr = ippNextAttribute(response); } /* * See if we have everything needed... */ if (name == NULL) break; if (pcap_data->count == 0) { printer = talloc_array(mem_ctx, struct pcap_printer, 1); } else {
int /* O - Exit status */ main(int argc, /* I - Number of command-line args */ char *argv[]) /* I - Command-line arguments */ { ipp_t *msg; /* Event message from scheduler */ ipp_state_t state; /* IPP event state */ struct sigaction action; /* POSIX sigaction data */ DBusConnection *con = NULL; /* Connection to DBUS server */ DBusError error; /* Error, if any */ DBusMessage *message; /* Message to send */ DBusMessageIter iter; /* Iterator for message data */ int lock_fd = -1; /* Lock file descriptor */ /* * Don't buffer stderr... */ setbuf(stderr, NULL); /* * Ignore SIGPIPE signals... */ memset(&action, 0, sizeof(action)); action.sa_handler = SIG_IGN; sigaction(SIGPIPE, &action, NULL); /* * Validate command-line options... */ if (argc != 3) { fputs("Usage: dbus dbus:/// notify-user-data\n", stderr); return (1); } if (strncmp(argv[1], "dbus:", 5)) { fprintf(stderr, "ERROR: Bad URI \"%s\"!\n", argv[1]); return (1); } /* * Loop forever until we run out of events... */ for (;;) { ipp_attribute_t *attr; /* Current attribute */ const char *event; /* Event name */ const char *signame = NULL;/* DBUS signal name */ char *printer_reasons = NULL; /* Printer reasons string */ char *job_reasons = NULL; /* Job reasons string */ const char *nul = ""; /* Empty string value */ int no = 0; /* Boolean "no" value */ int params = PARAMS_NONE; /* What parameters to include? */ /* * Get the next event... */ msg = ippNew(); while ((state = ippReadFile(0, msg)) != IPP_DATA) { if (state <= IPP_IDLE) break; } fprintf(stderr, "DEBUG: state=%d\n", state); if (state == IPP_ERROR) fputs("DEBUG: ippReadFile() returned IPP_ERROR!\n", stderr); if (state <= IPP_IDLE) { /* * Out of messages, free memory and then exit... */ ippDelete(msg); break; } /* * Verify connection to DBUS server... */ if (con && !dbus_connection_get_is_connected(con)) { dbus_connection_unref(con); con = NULL; } if (!con) { dbus_error_init(&error); con = dbus_bus_get(DBUS_BUS_SYSTEM, &error); if (!con) dbus_error_free(&error); else fputs("DEBUG: Connected to D-BUS\n", stderr); } if (!con) continue; if (lock_fd == -1 && acquire_lock(&lock_fd, lock_filename, sizeof(lock_filename))) continue; attr = ippFindAttribute(msg, "notify-subscribed-event", IPP_TAG_KEYWORD); if (!attr) continue; event = ippGetString(attr, 0, NULL); if (!strncmp(event, "server-", 7)) { const char *word2 = event + 7; /* Second word */ if (!strcmp(word2, "restarted")) signame = "ServerRestarted"; else if (!strcmp(word2, "started")) signame = "ServerStarted"; else if (!strcmp(word2, "stopped")) signame = "ServerStopped"; else if (!strcmp(word2, "audit")) signame = "ServerAudit"; else continue; } else if (!strncmp(event, "printer-", 8)) { const char *word2 = event + 8; /* Second word */ params = PARAMS_PRINTER; if (!strcmp(word2, "restarted")) signame = "PrinterRestarted"; else if (!strcmp(word2, "shutdown")) signame = "PrinterShutdown"; else if (!strcmp(word2, "stopped")) signame = "PrinterStopped"; else if (!strcmp(word2, "state-changed")) signame = "PrinterStateChanged"; else if (!strcmp(word2, "finishings-changed")) signame = "PrinterFinishingsChanged"; else if (!strcmp(word2, "media-changed")) signame = "PrinterMediaChanged"; else if (!strcmp(word2, "added")) signame = "PrinterAdded"; else if (!strcmp(word2, "deleted")) signame = "PrinterDeleted"; else if (!strcmp(word2, "modified")) signame = "PrinterModified"; else continue; } else if (!strncmp(event, "job-", 4)) { const char *word2 = event + 4; /* Second word */ params = PARAMS_JOB; if (!strcmp(word2, "state-changed")) signame = "JobState"; else if (!strcmp(word2, "created")) signame = "JobCreated"; else if (!strcmp(word2, "completed")) signame = "JobCompleted"; else if (!strcmp(word2, "stopped")) signame = "JobStopped"; else if (!strcmp(word2, "config-changed")) signame = "JobConfigChanged"; else if (!strcmp(word2, "progress")) signame = "JobProgress"; else continue; } else continue; /* * Create and send the new message... */ fprintf(stderr, "DEBUG: %s\n", signame); message = dbus_message_new_signal("/org/cups/cupsd/Notifier", "org.cups.cupsd.Notifier", signame); dbus_message_append_iter_init(message, &iter); attr = ippFindAttribute(msg, "notify-text", IPP_TAG_TEXT); if (attr) { const char *val = ippGetString(attr, 0, NULL); if (!dbus_message_iter_append_string(&iter, &val)) goto bail; } else goto bail; if (params >= PARAMS_PRINTER) { char *p; /* Pointer into printer_reasons */ size_t reasons_length; /* Required size of printer_reasons */ int i; /* Looping var */ int have_printer_params = 1;/* Do we have printer URI? */ /* STRING printer-uri or "" */ attr = ippFindAttribute(msg, "notify-printer-uri", IPP_TAG_URI); if (attr) { const char *val = ippGetString(attr, 0, NULL); if (!dbus_message_iter_append_string(&iter, &val)) goto bail; } else { have_printer_params = 0; dbus_message_iter_append_string(&iter, &nul); } /* STRING printer-name */ if (have_printer_params) { attr = ippFindAttribute(msg, "printer-name", IPP_TAG_NAME); if (attr) { const char *val = ippGetString(attr, 0, NULL); if (!dbus_message_iter_append_string(&iter, &val)) goto bail; } else goto bail; } else dbus_message_iter_append_string(&iter, &nul); /* UINT32 printer-state */ if (have_printer_params) { attr = ippFindAttribute(msg, "printer-state", IPP_TAG_ENUM); if (attr) { dbus_uint32_t val = ippGetInteger(attr, 0); dbus_message_iter_append_uint32(&iter, &val); } else goto bail; } else dbus_message_iter_append_uint32(&iter, &no); /* STRING printer-state-reasons */ if (have_printer_params) { attr = ippFindAttribute(msg, "printer-state-reasons", IPP_TAG_KEYWORD); if (attr) { int num_values = ippGetCount(attr); for (reasons_length = 0, i = 0; i < num_values; i++) /* All need commas except the last, which needs a nul byte. */ reasons_length += 1 + strlen(ippGetString(attr, i, NULL)); printer_reasons = malloc(reasons_length); if (!printer_reasons) goto bail; p = printer_reasons; for (i = 0; i < num_values; i++) { if (i) *p++ = ','; strlcpy(p, ippGetString(attr, i, NULL), reasons_length - (p - printer_reasons)); p += strlen(p); } if (!dbus_message_iter_append_string(&iter, &printer_reasons)) goto bail; } else goto bail; } else dbus_message_iter_append_string(&iter, &nul); /* BOOL printer-is-accepting-jobs */ if (have_printer_params) { attr = ippFindAttribute(msg, "printer-is-accepting-jobs", IPP_TAG_BOOLEAN); if (attr) { dbus_bool_t val = ippGetBoolean(attr, 0); dbus_message_iter_append_boolean(&iter, &val); } else goto bail; } else dbus_message_iter_append_boolean(&iter, &no); } if (params >= PARAMS_JOB) { char *p; /* Pointer into job_reasons */ size_t reasons_length; /* Required size of job_reasons */ int i; /* Looping var */ /* UINT32 job-id */ attr = ippFindAttribute(msg, "notify-job-id", IPP_TAG_INTEGER); if (attr) { dbus_uint32_t val = ippGetInteger(attr, 0); dbus_message_iter_append_uint32(&iter, &val); } else goto bail; /* UINT32 job-state */ attr = ippFindAttribute(msg, "job-state", IPP_TAG_ENUM); if (attr) { dbus_uint32_t val = ippGetInteger(attr, 0); dbus_message_iter_append_uint32(&iter, &val); } else goto bail; /* STRING job-state-reasons */ attr = ippFindAttribute(msg, "job-state-reasons", IPP_TAG_KEYWORD); if (attr) { int num_values = ippGetCount(attr); for (reasons_length = 0, i = 0; i < num_values; i++) /* All need commas except the last, which needs a nul byte. */ reasons_length += 1 + strlen(ippGetString(attr, i, NULL)); job_reasons = malloc(reasons_length); if (!job_reasons) goto bail; p = job_reasons; for (i = 0; i < num_values; i++) { if (i) *p++ = ','; strlcpy(p, ippGetString(attr, i, NULL), reasons_length - (p - job_reasons)); p += strlen(p); } if (!dbus_message_iter_append_string(&iter, &job_reasons)) goto bail; } else goto bail; /* STRING job-name or "" */ attr = ippFindAttribute(msg, "job-name", IPP_TAG_NAME); if (attr) { const char *val = ippGetString(attr, 0, NULL); if (!dbus_message_iter_append_string(&iter, &val)) goto bail; } else dbus_message_iter_append_string(&iter, &nul); /* UINT32 job-impressions-completed */ attr = ippFindAttribute(msg, "job-impressions-completed", IPP_TAG_INTEGER); if (attr) { dbus_uint32_t val = ippGetInteger(attr, 0); dbus_message_iter_append_uint32(&iter, &val); } else goto bail; } dbus_connection_send(con, message, NULL); dbus_connection_flush(con); /* * Cleanup... */ bail: dbus_message_unref(message); if (printer_reasons) free(printer_reasons); if (job_reasons) free(job_reasons); ippDelete(msg); } /* * Remove lock file... */ if (lock_fd >= 0) { close(lock_fd); release_lock(); } return (0); }
static int GetCupsPrinters(char ***printer) { http_t *http=NULL; /* HTTP object */ ipp_t *request=NULL; /* IPP request object */ ipp_t *response=NULL; /* IPP response object */ ipp_attribute_t *attr; /* Current IPP attribute */ int cnt=0; /* Connect to the HTTP server */ if ((http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption())) == NULL) goto bugout; /* Assemble the IPP request */ request = ippNew(); ippSetOperation( request, CUPS_GET_PRINTERS ); ippSetRequestId( request, 1 ); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, "en"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", NULL, "device-uri"); /* Send the request and get a response. */ if ((response = cupsDoRequest(http, request, "/")) == NULL) goto bugout; for (attr = ippFirstAttribute ( response ); attr != NULL; attr = ippNextAttribute( response )) { /* Skip leading attributes until we hit a printer. */ while (attr != NULL && ippGetGroupTag( attr ) != IPP_TAG_PRINTER) attr = ippNextAttribute( response ); if (attr == NULL) break; while (attr != NULL && ippGetGroupTag( attr ) == IPP_TAG_PRINTER) { if (strcmp(ippGetName( attr ), "device-uri") == 0 && ippGetValueTag( attr ) == IPP_TAG_URI && AddCupsList(ippGetString( attr, 0, NULL ), printer) == 0) cnt++; attr = ippNextAttribute( response ); } if (attr == NULL) break; } ippDelete(response); bugout: return cnt; }