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(); request->request.op.operation_id = IPP_RELEASE_JOB; request->request.op.request_id = 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(), 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", PRINTERNAME(snum)); if ((response = cupsDoRequest(http, request, httpPath)) != NULL) { if (response->request.status.status_code >= 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; }
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()); }
int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { int i; /* Looping var */ http_t *http; /* HTTP connection */ const char *server = NULL; /* Hostname from command-line */ int port = 0; /* Port number */ const char *cipherName = "UNKNOWN";/* Cipher suite name */ int dhBits = 0; /* Diffie-Hellman bits */ int tlsVersion = 0; /* TLS version number */ char uri[1024], /* Printer URI */ scheme[32], /* URI scheme */ host[256], /* Hostname */ userpass[256], /* Username/password */ resource[256]; /* Resource path */ int af = AF_UNSPEC, /* Address family */ tls_options = _HTTP_TLS_NONE, /* TLS options */ tls_min_version = _HTTP_TLS_1_0, tls_max_version = _HTTP_TLS_MAX, verbose = 0; /* Verbosity */ ipp_t *request, /* IPP Get-Printer-Attributes request */ *response; /* IPP Get-Printer-Attributes response */ ipp_attribute_t *attr; /* Current attribute */ const char *name; /* Attribute name */ char value[1024]; /* Attribute (string) value */ static const char * const pattrs[] = /* Requested attributes */ { "color-supported", "compression-supported", "document-format-supported", "pages-per-minute", "printer-location", "printer-make-and-model", "printer-state", "printer-state-reasons", "sides-supported", "uri-authentication-supported", "uri-security-supported" }; for (i = 1; i < argc; i ++) { if (!strcmp(argv[i], "--dh")) { tls_options |= _HTTP_TLS_ALLOW_DH; } else if (!strcmp(argv[i], "--no-cbc")) { tls_options |= _HTTP_TLS_DENY_CBC; } else if (!strcmp(argv[i], "--no-tls10")) { tls_min_version = _HTTP_TLS_1_1; } else if (!strcmp(argv[i], "--tls10")) { tls_min_version = _HTTP_TLS_1_0; tls_max_version = _HTTP_TLS_1_0; } else if (!strcmp(argv[i], "--rc4")) { tls_options |= _HTTP_TLS_ALLOW_RC4; } else if (!strcmp(argv[i], "--verbose") || !strcmp(argv[i], "-v")) { verbose = 1; } else if (!strcmp(argv[i], "-4")) { af = AF_INET; } else if (!strcmp(argv[i], "-6")) { af = AF_INET6; } else if (argv[i][0] == '-') { printf("tlscheck: Unknown option '%s'.\n", argv[i]); usage(); } else if (!server) { if (!strncmp(argv[i], "ipps://", 7)) { httpSeparateURI(HTTP_URI_CODING_ALL, argv[i], scheme, sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource)); server = host; } else { server = argv[i]; strlcpy(resource, "/ipp/print", sizeof(resource)); } } else if (!port && (argv[i][0] == '=' || isdigit(argv[i][0] & 255))) { if (argv[i][0] == '=') port = atoi(argv[i] + 1); else port = atoi(argv[i]); } else { printf("tlscheck: Unexpected argument '%s'.\n", argv[i]); usage(); } } if (!server) usage(); if (!port) port = 631; _httpTLSSetOptions(tls_options, tls_min_version, tls_max_version); http = httpConnect2(server, port, NULL, af, HTTP_ENCRYPTION_ALWAYS, 1, 30000, NULL); if (!http) { printf("%s: ERROR (%s)\n", server, cupsLastErrorString()); return (1); } #ifdef __APPLE__ SSLProtocol protocol; SSLCipherSuite cipher; char unknownCipherName[256]; int paramsNeeded = 0; const void *params; size_t paramsLen; OSStatus err; if ((err = SSLGetNegotiatedProtocolVersion(http->tls, &protocol)) != noErr) { printf("%s: ERROR (No protocol version - %d)\n", server, (int)err); httpClose(http); return (1); } switch (protocol) { default : tlsVersion = 0; break; case kSSLProtocol3 : tlsVersion = 30; break; case kTLSProtocol1 : tlsVersion = 10; break; case kTLSProtocol11 : tlsVersion = 11; break; case kTLSProtocol12 : tlsVersion = 12; break; } if ((err = SSLGetNegotiatedCipher(http->tls, &cipher)) != noErr) { printf("%s: ERROR (No cipher suite - %d)\n", server, (int)err); httpClose(http); return (1); } switch (cipher) { case TLS_NULL_WITH_NULL_NULL: cipherName = "TLS_NULL_WITH_NULL_NULL"; break; case TLS_RSA_WITH_NULL_MD5: cipherName = "TLS_RSA_WITH_NULL_MD5"; break; case TLS_RSA_WITH_NULL_SHA: cipherName = "TLS_RSA_WITH_NULL_SHA"; break; case TLS_RSA_WITH_RC4_128_MD5: cipherName = "TLS_RSA_WITH_RC4_128_MD5"; break; case TLS_RSA_WITH_RC4_128_SHA: cipherName = "TLS_RSA_WITH_RC4_128_SHA"; break; case TLS_RSA_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_RSA_WITH_3DES_EDE_CBC_SHA"; break; case TLS_RSA_WITH_NULL_SHA256: cipherName = "TLS_RSA_WITH_NULL_SHA256"; break; case TLS_RSA_WITH_AES_128_CBC_SHA256: cipherName = "TLS_RSA_WITH_AES_128_CBC_SHA256"; break; case TLS_RSA_WITH_AES_256_CBC_SHA256: cipherName = "TLS_RSA_WITH_AES_256_CBC_SHA256"; break; case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA"; paramsNeeded = 1; break; case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA"; paramsNeeded = 1; break; case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA"; paramsNeeded = 1; break; case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"; paramsNeeded = 1; break; case TLS_DH_DSS_WITH_AES_128_CBC_SHA256: cipherName = "TLS_DH_DSS_WITH_AES_128_CBC_SHA256"; paramsNeeded = 1; break; case TLS_DH_RSA_WITH_AES_128_CBC_SHA256: cipherName = "TLS_DH_RSA_WITH_AES_128_CBC_SHA256"; paramsNeeded = 1; break; case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: cipherName = "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"; paramsNeeded = 1; break; case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: cipherName = "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"; paramsNeeded = 1; break; case TLS_DH_DSS_WITH_AES_256_CBC_SHA256: cipherName = "TLS_DH_DSS_WITH_AES_256_CBC_SHA256"; paramsNeeded = 1; break; case TLS_DH_RSA_WITH_AES_256_CBC_SHA256: cipherName = "TLS_DH_RSA_WITH_AES_256_CBC_SHA256"; paramsNeeded = 1; break; case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: cipherName = "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"; paramsNeeded = 1; break; case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: cipherName = "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"; paramsNeeded = 1; break; case TLS_DH_anon_WITH_RC4_128_MD5: cipherName = "TLS_DH_anon_WITH_RC4_128_MD5"; paramsNeeded = 1; break; case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA"; paramsNeeded = 1; break; case TLS_DH_anon_WITH_AES_128_CBC_SHA256: cipherName = "TLS_DH_anon_WITH_AES_128_CBC_SHA256"; paramsNeeded = 1; break; case TLS_DH_anon_WITH_AES_256_CBC_SHA256: cipherName = "TLS_DH_anon_WITH_AES_256_CBC_SHA256"; paramsNeeded = 1; break; case TLS_PSK_WITH_RC4_128_SHA: cipherName = "TLS_PSK_WITH_RC4_128_SHA"; break; case TLS_PSK_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_PSK_WITH_3DES_EDE_CBC_SHA"; break; case TLS_PSK_WITH_AES_128_CBC_SHA: cipherName = "TLS_PSK_WITH_AES_128_CBC_SHA"; break; case TLS_PSK_WITH_AES_256_CBC_SHA: cipherName = "TLS_PSK_WITH_AES_256_CBC_SHA"; break; case TLS_DHE_PSK_WITH_RC4_128_SHA: cipherName = "TLS_DHE_PSK_WITH_RC4_128_SHA"; paramsNeeded = 1; break; case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA"; paramsNeeded = 1; break; case TLS_DHE_PSK_WITH_AES_128_CBC_SHA: cipherName = "TLS_DHE_PSK_WITH_AES_128_CBC_SHA"; paramsNeeded = 1; break; case TLS_DHE_PSK_WITH_AES_256_CBC_SHA: cipherName = "TLS_DHE_PSK_WITH_AES_256_CBC_SHA"; paramsNeeded = 1; break; case TLS_RSA_PSK_WITH_RC4_128_SHA: cipherName = "TLS_RSA_PSK_WITH_RC4_128_SHA"; break; case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA"; break; case TLS_RSA_PSK_WITH_AES_128_CBC_SHA: cipherName = "TLS_RSA_PSK_WITH_AES_128_CBC_SHA"; break; case TLS_RSA_PSK_WITH_AES_256_CBC_SHA: cipherName = "TLS_RSA_PSK_WITH_AES_256_CBC_SHA"; break; case TLS_PSK_WITH_NULL_SHA: cipherName = "TLS_PSK_WITH_NULL_SHA"; break; case TLS_DHE_PSK_WITH_NULL_SHA: cipherName = "TLS_DHE_PSK_WITH_NULL_SHA"; paramsNeeded = 1; break; case TLS_RSA_PSK_WITH_NULL_SHA: cipherName = "TLS_RSA_PSK_WITH_NULL_SHA"; break; case TLS_RSA_WITH_AES_128_GCM_SHA256: cipherName = "TLS_RSA_WITH_AES_128_GCM_SHA256"; break; case TLS_RSA_WITH_AES_256_GCM_SHA384: cipherName = "TLS_RSA_WITH_AES_256_GCM_SHA384"; break; case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: cipherName = "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"; paramsNeeded = 1; break; case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: cipherName = "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"; paramsNeeded = 1; break; case TLS_DH_RSA_WITH_AES_128_GCM_SHA256: cipherName = "TLS_DH_RSA_WITH_AES_128_GCM_SHA256"; paramsNeeded = 1; break; case TLS_DH_RSA_WITH_AES_256_GCM_SHA384: cipherName = "TLS_DH_RSA_WITH_AES_256_GCM_SHA384"; paramsNeeded = 1; break; case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: cipherName = "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256"; paramsNeeded = 1; break; case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: cipherName = "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384"; paramsNeeded = 1; break; case TLS_DH_DSS_WITH_AES_128_GCM_SHA256: cipherName = "TLS_DH_DSS_WITH_AES_128_GCM_SHA256"; paramsNeeded = 1; break; case TLS_DH_DSS_WITH_AES_256_GCM_SHA384: cipherName = "TLS_DH_DSS_WITH_AES_256_GCM_SHA384"; paramsNeeded = 1; break; case TLS_DH_anon_WITH_AES_128_GCM_SHA256: cipherName = "TLS_DH_anon_WITH_AES_128_GCM_SHA256"; paramsNeeded = 1; break; case TLS_DH_anon_WITH_AES_256_GCM_SHA384: cipherName = "TLS_DH_anon_WITH_AES_256_GCM_SHA384"; paramsNeeded = 1; break; case TLS_PSK_WITH_AES_128_GCM_SHA256: cipherName = "TLS_PSK_WITH_AES_128_GCM_SHA256"; break; case TLS_PSK_WITH_AES_256_GCM_SHA384: cipherName = "TLS_PSK_WITH_AES_256_GCM_SHA384"; break; case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: cipherName = "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256"; paramsNeeded = 1; break; case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: cipherName = "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384"; paramsNeeded = 1; break; case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: cipherName = "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256"; break; case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: cipherName = "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384"; break; case TLS_PSK_WITH_AES_128_CBC_SHA256: cipherName = "TLS_PSK_WITH_AES_128_CBC_SHA256"; break; case TLS_PSK_WITH_AES_256_CBC_SHA384: cipherName = "TLS_PSK_WITH_AES_256_CBC_SHA384"; break; case TLS_PSK_WITH_NULL_SHA256: cipherName = "TLS_PSK_WITH_NULL_SHA256"; break; case TLS_PSK_WITH_NULL_SHA384: cipherName = "TLS_PSK_WITH_NULL_SHA384"; break; case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256: cipherName = "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256"; paramsNeeded = 1; break; case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: cipherName = "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384"; paramsNeeded = 1; break; case TLS_DHE_PSK_WITH_NULL_SHA256: cipherName = "TLS_DHE_PSK_WITH_NULL_SHA256"; paramsNeeded = 1; break; case TLS_DHE_PSK_WITH_NULL_SHA384: cipherName = "TLS_DHE_PSK_WITH_NULL_SHA384"; paramsNeeded = 1; break; case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256: cipherName = "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256"; break; case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384: cipherName = "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384"; break; case TLS_RSA_PSK_WITH_NULL_SHA256: cipherName = "TLS_RSA_PSK_WITH_NULL_SHA256"; break; case TLS_RSA_PSK_WITH_NULL_SHA384: cipherName = "TLS_RSA_PSK_WITH_NULL_SHA384"; break; case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: cipherName = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"; paramsNeeded = 1; break; case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: cipherName = "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"; paramsNeeded = 1; break; case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: cipherName = "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256"; paramsNeeded = 1; break; case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: cipherName = "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384"; paramsNeeded = 1; break; case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: cipherName = "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"; paramsNeeded = 1; break; case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: cipherName = "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"; paramsNeeded = 1; break; case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: cipherName = "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256"; paramsNeeded = 1; break; case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: cipherName = "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384"; paramsNeeded = 1; break; case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: cipherName = "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"; paramsNeeded = 1; break; case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: cipherName = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"; paramsNeeded = 1; break; case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: cipherName = "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"; paramsNeeded = 1; break; case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: cipherName = "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384"; paramsNeeded = 1; break; case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: cipherName = "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"; paramsNeeded = 1; break; case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: cipherName = "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"; paramsNeeded = 1; break; case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: cipherName = "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256"; paramsNeeded = 1; break; case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: cipherName = "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384"; paramsNeeded = 1; break; case TLS_RSA_WITH_AES_128_CBC_SHA: cipherName = "TLS_RSA_WITH_AES_128_CBC_SHA"; break; case TLS_DH_DSS_WITH_AES_128_CBC_SHA: cipherName = "TLS_DH_DSS_WITH_AES_128_CBC_SHA"; paramsNeeded = 1; break; case TLS_DH_RSA_WITH_AES_128_CBC_SHA: cipherName = "TLS_DH_RSA_WITH_AES_128_CBC_SHA"; paramsNeeded = 1; break; case TLS_DHE_DSS_WITH_AES_128_CBC_SHA: cipherName = "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"; paramsNeeded = 1; break; case TLS_DHE_RSA_WITH_AES_128_CBC_SHA: cipherName = "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"; paramsNeeded = 1; break; case TLS_DH_anon_WITH_AES_128_CBC_SHA: cipherName = "TLS_DH_anon_WITH_AES_128_CBC_SHA"; paramsNeeded = 1; break; case TLS_RSA_WITH_AES_256_CBC_SHA: cipherName = "TLS_RSA_WITH_AES_256_CBC_SHA"; break; case TLS_DH_DSS_WITH_AES_256_CBC_SHA: cipherName = "TLS_DH_DSS_WITH_AES_256_CBC_SHA"; paramsNeeded = 1; break; case TLS_DH_RSA_WITH_AES_256_CBC_SHA: cipherName = "TLS_DH_RSA_WITH_AES_256_CBC_SHA"; paramsNeeded = 1; break; case TLS_DHE_DSS_WITH_AES_256_CBC_SHA: cipherName = "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"; paramsNeeded = 1; break; case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: cipherName = "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"; paramsNeeded = 1; break; case TLS_DH_anon_WITH_AES_256_CBC_SHA: cipherName = "TLS_DH_anon_WITH_AES_256_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDH_ECDSA_WITH_NULL_SHA: cipherName = "TLS_ECDH_ECDSA_WITH_NULL_SHA"; paramsNeeded = 1; break; case TLS_ECDH_ECDSA_WITH_RC4_128_SHA: cipherName = "TLS_ECDH_ECDSA_WITH_RC4_128_SHA"; paramsNeeded = 1; break; case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: cipherName = "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: cipherName = "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDHE_ECDSA_WITH_NULL_SHA: cipherName = "TLS_ECDHE_ECDSA_WITH_NULL_SHA"; paramsNeeded = 1; break; case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: cipherName = "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"; paramsNeeded = 1; break; case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: cipherName = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: cipherName = "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDH_RSA_WITH_NULL_SHA: cipherName = "TLS_ECDH_RSA_WITH_NULL_SHA"; paramsNeeded = 1; break; case TLS_ECDH_RSA_WITH_RC4_128_SHA: cipherName = "TLS_ECDH_RSA_WITH_RC4_128_SHA"; paramsNeeded = 1; break; case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: cipherName = "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: cipherName = "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDHE_RSA_WITH_NULL_SHA: cipherName = "TLS_ECDHE_RSA_WITH_NULL_SHA"; paramsNeeded = 1; break; case TLS_ECDHE_RSA_WITH_RC4_128_SHA: cipherName = "TLS_ECDHE_RSA_WITH_RC4_128_SHA"; paramsNeeded = 1; break; case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: cipherName = "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: cipherName = "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDH_anon_WITH_NULL_SHA: cipherName = "TLS_ECDH_anon_WITH_NULL_SHA"; paramsNeeded = 1; break; case TLS_ECDH_anon_WITH_RC4_128_SHA: cipherName = "TLS_ECDH_anon_WITH_RC4_128_SHA"; paramsNeeded = 1; break; case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA: cipherName = "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDH_anon_WITH_AES_128_CBC_SHA: cipherName = "TLS_ECDH_anon_WITH_AES_128_CBC_SHA"; paramsNeeded = 1; break; case TLS_ECDH_anon_WITH_AES_256_CBC_SHA: cipherName = "TLS_ECDH_anon_WITH_AES_256_CBC_SHA"; paramsNeeded = 1; break; default : snprintf(unknownCipherName, sizeof(unknownCipherName), "UNKNOWN_%04X", cipher); cipherName = unknownCipherName; break; } if (cipher == TLS_RSA_WITH_RC4_128_MD5 || cipher == TLS_RSA_WITH_RC4_128_SHA) { printf("%s: ERROR (Printers MUST NOT negotiate RC4 cipher suites.)\n", server); httpClose(http); return (1); } if ((err = SSLGetDiffieHellmanParams(http->tls, ¶ms, ¶msLen)) != noErr && paramsNeeded) { printf("%s: ERROR (Unable to get Diffie-Hellman parameters - %d)\n", server, (int)err); httpClose(http); return (1); } if (paramsLen < 128 && paramsLen != 0) { printf("%s: ERROR (Diffie-Hellman parameters MUST be at least 2048 bits, but Printer uses only %d bits/%d bytes)\n", server, (int)paramsLen * 8, (int)paramsLen); httpClose(http); return (1); } dhBits = (int)paramsLen * 8; #endif /* __APPLE__ */ if (dhBits > 0) printf("%s: OK (TLS: %d.%d, %s, %d DH bits)\n", server, tlsVersion / 10, tlsVersion % 10, cipherName, dhBits); else printf("%s: OK (TLS: %d.%d, %s)\n", server, tlsVersion / 10, tlsVersion % 10, cipherName); if (verbose) { httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipps", NULL, host, port, resource); request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES); 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_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (int)(sizeof(pattrs) / sizeof(pattrs[0])), NULL, pattrs); response = cupsDoRequest(http, request, resource); for (attr = ippFirstAttribute(response); attr; attr = ippNextAttribute(response)) { if (ippGetGroupTag(attr) != IPP_TAG_PRINTER) continue; if ((name = ippGetName(attr)) == NULL) continue; ippAttributeString(attr, value, sizeof(value)); printf(" %s=%s\n", name, value); } ippDelete(response); } httpClose(http); return (0); }
void cgiPrintCommand(http_t *http, /* I - Connection to server */ const char *dest, /* I - Destination printer */ const char *command, /* I - Command to send */ const char *title) /* I - Page/job title */ { int job_id; /* Command file job */ char uri[HTTP_MAX_URI], /* Job URI */ resource[1024], /* Printer resource path */ refresh[1024], /* Refresh URL */ command_file[1024]; /* Command "file" */ http_status_t status; /* Document status */ cups_option_t hold_option; /* job-hold-until option */ const char *user; /* User name */ ipp_t *request, /* Get-Job-Attributes request */ *response; /* Get-Job-Attributes response */ ipp_attribute_t *attr; /* Current job attribute */ static const char * const job_attrs[] =/* Job attributes we want */ { "job-state", "job-printer-state-message" }; /* * Create the CUPS command file... */ snprintf(command_file, sizeof(command_file), "#CUPS-COMMAND\n%s\n", command); /* * Show status... */ if (cgiSupportsMultipart()) { cgiStartMultipart(); cgiStartHTML(title); cgiCopyTemplateLang("command.tmpl"); cgiEndHTML(); fflush(stdout); } /* * Send the command file job... */ hold_option.name = "job-hold-until"; hold_option.value = "no-hold"; if ((user = getenv("REMOTE_USER")) != NULL) cupsSetUser(user); else cupsSetUser("anonymous"); if ((job_id = cupsCreateJob(http, dest, title, 1, &hold_option)) < 1) { cgiSetVariable("MESSAGE", cgiText(_("Unable to send command to printer driver"))); cgiSetVariable("ERROR", cupsLastErrorString()); cgiStartHTML(title); cgiCopyTemplateLang("error.tmpl"); cgiEndHTML(); if (cgiSupportsMultipart()) cgiEndMultipart(); return; } status = cupsStartDocument(http, dest, job_id, NULL, CUPS_FORMAT_COMMAND, 1); if (status == HTTP_CONTINUE) status = cupsWriteRequestData(http, command_file, strlen(command_file)); if (status == HTTP_CONTINUE) cupsFinishDocument(http, dest); if (cupsLastError() >= IPP_REDIRECTION_OTHER_SITE) { cgiSetVariable("MESSAGE", cgiText(_("Unable to send command to printer driver"))); cgiSetVariable("ERROR", cupsLastErrorString()); cgiStartHTML(title); cgiCopyTemplateLang("error.tmpl"); cgiEndHTML(); if (cgiSupportsMultipart()) cgiEndMultipart(); cupsCancelJob(dest, job_id); return; } /* * Wait for the job to complete... */ if (cgiSupportsMultipart()) { for (;;) { /* * Get the current job state... */ snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", job_id); request = ippNewRequest(IPP_GET_JOB_ATTRIBUTES); 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); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", 2, NULL, job_attrs); if ((response = cupsDoRequest(http, request, "/")) != NULL) cgiSetIPPVars(response, NULL, NULL, NULL, 0); attr = ippFindAttribute(response, "job-state", IPP_TAG_ENUM); if (!attr || attr->values[0].integer >= IPP_JOB_STOPPED || attr->values[0].integer == IPP_JOB_HELD) { ippDelete(response); break; } /* * Job not complete, so update the status... */ ippDelete(response); cgiStartHTML(title); cgiCopyTemplateLang("command.tmpl"); cgiEndHTML(); fflush(stdout); sleep(5); } } /* * Send the final page that reloads the printer's page... */ snprintf(resource, sizeof(resource), "/printers/%s", dest); cgiFormEncode(uri, resource, sizeof(uri)); snprintf(refresh, sizeof(refresh), "5;URL=%s", uri); cgiSetVariable("refresh_page", refresh); cgiStartHTML(title); cgiCopyTemplateLang("command.tmpl"); cgiEndHTML(); if (cgiSupportsMultipart()) cgiEndMultipart(); }
ipp_status_t /* O - IPP status code */ cupsCreateDestJob( http_t *http, /* I - Connection to destination */ cups_dest_t *dest, /* I - Destination */ cups_dinfo_t *info, /* I - Destination information */ int *job_id, /* O - Job ID or 0 on error */ const char *title, /* I - Job name */ int num_options, /* I - Number of job options */ cups_option_t *options) /* I - Job options */ { ipp_t *request, /* Create-Job request */ *response; /* Create-Job response */ ipp_attribute_t *attr; /* job-id attribute */ DEBUG_printf(("cupsCreateDestJob(http=%p, dest=%p(%s/%s), info=%p, " "job_id=%p, title=\"%s\", num_options=%d, options=%p)", http, dest, dest ? dest->name : NULL, dest ? dest->instance : NULL, info, job_id, title, num_options, options)); /* * Range check input... */ if (job_id) *job_id = 0; if (!http || !dest || !info || !job_id) { _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0); DEBUG_puts("1cupsCreateDestJob: Bad arguments."); return (IPP_STATUS_ERROR_INTERNAL); } /* * Build a Create-Job request... */ if ((request = ippNewRequest(IPP_OP_CREATE_JOB)) == NULL) { _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOMEM), 0); DEBUG_puts("1cupsCreateDestJob: Unable to create Create-Job 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); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); if (title) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, title); cupsEncodeOptions2(request, num_options, options, IPP_TAG_OPERATION); cupsEncodeOptions2(request, num_options, options, IPP_TAG_JOB); cupsEncodeOptions2(request, num_options, options, IPP_TAG_SUBSCRIPTION); /* * Send the request and get the job-id... */ response = cupsDoRequest(http, request, info->resource); if ((attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) != NULL) { *job_id = attr->values[0].integer; DEBUG_printf(("1cupsCreateDestJob: job-id=%d", *job_id)); } ippDelete(response); /* * Return the status code from the Create-Job request... */ DEBUG_printf(("1cupsCreateDestJob: %s (%s)", ippErrorString(cupsLastError()), cupsLastErrorString())); return (cupsLastError()); }
static int /* O - 0 on success, 1 on fail */ set_printer_options( http_t *http, /* I - Server connection */ char *printer, /* I - Printer */ int num_options, /* I - Number of options */ cups_option_t *options, /* I - Options */ char *file) /* I - PPD file/interface script */ { ipp_t *request; /* IPP Request */ const char *ppdfile; /* PPD filename */ int ppdchanged; /* PPD changed? */ ppd_file_t *ppd; /* PPD file */ ppd_choice_t *choice; /* Marked choice */ char uri[HTTP_MAX_URI], /* URI for printer/class */ line[1024], /* Line from PPD file */ keyword[1024], /* Keyword from Default line */ *keyptr, /* Pointer into keyword... */ tempfile[1024]; /* Temporary filename */ cups_file_t *in, /* PPD file */ *out; /* Temporary file */ const char *protocol, /* Old protocol option */ *customval, /* Custom option value */ *boolval; /* Boolean value */ int wrote_ipp_supplies = 0, /* Wrote cupsIPPSupplies keyword? */ wrote_snmp_supplies = 0;/* Wrote cupsSNMPSupplies keyword? */ DEBUG_printf(("set_printer_options(http=%p, printer=\"%s\", num_options=%d, " "options=%p, file=\"%s\")\n", http, printer, num_options, options, file)); /* * 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 * other options */ 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()); /* * Add the options... */ cupsEncodeOptions2(request, num_options, options, IPP_TAG_PRINTER); if ((protocol = cupsGetOption("protocol", num_options, options)) != NULL) { if (!_cups_strcasecmp(protocol, "bcp")) ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "port-monitor", NULL, "bcp"); else if (!_cups_strcasecmp(protocol, "tbcp")) ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "port-monitor", NULL, "tbcp"); } if (file) ppdfile = file; else if (request->request.op.operation_id == CUPS_ADD_MODIFY_PRINTER) ppdfile = cupsGetPPD(printer); else ppdfile = NULL; if (ppdfile != NULL) { /* * Set default options in the PPD file... */ ppd = ppdOpenFile(ppdfile); ppdMarkDefaults(ppd); cupsMarkOptions(ppd, num_options, options); if ((out = cupsTempFile2(tempfile, sizeof(tempfile))) == NULL) { _cupsLangPrintError(NULL, _("lpadmin: Unable to create temporary file")); ippDelete(request); if (ppdfile != file) unlink(ppdfile); return (1); } if ((in = cupsFileOpen(ppdfile, "r")) == NULL) { _cupsLangPrintf(stderr, _("lpadmin: Unable to open PPD file \"%s\" - %s"), ppdfile, strerror(errno)); ippDelete(request); if (ppdfile != file) unlink(ppdfile); cupsFileClose(out); unlink(tempfile); return (1); } ppdchanged = 0; while (cupsFileGets(in, line, sizeof(line))) { if (!strncmp(line, "*cupsIPPSupplies:", 17) && (boolval = cupsGetOption("cupsIPPSupplies", num_options, options)) != NULL) { wrote_ipp_supplies = 1; cupsFilePrintf(out, "*cupsIPPSupplies: %s\n", (!_cups_strcasecmp(boolval, "true") || !_cups_strcasecmp(boolval, "yes") || !_cups_strcasecmp(boolval, "on")) ? "True" : "False"); } else if (!strncmp(line, "*cupsSNMPSupplies:", 18) && (boolval = cupsGetOption("cupsSNMPSupplies", num_options, options)) != NULL) { wrote_snmp_supplies = 1; cupsFilePrintf(out, "*cupsSNMPSupplies: %s\n", (!_cups_strcasecmp(boolval, "true") || !_cups_strcasecmp(boolval, "yes") || !_cups_strcasecmp(boolval, "on")) ? "True" : "False"); } else if (strncmp(line, "*Default", 8)) cupsFilePrintf(out, "%s\n", line); else { /* * Get default option name... */ strlcpy(keyword, line + 8, sizeof(keyword)); for (keyptr = keyword; *keyptr; keyptr ++) if (*keyptr == ':' || isspace(*keyptr & 255)) break; *keyptr++ = '\0'; while (isspace(*keyptr & 255)) keyptr ++; if (!strcmp(keyword, "PageRegion") || !strcmp(keyword, "PageSize") || !strcmp(keyword, "PaperDimension") || !strcmp(keyword, "ImageableArea")) { if ((choice = ppdFindMarkedChoice(ppd, "PageSize")) == NULL) choice = ppdFindMarkedChoice(ppd, "PageRegion"); } else choice = ppdFindMarkedChoice(ppd, keyword); if (choice && strcmp(choice->choice, keyptr)) { if (strcmp(choice->choice, "Custom")) { cupsFilePrintf(out, "*Default%s: %s\n", keyword, choice->choice); ppdchanged = 1; } else if ((customval = cupsGetOption(keyword, num_options, options)) != NULL) { cupsFilePrintf(out, "*Default%s: %s\n", keyword, customval); ppdchanged = 1; } else cupsFilePrintf(out, "%s\n", line); } else cupsFilePrintf(out, "%s\n", line); } } if (!wrote_ipp_supplies && (boolval = cupsGetOption("cupsIPPSupplies", num_options, options)) != NULL) { cupsFilePrintf(out, "*cupsIPPSupplies: %s\n", (!_cups_strcasecmp(boolval, "true") || !_cups_strcasecmp(boolval, "yes") || !_cups_strcasecmp(boolval, "on")) ? "True" : "False"); } if (!wrote_snmp_supplies && (boolval = cupsGetOption("cupsSNMPSupplies", num_options, options)) != NULL) { cupsFilePrintf(out, "*cupsSNMPSupplies: %s\n", (!_cups_strcasecmp(boolval, "true") || !_cups_strcasecmp(boolval, "yes") || !_cups_strcasecmp(boolval, "on")) ? "True" : "False"); } cupsFileClose(in); cupsFileClose(out); ppdClose(ppd); /* * Do the request... */ ippDelete(cupsDoFileRequest(http, request, "/admin/", ppdchanged ? tempfile : file)); /* * Clean up temp files... (TODO: catch signals in case we CTRL-C during * lpadmin) */ if (ppdfile != file) unlink(ppdfile); unlink(tempfile); } else { /* * No PPD file - just set the options... */ ippDelete(cupsDoRequest(http, request, "/admin/")); } /* * Check the response... */ 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_from_class( http_t *http, /* I - Server connection */ char *printer, /* I - Printer to remove */ char *pclass) /* I - Class to remove from */ { int i, j, k; /* Looping vars */ ipp_t *request, /* IPP Request */ *response; /* IPP Response */ ipp_attribute_t *attr, /* Current attribute */ *members; /* Members in class */ char uri[HTTP_MAX_URI]; /* URI for printer/class */ DEBUG_printf(("delete_printer_from_class(%p, \"%s\", \"%s\")\n", http, printer, pclass)); /* * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * requesting-user-name */ request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/classes/%s", pclass); 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()); /* * Do the request and get back a response... */ if ((response = cupsDoRequest(http, request, "/classes/")) == NULL || response->request.status.status_code == IPP_NOT_FOUND) { _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString()); ippDelete(response); return (1); } /* * See if the printer is already in the class... */ if ((members = ippFindAttribute(response, "member-names", IPP_TAG_NAME)) == NULL) { _cupsLangPuts(stderr, _("lpadmin: No member names were seen.")); ippDelete(response); return (1); } for (i = 0; i < members->num_values; i ++) if (!_cups_strcasecmp(printer, members->values[i].string.text)) break; if (i >= members->num_values) { _cupsLangPrintf(stderr, _("lpadmin: Printer %s is not a member of class %s."), printer, pclass); ippDelete(response); return (1); } if (members->num_values == 1) { /* * Build a CUPS_DELETE_CLASS request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * requesting-user-name */ request = ippNewRequest(CUPS_DELETE_CLASS); 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()); } else { /* * Build a CUPS_ADD_MODIFY_CLASS request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * requesting-user-name * member-uris */ request = ippNewRequest(CUPS_ADD_MODIFY_CLASS); 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()); /* * Delete the printer from the class... */ members = ippFindAttribute(response, "member-uris", IPP_TAG_URI); attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_URI, "member-uris", members->num_values - 1, NULL, NULL); for (j = 0, k = 0; j < members->num_values; j ++) if (j != i) attr->values[k ++].string.text = _cupsStrAlloc(members->values[j].string.text); } /* * Then send the request... */ ippDelete(response); ippDelete(cupsDoRequest(http, request, "/admin/")); if (cupsLastError() > IPP_OK_CONFLICT) { _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString()); return (1); } else return (0); }
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); }
static void do_job_op(http_t *http, /* I - HTTP connection */ int job_id, /* I - Job ID */ ipp_op_t op) /* I - Operation to perform */ { ipp_t *request; /* IPP request */ char uri[HTTP_MAX_URI]; /* Job URI */ const char *user; /* Username */ /* * Build a job request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * job-uri or printer-uri (purge-jobs) * requesting-user-name */ request = ippNewRequest(op); snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", job_id); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); if ((user = getenv("REMOTE_USER")) == NULL) user = "******"; ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, user); /* * Do the request and get back a response... */ ippDelete(cupsDoRequest(http, request, "/jobs")); if (cupsLastError() <= IPP_OK_CONFLICT && getenv("HTTP_REFERER")) { /* * Redirect successful updates back to the parent page... */ char url[1024]; /* Encoded URL */ strlcpy(url, "5;URL=", sizeof(url)); cgiFormEncode(url + 6, getenv("HTTP_REFERER"), sizeof(url) - 6); cgiSetVariable("refresh_page", url); } else if (cupsLastError() == IPP_NOT_AUTHORIZED) { puts("Status: 401\n"); exit(0); } cgiStartHTML(cgiText(_("Jobs"))); if (cupsLastError() > IPP_OK_CONFLICT) cgiShowIPPError(_("Job operation failed")); else if (op == IPP_CANCEL_JOB) cgiCopyTemplateLang("job-cancel.tmpl"); else if (op == IPP_HOLD_JOB) cgiCopyTemplateLang("job-hold.tmpl"); else if (op == IPP_RELEASE_JOB) cgiCopyTemplateLang("job-release.tmpl"); else if (op == IPP_RESTART_JOB) cgiCopyTemplateLang("job-restart.tmpl"); cgiEndHTML(); }
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 *opt, /* Option pointer */ *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]) { for (opt = argv[i] + 1; *opt; opt ++) { switch (*opt) { 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."), argv[0]); #endif /* HAVE_SSL */ break; case 'U' : /* Username */ if (opt[1] != '\0') { cupsSetUser(opt + 1); opt += strlen(opt) - 1; } else { i ++; if (i >= argc) { _cupsLangPrintf(stderr, _("%s: Error - expected username after \"-U\" option."), argv[0]); return (1); } cupsSetUser(argv[i]); } break; case 'a' : /* Cancel all jobs */ op = purge ? IPP_PURGE_JOBS : IPP_CANCEL_JOBS; break; case 'h' : /* Connect to host */ if (http != NULL) { httpClose(http); http = NULL; } if (opt[1] != '\0') { cupsSetServer(opt + 1); opt += strlen(opt) - 1; } else { i ++; if (i >= argc) { _cupsLangPrintf(stderr, _("%s: Error - expected hostname after \"-h\" option."), argv[0]); return (1); } else cupsSetServer(argv[i]); } break; case 'u' : /* Username */ op = IPP_CANCEL_MY_JOBS; if (opt[1] != '\0') { user = opt + 1; opt += strlen(opt) - 1; } else { i ++; if (i >= argc) { _cupsLangPrintf(stderr, _("%s: Error - expected username after \"-u\" option."), argv[0]); return (1); } else user = argv[i]; } break; case 'x' : /* Purge job(s) */ purge = 1; if (op == IPP_CANCEL_JOBS) op = IPP_PURGE_JOBS; break; default : _cupsLangPrintf(stderr, _("%s: Error - unknown option \"%c\"."), argv[0], *opt); 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\"."), 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 connect to server."), 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); if (op == IPP_CANCEL_JOBS) op = IPP_CANCEL_MY_JOBS; } else ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); if (purge) ippAddBoolean(request, IPP_TAG_OPERATION, "purge-jobs", (char)purge); /* * Do the request and get back a response... */ if (op == IPP_CANCEL_JOBS && (!user || _cups_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"), 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_CANCEL_JOB) { /* * Open a connection to the server... */ if (http == NULL) if ((http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption())) == NULL) { _cupsLangPrintf(stderr, _("%s: Unable to contact server."), 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", (char)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"), argv[0], op == IPP_PURGE_JOBS ? "purge-jobs" : "cancel-job", cupsLastErrorString()); if (response) ippDelete(response); return (1); } ippDelete(response); } return (0); }
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); }
static int iprint_queue_get(const char *sharename, enum printing_types printing_type, char *lpq_command, print_queue_struct **q, print_status_struct *status) { fstring printername; http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ ipp_attribute_t *attr = NULL; /* Current attribute */ cups_lang_t *language = NULL; /* Default language */ char uri[HTTP_MAX_URI]; /* printer-uri attribute */ char serviceUri[HTTP_MAX_URI]; /* service-uri attribute */ char httpPath[HTTP_MAX_URI]; /* path portion of the uri */ int jobUseUnixTime = 0; /* Whether job times should * be assumed to be Unix time */ int qcount = 0, /* Number of active queue entries */ qalloc = 0; /* Number of queue entries allocated */ print_queue_struct *queue = NULL, /* Queue entries */ *temp; /* Temporary pointer for queue */ const char *user_name, /* job-originating-user-name attribute */ *job_name; /* job-name attribute */ int job_id; /* job-id attribute */ int job_k_octets; /* job-k-octets attribute */ time_t job_time; /* time-at-creation attribute */ time_t printer_current_time = 0; /* printer's current time */ time_t printer_up_time = 0; /* printer's uptime */ ipp_jstate_t job_status; /* job-status attribute */ int job_priority; /* job-priority attribute */ static const char *jattrs[] = /* Requested job attributes */ { "job-id", "job-k-octets", "job-name", "job-originating-user-name", "job-priority", "job-state", "time-at-creation", }; static const char *pattrs[] = /* Requested printer attributes */ { "printer-state", "printer-state-message", "printer-current-time", "printer-up-time" }; *q = NULL; /* HACK ALERT!!! The porblem with support the 'printer name' option is that we key the tdb off the sharename. So we will overload the lpq_command string to pass in the printername (which is basically what we do for non-cups printers ... using the lpq_command to get the queue listing). */ fstrcpy( printername, lpq_command ); DEBUG(5,("iprint_queue_get(%s, %p, %p)\n", printername, q, status)); /* * Make sure we don't ask for passwords... */ cupsSetPasswordCB(iprint_passwd_cb); /* * Try to connect to the server... */ if ((http = httpConnect(iprint_server(), ippPort())) == NULL) { DEBUG(0,("Unable to connect to iPrint server %s - %s\n", iprint_server(), strerror(errno))); goto out; } /* * Generate the printer URI and the service URI that goes with it... */ slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), printername); slprintf(serviceUri, sizeof(serviceUri) - 1, "ipp://%s/ipp/", iprint_server()); /* * For Linux iPrint servers from OES SP1 on, the iPrint server * uses Unix time for job start times unless it detects the iPrint * client in an http User-Agent header. (This was done to accomodate * CUPS broken behavior. According to RFC 2911, section 4.3.14, job * start times are supposed to be relative to how long the printer has * been up.) Since libcups doesn't allow us to set that header before * the request is sent, this ugly hack allows us to detect the server * version and decide how to interpret the job time. */ if (iprint_get_server_version(http, serviceUri) >= NOVELL_SERVER_VERSION_OES_SP1) jobUseUnixTime = 1; request = ippNew(); request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES; request->request.op.request_id = 2; language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (sizeof(pattrs) / sizeof(pattrs[0])), NULL, pattrs); /* * Do the request and get back a response... */ slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", printername); if ((response = cupsDoRequest(http, request, httpPath)) == NULL) { DEBUG(0,("Unable to get printer status for %s - %s\n", printername, ippErrorString(cupsLastError()))); *q = queue; goto out; } if (response->request.status.status_code >= IPP_OK_CONFLICT) { DEBUG(0,("Unable to get printer status for %s - %s\n", printername, ippErrorString(response->request.status.status_code))); *q = queue; goto out; } /* * Get the current printer status and convert it to the SAMBA values. */ if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL) { if (attr->values[0].integer == IPP_PRINTER_STOPPED) status->status = LPSTAT_STOPPED; else status->status = LPSTAT_OK; } if ((attr = ippFindAttribute(response, "printer-state-message", IPP_TAG_TEXT)) != NULL) fstrcpy(status->message, attr->values[0].string.text); if ((attr = ippFindAttribute(response, "printer-current-time", IPP_TAG_DATE)) != NULL) printer_current_time = ippDateToTime(attr->values[0].date); if ((attr = ippFindAttribute(response, "printer-up-time", IPP_TAG_INTEGER)) != NULL) printer_up_time = attr->values[0].integer; ippDelete(response); response = NULL; /* * Build an IPP_GET_JOBS request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * requested-attributes * printer-uri */ request = ippNew(); request->request.op.operation_id = IPP_GET_JOBS; request->request.op.request_id = 3; ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (sizeof(jattrs) / sizeof(jattrs[0])), NULL, jattrs); /* * Do the request and get back a response... */ slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", printername); if ((response = cupsDoRequest(http, request, httpPath)) == NULL) { DEBUG(0,("Unable to get jobs for %s - %s\n", uri, ippErrorString(cupsLastError()))); goto out; } if (response->request.status.status_code >= IPP_OK_CONFLICT) { DEBUG(0,("Unable to get jobs for %s - %s\n", uri, ippErrorString(response->request.status.status_code))); goto out; } /* * Process the jobs... */ qcount = 0; qalloc = 0; queue = NULL; for (attr = response->attrs; attr != NULL; attr = attr->next) { /* * Skip leading attributes until we hit a job... */ while (attr != NULL && attr->group_tag != IPP_TAG_JOB) attr = attr->next; if (attr == NULL) break; /* * Allocate memory as needed... */ if (qcount >= qalloc) { qalloc += 16; queue = SMB_REALLOC_ARRAY(queue, print_queue_struct, qalloc); if (queue == NULL) { DEBUG(0,("iprint_queue_get: Not enough memory!")); qcount = 0; goto out; } } temp = queue + qcount; memset(temp, 0, sizeof(print_queue_struct)); /* * Pull the needed attributes from this job... */ job_id = 0; job_priority = 50; job_status = IPP_JOB_PENDING; job_time = 0; job_k_octets = 0; user_name = NULL; job_name = NULL; while (attr != NULL && attr->group_tag == IPP_TAG_JOB) { if (attr->name == NULL) { attr = attr->next; break; } if (strcmp(attr->name, "job-id") == 0 && attr->value_tag == IPP_TAG_INTEGER) job_id = attr->values[0].integer; if (strcmp(attr->name, "job-k-octets") == 0 && attr->value_tag == IPP_TAG_INTEGER) job_k_octets = attr->values[0].integer; if (strcmp(attr->name, "job-priority") == 0 && attr->value_tag == IPP_TAG_INTEGER) job_priority = attr->values[0].integer; if (strcmp(attr->name, "job-state") == 0 && attr->value_tag == IPP_TAG_ENUM) job_status = (ipp_jstate_t)(attr->values[0].integer); if (strcmp(attr->name, "time-at-creation") == 0 && attr->value_tag == IPP_TAG_INTEGER) { /* * If jobs times are in Unix time, the accuracy of the job * start time depends upon the iPrint server's time being * set correctly. Otherwise, the accuracy depends upon * the Samba server's time being set correctly */ if (jobUseUnixTime) job_time = attr->values[0].integer; else job_time = time(NULL) - printer_up_time + attr->values[0].integer; } if (strcmp(attr->name, "job-name") == 0 && (attr->value_tag == IPP_TAG_NAMELANG || attr->value_tag == IPP_TAG_NAME)) job_name = attr->values[0].string.text; if (strcmp(attr->name, "job-originating-user-name") == 0 && (attr->value_tag == IPP_TAG_NAMELANG || attr->value_tag == IPP_TAG_NAME)) user_name = attr->values[0].string.text; attr = attr->next; } /* * See if we have everything needed... */ if (user_name == NULL || job_name == NULL || job_id == 0) { if (attr == NULL) break; else continue; } temp->job = job_id; temp->size = job_k_octets * 1024; temp->status = job_status == IPP_JOB_PENDING ? LPQ_QUEUED : job_status == IPP_JOB_STOPPED ? LPQ_PAUSED : job_status == IPP_JOB_HELD ? LPQ_PAUSED : LPQ_PRINTING; temp->priority = job_priority; temp->time = job_time; strncpy(temp->fs_user, user_name, sizeof(temp->fs_user) - 1); strncpy(temp->fs_file, job_name, sizeof(temp->fs_file) - 1); qcount ++; if (attr == NULL) break; } /* * Return the job queue... */ *q = queue; out: if (response) ippDelete(response); if (language) cupsLangFree(language); if (http) httpClose(http); return qcount; }
static int iprint_job_submit(int snum, struct printjob *pjob) { int ret = 1; /* Return value */ http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ ipp_attribute_t *attr; /* Current attribute */ cups_lang_t *language = NULL; /* Default language */ char uri[HTTP_MAX_URI]; /* printer-uri attribute */ char *clientname = NULL; /* hostname of client for job-originating-host attribute */ DEBUG(5,("iprint_job_submit(%d, %p (%d))\n", snum, pjob, pjob->sysjob)); /* * Make sure we don't ask for passwords... */ cupsSetPasswordCB(iprint_passwd_cb); /* * Try to connect to the server... */ if ((http = httpConnect(iprint_server(), ippPort())) == NULL) { DEBUG(0,("Unable to connect to iPrint server %s - %s\n", iprint_server(), strerror(errno))); goto out; } /* * Build an IPP_PRINT_JOB request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * requesting-user-name * [document-data] */ request = ippNew(); request->request.op.operation_id = IPP_PRINT_JOB; request->request.op.request_id = 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(), PRINTERNAME(snum)); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, pjob->user); clientname = client_name(); if (strcmp(clientname, "UNKNOWN") == 0) { clientname = client_addr(); } ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-originating-host-name", NULL, clientname); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, pjob->jobname); /* * Do the request and get back a response... */ slprintf(uri, sizeof(uri) - 1, "/ipp/%s", PRINTERNAME(snum)); if ((response = cupsDoFileRequest(http, request, uri, pjob->filename)) != NULL) { if (response->request.status.status_code >= IPP_OK_CONFLICT) { DEBUG(0,("Unable to print file to %s - %s\n", PRINTERNAME(snum), ippErrorString(cupsLastError()))); } else { ret = 0; } } else { DEBUG(0,("Unable to print file to `%s' - %s\n", PRINTERNAME(snum), ippErrorString(cupsLastError()))); } if ( ret == 0 ) unlink(pjob->filename); /* else print_job_end will do it for us */ if ( ret == 0 ) { attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER); if (attr != NULL && attr->group_tag == IPP_TAG_JOB) { pjob->sysjob = attr->values[0].integer; } } out: if (response) ippDelete(response); if (language) cupsLangFree(language); if (http) httpClose(http); return ret; }
static int iprint_get_server_version(http_t *http, char* serviceUri) { ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ ipp_attribute_t *attr; /* Current attribute */ cups_lang_t *language = NULL; /* Default language */ char *ver; /* server version pointer */ char *vertmp; /* server version tmp pointer */ int serverVersion = 0; /* server version */ char *os; /* server os */ int osFlag = 0; /* 0 for NetWare, 1 for anything else */ char *temp; /* pointer for string manipulation */ /* * Build an OPERATION_NOVELL_MGMT("get-server-version") request, * which requires the following attributes: * * attributes-charset * attributes-natural-language * operation-name * service-uri */ request = ippNew(); request->request.op.operation_id = OPERATION_NOVELL_MGMT; request->request.op.request_id = 1; language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "service-uri", NULL, serviceUri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "operation-name", NULL, "get-server-version"); /* * Do the request and get back a response... */ if (((response = cupsDoRequest(http, request, "/ipp/")) == NULL) || (response->request.status.status_code >= IPP_OK_CONFLICT)) goto out; if (((attr = ippFindAttribute(response, "server-version", IPP_TAG_STRING)) != NULL)) { if ((ver = strstr(attr->values[0].string.text, NOVELL_SERVER_VERSION_STRING)) != NULL) { ver += strlen(NOVELL_SERVER_VERSION_STRING); /* * Strangely, libcups stores a IPP_TAG_STRING (octet * string) as a null-terminated string with no length * even though it could be binary data with nulls in * it. Luckily, in this case the value is not binary. */ serverVersion = strtol(ver, &vertmp, 10); /* Check for not found, overflow or negative version */ if ((ver == vertmp) || (serverVersion < 0)) serverVersion = 0; } if ((os = strstr(attr->values[0].string.text, NOVELL_SERVER_SYSNAME)) != NULL) { os += strlen(NOVELL_SERVER_SYSNAME); if ((temp = strchr(os,'<')) != NULL) *temp = '\0'; if (strcmp(os,NOVELL_SERVER_SYSNAME_NETWARE)) osFlag = 1; /* 1 for non-NetWare systems */ } } out: if (response) ippDelete(response); if (language) cupsLangFree(language); if (osFlag == 0) serverVersion *= -1; return serverVersion; }
static void show_class(http_t *http, /* I - Connection to server */ const char *pclass) /* I - Name of class */ { ipp_t *request, /* IPP request */ *response; /* IPP response */ ipp_attribute_t *attr; /* IPP attribute */ char uri[HTTP_MAX_URI]; /* Printer URI */ char refresh[1024]; /* Refresh URL */ /* * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri */ request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/classes/%s", pclass); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); cgiGetAttributes(request, "class.tmpl"); /* * Do the request and get back a response... */ if ((response = cupsDoRequest(http, request, "/")) != NULL) { /* * Got the result; set the CGI variables and check the status of a * single-queue request... */ cgiSetIPPVars(response, NULL, NULL, NULL, 0); if (pclass && (attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL && attr->values[0].integer == IPP_PRINTER_PROCESSING) { /* * Class is processing - automatically refresh the page until we * are done printing... */ cgiFormEncode(uri, pclass, sizeof(uri)); snprintf(refresh, sizeof(refresh), "10;URL=/classes/%s", uri); cgiSetVariable("refresh_page", refresh); } /* * Delete the response... */ ippDelete(response); /* * Show the standard header... */ cgiStartHTML(pclass); /* * Show the class status... */ cgiCopyTemplateLang("class.tmpl"); /* * Show jobs for the specified class... */ cgiCopyTemplateLang("class-jobs-header.tmpl"); cgiShowJobs(http, pclass); } else { /* * Show the IPP error... */ cgiStartHTML(pclass); cgiShowIPPError(_("Unable to get class status")); } cgiEndHTML(); }
static void _pp_maintenance_command_execute_thread (GTask *task, gpointer source_object, gpointer task_data, GCancellable *cancellable) { PpMaintenanceCommand *command = PP_MAINTENANCE_COMMAND (source_object); PpMaintenanceCommandPrivate *priv = command->priv; gboolean success = FALSE; GError *error = NULL; if (_pp_maintenance_command_is_supported (priv->printer_name, priv->command)) { ipp_t *request; ipp_t *response = NULL; gchar *printer_uri; gchar *file_name = NULL; int fd = -1; printer_uri = g_strdup_printf ("ipp://localhost/printers/%s", priv->printer_name); request = ippNewRequest (IPP_PRINT_JOB); ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, printer_uri); ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, priv->title); ippAddString (request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, "document-format", NULL, "application/vnd.cups-command"); fd = g_file_open_tmp ("ccXXXXXX", &file_name, &error); if (fd != -1) { FILE *file; file = fdopen (fd, "w"); fprintf (file, "#CUPS-COMMAND\n"); fprintf (file, "%s\n", priv->command); fclose (file); response = cupsDoFileRequest (CUPS_HTTP_DEFAULT, request, "/", file_name); g_unlink (file_name); if (response != NULL) { if (ippGetStatusCode (response) <= IPP_OK_CONFLICT) { success = TRUE; } ippDelete (response); } } g_free (file_name); g_free (printer_uri); } else { success = TRUE; } if (!success) { g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, "Execution of maintenance command failed."); } g_task_return_boolean (task, success); }
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 gboolean _pp_maintenance_command_is_supported (const gchar *printer_name, const gchar *command) { ipp_attribute_t *attr = NULL; gboolean is_supported = FALSE; ipp_t *request; ipp_t *response = NULL; gchar *printer_uri; gchar *command_lowercase; GPtrArray *available_commands = NULL; int i; printer_uri = g_strdup_printf ("ipp://localhost/printers/%s", printer_name); request = ippNewRequest (IPP_GET_PRINTER_ATTRIBUTES); ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, printer_uri); ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", NULL, "printer-commands"); response = cupsDoRequest (CUPS_HTTP_DEFAULT, request, "/"); if (response != NULL) { if (ippGetStatusCode (response) <= IPP_OK_CONFLICT) { int commands_count; attr = ippFindAttribute (response, "printer-commands", IPP_TAG_ZERO); commands_count = attr != NULL ? ippGetCount (attr) : 0; if (commands_count > 0 && ippGetValueTag (attr) != IPP_TAG_NOVALUE && (ippGetValueTag (attr) == IPP_TAG_KEYWORD)) { available_commands = g_ptr_array_new_full (commands_count, g_free); for (i = 0; i < commands_count; ++i) { /* Array gains ownership of the lower-cased string */ g_ptr_array_add (available_commands, g_ascii_strdown (ippGetString (attr, i, NULL), -1)); } } } ippDelete (response); } if (available_commands != NULL) { command_lowercase = g_ascii_strdown (command, -1); for (i = 0; i < available_commands->len; ++i) { const gchar *available_command = g_ptr_array_index (available_commands, i); if (g_strcmp0 (available_command, command_lowercase) == 0) { is_supported = TRUE; break; } } g_free (command_lowercase); g_ptr_array_free (available_commands, TRUE); } g_free (printer_uri); return is_supported; }
static int /* O - 0 on success, 1 on fail */ add_printer_to_class(http_t *http, /* I - Server connection */ char *printer, /* I - Printer to add */ char *pclass) /* I - Class to add to */ { int i; /* Looping var */ ipp_t *request, /* IPP Request */ *response; /* IPP Response */ ipp_attribute_t *attr, /* Current attribute */ *members; /* Members in class */ char uri[HTTP_MAX_URI]; /* URI for printer/class */ DEBUG_printf(("add_printer_to_class(%p, \"%s\", \"%s\")\n", http, printer, pclass)); /* * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * requesting-user-name */ request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/classes/%s", pclass); 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()); /* * Do the request and get back a response... */ response = cupsDoRequest(http, request, "/"); /* * Build a CUPS_ADD_MODIFY_CLASS request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * requesting-user-name * member-uris */ request = ippNewRequest(CUPS_ADD_MODIFY_CLASS); 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()); /* * See if the printer is already in the class... */ if (response != NULL && (members = ippFindAttribute(response, "member-names", IPP_TAG_NAME)) != NULL) for (i = 0; i < members->num_values; i ++) if (_cups_strcasecmp(printer, members->values[i].string.text) == 0) { _cupsLangPrintf(stderr, _("lpadmin: Printer %s is already a member of class " "%s."), printer, pclass); ippDelete(request); ippDelete(response); return (0); } /* * OK, the printer isn't part of the class, so add it... */ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/printers/%s", printer); if (response != NULL && (members = ippFindAttribute(response, "member-uris", IPP_TAG_URI)) != NULL) { /* * Add the printer to the existing list... */ attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_URI, "member-uris", members->num_values + 1, NULL, NULL); for (i = 0; i < members->num_values; i ++) attr->values[i].string.text = _cupsStrAlloc(members->values[i].string.text); attr->values[i].string.text = _cupsStrAlloc(uri); } else ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_URI, "member-uris", NULL, uri); /* * Then send the request... */ ippDelete(response); ippDelete(cupsDoRequest(http, request, "/admin/")); if (cupsLastError() > IPP_OK_CONFLICT) { _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString()); return (1); } else return (0); }
static bool cups_cache_reload_async(int fd) { TALLOC_CTX *frame = talloc_stackframe(); struct pcap_cache *tmp_pcap_cache = NULL; http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ ipp_attribute_t *attr; /* Current attribute */ cups_lang_t *language = NULL; /* Default language */ char *name, /* printer-name attribute */ *info; /* printer-info attribute */ static const char *requested[] =/* Requested attributes */ { "printer-name", "printer-info" }; bool ret = False; size_t size; DEBUG(5, ("reloading cups printcap cache\n")); /* * Make sure we don't ask for passwords... */ cupsSetPasswordCB(cups_passwd_cb); /* * Try to connect to the server... */ if ((http = cups_connect(frame)) == NULL) { goto out; } /* * Build a CUPS_GET_PRINTERS request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * requested-attributes */ request = ippNew(); request->request.op.operation_id = CUPS_GET_PRINTERS; request->request.op.request_id = 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); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requested-attributes", (sizeof(requested) / sizeof(requested[0])), NULL, requested); /* * Do the request and get back a response... */ if ((response = cupsDoRequest(http, request, "/")) == NULL) { DEBUG(0,("Unable to get printer list - %s\n", ippErrorString(cupsLastError()))); goto out; } for (attr = response->attrs; attr != NULL;) { /* * Skip leading attributes until we hit a printer... */ while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER) attr = attr->next; if (attr == NULL) break; /* * Pull the needed attributes from this printer... */ name = NULL; info = NULL; while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) { if (strcmp(attr->name, "printer-name") == 0 && attr->value_tag == IPP_TAG_NAME) { if (!pull_utf8_talloc(frame, &name, attr->values[0].string.text, &size)) { goto out; } } if (strcmp(attr->name, "printer-info") == 0 && attr->value_tag == IPP_TAG_TEXT) { if (!pull_utf8_talloc(frame, &info, attr->values[0].string.text, &size)) { goto out; } } attr = attr->next; } /* * See if we have everything needed... */ if (name == NULL) break; if (!pcap_cache_add_specific(&tmp_pcap_cache, name, info)) { goto out; } } ippDelete(response); response = NULL; /* * Build a CUPS_GET_CLASSES request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * requested-attributes */ request = ippNew(); request->request.op.operation_id = CUPS_GET_CLASSES; 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, language->language); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requested-attributes", (sizeof(requested) / sizeof(requested[0])), NULL, requested); /* * Do the request and get back a response... */ if ((response = cupsDoRequest(http, request, "/")) == NULL) { DEBUG(0,("Unable to get printer list - %s\n", ippErrorString(cupsLastError()))); goto out; } for (attr = response->attrs; attr != NULL;) { /* * Skip leading attributes until we hit a printer... */ while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER) attr = attr->next; if (attr == NULL) break; /* * Pull the needed attributes from this printer... */ name = NULL; info = NULL; while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) { if (strcmp(attr->name, "printer-name") == 0 && attr->value_tag == IPP_TAG_NAME) { if (!pull_utf8_talloc(frame, &name, attr->values[0].string.text, &size)) { goto out; } } if (strcmp(attr->name, "printer-info") == 0 && attr->value_tag == IPP_TAG_TEXT) { if (!pull_utf8_talloc(frame, &info, attr->values[0].string.text, &size)) { goto out; } } attr = attr->next; } /* * See if we have everything needed... */ if (name == NULL) break; if (!pcap_cache_add_specific(&tmp_pcap_cache, name, info)) { goto out; } } ret = True; out: if (response) ippDelete(response); if (language) cupsLangFree(language); if (http) httpClose(http); /* Send all the entries up the pipe. */ if (tmp_pcap_cache) { pcap_printer_fn_specific(tmp_pcap_cache, send_pcap_info, (void *)&fd); pcap_cache_destroy_specific(&tmp_pcap_cache); } TALLOC_FREE(frame); return ret; }
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(); }
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); } }
void cgiPrintTestPage(http_t *http, /* I - Connection to server */ const char *dest) /* I - Destination printer/class */ { ipp_t *request, /* IPP request */ *response; /* IPP response */ char uri[HTTP_MAX_URI], /* Printer URI */ resource[1024], /* POST resource path */ refresh[1024], /* Refresh URL */ filename[1024]; /* Test page filename */ const char *datadir; /* CUPS_DATADIR env var */ const char *user; /* Username */ /* * See who is logged in... */ user = getenv("REMOTE_USER"); /* * Locate the test page file... */ if ((datadir = getenv("CUPS_DATADIR")) == NULL) datadir = CUPS_DATADIR; snprintf(filename, sizeof(filename), "%s/data/testprint", datadir); /* * Point to the printer/class... */ 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); /* * Build an IPP_PRINT_JOB request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * requesting-user-name */ request = ippNewRequest(IPP_PRINT_JOB); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); if (user) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, user); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, "Test Page"); /* * Do the request and get back a response... */ if ((response = cupsDoFileRequest(http, request, resource, filename)) != NULL) { cgiSetIPPVars(response, NULL, NULL, NULL, 0); ippDelete(response); } if (cupsLastError() <= IPP_OK_CONFLICT) { /* * Automatically reload the printer status page... */ cgiFormEncode(uri, resource, sizeof(uri)); snprintf(refresh, sizeof(refresh), "2;URL=%s", uri); cgiSetVariable("refresh_page", refresh); } else if (cupsLastError() == IPP_NOT_AUTHORIZED) { puts("Status: 401\n"); exit(0); } cgiStartHTML(cgiText(_("Print Test Page"))); if (cupsLastError() > IPP_OK_CONFLICT) cgiShowIPPError(_("Unable to print test page")); else { cgiSetVariable("PRINTER_NAME", dest); cgiCopyTemplateLang("test-page.tmpl"); } cgiEndHTML(); }
int /* O - Exit status */ main(int argc, /* I - Number of command-line args */ char *argv[]) /* I - Command-line arguments */ { int i; /* Looping var */ const char *opt, /* Current option character */ *name = NULL, /* Service name */ *type = "_ipp._tcp", /* Service type */ *domain = "local."; /* Service domain */ #ifdef HAVE_DNSSD DNSServiceRef ref; /* Browsing service reference */ #endif /* HAVE_DNSSD */ #ifdef HAVE_AVAHI AvahiClient *client; /* Client information */ int error; /* Error code, if any */ #endif /* HAVE_AVAHI */ for (i = 1; i < argc; i ++) if (!strcmp(argv[i], "snmp")) snmponly = 1; else if (!strcmp(argv[i], "ipp")) ipponly = 1; else { puts("Usage: ./ipp-printers [{ipp | snmp}]"); return (1); } /* * Create an array to track devices... */ devices = cupsArrayNew((cups_array_func_t)compare_devices, NULL); /* * Browse for different kinds of printers... */ if (DNSServiceCreateConnection(&main_ref) != kDNSServiceErr_NoError) { perror("ERROR: Unable to create service connection"); return (1); } fd = DNSServiceRefSockFD(main_ref); ipp_ref = main_ref; DNSServiceBrowse(&ipp_ref, kDNSServiceFlagsShareConnection, 0, "_ipp._tcp", NULL, browse_callback, devices); /* * Loop until we are killed... */ progress(); for (;;) { FD_ZERO(&input); FD_SET(fd, &input); timeout.tv_sec = 2; timeout.tv_usec = 500000; if (select(fd + 1, &input, NULL, NULL, &timeout) <= 0) { time_t curtime = time(NULL); for (device = (cups_device_t *)cupsArrayFirst(devices); device; device = (cups_device_t *)cupsArrayNext(devices)) if (!device->got_resolve) { if (!device->ref) break; if ((curtime - device->resolve_time) > 10) { device->got_resolve = -1; fprintf(stderr, "\rUnable to resolve \"%s\": timeout\n", device->name); progress(); } else break; } if (!device) break; } if (FD_ISSET(fd, &input)) { /* * Process results of our browsing... */ progress(); DNSServiceProcessResult(main_ref); } else { /* * Query any devices we've found... */ DNSServiceErrorType status; /* DNS query status */ int count; /* Number of queries */ for (device = (cups_device_t *)cupsArrayFirst(devices), count = 0; device; device = (cups_device_t *)cupsArrayNext(devices)) { if (!device->ref && !device->sent) { /* * Found the device, now get the TXT record(s) for it... */ if (count < 50) { device->resolve_time = time(NULL); device->ref = main_ref; status = DNSServiceResolve(&(device->ref), kDNSServiceFlagsShareConnection, 0, device->name, device->regtype, device->domain, resolve_callback, device); if (status != kDNSServiceErr_NoError) { fprintf(stderr, "\rUnable to resolve \"%s\": %d\n", device->name, status); progress(); } else count ++; } } else if (!device->sent && device->got_resolve) { /* * Got the TXT records, now report the device... */ DNSServiceRefDeallocate(device->ref); device->ref = 0; device->sent = 1; } } } } #ifndef DEBUG fprintf(stderr, "\rFound %d printers. Now querying for capabilities...\n", cupsArrayCount(devices)); #endif /* !DEBUG */ puts("#!/bin/sh -x"); puts("test -d results && rm -rf results"); puts("mkdir results"); puts("CUPS_DEBUG_LEVEL=6; export CUPS_DEBUG_LEVEL"); puts("CUPS_DEBUG_FILTER='^(ipp|http|_ipp|_http|cupsGetResponse|cupsSend|" "cupsWrite|cupsDo).*'; export CUPS_DEBUG_FILTER"); for (device = (cups_device_t *)cupsArrayFirst(devices); device; device = (cups_device_t *)cupsArrayNext(devices)) { if (device->got_resolve <= 0 || device->cups_shared) continue; #ifdef DEBUG fprintf(stderr, "Checking \"%s\" (got_resolve=%d, cups_shared=%d, uri=%s)\n", device->name, device->got_resolve, device->cups_shared, device->uri); #else fprintf(stderr, "Checking \"%s\"...\n", device->name); #endif /* DEBUG */ if ((http = httpConnect(device->host, device->port)) == NULL) { fprintf(stderr, "Failed to connect to \"%s\": %s\n", device->name, cupsLastErrorString()); continue; } request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, device->uri); response = cupsDoRequest(http, request, device->rp); if (cupsLastError() > IPP_OK_SUBST) fprintf(stderr, "Failed to query \"%s\": %s\n", device->name, cupsLastErrorString()); else { if ((attr = ippFindAttribute(response, "ipp-versions-supported", IPP_TAG_KEYWORD)) != NULL) { version = attr->values[0].string.text; for (i = 1; i < attr->num_values; i ++) if (strcmp(attr->values[i].string.text, version) > 0) version = attr->values[i].string.text; } else version = "1.0"; testfile = NULL; if ((attr = ippFindAttribute(response, "document-format-supported", IPP_TAG_MIMETYPE)) != NULL) { /* * Figure out the test file for printing, preferring PDF and PostScript * over JPEG and plain text... */ for (i = 0; i < attr->num_values; i ++) { if (!strcasecmp(attr->values[i].string.text, "application/pdf")) { testfile = "testfile.pdf"; break; } else if (!strcasecmp(attr->values[i].string.text, "application/postscript")) testfile = "testfile.ps"; else if (!strcasecmp(attr->values[i].string.text, "image/jpeg") && !testfile) testfile = "testfile.jpg"; else if (!strcasecmp(attr->values[i].string.text, "text/plain") && !testfile) testfile = "testfile.txt"; else if (!strcasecmp(attr->values[i].string.text, "application/vnd.hp-PCL") && !testfile) testfile = "testfile.pcl"; } if (!testfile) { fprintf(stderr, "Printer \"%s\" reports the following IPP file formats:\n", device->name); for (i = 0; i < attr->num_values; i ++) fprintf(stderr, " \"%s\"\n", attr->values[i].string.text); } } if (!testfile && device->pdl) { char *pdl, /* Copy of pdl string */ *start, *end; /* Pointers into pdl string */ pdl = strdup(device->pdl); for (start = device->pdl; start && *start; start = end) { if ((end = strchr(start, ',')) != NULL) *end++ = '\0'; if (!strcasecmp(start, "application/pdf")) { testfile = "testfile.pdf"; break; } else if (!strcasecmp(start, "application/postscript")) testfile = "testfile.ps"; else if (!strcasecmp(start, "image/jpeg") && !testfile) testfile = "testfile.jpg"; else if (!strcasecmp(start, "text/plain") && !testfile) testfile = "testfile.txt"; else if (!strcasecmp(start, "application/vnd.hp-PCL") && !testfile) testfile = "testfile.pcl"; } free(pdl); if (testfile) { fprintf(stderr, "Using \"%s\" for printer \"%s\" based on TXT record pdl " "info.\n", testfile, device->name); } else { fprintf(stderr, "Printer \"%s\" reports the following TXT file formats:\n", device->name); fprintf(stderr, " \"%s\"\n", device->pdl); } } if (!device->ty && (attr = ippFindAttribute(response, "printer-make-and-model", IPP_TAG_TEXT)) != NULL) device->ty = strdup(attr->values[0].string.text); if (strcmp(version, "1.0") && testfile && device->ty) { char filename[1024], /* Filename */ *fileptr; /* Pointer into filename */ const char *typtr; /* Pointer into ty */ if (!strncasecmp(device->ty, "DeskJet", 7) || !strncasecmp(device->ty, "DesignJet", 9) || !strncasecmp(device->ty, "OfficeJet", 9) || !strncasecmp(device->ty, "Photosmart", 10)) strlcpy(filename, "HP_", sizeof(filename)); else filename[0] = '\0'; fileptr = filename + strlen(filename); if (!strncasecmp(device->ty, "Lexmark International Lexmark", 29)) typtr = device->ty + 22; else typtr = device->ty; while (*typtr && fileptr < (filename + sizeof(filename) - 1)) { if (isalnum(*typtr & 255) || *typtr == '-') *fileptr++ = *typtr++; else { *fileptr++ = '_'; typtr++; } } *fileptr = '\0'; printf("# %s\n", device->name); printf("echo \"Testing %s...\"\n", device->name); if (!ipponly) { printf("echo \"snmpwalk -c public -v 1 -Cc %s 1.3.6.1.2.1.25 " "1.3.6.1.2.1.43 1.3.6.1.4.1.2699.1\" > results/%s.snmpwalk\n", device->host, filename); printf("snmpwalk -c public -v 1 -Cc %s 1.3.6.1.2.1.25 " "1.3.6.1.2.1.43 1.3.6.1.4.1.2699.1 | " "tee -a results/%s.snmpwalk\n", device->host, filename); } if (!snmponly) { printf("echo \"./ipptool-static -tIf %s -T 30 -d NOPRINT=1 -V %s %s " "ipp-%s.test\" > results/%s.log\n", testfile, version, device->uri, version, filename); printf("CUPS_DEBUG_LOG=results/%s.debug_log " "./ipptool-static -tIf %s -T 30 -d NOPRINT=1 -V %s %s " "ipp-%s.test | tee -a results/%s.log\n", filename, testfile, version, device->uri, version, filename); } puts(""); } else if (!device->ty) fprintf(stderr, "Ignoring \"%s\" since it doesn't provide a make and model.\n", device->name); else if (!testfile) fprintf(stderr, "Ignoring \"%s\" since it does not support a common format.\n", device->name); else fprintf(stderr, "Ignoring \"%s\" since it only supports IPP/1.0.\n", device->name); } ippDelete(response); httpClose(http); } return (0); }
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", (char)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); }
static void do_class_op(http_t *http, /* I - HTTP connection */ const char *printer, /* I - Printer name */ ipp_op_t op, /* I - Operation to perform */ const char *title) /* I - Title of page */ { ipp_t *request; /* IPP request */ char uri[HTTP_MAX_URI], /* Printer URI */ resource[HTTP_MAX_URI]; /* Path for request */ /* * Build a printer request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri */ request = ippNewRequest(op); httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/classes/%s", printer); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); /* * Do the request and get back a response... */ snprintf(resource, sizeof(resource), "/classes/%s", printer); ippDelete(cupsDoRequest(http, request, resource)); if (cupsLastError() == IPP_NOT_AUTHORIZED) { puts("Status: 401\n"); exit(0); } else if (cupsLastError() > IPP_OK_CONFLICT) { cgiStartHTML(title); cgiShowIPPError(_("Unable to do maintenance command")); } else { /* * Redirect successful updates back to the printer page... */ char url[1024], /* Printer/class URL */ refresh[1024]; /* Refresh URL */ cgiRewriteURL(uri, url, sizeof(url), NULL); cgiFormEncode(uri, url, sizeof(uri)); snprintf(refresh, sizeof(refresh), "5;URL=%s", uri); cgiSetVariable("refresh_page", refresh); cgiStartHTML(title); cgiSetVariable("IS_CLASS", "YES"); if (op == IPP_PAUSE_PRINTER) cgiCopyTemplateLang("printer-stop.tmpl"); else if (op == IPP_RESUME_PRINTER) cgiCopyTemplateLang("printer-start.tmpl"); else if (op == CUPS_ACCEPT_JOBS) cgiCopyTemplateLang("printer-accept.tmpl"); else if (op == CUPS_REJECT_JOBS) cgiCopyTemplateLang("printer-reject.tmpl"); else if (op == IPP_PURGE_JOBS) cgiCopyTemplateLang("printer-purge.tmpl"); } cgiEndHTML(); }
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((unsigned)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); }
static void show_all_classes(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 *classes; /* Array of class objects */ ipp_attribute_t *pclass; /* Class object */ int ascending, /* Order of classes (0 = descending) */ first, /* First class to show */ count; /* Number of classes */ const char *var; /* Form variable */ void *search; /* Search data */ char val[1024]; /* Form variable */ /* * Show the standard header... */ cgiStartHTML(cgiText(_("Classes"))); /* * Build a CUPS_GET_CLASSES request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * requesting-user-name */ request = ippNewRequest(CUPS_GET_CLASSES); if (user) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, user); cgiGetAttributes(request, "classes.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; classes = cgiGetIPPObjects(response, search); count = cupsArrayCount(classes); if (search) cgiFreeSearch(search); /* * Figure out which classes 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, pclass = (ipp_attribute_t *)cupsArrayIndex(classes, first); i < CUPS_PAGE_MAX && pclass; i ++, pclass = (ipp_attribute_t *)cupsArrayNext(classes)) cgiSetIPPObjectVars(pclass, NULL, i); } else { for (i = 0, pclass = (ipp_attribute_t *)cupsArrayIndex(classes, count - first - 1); i < CUPS_PAGE_MAX && pclass; i ++, pclass = (ipp_attribute_t *)cupsArrayPrev(classes)) cgiSetIPPObjectVars(pclass, NULL, i); } /* * Save navigation URLs... */ cgiSetVariable("THISURL", "/classes/"); 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("classes-header.tmpl"); if (count > CUPS_PAGE_MAX) cgiCopyTemplateLang("pager.tmpl"); cgiCopyTemplateLang("classes.tmpl"); if (count > CUPS_PAGE_MAX) cgiCopyTemplateLang("pager.tmpl"); /* * Delete the response... */ cupsArrayDelete(classes); ippDelete(response); } else { /* * Show the error... */ cgiShowIPPError(_("Unable to get class list")); } cgiEndHTML(); }
int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { int i; /* Looping var */ char *command, /* Command to do */ uri[1024], /* Printer URI */ *reason; /* Reason for reject/disable */ ipp_t *request; /* IPP request */ ipp_op_t op; /* Operation */ int cancel; /* Cancel jobs? */ _cupsSetLocale(argv); /* * See what operation we're supposed to do... */ if ((command = strrchr(argv[0], '/')) != NULL) command ++; else command = argv[0]; cancel = 0; if (!strcmp(command, "cupsaccept") || !strcmp(command, "accept")) op = CUPS_ACCEPT_JOBS; else if (!strcmp(command, "cupsreject") || !strcmp(command, "reject")) op = CUPS_REJECT_JOBS; else if (!strcmp(command, "cupsdisable") || !strcmp(command, "disable")) op = IPP_PAUSE_PRINTER; else if (!strcmp(command, "cupsenable") || !strcmp(command, "enable")) op = IPP_RESUME_PRINTER; else { _cupsLangPrintf(stderr, _("%s: Don't know what to do."), command); return (1); } reason = NULL; /* * Process command-line arguments... */ for (i = 1; i < argc; i ++) if (argv[i][0] == '-') { switch (argv[i][1]) { case 'E' : /* Encrypt */ #ifdef HAVE_SSL cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); #else _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), command); #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."), command); return (1); } cupsSetUser(argv[i]); } break; case 'c' : /* Cancel jobs */ cancel = 1; 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."), command); return (1); } cupsSetServer(argv[i]); } break; case 'r' : /* Reason for cancellation */ if (argv[i][2] != '\0') reason = argv[i] + 2; else { i ++; if (i >= argc) { _cupsLangPrintf(stderr, _("%s: Error - expected reason text after " "\"-r\" option."), command); return (1); } reason = argv[i]; } break; case '-' : if (!strcmp(argv[i], "--hold")) op = IPP_HOLD_NEW_JOBS; else if (!strcmp(argv[i], "--release")) op = IPP_RELEASE_HELD_NEW_JOBS; else { _cupsLangPrintf(stderr, _("%s: Error - unknown option \"%s\"."), command, argv[i]); return (1); } break; default : _cupsLangPrintf(stderr, _("%s: Error - unknown option \"%c\"."), command, argv[i][1]); return (1); } } else { /* * Accept/disable/enable/reject a destination... */ request = ippNewRequest(op); httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/printers/%s", argv[i]); 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()); if (reason != NULL) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT, "printer-state-message", NULL, reason); /* * Do the request and get back a response... */ ippDelete(cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/admin/")); if (cupsLastError() > IPP_OK_CONFLICT) { _cupsLangPrintf(stderr, _("%s: Operation failed: %s"), command, ippErrorString(cupsLastError())); return (1); } /* * Cancel all jobs if requested... */ if (cancel) { /* * Build an IPP_PURGE_JOBS request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri */ request = ippNewRequest(IPP_PURGE_JOBS); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippDelete(cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/admin/")); if (cupsLastError() > IPP_OK_CONFLICT) { _cupsLangPrintf(stderr, "%s: %s", command, cupsLastErrorString()); return (1); } } } return (0); }
BOOL iprint_cache_reload(void) { http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ ipp_attribute_t *attr; /* Current attribute */ cups_lang_t *language = NULL; /* Default language */ int i; BOOL ret = False; DEBUG(5, ("reloading iprint printcap cache\n")); /* * Make sure we don't ask for passwords... */ cupsSetPasswordCB(iprint_passwd_cb); /* * Try to connect to the server... */ if ((http = httpConnect(iprint_server(), ippPort())) == NULL) { DEBUG(0,("Unable to connect to iPrint server %s - %s\n", iprint_server(), strerror(errno))); goto out; } /* * Build a OPERATION_NOVELL_LIST_PRINTERS request, which requires the following attributes: * * attributes-charset * attributes-natural-language */ request = ippNew(); request->request.op.operation_id = OPERATION_NOVELL_LIST_PRINTERS; request->request.op.request_id = 1; language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "ipp-server", NULL, "ippSrvr"); /* * Do the request and get back a response... */ if ((response = cupsDoRequest(http, request, "/ipp")) == NULL) { DEBUG(0,("Unable to get printer list - %s\n", ippErrorString(cupsLastError()))); goto out; } for (attr = response->attrs; attr != NULL;) { /* * Skip leading attributes until we hit a printer... */ while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER) attr = attr->next; if (attr == NULL) break; /* * Pull the needed attributes from this printer... */ while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) { if (strcmp(attr->name, "printer-name") == 0 && (attr->value_tag == IPP_TAG_URI || attr->value_tag == IPP_TAG_NAME || attr->value_tag == IPP_TAG_TEXT || attr->value_tag == IPP_TAG_NAMELANG || attr->value_tag == IPP_TAG_TEXTLANG)) { for (i = 0; i<attr->num_values; i++) { char *url = attr->values[i].string.text; if (!url || !strlen(url)) continue; iprint_cache_add_printer(http, i+2, url); } } attr = attr->next; } } ret = True; out: if (response) ippDelete(response); if (language) cupsLangFree(language); if (http) httpClose(http); return ret; }