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; }
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 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; }
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 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); }
/////////////////////////////////////////////////////////////////////////////////////////// // // 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 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 {
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"); }
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 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; }