papi_status_t ipp_cancel_job(papi_service_t svc, papi_attribute_t **request, papi_attribute_t ***response) { papi_status_t status; papi_attribute_t **operational = NULL; char *message = NULL; char *queue = NULL; int id = -1; /* Get operational attributes from the request */ (void) papiAttributeListGetCollection(request, NULL, "operational-attributes-group", &operational); /* * the operational-attributes-group must contain: * job-uri (or printer-uri/job-id) */ get_printer_id(operational, &queue, &id); if (id < 0) { ipp_set_status(response, PAPI_BAD_REQUEST, "missing job-uri or job-id"); return (PAPI_BAD_REQUEST); } else if (queue == NULL) { ipp_set_status(response, PAPI_BAD_REQUEST, "missing printer-uri or job-uri"); return (PAPI_BAD_REQUEST); } /* * the operational-attributes-group may contain: * message */ (void) papiAttributeListGetString(operational, NULL, "message", &message); status = papiJobCancel(svc, queue, id); if (status != PAPI_OK) { ipp_set_status(response, status, "cancel failed: %s-%d: %s", (queue ? queue : "(null)"), id, ipp_svc_status_mesg(svc, status)); } else if (message != NULL) { /* add unsupported attribute group */ papi_attribute_t **unsupported = NULL; papiAttributeListAddValue(&unsupported, PAPI_ATTR_EXCL, "message", PAPI_COLLECTION, NULL); (void) papiAttributeListAddCollection(response, PAPI_ATTR_REPLACE, "unsupported-attributes-group", unsupported); papiAttributeListFree(unsupported); status = PAPI_OK_SUBST; ipp_set_status(response, status, "unsupported attribute in request"); } return (status); }
papi_status_t papiPrinterListJobs(papi_service_t handle, char *name, char **requested_attrs, int type_mask, int max_num_jobs, papi_job_t **jobs) { papi_status_t status, result = PAPI_INTERNAL_ERROR; service_t *svc = handle; papi_attribute_t **request = NULL, **op = NULL, **response = NULL; void *iter = NULL; if ((svc == NULL) || (name == NULL)) return (PAPI_BAD_ARGUMENT); /* if we are already connected, use that connection. */ if (svc->connection == NULL) if ((result = service_connect(svc, name)) != PAPI_OK) return (result); ipp_initialize_request(svc, &request, OPID_GET_JOBS); ipp_initialize_operational_attributes(svc, &op, name, -1); if (requested_attrs != NULL) { int i; for (i = 0; requested_attrs[i] != NULL; i++) papiAttributeListAddString(&op, PAPI_ATTR_APPEND, "requested-attributes", requested_attrs[i]); } papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, "operational-attributes-group", op); papiAttributeListFree(op); result = ipp_send_request(svc, request, &response); papiAttributeListFree(request); op = NULL; for (status = papiAttributeListGetCollection(response, &iter, "job-attributes-group", &op); status == PAPI_OK; status = papiAttributeListGetCollection(response, &iter, NULL, &op)) { job_t *j = NULL; if ((j = calloc(1, sizeof (*j))) == NULL) return (PAPI_TEMPORARY_ERROR); copy_attributes(&j->attributes, op); op = NULL; list_append(jobs, j); } papiAttributeListFree(response); return (result); }
papi_status_t papiPrinterModify(papi_service_t handle, char *name, papi_attribute_t **attributes, papi_printer_t *printer) { papi_status_t result = PAPI_INTERNAL_ERROR; service_t *svc = handle; printer_t *p = NULL; papi_attribute_t **request = NULL, **op = NULL, **response = NULL; if ((svc == NULL) || (name == NULL) || (printer == NULL)) return (PAPI_BAD_ARGUMENT); /* if we are already connected, use that connection. */ if (svc->connection == NULL) if ((result = service_connect(svc, name)) != PAPI_OK) return (result); if ((*printer = p = calloc(1, sizeof (*p))) == NULL) return (PAPI_TEMPORARY_ERROR); ipp_initialize_request(svc, &request, OPID_SET_PRINTER_ATTRIBUTES); ipp_initialize_operational_attributes(svc, &op, name, -1); papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, "operational-attributes-group", op); papiAttributeListFree(op); papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, "printer-attributes-group", attributes); result = ipp_send_request(svc, request, &response); papiAttributeListFree(request); op = NULL; papiAttributeListGetCollection(response, NULL, "printer-attributes-group", &op); copy_attributes(&p->attributes, op); papiAttributeListFree(response); return (result); }
papi_status_t papiPrintersList(papi_service_t handle, char **requested_attrs, papi_filter_t *filter, papi_printer_t **printers) { papi_status_t status, result = PAPI_INTERNAL_ERROR; service_t *svc = handle; papi_attribute_t **request = NULL, **op = NULL, **response = NULL; void *iter = NULL; if ((svc == NULL) || (printers == NULL)) return (PAPI_BAD_ARGUMENT); /* if we are already connected, use that connection. */ if (svc->connection == NULL) if ((result = service_connect(svc, DEFAULT_DEST)) != PAPI_OK) return (result); ipp_initialize_request(svc, &request, OPID_CUPS_GET_PRINTERS); ipp_initialize_operational_attributes(svc, &op, NULL, -1); if (requested_attrs != NULL) { int i; for (i = 0; requested_attrs[i] != NULL; i++) papiAttributeListAddString(&op, PAPI_ATTR_APPEND, "requested-attributes", requested_attrs[i]); } papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, "operational-attributes-group", op); papiAttributeListFree(op); result = ipp_send_request(svc, request, &response); papiAttributeListFree(request); op = NULL; for (status = papiAttributeListGetCollection(response, &iter, "printer-attributes-group", &op); status == PAPI_OK; status = papiAttributeListGetCollection(response, &iter, NULL, &op)) { printer_t *p = NULL; if ((p = calloc(1, sizeof (*p))) == NULL) return (PAPI_TEMPORARY_ERROR); copy_attributes(&p->attributes, op); op = NULL; list_append(printers, p); } papiAttributeListFree(response); return (result); }
static papi_status_t _printer_enable_disable_pause_resume_delete(papi_service_t handle, char *name, char *message, uint16_t type) { papi_status_t result = PAPI_INTERNAL_ERROR; service_t *svc = handle; papi_attribute_t **request = NULL, **op = NULL, **response = NULL; if ((svc == NULL) || (name == NULL)) return (PAPI_BAD_ARGUMENT); /* if we are already connected, use that connection. */ if (svc->connection == NULL) if ((result = service_connect(svc, name)) != PAPI_OK) return (result); ipp_initialize_request(svc, &request, type); ipp_initialize_operational_attributes(svc, &op, name, -1); switch (type) { case OPID_DISABLE_PRINTER: papiAttributeListAddString(&op, PAPI_ATTR_REPLACE, "printer-message-from-operator", message); break; case OPID_PAUSE_PRINTER: papiAttributeListAddString(&op, PAPI_ATTR_REPLACE, "printer-state-message", message); break; default: /* a message value is of no use */ break; } papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, "operational-attributes-group", op); papiAttributeListFree(op); result = ipp_send_request(svc, request, &response); papiAttributeListFree(request); papiAttributeListFree(response); return (result); }
static papi_status_t ipp_initialize_response(papi_attribute_t **request, papi_attribute_t ***response) { papi_attribute_t **operational = NULL; int i; if ((request == NULL) || (response == NULL)) return (PAPI_BAD_ARGUMENT); /* If the response was initialized, start over */ if (*response != NULL) { papiAttributeListFree(*response); *response = NULL; } /* Add the basic ipp header information to the response */ (void) papiAttributeListGetInteger(request, NULL, "version-major", &i); (void) papiAttributeListAddInteger(response, PAPI_ATTR_REPLACE, "version-major", i); (void) papiAttributeListGetInteger(request, NULL, "version-minor", &i); (void) papiAttributeListAddInteger(response, PAPI_ATTR_REPLACE, "version-minor", i); (void) papiAttributeListGetInteger(request, NULL, "request-id", &i); (void) papiAttributeListAddInteger(response, PAPI_ATTR_REPLACE, "request-id", i); /* Add a default operational attributes group to the response */ (void) papiAttributeListAddString(&operational, PAPI_ATTR_EXCL, "attributes-charset", "utf-8"); (void) papiAttributeListAddString(&operational, PAPI_ATTR_EXCL, "attributes-natural-language", "en-us"); (void) papiAttributeListAddCollection(response, PAPI_ATTR_REPLACE, "operational-attributes-group", operational); papiAttributeListFree(operational); return (PAPI_OK); }
static int ipp_handler(request_rec *r) { papi_attribute_t **request = NULL, **response = NULL; IPPListenerConfig *config; papi_status_t status; int ret; /* Really, IPP is all POST requests */ if (r->method_number != M_POST) return (DECLINED); #ifndef APACHE2 /* * An IPP request must have a MIME type of "application/ipp" * (RFC-2910, Section 4, page 19). If it doesn't match this * MIME type, we should decline the request and let someone else * try and handle it. */ if (r->headers_in != NULL) { char *mime_type = (char *)ap_table_get(r->headers_in, "Content-Type"); if ((mime_type == NULL) || (strcasecmp(mime_type, "application/ipp") != 0)) return (DECLINED); } #endif /* CHUNKED_DECHUNK might not work right for IPP? */ if ((ret = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)) != OK) return (ret); if (!ap_should_client_block(r)) return (HTTP_INTERNAL_SERVER_ERROR); #ifndef APACHE2 ap_soft_timeout("ipp_module: read/reply request ", r); #endif /* read the IPP request off the network */ status = ipp_read_message(read_data, r, &request, IPP_TYPE_REQUEST); if (status != PAPI_OK) _log_rerror(APLOG_MARK, APLOG_ERR, r, "read failed: %s\n", papiStatusString(status)); #ifdef DEBUG papiAttributeListPrint(stderr, request, "request (%d) ", getpid()); #endif (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL, "originating-host", (char *) #ifdef APACHE2 ap_get_remote_host (r->connection, r->per_dir_config, REMOTE_NAME, NULL)); #else ap_get_remote_host (r->connection, r->per_dir_config, REMOTE_NAME)); #endif (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL, "uri-port", ap_get_server_port(r)); if (r->headers_in != NULL) { char *host = (char *)ap_table_get(r->headers_in, "Host"); if ((host == NULL) || (host[0] == '\0')) host = (char *)ap_get_server_name(r); (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL, "uri-host", host); } (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL, "uri-path", r->uri); config = ap_get_module_config(r->per_dir_config, &ipp_module); if (config != NULL) { (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL, "conformance", config->conformance); (void) papiAttributeListAddCollection(&request, PAPI_ATTR_EXCL, "operations", config->operations); if (config->default_user != NULL) (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL, "default-user", config->default_user); if (config->default_svc != NULL) (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL, "default-service", config->default_svc); } /* * For Trusted Solaris, pass the fd number of the socket connection * to the backend so the it can be forwarded to the backend print * service to retrieve the sensativity label off of a multi-level * port. */ (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL, "peer-socket", ap_bfileno(r->connection->client, B_RD)); /* process the request */ status = ipp_process_request(request, &response, read_data, r); if (status != PAPI_OK) { errno = 0; _log_rerror(APLOG_MARK, APLOG_ERR, r, "request failed: %s\n", papiStatusString(status)); discard_data(r); } #ifdef DEBUG fprintf(stderr, "processing result: %s\n", papiStatusString(status)); papiAttributeListPrint(stderr, response, "response (%d) ", getpid()); #endif /* * If the client is using chunking and we have not yet received the * final "0" sized chunk, we need to discard any data that may * remain in the post request. */ if ((r->read_chunked != 0) && (ap_table_get(r->headers_in, "Content-Length") == NULL)) discard_data(r); /* write an IPP response back to the network */ r->content_type = "application/ipp"; #ifndef APACHE2 ap_send_http_header(r); #endif status = ipp_write_message(write_data, r, response); if (status != PAPI_OK) _log_rerror(APLOG_MARK, APLOG_ERR, r, "write failed: %s\n", papiStatusString(status)); #ifdef DEBUG fprintf(stderr, "write result: %s\n", papiStatusString(status)); fflush(stderr); #endif papiAttributeListFree(request); papiAttributeListFree(response); #ifndef APACHE2 ap_kill_timeout(r); if (ap_rflush(r) < 0) _log_rerror(APLOG_MARK, APLOG_ERR, r, "flush failed, response may not have been sent"); #endif return (OK); }