4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
33 #include <papi_impl.h>
36 * for an older application that may have been linked with a pre-v1.0
37 * PAPI implementation.
40 papiAttributeListAdd(papi_attribute_t
***attrs
, int flags
, char *name
,
41 papi_attribute_value_type_t type
, papi_attribute_value_t
*value
)
43 return (papiAttributeListAddValue(attrs
, flags
, name
, type
, value
));
46 #ifdef LP_USE_PAPI_ATTR
47 static papi_status_t
psm_modifyAttrsFile(papi_attribute_t
**attrs
, char *file
);
48 static papi_status_t
psm_modifyAttrsList(char *file
, papi_attribute_t
**attrs
,
49 papi_attribute_t
***newAttrs
);
53 check_job_id(papi_service_t svc
, char *printer
, int32_t id
)
55 papi_job_t
*jobs
= NULL
;
58 char *jattrs
[] = { "job-id",
59 "job-id-requested", NULL
};
61 status
= papiPrinterListJobs(svc
, printer
, jattrs
, PAPI_LIST_JOBS_ALL
,
64 if (status
!= PAPI_OK
) {
66 gettext("Failed to query service for %s: %s\n"),
67 printer
, lpsched_status_string(status
));
74 for (i
= 0; jobs
[i
] != NULL
; i
++) {
77 papi_attribute_t
**list
=
78 papiJobGetAttributeList(jobs
[i
]);
80 papiAttributeListGetInteger(list
, NULL
,
81 "job-id-requested", &rid
);
82 papiAttributeListGetInteger(list
, NULL
,
86 * check if id matches with either rid or jid
89 /* get the actual id and return it */
90 papiAttributeListGetInteger(list
, NULL
,
93 } else if (jid
== id
) {
96 * It is a remote lpd job.
97 * It cannot be modified based on job-id
103 * It is either local job or
115 papiJobFree(papi_job_t job
)
117 job_t
*tmp
= (job_t
*)job
;
120 papiAttributeListFree(tmp
->attributes
);
126 papiJobListFree(papi_job_t
*jobs
)
131 for (i
= 0; jobs
[i
] != NULL
; i
++) {
132 papiJobFree(jobs
[i
]);
139 papiJobGetAttributeList(papi_job_t job
)
141 job_t
*tmp
= (job_t
*)job
;
144 return (tmp
->attributes
);
150 papiJobGetPrinterName(papi_job_t job
)
152 job_t
*tmp
= (job_t
*)job
;
156 papiAttributeListGetString(tmp
->attributes
, NULL
,
157 "printer-name", &result
);
163 papiJobGetId(papi_job_t job
)
165 job_t
*tmp
= (job_t
*)job
;
169 papiAttributeListGetInteger(tmp
->attributes
, NULL
, "job-id",
176 create_request(papi_service_t svc
, char *printer
, papi_attribute_t
**attributes
)
180 if ((r
= calloc(1, sizeof (*r
))) != NULL
) {
181 char *hostname
= NULL
;
184 r
->destination
= printer_name_from_uri_id(printer
, -1);
186 papiAttributeListGetString(attributes
, NULL
,
187 "job-originating-host-name", &hostname
);
189 if (hostname
== NULL
) {
192 if (gethostname(host
, sizeof (host
)) == 0)
193 papiAttributeListAddString(&attributes
,
195 "job-originating-host-name",
199 job_attributes_to_lpsched_request(svc
, r
, attributes
);
206 authorized(service_t
*svc
, int32_t id
)
208 papi_status_t result
= PAPI_NOT_AUTHORIZED
; /* assume the worst */
212 snprintf(file
, sizeof (file
), "%d-0", id
);
213 if ((r
= getrequest(file
)) != NULL
) {
214 uid_t uid
= getuid();
215 struct passwd
*pw
= NULL
;
216 char *user
= "intruder"; /* assume an intruder */
218 if ((pw
= getpwuid(uid
)) != NULL
)
219 user
= pw
->pw_name
; /* use the process owner */
221 if ((uid
== 0) || (uid
== 71)) { /* root/lp can forge this */
223 s
= papiAttributeListGetString(svc
->attributes
, NULL
,
225 if (s
!= PAPI_OK
) /* true root/lp are almighty */
229 if (result
!= PAPI_OK
) {
230 if (strcmp(user
, r
->user
) == 0)
234 * user and r->user might contain the
237 char *token1
= strtok(r
->user
, "@");
238 char *token2
= strtok(NULL
, "@");
239 char *token3
= strtok(user
, "@");
240 char *token4
= strtok(NULL
, "@");
243 * token1 and token3 contain usernames
244 * token2 and token4 contain hostnames
246 if ((token1
== NULL
) || (token3
== NULL
))
247 result
= PAPI_NOT_AUTHORIZED
;
248 else if ((token4
!= NULL
) &&
249 (strcmp(token4
, "localhost") == 0) &&
250 (strcmp(token3
, "root") == 0) ||
251 (strcmp(token3
, "lp") == 0)) {
253 * root/lp user on server can
257 } else if (strcmp(token1
, token3
) == 0) {
260 * compare the hostnames
262 if ((token4
!= NULL
) &&
264 (strcmp(token4
, "localhost") ==
269 static char host
[256];
270 if (gethostname(host
,
271 sizeof (host
)) == 0) {
272 if ((host
!= NULL
) &&
279 } else if ((token4
!= NULL
) &&
281 (strcmp(token4
, token2
) == 0)) {
283 } else if ((token4
== NULL
) &&
286 * When the request is sent from
287 * client to server using ipp
298 result
= PAPI_NOT_FOUND
;
304 copy_file(char *from
, char *to
)
310 if ((ifd
= open(from
, O_RDONLY
)) < 0)
311 return (PAPI_DOCUMENT_ACCESS_ERROR
);
313 if ((ofd
= open(to
, O_WRONLY
)) < 0) {
315 return (PAPI_NOT_POSSIBLE
);
318 while ((rc
= read(ifd
, buf
, sizeof (buf
))) > 0)
328 #ifdef LP_USE_PAPI_ATTR
330 * *****************************************************************************
332 * Description: Create a file containing all the attributes in the attribute
333 * list passed to this function.
334 * This file is then passed through lpsched and given to either
335 * a slow-filter or to the printer's interface script to process
338 * Parameters: attrs - list of attributes and their values
339 * file - file pathname to create and put the attributes into.
341 * *****************************************************************************
345 psm_copy_attrsToFile(papi_attribute_t
**attrs
, char *file
)
348 papi_status_t result
= PAPI_OK
;
350 if ((attrs
!= NULL
) && (*attrs
!= NULL
)) {
353 if ((out
= fopen(file
, "w")) != NULL
) {
354 papiAttributeListPrint(out
, attrs
, "");
357 result
= PAPI_NOT_POSSIBLE
;
362 } /* psm_copy_attrsToFile */
366 * *****************************************************************************
368 * Description: Modify the given attribute 'file' with the attributes from the
369 * 'attrs' list. Attributes already in the file will be replaced
370 * with the new value. New attributes will be added into the file.
372 * Parameters: attrs - list of attributes and their values
373 * file - file pathname to create and put the attributes into.
375 * *****************************************************************************
379 psm_modifyAttrsFile(papi_attribute_t
**attrs
, char *file
)
382 papi_status_t result
= PAPI_OK
;
383 papi_attribute_t
**newAttrs
= NULL
;
387 if ((attrs
!= NULL
) && (*attrs
!= NULL
) && (file
!= NULL
)) {
390 * check file exist before try to modify it, if it doesn't
391 * exist assume there is an error
393 if (stat(file
, &tmpBuf
) == 0) {
395 * if file is currently empty just write the given
396 * attributes to the file otherwise exact the attributes
397 * from the file and modify them accordingly before
398 * writing them back to the file
400 if (tmpBuf
.st_size
== 0) {
401 newAttrs
= (papi_attribute_t
**)attrs
;
403 fd
= fopen(file
, "w");
405 papiAttributeListPrint(fd
,
409 result
= PAPI_NOT_POSSIBLE
;
413 psm_modifyAttrsList(file
, attrs
, &newAttrs
);
415 fd
= fopen(file
, "w");
417 papiAttributeListPrint(fd
,
421 result
= PAPI_NOT_POSSIBLE
;
424 papiAttributeListFree(newAttrs
);
427 result
= PAPI_NOT_POSSIBLE
;
432 } /* psm_modifyAttrsFile */
436 * *****************************************************************************
438 * Description: Extracts the attributes in the given attribute 'file' and
439 * creates a new list 'newAttrs' containing the modified list of
442 * Parameters: file - pathname of file containing attributes to be modified
443 * attrs - list of attributes and their values to modify
444 * newAttrs - returns the modified list of attributes
446 * *****************************************************************************
450 psm_modifyAttrsList(char *file
, papi_attribute_t
**attrs
,
451 papi_attribute_t
***newAttrs
)
454 papi_status_t result
= PAPI_OK
;
455 papi_attribute_t
*nextAttr
= NULL
;
456 papi_attribute_value_t
**values
= NULL
;
466 fd
= fopen(file
, "r");
471 count
= read(fD
, &aBuff
[0], sizeof (aBuff
) - 1);
472 while ((result
== PAPI_OK
) && (count
> 0)) {
473 aBuff
[count
+n
] = '\0';
474 if (count
== sizeof (aBuff
) - n
- 1) {
475 p
= strrchr(aBuff
, '\n');
477 /* terminate at last complete line */
481 result
= papiAttributeListFromString(
482 newAttrs
, PAPI_ATTR_EXCL
, aBuff
);
484 if (result
== PAPI_OK
) {
486 * handle any part lines and then read the next
487 * buffer from the file
492 n
= sizeof (aBuff
) - 1 - (p
- a
);
493 strncpy(aBuff
, p
, n
);
495 count
= read(fD
, &aBuff
[n
],
496 sizeof (aBuff
) - n
- 1);
503 /* now modify the attribute list with the new attributes in 'attrs' */
505 nextAttr
= papiAttributeListGetNext((papi_attribute_t
**)attrs
, &iter
);
506 while ((result
== PAPI_OK
) && (nextAttr
!= NULL
)) {
507 values
= nextAttr
->values
;
509 if ((values
!= NULL
) && (*values
!= NULL
)) {
510 result
= papiAttributeListAddValue(newAttrs
,
513 nextAttr
->type
, *values
);
517 while ((result
== PAPI_OK
) &&
518 (values
!= NULL
) && (*values
!= NULL
)) {
519 result
= papiAttributeListAddValue(newAttrs
,
522 nextAttr
->type
, *values
);
526 papiAttributeListGetNext((papi_attribute_t
**)attrs
, &iter
);
530 } /* papi_modifyAttrsList() */
535 papiJobSubmit(papi_service_t handle
, char *printer
,
536 papi_attribute_t
**job_attributes
,
537 papi_job_ticket_t
*job_ticket
,
538 char **files
, papi_job_t
*job
)
540 papi_status_t status
;
541 service_t
*svc
= handle
;
545 char *request_id
= NULL
;
552 if ((svc
== NULL
) || (printer
== NULL
) || (files
== NULL
) ||
554 return (PAPI_BAD_ARGUMENT
);
556 if (job_ticket
!= NULL
)
557 return (PAPI_OPERATION_NOT_SUPPORTED
);
560 for (file_no
= 0; files
[file_no
] != NULL
; file_no
++) {
561 if (access(files
[file_no
], R_OK
) < 0) {
563 gettext("Cannot access file: %s: %s"),
564 files
[file_no
], strerror(errno
));
565 return (PAPI_BAD_ARGUMENT
);
567 if (stat(files
[file_no
], &statbuf
) < 0) {
569 gettext("Cannot access file: %s: %s"),
570 files
[file_no
], strerror(errno
));
571 return (PAPI_DOCUMENT_ACCESS_ERROR
);
573 if (statbuf
.st_size
== 0) {
575 gettext("Zero byte (empty) file: %s"),
577 return (PAPI_BAD_ARGUMENT
);
581 if ((*job
= j
= calloc(1, sizeof (*j
))) == NULL
)
582 return (PAPI_TEMPORARY_ERROR
);
584 /* file_no + 1 for the control file (-0) */
585 status
= lpsched_alloc_files(svc
, file_no
+ 1, &request_id
);
586 if (status
!= PAPI_OK
)
589 request
= create_request(svc
, (char *)printer
,
590 (papi_attribute_t
**)job_attributes
);
592 for (i
= 0; files
[i
] != NULL
; i
++) {
593 papi_status_t status
;
594 snprintf(lpfile
, sizeof (lpfile
), "%s%s-%d",
595 "/var/spool/lp/temp/", request_id
, i
+1);
596 status
= copy_file(files
[i
], lpfile
);
597 if (status
!= PAPI_OK
) {
599 gettext("unable to copy: %s -> %s: %s"),
600 files
[i
], lpfile
, strerror(errno
));
601 freerequest(request
);
602 return (PAPI_DEVICE_ERROR
);
604 addlist(&(request
->file_list
), lpfile
);
607 #ifdef LP_USE_PAPI_ATTR
609 * store the job attributes in the PAPI job attribute file that was
610 * created by lpsched_alloc_files(), the attributes will then pass
611 * through lpsched and be given to the slow-filters and the printer's
612 * interface script to process them
614 snprintf(lpfile
, sizeof (lpfile
), "%s%s-%s",
615 "/var/spool/lp/temp/", request_id
, LP_PAPIATTRNAME
);
616 status
= psm_copy_attrsToFile(job_attributes
, lpfile
);
617 if (status
!= PAPI_OK
) {
618 detailed_error(svc
, "unable to copy attributes to file: %s: %s",
619 lpfile
, strerror(errno
));
620 return (PAPI_DEVICE_ERROR
);
624 /* store the meta-data file */
625 snprintf(lpfile
, sizeof (lpfile
), "%s-0", request_id
);
626 if (putrequest(lpfile
, request
) < 0) {
627 detailed_error(svc
, gettext("unable to save request: %s: %s"),
628 lpfile
, strerror(errno
));
629 freerequest(request
);
630 return (PAPI_DEVICE_ERROR
);
633 status
= lpsched_commit_job(svc
, lpfile
, &tmp
);
634 if (status
!= PAPI_OK
) {
636 freerequest(request
);
640 lpsched_request_to_job_attributes(request
, j
);
641 freerequest(request
);
643 if ((c
= strrchr(tmp
, '-')) != NULL
)
645 papiAttributeListAddInteger(&j
->attributes
, PAPI_ATTR_REPLACE
,
647 papiAttributeListAddString(&j
->attributes
, PAPI_ATTR_REPLACE
,
654 papiJobSubmitByReference(papi_service_t handle
, char *printer
,
655 papi_attribute_t
**job_attributes
,
656 papi_job_ticket_t
*job_ticket
,
657 char **files
, papi_job_t
*job
)
659 service_t
*svc
= handle
;
664 char *request_id
= NULL
;
669 char **file_list
= NULL
;
671 if ((svc
== NULL
) || (printer
== NULL
) || (files
== NULL
) ||
673 return (PAPI_BAD_ARGUMENT
);
675 if (job_ticket
!= NULL
)
676 return (PAPI_OPERATION_NOT_SUPPORTED
);
679 for (file_no
= 0; files
[file_no
] != NULL
; file_no
++) {
680 if (access(files
[file_no
], R_OK
) < 0) {
682 gettext("Cannot access file: %s: %s"),
683 files
[file_no
], strerror(errno
));
684 return (PAPI_DOCUMENT_ACCESS_ERROR
);
686 if (stat(files
[file_no
], &statbuf
) < 0) {
688 gettext("Cannot access file: %s: %s"),
689 files
[file_no
], strerror(errno
));
690 return (PAPI_DOCUMENT_ACCESS_ERROR
);
692 if (statbuf
.st_size
== 0) {
694 gettext("Zero byte (empty) file: %s"),
696 return (PAPI_BAD_ARGUMENT
);
699 if (files
[file_no
][0] != '/') {
700 char path
[MAXPATHLEN
];
702 if (getcwd(path
, sizeof (path
)) == NULL
) {
703 detailed_error(svc
, gettext(
704 "getcwd for file: %s: %s"),
707 return (PAPI_DOCUMENT_ACCESS_ERROR
);
709 strlcat(path
, "/", sizeof (path
));
710 if (strlcat(path
, files
[file_no
], sizeof (path
))
712 detailed_error(svc
, gettext(
713 "pathname too long: %s"),
715 return (PAPI_DOCUMENT_ACCESS_ERROR
);
717 addlist(&file_list
, path
);
719 addlist(&file_list
, (char *)files
[file_no
]);
722 if ((*job
= j
= calloc(1, sizeof (*j
))) == NULL
)
723 return (PAPI_TEMPORARY_ERROR
);
725 /* 1 for the control file (-0) */
726 status
= lpsched_alloc_files(svc
, 1, &request_id
);
727 if (status
!= PAPI_OK
)
730 request
= create_request(svc
, (char *)printer
,
731 (papi_attribute_t
**)job_attributes
);
732 request
->file_list
= file_list
;
734 #ifdef LP_USE_PAPI_ATTR
736 * store the job attributes in the PAPI job attribute file that was
737 * created by lpsched_alloc_files(), the attributes will then pass
738 * through lpsched and be given to the slow-filters and the printer's
739 * interface script to process them
741 snprintf(lpfile
, sizeof (lpfile
), "%s%s-%s",
742 "/var/spool/lp/temp/", request_id
, LP_PAPIATTRNAME
);
743 status
= psm_copy_attrsToFile(job_attributes
, lpfile
);
744 if (status
!= PAPI_OK
) {
745 detailed_error(svc
, "unable to copy attributes to file: %s: %s",
746 lpfile
, strerror(errno
));
747 return (PAPI_DEVICE_ERROR
);
751 /* store the meta-data file */
752 snprintf(lpfile
, sizeof (lpfile
), "%s-0", request_id
);
753 if (putrequest(lpfile
, request
) < 0) {
754 detailed_error(svc
, gettext("unable to save request: %s: %s"),
755 lpfile
, strerror(errno
));
756 freerequest(request
);
757 return (PAPI_DEVICE_ERROR
);
760 status
= lpsched_commit_job(svc
, lpfile
, &tmp
);
761 if (status
!= PAPI_OK
) {
763 freerequest(request
);
767 lpsched_request_to_job_attributes(request
, j
);
769 freerequest(request
);
771 if ((c
= strrchr(tmp
, '-')) != NULL
)
773 papiAttributeListAddInteger(&j
->attributes
, PAPI_ATTR_REPLACE
,
775 papiAttributeListAddString(&j
->attributes
, PAPI_ATTR_REPLACE
,
782 papiJobValidate(papi_service_t handle
, char *printer
,
783 papi_attribute_t
**job_attributes
,
784 papi_job_ticket_t
*job_ticket
,
785 char **files
, papi_job_t
*job
)
787 papi_status_t status
;
788 papi_attribute_t
**attributes
= NULL
;
791 papiAttributeListAddString(&attributes
, PAPI_ATTR_REPLACE
,
792 "job-hold-until", "indefinite");
793 for (i
= 0; job_attributes
[i
]; i
++)
794 list_append(&attributes
, job_attributes
[i
]);
796 status
= papiJobSubmitByReference(handle
, printer
,
797 (papi_attribute_t
**)attributes
,
798 job_ticket
, files
, job
);
799 if (status
== PAPI_OK
) {
800 int id
= papiJobGetId(*job
);
803 papiJobCancel(handle
, printer
, id
);
806 attributes
[1] = NULL
; /* after attr[0], they are in another list */
807 papiAttributeListFree(attributes
);
813 papiJobStreamOpen(papi_service_t handle
, char *printer
,
814 papi_attribute_t
**job_attributes
,
815 papi_job_ticket_t
*job_ticket
, papi_stream_t
*stream
)
817 papi_status_t status
;
818 service_t
*svc
= handle
;
819 job_stream_t
*s
= NULL
;
820 char *request_id
= NULL
;
823 if ((svc
== NULL
) || (printer
== NULL
) || (stream
== NULL
))
824 return (PAPI_BAD_ARGUMENT
);
826 if (job_ticket
!= NULL
)
827 return (PAPI_OPERATION_NOT_SUPPORTED
);
829 if ((*stream
= s
= calloc(1, sizeof (*s
))) == NULL
)
830 return (PAPI_TEMPORARY_ERROR
);
832 /* 1 for data, 1 for the meta-data (-0) */
833 status
= lpsched_alloc_files(svc
, 2, &request_id
);
834 if (status
!= PAPI_OK
)
837 papiAttributeListAddString(&job_attributes
, PAPI_ATTR_EXCL
,
838 "job-name", "standard input");
840 s
->request
= create_request(svc
, (char *)printer
,
841 (papi_attribute_t
**)job_attributes
);
842 snprintf(lpfile
, sizeof (lpfile
), "/var/spool/lp/temp/%s-1",
844 s
->fd
= open(lpfile
, O_WRONLY
);
845 addlist(&(s
->request
->file_list
), lpfile
);
847 #ifdef LP_USE_PAPI_ATTR
849 * store the job attributes in the PAPI job attribute file that was
850 * created by lpsched_alloc_files(), the attributes will then pass
851 * through lpsched and be given to the slow-filters and the printer's
852 * interface script to process them
854 snprintf(lpfile
, sizeof (lpfile
), "%s%s-%s",
855 "/var/spool/lp/temp/", request_id
, LP_PAPIATTRNAME
);
856 status
= psm_copy_attrsToFile(job_attributes
, lpfile
);
857 if (status
!= PAPI_OK
) {
858 detailed_error(svc
, "unable to copy attributes to file: %s: %s",
859 lpfile
, strerror(errno
));
862 return (PAPI_DEVICE_ERROR
);
866 /* store the meta-data file */
867 snprintf(lpfile
, sizeof (lpfile
), "%s-0", request_id
);
868 s
->meta_data_file
= strdup(lpfile
);
869 if (putrequest(lpfile
, s
->request
) < 0) {
870 detailed_error(svc
, gettext("unable to save request: %s: %s"),
871 lpfile
, strerror(errno
));
873 return (PAPI_DEVICE_ERROR
);
880 papiJobStreamWrite(papi_service_t handle
,
881 papi_stream_t stream
, void *buffer
, size_t buflen
)
883 service_t
*svc
= handle
;
884 job_stream_t
*s
= stream
;
886 if ((svc
== NULL
) || (stream
== NULL
) || (buffer
== NULL
))
887 return (PAPI_BAD_ARGUMENT
);
889 if (write(s
->fd
, buffer
, buflen
) != buflen
)
890 return (PAPI_DEVICE_ERROR
);
895 papiJobStreamClose(papi_service_t handle
,
896 papi_stream_t stream
, papi_job_t
*job
)
898 papi_status_t status
= PAPI_OK
;
899 service_t
*svc
= handle
;
900 job_stream_t
*s
= stream
;
902 char *tmp
= NULL
, *c
;
904 if ((svc
== NULL
) || (stream
== NULL
) || (job
== NULL
))
905 return (PAPI_BAD_ARGUMENT
);
907 if ((*job
= j
= calloc(1, sizeof (*j
))) == NULL
)
908 return (PAPI_TEMPORARY_ERROR
);
912 lpsched_request_to_job_attributes(s
->request
, j
);
914 if (s
->meta_data_file
!= NULL
) {
915 status
= lpsched_commit_job(svc
, s
->meta_data_file
, &tmp
);
916 if (status
!= PAPI_OK
) {
917 unlink(s
->meta_data_file
);
920 if ((c
= strrchr(tmp
, '-')) != NULL
)
922 papiAttributeListAddInteger(&j
->attributes
, PAPI_ATTR_REPLACE
,
924 papiAttributeListAddString(&j
->attributes
, PAPI_ATTR_REPLACE
,
926 free(s
->meta_data_file
);
928 freerequest(s
->request
);
935 papiJobQuery(papi_service_t handle
, char *printer
, int32_t job_id
,
936 char **requested_attrs
,
939 service_t
*svc
= handle
;
954 if ((handle
== NULL
) || (printer
== NULL
) || (job_id
< 0))
955 return (PAPI_BAD_ARGUMENT
);
957 dest
= printer_name_from_uri_id(printer
, job_id
);
958 snprintf(req_id
, sizeof (req_id
), "%s-%d", dest
, job_id
);
961 rc
= snd_msg(svc
, S_INQUIRE_REQUEST_RANK
, 0, "", "", req_id
, "", "");
963 return (PAPI_SERVICE_UNAVAILABLE
);
965 if (rcv_msg(svc
, R_INQUIRE_REQUEST_RANK
, &rc
, &request_id
,
966 &user
, &size
, &date
, &state
, &dest
, &form
,
967 &charset
, &rank
, &file
) < 0) {
969 gettext("failed to read response from scheduler"));
970 return (PAPI_DEVICE_ERROR
);
973 if ((request_id
== NULL
) || (request_id
[0] == NULL
))
974 return (PAPI_NOT_FOUND
);
976 if ((*job
= j
= calloc(1, sizeof (*j
))) == NULL
)
977 return (PAPI_TEMPORARY_ERROR
);
979 snprintf(req_id
, sizeof (req_id
), "%d-0", job_id
);
980 lpsched_read_job_configuration(svc
, j
, req_id
);
982 job_status_to_attributes(j
, request_id
, user
, size
, date
, state
,
983 dest
, form
, charset
, rank
, file
);
989 papiJobMove(papi_service_t handle
, char *printer
, int32_t job_id
,
992 papi_status_t result
= PAPI_OK
;
994 service_t
*svc
= handle
;
999 if ((svc
== NULL
) || (printer
== NULL
) || (job_id
< 0) ||
1000 (destination
== NULL
))
1001 return (PAPI_BAD_ARGUMENT
);
1003 queue
= printer_name_from_uri_id(printer
, job_id
);
1004 snprintf(req_id
, sizeof (req_id
), "%s-%d", queue
, job_id
);
1007 if (papiAttributeListGetString(svc
->attributes
, NULL
, "user-name",
1008 &user
) == PAPI_OK
) {
1009 REQUEST
*r
= getrequest(req_id
);
1011 if ((r
!= NULL
) && (r
->user
!= NULL
) &&
1012 (strcmp(r
->user
, user
) != 0))
1013 result
= PAPI_NOT_AUTHORIZED
;
1017 if (result
== PAPI_OK
) {
1019 char *dest
= printer_name_from_uri_id(destination
, -1);
1021 if ((snd_msg(svc
, S_MOVE_REQUEST
, req_id
, dest
) < 0) ||
1022 (rcv_msg(svc
, R_MOVE_REQUEST
, &status
, &bits
) < 0))
1023 status
= MTRANSMITERR
;
1027 result
= lpsched_status_to_papi_status(status
);
1034 papiJobCancel(papi_service_t handle
, char *printer
, int32_t job_id
)
1036 papi_status_t result
= PAPI_OK
;
1037 service_t
*svc
= handle
;
1042 if ((svc
== NULL
) || (printer
== NULL
) || (job_id
< 0))
1043 return (PAPI_BAD_ARGUMENT
);
1045 dest
= printer_name_from_uri_id(printer
, job_id
);
1046 snprintf(req_id
, sizeof (req_id
), "%s-%d", dest
, job_id
);
1049 if (papiAttributeListGetString(svc
->attributes
, NULL
, "user-name",
1050 &user
) == PAPI_OK
) {
1051 REQUEST
*r
= getrequest(req_id
);
1053 if ((result
= authorized(handle
, job_id
)) != PAPI_OK
)
1054 result
= PAPI_NOT_AUTHORIZED
;
1056 if ((r
!= NULL
) && (r
->user
!= NULL
) &&
1057 (strcmp(r
->user
, user
) != 0))
1058 result
= PAPI_NOT_AUTHORIZED
;
1062 if (result
== PAPI_OK
) {
1065 if ((snd_msg(svc
, S_CANCEL_REQUEST
, req_id
) < 0) ||
1066 (rcv_msg(svc
, R_CANCEL_REQUEST
, &status
) < 0))
1067 status
= MTRANSMITERR
;
1069 result
= lpsched_status_to_papi_status(status
);
1076 hold_release_job(papi_service_t handle
, char *printer
,
1077 int32_t job_id
, int flag
)
1079 papi_status_t status
;
1080 service_t
*svc
= handle
;
1085 if ((svc
== NULL
) || (printer
== NULL
) || (job_id
< 0))
1086 return (PAPI_BAD_ARGUMENT
);
1088 if ((status
= authorized(svc
, job_id
)) != PAPI_OK
)
1091 dest
= printer_name_from_uri_id(printer
, job_id
);
1092 status
= lpsched_start_change(svc
, dest
, job_id
, &file
);
1093 if (status
!= PAPI_OK
)
1096 if ((r
= getrequest(file
)) != NULL
) {
1097 r
->actions
&= ~ACT_RESUME
;
1100 r
->actions
|= ACT_HOLD
;
1103 r
->actions
|= ACT_RESUME
;
1106 r
->actions
|= ACT_IMMEDIATE
;
1109 if (putrequest(file
, r
) < 0) {
1111 gettext("failed to write job: %s: %s"),
1112 file
, strerror(errno
));
1114 return (PAPI_DEVICE_ERROR
);
1118 detailed_error(svc
, gettext("failed to read job: %s: %s"),
1119 file
, strerror(errno
));
1120 return (PAPI_DEVICE_ERROR
);
1123 status
= lpsched_end_change(svc
, dest
, job_id
);
1129 papiJobHold(papi_service_t handle
, char *printer
, int32_t job_id
)
1131 return (hold_release_job(handle
, printer
, job_id
, 0));
1135 papiJobRelease(papi_service_t handle
, char *printer
, int32_t job_id
)
1137 return (hold_release_job(handle
, printer
, job_id
, 1));
1141 papiJobPromote(papi_service_t handle
, char *printer
, int32_t job_id
)
1143 return (hold_release_job(handle
, printer
, job_id
, 2));
1147 papiJobModify(papi_service_t handle
, char *printer
, int32_t job_id
,
1148 papi_attribute_t
**attributes
, papi_job_t
*job
)
1150 papi_status_t status
;
1152 service_t
*svc
= handle
;
1156 char lpfile
[BUFSIZ
];
1157 int32_t job_id_actual
;
1159 if ((svc
== NULL
) || (printer
== NULL
) || (job_id
< 0) ||
1160 (attributes
== NULL
))
1161 return (PAPI_BAD_ARGUMENT
);
1163 if ((*job
= j
= calloc(1, sizeof (*j
))) == NULL
)
1164 return (PAPI_TEMPORARY_ERROR
);
1166 dest
= printer_name_from_uri_id(printer
, job_id
);
1169 * job-id might be job-id-requested
1170 * If it is job-id-requested then we need to
1171 * look for corresponding job-id
1173 job_id_actual
= check_job_id(svc
, printer
, job_id
);
1175 if (job_id_actual
< 0) {
1176 status
= PAPI_NOT_FOUND
;
1178 "failed to initiate change for job (%s-%d): %s",
1179 dest
, job_id
, "no such resource");
1183 status
= lpsched_start_change(svc
, dest
, job_id_actual
, &file
);
1184 if (status
!= PAPI_OK
)
1187 if ((r
= getrequest(file
)) != NULL
) {
1188 job_attributes_to_lpsched_request(handle
, r
,
1189 (papi_attribute_t
**)attributes
);
1190 #ifdef LP_USE_PAPI_ATTR
1192 * store the job attributes in the PAPI job attribute file
1193 * that was created by the original job request. We need to
1194 * modify the attributes in the file as per the new attributes
1196 snprintf(lpfile
, sizeof (lpfile
), "%s%d-%s",
1197 "/var/spool/lp/temp/", job_id_actual
, LP_PAPIATTRNAME
);
1198 status
= psm_modifyAttrsFile(attributes
, lpfile
);
1199 if (status
!= PAPI_OK
) {
1201 "unable to modify the attributes file: %s: %s",
1202 lpfile
, strerror(errno
));
1203 return (PAPI_DEVICE_ERROR
);
1207 if (putrequest(file
, r
) < 0) {
1209 gettext("failed to write job: %s: %s"),
1210 file
, strerror(errno
));
1212 return (PAPI_DEVICE_ERROR
);
1215 detailed_error(svc
, gettext("failed to read job: %s: %s"),
1216 file
, strerror(errno
));
1217 return (PAPI_DEVICE_ERROR
);
1220 status
= lpsched_end_change(svc
, dest
, job_id_actual
);
1221 lpsched_request_to_job_attributes(r
, j
);
1223 papiAttributeListAddInteger(&j
->attributes
, PAPI_ATTR_REPLACE
,
1224 "job-id", job_id_actual
);
1232 * Extension to PAPI, a variation of this is slated for post-1.0
1234 #define DUMMY_FILE "/var/spool/lp/fifos/FIFO"
1237 papiJobCreate(papi_service_t handle
, char *printer
,
1238 papi_attribute_t
**job_attributes
,
1239 papi_job_ticket_t
*job_ticket
, papi_job_t
*job
)
1241 papi_status_t status
;
1242 service_t
*svc
= handle
;
1245 char *request_id
= NULL
;
1248 char metadata_file
[MAXPATHLEN
];
1250 if ((svc
== NULL
) || (printer
== NULL
) || (job
== NULL
))
1251 return (PAPI_BAD_ARGUMENT
);
1253 if (job_ticket
!= NULL
)
1254 return (PAPI_JOB_TICKET_NOT_SUPPORTED
);
1256 if ((*job
= j
= calloc(1, sizeof (*j
))) == NULL
)
1257 return (PAPI_TEMPORARY_ERROR
);
1259 /* 1 for the control file (-0) */
1260 status
= lpsched_alloc_files(svc
, 1, &request_id
);
1261 if (status
!= PAPI_OK
)
1264 /* convert the attributes to an lpsched REQUEST structure */
1265 request
= create_request(svc
, (char *)printer
,
1266 (papi_attribute_t
**)job_attributes
);
1267 if (request
== NULL
)
1268 return (PAPI_TEMPORARY_ERROR
);
1269 addlist(&request
->file_list
, DUMMY_FILE
); /* add a dummy file */
1270 request
->actions
|= ACT_HOLD
; /* hold the job */
1272 #ifdef LP_USE_PAPI_ATTR
1274 * store the job attributes in the PAPI job attribute file that was
1275 * created by lpsched_alloc_files(), the attributes will then pass
1276 * through lpsched and be given to the slow-filters and the printer's
1277 * interface script to process them
1279 snprintf(metadata_file
, sizeof (metadata_file
), "%s%s-%s",
1280 "/var/spool/lp/temp/", request_id
, LP_PAPIATTRNAME
);
1281 status
= psm_copy_attrsToFile(job_attributes
, metadata_file
);
1282 if (status
!= PAPI_OK
) {
1283 detailed_error(svc
, "unable to copy attributes to file: %s: %s",
1284 metadata_file
, strerror(errno
));
1286 return (PAPI_DEVICE_ERROR
);
1290 /* store the REQUEST on disk */
1291 snprintf(metadata_file
, sizeof (metadata_file
), "%s-0", request_id
);
1293 if (putrequest(metadata_file
, request
) < 0) {
1294 detailed_error(svc
, gettext("unable to save request: %s: %s"),
1295 metadata_file
, strerror(errno
));
1296 return (PAPI_DEVICE_ERROR
);
1299 status
= lpsched_commit_job(svc
, metadata_file
, &tmp
);
1300 if (status
!= PAPI_OK
) {
1301 unlink(metadata_file
);
1305 lpsched_request_to_job_attributes(request
, j
);
1307 if ((c
= strrchr(tmp
, '-')) != NULL
)
1309 papiAttributeListAddInteger(&j
->attributes
, PAPI_ATTR_REPLACE
,
1311 papiAttributeListAddString(&j
->attributes
, PAPI_ATTR_REPLACE
,
1318 papiJobCommit(papi_service_t handle
, char *printer
, int32_t id
)
1320 papi_status_t status
= PAPI_OK
;
1321 service_t
*svc
= handle
;
1323 char *metadata_file
;
1326 if ((svc
== NULL
) || (printer
== NULL
))
1327 return (PAPI_BAD_ARGUMENT
);
1329 dest
= printer_name_from_uri_id(printer
, id
);
1330 /* tell the scheduler that we want to change the job */
1331 status
= lpsched_start_change(svc
, dest
, id
, &metadata_file
);
1332 if (status
!= PAPI_OK
)
1335 if ((r
= getrequest(metadata_file
)) != NULL
) {
1336 r
->actions
&= ~ACT_RESUME
;
1337 r
->actions
|= ACT_RESUME
;
1338 dellist(&r
->file_list
, DUMMY_FILE
);
1340 if (putrequest(metadata_file
, r
) < 0) {
1342 gettext("failed to write job: %s: %s"),
1343 metadata_file
, strerror(errno
));
1345 return (PAPI_DEVICE_ERROR
);
1348 detailed_error(svc
, gettext("failed to read job: %s: %s"),
1349 metadata_file
, strerror(errno
));
1350 return (PAPI_DEVICE_ERROR
);
1353 status
= lpsched_end_change(svc
, dest
, id
);
1360 papiJobStreamAdd(papi_service_t handle
, char *printer
, int32_t id
,
1361 papi_stream_t
*stream
)
1363 papi_status_t status
;
1364 service_t
*svc
= handle
;
1365 job_stream_t
*s
= NULL
;
1366 char *metadata_file
= NULL
;
1368 char path
[MAXPATHLEN
];
1370 /* allocate space for the stream */
1371 if ((*stream
= s
= calloc(1, sizeof (*s
))) == NULL
)
1372 return (PAPI_TEMPORARY_ERROR
);
1374 dest
= printer_name_from_uri_id(printer
, id
);
1375 /* create/open data file (only root or lp can really do this */
1376 snprintf(path
, sizeof (path
), "/var/spool/lp/temp/%d-XXXXXX", id
);
1377 if ((s
->fd
= mkstemp(path
)) < 0) {
1378 detailed_error(svc
, gettext("unable to create sink (%s): %s"),
1379 path
, strerror(errno
));
1381 return (PAPI_NOT_AUTHORIZED
);
1384 /* add data file to job */
1385 status
= lpsched_start_change(svc
, dest
, id
, &metadata_file
);
1386 if (status
!= PAPI_OK
) {
1393 if ((s
->request
= getrequest(metadata_file
)) == NULL
) {
1394 detailed_error(svc
, gettext("unable to load request: %s: %s"),
1395 metadata_file
, strerror(errno
));
1399 return (PAPI_NOT_POSSIBLE
);
1402 addlist(&(s
->request
->file_list
), path
);
1404 if (putrequest(metadata_file
, s
->request
) < 0) {
1405 detailed_error(svc
, gettext("unable to save request: %s: %s"),
1406 metadata_file
, strerror(errno
));
1410 return (PAPI_NOT_POSSIBLE
);
1413 status
= lpsched_end_change(svc
, dest
, id
);
1415 if (status
!= PAPI_OK
)