/////////////////////////////////////////////////////////////////////////////////////////// // // CS : PRIVATE gint checkPrinterState(gchar *pDestName, gchar *pURI, gchar *pServerName) // IN : gchar *pDestName : Printer name. // gchar *pURI : Printer URI. // gchar *pServerName : CUPS server name. // OUT : None. // RETURN : ID_ERR_NO_ERROR : No error. // ID_ERR_UNKNOWN_PRINTER : No printer registerd in CUPS. // ID_ERR_CUPS_API_FAILED : Error occured in CUPS API. // PRIVATE gint checkPrinterState(gchar *pDestName, gchar *pURI, gchar *pServerName) { /*** 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_pstate_t printerState = IPP_PRINTER_STOPPED; // Pointer to printer state. gint retVal = ID_ERR_UNKNOWN_PRINTER; // Return value. /*** Parameters end ***/ // CUPS http connect. if ((pHTTP = httpConnectEncrypt(pServerName, 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, pURI); if ((pResponse = cupsDoRequest(pHTTP, pRequest, "/")) != NULL) { if (ippGetStatusCode(pResponse) > IPP_OK_CONFLICT) { retVal = ID_ERR_CUPS_API_FAILED; } else { if ((pAttribute = ippFindAttribute(pResponse, "printer-state", IPP_TAG_ENUM)) != NULL) { printerState = (ipp_state_t) ippGetInteger(pAttribute, 0); } } ippDelete(pResponse); } else { retVal = ID_ERR_CUPS_API_FAILED; } cupsLangFree(pLanguage); httpClose(pHTTP); } if (printerState == IPP_PRINTER_IDLE || printerState == IPP_PRINTER_PROCESSING) { retVal = ID_ERR_NO_ERROR; } return(retVal); }// End checkPrinterState
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); }
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); }
int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { _ippdata_t data; /* IPP buffer */ ipp_uchar_t buffer[8192]; /* Write buffer data */ ipp_t *cols[2], /* Collections */ *size; /* media-size collection */ ipp_t *request; /* Request */ ipp_attribute_t *media_col, /* media-col attribute */ *media_size, /* media-size attribute */ *attr; /* Other attribute */ ipp_state_t state; /* State */ size_t length; /* Length of data */ cups_file_t *fp; /* File pointer */ size_t i; /* Looping var */ int status; /* Status of tests (0 = success, 1 = fail) */ #ifdef DEBUG const char *name; /* Option name */ #endif /* DEBUG */ status = 0; if (argc == 1) { /* * Test request generation code... */ printf("Create Sample Request: "); request = ippNew(); request->request.op.version[0] = 0x01; request->request.op.version[1] = 0x01; request->request.op.operation_id = IPP_OP_PRINT_JOB; request->request.op.request_id = 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_URI, "printer-uri", NULL, "ipp://localhost/printers/foo"); cols[0] = ippNew(); size = ippNew(); ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "x-dimension", 21590); ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "y-dimension", 27940); ippAddCollection(cols[0], IPP_TAG_JOB, "media-size", size); ippDelete(size); ippAddString(cols[0], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-color", NULL, "blue"); ippAddString(cols[0], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-type", NULL, "plain"); cols[1] = ippNew(); size = ippNew(); ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "x-dimension", 21000); ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "y-dimension", 29700); ippAddCollection(cols[1], IPP_TAG_JOB, "media-size", size); ippDelete(size); ippAddString(cols[1], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-color", NULL, "plaid"); ippAddString(cols[1], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-type", NULL, "glossy"); ippAddCollections(request, IPP_TAG_JOB, "media-col", 2, (const ipp_t **)cols); ippDelete(cols[0]); ippDelete(cols[1]); length = ippLength(request); if (length != sizeof(collection)) { printf("FAIL - wrong ippLength(), %d instead of %d bytes!\n", (int)length, (int)sizeof(collection)); status = 1; } else puts("PASS"); /* * Write test #1... */ printf("Write Sample to Memory: "); data.wused = 0; data.wsize = sizeof(buffer); data.wbuffer = buffer; while ((state = ippWriteIO(&data, (ipp_iocb_t)write_cb, 1, NULL, request)) != IPP_STATE_DATA) if (state == IPP_STATE_ERROR) break; if (state != IPP_STATE_DATA) { printf("FAIL - %d bytes written.\n", (int)data.wused); status = 1; } else if (data.wused != sizeof(collection)) { printf("FAIL - wrote %d bytes, expected %d bytes!\n", (int)data.wused, (int)sizeof(collection)); hex_dump("Bytes Written", data.wbuffer, data.wused); hex_dump("Baseline", collection, sizeof(collection)); status = 1; } else if (memcmp(data.wbuffer, collection, data.wused)) { for (i = 0; i < data.wused; i ++) if (data.wbuffer[i] != collection[i]) break; printf("FAIL - output does not match baseline at 0x%04x!\n", (unsigned)i); hex_dump("Bytes Written", data.wbuffer, data.wused); hex_dump("Baseline", collection, sizeof(collection)); status = 1; } else puts("PASS"); ippDelete(request); /* * Read the data back in and confirm... */ printf("Read Sample from Memory: "); request = ippNew(); data.rpos = 0; while ((state = ippReadIO(&data, (ipp_iocb_t)read_cb, 1, NULL, request)) != IPP_STATE_DATA) if (state == IPP_STATE_ERROR) break; length = ippLength(request); if (state != IPP_STATE_DATA) { printf("FAIL - %d bytes read.\n", (int)data.rpos); status = 1; } else if (data.rpos != data.wused) { printf("FAIL - read %d bytes, expected %d bytes!\n", (int)data.rpos, (int)data.wused); print_attributes(request, 8); status = 1; } else if (length != sizeof(collection)) { printf("FAIL - wrong ippLength(), %d instead of %d bytes!\n", (int)length, (int)sizeof(collection)); print_attributes(request, 8); status = 1; } else puts("PASS"); fputs("ippFindAttribute(media-col): ", stdout); if ((media_col = ippFindAttribute(request, "media-col", IPP_TAG_BEGIN_COLLECTION)) == NULL) { if ((media_col = ippFindAttribute(request, "media-col", IPP_TAG_ZERO)) == NULL) puts("FAIL (not found)"); else printf("FAIL (wrong type - %s)\n", ippTagString(media_col->value_tag)); status = 1; } else if (media_col->num_values != 2) { printf("FAIL (wrong count - %d)\n", media_col->num_values); status = 1; } else puts("PASS"); if (media_col) { fputs("ippFindAttribute(media-size 1): ", stdout); if ((media_size = ippFindAttribute(media_col->values[0].collection, "media-size", IPP_TAG_BEGIN_COLLECTION)) == NULL) { if ((media_size = ippFindAttribute(media_col->values[0].collection, "media-col", IPP_TAG_ZERO)) == NULL) puts("FAIL (not found)"); else printf("FAIL (wrong type - %s)\n", ippTagString(media_size->value_tag)); status = 1; } else { if ((attr = ippFindAttribute(media_size->values[0].collection, "x-dimension", IPP_TAG_INTEGER)) == NULL) { if ((attr = ippFindAttribute(media_size->values[0].collection, "x-dimension", IPP_TAG_ZERO)) == NULL) puts("FAIL (missing x-dimension)"); else printf("FAIL (wrong type for x-dimension - %s)\n", ippTagString(attr->value_tag)); status = 1; } else if (attr->values[0].integer != 21590) { printf("FAIL (wrong value for x-dimension - %d)\n", attr->values[0].integer); status = 1; } else if ((attr = ippFindAttribute(media_size->values[0].collection, "y-dimension", IPP_TAG_INTEGER)) == NULL) { if ((attr = ippFindAttribute(media_size->values[0].collection, "y-dimension", IPP_TAG_ZERO)) == NULL) puts("FAIL (missing y-dimension)"); else printf("FAIL (wrong type for y-dimension - %s)\n", ippTagString(attr->value_tag)); status = 1; } else if (attr->values[0].integer != 27940) { printf("FAIL (wrong value for y-dimension - %d)\n", attr->values[0].integer); status = 1; } else puts("PASS"); } fputs("ippFindAttribute(media-size 2): ", stdout); if ((media_size = ippFindAttribute(media_col->values[1].collection, "media-size", IPP_TAG_BEGIN_COLLECTION)) == NULL) { if ((media_size = ippFindAttribute(media_col->values[1].collection, "media-col", IPP_TAG_ZERO)) == NULL) puts("FAIL (not found)"); else printf("FAIL (wrong type - %s)\n", ippTagString(media_size->value_tag)); status = 1; } else { if ((attr = ippFindAttribute(media_size->values[0].collection, "x-dimension", IPP_TAG_INTEGER)) == NULL) { if ((attr = ippFindAttribute(media_size->values[0].collection, "x-dimension", IPP_TAG_ZERO)) == NULL) puts("FAIL (missing x-dimension)"); else printf("FAIL (wrong type for x-dimension - %s)\n", ippTagString(attr->value_tag)); status = 1; } else if (attr->values[0].integer != 21000) { printf("FAIL (wrong value for x-dimension - %d)\n", attr->values[0].integer); status = 1; } else if ((attr = ippFindAttribute(media_size->values[0].collection, "y-dimension", IPP_TAG_INTEGER)) == NULL) { if ((attr = ippFindAttribute(media_size->values[0].collection, "y-dimension", IPP_TAG_ZERO)) == NULL) puts("FAIL (missing y-dimension)"); else printf("FAIL (wrong type for y-dimension - %s)\n", ippTagString(attr->value_tag)); status = 1; } else if (attr->values[0].integer != 29700) { printf("FAIL (wrong value for y-dimension - %d)\n", attr->values[0].integer); status = 1; } else puts("PASS"); } } /* * Test hierarchical find... */ fputs("ippFindAttribute(media-col/media-size/x-dimension): ", stdout); if ((attr = ippFindAttribute(request, "media-col/media-size/x-dimension", IPP_TAG_INTEGER)) != NULL) { if (ippGetInteger(attr, 0) != 21590) { printf("FAIL (wrong value for x-dimension - %d)\n", ippGetInteger(attr, 0)); status = 1; } else puts("PASS"); } else { puts("FAIL (not found)"); status = 1; } fputs("ippFindNextAttribute(media-col/media-size/x-dimension): ", stdout); if ((attr = ippFindNextAttribute(request, "media-col/media-size/x-dimension", IPP_TAG_INTEGER)) != NULL) { if (ippGetInteger(attr, 0) != 21000) { printf("FAIL (wrong value for x-dimension - %d)\n", ippGetInteger(attr, 0)); status = 1; } else puts("PASS"); } else { puts("FAIL (not found)"); status = 1; } fputs("ippFindNextAttribute(media-col/media-size/x-dimension) again: ", stdout); if ((attr = ippFindNextAttribute(request, "media-col/media-size/x-dimension", IPP_TAG_INTEGER)) != NULL) { printf("FAIL (got %d, expected nothing)\n", ippGetInteger(attr, 0)); status = 1; } else puts("PASS"); ippDelete(request); /* * Read the mixed data and confirm we converted everything to rangeOfInteger * values... */ printf("Read Mixed integer/rangeOfInteger from Memory: "); request = ippNew(); data.rpos = 0; data.wused = sizeof(mixed); data.wsize = sizeof(mixed); data.wbuffer = mixed; while ((state = ippReadIO(&data, (ipp_iocb_t)read_cb, 1, NULL, request)) != IPP_STATE_DATA) if (state == IPP_STATE_ERROR) break; length = ippLength(request); if (state != IPP_STATE_DATA) { printf("FAIL - %d bytes read.\n", (int)data.rpos); status = 1; } else if (data.rpos != sizeof(mixed)) { printf("FAIL - read %d bytes, expected %d bytes!\n", (int)data.rpos, (int)sizeof(mixed)); print_attributes(request, 8); status = 1; } else if (length != (sizeof(mixed) + 4)) { printf("FAIL - wrong ippLength(), %d instead of %d bytes!\n", (int)length, (int)sizeof(mixed) + 4); print_attributes(request, 8); status = 1; } else puts("PASS"); fputs("ippFindAttribute(notify-lease-duration-supported): ", stdout); if ((attr = ippFindAttribute(request, "notify-lease-duration-supported", IPP_TAG_ZERO)) == NULL) { puts("FAIL (not found)"); status = 1; } else if (attr->value_tag != IPP_TAG_RANGE) { printf("FAIL (wrong type - %s)\n", ippTagString(attr->value_tag)); status = 1; } else if (attr->num_values != 2) { printf("FAIL (wrong count - %d)\n", attr->num_values); status = 1; } else if (attr->values[0].range.lower != 1 || attr->values[0].range.upper != 1 || attr->values[1].range.lower != 16 || attr->values[1].range.upper != 32) { printf("FAIL (wrong values - %d,%d and %d,%d)\n", attr->values[0].range.lower, attr->values[0].range.upper, attr->values[1].range.lower, attr->values[1].range.upper); status = 1; } else puts("PASS"); ippDelete(request); #ifdef DEBUG /* * Test that private option array is sorted... */ fputs("_ippCheckOptions: ", stdout); if ((name = _ippCheckOptions()) == NULL) puts("PASS"); else { printf("FAIL (\"%s\" out of order)\n", name); status = 1; } #endif /* DEBUG */ /* * Test _ippFindOption() private API... */ fputs("_ippFindOption(\"printer-type\"): ", stdout); if (_ippFindOption("printer-type")) puts("PASS"); else { puts("FAIL"); status = 1; } /* * Summarize... */ putchar('\n'); if (status) puts("Core IPP tests failed."); else puts("Core IPP tests passed."); } else { /* * Read IPP files... */ for (i = 1; i < (size_t)argc; i ++) { if ((fp = cupsFileOpen(argv[i], "r")) == NULL) { printf("Unable to open \"%s\" - %s\n", argv[i], strerror(errno)); status = 1; continue; } request = ippNew(); while ((state = ippReadIO(fp, (ipp_iocb_t)cupsFileRead, 1, NULL, request)) == IPP_STATE_ATTRIBUTE); if (state != IPP_STATE_DATA) { printf("Error reading IPP message from \"%s\"!\n", argv[i]); status = 1; } else { printf("\n%s:\n", argv[i]); print_attributes(request, 4); } ippDelete(request); cupsFileClose(fp); } } return (status); }
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; }
static int iprint_job_submit(int snum, struct printjob *pjob, enum printing_types printing_type, char *lpq_cmd) { int ret = 1; /* Return value */ 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 */ char uri[HTTP_MAX_URI]; /* printer-uri attribute */ DEBUG(5,("iprint_job_submit(%d, %p (%d))\n", snum, pjob, pjob->sysjob)); /* * 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 an IPP_PRINT_JOB request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * requesting-user-name * [document-data] */ request = ippNew(); ippSetOperation(request, IPP_PRINT_JOB); 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); slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), lp_printername(snum)); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, pjob->user); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-originating-host-name", NULL, pjob->clientmachine); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, pjob->jobname); /* * Do the request and get back a response... */ slprintf(uri, sizeof(uri) - 1, "/ipp/%s", lp_printername(snum)); if ((response = cupsDoFileRequest(http, request, uri, pjob->filename)) != NULL) { if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) { DEBUG(0,("Unable to print file to %s - %s\n", lp_printername(snum), ippErrorString(cupsLastError()))); } else { ret = 0; } } else { DEBUG(0,("Unable to print file to `%s' - %s\n", lp_printername(snum), ippErrorString(cupsLastError()))); } if ( ret == 0 ) unlink(pjob->filename); /* else print_job_end will do it for us */ if ( ret == 0 ) { attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER); if (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_JOB) { pjob->sysjob = ippGetInteger(attr, 0); } } 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 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
int KCupsConnection::renewDBusSubscription(int subscriptionId, int leaseDuration, const QStringList &events) { int ret = -1; if (!readyToStart()) { kWarning() << "Tryied to run on the wrong thread"; return subscriptionId; // This is not intended to be used in the gui thread } ipp_t *response = NULL; do { ipp_t *request; ipp_op_e operation; // check if we have a valid subscription ID if (subscriptionId >= 0) { // Add the "notify-events" values to the request operation = IPP_RENEW_SUBSCRIPTION; } else { operation = IPP_CREATE_PRINTER_SUBSCRIPTION; } // Lets create the request request = ippNewRequest(operation); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, KCUPS_PRINTER_URI, NULL, "/"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); if (operation == IPP_CREATE_PRINTER_SUBSCRIPTION) { // Add the "notify-events" values to the request QVariantHash values; values["notify-events"] = events; requestAddValues(request, values); ippAddString(request, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD, "notify-pull-method", NULL, "ippget"); ippAddString(request, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI, "notify-recipient-uri", NULL, "dbus://"); ippAddInteger(request, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, "notify-lease-duration", leaseDuration); } else { ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "notify-subscription-id", subscriptionId); ippAddInteger(request, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, "notify-lease-duration", leaseDuration); } // Do the request response = cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/"); } while (retry("/")); #ifdef HAVE_CUPS_1_6 if (response && ippGetStatusCode(response) == IPP_OK) { #else if (response && response->request.status.status_code == IPP_OK) { #endif // HAVE_CUPS_1_6 ipp_attribute_t *attr; if (subscriptionId >= 0) { // Request was ok, just return the current subscription ret = subscriptionId; } else if ((attr = ippFindAttribute(response, "notify-subscription-id", IPP_TAG_INTEGER)) == NULL) { kWarning() << "No notify-subscription-id in response!"; ret = -1; } else { #ifdef HAVE_CUPS_1_6 ret = ippGetInteger(attr, 0); } } else if (subscriptionId >= 0 && response && ippGetStatusCode(response) == IPP_NOT_FOUND) { kDebug() << "Subscription not found"; // When the subscription is not found try to get a new one return renewDBusSubscription(-1, leaseDuration, events); #else ret = attr->values[0].integer; } } else if (subscriptionId >= 0 && response && response->request.status.status_code == IPP_NOT_FOUND) { kDebug() << "Subscription not found"; // When the subscription is not found try to get a new one return renewDBusSubscription(-1, leaseDuration, events); #endif // HAVE_CUPS_1_6 } else { kWarning() << "Request failed" << lastError(); // When the server stops/restarts we will have some error so ignore it ret = subscriptionId; } ippDelete(response); 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"); }
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 void renew_subscription_thread (GTask *task, gpointer source_object, gpointer task_data, GCancellable *cancellable) { ipp_attribute_t *attr = NULL; CRSData *subscription_data = task_data; ipp_t *request; ipp_t *response = NULL; gint result = -1; if (g_cancellable_is_cancelled (cancellable)) return; if (subscription_data->id > 0) { request = ippNewRequest (IPP_RENEW_SUBSCRIPTION); ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, "/"); ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser ()); ippAddInteger (request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "notify-subscription-id", subscription_data->id); ippAddInteger (request, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, "notify-lease-duration", subscription_data->lease_duration); response = cupsDoRequest (CUPS_HTTP_DEFAULT, request, "/"); if (response != NULL && ippGetStatusCode (response) <= IPP_OK_CONFLICT) { if ((attr = ippFindAttribute (response, "notify-lease-duration", IPP_TAG_INTEGER)) == NULL) g_debug ("No notify-lease-duration in response!\n"); else if (ippGetInteger (attr, 0) == subscription_data->lease_duration) result = subscription_data->id; } } if (result < 0) { request = ippNewRequest (IPP_CREATE_PRINTER_SUBSCRIPTION); ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, "/"); ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser ()); ippAddStrings (request, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD, "notify-events", g_strv_length (subscription_data->events), NULL, (const char * const *) subscription_data->events); ippAddString (request, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD, "notify-pull-method", NULL, "ippget"); ippAddString (request, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI, "notify-recipient-uri", NULL, "dbus://"); ippAddInteger (request, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, "notify-lease-duration", subscription_data->lease_duration); response = cupsDoRequest (CUPS_HTTP_DEFAULT, request, "/"); if (response != NULL && ippGetStatusCode (response) <= IPP_OK_CONFLICT) { if ((attr = ippFindAttribute (response, "notify-subscription-id", IPP_TAG_INTEGER)) == NULL) g_debug ("No notify-subscription-id in response!\n"); else result = ippGetInteger (attr, 0); } } ippDelete (response); g_task_return_int (task, result); }