ipp_status_t cupsCancelDestJob(http_t *http, /* I - Connection to destination */ cups_dest_t *dest, /* I - Destination */ int job_id) /* I - Job ID */ { cups_dinfo_t *info; /* Destination information */ if ((info = cupsCopyDestInfo(http, dest)) != NULL) { ipp_t *request; /* Cancel-Job request */ request = ippNewRequest(IPP_OP_CANCEL_JOB); ippSetVersion(request, info->version / 10, info->version % 10); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, info->uri); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", job_id); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); ippDelete(cupsDoRequest(http, request, info->resource)); cupsFreeDestInfo(info); } return (cupsLastError()); }
/* Cancels subscription of given id */ static void cancel_subscription_thread (GTask *task, gpointer source_object, gpointer task_data, GCancellable *cancellable) { ipp_t *request; ipp_t *response = NULL; gint id = GPOINTER_TO_INT (task_data); if (id >= 0) { request = ippNewRequest (IPP_CANCEL_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", id); response = cupsDoRequest (CUPS_HTTP_DEFAULT, request, "/"); } g_task_return_boolean (task, response != NULL && ippGetStatusCode (response) <= IPP_OK); ippDelete (response); }
http_status_t /* O - HTTP status of request */ cupsStartDocument( http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ const char *name, /* I - Destination name */ int job_id, /* I - Job ID from @link cupsCreateJob@ */ const char *docname, /* I - Name of document */ const char *format, /* I - MIME type or @code CUPS_FORMAT_foo@ */ int last_document) /* I - 1 for last document in job, 0 otherwise */ { char resource[1024], /* Resource for destinatio */ printer_uri[1024]; /* Printer URI */ ipp_t *request; /* Send-Document request */ http_status_t status; /* HTTP status */ /* * Create a Send-Document request... */ if ((request = ippNewRequest(IPP_SEND_DOCUMENT)) == NULL) { _cupsSetError(IPP_INTERNAL_ERROR, strerror(ENOMEM), 0); return (HTTP_ERROR); } httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri), "ipp", NULL, "localhost", ippPort(), "/printers/%s", name); snprintf(resource, sizeof(resource), "/printers/%s", name); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, printer_uri); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", job_id); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); if (docname) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "document-name", NULL, docname); if (format) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", NULL, format); ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", last_document); /* * Send and delete the request, then return the status... */ status = cupsSendRequest(http, request, resource, CUPS_LENGTH_VARIABLE); ippDelete(request); return (status); }
static int /* O - 0 on success, 1 on fail */ enable_printer(http_t *http, /* I - Server connection */ char *printer) /* I - Printer to enable */ { ipp_t *request; /* IPP Request */ char uri[HTTP_MAX_URI]; /* URI for printer/class */ DEBUG_printf(("enable_printer(%p, \"%s\")\n", http, printer)); /* * Build a CUPS_ADD_MODIFY_PRINTER or CUPS_ADD_MODIFY_CLASS request, which * require the following attributes: * * attributes-charset * attributes-natural-language * printer-uri * requesting-user-name * printer-state * printer-is-accepting-jobs */ if (get_printer_type(http, printer, uri, sizeof(uri)) & CUPS_PRINTER_CLASS) request = ippNewRequest(CUPS_ADD_MODIFY_CLASS); else request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); ippAddInteger(request, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state", IPP_PRINTER_IDLE); ippAddBoolean(request, IPP_TAG_PRINTER, "printer-is-accepting-jobs", 1); /* * Do the request and get back a response... */ ippDelete(cupsDoRequest(http, request, "/admin/")); if (cupsLastError() > IPP_OK_CONFLICT) { _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString()); return (1); } else return (0); }
static int /* O - 0 on success, 1 on fail */ delete_printer_option(http_t *http, /* I - Server connection */ char *printer, /* I - Printer */ char *option) /* I - Option to delete */ { ipp_t *request; /* IPP request */ char uri[HTTP_MAX_URI]; /* URI for printer/class */ /* * Build a CUPS_ADD_MODIFY_PRINTER or CUPS_ADD_MODIFY_CLASS request, which * requires the following attributes: * * attributes-charset * attributes-natural-language * printer-uri * requesting-user-name * option with deleteAttr tag */ if (get_printer_type(http, printer, uri, sizeof(uri)) & CUPS_PRINTER_CLASS) request = ippNewRequest(CUPS_ADD_MODIFY_CLASS); else request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); ippAddInteger(request, IPP_TAG_PRINTER, IPP_TAG_DELETEATTR, option, 0); /* * Do the request and get back a response... */ ippDelete(cupsDoRequest(http, request, "/admin/")); if (cupsLastError() > IPP_OK_CONFLICT) { _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString()); return (1); } else return (0); }
void KCupsConnection::cancelDBusSubscription() { do { ipp_t *request; // Lets create the request request = ippNewRequest(IPP_CANCEL_SUBSCRIPTION); 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()); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "notify-subscription-id", m_subscriptionId); // Do the request ippDelete(cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/")); } while (retry("/")); // Reset the subscription id m_subscriptionId = -1; }
static int /* O - Command status */ send_state(const char *queue, /* I - Destination */ const char *list, /* I - Job or user */ int longstatus) /* I - List of jobs or users */ { int id; /* Job ID from list */ http_t *http; /* HTTP server connection */ ipp_t *request, /* IPP Request */ *response; /* IPP Response */ ipp_attribute_t *attr; /* Current attribute */ ipp_pstate_t state; /* Printer state */ const char *jobdest, /* Pointer into job-printer-uri */ *jobuser, /* Pointer to job-originating-user-name */ *jobname; /* Pointer to job-name */ ipp_jstate_t jobstate; /* job-state */ int jobid, /* job-id */ jobsize, /* job-k-octets */ jobcount, /* Number of jobs */ jobcopies, /* Number of copies */ rank; /* Rank of job */ char rankstr[255]; /* Rank string */ char namestr[1024]; /* Job name string */ char uri[HTTP_MAX_URI]; /* Printer URI */ char dest[256]; /* Printer/class queue */ static const char * const ranks[10] = /* Ranking strings */ { "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th" }; static const char * const requested[] = { /* Requested attributes */ "job-id", "job-k-octets", "job-state", "job-printer-uri", "job-originating-user-name", "job-name", "copies" }; /* * Try connecting to the local server... */ if ((http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption())) == NULL) { syslog(LOG_ERR, "Unable to connect to server %s: %s", cupsServer(), strerror(errno)); printf("Unable to connect to server %s: %s", cupsServer(), strerror(errno)); return (1); } /* * Get the actual destination name and printer state... */ if (get_printer(http, queue, dest, sizeof(dest), NULL, NULL, NULL, &state)) { syslog(LOG_ERR, "Unable to get printer %s: %s", queue, cupsLastErrorString()); printf("Unable to get printer %s: %s", queue, cupsLastErrorString()); return (1); } /* * Show the queue state... */ switch (state) { case IPP_PRINTER_IDLE : printf("%s is ready\n", dest); break; case IPP_PRINTER_PROCESSING : printf("%s is ready and printing\n", dest); break; case IPP_PRINTER_STOPPED : printf("%s is not ready\n", dest); break; } /* * Build an IPP_GET_JOBS or IPP_GET_JOB_ATTRIBUTES request, which requires * the following attributes: * * attributes-charset * attributes-natural-language * job-uri or printer-uri */ id = atoi(list); request = ippNewRequest(id ? IPP_GET_JOB_ATTRIBUTES : IPP_GET_JOBS); httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/printers/%s", dest); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); if (id) ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", id); else { ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, list); ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1); } ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", sizeof(requested) / sizeof(requested[0]), NULL, requested); /* * Do the request and get back a response... */ jobcount = 0; response = cupsDoRequest(http, request, "/"); if (cupsLastError() > IPP_OK_CONFLICT) { printf("get-jobs failed: %s\n", cupsLastErrorString()); ippDelete(response); return (1); } /* * Loop through the job list and display them... */ for (attr = response->attrs, rank = 1; attr; attr = attr->next) { /* * Skip leading attributes until we hit a job... */ while (attr && (attr->group_tag != IPP_TAG_JOB || !attr->name)) attr = attr->next; if (!attr) break; /* * Pull the needed attributes from this job... */ jobid = 0; jobsize = 0; jobstate = IPP_JOB_PENDING; jobname = "untitled"; jobuser = NULL; jobdest = NULL; jobcopies = 1; while (attr && attr->group_tag == IPP_TAG_JOB) { if (!strcmp(attr->name, "job-id") && attr->value_tag == IPP_TAG_INTEGER) jobid = attr->values[0].integer; if (!strcmp(attr->name, "job-k-octets") && attr->value_tag == IPP_TAG_INTEGER) jobsize = attr->values[0].integer; if (!strcmp(attr->name, "job-state") && attr->value_tag == IPP_TAG_ENUM) jobstate = (ipp_jstate_t)attr->values[0].integer; if (!strcmp(attr->name, "job-printer-uri") && attr->value_tag == IPP_TAG_URI) if ((jobdest = strrchr(attr->values[0].string.text, '/')) != NULL) jobdest ++; if (!strcmp(attr->name, "job-originating-user-name") && attr->value_tag == IPP_TAG_NAME) jobuser = attr->values[0].string.text; if (!strcmp(attr->name, "job-name") && attr->value_tag == IPP_TAG_NAME) jobname = attr->values[0].string.text; if (!strcmp(attr->name, "copies") && attr->value_tag == IPP_TAG_INTEGER) jobcopies = attr->values[0].integer; attr = attr->next; } /* * See if we have everything needed... */ if (!jobdest || !jobid) { if (!attr) break; else continue; } if (!longstatus && jobcount == 0) puts("Rank Owner Job File(s) Total Size"); jobcount ++; /* * Display the job... */ if (jobstate == IPP_JOB_PROCESSING) strlcpy(rankstr, "active", sizeof(rankstr)); else { snprintf(rankstr, sizeof(rankstr), "%d%s", rank, ranks[rank % 10]); rank ++; } if (longstatus) { puts(""); if (jobcopies > 1) snprintf(namestr, sizeof(namestr), "%d copies of %s", jobcopies, jobname); else strlcpy(namestr, jobname, sizeof(namestr)); printf("%s: %-33.33s [job %d localhost]\n", jobuser, rankstr, jobid); printf(" %-39.39s %.0f bytes\n", namestr, 1024.0 * jobsize); } else printf("%-7s %-7.7s %-7d %-31.31s %.0f bytes\n", rankstr, jobuser, jobid, jobname, 1024.0 * jobsize); if (!attr) break; } ippDelete(response); if (jobcount == 0) puts("no entries"); httpClose(http); 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); }
/////////////////////////////////////////////////////////////////////////////////////////// // // CS : PUBLIC gint removeJob(gchar *pDestName) // IN : gchar *pDestName : Printer name. // OUT : None. // RETURN : ID_ERR_NO_ERROR : No error. // ID_ERR_CUPS_API_FAILED : Error occured in CUPS API. // PUBLIC gint removeJob(gchar *pDestName) { /*** Parameters start ***/ http_t *pHTTP; // Pointer to HTTP connection. ipp_t *pRequest, // Pointer to CUPS IPP request. *pResponse; // Pointer to CUPS IPP response. cups_lang_t *pLanguage; // Pointer to language. gchar printerURI[HTTP_MAX_URI]; // Printer URI. gchar serverName[HTTP_MAX_URI]; // CUPS server name. gint jobID = 0; // Job ID. gint retVal = ID_ERR_NO_ERROR; // Return value. /*** Parameters end ***/ // Initialize buffer. memset(printerURI, 0, sizeof(printerURI)); memset(serverName, 0, sizeof(serverName)); // Get printer URI and CUPS server name. retVal = getPrinterURI(pDestName, printerURI, serverName, HTTP_MAX_URI); if (retVal == ID_ERR_NO_ERROR) { retVal = getJobID(pDestName, printerURI, serverName, &jobID); if (retVal == ID_ERR_PRINT_JOB_NOT_EXIST) { retVal = ID_ERR_NO_ERROR; } if (retVal == ID_ERR_NO_ERROR) { // CUPS http connect. if ((pHTTP = httpConnectEncrypt(serverName, ippPort(), cupsEncryption())) == NULL) { retVal = ID_ERR_CUPS_API_FAILED; } else { pRequest = ippNew(); ippSetOperation(pRequest, IPP_CANCEL_JOB); ippSetRequestId(pRequest, 1); pLanguage = bjcupsLangDefault(); // cupsLangDefault() -> bjcupsLangDefault() for cups-1.1.19 ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, cupsLangEncoding(pLanguage)); ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, pLanguage->language); ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, printerURI); ippAddInteger(pRequest, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", jobID); ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); if ((pResponse = cupsDoRequest(pHTTP, pRequest, "/jobs/")) != NULL) { if (ippGetStatusCode(pResponse) > IPP_OK_CONFLICT) { retVal = ID_ERR_CUPS_API_FAILED; } ippDelete(pResponse); } else { retVal = ID_ERR_CUPS_API_FAILED; } cupsLangFree(pLanguage); httpClose(pHTTP); } } } return(retVal); }// End removeJob
static int iprint_job_resume(int snum, struct printjob *pjob) { int ret = 1; /* Return value */ http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ cups_lang_t *language = NULL; /* Default language */ char uri[HTTP_MAX_URI]; /* printer-uri attribute */ char httpPath[HTTP_MAX_URI]; /* path portion of the printer-uri */ DEBUG(5,("iprint_job_resume(%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_RELEASE_JOB request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * job-id * requesting-user-name */ request = ippNew(); ippSetOperation(request, IPP_RELEASE_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); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", pjob->sysjob); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, pjob->user); /* * Do the request and get back a response... */ slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", lp_printername(snum)); if ((response = cupsDoRequest(http, request, httpPath)) != NULL) { if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) { DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob, ippErrorString(cupsLastError()))); } else { ret = 0; } } else { DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob, ippErrorString(cupsLastError()))); } out: if (response) ippDelete(response); if (language) cupsLangFree(language); if (http) httpClose(http); return ret; }
/* * Note that this function uses IPP_TAG_JOB, so it is * only suitable for IPP Group 2 attributes. * See RFC 2911. */ void gtk_cups_request_encode_option (GtkCupsRequest *request, const gchar *option, const gchar *value) { ipp_tag_t option_tag; g_return_if_fail (option != NULL); g_return_if_fail (value != NULL); option_tag = _find_option_tag (option); if (option_tag == IPP_TAG_ZERO) { option_tag = IPP_TAG_NAME; if (strcasecmp (value, "true") == 0 || strcasecmp (value, "false") == 0) { option_tag = IPP_TAG_BOOLEAN; } } switch (option_tag) { case IPP_TAG_INTEGER: case IPP_TAG_ENUM: ippAddInteger (request->ipp_request, IPP_TAG_JOB, option_tag, option, strtol (value, NULL, 0)); break; case IPP_TAG_BOOLEAN: { char b; if (strcasecmp (value, "true") == 0 || strcasecmp (value, "on") == 0 || strcasecmp (value, "yes") == 0) b = 1; else b = 0; ippAddBoolean (request->ipp_request, IPP_TAG_JOB, option, b); break; } case IPP_TAG_RANGE: { char *s; int lower; int upper; if (*value == '-') { lower = 1; s = (char *)value; } else lower = strtol (value, &s, 0); if (*s == '-') { if (s[1]) upper = strtol (s + 1, NULL, 0); else upper = 2147483647; } else upper = lower; ippAddRange (request->ipp_request, IPP_TAG_JOB, option, lower, upper); break; } case IPP_TAG_RESOLUTION: { char *s; int xres; int yres; ipp_res_t units; xres = strtol (value, &s, 0); if (*s == 'x') yres = strtol (s + 1, &s, 0); else yres = xres; if (strcasecmp (s, "dpc") == 0) units = IPP_RES_PER_CM; else units = IPP_RES_PER_INCH; ippAddResolution (request->ipp_request, IPP_TAG_JOB, option, units, xres, yres); break; } default: { char *values; char *s; int in_quotes; char *next; GPtrArray *strings; values = g_strdup (value); strings = NULL; in_quotes = 0; for (s = values, next = s; *s != '\0'; s++) { if (in_quotes != 2 && *s == '\'') { /* skip quoted value */ if (in_quotes == 0) in_quotes = 1; else in_quotes = 0; } else if (in_quotes != 1 && *s == '\"') { /* skip quoted value */ if (in_quotes == 0) in_quotes = 2; else in_quotes = 0; } else if (in_quotes == 0 && *s == ',') { /* found delimiter, add to value array */ *s = '\0'; if (strings == NULL) strings = g_ptr_array_new (); g_ptr_array_add (strings, next); next = s + 1; } else if (in_quotes == 0 && *s == '\\' && s[1] != '\0') { /* skip escaped character */ s++; } } if (strings == NULL) { /* single value */ ippAddString (request->ipp_request, IPP_TAG_JOB, option_tag, option, NULL, value); } else { /* multiple values */ /* add last value */ g_ptr_array_add (strings, next); ippAddStrings (request->ipp_request, IPP_TAG_JOB, option_tag, option, strings->len, NULL, (const char **) strings->pdata); g_ptr_array_free (strings, TRUE); } g_free (values); } break; } }
static void get_job_file(const char *job) /* I - Job ID */ { long jobid, /* Job ID */ docnum; /* Document number */ const char *jobptr; /* Pointer into job ID string */ char uri[1024]; /* job-uri */ http_t *http; /* Connection to server */ ipp_t *request; /* Request data */ int tempfd; /* Temporary file */ /* * Get the job ID and document number, if any... */ if ((jobptr = strrchr(job, '-')) != NULL) jobptr ++; else jobptr = job; jobid = strtol(jobptr, (char **)&jobptr, 10); if (*jobptr == ',') docnum = strtol(jobptr + 1, NULL, 10); else docnum = 1; if (jobid < 1 || jobid > INT_MAX) { _cupsLangPrintf(stderr, _("cupsfilter: Invalid job ID %d."), (int)jobid); exit(1); } if (docnum < 1 || docnum > INT_MAX) { _cupsLangPrintf(stderr, _("cupsfilter: Invalid document number %d."), (int)docnum); exit(1); } /* * Ask the server for the document file... */ if ((http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption())) == NULL) { _cupsLangPrintf(stderr, _("%s: Unable to connect to server."), "cupsfilter"); exit(1); } request = ippNewRequest(CUPS_GET_DOCUMENT); snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", (int)jobid); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "document-number", (int)docnum); if ((tempfd = cupsTempFd(TempFile, sizeof(TempFile))) == -1) { _cupsLangPrintError("ERROR", _("Unable to create temporary file")); httpClose(http); exit(1); } signal(SIGTERM, sighandler); ippDelete(cupsDoIORequest(http, request, "/", -1, tempfd)); close(tempfd); httpClose(http); if (cupsLastError() != IPP_OK) { _cupsLangPrintf(stderr, _("cupsfilter: Unable to get job file - %s"), cupsLastErrorString()); unlink(TempFile); exit(1); } }
http_status_t /* O - Status of document creation */ cupsStartDestDocument( http_t *http, /* I - Connection to destination */ cups_dest_t *dest, /* I - Destination */ cups_dinfo_t *info, /* I - Destination information */ int job_id, /* I - Job ID */ const char *docname, /* I - Document name */ const char *format, /* I - Document format */ int num_options, /* I - Number of document options */ cups_option_t *options, /* I - Document options */ int last_document) /* I - 1 if this is the last document */ { ipp_t *request; /* Send-Document request */ http_status_t status; /* HTTP status */ DEBUG_printf(("cupsStartDestDocument(http=%p, dest=%p(%s/%s), info=%p, " "job_id=%d, docname=\"%s\", format=\"%s\", num_options=%d, " "options=%p, last_document=%d)", http, dest, dest ? dest->name : NULL, dest ? dest->instance : NULL, info, job_id, docname, format, num_options, options, last_document)); /* * Range check input... */ if (!http || !dest || !info || job_id <= 0) { _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0); DEBUG_puts("1cupsStartDestDocument: Bad arguments."); return (HTTP_STATUS_ERROR); } /* * Create a Send-Document request... */ if ((request = ippNewRequest(IPP_OP_SEND_DOCUMENT)) == NULL) { _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOMEM), 0); DEBUG_puts("1cupsStartDestDocument: Unable to create Send-Document " "request."); return (HTTP_STATUS_ERROR); } ippSetVersion(request, info->version / 10, info->version % 10); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, info->uri); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", job_id); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); if (docname) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "document-name", NULL, docname); if (format) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", NULL, format); ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", last_document); cupsEncodeOptions2(request, num_options, options, IPP_TAG_OPERATION); cupsEncodeOptions2(request, num_options, options, IPP_TAG_DOCUMENT); /* * Send and delete the request, then return the status... */ status = cupsSendRequest(http, request, info->resource, CUPS_LENGTH_VARIABLE); ippDelete(request); return (status); }
int /* O - 1 on success, 0 on failure */ cupsCancelJob(const char *name, /* I - Name of printer or class */ int job) /* I - Job ID */ { char printer[HTTP_MAX_URI], /* Printer name */ hostname[HTTP_MAX_URI], /* Hostname */ uri[HTTP_MAX_URI]; /* Printer URI */ ipp_t *request, /* IPP request */ *response; /* IPP response */ _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ /* * See if we can connect to the server... */ if (!cups_connect(name, printer, hostname)) { DEBUG_puts("Unable to connect to server!"); return (0); } /* * Create a printer URI... */ if (httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/printers/%s", printer) != HTTP_URI_OK) { _cupsSetError(IPP_INTERNAL_ERROR, NULL); return (0); } /* * Build an IPP_CANCEL_JOB request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * job-id * [requesting-user-name] */ request = ippNewRequest(IPP_CANCEL_JOB); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", job); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); /* * Do the request... */ if ((response = cupsDoRequest(cg->http, request, "/jobs/")) != NULL) ippDelete(response); return (cg->last_error < IPP_REDIRECTION_OTHER_SITE); }
void cgiMoveJobs(http_t *http, /* I - Connection to server */ const char *dest, /* I - Destination or NULL */ int job_id) /* I - Job ID or 0 for all */ { int i; /* Looping var */ const char *user; /* Username */ ipp_t *request, /* IPP request */ *response; /* IPP response */ ipp_attribute_t *attr; /* Current attribute */ const char *name; /* Destination name */ const char *job_printer_uri; /* JOB_PRINTER_URI form variable */ char current_dest[1024]; /* Current destination */ /* * Make sure we have a username... */ if ((user = getenv("REMOTE_USER")) == NULL) { puts("Status: 401\n"); exit(0); } /* * See if the user has already selected a new destination... */ if ((job_printer_uri = cgiGetVariable("JOB_PRINTER_URI")) == NULL) { /* * Make sure necessary form variables are set... */ if (job_id) { char temp[255]; /* Temporary string */ sprintf(temp, "%d", job_id); cgiSetVariable("JOB_ID", temp); } if (dest) cgiSetVariable("PRINTER_NAME", dest); /* * No new destination specified, show the user what the available * printers/classes are... */ if (!dest) { /* * Get the current destination for job N... */ char job_uri[1024]; /* Job URI */ request = ippNewRequest(IPP_GET_JOB_ATTRIBUTES); snprintf(job_uri, sizeof(job_uri), "ipp://localhost/jobs/%d", job_id); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, job_uri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", NULL, "job-printer-uri"); if ((response = cupsDoRequest(http, request, "/")) != NULL) { if ((attr = ippFindAttribute(response, "job-printer-uri", IPP_TAG_URI)) != NULL) { /* * Pull the name from the URI... */ strlcpy(current_dest, strrchr(attr->values[0].string.text, '/') + 1, sizeof(current_dest)); dest = current_dest; } ippDelete(response); } if (!dest) { /* * Couldn't get the current destination... */ cgiStartHTML(cgiText(_("Move Job"))); cgiShowIPPError(_("Unable to find destination for job")); cgiEndHTML(); return; } } /* * Get the list of available destinations... */ request = ippNewRequest(CUPS_GET_PRINTERS); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", NULL, "printer-uri-supported"); if (user) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, user); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, "printer-type", CUPS_PRINTER_LOCAL); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, "printer-type-mask", CUPS_PRINTER_SCANNER); if ((response = cupsDoRequest(http, request, "/")) != NULL) { for (i = 0, attr = ippFindAttribute(response, "printer-uri-supported", IPP_TAG_URI); attr; attr = ippFindNextAttribute(response, "printer-uri-supported", IPP_TAG_URI)) { /* * Pull the name from the URI... */ name = strrchr(attr->values[0].string.text, '/') + 1; /* * If the name is not the same as the current destination, add it! */ if (_cups_strcasecmp(name, dest)) { cgiSetArray("JOB_PRINTER_URI", i, attr->values[0].string.text); cgiSetArray("JOB_PRINTER_NAME", i, name); i ++; } } ippDelete(response); } /* * Show the form... */ if (job_id) cgiStartHTML(cgiText(_("Move Job"))); else cgiStartHTML(cgiText(_("Move All Jobs"))); if (cgiGetSize("JOB_PRINTER_NAME") > 0) cgiCopyTemplateLang("job-move.tmpl"); else { if (job_id) cgiSetVariable("MESSAGE", cgiText(_("Unable to move job"))); else cgiSetVariable("MESSAGE", cgiText(_("Unable to move jobs"))); cgiSetVariable("ERROR", cgiText(_("No destinations added."))); cgiCopyTemplateLang("error.tmpl"); } } else { /* * Try moving the job or jobs... */ char uri[1024], /* Job/printer URI */ resource[1024], /* Post resource */ refresh[1024]; /* Refresh URL */ const char *job_printer_name; /* New printer name */ request = ippNewRequest(CUPS_MOVE_JOB); if (job_id) { /* * Move 1 job... */ snprintf(resource, sizeof(resource), "/jobs/%d", job_id); snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", job_id); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); } else { /* * Move all active jobs on a destination... */ snprintf(resource, sizeof(resource), "/%s/%s", cgiGetVariable("SECTION"), dest); httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", ippPort(), "/%s/%s", cgiGetVariable("SECTION"), dest); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); } ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-printer-uri", NULL, job_printer_uri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, user); ippDelete(cupsDoRequest(http, request, resource)); /* * Show the results... */ job_printer_name = strrchr(job_printer_uri, '/') + 1; if (cupsLastError() <= IPP_OK_CONFLICT) { const char *path = strstr(job_printer_uri, "/printers/"); if (!path) { path = strstr(job_printer_uri, "/classes/"); cgiSetVariable("IS_CLASS", "YES"); } if (path) { cgiFormEncode(uri, path, sizeof(uri)); snprintf(refresh, sizeof(refresh), "2;URL=%s", uri); cgiSetVariable("refresh_page", refresh); } } if (job_id) cgiStartHTML(cgiText(_("Move Job"))); else cgiStartHTML(cgiText(_("Move All Jobs"))); if (cupsLastError() > IPP_OK_CONFLICT) { if (job_id) cgiShowIPPError(_("Unable to move job")); else cgiShowIPPError(_("Unable to move jobs")); } else { cgiSetVariable("JOB_PRINTER_NAME", job_printer_name); cgiCopyTemplateLang("job-moved.tmpl"); } } cgiEndHTML(); }
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; }
ipp_status_t /* O - IPP status */ cupsCancelJob2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ const char *name, /* I - Name of printer or class */ int job_id, /* I - Job ID, @code CUPS_JOBID_CURRENT@ for the current job, or @code CUPS_JOBID_ALL@ for all jobs */ int purge) /* I - 1 to purge, 0 to cancel */ { char uri[HTTP_MAX_URI]; /* Job/printer URI */ ipp_t *request; /* IPP request */ /* * Range check input... */ if (job_id < -1 || (!name && job_id == 0)) { _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0); return (0); } /* * Connect to the default server as needed... */ if (!http) if ((http = _cupsConnect()) == NULL) return (IPP_SERVICE_UNAVAILABLE); /* * Build an IPP_CANCEL_JOB or IPP_PURGE_JOBS request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * job-uri or printer-uri + job-id * requesting-user-name * [purge-job] or [purge-jobs] */ request = ippNewRequest(job_id < 0 ? IPP_PURGE_JOBS : IPP_CANCEL_JOB); if (name) { httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", ippPort(), "/printers/%s", name); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", job_id); } else if (job_id > 0) { snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", job_id); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); } ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); if (purge && job_id >= 0) ippAddBoolean(request, IPP_TAG_OPERATION, "purge-job", 1); else if (!purge && job_id < 0) ippAddBoolean(request, IPP_TAG_OPERATION, "purge-jobs", 0); /* * Do the request... */ ippDelete(cupsDoRequest(http, request, "/jobs/")); return (cupsLastError()); }
ipp_t * /* O - Attributes */ serverLoadAttributes( const char *filename, /* I - File to load */ char **authtype, /* O - Authentication type, if any */ char **command, /* O - Command to run, if any */ char **device_uri, /* O - Device URI, if any */ char **make, /* O - Manufacturer */ char **model, /* O - Model */ char **proxy_user) /* O - Proxy user, if any */ { ipp_t *attrs; /* Attributes to return */ cups_file_t *fp; /* File */ int linenum = 0; /* Current line number */ char attr[128], /* Attribute name */ token[1024], /* Token from file */ *tokenptr; /* Pointer into token */ ipp_tag_t value; /* Current value type */ ipp_attribute_t *attrptr; /* Attribute pointer */ if ((fp = cupsFileOpen(filename, "r")) == NULL) { serverLog(SERVER_LOGLEVEL_ERROR, "Unable to open \"%s\": %s", filename, strerror(errno)); return (NULL); } attrs = ippNew(); while (get_token(fp, token, sizeof(token), &linenum) != NULL) { if (!_cups_strcasecmp(token, "ATTR")) { /* * Attribute... */ if (!get_token(fp, token, sizeof(token), &linenum)) { serverLog(SERVER_LOGLEVEL_ERROR, "Missing ATTR value tag on line %d of \"%s\".", linenum, filename); goto load_error; } if ((value = ippTagValue(token)) == IPP_TAG_ZERO) { serverLog(SERVER_LOGLEVEL_ERROR, "Bad ATTR value tag \"%s\" on line %d of \"%s\".", token, linenum, filename); goto load_error; } if (!get_token(fp, attr, sizeof(attr), &linenum)) { serverLog(SERVER_LOGLEVEL_ERROR, "Missing ATTR name on line %d of \"%s\".", linenum, filename); goto load_error; } if (!get_token(fp, token, sizeof(token), &linenum)) { serverLog(SERVER_LOGLEVEL_ERROR, "Missing ATTR value on line %d of \"%s\".", linenum, filename); goto load_error; } attrptr = NULL; switch (value) { case IPP_TAG_BOOLEAN : if (!_cups_strcasecmp(token, "true")) attrptr = ippAddBoolean(attrs, IPP_TAG_PRINTER, attr, 1); else attrptr = ippAddBoolean(attrs, IPP_TAG_PRINTER, attr, (char)atoi(token)); break; case IPP_TAG_INTEGER : case IPP_TAG_ENUM : if (!strchr(token, ',')) attrptr = ippAddInteger(attrs, IPP_TAG_PRINTER, value, attr, (int)strtol(token, &tokenptr, 0)); else { int values[100], /* Values */ num_values = 1; /* Number of values */ values[0] = (int)strtol(token, &tokenptr, 10); while (tokenptr && *tokenptr && num_values < (int)(sizeof(values) / sizeof(values[0]))) { if (*tokenptr == ',') tokenptr ++; else if (!isdigit(*tokenptr & 255) && *tokenptr != '-') break; values[num_values] = (int)strtol(tokenptr, &tokenptr, 0); num_values ++; } attrptr = ippAddIntegers(attrs, IPP_TAG_PRINTER, value, attr, num_values, values); } if (!tokenptr || *tokenptr) { serverLog(SERVER_LOGLEVEL_ERROR, "Bad %s value \"%s\" on line %d of \"%s\".", ippTagString(value), token, linenum, filename); goto load_error; } break; case IPP_TAG_RESOLUTION : { int xres, /* X resolution */ yres; /* Y resolution */ ipp_res_t units; /* Units */ char *start, /* Start of value */ *ptr, /* Pointer into value */ *next = NULL; /* Next value */ for (start = token; start; start = next) { xres = yres = (int)strtol(start, (char **)&ptr, 10); if (ptr > start && xres > 0) { if (*ptr == 'x') yres = (int)strtol(ptr + 1, (char **)&ptr, 10); } if (ptr && (next = strchr(ptr, ',')) != NULL) *next++ = '\0'; if (ptr <= start || xres <= 0 || yres <= 0 || !ptr || (_cups_strcasecmp(ptr, "dpi") && _cups_strcasecmp(ptr, "dpc") && _cups_strcasecmp(ptr, "dpcm") && _cups_strcasecmp(ptr, "other"))) { serverLog(SERVER_LOGLEVEL_ERROR, "Bad resolution value \"%s\" on line %d of \"%s\".", token, linenum, filename); goto load_error; } if (!_cups_strcasecmp(ptr, "dpc") || !_cups_strcasecmp(ptr, "dpcm")) units = IPP_RES_PER_CM; else units = IPP_RES_PER_INCH; if (attrptr) ippSetResolution(attrs, &attrptr, ippGetCount(attrptr), units, xres, yres); else attrptr = ippAddResolution(attrs, IPP_TAG_PRINTER, attr, units, xres, yres); } } break; case IPP_TAG_RANGE : { int lowers[4], /* Lower value */ uppers[4], /* Upper values */ num_vals; /* Number of values */ num_vals = sscanf(token, "%d-%d,%d-%d,%d-%d,%d-%d", lowers + 0, uppers + 0, lowers + 1, uppers + 1, lowers + 2, uppers + 2, lowers + 3, uppers + 3); if ((num_vals & 1) || num_vals == 0) { serverLog(SERVER_LOGLEVEL_ERROR, "Bad rangeOfInteger value \"%s\" on line %d of \"%s\".", token, linenum, filename); goto load_error; } attrptr = ippAddRanges(attrs, IPP_TAG_PRINTER, attr, num_vals / 2, lowers, uppers); } break; case IPP_TAG_BEGIN_COLLECTION : if (!strcmp(token, "{")) { ipp_t *col = get_collection(fp, filename, &linenum); /* Collection value */ if (col) { attrptr = ippAddCollection(attrs, IPP_TAG_PRINTER, attr, col); ippDelete(col); } else exit(1); } else { serverLog(SERVER_LOGLEVEL_ERROR, "Bad ATTR collection value on line %d of \"%s\".", linenum, filename); goto load_error; } do { ipp_t *col; /* Collection value */ long pos = cupsFileTell(fp); /* Save position of file */ if (!get_token(fp, token, sizeof(token), &linenum)) break; if (strcmp(token, ",")) { cupsFileSeek(fp, pos); break; } if (!get_token(fp, token, sizeof(token), &linenum) || strcmp(token, "{")) { serverLog(SERVER_LOGLEVEL_ERROR, "Unexpected \"%s\" on line %d of \"%s\".", token, linenum, filename); goto load_error; } if ((col = get_collection(fp, filename, &linenum)) == NULL) break; ippSetCollection(attrs, &attrptr, ippGetCount(attrptr), col); } while (!strcmp(token, "{")); break; case IPP_TAG_STRING : attrptr = ippAddOctetString(attrs, IPP_TAG_PRINTER, attr, token, (int)strlen(token)); break; default : serverLog(SERVER_LOGLEVEL_ERROR, "Unsupported ATTR value tag %s on line %d of \"%s\".", ippTagString(value), linenum, filename); goto load_error; 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 : if (!strchr(token, ',')) attrptr = ippAddString(attrs, IPP_TAG_PRINTER, value, attr, NULL, token); else { /* * Multiple string values... */ int num_values; /* Number of values */ char *values[100], /* Values */ *ptr; /* Pointer to next value */ values[0] = token; num_values = 1; for (ptr = strchr(token, ','); ptr; ptr = strchr(ptr, ',')) { if (ptr > token && ptr[-1] == '\\') _cups_strcpy(ptr - 1, ptr); else { *ptr++ = '\0'; values[num_values] = ptr; num_values ++; if (num_values >= (int)(sizeof(values) / sizeof(values[0]))) break; } } attrptr = ippAddStrings(attrs, IPP_TAG_PRINTER, value, attr, num_values, NULL, (const char **)values); } break; } if (!attrptr) { serverLog(SERVER_LOGLEVEL_ERROR, "Unable to add attribute on line %d of \"%s\": %s", linenum, filename, cupsLastErrorString()); goto load_error; } } else if (!_cups_strcasecmp(token, "AUTHTYPE") && authtype) { if (!get_token(fp, token, sizeof(token), &linenum)) { serverLog(SERVER_LOGLEVEL_ERROR, "Missing AUTHTYPE value on line %d of \"%s\".", linenum, filename); goto load_error; } *authtype = strdup(token); } else if (!_cups_strcasecmp(token, "COMMAND") && command) { if (!get_token(fp, token, sizeof(token), &linenum)) { serverLog(SERVER_LOGLEVEL_ERROR, "Missing COMMAND value on line %d of \"%s\".", linenum, filename); goto load_error; } *command = strdup(token); } else if (!_cups_strcasecmp(token, "DEVICEURI") && device_uri) { if (!get_token(fp, token, sizeof(token), &linenum)) { serverLog(SERVER_LOGLEVEL_ERROR, "Missing DEVICE-URI value on line %d of \"%s\".", linenum, filename); goto load_error; } *device_uri = strdup(token); } else if (!_cups_strcasecmp(token, "MAKE") && make) { if (!get_token(fp, token, sizeof(token), &linenum)) { serverLog(SERVER_LOGLEVEL_ERROR, "Missing MAKE value on line %d of \"%s\".", linenum, filename); goto load_error; } *make = strdup(token); } else if (!_cups_strcasecmp(token, "MODEL") && model) { if (!get_token(fp, token, sizeof(token), &linenum)) { serverLog(SERVER_LOGLEVEL_ERROR, "Missing MODEL value on line %d of \"%s\".", linenum, filename); goto load_error; } *model = strdup(token); } else if (!_cups_strcasecmp(token, "PROXYUSER") && proxy_user) { if (!get_token(fp, token, sizeof(token), &linenum)) { serverLog(SERVER_LOGLEVEL_ERROR, "Missing PROXY-USER value on line %d of \"%s\".", linenum, filename); goto load_error; } *proxy_user = strdup(token); } else { serverLog(SERVER_LOGLEVEL_ERROR, "Unknown directive \"%s\" on line %d of \"%s\".", token, linenum, filename); goto load_error; } } cupsFileClose(fp); return (attrs); /* * If we get here something bad happened... */ load_error: cupsFileClose(fp); ippDelete(attrs); return (NULL); }
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); }
static void show_all_printers(http_t *http, /* I - Connection to server */ const char *user) /* I - Username */ { int i; /* Looping var */ ipp_t *request, /* IPP request */ *response; /* IPP response */ cups_array_t *printers; /* Array of printer objects */ ipp_attribute_t *printer; /* Printer object */ int ascending, /* Order of printers (0 = descending) */ first, /* First printer to show */ count; /* Number of printers */ const char *var; /* Form variable */ void *search; /* Search data */ char val[1024]; /* Form variable */ fprintf(stderr, "DEBUG: show_all_printers(http=%p, user=\"%s\")\n", http, user ? user : "******"); /* * Show the standard header... */ cgiStartHTML(cgiText(_("Printers"))); /* * Build a CUPS_GET_PRINTERS request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-type * printer-type-mask * requesting-user-name */ request = ippNewRequest(CUPS_GET_PRINTERS); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, "printer-type", 0); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, "printer-type-mask", CUPS_PRINTER_CLASS); if (user) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, user); cgiGetAttributes(request, "printers.tmpl"); /* * Do the request and get back a response... */ if ((response = cupsDoRequest(http, request, "/")) != NULL) { /* * Get a list of matching job objects. */ if ((var = cgiGetVariable("QUERY")) != NULL && !cgiGetVariable("CLEAR")) search = cgiCompileSearch(var); else search = NULL; printers = cgiGetIPPObjects(response, search); count = cupsArrayCount(printers); if (search) cgiFreeSearch(search); /* * Figure out which printers to display... */ if ((var = cgiGetVariable("FIRST")) != NULL) first = atoi(var); else first = 0; if (first >= count) first = count - CUPS_PAGE_MAX; first = (first / CUPS_PAGE_MAX) * CUPS_PAGE_MAX; if (first < 0) first = 0; sprintf(val, "%d", count); cgiSetVariable("TOTAL", val); if ((var = cgiGetVariable("ORDER")) != NULL && *var) ascending = !_cups_strcasecmp(var, "asc"); else ascending = 1; if (ascending) { for (i = 0, printer = (ipp_attribute_t *)cupsArrayIndex(printers, first); i < CUPS_PAGE_MAX && printer; i ++, printer = (ipp_attribute_t *)cupsArrayNext(printers)) cgiSetIPPObjectVars(printer, NULL, i); } else { for (i = 0, printer = (ipp_attribute_t *)cupsArrayIndex(printers, count - first - 1); i < CUPS_PAGE_MAX && printer; i ++, printer = (ipp_attribute_t *)cupsArrayPrev(printers)) cgiSetIPPObjectVars(printer, NULL, i); } /* * Save navigation URLs... */ cgiSetVariable("THISURL", "/printers/"); if (first > 0) { sprintf(val, "%d", first - CUPS_PAGE_MAX); cgiSetVariable("PREV", val); } if ((first + CUPS_PAGE_MAX) < count) { sprintf(val, "%d", first + CUPS_PAGE_MAX); cgiSetVariable("NEXT", val); } /* * Then show everything... */ cgiCopyTemplateLang("search.tmpl"); cgiCopyTemplateLang("printers-header.tmpl"); if (count > CUPS_PAGE_MAX) cgiCopyTemplateLang("pager.tmpl"); cgiCopyTemplateLang("printers.tmpl"); if (count > CUPS_PAGE_MAX) cgiCopyTemplateLang("pager.tmpl"); /* * Delete the response... */ cupsArrayDelete(printers); ippDelete(response); } else { /* * Show the error... */ cgiShowIPPError(_("Unable to get printer list")); } cgiEndHTML(); }
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); }
int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { http_t *http; /* HTTP connection to server */ int i; /* Looping var */ int job_id; /* Job ID */ int num_dests; /* Number of destinations */ cups_dest_t *dests; /* Destinations */ char *dest, /* Destination printer */ *job, /* Job ID pointer */ *user; /* Cancel jobs for a user */ int purge; /* Purge or cancel jobs? */ char uri[1024]; /* Printer or job URI */ ipp_t *request; /* IPP request */ ipp_t *response; /* IPP response */ ipp_op_t op; /* Operation */ _cupsSetLocale(argv); /* * Setup to cancel individual print jobs... */ op = IPP_CANCEL_JOB; purge = 0; dest = NULL; user = NULL; http = NULL; num_dests = 0; dests = NULL; /* * Process command-line arguments... */ for (i = 1; i < argc; i ++) if (argv[i][0] == '-' && argv[i][1]) switch (argv[i][1]) { case 'E' : /* Encrypt */ #ifdef HAVE_SSL cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); if (http) httpEncryption(http, HTTP_ENCRYPT_REQUIRED); #else _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support compiled in!\n"), argv[0]); #endif /* HAVE_SSL */ break; case 'U' : /* Username */ if (argv[i][2] != '\0') cupsSetUser(argv[i] + 2); else { i ++; if (i >= argc) { _cupsLangPrintf(stderr, _("%s: Error - expected username after " "\'-U\' option!\n"), argv[0]); return (1); } cupsSetUser(argv[i]); } break; case 'a' : /* Cancel all jobs */ purge = 1; op = IPP_PURGE_JOBS; break; case 'h' : /* Connect to host */ if (http != NULL) { httpClose(http); http = NULL; } if (argv[i][2] != '\0') cupsSetServer(argv[i] + 2); else { i ++; if (i >= argc) { _cupsLangPrintf(stderr, _("%s: Error - expected hostname after " "\'-h\' option!\n"), argv[0]); return (1); } else cupsSetServer(argv[i]); } break; case 'u' : /* Username */ op = IPP_PURGE_JOBS; if (argv[i][2] != '\0') user = argv[i] + 2; else { i ++; if (i >= argc) { _cupsLangPrintf(stderr, _("%s: Error - expected username after " "\'-u\' option!\n"), argv[0]); return (1); } else user = argv[i]; } break; default : _cupsLangPrintf(stderr, _("%s: Error - unknown option \'%c\'!\n"), argv[0], argv[i][1]); return (1); } else { /* * Cancel a job or printer... */ if (num_dests == 0) num_dests = cupsGetDests(&dests); if (!strcmp(argv[i], "-")) { /* * Delete the current job... */ dest = ""; job_id = 0; } else if (cupsGetDest(argv[i], NULL, num_dests, dests) != NULL) { /* * Delete the current job on the named destination... */ dest = argv[i]; job_id = 0; } else if ((job = strrchr(argv[i], '-')) != NULL && isdigit(job[1] & 255)) { /* * Delete the specified job ID. */ dest = NULL; op = IPP_CANCEL_JOB; job_id = atoi(job + 1); } else if (isdigit(argv[i][0] & 255)) { /* * Delete the specified job ID. */ dest = NULL; op = IPP_CANCEL_JOB; job_id = atoi(argv[i]); } else { /* * Bad printer name! */ _cupsLangPrintf(stderr, _("%s: Error - unknown destination \"%s\"!\n"), argv[0], argv[i]); return (1); } /* * For Solaris LP compatibility, ignore a destination name after * cancelling a specific job ID... */ if (job_id && (i + 1) < argc && cupsGetDest(argv[i + 1], NULL, num_dests, dests) != NULL) i ++; /* * Open a connection to the server... */ if (http == NULL) if ((http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption())) == NULL) { _cupsLangPrintf(stderr, _("%s: Unable to contact server!\n"), argv[0]); return (1); } /* * Build an IPP request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri + job-id *or* job-uri * [requesting-user-name] */ request = ippNewRequest(op); if (dest) { httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/printers/%s", dest); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", job_id); } else { sprintf(uri, "ipp://localhost/jobs/%d", job_id); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); } if (user) { ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, user); ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1); } else ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); if (op == IPP_PURGE_JOBS) ippAddBoolean(request, IPP_TAG_OPERATION, "purge-jobs", purge); /* * Do the request and get back a response... */ if (op == IPP_PURGE_JOBS && (!user || strcasecmp(user, cupsUser()))) response = cupsDoRequest(http, request, "/admin/"); else response = cupsDoRequest(http, request, "/jobs/"); if (response == NULL || response->request.status.status_code > IPP_OK_CONFLICT) { _cupsLangPrintf(stderr, _("%s: %s failed: %s\n"), argv[0], op == IPP_PURGE_JOBS ? "purge-jobs" : "cancel-job", cupsLastErrorString()); if (response) ippDelete(response); return (1); } ippDelete(response); } if (num_dests == 0 && op == IPP_PURGE_JOBS) { /* * Open a connection to the server... */ if (http == NULL) if ((http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption())) == NULL) { _cupsLangPrintf(stderr, _("%s: Unable to contact server!\n"), argv[0]); return (1); } /* * Build an IPP request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri + job-id *or* job-uri * [requesting-user-name] */ request = ippNewRequest(op); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, "ipp://localhost/printers/"); if (user) { ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, user); ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1); } else ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); ippAddBoolean(request, IPP_TAG_OPERATION, "purge-jobs", purge); /* * Do the request and get back a response... */ response = cupsDoRequest(http, request, "/admin/"); if (response == NULL || response->request.status.status_code > IPP_OK_CONFLICT) { _cupsLangPrintf(stderr, _("%s: %s failed: %s\n"), argv[0], op == IPP_PURGE_JOBS ? "purge-jobs" : "cancel-job", cupsLastErrorString()); if (response) ippDelete(response); return (1); } ippDelete(response); } return (0); }
int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { http_t *http; /* HTTP connection to server */ int i; /* Looping var */ int job_id; /* Job ID */ const char *dest; /* Destination printer */ char *instance; /* Pointer to instance name */ char uri[1024]; /* Printer or job URI */ ipp_t *request; /* IPP request */ ipp_t *response; /* IPP response */ ipp_op_t op; /* Operation */ int num_dests; /* Number of destinations */ cups_dest_t *dests, /* Destinations */ *defdest; /* Default destination */ http_encryption_t encryption; /* Encryption? */ _cupsSetLocale(argv); /* * Setup to cancel individual print jobs... */ op = IPP_CANCEL_JOB; job_id = 0; dest = NULL; response = NULL; http = NULL; encryption = cupsEncryption(); /* * Open a connection to the server... */ if ((http = httpConnectEncrypt(cupsServer(), ippPort(), encryption)) == NULL) { _cupsLangPuts(stderr, _("lprm: Unable to contact server!\n")); return (1); } num_dests = cupsGetDests2(http, &dests); defdest = cupsGetDest(NULL, NULL, num_dests, dests); dest = defdest ? defdest->name : NULL; /* * Process command-line arguments... */ for (i = 1; i < argc; i ++) if (argv[i][0] == '-' && argv[i][1] != '\0') switch (argv[i][1]) { case 'E' : /* Encrypt */ #ifdef HAVE_SSL encryption = HTTP_ENCRYPT_REQUIRED; httpEncryption(http, encryption); cupsSetEncryption(encryption); #else _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support compiled in!\n"), argv[0]); #endif /* HAVE_SSL */ break; case 'P' : /* Cancel jobs on a printer */ if (argv[i][2]) dest = argv[i] + 2; else { i ++; dest = argv[i]; } if ((instance = strchr(dest, '/')) != NULL) *instance = '\0'; if (cupsGetDest(dest, NULL, num_dests, dests) == NULL) { _cupsLangPrintf(stderr, _("%s: Error - unknown destination \"%s\"!\n"), argv[0], dest); cupsFreeDests(num_dests, dests); httpClose(http); return(1); } break; case 'U' : /* Username */ if (argv[i][2] != '\0') cupsSetUser(argv[i] + 2); else { i ++; if (i >= argc) { _cupsLangPrintf(stderr, _("%s: Error - expected username after " "\'-U\' option!\n"), argv[0]); return (1); } cupsSetUser(argv[i]); } break; case 'h' : /* Connect to host */ if (argv[i][2] != '\0') cupsSetServer(argv[i] + 2); else { i ++; if (i >= argc) { _cupsLangPrintf(stderr, _("%s: Error - expected hostname after " "\'-h\' option!\n"), argv[0]); return (1); } else cupsSetServer(argv[i]); } httpClose(http); cupsFreeDests(num_dests, dests); if ((http = httpConnectEncrypt(cupsServer(), ippPort(), encryption)) == NULL) { _cupsLangPuts(stderr, _("lprm: Unable to contact server!\n")); return (1); } num_dests = cupsGetDests2(http, &dests); defdest = cupsGetDest(NULL, NULL, num_dests, dests); dest = defdest ? defdest->name : NULL; break; default : _cupsLangPrintf(stderr, _("%s: Error - unknown option \'%c\'!\n"), argv[0], argv[i][1]); cupsFreeDests(num_dests, dests); httpClose(http); return (1); } else { /* * Cancel a job or printer... */ if (isdigit(argv[i][0] & 255) && cupsGetDest(argv[i], NULL, num_dests, dests) == NULL) { dest = NULL; op = IPP_CANCEL_JOB; job_id = atoi(argv[i]); } else if (!strcmp(argv[i], "-")) { /* * Cancel all jobs */ op = IPP_PURGE_JOBS; } else { dest = argv[i]; job_id = 0; } /* * Build an IPP request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri + job-id *or* job-uri * [requesting-user-name] */ request = ippNewRequest(op); if (dest) { httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/printers/%s", dest); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", job_id); } else { sprintf(uri, "ipp://localhost/jobs/%d", job_id); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); } ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); /* * Do the request and get back a response... */ if (op == IPP_PURGE_JOBS) response = cupsDoRequest(http, request, "/admin/"); else response = cupsDoRequest(http, request, "/jobs/"); ippDelete(response); if (cupsLastError() > IPP_OK_CONFLICT) { _cupsLangPrintf(stderr, "%s: %s\n", argv[0], cupsLastErrorString()); cupsFreeDests(num_dests, dests); httpClose(http); return (1); } } /* * If nothing has been canceled yet, cancel the current job on the specified * (or default) printer... */ if (response == NULL) if (!cupsCancelJob(dest, 0)) { _cupsLangPrintf(stderr, "%s: %s\n", argv[0], cupsLastErrorString()); cupsFreeDests(num_dests, dests); httpClose(http); return (1); } cupsFreeDests(num_dests, dests); httpClose(http); return (0); }
int /* O - Number of printers */ cupsGetPrinters(char ***printers) /* O - Printers */ { int n; /* Number of printers */ ipp_t *request, /* IPP Request */ *response; /* IPP Response */ ipp_attribute_t *attr; /* Current attribute */ char **temp; /* Temporary pointer */ _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ if (printers == NULL) { _cupsSetError(IPP_INTERNAL_ERROR, NULL); return (0); } /* * Try to connect to the server... */ if (!cups_connect("default", NULL, NULL)) { DEBUG_puts("Unable to connect to server!"); return (0); } /* * Build a CUPS_GET_PRINTERS request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * requested-attributes */ request = ippNewRequest(CUPS_GET_PRINTERS); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", NULL, "printer-name"); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, "printer-type", 0); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, "printer-type-mask", CUPS_PRINTER_CLASS); /* * Do the request and get back a response... */ n = 0; *printers = NULL; if ((response = cupsDoRequest(cg->http, request, "/")) != NULL) { for (attr = response->attrs; attr != NULL; attr = attr->next) if (attr->name != NULL && strcasecmp(attr->name, "printer-name") == 0 && attr->value_tag == IPP_TAG_NAME) { if (n == 0) temp = malloc(sizeof(char *)); else temp = realloc(*printers, sizeof(char *) * (n + 1)); if (temp == NULL) { /* * Ran out of memory! */ while (n > 0) { n --; free((*printers)[n]); } free(*printers); ippDelete(response); return (0); } *printers = temp; temp[n] = strdup(attr->values[0].string.text); n ++; } ippDelete(response); } return (n); }
int main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { int i; /* Looping var */ const char *uri; /* URI to use */ int num_events; /* Number of events */ const char *events[100]; /* Events */ int subscription_id, /* notify-subscription-id */ sequence_number, /* notify-sequence-number */ interval; /* Interval between polls */ http_t *http; /* HTTP connection */ ipp_t *request, /* IPP request */ *response; /* IPP response */ ipp_attribute_t *attr; /* Current attribute */ #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) struct sigaction action; /* Actions for POSIX signals */ #endif /* HAVE_SIGACTION && !HAVE_SIGSET */ /* * Parse command-line... */ num_events = 0; uri = NULL; for (i = 1; i < argc; i ++) if (!strcmp(argv[i], "-E")) cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); else if (!strcmp(argv[i], "-e")) { i ++; if (i >= argc || num_events >= 100) usage(); events[num_events] = argv[i]; num_events ++; } else if (!strcmp(argv[i], "-h")) { i ++; if (i >= argc) usage(); cupsSetServer(argv[i]); } else if (uri || strncmp(argv[i], "ipp://", 6)) usage(); else uri = argv[i]; if (!uri) usage(); if (num_events == 0) { events[0] = "all"; num_events = 1; } /* * Connect to the server... */ if ((http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption())) == NULL) { perror(cupsServer()); return (1); } /* * Catch CTRL-C and SIGTERM... */ #ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */ sigset(SIGINT, sigterm_handler); sigset(SIGTERM, sigterm_handler); #elif defined(HAVE_SIGACTION) memset(&action, 0, sizeof(action)); sigemptyset(&action.sa_mask); action.sa_handler = sigterm_handler; sigaction(SIGINT, &action, NULL); sigaction(SIGTERM, &action, NULL); #else signal(SIGINT, sigterm_handler); signal(SIGTERM, sigterm_handler); #endif /* HAVE_SIGSET */ /* * Create the subscription... */ if (strstr(uri, "/jobs/")) { request = ippNewRequest(IPP_CREATE_JOB_SUBSCRIPTION); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); } else { request = ippNewRequest(IPP_CREATE_PRINTER_SUBSCRIPTION); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); } ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); ippAddStrings(request, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD, "notify-events", num_events, NULL, events); ippAddString(request, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD, "notify-pull-method", NULL, "ippget"); response = cupsDoRequest(http, request, uri); if (cupsLastError() >= IPP_BAD_REQUEST) { fprintf(stderr, "Create-%s-Subscription: %s\n", strstr(uri, "/jobs") ? "Job" : "Printer", cupsLastErrorString()); ippDelete(response); httpClose(http); return (1); } if ((attr = ippFindAttribute(response, "notify-subscription-id", IPP_TAG_INTEGER)) == NULL) { fputs("ERROR: No notify-subscription-id in response!\n", stderr); ippDelete(response); httpClose(http); return (1); } subscription_id = attr->values[0].integer; printf("Create-%s-Subscription: notify-subscription-id=%d\n", strstr(uri, "/jobs/") ? "Job" : "Printer", subscription_id); ippDelete(response); /* * Monitor for events... */ sequence_number = 0; while (!terminate) { /* * Get the current events... */ printf("\nGet-Notifications(%d,%d):", subscription_id, sequence_number); fflush(stdout); request = ippNewRequest(IPP_GET_NOTIFICATIONS); if (strstr(uri, "/jobs/")) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); else ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "notify-subscription-ids", subscription_id); if (sequence_number) ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "notify-sequence-numbers", sequence_number + 1); response = cupsDoRequest(http, request, uri); printf(" %s\n", ippErrorString(cupsLastError())); if (cupsLastError() >= IPP_BAD_REQUEST) fprintf(stderr, "Get-Notifications: %s\n", cupsLastErrorString()); else if (response) { print_attributes(response, 0); for (attr = ippFindAttribute(response, "notify-sequence-number", IPP_TAG_INTEGER); attr; attr = ippFindNextAttribute(response, "notify-sequence-number", IPP_TAG_INTEGER)) if (attr->values[0].integer > sequence_number) sequence_number = attr->values[0].integer; } if ((attr = ippFindAttribute(response, "notify-get-interval", IPP_TAG_INTEGER)) != NULL && attr->values[0].integer > 0) interval = attr->values[0].integer; else interval = 5; ippDelete(response); sleep(interval); } /* * Cancel the subscription... */ printf("\nCancel-Subscription:"); fflush(stdout); request = ippNewRequest(IPP_CANCEL_SUBSCRIPTION); if (strstr(uri, "/jobs/")) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); else ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); 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_id); ippDelete(cupsDoRequest(http, request, uri)); printf(" %s\n", ippErrorString(cupsLastError())); if (cupsLastError() >= IPP_BAD_REQUEST) fprintf(stderr, "Cancel-Subscription: %s\n", cupsLastErrorString()); /* * Close the connection and return... */ httpClose(http); return (0); }
void cupsdAddEvent( cupsd_eventmask_t event, /* I - Event */ cupsd_printer_t *dest, /* I - Printer associated with event */ cupsd_job_t *job, /* I - Job associated with event */ const char *text, /* I - Notification text */ ...) /* I - Additional arguments as needed */ { va_list ap; /* Pointer to additional arguments */ char ftext[1024]; /* Formatted text buffer */ ipp_attribute_t *attr; /* Printer/job attribute */ cupsd_event_t *temp; /* New event pointer */ cupsd_subscription_t *sub; /* Current subscription */ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddEvent(event=%s, dest=%p(%s), job=%p(%d), text=\"%s\", ...)", cupsdEventName(event), dest, dest ? dest->name : "", job, job ? job->id : 0, text); /* * Keep track of events with any OS-supplied notification mechanisms... */ LastEvent |= event; #ifdef HAVE_DBUS cupsd_send_dbus(event, dest, job); #endif /* HAVE_DBUS */ /* * Return if we aren't keeping events... */ if (MaxEvents <= 0) { cupsdLogMessage(CUPSD_LOG_WARN, "cupsdAddEvent: Discarding %s event since MaxEvents is %d!", cupsdEventName(event), MaxEvents); return; } /* * Then loop through the subscriptions and add the event to the corresponding * caches... */ for (temp = NULL, sub = (cupsd_subscription_t *)cupsArrayFirst(Subscriptions); sub; sub = (cupsd_subscription_t *)cupsArrayNext(Subscriptions)) { /* * Check if this subscription requires this event... */ if ((sub->mask & event) != 0 && (sub->dest == dest || !sub->dest) && (sub->job == job || !sub->job)) { /* * Need this event, so create a new event record... */ if ((temp = (cupsd_event_t *)calloc(1, sizeof(cupsd_event_t))) == NULL) { cupsdLogMessage(CUPSD_LOG_CRIT, "Unable to allocate memory for event - %s", strerror(errno)); return; } temp->event = event; temp->time = time(NULL); temp->attrs = ippNew(); temp->job = job; if (dest) temp->dest = dest; else if (job) temp->dest = dest = cupsdFindPrinter(job->dest); /* * Add common event notification attributes... */ ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_CHARSET, "notify-charset", NULL, "utf-8"); ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_LANGUAGE, "notify-natural-language", NULL, "en-US"); ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_INTEGER, "notify-subscription-id", sub->id); ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_INTEGER, "notify-sequence-number", sub->next_event_id); ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_KEYWORD, "notify-subscribed-event", NULL, cupsdEventName(event)); if (sub->user_data_len > 0) ippAddOctetString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, "notify-user-data", sub->user_data, sub->user_data_len); ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_INTEGER, "printer-up-time", time(NULL)); va_start(ap, text); vsnprintf(ftext, sizeof(ftext), text, ap); va_end(ap); ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_TEXT, "notify-text", NULL, ftext); if (dest) { /* * Add printer attributes... */ ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_URI, "notify-printer-uri", NULL, dest->uri); ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_NAME, "printer-name", NULL, dest->name); ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_ENUM, "printer-state", dest->state); if (dest->num_reasons == 0) ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_KEYWORD, "printer-state-reasons", NULL, dest->state == IPP_PRINTER_STOPPED ? "paused" : "none"); else ippAddStrings(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_KEYWORD, "printer-state-reasons", dest->num_reasons, NULL, (const char * const *)dest->reasons); ippAddBoolean(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, "printer-is-accepting-jobs", (char)dest->accepting); } if (job) { /* * Add job attributes... */ ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_INTEGER, "notify-job-id", job->id); ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_ENUM, "job-state", job->state_value); if ((attr = ippFindAttribute(job->attrs, "job-name", IPP_TAG_NAME)) != NULL) ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_NAME, "job-name", NULL, attr->values[0].string.text); switch (job->state_value) { case IPP_JOB_PENDING : if (dest && dest->state == IPP_PRINTER_STOPPED) ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_KEYWORD, "job-state-reasons", NULL, "printer-stopped"); else ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_KEYWORD, "job-state-reasons", NULL, "none"); break; case IPP_JOB_HELD : if (ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_KEYWORD) != NULL || ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME) != NULL) ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_KEYWORD, "job-state-reasons", NULL, "job-hold-until-specified"); else ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_KEYWORD, "job-state-reasons", NULL, "job-incoming"); break; case IPP_JOB_PROCESSING : ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_KEYWORD, "job-state-reasons", NULL, "job-printing"); break; case IPP_JOB_STOPPED : ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_KEYWORD, "job-state-reasons", NULL, "job-stopped"); break; case IPP_JOB_CANCELED : ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_KEYWORD, "job-state-reasons", NULL, "job-canceled-by-user"); break; case IPP_JOB_ABORTED : ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_KEYWORD, "job-state-reasons", NULL, "aborted-by-system"); break; case IPP_JOB_COMPLETED : ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_KEYWORD, "job-state-reasons", NULL, "job-completed-successfully"); break; } ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_INTEGER, "job-impressions-completed", job->sheets ? job->sheets->values[0].integer : 0); } /* * Send the notification for this subscription... */ cupsd_send_notification(sub, temp); } } if (temp) cupsdMarkDirty(CUPSD_DIRTY_SUBSCRIPTIONS); else cupsdLogMessage(CUPSD_LOG_DEBUG, "Discarding unused %s event...", cupsdEventName(event)); }
static ipp_t * /* O - Collection value */ get_collection(cups_file_t *fp, /* I - File to read from */ const char *filename, /* I - Attributes filename */ int *linenum) /* IO - Line number */ { char token[1024], /* Token from file */ attr[128]; /* Attribute name */ ipp_tag_t value; /* Current value type */ ipp_t *col = ippNew(); /* Collection value */ ipp_attribute_t *lastcol = NULL; /* Last collection attribute */ while (get_token(fp, token, sizeof(token), linenum) != NULL) { if (!strcmp(token, "}")) break; else if (!strcmp(token, "{") && lastcol) { /* * Another collection value */ ipp_t *subcol = get_collection(fp, filename, linenum); /* Collection value */ if (subcol) ippSetCollection(col, &lastcol, ippGetCount(lastcol), subcol); else goto col_error; } else if (!_cups_strcasecmp(token, "MEMBER")) { /* * Attribute... */ lastcol = NULL; if (!get_token(fp, token, sizeof(token), linenum)) { fprintf(stderr, "ippserver: Missing MEMBER value tag on line %d of \"%s\".\n", *linenum, filename); goto col_error; } if ((value = ippTagValue(token)) == IPP_TAG_ZERO) { fprintf(stderr, "ippserver: Bad MEMBER value tag \"%s\" on line %d of \"%s\".\n", token, *linenum, filename); goto col_error; } if (!get_token(fp, attr, sizeof(attr), linenum)) { fprintf(stderr, "ippserver: Missing MEMBER name on line %d of \"%s\".\n", *linenum, filename); goto col_error; } if (!get_token(fp, token, sizeof(token), linenum)) { fprintf(stderr, "ippserver: Missing MEMBER value on line %d of \"%s\".\n", *linenum, filename); goto col_error; } switch (value) { case IPP_TAG_BOOLEAN : if (!_cups_strcasecmp(token, "true")) ippAddBoolean(col, IPP_TAG_ZERO, attr, 1); else ippAddBoolean(col, IPP_TAG_ZERO, attr, (char)atoi(token)); break; case IPP_TAG_INTEGER : case IPP_TAG_ENUM : ippAddInteger(col, IPP_TAG_ZERO, value, attr, atoi(token)); break; case IPP_TAG_RESOLUTION : { int xres, /* X resolution */ yres; /* Y resolution */ char units[6]; /* Units */ if (sscanf(token, "%dx%d%5s", &xres, &yres, units) != 3 || (_cups_strcasecmp(units, "dpi") && _cups_strcasecmp(units, "dpc") && _cups_strcasecmp(units, "dpcm") && _cups_strcasecmp(units, "other"))) { fprintf(stderr, "ippserver: Bad resolution value \"%s\" on line %d of \"%s\".\n", token, *linenum, filename); goto col_error; } if (!_cups_strcasecmp(units, "dpi")) ippAddResolution(col, IPP_TAG_ZERO, attr, IPP_RES_PER_INCH, xres, yres); else if (!_cups_strcasecmp(units, "dpc") || !_cups_strcasecmp(units, "dpcm")) ippAddResolution(col, IPP_TAG_ZERO, attr, IPP_RES_PER_CM, xres, yres); else ippAddResolution(col, IPP_TAG_ZERO, attr, (ipp_res_t)0, xres, yres); } break; case IPP_TAG_RANGE : { int lowers[4], /* Lower value */ uppers[4], /* Upper values */ num_vals; /* Number of values */ num_vals = sscanf(token, "%d-%d,%d-%d,%d-%d,%d-%d", lowers + 0, uppers + 0, lowers + 1, uppers + 1, lowers + 2, uppers + 2, lowers + 3, uppers + 3); if ((num_vals & 1) || num_vals == 0) { fprintf(stderr, "ippserver: Bad rangeOfInteger value \"%s\" on line %d of \"%s\".\n", token, *linenum, filename); goto col_error; } ippAddRanges(col, IPP_TAG_ZERO, attr, num_vals / 2, lowers, uppers); } break; case IPP_TAG_BEGIN_COLLECTION : if (!strcmp(token, "{")) { ipp_t *subcol = get_collection(fp, filename, linenum); /* Collection value */ if (subcol) { lastcol = ippAddCollection(col, IPP_TAG_ZERO, attr, subcol); ippDelete(subcol); } else goto col_error; } else { fprintf(stderr, "ippserver: Bad collection value on line %d of \"%s\".\n", *linenum, filename); goto col_error; } break; case IPP_TAG_STRING : ippAddOctetString(col, IPP_TAG_ZERO, attr, token, (int)strlen(token)); break; default : if (!strchr(token, ',')) ippAddString(col, IPP_TAG_ZERO, value, attr, NULL, token); else { /* * Multiple string values... */ int num_values; /* Number of values */ char *values[100], /* Values */ *ptr; /* Pointer to next value */ values[0] = token; num_values = 1; for (ptr = strchr(token, ','); ptr; ptr = strchr(ptr, ',')) { *ptr++ = '\0'; values[num_values] = ptr; num_values ++; if (num_values >= (int)(sizeof(values) / sizeof(values[0]))) break; } ippAddStrings(col, IPP_TAG_ZERO, value, attr, num_values, NULL, (const char **)values); } break; } } } return (col); /* * If we get here there was a parse error; free memory and return. */ col_error: ippDelete(col); return (NULL); }
ipp_status_t /* O - IPP status code */ cupsCloseDestJob( http_t *http, /* I - Connection to destination */ cups_dest_t *dest, /* I - Destination */ cups_dinfo_t *info, /* I - Destination information */ int job_id) /* I - Job ID */ { int i; /* Looping var */ ipp_t *request = NULL;/* Close-Job/Send-Document request */ ipp_attribute_t *attr; /* operations-supported attribute */ DEBUG_printf(("cupsCloseDestJob(http=%p, dest=%p(%s/%s), info=%p, job_id=%d)", http, dest, dest ? dest->name : NULL, dest ? dest->instance : NULL, info, job_id)); /* * Range check input... */ if (!http || !dest || !info || job_id <= 0) { _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0); DEBUG_puts("1cupsCloseDestJob: Bad arguments."); return (IPP_STATUS_ERROR_INTERNAL); } /* * Build a Close-Job or empty Send-Document request... */ if ((attr = ippFindAttribute(info->attrs, "operations-supported", IPP_TAG_ENUM)) != NULL) { for (i = 0; i < attr->num_values; i ++) if (attr->values[i].integer == IPP_OP_CLOSE_JOB) { request = ippNewRequest(IPP_OP_CLOSE_JOB); break; } } if (!request) request = ippNewRequest(IPP_OP_SEND_DOCUMENT); if (!request) { _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOMEM), 0); DEBUG_puts("1cupsCloseDestJob: Unable to create Close-Job/Send-Document " "request."); return (IPP_STATUS_ERROR_INTERNAL); } ippSetVersion(request, info->version / 10, info->version % 10); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, info->uri); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", job_id); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); if (ippGetOperation(request) == IPP_OP_SEND_DOCUMENT) ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", 1); /* * Send the request and return the status... */ ippDelete(cupsDoRequest(http, request, info->resource)); DEBUG_printf(("1cupsCloseDestJob: %s (%s)", ippErrorString(cupsLastError()), cupsLastErrorString())); return (cupsLastError()); }
ipp_status_t /* O - Request status - @code IPP_OK@ on success. */ cupsGetDevices( http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ int timeout, /* I - Timeout in seconds or @code CUPS_TIMEOUT_DEFAULT@ */ const char *include_schemes, /* I - Comma-separated URI schemes to include or @code CUPS_INCLUDE_ALL@ */ const char *exclude_schemes, /* I - Comma-separated URI schemes to exclude or @code CUPS_EXCLUDE_NONE@ */ cups_device_cb_t callback, /* I - Callback function */ void *user_data) /* I - User data pointer */ { ipp_t *request, /* CUPS-Get-Devices request */ *response; /* CUPS-Get-Devices response */ ipp_attribute_t *attr; /* Current attribute */ const char *device_class, /* device-class value */ *device_id, /* device-id value */ *device_info, /* device-info value */ *device_location, /* device-location value */ *device_make_and_model, /* device-make-and-model value */ *device_uri; /* device-uri value */ int blocking; /* Current blocking-IO mode */ cups_option_t option; /* in/exclude-schemes option */ http_status_t status; /* HTTP status of request */ ipp_state_t state; /* IPP response state */ /* * Range check input... */ DEBUG_printf(("cupsGetDevices(http=%p, timeout=%d, include_schemes=\"%s\", exclude_schemes=\"%s\", callback=%p, user_data=%p)", (void *)http, timeout, include_schemes, exclude_schemes, (void *)callback, user_data)); if (!callback) return (IPP_STATUS_ERROR_INTERNAL); if (!http) http = _cupsConnect(); if (!http) return (IPP_STATUS_ERROR_SERVICE_UNAVAILABLE); /* * Create a CUPS-Get-Devices request... */ request = ippNewRequest(IPP_OP_CUPS_GET_DEVICES); if (timeout > 0) ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "timeout", timeout); if (include_schemes) { option.name = "include-schemes"; option.value = (char *)include_schemes; cupsEncodeOptions2(request, 1, &option, IPP_TAG_OPERATION); } if (exclude_schemes) { option.name = "exclude-schemes"; option.value = (char *)exclude_schemes; cupsEncodeOptions2(request, 1, &option, IPP_TAG_OPERATION); } /* * Send the request and do any necessary authentication... */ do { DEBUG_puts("2cupsGetDevices: Sending request..."); status = cupsSendRequest(http, request, "/", ippLength(request)); DEBUG_puts("2cupsGetDevices: Waiting for response status..."); while (status == HTTP_STATUS_CONTINUE) status = httpUpdate(http); if (status != HTTP_STATUS_OK) { httpFlush(http); if (status == HTTP_STATUS_UNAUTHORIZED) { /* * See if we can do authentication... */ DEBUG_puts("2cupsGetDevices: Need authorization..."); if (!cupsDoAuthentication(http, "POST", "/")) httpReconnect2(http, 30000, NULL); else { status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; break; } } #ifdef HAVE_SSL else if (status == HTTP_STATUS_UPGRADE_REQUIRED) { /* * Force a reconnect with encryption... */ DEBUG_puts("2cupsGetDevices: Need encryption..."); if (!httpReconnect2(http, 30000, NULL)) httpEncryption(http, HTTP_ENCRYPTION_REQUIRED); } #endif /* HAVE_SSL */ } } while (status == HTTP_STATUS_UNAUTHORIZED || status == HTTP_STATUS_UPGRADE_REQUIRED); DEBUG_printf(("2cupsGetDevices: status=%d", status)); ippDelete(request); if (status != HTTP_STATUS_OK) { _cupsSetHTTPError(status); return (cupsLastError()); } /* * Read the response in non-blocking mode... */ blocking = httpGetBlocking(http); httpBlocking(http, 0); response = ippNew(); device_class = NULL; device_id = NULL; device_info = NULL; device_location = ""; device_make_and_model = NULL; device_uri = NULL; attr = NULL; DEBUG_puts("2cupsGetDevices: Reading response..."); do { if ((state = ippRead(http, response)) == IPP_STATE_ERROR) break; DEBUG_printf(("2cupsGetDevices: state=%d, response->last=%p", state, (void *)response->last)); if (!response->attrs) continue; while (attr != response->last) { if (!attr) attr = response->attrs; else attr = attr->next; DEBUG_printf(("2cupsGetDevices: attr->name=\"%s\", attr->value_tag=%d", attr->name, attr->value_tag)); if (!attr->name) { if (device_class && device_id && device_info && device_make_and_model && device_uri) (*callback)(device_class, device_id, device_info, device_make_and_model, device_uri, device_location, user_data); device_class = NULL; device_id = NULL; device_info = NULL; device_location = ""; device_make_and_model = NULL; device_uri = NULL; } else if (!strcmp(attr->name, "device-class") && attr->value_tag == IPP_TAG_KEYWORD) device_class = attr->values[0].string.text; else if (!strcmp(attr->name, "device-id") && attr->value_tag == IPP_TAG_TEXT) device_id = attr->values[0].string.text; else if (!strcmp(attr->name, "device-info") && attr->value_tag == IPP_TAG_TEXT) device_info = attr->values[0].string.text; else if (!strcmp(attr->name, "device-location") && attr->value_tag == IPP_TAG_TEXT) device_location = attr->values[0].string.text; else if (!strcmp(attr->name, "device-make-and-model") && attr->value_tag == IPP_TAG_TEXT) device_make_and_model = attr->values[0].string.text; else if (!strcmp(attr->name, "device-uri") && attr->value_tag == IPP_TAG_URI) device_uri = attr->values[0].string.text; } } while (state != IPP_STATE_DATA); DEBUG_printf(("2cupsGetDevices: state=%d, response->last=%p", state, (void *)response->last)); if (device_class && device_id && device_info && device_make_and_model && device_uri) (*callback)(device_class, device_id, device_info, device_make_and_model, device_uri, device_location, user_data); /* * Set the IPP status and return... */ httpBlocking(http, blocking); httpFlush(http); if (status == HTTP_STATUS_ERROR) _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(http->error), 0); else { attr = ippFindAttribute(response, "status-message", IPP_TAG_TEXT); DEBUG_printf(("cupsGetDevices: status-code=%s, status-message=\"%s\"", ippErrorString(response->request.status.status_code), attr ? attr->values[0].string.text : "")); _cupsSetError(response->request.status.status_code, attr ? attr->values[0].string.text : ippErrorString(response->request.status.status_code), 0); } ippDelete(response); return (cupsLastError()); }