papi_status_t ipp_purge_jobs(papi_service_t svc, papi_attribute_t **request, papi_attribute_t ***response) { papi_status_t status; papi_job_t *jobs = NULL; papi_attribute_t **operational = NULL; char *queue = NULL; /* Get operational attributes from the request */ (void) papiAttributeListGetCollection(request, NULL, "operational-attributes-group", &operational); /* * The operational-attributes-group must contain: * printer-uri */ get_printer_id(operational, &queue, NULL); if (queue == NULL) { ipp_set_status(response, status, "printer-uri: %s", papiStatusString(status)); return (PAPI_BAD_REQUEST); } if ((status = papiPrinterPurgeJobs(svc, queue, &jobs)) != PAPI_OK) { ipp_set_status(response, status, "purge failed: %s: %s", (queue ? queue : "(null)"), ipp_svc_status_mesg(svc, status)); } papiJobListFree(jobs); return (status); }
static papi_status_t print_service_connect(papi_service_t *svc, papi_attribute_t **request, papi_attribute_t ***response) { papi_status_t status; papi_attribute_t **operational = NULL; char *printer_uri = NULL; char *svc_name = NULL; char *user = NULL; /* Get the operational attributes group from the request */ (void) papiAttributeListGetCollection(request, NULL, "operational-attributes-group", &operational); /* get the user name */ (void) papiAttributeListGetString(request, NULL, "default-user", &user); (void) papiAttributeListGetString(operational, NULL, "requesting-user-name", &user); /* get the printer or service name */ (void) papiAttributeListGetString(request, NULL, "default-service", &svc_name); get_printer_id(operational, &svc_name, NULL); status = papiServiceCreate(svc, svc_name, user, NULL, NULL, PAPI_ENCRYPT_NEVER, NULL); if (status != PAPI_OK) { ipp_set_status(response, status, "print service: %s", papiStatusString(status)); return (status); } /* * Trusted Solaris can't be trusting of intermediaries. Pass * the socket connection to the print service to retrieve the * sensativity label off of a multi-level port. */ { int fd = -1; (void) papiAttributeListGetInteger(request, NULL, "peer-socket", &fd); if (fd != -1) papiServiceSetPeer(*svc, fd); } return (status); }
papi_status_t ipp_process_request(papi_attribute_t **request, papi_attribute_t ***response, ipp_reader_t iread, void *fd) { papi_status_t result = PAPI_OK; ipp_initialize_response(request, response); #ifdef DEBUG fprintf(stderr, "REQUEST:"); papiAttributeListPrint(stderr, request, " %d ", getpid()); fprintf(stderr, "\n"); #endif /* verify that the request is "well-formed" */ if ((result = ipp_validate_request(request, response)) == PAPI_OK) { papi_service_t svc = NULL; ipp_handler_t *handler; result = print_service_connect(&svc, request, response); handler = ipp_operation_handler(request, response); /* process the request */ if ((result == PAPI_OK) && (handler != NULL)) result = (handler)(svc, request, response, iread, fd); #ifdef DEBUG fprintf(stderr, "RESULT: %s\n", papiStatusString(result)); #endif papiServiceDestroy(svc); } (void) papiAttributeListAddInteger(response, PAPI_ATTR_EXCL, "status-code", result); massage_response(request, *response); #ifdef DEBUG fprintf(stderr, "RESPONSE:"); papiAttributeListPrint(stderr, *response, " %d ", getpid()); fprintf(stderr, "\n"); #endif return (result); }
/*ARGSUSED0*/ static const char * ipp_operation(cmd_parms *cmd, void *cfg, char *op, char *toggle) { IPPListenerConfig *config = (IPPListenerConfig *)cfg; papi_status_t status; status = ipp_configure_operation(&config->operations, op, toggle); switch (status) { case PAPI_OK: return (NULL); case PAPI_BAD_ARGUMENT: return (gettext("internal error (invalid argument)")); default: return (papiStatusString(status)); } /* NOTREACHED */ /* return (gettext("contact your software vendor")); */ }
/* * When the PAPI supports papiJobCreate(), papiJobStreamAdd() and * papiJobClose(), this will be much cleaner and more efficient, but in the * meantime, we are using a private, non-standard interface to do this. */ papi_status_t ipp_send_document(papi_service_t svc, papi_attribute_t **request, papi_attribute_t ***response, ipp_reader_t iread, void *fd) { papi_status_t status; papi_stream_t s = NULL; papi_job_t j = NULL; papi_attribute_t **operational = NULL; papi_attribute_t **job_attributes = NULL; char *queue = NULL; ssize_t rc; int id = -1; char buf[BUFSIZ]; char last = PAPI_FALSE; char *keys[] = { "attributes-natural-language", "attributes-charset", "printer-uri", "job-id", "job-uri", "last-document", NULL }; /* 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) * last-document */ 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); } status = papiAttributeListGetBoolean(operational, NULL, "last-document", &last); if (status != PAPI_OK) { ipp_set_status(response, status, "last-document: %s", papiStatusString(status)); return (PAPI_BAD_REQUEST); } /* * the operational-attributes-group may contain: * document-name * compression * document-format * document-natural-language * Simply copy the entire contents of the operational-attributes-group * for the PAPI call's possible use. */ split_and_copy_attributes(keys, operational, NULL, &job_attributes); /* copy any job-attributes-group attributes for the PAPI call */ if (papiAttributeListGetCollection(request, NULL, "job-attributes-group", &operational) == PAPI_OK) copy_attributes(&job_attributes, operational); /* create a stream to write the document data on */ status = papiJobStreamAdd(svc, queue, id, &s); papiAttributeListFree(job_attributes); if (status != PAPI_OK) { ipp_set_status(response, status, "job submission: %s", ipp_svc_status_mesg(svc, status)); return (status); } /* copy the document data from the IPP connection to the stream */ while ((status == PAPI_OK) && ((rc = iread(fd, buf, sizeof (buf))) > 0)) status = papiJobStreamWrite(svc, s, buf, rc); if (status != PAPI_OK) { ipp_set_status(response, status, "write job data: %s", ipp_svc_status_mesg(svc, status)); return (status); } /* close the stream */ status = papiJobStreamClose(svc, s, &j); if (status != PAPI_OK) { ipp_set_status(response, status, "close job stream: %s", ipp_svc_status_mesg(svc, status)); papiJobFree(j); /* we shouldn't have a job, but just in case */ return (status); } /* if it's the last document, commit the job */ if (last == PAPI_TRUE) { status = papiJobCommit(svc, queue, id); } /* add the job attributes to the response in a job-attributes-group */ if (j != NULL) { papi_to_ipp_job_group(response, request, PAPI_ATTR_REPLACE, j); papiJobFree(j); } return (status); }
papi_status_t ipp_validate_job(papi_service_t svc, papi_attribute_t **request, papi_attribute_t ***response, ipp_reader_t iread, void *fd) { papi_status_t status; papi_job_t j = NULL; papi_attribute_t **operational = NULL; papi_attribute_t **job_attributes = NULL; char *queue = NULL; char *files[] = { "/etc/syslog.conf", NULL }; ssize_t rc; char buf[BUFSIZ]; char *keys[] = { "attributes-natural-language", "attributes-charset", "printer-uri", NULL }; /* Get operational attributes from the request */ (void) papiAttributeListGetCollection(request, NULL, "operational-attributes-group", &operational); /* * The operational-attributes-group must contain: * printer-uri */ get_printer_id(operational, &queue, NULL); if (queue == NULL) { ipp_set_status(response, status, "printer-uri: %s", papiStatusString(status)); return (PAPI_BAD_REQUEST); } /* * The operational-attributes-group may contain: * job-name * ipp-attribute-fidelity * document-name * compression * document-format * document-natural-language * job-k-octets * job-impressions * job-media-sheets * Simply copy the entire contents of the operational-attributes-group * for the PAPI call's possible use. */ split_and_copy_attributes(keys, operational, NULL, &job_attributes); /* copy any job-attributes-group attributes for the PAPI call */ if (papiAttributeListGetCollection(request, NULL, "job-attributes-group", &operational) == PAPI_OK) copy_attributes(&job_attributes, operational); /* request job validation */ status = papiJobValidate(svc, queue, job_attributes, NULL, files, &j); papiAttributeListFree(job_attributes); if (status != PAPI_OK) { ipp_set_status(response, status, "validating job: %s", ipp_svc_status_mesg(svc, status)); papiJobFree(j); /* we shouldn't have a job, but just in case */ return (status); } /* add the job attributes to the response in a job-attributes-group */ if (j != NULL) { papi_to_ipp_job_group(response, request, PAPI_ATTR_REPLACE, j); papiJobFree(j); } return (status); }
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); }
int main(int ac, char *av[]) { int exit_code = 0; char *user = NULL; papi_encryption_t encryption = PAPI_ENCRYPT_NEVER; int c; int32_t rid = -1; int first_dest = 0; (void) setlocale(LC_ALL, ""); (void) textdomain("SUNW_OST_OSCMD"); if (ac == 1) usage(av[0]); while ((c = getopt(ac, av, "Eu:")) != EOF) switch (c) { case 'E': encryption = PAPI_ENCRYPT_REQUIRED; break; case 'u': user = optarg; break; default: usage(av[0]); } for (c = optind; c < ac; c++) { papi_status_t status; papi_service_t svc = NULL; papi_job_t *jobs = NULL; char *printer = NULL; int32_t id = -1; status = papiServiceCreate(&svc, av[c], NULL, NULL, cli_auth_callback, encryption, NULL); if (status != PAPI_OK) { if (first_dest == 0) { (void) get_printer_id(av[c], &printer, &id); status = papiServiceCreate(&svc, printer, NULL, NULL, cli_auth_callback, encryption, NULL); } if (status != PAPI_OK) { fprintf(stderr, gettext( "Failed to contact service for %s: %s\n"), printer, verbose_papi_message(svc, status)); exit(1); } } else { first_dest = 1; printer = av[c]; } #define OUT ((status == PAPI_OK) ? stdout : stderr) if (id != -1) { /* it's a job */ char *mesg = gettext("cancelled"); /* * Check if the job-id is job-id-requested * or job-id. If it is job-id-requested then find * corresponding job-id and send it to cancel */ rid = job_to_be_queried(svc, printer, id); if (rid < 0) { /* * Either it is a remote job which cannot be * cancelled based on job-id or job-id is * not found */ exit_code = 1; fprintf(OUT, "%s-%d: %s\n", printer, id, gettext("not-found")); } else { status = papiJobCancel(svc, printer, rid); if (status == PAPI_NOT_AUTHORIZED) { mesg = papiStatusString(status); exit_code = 1; } else if (status != PAPI_OK) { mesg = gettext( verbose_papi_message( svc, status)); exit_code = 1; } fprintf(OUT, "%s-%d: %s\n", printer, id, mesg); } } else { /* it's a printer */ if (user == NULL) { /* Remove first job from printer */ status = papiPrinterListJobs(svc, printer, NULL, NULL, 0, &jobs); if (status != PAPI_OK) { fprintf(stderr, gettext( "ListJobs %s: %s\n"), printer, verbose_papi_message(svc, status)); exit_code = 1; } if (jobs != NULL && *jobs != NULL) { char *mesg = gettext("cancelled"); id = papiJobGetId(*jobs); status = papiJobCancel(svc, printer, id); if (status == PAPI_NOT_AUTHORIZED) { mesg = papiStatusString(status); exit_code = 1; } else if (status != PAPI_OK) { mesg = gettext( verbose_papi_message( svc, status)); exit_code = 1; } /* * If job-id-requested exists for this * job-id then that should be displayed */ rid = get_job_id_requested(*jobs); if (rid >= 0) fprintf(OUT, "%s-%d: %s\n", printer, rid, mesg); else fprintf(OUT, "%s-%d: %s\n", printer, id, mesg); } papiJobListFree(jobs); } else { /* Purging user's print jobs */ exit_code = cancel_jobs_for_user(user, encryption, printer); } } papiServiceDestroy(svc); } if (optind == ac) exit_code = cancel_jobs_for_user(user, encryption, NULL); return (exit_code); }