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); }
char * printer_name_from_uri_id(char *uri, int32_t id) { REQUEST *request = NULL; char *result = ""; if (uri != NULL) { if ((result = strrchr(uri, '/')) != NULL) { result += 1; } else result = (char *)uri; if ((strcmp(result, "jobs") == 0) || (strcmp(result, "any") == 0) || (strcmp(result, "all") == 0)) result = ""; } if ((result[0] == NULL) && (id != -1)) { char path[32]; snprintf(path, sizeof (path), "%d-0", id); if ((request = getrequest(path)) != NULL) result = request->destination; } result = strdup(result); if (request != NULL) freerequest(request); return (result); }
static papi_status_t authorized(service_t *svc, int32_t id) { papi_status_t result = PAPI_NOT_AUTHORIZED; /* assume the worst */ char file[32]; REQUEST *r; snprintf(file, sizeof (file), "%d-0", id); if ((r = getrequest(file)) != NULL) { uid_t uid = getuid(); struct passwd *pw = NULL; char *user = "******"; /* assume an intruder */ if ((pw = getpwuid(uid)) != NULL) user = pw->pw_name; /* use the process owner */ if ((uid == 0) || (uid == 71)) { /* root/lp can forge this */ papi_status_t s; s = papiAttributeListGetString(svc->attributes, NULL, "user-name", &user); if (s != PAPI_OK) /* true root/lp are almighty */ result = PAPI_OK; } if ((result != PAPI_OK) && (strcmp(user, r->user) == 0)) result = PAPI_OK; freerequest(r); } else result = PAPI_NOT_FOUND; 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 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 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 papiJobStreamClose(papi_service_t handle, papi_stream_t stream, papi_job_t *job) { papi_status_t status = PAPI_OK; service_t *svc = handle; job_stream_t *s = stream; job_t *j = NULL; char *tmp = NULL, *c; if ((svc == NULL) || (stream == NULL) || (job == NULL)) return (PAPI_BAD_ARGUMENT); if ((*job = j = calloc(1, sizeof (*j))) == NULL) return (PAPI_TEMPORARY_ERROR); close(s->fd); lpsched_request_to_job_attributes(s->request, j); if (s->meta_data_file != NULL) { status = lpsched_commit_job(svc, s->meta_data_file, &tmp); if (status != PAPI_OK) { unlink(s->meta_data_file); return (status); } if ((c = strrchr(tmp, '-')) != NULL) c++; papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE, "job-id", atoi(c)); papiAttributeListAddString(&j->attributes, PAPI_ATTR_REPLACE, "job-uri", tmp); free(s->meta_data_file); } freerequest(s->request); free(s); return (PAPI_OK); }
papi_status_t papiJobSubmitByReference(papi_service_t handle, char *printer, papi_attribute_t **job_attributes, papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) { service_t *svc = handle; struct stat statbuf; job_t *j; int file_no; short status; char *request_id = NULL; REQUEST *request; char *c; char *tmp = NULL; char lpfile[BUFSIZ]; char **file_list = NULL; if ((svc == NULL) || (printer == NULL) || (files == NULL) || (job == NULL)) return (PAPI_BAD_ARGUMENT); if (job_ticket != NULL) return (PAPI_OPERATION_NOT_SUPPORTED); if (files != NULL) for (file_no = 0; files[file_no] != NULL; file_no++) { if (access(files[file_no], R_OK) < 0) { detailed_error(svc, gettext("Cannot access file: %s: %s"), files[file_no], strerror(errno)); return (PAPI_DOCUMENT_ACCESS_ERROR); } if (stat(files[file_no], &statbuf) < 0) { detailed_error(svc, gettext("Cannot access file: %s: %s"), files[file_no], strerror(errno)); return (PAPI_DOCUMENT_ACCESS_ERROR); } if (statbuf.st_size == 0) { detailed_error(svc, gettext("Zero byte (empty) file: %s"), files[file_no]); return (PAPI_BAD_ARGUMENT); } if (files[file_no][0] != '/') { char path[MAXPATHLEN]; if (getcwd(path, sizeof (path)) == NULL) { detailed_error(svc, gettext( "getcwd for file: %s: %s"), files[file_no], strerror(errno)); return (PAPI_DOCUMENT_ACCESS_ERROR); } strlcat(path, "/", sizeof (path)); if (strlcat(path, files[file_no], sizeof (path)) >= sizeof (path)) { detailed_error(svc, gettext( "pathname too long: %s"), files[file_no]); return (PAPI_DOCUMENT_ACCESS_ERROR); } addlist(&file_list, path); } else addlist(&file_list, (char *)files[file_no]); } if ((*job = j = calloc(1, sizeof (*j))) == NULL) return (PAPI_TEMPORARY_ERROR); /* 1 for the control file (-0) */ status = lpsched_alloc_files(svc, 1, &request_id); if (status != PAPI_OK) return (status); request = create_request(svc, (char *)printer, (papi_attribute_t **)job_attributes); request->file_list = file_list; #ifdef LP_USE_PAPI_ATTR /* * store the job attributes in the PAPI job attribute file that was * created by lpsched_alloc_files(), the attributes will then pass * through lpsched and be given to the slow-filters and the printer's * interface script to process them */ snprintf(lpfile, sizeof (lpfile), "%s%s-%s", "/var/spool/lp/temp/", request_id, LP_PAPIATTRNAME); status = psm_copy_attrsToFile(job_attributes, lpfile); if (status != PAPI_OK) { detailed_error(svc, "unable to copy attributes to file: %s: %s", lpfile, strerror(errno)); return (PAPI_DEVICE_ERROR); } #endif /* store the meta-data file */ snprintf(lpfile, sizeof (lpfile), "%s-0", request_id); if (putrequest(lpfile, request) < 0) { detailed_error(svc, gettext("unable to save request: %s: %s"), lpfile, strerror(errno)); freerequest(request); return (PAPI_DEVICE_ERROR); } status = lpsched_commit_job(svc, lpfile, &tmp); if (status != PAPI_OK) { unlink(lpfile); freerequest(request); return (status); } lpsched_request_to_job_attributes(request, j); freerequest(request); if ((c = strrchr(tmp, '-')) != NULL) c++; papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE, "job-id", atoi(c)); papiAttributeListAddString(&j->attributes, PAPI_ATTR_REPLACE, "job-uri", tmp); return (PAPI_OK); }
static papi_status_t authorized(service_t *svc, int32_t id) { papi_status_t result = PAPI_NOT_AUTHORIZED; /* assume the worst */ char file[32]; REQUEST *r; snprintf(file, sizeof (file), "%d-0", id); if ((r = getrequest(file)) != NULL) { uid_t uid = getuid(); struct passwd *pw = NULL; char *user = "******"; /* assume an intruder */ if ((pw = getpwuid(uid)) != NULL) user = pw->pw_name; /* use the process owner */ if ((uid == 0) || (uid == 71)) { /* root/lp can forge this */ papi_status_t s; s = papiAttributeListGetString(svc->attributes, NULL, "user-name", &user); if (s != PAPI_OK) /* true root/lp are almighty */ result = PAPI_OK; } if (result != PAPI_OK) { if (strcmp(user, r->user) == 0) result = PAPI_OK; else { /* * user and r->user might contain the * host info also */ char *token1 = strtok(r->user, "@"); char *token2 = strtok(NULL, "@"); char *token3 = strtok(user, "@"); char *token4 = strtok(NULL, "@"); /* * token1 and token3 contain usernames * token2 and token4 contain hostnames */ if ((token1 == NULL) || (token3 == NULL)) result = PAPI_NOT_AUTHORIZED; else if ((token4 != NULL) && (strcmp(token4, "localhost") == 0) && (strcmp(token3, "root") == 0) || (strcmp(token3, "lp") == 0)) { /* * root/lp user on server can * cancel any requset */ result = PAPI_OK; } else if (strcmp(token1, token3) == 0) { /* * usernames are same * compare the hostnames */ if ((token4 != NULL) && (token2 != NULL) && (strcmp(token4, "localhost") == 0)) { /* * Its server machine */ static char host[256]; if (gethostname(host, sizeof (host)) == 0) { if ((host != NULL) && (strcmp(host, token2) == 0)) result = PAPI_OK; } } else if ((token4 != NULL) && (token2 != NULL) && (strcmp(token4, token2) == 0)) { result = PAPI_OK; } else if ((token4 == NULL) && (token2 != NULL)) { /* * When the request is sent from * client to server using ipp * token4 is NULL */ result = PAPI_OK; } } } } freerequest(r); } else result = PAPI_NOT_FOUND; return (result); }
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); }
void s_print_request(char *m, MESG *md) { extern char *Local_System; char *file; char *idno; char *path; char *req_file; char *req_id = 0; RSTATUS *rp; REQUEST *r; SECURE *s; struct passwd *pw; short err; short status; off_t size; uid_t org_uid; gid_t org_gid; #ifdef LP_USE_PAPI_ATTR struct stat tmpBuf; char tmpName[BUFSIZ]; #endif (void) getmessage(m, S_PRINT_REQUEST, &file); syslog(LOG_DEBUG, "s_print_request(%s)", (file ? file : "NULL")); /* * "NewRequest" points to a request that's not yet in the * request list but is to be considered with the rest of the * requests (e.g. calculating # of requests awaiting a form). */ if ((rp = NewRequest = new_rstatus(NULL, NULL)) == NULL) status = MNOMEM; else { req_file = reqpath(file, &idno); path = makepath(Lp_Tmp, req_file, (char *)0); (void) chownmod(path, Lp_Uid, Lp_Gid, 0644); Free(path); if (!(r = Getrequest(req_file))) status = MNOOPEN; else { rp->req_file = Strdup(req_file); freerequest(rp->request); rp->request = r; rp->request->outcome = 0; rp->secure->uid = md->uid; rp->secure->gid = md->gid; if (md->slabel != NULL) rp->secure->slabel = Strdup(md->slabel); pw = getpwuid(md->uid); endpwent(); if (pw && pw->pw_name && *pw->pw_name) rp->secure->user = Strdup(pw->pw_name); else { rp->secure->user = Strdup(BIGGEST_NUMBER_S); (void) sprintf(rp->secure->user, "%u", md->uid); } if ((rp->request->actions & ACT_SPECIAL) == ACT_HOLD) rp->request->outcome |= RS_HELD; if ((rp->request->actions & ACT_SPECIAL) == ACT_RESUME) rp->request->outcome &= ~RS_HELD; if ((rp->request->actions & ACT_SPECIAL) == ACT_IMMEDIATE) { if (!md->admin) { status = MNOPERM; goto Return; } rp->request->outcome |= RS_IMMEDIATE; } size = chfiles(rp->request->file_list, Lp_Uid, Lp_Gid); if (size < 0) { /* * at this point, chfiles() may have * failed because the file may live on * an NFS mounted filesystem, under * a directory of mode 700. such a * directory isn't accessible even by * root, according to the NFS protocol * (i.e. the Stat() in chfiles() failed). * this most commonly happens via the * automounter, and rlogin. thus we * change our euid/egid to that of the * user, and try again. if *this* fails, * then the file must really be * inaccessible. */ org_uid = geteuid(); org_gid = getegid(); if (setegid(md->gid) != 0) { status = MUNKNOWN; goto Return; } if (seteuid(md->uid) != 0) { setgid(org_gid); status = MUNKNOWN; goto Return; } size = chfiles(rp->request->file_list, Lp_Uid, Lp_Gid); if (seteuid(org_uid) != 0) { /* should never happen */ note("s_print_request(): "); note("seteuid back to uid=%d " "failed!!\n", org_uid); size = -1; } if (setegid(org_gid) != 0) { /* should never happen */ note("s_print_request(): "); note("setegid back to uid=%d " "failed!!\n", org_uid); size = -1; } if (size < 0) { status = MUNKNOWN; goto Return; } } if (!(rp->request->outcome & RS_HELD) && size == 0) { status = MNOPERM; goto Return; } rp->secure->size = size; (void) time(&rp->secure->date); rp->secure->req_id = NULL; if (!rp->request->title) { if (strlen(*rp->request->file_list) < (size_t)24) rp->request->title = Strdup(*rp->request->file_list); else { char *r; if (r = strrchr( *rp->request->file_list, '/')) r++; else r = *rp->request->file_list; rp->request->title = malloc(25); sprintf(rp->request->title, "%-.24s", r); } } if ((err = validate_request(rp, &req_id, 0)) != MOK) status = err; else { /* * "req_id" will be supplied if this is from a * remote system. */ if (rp->secure->req_id == NULL) { req_id = makestr(req_id, "-", idno, (char *)0); rp->secure->req_id = req_id; } else req_id = rp->secure->req_id; #ifdef LP_USE_PAPI_ATTR /* * Check if the PAPI job attribute file * exists, if it does change the * permissions and ownership of the file. * This file is created when print jobs * are submitted via the PAPI interface, * the file pathname of this file is * passed to the slow-filters and printer * interface script as an environment * variable when they are executed */ snprintf(tmpName, sizeof (tmpName), "%s-%s", idno, LP_PAPIATTRNAME); path = makepath(Lp_Temp, tmpName, (char *)0); if (stat(path, &tmpBuf) == 0) { syslog(LOG_DEBUG, "s_print_request: "\ "attribute file ='%s'", path); /* * IPP job attribute file exists * for this job so change * permissions and ownership of * the file */ (void) chownmod(path, Lp_Uid, Lp_Gid, 0644); Free(path); } else { syslog(LOG_DEBUG, "s_print_request: "\ "no attribute file"); } #endif /* * fix for bugid 1103890. * use Putsecure instead. */ if ((Putsecure(req_file, rp->secure) == -1) || (putrequest(req_file, rp->request) == -1)) status = MNOMEM; else { status = MOK; insertr(rp); NewRequest = 0; if (rp->slow) schedule(EV_SLOWF, rp); else schedule(EV_INTERF, rp->printer); del_flt_act(md, FLT_FILES); } } } } Return: NewRequest = 0; Free(req_file); Free(idno); if (status != MOK && rp) { rmfiles(rp, 0); free_rstatus(rp); } mputm(md, R_PRINT_REQUEST, status, NB(req_id), chkprinter_result); }
void s_end_change_request(char *m, MESG *md) { char *req_id; RSTATUS *rp; off_t size; off_t osize; short err; short status; REQUEST *r = 0; REQUEST oldr; int call_schedule = 0; int move_ok = 0; char *path; char tmpName[BUFSIZ]; struct stat tmpBuf; (void) getmessage(m, S_END_CHANGE_REQUEST, &req_id); syslog(LOG_DEBUG, "s_end_change_request(%s)", (req_id ? req_id : "NULL")); if (!(rp = request_by_id(req_id))) status = MUNKNOWN; else if ((md->admin == 0) && (is_system_labeled()) && (md->slabel != NULL) && (rp->secure->slabel != NULL) && (!STREQU(md->slabel, rp->secure->slabel))) status = MUNKNOWN; else if (!(rp->request->outcome & RS_CHANGING)) status = MNOSTART; else { path = makepath(Lp_Tmp, rp->req_file, (char *)0); (void) chownmod(path, Lp_Uid, Lp_Gid, 0644); Free(path); #ifdef LP_USE_PAPI_ATTR /* * Check if the PAPI job attribute file exists, * if it does change the permission and the ownership * of the file to be "Lp_Uid". */ snprintf(tmpName, sizeof (tmpName), "%s-%s", strtok(strdup(rp->req_file), "-"), LP_PAPIATTRNAME); path = makepath(Lp_Tmp, tmpName, (char *)0); if (stat(path, &tmpBuf) == 0) { syslog(LOG_DEBUG, "s_end_change_request: attribute file ='%s'", path); /* * IPP job attribute file exists for this job so * change permissions and ownership of the file */ (void) chownmod(path, Lp_Uid, Lp_Gid, 0644); Free(path); } else { syslog(LOG_DEBUG, "s_end_change_request: no attribute file"); } #endif rp->request->outcome &= ~(RS_CHANGING); del_flt_act(md, FLT_CHANGE); /* * The RS_CHANGING bit may have been the only thing * preventing this request from filtering or printing, * so regardless of what happens below, * we must check to see if the request can proceed. */ call_schedule = 1; if (!(r = Getrequest(rp->req_file))) status = MNOOPEN; else { oldr = *(rp->request); *(rp->request) = *r; move_ok = STREQU(oldr.destination, r->destination); /* * Preserve the current request status! */ rp->request->outcome = oldr.outcome; /* * Here's an example of the dangers one meets * when public flags are used for private * purposes. ".actions" (indeed, anything in the * REQUEST structure) is set by the person * changing the job. However, lpsched uses * ".actions" as place to indicate that a job * came from a remote system and we must send * back job completion--this is a strictly * private flag that we must preserve. */ rp->request->actions |= (oldr.actions & ACT_NOTIFY); if ((rp->request->actions & ACT_SPECIAL) == ACT_HOLD) { rp->request->outcome |= RS_HELD; /* * To be here means either the user owns * the request or he or she is the * administrator. Since we don't want to * set the RS_ADMINHELD flag if the user * is the administrator, the following * compare will work. */ if (md->uid != rp->secure->uid) rp->request->outcome |= RS_ADMINHELD; } if ((rp->request->actions & ACT_SPECIAL) == ACT_RESUME) { if ((rp->request->outcome & RS_ADMINHELD) && !md->admin) { status = MNOPERM; goto Return; } rp->request->outcome &= ~(RS_ADMINHELD|RS_HELD); } if ((rp->request->actions & ACT_SPECIAL) == ACT_IMMEDIATE) { if (!md->admin) { status = MNOPERM; goto Return; } rp->request->outcome |= RS_IMMEDIATE; } size = chfiles(rp->request->file_list, Lp_Uid, Lp_Gid); if (size < 0) { status = MUNKNOWN; goto Return; } if (!(rp->request->outcome & RS_HELD) && size == 0) { status = MNOPERM; goto Return; } osize = rp->secure->size; rp->secure->size = size; if (move_ok == 0) { char *dest = strdup(r->destination); if ((status = mv_file(rp, dest)) == MOK) rp->secure->size = osize; free(dest); } else if ((err = validate_request(rp, (char **)0, move_ok)) != MOK) { status = err; rp->secure->size = osize; } else { status = MOK; if ((rp->request->outcome & RS_IMMEDIATE) || (rp->request->priority != oldr.priority)) { remover(rp); insertr(rp); } freerequest(&oldr); (void) putrequest(rp->req_file, rp->request); /* * fix for bugid 1103890. * use Putsecure instead. */ (void) Putsecure(rp->req_file, rp->secure); } } } Return: if (status != MOK && rp) { if (r) { freerequest(r); *(rp->request) = oldr; } if (status != MNOSTART) (void) putrequest(rp->req_file, rp->request); } if (call_schedule) maybe_schedule(rp); mputm(md, R_END_CHANGE_REQUEST, status, chkprinter_result); }
papi_status_t papiJobSubmit(papi_service_t handle, char *printer, papi_attribute_t **job_attributes, papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) { papi_status_t status; service_t *svc = handle; job_t *j; int file_no; char *request_id = NULL; REQUEST *request; int i; char *c; char *tmp = NULL; char lpfile[BUFSIZ]; if ((svc == NULL) || (printer == NULL) || (files == NULL) || (job == NULL)) return (PAPI_BAD_ARGUMENT); if (job_ticket != NULL) return (PAPI_OPERATION_NOT_SUPPORTED); if (files != NULL) for (file_no = 0; files[file_no] != NULL; file_no++) if (access(files[file_no], R_OK) < 0) { detailed_error(svc, gettext("Cannot access file: %s: %s"), files[file_no], strerror(errno)); return (PAPI_BAD_ARGUMENT); } if ((*job = j = calloc(1, sizeof (*j))) == NULL) return (PAPI_TEMPORARY_ERROR); /* file_no + 1 for the control file (-0) */ status = lpsched_alloc_files(svc, file_no + 1, &request_id); if (status != PAPI_OK) return (status); request = create_request(svc, (char *)printer, (papi_attribute_t **)job_attributes); for (i = 0; files[i] != NULL; i++) { papi_status_t status; snprintf(lpfile, sizeof (lpfile), "%s%s-%d", "/var/spool/lp/temp/", request_id, i+1); status = copy_file(files[i], lpfile); if (status != PAPI_OK) { detailed_error(svc, gettext("unable to copy: %s -> %s: %s"), files[i], lpfile, strerror(errno)); freerequest(request); return (PAPI_DEVICE_ERROR); } addlist(&(request->file_list), lpfile); } #ifdef LP_USE_PAPI_ATTR /* * store the job attributes in the PAPI job attribute file that was * created by lpsched_alloc_files(), the attributes will then pass * through lpsched and be given to the slow-filters and the printer's * interface script to process them */ snprintf(lpfile, sizeof (lpfile), "%s%s-%s", "/var/spool/lp/temp/", request_id, LP_PAPIATTRNAME); status = psm_copy_attrsToFile(job_attributes, lpfile); if (status != PAPI_OK) { detailed_error(svc, "unable to copy attributes to file: %s: %s", lpfile, strerror(errno)); return (PAPI_DEVICE_ERROR); } #endif /* store the meta-data file */ snprintf(lpfile, sizeof (lpfile), "%s-0", request_id); if (putrequest(lpfile, request) < 0) { detailed_error(svc, gettext("unable to save request: %s: %s"), lpfile, strerror(errno)); freerequest(request); return (PAPI_DEVICE_ERROR); } status = lpsched_commit_job(svc, lpfile, &tmp); if (status != PAPI_OK) { unlink(lpfile); freerequest(request); return (status); } lpsched_request_to_job_attributes(request, j); freerequest(request); if ((c = strrchr(tmp, '-')) != NULL) c++; papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE, "job-id", atoi(c)); papiAttributeListAddString(&j->attributes, PAPI_ATTR_REPLACE, "job-uri", tmp); return (PAPI_OK); }