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
;
955 if ((handle
== NULL
) || (printer
== NULL
) || (job_id
< 0))
956 return (PAPI_BAD_ARGUMENT
);
958 dest
= printer_name_from_uri_id(printer
, job_id
);
959 snprintf(req_id
, sizeof (req_id
), "%s-%d", dest
, job_id
);
962 rc
= snd_msg(svc
, S_INQUIRE_REQUEST_RANK
, 0, "", "", req_id
, "", "");
964 return (PAPI_SERVICE_UNAVAILABLE
);
966 if (rcv_msg(svc
, R_INQUIRE_REQUEST_RANK
, &rc
, &request_id
,
967 &user
, &slabel
, &size
, &date
, &state
, &dest
, &form
,
968 &charset
, &rank
, &file
) < 0) {
970 gettext("failed to read response from scheduler"));
971 return (PAPI_DEVICE_ERROR
);
974 if ((request_id
== NULL
) || (request_id
[0] == NULL
))
975 return (PAPI_NOT_FOUND
);
977 if ((*job
= j
= calloc(1, sizeof (*j
))) == NULL
)
978 return (PAPI_TEMPORARY_ERROR
);
980 snprintf(req_id
, sizeof (req_id
), "%d-0", job_id
);
981 lpsched_read_job_configuration(svc
, j
, req_id
);
983 job_status_to_attributes(j
, request_id
, user
, slabel
, size
, date
, state
,
984 dest
, form
, charset
, rank
, file
);
990 papiJobMove(papi_service_t handle
, char *printer
, int32_t job_id
,
993 papi_status_t result
= PAPI_OK
;
995 service_t
*svc
= handle
;
1000 if ((svc
== NULL
) || (printer
== NULL
) || (job_id
< 0) ||
1001 (destination
== NULL
))
1002 return (PAPI_BAD_ARGUMENT
);
1004 queue
= printer_name_from_uri_id(printer
, job_id
);
1005 snprintf(req_id
, sizeof (req_id
), "%s-%d", queue
, job_id
);
1008 if (papiAttributeListGetString(svc
->attributes
, NULL
, "user-name",
1009 &user
) == PAPI_OK
) {
1010 REQUEST
*r
= getrequest(req_id
);
1012 if ((r
!= NULL
) && (r
->user
!= NULL
) &&
1013 (strcmp(r
->user
, user
) != 0))
1014 result
= PAPI_NOT_AUTHORIZED
;
1018 if (result
== PAPI_OK
) {
1020 char *dest
= printer_name_from_uri_id(destination
, -1);
1022 if ((snd_msg(svc
, S_MOVE_REQUEST
, req_id
, dest
) < 0) ||
1023 (rcv_msg(svc
, R_MOVE_REQUEST
, &status
, &bits
) < 0))
1024 status
= MTRANSMITERR
;
1028 result
= lpsched_status_to_papi_status(status
);
1035 papiJobCancel(papi_service_t handle
, char *printer
, int32_t job_id
)
1037 papi_status_t result
= PAPI_OK
;
1038 service_t
*svc
= handle
;
1043 if ((svc
== NULL
) || (printer
== NULL
) || (job_id
< 0))
1044 return (PAPI_BAD_ARGUMENT
);
1046 dest
= printer_name_from_uri_id(printer
, job_id
);
1047 snprintf(req_id
, sizeof (req_id
), "%s-%d", dest
, job_id
);
1050 if (papiAttributeListGetString(svc
->attributes
, NULL
, "user-name",
1051 &user
) == PAPI_OK
) {
1052 REQUEST
*r
= getrequest(req_id
);
1054 if ((result
= authorized(handle
, job_id
)) != PAPI_OK
)
1055 result
= PAPI_NOT_AUTHORIZED
;
1057 if ((r
!= NULL
) && (r
->user
!= NULL
) &&
1058 (strcmp(r
->user
, user
) != 0))
1059 result
= PAPI_NOT_AUTHORIZED
;
1063 if (result
== PAPI_OK
) {
1066 if ((snd_msg(svc
, S_CANCEL_REQUEST
, req_id
) < 0) ||
1067 (rcv_msg(svc
, R_CANCEL_REQUEST
, &status
) < 0))
1068 status
= MTRANSMITERR
;
1070 result
= lpsched_status_to_papi_status(status
);
1077 hold_release_job(papi_service_t handle
, char *printer
,
1078 int32_t job_id
, int flag
)
1080 papi_status_t status
;
1081 service_t
*svc
= handle
;
1086 if ((svc
== NULL
) || (printer
== NULL
) || (job_id
< 0))
1087 return (PAPI_BAD_ARGUMENT
);
1089 if ((status
= authorized(svc
, job_id
)) != PAPI_OK
)
1092 dest
= printer_name_from_uri_id(printer
, job_id
);
1093 status
= lpsched_start_change(svc
, dest
, job_id
, &file
);
1094 if (status
!= PAPI_OK
)
1097 if ((r
= getrequest(file
)) != NULL
) {
1098 r
->actions
&= ~ACT_RESUME
;
1101 r
->actions
|= ACT_HOLD
;
1104 r
->actions
|= ACT_RESUME
;
1107 r
->actions
|= ACT_IMMEDIATE
;
1110 if (putrequest(file
, r
) < 0) {
1112 gettext("failed to write job: %s: %s"),
1113 file
, strerror(errno
));
1115 return (PAPI_DEVICE_ERROR
);
1119 detailed_error(svc
, gettext("failed to read job: %s: %s"),
1120 file
, strerror(errno
));
1121 return (PAPI_DEVICE_ERROR
);
1124 status
= lpsched_end_change(svc
, dest
, job_id
);
1130 papiJobHold(papi_service_t handle
, char *printer
, int32_t job_id
)
1132 return (hold_release_job(handle
, printer
, job_id
, 0));
1136 papiJobRelease(papi_service_t handle
, char *printer
, int32_t job_id
)
1138 return (hold_release_job(handle
, printer
, job_id
, 1));
1142 papiJobPromote(papi_service_t handle
, char *printer
, int32_t job_id
)
1144 return (hold_release_job(handle
, printer
, job_id
, 2));
1148 papiJobModify(papi_service_t handle
, char *printer
, int32_t job_id
,
1149 papi_attribute_t
**attributes
, papi_job_t
*job
)
1151 papi_status_t status
;
1153 service_t
*svc
= handle
;
1157 char lpfile
[BUFSIZ
];
1158 int32_t job_id_actual
;
1160 if ((svc
== NULL
) || (printer
== NULL
) || (job_id
< 0) ||
1161 (attributes
== NULL
))
1162 return (PAPI_BAD_ARGUMENT
);
1164 if ((*job
= j
= calloc(1, sizeof (*j
))) == NULL
)
1165 return (PAPI_TEMPORARY_ERROR
);
1167 dest
= printer_name_from_uri_id(printer
, job_id
);
1170 * job-id might be job-id-requested
1171 * If it is job-id-requested then we need to
1172 * look for corresponding job-id
1174 job_id_actual
= check_job_id(svc
, printer
, job_id
);
1176 if (job_id_actual
< 0) {
1177 status
= PAPI_NOT_FOUND
;
1179 "failed to initiate change for job (%s-%d): %s",
1180 dest
, job_id
, "no such resource");
1184 status
= lpsched_start_change(svc
, dest
, job_id_actual
, &file
);
1185 if (status
!= PAPI_OK
)
1188 if ((r
= getrequest(file
)) != NULL
) {
1189 job_attributes_to_lpsched_request(handle
, r
,
1190 (papi_attribute_t
**)attributes
);
1191 #ifdef LP_USE_PAPI_ATTR
1193 * store the job attributes in the PAPI job attribute file
1194 * that was created by the original job request. We need to
1195 * modify the attributes in the file as per the new attributes
1197 snprintf(lpfile
, sizeof (lpfile
), "%s%d-%s",
1198 "/var/spool/lp/temp/", job_id_actual
, LP_PAPIATTRNAME
);
1199 status
= psm_modifyAttrsFile(attributes
, lpfile
);
1200 if (status
!= PAPI_OK
) {
1202 "unable to modify the attributes file: %s: %s",
1203 lpfile
, strerror(errno
));
1204 return (PAPI_DEVICE_ERROR
);
1208 if (putrequest(file
, r
) < 0) {
1210 gettext("failed to write job: %s: %s"),
1211 file
, strerror(errno
));
1213 return (PAPI_DEVICE_ERROR
);
1216 detailed_error(svc
, gettext("failed to read job: %s: %s"),
1217 file
, strerror(errno
));
1218 return (PAPI_DEVICE_ERROR
);
1221 status
= lpsched_end_change(svc
, dest
, job_id_actual
);
1222 lpsched_request_to_job_attributes(r
, j
);
1224 papiAttributeListAddInteger(&j
->attributes
, PAPI_ATTR_REPLACE
,
1225 "job-id", job_id_actual
);
1233 * Extension to PAPI, a variation of this is slated for post-1.0
1235 #define DUMMY_FILE "/var/spool/lp/fifos/FIFO"
1238 papiJobCreate(papi_service_t handle
, char *printer
,
1239 papi_attribute_t
**job_attributes
,
1240 papi_job_ticket_t
*job_ticket
, papi_job_t
*job
)
1242 papi_status_t status
;
1243 service_t
*svc
= handle
;
1246 char *request_id
= NULL
;
1249 char metadata_file
[MAXPATHLEN
];
1251 if ((svc
== NULL
) || (printer
== NULL
) || (job
== NULL
))
1252 return (PAPI_BAD_ARGUMENT
);
1254 if (job_ticket
!= NULL
)
1255 return (PAPI_JOB_TICKET_NOT_SUPPORTED
);
1257 if ((*job
= j
= calloc(1, sizeof (*j
))) == NULL
)
1258 return (PAPI_TEMPORARY_ERROR
);
1260 /* 1 for the control file (-0) */
1261 status
= lpsched_alloc_files(svc
, 1, &request_id
);
1262 if (status
!= PAPI_OK
)
1265 /* convert the attributes to an lpsched REQUEST structure */
1266 request
= create_request(svc
, (char *)printer
,
1267 (papi_attribute_t
**)job_attributes
);
1268 if (request
== NULL
)
1269 return (PAPI_TEMPORARY_ERROR
);
1270 addlist(&request
->file_list
, DUMMY_FILE
); /* add a dummy file */
1271 request
->actions
|= ACT_HOLD
; /* hold the job */
1273 #ifdef LP_USE_PAPI_ATTR
1275 * store the job attributes in the PAPI job attribute file that was
1276 * created by lpsched_alloc_files(), the attributes will then pass
1277 * through lpsched and be given to the slow-filters and the printer's
1278 * interface script to process them
1280 snprintf(metadata_file
, sizeof (metadata_file
), "%s%s-%s",
1281 "/var/spool/lp/temp/", request_id
, LP_PAPIATTRNAME
);
1282 status
= psm_copy_attrsToFile(job_attributes
, metadata_file
);
1283 if (status
!= PAPI_OK
) {
1284 detailed_error(svc
, "unable to copy attributes to file: %s: %s",
1285 metadata_file
, strerror(errno
));
1287 return (PAPI_DEVICE_ERROR
);
1291 /* store the REQUEST on disk */
1292 snprintf(metadata_file
, sizeof (metadata_file
), "%s-0", request_id
);
1294 if (putrequest(metadata_file
, request
) < 0) {
1295 detailed_error(svc
, gettext("unable to save request: %s: %s"),
1296 metadata_file
, strerror(errno
));
1297 return (PAPI_DEVICE_ERROR
);
1300 status
= lpsched_commit_job(svc
, metadata_file
, &tmp
);
1301 if (status
!= PAPI_OK
) {
1302 unlink(metadata_file
);
1306 lpsched_request_to_job_attributes(request
, j
);
1308 if ((c
= strrchr(tmp
, '-')) != NULL
)
1310 papiAttributeListAddInteger(&j
->attributes
, PAPI_ATTR_REPLACE
,
1312 papiAttributeListAddString(&j
->attributes
, PAPI_ATTR_REPLACE
,
1319 papiJobCommit(papi_service_t handle
, char *printer
, int32_t id
)
1321 papi_status_t status
= PAPI_OK
;
1322 service_t
*svc
= handle
;
1324 char *metadata_file
;
1327 if ((svc
== NULL
) || (printer
== NULL
))
1328 return (PAPI_BAD_ARGUMENT
);
1330 dest
= printer_name_from_uri_id(printer
, id
);
1331 /* tell the scheduler that we want to change the job */
1332 status
= lpsched_start_change(svc
, dest
, id
, &metadata_file
);
1333 if (status
!= PAPI_OK
)
1336 if ((r
= getrequest(metadata_file
)) != NULL
) {
1337 r
->actions
&= ~ACT_RESUME
;
1338 r
->actions
|= ACT_RESUME
;
1339 dellist(&r
->file_list
, DUMMY_FILE
);
1341 if (putrequest(metadata_file
, r
) < 0) {
1343 gettext("failed to write job: %s: %s"),
1344 metadata_file
, strerror(errno
));
1346 return (PAPI_DEVICE_ERROR
);
1349 detailed_error(svc
, gettext("failed to read job: %s: %s"),
1350 metadata_file
, strerror(errno
));
1351 return (PAPI_DEVICE_ERROR
);
1354 status
= lpsched_end_change(svc
, dest
, id
);
1361 papiJobStreamAdd(papi_service_t handle
, char *printer
, int32_t id
,
1362 papi_stream_t
*stream
)
1364 papi_status_t status
;
1365 service_t
*svc
= handle
;
1366 job_stream_t
*s
= NULL
;
1367 char *metadata_file
= NULL
;
1369 char path
[MAXPATHLEN
];
1371 /* allocate space for the stream */
1372 if ((*stream
= s
= calloc(1, sizeof (*s
))) == NULL
)
1373 return (PAPI_TEMPORARY_ERROR
);
1375 dest
= printer_name_from_uri_id(printer
, id
);
1376 /* create/open data file (only root or lp can really do this */
1377 snprintf(path
, sizeof (path
), "/var/spool/lp/temp/%d-XXXXXX", id
);
1378 if ((s
->fd
= mkstemp(path
)) < 0) {
1379 detailed_error(svc
, gettext("unable to create sink (%s): %s"),
1380 path
, strerror(errno
));
1382 return (PAPI_NOT_AUTHORIZED
);
1385 /* add data file to job */
1386 status
= lpsched_start_change(svc
, dest
, id
, &metadata_file
);
1387 if (status
!= PAPI_OK
) {
1394 if ((s
->request
= getrequest(metadata_file
)) == NULL
) {
1395 detailed_error(svc
, gettext("unable to load request: %s: %s"),
1396 metadata_file
, strerror(errno
));
1400 return (PAPI_NOT_POSSIBLE
);
1403 addlist(&(s
->request
->file_list
), path
);
1405 if (putrequest(metadata_file
, s
->request
) < 0) {
1406 detailed_error(svc
, gettext("unable to save request: %s: %s"),
1407 metadata_file
, strerror(errno
));
1411 return (PAPI_NOT_POSSIBLE
);
1414 status
= lpsched_end_change(svc
, dest
, id
);
1416 if (status
!= PAPI_OK
)