static REQUEST * create_request(papi_service_t svc, char *printer, papi_attribute_t **attributes) { REQUEST *r; if ((r = calloc(1, sizeof (*r))) != NULL) { char *hostname = NULL; r->priority = -1; r->destination = printer_name_from_uri_id(printer, -1); papiAttributeListGetString(attributes, NULL, "job-originating-host-name", &hostname); if (hostname == NULL) { char host[BUFSIZ]; if (gethostname(host, sizeof (host)) == 0) papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE, "job-originating-host-name", host); } job_attributes_to_lpsched_request(svc, r, attributes); } return (r); }
papi_status_t papiJobMove(papi_service_t handle, char *printer, int32_t job_id, char *destination) { papi_status_t result = PAPI_OK; long bits; service_t *svc = handle; char req_id[64]; char *queue; char *user = NULL; if ((svc == NULL) || (printer == NULL) || (job_id < 0) || (destination == NULL)) return (PAPI_BAD_ARGUMENT); queue = printer_name_from_uri_id(printer, job_id); snprintf(req_id, sizeof (req_id), "%s-%d", queue, job_id); free(queue); if (papiAttributeListGetString(svc->attributes, NULL, "user-name", &user) == PAPI_OK) { REQUEST *r = getrequest(req_id); if ((r != NULL) && (r->user != NULL) && (strcmp(r->user, user) != 0)) result = PAPI_NOT_AUTHORIZED; freerequest(r); } if (result == PAPI_OK) { short status = MOK; char *dest = printer_name_from_uri_id(destination, -1); if ((snd_msg(svc, S_MOVE_REQUEST, req_id, dest) < 0) || (rcv_msg(svc, R_MOVE_REQUEST, &status, &bits) < 0)) status = MTRANSMITERR; free(dest); result = lpsched_status_to_papi_status(status); } return (result); }
papi_status_t papiJobQuery(papi_service_t handle, char *printer, int32_t job_id, char **requested_attrs, papi_job_t *job) { service_t *svc = handle; job_t *j; char *dest; char req_id[32]; short rc; char *form = NULL, *request_id = NULL, *charset = NULL, *user = NULL, *slabel = NULL, *file = NULL; time_t date = 0; size_t size = 0; short rank = 0, state = 0; if ((handle == NULL) || (printer == NULL) || (job_id < 0)) return (PAPI_BAD_ARGUMENT); dest = printer_name_from_uri_id(printer, job_id); snprintf(req_id, sizeof (req_id), "%s-%d", dest, job_id); free(dest); rc = snd_msg(svc, S_INQUIRE_REQUEST_RANK, 0, "", "", req_id, "", ""); if (rc < 0) return (PAPI_SERVICE_UNAVAILABLE); if (rcv_msg(svc, R_INQUIRE_REQUEST_RANK, &rc, &request_id, &user, &slabel, &size, &date, &state, &dest, &form, &charset, &rank, &file) < 0) { detailed_error(svc, gettext("failed to read response from scheduler")); return (PAPI_DEVICE_ERROR); } if ((request_id == NULL) || (request_id[0] == NULL)) return (PAPI_NOT_FOUND); if ((*job = j = calloc(1, sizeof (*j))) == NULL) return (PAPI_TEMPORARY_ERROR); snprintf(req_id, sizeof (req_id), "%d-0", job_id); lpsched_read_job_configuration(svc, j, req_id); job_status_to_attributes(j, request_id, user, slabel, size, date, state, dest, form, charset, rank, file); return (PAPI_OK); }
static REQUEST * create_request(papi_service_t svc, char *printer, papi_attribute_t **attributes) { static REQUEST r; memset(&r, 0, sizeof (r)); r.priority = -1; r.destination = printer_name_from_uri_id(printer, -1); job_attributes_to_lpsched_request(svc, &r, attributes); return (&r); }
papi_status_t hold_release_job(papi_service_t handle, char *printer, int32_t job_id, int flag) { papi_status_t status; service_t *svc = handle; REQUEST *r = NULL; char *file; char *dest; if ((svc == NULL) || (printer == NULL) || (job_id < 0)) return (PAPI_BAD_ARGUMENT); if ((status = authorized(svc, job_id)) != PAPI_OK) return (status); dest = printer_name_from_uri_id(printer, job_id); status = lpsched_start_change(svc, dest, job_id, &file); if (status != PAPI_OK) return (status); if ((r = getrequest(file)) != NULL) { r->actions &= ~ACT_RESUME; switch (flag) { case 0: r->actions |= ACT_HOLD; break; case 1: r->actions |= ACT_RESUME; break; case 2: r->actions |= ACT_IMMEDIATE; break; } if (putrequest(file, r) < 0) { detailed_error(svc, gettext("failed to write job: %s: %s"), file, strerror(errno)); freerequest(r); return (PAPI_DEVICE_ERROR); } freerequest(r); } else { detailed_error(svc, gettext("failed to read job: %s: %s"), file, strerror(errno)); return (PAPI_DEVICE_ERROR); } status = lpsched_end_change(svc, dest, job_id); return (status); }
papi_status_t papiPrinterPurgeJobs(papi_service_t handle, char *name, papi_job_t **jobs) { service_t *svc = handle; papi_status_t result = PAPI_OK_SUBST; short more; long status; char *dest; char *req_id; if ((handle == NULL) || (name == NULL)) return (PAPI_BAD_ARGUMENT); dest = printer_name_from_uri_id(name, -1); more = snd_msg(svc, S_CANCEL, dest, "", ""); free(dest); if (more < 0) return (PAPI_SERVICE_UNAVAILABLE); do { if (rcv_msg(svc, R_CANCEL, &more, &status, &req_id) < 0) return (PAPI_SERVICE_UNAVAILABLE); switch (status) { case MOK: papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND, "canceled-jobs", req_id); break; case M2LATE: case MUNKNOWN: case MNOINFO: papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND, "cancel-failed", req_id); result = PAPI_DEVICE_ERROR; break; case MNOPERM: papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND, "cancel-failed", req_id); result = PAPI_NOT_AUTHORIZED; break; default: detailed_error(svc, gettext("cancel failed, bad status (%d)\n"), status); return (PAPI_DEVICE_ERROR); } } while (more == MOKMORE); return (result); }
papi_status_t papiJobCancel(papi_service_t handle, char *printer, int32_t job_id) { papi_status_t result = PAPI_OK; service_t *svc = handle; char req_id[64]; char *dest; char *user = NULL; if ((svc == NULL) || (printer == NULL) || (job_id < 0)) return (PAPI_BAD_ARGUMENT); dest = printer_name_from_uri_id(printer, job_id); snprintf(req_id, sizeof (req_id), "%s-%d", dest, job_id); free(dest); if (papiAttributeListGetString(svc->attributes, NULL, "user-name", &user) == PAPI_OK) { REQUEST *r = getrequest(req_id); if ((result = authorized(handle, job_id)) != PAPI_OK) result = PAPI_NOT_AUTHORIZED; if ((r != NULL) && (r->user != NULL) && (strcmp(r->user, user) != 0)) result = PAPI_NOT_AUTHORIZED; freerequest(r); } if (result == PAPI_OK) { short status = MOK; if ((snd_msg(svc, S_CANCEL_REQUEST, req_id) < 0) || (rcv_msg(svc, R_CANCEL_REQUEST, &status) < 0)) status = MTRANSMITERR; result = lpsched_status_to_papi_status(status); } return (result); }
papi_status_t papiJobCommit(papi_service_t handle, char *printer, int32_t id) { papi_status_t status = PAPI_OK; service_t *svc = handle; REQUEST *r = NULL; char *metadata_file; char *dest; if ((svc == NULL) || (printer == NULL)) return (PAPI_BAD_ARGUMENT); dest = printer_name_from_uri_id(printer, id); /* tell the scheduler that we want to change the job */ status = lpsched_start_change(svc, dest, id, &metadata_file); if (status != PAPI_OK) return (status); if ((r = getrequest(metadata_file)) != NULL) { r->actions &= ~ACT_RESUME; r->actions |= ACT_RESUME; dellist(&r->file_list, DUMMY_FILE); if (putrequest(metadata_file, r) < 0) { detailed_error(svc, gettext("failed to write job: %s: %s"), metadata_file, strerror(errno)); freerequest(r); return (PAPI_DEVICE_ERROR); } } else { detailed_error(svc, gettext("failed to read job: %s: %s"), metadata_file, strerror(errno)); return (PAPI_DEVICE_ERROR); } status = lpsched_end_change(svc, dest, id); freerequest(r); return (status); }
papi_status_t papiPrinterRemove(papi_service_t handle, char *name) { papi_status_t result; char *dest; if ((handle == NULL) || (name == NULL)) return (PAPI_BAD_ARGUMENT); dest = printer_name_from_uri_id(name, -1); if (isprinter(dest) != 0) { result = lpsched_remove_printer(handle, dest); } else if (isclass(dest) != 0) { result = lpsched_remove_class(handle, dest); } else result = PAPI_NOT_FOUND; free(dest); return (result); }
papi_status_t papiPrinterAdd(papi_service_t handle, char *name, papi_attribute_t **attributes, papi_printer_t *result) { papi_status_t status; printer_t *p = NULL; char *dest; if ((handle == NULL) || (name == NULL) || (attributes == NULL)) return (PAPI_BAD_ARGUMENT); dest = printer_name_from_uri_id(name, -1); if (isprinter(dest) != 0) { status = lpsched_add_modify_printer(handle, dest, attributes, 0); if ((*result = p = calloc(1, sizeof (*p))) != NULL) lpsched_printer_configuration_to_attributes(handle, p, dest); else status = PAPI_TEMPORARY_ERROR; } else if (isclass(dest) != 0) { status = lpsched_add_modify_class(handle, dest, attributes); if ((*result = p = calloc(1, sizeof (*p))) != NULL) lpsched_class_configuration_to_attributes(handle, p, dest); else status = PAPI_TEMPORARY_ERROR; } else status = PAPI_NOT_FOUND; free(dest); return (status); }
papi_status_t papiJobStreamAdd(papi_service_t handle, char *printer, int32_t id, papi_stream_t *stream) { papi_status_t status; service_t *svc = handle; job_stream_t *s = NULL; char *metadata_file = NULL; char *dest; char path[MAXPATHLEN]; /* allocate space for the stream */ if ((*stream = s = calloc(1, sizeof (*s))) == NULL) return (PAPI_TEMPORARY_ERROR); dest = printer_name_from_uri_id(printer, id); /* create/open data file (only root or lp can really do this */ snprintf(path, sizeof (path), "/var/spool/lp/temp/%d-XXXXXX", id); if ((s->fd = mkstemp(path)) < 0) { detailed_error(svc, gettext("unable to create sink (%s): %s"), path, strerror(errno)); free(s); return (PAPI_NOT_AUTHORIZED); } /* add data file to job */ status = lpsched_start_change(svc, dest, id, &metadata_file); if (status != PAPI_OK) { close(s->fd); free(s); unlink(path); return (status); } if ((s->request = getrequest(metadata_file)) == NULL) { detailed_error(svc, gettext("unable to load request: %s: %s"), metadata_file, strerror(errno)); close(s->fd); free(s); unlink(path); return (PAPI_NOT_POSSIBLE); } addlist(&(s->request->file_list), path); if (putrequest(metadata_file, s->request) < 0) { detailed_error(svc, gettext("unable to save request: %s: %s"), metadata_file, strerror(errno)); close(s->fd); free(s); unlink(path); return (PAPI_NOT_POSSIBLE); } status = lpsched_end_change(svc, dest, id); if (status != PAPI_OK) return (status); return (PAPI_OK); }
papi_status_t papiJobModify(papi_service_t handle, char *printer, int32_t job_id, papi_attribute_t **attributes, papi_job_t *job) { papi_status_t status; job_t *j = NULL; service_t *svc = handle; char *file = NULL; char *dest; REQUEST *r = NULL; char lpfile[BUFSIZ]; if ((svc == NULL) || (printer == NULL) || (job_id < 0) || (attributes == NULL)) return (PAPI_BAD_ARGUMENT); if ((*job = j = calloc(1, sizeof (*j))) == NULL) return (PAPI_TEMPORARY_ERROR); dest = printer_name_from_uri_id(printer, job_id); status = lpsched_start_change(svc, dest, job_id, &file); if (status != PAPI_OK) return (status); if ((r = getrequest(file)) != NULL) { job_attributes_to_lpsched_request(handle, r, (papi_attribute_t **)attributes); #ifdef LP_USE_PAPI_ATTR /* * store the job attributes in the PAPI job attribute file * that was created by the origonal job request. We need to * modify the attributes in the file as per the new attributes */ snprintf(lpfile, sizeof (lpfile), "%s%d-%s", "/var/spool/lp/temp/", job_id, LP_PAPIATTRNAME); status = psm_modifyAttrsFile(attributes, lpfile); if (status != PAPI_OK) { detailed_error(svc, "unable to modify the attributes file: %s: %s", lpfile, strerror(errno)); return (PAPI_DEVICE_ERROR); } #endif if (putrequest(file, r) < 0) { detailed_error(svc, gettext("failed to write job: %s: %s"), file, strerror(errno)); freerequest(r); return (PAPI_DEVICE_ERROR); } } else { detailed_error(svc, gettext("failed to read job: %s: %s"), file, strerror(errno)); return (PAPI_DEVICE_ERROR); } status = lpsched_end_change(svc, dest, job_id); lpsched_request_to_job_attributes(r, j); papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE, "job-id", job_id); freerequest(r); 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) { service_t *svc = handle; char *dest; short rc; int count = 1; if ((handle == NULL) || (name == NULL) || (jobs == NULL)) return (PAPI_BAD_ARGUMENT); dest = printer_name_from_uri_id(name, -1); rc = snd_msg(svc, S_INQUIRE_REQUEST_RANK, 0, "", dest, "", "", ""); free(dest); if (rc < 0) return (PAPI_SERVICE_UNAVAILABLE); do { job_t *job = NULL; char *dest = NULL, *ptr, *form = NULL, *req_id = NULL, *charset = NULL, *owner = NULL, *slabel = NULL, *file = NULL; time_t date = 0; size_t size = 0; short rank = 0, state = 0; if (rcv_msg(svc, R_INQUIRE_REQUEST_RANK, &rc, &req_id, &owner, &slabel, &size, &date, &state, &dest, &form, &charset, &rank, &file) < 0) return (PAPI_SERVICE_UNAVAILABLE); if ((rc != MOK) && (rc != MOKMORE)) continue; /* * at this point, we should check to see if the job matches the * selection criterion defined in "type_mask". */ /* too many yet? */ if ((max_num_jobs != 0) && (count++ > max_num_jobs)) continue; if ((job = calloc(1, sizeof (*job))) == NULL) continue; job_status_to_attributes(job, req_id, owner, slabel, size, date, state, dest, form, charset, rank, file); if ((ptr = strrchr(file, '-')) != NULL) { *++ptr = '0'; *++ptr = NULL; } lpsched_read_job_configuration(svc, job, file); list_append(jobs, job); } while (rc == MOKMORE); if (rc == MNOINFO) /* If no jobs are found, it's still ok */ rc = MOK; return (lpsched_status_to_papi_status(rc)); }
papi_status_t papiPrinterQuery(papi_service_t handle, char *name, char **requested_attrs, papi_attribute_t **job_attrs, papi_printer_t *printer) { papi_status_t pst; service_t *svc = handle; printer_t *p = NULL; char *dest; short status = MOK; char *pname = NULL, *form = NULL, *request_id = NULL, *character_set = NULL, *reject_reason = NULL, *disable_reason = NULL; short printer_status = 0; long enable_date = 0, reject_date = 0; if ((handle == NULL) || (name == NULL) || (printer == NULL)) return (PAPI_BAD_ARGUMENT); if ((*printer = p = calloc(1, sizeof (*p))) == NULL) return (PAPI_TEMPORARY_ERROR); dest = printer_name_from_uri_id(name, -1); if (strcmp(dest, "_default") == 0) { static char *_default; if (_default == NULL) { int fd; static char buf[128]; if ((fd = open("/etc/lp/default", O_RDONLY)) >= 0) { read(fd, buf, sizeof (buf)); close(fd); _default = strtok(buf, " \t\n"); } } dest = _default; } if (isprinter(dest) != 0) { pst = lpsched_printer_configuration_to_attributes(svc, p, dest); if (pst != PAPI_OK) return (pst); /* get the spooler status data now */ if (snd_msg(svc, S_INQUIRE_PRINTER_STATUS, dest) < 0) return (PAPI_SERVICE_UNAVAILABLE); if (rcv_msg(svc, R_INQUIRE_PRINTER_STATUS, &status, &pname, &form, &character_set, &disable_reason, &reject_reason, &printer_status, &request_id, &enable_date, &reject_date) < 0) return (PAPI_SERVICE_UNAVAILABLE); printer_status_to_attributes(p, pname, form, character_set, disable_reason, reject_reason, printer_status, request_id, enable_date, reject_date); } else if (isclass(dest) != 0) { pst = lpsched_class_configuration_to_attributes(svc, p, dest); if (pst != PAPI_OK) return (pst); /* get the spooler status data now */ if (snd_msg(svc, S_INQUIRE_CLASS, dest) < 0) return (PAPI_SERVICE_UNAVAILABLE); if (rcv_msg(svc, R_INQUIRE_CLASS, &status, &pname, &printer_status, &reject_reason, &reject_date) < 0) return (PAPI_SERVICE_UNAVAILABLE); class_status_to_attributes(p, pname, printer_status, reject_reason, reject_date); } else if (strcmp(dest, "PrintService") == 0) { /* fill the printer object with service information */ lpsched_service_information(&p->attributes); } else return (PAPI_NOT_FOUND); free(dest); return (PAPI_OK); }