diff options
author | jacobs <none@none> | 2006-06-22 13:28:31 -0700 |
---|---|---|
committer | jacobs <none@none> | 2006-06-22 13:28:31 -0700 |
commit | 355b4669e025ff377602b6fc7caaf30dbc218371 (patch) | |
tree | 29a740456e8d09f935e18068ce72814285fafeec /usr/src | |
parent | 5d0bc3ededb82d77f7c33d8f58e517a837ba5140 (diff) | |
download | illumos-gate-355b4669e025ff377602b6fc7caaf30dbc218371.tar.gz |
LSARC/2003/547 PAPI Print Commands
LSARC/2006/172 PAPI Print Commands Packaging Breakout
4144591 lpstat -d reports *process* default printer as *system* default printer
4299193 lp -cd <queue> <file> causes multiple -d options errors
4327963 RFE cancel on local queue should not require in.lpd
4331220 lpmove doesn't work on remote print queues
4470602 Customer wants to increase print limit of 52 files to 300
4949866 lpstat shows FAILED printers due to expanded status message
4994469 lpadmin doesn't add filter definitions for printers
6302778 RUNPATH & RPATH errors in SUNWipplu package
6314007 lpstat should report paper type list supported by a printer
6317991 lprm -Pprintername - command results in aSegmentation fault
6338002 lpsched support for PAPI is incomplete
6346505 print commands should use PAPI for service interaction (LSARC/2003/547)
6364267 psm-lpsched has replicated code
6389273 RUNPATH and RPATH failures in SUNWippcore
--HG--
rename : usr/src/cmd/lp/cmd/cancel.c => deleted_files/usr/src/cmd/lp/cmd/cancel.c
rename : usr/src/cmd/lp/cmd/comb.c => deleted_files/usr/src/cmd/lp/cmd/comb.c
rename : usr/src/cmd/lp/cmd/lp.c => deleted_files/usr/src/cmd/lp/cmd/lp.c
rename : usr/src/cmd/lp/cmd/lpc/Makefile => deleted_files/usr/src/cmd/lp/cmd/lpc/Makefile
rename : usr/src/cmd/lp/cmd/lpc/cmds.c => deleted_files/usr/src/cmd/lp/cmd/lpc/cmds.c
rename : usr/src/cmd/lp/cmd/lpc/cmdtab.c => deleted_files/usr/src/cmd/lp/cmd/lpc/cmdtab.c
rename : usr/src/cmd/lp/cmd/lpc/fatalmsg.c => deleted_files/usr/src/cmd/lp/cmd/lpc/fatalmsg.c
rename : usr/src/cmd/lp/cmd/lpc/global.c => deleted_files/usr/src/cmd/lp/cmd/lpc/global.c
rename : usr/src/cmd/lp/cmd/lpc/lpc.c => deleted_files/usr/src/cmd/lp/cmd/lpc/lpc.c
rename : usr/src/cmd/lp/cmd/lpc/lpc.h => deleted_files/usr/src/cmd/lp/cmd/lpc/lpc.h
rename : usr/src/cmd/lp/cmd/lpc/process.c => deleted_files/usr/src/cmd/lp/cmd/lpc/process.c
rename : usr/src/cmd/lp/cmd/lpc/sndrcv.c => deleted_files/usr/src/cmd/lp/cmd/lpc/sndrcv.c
rename : usr/src/cmd/lp/cmd/lpc/topq.c => deleted_files/usr/src/cmd/lp/cmd/lpc/topq.c
rename : usr/src/cmd/lp/cmd/lpmove.c => deleted_files/usr/src/cmd/lp/cmd/lpmove.c
rename : usr/src/cmd/lp/cmd/lpstat/Makefile => deleted_files/usr/src/cmd/lp/cmd/lpstat/Makefile
rename : usr/src/cmd/lp/cmd/lpstat/accept.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/accept.c
rename : usr/src/cmd/lp/cmd/lpstat/add_mounted.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/add_mounted.c
rename : usr/src/cmd/lp/cmd/lpstat/charset.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/charset.c
rename : usr/src/cmd/lp/cmd/lpstat/class.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/class.c
rename : usr/src/cmd/lp/cmd/lpstat/device.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/device.c
rename : usr/src/cmd/lp/cmd/lpstat/done.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/done.c
rename : usr/src/cmd/lp/cmd/lpstat/form.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/form.c
rename : usr/src/cmd/lp/cmd/lpstat/lpstat.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/lpstat.c
rename : usr/src/cmd/lp/cmd/lpstat/lpstat.h => deleted_files/usr/src/cmd/lp/cmd/lpstat/lpstat.h
rename : usr/src/cmd/lp/cmd/lpstat/output.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/output.c
rename : usr/src/cmd/lp/cmd/lpstat/parse.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/parse.c
rename : usr/src/cmd/lp/cmd/lpstat/printer.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/printer.c
rename : usr/src/cmd/lp/cmd/lpstat/request.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/request.c
rename : usr/src/cmd/lp/cmd/lpstat/send_message.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/send_message.c
rename : usr/src/cmd/lp/lib/papi/attribute.c => deleted_files/usr/src/cmd/lp/lib/papi/attribute.c
rename : usr/src/cmd/lp/lib/papi/list.c => deleted_files/usr/src/cmd/lp/lib/papi/list.c
rename : usr/src/cmd/lp/lib/papi/papi.h => deleted_files/usr/src/cmd/lp/lib/papi/papi.h
rename : usr/src/cmd/lp/lib/papi/status.c => deleted_files/usr/src/cmd/lp/lib/papi/status.c
rename : usr/src/cmd/print/cancel/Makefile => deleted_files/usr/src/cmd/print/cancel/Makefile
rename : usr/src/cmd/print/cancel/cancel.c => deleted_files/usr/src/cmd/print/cancel/cancel.c
rename : usr/src/cmd/print/cancel/cancel_list.c => deleted_files/usr/src/cmd/print/cancel/cancel_list.c
rename : usr/src/cmd/print/cancel/cancel_list.h => deleted_files/usr/src/cmd/print/cancel/cancel_list.h
rename : usr/src/cmd/print/lp/Makefile => deleted_files/usr/src/cmd/print/lp/Makefile
rename : usr/src/cmd/print/lpmove/Makefile => deleted_files/usr/src/cmd/print/lpmove/Makefile
rename : usr/src/cmd/print/lpmove/lpmove.c => deleted_files/usr/src/cmd/print/lpmove/lpmove.c
rename : usr/src/cmd/print/lpstat/Makefile => deleted_files/usr/src/cmd/print/lpstat/Makefile
rename : usr/src/cmd/print/lpstat/bsd-functions.c => deleted_files/usr/src/cmd/print/lpstat/bsd-functions.c
rename : usr/src/cmd/print/lpstat/bsd-functions.h => deleted_files/usr/src/cmd/print/lpstat/bsd-functions.h
rename : usr/src/cmd/print/lpstat/lpstat.c => deleted_files/usr/src/cmd/print/lpstat/lpstat.c
rename : usr/src/cmd/print/lpstat/parse.h => deleted_files/usr/src/cmd/print/lpstat/parse.h
rename : usr/src/cmd/print/lpstat/parse_bsd.c => deleted_files/usr/src/cmd/print/lpstat/parse_bsd.c
rename : usr/src/cmd/print/lpstat/sysv-functions.c => deleted_files/usr/src/cmd/print/lpstat/sysv-functions.c
rename : usr/src/cmd/print/lpstat/sysv-functions.h => deleted_files/usr/src/cmd/print/lpstat/sysv-functions.h
rename : usr/src/cmd/print/scripts/accept => deleted_files/usr/src/cmd/print/scripts/accept
rename : usr/src/cmd/lp/lib/papi/mapfile-vers => usr/src/cmd/lp/lib/papi/mapfile
rename : usr/src/cmd/print/lp/cleanup.xml => usr/src/cmd/print/gateway/cleanup.xml
rename : usr/src/cmd/print/lp/print-cleanup => usr/src/cmd/print/gateway/print-cleanup
rename : usr/src/cmd/print/lp/lp.c => usr/src/cmd/print/gateway/printd.c
rename : usr/src/lib/print/job.c => usr/src/lib/print/libprint/common/job.c
rename : usr/src/lib/print/job.h => usr/src/lib/print/libprint/common/job.h
rename : usr/src/lib/print/list.c => usr/src/lib/print/libprint/common/list.c
rename : usr/src/lib/print/list.h => usr/src/lib/print/libprint/common/list.h
rename : usr/src/lib/print/llib-lprint => usr/src/lib/print/libprint/common/llib-lprint
rename : usr/src/lib/print/mapfile-vers => usr/src/lib/print/libprint/common/mapfile-vers
rename : usr/src/lib/print/misc.c => usr/src/lib/print/libprint/common/misc.c
rename : usr/src/lib/print/misc.h => usr/src/lib/print/libprint/common/misc.h
rename : usr/src/lib/print/network.c => usr/src/lib/print/libprint/common/network.c
rename : usr/src/lib/print/network.h => usr/src/lib/print/libprint/common/network.h
rename : usr/src/lib/print/ns.c => usr/src/lib/print/libprint/common/ns.c
rename : usr/src/lib/print/ns.h => usr/src/lib/print/libprint/common/ns.h
rename : usr/src/lib/print/ns_bsd_addr.c => usr/src/lib/print/libprint/common/ns_bsd_addr.c
rename : usr/src/lib/print/ns_cmn_kvp.c => usr/src/lib/print/libprint/common/ns_cmn_kvp.c
rename : usr/src/lib/print/ns_cmn_printer.c => usr/src/lib/print/libprint/common/ns_cmn_printer.c
rename : usr/src/lib/print/nss_convert.c => usr/src/lib/print/libprint/common/nss_convert.c
rename : usr/src/lib/print/nss_ldap.c => usr/src/lib/print/libprint/common/nss_ldap.c
rename : usr/src/lib/print/nss_printer.c => usr/src/lib/print/libprint/common/nss_printer.c
rename : usr/src/lib/print/nss_write.c => usr/src/lib/print/libprint/common/nss_write.c
rename : usr/src/lib/print/sunPrinter.at.conf.txt => usr/src/lib/print/libprint/common/sunPrinter.at.conf.txt
rename : usr/src/lib/print/sunPrinter.oc.conf.txt => usr/src/lib/print/libprint/common/sunPrinter.oc.conf.txt
Diffstat (limited to 'usr/src')
282 files changed, 29605 insertions, 14307 deletions
diff --git a/usr/src/cmd/lp/cmd/Makefile b/usr/src/cmd/lp/cmd/Makefile index 2a50a58144..28a60c9026 100644 --- a/usr/src/cmd/lp/cmd/Makefile +++ b/usr/src/cmd/lp/cmd/Makefile @@ -33,12 +33,9 @@ include ../Makefile.lp OWNER = root -SUBDIRS = lpc lptest lpadmin lpsched lpstat adaptor scripts +SUBDIRS = lptest lpadmin lpsched adaptor scripts -LOCALPROG1 = lp lpsystem lpmove lpshut -LOCALPROG2 = accept -LOCALPROG = $(LOCALPROG1) $(LOCALPROG2) -LOCALLINKS = disable enable reject +LOCALPROG = lpsystem lpshut SBINPROG = lpfilter lpforms lpusers @@ -46,35 +43,27 @@ LIBLINKS = $(SBINPROG) PROG = $(LOCALPROG) $(SBINPROG) -COMMONOBJ= comb.o -OTHEROBJS= cancel.o lp.o $(SBINPROG:=.o) - -OBJS= $(COMMONOBJ) $(OTHEROBJS) +OBJS= $(SBINPROG:=.o) SRCS= $(OBJS:.o=.c) POFILE= lp_cmd.po -POFILES= $(SRCS:%.c=%.po) lpsystem.po lpmove.po lpschedlpshut.po +POFILES= $(SRCS:%.c=%.po) lpsystem.po lpschedlpshut.po ROOTLIBLPLOCLPROG= $(LOCALPROG:%=$(ROOTLIBLPLOCL)/%) ROOTSBINPROG= $(SBINPROG:%=$(ROOTUSRSBIN)/%) ROOTSYMLINKS= $(LIBLINKS:%=$(ROOTLIB)/%) -ROOTSYMLINKS2= $(LOCALLINKS:%=$(ROOTLIBLPLOCL)/%) CPPFLAGS = -I$(LPINC) $(CPPFLAGS.master) # conditional assignments # -accept:= LDLIBS += $(LIBMSG) $(LIBACC) $(LIBOAM) $(LIBLP) -cancel:= LDLIBS += $(LIBREQ) $(LIBMSG) $(LIBOAM) $(LIBLP) -lp:= LDLIBS += $(LIBPRT) $(LIBREQ) $(LIBMSG) $(LIBOAM) $(LIBLP) lpfilter:= LDLIBS += $(LIBFLT) $(LIBMSG) $(LIBACC) $(LIBOAM) $(LIBLP) \ -lgen -z lazyload -lsecdb -z nolazyload lpforms:= LDLIBS += $(LIBFRM) $(LIBMSG) $(LIBREQ) $(LIBOAM) \ $(LIBACC) $(LIBLP) \ -z lazyload -lsecdb -z nolazyload -lpmove:= LDLIBS += $(LIBMSG) $(LIBACC) $(LIBOAM) $(LIBLP) lpshut:= LDLIBS += $(LIBMSG) $(LIBOAM) $(LIBLP) lpsystem:= LDLIBS += $(LIBSYS) $(LIBMSG) $(LIBACC) $(LIBOAM) $(LIBLP) \ -lnsl -z lazyload -lsecdb -z nolazyload @@ -84,13 +73,8 @@ lpusers:= LDLIBS += $(LIBMSG) $(LIBACC) $(LIBOAM) $(LIBUSR) $(LIBLP) all: $(PROG) $(SUBDIRS) -accept: $(COMMONOBJ) - $(LINK.c) -o $@ $(COMMONOBJ) $(LDFLAGS) $(LDLIBS) - $(POST_PROCESS) - - install: $(PROG) $(ROOTLIBLPLOCLPROG) $(ROOTSBINPROG) \ - $(ROOTSYMLINKS) $(ROOTSYMLINKS2) $(SUBDIRS) + $(ROOTSYMLINKS) $(SUBDIRS) catalog: $(SUBDIRS) $(POFILE) $(CP) $(POFILE) .. @@ -101,7 +85,7 @@ clean: $(SUBDIRS) clobber: $(SUBDIRS) local_clobber local_clobber: - $(RM) $(OBJS) $(PROG) lpmove.o lpsystem.o $(CLOBBERFILES) + $(RM) $(OBJS) $(PROG) lpsystem.o $(CLOBBERFILES) strip: $(SUBDIRS) $(STRIP) $(PROG) @@ -109,16 +93,9 @@ strip: $(SUBDIRS) lint: $(LINT.c) $(SRCS) $(LDLIBS) -$(LOCALPROG1) $(SBINPROG): $$@.o - $(LINK.c) -o $@ $@.o $(LDFLAGS) $(LDLIBS) - $(POST_PROCESS) - $(ROOTSYMLINKS): $(RM) $@; $(SYMLINK) ../sbin/$(@F) $@ -$(ROOTSYMLINKS2): - $(RM) $@; $(SYMLINK) ./accept $@ - $(SUBDIRS): FRC @cd $@; pwd; $(MAKE) $(TARGET) diff --git a/usr/src/cmd/lp/cmd/adaptor/Makefile b/usr/src/cmd/lp/cmd/adaptor/Makefile index f7d7d7508b..04aaa4547b 100644 --- a/usr/src/cmd/lp/cmd/adaptor/Makefile +++ b/usr/src/cmd/lp/cmd/adaptor/Makefile @@ -38,7 +38,7 @@ include ../../Makefile.lp ROOTLIBDIR= $(ROOT)/usr/lib/print/bsd-adaptor CPPFLAGS += -I$(LPINC) -CPPFLAGS += -I$(SRC)/lib +CPPFLAGS += -I$(SRC)/lib/print/libprint/common LDLIBS += -lprint -z lazyload -ltsol -z nolazyload -lc LDLIBS += -L$(SRC)/cmd/lp/lib/msgs -llpmsg LDLIBS += -L$(SRC)/cmd/lp/lib/class -llpcls diff --git a/usr/src/cmd/lp/cmd/adaptor/cancel_job.c b/usr/src/cmd/lp/cmd/adaptor/cancel_job.c index 7ffa9af79b..4ae65e5dcc 100644 --- a/usr/src/cmd/lp/cmd/adaptor/cancel_job.c +++ b/usr/src/cmd/lp/cmd/adaptor/cancel_job.c @@ -44,7 +44,7 @@ #include "misc.h" /* print NS include */ -#include <print/ns.h> +#include <ns.h> static char * diff --git a/usr/src/cmd/lp/cmd/cancel.c b/usr/src/cmd/lp/cmd/cancel.c deleted file mode 100644 index 9acdbe805b..0000000000 --- a/usr/src/cmd/lp/cmd/cancel.c +++ /dev/null @@ -1,501 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 1996 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - - -#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.14 */ - -#include "stdio.h" -#include "stdlib.h" -#include "signal.h" -#include "string.h" -#include "errno.h" -#if defined(__STDC__) -#include "stdarg.h" -#else -#include "varargs.h" -#endif -#include "sys/types.h" - -#include "lp.h" -#include "requests.h" -#include "msgs.h" - -#define WHO_AM_I I_AM_CANCEL -#include "oam.h" -#include <locale.h> - -#define OPT_LIST "u:" - -/* - * There are no sections of code in this progam that have to be - * protected from interrupts. We do want to catch them, however, - * so we can clean up properly. - */ - -char *users = NULL; - -void startup(), - cleanup(), - cancel(), - restart(), /* a misnomer */ - ucancel(); - -#if defined(__STDC__) -void send_message ( int , ... ); -void recv_message ( int , ... ); -#else -void send_message(), - recv_message(); -#endif - -/** - ** usage() - **/ - -void usage () -{ - (void) printf("%s\n", gettext("usage: cancel id ... printer ...")); - (void) printf("%s\n", gettext(" or cancel -u id-list printer ...")); - - return; -} - -/** - ** main() - **/ - -int main (argc, argv) - int argc; - char *argv[]; -{ - extern int optind, - opterr, - optopt, - getopt(); - - extern char *optarg; - - int c; - - char *arg, - *p, - **users = 0, - **pu; - - setlocale(LC_ALL, ""); -#if !defined(TEXT_DOMAIN) -#define TEXT_DOMAIN "SYS_TEST" -#endif - (void) textdomain(TEXT_DOMAIN); - - opterr = 0; - - while ((c = getopt(argc, argv, OPT_LIST)) != -1) switch (c) { - - case 'u': - if (users) - LP_ERRMSG1 (WARNING, E_LP_2MANY, 'u'); - users = getlist(optarg, LP_WS, LP_SEP); - break; - - default: - if (optopt == '?') { - usage (); - exit (0); - } - (p = "-X")[1] = optopt; - if (strchr(OPT_LIST, optopt)) - LP_ERRMSG1 (ERROR, E_LP_OPTARG, p); - else - LP_ERRMSG1 (ERROR, E_LP_OPTION, p); - exit (1); - - } - - if (optind == argc && !users) { - LP_ERRMSG (ERROR, E_CAN_NOACT); - exit (1); - } - - startup (); - - if (optind == argc) - for (pu = users; *pu; pu++) - ucancel (*pu, NAME_ALL); - - else while (optind < argc) { - - arg = argv[optind++]; - - if (users) { - if (isprinter(arg) || STREQU(NAME_ALL, arg)) - for (pu = users; *pu; pu++) - ucancel (*pu, arg); - else - LP_ERRMSG1 (WARNING, E_CAN_BADARG, arg); - } else - if (isrequest(arg)) - cancel (arg); - else if (isprinter(arg)) - restart (arg); - else - LP_ERRMSG1 (WARNING, E_CAN_BADARG, arg); - - } - - cleanup (); - return (0); -} - -/** - ** cancel() - CANCEL ONE REQUEST - **/ - -void cancel (req) - char *req; -{ - short status; - - /* - * Now try to cancel the request. - */ - - send_message (S_CANCEL_REQUEST, req); - recv_message (R_CANCEL_REQUEST, &status); - - switch (status) { - - case MOK: - printf(gettext("request \"%s\" cancelled\n"), req); - break; - - case MUNKNOWN: - case MNOINFO: - LP_ERRMSG1 (WARNING, E_LP_UNKREQID, req); - break; - - case M2LATE: - LP_ERRMSG1 (WARNING, E_LP_2LATE, req); - break; - - case MNOPERM: - LP_ERRMSG1 (WARNING, E_CAN_CANT, req); - break; - - default: - LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status); - cleanup (); - exit (1); - } - return; -} - -/** - ** restart() - CANCEL REQUEST CURRENTLY PRINTING ON GIVEN PRINTER - **/ - -void restart (printer) - char *printer; -{ - char *req_id, - *s_ignore; - - short status, - h_ignore; - - long l_ignore; - - - /* - * Get the list of requests queued for this printer. - */ - - send_message (S_INQUIRE_PRINTER_STATUS, printer); - recv_message ( - R_INQUIRE_PRINTER_STATUS, - &status, - &s_ignore, /* printer */ - &s_ignore, /* form */ - &s_ignore, /* print_wheel */ - &s_ignore, /* dis_reason */ - &s_ignore, /* rej_reason */ - &h_ignore, /* p_status */ - &req_id, - &l_ignore, /* dis_date */ - &l_ignore /* rej_date */ - ); - - switch (status) { - - case MOK: - if (!req_id || !*req_id) - LP_ERRMSG1 (WARNING, E_LP_PNBUSY, printer); - else - cancel (req_id); - break; - - default: - LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status); - cleanup (); - exit (1); - - } - - return; -} - -/** - ** ucancel() - **/ - -void ucancel (user, printer) - char * user; - char * printer; -{ - int i; - - short more; - - long status; - - char * req_id; - - - send_message (S_CANCEL, printer, user, ""); - - do { - recv_message (R_CANCEL, &more, &status, &req_id); - - switch (status) { - - case MOK: - printf(gettext("request \"%s\" cancelled\n"), req_id); - break; - - case M2LATE: - LP_ERRMSG1 (WARNING, E_LP_2LATE, req_id); - break; - - case MNOPERM: - LP_ERRMSG1 (WARNING, E_CAN_CANT, req_id); - break; - - case MUNKNOWN: - case MNOINFO: - if (STREQU(user, NAME_ALL) && STREQU(printer, NAME_ALL)) - LP_ERRMSG (WARNING, E_CAN_ANYUSERANYP); - else if (STREQU(user, NAME_ALL)) - LP_ERRMSG1 (WARNING, E_CAN_ANYUSERP, printer); - else if (STREQU(printer, NAME_ALL)) - LP_ERRMSG1 (WARNING, E_CAN_NOUSERANYP, user); - else - LP_ERRMSG2 (WARNING, E_CAN_NOUSERP, printer, user); - break; - - default: - LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status); - cleanup (); - exit (1); - } - - } while (more == MOKMORE); - - return; -} - -/** - ** startup() - OPEN MESSAGE QUEUE TO SPOOLER - **/ - -void startup () -{ - void catch(); - - /* - * Open a private queue for messages to the Spooler. - * An error is deadly. - */ - if (mopen() == -1) { - - switch (errno) { - case ENOMEM: - case ENOSPC: - LP_ERRMSG (ERROR, E_LP_MLATER); - break; - default: - LP_ERRMSG (ERROR, E_LP_NEEDSCHED); - break; - } - - exit (1); - } - - /* - * Now that the queue is open, quickly trap signals - * that we might get so we'll be able to close the - * queue again, regardless of what happens. - */ - if(signal(SIGHUP, SIG_IGN) != SIG_IGN) - signal(SIGHUP, catch); - if(signal(SIGINT, SIG_IGN) != SIG_IGN) - signal(SIGINT, catch); - if(signal(SIGQUIT, SIG_IGN) != SIG_IGN) - signal(SIGQUIT, catch); - if(signal(SIGTERM, SIG_IGN) != SIG_IGN) - signal(SIGTERM, catch); -} - -/** - ** catch() - CATCH INTERRUPT, HANGUP, ETC. - **/ - -void catch (sig) - int sig; -{ - signal (sig, SIG_IGN); - cleanup (); - exit (1); -} - -/** - ** cleanup() - CLOSE THE MESSAGE QUEUE TO THE SPOOLER - **/ - -void cleanup () -{ - (void)mclose (); - return; -} - -/** - ** send_message() - HANDLE MESSAGE SENDING TO SPOOLER - **/ - -/*VARARGS1*/ - -void -#if defined(__STDC__) -send_message ( - int type, - ... -) -#else -send_message (type, va_alist) - int type; - va_dcl -#endif -{ - va_list ap; - - char buffer[MSGMAX]; - - -#if defined(__STDC__) - va_start (ap, type); -#else - va_start (ap); -#endif - - switch (type) { - - case S_INQUIRE_PRINTER_STATUS: - case S_CANCEL_REQUEST: - case S_CANCEL: - (void)_putmessage (buffer, type, ap); - break; - - } - - va_end (ap); - - if (msend(buffer) == -1) { - LP_ERRMSG (ERROR, E_LP_MSEND); - cleanup (); - exit (1); - } - - return; -} - -/** - ** recv_message() - HANDLE MESSAGES BACK FROM SPOOLER - **/ - -/*VARARGS1*/ - -void -#if defined(__STDC__) -recv_message ( - int type, - ... -) -#else -recv_message (type, va_alist) - int type; - va_dcl -#endif -{ - va_list ap; - - static char buffer[MSGMAX]; - - int rc; - - -#if defined(__STDC__) - va_start (ap, type); -#else - va_start (ap); -#endif - - if (mrecv(buffer, MSGMAX) != type) { - LP_ERRMSG (ERROR, E_LP_MRECV); - cleanup (); - exit (1); - } - - switch(type) { - - case R_INQUIRE_PRINTER_STATUS: - case R_CANCEL_REQUEST: - case R_CANCEL: - rc = _getmessage(buffer, type, ap); - if (rc != type) { - LP_ERRMSG1 (ERROR, E_LP_BADREPLY, rc); - cleanup (); - exit (1); - } - break; - - } - - va_end (ap); - - return; -} diff --git a/usr/src/cmd/lp/cmd/comb.c b/usr/src/cmd/lp/cmd/comb.c deleted file mode 100644 index 595fed9651..0000000000 --- a/usr/src/cmd/lp/cmd/comb.c +++ /dev/null @@ -1,488 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <assert.h> -#include <signal.h> -#include <string.h> -#include <locale.h> - -#include "lp.h" -#include "msgs.h" - -#define WHO_AM_I I_AM_COMB -#include "oam.h" - -#define NULL 0 - -char message[MSGMAX], - reply[MSGMAX]; - -void reject(), accept(), enable(), disable(); - -int -main(int argc, char *argv[]) -{ - char *p; - - (void) setlocale(LC_ALL, ""); -#if !defined(TEXT_DOMAIN) -#define TEXT_DOMAIN "SYS_TEST" -#endif - (void) textdomain(TEXT_DOMAIN); - - if (p = strrchr(argv[0], '/')) - p++; - else - p = argv[0]; - - strncpy(who_am_i+3, p, 14); - - if (STREQU(p, "reject")) reject(argc, argv); - if (STREQU(p, "accept")) accept(argc, argv); - if (STREQU(p, "enable")) enable(argc, argv); - if (STREQU(p, "disable")) disable(argc, argv); - - return (0); -} - -void startup(), cleanup(), err_exit(); - -#if defined(__STDC__) -void catch(); -#else -int catch(); -#endif - -void -reject(argc, argv) -int argc; -char *argv[]; -{ - int i, c, dests = 0, rc = 0; - char *dest, *reason = "unknown reason"; - int type, size; - short status; - extern char *optarg; - extern int optind, opterr, optopt; - - if(argc == 1 || STREQU(argv[1], "-?")) { -usage: - printf(gettext("usage: reject [-r [reason]] dest ...\n")); - cleanup(); - exit(argc == 1); - } - - startup(); - - opterr = 0; /* disable printing of errors by getopt */ - for(i = 1; i < argc; i++) { - dest = argv[i]; - if(*(dest) == '-' && strcmp (dest,"-") != 0) { - optind = i; - c = getopt(argc, argv, "r:"); - switch (c) { - case 'r': - if (isprinter(optarg) || isclass(optarg)) - optind--; - else - { - reason = optarg; - if (strlen(reason) > (size_t) 1024) - reason[1024] = '\0'; - } - break; - - case '?': - if (optopt == '?') - goto usage; - LP_ERRMSG1 (ERROR, E_LP_OPTION, argv[optind-1]); - err_exit(); - } - i = optind-1; - } else { - dests++; - /* reject(dest, reason) */ - size = putmessage(message, S_REJECT_DEST, dest, reason); - assert(size != -1); - if (msend(message)) { - LP_ERRMSG(ERROR, E_LP_MSEND); - err_exit(); - } - if ((type = mrecv(reply, sizeof(reply))) == -1) { - LP_ERRMSG(ERROR, E_LP_MRECV); - err_exit(); - } - if (type != R_REJECT_DEST - || getmessage(reply, type, &status) == -1) { - LP_ERRMSG1(ERROR, E_LP_BADREPLY, type); - err_exit(); - } - switch (status) { - case MOK: - printf(gettext("destination \"%s\" will no longer accept requests\n"), dest); - continue; - case MERRDEST: - LP_ERRMSG1(WARNING, E_REJ_2TIME, dest); - break; - case MNODEST: - LP_ERRMSG1(ERROR, E_LP_DSTUNK, dest); - rc = 1; - break; - case MNOPERM: - LP_ERRMSG (ERROR, E_LP_NOTADM); - rc = 1; - break; - default: - LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status); - rc = 1; - } - } - } - - cleanup(); - - if(dests == 0) { - LP_ERRMSG(ERROR, E_LP_NODEST); - exit(1); - } - exit(rc); -} - -void -accept(argc, argv) -int argc; -char *argv[]; -{ - int size, type, i, rc = 0; - short status; - char *dest, *strcpy(); - - if(argc == 1 || STREQU(argv[1], "-?")) { -usage: - printf(gettext("usage: accept dest ...\n")); - cleanup(); - exit(argc == 1); - } - - startup(); - - for(i = 1; i < argc; i++) { - dest = argv[i]; - if (STREQU(dest, "-?")) - goto usage; - size = putmessage(message, S_ACCEPT_DEST, dest); - assert(size != -1); - if (msend(message)) { - LP_ERRMSG(ERROR, E_LP_MSEND); - err_exit(); - } - if ((type = mrecv(reply, sizeof(reply))) == -1) { - LP_ERRMSG(ERROR, E_LP_MRECV); - err_exit(); - } - if (type != R_ACCEPT_DEST || getmessage(reply, type, &status) == -1) { - LP_ERRMSG1 (ERROR, E_LP_BADREPLY, type); - err_exit(); - } - - switch (status) { - case MOK: - printf(gettext("destination \"%s\" now accepting requests\n"), dest); - continue; - case MERRDEST: - LP_ERRMSG1(WARNING, E_ACC_2TIME, dest); - rc = 1; - break; - case MNODEST: - LP_ERRMSG1(ERROR, E_LP_DSTUNK, dest); - rc = 1; - break; - case MNOPERM: - LP_ERRMSG (ERROR, E_LP_NOTADM); - rc = 1; - break; - default: - LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status); - rc = 1; - } - } - - cleanup(); - exit(rc); -} - -void -enable(argc, argv) -int argc; -char *argv[]; -{ - int i, type, size, rc = 0; - short status; - char *dest, *strcpy(); - - if(argc == 1 || STREQU(argv[1], "-?")) { -usage: - printf(gettext("usage: enable printer ...\n")); - cleanup(); - exit(argc == 1); - } - - startup(); - - for(i = 1; i < argc; i++) { - dest = argv[i]; - if (STREQU(dest, "-?")) - goto usage; - if (isclass(dest)) { - LP_ERRMSG1 (ERROR, E_ENA_CLASS, dest); - continue; /* MR bl88-02715 */ - } - size = putmessage(message, S_ENABLE_DEST, dest); - assert(size != -1); - if (msend(message)) { - LP_ERRMSG(ERROR, E_LP_MSEND); - err_exit(); - } - if ((type = mrecv(reply, sizeof(reply))) == -1) { - LP_ERRMSG(ERROR, E_LP_MRECV); - err_exit(); - } - if (type != R_ENABLE_DEST || getmessage(reply, type, &status) == -1) { - LP_ERRMSG1 (ERROR, E_LP_BADREPLY, type); - err_exit(); - } - - switch (status) { - case MOK: - printf(gettext("printer \"%s\" now enabled\n"), dest); - continue; - case MERRDEST: - LP_ERRMSG1(WARNING, E_ENA_2TIME, dest); - rc = 1; - break; - case MNODEST: - LP_ERRMSG1(ERROR, E_LP_DSTUNK, dest); - rc = 1; - break; - case MNOPERM: - LP_ERRMSG (ERROR, E_LP_NOTADM); - rc = 1; - break; - default: - LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status); - } - } - - cleanup(); - - exit(rc); -} - -#define TRUE 1 -#define FALSE 0 - -void -disable(argc, argv) -int argc; -char **argv; -{ - int rc = 0, cancel = FALSE, Wait = FALSE, - dests = 0, type, size, c; - short status, when; - char *reason = "unknown reason", *dest, *req_id; - extern char *optarg; - extern int optind, opterr, optopt; - - if(argc == 1 || STREQU(argv[1], "-?")) { -usage: - printf(gettext("usage: disable [-c|-W] [-r [reason]] printer ...\n")); - cleanup(); - exit(argc == 1); - } - - opterr = 0; /* disable printing of errors by getopt */ - while ((c = getopt(argc, argv, "cWr:")) != -1) - switch(c) { - case 'c': - if (cancel) - LP_ERRMSG1 (WARNING, E_LP_2MANY, 'c'); - cancel = TRUE; - break; - case 'W': - if (Wait) - LP_ERRMSG1 (WARNING, E_LP_2MANY, 'W'); - Wait = TRUE; - break; - case 'r': - if (isprinter(optarg) || isclass(optarg)) - optind--; - else - { - reason = optarg; - if (strlen(reason) > (size_t) 1024) - reason[1024] = '\0'; - } - break; - - case '?': - if (optopt == '?') - goto usage; - LP_ERRMSG1 (ERROR, E_LP_OPTION, argv[optind-1]); - exit(1); - } - - if (Wait && cancel) { - LP_ERRMSG(ERROR, E_LP_OPTCOMB); - exit(1); - } - - startup(); - - for ( ;optind < argc; optind++) { - dest = argv[optind]; - if(*(dest) == '-' && strcmp (dest,"-") != 0) { - c = getopt(argc, argv, "r:"); - switch (c) { - case 'r': - if (isprinter(optarg) || isclass(optarg)) - optind--; - else - reason = optarg; - break; - case '?': - LP_ERRMSG1 (ERROR, E_LP_OPTION, argv[optind-1]); - err_exit(); - } - optind--; - } else { - if (isclass(dest)) { - LP_ERRMSG1 (ERROR, E_DIS_CLASS, dest); - continue; /* MR bl88-02715 */ - } - dests++; - /* disable(dest, reason, cancel, Wait); */ - when = (Wait) ? 1 : ((cancel) ? 2 : 0); - size = putmessage(message, S_DISABLE_DEST, dest, reason, when); - assert(size != -1); - if (msend(message)) { - LP_ERRMSG(ERROR, E_LP_MSEND); - err_exit(); - } - if ((type = mrecv(reply, sizeof(reply))) == -1) { - LP_ERRMSG(ERROR, E_LP_MRECV); - err_exit(); - } - if (type != R_DISABLE_DEST - || getmessage(reply, type, &status, &req_id) == -1) { - LP_ERRMSG1 (ERROR, E_LP_BADREPLY, type); - err_exit(); - } - switch (status) { - case MOK: - if (req_id && *req_id) - printf(gettext("request \"%s\" cancelled\n"), req_id); - printf(gettext("printer \"%s\" now disabled\n"), dest); - break; - case MERRDEST: - LP_ERRMSG1(WARNING, E_DIS_2TIME, dest); - break; - case MNODEST: - LP_ERRMSG1(ERROR, E_LP_DSTUNK, dest); - rc = 1; - break; - case MNOPERM: - LP_ERRMSG (ERROR, E_LP_NOTADM); - rc = 1; - break; - default: - LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status); - rc = 1; - } - } - } - - cleanup(); - - if(dests == 0) { - LP_ERRMSG(ERROR, E_LP_NODEST); - exit(1); - } - - exit(rc); -} - -void -startup() -{ -#if defined(__STDC__) - void catch(); -#endif - - if (mopen()) {LP_ERRMSG(ERROR, E_LP_MOPEN); exit(1);} - - if(signal(SIGHUP, SIG_IGN) != SIG_IGN) - signal(SIGHUP, catch); - if(signal(SIGINT, SIG_IGN) != SIG_IGN) - signal(SIGINT, catch); - if(signal(SIGQUIT, SIG_IGN) != SIG_IGN) - signal(SIGQUIT, catch); - if(signal(SIGTERM, SIG_IGN) != SIG_IGN) - signal(SIGTERM, catch); -} - -/* catch -- catch signals */ - -#if defined(__STDC__) -void catch() -#else -int catch() -#endif -{ - - signal(SIGHUP, SIG_IGN); - signal(SIGINT, SIG_IGN); - signal(SIGQUIT, SIG_IGN); - signal(SIGTERM, SIG_IGN); - err_exit(); -} - -void -cleanup() -{ - (void)mclose (); -} - -void -err_exit() -{ - cleanup(); - exit(1); -} diff --git a/usr/src/cmd/lp/cmd/lp.c b/usr/src/cmd/lp/cmd/lp.c deleted file mode 100644 index d24d6791a8..0000000000 --- a/usr/src/cmd/lp/cmd/lp.c +++ /dev/null @@ -1,1082 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* lp -- print files on a line printer */ - -#include <stdio.h> -#include <sys/types.h> -#include <sys/uio.h> -#include <unistd.h> -#include <stdlib.h> -#include <errno.h> -#include <signal.h> -#include <assert.h> -#include <locale.h> -#include <string.h> -#include "requests.h" -#include "lp.h" -#include "msgs.h" -#include "printers.h" - -#define WHO_AM_I I_AM_LP -#include "oam.h" - -#define TRUE 1 -#define FALSE 0 -#define ALERT_CMD "/etc/lp/alerts/jobdone" - /* file to run when job is done if -p option is selected */ -short alertMsg = FALSE; /* TRUE => user wants notification via - running /etc/lp/alerts/jobdone - FALSE => don't do it */ -#define HOLD 1 -#define RESUME 2 -#define IMMEDIATE 3 -#define POSTSCRIPT "postscript" - -static struct stat stbuf; /* Global stat buffer */ -static char *dest = NULL; /* destination class or printer */ -static char *title = NULL; /* User-supplied title for output */ -static int specialh = 0; /* -H flag indicates special handling */ -static char *formname = NULL; /* form to use */ -static char *char_set = NULL; /* print wheel or character set to use */ -static char *cont_type = NULL; /* content type of input files */ -static char *curdir; /* working directory at time of request */ -static char reqfile[20]; /* name of request file */ -static char *stdinfile; -static char *rfilebase; -static short priority = -1; /* priority of print request */ -static short copies = 0; /* number of copies of output */ -static char **opts = NULL; /* options for interface program */ -static char **yopts = NULL; /* options for filter program */ -static char *pages = NULL; /* pages to be printed */ -static short silent = FALSE; /* don't run off at the mouth */ -static short mail = FALSE; /* TRUE => user wants mail, FALSE ==> no mail */ -static short wrt = FALSE; /* TRUE => user wants notification on tty - * via write, FALSE => don't write - */ -static short raw = FALSE; /* set option xx"stty=raw"xx and raw flag if - * true - */ -static short copy = FALSE; /* TRUE => copy files, FALSE ==> don't */ -static char *pre_rqid = NULL; /* previos request id (-i option) */ -static char *reqid = NULL; /* request id for this job */ - -static char **files = NULL; /* list of file to be printed */ -static int nfiles = 0; /* # of files on cmd line (excluding "-") */ -static int stdinp = 0; /* indicates how many times to print std input - *-1 ==> standard input empty - */ -static int Tflag = 0; /* 0, -T not specified, 1, -T specified - * this flag used for autorecognizing - * postscript - * if == 1, autorec. ps. is off! - */ - -static int exit_code = 0; /* exit with this value */ - -extern char *sprintlist(); -extern int appendlist(); - -static void startup(), clean_up(), err_exit(), savestd(), arps(REQUEST *rqp), - ack_job(), catch(), allocfiles(), end_change(char *, REQUEST *); -static int psfile(char *); -static char *start_ch(char *), *getfiles(int), *que_job(REQUEST *); -static REQUEST *makereq(); - -#define OPTSTRING "q:H:f:d:T:S:o:y:P:i:cmwpn:st:r" - -static void -chk_cont_type(str) -char *str; -{ - if (STREQU(str, NAME_ANY) || STREQU(str, NAME_TERMINFO)) { - LP_ERRMSG2(ERROR, E_LP_BADOARG, 'T', str); - exit(1); - } -} - -char * -mkAlertCmd(char *reqfile) -{ - char *str,*ptr; - int len; - - str = (char *) malloc(strlen(ALERT_CMD) + strlen(dest) + - strlen(reqfile) + 3); - ptr = strchr(reqfile,'-'); - len = (ptr ? ptr-reqfile : strlen(reqfile)); - sprintf(str,"%s %s %.*s", ALERT_CMD, dest, len, reqfile); - - return(str); -} - -int -main(int argc, char *argv[]) -{ - int letter; - char *p, **templist, **stemp; - char *file; - REQUEST *reqp, *makereq(); - int fileargs = 0; - extern char *optarg; - extern int optind, opterr, optopt; - - (void) setlocale (LC_ALL, ""); -#if !defined(TEXT_DOMAIN) -#define TEXT_DOMAIN "SYS_TEST" -#endif - (void) textdomain(TEXT_DOMAIN); - - opterr = 0; /* disable printing of errors by getopt */ - while ((letter = getopt(argc, argv, OPTSTRING)) != -1) - switch(letter) { - case 'c': /* copy files */ - if (copy) LP_ERRMSG1(WARNING, E_LP_2MANY, 'c'); - copy = TRUE; - break; - case 'd': /* destination */ - if (dest) LP_ERRMSG1(WARNING, E_LP_2MANY, 'd'); - dest = optarg; - if (!isprinter(dest) && !isclass(dest) && !STREQU(dest, NAME_ANY)) { - LP_ERRMSG1(ERROR, E_LP_DSTUNK, dest); - exit (1); - } - break; - case 'f': - if (formname) LP_ERRMSG1(WARNING, E_LP_2MANY, 'f'); - formname = optarg; - break; - case 'H': - if (specialh) LP_ERRMSG1(WARNING, E_LP_2MANY, 'H'); - if (STREQU(optarg, "hold")) specialh = HOLD; - else if (STREQU(optarg, "resume")) specialh = RESUME; - else if (STREQU(optarg, "immediate")) specialh = IMMEDIATE; - else { - LP_ERRMSG2(ERROR, E_LP_BADOARG, 'H', optarg); - exit(1); - } - break; - case 'i': - if (pre_rqid) LP_ERRMSG1(WARNING, E_LP_2MANY, 'i'); - pre_rqid = optarg; - break; - case 'm': /* mail */ - if (mail) LP_ERRMSG1(WARNING, E_LP_2MANY, 'm'); - mail = TRUE; - break; - case 'n': /* # of copies */ - if (copies) LP_ERRMSG1(WARNING, E_LP_2MANY, 'n'); - if ( - *optarg == 0 - || (copies=(int)strtol(optarg, &p, 10)) <= 0 - || *p - ) { - LP_ERRMSG2(ERROR, E_LP_BADOARG, 'n', optarg); - exit(1); - } - break; - case 'o': /* option for interface program */ - stemp = templist = getlist(optarg, " \t", ""); /* MR bl88-13915 */ - if (!stemp) - break; /* MR bl88-14720 */ - while (*templist) - appendlist(&opts, *templist++); - freelist(stemp); - break; - case 'y': - stemp = templist = getlist(optarg, " \t", ","); - if (!stemp) - break; /* MR bl88-14720 */ - while (*templist) - appendlist(&yopts, *templist++); - freelist(stemp); - break; - case 'P': - if (pages) LP_ERRMSG1(WARNING, E_LP_2MANY, 'P'); - pages = optarg; - break; - case 'q': - if (priority != -1) LP_ERRMSG1(WARNING, E_LP_2MANY, 'q'); - priority = (int)strtol(optarg, &p, 10); - if (*p || priority<0 || priority>39) { - LP_ERRMSG1(ERROR, E_LP_BADPRI, optarg); - exit(1); - } - break; - case 'r': - if (raw) LP_ERRMSG1(WARNING, E_LP_2MANY, 'r'); - raw = TRUE; - break; - case 's': /* silent */ - if (silent) LP_ERRMSG1(WARNING, E_LP_2MANY, 's'); - silent = 1; - break; - case 'S': - if (char_set) LP_ERRMSG1(WARNING, E_LP_2MANY, 'S'); - char_set = optarg; - break; - case 't': /* title */ - if (title) LP_ERRMSG1(WARNING, E_LP_2MANY, 't'); - title = optarg; - break; - case 'T': - if (cont_type) LP_ERRMSG1(WARNING, E_LP_2MANY, 'T'); - chk_cont_type(optarg); - cont_type = optarg; - Tflag++; - break; - case 'p': - if (alertMsg) LP_ERRMSG1(WARNING, E_LP_2MANY, 'p'); - alertMsg = TRUE; - break; - case 'w': /* write */ - if (wrt) LP_ERRMSG1(WARNING, E_LP_2MANY, 'w'); - wrt = TRUE; - break; - default: - if (optopt == '?') { - - (void)printf( - gettext("usage:\n\n(submit file(s) for printing)\n")); - - (void) printf (gettext(\ -"lp [options] { file-name ... | - }\n")); - - (void) printf (gettext( -" [-c] (make copies first)\n" -" [-d destination] (printer/class to use)\n" -" [-f form [-d any]] (print on this form)\n" -" [-H hold] (don't print yet)\n" -" [-H immediate] (print first--reserved)\n" -" [-m | -w] (mail/write when done)\n" -" [-p] (notify when done via ToolTalk)\n" -" [-n copies] (print this many copies)\n" -" [-o nobanner] (no banner page)\n")); - - (void) printf (gettext( -" [-o nofilebreak] (no inter-file formfeed)\n" -" [-o length=scaled-number] (page length)\n" -" [-o width=scaled-number] (page width)\n")); - - (void) printf (gettext( -" [-o lpi=scaled-number] (line pitch)\n" -" [-o cpi=scaled-number] (character pitch)\n")); - - (void) printf (gettext( -" [-o stty='stty-options'] (port characteristics)\n" -" [-o other-local-options] (as defined locally)\n")); - - (void) printf (gettext( -" [-P page-list] (locally defined)\n" -" [-q priority] (priority level)\n" -" [-r] (use no filter)\n")); - - (void) printf (gettext( -" [-s] (no request-id message)\n" -" [-S char-set | print-wheel [-d any]] (font to start with)\n" -" [-t title] (title for banner page)\n" -" [-T file-type] (type of input files)\n" -" [-y local-modes] (locally defined)\n" -"\n")); - - (void) printf(gettext( -" (change previous request)\n" -" lp -i request-id {options}\n" -" [-H resume] (resume held request)\n" -" [other options listed above]\n")); - - exit(0); - } - (p = "-X")[1] = optopt; - if (strchr(OPTSTRING, optopt)) - LP_ERRMSG1(ERROR, E_LP_OPTARG, p); - else - LP_ERRMSG1(ERROR, E_LP_OPTION, p); - exit(1); - } - - if ((mail && wrt) || (mail && alertMsg) || (wrt && alertMsg)) - LP_ERRMSG(WARNING, E_LPP_COMBMW); - - while (optind < argc) { - fileargs++; - file = argv[optind++]; - if(strcmp(file, "-") == 0) { - stdinp++; - appendlist(&files, file); - } else { - if(Access(file, 4/*read*/) || Stat(file, &stbuf)) { - if (errno == EOVERFLOW) - LP_ERRMSG2(WARNING, E_LP_LARGEFILE, file, errno); - else - LP_ERRMSG2(WARNING, E_LP_BADFILE, file, errno); - exit_code = 1; - } else if((stbuf.st_mode & S_IFMT) == S_IFDIR) { - LP_ERRMSG1(WARNING, E_LP_ISDIR, file); - exit_code = 1; - } else if(stbuf.st_size == 0) { - LP_ERRMSG1(WARNING, E_LP_EMPTY, file); - exit_code = 1; - } else { - nfiles++; - appendlist(&files, file); - continue; - } - } - } - - if(fileargs == 0) { - if (!pre_rqid) stdinp = 1; - } else if (pre_rqid) { - LP_ERRMSG(ERROR, E_LPP_ILLARG); - exit(1); - } else if(nfiles == 0 && stdinp == 0) { - LP_ERRMSG(ERROR, E_LP_NOFILES); - exit(1); - } - -/* args parsed, now let's do it */ - - startup(); /* open message queue - and catch interupts so it gets closed too */ - - if (!(reqp = makereq())) { /* establish defaults & sanity check args */ - LP_ERRMSG1(ERROR, E_LPP_FGETREQ, pre_rqid); - err_exit(); - } - - /* allocate files for request, standard input and files if copy */ - if (pre_rqid) { - if (putrequest(reqfile, reqp) == -1) { /* write request file */ -puterr: - switch(errno) { - default: - LP_ERRMSG(ERROR, E_LPP_FPUTREQ); - err_exit(); - } - } - end_change(pre_rqid, reqp); - reqid = pre_rqid; - } else { - allocfiles(); - if(stdinp > 0) { - savestd(); /* save standard input */ - } - reqp->file_list = files; - arps(reqp); /* autorecognize postscript */ - if (alertMsg) reqp->alert = mkAlertCmd(reqfile); - if (putrequest(reqfile, reqp) == -1) goto puterr; - reqid = que_job(reqp); - } - - signal(SIGHUP, SIG_IGN); - signal(SIGINT, SIG_IGN); - signal(SIGQUIT, SIG_IGN); - signal(SIGTERM, SIG_IGN); - - clean_up(); - ack_job(); /* issue request id message */ - - return (exit_code); -} -/* startup -- initialization routine */ - -static void -startup() -{ - void catch(); - int try = 0; - - for (;;) - if (mopen() == 0) break; - else { - if (errno == ENOSPC && try++ < 5) { - (void) sleep(3); - continue; - } - LP_ERRMSG(ERROR, E_LP_MOPEN); - exit(1); - } - - if(signal(SIGHUP, SIG_IGN) != SIG_IGN) - signal(SIGHUP, catch); - if(signal(SIGINT, SIG_IGN) != SIG_IGN) - signal(SIGINT, catch); - if(signal(SIGQUIT, SIG_IGN) != SIG_IGN) - signal(SIGQUIT, catch); - if(signal(SIGTERM, SIG_IGN) != SIG_IGN) - signal(SIGTERM, catch); - - (void) umask(0000); - curdir = getcwd(NULL, 512); -} - -/* catch -- catch signals */ - -static void -catch() -{ - signal(SIGHUP, SIG_IGN); - signal(SIGINT, SIG_IGN); - signal(SIGQUIT, SIG_IGN); - signal(SIGTERM, SIG_IGN); - err_exit(); -} - -/* clean_up -- called by catch() after interrupts - or by err_exit() after errors */ - -static void -clean_up() -{ - (void)mclose (); -} - -static void -err_exit() -{ - clean_up(); - exit(1); -} - -/* - * copyfile(stream, name) -- copy stream to file "name" - */ - -static void -copyfile(stream, name) -FILE *stream; -char *name; -{ - FILE *ostream; - int i; - char buf[BUFSIZ]; - - if ((ostream = fopen(name, "w")) == NULL) { - LP_ERRMSG2(ERROR, E_LP_BADFILE, name, errno); - return; - } - - Chmod(name, 0600); - errno = 0; - while ((i = fread(buf, sizeof(char), BUFSIZ, stream)) > 0) { - (void) fwrite(buf, sizeof(char), i, ostream); - if (feof(stream)) break; - } - if (errno != 0) { - if (errno == ENOSPC) { - LP_ERRMSG(ERROR, E_LP_NOSPACE); - } else { - LP_ERRMSG2(ERROR, E_LP_BADFILE, name, errno); - } - err_exit(); - } - - (void) fclose(ostream); -} -/* makereq -- sanity check args, establish defaults */ - -static REQUEST * -makereq() -{ - static REQUEST rq; - REQUEST *oldrqp; - char *preqfile; - char **optp, *pdest = dest; - - /* - * begin changes for 1112940 - * The test used to look like: if (!dest && !pre_rqid && !cont_type) - * Now, if either LPDEST or a default is set, use those instead of "any". - * This is probably more like what the user expects and the SVID isn't - * real clear about the interaction of LPDEST, the default and -T. - * If the printer can't handle this content, we'll get an error later. - */ - if (!dest && !pre_rqid) { - if ((dest = getenv("LPDEST")) && *dest) - ; - else { - if (!(dest = getdefault())) { - if (cont_type) - dest = "any"; - else { - LP_ERRMSG(ERROR, E_LPP_NODEST); - err_exit(); - } - } - } - } - /* end changes for 1112940 */ - - if (!dest) dest = "any"; - - if (!pre_rqid && !cont_type) { - cont_type = getenv("LPTYPE"); - if (cont_type != (char *) NULL) { - Tflag++;/* for autorecognizing postscript, LPTYPE is */ - /* equivalent to specifying "-T" */ - } - } - if (!pre_rqid && !cont_type) - cont_type = NAME_SIMPLE; - - if (formname && opts) - for (optp = opts; *optp; optp++) - if (STRNEQU("lpi=", *optp, 4) - || STRNEQU("cpi=", *optp, 4) - || STRNEQU("length=", *optp, 7) - || STRNEQU("width=", *optp, 6)) { - LP_ERRMSG(ERROR, E_LP_OPTCOMB); - err_exit(); - } - - if (raw && (yopts || pages)) { - LP_ERRMSG(ERROR, E_LP_OPTCOMB); - err_exit(); - } - - /* now to build the request */ - if (pre_rqid) { - preqfile = start_ch(pre_rqid); - (void) strlcpy(reqfile, preqfile, sizeof (reqfile)); - if (!(oldrqp = getrequest(preqfile))) return (NULL); - rq.copies = (copies) ? copies : oldrqp->copies; - rq.destination = (pdest) ? dest : oldrqp->destination; - rq.file_list = oldrqp->file_list; - rq.form = (formname) ? formname : oldrqp->form; - rq.actions = (specialh) ? ((specialh == HOLD) ? ACT_HOLD : - ((specialh == RESUME) ? ACT_RESUME : ACT_IMMEDIATE)) : - oldrqp->actions; - if (wrt) rq.actions |= ACT_WRITE; - if (mail) rq.actions |= ACT_MAIL; - if (raw) { - rq.actions |= ACT_RAW; - /*appendlist(&opts, "stty=raw");*/ - } - rq.options = (opts) ? sprintlist(opts) : oldrqp->options; - rq.priority = (priority == -1) ? oldrqp->priority : priority; - rq.pages = (pages) ? pages : oldrqp->pages; - rq.charset = (char_set) ? char_set : oldrqp->charset; - rq.modes = (yopts) ? sprintlist(yopts) : oldrqp->modes; - rq.title = (title) ? title : oldrqp->title; - rq.input_type = (cont_type) ? cont_type : oldrqp->input_type; - rq.alert = (alertMsg) ? mkAlertCmd(reqfile) : oldrqp->alert; - rq.user = oldrqp->user; - rq.outcome = 0; - rq.version = VERSION_NEW_LP; - return(&rq); - } - rq.copies = (copies) ? copies : 1; - rq.destination = dest; - rq.form = formname; - rq.actions = (specialh) ? ((specialh == HOLD) ? ACT_HOLD : - ((specialh == RESUME) ? ACT_RESUME : ACT_IMMEDIATE)) : 0; - if (wrt) rq.actions |= ACT_WRITE; - if (mail) rq.actions |= ACT_MAIL; - if (raw) { - rq.actions |= ACT_RAW; - /*appendlist(&opts, "stty=raw");*/ - } - rq.alert = NULL; - rq.options = sprintlist(opts); - rq.priority = priority; - rq.pages = pages; - rq.charset = char_set; - rq.modes = sprintlist(yopts); - rq.title = title; - rq.input_type = cont_type; - rq.file_list = 0; - rq.user = getname(); - rq.version = VERSION_NEW_LP; - return(&rq); -} - -/* files -- process command line file arguments */ -static void -allocfiles() -{ - char **reqfiles = 0, **filep, *p, *prefix; - FILE *f; - int numfiles, filenum = 1; - - numfiles = 1 + ((stdinp > 0) ? 1 : 0) + ((copy) ? nfiles : 0); - - if ((prefix = getfiles(numfiles)) == NULL) - { - numfiles += nfiles; - prefix = getfiles(numfiles); - copy = 1; - } - - (void) strlcpy(reqfile, prefix, sizeof (reqfile)); - (void) strlcat(reqfile, "-0000", sizeof (reqfile)); - rfilebase = makepath(Lp_Temp, reqfile, NULL); - if (stdinp > 0) { - stdinfile = strdup(rfilebase); - p = strchr(stdinfile, 0) - 4; - *p++ = '1'; - *p = 0; - filenum++; - } - p = strchr(reqfile, 0) - 4; *p++ = '0'; *p = 0; - p = strchr(rfilebase, 0) - 4; - - if (!files) appendlist(&files, "-"); - - for (filep = files; *filep; filep++) { - if(STREQU(*filep, "-")) { - if(stdinp > 0) - appendlist(&reqfiles, stdinfile); - } else { - if(copy) { - if (f = fopen(*filep, "r")) { - (void) snprintf(p, sizeof ("0000"), "%d", filenum++); - copyfile(f, rfilebase); - appendlist(&reqfiles, rfilebase); - (void) fclose(f); - } else - LP_ERRMSG2(WARNING, E_LP_BADFILE, *filep, errno); - } else { - if (**filep == '/' || (curdir && *curdir)) - appendlist(&reqfiles, - (**filep == '/') ? *filep - : makepath(curdir, *filep, (char *)0)); - else { - LP_ERRMSG (ERROR, E_LPP_CURDIR); - err_exit (); - } - } - } - } - freelist(files); - files = reqfiles; -} - -/* start_ch -- start change request */ -static char * -start_ch(char *rqid) -{ - int size, type; - short status; - char message[100], - reply[100], - *rqfile; - - size = putmessage(message, S_START_CHANGE_REQUEST, rqid); - assert(size != -1); - if (msend(message)) { - LP_ERRMSG(ERROR, E_LP_MSEND); - err_exit(); - } - if ((type = mrecv(reply, 100)) == -1) { - LP_ERRMSG(ERROR, E_LP_MRECV); - err_exit(); - } - if (type != R_START_CHANGE_REQUEST - || getmessage(reply, type, &status, &rqfile) == -1) { - LP_ERRMSG1(ERROR, E_LP_BADREPLY, type); - err_exit(); - } - - switch (status) { - case MOK: - return(strdup(rqfile)); - case MNOPERM: - LP_ERRMSG(ERROR, E_LP_NOTADM); - break; - case MUNKNOWN: - LP_ERRMSG1(ERROR, E_LP_UNKREQID, rqid); - break; - case MBUSY: - LP_ERRMSG1(ERROR, E_LP_BUSY, rqid); - break; - case M2LATE: - LP_ERRMSG1(ERROR, E_LP_2LATE, rqid); - break; - case MGONEREMOTE: - LP_ERRMSG1(ERROR, E_LP_GONEREMOTE, rqid); - break; - default: - LP_ERRMSG1(ERROR, E_LP_BADSTATUS, status); - } - err_exit(); - /*NOTREACHED*/ - return (NULL); -} - -static void -end_change(char *rqid, REQUEST *rqp) -{ - int size, type; - long chkbits; - short status; - char message[255], - reply[100], - *chkp; - - size = putmessage(message, S_END_CHANGE_REQUEST, rqid); - assert(size != -1); - if (msend(message)) { - LP_ERRMSG(ERROR, E_LP_MSEND); - err_exit(); - } - if ((type = mrecv(reply, 100)) == -1) { - LP_ERRMSG(ERROR, E_LP_MRECV); - err_exit(); - } - if (type != R_END_CHANGE_REQUEST - || getmessage(reply, type, &status, &chkbits) == -1) { - LP_ERRMSG1(ERROR, E_LP_BADREPLY, type); - err_exit(); - } - - switch (status) { - case MOK: - return; - case MNOPERM: - LP_ERRMSG(ERROR, E_LP_NOTADM); - break; - case MNOSTART: - LP_ERRMSG(ERROR, E_LPP_NOSTART); - break; - case MNODEST: - LP_ERRMSG1(ERROR, E_LP_DSTUNK, rqp->destination); - break; - case MDENYDEST: - if (chkbits) { - chkp = message; - /* PCK_TYPE indicates a Terminfo error, and should */ - /* be handled as a ``get help'' problem. */ - if (chkbits & PCK_TYPE) chkp += sprintf(chkp, ""); - if (chkbits & PCK_CHARSET) - chkp += sprintf(chkp, "-S character-set, "); - if (chkbits & PCK_CPI) chkp += sprintf(chkp, "-o cpi=, "); - if (chkbits & PCK_LPI) chkp += sprintf(chkp, "-o lpi=, "); - if (chkbits & PCK_WIDTH) chkp += sprintf(chkp, "-o width=, "); - if (chkbits & PCK_LENGTH) chkp += sprintf(chkp, "-o length=, "); - if (chkbits & PCK_BANNER) chkp += sprintf(chkp, "-o nobanner, "); - if (chkbits & PCK_PAPER) - chkp += snprintf(chkp, sizeof (message) - (chkp - message), - gettext("does not print on specified type of paper, ")); - - if (chkp - 2 >= message + sizeof (message)) - message[sizeof(message) - 1] = 0; - else - chkp[-2] = 0; - LP_ERRMSG1(ERROR, E_LP_PTRCHK, message); - } - else LP_ERRMSG1(ERROR, E_LP_DENYDEST, rqp->destination); - break; - case MNOMEDIA: - LP_ERRMSG(ERROR, E_LPP_NOMEDIA); - break; - case MDENYMEDIA: - if (chkbits & PCK_CHARSET) LP_ERRMSG(ERROR, E_LPP_FORMCHARSET); - else LP_ERRMSG1(ERROR, E_LPP_DENYMEDIA, rqp->form); - break; - case MNOMOUNT: - LP_ERRMSG(ERROR, E_LPP_NOMOUNT); - break; - case MNOFILTER: - LP_ERRMSG(ERROR, E_LP_NOFILTER); - break; - case MERRDEST: - LP_ERRMSG1(ERROR, E_LP_REQDENY, rqp->destination); - break; - case MNOOPEN: - LP_ERRMSG(ERROR, E_LPP_NOOPEN); - break; - default: - LP_ERRMSG1(ERROR, E_LP_BADSTATUS, status); - } - err_exit(); -} - -/* getfile -- allocate the requested number of temp files */ -static char * -getfiles(int number) -{ - int size, type; - short status; - char message[100], - reply[100], - *pfix; - - size = putmessage(message, S_ALLOC_FILES, number); - assert(size != -1); - if (msend(message)) { - LP_ERRMSG(ERROR, E_LP_MSEND); - err_exit(); - } - if ((type = mrecv(reply, 100)) == -1) { - LP_ERRMSG(ERROR, E_LP_MRECV); - err_exit(); - } - if (type != R_ALLOC_FILES - || getmessage(reply, type, &status, &pfix) == -1) { - LP_ERRMSG1(ERROR, E_LP_BADREPLY, type); - err_exit(); - } - - switch (status) { - case MOK: - return(strdup(pfix)); - case MOKREMOTE: - clean_up(); - startup(); - return(NULL); - case MNOMEM: - LP_ERRMSG(ERROR, E_LP_NOSPACE); - break; - case MERRDEST: - LP_ERRMSG(ERROR, E_LP_NOREQ); - break; - default: - LP_ERRMSG1(ERROR, E_LP_BADSTATUS, status); - } - err_exit(); - /*NOTREACHED*/ - return (NULL); -} - -static char * -que_job(REQUEST *rqp) -{ - int size, type; - long chkbits; - short status; - char message[255], - reply[100], - *chkp, - *req_id; - - size = putmessage(message, S_PRINT_REQUEST, reqfile); - assert(size != -1); - if (msend(message)) { - LP_ERRMSG(ERROR, E_LP_MSEND); - err_exit(); - } - if ((type = mrecv(reply, 100)) == -1) { - LP_ERRMSG(ERROR, E_LP_MRECV); - err_exit(); - } - if (type != R_PRINT_REQUEST - || getmessage(reply, type, &status, &req_id, &chkbits) == -1) { - LP_ERRMSG1(ERROR, E_LP_BADREPLY, type); - err_exit(); - } - - switch (status) { - case MOK: - return(strdup(req_id)); - case MNOPERM: - LP_ERRMSG(ERROR, E_LP_NOTADM); - break; - case MNODEST: - LP_ERRMSG1(ERROR, E_LP_DSTUNK, rqp->destination); - break; - case MDENYDEST: - if (chkbits) { - chkp = message; - /* PCK_TYPE indicates a Terminfo error, and should */ - /* be handled as a ``get help'' problem. */ - if (chkbits & PCK_TYPE) chkp += sprintf(chkp, ""); - if (chkbits & PCK_CHARSET) chkp += sprintf(chkp, "-S character-set, "); - if (chkbits & PCK_CPI) chkp += sprintf(chkp, "-o cpi=, "); - if (chkbits & PCK_LPI) chkp += sprintf(chkp, "-o lpi=, "); - if (chkbits & PCK_WIDTH) chkp += sprintf(chkp, "-o width=, "); - if (chkbits & PCK_LENGTH) chkp += sprintf(chkp, "-o length=, "); - if (chkbits & PCK_BANNER) chkp += sprintf(chkp, "-o nobanner, "); - if (chkbits & PCK_PAPER) - chkp += snprintf(chkp, sizeof (message) - (chkp - message), - gettext("does not print on specified type of paper, ")); - - if (chkp - 2 >= message + sizeof (message)) - message[sizeof(message) - 1] = 0; - else - chkp[-2] = 0; - LP_ERRMSG1(ERROR, E_LP_PTRCHK, message); - } - else LP_ERRMSG1(ERROR, E_LP_DENYDEST, rqp->destination); - break; - case MNOMEDIA: - LP_ERRMSG(ERROR, E_LPP_NOMEDIA); - break; - case MDENYMEDIA: - if (chkbits & PCK_CHARSET) LP_ERRMSG(ERROR, E_LPP_FORMCHARSET); - else LP_ERRMSG1(ERROR, E_LPP_DENYMEDIA, rqp->form); - break; - case MNOMOUNT: - LP_ERRMSG(ERROR, E_LPP_NOMOUNT); - break; - case MNOFILTER: - LP_ERRMSG(ERROR, E_LP_NOFILTER); - break; - case MERRDEST: - LP_ERRMSG1(ERROR, E_LP_REQDENY, rqp->destination); - break; - case MNOOPEN: - LP_ERRMSG(ERROR, E_LPP_NOOPEN); - break; - case MUNKNOWN: - LP_ERRMSG(ERROR, E_LPP_ODDFILE); - break; - default: - LP_ERRMSG1(ERROR, E_LP_BADSTATUS, status); - } - err_exit(); - /*NOTREACHED*/ - return (NULL); -} - -/* ack_job -- issue request id message */ -static void -ack_job() -{ - if(silent || pre_rqid) return; - printf(gettext("request id is %s "), reqid); - if (nfiles > 0) { - if (stdinp > 0) { - printf(gettext( - "(%d file(s) and standard input)\n"), nfiles); - } else { - printf(gettext("(%d file(s))\n"), nfiles); - } - } else if (stdinp > 0) { - printf(gettext("(standard input)\n")); - } else - printf("\n"); -} - -/* savestd -- save standard input */ -static void -savestd() -{ - copyfile(stdin, stdinfile); - Stat(stdinfile, &stbuf); - if(stbuf.st_size == 0) { - if(nfiles == 0) { - LP_ERRMSG(ERROR, E_LP_NOFILES); - err_exit(); - } else {/* inhibit printing of std input */ - LP_ERRMSG1(WARNING, E_LP_EMPTY, "(standard input)"); - stdinp = -1; - } - } - else { /* see if our non-zero size file is postscript */ - if (!Tflag && psfile(stdinfile)) { - cont_type = POSTSCRIPT; - } - } -} - -/* psfile(): Determine whether a file is postscript or not - * input: char string of the filename - * ouput: 0 if the file isn't postscript, - * non-zero if it is. - * Description: - * This routine looks to see if the "%!" characters are the first - * parts of the document (See PostScript Language Reference Manual, - * Second Edition - Adobe Systems Inc.; Appendix G - D.S.C. 3.0, p. 621). - * - * This code has been blatently (and legally) ripped off from lpr, - * with only one apology: USL should've done this in the first place!! - */ - -#define PSCOM "%!" -#define PC_PSCOM "\004%!" - -static int -psfile(char *fname) -{ - int fd; - register int ret = 0; - char buf[sizeof(PC_PSCOM)-1]; - - if ((fd = open(fname, O_RDONLY)) >= 0 && - read(fd, buf, sizeof(buf)) == sizeof(buf) && - ((strncmp(buf, PSCOM, sizeof(PSCOM)-1) == 0) || - (strncmp(buf, PC_PSCOM, sizeof(PC_PSCOM)-1) == 0))) - ret++; - (void)close(fd); - return(ret); -} - -/* arps(): autorecognize postscript files - * input: REQUEST pointer. - * ouput: none directly; the REQUEST pointer may be modified. - * description: - * this routine is called before the REQUEST structure - * is written to disk. the list of files to be printed is - * examined to see if all of the files are postscript. if - * they are, then the input_type field is changed to - * "postscript". - * - * NOTE WELL - autorecognition is not done under the following - * conditions: - * 1) The -T flag has been used. - * 2) *Any* file in the file_list is *not* postscript. Right now, - * this is actually an ugly design decision. The request - * file specifies only one input_type for all of the files - * in the request. If any type isn't postscript, then - * input_type is unmodified, and the request will be - * treated as "simple". The reason for this is due - * to the design of the lp subsystem. What's need is - * to change the request handling to allow for multiple - * file types per request. However, this current - * implementation will fit in 100% with the original - * design of the lp subsystem. - */ -static void -arps(REQUEST * rqp) -{ - char **lfiles; - int start = 0; - int current; - - if (Tflag != 0) { - return; - } - - lfiles = rqp->file_list; - start = psfile(*lfiles); - - for (lfiles++; (lfiles != NULL) && (*lfiles != NULL); lfiles++) { - current = psfile(*lfiles); - if (current != start) { - return; - } - } - - if (start != 0) { /* all the files are postscript */ - rqp->input_type = POSTSCRIPT; - } -} diff --git a/usr/src/cmd/lp/cmd/lpc/Makefile b/usr/src/cmd/lp/cmd/lpc/Makefile deleted file mode 100644 index d4704db6ba..0000000000 --- a/usr/src/cmd/lp/cmd/lpc/Makefile +++ /dev/null @@ -1,77 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# ident "%Z%%M% %I% %E% SMI" -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# cmd/lp/cmd/lpc/Makefile -# - -include ../../Makefile.lp - -PROG= lpc - -ROOTUSRUCBSYMLINK= $(ROOTUSRUCB)/$(PROG) -ROOTUSRBINPROG= $(PROG:%=$(ROOTBIN)/%) - -SRCS= cmds.c cmdtab.c lpc.c process.c topq.c fatalmsg.c sndrcv.c \ - global.c - -OBJS= $(SRCS:.c=.o) - - -CPPFLAGS = -I. -I$(LPINC) $(CPPFLAGS.master) -LDLIBS += $(LIBREQ) $(LIBMSG) $(LIBOAM) \ - $(LIBPRT) $(LIBSEC) $(LIBLP) - -POFILE = lp_cmd_lpc.po - -.KEEP_STATE: - -.PARALLEL: $(OBJS) - -all: $(PROG) - -$(PROG): $(OBJS) - $(LINK.c) $(OBJS) -o $@ $(LDLIBS) - $(POST_PROCESS) - -install: all .WAIT $(ROOTUSRBINPROG) $(ROOTUSRUCBSYMLINK) - -$(ROOTUSRUCBSYMLINK): - $(RM) $@; $(SYMLINK) ../bin/$(PROG) $@ - -clean: - $(RM) $(OBJS) - -clobber: clean - -$(RM) $(PROG) $(CLOBBERFILES) - -strip: - $(STRIP) $(PROG) - -lint: - $(LINT.c) $(SRCS) $(LDLIBS) - -include ../Makefile.msg diff --git a/usr/src/cmd/lp/cmd/lpc/cmds.c b/usr/src/cmd/lp/cmd/lpc/cmds.c deleted file mode 100644 index e877fb71e4..0000000000 --- a/usr/src/cmd/lp/cmd/lpc/cmds.c +++ /dev/null @@ -1,432 +0,0 @@ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - -/* - * Copyright (c) 1983 Regents of the University of California. - * All rights reserved. The Berkeley software License Agreement - * specifies the terms and conditions for redistribution. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* -** lpc -- line printer control program -- commands: -** -*/ -#include <locale.h> -#include <stdio.h> -#include <ctype.h> -#include <string.h> -#include "msgs.h" -#include "lpc.h" - -#define REQUEUE_CURR 0 /* Stop immediately and requeue current job */ -#define WAIT_CURR 1 /* Finish current job before stopping */ -#define ABORT_CURR 2 /* Abort current job */ - -int When; -char *Reason; - -extern char *Printer; -extern char *Lhost; - -#if defined(__STDC__) -static int doarg(char *); -#else -static int doarg(); -#endif - -/* - * kill an existing daemon and disable printing. - */ -void -#if defined(__STDC__) -_abort(int argc, char **argv) -#else -_abort(argc, argv) -int argc; -char **argv; -#endif -{ - When = REQUEUE_CURR; - Reason = NULL; - if (argc == 1) - printf(gettext("Usage: abort {all | printer ...}\n")); - else if (argc == 2 && !strcmp(argv[1], "all")) - do_all(disablepr); - else - while (--argc) - disablepr(*++argv); -} - - -/* - * Kill and restart the daemon. - */ -void -#if defined(__STDC__) -restart(int argc, char **argv) -#else -restart(argc, argv) -int argc; -char **argv; -#endif -{ - When = REQUEUE_CURR; - Reason = NULL; - if (argc == 1) - printf(gettext("Usage: restart {all | printer ...}\n")); - else if (argc == 2 && !strcmp(argv[1], "all")) - do_all(restartpr); - else - while (--argc) - restartpr(*++argv); -} - - -/* - * Enable printing on the specified printer and startup the daemon. - */ -void -#if defined(__STDC__) -start(int argc, char **argv) -#else -start(argc, argv) -int argc; -char **argv; -#endif -{ - if (argc == 1) - printf(gettext("Usage: start {all | printer ...}\n")); - else if (argc == 2 && !strcmp(argv[1], "all")) - do_all(enablepr); - else - while (--argc) - enablepr(*++argv); -} -/* - * Stop the specified daemon after completing the current job and disable - * printing. (Disable only the printer not the queue ) - */ -void -#if defined(__STDC__) -stop(int argc, char **argv) -#else -stop(argc, argv) -int argc; -char **argv; -#endif -{ - When = WAIT_CURR; - Reason = NULL; - if (argc == 1) - printf(gettext("Usage: stop {all | printer ...}\n")); - else if (argc == 2 && !strcmp(argv[1], "all")) - do_all(disablepr); - else - while (--argc) - disablepr(*++argv); -} - -/* - * Enable everything and start printer (undo `down'). - */ -void -#if defined(__STDC__) -up(int argc, char **argv) -#else -up(argc, argv) -int argc; -char **argv; -#endif -{ - if (argc == 1) - printf(gettext("Usage: up {all | printer ...}\n")); - else if (argc == 2 && !strcmp(argv[1], "all")) - do_all(uppr); - else - while (--argc) - uppr(*++argv); -} - -/* - * Disable queuing and printing and put a message into the status file - * (reason for being down). - */ -void -#if defined(__STDC__) -down(int argc, char **argv) -#else -down(argc, argv) -int argc; -char **argv[]; -#endif -{ - if (argc == 1) { - printf(gettext("Usage: down {all | printer} [message ...]\n")); - return; - } - When = WAIT_CURR; - Reason = get_reason(argc-2, &argv[2]); - if (!strcmp(argv[1], "all")) - do_all(downpr); - else - downpr(argv[1]); -} - -/* -** -** Queue Control commands (enable, disable) -** -*/ - -/* - * Enable queuing to the printer (allow lpr's). - */ -void -#if defined(__STDC__) -enable(int argc, char **argv) -#else -enable(argc, argv) -int argc; -char **argv; -#endif -{ - if (argc == 1) - printf(gettext("Usage: enable {all | printer ...}\n")); - else if (argc == 2 && !strcmp(argv[1], "all")) - do_all(enableq); - else - while (--argc) - enableq(*++argv); -} - - -/* - * Disable queuing. - */ -void -#if defined(__STDC__) -disable(int argc, char **argv) -#else -disable(argc, argv) -int argc; -char **argv; -#endif -{ - Reason = NULL; - if (argc == 1) - printf(gettext("Usage: disable {all | printer ...}\n")); - else if (argc == 2 && !strcmp(argv[1], "all")) - do_all(disableq); - else - while (--argc) - disableq(*++argv); -} - -/* -** Status of printers and queues -**/ - -/* - * Print the status of each queue listed or all the queues. - */ -void -#if defined(__STDC__) -status(int argc, char **argv) -#else -status(argc, argv) -int argc; -char **argv; -#endif -{ - if( (argc == 1) || (argc == 2 && !strcmp(argv[1], "all"))) - do_all(statuspr); - else - while (--argc) - statuspr(*++argv); -} - - -/* - * Put the specified jobs at the top of printer queue. - */ -void -#if defined(__STDC__) -topq(int argc, char **argv) -#else -topq(argc, argv) -int argc; -char **argv; -#endif -{ - register int i; - int changed; - - if (argc < 3) { - printf(gettext("Usage: topq printer [jobnum ...] [user ...]\n")); - return; - } - - --argc; - Printer = *++argv; - - /* - * Check if it is a known printer - */ - if(isprinter(Printer)) - printf("%s:\n", Printer); - else{ - printf(gettext("%s: unknown printer\n"), Printer); - return; - } - - /* - * Find if a requestid or a user name is specified - * Also accept job# (LPD style ) - */ - changed = 0; - for (i = argc; --i; ) { - if (doarg(argv[i]) == 0) { - printf(gettext("\tjob %s is not in the queue\n"), argv[i]); - continue; - } else - changed++; - - } - if (!changed) - printf(gettext("\tqueue order unchanged\n")); - return; - -} - -static int -#if defined(__STDC__) -doarg(char *job) -#else -doarg(job) -char *job; -#endif -{ - - char *cp; - int jobnum, n; - char *machine = NULL; - - /* - ** Look for a job item consisting of system name, colon, number - ** (example: ucbarpa:114) - */ - if ((cp = strpbrk(job, "!:")) != NULL) { - *cp++ = NULL; - if (strcmp(Lhost, job)) - machine = job; - job = cp; - } - - /* - ** Check for job specified by number (example: 112 or 235ucbarpa). - */ - if (isdigit(*job) ) { - /* - ** Find machine name if it is of the type "job#machine" - **/ - jobnum = strtol(job, &cp, 10); - /* rest of the string ought to be a machine name */ - if (*cp && strcmp(Lhost, cp)) - machine = cp; - job = (char *)malloc(strlen(Printer) + cp - job + 2); - sprintf(job, "%s-%d", Printer, jobnum); - n = topq_reqid(job, machine); - free(job); - return(n); - } - /* - ** If it is a request-id, process it. - */ - if (isrequest(job)) - return(topq_reqid(job, machine)); - - /* - ** Process item consisting of owner's name (example: henry). - ** job is user name. - **/ - return(topq_user(job, machine)); - -} - -char * -#if defined(__STDC__) -get_reason(int argc, char **argv) -#else -get_reason(argc, argv) -int argc; -char **argv; -#endif -{ - char *cpto, *cpfrom; - static char buf[1024]; - - /* - * Obtain the reason - */ - - if (!argc) - return(NULL); - cpto = buf; - while (--argc >= 0) { - cpfrom = *argv++; - while (*cpto++ = *cpfrom++) - ; - cpto[-1] = ' '; - } - cpto[-1] = '\n'; - *cpto = NULL; - - return(buf); -} - -/* - * Remove all spool files and temporaries from the spooling area. - */ -void -#if defined(__STDC__) -clean(int argc, char **argv) -#else -clean(argc, argv) -int argc; -char **argv; -#endif -{ - if (argc == 1) - printf(gettext("Usage: clean {all | printer ...}\n")); - else if (argc == 2 && !strcmp(argv[1], "all")) - do_all(cleanpr); - else - while (--argc) - cleanpr(*++argv); -} - -/* - * Exit lpc - */ -/*ARGSUSED*/ -void -#if defined(__STDC__) -quit(int argc, char **argv) -#else -quit(argc, argv) -int argc; -char **argv; -#endif -{ - void done(); - - done(0); -} - diff --git a/usr/src/cmd/lp/cmd/lpc/cmdtab.c b/usr/src/cmd/lp/cmd/lpc/cmdtab.c deleted file mode 100644 index 602f06d3df..0000000000 --- a/usr/src/cmd/lp/cmd/lpc/cmdtab.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - - -#ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.1 */ - -/* - * Copyright (c) 1983 Regents of the University of California. - * All rights reserved. The Berkeley software License Agreement - * specifies the terms and conditions for redistribution. - */ - -/* - * lpc -- command tables - */ - -#include "lpc.h" - -char aborthelp[] = "terminate a spooling daemon immediately and disable printing"; -char cleanhelp[] = "remove cruft files from a queue"; -char enablehelp[] = "turn a spooling queue on"; -char disablehelp[] = "turn a spooling queue off"; -char downhelp[] = "do a 'stop' followed by 'disable' and put a message in status"; -char helphelp[] = "get help on commands"; -char quithelp[] = "exit lpc"; -char restarthelp[] = "kill (if possible) and restart a spooling daemon"; -char starthelp[] = "enable printing and start a spooling daemon"; -char statushelp[] = "show status of daemon and queue"; -char stophelp[] = "stop a spooling daemon after current job completes and disable printing"; -char topqhelp[] = "put job at top of printer queue"; -char uphelp[] = "enable everything and restart spooling daemon"; - -struct cmd cmdtab[] = { - { "abort", aborthelp, _abort, 1 }, - { "clean", cleanhelp, clean, 1 }, - { "enable", enablehelp, enable, 1 }, - { "exit", quithelp, quit, 0 }, - { "disable", disablehelp, disable, 1 }, - { "down", downhelp, down, 1 }, - { "help", helphelp, help, 0 }, - { "quit", quithelp, quit, 0 }, - { "restart", restarthelp, restart, 0 }, - { "start", starthelp, start, 1 }, - { "status", statushelp, status, 0 }, - { "stop", stophelp, stop, 1 }, - { "topq", topqhelp, topq, 1 }, - { "up", uphelp, up, 1 }, - { "?", helphelp, help, 0 }, - { 0 }, -}; - -int NCMDS = sizeof (cmdtab) / sizeof (cmdtab[0]) - 1; diff --git a/usr/src/cmd/lp/cmd/lpc/fatalmsg.c b/usr/src/cmd/lp/cmd/lpc/fatalmsg.c deleted file mode 100644 index 521061e152..0000000000 --- a/usr/src/cmd/lp/cmd/lpc/fatalmsg.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2002 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - - -/* - * University Copyright- Copyright (c) 1982, 1986, 1988 - * The Regents of the University of California - * All Rights Reserved - * - * University Acknowledgment- Portions of this document are derived from - * software developed by the University of California, Berkeley, and its - * contributors. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <string.h> -#if defined(__STDC__) -#include <stdarg.h> -#else -#include <varargs.h> -#endif -#define WHO_AM_I I_AM_OZ /* to get oam.h to unfold */ -#include "oam.h" -#include "lpd.h" - -/* - * Report fatal error and exit - */ -/*VARARGS1*/ -void -#if defined (__STDC__) -fatal(char *fmt, ...) -#else -fatal(fmt, va_alist) -char *fmt; -va_dcl -#endif -{ - va_list argp; - - if (Rhost) - (void)printf("%s: ", Lhost); - printf("%s: ", Name); - if (Printer) - (void)printf("%s: ", Printer); -#if defined (__STDC__) - va_start(argp, fmt); -#else - va_start(argp); -#endif - (void)vprintf(fmt, argp); - va_end(argp); - putchar('\n'); - fflush(stdout); - done(1); /* defined by invoker */ - /*NOTREACHED*/ -} - -/* - * Format lp error message to stderr - * (this will probably change to remain compatible with LP) - */ -/*VARARGS1*/ -void -#if defined (__STDC__) -_lp_msg(long msgid, va_list argp) -#else -_lp_msg(msgid, argp) -long msgid; -va_list argp; -#endif -{ - char label[20]; - - (void)vsprintf(_m_, agettxt(msgid, _a_, MSGSIZ), argp); - strcpy(label, "UX:"); - (void)strlcat(label, basename(Name), sizeof (label)); - fmtmsg(label, ERROR, _m_, agettxt(msgid+1, _a_, MSGSIZ)); -} - -/* - * Format lp error message to stderr - */ -/*VARARGS1*/ -void -#if defined (__STDC__) -lp_msg(long msgid, ...) -#else -lp_msg(msgid, va_alist) -long msgid; -va_dcl -#endif -{ - va_list argp; - -#if defined (__STDC__) - va_start(argp, msgid); -#else - va_start(argp); -#endif - _lp_msg(msgid, argp); - va_end(argp); -} - -/* - * Report lp error message to stderr and exit - */ -/*VARARGS1*/ -void -#if defined (__STDC__) -lp_fatal(long msgid, ...) -#else -lp_fatal(msgid, va_alist) -long msgid; -va_dcl -#endif -{ - va_list argp; - -#if defined (__STDC__) - va_start(argp, msgid); -#else - va_start(argp); -#endif - _lp_msg(msgid, argp); - va_end(argp); - - done(1); /* Supplied by caller */ - /*NOTREACHED*/ -} diff --git a/usr/src/cmd/lp/cmd/lpc/global.c b/usr/src/cmd/lp/cmd/lpc/global.c deleted file mode 100644 index 83fa12c222..0000000000 --- a/usr/src/cmd/lp/cmd/lpc/global.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - - -/* - * University Copyright- Copyright (c) 1982, 1986, 1988 - * The Regents of the University of California - * All Rights Reserved - * - * University Acknowledgment- Portions of this document are derived from - * software developed by the University of California, Berkeley, and its - * contributors. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.2 */ - -#include "msgs.h" - -char *Lhost; /* Local host name */ -char *Rhost; /* Remote host name */ -char *Name; /* Program name */ -char *Printer; /* Printer name */ -char Msg[MSGMAX]; /* Message buffer */ diff --git a/usr/src/cmd/lp/cmd/lpc/lpc.c b/usr/src/cmd/lp/cmd/lpc/lpc.c deleted file mode 100644 index 09c4641f96..0000000000 --- a/usr/src/cmd/lp/cmd/lpc/lpc.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - -/* - * Copyright (c) 1983 Regents of the University of California. - * All rights reserved. The Berkeley software License Agreement - * specifies the terms and conditions for redistribution. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * lpc -- line printer control program - */ -#include <locale.h> -#include <stdio.h> -#include <signal.h> -#include <ctype.h> -#include <setjmp.h> -#include <pwd.h> -#include <assert.h> -#include <sys/systeminfo.h> - -#include "lpc.h" - -#include "lp.h" -#include "msgs.h" -#include "oam_def.h" - - -int fromatty; - -char cmdline[200]; -int margc; -char *margv[20]; -int top; -int isadmin; /* set if root or lp */ - -jmp_buf toplevel; - -extern struct cmd cmdtab[]; -extern int NCMDS; - -extern char *Lhost; -extern char *Printer; -extern char *Name; - -#if defined (__STDC__) - void done(int); -static struct cmd * getcmd(char *); -static void cmdscanner(int); -static void intr(int); -static void makeargv(void); -static void startup(void); -#else - void done(); -static struct cmd * getcmd(); -static void cmdscanner(); -static void intr(); -static void makeargv(); -static void startup(); -#endif - -int -main(int argc, char *argv[]) -{ - register struct cmd *c; - struct passwd *p; - char my_name[MAXNAMELEN]; - - (void) setlocale (LC_ALL, ""); - -#if !defined(TEXT_DOMAIN) -#define TEXT_DOMAIN "SYS_TEST" -#endif - (void) textdomain(TEXT_DOMAIN); - - Name = argv[0]; - if (sysinfo(SI_HOSTNAME, my_name, sizeof (my_name)) < 0) { - perror(Name); - exit(1); - } - Lhost = my_name; - - isadmin = getuid() == 0 || - (p = getpwnam(LPUSER)) && p->pw_uid == getuid(); - endpwent(); - - if (--argc > 0) { - c = getcmd(*++argv); - if (c == (struct cmd *)-1) { - printf(gettext("?Ambiguous command\n")); - exit(1); - } - if (c == 0) { - printf(gettext("?Invalid command\n")); - exit(1); - } - if (c->c_priv && !isadmin) { - printf(gettext("?Privileged command\n")); - exit(1); - } - startup(); - (*c->c_handler)(argc, argv); - done(0); - } - - startup(); - - fromatty = isatty(fileno(stdin)); - top = setjmp(toplevel) == 0; - if (top) - sigset(SIGINT, intr); - for (;;) { - cmdscanner(top); - top = 1; - } -} - -/*ARGSUSED*/ -static void -#if defined(__STDC__) -intr(int s) -#else -intr(s) -int s; -#endif -{ - if (!fromatty) - done(0); - longjmp(toplevel, 1); -} - -/* - * Command parser. - */ -static void -#if defined(__STDC__) -cmdscanner(int top) -#else -cmdscanner(top) -int top; -#endif -{ - register struct cmd *c; - - if (!top) - putchar('\n'); - for (;;) { - if (fromatty) { - printf("lpc> "); - fflush(stdout); - } - if (fgets(cmdline, sizeof (cmdline), stdin) == 0) - done(0); - if (cmdline[0] == 0) - break; - makeargv(); - if (!margv[0]) - break; - c = getcmd(margv[0]); - if (c == (struct cmd *)-1) { - printf(gettext("?Ambiguous command\n")); - continue; - } - if (c == 0) { - printf(gettext("?Invalid command\n")); - continue; - } - if (c->c_priv && !isadmin) { - printf(gettext("?Privileged command\n")); - continue; - } - (*c->c_handler)(margc, margv); - } - longjmp(toplevel, 0); -} - -static struct cmd * -#if defined(__STDC__) -getcmd(register char *name) -#else -getcmd(name) -register char *name; -#endif -{ - register char *p, *q; - register struct cmd *c, *found; - register int nmatches, longest; - - longest = 0; - nmatches = 0; - found = 0; - if (!name) return(0); - for (c = cmdtab; p = c->c_name; c++) { - for (q = name; *q == *p++; q++) - if (*q == 0) /* exact match? */ - return(c); - if (!*q) { /* the name was a prefix */ - if (q - name > longest) { - longest = q - name; - nmatches = 1; - found = c; - } else if (q - name == longest) - nmatches++; - } - } - if (nmatches > 1) - return((struct cmd *)-1); - return(found); -} - -/* - * Slice a string up into argc/argv. - */ -static void -#if defined(__STDC__) -makeargv(void) -#else -makeargv() -#endif -{ - register char *cp; - register char **argp = margv; - - margc = 0; - for (cp = cmdline; *cp;) { - while (isspace(*cp)) - cp++; - if (*cp == '\0') - break; - *argp++ = cp; - margc += 1; - while (*cp != '\0' && !isspace(*cp)) - cp++; - if (*cp == '\0') - break; - *cp++ = '\0'; - } - *argp++ = 0; -} - -#define HELPINDENT (sizeof ("directory")) - -/* - * Help command. - */ -void -#if defined(__STDC__) -help(int argc, char **argv) -#else -help(argc, argv) -int argc; -char **argv; -#endif -{ - register struct cmd *c; - - if (argc == 1) { - register int i, j, w; - int columns, width = 0, lines; - - printf(gettext("Commands may be abbreviated. Commands are:\n\n")); - for (c = cmdtab; c < &cmdtab[NCMDS]; c++) { - int len = strlen(c->c_name); - - if (len > width) - width = len; - } - width = (width + 8) &~ 7; - columns = 80 / width; - if (columns == 0) - columns = 1; - lines = (NCMDS + columns - 1) / columns; - for (i = 0; i < lines; i++) { - for (j = 0; j < columns; j++) { - c = cmdtab + j * lines + i; - printf("%s", c->c_name); - if (c + lines >= &cmdtab[NCMDS]) { - printf("\n"); - break; - } - w = strlen(c->c_name); - while (w < width) { - w = (w + 8) &~ 7; - putchar('\t'); - } - } - } - return; - } - while (--argc > 0) { - register char *arg; - arg = *++argv; - c = getcmd(arg); - if (c == (struct cmd *)-1) - printf(gettext("?Ambiguous help command %s\n"), arg); - else if (c == (struct cmd *)0) - printf(gettext("?Invalid help command %s\n"), arg); - else - printf("%-*s\t%s\n", HELPINDENT, - c->c_name, c->c_help); - } -} - -static void -#if defined(__STDC__) -catch(int s) -#else -catch(s) -int s; -#endif -{ - done(2); -} - -static void -#if defined(__STDC__) -startup(void) -#else -startup() -#endif -{ - register int try = 0; - - if (sigset(SIGHUP, SIG_IGN) != SIG_IGN) - (void)sigset(SIGHUP, catch); - if (sigset(SIGINT, SIG_IGN) != SIG_IGN) - (void)sigset(SIGINT, catch); - if (sigset(SIGQUIT, SIG_IGN) != SIG_IGN) - (void)sigset(SIGQUIT, catch); - if (sigset(SIGTERM, SIG_IGN) != SIG_IGN) - (void)sigset(SIGTERM, catch); - - (void)mopen(); -} - -void -#if defined(__STDC__) -done(int rc) -#else -done(rc) -int rc; -#endif -{ - (void)mclose(); - exit(rc); -} diff --git a/usr/src/cmd/lp/cmd/lpc/lpc.h b/usr/src/cmd/lp/cmd/lpc/lpc.h deleted file mode 100644 index a9af649549..0000000000 --- a/usr/src/cmd/lp/cmd/lpc/lpc.h +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - - -#ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.1 */ - -/* - * Copyright (c) 1983 Regents of the University of California. - * All rights reserved. The Berkeley software License Agreement - * specifies the terms and conditions for redistribution. - * - */ - -/* - * Line printer control program. - */ -struct cmd { - char *c_name; /* command name */ - char *c_help; /* help message */ - void (*c_handler)(); /* routine to do the work */ - int c_priv; /* privileged command */ -}; - -#if defined(__STDC__) -char * get_reason(int, char **); -int topq_reqid(char *, char *); -int topq_user(char *, char *); -void _abort(int, char **); -void clean(int, char **); -void cleanpr(char *); -void disable(int, char **); -void disablepr(char *); -void disableq(char *); -void do_all(void (*)(char *)); -void down(int, char **); -void downpr(char *); -void enable(int, char **); -void enablepr(char *); -void enableq(char *); -void help(int, char **); -void quit(int, char **); -void restart(int, char **); -void restartpr(char *); -void start(int, char **); -void status(int, char **); -void statuspr(char *); -void stop(int, char **); -void topq(int, char **); -void up(int, char **); -void uppr(char *); -#else -char * get_reason(); -int topq_reqid(); -int topq_user(); -void _abort(); -void clean(); -void cleanpr(); -void disable(); -void disablepr(); -void disableq(); -void do_all(); -void down(); -void downpr(); -void enable(); -void enablepr(); -void enableq(); -void help(); -void quit(); -void restart(); -void restartpr(); -void start(); -void status(); -void statuspr(); -void stop(); -void topq(); -void up(); -void uppr(); -#endif diff --git a/usr/src/cmd/lp/cmd/lpc/process.c b/usr/src/cmd/lp/cmd/lpc/process.c deleted file mode 100644 index ddeda2c430..0000000000 --- a/usr/src/cmd/lp/cmd/lpc/process.c +++ /dev/null @@ -1,534 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - -/* - * University Copyright- Copyright (c) 1982, 1986, 1988 - * The Regents of the University of California - * All Rights Reserved - * - * University Acknowledgment- Portions of this document are derived from - * software developed by the University of California, Berkeley, and its - * contributors. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <assert.h> -#include <locale.h> - -#include "lp.h" -#include "printers.h" -#include "class.h" -#include "msgs.h" -#include "requests.h" -#include "oam.h" -#include "oam_def.h" -#include "lpc.h" - -struct prnames { - char *printer; - struct prnames *next; -}; - -struct prnames *prhead; - -int got_all_prnames; - -extern int When; -extern char *Reason; - -#if defined (__STDC__) -static void unlinkf(char *); -#else -static void unlinkf(); -#endif - -/** - ** Obtain all printer names from LPSCHED and save them in - ** a linked list of printer names. - **/ -static void -#if defined(__STDC__) -get_all_prnames(void) -#else -get_all_prnames() -#endif -{ - - - - char *printer, - *reject_reason, - *request_id, - *form, - *char_set, - *disable_reason; - - short printer_status, - status; - - long enable_date, - reject_date; - - int rc; - register struct prnames *ptr, *prcur; - - - if (got_all_prnames) - return; - - - /* - * Send a message to LPSCHED to retrive all printer names - * This is done by sending a: S_INQUIRE_PRINTER_STATUS to LPSCHED. - * This will return the current status of the job underway on - * all the printers on the system. - */ - prhead = NULL; - snd_msg(S_INQUIRE_PRINTER_STATUS, ""); - do { - rcv_msg(R_INQUIRE_PRINTER_STATUS, &status, - &printer, - &form, - &char_set, - &disable_reason, - &reject_reason, - &printer_status, - &request_id, - &enable_date, - &reject_date); - if(!(ptr = (struct prnames *)malloc(sizeof(struct prnames)))) { - lp_fatal(E_LP_MALLOC); - /*NOTREACHED*/ - } - if(prhead == NULL) - prhead = ptr; - else - prcur->next = ptr; - prcur = ptr; - /* Copy : printer name - * Increment the entry count. - */ - ptr->printer = (char *)malloc(strlen(printer) + 1); - strcpy(ptr->printer, printer); - ptr->next = NULL; - } while(status== MOKMORE); - got_all_prnames = 1; - return; -} - - - -/* -** The actual work in passing the commands to LPCSHED is done here -** i.e: Enable/disable the queues -** Enable/disable the printers -** canceling jobs and the temporary files etc -**/ - -/* -** Disable the queue to a printer. -**/ -void -#if defined(__STDC__) -disableq(char *dest) -#else -disableq(dest) -char *dest; -#endif -{ - short status; - char *reason = Reason; - - if (!reason) - reason = "unknown reason"; - - snd_msg(S_REJECT_DEST, dest, reason); - rcv_msg(R_REJECT_DEST, &status); - switch (status) { - case MOK: - case MERRDEST: - printf(gettext("%s:\n\tqueuing disabled\n"), dest); - break; - case MNODEST: - printf(gettext("unknown printer %s\n"), dest); - break; - case MNOPERM: - printf(gettext("%s:\n\tcannot disable queuing\n"), dest); - break; - default: - lp_fatal(E_LP_BADSTATUS, status); - /*NOTREACHED*/ - } -} -/* -** Enable the queue to a printer. -**/ - -void -#if defined(__STDC__) -enableq(char *dest) -#else -enableq(dest) -char *dest; -#endif -{ - short status; - - snd_msg(S_ACCEPT_DEST, dest); - rcv_msg(R_ACCEPT_DEST, &status); - switch (status) { - case MOK: - case MERRDEST: - printf("%s:\n", dest); - printf(gettext("\tqueueing enabled\n")); - break; - case MNODEST: - printf(gettext("unknown printer %s\n"), dest); - break; - case MNOPERM: - printf("%s:\n", dest); - printf(gettext("\tcannot enable queueing\n")); - break; - default: - lp_fatal(E_LP_BADSTATUS, status); - /*NOTREACHED*/ - } - -} - -/* -** Enable printing on the given printer. -**/ -void -#if defined(__STDC__) -enablepr(char *dest) -#else -enablepr(dest) -char *dest; -#endif -{ - short status; - - snd_msg(S_ENABLE_DEST, dest); - rcv_msg(R_ENABLE_DEST, &status); - switch (status) { - case MOK: - case MERRDEST: - printf("%s:\n", dest); - printf(gettext("\tprinting enabled\n")); - break; - case MNODEST: - printf(gettext("unknown printer %s\n"), dest); - break; - case MNOPERM: - printf("%s:\n", dest); - printf(gettext("\tcannot enable printing\n")); - break; - default: - lp_fatal(E_LP_BADSTATUS, status); - /*NOTREACHED*/ - } -} - -/* -** Disable printing on the named printer. -**/ -void -#if defined(__STDC__) -disablepr(char *dest) -#else -disablepr(dest) -char *dest; -#endif -{ - short status; - char *req_id; - char *reason = Reason; - - if (!reason) - reason = "stopped by user"; - - snd_msg(S_DISABLE_DEST, dest, reason, When); - rcv_msg(R_DISABLE_DEST, &status, &req_id); - switch (status) { - case MOK: - case MERRDEST: - printf("%s:\n", dest); - printf(gettext("\tprinting disabled\n")); - break; - case MNODEST: - printf(gettext("unknown printer %s\n"), dest); - break; - case MNOPERM: - printf("%s:\n", dest); - printf(gettext("\tcannot disable printing\n")); - break; - default: - lp_fatal(E_LP_BADSTATUS, status); - /*NOTREACHED*/ - } - return; -} - -void -#if defined(__STDC__) -statuspr(char *printer) -#else -statuspr(printer) -char *printer; -#endif -{ - char *tprinter; - - int rc, entry_count; - - char *user, - *reject_reason, - *request_id, - *form, - *slabel, - *file, - *char_set, - *disable_reason; - - short printer_status, - status, rank, - state; - - long size, - enable_date, - reject_date, - date; - char buff[100]; - - entry_count = 0; - snd_msg(S_INQUIRE_PRINTER_STATUS, printer); - rcv_msg(R_INQUIRE_PRINTER_STATUS, &status, - &tprinter, - &form, - &char_set, - &disable_reason, - &reject_reason, - &printer_status, - &request_id, - &enable_date, - &reject_date); - switch (status) { - case MOK: - case MOKMORE: - break; - case MNODEST: - printf(gettext("unknown printer %s\n"), printer); - return; - default: - lp_fatal(E_LP_BADSTATUS, status); - /*NOTREACHED*/ - } - printf("%s:\n", printer); - printf(gettext("\tqueueing is %s\n"), printer_status & PS_REJECTED ? gettext("disabled") : - gettext("enabled")); - printf(gettext("\tprinting is %s\n"), printer_status & PS_DISABLED ? gettext("disabled") : - gettext("enabled")); - snd_msg(S_INQUIRE_REQUEST_RANK, "", "", printer, "", ""); - do { - rcv_msg(R_INQUIRE_REQUEST_RANK, &status, - &request_id, - &user, - &slabel, - &size, - &date, - &state, - &tprinter, - &form, - &char_set, - &rank, - &file); - switch (status) { - case MOK: - case MOKMORE: - if (!(state & RS_DONE)) - entry_count++; - break; - case MNOINFO: - break; - default: - lp_fatal(E_LP_BADSTATUS, status); - /*NOTREACHED*/ - } - } while (status == MOKMORE); - if (entry_count == 0 ) - printf(gettext("\tno entries\n")); - else if (entry_count == 1) - printf(gettext("\t1 entry in spool area\n")); - else - printf(gettext("\t%d entries in spool area\n"), entry_count); - if (entry_count) { - if (!(printer_status & (PS_FAULTED|PS_DISABLED))) - printf(gettext("\t%s is ready and printing\n"), printer); - else if (printer_status & PS_FAULTED) - printf(gettext("\twaiting for %s to become ready (offline?)\n"), printer); - } - - /*??? what to do for remote printers: - possible status: - "waiting for RM to come up" - "waiting for queue to be enabled on RM" - "sending to RM" - "no space on remote; waiting for queue to drain" - */ -} - -void -#if defined(__STDC__) -restartpr(char *dest) -#else -restartpr(dest) -char *dest; -#endif -{ - disablepr(dest); - enablepr(dest); -} - -void -#if defined(__STDC__) -uppr(char *dest) -#else -uppr(dest) -char *dest; -#endif -{ - enableq(dest); - enablepr(dest); -} - -void -#if defined(__STDC__) -downpr(char *dest) -#else -downpr(dest) -char *dest; -#endif -{ - disableq(dest); - disablepr(dest); -} - -/* avoids compiler type checking problem */ -static int -#if defined(__STDC__) -_strcmp(const void *s1, const void *s2) -#else -_strcmp(s1, s2) -void *s1; -void *s2; -#endif -{ - return(strcmp(s1, s2)); -} - -void -#if defined(__STDC__) -cleanpr(char *dest) -#else -cleanpr(dest) -char *dest; -#endif -{ - int i; - short more; - long status; - char * req_id; - - snd_msg(S_CANCEL, dest, "", ""); - - do { - rcv_msg(R_CANCEL, &more, &status, &req_id); - - switch (status) { - case MOK: - printf(gettext("\tremoved %s\n"), req_id); - break; - case M2LATE: - printf(gettext("\tbusy %s failed\n"), req_id); - break; - case MUNKNOWN: - case MNOINFO: - case MNOPERM: - printf(gettext("\t%s failed\n"), req_id); - break; - default: - printf(gettext("Unknown status from scheduler (%d)\n"), - status); - exit (1); - } - - } while (more == MOKMORE); - - return; - - - -} - -static void -#if defined(__STDC__) -unlinkf(char *name) -#else -unlinkf(name) -char *name; -#endif -{ - if (unlink(name) < 0) - printf(gettext("\tcannot remove %s\n"), name); - else - printf(gettext("\tremoved %s\n"), name); -} - -void -#if defined(__STDC__) -do_all(void (*func)(char *)) -#else -do_all(func) -void (*func)(); -#endif -{ - register struct prnames *ptr; - - get_all_prnames(); - - for (ptr = prhead; ptr; ptr = ptr->next) - (*func)(ptr->printer); -} diff --git a/usr/src/cmd/lp/cmd/lpc/sndrcv.c b/usr/src/cmd/lp/cmd/lpc/sndrcv.c deleted file mode 100644 index b989ba5a86..0000000000 --- a/usr/src/cmd/lp/cmd/lpc/sndrcv.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - - -/* - * University Copyright- Copyright (c) 1982, 1986, 1988 - * The Regents of the University of California - * All Rights Reserved - * - * University Acknowledgment- Portions of this document are derived from - * software developed by the University of California, Berkeley, and its - * contributors. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.2 */ - -#if defined(__STDC__) -#include <stdarg.h> -#else -#include <varargs.h> -#endif -#include "lp.h" -#include "msgs.h" -#define WHO_AM_I I_AM_OZ /* to get oam.h to unfold */ -#include "oam.h" -#include "lpd.h" - -/* - * Format and send message to lpsched - * (die if any errors occur) - */ -/*VARARGS1*/ -void -#if defined (__STDC__) -snd_msg(int type, ...) -#else -snd_msg(type, va_alist) -int type; -va_dcl -#endif -{ - va_list ap; - -#if defined (__STDC__) - va_start(ap, type); -#else - va_start(ap); -#endif - (void)_putmessage (Msg, type, ap); - va_end(ap); - if (msend(Msg) == -1) { - lp_fatal(E_LP_MSEND); - /*NOTREACHED*/ - } -} - -/* - * Recieve message from lpsched - * (die if any errors occur) - */ -void -#if defined (__STDC__) -rcv_msg(int type, ...) -#else -rcv_msg(type, va_alist) -int type; -va_dcl -#endif -{ - va_list ap; - int rc; - - if ((rc = mrecv(Msg, MSGMAX)) != type) { - if (rc == -1) - lp_fatal(E_LP_MRECV); - else - lp_fatal(E_LP_BADREPLY, rc); - /*NOTREACHED*/ - } -#if defined (__STDC__) - va_start(ap, type); -#else - va_start(ap); -#endif - rc = _getmessage(Msg, type, ap); - va_end(ap); - if (rc < 0) { - lp_fatal(E_LP_GETMSG, PERROR); - /*NOTREACHED*/ - } -} diff --git a/usr/src/cmd/lp/cmd/lpc/topq.c b/usr/src/cmd/lp/cmd/lpc/topq.c deleted file mode 100644 index 4a5b0fccff..0000000000 --- a/usr/src/cmd/lp/cmd/lpc/topq.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - -/* - * University Copyright- Copyright (c) 1982, 1986, 1988 - * The Regents of the University of California - * All Rights Reserved - * - * University Acknowledgment- Portions of this document are derived from - * software developed by the University of California, Berkeley, and its - * contributors. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <locale.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <assert.h> - -#include "lp.h" -#include "printers.h" -#include "class.h" -#include "msgs.h" -#include "requests.h" -#define WHO_AM_I I_AM_OZ -#include "oam_def.h" - -extern char *Printer; - -#if defined(__STDC__) -static char * start_change(char *); -static int end_change(char *); -#else -static char * start_change(); -static int end_change(); -#endif - -int -#if defined(__STDC__) -topq_reqid(char *reqid, char *machine) -#else -topq_reqid(reqid, machine) -char *reqid; -char *machine; -#endif -{ - - /* - ** This is similar to: lp -i request-id -H IMMEDIATE - */ - - char *reqfile; /* Name of request file */ - REQUEST *oldrqp; - char buf[50]; - - if (machine) { - (void) snprintf(buf, sizeof (buf), "%s!%s", machine, reqid); - reqid = buf; - } - if (!(reqfile = start_change(reqid))) - return(0); - - if (!(oldrqp = getrequest(reqfile))) - return (0); - - oldrqp->actions |= ACT_IMMEDIATE; - - if (putrequest(reqfile, oldrqp) == -1) { /* write request file */ - switch(errno) { - default: - lp_fatal(E_LPP_FPUTREQ); - /*NOTREACHED*/ - } - } - free(reqfile); - (void)end_change(reqid); - - printf(gettext("\tmoved %s\n"), reqid); - return(1); -} - - -/* start_change -- start change request */ -static char * -#if defined(__STDC__) -start_change(char *rqid) -#else -start_change(rqid) -char *rqid; -#endif -{ - short status; - char *rqfile; - - snd_msg(S_START_CHANGE_REQUEST, rqid); - rcv_msg(R_START_CHANGE_REQUEST, &status, &rqfile); - - switch (status) { - case MOK: - return((char *)strdup(rqfile)); - default: - return(NULL); - } -} - -static int -#if defined(__STDC__) -end_change(char *rqid) -#else -end_change(rqid) -char *rqid; -#endif -{ - long chkbits; - short status; - - snd_msg(S_END_CHANGE_REQUEST, rqid); - rcv_msg(R_END_CHANGE_REQUEST, &status, &chkbits); - - switch (status) { - case MOK: - return(1); - default: - return(0); - } -} - -/* -** topq command handler if user name is specified -** Find request-ids of all jobs submitted by the user. -** Save the request-ids -** Follow the same method as in topq_reqid for each if the ids. -*/ -int -#if defined(__STDC__) -topq_user(char *user, char *machine) -#else -topq_user(user, machine) -char *user; -char *machine; -#endif -{ - char *request_id, *form, *slabel, *character_set; - char buf[50]; - char **rqlist = NULL, **pp; - short state, status; - long size, date; - int count = 0; - - - if (machine) { - (void) snprintf(buf, sizeof (buf), "%s!%s", machine, user); - user = buf; - } - snd_msg(S_INQUIRE_REQUEST, "", Printer, "", user, ""); - do { - rcv_msg(R_INQUIRE_REQUEST, &status, - &request_id, - &user, - &slabel, - &size, - &date, - &state, - &Printer, - &form, - &character_set); - switch (status) { - case MOK: - case MOKMORE: - appendlist(&rqlist, request_id); - break; - default: - return(0); - } - } while (status == MOKMORE); - for (pp = rqlist; *pp; pp++) - count += topq_reqid(*pp, machine); - freelist(rqlist); - return(count); /* Number of jobs moved to topq */ -} diff --git a/usr/src/cmd/lp/cmd/lpmove.c b/usr/src/cmd/lp/cmd/lpmove.c deleted file mode 100644 index 56d52e38b1..0000000000 --- a/usr/src/cmd/lp/cmd/lpmove.c +++ /dev/null @@ -1,376 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* lpmove dest1 dest2 - move all requests from dest1 to dest2 - * lpmove request ... dest - move requests to destination dest - * - * This command may be used only by an LP Administrator - */ - -#include <assert.h> -#include <signal.h> -#include <locale.h> -#include <sys/types.h> - -#include "lp.h" -#include "msgs.h" -#include "printers.h" - -#define WHO_AM_I I_AM_LPMOVE -#include "oam.h" - -char message[100], - reply[100]; - -#define TRUE 1 -#define FALSE 0 - -void startup(), cleanup(), err_exit(); -static int accept(char *); -static int reject(char *, char *); - -#if defined(__STDC__) -void catch(); -#else -int catch(); -#endif - -void -usage() -{ - (void) printf (gettext( -"usage:\n" -"\n" -" (move all requests, reject any new requests)\n" -" lpmove from-destination to-destination\n" -"\n" -" (move individual requests)\n" -" lpmove requests ... to-destination\n")); - - return; -} - -char *strncpy(); - -int -main(int argc, char *argv[]) -{ - int i, type, size, rc = 0, wasrej; - short status; - char *strchr(), *rq_id, *chkp; - long chkbits; - short nmove = 0; - - (void) setlocale(LC_ALL, ""); - -#if !defined(TEXT_DOMAIN) -#define TEXT_DOMAIN "SYS_TEST" -#endif - (void) textdomain(TEXT_DOMAIN); - - if (argc == 2 && STREQU(argv[1], "-?")) { - usage(); - exit(0); - } - if(argc < 3) { - usage(); - exit(1); - } - - startup(); - - if (!isrequest(argv[1])) { /* if first arg is a dest */ - if(argc != 3) { - usage(); - exit(1); - } - - if ((wasrej = reject(argv[1],argv[2])) == 1) err_exit(); - - printf(gettext("move in progress ...\n")); - size = putmessage(message, S_MOVE_DEST, argv[1], argv[2]); - assert(size != -1); - if (msend(message)) { - LP_ERRMSG(ERROR, E_LP_MSEND); - goto Errexit; - } - while (1) { - if ((type = mrecv(reply, sizeof(reply))) == -1) { - LP_ERRMSG(ERROR, E_LP_MRECV); - goto Errexit; - } - if (type != R_MOVE_DEST - || getmessage(reply, type, &status, &rq_id, &nmove) == -1) { - LP_ERRMSG1 (ERROR, E_LP_BADREPLY, type); - goto Errexit; - } - switch (status) { - case MOK: - break; - case MNODEST: - LP_ERRMSG1(ERROR, E_LP_DSTUNK, rq_id); -Errexit: if (!wasrej) accept(argv[1]); - err_exit(); - case MERRDEST: - LP_ERRMSG1(WARNING, E_MOV_BADDEST, rq_id); - rc = 1; - break; - case MMORERR: - LP_ERRMSG1(WARNING, E_MOV_BADDEST, rq_id); - rc = 1; - continue; - case MNOPERM: - LP_ERRMSG(ERROR, E_LP_NOTADM); - err_exit(); - default: - LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status); - rc = 1; - } - break; - } - printf(gettext("total of %d requests moved from %s to %s\n"), - nmove, argv[1], argv[2]); - } else { - for(i = 1; i < argc - 1; i++) { - size = putmessage(message, - S_MOVE_REQUEST, argv[i], argv[argc-1]); - assert(size != -1); - if (msend(message)) { - LP_ERRMSG(ERROR, E_LP_MSEND); - err_exit(); - } - if ((type = mrecv(reply, sizeof(reply))) == -1) { - LP_ERRMSG(ERROR, E_LP_MRECV); - err_exit(); - } - if (type != R_MOVE_REQUEST - || getmessage(reply, type, &status, &chkbits) == -1) { - LP_ERRMSG1 (ERROR, E_LP_BADREPLY, type); - err_exit(); - } - switch (status) { - case MOK: - nmove++; - break; - case MDENYDEST: - if (chkbits) { - chkp = message; - if (chkbits & PCK_TYPE) chkp += sprintf(chkp, "printer type, "); - if (chkbits & PCK_CHARSET) chkp += sprintf(chkp, "character set, "); - if (chkbits & PCK_CPI) chkp += sprintf(chkp, "cpi, "); - if (chkbits & PCK_LPI) chkp += sprintf(chkp, "lpi, "); - if (chkbits & PCK_WIDTH) chkp += sprintf(chkp, "width, "); - if (chkbits & PCK_LENGTH) chkp += sprintf(chkp, "length, "); - if (chkbits & PCK_BANNER) chkp += sprintf(chkp, "banner req., "); - chkp[-2] = 0; - LP_ERRMSG2(ERROR, E_MOV_PTRCHK, argv[i], message); - } - else LP_ERRMSG1(ERROR, E_MOV_DENYDEST, argv[i]); - rc = 1; - break; - case MNOMEDIA: - LP_ERRMSG1(ERROR, E_MOV_NOMEDIA, argv[i]); - rc = 1; - break; - case MDENYMEDIA: - LP_ERRMSG1(ERROR, E_MOV_DENYMEDIA, argv[i]); - rc = 1; - break; - case MNOMOUNT: - LP_ERRMSG1(ERROR, E_MOV_NOMOUNT, argv[i]); - rc = 1; - break; - case MNOFILTER: - LP_ERRMSG1(ERROR, E_MOV_NOFILTER, argv[i]); - rc = 1; - break; - case MERRDEST: - LP_ERRMSG1(ERROR, E_LP_REQDENY, argv[argc-1]); - rc = 1; - break; - case MNODEST: - LP_ERRMSG1(ERROR, E_LP_DSTUNK, argv[argc-1]); - err_exit(); - case MUNKNOWN: - LP_ERRMSG1(ERROR, E_LP_UNKREQID, argv[i]); - rc = 1; - break; - case MBUSY: - LP_ERRMSG1(ERROR, E_LP_BUSY, argv[i]); - rc = 1; - break; - case M2LATE: - LP_ERRMSG1(ERROR, E_LP_2LATE, argv[i]); - rc = 1; - break; - case MNOPERM: - LP_ERRMSG (ERROR, E_LP_NOTADM); - err_exit(); - case MGONEREMOTE: - LP_ERRMSG1(ERROR, E_LP_GONEREMOTE, argv[i]); - break; - default: - LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status); - rc = 1; - } - } - printf(gettext("total of %d requests moved to %s\n"), nmove, argv[argc-1]); - } - - cleanup(); - return (rc); -} - -static int -accept(char *dest) -{ - int type, size; - short status; - - size = putmessage(message, S_ACCEPT_DEST, dest); - assert(size != -1); - if (msend(message)) { - LP_ERRMSG(ERROR, E_LP_MSEND); - return(1); - } - if ((type = mrecv(reply, size)) == -1) { - LP_ERRMSG(ERROR, E_LP_MRECV); - return(1); - } - if (type != R_ACCEPT_DEST - || getmessage(reply, type, &status) == -1) { - LP_ERRMSG(ERROR, E_LP_BADREPLY); - return(1); - } - switch (status) { - case MNODEST: - LP_ERRMSG1(ERROR, E_LP_DSTUNK, dest); - return(1); - case MNOPERM: - LP_ERRMSG (ERROR, E_LP_NOTADM); - return(1); - default: - LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status); - return(1); - case MOK: - case MERRDEST: - ; - } - - return (0); -} - -static int -reject(char *d1, char *d2) -{ - int type, size; - short status; - char reason[128]; - - /* reject(dest, reason) */ - snprintf(reason, sizeof (reason), "requests moved to %s", d2); - size = putmessage(message, S_REJECT_DEST, d1, reason); - assert(size != -1); - if (msend(message)) { - LP_ERRMSG(ERROR, E_LP_MSEND); - return(1); - } - if ((type = mrecv(reply, size)) == -1) { - LP_ERRMSG(ERROR, E_LP_MRECV); - return(1); - } - if (type != R_REJECT_DEST - || getmessage(reply, type, &status) == -1) { - LP_ERRMSG(ERROR, E_LP_BADREPLY); - return(1); - } - switch (status) { - case MNODEST: - LP_ERRMSG1(ERROR, E_LP_DSTUNK, d1); - return(1); - case MNOPERM: - LP_ERRMSG (ERROR, E_LP_NOTADM); - return(1); - default: - LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status); - return(1); - case MERRDEST: - return(-1); /* was rejecting */ - case MOK: - printf(gettext("destination %s is not accepting requests\n"), d1); - break; - } - - return (0); -} - -void -startup() -{ - if (mopen()) {LP_ERRMSG(ERROR, E_LP_MOPEN); exit(1);} - - if(signal(SIGHUP, SIG_IGN) != SIG_IGN) - signal(SIGHUP, catch); - if(signal(SIGINT, SIG_IGN) != SIG_IGN) - signal(SIGINT, catch); - if(signal(SIGQUIT, SIG_IGN) != SIG_IGN) - signal(SIGQUIT, catch); - if(signal(SIGTERM, SIG_IGN) != SIG_IGN) - signal(SIGTERM, catch); -} - -/* catch -- catch signals */ - -#if defined(__STDC__) -void -#endif -catch() -{ - - signal(SIGHUP, SIG_IGN); - signal(SIGINT, SIG_IGN); - signal(SIGQUIT, SIG_IGN); - signal(SIGTERM, SIG_IGN); - err_exit(); -} - -void -cleanup() -{ - (void)mclose (); -} - -void -err_exit() -{ - cleanup(); - exit(1); -} diff --git a/usr/src/cmd/lp/cmd/lpstat/accept.c b/usr/src/cmd/lp/cmd/lpstat/accept.c deleted file mode 100644 index 987682cde8..0000000000 --- a/usr/src/cmd/lp/cmd/lpstat/accept.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - - -/* - * Copyright 2002 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <locale.h> -#include "stdio.h" - -#include "lp.h" -#include "class.h" -#include "msgs.h" - -#define WHO_AM_I I_AM_LPSTAT -#include "oam.h" - -#include "lpstat.h" - -/** - ** do_accept() - **/ - -void -#if defined(__STDC__) -do_accept ( - char ** list -) -#else -do_accept (list) - char **list; -#endif -{ - while (*list) { - if (STREQU(*list, NAME_ALL)) { - send_message (S_INQUIRE_CLASS, ""); - (void)output (R_INQUIRE_CLASS); - send_message (S_INQUIRE_PRINTER_STATUS, ""); - (void)output (R_INQUIRE_PRINTER_STATUS); - - } else if (isclass(*list)) { - send_message (S_INQUIRE_CLASS, *list); - (void)output (R_INQUIRE_CLASS); - - } else { - send_message (S_INQUIRE_PRINTER_STATUS, *list); - switch (output(R_INQUIRE_PRINTER_STATUS)) { - case MNODEST: - LP_ERRMSG1 (ERROR, E_LP_BADDEST, *list); - exit_rc = 1; - break; - } - - } - list++; - } - return; -} - -/** - ** putqline() - **/ - -void -putqline(char *dest, int rejecting, time_t date, char *reject_reason) -{ - char reject_date[SZ_DATE_BUFF]; - - (void) strftime(reject_date, sizeof (reject_date), NULL, - localtime(&date)); - - - if (!rejecting) - (void) printf(gettext("%s accepting requests since %s\n"), - dest, reject_date); - else - (void) printf( - gettext("%s not accepting requests since %s -\n\t%s\n"), - dest, reject_date, reject_reason); - return; -} diff --git a/usr/src/cmd/lp/cmd/lpstat/add_mounted.c b/usr/src/cmd/lp/cmd/lpstat/add_mounted.c deleted file mode 100644 index f89f633caf..0000000000 --- a/usr/src/cmd/lp/cmd/lpstat/add_mounted.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 1993 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - - -#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.8 */ - -#include "string.h" -#include "errno.h" -#include "sys/types.h" -#include "stdlib.h" - -#include "lp.h" -#include "printers.h" - -#define WHO_AM_I I_AM_LPSTAT -#include "oam.h" - -#include "lpstat.h" - - -#define nuther_mount() (MOUNTED *)Malloc(sizeof(MOUNTED)) - -static MOUNTED mounted_forms_head = { 0, 0, 0 }, - mounted_pwheels_head = { 0, 0, 0 }; - -MOUNTED *mounted_forms = &mounted_forms_head, - *mounted_pwheels = &mounted_pwheels_head; - -static void insert_mounted ( MOUNTED * , char * , char * , char * ); -static int cs_addlist ( char *** , char * ); - -/** - ** add_mounted() - ADD A FORM, PRINTWHEEL TO LIST - **/ - -void -add_mounted(char *printer, char *form, char *pwheel) -{ - register PRINTER *pp; - - register char **pcs; - char *ptrForm,*ptrEndForm; - - - /* - * Add this form to the list of mounted forms. - */ - if (form && *form) - if (ptrEndForm = strchr(form,*LP_SEP) ) { - ptrForm = form; - while (ptrEndForm) { - *ptrEndForm = 0; - insert_mounted(mounted_forms, ptrForm, printer, - (char *)0); - ptrForm = ptrEndForm+1; - ptrEndForm = strchr(ptrForm,*LP_SEP); - } - } else - insert_mounted(mounted_forms, form, printer, (char *)0); - - /* - * Add this print wheel to the list of mounted print - * wheels. - */ - if (pwheel && *pwheel) - insert_mounted ( - mounted_pwheels, - pwheel, - printer, - "!" - ); - - if (!(pp = getprinter(printer))) { - LP_ERRMSG2 (ERROR, E_LP_GETPRINTER, printer, PERROR); - done(1); - } - - /* - * Add the list of administrator supplied character-set - * or print wheel aliases to the list. - */ - if (pp->char_sets) - for (pcs = pp->char_sets; *pcs; pcs++) - if (pp->daisy) - insert_mounted ( - mounted_pwheels, - *pcs, - printer, - (char *)0 - ); - - else { - register char *terminfo_name, - *alias; - - if ( - (terminfo_name = strtok(*pcs, "=")) - && (alias = strtok((char *)0, "=")) - ) - insert_mounted ( - mounted_pwheels, - alias, - printer, - terminfo_name - ); - } - - /* - * Do the aliases built into the Terminfo database for - * this printer's type. This applies only to printers - * that have defined character sets. - */ - if ((pcs = get_charsets(pp, 1))) - for ( ; *pcs; pcs++) { - register char *terminfo_name, - *alias; - - if ( - (terminfo_name = strtok(*pcs, "=")) - && (alias = strtok((char *)0, "=")) - ) - insert_mounted ( - mounted_pwheels, - alias, - printer, - terminfo_name - ); - } - - - return; -} - -/** - ** insert_mounted() - **/ - -static void -insert_mounted(MOUNTED *ml, char *name, char *printer, char *tag) -{ - register MOUNTED *pm; - - register char *nm, - *pnm; - - - /* - * For forms: Each printer that has the form mounted is - * marked with a leading '!'. - * For print wheels and character sets: Each character - * set name is marked with a leading '!'; each printer - * that has a print wheel mounted is marked with a leading '!'. - */ - - if (tag && tag[0] != '!') { - nm = Malloc(1 + strlen(name) + 1); - nm[0] = '!'; - (void)strcpy (nm + 1, name); - } else - nm = name; - - for ( - pm = ml; - pm->name && !STREQU(pm->name, nm); - pm = pm->forward - ) - ; - - if (tag && tag[0] == '!') { - pnm = Malloc(1 + strlen(printer) + 1); - pnm[0] = '!'; - (void)strcpy (pnm + 1, printer); - - } else if (tag) { - pnm = Malloc(strlen(printer) + 1 + strlen(tag) + 1); - (void)sprintf (pnm, "%s=%s", printer, tag); - - } else - pnm = printer; - - - if (cs_addlist(&(pm->printers), pnm) == -1) { - LP_ERRMSG (ERROR, E_LP_MALLOC); - done (1); - } - - if (!pm->name) { - pm->name = strdup(nm); - pm = (pm->forward = nuther_mount()); - pm->name = 0; - pm->printers = 0; - pm->forward = 0; - } - - return; -} - -/** - ** cs_addlist() - **/ - -static int -cs_addlist(char ***plist, char *item) -{ - register char **pl; - - register int n; - - if (*plist) { - - n = lenlist(*plist); - - for (pl = *plist; *pl; pl++) - if ( - (*pl)[0] == '!' && STREQU((*pl)+1, item) - || STREQU(*pl, item) - ) - break; - - if (!*pl) { - - n++; - *plist = (char **)Realloc( - (char *)*plist, - (n + 1) * sizeof(char *) - ); - (*plist)[n - 1] = strdup(item); - (*plist)[n] = 0; - - } - - } else { - - *plist = (char **)Malloc(2 * sizeof(char *)); - (*plist)[0] = strdup(item); - (*plist)[1] = 0; - - } - - return (0); -} diff --git a/usr/src/cmd/lp/cmd/lpstat/charset.c b/usr/src/cmd/lp/cmd/lpstat/charset.c deleted file mode 100644 index 6d6f504e9c..0000000000 --- a/usr/src/cmd/lp/cmd/lpstat/charset.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 1991 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - - -#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.6 */ - -#include "string.h" -#include "sys/types.h" -#include "stdlib.h" - -#include "lp.h" -#include "form.h" -#include "access.h" -#include "printers.h" - -#define WHO_AM_I I_AM_LPSTAT -#include "oam.h" - -#include "lpstat.h" -#include <locale.h> - -extern char *tparm(); - -#if defined(__STDC__) -static void putsline ( MOUNTED * ); -#else -static void putsline(); -#endif - -/** - ** do_charset() - **/ - -void -#if defined(__STDC__) -do_charset ( - char ** list -) -#else -do_charset (list) - char ** list; -#endif -{ - register MOUNTED * pm; - - register int found; - - - while (*list) { - if (STREQU(NAME_ALL, *list)) - for (pm = mounted_pwheels; pm->name; pm = pm->forward) - putsline (pm); - - else { - found = 0; - for (pm = mounted_pwheels; pm->name; pm = pm->forward) - if ( - pm->name[0] == '!' - && STREQU(pm->name + 1, *list) - || STREQU(pm->name, *list) - ) { - putsline (pm); - found = 1; - } - if (!found) { - LP_ERRMSG1 (ERROR, E_STAT_BADSET, *list); - exit_rc = 1; - } - } - list++; - } - return; -} - -/** - ** putsline() - **/ - -static void -#if defined(__STDC__) -putsline ( - MOUNTED * pm -) -#else -putsline (pm) - register MOUNTED *pm; -#endif -{ - register char ** pp; - register char * sep; - - - if (pm->name[0] != '!') { - - if ((pp = pm->printers)) - if (verbosity & V_LONG) { - (void)printf (gettext("print wheel %s\n\tavailable on:"), pm->name); - while (*pp) { - if ((*pp)[0] == '!') - (void)printf ( - gettext("\n\t\t%s (mounted)"), - *pp + 1 - ); - else - (void)printf ("\n\t\t%s", *pp); - pp++; - } - } else { - sep = ", mounted on "; - while (*pp) { - if ((verbosity & V_LONG) || (*pp)[0] == '!') { - (void)printf ( - "%s%s", - sep, - ((*pp)[0] == '!'? *pp + 1 : *pp) - ); - sep = ","; - } - pp++; - } - } - - (void)printf ("\n"); - - } else { - - (void)printf (gettext("character set %s\n"), pm->name + 1); - - if ((verbosity & V_LONG) && (pp = pm->printers)) { - (void)printf (gettext("\tavailable on:\n")); - while (*pp) { - (void)printf ( - "\t\t%s (as %s)\n", - strtok(*pp, "="), - strtok((char *)0, "=") - ); - pp++; - } - } - - } - return; -} - -/** - ** get_charsets() - CONSTRUCT (char **) LIST OF CHARSETS FROM csnm - **/ - -char ** -#if defined(__STDC__) -get_charsets ( - PRINTER * prbufp, - int addcs -) -#else -get_charsets (prbufp, addcs) - PRINTER *prbufp; - register int addcs; -#endif -{ - register int cs = 0; - - register char * name; - - register char ** pt; - - char * csnm; - char ** list = 0; - - - if ( - prbufp->printer_types - && !STREQU(*(prbufp->printer_types), NAME_UNKNOWN) - && !prbufp->daisy - ) - for (pt = prbufp->printer_types; *pt; pt++) - if (tidbit(*pt, "csnm", &csnm) != -1 && csnm && *csnm) { - for (cs = 0; cs <= 63; cs++) - if ((name = tparm(csnm, cs)) && *name) { - - if (addcs) { - register char *nm = Malloc( - 2+2+1 + strlen(name) + 1 - ); - - sprintf (nm, "cs%d=%s", cs, name); - name = nm; - } - - if (addlist(&list, name) == -1) { - LP_ERRMSG (ERROR, E_LP_MALLOC); - done (1); - } - - } else - /* - * Assume that a break in the - * numbers means we're done. - */ - break; - } - - return (list); -} diff --git a/usr/src/cmd/lp/cmd/lpstat/class.c b/usr/src/cmd/lp/cmd/lpstat/class.c deleted file mode 100644 index c567d86971..0000000000 --- a/usr/src/cmd/lp/cmd/lpstat/class.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 1991 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - - -#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.5 */ - -#include <locale.h> -#include "stdio.h" - -#include "lp.h" -#include "class.h" - -#define WHO_AM_I I_AM_LPSTAT -#include "oam.h" - -#include "lpstat.h" - - -#if defined(__STDC__) -static void putcline ( CLASS * ); -#else -static void putcline(); -#endif - -/** - ** do_class() - **/ - -void -#if defined(__STDC__) -do_class ( - char ** list -) -#else -do_class (list) - char **list; -#endif -{ - register CLASS *pc; - - printlist_setup ("\t", 0, 0, 0); - while (*list) { - if (STREQU(NAME_ALL, *list)) - while ((pc = getclass(NAME_ALL))) - putcline (pc); - - else if ((pc = getclass(*list))) - putcline (pc); - - else { - LP_ERRMSG1 (ERROR, E_LP_NOCLASS, *list); - exit_rc = 1; - } - list++; - } - printlist_unsetup (); - return; -} - -/** - ** putcline() - **/ - -static void -#if defined(__STDC__) -putcline ( - CLASS * pc -) -#else -putcline (pc) - register CLASS *pc; -#endif -{ - (void) printf(gettext("members of class %s:\n"), pc->name); - printlist (stdout, pc->members); - return; -} diff --git a/usr/src/cmd/lp/cmd/lpstat/device.c b/usr/src/cmd/lp/cmd/lpstat/device.c deleted file mode 100644 index afc21c56a8..0000000000 --- a/usr/src/cmd/lp/cmd/lpstat/device.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 1991 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - - -#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.9 */ - -#include <locale.h> -#include "sys/types.h" -#include "string.h" - -#include "lp.h" -#include "printers.h" - -#define WHO_AM_I I_AM_LPSTAT -#include "oam.h" - -#include "lpstat.h" - - -#if defined(__STDC__) -static void putdline ( PRINTER * ); -#else -static void putdline(); -#endif - -/** - ** do_device() - **/ - -void -#if defined(__STDC__) -do_device ( - char ** list -) -#else -do_device (list) - char **list; -#endif -{ - register PRINTER *pp; - - - while (*list) { - if (STREQU(NAME_ALL, *list)) - while ((pp = getprinter(NAME_ALL))) - putdline (pp); - - else if ((pp = getprinter(*list))) - putdline (pp); - - else { - LP_ERRMSG1 (ERROR, E_LP_NOPRINTER, *list); - exit_rc = 1; - } - - list++; - } - return; -} - -/** - ** putdline() - **/ - -static void -#if defined(__STDC__) -putdline ( - PRINTER * pp -) -#else -putdline (pp) - register PRINTER *pp; -#endif -{ - if (!pp->device && !pp->dial_info && !pp->remote) { - LP_ERRMSG1 (ERROR, E_LP_PGONE, pp->name); - - } else if (pp->remote) { - char * cp = strchr(pp->remote, BANG_C); - - - if (cp) - *cp++ = 0; - (void)printf (gettext("system for %s: %s"), pp->name, pp->remote); - if (cp) - (void)printf (gettext(" (as printer %s)"), cp); - (void)printf ("\n"); - - } else if (pp->dial_info) { - (void)printf (gettext("dial token for %s: %s"), pp->name, pp->dial_info); - if (pp->device) - (void)printf (gettext(" (on port %s)"), pp->device); - (void)printf ("\n"); - - } else { - (void)printf (gettext("device for %s: %s"), pp->name, pp->device); -#if defined(CAN_DO_MODULES) - if (verbosity & V_MODULES) - if ( - emptylist(pp->modules) - || STREQU(NAME_NONE, pp->modules[0]) - ) - (void)printf (gettext(" (no modules)")); - else if (STREQU(NAME_KEEP, pp->modules[0])) - (void)printf (gettext(" (keep startup modules)")); - else if (STREQU(NAME_DEFAULT, pp->modules[0])) - (void)printf (gettext(" %s (default)"), DEFMODULES); - else { - (void)printf (" "); - printlist_setup ("", 0, ",", ""); - printlist (stdout, pp->modules); - printlist_unsetup (); - } -#endif - (void)printf ("\n"); - } - - return; -} diff --git a/usr/src/cmd/lp/cmd/lpstat/done.c b/usr/src/cmd/lp/cmd/lpstat/done.c deleted file mode 100644 index edbaffc42d..0000000000 --- a/usr/src/cmd/lp/cmd/lpstat/done.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - - -#ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.4 */ - -#include "lpstat.h" - -/** - ** done() - CLEAN UP AND EXIT - **/ - -void -#if defined(__STDC__) -done ( - int rc -) -#else -done (rc) - int rc; -#endif -{ - (void)mclose (); - - if (!rc && exit_rc) - exit (exit_rc); - else - exit (rc); -} diff --git a/usr/src/cmd/lp/cmd/lpstat/form.c b/usr/src/cmd/lp/cmd/lpstat/form.c deleted file mode 100644 index 60feda5eb5..0000000000 --- a/usr/src/cmd/lp/cmd/lpstat/form.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 1993 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - - -#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.9 */ - -#include <locale.h> -#include "stdio.h" - -#include "string.h" - -#include "lp.h" -#include "form.h" -#include "access.h" -#include "msgs.h" - -#define WHO_AM_I I_AM_LPSTAT -#include "oam.h" - -#include "lpstat.h" - -static void putfline ( FORM * ); - -/** - ** do_form() - **/ - -void -do_form(char **list) -{ - FORM form; - - while (*list) { - if (STREQU(NAME_ALL, *list)) - while (getform(NAME_ALL, &form, (FALERT *)0, (FILE **)0) != -1) - putfline (&form); - - else if (getform(*list, &form, (FALERT *)0, (FILE **)0) != -1) { - putfline (&form); - - } else { - LP_ERRMSG1 (ERROR, E_LP_NOFORM, *list); - exit_rc = 1; - } - - list++; - } - printsdn_unsetup (); - return; -} - -/** - ** putfline() - **/ - -static void -putfline(FORM *pf) -{ - register MOUNTED *pm; - - - (void) printf(gettext("form %s"), pf->name); - - (void) printf(gettext(" is %s to you"), - is_user_allowed_form(getname(), pf->name) ? - gettext( "available") : - gettext("not available")); - - for (pm = mounted_forms; pm->forward; pm = pm->forward) - if (STREQU(pm->name, pf->name)) { - if (pm->printers) { - (void) printf(gettext(", mounted on ")); - printlist_setup (0, 0, ",", ""); - printlist (stdout, pm->printers); - printlist_unsetup(); - } - break; - } - - (void) printf("\n"); - - if (verbosity & V_LONG) { - - printsdn_setup (gettext("\tPage length: "), 0, 0); - printsdn (stdout, pf->plen); - - printsdn_setup (gettext("\tPage width: "), 0, 0); - printsdn (stdout, pf->pwid); - - (void) printf(gettext("\tNumber of pages: %d\n"), pf->np); - - printsdn_setup (gettext("\tLine pitch: "), 0, 0); - printsdn (stdout, pf->lpi); - - (void) printf(gettext("\tCharacter pitch:")); - if (pf->cpi.val == N_COMPRESSED) - (void) printf(" %s\n", NAME_COMPRESSED); - else { - printsdn_setup (" ", 0, 0); - printsdn (stdout, pf->cpi); - } - - (void) printf(gettext("\tCharacter set choice: %s%s\n"), - (pf->chset? pf->chset : NAME_ANY), - (pf->mandatory ? ", mandatory" : "")); - - (void) printf(gettext("\tRibbon color: %s\n"), - (pf->rcolor? pf->rcolor : NAME_ANY)); - - if (pf->paper) - (void) printf(gettext("\tpaper: %s\n"), pf->paper); - - if (pf->comment) - (void) printf(gettext("\tComment:\n\t%s\n"), - pf->comment); - } - return; -} - -/** - ** do_paper() - **/ - -void -do_paper(char **list) -{ - while (*list) { - if (STREQU(NAME_ALL, *list)) { - send_message (S_PAPER_ALLOWED, ""); - (void)output(R_PAPER_ALLOWED); - } else { - send_message (S_PAPER_ALLOWED, *list); - switch (output(R_PAPER_ALLOWED)) { - case MNODEST: - LP_ERRMSG1 (ERROR, E_LP_NOPRINTER, *list); - exit_rc = 1; - break; - } - } - - list++; - } - printsdn_unsetup (); -} - -/** - ** putppline() - **/ - -void -putppline(char *printer, char *paperAllowed) -{ - char *ptr; - - ptr = paperAllowed; - while (ptr = strchr(ptr,' ')) { - *ptr = ','; - ptr++; - } - (void) printf(gettext("paper allowed for printer %s: %s\n"), printer, - paperAllowed); -} diff --git a/usr/src/cmd/lp/cmd/lpstat/lpstat.c b/usr/src/cmd/lp/cmd/lpstat/lpstat.c deleted file mode 100644 index 5a264904cb..0000000000 --- a/usr/src/cmd/lp/cmd/lpstat/lpstat.c +++ /dev/null @@ -1,244 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "stdio.h" -#include "errno.h" -#include "sys/types.h" -#include "signal.h" -#include "stdlib.h" - -#include "lp.h" -#include "msgs.h" -#include "printers.h" - -#define WHO_AM_I I_AM_LPSTAT -#include "oam.h" - -#include "lpstat.h" -#include <locale.h> - - -#ifdef SIGPOLL -static void -#else -static int -#endif -#if defined(__STDC__) - catch ( int ); -#else - catch(); -#endif - -#if defined(__STDC__) -static void mallocfail ( void ); -#else -static void mallocfail (); -#endif - -int exit_rc = 0, - inquire_type = INQ_UNKNOWN, - scheduler_active = 0, - r; /* Says -r was specified */ - -char *alllist[] = { - NAME_ALL, - 0 -}; - -/** - ** main() - **/ - -int -#if defined(__STDC__) -main ( - int argc, - char * argv[] -) -#else -main (argc, argv) - int argc; - char *argv[]; -#endif -{ - (void) setlocale (LC_ALL, ""); - -#if !defined(TEXT_DOMAIN) -#define TEXT_DOMAIN "SYS_TEST" -#endif - (void) textdomain(TEXT_DOMAIN); - - lp_alloc_fail_handler = mallocfail; - parse (argc, argv); - done (0); - /*NOTREACHED*/ - return (0); -} - -/** - ** def() - **/ - -void -#if defined(__STDC__) -def ( - void -) -#else -def () -#endif -{ - char *name; - - if ((name = getdefault())) - (void) printf(gettext("system default destination: %s\n"), name); - else - (void) printf(gettext("no system default destination\n")); - - return; -} - -/** - ** running() - **/ - -void -#if defined(__STDC__) -running ( - void -) -#else -running () -#endif -{ - (void) printf((scheduler_active ? gettext("scheduler is running\n") : - gettext("scheduler is not running\n"))); - return; -} - -/** - ** printer_configured() - **/ -int -printer_configured(void) -{ - long lastdir = -1; - char *name; - int nameisprinter; - - while ((name = next_dir(Lp_A_Printers, &lastdir)) != NULL) { - nameisprinter = isprinter(name); - Free(name); - if (nameisprinter) - return (1); - } - return (0); -} - -/** - ** startup() - **/ - -void -#if defined(__STDC__) -startup ( - void -) -#else -startup () -#endif -{ - int try; - - - if (signal(SIGHUP, SIG_IGN) != SIG_IGN) - (void)signal (SIGHUP, catch); - - if (signal(SIGINT, SIG_IGN) != SIG_IGN) - (void)signal (SIGINT, catch); - - if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) - (void)signal (SIGQUIT, catch); - - if (signal(SIGTERM, SIG_IGN) != SIG_IGN) - (void)signal (SIGTERM, catch); - - for (try = 1; try <= 5; try++) { - scheduler_active = (mopen() == 0); - if (scheduler_active || errno != ENOSPC) - break; - sleep (3); - } - - return; -} - -/** - ** catch() - **/ - -#ifdef SIGPOLL -static void -#else -static int -#endif -#if defined(__STDC__) -catch ( - int ignore -) -#else -catch (ignore) - int ignore; -#endif -{ - (void)signal (SIGHUP, SIG_IGN); - (void)signal (SIGINT, SIG_IGN); - (void)signal (SIGQUIT, SIG_IGN); - (void)signal (SIGTERM, SIG_IGN); - done (2); -} - -/** - ** mallocfail() - **/ - -static void -#if defined(__STDC__) -mallocfail ( - void -) -#else -mallocfail () -#endif -{ - LP_ERRMSG (ERROR, E_LP_MALLOC); - done (1); -} diff --git a/usr/src/cmd/lp/cmd/lpstat/lpstat.h b/usr/src/cmd/lp/cmd/lpstat/lpstat.h deleted file mode 100644 index b1d9a6d76f..0000000000 --- a/usr/src/cmd/lp/cmd/lpstat/lpstat.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ - - -#ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.7 */ - -#include <sys/types.h> -#include <time.h> - -#define DESTMAX 14 /* max length of destination name */ -#define SEQLEN 8 /* max length of sequence number */ -#define IDSIZE DESTMAX+SEQLEN+1 /* maximum length of request id */ -#define LOGMAX 15 /* maximum length of logname */ -#define OSIZE 7 -#define SZ_DATE_BUFF 100 /* size of conversion buff for dates */ - -#define INQ_UNKNOWN -1 -#define INQ_ACCEPT 0 -#define INQ_PRINTER 1 -#define INQ_STORE 2 -#define INQ_USER 3 - -#define V_LONG 0x0001 -#define V_BITS 0x0002 -#define V_RANK 0x0004 -#define V_MODULES 0x0008 - -#define BITPRINT(S,B) \ - if ((S)&(B)) { (void)printf("%s%s",sep,#B); sep = "|"; } - -typedef struct mounted { - char *name, - **printers; - struct mounted *forward; -} MOUNTED; - -void add_mounted ( char * , char * , char * ); -void def ( void ); -void do_accept ( char ** ); -void do_charset ( char ** ); -void do_class ( char ** ); -void do_device ( char ** ); -void do_form ( char ** ); -void do_paper ( char ** ); -void do_printer ( char ** ); -void do_request ( char ** ); -void do_user ( char ** ); -void done ( int ); -void parse ( int , char ** ); -void putoline(char *, char *, char *, long, time_t, int, char *, - char *, char *, int); -void putpline(char *, int, char *, time_t, char *, char *, char *); -void putqline(char *, int, time_t, char *); -void putppline ( char * , char *); -void running ( void ); -void send_message ( int , ... ); -void startup ( void ); - -int output ( int ); -int printer_configured ( void ); - -#if defined(_LP_PRINTERS_H) -char ** get_charsets ( PRINTER * , int ); -#endif - -extern int exit_rc; -extern int inquire_type; -extern int D; -extern int remote_cmd; -extern int scheduler_active; - -extern char *alllist[]; - -extern unsigned int verbosity; - -extern MOUNTED *mounted_forms; -extern MOUNTED *mounted_pwheels; diff --git a/usr/src/cmd/lp/cmd/lpstat/output.c b/usr/src/cmd/lp/cmd/lpstat/output.c deleted file mode 100644 index 1cf20519a3..0000000000 --- a/usr/src/cmd/lp/cmd/lpstat/output.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "stdio.h" -#include "errno.h" -#include "sys/types.h" - -#include "lp.h" -#include "printers.h" -#include "class.h" -#include "msgs.h" - -#define WHO_AM_I I_AM_LPSTAT -#include "oam.h" - -#include "lpstat.h" - -/* - * output() - RECEIVE MESSAGE BACK FROM SPOOLER, PRODUCE OUTPUT - */ - -int -output(int type) -{ - char buffer[MSGMAX]; - - int rc; - - char *class, - *user, - *slabel, - *reject_reason, - *request_id, - *printer, - *paperAllowed, - *form, - *file, - *character_set, - *disable_reason; - - short printer_status, - class_status, - state, - status, - rank = 0; - - long size, - enable_date, - reject_date, - date; - - - if (!scheduler_active) { - static int complained = 0; - - if (!complained) { - if (printer_configured()) { - LP_ERRMSG (ERROR, E_LP_NEEDSCHED); - exit_rc = 1; - } - complained = 1; - } - return (MOK); - } - - status = MOKMORE; - while (status == MOKMORE) { - - if ((rc = mrecv(buffer, MSGMAX)) != type) { - if (rc == -1 && errno == EIDRM) - LP_ERRMSG (ERROR, E_LP_MRECV); - else - LP_ERRMSG1 (ERROR, E_LP_BADREPLY, rc); - done (1); - } - - switch (type) { - - case R_PAPER_ALLOWED: - if (getmessage( - buffer, - R_PAPER_ALLOWED, - &status, - &printer, - &paperAllowed - ) == -1) { - LP_ERRMSG1 (ERROR, E_LP_GETMSG, PERROR); - done (1); - } - - switch (status) { - case MOK: - case MOKMORE: - putppline(printer, paperAllowed); - break; - - } - break; - - case R_INQUIRE_REQUEST: - if (getmessage( - buffer, - R_INQUIRE_REQUEST, - &status, - &request_id, - &user, - &slabel, - &size, - &date, - &state, - &printer, - &form, - &character_set, - &file) == -1) - { - LP_ERRMSG1 (ERROR, E_LP_GETMSG, PERROR); - done (1); - } - - switch (status) { - - case MOK: - case MOKMORE: - putoline(request_id, user, slabel, size, date, - state, printer, form, character_set, - ++rank); - break; - - } - break; - - case R_INQUIRE_REQUEST_RANK: - if (getmessage( - buffer, - R_INQUIRE_REQUEST_RANK, - &status, - &request_id, - &user, - &slabel, - &size, - &date, - &state, - &printer, - &form, - &character_set, - &rank, - &file) == -1) - { - LP_ERRMSG1 (ERROR, E_LP_GETMSG, PERROR); - done (1); - } - - switch (status) { - - case MOK: - case MOKMORE: - putoline(request_id, user, slabel, size, date, - state, printer, form, character_set, - rank); - break; - - } - break; - - case R_INQUIRE_PRINTER_STATUS: - if (getmessage( - buffer, - R_INQUIRE_PRINTER_STATUS, - &status, - &printer, - &form, - &character_set, - &disable_reason, - &reject_reason, - &printer_status, - &request_id, - &enable_date, - &reject_date) == -1) - { - LP_ERRMSG1 (ERROR, E_LP_GETMSG, PERROR); - done (1); - } - - switch (status) { - - case MOK: - case MOKMORE: - switch (inquire_type) { - case INQ_ACCEPT: - putqline(printer, - (printer_status & PS_REJECTED), - reject_date, reject_reason); - break; - - case INQ_PRINTER: - putpline(printer, printer_status, - request_id, enable_date, - disable_reason, form, - character_set); - break; - - case INQ_STORE: - add_mounted ( - printer, - form, - character_set); - break; - - } - break; - - } - break; - - case R_INQUIRE_CLASS: - if (getmessage( - buffer, - R_INQUIRE_CLASS, - &status, - &class, - &class_status, - &reject_reason, - &reject_date) == -1) - { - LP_ERRMSG1 (ERROR, E_LP_GETMSG, PERROR); - done (1); - } - - switch (status) { - - case MOK: - case MOKMORE: - switch (inquire_type) { - case INQ_ACCEPT: - putqline(class, - (class_status & CS_REJECTED), - reject_date, reject_reason); - break; - } - break; - - } - break; - } - } - - switch (status) { - - case MOK: - case MNOINFO: - case MNODEST: - case MUNKNOWN: - return (status); - - default: /* we are lost */ - LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status); - done(1); - - } - /*NOTREACHED*/ - return (0); -} diff --git a/usr/src/cmd/lp/cmd/lpstat/parse.c b/usr/src/cmd/lp/cmd/lpstat/parse.c deleted file mode 100644 index c408d844a9..0000000000 --- a/usr/src/cmd/lp/cmd/lpstat/parse.c +++ /dev/null @@ -1,379 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "string.h" -#include "sys/types.h" -#include "stdlib.h" - -#include "lp.h" -#include "printers.h" - -#define WHO_AM_I I_AM_LPSTAT -#include "oam.h" - -#include "lpstat.h" -#include <locale.h> - -typedef struct execute { - char *list; - void (*func)(); - int inquire_type; - struct execute *forward; -} EXECUTE; - -static int r = 0; -int D = 0, - remote_cmd = 0; - -unsigned int verbosity = 0; - -extern char *optarg; - -extern int getopt(), - optind, - opterr, - optopt; - - -static void usage ( void ); - -#if defined(CAN_DO_MODULES) -#define OPT_LIST "a:c:do:p:rstu:v:f:TDS:lLRHP:" -#else -#define OPT_LIST "a:c:do:p:rstu:v:f:TDS:lLRP:" -#endif - -#define QUEUE(LIST, FUNC, TYPE) \ - { \ - next->list = LIST; \ - next->func = FUNC; \ - next->inquire_type = TYPE; \ - next->forward = (EXECUTE *)Malloc(sizeof(EXECUTE)); \ - (next = next->forward)->forward = 0; \ - } - -/** - ** parse() - PARSE COMMAND LINE OPTIONS - **/ - -/* - * This routine parses the command line, builds a linked list of - * function calls desired, then executes them in the order they - * were received. This is necessary as we must apply -l to all - * options. So, we could either stash the calls away, or go - * through parsing twice. I chose to build the linked list. - */ - -void -parse(int argc, char **argv) -{ - int optsw; - int ac; - int need_mount = 0; - - char ** av; - char * p; - char ** list; - - EXECUTE linked_list; - - register EXECUTE * next = &linked_list; - - - next->forward = 0; - - /* - * Add a fake value to the end of the "argv" list, to - * catch the case that a valued-option comes last. - */ - av = (char **)Malloc((argc + 2) * sizeof(char *)); - for (ac = 0; ac < argc; ac++) - av[ac] = argv[ac]; - av[ac++] = "--"; - - opterr = 0; - - while ((optsw = getopt(ac, (char * const *)av, OPT_LIST)) != -1) { - - switch(optsw) { - - /* - * These option letters MAY take a value. Check the value; - * if it begins with a '-', assume it's really the next - * argument. - */ - case 'a': - case 'c': - case 'o': - case 'p': - case 'u': - case 'v': - case 'f': - case 'P': - case 'S': - if (*optarg == '-') { - /* - * This will work if we were given - * - * -x -foo - * - * but would fail if we were given - * - * -x-foo - */ - optind--; - optarg = NAME_ALL; - } - break; - } - - switch(optsw) { - case 'a': /* acceptance status */ - QUEUE (optarg, do_accept, INQ_ACCEPT); - break; - - case 'c': /* class to printer mapping */ - QUEUE (optarg, do_class, 0); - break; - - case 'd': /* default destination */ - QUEUE (0, def, 0); - break; - - case 'D': /* Description of printers */ - D = 1; - break; - - case 'f': /* do forms */ - QUEUE (optarg, do_form, 0); - need_mount = 1; - break; - - case 'P': /* do forms */ - QUEUE (optarg, do_paper, 0); - break; - -#if defined(CAN_DO_MODULES) - case 'H': /* show modules pushed for printer */ - verbosity |= V_MODULES; - break; -#endif - - case 'l': /* verbose output */ - verbosity |= V_LONG; - verbosity &= ~V_BITS; - break; - - case 'L': /* Local only */ - remote_cmd = 0; - break; - - case 'o': /* output for destinations */ - QUEUE (optarg, do_request, 0); - break; - - case 'p': /* printer status */ - QUEUE (optarg, do_printer, INQ_PRINTER); - break; - - case 'R': /* show rank in queue */ - verbosity |= V_RANK; - break; - - case 'r': /* is scheduler running? */ - QUEUE (0, running, 0); - r = 1; - break; - - case 's': /* configuration summary */ - QUEUE (0, running, 0); - QUEUE (0, def, 0); - QUEUE (NAME_ALL, do_class, 0); - QUEUE (NAME_ALL, do_device, 0); - QUEUE (NAME_ALL, do_form, 0); - QUEUE (NAME_ALL, do_charset, 0); - r = 1; - need_mount = 1; - break; - - case 'S': /* character set info */ - QUEUE (optarg, do_charset, 0); - need_mount = 1; - break; - - case 't': /* print all info */ - QUEUE (0, running, 0); - QUEUE (0, def, 0); - QUEUE (NAME_ALL, do_class, 0); - QUEUE (NAME_ALL, do_device, 0); - QUEUE (NAME_ALL, do_accept, INQ_ACCEPT); - QUEUE (NAME_ALL, do_printer, INQ_PRINTER); - QUEUE (NAME_ALL, do_form, 0); - QUEUE (NAME_ALL, do_charset, 0); - QUEUE (NAME_ALL, do_request, 0); - r = 1; - need_mount = 1; - break; - - case 'T': /* (trace) special debugging output */ - verbosity |= V_BITS; - verbosity &= ~V_LONG; - break; - - case 'u': /* output by user */ - QUEUE (optarg, do_user, INQ_USER); - break; - - case 'v': /* printers to devices mapping */ - QUEUE (optarg, do_device, 0); - break; - - default: - if (optopt == '?') { - usage (); - done (0); - } - - (p = "-X")[1] = optopt; - - if (strchr(OPT_LIST, optopt)) - LP_ERRMSG1 (ERROR, E_LP_OPTARG, p); - else - LP_ERRMSG1 (ERROR, E_LP_USAGE, p); - done(1); - break; - } - - } - -#ifdef NEVER - if (getenv("LPSTAT_NO_REMOTE")) - remote_cmd = 0; -#endif /* NEVER */ - - /* - * Note: "argc" here, not "ac", to skip our fake option. - * We could use either "argv" or "av", since for the range - * of interest they're the same. - */ - - list = 0; - while (optind < argc) - if (addlist(&list, av[optind++]) == -1) { - LP_ERRMSG (ERROR, E_LP_MALLOC); - done(1); - } - if (list) - QUEUE (sprintlist(list), do_request, 0); - - if (argc == 1 || (verbosity & V_RANK) && argc == 2) - QUEUE (getname(), do_user, INQ_USER); - - startup (); - - /* - Linked list is completed, load up mount info if - needed then do the requests - */ - - if (need_mount) { - inquire_type = INQ_STORE; - do_printer (alllist); - } - - for (next = &linked_list; next->forward; next = next->forward) { - inquire_type = next->inquire_type; - if (!next->list) - (*next->func) (); - else if (!*next->list) - (*next->func) (alllist); - else - (*next->func) (getlist(next->list, LP_WS, LP_SEP)); - } - - return; -} - -/** - ** usage() - PRINT USAGE MESSAGE - **/ - -static void -usage(void) -{ - -#if defined(CAN_DO_MODULES) - - (void) printf (gettext( -"usage:\n" -" lpstat [options] [request-ids]\n" -" [-a printers,classes] (show acceptance status)\n" -" [-c classes] (show available classes)\n" -" [-d] (show default destination)\n" -" [-D] (-p only: describe printers)\n" -" [-f forms] (show available forms)\n" -" [-l] (be verbose)\n" -" [-o printers,classes,req-ids] (show status of requests)\n" -" [-p printers] (show available printers)\n" -" [-P] (show paper types)\n" -" [-R] (show rank in queue)\n" -" [-r] (show status of Spooler)\n" -" [-s] (show summary status)\n" -" [-S char-sets,print-wheels] (show available \"fonts\")\n" -" [-t] (show status of everything)\n" -" [-u users] (show status of user requests)\n" -" [-v printers [-H]] (show devices used by printers)\n" -" (\"all\" allowed with -a,-c,-f,-o,-p,-S,-u,-v options)\n")); -#else - - (void) printf (gettext( -"usage:\n" -" lpstat [options] [request-ids]\n" -" [-a printers,classes] (show acceptance status)\n" -" [-c classes] (show available classes)\n" -" [-d] (show default destination)\n" -" [-D] (-p only: describe printers)\n" -" [-f forms] (show available forms)\n" -" [-l] (be verbose)\n" -" [-o printers,classes,req-ids] (show status of requests)\n" -" [-p printers] (show available printers)\n" -" [-P] (show paper types)\n" -" [-R] (show rank in queue)\n" -" [-r] (show status of Spooler)\n" -" [-s] (show summary status)\n" -" [-S char-sets,print-wheels] (show available \"fonts\")\n" -" [-t] (show status of everything)\n" -" [-u users] (show status of user requests)\n" -" [-v printers] (show devices used by printers)\n" -" (\"all\" allowed with -a,-c,-f,-o,-p,-S,-u,-v options)\n")); -#endif - return; -} diff --git a/usr/src/cmd/lp/cmd/lpstat/printer.c b/usr/src/cmd/lp/cmd/lpstat/printer.c deleted file mode 100644 index 5e83017193..0000000000 --- a/usr/src/cmd/lp/cmd/lpstat/printer.c +++ /dev/null @@ -1,555 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - - -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <locale.h> -#include "stdio.h" -#include "string.h" -#include "errno.h" -#include "sys/types.h" -#include "stdlib.h" - -#include "lp.h" -#include "printers.h" -#include "msgs.h" - -#define WHO_AM_I I_AM_LPSTAT -#include "oam.h" - -#include "lpstat.h" - -static void figure_pitch_size(char *, SCALED *, SCALED *, SCALED *, - SCALED *); -static void printallowdeny(FILE *, int, char **, char **); -static void printpwheels(PRINTER *, char *); -static void printsets(PRINTER *); -static int put_flt(char *printer, char *flt); - -#define USERS_AD 0 -#define FORMS_AD 1 - -/* - * do_printer() - */ - -void -do_printer(char **list) -{ - while (*list) { - if (STREQU(*list, NAME_ALL)) { - send_message(S_INQUIRE_PRINTER_STATUS, ""); - (void) output(R_INQUIRE_PRINTER_STATUS); - - } else { - send_message(S_INQUIRE_PRINTER_STATUS, *list); - switch (output(R_INQUIRE_PRINTER_STATUS)) { - case MNODEST: - LP_ERRMSG1(ERROR, E_LP_NOPRINTER, *list); - exit_rc = 1; - break; - } - } - list++; - } -} - -/* - * putpline() - DISPLAY STATUS OF PRINTER - */ - -void -putpline(char *printer, int printer_status, char *request_id, - time_t date, char *disable_reason, char *form, - char *character_set) -{ - register PRINTER *prbufp; - char **u_allow = 0, - **u_deny = 0, - **f_allow = 0, - **f_deny = 0, - **pt; - char enable_date[SZ_DATE_BUFF]; - int multi_type; - - if (!(prbufp = getprinter(printer))) { - LP_ERRMSG2(ERROR, E_LP_GETPRINTER, printer, PERROR); - done(1); - } - - (void) strftime(enable_date, sizeof (enable_date), NULL, - localtime(&date)); - - /* - * if (prbufp->login) - * printf(gettext(" (login terminal)")); - */ - - if (!(printer_status & (PS_DISABLED|PS_LATER))) { - if (printer_status & PS_FAULTED) { - if (printer_status & PS_BUSY) - printf(gettext( - "printer %s faulted printing %s."), - printer, request_id); - else - printf(gettext("printer %s faulted."), - printer); - } else if (printer_status & PS_BUSY) - printf(gettext("printer %s now printing %s."), - printer, request_id); - else - printf(gettext("printer %s is idle."), printer); - - printf(gettext(" enabled since %s."), enable_date); - - } else if (printer_status & PS_DISABLED) - printf(gettext("printer %s disabled since %s."), - printer, enable_date); - - else if (printer_status & PS_LATER) - printf(gettext("printer %s waiting for auto-retry."), printer); - - (void) load_userprinter_access(printer, &u_allow, &u_deny); - printf(is_user_allowed(getname(), u_allow, u_deny) ? - gettext(" available.\n") : gettext(" not available.\n")); - - if (printer_status & (PS_FAULTED | PS_DISABLED|PS_LATER)) { - if (strncmp("Warning: ", disable_reason, 9) == 0) { - if (! put_flt(printer, disable_reason)) - printf("\t%s\n", gettext(disable_reason)); - } - else - printf("\t%s\n", gettext(disable_reason)); - } - - if (D && !(verbosity & (V_LONG|V_BITS))) - printf(gettext("\tDescription: %s\n"), - NB(prbufp->description)); - - else if (verbosity & V_BITS) { - register char *sep = " "; - - BITPRINT(printer_status, PS_REJECTED); - BITPRINT(printer_status, PS_DISABLED); - BITPRINT(printer_status, PS_FAULTED); - BITPRINT(printer_status, PS_BUSY); - BITPRINT(printer_status, PS_LATER); - BITPRINT(printer_status, PS_REMOTE); - if (sep[0] == '|') - printf("\n"); - - } else if (verbosity & V_LONG) { - char *ptrForm, *ptrEndForm; - int trayNum; - - if (form && (ptrEndForm = strchr(form, *LP_SEP))) { - if (*(ptrEndForm+1)) { - printf(gettext("\tForms mounted:\n")); - ptrForm = form; - trayNum = 1; - while (ptrEndForm) { - *ptrEndForm = 0; - printf(gettext("\ttray %d: %s\n"), - trayNum++, ptrForm); - ptrForm = ptrEndForm+1; - ptrEndForm = strchr(ptrForm, *LP_SEP); - } - } else { - *ptrEndForm = 0; - printf(gettext("\tForm mounted: %s\n"), - NB(form)); - } - } else if (!prbufp->remote) - printf(gettext("\tForm mounted: %s\n"), NB(form)); - - printf(gettext("\tContent types:")); - if (prbufp->input_types) { - printlist_setup(" ", 0, ",", ""); - printlist(stdout, prbufp->input_types); - printlist_unsetup(); - } - printf("\n"); - - printf(gettext("\tPrinter types:")); - if (prbufp->printer_types) { - printlist_setup(" ", 0, ",", ""); - printlist(stdout, prbufp->printer_types); - printlist_unsetup(); - } else - printf(gettext(" (unknown)")); - printf("\n"); - - printf(gettext("\tDescription: %s\n"), NB(prbufp->description)); - - if (!prbufp->remote) - printf(gettext("\tConnection: %s\n"), - (prbufp->dial_info ? prbufp->dial_info : - gettext(NAME_DIRECT))); - - if (!prbufp->remote) - printf(gettext("\tInterface: %s\n"), - NB(prbufp->interface)); - - if (!prbufp->remote) { - if (prbufp->ppd != NULL) { - printf(gettext("\tPPD: %s\n"), NB(prbufp->ppd)); - } else { - printf(gettext("\tPPD: %s\n"), "none"); - } - } - - if (!prbufp->remote) { - if (is_user_admin()) { - printf("\t"); - printalert(stdout, &(prbufp->fault_alert), 1); - } - printf(gettext("\tAfter fault: %s\n"), - (prbufp->fault_rec ? prbufp->fault_rec : - gettext(NAME_CONTINUE))); - } - - (void) load_formprinter_access(printer, &f_allow, &f_deny); - printallowdeny(stdout, USERS_AD, u_allow, u_deny); - printallowdeny(stdout, FORMS_AD, f_allow, f_deny); - - switch (prbufp->banner) { - case BAN_ALWAYS: - printf(gettext("\tBanner required\n")); - break; - case BAN_OPTIONAL: - printf(gettext("\tBanner not required\n")); - break; - case BAN_NEVER: - printf(gettext("\tBanner page never printed\n")); - break; - } - - if (prbufp->daisy) { - printf(gettext("\tPrint wheels:\n")); - printpwheels(prbufp, character_set); - } else { - printf(gettext("\tCharacter sets:\n")); - printsets(prbufp); - } - - multi_type = (lenlist(prbufp->printer_types) > 1); - for (pt = prbufp->printer_types; *pt; pt++) { - - SCALED cpi; - SCALED lpi; - SCALED pwid; - SCALED plen; - - cpi = prbufp->cpi; - lpi = prbufp->lpi; - pwid = prbufp->pwid; - plen = prbufp->plen; - - figure_pitch_size (*pt, &cpi, &lpi, &pwid, &plen); - - if (multi_type) - printf(gettext("\tDefault pitch(%s):"), *pt); - else - printf(gettext("\tDefault pitch:")); - - if (cpi.val == N_COMPRESSED) - printf(" %s CPI", NAME_COMPRESSED); - else { - printsdn_setup(" ", gettext(" CPI"), ""); - printsdn(stdout, cpi); - } - printsdn_setup(" ", gettext(" LPI"), ""); - printsdn(stdout, lpi); - printf("\n"); - - if (multi_type) - printf(gettext("\tDefault page size(%s):"), - *pt); - else - printf(gettext("\tDefault page size:")); - - printsdn_setup(" ", gettext(" wide"), ""); - printsdn(stdout, pwid); - printsdn_setup(" ", gettext(" long"), ""); - printsdn(stdout, plen); - printf("\n"); - - printsdn_unsetup(); - } - - if (!prbufp->remote) - printf(gettext("\tDefault port settings: %s "), - NB(prbufp->stty)); - if (!prbufp->remote) { - if (prbufp->speed && prbufp->dial_info) - if (!STREQU(prbufp->dial_info, NAME_DIRECT)) - printf("%s", NB(prbufp->speed)); - printf("\n"); - } - - if (!prbufp->remote) { - if (prbufp->options) { - printf(gettext("\tOptions:")); - printlist_setup(" ", 0, ",", ""); - printlist(stdout, prbufp->options); - printlist_unsetup(); - printf("\n"); - } - } - - printf("\n"); - } -} - -/* - * figure_pitch_size() - CALCULATE *REAL* DEFAULT PITCH, PAGE SIZE - */ - -static void -figure_pitch_size(char *type, SCALED *cpi, SCALED *lpi, SCALED *pwid, - SCALED *plen) -{ - short orc, - orhi, - orl, - orvi, - cols, - lines; - - /* - * The user want's to know how the page will look if - * he or she uses this printer. Thus, if the administrator - * hasn't set any defaults, figure out what they are from - * the Terminfo entry. - */ - if (!type || STREQU(type, NAME_UNKNOWN)) - return; - - /* - * NOTE: We should never get a failure return unless - * someone has trashed the printer configuration file. - * Also, if we don't fail the first time, we can't fail - * subsequently. - */ - if (tidbit(type, "orc", &orc) == -1) - return; - (void) tidbit(type, "orhi", &orhi); - (void) tidbit(type, "orl", &orl); - (void) tidbit(type, "orvi", &orvi); - (void) tidbit(type, "cols", &cols); - (void) tidbit(type, "lines", &lines); - -#define COMPUTE(ORI, OR) \ - (ORI != -1 && OR != -1? (int)((ORI / (double)OR) + .5) : 0) - - if (cpi->val <= 0) { - cpi->val = (float)COMPUTE(orhi, orc); - cpi->sc = 0; - } - if (lpi->val <= 0) { - lpi->val = (float)COMPUTE(orvi, orl); - lpi->sc = 0; - } - if (pwid->val <= 0) { - pwid->val = (float)cols; - pwid->sc = 0; - } - if (plen->val <= 0) { - plen->val = (float)lines; - plen->sc = 0; - } - -} - -/* - * printallowdeny() - PRINT ALLOW/DENY LIST NICELY - */ - -static void -printallowdeny(FILE *fp, int type, char **allow, char **deny) -{ - - printlist_setup("\t\t", 0, 0, 0); - - if (allow || deny && !*deny || !deny) { - if (type == USERS_AD) - (void) fprintf(fp, gettext("\tUsers allowed:\n")); - else - (void) fprintf(fp, gettext("\tForms allowed:\n")); - if (allow && *allow) - printlist(fp, allow); - else if (allow && !*allow || !deny) - (void) fprintf(fp, gettext("\t\t(none)\n")); - else - (void) fprintf(fp, gettext("\t\t(all)\n")); - - } else { - if (type == USERS_AD) - (void) fprintf(fp, gettext("\tUsers denied:\n")); - else - (void) fprintf(fp, gettext("\tForms denied:\n")); - printlist(fp, deny); - - } - - printlist_unsetup(); -} - -/* - * printpwheels() - PRINT LIST OF PRINT WHEELS - */ - -static void -printpwheels(PRINTER *prbufp, char *pwheel) -{ - register char **list; - - register int mount_in_list = 0, - something_shown = 0; - - - if ((list = prbufp->char_sets)) - while (*list) { - printf("\t\t%s", *list); - if (pwheel && STREQU(*list, pwheel)) { - printf(gettext(" (mounted)")); - mount_in_list = 1; - } - printf("\n"); - list++; - something_shown = 1; - } - - if (!mount_in_list && pwheel && *pwheel) { - printf(gettext("\t\t%s (mounted)\n"), pwheel); - something_shown = 1; - } - - if (!something_shown) - printf(gettext("\t\t(none)\n")); -} - -/* - * printsets() - PRINT LIST OF CHARACTER SETS, WITH MAPPING - */ - -static void -printsets(PRINTER *prbufp) -{ - register char **alist = prbufp->char_sets, - *cp; - - char **tlist = 0; - - - /* - * We'll report the administrator defined character set aliases - * and any OTHER character sets we find in the Terminfo database. - */ - tlist = get_charsets(prbufp, 0); - - if ((!alist || !*alist) && (!tlist || !*tlist)) { - printf(gettext("\t\t(none)\n")); - return; - } - - if (alist) - while (*alist) { - cp = strchr(*alist, '='); - if (cp) - *cp++ = 0; - - /* - * Remove the alias from the Terminfo list so - * we don't report it twice. - */ - if (dellist(&tlist, *alist) == -1) { - LP_ERRMSG(ERROR, E_LP_MALLOC); - done(1); - } - - if (cp) - printf("\t\t%s (as %s)\n", cp, *alist); - else - printf("\t\t%s\n", *alist); - - alist++; - } - - if (tlist) - while (*tlist) - printf("\t\t%s\n", *tlist++); - -} - -/* - * if the msg is in the format: - * Warning: <printer> is down: <reason>\n - * break it up and reprint it out so we can do it in the users language. - */ -static int -put_flt(char *printer, char *flt) -{ - char *dup, *p; - - if ((dup = strdup(flt)) == NULL) - return (0); - - if (strtok(dup + 9, " ") == NULL) { /* start after "Warning: " */ - free(dup); - return (0); - } - - p = strtok(NULL, " "); - if (p == NULL || strcmp(p, "is") != 0) { - free(dup); - return (0); - } - - p = strtok(NULL, " "); - if (p == NULL || strcmp(p, "down:") != 0) { - free(dup); - return (0); - } - - p += 6; - if (*p == NULL) { - free(dup); - return (0); - } - - if (*(p + (strlen(p) - 1)) == '\n') - *(p + (strlen(p) - 1)) = 0; - putchar('\t'); - printf(gettext("Warning: %s is down: %s\n"), printer, gettext(p)); - - free(dup); - return (1); -} diff --git a/usr/src/cmd/lp/cmd/lpstat/request.c b/usr/src/cmd/lp/cmd/lpstat/request.c deleted file mode 100644 index 6ced71d4e1..0000000000 --- a/usr/src/cmd/lp/cmd/lpstat/request.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <locale.h> -#include "stdio.h" -#include "pwd.h" -#include "sys/types.h" - -#include "lp.h" -#include "strings.h" -#include "msgs.h" -#include "requests.h" - -#define WHO_AM_I I_AM_LPSTAT -#include "oam.h" - -#include "lpstat.h" - - -/* - * do_request() - */ - -void -do_request(char **list) -{ - while (*list) { - if (STREQU(NAME_ALL, *list)) { - if (remote_cmd || verbosity & V_RANK) { - send_message(S_INQUIRE_REQUEST_RANK, - (remote_cmd ? 2 : 1), - "", "", "", "", ""); - (void) output (R_INQUIRE_REQUEST_RANK); - } else { - send_message (S_INQUIRE_REQUEST, - "", "", "", "", ""); - (void) output (R_INQUIRE_REQUEST); - } - - } else if (isrequest(*list)) { - if (remote_cmd || verbosity & V_RANK) { - send_message (S_INQUIRE_REQUEST_RANK, - (remote_cmd ? 2 : 1), - "", "", *list, "", ""); - switch (output(R_INQUIRE_REQUEST_RANK)) { - case MNOINFO: - LP_ERRMSG1 (ERROR, - E_STAT_DONE, *list); - exit_rc = 1; - break; - } - } else { - send_message (S_INQUIRE_REQUEST, - "", "", *list, "", ""); - switch (output(R_INQUIRE_REQUEST)) { - case MNOINFO: - LP_ERRMSG1 (ERROR, - E_STAT_DONE, *list); - exit_rc = 1; - break; - } - } - - } else { - if (remote_cmd || verbosity & V_RANK) { - send_message(S_INQUIRE_REQUEST_RANK, - (remote_cmd ? 2 : 1), - "", *list, "", "", ""); - switch (output(R_INQUIRE_REQUEST_RANK)) { - case MNOINFO: - if (!isprinter(*list) && - !isclass(*list)) { - LP_ERRMSG1 (ERROR, - E_STAT_BADSTAT, *list); - exit_rc = 1; - } - break; - } - } else { - send_message (S_INQUIRE_REQUEST, - "", *list, "", "", ""); - switch (output(R_INQUIRE_REQUEST)) { - case MNOINFO: - if (!isprinter(*list) && - !isclass(*list)) { - LP_ERRMSG1 (ERROR, - E_STAT_BADSTAT, *list); - exit_rc = 1; - } - break; - } - } - - } - list++; - } - return; -} - -/* - * do_user() - */ - -static char *user_name = NULL; - -void -do_user(char **list) -{ - user_name = NULL; - - while (*list) { - if (STREQU(NAME_ALL, *list)) { - if (remote_cmd || verbosity & V_RANK) { - send_message (S_INQUIRE_REQUEST_RANK, - (remote_cmd ? 2 : 1), - "", "", "", "", ""); - (void) output (R_INQUIRE_REQUEST_RANK); - } else { - send_message (S_INQUIRE_REQUEST, - "", "", "", "", ""); - (void) output (R_INQUIRE_REQUEST); - } - } else { - user_name = *list; - if (remote_cmd || verbosity & V_RANK) { - send_message (S_INQUIRE_REQUEST_RANK, - (remote_cmd ? 2 : 1), - "", "", "", *list, ""); - switch (output(R_INQUIRE_REQUEST_RANK)) { - case MNOINFO: - if (!getpwnam(*list)) - LP_ERRMSG1 (WARNING, - E_STAT_USER, *list); - break; - } - } else { - send_message (S_INQUIRE_REQUEST, - "", "", "", *list, ""); - switch (output(R_INQUIRE_REQUEST)) { - case MNOINFO: - if (!getpwnam(*list)) - LP_ERRMSG1 (WARNING, - E_STAT_USER, *list); - break; - } - } - } - list++; - } - user_name = NULL; -} - - -/* - * putoline() - */ - -void -putoline(char *request_id, char *user, char *slabel, long size, time_t clock, - int state, char *printer, char *form, char *character_set, int rank) -{ - int showRank; - char user_buf[LOGMAX]; - char date[SZ_DATE_BUFF]; - - if ((slabel != NULL) && (slabel[0] != '\0')) - snprintf(user_buf, sizeof (user_buf), "%s:%s", user, slabel); - else - snprintf(user_buf, sizeof (user_buf), "%s", user); - - /* - * This is the basic time format used in the output. It represents - * all times of the form "Dec 11 11:04" seen in the output. - */ - (void) strftime(date, sizeof (date), "%b %d %R", localtime(&clock)); - if (user_name) - if (!strchr(user_name, '!')) { - char buf[512]; - - snprintf(buf, sizeof (buf), "all!%s", user_name); - if (!bangequ(buf, user)) - return; - } - else if (!bangequ(user_name, user)) - return; - - - showRank = (verbosity & V_RANK); - if (showRank) - (void) printf("%3d ", rank); - - (void) printf( - "%-*s %-*s %*ld %s%s", - ((showRank) ? IDSIZE - 2 : IDSIZE), - request_id, - LOGMAX-1, - user_buf, - OSIZE, - size, - ((showRank) ? "" : " "), - date); - - if (!(verbosity & (V_LONG|V_BITS))) { - - /* - * Unless the -l option is given, we show the CURRENT - * status. Check the status bits in reverse order of - * chronology, i.e. go with the bit that would have been - * set last. Old bits don't get cleared by the Spooler. - * We only have space for 21 characters! - */ - - if (state & RS_NOTIFYING) - (void) printf(gettext(" notifying user")); - - else if (state & RS_CANCELLED) - (void) printf(gettext(" canceled")); - - else if (state & RS_PRINTED) - (void) printf(gettext(" finished printing")); - - else if (state & RS_PRINTING) - (void) printf(gettext(" on %s"), printer); - - else if (state & RS_ADMINHELD) - (void) printf(gettext(" held by admin")); - - else if (state & RS_HELD) - (void) printf(gettext(" being held")); - - else if (state & RS_FILTERED) - (void) printf(gettext(" filtered")); - - else if (state & RS_FILTERING) - (void) printf(gettext(" being filtered")); - - else if (state & RS_CHANGING) - (void) printf(gettext(" held for change")); - - } else if (verbosity & V_BITS) { - register char *sep = "\n "; - - BITPRINT (state, RS_HELD); - BITPRINT (state, RS_FILTERING); - BITPRINT (state, RS_FILTERED); - BITPRINT (state, RS_PRINTING); - BITPRINT (state, RS_PRINTED); - BITPRINT (state, RS_CHANGING); - BITPRINT (state, RS_CANCELLED); - BITPRINT (state, RS_IMMEDIATE); - BITPRINT (state, RS_FAILED); - BITPRINT (state, RS_SENDING); - BITPRINT (state, RS_NOTIFY); - BITPRINT (state, RS_NOTIFYING); - BITPRINT (state, RS_SENT); - BITPRINT (state, RS_ADMINHELD); - BITPRINT (state, RS_REFILTER); - BITPRINT (state, RS_STOPPED); - - } else if (verbosity & V_LONG) { - /* - * Here we show all the interesting states the job - * has gone through. Left to right they are in - * chronological order. - */ - - if (state & RS_PRINTING) { - (void) printf(gettext("\n\ton %s"), printer); - } else if (state & RS_CANCELLED) { - (void) printf(gettext("\n\tcanceled")); - } else if (state & RS_FAILED) { - (void) printf(gettext("\n\tfailed")); - } else if (state & RS_PRINTED) { - (void) printf(gettext("\n\tfinished on %s"), printer); - /* - * WATCH IT! We make the request ID unusable after - * the next line. - */ - } else if (!STREQU(strtok(request_id, "-"), printer)) { - (void) printf(gettext("\n\tassigned %s"), printer); - } else { - if (state & RS_SENT) - (void)printf ( - gettext("\n\tqueued remotely for %s"), - printer); - else - (void)printf (gettext("\n\tqueued for %s"), - printer); - } - - if (!(state & RS_DONE)) { - if (form && *form) { - (void) printf(gettext(", form %s"), form); - } - if (character_set && *character_set) { - (void) printf(gettext(", charset %s"), - character_set); - } - } - - if (state & RS_NOTIFYING) { - (void) printf(gettext(", notifying user")); - } else if (state & RS_CHANGING) { - (void) printf(gettext(", held for change")); - } else if (state & RS_ADMINHELD) { - (void) printf(gettext(", held by admin")); - } else if (state & RS_HELD) { - (void) printf(gettext(", being held")); - } - - if (state & RS_FILTERED) { - (void) printf(gettext(", filtered")); - } else if (state & RS_FILTERING) { - (void) printf(gettext(", being filtered")); - } - } - (void) printf("\n"); - return; -} diff --git a/usr/src/cmd/lp/cmd/lpstat/send_message.c b/usr/src/cmd/lp/cmd/lpstat/send_message.c deleted file mode 100644 index e241825717..0000000000 --- a/usr/src/cmd/lp/cmd/lpstat/send_message.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - - -#ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.5 */ - -#include "stdio.h" - -#if defined(__STDC__) -#include "stdarg.h" -#else -#include "varargs.h" -#endif - -#include "msgs.h" - -#define WHO_AM_I I_AM_LPSTAT -#include "oam.h" - -#include "lpstat.h" - - -/** - ** send_message() - HANDLE MESSAGE SENDING TO SPOOLER - **/ - -/*VARARGS1*/ -void -#if defined(__STDC__) -send_message ( - int type, - ... -) -#else -send_message (type, va_alist) - int type; - va_dcl -#endif -{ - va_list ap; - - int n; - - char msgbuf[MSGMAX]; - - - if (!scheduler_active) - return; - -#if defined(__STDC__) - va_start (ap, type); -#else - va_start (ap); -#endif - - (void)_putmessage (msgbuf, type, ap); - - va_end (ap); - - if (msend(msgbuf) == -1) { - LP_ERRMSG (ERROR, E_LP_MSEND); - done(1); - } - - return; -} diff --git a/usr/src/cmd/lp/lib/access/Makefile b/usr/src/cmd/lp/lib/access/Makefile index 97c6801b34..7734b7a65f 100644 --- a/usr/src/cmd/lp/lib/access/Makefile +++ b/usr/src/cmd/lp/lib/access/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -19,8 +18,9 @@ # # CDDL HEADER END # + # -# Copyright 1990-2003 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -44,7 +44,7 @@ include ../../Makefile.lp # This library is not installed in the proto area. LIBS = $(LIBRARY) -CPPFLAGS = -I../../include $(CPPFLAGS.master) +CPPFLAGS = -I../../include $(CPPFLAGS.master) $(C_PICFLAGS) -D_TS_ERRNO POFILE = lp_lib_access.po diff --git a/usr/src/cmd/lp/lib/papi/Makefile b/usr/src/cmd/lp/lib/papi/Makefile index 72c7ff60a5..2f3d18a668 100644 --- a/usr/src/cmd/lp/lib/papi/Makefile +++ b/usr/src/cmd/lp/lib/papi/Makefile @@ -17,8 +17,6 @@ # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END - - # # # Copyright 2006 Sun Microsystems, Inc. All rights reserved. @@ -34,8 +32,8 @@ VERS=.1 LPSCHED_OBJS = lpsched-msgs.o lpsched-service.o lpsched-printers.o \ lpsched-jobs.o lpsched-misc.o -OBJECTS = $(LPSCHED_OBJS) \ - list.o attribute.o status.o service.o printer.o job.o +OBJECTS = $(LPSCHED_OBJS) service.o printer.o job.o ppd.o library.o + include ../../../../lib/Makefile.lib include ../../Makefile.lp @@ -44,7 +42,7 @@ ROOTLIBDIR= $(ROOT)/usr/lib/print CPPFLAGS = -I. CPPFLAGS += -I$(LPINC) -CPPFLAGS += -I$(SRC)/lib +CPPFLAGS += -I$(SRC)/lib/print/libpapi-common/common CPPFLAGS += -D_REENTRANT CPPFLAGS += $(ENVCPPFLAGS1) CPPFLAGS += $(ENVCPPFLAGS2) @@ -55,11 +53,12 @@ LDLIBS += -L$(SRC)/cmd/lp/lib/class -llpcls LDLIBS += -L$(SRC)/cmd/lp/lib/requests -llpreq LDLIBS += -L$(SRC)/cmd/lp/lib/secure -llpsec LDLIBS += -L$(SRC)/cmd/lp/lib/forms -llpfrm +LDLIBS += -L$(SRC)/cmd/lp/lib/access -llpacc LDLIBS += -L$(SRC)/cmd/lp/lib/lp -llp -MAPFILES= mapfile-vers +MAPFILES= mapfile MAPOPTS= $(MAPFILES:%=-M%) -DYNFLAGS += $(MAPOPTS) +DYNFLAGS += $(BDIRECT) $(MAPOPTS) LIBS = $(DYNLIB) diff --git a/usr/src/cmd/lp/lib/papi/job.c b/usr/src/cmd/lp/lib/papi/job.c index ff8aea70b7..776e6dee1c 100644 --- a/usr/src/cmd/lp/lib/papi/job.c +++ b/usr/src/cmd/lp/lib/papi/job.c @@ -35,11 +35,22 @@ #include <sys/stat.h> #include <papi_impl.h> + +/* + * for an older application that may have been linked with a pre-v1.0 + * PAPI implementation. + */ +papi_status_t +papiAttributeListAdd(papi_attribute_t ***attrs, int flags, char *name, + papi_attribute_value_type_t type, papi_attribute_value_t *value) +{ + return (papiAttributeListAddValue(attrs, flags, name, type, value)); +} + #ifdef LP_USE_PAPI_ATTR -static papi_status_t psm_modifyAttrsFile(const papi_attribute_t **attrs, - char *file); -static papi_status_t psm_modifyAttrsList(char *file, - const papi_attribute_t **attrs, papi_attribute_t ***newAttrs); +static papi_status_t psm_modifyAttrsFile(papi_attribute_t **attrs, char *file); +static papi_status_t psm_modifyAttrsList(char *file, papi_attribute_t **attrs, + papi_attribute_t ***newAttrs); #endif @@ -104,12 +115,6 @@ papiJobGetId(papi_job_t job) return (result); } -papi_job_ticket_t * -papiJobGetJobTicket(papi_job_t job) -{ - return (NULL); /* NOT SUPPORTED */ -} - static REQUEST * create_request(papi_service_t svc, char *printer, papi_attribute_t **attributes) { @@ -158,7 +163,7 @@ authorized(service_t *svc, int32_t id) } static papi_status_t -copy_file(const char *from, char *to) +copy_file(char *from, char *to) { int ifd, ofd; char buf[BUFSIZ]; @@ -199,23 +204,18 @@ copy_file(const char *from, char *to) */ static papi_status_t -psm_copy_attrsToFile(const papi_attribute_t **attrs, char *file) +psm_copy_attrsToFile(papi_attribute_t **attrs, char *file) { papi_status_t result = PAPI_OK; - FILE *out = NULL; - - if ((attrs != NULL) && (*attrs != NULL)) - { - out = fopen(file, "w"); - if (out != NULL) - { - papiAttributeListPrint( - out, "", (papi_attribute_t **)attrs); + + if ((attrs != NULL) && (*attrs != NULL)) { + FILE *out = NULL; + + if ((out = fopen(file, "w")) != NULL) { + papiAttributeListPrint(out, attrs, ""); fclose(out); - } - else - { + } else { result = PAPI_NOT_POSSIBLE; } } @@ -238,7 +238,7 @@ psm_copy_attrsToFile(const papi_attribute_t **attrs, char *file) */ static papi_status_t -psm_modifyAttrsFile(const papi_attribute_t **attrs, char *file) +psm_modifyAttrsFile(papi_attribute_t **attrs, char *file) { papi_status_t result = PAPI_OK; @@ -246,61 +246,46 @@ psm_modifyAttrsFile(const papi_attribute_t **attrs, char *file) struct stat tmpBuf; FILE *fd = NULL; - if ((attrs != NULL) && (*attrs != NULL) && (file != NULL)) - { + if ((attrs != NULL) && (*attrs != NULL) && (file != NULL)) { /* * check file exist before try to modify it, if it doesn't * exist assume there is an error */ - if (stat(file, &tmpBuf) == 0) - { + if (stat(file, &tmpBuf) == 0) { /* * if file is currently empty just write the given * attributes to the file otherwise exact the attributes * from the file and modify them accordingly before * writing them back to the file */ - if (tmpBuf.st_size == 0) - { -printf("psm_modifyAttrsFile() @1 - empty attribute file\n"); + if (tmpBuf.st_size == 0) { newAttrs = (papi_attribute_t **)attrs; fd = fopen(file, "w"); - if (fd != NULL) - { + if (fd != NULL) { papiAttributeListPrint(fd, - "", newAttrs); + newAttrs, ""); fclose(fd); - } - else - { + } else { result = PAPI_NOT_POSSIBLE; } - } - else - { -printf("psm_modifyAttrsFile() @2 - modify file\n"); + } else { result = psm_modifyAttrsList(file, attrs, &newAttrs); fd = fopen(file, "w"); - if (fd != NULL) - { + if (fd != NULL) { papiAttributeListPrint(fd, - "", newAttrs); + newAttrs, ""); fclose(fd); - } - else - { + } else { result = PAPI_NOT_POSSIBLE; } papiAttributeListFree(newAttrs); } - } - else - { + } else { result = PAPI_NOT_POSSIBLE; } } @@ -324,7 +309,7 @@ printf("psm_modifyAttrsFile() @2 - modify file\n"); */ static papi_status_t -psm_modifyAttrsList(char *file, const papi_attribute_t **attrs, +psm_modifyAttrsList(char *file, papi_attribute_t **attrs, papi_attribute_t ***newAttrs) { @@ -341,39 +326,30 @@ psm_modifyAttrsList(char *file, const papi_attribute_t **attrs, int n = 0; fd = fopen(file, "r"); - if (fd != NULL) - { + if (fd != NULL) { fD = fileno(fd); a = &aBuff[0]; p = &aBuff[0]; count = read(fD, &aBuff[0], sizeof (aBuff) - 1); - while ((result == PAPI_OK) && (count > 0)) - { + while ((result == PAPI_OK) && (count > 0)) { aBuff[count+n] = '\0'; - if (count == sizeof (aBuff) - n - 1) - { + if (count == sizeof (aBuff) - n - 1) { p = strrchr(aBuff, '\n'); - if (p != NULL) - { + if (p != NULL) { /* terminate at last complete line */ *p = '\0'; } } -printf("psm_modifyAttrsList() @3 - aBuff=\n"); -printf("%s\n", aBuff); result = papiAttributeListFromString( newAttrs, PAPI_ATTR_EXCL, aBuff); -printf("psm_modifyAttrsList() @4 - result=%d\n", result); - if (result == PAPI_OK) - { + if (result == PAPI_OK) { /* * handle any part lines and then read the next * buffer from the file */ n = 0; - if (p != a) - { + if (p != a) { p++; /* skip NL */ n = sizeof (aBuff) - 1 - (p - a); strncpy(aBuff, p, n); @@ -389,13 +365,11 @@ printf("psm_modifyAttrsList() @4 - result=%d\n", result); /* now modify the attribute list with the new attributes in 'attrs' */ nextAttr = papiAttributeListGetNext((papi_attribute_t **)attrs, &iter); - while ((result == PAPI_OK) && (nextAttr != NULL)) - { + while ((result == PAPI_OK) && (nextAttr != NULL)) { values = nextAttr->values; - if ((values != NULL) && (*values != NULL)) - { - result = papiAttributeListAdd(newAttrs, + if ((values != NULL) && (*values != NULL)) { + result = papiAttributeListAddValue(newAttrs, PAPI_ATTR_REPLACE, nextAttr->name, nextAttr->type, *values); @@ -403,9 +377,8 @@ printf("psm_modifyAttrsList() @4 - result=%d\n", result); } while ((result == PAPI_OK) && - (values != NULL) && (*values != NULL)) - { - result = papiAttributeListAdd(newAttrs, + (values != NULL) && (*values != NULL)) { + result = papiAttributeListAddValue(newAttrs, PAPI_ATTR_APPEND, nextAttr->name, nextAttr->type, *values); @@ -421,10 +394,10 @@ printf("psm_modifyAttrsList() @4 - result=%d\n", result); papi_status_t -papiJobSubmit(papi_service_t handle, const char *printer, - const papi_attribute_t **job_attributes, - const papi_job_ticket_t *job_ticket, - const char **files, papi_job_t *job) +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; @@ -526,10 +499,10 @@ papiJobSubmit(papi_service_t handle, const char *printer, } papi_status_t -papiJobSubmitByReference(papi_service_t handle, const char *printer, - const papi_attribute_t **job_attributes, - const papi_job_ticket_t *job_ticket, - const char **files, papi_job_t *job) +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; job_t *j; @@ -620,10 +593,10 @@ papiJobSubmitByReference(papi_service_t handle, const char *printer, } papi_status_t -papiJobValidate(papi_service_t handle, const char *printer, - const papi_attribute_t **job_attributes, - const papi_job_ticket_t *job_ticket, - const char **files, papi_job_t *job) +papiJobValidate(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; papi_attribute_t **attributes = NULL; @@ -635,7 +608,7 @@ papiJobValidate(papi_service_t handle, const char *printer, list_append(&attributes, job_attributes[i]); status = papiJobSubmitByReference(handle, printer, - (const papi_attribute_t **)attributes, + (papi_attribute_t **)attributes, job_ticket, files, job); if (status == PAPI_OK) { int id = papiJobGetId(*job); @@ -651,9 +624,9 @@ papiJobValidate(papi_service_t handle, const char *printer, } papi_status_t -papiJobStreamOpen(papi_service_t handle, const char *printer, - const papi_attribute_t **job_attributes, - const papi_job_ticket_t *job_ticket, papi_stream_t *stream) +papiJobStreamOpen(papi_service_t handle, char *printer, + papi_attribute_t **job_attributes, + papi_job_ticket_t *job_ticket, papi_stream_t *stream) { papi_status_t status; service_t *svc = handle; @@ -716,7 +689,7 @@ papiJobStreamOpen(papi_service_t handle, const char *printer, papi_status_t papiJobStreamWrite(papi_service_t handle, - papi_stream_t stream, const void *buffer, const size_t buflen) + papi_stream_t stream, void *buffer, size_t buflen) { service_t *svc = handle; job_stream_t *s = stream; @@ -769,8 +742,8 @@ papiJobStreamClose(papi_service_t handle, } papi_status_t -papiJobQuery(papi_service_t handle, const char *printer, const int32_t job_id, - const char **requested_attrs, +papiJobQuery(papi_service_t handle, char *printer, int32_t job_id, + char **requested_attrs, papi_job_t *job) { service_t *svc = handle; @@ -824,7 +797,51 @@ papiJobQuery(papi_service_t handle, const char *printer, const int32_t job_id, } papi_status_t -papiJobCancel(papi_service_t handle, const char *printer, const int32_t job_id) +papiJobMove(papi_service_t handle, char *printer, int32_t job_id, + char *destination) +{ + papi_status_t result = PAPI_OK; + 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) < 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; @@ -843,7 +860,8 @@ papiJobCancel(papi_service_t handle, const char *printer, const int32_t job_id) &user) == PAPI_OK) { REQUEST *r = getrequest(req_id); - if ((r != NULL) && (strcmp(r->user, user) != 0)) + if ((r != NULL) && (r->user != NULL) && + (strcmp(r->user, user) != 0)) result = PAPI_NOT_AUTHORIZED; freerequest(r); } @@ -862,8 +880,8 @@ papiJobCancel(papi_service_t handle, const char *printer, const int32_t job_id) } papi_status_t -hold_release_job(papi_service_t handle, const char *printer, - const int32_t job_id, int flag) +hold_release_job(papi_service_t handle, char *printer, + int32_t job_id, int flag) { papi_status_t status; service_t *svc = handle; @@ -884,16 +902,25 @@ hold_release_job(papi_service_t handle, const char *printer, if ((r = getrequest(file)) != NULL) { r->actions &= ~ACT_RESUME; - if (flag == 0) + switch (flag) { + case 0: r->actions |= ACT_HOLD; - else + 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)); @@ -901,34 +928,31 @@ hold_release_job(papi_service_t handle, const char *printer, } status = lpsched_end_change(svc, dest, job_id); - freerequest(r); - free(dest); return (status); } papi_status_t -papiJobHold(papi_service_t handle, const char *printer, const int32_t job_id, - const char *hold_until, const time_t *hold_until_time) +papiJobHold(papi_service_t handle, char *printer, int32_t job_id) { return (hold_release_job(handle, printer, job_id, 0)); } papi_status_t -papiJobRelease(papi_service_t handle, const char *printer, const int32_t job_id) +papiJobRelease(papi_service_t handle, char *printer, int32_t job_id) { return (hold_release_job(handle, printer, job_id, 1)); } papi_status_t -papiJobRestart(papi_service_t handle, const char *printer, const int32_t job_id) +papiJobPromote(papi_service_t handle, char *printer, int32_t job_id) { - return (PAPI_OPERATION_NOT_SUPPORTED); + return (hold_release_job(handle, printer, job_id, 2)); } papi_status_t -papiJobModify(papi_service_t handle, const char *printer, const int32_t job_id, - const papi_attribute_t **attributes, papi_job_t *job) +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; @@ -989,7 +1013,6 @@ papiJobModify(papi_service_t handle, const char *printer, const int32_t job_id, status = lpsched_end_change(svc, dest, job_id); lpsched_request_to_job_attributes(r, j); freerequest(r); - free(dest); return (status); } @@ -1000,9 +1023,9 @@ papiJobModify(papi_service_t handle, const char *printer, const int32_t job_id, #define DUMMY_FILE "/var/spool/lp/fifos/FIFO" papi_status_t -papiJobCreate(papi_service_t handle, const char *printer, - const papi_attribute_t **job_attributes, - const papi_job_ticket_t *job_ticket, papi_job_t *job) +papiJobCreate(papi_service_t handle, char *printer, + papi_attribute_t **job_attributes, + papi_job_ticket_t *job_ticket, papi_job_t *job) { papi_status_t status; service_t *svc = handle; @@ -1030,6 +1053,8 @@ papiJobCreate(papi_service_t handle, const char *printer, /* convert the attributes to an lpsched REQUEST structure */ request = create_request(svc, (char *)printer, (papi_attribute_t **)job_attributes); + if (request == NULL) + return (PAPI_TEMPORARY_ERROR); addlist(&request->file_list, DUMMY_FILE); /* add a dummy file */ request->actions |= ACT_HOLD; /* hold the job */ @@ -1046,12 +1071,14 @@ papiJobCreate(papi_service_t handle, const char *printer, if (status != PAPI_OK) { detailed_error(svc, "unable to copy attributes to file: %s: %s", metadata_file, strerror(errno)); + free(request_id); return (PAPI_DEVICE_ERROR); } #endif /* store the REQUEST on disk */ snprintf(metadata_file, sizeof (metadata_file), "%s-0", request_id); + free(request_id); if (putrequest(metadata_file, request) < 0) { detailed_error(svc, gettext("unable to save request: %s: %s"), metadata_file, strerror(errno)); @@ -1103,6 +1130,7 @@ papiJobCommit(papi_service_t handle, char *printer, int32_t id) detailed_error(svc, gettext("failed to write job: %s: %s"), metadata_file, strerror(errno)); + freerequest(r); return (PAPI_DEVICE_ERROR); } } else { @@ -1113,7 +1141,6 @@ papiJobCommit(papi_service_t handle, char *printer, int32_t id) status = lpsched_end_change(svc, dest, id); freerequest(r); - free(dest); return (status); } @@ -1173,7 +1200,6 @@ papiJobStreamAdd(papi_service_t handle, char *printer, int32_t id, } status = lpsched_end_change(svc, dest, id); - free(dest); if (status != PAPI_OK) return (status); diff --git a/usr/src/cmd/lp/lib/papi/library.c b/usr/src/cmd/lp/lib/papi/library.c new file mode 100644 index 0000000000..53c3a956a6 --- /dev/null +++ b/usr/src/cmd/lp/lib/papi/library.c @@ -0,0 +1,98 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/*LINTLIBRARY*/ + +#include <stdio.h> +#include <string.h> +#include <papi.h> + +static char *calls[] = { + /* Attribute Calls */ + "papiAttributeListAddValue", + "papiAttributeListAddBoolean", "papiAttributeListAddCollection", + "papiAttributeListAddDatetime", "papiAttributeListAddInteger", + "papiAttributeListAddMetadata", "papiAttributeListAddRange", + "papiAttributeListAddResolution", "papiAttributeListAddString", + "papiAttributeListDelete", + "papiAttributeListGetValue", "papiAttributeListGetNext", + "papiAttributeListFind", + "papiAttributeListGetBoolean", "papiAttributeListGetCollection", + "papiAttributeListGetDatetime", "papiAttributeListGetInteger", + "papiAttributeListGetMetadata", "papiAttributeListGetRange", + "papiAttributeListGetResolution", "papiAttributeListGetString", + "papiAttributeListFromString", "papiAttributeListToString", + "papiAttributeListFree", + /* Job Calls */ + "papiJobSubmit", "papiJobSubmitByReference", "papiJobValidate", + "papiJobStreamOpen", "papiJobStreamWrite", "papiJobStreamClose", + "papiJobQuery", "papiJobModify", "papiJobCancel", "papiJobPromote", + "papiJobGetAttributeList", "papiJobGetId", "papiJobGetPrinterName", + "papiJobFree", "papiJobListFree", + "papiJobHold", "papiJobRelease", + /* Printer Calls */ + "papiPrintersList", "papiPrinterQuery", "papiPrinterModify", + "papiPrinterAdd", "papiPrinterRemove", + "papiPrinterPause", "papiPrinterResume", + "papiPrinterDisable", "papiPrinterEnable", + "papiPrinterPurgeJobs", "papiPrinterListJobs", + "papiPrinterGetAttributeList", + "papiPrinterFree", "papiPrinterListFree", + /* Service Calls */ + "papiServiceCreate", "papiServiceDestroy", + "papiServiceGetAppData", + "papiServiceGetEncryption", "papiServiceGetPassword", + "papiServiceGetServiceName", "papiServiceGetUserName", + "papiServiceSetAppData", "papiServiceSetAuthCB", + "papiServiceSetEncryption", "papiServiceSetPassword", + "papiServiceSetUserName", + "papiServiceGetAttributeList", "papiServiceGetStatusMessage", + /* Misc Calls */ + "papiStatusString", + "papiLibrarySupportedCall", "papiLibrarySupportedCalls", + NULL +}; + +char ** +papiLibrarySupportedCalls() +{ + return (calls); +} + +char +papiLibrarySupportedCall(const char *name) +{ + int i; + + for (i = 0; calls[i] != NULL; i++) + if (strcmp(name, calls[i]) == 0) + return (PAPI_TRUE); + + return (PAPI_FALSE); +} diff --git a/usr/src/cmd/lp/lib/papi/lpsched-jobs.c b/usr/src/cmd/lp/lib/papi/lpsched-jobs.c index 225cc08dcf..a4fea773a5 100644 --- a/usr/src/cmd/lp/lib/papi/lpsched-jobs.c +++ b/usr/src/cmd/lp/lib/papi/lpsched-jobs.c @@ -44,14 +44,14 @@ papi_status_t job_attributes_to_lpsched_request(papi_service_t svc, REQUEST *r, papi_attribute_t **attributes) { + papi_status_t status = PAPI_OK; papi_attribute_t *attr; + papi_attribute_t **unmapped = NULL; int i; char *s; char **options = NULL; char **modes = NULL; - char *class = NULL; - char *job_name = NULL; char pr_filter = 0; char *pr_title = NULL; @@ -59,26 +59,36 @@ job_attributes_to_lpsched_request(papi_service_t svc, REQUEST *r, int pr_indent = -1; int numberUp = 0; int orientation = 0; - int lowerPage = 0; - int upperPage = 0; - papi_status_t getResult = 0; + int lower = 0; + int upper = 0; char buf[256]; void *iterator = NULL; - - char banner = 0; + char *mapped_keys[] = { "copies", "document-format", "form", + "job-class", "job-hold-until", "job-host", "job-name", + "job-originating-user-name", "job-printer", + "job-sheets", "lp-charset", "lp-modes", "number-up", + "orienttation-requested", "page-ranges", "pr-filter", + "pr-indent", "pr-title", "pr-width", "priority", + "requesting-user-name", NULL }; if (attributes == NULL) return (PAPI_BAD_ARGUMENT); - papiAttributeListGetString(attributes, NULL, "job-printer", - &r->destination); + /* replace the current destination */ + papiAttributeListGetLPString(attributes, + "job-printer", &r->destination); + /* set the copies. We need at least 1 */ i = r->copies; papiAttributeListGetInteger(attributes, NULL, "copies", &i); if (i <= 0) i = 1; r->copies = i; + /* + * set the priority. PAPI/IPP uses 1-100, lpsched use 0-39, so we + * have to convert it. + */ if (papiAttributeListGetInteger(attributes, NULL, "priority", &i) == PAPI_OK) { if ((i < 1) || (i > 100)) @@ -86,56 +96,41 @@ job_attributes_to_lpsched_request(papi_service_t svc, REQUEST *r, i = (i + 1) / 2.5; r->priority = i; } - if ((r->priority < 0) || (r->priority > 39)) r->priority = 20; - /* - * 'media' size should be processed both in the lpsched filter and - * the foomatic filter (if present) so that we ensure the result of - * other options like 'page-ranges' are consistent. - */ -/* - * TODO - I thing we should really have this but I can't get it to filter - * so its commented out for now (paulcun) - * papiAttributeListGetString(attributes, NULL, "media", &r->form); - */ + /* set the requested form to print on */ + papiAttributeListGetLPString(attributes, "form", &r->form); + /* set the page range */ #ifndef LP_USE_PAPI_ATTR - papiAttributeListGetString(attributes, NULL, "page-ranges", &r->pages); + papiAttributeListGetLPString(attributes, "page-ranges", &r->pages); #else - getResult = - papiAttributeListGetRange(attributes, &iterator, - "page-ranges", &lowerPage, &upperPage); - while (getResult == PAPI_OK) { - if (r->pages == NULL) { - snprintf(buf, sizeof (buf), - "%d-%d", lowerPage, upperPage); - r->pages = (char *)strdup(buf); - } - else - { + for (status = papiAttributeListGetRange(attributes, &iterator, + "page-ranges", &lower, &upper); + status == PAPI_OK; + status = papiAttributeListGetRange(attributes, &iterator, + "page-ranges", &lower, &upper)) { + if (r->pages != NULL) { snprintf(buf, sizeof (buf), "%s,%d-%d", - r->pages, lowerPage, upperPage); + r->pages, lower, upper); free(r->pages); - r->pages = (char *)strdup(buf); - } - /* - * get the next value; note the attribute 'name' is set to - * NULL to do this. - */ - getResult = - papiAttributeListGetRange(attributes, &iterator, - "page-ranges", &lowerPage, &upperPage); + } else + snprintf(buf, sizeof (buf), "%d-%d", lower, upper); + r->pages = (char *)strdup(buf); } #endif - + /* + * set the document format, converting to old format names as + * as needed. + */ s = NULL; papiAttributeListGetString(attributes, NULL, "document-format", &s); if (s != NULL) r->input_type = strdup(mime_type_to_lp_type(s)); + /* * If we don't have an owner, set one. */ @@ -165,6 +160,7 @@ job_attributes_to_lpsched_request(papi_service_t svc, REQUEST *r, r->user = strdup(user); } + /* set any held state */ s = NULL; papiAttributeListGetString(attributes, NULL, "job-hold-until", &s); if (s != NULL) { @@ -178,7 +174,8 @@ job_attributes_to_lpsched_request(papi_service_t svc, REQUEST *r, r->actions |= ACT_HOLD; } - papiAttributeListGetString(attributes, NULL, "lp-charset", &r->charset); + /* set lp charset/printwheel */ + papiAttributeListGetLPString(attributes, "lp-charset", &r->charset); /* legacy pr(1) filter related garbage "lpr -p" */ papiAttributeListGetBoolean(attributes, NULL, "pr-filter", &pr_filter); @@ -208,12 +205,16 @@ job_attributes_to_lpsched_request(papi_service_t svc, REQUEST *r, "pr(1) filter options specified without enabling pr(1) filter")); /* add burst page information */ - papiAttributeListGetBoolean(attributes, NULL, "job-sheets", &banner); - papiAttributeListGetString(attributes, NULL, "job-class", &class); - papiAttributeListGetString(attributes, NULL, "job-name", &job_name); - - { + s = NULL; + papiAttributeListGetString(attributes, NULL, "job-sheets", &s); + if ((s != NULL) && (strcasecmp(s, "none") == 0)) { char buf[128]; + char *class = NULL; + char *job_name = NULL; + + papiAttributeListGetLPString(attributes, "job-class", &class); + papiAttributeListGetLPString(attributes, "job-name", &job_name); + /* burst page is enabled by default, add the title */ snprintf(buf, sizeof (buf), "%s%s%s", (job_name ? job_name : ""), @@ -224,27 +225,9 @@ job_attributes_to_lpsched_request(papi_service_t svc, REQUEST *r, free(r->title); r->title = strdup(buf); } - } - if (banner == 0) /* burst page is disabled via lp "option" */ + } else /* burst page is disabled via lp "option" */ appendlist(&options, "nobanner"); - /* add "lp -o" options */ - attr = papiAttributeListFind(attributes, "lp-options"); - if ((attr != NULL) && (attr->type == PAPI_STRING) && - (attr->values != NULL)) { - int i; - - for (i = 0; attr->values[i] != NULL; i++) - appendlist(&options, attr->values[i]->string); - } - - if (options != NULL) { - if (r->options != NULL) - free(r->options); - r->options = sprintlist(options); - freelist(options); - } - /* Convert attribute "number-up" to mode group=n */ papiAttributeListGetInteger(attributes, NULL, "number-up", &numberUp); if ((numberUp >= 2) && ((numberUp % 2) == 0)) { @@ -260,45 +243,15 @@ job_attributes_to_lpsched_request(papi_service_t svc, REQUEST *r, "orientation-requested", &orientation); if ((orientation >= 3) && (orientation <= 6)) { switch (orientation) { - case 3: - { - /* 3 = portrait */ - appendlist(&modes, "portrait"); - break; - } - - case 4: - { - /* 4 = landscape */ - appendlist(&modes, "landscape"); - break; - } - - case 5: - { - /* - * 5 = reverse-landscape - not supported in - * lpsched so just use 'landscape' for now - */ - appendlist(&modes, "landscape"); - break; - } - - case 6: - { - /* - * 6 = reverse-portrait not supported in - * lpsched so just use 'portrait' for now - */ - appendlist(&modes, "portrait"); - break; - } - - default: - { - appendlist(&modes, "portrait"); - break; - } + case 4: /* landscape */ + case 5: /* reverse-landscape, use landscape instead */ + appendlist(&modes, "landscape"); + break; + case 3: /* portrait */ + case 6: /* reverse-portrait, use portrait instead */ + default: + appendlist(&modes, "portrait"); + break; } } @@ -319,6 +272,29 @@ job_attributes_to_lpsched_request(papi_service_t svc, REQUEST *r, freelist(modes); } + /* add any unconsumed attributes to the "options" list */ + split_and_copy_attributes(mapped_keys, attributes, NULL, &unmapped); + if (unmapped != NULL) { /* convert them to lp options */ + char *buf = malloc(1024); + ssize_t size = 1024; + + while (papiAttributeListToString(unmapped, ", ", buf, size) + != PAPI_OK) { + size += 1024; + buf = realloc(buf, size); + } + appendlist(&options, buf); + free(buf); + papiAttributeListFree(unmapped); + } + + if (options != NULL) { + if (r->options != NULL) + free(r->options); + r->options = sprintlist(options); + freelist(options); + } + return (PAPI_OK); } @@ -388,26 +364,16 @@ lpsched_request_to_job_attributes(REQUEST *r, job_t *j) "copies", r->copies); /* destination */ - addLPString(&j->attributes, PAPI_ATTR_REPLACE, "printer-name", - r->destination); - - /* file_list */ - addLPStrings(&j->attributes, PAPI_ATTR_REPLACE, - "lpsched-files", r->file_list); + papiAttributeListAddLPString(&j->attributes, PAPI_ATTR_REPLACE, + "printer-name", r->destination); /* form */ - addLPString(&j->attributes, PAPI_ATTR_REPLACE, "media", r->form); - - /* actions */ - papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE, - "lpsched-actions", r->actions); - - /* alert */ - addLPString(&j->attributes, PAPI_ATTR_REPLACE, "lp-alert", r->alert); + papiAttributeListAddLPString(&j->attributes, PAPI_ATTR_REPLACE, + "form", r->form); /* options */ - addLPString(&j->attributes, PAPI_ATTR_REPLACE, - "lp-options", r->options); + papiAttributeListFromString(&j->attributes, PAPI_ATTR_APPEND, + r->options); tmp = (((r->options != NULL) && (strstr(r->options, "nobanner") != NULL)) ? "none" : "standard"); @@ -429,33 +395,30 @@ lpsched_request_to_job_attributes(REQUEST *r, job_t *j) "job-priority", (int)((r->priority + 1) * 2.5)); /* pages */ - addLPString(&j->attributes, PAPI_ATTR_REPLACE, "page-ranges", r->pages); + papiAttributeListAddLPString(&j->attributes, PAPI_ATTR_REPLACE, + "page-ranges", r->pages); /* charset */ - addLPString(&j->attributes, PAPI_ATTR_REPLACE, "lp-charset", - r->charset); + papiAttributeListAddLPString(&j->attributes, PAPI_ATTR_REPLACE, + "lp-charset", r->charset); /* modes */ - addLPString(&j->attributes, PAPI_ATTR_REPLACE, "lp-modes", r->modes); + papiAttributeListAddLPString(&j->attributes, PAPI_ATTR_REPLACE, + "lp-modes", r->modes); /* title */ - addLPString(&j->attributes, PAPI_ATTR_REPLACE, "job-name", r->title); + papiAttributeListAddLPString(&j->attributes, PAPI_ATTR_REPLACE, + "job-name", r->title); /* input_type */ /* user */ - addLPString(&j->attributes, PAPI_ATTR_REPLACE, + papiAttributeListAddLPString(&j->attributes, PAPI_ATTR_REPLACE, "job-originating-user-name", r->user); /* outcome */ - papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE, - "lpsched-outcome", r->outcome); lpsched_request_outcome_to_attributes(&j->attributes, r->outcome); - /* version */ - papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE, - "lpsched-version", r->version); - /* constants, (should be derived from options) */ papiAttributeListAddInteger(&j->attributes, PAPI_ATTR_REPLACE, "number-up", 1); @@ -476,7 +439,7 @@ job_status_to_attributes(job_t *job, char *req_id, char *user, char *slabel, char buf[BUFSIZ]; char *p; - addLPString(&job->attributes, PAPI_ATTR_REPLACE, + papiAttributeListAddLPString(&job->attributes, PAPI_ATTR_REPLACE, "job-originating-user-name", user); papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE, "job-k-octets", size/1024); @@ -486,10 +449,12 @@ job_status_to_attributes(job_t *job, char *req_id, char *user, char *slabel, papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE, "job-id", atoi(++p)); } - snprintf(buf, sizeof (buf), "lpsched://%s/%d", destination, atoi(p)); + snprintf(buf, sizeof (buf), "lpsched://localhost/printers/%s/%d", + destination, atoi(p)); papiAttributeListAddString(&job->attributes, PAPI_ATTR_REPLACE, "job-uri", buf); - snprintf(buf, sizeof (buf), "lpsched://%s", destination); + snprintf(buf, sizeof (buf), "lpsched://localhost/printers/%s", + destination); papiAttributeListAddString(&job->attributes, PAPI_ATTR_REPLACE, "job-printer-uri", buf); papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE, @@ -498,25 +463,26 @@ job_status_to_attributes(job_t *job, char *req_id, char *user, char *slabel, "output-device-assigned", destination); papiAttributeListAddString(&job->attributes, PAPI_ATTR_REPLACE, "printer-name", destination); - addLPString(&job->attributes, PAPI_ATTR_REPLACE, "media", form); + papiAttributeListAddLPString(&job->attributes, PAPI_ATTR_REPLACE, + "form", form); lpsched_request_outcome_to_attributes(&job->attributes, state); papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE, "time-at-creation", date); - addLPString(&job->attributes, PAPI_ATTR_REPLACE, + papiAttributeListAddLPString(&job->attributes, PAPI_ATTR_REPLACE, "lpsched-request-id", req_id); - addLPString(&job->attributes, PAPI_ATTR_REPLACE, + papiAttributeListAddLPString(&job->attributes, PAPI_ATTR_REPLACE, "lp-charset", charset); papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE, "lpsched-job-state", state); papiAttributeListAddInteger(&job->attributes, PAPI_ATTR_REPLACE, "number-of-intervening-jobs", rank - 1); - addLPString(&job->attributes, PAPI_ATTR_REPLACE, + papiAttributeListAddLPString(&job->attributes, PAPI_ATTR_REPLACE, "lpsched-file", file); - addLPString(&job->attributes, PAPI_ATTR_EXCL, + papiAttributeListAddLPString(&job->attributes, PAPI_ATTR_EXCL, "job-name", file); - addLPString(&job->attributes, PAPI_ATTR_EXCL, + papiAttributeListAddLPString(&job->attributes, PAPI_ATTR_EXCL, "tsol-sensitivity-label", slabel); } diff --git a/usr/src/cmd/lp/lib/papi/lpsched-misc.c b/usr/src/cmd/lp/lib/papi/lpsched-misc.c index 0ed7895fbb..97047a8357 100644 --- a/usr/src/cmd/lp/lib/papi/lpsched-misc.c +++ b/usr/src/cmd/lp/lib/papi/lpsched-misc.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -36,7 +35,8 @@ papi_status_t -addLPString(papi_attribute_t ***list, int flags, char *name, char *value) +papiAttributeListAddLPString(papi_attribute_t ***list, int flags, char *name, + char *value) { papi_status_t result = PAPI_BAD_ARGUMENT; @@ -47,7 +47,7 @@ addLPString(papi_attribute_t ***list, int flags, char *name, char *value) } papi_status_t -addLPStrings(papi_attribute_t ***list, int flags, char *name, +papiAttributeListAddLPStrings(papi_attribute_t ***list, int flags, char *name, char **values) { papi_status_t result = PAPI_OK; @@ -64,8 +64,45 @@ addLPStrings(papi_attribute_t ***list, int flags, char *name, return (result); } +void +papiAttributeListGetLPString(papi_attribute_t **attributes, char *key, + char **string) +{ + char *value = NULL; + + papiAttributeListGetString(attributes, NULL, key, &value); + if (value != NULL) { + if (*string != NULL) + free(*string); + *string = strdup(value); + } +} + +void +papiAttributeListGetLPStrings(papi_attribute_t **attributes, char *key, + char ***strings) +{ + papi_status_t status; + char **values = NULL; + char *value = NULL; + void *iter = NULL; + + for (status = papiAttributeListGetString(attributes, &iter, + key, &value); + status == PAPI_OK; + status = papiAttributeListGetString(attributes, &iter, + NULL, &value)) + addlist(&values, value); + + if (values != NULL) { + if (*strings != NULL) + freelist(*strings); + *strings = values; + } +} + char * -printer_name_from_uri_id(const char *uri, int32_t id) +printer_name_from_uri_id(char *uri, int32_t id) { REQUEST *request = NULL; char *result = ""; diff --git a/usr/src/cmd/lp/lib/papi/lpsched-msgs.c b/usr/src/cmd/lp/lib/papi/lpsched-msgs.c index 7da01787da..5f5806276b 100644 --- a/usr/src/cmd/lp/lib/papi/lpsched-msgs.c +++ b/usr/src/cmd/lp/lib/papi/lpsched-msgs.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -33,12 +32,14 @@ #include <libintl.h> #include <string.h> #include <stdlib.h> +#include <errno.h> /* lpsched include files */ #include "lp.h" #include "msgs.h" #include "printers.h" +#include "class.h" #include <papi_impl.h> @@ -139,6 +140,8 @@ lpsched_status_to_papi_status(int status) return (PAPI_SERVICE_UNAVAILABLE); case M2LATE: return (PAPI_GONE); + case MBUSY: + return (PAPI_PRINTER_BUSY); case MOK: case MOKMORE: return (PAPI_OK); @@ -233,7 +236,7 @@ lpsched_commit_job(papi_service_t svc, char *job, char **tmp) } papi_status_t -lpsched_start_change(papi_service_t svc, const char *printer, int32_t job_id, +lpsched_start_change(papi_service_t svc, char *printer, int32_t job_id, char **tmp) { papi_status_t result = PAPI_OK; @@ -264,7 +267,7 @@ lpsched_start_change(papi_service_t svc, const char *printer, int32_t job_id, } papi_status_t -lpsched_end_change(papi_service_t svc, const char *printer, int32_t job_id) +lpsched_end_change(papi_service_t svc, char *printer, int32_t job_id) { papi_status_t result = PAPI_OK; short status = MOK; @@ -294,7 +297,62 @@ lpsched_end_change(papi_service_t svc, const char *printer, int32_t job_id) } papi_status_t -lpsched_enable_printer(papi_service_t svc, const char *printer) +lpsched_accept_printer(papi_service_t svc, char *printer) +{ + papi_status_t result = PAPI_OK; + short status; + char *req_id; + char *dest; + + if ((svc == NULL) || (printer == NULL)) + return (PAPI_BAD_ARGUMENT); + + dest = printer_name_from_uri_id(printer, -1); + if ((snd_msg(svc, S_ACCEPT_DEST, dest) < 0) || + (rcv_msg(svc, R_ACCEPT_DEST, &status, &req_id) < 0)) + status = MTRANSMITERR; + free(dest); + + if ((status != MOK) && (status != MERRDEST)) { + detailed_error(svc, "%s: %s", printer, + lpsched_status_string(status)); + result = lpsched_status_to_papi_status(status); + } + + return (result); +} + +papi_status_t +lpsched_reject_printer(papi_service_t svc, char *printer, char *message) +{ + papi_status_t result = PAPI_OK; + short status; + char *req_id; + char *dest; + + if ((svc == NULL) || (printer == NULL)) + return (PAPI_BAD_ARGUMENT); + + if (message == NULL) + message = "stopped by user"; + + dest = printer_name_from_uri_id(printer, -1); + if ((snd_msg(svc, S_REJECT_DEST, dest, message, 0) < 0) || + (rcv_msg(svc, R_REJECT_DEST, &status, &req_id) < 0)) + status = MTRANSMITERR; + free(dest); + + if ((status != MOK) && (status != MERRDEST)) { + detailed_error(svc, "%s: %s", printer, + lpsched_status_string(status)); + result = lpsched_status_to_papi_status(status); + } + + return (result); +} + +papi_status_t +lpsched_enable_printer(papi_service_t svc, char *printer) { papi_status_t result = PAPI_OK; short status; @@ -320,8 +378,7 @@ lpsched_enable_printer(papi_service_t svc, const char *printer) } papi_status_t -lpsched_disable_printer(papi_service_t svc, const char *printer, - const char *message) +lpsched_disable_printer(papi_service_t svc, char *printer, char *message) { papi_status_t result = PAPI_OK; short status; @@ -348,3 +405,216 @@ lpsched_disable_printer(papi_service_t svc, const char *printer, return (result); } + +papi_status_t +lpsched_load_unload_dest(papi_service_t handle, char *dest, int type) +{ + service_t *svc = handle; + papi_status_t result; + short status = MOK; + + /* tell the scheduler it's going */ + if (snd_msg(svc, type, dest, "", "") < 0) + return (PAPI_SERVICE_UNAVAILABLE); + + switch (type) { + case S_LOAD_PRINTER: + type = R_LOAD_PRINTER; + break; + case S_UNLOAD_PRINTER: + type = R_UNLOAD_PRINTER; + break; + case S_LOAD_CLASS: + type = R_LOAD_CLASS; + break; + case S_UNLOAD_CLASS: + type = R_UNLOAD_CLASS; + } + + if (rcv_msg(svc, type, &status) < 0) + return (PAPI_SERVICE_UNAVAILABLE); + + result = lpsched_status_to_papi_status(status); + + return (result); +} + +papi_status_t +lpsched_remove_class(papi_service_t handle, char *dest) +{ + papi_status_t result; + + /* tell the scheduler it's going */ + result = lpsched_load_unload_dest(handle, dest, S_UNLOAD_CLASS); + + if (result == PAPI_OK) { + /* remove the scheduler config files */ + if (delclass(dest) == -1) + result = PAPI_SERVICE_UNAVAILABLE; + } + + return (result); +} + +static void +remove_from_class(papi_service_t handle, char *dest, CLASS *cls) +{ + if (dellist(&cls->members, dest) == 0) { + if (cls->members != NULL) { + if (putclass(cls->name, cls) == 0) + (void) lpsched_load_unload_dest(handle, + cls->name, S_LOAD_CLASS); + } else + (void) lpsched_remove_class(handle, cls->name); + } +} + +papi_status_t +lpsched_remove_printer(papi_service_t handle, char *dest) +{ + + papi_status_t result; + + /* tell the scheduler it's going */ + result = lpsched_load_unload_dest(handle, dest, S_UNLOAD_PRINTER); + + if (result == PAPI_OK) { + CLASS *cls; + char *dflt; + + /* remove the scheduler config files */ + if (delprinter(dest) == -1) + return (PAPI_SERVICE_UNAVAILABLE); + + /* remove from any classes */ + while ((cls = getclass(NAME_ALL)) != NULL) + if (searchlist(dest, cls->members) != 0) + remove_from_class(handle, dest, cls); + + /* reset the default if it needs to be done */ + if (((dflt = getdefault()) != NULL) && + (strcmp(dflt, dest) == 0)) + putdefault(NAME_NONE); + } + + return (result); +} + +papi_status_t +lpsched_add_modify_class(papi_service_t handle, char *dest, + papi_attribute_t **attributes) +{ + papi_status_t result; + void *iter = NULL; + char **members = NULL; + char *member; + + /* + * The only attribute that we can modify for a class is the set of + * members. Anything else will be ignored. + */ + for (result = papiAttributeListGetString(attributes, &iter, + "member-names", &member); + result == PAPI_OK; + result = papiAttributeListGetString(attributes, &iter, + NULL, &member)) + addlist(&members, member); + + if (members != NULL) { + /* modify the configuration file */ + CLASS class; + + memset(&class, 0, sizeof (class)); + class.name = dest; + class.members = members; + + if (putclass(dest, &class) == -1) { + if ((errno == EPERM) || (errno == EACCES)) + result = PAPI_NOT_AUTHORIZED; + else + result = PAPI_NOT_POSSIBLE; + } else + result = PAPI_OK; + + freelist(members); + } else + result = PAPI_ATTRIBUTES; + + /* tell the scheduler about the changes */ + if (result == PAPI_OK) + result = lpsched_load_unload_dest(handle, dest, S_LOAD_CLASS); + + return (result); +} + +papi_status_t +lpsched_add_printer(papi_service_t handle, char *dest, + papi_attribute_t **attributes) +{ + PRINTER *p; + papi_status_t result = PAPI_TEMPORARY_ERROR; + + if ((p = calloc(1, sizeof (*p))) != NULL) { + p->name = strdup(dest); + p->banner = BAN_ALWAYS; + p->interface = strdup("/usr/lib/lp/model/uri"); + p->fault_alert.shcmd = strdup("mail"); + + attributes_to_printer(attributes, p); + + if (putprinter(dest, p) == -1) { + if ((errno == EPERM) || (errno == EACCES)) + result = PAPI_NOT_AUTHORIZED; + else + result = PAPI_NOT_POSSIBLE; + } else + result = PAPI_OK; + + freeprinter(p); + } + + /* tell the scheduler about the changes */ + if (result == PAPI_OK) + result = lpsched_load_unload_dest(handle, dest, S_LOAD_PRINTER); + + return (result); +} + +papi_status_t +lpsched_add_modify_printer(papi_service_t handle, char *dest, + papi_attribute_t **attributes, int type) +{ + PRINTER *p; + papi_status_t result; + + if (type == 0) { + if ((p = calloc(1, sizeof (*p))) != NULL) { + p->name = strdup(dest); + p->banner = BAN_ALWAYS; + p->interface = strdup("/usr/lib/lp/model/uri"); + p->fault_alert.shcmd = strdup("mail"); + } + } else + p = getprinter(dest); + + if (p != NULL) { + attributes_to_printer(attributes, p); + + if (putprinter(dest, p) == -1) { + if ((errno == EPERM) || (errno == EACCES)) + result = PAPI_NOT_AUTHORIZED; + else + result = PAPI_NOT_POSSIBLE; + } else + result = PAPI_OK; + + freeprinter(p); + } else + result = PAPI_NOT_POSSIBLE; + + /* tell the scheduler about the changes */ + if (result == PAPI_OK) + result = lpsched_load_unload_dest(handle, dest, S_LOAD_PRINTER); + + return (result); +} diff --git a/usr/src/cmd/lp/lib/papi/lpsched-printers.c b/usr/src/cmd/lp/lib/papi/lpsched-printers.c index d425c1bef7..408af31962 100644 --- a/usr/src/cmd/lp/lib/papi/lpsched-printers.c +++ b/usr/src/cmd/lp/lib/papi/lpsched-printers.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -31,12 +30,12 @@ #include <stdlib.h> #include <libintl.h> #include <unistd.h> +#include <string.h> #include <sys/utsname.h> #include <papi_impl.h> #include "class.h" - void lpsched_printer_status_to_attributes(papi_attribute_t ***attrs, unsigned short status) @@ -73,25 +72,9 @@ lpsched_printer_status_to_attributes(papi_attribute_t ***attrs, papiAttributeListAddBoolean(attrs, PAPI_ATTR_REPLACE, "printer-is-accepting-jobs", ((status & PS_REJECTED) != PS_REJECTED)); - papiAttributeListAddInteger(attrs, PAPI_ATTR_REPLACE, - "lpsched-status", status); papiAttributeListAddBoolean(attrs, PAPI_ATTR_REPLACE, "printer-is-processing-jobs", ((status & PS_DISABLED) != PS_DISABLED)); - papiAttributeListAddBoolean(attrs, PAPI_ATTR_REPLACE, - "lpsched-faulted", (status & PS_FAULTED)); - papiAttributeListAddBoolean(attrs, PAPI_ATTR_REPLACE, - "lpsched-busy", (status & PS_BUSY)); - papiAttributeListAddBoolean(attrs, PAPI_ATTR_REPLACE, - "lpsched-later", (status & PS_LATER)); - papiAttributeListAddBoolean(attrs, PAPI_ATTR_REPLACE, - "lpsched-remote", (status & PS_REMOTE)); - papiAttributeListAddBoolean(attrs, PAPI_ATTR_REPLACE, - "lpsched-show-fault", (status & PS_SHOW_FAULT)); - papiAttributeListAddBoolean(attrs, PAPI_ATTR_REPLACE, - "lpsched-use-as-key", (status & PS_USE_AS_KEY)); - papiAttributeListAddBoolean(attrs, PAPI_ATTR_REPLACE, - "lpsched-form-fault", (status & PS_FORM_FAULT)); } void @@ -113,12 +96,23 @@ lpsched_printer_defaults(papi_attribute_t ***attributes) "job-priority-default", 20); papiAttributeListAddRange(attributes, PAPI_ATTR_REPLACE, "copies-supported", 1, 65535); + papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE, + "copies-default", 1); papiAttributeListAddBoolean(attributes, PAPI_ATTR_REPLACE, "page-ranges-supported", PAPI_TRUE); papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE, "number-up-supported", 1); papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE, "number-up-default", 1); + papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE, + "job-hold-until-supported", "no-hold"); + papiAttributeListAddString(attributes, PAPI_ATTR_APPEND, + "job-hold-until-supported", "indefinite"); + papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE, + "job-hold-until-default", "no-hold"); + papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE, + "document-format-default", "application/octet-stream"); + } papi_status_t @@ -128,6 +122,7 @@ lpsched_printer_configuration_to_attributes(service_t *svc, printer_t *p, PRINTER *tmp; char buf[BUFSIZ+1]; struct utsname sysname; + char **allowed = NULL, **denied = NULL; if ((svc == NULL) || (p == NULL) || (dest == NULL)) return (PAPI_BAD_ARGUMENT); @@ -140,12 +135,13 @@ lpsched_printer_configuration_to_attributes(service_t *svc, printer_t *p, } /* name */ - addLPString(&p->attributes, PAPI_ATTR_REPLACE, + papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE, "printer-name", tmp->name); if (tmp->name != NULL) { char uri[BUFSIZ]; - snprintf(uri, sizeof (uri), "lpsched://%s", tmp->name); + snprintf(uri, sizeof (uri), "lpsched://localhost/printers/%s", + tmp->name); papiAttributeListAddString(&p->attributes, PAPI_ATTR_REPLACE, "printer-uri-supported", uri); } @@ -166,53 +162,53 @@ lpsched_printer_configuration_to_attributes(service_t *svc, printer_t *p, int i; for (i = 0; tmp->input_types[i] != NULL; i++) - addLPString(&p->attributes, + papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_APPEND, "document-format-supported", lp_type_to_mime_type(tmp->input_types[i])); } /* description */ - addLPString(&p->attributes, PAPI_ATTR_REPLACE, + papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE, "printer-info", tmp->description); /* add lpsched specific attributes */ - addLPString(&p->attributes, PAPI_ATTR_REPLACE, + papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE, "device-uri", tmp->device); - addLPString(&p->attributes, PAPI_ATTR_REPLACE, + papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE, "lpsched-dial-info", tmp->dial_info); - addLPString(&p->attributes, PAPI_ATTR_REPLACE, + papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE, "lpsched-fault-recovery", tmp->fault_rec); - addLPString(&p->attributes, PAPI_ATTR_REPLACE, + papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE, "lpsched-interface-script", tmp->interface); - addLPString(&p->attributes, PAPI_ATTR_REPLACE, + papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE, "lpsched-data-rate", tmp->speed); - addLPString(&p->attributes, PAPI_ATTR_REPLACE, + papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE, "lpsched-stty", tmp->stty); - addLPString(&p->attributes, PAPI_ATTR_REPLACE, - "lpsched-remote", tmp->remote); papiAttributeListAddBoolean(&p->attributes, PAPI_ATTR_REPLACE, "lpsched-login-term", tmp->login); papiAttributeListAddBoolean(&p->attributes, PAPI_ATTR_REPLACE, "lpsched-daisy", tmp->daisy); - addLPStrings(&p->attributes, PAPI_ATTR_REPLACE, + papiAttributeListAddLPStrings(&p->attributes, PAPI_ATTR_REPLACE, "lpsched-charsets", tmp->char_sets); #ifdef CAN_DO_MODULES - addLPStrings(&p->attributes, PAPI_ATTR_REPLACE, + papiAttributeListAddLPStrings(&p->attributes, PAPI_ATTR_REPLACE, "lpsched-modules", tmp->modules); #endif /* CAN_DO_MODULES */ - addLPStrings(&p->attributes, PAPI_ATTR_REPLACE, + papiAttributeListAddLPStrings(&p->attributes, PAPI_ATTR_REPLACE, "lpsched-options", tmp->options); - addLPStrings(&p->attributes, PAPI_ATTR_REPLACE, + papiAttributeListAddLPStrings(&p->attributes, PAPI_ATTR_REPLACE, "lpsched-printer-type", tmp->printer_types); - addLPString(&p->attributes, PAPI_ATTR_REPLACE, + if (tmp->fault_alert.shcmd != NULL) { + papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE, "lpsched-fault-alert-command", tmp->fault_alert.shcmd); - papiAttributeListAddInteger(&p->attributes, PAPI_ATTR_REPLACE, + papiAttributeListAddInteger(&p->attributes, PAPI_ATTR_REPLACE, "lpsched-fault-alert-threshold", tmp->fault_alert.Q); - papiAttributeListAddInteger(&p->attributes, PAPI_ATTR_REPLACE, + papiAttributeListAddInteger(&p->attributes, PAPI_ATTR_REPLACE, "lpsched-fault-alert-interval", tmp->fault_alert.W); + } papiAttributeListAddInteger(&p->attributes, PAPI_ATTR_REPLACE, "lpsched-cpi-value", tmp->cpi.val); papiAttributeListAddInteger(&p->attributes, PAPI_ATTR_REPLACE, @@ -229,6 +225,14 @@ lpsched_printer_configuration_to_attributes(service_t *svc, printer_t *p, "lpsched-pwid-value", tmp->pwid.val); papiAttributeListAddInteger(&p->attributes, PAPI_ATTR_REPLACE, "lpsched-pwid-unit", tmp->pwid.sc); + + /* allow/deny list */ + load_userprinter_access(dest, &allowed, &denied); + papiAttributeListAddLPStrings(&p->attributes, PAPI_ATTR_REPLACE, + "requesting-user-name-allowed", allowed); + papiAttributeListAddLPStrings(&p->attributes, PAPI_ATTR_REPLACE, + "requesting-user-name-denied", denied); + #ifdef LP_USE_PAPI_ATTR if (tmp->ppd != NULL) { int fd; @@ -242,12 +246,14 @@ lpsched_printer_configuration_to_attributes(service_t *svc, printer_t *p, snprintf(buf, sizeof (buf), "file://%s%s/ppd/%s.ppd", sysname.nodename, ETCDIR, tmp->name); papiAttributeListAddString(&p->attributes, PAPI_ATTR_REPLACE, - "lpsched-printer-ppd-uri", buf); + "ppd-file-uri", buf); snprintf(buf, sizeof (buf), "file://%s%s", sysname.nodename, tmp->ppd); papiAttributeListAddString(&p->attributes, PAPI_ATTR_REPLACE, "lpsched-printer-configure-ppd-uri", buf); + papiAttributeListAddString(&p->attributes, PAPI_ATTR_REPLACE, + "lpsched-ppd-source-path", tmp->ppd); snprintf(buf, sizeof (buf), "%s/ppd/%s.ppd", ETCDIR, tmp->name); @@ -255,56 +261,7 @@ lpsched_printer_configuration_to_attributes(service_t *svc, printer_t *p, * We don't return error on any of the error conditions, we just * silently return without adding the attribute. */ - if (((fd = open(buf, O_RDONLY)) >= 0) && - (fstat(fd, &sbuf) == 0)) { - char *contents; - - if ((contents = malloc(sbuf.st_size + 1)) != NULL) { - int pos = 0, rd, rdsize; - - rdsize = sbuf.st_blksize; - - while (rd = read(fd, contents + pos, rdsize)) { - if (rd < 0) { - if (errno == EINTR) { - continue; - } else { - break; - } - } - pos += rd; - - /* - * Don't write past the end of our - * buffer. This is paranoid, in case - * the file increased size while we were - * reading it. - */ - if (pos + rdsize > sbuf.st_size) { - rdsize = sbuf.st_size - pos; - } - } - - /* File didn't change size while reading. */ - if (pos + rd == sbuf.st_size) { - /* - * Terminate the buffer and set - * attribute. This assume that there - * are no null bytes in the ppd file. - */ - contents[pos + rd] = '\0'; - - papiAttributeListAddString( - &p->attributes, - PAPI_ATTR_REPLACE, - "lpsched-printer-ppd-contents", - contents); - } - - free(contents); - } - } - close(fd); + PPDFileToAttributesList(&p->attributes, buf); } #endif @@ -315,25 +272,25 @@ lpsched_printer_configuration_to_attributes(service_t *svc, printer_t *p, papi_status_t printer_status_to_attributes(printer_t *p, char *printer, char *form, - char *character_set, char *reject_reason, char *disable_reason, + char *character_set, char *disable_reason, char *reject_reason, short status, char *request_id, - long enable_date, long reject_date) + long disable_date, long reject_date) { if (p == NULL) return (PAPI_BAD_ARGUMENT); - addLPString(&p->attributes, PAPI_ATTR_REPLACE, - "media-ready", form); - addLPString(&p->attributes, PAPI_ATTR_REPLACE, + papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE, + "form-ready", form); + papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE, "lpsched-active-job", request_id); - addLPString(&p->attributes, PAPI_ATTR_REPLACE, + papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE, "lpsched-mounted-char-set", character_set); - addLPString(&p->attributes, PAPI_ATTR_REPLACE, - "printer-reject-reason", reject_reason); - addLPString(&p->attributes, PAPI_ATTR_REPLACE, - "printer-disable-reason", disable_reason); + papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE, + "lpsched-disable-reason", disable_reason); papiAttributeListAddDatetime(&p->attributes, PAPI_ATTR_REPLACE, - "lpsched-enable-date", enable_date); + "lpsched-disable-date", disable_date); + papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE, + "lpsched-reject-reason", reject_reason); papiAttributeListAddDatetime(&p->attributes, PAPI_ATTR_REPLACE, "lpsched-reject-date", reject_date); @@ -378,12 +335,13 @@ lpsched_class_configuration_to_attributes(service_t *svc, printer_t *p, } /* name */ - addLPString(&p->attributes, PAPI_ATTR_REPLACE, + papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE, "printer-name", tmp->name); if (tmp->name != NULL) { char uri[BUFSIZ]; - snprintf(uri, sizeof (uri), "lpsched://%s", tmp->name); + snprintf(uri, sizeof (uri), "lpsched://localhost/printers/%s", + tmp->name); papiAttributeListAddString(&p->attributes, PAPI_ATTR_REPLACE, "printer-uri-supported", uri); } @@ -410,8 +368,8 @@ class_status_to_attributes(printer_t *p, char *printer, short status, if (p == NULL) return (PAPI_BAD_ARGUMENT); - addLPString(&p->attributes, PAPI_ATTR_REPLACE, - "printer-reject-reason", reject_reason); + papiAttributeListAddLPString(&p->attributes, PAPI_ATTR_REPLACE, + "lpsched-reject-reason", reject_reason); papiAttributeListAddDatetime(&p->attributes, PAPI_ATTR_REPLACE, "lpsched-reject-date", reject_date); @@ -432,3 +390,70 @@ class_status_to_attributes(printer_t *p, char *printer, short status, return (PAPI_OK); } + +papi_status_t +attributes_to_printer(papi_attribute_t **attributes, PRINTER *tmp) +{ + papi_status_t status; + void *iter = NULL; + char *string = NULL; + int flags; + char **list = NULL; + + /* banner needs some conversion to the bitfield */ + iter = NULL, string = NULL; flags = 0; + for (status = papiAttributeListGetString(attributes, &iter, + "job-sheets-supported", &string); + status == PAPI_OK; + status = papiAttributeListGetString(attributes, &iter, + NULL, &string)) + if (strcasecmp(string, "none") == 0) + flags |= BAN_NEVER; + else if (strcasecmp(string, "standard") == 0) + flags |= BAN_ALWAYS; + if (flags != 0) + tmp->banner = flags; + + /* input_types needs mime-type conversion */ + iter = NULL, string = NULL; list = NULL; + for (status = papiAttributeListGetString(attributes, &iter, + "document-format-supported", &string); + status == PAPI_OK; + status = papiAttributeListGetString(attributes, &iter, + NULL, &string)) + addlist(&list, mime_type_to_lp_type(string)); + if (list != NULL) { + if (tmp->input_types != NULL) + freelist(tmp->input_types); + tmp->input_types = list; + } + + papiAttributeListGetLPString(attributes, + "device-uri", &tmp->device); + papiAttributeListGetLPString(attributes, + "printer-info", &tmp->description); + papiAttributeListGetLPString(attributes, + "lpsched-dial-info", &tmp->dial_info); + papiAttributeListGetLPString(attributes, + "lpsched-fault-recovery", &tmp->fault_rec); + papiAttributeListGetLPString(attributes, + "lpsched-interface-script", &tmp->interface); + papiAttributeListGetLPString(attributes, + "lpsched-data-rate", &tmp->speed); + papiAttributeListGetLPString(attributes, + "lpsched-stty", &tmp->stty); + papiAttributeListGetLPStrings(attributes, + "lpsched-charsets", &tmp->char_sets); + papiAttributeListGetLPStrings(attributes, + "lpsched-printer-types", &tmp->printer_types); + papiAttributeListGetLPStrings(attributes, + "lpsched-options", &tmp->options); + papiAttributeListGetLPStrings(attributes, + "lpsched-modules", &tmp->modules); +#ifdef LP_USE_PAPI_ATTR + papiAttributeListGetLPString(attributes, + "lpsched-printer-ppd-uri", &tmp->ppd); +#endif + + return (PAPI_OK); +} diff --git a/usr/src/cmd/lp/lib/papi/lpsched-service.c b/usr/src/cmd/lp/lib/papi/lpsched-service.c index 8b6d6b944b..33f0082944 100644 --- a/usr/src/cmd/lp/lib/papi/lpsched-service.c +++ b/usr/src/cmd/lp/lib/papi/lpsched-service.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -36,13 +35,13 @@ void -lpsched_service_information(printer_t *p) +lpsched_service_information(papi_attribute_t ***attrs) { FORM form; while (getform(NAME_ALL, &form, (FALERT *)0, (FILE **)0) != -1) { - papiAttributeListAddString(&p->attributes, PAPI_ATTR_APPEND, - "media-supported", form.name); + papiAttributeListAddString(attrs, PAPI_ATTR_APPEND, + "form-supported", form.name); freeform(&form); } } diff --git a/usr/src/cmd/lp/lib/papi/mapfile b/usr/src/cmd/lp/lib/papi/mapfile new file mode 100644 index 0000000000..a10fae2acf --- /dev/null +++ b/usr/src/cmd/lp/lib/papi/mapfile @@ -0,0 +1,151 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# Generic interface definition for usr/src/cmd/lp/lib/papi +# +# For information regarding the establishment of versioned definitions see: +# The Linker and Libraries Manual (version 2.5 or greater) +# This is part of the Developers Guide in the Answerbook. Specifically refer +# to Chapter 2 under section "Defining Additional Symbols" through section +# "Reducing Symbol Scope", and Chapter 5 "Versioning". +# +# For specific OSNET rules for the modification (evolution) of these version +# definitions see: +# Policy for Shared Library Version Names and Interface Definitions + +SUNW_1.0 { + global: + # PAPI Attribute Calls + papiAttributeListAdd; + papiAttributeListAddValue = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddBoolean = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddCollection = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddDatetime = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddInteger = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddMetadata = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddRange = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddResolution = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddString = FUNCTION FILTER libpapi-common.so ; + papiAttributeListDelete = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetValue = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetNext = FUNCTION FILTER libpapi-common.so ; + papiAttributeListFind = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetBoolean = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetCollection = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetDatetime = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetInteger = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetMetadata = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetRange = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetResolution = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetString = FUNCTION FILTER libpapi-common.so ; + papiAttributeListFromString = FUNCTION FILTER libpapi-common.so ; + papiAttributeListToString = FUNCTION FILTER libpapi-common.so ; + papiAttributeListFree = FUNCTION FILTER libpapi-common.so ; + + # PAPI Service Calls + papiServiceCreate; + papiServiceDestroy; + papiServiceSetUserName; + papiServiceSetPassword; + papiServiceSetEncryption; + papiServiceSetAuthCB; + papiServiceSetAppData; + papiServiceGetUserName; + papiServiceGetPassword; + papiServiceGetEncryption; + papiServiceGetAppData; + papiServiceGetServiceName; + papiServiceGetAttributeList; + papiServiceGetStatusMessage; + + # PAPI Printer Calls + papiPrintersList; + papiPrinterQuery; + papiPrinterAdd; + papiPrinterModify; + papiPrinterRemove; + papiPrinterDisable; + papiPrinterEnable; + papiPrinterPause; + papiPrinterResume; + papiPrinterPurgeJobs; + papiPrinterListJobs; + papiPrinterGetAttributeList; + papiPrinterFree; + papiPrinterListFree; + + # PAPI Job Calls + papiJobSubmit; + papiJobSubmitByReference; + papiJobValidate; + papiJobStreamOpen; + papiJobStreamWrite; + papiJobStreamClose; + papiJobQuery; + papiJobModify; + papiJobMove; + papiJobCancel; + papiJobHold; + papiJobRelease; + papiJobRestart = FUNCTION FILTER libpapi-common.so ; + papiJobPromote; + papiJobGetAttributeList; + papiJobGetPrinterName; + papiJobGetId; + papiJobGetJobTicket = FUNCTION FILTER libpapi-common.so ; + papiJobFree; + papiJobListFree; + + # Misc. PAPI Calls + papiStatusString = FUNCTION FILTER libpapi-common.so ; + papiLibrarySupportedCall; + papiLibrarySupportedCalls; +}; + +SUNWprivate_1.0 { + global: + papiServiceSetPeer; # used by to pass peer connection + papiJobCreate; + papiJobStreamAdd; + papiJobCommit; + + # Misc. supporting calls + # URI + uri_from_string = FUNCTION FILTER libpapi-common.so ; + uri_to_string = FUNCTION FILTER libpapi-common.so ; + uri_free = FUNCTION FILTER libpapi-common.so ; + # list + list_remove = FUNCTION FILTER libpapi-common.so ; + list_append = FUNCTION FILTER libpapi-common.so ; + list_concatenate = FUNCTION FILTER libpapi-common.so ; + + # extra Attribute Calls + copy_attributes = FUNCTION FILTER libpapi-common.so ; + split_and_copy_attributes = FUNCTION FILTER libpapi-common.so ; + papiAttributeListPrint = FUNCTION FILTER libpapi-common.so ; + + local: + *; +}; diff --git a/usr/src/cmd/lp/lib/papi/mapfile-vers b/usr/src/cmd/lp/lib/papi/mapfile-vers deleted file mode 100644 index 2bddef28d0..0000000000 --- a/usr/src/cmd/lp/lib/papi/mapfile-vers +++ /dev/null @@ -1,125 +0,0 @@ -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Generic interface definition for usr/src/cmd/lp/lib/papi -# -# For information regarding the establishment of versioned definitions see: -# The Linker and Libraries Manual (version 2.5 or greater) -# This is part of the Developers Guide in the Answerbook. Specifically refer -# to Chapter 2 under section "Defining Additional Symbols" through section -# "Reducing Symbol Scope", and Chapter 5 "Versioning". -# -# For specific OSNET rules for the modification (evolution) of these version -# definitions see: -# Policy for Shared Library Version Names and Interface Definitions - - -SUNWprivate_1.1 { - global: - - papiAttributeListAdd; - papiAttributeListAddString; - papiAttributeListAddInteger; - papiAttributeListAddBoolean; - papiAttributeListAddRange; - papiAttributeListAddResolution; - papiAttributeListAddDatetime; - papiAttributeListAddCollection; - papiAttributeListDelete; - papiAttributeListGetValue; - papiAttributeListGetString; - papiAttributeListGetInteger; - papiAttributeListGetBoolean; - papiAttributeListGetRange; - papiAttributeListGetResolution; - papiAttributeListGetDatetime; - papiAttributeListGetCollection; - papiAttributeListFree; - papiAttributeListFind; - papiAttributeListGetNext; - papiAttributeListFromString; - papiAttributeListToString; - - papiServiceCreate; - papiServiceDestroy; - papiServiceSetPeer; # used by to pass peer connection - papiServiceSetUserName; - papiServiceSetPassword; - papiServiceSetEncryption; - papiServiceSetAuthCB; - papiServiceSetAppData; - papiServiceGetUserName; - papiServiceGetPassword; - papiServiceGetEncryption; - papiServiceGetAppData; - papiServiceGetServiceName; - papiServiceGetStatusMessage; - - papiPrintersList; - papiPrinterQuery; - papiPrinterModify; - papiPrinterPause; - papiPrinterResume; - papiPrinterPurgeJobs; - papiPrinterListJobs; - papiPrinterGetAttributeList; - papiPrinterFree; - papiPrinterListFree; - - papiJobSubmit; - papiJobSubmitByReference; - papiJobValidate; - papiJobStreamOpen; - papiJobStreamWrite; - papiJobStreamClose; - papiJobQuery; - papiJobModify; - papiJobCancel; - papiJobHold; - papiJobRelease; - papiJobRestart; - papiJobGetAttributeList; - papiJobGetPrinterName; - papiJobGetId; - papiJobGetJobTicket; - papiJobFree; - papiJobListFree; - - papiStatusString; - #papiLibrarySupportedCalls; - #papiLibrarySupportedCall; - - papiAttributeListPrint; - list_append; - - papiJobCreate; - papiJobStreamAdd; - papiJobCommit; - - local: - *; -}; - diff --git a/usr/src/cmd/lp/lib/papi/papi_impl.h b/usr/src/cmd/lp/lib/papi/papi_impl.h index d2359f4e73..5d13df73ee 100644 --- a/usr/src/cmd/lp/lib/papi/papi_impl.h +++ b/usr/src/cmd/lp/lib/papi/papi_impl.h @@ -54,7 +54,7 @@ extern "C" { typedef struct { papi_attribute_t **attributes; - int (*authCB)(papi_service_t svc); + int (*authCB)(papi_service_t svc, void *app_data); void *app_data; MESG *md; char *msgbuf; @@ -86,18 +86,27 @@ extern void job_status_to_attributes(job_t *job, char *req_id, char *user, char *charset, short rank, char *file); extern papi_status_t addLPString(papi_attribute_t ***list, int flags, char *name, char *value); -extern papi_status_t addLPStrings(papi_attribute_t ***list, +extern papi_status_t papiAttributeListAddLPStrings(papi_attribute_t ***list, int flags, char *name, char **values); +extern void papiAttributeListGetLPString(papi_attribute_t **attributes, + char *key, char **string); +extern void papiAttributeListGetLPStrings(papi_attribute_t **attributes, + char *key, char ***string); + extern papi_status_t lpsched_printer_configuration_to_attributes( service_t *svc, printer_t *p, char *dest); extern papi_status_t lpsched_class_configuration_to_attributes(service_t *svc, printer_t *p, char *dest); extern papi_status_t class_status_to_attributes(printer_t *p, char *printer, short status, char *reject_reason, long reject_date); +extern papi_status_t lpsched_reject_printer(papi_service_t svc, + char *printer, char *message); +extern papi_status_t lpsched_accept_printer(papi_service_t svc, + char *printer); extern papi_status_t lpsched_disable_printer(papi_service_t svc, - const char *printer, const char *message); + char *printer, char *message); extern papi_status_t lpsched_enable_printer(papi_service_t svc, - const char *printer); + char *printer); extern papi_status_t lpsched_status_to_papi_status(int status); extern papi_status_t job_attributes_to_lpsched_request(papi_service_t svc, REQUEST *r, papi_attribute_t **attributes); @@ -106,31 +115,32 @@ extern papi_status_t lpsched_alloc_files(papi_service_t svc, int number, extern papi_status_t lpsched_commit_job(papi_service_t svc, char *job, char **tmp); extern papi_status_t lpsched_start_change(papi_service_t svc, - const char *printer, int32_t job_id, char **tmp); + char *printer, int32_t job_id, char **tmp); extern papi_status_t lpsched_end_change(papi_service_t svc, - const char *printer, int32_t job_id); + char *printer, int32_t job_id); extern papi_status_t printer_status_to_attributes(printer_t *p, char *printer, char *form, char *character_set, char *reject_reason, char *disable_reason, short status, char *request_id, long enable_date, long reject_date); - -extern void lpsched_service_information(printer_t *p); +extern papi_status_t lpsched_remove_printer(papi_service_t svc, char *dest); +extern papi_status_t lpsched_remove_class(papi_service_t svc, char *dest); +extern papi_status_t lpsched_add_modify_printer(papi_service_t svc, char *dest, + papi_attribute_t **attributes, int type); +extern papi_status_t lpsched_add_modify_class(papi_service_t svc, char *dest, + papi_attribute_t **attributes); + +extern void lpsched_service_information(papi_attribute_t ***attrs); extern void lpsched_request_to_job_attributes(REQUEST *r, job_t *j); extern void detailed_error(service_t *svc, char *fmt, ...); extern char *banner_type(unsigned short banner); extern char *mime_type_to_lp_type(char *mime_type); extern char *lp_type_to_mime_type(char *lp_type); -extern char *fifo_name_from_uri(const char *uri); -extern char *printer_name_from_uri_id(const char *uri, int32_t id); +extern char *fifo_name_from_uri(char *uri); +extern char *printer_name_from_uri_id(char *uri, int32_t id); extern int snd_msg(service_t *svc, int type, ...); extern int rcv_msg(service_t *svc, int type, ...); -extern int list_append(); -extern void list_remove(); - - - #ifdef __cplusplus } #endif diff --git a/usr/src/cmd/lp/lib/papi/ppd.c b/usr/src/cmd/lp/lib/papi/ppd.c new file mode 100644 index 0000000000..5facf902be --- /dev/null +++ b/usr/src/cmd/lp/lib/papi/ppd.c @@ -0,0 +1,164 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * This file contains an extremely rudimentary implementation of PPD file + * parsing support. The parsing done here converts the contents of a PPD + * file into a set of PAPI attributes that applications can use to build + * print panels. + */ + +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include <papi.h> + +static void +process_line(char *line, char **key, char **value, char **comment) +{ + char *ptr, *ptr2; + + *key = &line[1]; + *value = NULL; + *comment = NULL; + + if ((ptr = strchr(line, ':')) == NULL) + return; + + /* + * line is in the form: + * *key: value/comment + * or + * *key value/comment: data + */ + *ptr++ = NULL; + while (isspace(*ptr) != 0) + ptr++; + + if ((ptr2 = strchr(line, ' ')) != NULL) { + ptr = ptr2; + /* + * line is in the form: + * *key value/comment: data + */ + *ptr++ = NULL; + while (*ptr == ' ') + ptr++; + } + + if (*ptr == '*') + ptr++; + + *value = ptr; + + if ((ptr = strchr(ptr, '/')) != NULL) { + *ptr++ = NULL; + *comment = ptr; + } +} + +papi_status_t +PPDFileToAttributesList(papi_attribute_t ***attributes, char *filename) +{ + papi_status_t status = PAPI_OK; + FILE *fp; + char line[256]; + char capability[256]; + char def[256]; + char supported[256]; + char *current_group_name = NULL; + + int ui = 0; + + if ((fp = fopen(filename, "r")) == NULL) + return (PAPI_NOT_POSSIBLE); + + while ((status == PAPI_OK) && + (fgets(line, sizeof (line), fp) != NULL)) { + char *key = NULL, *value = NULL, *text = NULL; + + /* we want *key...: "value" */ + if (line[0] != '*') + continue; + + if (strchr(line, ':') == NULL) + continue; + + if ((text = strrchr(line, '\n')) != NULL) + *text = NULL; + + process_line(line, &key, &value, &text); + + if ((strcasecmp(key, "PageSize") == 0) || + (strcasecmp(key, "InputSlot") == 0)) + key = "media"; + + if (strcasecmp(key, "OpenGroup") == 0) { + if (value == NULL) + value = "unknown"; + current_group_name = strdup(value); + } else if (strcasecmp(key, "OpenUI") == 0) { + if ((strcasecmp(value, "PageSize") == 0) || + (strcasecmp(value, "InputSlot") == 0)) + value = "media"; + snprintf(capability, sizeof (capability), "%s", value); + snprintf(def, sizeof (def), + "%s-default", value); + snprintf(supported, sizeof (supported), + "%s-supported", value); + ui = 1; + } else if (strcasecmp(key, "CloseGroup") == 0) { + /* do nothing */ + } else if (strcasecmp(key, "CloseUI") == 0) { + ui = 0; + /* do nothing */ + } else if (strcasecmp(key, "Manufacturer") == 0) { + status = papiAttributeListAddString(attributes, + PAPI_ATTR_EXCL, + "printer-make", value); + } else if (strcasecmp(key, "ModelName") == 0) { + status = papiAttributeListAddString(attributes, + PAPI_ATTR_EXCL, + "printer-model", value); + } else if (strcasecmp(key, "ShortNickName") == 0) { + status = papiAttributeListAddString(attributes, + PAPI_ATTR_EXCL, + "printer-make-and-model", value); + } else if ((strncasecmp(key, "Default", 7) == 0) && ui) { + status = papiAttributeListAddString(attributes, + PAPI_ATTR_EXCL, + def, value); + } else if ((strcasecmp(key, capability) == 0) && ui) { + status = papiAttributeListAddString(attributes, + PAPI_ATTR_APPEND, + supported, value); + } + } + fclose(fp); + + return (status); +} diff --git a/usr/src/cmd/lp/lib/papi/printer.c b/usr/src/cmd/lp/lib/papi/printer.c index 2bfc1eabc8..8d1c6f6459 100644 --- a/usr/src/cmd/lp/lib/papi/printer.c +++ b/usr/src/cmd/lp/lib/papi/printer.c @@ -59,8 +59,8 @@ papiPrinterListFree(papi_printer_t *printers) } papi_status_t -papiPrintersList(papi_service_t handle, const char **requested_attrs, - const papi_filter_t *filter, papi_printer_t **printers) +papiPrintersList(papi_service_t handle, char **requested_attrs, + papi_filter_t *filter, papi_printer_t **printers) { service_t *svc = handle; printer_t *p = NULL; @@ -139,9 +139,9 @@ papiPrintersList(papi_service_t handle, const char **requested_attrs, } papi_status_t -papiPrinterQuery(papi_service_t handle, const char *name, - const char **requested_attrs, - const papi_attribute_t **job_attrs, +papiPrinterQuery(papi_service_t handle, char *name, + char **requested_attrs, + papi_attribute_t **job_attrs, papi_printer_t *printer) { papi_status_t pst; @@ -166,6 +166,22 @@ papiPrinterQuery(papi_service_t handle, const char *name, 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) @@ -202,7 +218,7 @@ papiPrinterQuery(papi_service_t handle, const char *name, reject_reason, reject_date); } else if (strcmp(dest, "PrintService") == 0) { /* fill the printer object with service information */ - lpsched_service_information(p); + lpsched_service_information(&p->attributes); } else return (PAPI_NOT_FOUND); @@ -212,19 +228,108 @@ papiPrinterQuery(papi_service_t handle, const char *name, } papi_status_t -papiPrinterModify(papi_service_t handle, const char *name, - const papi_attribute_t **attributes, papi_printer_t *result) +papiPrinterAdd(papi_service_t handle, char *name, + papi_attribute_t **attributes, papi_printer_t *result) { - service_t *svc = handle; + 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 +papiPrinterModify(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, 1); + + 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 +papiPrinterRemove(papi_service_t handle, char *name) +{ + papi_status_t result; + char *dest; - if ((svc == NULL) || (name == NULL) || (attributes == NULL)) + if ((handle == NULL) || (name == NULL)) return (PAPI_BAD_ARGUMENT); - return (PAPI_OPERATION_NOT_SUPPORTED); + 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 -papiPrinterPause(papi_service_t handle, const char *name, const char *message) +papiPrinterDisable(papi_service_t handle, char *name, char *message) { papi_status_t result; @@ -237,7 +342,7 @@ papiPrinterPause(papi_service_t handle, const char *name, const char *message) } papi_status_t -papiPrinterResume(papi_service_t handle, const char *name) +papiPrinterEnable(papi_service_t handle, char *name) { papi_status_t result; @@ -250,7 +355,33 @@ papiPrinterResume(papi_service_t handle, const char *name) } papi_status_t -papiPrinterPurgeJobs(papi_service_t handle, const char *name, papi_job_t **jobs) +papiPrinterPause(papi_service_t handle, char *name, char *message) +{ + papi_status_t result; + + if ((handle == NULL) || (name == NULL)) + return (PAPI_BAD_ARGUMENT); + + result = lpsched_reject_printer(handle, name, message); + + return (result); +} + +papi_status_t +papiPrinterResume(papi_service_t handle, char *name) +{ + papi_status_t result; + + if ((handle == NULL) || (name == NULL)) + return (PAPI_BAD_ARGUMENT); + + result = lpsched_accept_printer(handle, name); + + return (result); +} + +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; @@ -263,10 +394,10 @@ papiPrinterPurgeJobs(papi_service_t handle, const char *name, papi_job_t **jobs) return (PAPI_BAD_ARGUMENT); dest = printer_name_from_uri_id(name, -1); - if (snd_msg(svc, S_CANCEL, dest, "", "") < 0) - return (PAPI_SERVICE_UNAVAILABLE); - + 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) @@ -300,9 +431,9 @@ papiPrinterPurgeJobs(papi_service_t handle, const char *name, papi_job_t **jobs) } papi_status_t -papiPrinterListJobs(papi_service_t handle, const char *name, - const char **requested_attrs, const int type_mask, - const int max_num_jobs, papi_job_t **jobs) +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; diff --git a/usr/src/cmd/lp/lib/papi/service.c b/usr/src/cmd/lp/lib/papi/service.c index f9c9162406..a15434fcfb 100644 --- a/usr/src/cmd/lp/lib/papi/service.c +++ b/usr/src/cmd/lp/lib/papi/service.c @@ -38,10 +38,10 @@ #include <tsol/label.h> papi_status_t -papiServiceCreate(papi_service_t *handle, const char *service_name, - const char *user_name, const char *password, - const int (*authCB)(papi_service_t svc), - const papi_encryption_t encryption, void *app_data) +papiServiceCreate(papi_service_t *handle, char *service_name, + char *user_name, char *password, + int (*authCB)(papi_service_t svc, void *app_data), + papi_encryption_t encryption, void *app_data) { service_t *svc = NULL; char *path = Lp_FIFO; @@ -125,7 +125,7 @@ papiServiceSetPeer(papi_service_t handle, int peerfd) } papi_status_t -papiServiceSetUserName(papi_service_t handle, const char *user_name) +papiServiceSetUserName(papi_service_t handle, char *user_name) { service_t *svc = handle; @@ -137,7 +137,7 @@ papiServiceSetUserName(papi_service_t handle, const char *user_name) } papi_status_t -papiServiceSetPassword(papi_service_t handle, const char *password) +papiServiceSetPassword(papi_service_t handle, char *password) { service_t *svc = handle; @@ -150,7 +150,7 @@ papiServiceSetPassword(papi_service_t handle, const char *password) papi_status_t papiServiceSetEncryption(papi_service_t handle, - const papi_encryption_t encryption) + papi_encryption_t encryption) { service_t *svc = handle; @@ -163,20 +163,20 @@ papiServiceSetEncryption(papi_service_t handle, papi_status_t papiServiceSetAuthCB(papi_service_t handle, - const int (*authCB)(papi_service_t svc)) + int (*authCB)(papi_service_t svc, void *app_data)) { service_t *svc = handle; if (svc == NULL) return (PAPI_BAD_ARGUMENT); - svc->authCB = (int (*)(papi_service_t svc))authCB; + svc->authCB = (int (*)(papi_service_t svc, void *app_data))authCB; return (PAPI_OK); } papi_status_t -papiServiceSetAppData(papi_service_t handle, const void *app_data) +papiServiceSetAppData(papi_service_t handle, void *app_data) { service_t *svc = handle; @@ -252,6 +252,20 @@ papiServiceGetAppData(papi_service_t handle) return (result); } +papi_attribute_t ** +papiServiceGetAttributeList(papi_service_t handle) +{ + service_t *svc = handle; + papi_attribute_t **result = NULL; + + if (svc != NULL) { + lpsched_service_information(&svc->attributes); + result = svc->attributes; + } + + return (result); +} + char * papiServiceGetStatusMessage(papi_service_t handle) { diff --git a/usr/src/cmd/print/Makefile b/usr/src/cmd/print/Makefile index ff02c70dbf..27ccdf43ad 100644 --- a/usr/src/cmd/print/Makefile +++ b/usr/src/cmd/print/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -36,13 +35,10 @@ PRINT_SUBDIRS = \ scripts \ lpget \ lpset \ - lp \ - lpstat \ - cancel \ - lpmove \ conv_fix \ printer-info \ - gateway + gateway \ + bsd-sysv-commands SUBDIRS = $(PRINT_SUBDIRS) $(JAVA_SUBDIRS) diff --git a/usr/src/cmd/print/Makefile.sp b/usr/src/cmd/print/Makefile.sp index f4510a84a8..af1d87d236 100644 --- a/usr/src/cmd/print/Makefile.sp +++ b/usr/src/cmd/print/Makefile.sp @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -19,8 +18,9 @@ # # CDDL HEADER END # + # -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -87,7 +87,7 @@ INCSYS = $(INC)/sys LPINC = $(SRC)/include #NPRTINC = $(NPRTROOT)/include -NPRTINC = $(SRC)/lib +NPRTINC = $(SRC)/lib/print/libprint/common LPLIB = $(SRC)/lib LDLIBS += -L$(LPLIB) diff --git a/usr/src/cmd/print/bsd-sysv-commands/Makefile b/usr/src/cmd/print/bsd-sysv-commands/Makefile new file mode 100644 index 0000000000..ee16f07879 --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/Makefile @@ -0,0 +1,84 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +UCBPROGS = lpr lpq lprm lpc +BINPROGS = lp lpstat cancel enable disable $(UCBPROGS) + +SBINPROGS = accept reject lpmove + + +OBJS = $(BINPROGS:=.o) $(SBINPROGS:=.o) common.o + +ROOTBINPROGS = $(BINPROGS:%=$(ROOTBIN)/%) +ROOTUSRSBINPROGS = $(SBINPROGS:%=$(ROOTUSRSBIN)/%) + + +FILEMODE = 0555 +OWNER = root + +include ../../Makefile.cmd + +CFLAGS += $(CCVERBOSE) +CPPFLAGS += -I. +CPPFLAGS += -I../../../lib/print/libpapi-common/common +LDLIBS += -lpapi -lc + +# each program needs common.o as well +$(BINPROGS) $(SBINPROGS): $(BINPROGS:%=%.c) $(SBINPROGS:%=%.c) common.o + $(LINK.c) -o $@ $@.c common.o $(LDLIBS) + $(POST_PROCESS) + +# ucb links (lptest is handled in usr/src/cmd/lp/cmd/Makefile) +ROOTUSRUCB = $(ROOT)/usr/ucb +ROOTUCBSYMLINKS = $(UCBPROGS:%=$(ROOTUSRUCB)/%) +$(ROOTUSRUCB)/%: $(ROOTUSRUCB) % + +$(ROOTUCBSYMLINKS): + $(RM) $@; $(SYMLINK) ../bin/$(@F) $@ + +# usr/lib links +ROOTUSRLIBSYMLINKS = $(SBINPROGS:%=$(ROOTLIB)/%) +$(ROOTLIB)/%: $(ROOTLIB) % + +$(ROOTUSRLIBSYMLINKS): + $(RM) $@; $(SYMLINK) ../sbin/$(@F) $@ + +.KEEP_STATE: + +all: $(BINPROGS) $(SBINPROGS) + +install: $(BINPROGS) $(SBINPROGS) $(ROOTBINPROGS) $(ROOTUSRSBINPROGS) \ + $(ROOTUCBSYMLINKS) $(ROOTUSRLIBSYMLINKS) + +clean: + $(RM) $(OBJS) + +CLOBBERFILES += $(BINPROGS) $(SBINPROGS) + +lint: + +include ../../Makefile.targ diff --git a/usr/src/cmd/print/bsd-sysv-commands/accept.c b/usr/src/cmd/print/bsd-sysv-commands/accept.c new file mode 100644 index 0000000000..c20f9344de --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/accept.c @@ -0,0 +1,104 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: accept.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <locale.h> +#include <libintl.h> +#include <papi.h> +#include "common.h" + +static void +usage(char *program) +{ + char *name; + + if ((name = strrchr(program, '/')) == NULL) + name = program; + else + name++; + + fprintf(stdout, + gettext("Usage: %s destination ...\n"), + name); + exit(1); +} + +int +main(int ac, char *av[]) +{ + papi_status_t status; + papi_service_t svc = NULL; + papi_encryption_t encryption = PAPI_ENCRYPT_NEVER; + int exit_status = 0; + int c; + + (void) setlocale(LC_ALL, ""); + (void) textdomain("SUNW_OST_OSCMD"); + + while ((c = getopt(ac, av, "E")) != EOF) + switch (c) { + case 'E': + encryption = PAPI_ENCRYPT_ALWAYS; + break; + default: + usage(av[0]); + } + + if (ac == optind) + usage(av[0]); + + for (c = optind; c < ac; c++) { + char *printer = av[c]; + + status = papiServiceCreate(&svc, printer, NULL, NULL, + cli_auth_callback, encryption, NULL); + if (status != PAPI_OK) { + fprintf(stderr, gettext( + "Failed to contact service for %s: %s\n"), + printer, verbose_papi_message(svc, status)); + exit_status = 1; + } + + status = papiPrinterResume(svc, printer); + if (status != PAPI_OK) { + fprintf(stderr, gettext("accept: %s: %s\n"), printer, + verbose_papi_message(svc, status)); + exit_status = 1; + } + + papiServiceDestroy(svc); + } + + return (exit_status); +} diff --git a/usr/src/cmd/print/bsd-sysv-commands/cancel.c b/usr/src/cmd/print/bsd-sysv-commands/cancel.c new file mode 100644 index 0000000000..c95279ad5e --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/cancel.c @@ -0,0 +1,127 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: cancel.c 147 2006-04-25 16:51:06Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <locale.h> +#include <libintl.h> +#include <papi.h> +#include "common.h" + +static void +usage(char *program) +{ + char *name; + + if ((name = strrchr(program, '/')) == NULL) + name = program; + else + name++; + + fprintf(stdout, "Usage: %s [-u user] (printer|request-id ...)\n", name); + exit(1); +} + +int +main(int ac, char *av[]) +{ + int exit_code = 0; + char *user = NULL; + papi_encryption_t encryption = PAPI_ENCRYPT_NEVER; + int c; + + (void) setlocale(LC_ALL, ""); + (void) textdomain("SUNW_OST_OSCMD"); + + while ((c = getopt(ac, av, "Eu:")) != EOF) + switch (c) { + case 'E': + encryption = PAPI_ENCRYPT_REQUIRED; + break; + case 'u': + user = optarg; + break; + default: + usage(av[0]); + } + + for (c = optind; c < ac; c++) { + papi_status_t status; + papi_service_t svc = NULL; + papi_job_t *jobs = NULL; + char *printer = NULL; + int32_t id = -1; + + (void) get_printer_id(av[c], &printer, &id); + + status = papiServiceCreate(&svc, printer, user, NULL, + cli_auth_callback, encryption, NULL); + if (status != PAPI_OK) { + fprintf(stderr, gettext( + "Failed to contact service for %s: %s\n"), + printer, verbose_papi_message(svc, status)); + exit(1); + } + +#define OUT ((status == PAPI_OK) ? stdout : stderr) + + if (id != -1) { /* it's a job */ + char *mesg = "cancelled"; + + status = papiJobCancel(svc, printer, id); + if (status != PAPI_OK) { + mesg = verbose_papi_message(svc, status); + exit_code = 1; + } + fprintf(OUT, "%s-%d: %s\n", printer, id, mesg); + } else { /* it's a printer */ + status = papiPrinterPurgeJobs(svc, printer, &jobs); + if (status != PAPI_OK) { + fprintf(stderr, gettext("PurgeJobs %s: %s\n"), + printer, + verbose_papi_message(svc, status)); + exit_code = 1; + } + + while ((jobs != NULL) && (*jobs != NULL)) + fprintf(OUT, "%s-%d: %s\n", printer, + papiJobGetId(*jobs++), "cancelled"); + + papiJobListFree(jobs); + } + + papiServiceDestroy(svc); + } + + return (exit_code); +} diff --git a/usr/src/cmd/print/bsd-sysv-commands/common.c b/usr/src/cmd/print/bsd-sysv-commands/common.c new file mode 100644 index 0000000000..5d70752563 --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/common.c @@ -0,0 +1,491 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: common.c 162 2006-05-08 14:17:44Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <alloca.h> +#include <string.h> +#include <libintl.h> +#include <ctype.h> +#include <pwd.h> +#include <papi.h> +#include "common.h" + +#ifndef HAVE_GETPASSPHRASE /* some systems don't have getpassphrase() */ +#define getpassphrase getpass +#endif + +/* give the most verbose error message to the caller */ +char * +verbose_papi_message(papi_service_t svc, papi_status_t status) +{ + char *mesg; + + mesg = papiServiceGetStatusMessage(svc); + + if (mesg == NULL) + mesg = papiStatusString(status); + + return (mesg); +} + +static int +match_job(int id, char *user, int ac, char *av[]) +{ + int i; + + for (i = 0; i < ac; i++) + if (strcmp("-", av[i]) == 0) + return (0); /* "current" user match */ + else if ((isdigit(av[i][0]) != 0) && (id == atoi(av[i]))) + return (0); /* job-id match */ + else if (strcmp(user, av[i]) == 0) + return (0); /* user match */ + + return (-1); +} + +/* + * to support job/printer status + */ +static char * +state_string(int state) +{ + switch (state) { + case 3: + return (gettext("idle")); + case 4: + return (gettext("processing")); + case 5: + return (gettext("stopped")); + default: + return (gettext("unknown")); + } +} + +static char *_rank_suffixes[] = { + "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th" +}; + +static char * +rank_string(const int rank) +{ + static char buf[12]; + + if (rank < 0) + snprintf(buf, sizeof (buf), gettext("invalid")); + else if (rank == 0) + snprintf(buf, sizeof (buf), gettext("active")); + else if ((rank > 10) && (rank < 14)) + sprintf(buf, "%dth", rank); + else + sprintf(buf, "%d%s", rank, _rank_suffixes[rank % 10]); + + return (buf); +} + +static void +printer_state_line(FILE *fp, papi_printer_t p, int num_jobs, char *name) +{ + papi_attribute_t **list = papiPrinterGetAttributeList(p); + int state = 0; + char *reason = ""; + + (void) papiAttributeListGetInteger(list, NULL, + "printer-state", &state); + (void) papiAttributeListGetString(list, NULL, + "printer-state-reasons", &reason); + (void) papiAttributeListGetString(list, NULL, + "printer-name", &name); + + if ((state != 0x03) || (num_jobs != 0)) { + fprintf(fp, "%s: %s", name, state_string(state)); + if (state == 0x05) /* stopped */ + fprintf(fp, ": %s\n", reason); + else + fprintf(fp, "\n"); + } else + fprintf(fp, "no entries\n"); +} + +static void +print_header(FILE *fp) +{ + fprintf(fp, gettext("Rank\tOwner\t Job\tFile(s)\t\t\t\tTotal Size\n")); +} + +static void +print_job_line(FILE *fp, int count, papi_job_t job, int fmt, int ac, char *av[]) +{ + papi_attribute_t **list = papiJobGetAttributeList(job); + int copies = 1, id = 0, rank = count, size = 0; + char *name = "print job"; + char *user = "nobody"; + char *host = "localhost"; + char *suffix = "k"; + + (void) papiAttributeListGetInteger(list, NULL, + "job-id", &id); + (void) papiAttributeListGetString(list, NULL, + "job-originating-user-name", &user); + + /* if we are looking and it doesn't match, return early */ + if ((ac > 0) && (match_job(id, user, ac, av) < 0)) + return; + + (void) papiAttributeListGetInteger(list, NULL, + "copies", &copies); + (void) papiAttributeListGetInteger(list, NULL, + "number-of-intervening-jobs", &rank); + + if (papiAttributeListGetInteger(list, NULL, "job-octets", &size) + == PAPI_OK) + suffix = "bytes"; + else + (void) papiAttributeListGetInteger(list, NULL, + "job-k-octets", &size); + (void) papiAttributeListGetString(list, NULL, + "job-name", &name); + + size *= copies; + + if (fmt == 3) { + fprintf(fp, gettext("%s\t%-8.8s %d\t%-32.32s%d %s\n"), + rank_string(++rank), user, id, name, size, suffix); + } else + fprintf(fp, gettext( + "\n%s: %s\t\t\t\t[job %d %s]\n\t%-32.32s\t%d %s\n"), + user, rank_string(++rank), id, host, name, size, + suffix); +} + +/* + * to support job cancelation + */ +static void +cancel_job(papi_service_t svc, FILE *fp, char *printer, papi_job_t job, + int ac, char *av[]) +{ + papi_status_t status; + papi_attribute_t **list = papiJobGetAttributeList(job); + int id = 0; + char *user = ""; + char *mesg = gettext("cancelled"); + + papiAttributeListGetInteger(list, NULL, + "job-id", &id); + papiAttributeListGetString(list, NULL, + "job-originating-user-name", &user); + + /* if we are looking and it doesn't match, return early */ + if ((ac > 0) && (match_job(id, user, ac, av) < 0)) + return; + + status = papiJobCancel(svc, printer, id); + if (status != PAPI_OK) + mesg = papiStatusString(status); + + fprintf(fp, "%s-%d: %s\n", printer, id, mesg); +} + +int +berkeley_queue_report(papi_service_t svc, FILE *fp, char *dest, int fmt, + int ac, char *av[]) +{ + papi_status_t status; + papi_printer_t p = NULL; + papi_job_t *jobs = NULL; + char *pattrs[] = { "printer-name", "printer-state", + "printer-state-reasons", NULL }; + char *jattrs[] = { + "job-name", "job-octets", "job-k-octets", + "job-originating-user-name", "job-id", + "number-of-intervening-jobs", NULL }; + int num_jobs = 0; + + status = papiPrinterQuery(svc, dest, pattrs, NULL, &p); + if (status != PAPI_OK) { + fprintf(fp, gettext( + "Failed to query service for state of %s: %s\n"), + dest, verbose_papi_message(svc, status)); + return (-1); + } + + status = papiPrinterListJobs(svc, dest, jattrs, PAPI_LIST_JOBS_ALL, + 0, &jobs); + if (status != PAPI_OK) { + fprintf(fp, gettext( + "Failed to query service for jobs on %s: %s\n"), + dest, verbose_papi_message(svc, status)); + return (-1); + } + if (jobs != NULL) { + while (jobs[num_jobs] != NULL) + num_jobs++; + } + + printer_state_line(fp, p, num_jobs, dest); + if (num_jobs > 0) { + int i; + + if (fmt == 3) + print_header(fp); + for (i = 0; jobs[i] != NULL; i++) + print_job_line(fp, i, jobs[i], fmt, ac, av); + } + + papiPrinterFree(p); + papiJobListFree(jobs); + + return (num_jobs); +} + +int +berkeley_cancel_request(papi_service_t svc, FILE *fp, char *dest, + int ac, char *av[]) +{ + papi_status_t status; + papi_job_t *jobs = NULL; + char *jattrs[] = { "job-originating-user-name", "job-id", NULL }; + + status = papiPrinterListJobs(svc, dest, jattrs, PAPI_LIST_JOBS_ALL, + 0, &jobs); + + if (status != PAPI_OK) { + fprintf(fp, gettext("Failed to query service for %s: %s\n"), + dest, verbose_papi_message(svc, status)); + return (-1); + } + + /* cancel the job(s) */ + if (jobs != NULL) { + int i; + + for (i = 0; jobs[i] != NULL; i++) + cancel_job(svc, fp, dest, jobs[i], ac, av); + } + + papiJobListFree(jobs); + + return (0); +} + +int +get_printer_id(char *name, char **printer, int *id) +{ + int result = -1; + + if (name != NULL) { + char *p = strrchr(name, '-'); + + *printer = name; + if (p != NULL) { + char *s = NULL; + + *id = strtol(p + 1, &s, 10); + if (s[0] != '\0') + *id = -1; + else + *p = '\0'; + result = 0; + } else + *id = -1; + } + + return (result); +} + +/* + * strsplit() splits a string into a NULL terminated array of substrings + * determined by a seperator. The original string is modified, and newly + * allocated space is only returned for the array itself. If more than + * 1024 substrings exist, they will be ignored. + */ +char ** +strsplit(char *string, const char *seperators) +{ + char *list[BUFSIZ], + **result; + int length = 0; + + if ((string == NULL) || (seperators == NULL)) + return (NULL); + + (void) memset(list, 0, sizeof (list)); + for (list[length] = strtok(string, seperators); + (list[length] != NULL) && (length < (BUFSIZ - 2)); + list[length] = strtok(NULL, seperators)) + length++; + + if ((result = (char **)calloc(length+1, sizeof (char *))) != NULL) + (void) memcpy(result, list, length * sizeof (char *)); + + return (result); +} + +papi_status_t +jobSubmitSTDIN(papi_service_t svc, char *printer, papi_attribute_t **list, + papi_job_t *job) +{ + papi_status_t status; + papi_stream_t stream = NULL; + int rc; + char buf[BUFSIZ]; + + status = papiJobStreamOpen(svc, printer, list, NULL, &stream); + while ((status == PAPI_OK) && ((rc = read(0, buf, sizeof (buf))) > 0)) + status = papiJobStreamWrite(svc, stream, buf, rc); + + if (status == PAPI_OK) + status = papiJobStreamClose(svc, stream, job); + + return (status); +} + +static char ** +all_list(papi_service_t svc) +{ + papi_status_t status; + papi_printer_t printer = NULL; + char *list[] = { "member-names", NULL }; + char **result = NULL; + + status = papiPrinterQuery(svc, "_all", list, NULL, &printer); + if ((status == PAPI_OK) && (printer != NULL)) { + papi_attribute_t **attributes = + papiPrinterGetAttributeList(printer); + if (attributes != NULL) { + void *iter = NULL; + char *value = NULL; + + for (status = papiAttributeListGetString(attributes, + &iter, "member-names", &value); + status == PAPI_OK; + status = papiAttributeListGetString(attributes, + &iter, NULL, &value)) + list_append(&result, strdup(value)); + } + papiPrinterFree(printer); + } + + return (result); +} + +static char ** +printers_list(papi_service_t svc) +{ + papi_status_t status; + papi_printer_t *printers = NULL; + char *keys[] = { "printer-name", NULL }; + char **result = NULL; + + status = papiPrintersList(svc, keys, NULL, &printers); + if ((status == PAPI_OK) && (printers != NULL)) { + int i; + + for (i = 0; printers[i] != NULL; i++) { + papi_attribute_t **attributes = + papiPrinterGetAttributeList(printers[i]); + char *name = NULL; + + (void) papiAttributeListGetString(attributes, NULL, + "printer-name", &name); + if ((name != NULL) && (strcmp(name, "_default") != 0)) + list_append(&result, strdup(name)); + } + papiPrinterListFree(printers); + } + + return (result); +} + +char ** +interest_list(papi_service_t svc) +{ + static char been_here; + static char **result; + + if (been_here == 0) { /* only do this once */ + been_here = 1; + + if ((result = all_list(svc)) == NULL) + result = printers_list(svc); + } + + return (result); +} + +char * +localhostname() +{ + static char *result; + + if (result == NULL) { + static char buf[256]; + + if (gethostname(buf, sizeof (buf)) == 0) + result = buf; + } + + return (result); +} + +int +cli_auth_callback(papi_service_t svc, void *app_data) +{ + char prompt[BUFSIZ]; + char *user, *svc_name, *passphrase; + + /* get the name of the service we are contacting */ + if ((svc_name = papiServiceGetServiceName(svc)) == NULL) + return (-1); + + /* find our who we are supposed to be */ + if ((user = papiServiceGetUserName(svc)) == NULL) { + struct passwd *pw; + + if ((pw = getpwuid(getuid())) != NULL) + user = pw->pw_name; + else + user = "nobody"; + } + + /* build the prompt string */ + snprintf(prompt, sizeof (prompt), + gettext("passphrase for %s to access %s: "), user, svc_name); + + /* ask for the passphrase */ + if ((passphrase = getpassphrase(prompt)) != NULL) + papiServiceSetPassword(svc, passphrase); + + return (0); +} diff --git a/usr/src/cmd/print/bsd-sysv-commands/common.h b/usr/src/cmd/print/bsd-sysv-commands/common.h new file mode 100644 index 0000000000..92a2b5b66c --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/common.h @@ -0,0 +1,66 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +#ifndef _BSD_SYSV_COMMON_H +#define _BSD_SYSV_COMMON_H + +/* $Id: common.h 162 2006-05-08 14:17:44Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <papi.h> + +#include <config-site.h> + +#ifdef __cplusplus +extern "C" { +#endif + +extern char **strsplit(char *string, const char *seperators); +extern char *verbose_papi_message(papi_service_t svc, papi_status_t status); + +extern int berkeley_cancel_request(papi_service_t svc, FILE *fp, char *dest, + int ac, char *av[]); + +extern int get_printer_id(char *name, char **printer, int *id); + +extern int berkeley_queue_report(papi_service_t svc, FILE *fp, char *dest, + int fmt, int ac, char *av[]); + +extern papi_status_t jobSubmitSTDIN(papi_service_t svc, char *printer, + papi_attribute_t **list, papi_job_t *job); + +extern char **interest_list(papi_service_t svc); +extern char *localhostname(); + +extern int cli_auth_callback(papi_service_t svc, void *app_data); + +#ifdef __cplusplus +} +#endif + +#endif /* _BSD_SYSV_COMMON_H */ diff --git a/usr/src/cmd/print/bsd-sysv-commands/disable.c b/usr/src/cmd/print/bsd-sysv-commands/disable.c new file mode 100644 index 0000000000..8b813b6d56 --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/disable.c @@ -0,0 +1,149 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: disable.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <locale.h> +#include <libintl.h> +#include <papi.h> +#include "common.h" + +static void +usage(char *program) +{ + char *name; + + if ((name = strrchr(program, '/')) == NULL) + name = program; + else + name++; + + fprintf(stdout, + gettext("Usage: %s [-c] [-W] [-r reason] destination ...\n"), + name); + exit(1); +} + +static void +cancel_active_job(papi_service_t svc, char *dest) +{ + papi_status_t status; + papi_job_t *j = NULL; + char *req_attrs[] = { "job-state", "job-id", NULL }; + + status = papiPrinterListJobs(svc, dest, req_attrs, 0, 0, &j); + if ((status == PAPI_OK) && (j != NULL)) { + int i; + + for (i = 0; j[i] != NULL; j++) { + papi_attribute_t **a = papiJobGetAttributeList(j[i]); + int state = 0; + + if (a == NULL) + continue; + + (void) papiAttributeListGetInteger(a, NULL, + "job-state", &state); + if (state == 0x05) { /* processing */ + int32_t id = papiJobGetId(j[i]); + + (void) papiJobCancel(svc, dest, id); + } + } + papiJobListFree(j); + } +} + +int +main(int ac, char *av[]) +{ + papi_status_t status; + papi_service_t svc = NULL; + papi_encryption_t encryption = PAPI_ENCRYPT_NEVER; + int exit_status = 0; + int cancel = 0; + int pending = 0; /* not implemented */ + char *reason = NULL; + int c; + + (void) setlocale(LC_ALL, ""); + (void) textdomain("SUNW_OST_OSCMD"); + + while ((c = getopt(ac, av, "EcWr:")) != EOF) + switch (c) { + case 'c': /* cancel active job first */ + cancel = 1; + break; + case 'W': /* wait for active request, not implemented */ + pending = 1; + break; + case 'r': /* reason */ + reason = optarg; + break; + case 'E': + encryption = PAPI_ENCRYPT_NEVER; + break; + default: + usage(av[0]); + } + + if (ac <= optind) + usage(av[0]); + + while (optind < ac) { + char *printer = av[optind++]; + + status = papiServiceCreate(&svc, printer, NULL, NULL, + cli_auth_callback, encryption, NULL); + if (status != PAPI_OK) { + fprintf(stderr, gettext( + "Failed to contact service for %s: %s\n"), + printer, verbose_papi_message(svc, status)); + exit_status = 1; + } + + status = papiPrinterDisable(svc, printer, reason); + if (status != PAPI_OK) { + fprintf(stderr, gettext("disable: %s: %s\n"), printer, + verbose_papi_message(svc, status)); + exit_status = 1; + } + + if (cancel != 0) + cancel_active_job(svc, printer); + + papiServiceDestroy(svc); + } + + return (exit_status); +} diff --git a/usr/src/cmd/print/bsd-sysv-commands/enable.c b/usr/src/cmd/print/bsd-sysv-commands/enable.c new file mode 100644 index 0000000000..1bf7a0ccce --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/enable.c @@ -0,0 +1,104 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: enable.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <locale.h> +#include <libintl.h> +#include <papi.h> +#include "common.h" + +static void +usage(char *program) +{ + char *name; + + if ((name = strrchr(program, '/')) == NULL) + name = program; + else + name++; + + fprintf(stdout, + gettext("Usage: %s destination ...\n"), + name); + exit(1); +} + +int +main(int ac, char *av[]) +{ + papi_status_t status; + papi_service_t svc = NULL; + papi_encryption_t encryption = PAPI_ENCRYPT_NEVER; + int exit_status = 0; + int c; + + (void) setlocale(LC_ALL, ""); + (void) textdomain("SUNW_OST_OSCMD"); + + while ((c = getopt(ac, av, "E")) != EOF) + switch (c) { + case 'E': + encryption = PAPI_ENCRYPT_ALWAYS; + break; + default: + usage(av[0]); + } + + if (ac == optind) + usage(av[0]); + + for (c = optind; c < ac; c++) { + char *printer = av[c]; + + status = papiServiceCreate(&svc, printer, NULL, NULL, + cli_auth_callback, encryption, NULL); + if (status != PAPI_OK) { + fprintf(stderr, gettext( + "Failed to contact service for %s: %s\n"), + printer, verbose_papi_message(svc, status)); + exit_status = 1; + } + + status = papiPrinterEnable(svc, printer); + if (status != PAPI_OK) { + fprintf(stderr, gettext("enable: %s: %s\n"), printer, + verbose_papi_message(svc, status)); + exit_status = 1; + } + + papiServiceDestroy(svc); + } + + return (exit_status); +} diff --git a/usr/src/cmd/print/bsd-sysv-commands/in.lpd.c b/usr/src/cmd/print/bsd-sysv-commands/in.lpd.c new file mode 100644 index 0000000000..465189daf1 --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/in.lpd.c @@ -0,0 +1,242 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: in.lpd.c 170 2006-05-20 05:58:49Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <errno.h> +#include <syslog.h> +#include <libintl.h> + +#include <papi.h> +#include "common.h" + +#define ACK(fp) { (void) fputc('\0', fp); (void) fflush(fp); } +#define NACK(fp) { (void) fputc('\1', fp); (void) fflush(fp); } + +/* + * This file contains the front-end of the BSD Print Protocol adaptor. This + * code assumes a BSD Socket interface to the networking side. + */ + +void +fatal(FILE *fp, char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vsyslog(LOG_DEBUG, fmt, ap); + vfprintf(fp, fmt, ap); + va_end(ap); +} + +static void +cleanup(char **files) +{ + if (files != NULL) { + int i; + + for (i = 0; files[i] != NULL; i++) + unlink(files[i]); + } +} + +static void +berkeley_receive_files(papi_service_t svc, FILE *ifp, FILE *ofp) +{ + char line[BUFSIZ]; + char **files = NULL; /* the job data files */ + + /* This should actually implement transfer job from RFC-1179 */ + ACK(ofp); + + while (fgets(line, sizeof (line), ifp) != NULL) { + switch (line[0]) { + case 0x01: /* Abort */ + cleanup(files); + break; + case 0x02: /* Receive control file */ + + break; + case 0x03: { /* Receive data file */ + char file[] = "lpdXXXXXX"; + int fd; + + fd = mkstemp(file); + + list_append(&files, strdup(file)); + } + break; + default: + fatal(ofp, "protocol screwup"); + cleanup(files); + break; + } + } + + cleanup(files); +} + +static void +berkeley_transfer_files(papi_service_t svc, FILE *ifp, FILE *ofp, + char *printer) +{ + papi_status_t status; + papi_printer_t p = NULL; + char *keys[] = { "printer-is-accepting", NULL }; + + status = papiPrinterQuery(svc, printer, keys, NULL, &p); + if ((status == PAPI_OK) && (p != NULL)) { + papi_attribute_t **attrs = papiPrinterGetAttributeList(p); + char accepting = PAPI_FALSE; + + papiAttributeListGetBoolean(attrs, NULL, + "printer-is-accepting", &accepting); + + if (accepting == PAPI_TRUE) + berkeley_receive_files(svc, ifp, ofp); + else + NACK(ofp); + + papiPrinterFree(p); + } else + NACK(ofp); +} + +/* + * This is the entry point for this program. The program takes the + * following options: + * (none) + */ +int +main(int ac, char *av[]) +{ + papi_status_t status; + papi_service_t svc = NULL; + papi_encryption_t encryption = PAPI_ENCRYPT_NEVER; + FILE *ifp = stdin, + *ofp = stdout; + int c; + char buf[BUFSIZ], + **args, + *printer; + + openlog("bsd-gw", LOG_PID, LOG_LPR); + + while ((c = getopt(ac, av, "d")) != EOF) + switch (c) { + case 'E': + encryption = PAPI_ENCRYPT_ALWAYS; + break; + case 'd': + default: + ; + } + + if (fgets(buf, sizeof (buf), ifp) == NULL) { + if (feof(ifp) == 0) + syslog(LOG_ERR, "Error reading from connection: %s", + strerror(errno)); + exit(1); + } + + if ((buf[0] < 1) || (buf[0] > 5)) { + fatal(ofp, "Invalid protocol request (%d): %c%s\n", + buf[0], buf[0], buf); + exit(1); + } + + args = strsplit(&buf[1], "\t\n "); + printer = *args++; + + if (printer == NULL) { + fatal(ofp, "Can't determine requested printer"); + exit(1); + } + + status = papiServiceCreate(&svc, printer, NULL, NULL, NULL, + encryption, NULL); + if (status != PAPI_OK) { + fatal(ofp, "Failed to contact service for %s: %s\n", printer, + verbose_papi_message(svc, status)); + exit(1); + } + +#ifdef HAVE_IS_SYSTEM_LABELED + if (is_system_labeled()) { + int fd = fileno(ifp); + + (void) papiServiceSetPeer(svc, fd); + } +#endif + + switch (buf[0]) { + case '\1': /* restart printer */ + ACK(ofp); /* there is no equivalent */ + break; + case '\2': /* transfer job(s) */ + berkeley_transfer_files(svc, ifp, ofp, printer); + break; + case '\3': /* show queue (short) */ + case '\4': { /* show queue (long) */ + int count; + + for (count = 0; args[count] != 0; count++); + + berkeley_queue_report(svc, ofp, printer, buf[0], count, args); + } + break; + case '\5': { /* cancel job(s) */ + char *requestor = *args++; + int count; + + status = papiServiceSetUserName(svc, requestor); + for (count = 0; args[count] != 0; count++); + + berkeley_cancel_request(svc, ofp, printer, count, args); + } + break; + default: + fatal(ofp, "unsupported protocol request (%c), %s", + buf[0], &buf[1]); + } + + (void) fflush(ofp); + + syslog(LOG_DEBUG, "protocol request(%d) for %s completed: %s", + buf[0], printer, papiStatusString(status)); + syslog(LOG_DEBUG, "detail: %s", verbose_papi_message(svc, status)); + + papiServiceDestroy(svc); + + return (0); +} diff --git a/usr/src/cmd/print/bsd-sysv-commands/lp.c b/usr/src/cmd/print/bsd-sysv-commands/lp.c new file mode 100644 index 0000000000..702f1b8d00 --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/lp.c @@ -0,0 +1,328 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: lp.c 169 2006-05-20 05:58:14Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <locale.h> +#include <libintl.h> +#include <papi.h> +#include "common.h" + +#ifdef HAVE_LIBMAGIC /* for mimetype auto-detection */ +#include <magic.h> +#endif /* HAVE_LIBMAGIC */ + +static void +usage(char *program) +{ + char *name; + + if ((name = strrchr(program, '/')) == NULL) + name = program; + else + name++; + + fprintf(stdout, + gettext("Usage: %s [-c] [-m] [-p] [-s] [-w] [-d destination] " + "[-f form-name] [-H special-handling] [-n number] " + "[-o option] [-P page-list] [-q priority-level] " + "[-S character-set | print-wheel] [-t title] [-v] " + "[-T content-type [-r]] [-y mode-list] [file...]\n"), + name); + exit(1); +} + +static struct { + char *mime_type; + char *lp_type; +} type_map[] = { + { "text/plain", "simple" }, + { "application/octet-stream", "raw" }, + { "application/octet-stream", "any" }, + { "application/postscript", "postscript" }, + { "application/postscript", "ps" }, + { "application/x-cif", "cif" }, + { "application/x-dvi", "dvi" }, + { "application/x-plot", "plot" }, + { "application/x-ditroff", "troff" }, + { "application/x-troff", "otroff" }, + { "application/x-pr", "pr" }, + { "application/x-fortran", "fortran" }, + { "application/x-raster", "raster" }, + { NULL, NULL} +}; + +static char * +lp_type_to_mime_type(char *lp_type) +{ + int i; + + if (lp_type == NULL) + return ("application/octet-stream"); + + for (i = 0; type_map[i].lp_type != NULL; i++) + if (strcasecmp(type_map[i].lp_type, lp_type) == 0) + return (type_map[i].mime_type); + + return (lp_type); +} + +int +main(int ac, char *av[]) +{ + papi_status_t status; + papi_service_t svc = NULL; + papi_attribute_t **list = NULL; + papi_encryption_t encryption = PAPI_ENCRYPT_NEVER; + papi_job_t job = NULL; + char *printer = NULL; + char b = PAPI_TRUE; + int copy = 0; + int silent = 0; + int dump = 0; + int validate = 0; + int modify = -1; + int c; + + (void) setlocale(LC_ALL, ""); + (void) textdomain("SUNW_OST_OSCMD"); + + while ((c = getopt(ac, av, "DEH:P:S:T:cd:f:i:mn:o:pq:rst:Vwy:")) != EOF) + switch (c) { + case 'H': /* handling */ + if (strcasecmp(optarg, "hold") == 0) + papiAttributeListAddString(&list, + PAPI_ATTR_EXCL, + "job-hold-until", "indefinite"); + else if (strcasecmp(optarg, "release") == 0) + papiAttributeListAddString(&list, + PAPI_ATTR_EXCL, + "job-hold-until", "no-hold"); + else if (strcasecmp(optarg, "immediate") == 0) + papiAttributeListAddInteger(&list, + PAPI_ATTR_EXCL, + "job-priority", 100); + else + papiAttributeListAddString(&list, + PAPI_ATTR_EXCL, + "job-hold-until", optarg); + break; + case 'P': /* page list */ + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "page-ranges", optarg); + break; + case 'S': /* charset */ + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "lp-charset", optarg); + break; + case 'T': /* type */ + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "document-format", + lp_type_to_mime_type(optarg)); + break; + case 'D': /* dump */ + dump = 1; + break; + case 'c': /* copy */ + copy = 1; + break; + case 'd': /* destination */ + printer = optarg; + break; + case 'f': /* form */ + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "media", optarg); + break; + case 'i': /* modify job */ + if ((get_printer_id(optarg, &printer, &modify) < 0) || + (modify < 0)) { + fprintf(stderr, + gettext("invalid request id: %s\n"), + optarg); + exit(1); + } + break; + case 'm': /* mail when complete */ + papiAttributeListAddBoolean(&list, PAPI_ATTR_EXCL, + "rfc-1179-mail", 1); + break; + case 'n': /* copies */ + papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL, + "copies", atoi(optarg)); + break; + case 'o': /* lp "options" */ + papiAttributeListFromString(&list, + PAPI_ATTR_REPLACE, optarg); + break; + case 'p': /* Solaris - notification */ + papiAttributeListAddBoolean(&list, PAPI_ATTR_EXCL, + "rfc-1179-mail", 1); + break; + case 'q': { /* priority */ + int i = atoi(optarg); + + i = 99 * (39 - i) / 39 + 1; + if ((i < 1) || (i > 100)) { + fprintf(stderr, gettext( + "priority must be between 0 and 39.\n")); + exit(1); + } + papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL, + "priority", i); + } + break; + case 'r': /* "raw" mode */ + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "document-format", + "application/octet-stream"); + papiAttributeListAddString(&list, PAPI_ATTR_APPEND, + "stty", "raw"); + break; + case 's': /* suppress message */ + silent = 1; + break; + case 't': /* title */ + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "job-name", optarg); + break; + case 'V': /* validate */ + validate = 1; + break; + case 'w': + papiAttributeListAddBoolean(&list, PAPI_ATTR_EXCL, + "rfc-1179-mail", 1); + break; + case 'y': /* lp "modes" */ + papiAttributeListAddString(&list, PAPI_ATTR_APPEND, + "lp-modes", optarg); + break; + case 'E': + encryption = PAPI_ENCRYPT_REQUIRED; + break; + default: + usage(av[0]); + } + + /* convert "banner", "nobanner" to "job-sheet" */ + if (papiAttributeListGetBoolean(list, NULL, "banner", &b) == PAPI_OK) { + (void) papiAttributeListDelete(&list, "banner"); + if (b == PAPI_FALSE) + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "job-sheets", "none"); + } + + if ((printer == NULL) && + ((printer = getenv("PRINTER")) == NULL) && + ((printer = getenv("LPDEST")) == NULL)) + printer = DEFAULT_DEST; + + if (modify == -1) { + char *document_format = "application/octet-stream"; + +#ifdef MAGIC_MIME + if (optind != ac) { + /* get the mime type of the file data */ + magic_t ms = NULL; + + if ((ms = magic_open(MAGIC_MIME)) != NULL) { + document_format = magic_file(ms, av[optind]); + magic_close(ms); + } + } +#endif + + papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL, "copies", 1); + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "document-format", document_format); + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "job-sheets", "standard"); + } + + status = papiServiceCreate(&svc, printer, NULL, NULL, cli_auth_callback, + encryption, NULL); + if (status != PAPI_OK) { + fprintf(stderr, gettext( + "Failed to contact service for %s: %s\n"), printer, + verbose_papi_message(svc, status)); + exit(1); + } + + if (modify != -1) + status = papiJobModify(svc, printer, modify, list, &job); + else if (optind == ac) /* no file list, use stdin */ + status = jobSubmitSTDIN(svc, printer, list, &job); + else if (validate == 1) /* validate the request can be processed */ + status = papiJobValidate(svc, printer, list, + NULL, &av[optind], &job); + else if (copy == 0) /* reference the files in the job, default */ + status = papiJobSubmitByReference(svc, printer, list, + NULL, &av[optind], &job); + else /* copy the files before return, -c */ + status = papiJobSubmit(svc, printer, list, + NULL, &av[optind], &job); + + papiAttributeListFree(list); + + if (status != PAPI_OK) { + fprintf(stderr, gettext("%s: %s\n"), printer, + verbose_papi_message(svc, status)); + papiJobFree(job); + papiServiceDestroy(svc); + exit(1); + } + + if (((silent == 0) || (dump != 0)) && + ((list = papiJobGetAttributeList(job)) != NULL)) { + char *dest = "unknown"; + int32_t id = 0; + + papiAttributeListGetString(list, NULL, "printer-name", &dest); + papiAttributeListGetInteger(list, NULL, "job-id", &id); + printf(gettext("request id is %s-%d "), dest, id); + if (ac != optind) + printf("(%d file(s))\n", ac - optind); + else + printf("(standard input)\n"); + + if (dump != 0) { + printf("job attributes:\n"); + papiAttributeListPrint(stdout, list, "\t"); + printf("\n"); + } + } + + papiJobFree(job); + papiServiceDestroy(svc); + + return (0); +} diff --git a/usr/src/cmd/print/bsd-sysv-commands/lpc.c b/usr/src/cmd/print/bsd-sysv-commands/lpc.c new file mode 100644 index 0000000000..6d0aa6135d --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/lpc.c @@ -0,0 +1,540 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: lpc.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <locale.h> +#include <libintl.h> +#include <papi.h> +#include "common.h" + +typedef int (cmd_handler_t)(papi_service_t, char **); + +static papi_encryption_t encryption = PAPI_ENCRYPT_NEVER; + +/* ARGSUSED0 */ +static int +lpc_exit(papi_service_t svc, char **args) +{ + exit(0); + /* NOTREACHED */ + return (0); +} + +static int +lpc_status(papi_service_t svc, char **args) +{ + papi_status_t status; + papi_printer_t p = NULL; + char *pattrs[] = { "printer-state", "printer-state-reasons", + "printer-is-accepting-jobs", NULL }; + char *destination = args[1]; + + status = papiPrinterQuery(svc, destination, pattrs, NULL, &p); + if (status == PAPI_OK) { + papi_attribute_t **list = papiPrinterGetAttributeList(p); + char accepting = 0; + int32_t state = 0; + + printf("%s:\n", destination); + + (void) papiAttributeListGetBoolean(list, NULL, + "printer-is-accepting-jobs", &accepting); + printf(gettext("\tqueueing is %s\n"), + (accepting ? gettext("enabled") : gettext("disabled"))); + + (void) papiAttributeListGetInteger(list, NULL, + "printer-state", &state); + printf("\tprinting is %s\n", + ((state != 0x05) ? gettext("enabled") : + gettext("disabled"))); + + if (state != 0x03) { /* !idle */ + papi_job_t *jobs = NULL; + int i = 0; + + (void) papiPrinterListJobs(svc, destination, NULL, + PAPI_LIST_JOBS_ALL, 0, &jobs); + if (jobs != NULL) { + for (i = 0; jobs[i] != NULL; i++); + papiJobListFree(jobs); + } + printf(gettext("\t%d entries in spool area\n"), i); + } else + printf(gettext("\tno entries\n")); + + if (state == 0x04) + printf(gettext("\tdaemon present\n")); + + } else { + fprintf(stderr, "%s: %s\n", destination, + verbose_papi_message(svc, status)); + return (-1); + } + + papiPrinterFree(p); + + return (0); +} + +static int +lpc_abort(papi_service_t svc, char **args) +{ + papi_status_t status; + char *destination = args[1]; + + if (destination == NULL) { + fprintf(stderr, gettext("Usage: abort (destination)\n")); + return (-1); + } + + status = papiPrinterPause(svc, destination, "paused via lpc abort"); + if (status == PAPI_OK) { + printf(gettext("%s: processing disabled after current job\n"), + destination); + } else { + fprintf(stderr, "%s: %s\n", destination, + verbose_papi_message(svc, status)); + } + + return (0); +} + +static int +lpc_clean(papi_service_t svc, char **args) +{ + papi_status_t status; + papi_job_t *jobs = NULL; + char *destination = args[1]; + + if (destination == NULL) { + fprintf(stderr, gettext("Usage: clean (destination)\n")); + return (-1); + } + + status = papiPrinterPurgeJobs(svc, destination, &jobs); + if (status != PAPI_OK) { + fprintf(stderr, gettext("clean: %s: %s\n"), destination, + verbose_papi_message(svc, status)); + return (-1); + } + + if (jobs != NULL) { + int i; + + for (i = 0; jobs[i] != NULL; i++) + printf(gettext("\t%s-%d: cancelled\n"), destination, + papiJobGetId(jobs[i])); + + papiJobListFree(jobs); + } + + return (0); +} + +static int +lpc_disable(papi_service_t svc, char **args) +{ + papi_status_t status; + char *destination = args[1]; + + if (destination == NULL) { + fprintf(stderr, gettext("Usage: disable: (destination)\n")); + return (-1); + } + + status = papiPrinterDisable(svc, destination, NULL); + if (status != PAPI_OK) { + fprintf(stderr, gettext("disable: %s: %s\n"), destination, + verbose_papi_message(svc, status)); + return (-1); + } + + return (0); +} + +static int +lpc_enable(papi_service_t svc, char **args) +{ + papi_status_t status; + char *destination = args[1]; + + if (destination == NULL) { + fprintf(stderr, gettext("Usage: enable: (destination)\n")); + return (-1); + } + + status = papiPrinterEnable(svc, destination); + if (status != PAPI_OK) { + fprintf(stderr, gettext("enable: %s: %s\n"), destination, + verbose_papi_message(svc, status)); + return (-1); + } + + return (0); +} + +static int +lpc_restart(papi_service_t svc, char **args) +{ + int rc = 0; + + rc += lpc_disable(svc, args); + rc += lpc_enable(svc, args); + + return (rc); +} + +static int +lpc_start(papi_service_t svc, char **args) +{ + papi_status_t status; + char *destination = args[1]; + + if (destination == NULL) { + fprintf(stderr, gettext("Usage: start (destination)\n")); + return (-1); + } + + status = papiPrinterResume(svc, destination); + if (status != PAPI_OK) { + fprintf(stderr, gettext("start: %s: %s\n"), destination, + verbose_papi_message(svc, status)); + return (-1); + } + + return (0); +} + +static int +lpc_stop(papi_service_t svc, char **args) +{ + papi_status_t status; + char *destination = args[1]; + + if (destination == NULL) { + fprintf(stderr, gettext("Usage: stop (destination)\n")); + return (-1); + } + + status = papiPrinterPause(svc, destination, "paused via lpc"); + if (status != PAPI_OK) { + fprintf(stderr, gettext("stop: %s: %s\n"), destination, + verbose_papi_message(svc, status)); + return (-1); + } + + return (0); +} + +static int +lpc_topq(papi_service_t svc, char **args) +{ + papi_status_t status; + char *destination = args[1]; + int32_t id = atoi(args[2]); + + if (destination == NULL) { + fprintf(stderr, gettext("Usage: topq (destination) (id)\n")); + return (-1); + } + + status = papiJobPromote(svc, destination, id); + if (status != PAPI_OK) { + fprintf(stderr, gettext("topq: %s %d: %s\n"), destination, id, + verbose_papi_message(svc, status)); + return (-1); + } + + return (0); +} + +static int +lpc_up(papi_service_t svc, char **args) +{ + int rc = 0; + + rc += lpc_enable(svc, args); + rc += lpc_start(svc, args); + + return (rc); +} + +static int +lpc_down(papi_service_t svc, char **args) +{ + int rc = 0; + + rc += lpc_disable(svc, args); + rc += lpc_stop(svc, args); + + return (rc); +} + +static int lpc_help(papi_service_t svc, char **args); /* forward reference */ + +static char help_help[] = "get help on commands"; +static char help_exit[] = "exit lpc"; +static char help_status[] = "show status of daemon and queue"; +static char help_abort[] = + "disable print queue terminating any active job processing"; +static char help_clean[] = "remove all jobs from a queue"; +static char help_disable[] = "turn off spooling to a queue"; +static char help_down[] = + "turn off queueing and printing for a queue and set a reason"; +static char help_enable[] = "turn on spooling to a queue"; +static char help_restart[] = "restart job processing for a queue"; +static char help_start[] = "turn on printing from a queue"; +static char help_stop[] = "turn off printing from a queue"; +static char help_up[] = "turn on queueing and printing for a queue"; +static char help_topq[] = "put a job at the top of the queue"; + +static struct { + char *cmd; + int (*handler)(papi_service_t svc, char **args); + char *help_string; + int num_args; +} cmd_tab[] = { + { "?", lpc_help, help_help, 0 }, + { "help", lpc_help, help_help, 0 }, + { "exit", lpc_exit, help_exit, 0 }, + { "quit", lpc_exit, help_exit, 0 }, + { "status", lpc_status, help_status, 1 }, + { "abort", lpc_abort, help_abort, 1 }, + { "clean", lpc_clean, help_clean, 1 }, + { "disable", lpc_disable, help_disable, 1 }, + { "down", lpc_down, help_down, 2 }, + { "enable", lpc_enable, help_enable, 1 }, + { "restart", lpc_restart, help_restart, 1 }, + { "start", lpc_start, help_start, 1 }, + { "stop", lpc_stop, help_stop, 1 }, + { "up", lpc_up, help_up, 1 }, + { "topq", lpc_topq, help_topq, 2 }, + { NULL, NULL, NULL, 0 } +}; + +static int +lpc_handler(char *cmd, cmd_handler_t **handler) +{ + int i; + + for (i = 0; cmd_tab[i].cmd != NULL; i++) + if (strcmp(cmd, cmd_tab[i].cmd) == 0) { + *handler = cmd_tab[i].handler; + return (cmd_tab[i].num_args); + } + return (-1); +} + +static char * +lpc_helptext(char *cmd) +{ + int i; + + for (i = 0; cmd_tab[i].cmd != NULL; i++) + if (strcmp(cmd, cmd_tab[i].cmd) == 0) + return (gettext(cmd_tab[i].help_string)); + return (NULL); +} + +/* ARGSUSED0 */ +static int +lpc_help(papi_service_t svc, char **args) +{ + if (args[1] == NULL) { + int i; + + printf(gettext("Commands are:\n\n")); + for (i = 0; cmd_tab[i].cmd != NULL; i++) { + printf("\t%s", cmd_tab[i].cmd); + if ((i % 7) == 6) + printf("\n"); + } + if ((i % 7) != 6) + printf("\n"); + } else { + char *helptext = lpc_helptext(args[1]); + + if (helptext == NULL) + helptext = gettext("no such command"); + + printf("%s: %s\n", args[1], helptext); + } + + return (0); +} + +static int +process_one(int (*handler)(papi_service_t, char **), char **av, int expected) +{ + int rc = -1; + papi_status_t status = PAPI_OK; + papi_service_t svc = NULL; + char *printer = av[1]; + + if ((printer != NULL) && (expected != 0)) { + status = papiServiceCreate(&svc, printer, NULL, NULL, + cli_auth_callback, encryption, NULL); + if (status != PAPI_OK) { + fprintf(stderr, gettext( + "Failed to contact service for %s: %s\n"), + printer, verbose_papi_message(svc, status)); + } + } + + if (status == PAPI_OK) + rc = handler(svc, av); + + if (svc != NULL) + papiServiceDestroy(svc); + + return (rc); +} + +static int +process_all(int (*handler)(papi_service_t, char **), char **av, int expected) +{ + papi_status_t status; + papi_service_t svc = NULL; + char **printers; + int rc = 0; + + status = papiServiceCreate(&svc, NULL, NULL, NULL, NULL, + encryption, NULL); + if (status != PAPI_OK) { + fprintf(stderr, gettext("Failed to contact service: %s\n"), + verbose_papi_message(svc, status)); + return (-1); + } + + if ((printers = interest_list(svc)) != NULL) { + int i; + + for (i = 0; printers[i] != NULL; i++) { + av[1] = printers[i]; + rc += process_one(handler, av, expected); + } + } + + papiServiceDestroy(svc); + + return (rc); +} + +static int +process(int ac, char **av) +{ + int (*handler)(papi_service_t, char **) = NULL; + int num_args = -1; + + char *printer = av[1]; + int rc = -1; + + if ((num_args = lpc_handler(av[0], &handler)) < 0) { + printf(gettext("%s: invalid command\n"), av[0]); + return (-1); + } + + if (((printer != NULL) && (strcmp(printer, "all") != 0)) || + (num_args <= ac)) + rc = process_one(handler, av, num_args); + else + rc = process_all(handler, av, num_args); + + return (rc); +} + +static void +usage(char *program) +{ + char *name; + + if ((name = strrchr(program, '/')) == NULL) + name = program; + else + name++; + + fprintf(stdout, + gettext("Usage: %s [ command [ parameter...]]\n"), + name); + exit(1); +} + +static void +lpc_shell() +{ + for (;;) { + char line[256]; + char **av = NULL; + int ac = 0; + + /* prompt */ + fprintf(stdout, "lpc> "); + fflush(stdout); + + /* get command */ + if (fgets(line, sizeof (line), stdin) == NULL) + exit(1); + if ((av = strsplit(line, " \t\n")) != NULL) + for (ac = 0; av[ac] != NULL; ac++); + + (void) process(ac, av); + free(av); + } +} + +int +main(int ac, char *av[]) +{ + int result = 0; + int c; + + (void) setlocale(LC_ALL, ""); + (void) textdomain("SUNW_OST_OSCMD"); + + while ((c = getopt(ac, av, "E")) != EOF) + switch (c) { + case 'E': + encryption = PAPI_ENCRYPT_ALWAYS; + break; + default: + usage(av[0]); + } + + if (optind == ac) + lpc_shell(); + else + result = process(optind - 2, &av[optind]); + + return (result); +} diff --git a/usr/src/cmd/print/bsd-sysv-commands/lpmove.c b/usr/src/cmd/print/bsd-sysv-commands/lpmove.c new file mode 100644 index 0000000000..cca6c3fcb1 --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/lpmove.c @@ -0,0 +1,165 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: lpmove.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <locale.h> +#include <libintl.h> +#include <papi.h> +#include "common.h" + +static void +usage(char *program) +{ + char *name; + + if ((name = strrchr(program, '/')) == NULL) + name = program; + else + name++; + + fprintf(stdout, + gettext("Usage: %s [request-id] (destination)\n" + " %s (source) (destination)\n"), name); + exit(1); +} + +static int +move_job(papi_service_t svc, char *src, int32_t id, char *dest) +{ + int result = 0; + papi_status_t status; + char *mesg = gettext("moved"); + + status = papiJobMove(svc, src, id, dest); + if (status != PAPI_OK) { + mesg = (char *)verbose_papi_message(svc, status); + result = -1; + } + fprintf(stderr, gettext("%s-%d to %s: %s\n"), src, id, dest, mesg); + + return (result); +} + +int +main(int ac, char *av[]) +{ + int exit_code = 0; + papi_encryption_t encryption = PAPI_ENCRYPT_NEVER; + char *destination = NULL; + int c; + + (void) setlocale(LC_ALL, ""); + (void) textdomain("SUNW_OST_OSCMD"); + + while ((c = getopt(ac, av, "E:")) != EOF) + switch (c) { + case 'E': + encryption = PAPI_ENCRYPT_REQUIRED; + break; + default: + usage(av[0]); + } + + if (optind >= ac - 1) + usage(av[0]); + + destination = av[--ac]; + + for (c = optind; c < ac; c++) { + papi_status_t status; + papi_service_t svc = NULL; + papi_job_t *jobs = NULL; + char *printer = NULL; + int32_t id = -1; + + (void) get_printer_id(av[c], &printer, &id); + + status = papiServiceCreate(&svc, printer, NULL, NULL, + cli_auth_callback, encryption, NULL); + if (status != PAPI_OK) { + fprintf(stderr, gettext( + "Failed to contact service for %s: %s\n"), + printer, verbose_papi_message(svc, status)); + exit(1); + } + + if (id != -1) { /* it's a job */ + if (move_job(svc, printer, id, destination) < 0) + exit_code = 1; + } else { /* it's a printer */ + char message[128]; + int count = 0; + + snprintf(message, sizeof (message), "moved jobs to %s", + destination); + status = papiPrinterDisable(svc, printer, message); + if (status != PAPI_OK) { + fprintf(stderr, gettext("Disable %s: %s\n"), + printer, + verbose_papi_message(svc, status)); + exit_code = 1; + } else + printf(gettext( + "destination %s is not accepting requests\n"), + printer); + + status = papiPrinterListJobs(svc, printer, NULL, + 0, 0, &jobs); + if (status != PAPI_OK) { + fprintf(stderr, gettext("Jobs %s: %s\n"), + printer, + verbose_papi_message(svc, status)); + exit_code = 1; + } + + printf(gettext("move in progress ...\n")); + while ((jobs != NULL) && (*jobs != NULL)) { + id = papiJobGetId(*jobs++); + if (move_job(svc, printer, id, destination) < 0) + exit_code = 1; + else + count++; + } + printf(gettext( + "total of %d requests moved from %s to %s\n"), + count, printer, destination); + + papiJobListFree(jobs); + } + + papiServiceDestroy(svc); + } + + return (exit_code); +} diff --git a/usr/src/cmd/print/bsd-sysv-commands/lpq.c b/usr/src/cmd/print/bsd-sysv-commands/lpq.c new file mode 100644 index 0000000000..188a5669d6 --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/lpq.c @@ -0,0 +1,134 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: lpq.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <locale.h> +#include <libintl.h> +#include <papi.h> +#include "common.h" + +static void +usage(char *program) +{ + char *name; + + if ((name = strrchr(program, '/')) == NULL) + name = program; + else + name++; + + fprintf(stdout, gettext("Usage: %s [-P printer] (user|id ...)\n"), + name); + exit(1); +} + +static void +clear_screen() +{ + static char buf[32]; + + /* quick and dirty for now, this should be fixed real soon */ + if (buf[0] == '\0') { + FILE *fp = popen("/bin/tput clear", "r"); + if (fp != NULL) { + fgets(buf, sizeof (buf), fp); + fclose(fp); + } + } + printf("%s", buf); +} + +int +main(int ac, char *av[]) +{ + char *printer = NULL; + papi_status_t status; + papi_service_t svc = NULL; + papi_encryption_t encryption = PAPI_ENCRYPT_NEVER; + int format = 3; /* lpq short format */ + int interval = 0; + int num_jobs; + int c; + + (void) setlocale(LC_ALL, ""); + (void) textdomain("SUNW_OST_OSCMD"); + + while ((c = getopt(ac, av, "EP:l")) != EOF) + switch (c) { + case 'E': + encryption = PAPI_ENCRYPT_REQUIRED; + break; + case 'P': + printer = optarg; + break; + case 'l': + format = 4; /* lpq long format */ + break; + default: + usage(av[0]); + } + + if ((optind < ac) && (av[optind][0] == '+')) + interval = atoi(av[optind++]); + + if ((printer == NULL) && + ((printer = getenv("PRINTER")) == NULL) && + ((printer = getenv("LPDEST")) == NULL)) + printer = DEFAULT_DEST; + + status = papiServiceCreate(&svc, printer, NULL, NULL, cli_auth_callback, + encryption, NULL); + if (status != PAPI_OK) { + fprintf(stderr, gettext( + "Failed to contact service for %s: %s\n"), printer, + verbose_papi_message(svc, status)); + papiServiceDestroy(svc); + exit(1); + } + + do { + if (interval != 0) + clear_screen(); + + num_jobs = berkeley_queue_report(svc, stdout, printer, format, + ac - optind, &av[optind]); + + if ((interval != 0) && (num_jobs > 0)) + sleep(interval); + } while ((interval > 0) && (num_jobs > 0)); + + papiServiceDestroy(svc); + + return (0); +} diff --git a/usr/src/cmd/print/bsd-sysv-commands/lpr.c b/usr/src/cmd/print/bsd-sysv-commands/lpr.c new file mode 100644 index 0000000000..b273cfe6c0 --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/lpr.c @@ -0,0 +1,270 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: lpr.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <locale.h> +#include <libintl.h> +#include <papi.h> +#include "common.h" + +#ifdef HAVE_LIBMAGIC /* for mimetype auto-detection */ +#include <magic.h> +#endif /* HAVE_LIBMAGIC */ + +static void +usage(char *program) +{ + char *name; + + if ((name = strrchr(program, '/')) == NULL) + name = program; + else + name++; + + fprintf(stdout, + gettext("Usage: %s [-P printer] [-# copies] [-C class] " + "[-J job] [-T title] " + "[-p [-i indent] [-w width]] " + "[-1|-2|-3|-4 font] [-m] [-h] [-s] " + "[-filter_option] [file ..]\n"), name); + exit(1); +} + +int +main(int ac, char *av[]) +{ + papi_status_t status; + papi_service_t svc = NULL; + papi_attribute_t **list = NULL; + papi_job_t job = NULL; + int exit_code = 0; + char *printer = NULL; + papi_encryption_t encryption = PAPI_ENCRYPT_NEVER; + int dump = 0; + int validate = 0; + int remove = 0; + int copy = 1; /* default is to copy the data */ + char *document_format = "application/octet-stream"; + int c; + + (void) setlocale(LC_ALL, ""); + (void) textdomain("SUNW_OST_OSCMD"); + + while ((c = getopt(ac, av, + "EP:#:C:DVJ:T:w:i:hplrstdgvcfmn1:2:3:4:")) != EOF) + switch (c) { + case 'E': + encryption = PAPI_ENCRYPT_REQUIRED; + break; + case 'P': + printer = optarg; + break; + case '#': + papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL, + "copies", atoi(optarg)); + break; + case 'C': + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "rfc-1179-class", optarg); + break; + case 'D': + dump = 1; + break; + case 'J': + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "job-name", optarg); + break; + case 'T': + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "pr-title", optarg); + break; + case 'p': + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "document-format", "application/x-pr"); + papiAttributeListAddBoolean(&list, PAPI_ATTR_EXCL, + "pr-filter", 1); + break; + case 'i': + papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL, + "pr-indent", atoi(optarg)); + break; + case 'w': + papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL, + "pr-width", atoi(optarg)); + break; + case 'h': + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "job-sheets", "none"); + break; + case 'l': + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "document-format", "application/octet-stream"); + break; + case 'o': + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "document-format", "application/postscript"); + break; + case 'c': + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "document-format", "application/x-cif"); + break; + case 'd': + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "document-format", "application/x-dvi"); + break; + case 'f': + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "document-format", "application/x-fortran"); + break; + case 'g': + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "document-format", "application/x-plot"); + break; + case 'n': + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "document-format", "application/x-ditroff"); + break; + case 't': + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "document-format", "application/x-troff"); + break; + case 'v': + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "document-format", "application/x-raster"); + break; + case 'm': + papiAttributeListAddBoolean(&list, PAPI_ATTR_EXCL, + "rfc-1179-mail", 1); + break; + case 'r': + remove = 1; + break; + case 's': + copy = 0; + break; + case 'V': /* validate */ + validate = 1; + break; + case '1': + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "rfc-1179-font-r", optarg); + break; + case '2': + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "rfc-1179-font-i", optarg); + break; + case '3': + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "rfc-1179-font-b", optarg); + break; + case '4': + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "rfc-1179-font-s", optarg); + break; + default: + usage(av[0]); + } + + if ((remove != 0) && (copy == 0)) { + fprintf(stderr, gettext( + "-r and -s may not be used together\n")); + exit(1); + } + + if ((printer == NULL) && + ((printer = getenv("PRINTER")) == NULL) && + ((printer = getenv("LPDEST")) == NULL)) + printer = DEFAULT_DEST; + +#ifdef MAGIC_MIME + if (optind != ac) { + /* get the mime type of the file data */ + magic_t ms; + + if ((ms = magic_open(MAGIC_MIME)) != NULL) { + document_format = magic_file(ms, av[optind]); + magic_close(ms); + } + } +#endif + + papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL, "copies", 1); + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "document-format", document_format); + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "job-sheets", "standard"); + + status = papiServiceCreate(&svc, printer, NULL, NULL, cli_auth_callback, + encryption, NULL); + if (status != PAPI_OK) { + fprintf(stderr, gettext( + "Failed to contact service for %s: %s\n"), printer, + verbose_papi_message(svc, status)); + exit(1); + } + + if (validate == 1) /* validate the request can be processed */ + status = papiJobValidate(svc, printer, list, + NULL, &av[optind], &job); + else if (optind == ac) /* no file list, use stdin */ + status = jobSubmitSTDIN(svc, printer, list, &job); + else if (copy == 0) /* reference the files in the job, default */ + status = papiJobSubmitByReference(svc, printer, list, + NULL, &av[optind], &job); + else /* copy the files before return, -c */ + status = papiJobSubmit(svc, printer, list, + NULL, &av[optind], &job); + + papiAttributeListFree(list); + + if (status != PAPI_OK) { + fprintf(stderr, gettext("%s: %s\n"), printer, + verbose_papi_message(svc, status)); + papiJobFree(job); + papiServiceDestroy(svc); + exit(1); + } + + if (dump != 0) { + list = papiJobGetAttributeList(job); + printf("job attributes:\n"); + papiAttributeListPrint(stdout, list, "\t"); + printf("\n"); + } + + papiJobFree(job); + papiServiceDestroy(svc); + + return (exit_code); +} diff --git a/usr/src/cmd/print/bsd-sysv-commands/lprm.c b/usr/src/cmd/print/bsd-sysv-commands/lprm.c new file mode 100644 index 0000000000..841a5da811 --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/lprm.c @@ -0,0 +1,101 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: lprm.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <locale.h> +#include <libintl.h> +#include <papi.h> +#include "common.h" + +static void +usage(char *program) +{ + char *name; + + if ((name = strrchr(program, '/')) == NULL) + name = program; + else + name++; + + fprintf(stdout, gettext("Usage: %s [-P printer] (user|id ...)\n"), + name); + exit(1); +} + +int +main(int ac, char *av[]) +{ + papi_status_t status; + papi_service_t svc = NULL; + papi_encryption_t encryption = PAPI_ENCRYPT_NEVER; + char *printer = NULL; + int c; + + (void) setlocale(LC_ALL, ""); + (void) textdomain("SUNW_OST_OSCMD"); + + while ((c = getopt(ac, av, "EP:")) != EOF) + switch (c) { + case 'E': + encryption = PAPI_ENCRYPT_REQUIRED; + break; + case 'P': + printer = optarg; + break; + default: + usage(av[0]); + } + + if ((printer == NULL) && + ((printer = getenv("PRINTER")) == NULL) && + ((printer = getenv("LPDEST")) == NULL)) + printer = DEFAULT_DEST; + + status = papiServiceCreate(&svc, printer, NULL, NULL, cli_auth_callback, + encryption, NULL); + if (status != PAPI_OK) { + fprintf(stderr, gettext( + "Failed to contact service for %s: %s\n"), + printer, verbose_papi_message(svc, status)); + papiServiceDestroy(svc); + return (1); + } + + berkeley_cancel_request(svc, stdout, printer, + ac - optind, &av[optind]); + + papiServiceDestroy(svc); + + return (0); +} diff --git a/usr/src/cmd/print/bsd-sysv-commands/lpstat.c b/usr/src/cmd/print/bsd-sysv-commands/lpstat.c new file mode 100644 index 0000000000..466025da9a --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/lpstat.c @@ -0,0 +1,1015 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: lpstat.c 173 2006-05-25 04:52:06Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <locale.h> +#include <libintl.h> +#include <pwd.h> +#include <papi.h> +#include <uri.h> +#include "common.h" + +static void +usage(char *program) +{ + char *name; + + if ((name = strrchr(program, '/')) == NULL) + name = program; + else + name++; + + fprintf(stdout, gettext("Usage: %s [-d] [-r] [-s] [-t] [-a [list]] " + "[-c [list]] [-o [list] [-l]] [-R [list] [-l]] " + "[-p [list] [-D] [-l]] [-v [list]] [-S [list] [-l]] " + "[-f [list] [-l]] [-u list]\n"), + name); + exit(1); +} + +static char * +nctime(time_t *t) +{ + static char buf[64]; + struct tm *tm = localtime(t); + + (void) strftime(buf, sizeof (buf), "%c", tm); + + return (buf); +} + +static char * +printer_name(papi_printer_t printer) +{ + papi_attribute_t **attributes = papiPrinterGetAttributeList(printer); + char *result = NULL; + + if (attributes != NULL) + papiAttributeListGetString(attributes, NULL, + "printer-name", &result); + + return (result); +} + +static int +lpstat_default_printer(papi_encryption_t encryption) +{ + papi_status_t status; + papi_service_t svc = NULL; + papi_printer_t p = NULL; + char *name = NULL; + + status = papiServiceCreate(&svc, NULL, NULL, NULL, cli_auth_callback, + encryption, NULL); + if (status == PAPI_OK) { + char *req[] = { "printer-name", NULL }; + + status = papiPrinterQuery(svc, DEFAULT_DEST, req, NULL, &p); + if (p != NULL) + name = printer_name(p); + } + if (name != NULL) + printf(gettext("system default printer: %s\n"), name); + else + printf(gettext("no system default destination\n")); + papiPrinterFree(p); + papiServiceDestroy(svc); + + return (0); +} + +static int +lpstat_service_status(papi_encryption_t encryption) +{ + int result = 0; + papi_status_t status; + papi_service_t svc = NULL; + char *name = NULL; + + if (((name = getenv("PAPI_SERVICE_URI")) == NULL) && + ((name = getenv("IPP_SERVER")) == NULL) && + ((name = getenv("CUPS_SERVER")) == NULL)) + name = DEFAULT_SERVICE_URI; + + status = papiServiceCreate(&svc, name, NULL, NULL, cli_auth_callback, + encryption, NULL); + if (status != PAPI_OK) { + printf(gettext("scheduler is not running\n")); + result = -1; + } else + printf(gettext("scheduler is running\n")); + papiServiceDestroy(svc); + + return (result); +} + +static char * +get_device_uri(papi_service_t svc, char *name) +{ + papi_status_t status; + papi_printer_t p = NULL; + char *keys[] = { "device-uri", NULL }; + char *result = NULL; + + status = papiPrinterQuery(svc, name, keys, NULL, &p); + if ((status == PAPI_OK) && (p != NULL)) { + papi_attribute_t **attrs = papiPrinterGetAttributeList(p); + + (void) papiAttributeListGetString(attrs, NULL, + "device-uri", &result); + if (result != NULL) + result = strdup(result); + + papiPrinterFree(p); + } + + return (result); +} + +static char *report_device_keys[] = { "printer-name", "printer-uri-supported", + NULL }; +/* ARGSUSED2 */ +static int +report_device(papi_service_t svc, char *name, papi_printer_t printer, + int verbose, int description) +{ + papi_status_t status; + papi_attribute_t **attrs = papiPrinterGetAttributeList(printer); + char *uri = NULL; + char *device = NULL; + uri_t *u = NULL; + + if (name == NULL) { + status = papiAttributeListGetString(attrs, NULL, + "printer-name", &name); + if (status != PAPI_OK) + status = papiAttributeListGetString(attrs, NULL, + "printer-uri-supported", &name); + } + + if (name == NULL) + return (-1); + + (void) papiAttributeListGetString(attrs, NULL, + "printer-uri-supported", &uri); + + if ((uri != NULL) && (uri_from_string(uri, &u) == 0)) { + char *nodename = localhostname(); + + if ((u->host == NULL) || + (strcasecmp(u->host, "localhost") == 0) || + (strcasecmp(u->host, nodename) == 0)) + device = get_device_uri(svc, name); + + if (device != NULL) { + printf(gettext("device for %s: %s\n"), name, device); + return (0); + } else if (uri != NULL) { + printf(gettext("system for %s: %s (as %s)\n"), name, + u->host, uri); + return (0); + } + + uri_free(u); + } + + return (0); +} + +static char *report_accepting_keys[] = { "printer-name", + "printer-uri-supported", "printer-is-accepting-jobs", + "printer-up-time", "printer-state-time", + "lpsched-reject-date", "lpsched-reject-reason", NULL }; +/* ARGSUSED2 */ +static int +report_accepting(papi_service_t svc, char *name, papi_printer_t printer, + int verbose, int description) +{ + papi_status_t status; + papi_attribute_t **attrs = papiPrinterGetAttributeList(printer); + time_t curr; + char boolean = PAPI_FALSE; + + if (name == NULL) { + status = papiAttributeListGetString(attrs, NULL, + "printer-name", &name); + if (status != PAPI_OK) + status = papiAttributeListGetString(attrs, NULL, + "printer-uri-supported", &name); + } + if (name == NULL) + return (-1); + + (void) papiAttributeListGetBoolean(attrs, NULL, + "printer-is-accepting-jobs", &boolean); + (void) time(&curr); + (void) papiAttributeListGetDatetime(attrs, NULL, + "printer-up-time", &curr); + (void) papiAttributeListGetDatetime(attrs, NULL, + "printer-state-time", &curr); + (void) papiAttributeListGetDatetime(attrs, NULL, + "lpsched-reject-date", &curr); + + if (boolean == PAPI_TRUE) { + printf(gettext("%s accepting requests since %s\n"), + name, nctime(&curr)); + } else { + char *reason = "unknown reason"; + + (void) papiAttributeListGetString(attrs, NULL, + "lpsched-reject-reason", &reason); + + printf(gettext("%s not accepting requests since %s\n\t%s\n"), + name, nctime(&curr), reason); + } + + return (0); +} + +static char *report_class_keys[] = { "printer-name", "printer-uri-supported", + "member-names", NULL }; +/* ARGSUSED2 */ +static int +report_class(papi_service_t svc, char *name, papi_printer_t printer, + int verbose, int description) +{ + papi_status_t status; + papi_attribute_t **attrs = papiPrinterGetAttributeList(printer); + char *member = NULL; + void *iter = NULL; + + status = papiAttributeListGetString(attrs, &iter, + "member-names", &member); + if (status == PAPI_NOT_FOUND) /* it's not a class */ + return (0); + + if (name == NULL) { + status = papiAttributeListGetString(attrs, NULL, + "printer-name", &name); + if (status != PAPI_OK) + status = papiAttributeListGetString(attrs, NULL, + "printer-uri-supported", &name); + } + if (name == NULL) + return (-1); + + printf(gettext("members of class %s:\n\t%s\n"), name, member); + while (papiAttributeListGetString(attrs, &iter, NULL, &member) + == PAPI_OK) + printf("\t%s\n", member); + + return (0); +} + +static char *report_printer_keys[] = { "printer-name", + "printer-uri-supported", "printer-state", + "printer-up-time", "printer-state-time", + "lpsched-disable-date", "printer-state-reasons", + "lpsched-disable-reason", NULL }; +/* ARGSUSED2 */ +static int +report_printer(papi_service_t svc, char *name, papi_printer_t printer, + int verbose, int description) +{ + papi_status_t status; + papi_attribute_t **attrs = papiPrinterGetAttributeList(printer); + time_t curr; + int32_t pstat = 0; + char *member = NULL; + + status = papiAttributeListGetString(attrs, NULL, + "member-names", &member); + if (status == PAPI_OK) /* it's a class */ + return (0); + + if (name == NULL) { + status = papiAttributeListGetString(attrs, NULL, + "printer-name", &name); + if (status != PAPI_OK) + status = papiAttributeListGetString(attrs, NULL, + "printer-uri-supported", &name); + } + if (name == NULL) + return (-1); + + printf(gettext("printer %s "), name); + + status = papiAttributeListGetInteger(attrs, NULL, + "printer-state", &pstat); + + switch (pstat) { + case 0x03: /* idle */ + printf(gettext("idle. enabled")); + break; + case 0x04: { /* processing */ + char *requested[] = { "job-id", NULL }; + papi_job_t *j = NULL; + int32_t jobid = 0; + + (void) papiPrinterListJobs(svc, name, requested, 0, 1, &j); + if ((j != NULL) && (j[0] != NULL)) + jobid = papiJobGetId(j[0]); + papiJobListFree(j); + + printf(gettext("now printing %s-%d. enabled"), name, jobid); + } + break; + case 0x05: /* stopped */ + printf(gettext("disabled")); + break; + default: + printf(gettext("unknown state(0x%x)."), pstat); + break; + } + + (void) time(&curr); + (void) papiAttributeListGetDatetime(attrs, NULL, + "printer-up-time", &curr); + (void) papiAttributeListGetDatetime(attrs, NULL, + "printer-state-time", &curr); + (void) papiAttributeListGetDatetime(attrs, NULL, + "lpsched-disable-date", &curr); + printf(gettext(" since %s. available.\n"), nctime(&curr)); + + if (pstat == 0x05) { + char *reason = "unknown reason"; + + (void) papiAttributeListGetString(attrs, NULL, + "printer-state-reasons", &reason); + (void) papiAttributeListGetString(attrs, NULL, + "lpsched-disable-reason", &reason); + printf(gettext("\t%s\n"), reason); + } + + if (verbose == 1) { + void *iter; + char *str; + + str = ""; + (void) papiAttributeListGetString(attrs, NULL, + "form-ready", &str); + printf(gettext("\tForm mounted: %s\n"), str); + + str = ""; + iter = NULL; + (void) papiAttributeListGetString(attrs, &iter, + "document-format-supported", &str); + printf(gettext("\tContent types: %s"), str); + while (papiAttributeListGetString(attrs, &iter, NULL, &str) + == PAPI_OK) + printf(", %s", str); + printf("\n"); + + str = ""; + (void) papiAttributeListGetString(attrs, NULL, + "printer-info", &str); + printf(gettext("\tDescription: %s\n"), str); + + str = ""; + (void) papiAttributeListGetString(attrs, NULL, + "lpsched-dial-info", &str); + printf(gettext("\tConnection: %s\n"), + ((str[0] != '\0') ? gettext("direct") : str)); + + str = ""; + (void) papiAttributeListGetString(attrs, NULL, + "lpsched-interface-script", &str); + printf(gettext("\tInterface: %s\n"), str); + + str = NULL; + (void) papiAttributeListGetString(attrs, NULL, + "ppd-file-uri", &str); + (void) papiAttributeListGetString(attrs, NULL, + "lpsched-ppd-source-path", &str); + if (str != NULL) + printf(gettext("\tPPD: %s\n"), str); + + str = NULL; + (void) papiAttributeListGetString(attrs, NULL, + "lpsched-fault-alert-command", &str); + if (str != NULL) + printf(gettext("\tOn fault: %s\n"), str); + + str = ""; + (void) papiAttributeListGetString(attrs, NULL, + "lpsched-fault-recovery", &str); + printf(gettext("\tAfter fault: %s\n"), + ((str[0] == '\0') ? gettext("continue") : str)); + + str = "(all)"; + iter = NULL; + (void) papiAttributeListGetString(attrs, &iter, + "requesting-user-name-allowed", &str); + printf(gettext("\tUsers allowed:\n\t\t%s\n"), + ((str[0] == '\0') ? gettext("(none)") : str)); + if ((str != NULL) && (str[0] != '\0')) + while (papiAttributeListGetString(attrs, &iter, NULL, + &str) == PAPI_OK) + printf("\t\t%s\n", str); + + str = NULL; + iter = NULL; + (void) papiAttributeListGetString(attrs, &iter, + "requesting-user-name-denied", &str); + if (str != NULL) { + printf(gettext("\tUsers denied:\n\t\t%s\n"), + ((str[0] == '\0') ? gettext("(none)") : str)); + if ((str != NULL) && (str[0] != '\0')) + while (papiAttributeListGetString(attrs, &iter, + NULL, &str) == PAPI_OK) + printf("\t\t%s\n", str); + } + + str = "(none)"; + iter = NULL; + (void) papiAttributeListGetString(attrs, &iter, + "form-supported", &str); + printf(gettext("\tForms allowed:\n\t\t%s\n"), + ((str[0] == '\0') ? gettext("(none)") : str)); + if ((str != NULL) && (str[0] != '\0')) + while (papiAttributeListGetString(attrs, &iter, NULL, + &str) == PAPI_OK) + printf("\t\t%s\n", str); + + str = ""; + iter = NULL; + (void) papiAttributeListGetString(attrs, &iter, + "media-supported", &str); + printf(gettext("\tMedia supported:\n\t\t%s\n"), + ((str[0] == '\0') ? gettext("(none)") : str)); + if ((str != NULL) && (str[0] != '\0')) + while (papiAttributeListGetString(attrs, &iter, NULL, + &str) == PAPI_OK) + printf("\t\t%s\n", str); + + str = ""; + (void) papiAttributeListGetString(attrs, NULL, + "job-sheets-supported", &str); + printf(gettext("\tBanner %s\n"), + (strcasecmp(str, "none") == 0 ? + gettext("not required") : gettext("required"))); + + str = ""; + iter = NULL; + (void) papiAttributeListGetString(attrs, &iter, + "lpsched-print-wheels", &str); + printf(gettext("\tCharacter sets:\n\t\t%s\n"), + ((str[0] == '\0') ? gettext("(none)") : str)); + if ((str != NULL) && (str[0] != '\0')) + while (papiAttributeListGetString(attrs, &iter, NULL, + &str) == PAPI_OK) + printf("\t\t%s\n", str); + + printf(gettext("\tDefault pitch:\n")); + printf(gettext("\tDefault page size:\n")); + printf(gettext("\tDefault port setting:\n")); + + str = ""; + iter = NULL; + (void) papiAttributeListGetString(attrs, &iter, + "lpsched-options", &str); + if (str != NULL) { + printf(gettext("\tOptions: %s"), str); + while (papiAttributeListGetString(attrs, &iter, NULL, + &str) == PAPI_OK) + printf(", %s", str); + printf("\n"); + } + + } else if (description == 1) { + char *str = ""; + (void) papiAttributeListGetString(attrs, NULL, + "printer-description", &str); + printf(gettext("\tDescription: %s\n"), str); + } else if (verbose > 1) + papiAttributeListPrint(stdout, attrs, "\t"); + + if (verbose > 0) + printf("\n"); + + return (0); +} + +static int +printer_query(char *name, int (*report)(papi_service_t, char *, papi_printer_t, + int, int), papi_encryption_t encryption, + int verbose, int description) +{ + int result = 0; + papi_status_t status; + papi_service_t svc = NULL; + + status = papiServiceCreate(&svc, name, NULL, NULL, cli_auth_callback, + encryption, NULL); + if (status != PAPI_OK) { + fprintf(stderr, gettext( + "Failed to contact service for %s: %s\n"), + name ? name : "(NULL)", + verbose_papi_message(svc, status)); + papiServiceDestroy(svc); + return (-1); + } + + if (name == NULL) { /* all */ + char **interest = interest_list(svc); + + if (interest != NULL) { + int i; + + for (i = 0; interest[i] != NULL; i++) + result += printer_query(interest[i], report, + encryption, verbose, + description); + } + } else { + papi_printer_t printer = NULL; + char **keys = NULL; + + /* + * Limit the query to only required data to reduce the need + * to go remote for information. + */ + if (report == report_device) + keys = report_device_keys; + else if (report == report_class) + keys = report_class_keys; + else if (report == report_accepting) + keys = report_accepting_keys; + else if ((report == report_printer) && (verbose == 0)) + keys = report_printer_keys; + + status = papiPrinterQuery(svc, name, keys, NULL, &printer); + if (status != PAPI_OK) { + fprintf(stderr, gettext( + "Failed to get printer info for %s: %s\n"), + name, verbose_papi_message(svc, status)); + papiServiceDestroy(svc); + return (-1); + } + + if (printer != NULL) + result = report(svc, name, printer, verbose, + description); + + papiPrinterFree(printer); + } + + papiServiceDestroy(svc); + + return (result); +} + +static int +match_user(char *user, char **list) +{ + int i; + + for (i = 0; list[i] != NULL; i++) { + if (strcmp(user, list[i]) == 0) + return (0); + } + + return (-1); +} + +static char **users = NULL; + +static int +report_job(papi_job_t job, int show_rank, int verbose) +{ + papi_attribute_t **attrs = papiJobGetAttributeList(job); + time_t clock = 0; + char date[24]; + char request[26]; + char *user = "unknown"; + int32_t size = 0; + int32_t jstate = 0; + + char *destination = "unknown"; + int32_t id = -1; + + (void) papiAttributeListGetString(attrs, NULL, + "job-originating-user-name", &user); + + if ((users != NULL) && (match_user(user, users) < 0)) + return (0); + + (void) papiAttributeListGetInteger(attrs, NULL, "job-k-octets", &size); + size *= 1024; /* for the approximate byte size */ + (void) papiAttributeListGetInteger(attrs, NULL, "job-octets", &size); + + (void) time(&clock); + (void) papiAttributeListGetInteger(attrs, NULL, + "time-at-creation", (int32_t *)&clock); + (void) strftime(date, sizeof (date), "%b %d %R", localtime(&clock)); + + (void) papiAttributeListGetString(attrs, NULL, + "job-printer-uri", &destination); + (void) papiAttributeListGetString(attrs, NULL, + "printer-name", &destination); + (void) papiAttributeListGetInteger(attrs, NULL, + "job-id", &id); + snprintf(request, sizeof (request), "%s-%d", destination, id); + + if (show_rank != 0) { + int32_t rank = -1; + + (void) papiAttributeListGetInteger(attrs, NULL, + "number-of-intervening-jobs", &rank); + rank++; + + printf("%3d %-21s %-14s %7ld %s", + rank, request, user, size, date); + } else + printf("%-23s %-14s %7ld %s", request, user, size, date); + + (void) papiAttributeListGetInteger(attrs, NULL, + "job-state", &jstate); + if (jstate == 0x04) + printf(gettext(", being held")); + else if (jstate == 0x07) + printf(gettext(", cancelled")); + else if (jstate == 0x09) + printf(gettext(", complete")); + + if (verbose == 1) { + (void) papiAttributeListGetString(attrs, NULL, + "output-device-assigned", &destination); + printf("\n\t assigned %s", destination); + } else if (verbose > 1) { + printf("\n"); + papiAttributeListPrint(stdout, attrs, "\t"); + } + + printf("\n"); + + return (0); +} + +static int +job_query(char *request, int (*report)(papi_job_t, int, int), + papi_encryption_t encryption, int show_rank, int verbose) +{ + int result = 0; + papi_status_t status; + papi_service_t svc = NULL; + char *printer = NULL; + int32_t id = -1; + + get_printer_id(request, &printer, &id); + + status = papiServiceCreate(&svc, printer, NULL, NULL, cli_auth_callback, + encryption, NULL); + if (status != PAPI_OK) { + fprintf(stderr, gettext( + "Failed to contact service for %s: %s\n"), + (printer ? printer : "all"), + verbose_papi_message(svc, status)); + return (-1); + } + + if (printer == NULL) { /* all */ + char **interest = interest_list(svc); + + if (interest != NULL) { + int i; + + for (i = 0; interest[i] != NULL; i++) + result += job_query(interest[i], report, + encryption, show_rank, verbose); + } + } else if (id == -1) { /* a printer */ + papi_job_t *jobs = NULL; + + status = papiPrinterListJobs(svc, printer, NULL, 0, 0, &jobs); + if (status != PAPI_OK) { + fprintf(stderr, gettext( + "Failed to get job list: %s\n"), + verbose_papi_message(svc, status)); + papiServiceDestroy(svc); + return (-1); + } + + if (jobs != NULL) { + int i; + + for (i = 0; jobs[i] != NULL; i++) + result += report(jobs[i], show_rank, verbose); + } + + papiJobListFree(jobs); + } else { /* a job */ + papi_job_t job = NULL; + + status = papiJobQuery(svc, printer, id, NULL, &job); + if (status != PAPI_OK) { + fprintf(stderr, gettext( + "Failed to get job info for %s: %s\n"), + request, verbose_papi_message(svc, status)); + papiServiceDestroy(svc); + return (-1); + } + + if (job != NULL) + result = report(job, show_rank, verbose); + + papiJobFree(job); + } + + papiServiceDestroy(svc); + + return (result); +} + +static int +report_form(char *name, papi_attribute_t **attrs, int verbose) +{ + papi_status_t status; + char *form = NULL; + void *iter = NULL; + + for (status = papiAttributeListGetString(attrs, &iter, + "form-supported", &form); + status == PAPI_OK; + status = papiAttributeListGetString(attrs, &iter, + NULL, &form)) { + if ((name == NULL) || (strcmp(name, form) == 0)) { + printf(gettext("form %s is available to you\n"), form); + if (verbose != 0) { + char *detail = NULL; + status = papiAttributeListGetString(attrs, NULL, + "form-supported-detail", + &detail); + if (status == PAPI_OK) + printf("%s\n", detail); + } + } + } + + return (0); +} + +static int +report_print_wheels(char *name, papi_attribute_t **attrs, int verbose) +{ + papi_status_t status; + char *pw = NULL; + void *iter = NULL; + + for (status = papiAttributeListGetString(attrs, &iter, + "pw-supported", &pw); + status == PAPI_OK; + status = papiAttributeListGetString(attrs, &iter, NULL, &pw)) { + if ((name == NULL) || (strcmp(name, pw) == 0)) { + printf(gettext("charset %s is available\n"), pw); + if (verbose != 0) { + char *info = NULL; + status = papiAttributeListGetString(attrs, NULL, + "pw-supported-extra", &info); + if (status == PAPI_OK) + printf("%s\n", info); + } + } + } + + return (0); +} + +static int +service_query(char *name, int (*report)(char *, papi_attribute_t **, int), + papi_encryption_t encryption, int verbose) +{ + int result = 0; + papi_status_t status; + papi_service_t svc = NULL; + papi_attribute_t **attrs = NULL; + + status = papiServiceCreate(&svc, name, NULL, NULL, cli_auth_callback, + encryption, NULL); + if (status != PAPI_OK) { + papiServiceDestroy(svc); + return (-1); + } + + attrs = papiServiceGetAttributeList(svc); + if (attrs != NULL) { + result = report(name, attrs, verbose); + + if (verbose > 1) { + printf("\n"); + papiAttributeListPrint(stdout, attrs, "\t"); + printf("\n"); + } + } + + papiServiceDestroy(svc); + + return (result); +} + +int +main(int ac, char *av[]) +{ + int exit_code = 0; + papi_encryption_t encryption = PAPI_ENCRYPT_NEVER; + int rank = 0; + int verbose = 0; + int description = 0; + int c; + char **argv; + + (void) setlocale(LC_ALL, ""); + (void) textdomain("SUNW_OST_OSCMD"); + + argv = (char **)calloc((ac + 1), sizeof (char *)); + for (c = 0; c < ac; c++) + argv[c] = av[c]; + argv[c++] = "--"; + ac = c; + + /* preprocess argument list looking for '-l' or '-R' so it can trail */ + while ((c = getopt(ac, argv, "LEDf:S:stc:p:a:drs:v:l:o:R:u:")) != EOF) + switch (c) { + case 'l': + if ((optarg == NULL) || (optarg[0] == '-')) + optarg = "1"; + verbose = atoi(optarg); + break; + case 'D': + description = 1; + break; + case 'R': + rank = 1; + break; + case 'E': + encryption = PAPI_ENCRYPT_REQUIRED; + break; + default: + break; + } + optind = 1; + + /* process command line arguments */ + while ((c = getopt(ac, argv, "LEDf:S:stc:p:a:drs:v:l:o:R:u:")) != EOF) { + switch (c) { /* these may or may not have an option */ + case 'a': + case 'c': + case 'p': + case 'o': + case 'R': + case 'u': + case 'v': + case 'l': + case 'f': + case 'S': + if (optarg[0] == '-') { + /* this check stop a possible infinite loop */ + if ((optind > 1) && (argv[optind-1][1] != c)) + optind--; + optarg = NULL; + } else if (strcmp(optarg, "all") == 0) + optarg = NULL; + } + + switch (c) { + case 'a': + exit_code += printer_query(optarg, report_accepting, + encryption, verbose, 0); + break; + case 'c': + exit_code += printer_query(optarg, report_class, + encryption, verbose, 0); + break; + case 'p': + exit_code += printer_query(optarg, report_printer, + encryption, verbose, + description); + break; + case 'd': + exit_code += lpstat_default_printer(encryption); + break; + case 'r': + exit_code += lpstat_service_status(encryption); + break; + case 'u': + if (optarg != NULL) + users = strsplit(optarg, ", \n"); + exit_code += job_query(NULL, report_job, + encryption, rank, verbose); + if (users != NULL) { + free(users); + users = NULL; + } + break; + case 'v': + exit_code += printer_query(optarg, report_device, + encryption, verbose, 0); + break; + case 'o': + exit_code += job_query(optarg, report_job, + encryption, rank, verbose); + break; + case 'f': + exit_code += service_query(optarg, report_form, + encryption, verbose); + break; + case 'S': + exit_code += service_query(optarg, report_print_wheels, + encryption, verbose); + break; + case 's': + exit_code += lpstat_service_status(encryption); + exit_code += lpstat_default_printer(encryption); + exit_code += printer_query(NULL, report_class, + encryption, verbose, 0); + exit_code += printer_query(NULL, report_device, + encryption, verbose, 0); + exit_code += service_query(optarg, report_form, + encryption, verbose); + exit_code += service_query(optarg, report_print_wheels, + encryption, verbose); + break; + case 't': + exit_code += lpstat_service_status(encryption); + exit_code += lpstat_default_printer(encryption); + exit_code += printer_query(NULL, report_class, + encryption, verbose, 0); + exit_code += printer_query(NULL, report_device, + encryption, verbose, 0); + exit_code += printer_query(NULL, report_accepting, + encryption, verbose, 0); + exit_code += printer_query(NULL, report_printer, + encryption, verbose, 0); + exit_code += service_query(optarg, report_form, + encryption, verbose); + exit_code += service_query(optarg, report_print_wheels, + encryption, verbose); + exit_code += job_query(NULL, report_job, + encryption, rank, verbose); + break; + case 'L': /* local-only, ignored */ + case 'l': /* increased verbose level in first pass */ + case 'D': /* set "description" flag in first pass */ + case 'R': /* set "rank" flag in first pass */ + case 'E': /* set encryption in the first pass */ + break; + default: + usage(av[0]); + } + } + ac--; + + if (ac == 1) { /* report on my jobs */ + struct passwd *pw = getpwuid(getuid()); + + if (pw != NULL) + users = strsplit(pw->pw_name, ""); + exit_code += job_query(NULL, report_job, encryption, + rank, verbose); + if (users != NULL) { + free(users); + users = NULL; + } + } else { + for (c = optind; c < ac; c++) + exit_code += job_query(argv[c], report_job, encryption, + rank, verbose); + } + + + if (exit_code != 0) + exit_code = 1; + + return (exit_code); +} diff --git a/usr/src/cmd/print/bsd-sysv-commands/reject.c b/usr/src/cmd/print/bsd-sysv-commands/reject.c new file mode 100644 index 0000000000..58eb2829d0 --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/reject.c @@ -0,0 +1,108 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: reject.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <locale.h> +#include <libintl.h> +#include <papi.h> +#include "common.h" + +static void +usage(char *program) +{ + char *name; + + if ((name = strrchr(program, '/')) == NULL) + name = program; + else + name++; + + fprintf(stdout, + gettext("Usage: %s destination ...\n"), + name); + exit(1); +} + +int +main(int ac, char *av[]) +{ + papi_status_t status; + papi_service_t svc = NULL; + papi_encryption_t encryption = PAPI_ENCRYPT_NEVER; + char *reason = NULL; + int exit_status = 0; + int c = 1; + + (void) setlocale(LC_ALL, ""); + (void) textdomain("SUNW_OST_OSCMD"); + + while ((c = getopt(ac, av, "Er:")) != EOF) + switch (c) { + case 'r': /* reason */ + reason = optarg; + break; + case 'E': + encryption = PAPI_ENCRYPT_ALWAYS; + break; + default: + usage(av[0]); + } + + if (ac <= optind) + usage(av[0]); + + while (optind < ac) { + char *printer = av[optind++]; + + status = papiServiceCreate(&svc, printer, NULL, NULL, + cli_auth_callback, encryption, NULL); + if (status != PAPI_OK) { + fprintf(stderr, gettext( + "Failed to contact service for %s: %s\n"), + printer, verbose_papi_message(svc, status)); + exit_status = 1; + } + + status = papiPrinterPause(svc, printer, reason); + if (status != PAPI_OK) { + fprintf(stderr, gettext("reject: %s: %s\n"), printer, + verbose_papi_message(svc, status)); + exit_status = 1; + } + + papiServiceDestroy(svc); + } + + return (exit_status); +} diff --git a/usr/src/cmd/print/cancel/Makefile b/usr/src/cmd/print/cancel/Makefile deleted file mode 100644 index f7d257fd90..0000000000 --- a/usr/src/cmd/print/cancel/Makefile +++ /dev/null @@ -1,86 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# ident "%Z%%M% %I% %E% SMI" -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# cmd/lp/client/cancel/Makefile -# - -include ../Makefile.sp - -PROG= cancel - -SRCS= cancel.c cancel_list.c - -OBJS= $(SRCS:.c=.o) - -ROOTBINPROG= $(PROG:%=$(ROOTBIN)/%) -ROOTUSRBINSYMLINK= $(ROOTBIN)/lprm -ROOTUSRUCBSYMLINK= $(ROOTUSRUCB)/lprm - -FILEMODE= 04511 -OWNER= root - -CPPFLAGS += -I. -I$(NPRTINC) #$(CPPFLAGS.master) -LDLIBS += $(LIBNPRT) - -.KEEP_STATE: - -all: $(PROG) - -$(PROG): $(OBJS) - $(LINK.c) $(OBJS) -o $@ $(LDLIBS) - $(POST_PROCESS) - -install: all $(ROOTBIN) $(ROOTBINPROG) $(ROOTUSRBINSYMLINK) \ - $(ROOTUSRUCBSYMLINK) - -$(ROOTBIN): - $(INS.dir) - -$(ROOTUSRBINSYMLINK): - $(RM) $@; $(SYMLINK) $(PROG) $@ - -$(ROOTUSRUCBSYMLINK): - $(RM) $@; $(SYMLINK) ../bin/lprm $@ - -strip: - $(STRIP) $(PROG) - -lint: - $(LINT.c) $(SRCS) $(LDLIBS) - -cstyle: - cstyle $(SRCS) - -_msg: - @echo "Messages are made in usr/src/cmd/print" - -clean: - $(RM) $(OBJS) - -clobber: clean - -$(RM) $(PROG) $(CLOBBERFILES) - diff --git a/usr/src/cmd/print/cancel/cancel.c b/usr/src/cmd/print/cancel/cancel.c deleted file mode 100644 index acfc529344..0000000000 --- a/usr/src/cmd/print/cancel/cancel.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <stdarg.h> -#include <unistd.h> -#include <string.h> -#include <syslog.h> -#include <ctype.h> -#include <locale.h> -#ifndef SUNOS_4 -#include <libintl.h> -#endif - -#include <print/ns.h> -#include <print/network.h> -#include <print/misc.h> -#include <print/list.h> -#include <print/job.h> - -#include <cancel_list.h> - -extern char *optarg; -extern int optind, opterr, optopt; -int exit_code = 0; -extern char *getenv(const char *); - -static int all = 0; /* global for canceling everything */ - - - -static char * -vappend_list(void **list) -{ - int current = 0; - char *string; - int stringlen; - int listlen; - int strsize = BUFSIZ; - - - string = malloc(strsize); - (void) memset(string, NULL, sizeof (string)); - - if (list != NULL) { - while (list[current] != NULL) { - stringlen = strlen(string); - listlen = strlen(list[current]); - if (strsize < (stringlen + listlen + 2)) { - strsize = stringlen + listlen + 2; - string = realloc(string, strsize); - } - - (void) strcat(string, " "); - (void) strcat(string, list[current]); - current++; - } - } - - return (string); -} - - -/* - * vcancel_local() attempts to cancel all locally spooled jobs that are - * are associated with a cancel_req_t structure. This function is - * intended to be called by list_iterate(). - */ -static int -vcancel_local(cancel_req_t *entry, va_list ap) -{ - char *user = va_arg(ap, char *); - job_t **list = NULL; - - list = job_list_append(list, entry->binding->printer, - entry->binding->server, SPOOL_DIR); - return (list_iterate((void **)list, (VFUNC_T)vjob_cancel, user, - entry->binding->printer, entry->binding->server, - entry->list)); -} - - -/* - * vcancel_remote() attempts to send a cancel request to a print server - * for any jobs that might be associated with the cancel_req_t structure - * passed in. This function is intended to be called by list_iterate(). - */ -static int -vcancel_remote(cancel_req_t *entry, va_list ap) -{ - char buf[BUFSIZ], - *user = va_arg(ap, char *), - *printer = entry->binding->printer, - *server = entry->binding->server; - int nd, - rc; - char *string; - - if ((nd = net_open(server, 15)) < 0) { - (void) fprintf(stderr, - gettext("could not talk to print service at %s\n"), - server); - return (-1); - } - - (void) memset(buf, NULL, sizeof (buf)); - - if (strcmp(user, "-all") != 0) - string = vappend_list((void *)entry->list); - - syslog(LOG_DEBUG, "vcancel_remote(): %s %s%s", printer, user, string); - rc = net_printf(nd, "%c%s %s%s\n", REMOVE_REQUEST, printer, user, - string); - if (rc < 0) - syslog(LOG_ERR, "net_printf() failed: %m"); - - while (memset(buf, NULL, sizeof (buf)) && - (net_read(nd, buf, sizeof (buf)) > 0)) - (void) printf("%s", buf); - - (void) net_close(nd); - return (0); -} - - -/* - * vsysv_printer() adds an entry to the cancel list with the items supplied. - */ -static void -vsysv_printer(char *printer, va_list ap) -{ - cancel_req_t ***list = va_arg(ap, cancel_req_t ***); - char **items = va_arg(ap, char **); - - *list = cancel_list_add_list(*list, printer, items); -} - -/* - * vsysv_binding() adds an entry to the cancel list with the items supplied. - */ -static void -vsysv_binding(ns_bsd_addr_t *binding, va_list ap) -{ - cancel_req_t ***list = va_arg(ap, cancel_req_t ***); - char **items = va_arg(ap, char **); - - *list = cancel_list_add_binding_list(*list, binding, items); -} - -/* - * sysv_remove() parses the command line arguments as defined for cancel - * and builds a list of cancel_req_t structures to return - */ -static cancel_req_t ** -sysv_remove(int ac, char **av) -{ - char *printer, - **printers = NULL, - **items = NULL; - int c; - int user = 0; - cancel_req_t **list = NULL; - - if (ac == 1) { - (void) fprintf(stderr, - gettext("printer, request-id, and/or user required\n")); - exit(-1); - } - - if ((printer = getenv((const char *)"LPDEST")) == NULL) - printer = getenv((const char *)"PRINTER"); - if (printer == NULL) - printer = NS_NAME_DEFAULT; - - while ((c = getopt(ac, av, "u")) != EOF) - switch (c) { - case 'u': - user++; - break; - default: - (void) fprintf(stderr, - "Usage:\t%s [-u user-list] [printer-list]\n", av[0]); - (void) fprintf(stderr, - "\t%s [request-list] [printer-list]\n", av[0]); - exit(-1); - } - - ac--; - while (optind <= ac) { /* pull printers off */ - char *p, - *q; - - if (((p = strrchr(av[ac], ':')) != NULL) && - ((q = strrchr(p, '-')) != NULL)) { - int req = 0; - while (*++q != NULL) - if (isdigit(*q) == 0) - req++; - if (req == 0) - break; - } - if ((ns_bsd_addr_get_name(av[ac])) != NULL) { - printers = (char **)list_append((void **)printers, - (void *)av[ac]); - } else - break; - ac--; - } - - while (optind <= ac) { /* get reqs or users */ - if (user != 0) { /* list o users */ - items = (char **)list_append((void **)items, - (void *)av[ac]); - } else { /* list o jobs */ - char *p; - - if ((p = strrchr(av[ac], '-')) != NULL) { /* job-id */ - *(p++) = NULL; - if (*p == NULL) { - (void) fprintf(stderr, - gettext("invalid job id: %s-\n"), - av[ac]); - exit(-1); - } - list = cancel_list_add_item(list, av[ac], p); - } else { /* just a number */ - list = cancel_list_add_item(list, av[ac], NULL); - } - } - ac--; - } - - if ((printers == NULL) && (items != NULL)) { /* handle "all" printers */ - ns_bsd_addr_t **addrs = NULL; - - if ((addrs = ns_bsd_addr_get_all(UNIQUE)) != NULL) - (void) list_iterate((void **)addrs, - (VFUNC_T)vsysv_binding, &list, items); - } - - if ((list == NULL) && (items == NULL)) - items = (char **)list_append((void **)items, NULL); - - (void) list_iterate((void **)printers, (VFUNC_T)vsysv_printer, - &list, items); - - return (list); -} - - -/* - * bsd_remove() parses the command line arguments as defined for lprm - * and builds a list of cancel_req_t structures to return - */ -static cancel_req_t ** -bsd_remove(int ac, char **av) -{ - char *printer; - int c; - cancel_req_t **list = NULL; - - if ((printer = getenv((const char *)"PRINTER")) == NULL) - printer = getenv((const char *)"LPDEST"); - if (printer == NULL) - printer = NS_NAME_DEFAULT; - - while ((c = getopt(ac, av, "P:-")) != EOF) - switch (c) { - case 'P': - printer = optarg; - break; - default: - (void) fprintf(stderr, gettext( - "Usage: %s [-P printer] [-] [job # ...] [username ...]\n"), - av[0]); - exit(-1); - } - - while (optind < ac) - if (strcmp(av[optind++], "-") == 0) { - if (getuid() == 0) { - all = 1; - list = cancel_list_add_item(list, printer, - "-all"); - } else { - list = cancel_list_add_item(list, printer, - get_user_name()); - } - } else { - list = cancel_list_add_item(list, printer, - av[optind-1]); - } - - if (list == NULL) - list = cancel_list_add_item(list, printer, NULL); - - return (list); -} - - -/* - * main() calls the appropriate routine to parse the command line arguments - * and then calls the local remove routine, followed by the remote remove - * routine to remove jobs. - */ -int -main(int ac, char *av[]) -{ - int rc = 0; - char *program; - cancel_req_t **list = NULL; - - (void) setlocale(LC_ALL, ""); - -#if !defined(TEXT_DOMAIN) -#define TEXT_DOMAIN "SYS_TEST" -#endif - (void) textdomain(TEXT_DOMAIN); - - if ((program = strrchr(av[0], '/')) == NULL) - program = av[0]; - else - program++; - - openlog(program, LOG_PID, LOG_LPR); - - if (check_client_spool(NULL) < 0) { - (void) fprintf(stderr, - gettext("couldn't validate local spool area (%s)\n"), - SPOOL_DIR); - return (-1); - } - - if (strcmp(program, "lprm") == 0) - list = bsd_remove(ac, av); - else - list = sysv_remove(ac, av); - - (void) chdir(SPOOL_DIR); - if (list_iterate((void **)list, (VFUNC_T)vcancel_local, - get_user_name()) != 0) - start_daemon(1); - - rc = list_iterate((void **)list, (VFUNC_T)vcancel_remote, - ((all == 0) ? get_user_name() : "-all")); - - if (exit_code == 0) - exit_code = rc; - - return (exit_code); -} diff --git a/usr/src/cmd/print/cancel/cancel_list.c b/usr/src/cmd/print/cancel/cancel_list.c deleted file mode 100644 index d9ad68ebab..0000000000 --- a/usr/src/cmd/print/cancel/cancel_list.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 1998-2002 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <stdarg.h> -#include <string.h> -#include <syslog.h> -#ifndef SUNOS_4 -#include <libintl.h> -#endif - -#include <print/ns.h> -#include <print/network.h> -#include <print/misc.h> -#include <print/list.h> -#include <print/job.h> - -#include <cancel_list.h> - - -/* - * printer_compair() compares the printer name in the cancel request and the - * printer name passed in. If they match, 0 is returned. - */ -static int -printer_compair(cancel_req_t *cancel, char *printer) -{ - return (strcmp(cancel->printer, printer)); -} - -/* - * binding_compair() compares the binding in the cancel request and the - * binding passed in. If they match, 0 is returned. - */ -static int -binding_compair(cancel_req_t *cancel, ns_bsd_addr_t *binding) -{ - return (strcmp(cancel->binding->printer, binding->printer) || - strcmp(cancel->binding->server, binding->server)); -} - - -/* - * cancel_list_element() adds information to the cancel list. It either adds - * information to an existing cancel entry if the printers match, or - * adds a new entry to the cancel list. It returns the new list in either - * case. - */ -static cancel_req_t * -cancel_list_element(cancel_req_t ***list, char *printer) -{ - cancel_req_t *element = NULL; - - if ((element = (cancel_req_t *)list_locate((void **)*list, - (COMP_T)printer_compair, (void *)printer)) == NULL) { - if ((element = calloc(1, sizeof (*element))) != NULL) { - if ((element->binding = ns_bsd_addr_get_name(printer)) - == NULL) { - extern int exit_code; - - free(element); - if (strcmp(printer, NS_NAME_DEFAULT) == 0) - (void) fprintf(stderr, gettext( - "No default destination\n")); - else - (void) fprintf(stderr, gettext( - "%s: unknown printer\n"), - printer); - exit_code = -1; - return (NULL); - } - element->printer = strdup(printer); - *list = (cancel_req_t **)list_append((void **)*list, - (void *)element); - } - } - - return (element); -} - - -/* - * cancel_list_element_by_binding() returns an element in the cancel list - * passed in that matches the binding passed in. If none exists, then - * one is created, inserted and returned. - */ -static cancel_req_t * -cancel_list_element_by_binding(cancel_req_t ***list, ns_bsd_addr_t *binding) -{ - cancel_req_t *element = NULL; - - if ((element = (cancel_req_t *)list_locate((void **)*list, - (COMP_T)binding_compair, (void *)binding)) == NULL) { - if ((element = calloc(1, sizeof (*element))) != NULL) { - element->printer = strdup(binding->printer); - element->binding = binding; - *list = (cancel_req_t **)list_append((void **)*list, - (void *)element); - } - } - - return (element); -} - - -/* - * cancel_list_add_item() adds information to the cancel list. It either adds - * information to an existing cancel entry if the printers match, or - * adds a new entry to the cancel list. It returns the new list in either - * case. - */ -cancel_req_t ** -cancel_list_add_item(cancel_req_t **list, char *printer, char *item) -{ - cancel_req_t *element = NULL; - - if ((element = cancel_list_element(&list, printer)) != NULL) - element->list = (char **)list_append((void **)element->list, - (void *)item); - return (list); -} - - -/* - * cancel_list_add_list() adds information to the cancel list. It either adds - * information to an existing cancel entry if the printers match, or - * adds a new entry to the cancel list. It returns the new list in either - * case. - */ -cancel_req_t ** -cancel_list_add_list(cancel_req_t **list, char *printer, char **items) -{ - cancel_req_t *element = NULL; - - if ((element = cancel_list_element(&list, printer)) != NULL) - element->list = (char **)list_concatenate( - (void **)element->list, (void **)items); - return (list); -} - - -/* - * cancel_list_add_binding_list() adds information to the cancel list. It - * either adds information to an existing cancel entry if the bindings - * match, or adds a new entry to the cancel list. It returns the new - * list in either case. - */ -cancel_req_t ** -cancel_list_add_binding_list(cancel_req_t **list, ns_bsd_addr_t *binding, - char **items) -{ - cancel_req_t *element = NULL; - - if ((element = cancel_list_element_by_binding(&list, binding)) != NULL) - element->list = (char **)list_concatenate( - (void **)element->list, (void **)items); - return (list); -} diff --git a/usr/src/cmd/print/cancel/cancel_list.h b/usr/src/cmd/print/cancel/cancel_list.h deleted file mode 100644 index d535e0f3ff..0000000000 --- a/usr/src/cmd/print/cancel/cancel_list.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1998 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _CANCEL_LIST_H -#define _CANCEL_LIST_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct _cancel_req cancel_req_t; -struct _cancel_req { - char *printer; - ns_bsd_addr_t *binding; - char **list; -}; - -extern cancel_req_t ** cancel_list_add_item(cancel_req_t **list, char *printer, - char *item); -extern cancel_req_t ** cancel_list_add_list(cancel_req_t **list, char *printer, - char **items); -extern cancel_req_t ** cancel_list_add_binding_list(cancel_req_t **list, - ns_bsd_addr_t *binding, char **items); - -#ifdef __cplusplus -} -#endif - -#endif /* _CANCEL_LIST_H */ diff --git a/usr/src/cmd/print/gateway/Makefile b/usr/src/cmd/print/gateway/Makefile index 854e08ea98..59ecd07cae 100644 --- a/usr/src/cmd/print/gateway/Makefile +++ b/usr/src/cmd/print/gateway/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # pragma ident "%Z%%M% %I% %E% SMI" @@ -30,19 +29,29 @@ include ../Makefile.sp -MANIFEST= rfc1179.xml - +MANIFEST= rfc1179.xml cleanup.xml ROOTMANIFESTDIR= $(ROOTSVCAPPLICATIONPRINT) $(ROOTMANIFEST) := FILEMODE= 444 -SUBDIRS= translators +ROOTMETHOD= $(ROOTLIBSVCMETHOD)/print-cleanup +$(ROOTLIBSVCMETHOD)/print-cleanup := FILEMODE=555 -PROG= in.lpd +ROOTLIBPRINT= $(ROOTLIB)/print +$(ROOTLIBPRINT) := OWNER=root +$(ROOTLIBPRINT) := GROUP=lp -SRCS= main.c adaptor.c +PRINTDPROG= printd +PRINTDSRCS= printd.c +PRINTDOBJS= $(PRINTDSRCS:.c=.o) +$(PRINTDPROG) := LDLIBS += $(LIBNPRT) +$(ROOTLIBPRINT)/$(PRINTDPROG) := FILEMODE= 555 -OBJS= $(SRCS:.c=.o) +INLPDPROG= in.lpd +INLPDSRCS= main.c adaptor.c +INLPDOBJS= $(INLPDSRCS:.c=.o) +$(INLPDPROG) := LDLIBS += -lsocket -lnsl $(LIBNPRT) +SUBDIRS= translators FILEMODE= 0555 OWNER= root @@ -50,31 +59,39 @@ GROUP= bin CPPFLAGS += -I. -I$(NPRTINC) #$(CPPFLAGS.master) -LDLIBS += -lsocket -lnsl $(LIBNPRT) .KEEP_STATE: -all: $(PROG) $(SUBDIRS) +all: $(PRINTDPROG) $(INLPDPROG) $(SUBDIRS) + +$(PRINTDPROG): $(PRINTDOBJS) + $(LINK.c) $(PRINTDOBJS) -o $@ $(LDLIBS) + $(POST_PROCESS) -$(PROG): $(OBJS) - $(LINK.c) $(OBJS) -o $@ $(LDLIBS) +$(INLPDPROG): $(INLPDOBJS) + $(LINK.c) $(INLPDOBJS) -o $@ $(LDLIBS) $(POST_PROCESS) -install: all $(ROOTLIBPRINTPROG) $(SUBDIRS) $(ROOTMANIFEST) +ROOTLIBPRINTPROG= $(PRINTDPROG:%=$(ROOTLIBPRINT)/%) \ + $(INLPDPROG:%=$(ROOTLIBPRINT)/%) + +install: all $(ROOTLIBPRINTPROG) $(SUBDIRS) $(ROOTMANIFEST) \ + $(ROOTMETHOD) $(ROOTLIBPRINT) check: $(CHKMANIFEST) strip: $(SUBDIRS) - $(STRIP) $(PROG) + $(STRIP) $(PRINTDPROG) $(INLPDPROG) cstyle: - cstyle $(SRCS) + cstyle $(PRINTDSRCS) $(INLPDSRCS) lint: - $(LINT.c) $(SRCS) $(LDLIBS) + $(LINT.c) $(PRINTDSRCS) $(LDLIBS) + $(LINT.c) $(INLPDSRCS) $(LDLIBS) clean clobber: $(SUBDIRS) - $(RM) $(OBJS) + $(RM) $(PRINTDOBJS) $(INLPDOBJS) _msg: @echo "Messages are made in usr/src/cmd/print" @@ -83,3 +100,18 @@ $(SUBDIRS): FRC @cd $@; pwd; $(MAKE) $(TARGET) FRC: + + + +# +# PRINTSYMLINK= $(ROOTLIB)/print/printd +# +# FILEMODE= 04511 +# OWNER= root +# +# CPPFLAGS += -I$(NPRTINC) +# LDLIBS += $(LIBNPRT) +# +# install: all $(ROOTBIN) $(ROOTLIB)/print $(ROOTBINPROG) \ +# $(ROOTUSRBINSYMLINK) $(ROOTUSRUCBSYMLINK) $(PRINTSYMLINK) \ +# $(ROOTMANIFEST) $(ROOTMETHOD) diff --git a/usr/src/cmd/print/gateway/adaptor.c b/usr/src/cmd/print/gateway/adaptor.c index 8bb14c148b..e53e92bca7 100644 --- a/usr/src/cmd/print/gateway/adaptor.c +++ b/usr/src/cmd/print/gateway/adaptor.c @@ -37,7 +37,7 @@ #include <syslog.h> #include <adaptor.h> -#include <print/ns.h> +#include <ns.h> #ifndef RTLD_GLOBAL /* for OSF/1 */ #define RTLD_GLOBAL 0 diff --git a/usr/src/cmd/print/lp/cleanup.xml b/usr/src/cmd/print/gateway/cleanup.xml index 50118847d2..50118847d2 100644 --- a/usr/src/cmd/print/lp/cleanup.xml +++ b/usr/src/cmd/print/gateway/cleanup.xml diff --git a/usr/src/cmd/print/lp/print-cleanup b/usr/src/cmd/print/gateway/print-cleanup index 7780bcd68b..7780bcd68b 100644 --- a/usr/src/cmd/print/lp/print-cleanup +++ b/usr/src/cmd/print/gateway/print-cleanup diff --git a/usr/src/cmd/print/gateway/printd.c b/usr/src/cmd/print/gateway/printd.c new file mode 100644 index 0000000000..d94ea5cbcb --- /dev/null +++ b/usr/src/cmd/print/gateway/printd.c @@ -0,0 +1,336 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <ctype.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <sys/systeminfo.h> +#include <sys/param.h> +#include <stdarg.h> +#include <signal.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <syslog.h> +#include <termios.h> +#include <libintl.h> +#include <locale.h> +#include <pwd.h> +#include <grp.h> + +#include <ns.h> +#include <network.h> +#include <misc.h> +#include <list.h> +#include <job.h> + +static int connection_failed = 0; + +/* + * lpr/lp + * This program will submit print jobs to a spooler using the BSD + * printing protcol as defined in RFC1179, plus some extension for + * support of additional lp functionality. + */ + +#define SEND_RETRY -1 +#define SEND_ABORT -2 + +/*ARGSUSED*/ +static void sigpipe_handler(int i) +{ + syslog(LOG_ERR, "Warning: Received SIGPIPE; continuing"); + (void) signal(SIGPIPE, sigpipe_handler); +} + +static int +sendfile(jobfile_t *file, int nd, int type) +{ + int rc = -1; + + syslog(LOG_DEBUG, "sendfile(%s, %d, %d)", + ((file != NULL) ? file->jf_spl_path : "NULL"), nd, type); + if (file && file->jf_spl_path) { + rc = net_send_file(nd, file->jf_spl_path, file->jf_data, + file->jf_size, type); + } + return (rc); +} + + +/* + * send_job() sends a job to a remote print server. + */ +static int +send_job(job_t *job) +{ + int lockfd, + lock_size, + nd, + tmp, + rc = 0; + struct passwd *p = NULL; + char buf[BUFSIZ]; + + syslog(LOG_DEBUG, "send_job(%s, %s, %d): called", job->job_printer, + job->job_server, job->job_id); + if ((lockfd = get_lock(job->job_cf->jf_src_path, 0)) < 0) { + (void) close(lockfd); + return (SEND_RETRY); + } + + /* is job complete ? */ + + lock_size = file_size(job->job_cf->jf_src_path); + (void) sprintf(buf, "%ld\n", getpid()); /* add pid to lock file */ + (void) lseek(lockfd, 0, SEEK_END); + (void) write(lockfd, buf, strlen(buf)); + + syslog(LOG_DEBUG, "send_job(%s, %s, %d): have lock", job->job_printer, + job->job_server, job->job_id); + connection_failed = 0; + if ((nd = net_open(job->job_server, 5)) < 0) { + connection_failed = 1; + if ((nd != NETWORK_ERROR_UNKNOWN) && (nd != NETWORK_ERROR_PORT)) + job_destroy(job); + else + (void) ftruncate(lockfd, lock_size); + (void) close(lockfd); + return ((nd == NETWORK_ERROR_UNKNOWN) || + (nd == NETWORK_ERROR_PORT) ? SEND_RETRY : SEND_ABORT); + } + + if (net_send_message(nd, "%c%s\n", XFER_REQUEST, job->job_printer) + != 0) { + (void) net_close(nd); + syslog(LOG_WARNING, + "send_job failed job %d (%s@%s) check status\n", + job->job_id, job->job_printer, job->job_server); + (void) ftruncate(lockfd, lock_size); + (void) close(lockfd); + return (SEND_RETRY); + } + + syslog(LOG_DEBUG, "send_job(%s, %s, %d): send data", job->job_printer, + job->job_server, job->job_id); + + if ((p = getpwnam(job->job_user)) != NULL) { + /* + * attempt to become the job owner: uid, euid, gid, and + * supplementary groups while we try to send the job data. + * The real uid is changed with setreuid() separately from + * changing the effective uid so that we retain the saved + * uid to elevate privilege later. Combining these changes + * would result in a change to the saved uid also and a loss + * of the ability to elevate privilege later. + */ + (void) setuid(0); + (void) initgroups(job->job_user, p->pw_gid); + (void) setgid(p->pw_gid); + (void) setreuid(p->pw_uid, -1); + (void) seteuid(p->pw_uid); + } + + for (tmp = 0; job->job_df_list[tmp] != NULL; tmp++) + if ((rc = sendfile(job->job_df_list[tmp], nd, XFER_DATA)) < 0) + break; /* there was an error, quit now */ + tmp = errno; + if (p != NULL) { + /* + * lose the supplemental groups and elevate our effective + * uid to root so that we can destroy jobs and/or become + * other job owners later on. + */ + (void) seteuid(0); + (void) initgroups("root", 1); + } + errno = tmp; + + if (rc < 0) { + if (errno == ENOENT) { + (void) net_close(nd); + job_destroy(job); + (void) close(lockfd); + return (SEND_ABORT); + } else if (errno == EACCES) { + /* probably trying to circumvent file security */ + (void) net_close(nd); + job_destroy(job); + (void) close(lockfd); + return (SEND_ABORT); + } else { + (void) net_close(nd); + (void) ftruncate(lockfd, lock_size); + (void) close(lockfd); + return (SEND_RETRY); + } + } + + if (sendfile(job->job_cf, nd, XFER_CONTROL) < 0) { + (void) net_send_message(nd, "%c\n", XFER_CLEANUP); + (void) net_close(nd); + (void) ftruncate(lockfd, lock_size); + (void) close(lockfd); + return (SEND_RETRY); + } + + syslog(LOG_DEBUG, "send_job(%s, %s, %d): complete", job->job_printer, + job->job_server, job->job_id); + (void) net_close(nd); + job_destroy(job); + (void) close(lockfd); + return (0); +} + + +/* + * xfer_daemon() attempts to start up a daemon for transfering jobs to a remote + * print server. The daemon runs if it can get the master lock, and it + * runs until there are no jobs waiting for transfer. + */ +static void +xfer_daemon() +{ + job_t **list = NULL; + int i, + rc; + + + + closelog(); + closefrom(0); + + (void) open("/dev/null", O_RDONLY); + (void) open("/dev/null", O_WRONLY); + (void) dup(1); + + (void) setuid(0); + (void) setsid(); + openlog("printd", LOG_PID, LOG_LPR); + if (fork() != 0) + exit(0); + + if ((i = get_lock(MASTER_LOCK, 1)) < 0) + exit(0); + + (void) chdir(SPOOL_DIR); + while ((list = job_list_append(NULL, NULL, NULL, SPOOL_DIR)) != NULL) { + job_t **tmp; + + syslog(LOG_DEBUG, "got the queue..."); + for (tmp = list; *tmp != NULL; tmp++) { + /* + * Bugid: 4133175 printd dies when data is removed or + * permissions are changed. Memory is freed twice. + * Fix: Do not process anything else in the list + * if the return code is SEND_ABORT as the memory + * has already been freed by job_destroy(). + */ + rc = send_job(*tmp); + if ((rc != 0) && (rc != SEND_ABORT)) { + char *s = strdup((*tmp)->job_server); + char *p = strdup((*tmp)->job_printer); + + if (rc != SEND_ABORT) /* already free */ + job_free(*tmp); + + for (tmp++; ((*tmp != NULL) && + (strcmp(s, (*tmp)->job_server) == 0)); + tmp++) + if ((connection_failed == 0) && + (strcmp(p, + (*tmp)->job_printer) == 0)) + job_free(*tmp); + else + break; + tmp--; + free(s); + free(p); + } + } + free(list); + + /* look for more work to do before we sleep */ + if ((list = job_list_append(NULL, NULL, NULL, + SPOOL_DIR)) != NULL) { + (void) list_iterate((void **)list, (VFUNC_T)job_free); + free(list); + (void) sleep(60); + } + } + syslog(LOG_DEBUG, "daemon exiting..."); +} + +int +main(int ac, char *av[]) +{ + ns_bsd_addr_t *binding = NULL; + int numFiles = 0, + queueStdin = 0, + exit_code = 0; + char *program, + *user, + hostname[128], + buf[BUFSIZ]; + job_t *job; + + (void) setlocale(LC_ALL, ""); + +#if !defined(TEXT_DOMAIN) +#define TEXT_DOMAIN "SYS_TEST" +#endif + (void) textdomain(TEXT_DOMAIN); + + if ((program = strrchr(av[0], '/')) == NULL) + program = av[0]; + else + program++; + + openlog(program, LOG_PID, LOG_LPR); + + /* + * Bugid: 4013980 Application changed fd 1 to a pipe that has + * no reader; we write to stdout and catch a sigpipe and exit. + * Fix: catch signal, complain to syslog, and continue. + */ + (void) signal(SIGPIPE, sigpipe_handler); + + if (check_client_spool(NULL) < 0) { + (void) fprintf(stderr, + gettext("couldn't validate local spool area (%s)\n"), + SPOOL_DIR); + return (-1); + } + + xfer_daemon(); + + exit(0); +} diff --git a/usr/src/cmd/print/gateway/translators/cascade/cascade.c b/usr/src/cmd/print/gateway/translators/cascade/cascade.c index 07372cdb99..8e50a9b0d7 100644 --- a/usr/src/cmd/print/gateway/translators/cascade/cascade.c +++ b/usr/src/cmd/print/gateway/translators/cascade/cascade.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -39,11 +38,11 @@ #include <unistd.h> #include <libintl.h> -#include <print/ns.h> -#include <print/job.h> -#include <print/list.h> -#include <print/misc.h> -#include <print/network.h> +#include <ns.h> +#include <job.h> +#include <list.h> +#include <misc.h> +#include <network.h> static ns_printer_t *printer_object = NULL; diff --git a/usr/src/cmd/print/gateway/translators/test/test.c b/usr/src/cmd/print/gateway/translators/test/test.c index 243da2f740..1749e5c2e8 100644 --- a/usr/src/cmd/print/gateway/translators/test/test.c +++ b/usr/src/cmd/print/gateway/translators/test/test.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1998 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -35,7 +34,7 @@ #include <stdarg.h> #include <syslog.h> -#include <print/ns.h> +#include <ns.h> static ns_printer_t *printer_object = NULL; diff --git a/usr/src/cmd/print/lp/Makefile b/usr/src/cmd/print/lp/Makefile deleted file mode 100644 index 3e813bb0a2..0000000000 --- a/usr/src/cmd/print/lp/Makefile +++ /dev/null @@ -1,97 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# -# cmd/lp/client/lp/Makefile -# - -include ../Makefile.sp - -PROG= lp - -MANIFEST= cleanup.xml - -SRCS= $(PROG).c - -ROOTMANIFESTDIR= $(ROOTSVCAPPLICATIONPRINT) -ROOTMETHOD= $(ROOTLIBSVCMETHOD)/print-cleanup -$(ROOTMANIFEST) := FILEMODE= 444 - -OBJS= $(SRCS:.c=.o) - -ROOTBINPROG= $(PROG:%=$(ROOTBIN)/%) -ROOTUSRBINSYMLINK= $(ROOTBIN)/lpr -ROOTUSRUCBSYMLINK= $(ROOTUSRUCB)/lpr -PRINTSYMLINK= $(ROOTLIB)/print/printd -$(ROOTLIB)/print := OWNER=root -$(ROOTLIB)/print := GROUP=lp -$(ROOTLIBSVCMETHOD)/print-cleanup := FILEMODE=555 - -FILEMODE= 04511 -OWNER= root - -CPPFLAGS += -I$(NPRTINC) -LDLIBS += $(LIBNPRT) - -.KEEP_STATE: - -all: $(PROG) - -install: all $(ROOTBIN) $(ROOTLIB)/print $(ROOTBINPROG) \ - $(ROOTUSRBINSYMLINK) $(ROOTUSRUCBSYMLINK) $(PRINTSYMLINK) \ - $(ROOTMANIFEST) $(ROOTMETHOD) - -check: $(CHKMANIFEST) - -$(ROOTBIN) $(ROOTLIB)/print: - $(INS.dir) - -$(ROOTUSRBINSYMLINK): - $(RM) $@; $(SYMLINK) $(PROG) $@ - -$(ROOTUSRUCBSYMLINK): - $(RM) $@; $(SYMLINK) ../bin/lpr $@ - -$(PRINTSYMLINK): - $(RM) $@; $(SYMLINK) ../../bin/$(PROG) $@ - -strip: - $(STRIP) $(PROG) - -lint: - $(LINT.c) $(PROG).c $(LDLIBS) - -cstyle: - cstyle $(SRCS) - -_msg: - @echo "Messages are made in usr/src/cmd/print" - -clean: - $(RM) $(OBJS) - -clobber: clean - -$(RM) $(PROG) $(CLOBBERFILES) diff --git a/usr/src/cmd/print/lp/lp.c b/usr/src/cmd/print/lp/lp.c deleted file mode 100644 index dce11659f7..0000000000 --- a/usr/src/cmd/print/lp/lp.c +++ /dev/null @@ -1,1281 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <ctype.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <sys/systeminfo.h> -#include <sys/param.h> -#include <stdarg.h> -#include <signal.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <syslog.h> -#include <termios.h> -#include <libintl.h> -#include <locale.h> -#include <pwd.h> -#include <grp.h> - -#include <print/ns.h> -#include <print/network.h> -#include <print/misc.h> -#include <print/list.h> -#include <print/job.h> - -/* - * lpr/lp - * This program will submit print jobs to a spooler using the BSD - * printing protcol as defined in RFC1179, plus some extension for - * support of additional lp functionality. - */ - -extern char *optarg; -extern int optind, opterr, optopt; -extern char *getenv(const char *); - -#define SEND_RETRY -1 -#define SEND_ABORT -2 - - -static int priority = -1, - copies = 1, - width = -1, /* pr width */ - indent = -1, /* pr indent */ - linked = 0, - mail = 0, - delete = 0, - suppress = 1, - banner = 1, - connection_failed = 0; -static char *printer = NULL, - *form = NULL, - *charset = NULL, - *title = NULL, /* pr title */ - *class = NULL, - *jobName = NULL, - *notification = NULL, - *handling = NULL, - *pages = NULL, - **mode = NULL, - **s5options = NULL, - *s5type = NULL, - *internal_type = NULL, - *fontR = NULL, - *fontI = NULL, - *fontB = NULL, - *fontS = NULL, - type = CF_PRINT_ASCII; - -static struct s5_types { - char *name; - char type; -} output_types[] = { /* known LP "-T" types */ -/* - * Switched to ASCII, because some BSD systems don't like the 'o' file - * type. - */ - { "postscript", CF_PRINT_ASCII }, - { "ps", CF_PRINT_ASCII }, - { "simple", CF_PRINT_ASCII }, - { "ascii", CF_PRINT_ASCII }, - { "raw", CF_PRINT_RAW }, - { "dvi", CF_PRINT_DVI }, - { "tex", CF_PRINT_DVI }, - { "raster", CF_PRINT_RAS }, - { "ditroff", CF_PRINT_DROFF }, - { "otroff", CF_PRINT_TROFF }, - { "troff", CF_PRINT_DROFF }, - { "cif", CF_PRINT_CIF }, - { "plot", CF_PRINT_PLOT }, - { "fortran", CF_PRINT_FORT }, - { "pr", CF_PRINT_PR }, - NULL -}; - -/*ARGSUSED*/ -static void sigbus_handler(int i) -{ - (void) fprintf(stderr, - gettext("No space in /var/spool/print to store job")); - exit(-1); -} - -/*ARGSUSED*/ -static void sigpipe_handler(int i) -{ - syslog(LOG_ERR, "Warning: Received SIGPIPE; continuing"); - (void) signal(SIGPIPE, sigpipe_handler); -} - - -#define OLD_LP "/usr/lib/lp/local/lp" /* for local lpsched printers */ -#ifdef OLD_LP -/* - * this will submit the job to a local lpsched using the old interface. - * the argument vector is rebuilt with a new destination, because - * the old name may have been an alias or because it was actually - * lpr(1b) that was called. - */ -static void -submit_local_lp(char *program, int ac, char *av[]) -{ - uid_t ruid = getuid(); - struct passwd *pw; - int argc = 0; - char **argv; - - /* - * We allocate the space for ac+5 items, which include all the file - * arguments(ac), generic arguments(OLD_LP, "-d" and "printer") and - * "-s" option of lpr. The extra item is just a cushion. - */ - if ((argv = (char **)calloc(ac + 5, sizeof (char *))) == NULL) { - (void) fprintf(stderr, - gettext("not enough memory for argument vector\n")); - exit(1); - } - argv[argc++] = OLD_LP; - argv[argc++] = "-d"; - argv[argc++] = printer; - - if (strcmp(program, "lp") == 0) { - int i = 0; - - while (++i < ac) - if (strncmp(av[i], "-d", 2) != 0) { - argv[argc++] = av[i]; - } else if (strlen(av[i]) == 2) - i++; - } else { /* convert lpr options */ - argv[argc++] = "-s"; /* supress id message */ - - if (linked == 0) - argv[argc++] = "-c"; - - if (copies > 1) { - char buf[12]; - (void) sprintf(buf, "%d", copies); - argv[argc++] = "-n"; - argv[argc++] = strdup(buf); - } - if (banner == 0) { - argv[argc++] = "-o"; - argv[argc++] = "nobanner"; - } - if (title != NULL) { - char buf[BUFSIZ]; - (void) snprintf(buf, sizeof (buf), "prtitle='%s'", - title); - argv[argc++] = "-y"; - argv[argc++] = strdup(buf); - } - if (width > 0) { - char buf[16]; - (void) sprintf(buf, "prwidth=%d", width); - argv[argc++] = "-y"; - argv[argc++] = strdup(buf); - } - if (indent > 0) { - char buf[16]; - (void) sprintf(buf, "indent=%d", indent); - argv[argc++] = "-y"; - argv[argc++] = strdup(buf); - } - if (mail != 0) - argv[argc++] = "-m"; - if ((jobName != NULL) || (class != NULL)) { - char buf[128]; - snprintf(buf, sizeof (buf), "%s%s%s", - (jobName ? jobName : ""), - (jobName && class ? "\\n#####\\n#####\\t\\t " - : ""), (class ? class : "")); - argv[argc++] = "-t"; - argv[argc++] = strdup(buf); - } - - if (type != CF_PRINT_ASCII) { - struct s5_types *tmp; - - for (tmp = output_types; tmp->name != NULL; tmp++) - if (tmp->type == type) { - argv[argc++] = "-T"; - argv[argc++] = tmp->name; - break; - } - } - - while (optind < ac) - argv[argc++] = av[optind++]; - - } - - ruid = getuid(); - if ((pw = getpwuid(ruid)) != NULL) - (void) initgroups(pw->pw_name, pw->pw_gid); - (void) setuid(ruid); - - argv[argc++] = NULL; - (void) execv(OLD_LP, argv); -} -#endif - - -/* - * cheat and look in the LP interface to determine if a local printer is - * rejecting. If so, don't queue the job. If the printer is remote or - * accepting, queue it. This approximates behaviour of previous releases - * The check is being done this way for performance. - */ -static int -rejecting(char *printer) -{ - int rc = 0, found = 0; - FILE *fp; - - if ((fp = fopen("/usr/spool/lp/system/pstatus", "r+")) != NULL) { - char buf[BUFSIZ]; - - while (fgets(buf, sizeof (buf), fp) != NULL) { - buf[strlen(buf)-1] = NULL; - if (strcmp(buf, printer) == 0) { - char *ptr; - - found = 1; - (void) fgets(buf, sizeof (buf), fp); - buf[strlen(buf)-1] = NULL; - ptr = strrchr(buf, ' '); - if (ptr && (strcmp(++ptr, "rejecting") == 0)) { - rc = 1; - break; - } - } - } - } - (void) fclose(fp); - - /* if we have'nt found the name it could be a class */ - if (!found) { - if ((fp = fopen("/usr/spool/lp/system/cstatus", - "r+")) != NULL) { - - char buf2[BUFSIZ]; - - while (fgets(buf2, sizeof (buf2), fp) != NULL) { - buf2[strlen(buf2)-1] = NULL; - if (strcmp(buf2, printer) == 0) { - fgets(buf2, sizeof (buf2), fp); - buf2[strlen(buf2)-1] = NULL; - if (strcmp(buf2, "rejecting") == 0) { - rc = 1; - break; - } - } - } - - } - } - - (void) fclose(fp); - return (rc); -} - -/* - * Remove special characters before popen (change them into '_'). - */ -static void -clean_string(char *ptr) -{ - char *cp; - wchar_t wc; - int len; - - for (cp = ptr; *cp != NULL; ) { - if ((len = mbtowc(&wc, cp, MB_CUR_MAX)) == -1) { - cp++; - continue; - } - - if (len == 1 && - ((wc == L'`') || (wc == L'&') || (wc == L';') || - (wc == L'|') || (wc == L'>') || (wc == L'^') || - (wc == L'$') || (wc == L'(') || (wc == L')') || - (wc == L'<') || (wc == L'*') || (wc == L'?') || - (wc == L'['))) - *cp = '_'; - cp += len; - } -} - - -static int _notified = 0; - -static void -error_notify(char *user, int id, char *msg, ...) -{ - if (_notified++ == 0) { - char *tmp; - char cmd[BUFSIZ]; - FILE *fp; - va_list ap; - - va_start(ap, msg); - tmp = strdup(user); - clean_string(tmp); - (void) snprintf(cmd, sizeof (cmd), - "/bin/write %s >/dev/null 2>&1", tmp); - free(tmp); - fp = popen(cmd, "w+"); - (void) fprintf(fp, - gettext("\n\tError transfering print job %d\n"), id); - (void) vfprintf(fp, msg, ap); - (void) pclose(fp); - va_end(ap); - } -} - - - -/* - * bsd_options() parses the command line using the BSD lpr semantics and sets - * several global variables for use in building the print request. - */ -static void -bsd_options(int ac, char *av[]) -{ - int c; - - while ((c = getopt(ac, av, - "P:#:C:J:T:w:i:hplrstdgvcfmn1:2:3:4:")) != EOF) - switch (c) { - case 'P': - printer = optarg; - break; - case '#': - copies = atoi(optarg); - break; - case 'C': - class = optarg; - break; - case 'J': - jobName = optarg; - break; - case 'T': - title = optarg; - break; - case 'w': - width = atoi(optarg); - break; - case 'm': - mail++; - break; - case 'i': /* this may or may not have an arguement */ - if (isdigit(optarg[0]) == 0) { - indent = 8; - optind--; - } else - indent = atoi(optarg); - break; - case 'h': - banner = 0; - break; - case 'r': - delete = 1; - break; - case 's': - linked = 1; - break; - case 'l' : - type = CF_PRINT_RAW; - break; - case 'd' : - type = CF_PRINT_DVI; - break; - case 't' : - type = CF_PRINT_TROFF; - break; - case 'g' : - type = CF_PRINT_PLOT; - break; - case 'v' : - type = CF_PRINT_RAS; - break; - case 'c' : - type = CF_PRINT_CIF; - break; - case 'f' : - type = CF_PRINT_FORT; - break; - case 'n' : - type = CF_PRINT_DROFF; - break; - case 'o' : - type = CF_PRINT_PS; - break; - case 'p' : - type = CF_PRINT_PR; - break; - case '1' : - fontR = optarg; - break; - case '2' : - fontI = optarg; - break; - case '3' : - fontB = optarg; - break; - case '4' : - fontS = optarg; - break; - default: - (void) fprintf(stderr, - gettext("Usage: %s [-Pprinter] [-#num] " - "[-Cclass] [-Jjob] [-Ttitle] [-i [indent]] " - "[-1234 font] [-wcols] [-m] [-h] [-s] " - "[-pltndgvcf] files ...\n"), - av[0]); - exit(1); - } - - /* - * The pr filter must be specified with the - * title, width, and indent options - */ - if ((title != NULL) && (type != CF_PRINT_PR)) - (void) fprintf(stderr, gettext( - "Warning: title option ignored as the pr " - "filter option was not specified\n")); - if ((width > 0) && (type != CF_PRINT_PR)) - (void) fprintf(stderr, gettext( - "Warning: width option ignored as the pr " - "filter option was not specified\n")); - if ((indent > 0) && (type != CF_PRINT_PR)) - (void) fprintf(stderr, gettext( - "Warning: indent option ignored as the pr " - "filter option was not specified\n")); -} - -/* - * sysv_options() parses the command line using the BSD lpr semantics and sets - * several global variables for use in building the print request. - */ -static void -sysv_options(int ac, char *av[]) -{ - int c; - -#ifdef OLD_LP - if ((ac > 2) && (strcmp(av[1], "-i") == 0)) { - if (access(OLD_LP, F_OK) == 0) { - /* - * limit ourselves to real user's perms before exec'ing - */ - (void) setuid(getuid()); - (void) execv(OLD_LP, av); - perror("exec local modify"); - } else - (void) printf(gettext( - "job modification not supported on clients\n")); - exit(-1); - } -#endif - - linked = 1; - suppress = 0; - while ((c = getopt(ac, av, "H:P:S:T:d:f:i:o:q:t:y:cmwn:prs")) != EOF) - switch (c) { - case 'q': - priority = atoi(optarg); - break; - case 'H': - handling = optarg; - break; - case 'f': - form = optarg; - break; - case 'd': - printer = optarg; - break; - case 'T': - { - struct s5_types *tmp; - int flag = 0; - - for (tmp = output_types; - ((flag == 0) && (tmp->name != NULL)); tmp++) - if (strcasecmp(tmp->name, optarg) == 0) { - type = tmp->type; - flag++; - } - if (flag == 0) - s5type = optarg; - else - internal_type = optarg; - break; - } - case 'S': - charset = optarg; - break; - case 'o': - { - char *p, *q = strdup(optarg); - - /* - * -o nobanner will no longer generate a warning or - * Onobanner in the control file. If "nobanner" is - * embedded in an option list, the option list will - * still generate a warning or 'O' message in the - * control file. - */ - if (strcmp("nobanner", optarg) != 0) - s5options = (char **)list_append( - (void**)s5options, - (void *)strdup(optarg)); - - for (p = strtok(q, "\t ,"); p != NULL; - p = strtok(NULL, "\t ,")) - if (strcmp(p, "nobanner") == 0) { - banner = 0; - break; - } - } - break; - case 'y': - { - char *p, *q = strdup(optarg); - - for (p = strtok(q, "\t ,"); p != NULL; - p = strtok(NULL, "\t ,")) - if (strcmp(p, "catv_filter") == 0) - type = CF_PRINT_RAW; - else - mode = (char **)list_append( - (void **)mode, - (void *)p); - } - break; - case 'P': - pages = optarg; - break; - case 'i': - (void) printf(gettext( - "job modification (-i) only supported on server\n")); - break; - case 'c': - linked = 0; - break; - case 'm': - mail++; - break; - case 'w': - mail++; - break; - case 'p': - notification = optarg; - break; - case 'n': - if ((optarg == 0) || (*optarg == '-')) { - (void) fprintf(stderr, gettext( - "-n requires a positive integer argument\n")); - exit(1); - } - copies = atoi(optarg); - break; - case 's': - suppress = 1; - break; - case 't': - jobName = optarg; - break; - case 'r': - /* not supported - raw */ - break; - default: - (void) fprintf(stderr, - gettext("Usage: %s [-d dest] [-cmwsr] [-n num] " - "[-t title] [-p notification] [-P page-list] " - "[-i job-id] [y modes] [-o options] " - "[-S char-set] [-T input-type] [H handling] " - "[-q priority] files ...\n"), - av[0]); - exit(1); - } -} - - -/* - * stdin_to_file() reads standard input into a file and returns the file name - * to the caller - */ -static char * -stdin_to_file() -{ - int fd, - rc; - char *name, - buf[BUFSIZ]; - - (void) putenv("TMPDIR="); /* stop user moving the temp file */ - - snprintf(buf, sizeof (buf), "/tmp/stdinXXXXXX"); - if ((fd = mkstemp(buf)) < 0) - return (NULL); - fchmod(fd, 0640); - if ((name = strdup(buf)) == NULL) { - close(fd); - return (NULL); - } - syslog(LOG_DEBUG, "stdin_to_file: %s", name); - while ((rc = read(0, buf, sizeof (buf))) > 0) - (void) write(fd, buf, rc); - (void) close(fd); - return (name); -} - - -static int -sendfile(jobfile_t *file, int nd, int type) -{ - int rc = -1; - - syslog(LOG_DEBUG, "sendfile(%s, %d, %d)", - ((file != NULL) ? file->jf_spl_path : "NULL"), nd, type); - if (file && file->jf_spl_path) { - rc = net_send_file(nd, file->jf_spl_path, file->jf_data, - file->jf_size, type); - } - return (rc); -} - - -/* - * send_job() sends a job to a remote print server. - */ -static int -send_job(job_t *job) -{ - int lockfd, - lock_size, - nd, - tmp, - rc = 0; - struct passwd *p = NULL; - char buf[BUFSIZ]; - - syslog(LOG_DEBUG, "send_job(%s, %s, %d): called", job->job_printer, - job->job_server, job->job_id); - if ((lockfd = get_lock(job->job_cf->jf_src_path, 0)) < 0) { - (void) close(lockfd); - return (SEND_RETRY); - } - - /* is job complete ? */ - - lock_size = file_size(job->job_cf->jf_src_path); - (void) sprintf(buf, "%ld\n", getpid()); /* add pid to lock file */ - (void) lseek(lockfd, 0, SEEK_END); - (void) write(lockfd, buf, strlen(buf)); - - syslog(LOG_DEBUG, "send_job(%s, %s, %d): have lock", job->job_printer, - job->job_server, job->job_id); - connection_failed = 0; - if ((nd = net_open(job->job_server, 5)) < 0) { - connection_failed = 1; - if ((nd != NETWORK_ERROR_UNKNOWN) && (nd != NETWORK_ERROR_PORT)) - job_destroy(job); - else - (void) ftruncate(lockfd, lock_size); - (void) close(lockfd); - return ((nd == NETWORK_ERROR_UNKNOWN) || - (nd == NETWORK_ERROR_PORT) ? SEND_RETRY : SEND_ABORT); - } - - if (net_send_message(nd, "%c%s\n", XFER_REQUEST, job->job_printer) - != 0) { - (void) net_close(nd); - syslog(LOG_WARNING, - "send_job failed job %d (%s@%s) check status\n", - job->job_id, job->job_printer, job->job_server); - error_notify(job->job_user, job->job_id, - gettext("\t\t check queue for (%s@%s)\n"), - job->job_printer, job->job_server); - (void) ftruncate(lockfd, lock_size); - (void) close(lockfd); - return (SEND_RETRY); - } - - syslog(LOG_DEBUG, "send_job(%s, %s, %d): send data", job->job_printer, - job->job_server, job->job_id); - - if ((p = getpwnam(job->job_user)) != NULL) { - /* - * attempt to become the job owner: uid, euid, gid, and - * supplementary groups while we try to send the job data. - * The real uid is changed with setreuid() separately from - * changing the effective uid so that we retain the saved - * uid to elevate privilege later. Combining these changes - * would result in a change to the saved uid also and a loss - * of the ability to elevate privilege later. - */ - (void) setuid(0); - (void) initgroups(job->job_user, p->pw_gid); - (void) setgid(p->pw_gid); - (void) setreuid(p->pw_uid, -1); - (void) seteuid(p->pw_uid); - } - - for (tmp = 0; job->job_df_list[tmp] != NULL; tmp++) - if ((rc = sendfile(job->job_df_list[tmp], nd, XFER_DATA)) < 0) - break; /* there was an error, quit now */ - tmp = errno; - if (p != NULL) { - /* - * lose the supplemental groups and elevate our effective - * uid to root so that we can destroy jobs and/or become - * other job owners later on. - */ - (void) seteuid(0); - (void) initgroups("root", 1); - } - errno = tmp; - - if (rc < 0) { - if (errno == ENOENT) { - (void) net_close(nd); - error_notify(job->job_user, job->job_id, gettext( - "\t\tdata removed before transfer, job " - "canceled.\n\t\tTry \"lp -c\" or \"lpr\"\n")); - job_destroy(job); - (void) close(lockfd); - return (SEND_ABORT); - } else if (errno == EACCES) { - /* probably trying to circumvent file security */ - (void) net_close(nd); - error_notify(job->job_user, job->job_id, gettext( - "\t\tunable to read job data.\n")); - job_destroy(job); - (void) close(lockfd); - return (SEND_ABORT); - } else { - (void) net_close(nd); - (void) ftruncate(lockfd, lock_size); - error_notify(job->job_user, job->job_id, - gettext("\t\t check queue for (%s@%s)\n"), - job->job_printer, job->job_server); - (void) close(lockfd); - return (SEND_RETRY); - } - } - - if (sendfile(job->job_cf, nd, XFER_CONTROL) < 0) { - (void) net_send_message(nd, "%c\n", XFER_CLEANUP); - (void) net_close(nd); - (void) ftruncate(lockfd, lock_size); - error_notify(job->job_user, job->job_id, - gettext("\t\t check queue for (%s@%s)\n"), - job->job_printer, job->job_server); - (void) close(lockfd); - return (SEND_RETRY); - } - - syslog(LOG_DEBUG, "send_job(%s, %s, %d): complete", job->job_printer, - job->job_server, job->job_id); - (void) net_close(nd); - job_destroy(job); - (void) close(lockfd); - return (0); -} - - -/* - * xfer_daemon() attempts to start up a daemon for transfering jobs to a remote - * print server. The daemon runs if it can get the master lock, and it - * runs until there are no jobs waiting for transfer. - */ -static void -xfer_daemon() -{ - job_t **list = NULL; - int i, - rc; - - - - closelog(); - closefrom(0); - - _notified = 1; - (void) open("/dev/null", O_RDONLY); - (void) open("/dev/null", O_WRONLY); - (void) dup(1); - - (void) setuid(0); - (void) setsid(); - openlog("printd", LOG_PID, LOG_LPR); - if (fork() != 0) - exit(0); - - if ((i = get_lock(MASTER_LOCK, 1)) < 0) - exit(0); - - (void) chdir(SPOOL_DIR); - while ((list = job_list_append(NULL, NULL, NULL, SPOOL_DIR)) != NULL) { - job_t **tmp; - - syslog(LOG_DEBUG, "got the queue..."); - for (tmp = list; *tmp != NULL; tmp++) { - /* - * Bugid: 4133175 printd dies when data is removed or - * permissions are changed. Memory is freed twice. - * Fix: Do not process anything else in the list - * if the return code is SEND_ABORT as the memory - * has already been freed by job_destroy(). - */ - rc = send_job(*tmp); - if ((rc != 0) && (rc != SEND_ABORT)) { - char *s = strdup((*tmp)->job_server); - char *p = strdup((*tmp)->job_printer); - - if (rc != SEND_ABORT) /* already free */ - job_free(*tmp); - - for (tmp++; ((*tmp != NULL) && - (strcmp(s, (*tmp)->job_server) == 0)); - tmp++) - if ((connection_failed == 0) && - (strcmp(p, - (*tmp)->job_printer) == 0)) - job_free(*tmp); - else - break; - tmp--; - free(s); - free(p); - } - } - free(list); - - /* look for more work to do before we sleep */ - if ((list = job_list_append(NULL, NULL, NULL, - SPOOL_DIR)) != NULL) { - (void) list_iterate((void **)list, (VFUNC_T)job_free); - free(list); - (void) sleep(60); - } - } - syslog(LOG_DEBUG, "daemon exiting..."); -} - -static void -append_string(char *s, va_list ap) -{ - char *buf = va_arg(ap, char *); - - if (strlen(buf) != 0) - (void) strcat(buf, " "); - (void) strcat(buf, s); -} - - -static char * -build_string(char **list) -{ - int size = 0; - char *buf = NULL; - - if (list != NULL) { - size = list_iterate((void **)list, (VFUNC_T)strlen); - size += 16; - buf = malloc(size); - (void) memset(buf, NULL, size); - (void) list_iterate((void **)list, (VFUNC_T)append_string, buf); - } - return (buf); -} - - -#define ADD_PRIMATIVE(job, primative, value) \ - if ((job != NULL) && (value != NULL)) \ - (void) job_primative(job, primative, value); -#define ADD_SVR4_PRIMATIVE(job, primative, value) \ - if ((job != NULL) && (value != NULL)) (void) job_svr4_primative(job, \ - primative, value); - -#define ADD_INT_PRIMATIVE(job, primative, value, ok) \ - if ((job != NULL) && (value != ok)) { \ - (void) sprintf(buf, "%d", value); \ - (void) job_primative(job, primative, buf); \ - } -#define ADD_SVR4_INT_PRIMATIVE(job, primative, value, ok) \ - if ((job != NULL) && (value != ok)) { \ - (void) sprintf(buf, "%d", value); \ - (void) job_svr4_primative(job, primative, \ - buf); \ - } - -#define OPTION_ERROR(option, value) \ - if (value != NULL) \ - (void) fprintf(stderr, gettext("\tignoring: %s %s\n"), \ - option, value); - -#define OPTION_ERROR_INT(option, value) \ - if (value != -1) \ - (void) fprintf(stderr, gettext("\tignoring: %s %d\n"), \ - option, value); - - - -/* - * Main program. if called with "lpr" use the BSD syntax, if called - * with "lp", use the SYSV syntax. If called by any other name, - * become a transfer daemon. In the lpr/lp case, build a job and - * attempt to send it to the print server. If the server doesn't - * respond, become a daemon if none is currently running and attempt - * to xfer all waiting jobs. - */ -int -main(int ac, char *av[]) -{ - ns_bsd_addr_t *binding = NULL; - int numFiles = 0, - queueStdin = 0, - exit_code = 0; - char *program, - *user, - hostname[128], - buf[BUFSIZ]; - job_t *job; - - (void) setlocale(LC_ALL, ""); - -#if !defined(TEXT_DOMAIN) -#define TEXT_DOMAIN "SYS_TEST" -#endif - (void) textdomain(TEXT_DOMAIN); - - if ((program = strrchr(av[0], '/')) == NULL) - program = av[0]; - else - program++; - - openlog(program, LOG_PID, LOG_LPR); - - /* - * Bugid: 4013980 Application changed fd 1 to a pipe that has - * no reader; we write to stdout and catch a sigpipe and exit. - * Fix: catch signal, complain to syslog, and continue. - */ - (void) signal(SIGPIPE, sigpipe_handler); - - if (check_client_spool(NULL) < 0) { - (void) fprintf(stderr, - gettext("couldn't validate local spool area (%s)\n"), - SPOOL_DIR); - return (-1); - } - if (strcmp(program, "lpr") == 0) { - if ((printer = getenv((const char *)"PRINTER")) == NULL) - printer = getenv((const char *)"LPDEST"); - bsd_options(ac, av); - } else if (strcmp(program, "lp") == 0) { - if ((printer = getenv((const char *)"LPDEST")) == NULL) - printer = getenv((const char *)"PRINTER"); - sysv_options(ac, av); - } else { - xfer_daemon(); - return (0); - } - - if (printer == NULL) { - ns_printer_t *pobj = ns_printer_get_name(NS_NAME_DEFAULT, NULL); - - if (pobj != NULL) { - printer = ns_get_value_string(NS_KEY_USE, pobj); - ns_printer_destroy(pobj); - } - - if (printer == NULL) - printer = NS_NAME_DEFAULT; - } - - if (printer == NULL) { - (void) fprintf(stderr, gettext("No default destination\n")); - return (1); - } - - if ((binding = ns_bsd_addr_get_name(printer)) == NULL) { - (void) fprintf(stderr, gettext("%s: unknown printer\n"), - printer); - return (1); - } - - if (rejecting(binding->printer) != 0) { - (void) fprintf(stderr, gettext( - "%s: requests are not being accepted\n"), - printer); - return (1); - } - - (void) sysinfo(SI_HOSTNAME, hostname, sizeof (hostname)); -#ifdef OLD_LP - /* - * If the server is local, there is lp server configuration, and - * the old lp is still hanging around, use it to submit the job. - */ - { - char cpath[MAXPATHLEN], - ppath[MAXPATHLEN]; - - (void) snprintf(ppath, sizeof (ppath), - "/etc/lp/printers/%s/configuration", binding->printer); - (void) snprintf(cpath, sizeof (cpath), - "/etc/lp/classes/%s", binding->printer); - if (((strcasecmp(binding->server, hostname) == 0) || - (strcasecmp(binding->server, "localhost") == 0)) && - ((access(ppath, F_OK) == 0) || - (access(cpath, F_OK) == 0)) && - (access(OLD_LP, F_OK) == 0)) { - printer = binding->printer; - submit_local_lp(program, ac, av); - } - } -#endif - - if ((job = job_create(strdup(binding->printer), strdup(binding->server), - SPOOL_DIR)) == NULL) { - syslog(LOG_ERR, - "Error creating job: check spooling directory: %s", - SPOOL_DIR); - (void) fprintf(stderr, gettext( - "Error creating job: check spooling directory: %s\n"), - SPOOL_DIR); - return (-1); - } - - (void) umask(0); - user = get_user_name(); - - ADD_PRIMATIVE(job, CF_HOST, hostname); - ADD_PRIMATIVE(job, CF_USER, user); - ADD_PRIMATIVE(job, CF_TITLE, title); - - - if (banner != 0) { - if (jobName != NULL) { - ADD_PRIMATIVE(job, CF_JOBNAME, jobName); - } else if ((av[optind] == NULL) || - (strcmp(av[optind], "-") == 0)) { - ADD_PRIMATIVE(job, CF_JOBNAME, "standard input"); - } else { - ADD_PRIMATIVE(job, CF_JOBNAME, av[optind]); - } - ADD_PRIMATIVE(job, CF_CLASS, (class ? class : hostname)); - ADD_PRIMATIVE(job, CF_PRINT_BANNER, user); - } - - if (mail != 0) { - (void) snprintf(buf, sizeof (buf), "%s@%s", user, hostname); - ADD_PRIMATIVE(job, CF_MAIL, buf); - } - - ADD_INT_PRIMATIVE(job, CF_INDENT, indent, -1); /* ASCII */ - ADD_INT_PRIMATIVE(job, CF_WIDTH, width, -1); - - if ((type == CF_PRINT_DVI) || (type == CF_PRINT_DROFF) || - (type == CF_PRINT_TROFF)) { - ADD_PRIMATIVE(job, CF_FONT_TROFF_R, fontR); - ADD_PRIMATIVE(job, CF_FONT_TROFF_I, fontI); - ADD_PRIMATIVE(job, CF_FONT_TROFF_B, fontB); - ADD_PRIMATIVE(job, CF_FONT_TROFF_S, fontS); - } - - if (binding->extension == NULL) - binding->extension = ""; - - if ((strcasecmp(binding->extension, NS_EXT_SOLARIS) == 0) || - (strcasecmp(binding->extension, NS_EXT_GENERIC) == 0)) { - /* RFC1179 compliant don't get this */ - syslog(LOG_DEBUG, "main(): add Solaris extensions"); - ADD_PRIMATIVE(job, CF_SYSV_OPTION, build_string(s5options)); - ADD_SVR4_INT_PRIMATIVE(job, CF_SYSV_PRIORITY, priority, -1); - ADD_SVR4_PRIMATIVE(job, CF_SYSV_FORM, form); - ADD_SVR4_PRIMATIVE(job, CF_SYSV_CHARSET, charset); - ADD_SVR4_PRIMATIVE(job, CF_SYSV_NOTIFICATION, notification); - ADD_SVR4_PRIMATIVE(job, CF_SYSV_HANDLING, handling); - ADD_SVR4_PRIMATIVE(job, CF_SYSV_PAGES, pages); - if (s5type != NULL) { - ADD_SVR4_PRIMATIVE(job, CF_SYSV_TYPE, s5type); - } else if (internal_type != NULL) - ADD_SVR4_PRIMATIVE(job, CF_SYSV_TYPE, internal_type); - ADD_SVR4_PRIMATIVE(job, CF_SYSV_MODE, build_string(mode)); - } else if (strcasecmp(binding->extension, NS_EXT_HPUX) == 0) { - syslog(LOG_DEBUG, "main(): add HP-UX extensions"); - if (s5options != NULL) { - char buf[BUFSIZ]; - - (void) snprintf(buf, sizeof (buf), " O%s", - build_string(s5options)); - ADD_PRIMATIVE(job, CF_SOURCE_NAME, buf); - } - } else { - if ((s5options != NULL) || (form != NULL) || (pages != NULL) || - (charset != NULL) || (notification != NULL) || - (handling != NULL) || (s5type != NULL) || (mode != NULL) || - (priority != -1)) - (void) fprintf(stderr, gettext( - "Warning: %s not configured to handle all lp options:\n"), - printer); - OPTION_ERROR("-o", build_string(s5options)); - OPTION_ERROR("-f", form); - OPTION_ERROR("-P", pages); - OPTION_ERROR("-S", charset); - OPTION_ERROR("-p", notification); - OPTION_ERROR("-H", handling); - OPTION_ERROR("-T", s5type); - OPTION_ERROR("-y", build_string(mode)); - OPTION_ERROR_INT("-q", priority); - } - - syslog(LOG_DEBUG, "main(): add files"); - if (ac-optind > 0) { - while (optind < ac) - if (strcmp(av[optind++], "-") == 0) - queueStdin++; - else if (job_add_data_file(job, av[optind-1], title, - type, copies, linked, delete) < 0) { - switch (errno) { - case EISDIR: - (void) fprintf(stderr, gettext( - "%s: not a regular file\n"), - av[optind-1]); - break; - case ESRCH: - (void) fprintf(stderr, gettext( - "%s: empty file\n"), - av[optind-1]); - break; - case ENFILE: - (void) fprintf(stderr, gettext( - "too many files, ignoring %s\n"), - av[optind-1]); - break; - case EOVERFLOW: - (void) fprintf(stderr, gettext( - "%s: largefile (>= 2GB), ignoring\n"), - av[optind-1]); - break; - default: - perror(av[optind-1]); - } - exit_code = -1; - } else - numFiles++; - } else - queueStdin++; - - if (queueStdin != 0) { - char *name; - - /* standard input */ - if ((name = stdin_to_file()) != NULL) { - if (job_add_data_file(job, name, - gettext("standard input"), - type, copies, 0, 0) < 0) { - switch (errno) { - case ESRCH: - (void) fprintf(stderr, gettext( - "standard input empty\n")); - break; - case ENFILE: - (void) fprintf(stderr, gettext( - "too many files, ignoring standard input\n")); - break; - default: - perror(name); - } - exit_code = -1; - } else - numFiles++; - (void) unlink(name); - free(name); - } - } - - if (numFiles == 0) - return (-1); - - if (seteuid(0) < 0) - perror("seteuid(0)"); - - (void) signal(SIGBUS, sigbus_handler); - (void) chdir(SPOOL_DIR); - (void) job_store(job); - - if (suppress == 0) - if (numFiles == 1) - (void) printf( - gettext("request id is %s-%d (%d file)\n"), - printer, job->job_id, numFiles); - else - (void) printf( - gettext("request id is %s-%d (%d files)\n"), - printer, job->job_id, numFiles); - (void) fflush(stdout); - - /* - * bgolden 10/2/96 - * BUG 1264627 - * when executed from xemacs, a sighup will kill - * the child before the job is sent. ignore the signal - */ - (void) signal(SIGHUP, SIG_IGN); - - switch (fork()) { /* for immediate response */ - case -1: - syslog(LOG_ERR, "fork() failed: %m"); - break; - case 0: - break; - default: - return (exit_code); - } - - if (send_job(job) == SEND_RETRY) { - syslog(LOG_DEBUG, "main(): transfer failed"); - start_daemon(0); - } - else - syslog(LOG_DEBUG, "main(): transfer succeeded"); - - return (0); -} diff --git a/usr/src/cmd/print/lpget/lpget.c b/usr/src/cmd/print/lpget/lpget.c index abe52330e0..9e6b0e3f00 100644 --- a/usr/src/cmd/print/lpget/lpget.c +++ b/usr/src/cmd/print/lpget/lpget.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1998 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -38,9 +37,9 @@ #include <libintl.h> #endif -#include <print/ns.h> -#include <print/misc.h> -#include <print/list.h> +#include <ns.h> +#include <misc.h> +#include <list.h> extern char *optarg; extern int optind, opterr, optopt; diff --git a/usr/src/cmd/print/lpmove/Makefile b/usr/src/cmd/print/lpmove/Makefile deleted file mode 100644 index 7892c91c36..0000000000 --- a/usr/src/cmd/print/lpmove/Makefile +++ /dev/null @@ -1,77 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright (c) 1994, 1995, 1996 by Sun Microsystems, Inc. -# All Rights Reserved -# -# ident "%Z%%M% %I% %E% SMI" -# -# cmd/lp/client/lpmove/Makefile -# - -include ../Makefile.sp - -PROG= lpmove - -SRCS= $(PROG).c - -OBJS= $(SRCS:.c=.o) - -ROOTUSRSBINPROG= $(PROG:%=$(ROOTUSRSBIN)/%) -ROOTUSRLIBSYMLINK= $(PROG:%=$(ROOTLIB)/%) - -FILEMODE= 04511 -OWNER= root - -CPPFLAGS += -I$(NPRTINC) -LDLIBS += $(LIBNPRT) - -.KEEP_STATE: - -all: $(PROG) - -install: all $(ROOTUSRSBIN) $(ROOTUSRSBINPROG) $(ROOTUSRLIBSYMLINK) - - -$(ROOTUSRSBIN): - $(INS.dir) - -$(ROOTUSRLIBSYMLINK): - $(RM) $@; $(SYMLINK) ../sbin/$(PROG) $@ - -strip: - $(STRIP) $(PROG) - -lint: - $(LINT.c) $(PROG).c $(LDLIBS) - -cstyle: - cstyle $(SRCS) - -_msg: - @echo "Messages are made in usr/src/cmd/print" - -clean: - $(RM) $(OBJS) - -clobber: clean - -$(RM) $(PROG) $(CLOBBERFILES) diff --git a/usr/src/cmd/print/lpmove/lpmove.c b/usr/src/cmd/print/lpmove/lpmove.c deleted file mode 100644 index e3d32afee2..0000000000 --- a/usr/src/cmd/print/lpmove/lpmove.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <stdarg.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <syslog.h> -#include <locale.h> -#ifndef SUNOS_4 -#include <libintl.h> -#endif - -#include <print/ns.h> -#include <print/network.h> -#include <print/misc.h> -#include <print/list.h> -#include <print/job.h> - -/* - * lpr/lp - * This program will submit print jobs to a spooler using the BSD - * printing protcol as defined in RFC1179, plus some extension for - * support of additional lp functionality. - */ - -extern char *optarg; -extern int optind, opterr, optopt; -extern char *getenv(const char *); - - -/* - * creates a new job moves/modifies control data and data files. - * If a job is moved, we should return 1 regardless of whether we - * killed the daemon or not. This will allow us to attempt to start - * the transfer agent for any jobs in /var/spool/print. - */ -static int -vjob_reset_destination(job_t *job, va_list ap) -{ - char *user = va_arg(ap, char *), - buf[BUFSIZ]; - int id = va_arg(ap, int), - lock; - ns_bsd_addr_t *src = va_arg(ap, ns_bsd_addr_t *), - *dst = va_arg(ap, ns_bsd_addr_t *); - - - if ((id != -1) && (job->job_id != id)) - return (0); - if (strcmp(job->job_server, src->server) != 0) - return (0); - if ((strcmp(user, "root") != 0) && - (strcmp(user, job->job_user) != 0)) - return (0); - - while ((lock = get_lock(job->job_cf->jf_src_path, 0)) < 0) - (void) kill_process(job->job_cf->jf_src_path); - - /* just do it */ - (void) snprintf(buf, sizeof (buf), "%s:%s\n", dst->server, - dst->printer); - (void) ftruncate(lock, 0); - (void) write(lock, buf, strlen(buf)); - (void) close(lock); - (void) printf(gettext("moved: %s-%d to %s-%d\n"), src->printer, - job->job_id, dst->printer, job->job_id); - return (1); -} - - -static int -job_move(char *user, int id, ns_bsd_addr_t *src_binding, - ns_bsd_addr_t *dst_binding) -{ - job_t **list = NULL; - int rc = 0; - - if ((list = job_list_append(NULL, src_binding->printer, - src_binding->server, SPOOL_DIR)) != NULL) - rc = list_iterate((void **)list, - (VFUNC_T)vjob_reset_destination, user, id, - src_binding, dst_binding); - return (rc); - -} - -/* - * move print jobs from one queue to another. This gets the lock - * file (killing the locking process if necessary), Moves the jobs, and - * restarts the transfer daemon. - */ - -#define OLD_LPMOVE "/usr/lib/lp/local/lpmove" - -int -main(int ac, char *av[]) -{ - char *program = NULL, - *dst = NULL, - *user = get_user_name(); - char **argv = NULL; - int remote_moved = 0, - i, argc = 0; - ns_bsd_addr_t *dst_binding; - - (void) setlocale(LC_ALL, ""); - -#if !defined(TEXT_DOMAIN) -#define TEXT_DOMAIN "SYS_TEST" -#endif - (void) textdomain(TEXT_DOMAIN); - - if ((program = strrchr(av[0], '/')) == NULL) - program = av[0]; - else - program++; - - openlog(program, LOG_PID, LOG_LPR); - - if (access(OLD_LPMOVE, F_OK) == 0) { /* copy args for local move */ - if ((argv = (char **)calloc(ac + 1, sizeof (char *))) == NULL) { - fprintf(stderr, gettext("lpmove: out of memory\n")); - exit(1); - } - - if (av[0] != NULL) - argv[argc++] = strdup(av[0]); - } - - (void) chdir(SPOOL_DIR); - - /* - * Get the destination; use binding to set it; the input may - * be an alias, not a printer name - */ - dst = av[--ac]; - if ((dst_binding = ns_bsd_addr_get_name(dst)) == NULL) { - (void) fprintf(stderr, gettext("%s: unknown printer\n"), dst); - return (-1); - } - - /* - * Decrement orig arg count so the following for() loop iterates for - * each source request or destination. Also, when we later check if - * there are local jobs to move, we will be comparing number of remote - * requests moved with the total number supplied. - */ - ac--; - - for (i = 1; i <= ac; i++) { - ns_bsd_addr_t *src_binding = NULL; - char *src = av[i], *s, *str; - int id = -1; - - /* - * if the argument contains a '-', see if it is a request - * or a printer. - */ - if ((s = strrchr(src, '-')) != NULL) { - *(s++) = NULL; - - errno = 0; - id = strtol(s, &str, 10); - if (((id <= 0) && (errno != 0)) || (*str != NULL)) { - id = -1; - *(--s) = '-'; - } - } - - /* - * get the binding for the printer, so we can use the printer - * name from the binding to move the job(s) - */ - if ((src_binding = ns_bsd_addr_get_name(src)) == NULL) { - (void) fprintf(stderr, - gettext("%s: unknown printer\n"), src); - return (-1); - } - - if (job_move(user, id, src_binding, dst_binding) == 0) { - /* - * There was nothing "remote" to move, so add it to the - * list of "local" items to move. Use the printer name - * from the binding, because that is the one that - * lpsched is most likely to understand. - */ - char buf[BUFSIZ]; - - (void) snprintf(buf, sizeof (buf), "%s%s%s", - src_binding->printer, - (id == -1 ? "" : "-"), - (id == -1 ? "" : s)); - argv[argc++] = strdup(buf); - } else - remote_moved++; - } - - /* if we moved a "remote" job(s), try to (re)start the transfer agent */ - if (remote_moved != 0) - start_daemon(1); - - /* if there is something "local" to move, try it */ - if ((argv != NULL) && (remote_moved != ac)) { - argv[argc++] = strdup(dst_binding->printer); - - /* limit ourselves to real user's perms before exec'ing */ - (void) setuid(getuid()); - (void) execv(OLD_LPMOVE, argv); - } - - return (0); -} diff --git a/usr/src/cmd/print/lpset/lpset.c b/usr/src/cmd/print/lpset/lpset.c index 716065c470..b579c0cee0 100644 --- a/usr/src/cmd/print/lpset/lpset.c +++ b/usr/src/cmd/print/lpset/lpset.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 1998-2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -41,9 +40,9 @@ #endif #include <pwd.h> -#include <print/ns.h> -#include <print/misc.h> -#include <print/list.h> +#include <ns.h> +#include <misc.h> +#include <list.h> extern char *optarg; extern int optind, opterr, optopt; diff --git a/usr/src/cmd/print/lpstat/Makefile b/usr/src/cmd/print/lpstat/Makefile deleted file mode 100644 index 0e77ee879b..0000000000 --- a/usr/src/cmd/print/lpstat/Makefile +++ /dev/null @@ -1,85 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# -# cmd/lp/client/lpstat/Makefile -# - -include ../Makefile.sp - -PROG= lpstat - -SRCS= lpstat.c sysv-functions.c bsd-functions.c parse_bsd.c - -OBJS= $(SRCS:.c=.o) - -ROOTBINPROG= $(PROG:%=$(ROOTBIN)/%) -ROOTUSRBINSYMLINK= $(ROOTBIN)/lpq -ROOTUSRUCBSYMLINK= $(ROOTUSRUCB)/lpq - -FILEMODE= 04511 -OWNER= root - -CPPFLAGS += -I. -I$(NPRTINC) -LDLIBS += $(LIBNPRT) - -.KEEP_STATE: - -all: $(PROG) - -$(PROG): $(OBJS) - $(LINK.c) $(OBJS) -o $@ $(LDLIBS) - $(POST_PROCESS) - -install: all $(ROOTBIN) $(ROOTBINPROG) $(ROOTUSRBINSYMLINK) \ - $(ROOTUSRUCBSYMLINK) - -$(ROOTBIN): - $(INS.dir) - -$(ROOTUSRBINSYMLINK): - $(RM) $@; $(SYMLINK) $(PROG) $@ - -$(ROOTUSRUCBSYMLINK): - $(RM) $@; $(SYMLINK) ../bin/lpq $@ - -strip: - $(STRIP) $(PROG) - -lint: - $(LINT.c) $(SRCS) $(LDLIBS) - -cstyle: - cstyle $(SRCS) - -_msg: - @echo "Messages are made in usr/src/cmd/print" - -clean: - $(RM) $(OBJS) - -clobber: clean - -$(RM) $(PROG) $(CLOBBERFILES) diff --git a/usr/src/cmd/print/lpstat/bsd-functions.c b/usr/src/cmd/print/lpstat/bsd-functions.c deleted file mode 100644 index 8b5b42fe46..0000000000 --- a/usr/src/cmd/print/lpstat/bsd-functions.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1998 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/fcntl.h> -#include <ctype.h> -#include <string.h> -#include <unistd.h> -#include <stdarg.h> -#include <syslog.h> -#ifndef SUNOS_4 -#include <libintl.h> -#endif -extern char *getenv(const char *); - -#include <print/ns.h> -#include <print/network.h> -#include <print/misc.h> -#include <print/list.h> -#include <print/job.h> - -#include "bsd-functions.h" - - -static char *order[] = { - "", "st", "nd", "rd", "th", "th", "th", "th", "th", "th", "th" }; - -static char * -show_rank(int i) -{ - static char rank[12]; - if ((i%100)/10 == 1) - (void) sprintf(rank, "%dth", i); - else - (void) sprintf(rank, "%d%s", i, order[i%10]); - return (rank); -} - - -static int -vadd_file(jobfile_t *file, va_list ap) -{ - char *mesg = va_arg(ap, char *); - - if (file != NULL) { - (void) strlcat(mesg, file->jf_name, BUFSIZ); - (void) strlcat(mesg, " ", BUFSIZ); - return (file->jf_size); - } - return (0); -} - -/*ARGSUSED*/ -static int -vprint_file(jobfile_t *file, va_list ap) -{ - if (file != NULL) - (void) printf("\t%-33.33s%ld bytes\n", file->jf_name, - file->jf_size); - return (0); -} - -static int -vprint_job(job_t *job, va_list ap) -{ - int jobSize = 0, - *rank, - format, - curr, - printIt = 0, - ac; - char fileList[BUFSIZ], - *printer, - **av; - - printer = va_arg(ap, char *); - format = va_arg(ap, int); - rank = va_arg(ap, int *); - ac = va_arg(ap, int); - av = va_arg(ap, char **); - - if (strcmp(job->job_printer, printer) != 0) - return (0); - - if (ac > 0) { - for (curr = 0; curr < ac; curr++) - if ((av[curr][0] >= '0') && (av[curr][0] <= '9') && - (job->job_id == atoi(av[curr])) || - (strcmp(job->job_user, av[curr]) == 0)) { - printIt++; - break; - } - } else - printIt++; - - if (printIt != 0) { - if (format == SHOW_QUEUE_SHORT_REQUEST) { - (void) memset(fileList, 0, sizeof (fileList)); - jobSize = list_iterate((void **)job->job_df_list, - (VFUNC_T)vadd_file, fileList); - (void) printf( - "%-7.7s%-8.8s %3.3d %-38.38s%d bytes\n", - show_rank((*rank)++), job->job_user, - job->job_id, fileList, jobSize); - } else { - (void) printf("%s: %-7.7s \t\t\t\t [job %.3d%s]\n", - job->job_user, show_rank((*rank)++), - job->job_id, job->job_host); - (void) list_iterate((void **)job->job_df_list, - (VFUNC_T)vprint_file); - (void) printf("\n"); - } - } - return (0); -} - -static int -vjob_count(job_t *job, va_list ap) -{ - int curr, - ac; - char *printer, - **av; - - printer = va_arg(ap, char *); - ac = va_arg(ap, int); - av = va_arg(ap, char **); - - if (strcmp(job->job_printer, printer) != 0) - return (0); - - if (ac == 0) - return (1); - - for (curr = 0; curr < ac; curr++) - if ((av[curr][0] >= '0') && (av[curr][0] <= '9') && - (job->job_id == atoi(av[curr])) || - (strcmp(job->job_user, av[curr]) == 0)) - return (1); - - return (0); -} - - -void -clear_screen() /* for now use tput rather than link in UCB stuff */ -{ - (void) system("/bin/tput clear"); -} - - -int -bsd_queue(ns_bsd_addr_t *binding, int format, int ac, char *av[]) -{ - char *server = NULL, - *printer = NULL; - job_t **list = NULL; - int nd = -1, - idle = 0, - rc; - - server = binding->server; - printer = binding->printer; - - if ((nd = net_open(server, 15)) >= 0) { - char buf[BUFSIZ]; - - (void) memset(buf, 0, sizeof (buf)); - while (ac--) { /* potential SEGV if av's are more than BUFSIZ */ - (void) strlcat(buf, av[ac], sizeof (buf)); - if (strlcat(buf, " ", sizeof (buf)) >= sizeof (buf)) { - syslog(LOG_ERR, "bsd_queue: buffer overflow"); - } - } - - rc = net_printf(nd, "%c%s %s\n", format, printer, buf); - if (rc < 0) - syslog(LOG_ERR, "net_printf() failed: %m"); -#ifdef SUNOS_4 - do { - (void) memset(buf, 0, sizeof (buf)); - if ((ac = net_read(nd, buf, sizeof (buf))) > 0) - (void) printf("%s", buf); - } while (ac > 0); -#else - while (memset(buf, 0, sizeof (buf)) && - (net_read(nd, buf, sizeof (buf)) > 0)) { - (void) printf("%s", buf); - if (strstr(buf, "no entries") != 0) - idle = 1; - } -#endif - - (void) net_close(nd); - } - - if (nd < 0) { - if (server != NULL) - (void) fprintf(stderr, gettext( - "could not talk to print service at %s\n"), - server); - else - (void) fprintf(stderr, gettext( - "could not locate server for printer: %s\n"), - printer); - } - - if (((list = job_list_append(NULL, printer, - server, SPOOL_DIR)) != NULL) && - (list_iterate((void **)list, (VFUNC_T)vjob_count, printer, - ac, av) != 0)) { - if ((nd < 0) && (format == SHOW_QUEUE_SHORT_REQUEST)) - (void) printf(gettext( - "Rank\tOwner Job\tFiles\t\t\t\t\tTotal Size\n")); - } - - if (format == SHOW_QUEUE_LONG_REQUEST) - (void) printf("\n"); - - nd = 1; - (void) list_iterate((void **)list, (VFUNC_T)vprint_job, printer, format, - &nd, ac, av); - - if ((idle == 1) && (list == NULL)) - return (1); - else - return (0); -} diff --git a/usr/src/cmd/print/lpstat/bsd-functions.h b/usr/src/cmd/print/lpstat/bsd-functions.h deleted file mode 100644 index b12adedc84..0000000000 --- a/usr/src/cmd/print/lpstat/bsd-functions.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1998 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _BSD_FUNCTIONS_H -#define _BSD_FUNCTIONS_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -extern int bsd_queue(ns_bsd_addr_t *binding, int format, int ac, char *av[]); -extern void clear_screen(); - -#ifdef __cplusplus -} -#endif - - -#endif /* _BSD_FUNCTIONS_H */ diff --git a/usr/src/cmd/print/lpstat/lpstat.c b/usr/src/cmd/print/lpstat/lpstat.c deleted file mode 100644 index 0902aa51fa..0000000000 --- a/usr/src/cmd/print/lpstat/lpstat.c +++ /dev/null @@ -1,806 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/fcntl.h> -#include <ctype.h> -#include <string.h> -#include <stdarg.h> -#include <unistd.h> -#include <syslog.h> -#include <locale.h> -#ifndef SUNOS_4 -#include <libintl.h> -#endif -#include <sys/systeminfo.h> -#include <sys/param.h> -#include <errno.h> -#include <netdb.h> - -#include <print/ns.h> -#include <print/network.h> -#include <print/misc.h> -#include <print/list.h> -#include <print/job.h> - -#include "parse.h" -#include "sysv-functions.h" -#include "bsd-functions.h" - -extern char *optarg; -extern int optind, opterr, optopt; -extern char *getenv(const char *); -extern char *getname(void); - -static int exit_code = 0; -static int _processing_all = 0; - - -static ns_bsd_addr_t **_printer_bindings = NULL; -static ns_bsd_addr_t **_printer_bindings_unique = NULL; - - -static int sysvVerbose = 0; -static int sysvDesc = 0; -static int sysvLocal = 0; - -static int bsdFormat = SHOW_QUEUE_SHORT_REQUEST; -static int bsdInterval = 0; -static char **bsdv; -static int bsdc; - -typedef enum _work_type work_type_t; -typedef struct _work_entry work_entry_t; - -enum _work_type { ACCEPTING, DEFAULT, ENTRIES, STATUS, RUNNING, RANK, SUMMARY, - FULL, USER, DEVICE, FORMS, CLASSES, CHAR_SETS, BSD_QUEUE }; -struct _work_entry { - ns_bsd_addr_t *binding; - char *printer; - char *user; - int id; - work_type_t type; -}; - -static work_entry_t **workList = NULL; - - -static void -work_list_append(char *printer, char *user, int id, work_type_t type) -{ - work_entry_t *tmp = (work_entry_t *)calloc(1, sizeof (work_entry_t)); - - if (tmp == NULL) - return; - if (user != NULL) - tmp->user = strdup(user); - tmp->id = id; - tmp->type = type; - if (printer != NULL) { - tmp->printer = strdup(printer); - if ((tmp->binding = ns_bsd_addr_get_name(printer)) != NULL) - workList = (work_entry_t **)list_append( - (void **)workList, - (void *)tmp); - else if (strcmp(printer, NS_NAME_DEFAULT) == 0) { - (void) fprintf(stderr, - gettext("No default destination\n")); - exit_code = 1; - } else { - (void) fprintf(stderr, gettext("%s: unknown printer\n"), - printer); - exit_code = 1; - } - } else - workList = (work_entry_t **)list_append((void **)workList, - (void *)tmp); -} - - -static char * -check_for_req_id(char *name) -{ - char *p; - char *p1; - - /* request id has the form <name>-<number> */ - p1 = name + strlen(name); - if (p1 == name) - return (NULL); - p = p1 - 1; - while (p > name && isdigit(*p)) - p--; - if (*p != '-' || p == name) - return (NULL); - else - return (p); -} - -static void -work_list_append_list(char *list, work_type_t type) -{ - char *p; - char *elem; - - if (list == NULL) { - work_list_append(NULL, NULL, -1, type); - return; - } - - for (elem = strtok(list, "\t ,"); elem != NULL; - elem = strtok(NULL, "\t ,")) { - switch (type) { - case RANK: - case ACCEPTING: - case STATUS: - case DEVICE: - work_list_append(elem, NULL, -1, type); - break; - case CHAR_SETS: - case CLASSES: - case FORMS: - case USER: - work_list_append(NULL, elem, -1, type); - break; - case ENTRIES: - if ((p = check_for_req_id(elem)) == NULL) - work_list_append(elem, NULL, -1, ENTRIES); - else if (ns_bsd_addr_get_name(elem) != NULL) - work_list_append(elem, NULL, -1, ENTRIES); - else { - *p++ = '\0'; - work_list_append(elem, NULL, atoi(p), ENTRIES); - } - break; - } - } -} - -static char * -lpstat_opt(work_type_t type) -{ - switch (type) { - case STATUS: - return ("-p"); - case RANK: - return ("-R"); - case USER: - return ("-u"); - case ENTRIES: - return ("-o"); - default: - return (NULL); - } -} - -/* - * This function is for a performance improvement. - */ - -static int -is_local_printer(char *server, char *printer) -{ - static char *hostname, hbuf[MAXHOSTNAMELEN]; - char buf[MAXPATHLEN]; - - if ((server == NULL) || (printer == NULL)) { - errno = EINVAL; - return (-1); - } - - if (hostname == NULL) { - sysinfo(SI_HOSTNAME, hbuf, sizeof (hbuf)); - hostname = hbuf; - } - - if ((strcasecmp(server, hostname) != 0) && - (strcasecmp(server, "localhost") != 0)) - return (1); - - snprintf(buf, sizeof (buf), "/etc/lp/printers/%s/configuration", - printer); - if (access(buf, F_OK) != 0) { - /* OK its not a local printer but may be a local class */ - snprintf(buf, sizeof (buf), "/etc/lp/classes/%s", printer); - if (access(buf, F_OK) != 0) - return (1); - } - return (0); -} - -/* - * Determine if there are any local printers in the list - */ -static int -local_printers(ns_bsd_addr_t **printers) -{ - static int local_printer_found = 0; - static int already_looked = 0; - - if (already_looked == 0) { - already_looked = 1; - if ((printers == NULL) || (*printers == NULL)) { - return (0); - } - - /* Step through list and break out if we find a local printer */ - while (*printers != NULL) { - if (((*printers)->server == NULL) || - ((*printers)->printer == NULL)) - continue; - if (is_local_printer((*printers)->server, - (*printers)->printer) == 0) - break; - printers++; - } - - if ((printers != NULL) && (*printers != NULL)) - local_printer_found = 1; - } - - return (local_printer_found); -} - - -/* - * Determine if local status needs to be run. This is true - * if there are any local printers in the list with a local - * printer definition. - */ -static int -need_local_status(ns_bsd_addr_t **printers, ns_bsd_addr_t *binding) -{ - - return ((local_printers(_printer_bindings) == 1) || - ((binding != NULL) && - (is_local_printer(binding->server, - binding->printer) == 0))); -} - - -static int -work_execute(work_entry_t *work, int verb) -{ - char *printer = NULL; - char *server = NULL; - print_queue_t *qp; - int rank = 0; - int rc = 0; - - switch (work->type) { - case RUNNING: - sysv_running(); - return (0); - case DEFAULT: - sysv_default(); - return (0); - case FORMS: - return (sysv_local_status("-f", work->user, verb, 0, - gettext("form listing not supported on client\n"))); - case CLASSES: - return (sysv_local_status("-c", work->user, 0, 0, - gettext("class listing not supported on client\n"))); - case CHAR_SETS: - return (sysv_local_status("-S", work->user, verb, 0, - gettext("char set listing not supported on client\n"))); - } - - if ((work->binding->printer == NULL) && - (work->binding->server == NULL)) - return (0); - - /* - * If the printer is a local LP printer, we can use the local lpstat - * and it should be faster than going via the network. - */ - if ((is_local_printer(work->binding->server, - work->binding->printer) == 0) && - ((work->binding->pname == NULL) || - (strcmp(work->binding->printer, work->binding->pname) == 0) || - (strcmp(work->binding->pname, NS_NAME_DEFAULT) == 0))) { - char *option = lpstat_opt(work->type); - - if (option != NULL) { - /* - * If we are processing all printers - * (ie. -p, -o, -r, - * -u, -t), simply return, because the local lpstat - * was already run and all local printers were reported - * against. - */ - if (_processing_all != 0) - return (0); - - if (work->printer) - return (sysv_local_status(option, - work->printer, verb, sysvDesc, - gettext("can't execute \n"))); - else if (work->user) - return (sysv_local_status(option, - work->user, verb, sysvDesc, - gettext("can't execute \n"))); - else - return (sysv_local_status(option, - "", verb, sysvDesc, - gettext("can't execute \n"))); - } - } - - if ((printer = strchr(work->binding->printer, '|')) != NULL) - *printer = NULL; - printer = work->binding->printer; - server = work->binding->server; - - switch (work->type) { - case STATUS: - case RANK: - case USER: - case ENTRIES: - if ((qp = sysv_get_queue(work->binding, sysvLocal)) != NULL) { - qp->jobs = job_list_append(qp->jobs, printer, - server, SPOOL_DIR); - switch (work->type) { - case STATUS: - if (work->binding->pname) - rc += sysv_queue_state(qp, - work->binding->pname, verb, - sysvDesc); - else - rc += sysv_queue_state(qp, printer, - verb, sysvDesc); - break; - case ENTRIES: - case USER: - rank = -1; - /*FALLTHRU*/ - case RANK: - if ((work->binding->pname != NULL) && - (strcmp(work->binding->pname, - NS_NAME_DEFAULT) != 0)) - (void) list_iterate((void **)qp->jobs, - (VFUNC_T)vsysv_queue_entry, - work->binding->pname, work->user, - work->id, verb, &rank); - else - (void) list_iterate((void **)qp->jobs, - (VFUNC_T)vsysv_queue_entry, printer, - work->user, work->id, verb, &rank); - break; - } - if ((qp->state == RAW) && (qp->status != NULL)) { - (void) printf("%s", qp->status); - qp->status = NULL; - } - } - break; - default: - switch (work->type) { - case DEVICE: - rc += sysv_system(work->binding); - break; - case ACCEPTING: - rc += sysv_accept(work->binding); - break; - case BSD_QUEUE: - do { - int i; - - if (bsdInterval != 0) - clear_screen(); - if (bsd_queue(work->binding, bsdFormat, - bsdc, bsdv) != 0) - break; - if (bsdInterval != 0) - (void) sleep(bsdInterval); - } while (bsdInterval != 0); - break; - } - } - - return (rc); -} - - -static int -vbinding_execute(ns_bsd_addr_t *binding, va_list ap) -{ - work_entry_t *work = va_arg(ap, work_entry_t *); - int verbose = va_arg(ap, int); - - work->binding = binding; - return (work_execute(work, verbose)); -} - - - - - -static int -vwork_list_execute(work_entry_t *work, va_list ap) -{ - int verbose = va_arg(ap, int); - work_entry_t tmp; - int rc = 0; - - if ((work->binding == NULL) || ((work->binding->printer == NULL) && - (work->binding->server == NULL))) { - switch (work->type) { - case RUNNING: - case DEFAULT: - case CLASSES: - case FORMS: - case CHAR_SETS: - rc += work_execute(work, verbose); - break; - case STATUS: - case RANK: - case ENTRIES: - case ACCEPTING: - case DEVICE: - case SUMMARY: - case USER: - case FULL: - - if (_printer_bindings == NULL) { - if (sysvLocal == 0) { - _printer_bindings = - ns_bsd_addr_get_all(LOCAL_UNIQUE); - _printer_bindings_unique = - ns_bsd_addr_get_all(UNIQUE); - } else { - _printer_bindings = - ns_bsd_addr_get_list(LOCAL_UNIQUE); - _printer_bindings_unique = - ns_bsd_addr_get_list(UNIQUE); - } - } - - (void) memcpy(&tmp, work, sizeof (tmp)); - - if (work->type == FULL || work->type == SUMMARY) { - tmp.type = RUNNING; - rc += work_execute(&tmp, verbose); - - tmp.type = DEFAULT; - rc += work_execute(&tmp, verbose); - - tmp.type = CLASSES; - rc += work_execute(&tmp, verbose); - - tmp.type = DEVICE; - rc += list_iterate( - (void **)_printer_bindings, - (VFUNC_T)vbinding_execute, - &tmp, verbose); - - tmp.type = CHAR_SETS; - rc += work_execute(&tmp, verbose); - - - if (work->type == FULL) { - _processing_all = 1; - tmp.type = ACCEPTING; - rc += list_iterate( - (void **)_printer_bindings, - (VFUNC_T)vbinding_execute, - &tmp, verbose); - if (need_local_status(_printer_bindings, - work->binding) == 1) - sysv_local_status("-p", "", - verbose, sysvDesc, - gettext( - "can't execute \n")); - - tmp.type = STATUS; - rc += list_iterate( - (void **)_printer_bindings, - (VFUNC_T)vbinding_execute, - &tmp, verbose); - if (need_local_status(_printer_bindings, - work->binding) == 1) - sysv_local_status("-o", "", - verbose, sysvDesc, - gettext( - "can't execute \n")); - - tmp.type = ENTRIES; - rc += list_iterate( - (void **)_printer_bindings_unique, - (VFUNC_T)vbinding_execute, - &tmp, verbose); - _processing_all = 0; - } - - /* - * Put this here to preserve same ordering - * as found in previous releases. - */ - if (work->type == FULL || - work->type == SUMMARY) { - - tmp.type = FORMS; - rc += work_execute(&tmp, verbose); - } - - } else if ((work->type == ACCEPTING) || - (work->type == DEVICE)) { - tmp.type = work->type; - rc += list_iterate( - (void **)_printer_bindings, - (VFUNC_T)vbinding_execute, - &tmp, verbose); - - } else if (work->type == USER || - work->type == STATUS || - work->type == ENTRIES || - work->type == RANK) { - - if (need_local_status(_printer_bindings, - work->binding) == 1) { - char *option = lpstat_opt(work->type); - if ((work->type == USER) && - (work->user != NULL)) { - sysv_local_status(option, - work->user, verbose, - sysvDesc, - gettext( - "can't execute \n")); - } else { - sysv_local_status(option, "", - verbose, sysvDesc, - gettext( - "can't execute \n")); - } - } - - _processing_all = 1; - tmp.type = work->type; - if (work->type == STATUS) { - rc += list_iterate( - (void **)_printer_bindings, - (VFUNC_T)vbinding_execute, - &tmp, verbose); - } else { - rc += list_iterate( - (void **)_printer_bindings_unique, - (VFUNC_T)vbinding_execute, - &tmp, verbose); - } - _processing_all = 0; - } else - rc += list_iterate( - (void **)_printer_bindings, - (VFUNC_T)vbinding_execute, &tmp, - verbose); - return (rc); - default: - return (rc); - } - } else { - rc += work_execute(work, verbose); - } - return (rc); -} - -static void -sysv_options(int ac, char *av[]) -{ - char **argv, - *program; - int c; - int argc = 0; - char *user; - - if ((program = strrchr(av[0], '/')) == NULL) - program = av[0]; - else - program++; - - argv = (char **)calloc((ac + 1), sizeof (char *)); - - if (argv == NULL) { - fprintf(stderr, gettext("memory allocation failed\n")); - exit(1); - } - for (argc = 0; argc < ac; argc++) - argv[argc] = av[argc]; - argv[argc++] = "--"; - - while ((c = getopt(argc, argv, "R:a:c:f:o:p:u:v:DLSdlrst")) != EOF) { - switch (c) { /* these may or may not have an option */ - case 'R': - case 'a': - case 'c': - case 'f': - case 'o': - case 'p': - case 'u': - case 'v': - if (optarg[0] == '-') { - /* this check stop a possible infinite loop */ - if ((optind > 1) && (argv[optind-1][1] != c)) - optind--; - optarg = NULL; - } else if (strcmp(optarg, "all") == 0) - optarg = NULL; - } - - switch (c) { - case 'D': - sysvDesc++; - break; - case 'L': - sysvLocal++; - /* undocumented option that keeps it long and local */ - break; - case 'R': - work_list_append_list(optarg, RANK); - break; - case 'S': - work_list_append_list(optarg, CHAR_SETS); - break; - case 'a': - work_list_append_list(optarg, ACCEPTING); - break; - case 'c': - work_list_append_list(optarg, CLASSES); - break; - case 'd': - work_list_append(NULL, NULL, -1, DEFAULT); - break; - case 'f': - work_list_append_list(optarg, FORMS); - break; - case 'l': - sysvVerbose++; - break; - case 'o': - work_list_append_list(optarg, ENTRIES); - break; - case 'p': - work_list_append_list(optarg, STATUS); - break; - case 'r': - work_list_append(NULL, NULL, -1, RUNNING); - break; - case 's': - work_list_append(NULL, NULL, -1, SUMMARY); - break; - case 't': - work_list_append(NULL, NULL, -1, FULL); - break; - case 'u': - work_list_append_list(optarg, USER); - break; - case 'v': - work_list_append_list(optarg, DEVICE); - break; - default: - (void) fprintf(stderr, - gettext( - "Usage: %s [-drtslDL] [-R [list]] [-S [list]] " - "[-a [list]] [-c [list]] [-f [list]] " - "[-o [list]] [-p [printer]] [-u [list]] " - "[-v [list]] [list]\n"), - av[0]); - exit(1); - } - } - for (argc = optind; argc < ac; argc++) /* add requests */ - work_list_append_list(av[argc], ENTRIES); - - if ((workList == NULL) && (ac == 1)) { - user = get_user_name(); - work_list_append(NULL, user, -1, USER); - } -} - - -static void -bsd_options(int ac, char **av) -{ - char *printer; - int c; - - if ((bsdv = (char **)calloc(ac, sizeof (char *))) == NULL) - return; - - if ((printer = getenv((const char *)"PRINTER")) == NULL) - printer = getenv((const char *)"LPDEST"); - if (printer == NULL) - printer = NS_NAME_DEFAULT; - - while ((c = getopt(ac, av, "lP:+:")) != EOF) - switch (c) { - case 'l': - bsdFormat = SHOW_QUEUE_LONG_REQUEST; - break; - case 'P': - printer = optarg; - break; - default: - (void) fprintf(stderr, - gettext("Usage: %s [-P printer] [-l] [+ interval] [list]\n"), - av[0]); - exit(1); - } - - work_list_append(printer, NULL, -1, BSD_QUEUE); - - while (optind < ac) - if (av[optind][0] == '+') - bsdInterval = atoi(&av[optind++][1]); - else - bsdv[bsdc++] = av[optind++]; -} - - -int -main(int ac, char *av[]) -{ - char *program; - int rc = 0; - - (void) setlocale(LC_ALL, ""); - -#if !defined(TEXT_DOMAIN) -#define TEXT_DOMAIN "SYS_TEST" -#endif - (void) textdomain(TEXT_DOMAIN); - - if ((program = strrchr(av[0], '/')) == NULL) - program = av[0]; - else - program++; - - openlog(program, LOG_PID, LOG_LPR); - - if (check_client_spool(NULL) < 0) { - (void) fprintf(stderr, gettext("couldn't validate local spool " - "area (%s)\n"), SPOOL_DIR); - return (1); - } - (void) chdir(SPOOL_DIR); - - if (strcmp(program, "lpq") == 0) - bsd_options(ac, av); - else { - sysv_options(ac, av); - } - - rc = list_iterate((void **)workList, (VFUNC_T)vwork_list_execute, - sysvVerbose, sysvDesc); - - if (exit_code == 0) - exit_code = rc; - - return (exit_code); -} diff --git a/usr/src/cmd/print/lpstat/parse.h b/usr/src/cmd/print/lpstat/parse.h deleted file mode 100644 index fb4abd3d9f..0000000000 --- a/usr/src/cmd/print/lpstat/parse.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1998 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _PARSE_H -#define _PARSE_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct _print_queue { - ns_bsd_addr_t *binding; - char *status; - enum { RAW, IDLE, PRINTING, FAULTED, DISABLED } state; - job_t **jobs; -} print_queue_t; - -extern print_queue_t *parse_bsd_queue(ns_bsd_addr_t *binding, char *data, - int len); -#ifdef __cplusplus -} -#endif - -#endif /* _PARSE_H */ diff --git a/usr/src/cmd/print/lpstat/parse_bsd.c b/usr/src/cmd/print/lpstat/parse_bsd.c deleted file mode 100644 index 963ea8f048..0000000000 --- a/usr/src/cmd/print/lpstat/parse_bsd.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1998-2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - - -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/fcntl.h> -#include <ctype.h> -#include <string.h> -#include <stdarg.h> -#include <libintl.h> - -#include <print/ns.h> -#include <print/network.h> -#include <print/misc.h> -#include <print/job.h> -#include <print/list.h> - -#include "parse.h" - - -#define MERR_NOMEM "ERROR: no memory\n" -#define STRNCASECMP(a, b) strncasecmp(a, b, strlen(b)) - -static job_t * -parse_bsd_entry(char *data) -{ - job_t *tmp; - char *p; - - tmp = (job_t *)malloc(sizeof (*tmp)); - if (tmp == NULL) { - (void) fprintf(stderr, gettext(MERR_NOMEM)); - return (NULL); - } - (void) memset(tmp, 0, sizeof (*tmp)); - - /* - * 1st line... - * user: rank [job (ID)(host)]\n - */ - if ((p = strtok(data, ": ")) == NULL) /* user: ... */ - return (NULL); - tmp->job_user = strdup(p); - p = strtok(NULL, "\t "); /* ...rank... */ - p = strtok(NULL, " "); /* ...[job ... */ - if ((p = strtok(NULL, "]\n")) == NULL) /* ... (id)(hostname)] */ - return (NULL); - while (isspace(*p)) p++; - tmp->job_id = atoi(p); - while (isdigit(*(++p))); - while (isspace(*p)) p++; - tmp->job_host = strdup(p); - - /* - * rest o lines - * file size bytes\n - */ - do { - jobfile_t *file; - - p = strtok(NULL, "\t "); - p = strtok(NULL, "\t "); /* file Name */ - if (p != NULL) { - file = (jobfile_t *)malloc(sizeof (*file)); - if (file == NULL) { - (void) fprintf(stderr, gettext(MERR_NOMEM)); - return (NULL); - } - file->jf_name = strdup(p); - if ((p = strtok(NULL, "\t ")) != NULL) - if ((file->jf_size = atoi(p)) == 0) - while ((p = strtok(NULL, "\t ")) - != NULL) - if (isdigit(p[0])) { - file->jf_size = atoi(p); - break; - } - tmp->job_df_list = (jobfile_t **)list_append((void **) - tmp->job_df_list, - (void *)file); - } - } while (p != NULL); - return (tmp); -} - - -/*ARGSUSED*/ -print_queue_t * -parse_bsd_queue(ns_bsd_addr_t *binding, char *data, int len) -{ - char *p; - print_queue_t *tmp; - - tmp = (print_queue_t *)malloc(sizeof (*tmp)); - if (tmp == NULL) { - (void) fprintf(stderr, gettext(MERR_NOMEM)); - return (NULL); - } - (void) memset(tmp, 0, sizeof (*tmp)); - tmp->state = RAW; - tmp->status = data; - tmp->binding = binding; - - if (data == NULL) - return (tmp); - - if ((p = strstr(data, "\n\n")) == NULL) { - if (strstr(data, "no entries") != NULL) - tmp->state = IDLE; - return (tmp); - } - - *(p++) = NULL; - tmp->status = strdup(data); - data = ++p; - - tmp->state = FAULTED; /* Error */ - if (STRNCASECMP(tmp->status, "no entries") == 0) - tmp->state = IDLE; - else if (STRNCASECMP((tmp->status + strlen(tmp->status) - - strlen("ready and printing")), - "ready and printing") == 0) - tmp->state = PRINTING; - - do { /* parse jobs */ - job_t *job; - char *q = data; - - if ((p = strstr(data, "\n\n")) != NULL) { - *(++p) = NULL; - data = ++p; - } - if ((job = parse_bsd_entry(q)) == NULL) - break; - - job->job_server = strdup(binding->server); - job->job_printer = strdup(binding->printer); - tmp->jobs = (job_t **)list_append((void **)tmp->jobs, - (void *)job); - } while (p != NULL); - - return (tmp); -} diff --git a/usr/src/cmd/print/lpstat/sysv-functions.c b/usr/src/cmd/print/lpstat/sysv-functions.c deleted file mode 100644 index 35520fddd3..0000000000 --- a/usr/src/cmd/print/lpstat/sysv-functions.c +++ /dev/null @@ -1,619 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1998-2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/fcntl.h> -#include <sys/wait.h> -#include <ctype.h> -#include <string.h> -#include <stdarg.h> -#include <unistd.h> -#include <errno.h> -#include <unistd.h> -#include <syslog.h> -#ifndef SUNOS_4 -#include <libintl.h> -#endif - -#include <print/ns.h> -#include <print/list.h> -#include <print/misc.h> -#include <print/job.h> -#include <print/network.h> - -#include "parse.h" -#include "sysv-functions.h" - -extern char *getenv(const char *); - -static print_queue_t **_queue_list = NULL; - -static int sysv_displayLocalLPSTAT(char *pname, char *aname); - -#define ALL "all" -static int -compair_user(char *full, char *user, char *host) -{ - char *u1, - *h1; - - if (full == NULL) - return (0); - - if ((strcmp(full, ALL) == 0) || strcmp(full, user) == 0) - return (0); - if ((u1 = strchr(full, '!')) == NULL) - return (-1); - h1 = strcdup(full, '!'); - u1++; - if (((strcmp(u1, ALL) == 0) || (strcmp(u1, user) == 0)) && - (strcmp(h1, host) == 0)) { - free(h1); - return (0); - } - if (((strcmp(h1, ALL) == 0) || (strcmp(h1, host) == 0)) && - (strcmp(u1, user) == 0)) { - free(h1); - return (0); - } - free(h1); - return (-1); -} - - -static int -compair_queue_binding(print_queue_t *queue, ns_bsd_addr_t *binding) -{ - if ((queue == NULL) || (binding == NULL)) - return (-1); - if ((strcmp(queue->binding->printer, binding->printer) == 0) && - (strcmp(queue->binding->server, binding->server) == 0)) - return (0); - return (-1); -} - - - -static char * -get_queue_buffer(ns_bsd_addr_t *binding) -{ - char *q = NULL, - *p = NULL, - *server, - *printer; - int nd, - rc, - count = 0, - q_size = 0, - p_left = 0; - - server = binding->server; - printer = binding->printer; - - if ((nd = net_open(server, 15)) < 0) { - char err[128]; - - (void) snprintf(err, sizeof (err), - gettext("server %s not responding\n\n"), - server); - return (strdup(err)); - } - - rc = net_printf(nd, "%c%s \n", SHOW_QUEUE_LONG_REQUEST, printer); - if (rc < 0) - syslog(LOG_ERR, "net_printf() failed: %m"); - - do { - p += count; - if ((p_left -= count) < 10) { - char *t; - -#ifdef SUNOS_4 - if (q == NULL) { - p = q = malloc(BUFSIZ); - (void) memset(p, NULL, BUFSIZ); - q_size = BUFSIZ; - } else { - q_size += BUFSIZ; - t = malloc(q_size); - (void) memset(t, NULL, q_size); - strcpy(t, q); - free(q); - p = t + (p - q); - q = t; - } -#else - if ((t = (char *)realloc(q, q_size += BUFSIZ)) != q) { - p = t + (p - q); - q = t; - } -#endif - p_left += BUFSIZ; - (void) memset(p, NULL, p_left); - } - } while ((count = net_read(nd, p, p_left)) > 0); - - (void) net_close(nd); - - return (q); -} - - - -print_queue_t * -sysv_get_queue(ns_bsd_addr_t *binding, int local) -{ - print_queue_t *qp = NULL; - char *buf; - - if (_queue_list != NULL) /* did we already get it ? */ - if ((qp = (print_queue_t *)list_locate((void **)_queue_list, - (COMP_T)compair_queue_binding, binding)) != NULL) - return (qp); - - if (local == 0) - buf = (char *)get_queue_buffer(binding); - else - buf = strdup("no entries\n"); - - if (buf != NULL) { - qp = parse_bsd_queue(binding, buf, strlen(buf)); - _queue_list = (print_queue_t **)list_append((void **) - _queue_list, (void *)qp); - } - return (qp); -} - - - - - - - /* - * SYSV (lpstat) specific routines - */ - -static int -vJobfile_size(jobfile_t *file) -{ - if (file != NULL) - return (file->jf_size); - return (0); -} - - -void -vsysv_queue_entry(job_t *job, va_list ap) -{ - char id[128], - user[128], - *printer = va_arg(ap, char *), - *in_user = va_arg(ap, char *); - int in_id = va_arg(ap, int), - verbose = va_arg(ap, int), - *rank = va_arg(ap, int *), - size = 0; - - if ((in_id != -1) && (in_id != job->job_id)) - return; - if (compair_user(in_user, job->job_user, job->job_host) != 0) - return; - - (void) sprintf(id, "%.16s-%-5d", printer, job->job_id); - (void) snprintf(user, sizeof (user), "%s@%s", job->job_user, - job->job_host); - size = list_iterate((void **)job->job_df_list, (VFUNC_T)vJobfile_size); - if (*rank >= 0) - (void) printf("%d ", (*rank)++); - (void) printf("%-*s %-*s %*d %s%s", (*rank >= 0 ? 20 : 22), id, 15, - user, 7, size, (*rank >= 0 ? "" : " "), short_date()); - if (verbose == 0) { - if (*rank == 1) - (void) printf(" on %s", printer); - (void) printf("\n"); - } else - (void) printf("\n\t%s %s\n", - ((*rank > 1) ? "on" : "assigned"), printer); -} - - -#define OLD_LPSTAT "/usr/lib/lp/local/lpstat" /* for -c -f -S */ -#ifdef OLD_LPSTAT -static int -local_printer(char *name) -{ - char buf[128]; - - (void) snprintf(buf, sizeof (buf), - "/etc/lp/printers/%s/configuration", name); - return (access(buf, F_OK)); -} - -static int -local_class(char *name) -{ - char buf[128]; - - (void) snprintf(buf, sizeof (buf), - "/etc/lp/classes/%s", name); - return (access(buf, F_OK)); -} - -int -sysv_local_status(char *option, char *arg, int verbose, - int description, char *invalid) -{ - pid_t stat; - - if (access(OLD_LPSTAT, F_OK) == 0) { - char buf[BUFSIZ]; - - /* - * Need the fflush to preserve output order when - * output re-directed to a file. Close of old lpstat - * flushes buffers causing old lpstat output to preceed - * all other output to the file. - */ - (void) fflush(stdout); - (void) fflush(stderr); - (void) snprintf(buf, sizeof (buf), - "%s %s %s%s%s", OLD_LPSTAT, option, - (arg ? arg : ""), (verbose ? " -l" : ""), - (description ? " -D" : "")); - stat = system(buf); - if (WIFEXITED(stat)) { - return (WEXITSTATUS(stat)); - } else { - if (stat == -1) - return (errno); - else - return (ENOMSG); - } - } else - (void) printf("%s", invalid); - - return (0); -} -#endif - - -int -sysv_queue_state(print_queue_t *qp, char *printer, int verbose, int description) -{ -#ifdef OLD_LPSTAT - pid_t stat; - - if ((local_printer(printer) == 0) && (access(OLD_LPSTAT, F_OK) == 0)) { - char buf[BUFSIZ]; - - /* see sysv_local_status for reason for fflush */ - (void) fflush(stdout); - (void) fflush(stderr); - (void) snprintf(buf, sizeof (buf), - "%s -p %s%s%s", OLD_LPSTAT, printer, - (verbose ? " -l" : ""), (description ? " -D" : "")); - stat = system(buf); - if (WIFEXITED(stat)) { - return (WEXITSTATUS(stat)); - } else { - if (stat == -1) - return (errno); - else - return (ENOMSG); - } - - - } -#endif - - (void) printf(gettext("printer %s "), printer); - switch (qp->state) { - case IDLE: - (void) printf(gettext("is idle. ")); - break; - case PRINTING: - (void) printf(gettext("now printing %s-%d. "), printer, - qp->jobs[0]->job_id); - break; - case FAULTED: - (void) printf(gettext("faulted printing %s-%d. "), printer, - (qp->jobs != NULL ? qp->jobs[0]->job_id : 0)); - break; - case RAW: - (void) printf(gettext("unknown state. ")); - break; - default: - (void) printf(gettext("disabled. ")); - } - (void) printf(gettext("enabled since %s. available.\n"), long_date()); - if (qp->state == FAULTED) - (void) printf("\t%s\n", qp->status); - if (description != 0) { - ns_printer_t *pobj; - char *desc; - - if (((pobj = ns_printer_get_name(qp->binding->printer, NULL)) - != NULL) && - ((desc = ns_get_value(NS_KEY_DESCRIPTION, pobj)) != NULL)) - (void) printf(gettext("\tDescription: %s\n"), desc); - else - (void) printf(gettext("\tDescription: %s@%s\n"), - qp->binding->printer, qp->binding->server); - } - if (verbose != 0) - (void) printf( - gettext("\tRemote Name: %s\n\tRemote Server: %s\n"), - qp->binding->printer, qp->binding->server); - - return (0); -} - - -int -sysv_accept(ns_bsd_addr_t *binding) -{ -#ifdef OLD_LPSTAT - int result = 0; - - if (((local_printer(binding->printer) == 0) || - (local_class(binding->printer) == 0)) && - (access(OLD_LPSTAT, F_OK) == 0)) { - /* - * Locally attached printer, so display its accept state using - * the old lpstat utility. - */ - result = sysv_displayLocalLPSTAT(binding->printer, - binding->pname); - return (result); - } -#endif - - - if (binding->pname != NULL) - (void) printf(gettext("%s accepting requests since %s\n"), - binding->pname, long_date()); - else - (void) printf(gettext("%s accepting requests since %s\n"), - binding->printer, long_date()); - - return (0); -} - - - -#ifdef OLD_LPSTAT -/* - * FUNCTION: sysv_displayLocalLPSTAT() - * - * DESCRIPTION: This function uses the old lpstat (/usr/lib/lp/local/lpstat) - * utility to display the accepting state (-a option) for locally - * attached printers. - * If an alias name is given then the output from lpstat is - * captured and modified to show the alias name instead of the - * printer's real name. Note: this is done because the old lpstat - * can not handle alias names. - * - * PARAMETERS: - * Input: char *pname - printers real name - * char *aname - printers alias name - * - * RETURNS: 0 = completed okay, otherwise error - * - */ - -static int -sysv_displayLocalLPSTAT(char *pname, char *aname) - -{ - int result = ENOMSG; - char buf[BUFSIZ]; - FILE *fd = NULL; - char *tmp = NULL; - - /* see sysv_local_status for reason for fflush */ - (void) fflush(stdout); - (void) fflush(stderr); - - if (((pname != NULL) && (aname != NULL)) && - (strcmp(pname, aname) != 0)) - { - /* - * This is a request to display status of an aliased local - * printer, so capture the output from the local lpstat for the - * real printer and then display that output with the alias - * name instead of the real name. - */ - - (void) snprintf(buf, sizeof (buf), "%s -a %s", - OLD_LPSTAT, pname); - - /* execute the local lpstat utility and display output */ - - fd = popen(buf, "r"); - if (fd != NULL) - { - tmp = fgets(buf, sizeof (buf), fd); - if (tmp != NULL) - { - result = 0; - - if (strncmp(buf, pname, strlen(pname)) == 0) - { - printf("%s", aname); - printf("%s", &(buf[strlen(pname)])); - - tmp = fgets(buf, sizeof (buf), fd); - } - - /* - * finish reading and displaying the - * output from the lpstat utility - */ - - while (tmp != NULL) - { - printf("%s", buf); - tmp = fgets(buf, sizeof (buf), fd); - } - } - - (void) pclose(fd); - } - } - - else - if (pname != NULL) - { - /* - * Not an alias so directly display output from the - * local lpstat utility - */ - (void) snprintf(buf, sizeof (buf), "%s -a %s", - OLD_LPSTAT, pname); - result = system(buf); - - if (WIFEXITED(result)) - { - result = WEXITSTATUS(result); - } - else - if (result == -1) - { - result = errno; - } - else - { - result = ENOMSG; - } - } - - return (result); -} /* sysv_displayLocalLPSTAT */ -#endif - - - -int -sysv_system(ns_bsd_addr_t *binding) -{ - char *host; - char *printer; - pid_t stat; - - if (binding->pname) - printer = binding->pname; - else - printer = binding->printer; - host = binding->server; -#ifdef OLD_LPSTAT - - if ((local_printer(printer) == 0) && (access(OLD_LPSTAT, F_OK) == 0)) { - char buf[BUFSIZ]; - - /* see sysv_local_status for reason for fflush */ - (void) fflush(stdout); - (void) fflush(stderr); - (void) snprintf(buf, sizeof (buf), - "%s -v %s", OLD_LPSTAT, printer); - stat = system(buf); - - if (WIFEXITED(stat)) { - return (WEXITSTATUS(stat)); - } else { - if (stat == -1) - return (errno); - else - return (ENOMSG); - } - } else -#endif - if (printer && host) { - if (strcmp(printer, binding->printer) == 0) - (void) printf(gettext("system for %s: %s\n"), printer, - host); - else - (void) printf( - gettext("system for %s: %s (as printer %s)\n"), - printer, host, binding->printer); - } - - return (0); -} - - -void -sysv_running() -{ - int lock; - struct stat st; - - lock = stat("/usr/spool/lp/SCHEDLOCK", &st); - if (lock < 0) - (void) printf(gettext("scheduler is not running\n")); - else - (void) printf(gettext("scheduler is running\n")); -} - - -void -sysv_default() -{ - char *printer; - - if ((printer = getenv((const char *)"LPDEST")) == NULL) - printer = getenv((const char *)"PRINTER"); - if (printer == NULL) { - ns_printer_t *p; - - if ((p = ns_printer_get_name(NS_NAME_DEFAULT, NULL)) != NULL) { - printer = ns_get_value(NS_KEY_USE, p); - /* - * Fall back to the printer name out of - * the "bsdaddr" attribute - */ - if (printer == NULL) { - ns_bsd_addr_t *a = - ns_get_value(NS_KEY_BSDADDR, p); - if ((a != NULL) && (a->printer != NULL)) { - static char buf[64]; - (void) snprintf(buf, sizeof (buf), "%s", - a->printer); - printer = buf; - } - } - } - } - if (printer != NULL) - (void) printf(gettext("system default destination: %s\n"), - printer); - else - (void) printf(gettext("no system default destination\n")); -} diff --git a/usr/src/cmd/print/lpstat/sysv-functions.h b/usr/src/cmd/print/lpstat/sysv-functions.h deleted file mode 100644 index eea04ecc4b..0000000000 --- a/usr/src/cmd/print/lpstat/sysv-functions.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1998 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _SYSV_FUNCTIONS_H -#define _SYSV_FUNCTIONS_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -extern void vsysv_queue_entry(job_t *job, va_list ap); -extern int sysv_queue_state(print_queue_t *qp, char *printer, int verbose, - int description); -extern int sysv_accept(ns_bsd_addr_t *binding); -extern int sysv_system(ns_bsd_addr_t *binding); -extern void sysv_running(); -extern void sysv_default(); -extern int sysv_local_status(char *, char *, int, int, char *); -extern print_queue_t *sysv_get_queue(ns_bsd_addr_t *binding, int local); - -#ifdef __cplusplus -} -#endif - -#endif /* _SYSV_FUNCTIONS_H */ diff --git a/usr/src/cmd/print/scripts/Makefile b/usr/src/cmd/print/scripts/Makefile index 5012684790..0e9e771bec 100644 --- a/usr/src/cmd/print/scripts/Makefile +++ b/usr/src/cmd/print/scripts/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -39,7 +38,7 @@ OWNER = root GROUP = lp FILEMODE = 0755 -MSGFILES = accept lpadmin +MSGFILES = lpadmin POFILE = scripts.po PROG = conv_lp conv_lpd Makefile.yp @@ -47,7 +46,7 @@ ROOTLIBPRINTPROG= $(PROG:%=$(ROOTPRINTLIB)/%) $(ROOTLIBPRINTPROG) := FILEMODE=0555 $(ROOTPRINTLIB)/Makefile.yp := FILEMODE=0444 -USRSBINPROG= accept lpsystem lpadmin +USRSBINPROG= lpsystem lpadmin ROOTUSRSBINPROG= $(USRSBINPROG:%=$(ROOTUSRSBIN)/%) $(ROOTUSRSBINPROG) := FILEMODE=555 @@ -63,10 +62,6 @@ $(ROOTPPDPROGS) := OWNER=root $(ROOTPPDPROGS) := GROUP=lp $(ROOTPPDPROGS) := FILEMODE=555 -ACCEPTLINKS= $(ROOTUSRSBIN)/reject $(ROOTBIN)/enable \ - $(ROOTBIN)/disable $(ROOTLIB)/accept \ - $(ROOTLIB)/reject - LIBLINKS= $(ROOTLIB)/lpadmin $(ROOTLIB)/lpsystem @@ -89,9 +84,6 @@ $(ROOTLIB)/lpadmin: $(ROOTLIB)/lpsystem: $(RM) $@; $(SYMLINK) ../sbin/lpsystem $@ -$(ACCEPTLINKS): - $(RM) $@; $(SYMLINK) ../sbin/accept $@ - $(ROOTLNKPROGS) : $(ROOTSTARTPROG) $(RM) $@; $(LN) $(ROOTSTARTPROG) $@ @@ -116,8 +108,7 @@ install: $(ROOTINIT_D) $(ROOTLNKPROGS) \ $(ROOTLIBPRINTPROG) $(ROOTSTARTPROG) \ $(ROOTUSRSBIN) $(ROOTUSRSBINPROG) \ $(ROOTVARSPOOLPRINT) $(ROOTPCONF) \ - $(ROOTPPDPROGS) \ - $(LIBLINKS) $(ACCEPTLINKS) + $(ROOTPPDPROGS) $(LIBLINKS) $(SYMLINKS1): $(RM) $@; $(SYMLINK) ../sbin/$(SBINPROG1) $@ @@ -125,9 +116,6 @@ $(SYMLINKS1): $(SYMLINKS2): $(RM) $@; $(SYMLINK) ../sbin/$(SBINPROG2) $@ -$(REJECTLINK): - $(RM) $@; $(SYMLINK) accept $@ - clean: $(RM) $(POFILE) diff --git a/usr/src/cmd/print/scripts/accept b/usr/src/cmd/print/scripts/accept deleted file mode 100644 index 8d2fb4a995..0000000000 --- a/usr/src/cmd/print/scripts/accept +++ /dev/null @@ -1,141 +0,0 @@ -#!/bin/sh -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright (c) 1994, 1995, 1996 by Sun Microsystems, Inc. -# All Rights Reserved -# -# ident "%Z%%M% %I% %E% SMI" -# -PATH=/usr/ucb:/bin:/usr/bin:/usr/sbin export PATH -cmd_name=`basename $0` -args="" -reason="" -destinations="" -exit_code=0 -local_exit=0 - -TEXTDOMAIN="SUNW_OST_OSCMD" -export TEXTDOMAIN - -# -# check for some options -# -if [ $# -lt 1 ] ; then - gettext "Usage: " - echo -n $cmd_name $valid_opts - gettext " printer ..." - echo - exit 1 -fi - -# set variables for command -case $cmd_name in - accept) - valid_opts="" - options="\?" - ;; - enable) - valid_opts="" - options="\?" - ;; - reject) - valid_opts="[ -r reason ]" - options="r:" - ;; - disable) - valid_opts="[ -c | -W ] [ -r reason ]" - options="Wcr:" - ;; - *) - gettext "Error: " - echo -n $cmd_name - gettext " - invalid name" - echo - exit 1 - ;; -esac - -# Strip off legal options -while getopts $options arg -do - case $arg in - c|W) - args="${args} -$arg" - ;; - r) - reason=${OPTARG} - ;; - \?) - gettext "Usage: " - echo -n $cmd_name $valid_opts - gettext " printer ..." - echo - exit 1 - ;; - esac -done -shift `expr $OPTIND - 1` - - -if [ "$*" = "" ] ; then - gettext "No destination specified" - echo - exit 1 -fi - -# Each destination -for printer in $* -do - if [ -f /etc/lp/classes/$printer -o -d /etc/lp/printers/$printer -a \ - -f /usr/lib/lp/local/$cmd_name ] - then - destinations="${destinations} ${printer}" - else - check=`lpstat -v $printer -L` - if [ -n "$check" ] - then - gettext "Warning: " - echo -n $printer - gettext " is remote, $cmd_name has no meaning." - echo - else - exit_code=1 - fi - fi -done - -if [ -n "$destinations" ] -then - if [ -n "$reason" ] ; then - /usr/lib/lp/local/$cmd_name -r "$reason" $args $destinations - else - /usr/lib/lp/local/$cmd_name $args $destinations - fi - local_exit=$? -fi - -if [ ${local_exit} -ne 0 ] ; then - exit ${local_exit} -else - exit ${exit_code} -fi diff --git a/usr/src/cmd/print/scripts/lpadmin b/usr/src/cmd/print/scripts/lpadmin index e4cc8ea85f..ee6d1ccb4d 100644 --- a/usr/src/cmd/print/scripts/lpadmin +++ b/usr/src/cmd/print/scripts/lpadmin @@ -3,9 +3,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -21,7 +20,7 @@ # CDDL HEADER END # # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -318,6 +317,14 @@ if [ -f /usr/lib/lp/local/$cmd_name ] ; then fi eval $CMD exit_code=$? + # add filters to the print server + if [ ! -f /etc/lp/filter.table ] ; then + cd /etc/lp/fd ; for filter in *.fd ; do + /usr/sbin/lpfilter \ + -f `/usr/bin/basename $filter .fd` \ + -F $filter + done + fi fi fi @@ -325,21 +332,34 @@ if [ $exit_code != 0 ] ; then exit $exit_code fi - -# split the "server" into printer and server +# process the "server" value +# It can be a hostname, UUCP form (server!queue), RCMD form(queue@server), +# or in URI form ({scheme}://{endpoint}) +# +case "${server}" in + *://*) # URI form + uri=${server} + rem_printer=`expr "${server}" : ".*://.*/\([^/]*\)"` + server=`expr "${server}" : ".*://\([^/]*\)/.*"` + ;; + *@*) # RCMD form + rem_printer=`expr "${server}" : "\(.*\)@.*"` + server=`expr "${server}" : ".*@\(.*\)"` + ;; + *!*) # UUCP form + rem_printer=`expr "${server}" : ".*!\(.*\)"` + server=`expr "${server}" : "\(.*\)!.*"` + ;; + *) # hostname + rem_printer=${printer} + ;; +esac +# default URI form is "lpd" form if [ -n "${server}" ] ; then - if [ `echo ${server} | /bin/grep -c !` = 1 ] ; then - rem_printer=`echo ${server} | cut -d! -f2` - fi - server=`echo ${server} | cut -d! -f1` + uri=${uri:-"lpd://${server}/printers/${rem_printer}#Solaris"} + bsdaddr="${server},${rem_printer},Solaris" fi -if [ -z "${rem_printer}" ] ; then - rem_printer=${printer} -fi - - - # # Do the Solstice Print Configuration in /etc # @@ -356,10 +376,12 @@ else fi fi - if [ -n "${printer}" -a -n "${server}" ] ; then - ${LPSET} -n system \ - -a "bsdaddr=${server},${rem_printer},Solaris" \ - ${printer} + if [ -n "${printer}" -a -n "${uri}" ] ; then + ${LPSET} -n system -a "printer-uri-supported=${uri}" ${printer} + exit_code=$? + fi + if [ -n "${printer}" -a -n "${bsdaddr}" ] ; then + ${LPSET} -n system -a "bsdaddr=${bsdaddr}" ${printer} exit_code=$? fi if [ -n "${printer}" -a -n "${description}" ] ; then @@ -377,14 +399,14 @@ else # If the class doesn't already exist in printers.conf, add it. - if [ -n "${server}" ] ; then - CHOST=$server - else - CHOST=$HOST - fi + server=${server:-$HOST} + uri="lpd://${server}/printers/${class}#Solaris" + bsdaddr="${server},${class},Solaris" if [ ${lpget_class} -ne 0 ] ; then ${LPSET} -n system \ - -a "bsdaddr=${CHOST},${class},Solaris" ${class} + -a "printer-uri-supported=${uri}" \ + -a "bsdaddr=${bsdaddr}" \ + ${class} exit_code=$? fi fi diff --git a/usr/src/lib/print/Makefile b/usr/src/lib/print/Makefile index 63feb1e6e9..fd931373e8 100644 --- a/usr/src/lib/print/Makefile +++ b/usr/src/lib/print/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -20,71 +19,76 @@ # CDDL HEADER END # # -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" # -# cmd/lp/client/lib/Makefile -# - -LIBRARY = libprint.a -VERS=.2 - -FILEMODE= 0555 - -NS_CMN = ns_bsd_addr.o ns_cmn_kvp.o ns_cmn_printer.o -NS_SWITCH = nss_printer.o nss_convert.o nss_write.o nss_ldap.o -NS_SUPPORT = ns.o ${NS_CMN} ${NS_SWITCH} - -OBJECTS = network.o job.o list.o misc.o $(NS_SUPPORT) +SUBDIRS = \ + libprint \ + libpapi-common \ + libpapi-dynamic \ + libpapi-lpd \ + libipp-core \ + libhttp-core \ + libpapi-ipp \ + libipp-listener \ + mod_ipp + +all := TARGET = all +clean := TARGET = clean +clobber := TARGET = clobber +install := TARGET = install +install_h := TARGET = install_h +lint := TARGET = lint + +include $(SRC)/Makefile.master + +TEXT_DOMAIN= SUNW_OST_OSLIB +POFILE= print-lib.po -include ../Makefile.lib - -MAPFILES= mapfile-vers -MAPOPTS= $(MAPFILES:%=-M %) - -CPPFLAGS += -I../../head -I../ -I. -D_REENTRANT -LDLIBS += -lnsl -lsocket -lc -lldap -DYNFLAGS += $(MAPOPTS) +.KEEP_STATE: +all: $(TXTS) $(SUBDIRS) -LIBS = $(DYNLIB) # could be += for static and dynamic -# for messaging catalog # -POFILE= bsd.po -SRCS= $(OBJECTS:%.o=%.c) -XGETFLAGS +=-a - -.KEEP_STATE: - -_msg: $(POFILE) +# Each message catalog file is generated in each sub +# directory and copied to the usr/src/cmd/lp/ directory. +# Those message catalog files are consolidated into one +# message catalog file. The consolidated one will be copied +# into the $(ROOT)/catalog/SUNW_OST_OSCMD/ directory. +# -$(POFILE): $(SRCS) - $(RM) $@ - $(COMPILE.cpp) $(SRCS) > $(POFILE).i - $(XGETTEXT) $(XGETFLAGS) $(POFILE).i - sed "/^domain/d" messages.po > $@ - $(RM) messages.po $(POFILE).i +_msg: $(MSGDOMAIN) + @$(RM) $(POFILE) + $(XGETTEXT) -s `/bin/find . -type d -name SCCS -prune -o -type f -name '*.c' -print` + @/bin/cat messages.po | sed '/domain/d' > $(POFILE) + @$(RM) messages.po + $(RM) $(MSGDOMAIN)/$(POFILE) + /bin/cp $(POFILE) $(MSGDOMAIN) -all : $(LIBS) +install: $(ROOTDIRS) $(ROOTSYMLINKDIRS) $(SUBDIRS) -install: $(ROOTLIBDIR) $(ROOTLIBS) $(ROOTLINKS) +install_h clean strip lint: $(SUBDIRS) -# definitions for lint +clobber: $(SUBDIRS) local_clobber -$(LINTLIB):= SRCS = llib-lprint -CLEANFILES += $(LINTLIB) $(LINTOUT) +local_clobber: + $(RM) $(CLOBBERFILES) $(POFILE) -lint: lintcheck +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) -cstyle: - cstyle $(SRCS) +FRC: -strip : +include $(SRC)/Makefile.msg.targ -$(ROOTLIBDIR): - $(INS.dir) +# Dependencies +libpapi-dynamic: libpapi-common +libpapi-lpd: libpapi-dynamic +libipp-core: libpapi-common +libpapi-ipp: libpapi-common libipp-core libhttp-core +libipp-listener: libpapi-dynamic libipp-core +mod_ipp: libipp-listener -include ../Makefile.targ diff --git a/usr/src/lib/print/job.h b/usr/src/lib/print/job.h deleted file mode 100644 index eed81c5f00..0000000000 --- a/usr/src/lib/print/job.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1998 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _JOB_H -#define _JOB_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/va_list.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Sequence number space - */ -#define JOB_ID_START 0 -#define JOB_ID_END 999 - -/* - * Job related files - */ -#define SEQUENCE_FILE ".seq" /* sequence numbers */ -#define TEMP_FILE_PREFIX "tf" /* printer:server */ -#define XFER_FILE_PREFIX "xf" /* printer:server */ -#define CONTROL_FILE_PREFIX "cf" /* job control data */ -#define DATA_FILE_PREFIX "df" /* job data file */ - -/* - * RFC-1179 Control File Primatives - */ -#define CF_CLASS 'C' /* C(ClassName)\n - for banner page */ -#define CF_HOST 'H' /* H(Hostname)\n - host submitting job */ -#define CF_INDENT 'I' /* I(indent)\n - # of spaces for 'f' */ -#define CF_JOBNAME 'J' /* J(Jobname)\n - name of job for banner */ -#define CF_PRINT_BANNER 'L' /* L[User]\n - User name on burst page */ -#define CF_MAIL 'M' /* M(user)\n - User to mail when done */ -#define CF_SOURCE_NAME 'N' /* N(name)\n - source of data file */ -#define CF_USER 'P' /* P(name)\n - requesting user */ -#define CF_SYMLINK 'S' /* S(device) (inode)\n - foget it */ -#define CF_TITLE 'T' /* T(title)\n - for pr */ -#define CF_UNLINK 'U' /* U(file)\n - unlink file */ -#define CF_WIDTH 'W' /* W(width)\n - column width */ -#define CF_FONT_TROFF_R '1' /* 1(file)\n - file with Times Roman font */ -#define CF_FONT_TROFF_I '2' /* 2(file)\n - file with Times Italic font */ -#define CF_FONT_TROFF_B '3' /* 3(file)\n - file with Times Bold font */ -#define CF_FONT_TROFF_S '4' /* 4(file)\n - file with Times Special font */ -#define CF_PRINT_CIF 'c' /* c(file)\n - print/plot file as CIF data */ -#define CF_PRINT_DVI 'd' /* d(file)\n - print file as DVI data */ -#define CF_PRINT_ASCII 'f' /* f(file)\n - print file as ASCII */ -#define CF_PRINT_PLOT 'g' /* g(file)\n - print file as plot data */ -#define CF_KERBERIZED 'k' /* k...\n - for Kerberos */ -#define CF_PRINT_RAW 'l' /* l(file)\n - print file dammit */ -#define CF_PRINT_DROFF 'n' /* n(file)\n - print file as ditroff output */ -#define CF_PRINT_PS 'o' /* o(file)\n - print file as PostScript */ -#define CF_PRINT_PR 'p' /* p(file)\n - print file thru "pr" */ -#define CF_PRINT_FORT 'r' /* r(file)\n - print file as fortran */ -#define CF_PRINT_TROFF 't' /* n(file)\n - print file as troff output */ -#define CF_PRINT_RAS 'v' /* v(file)\n - print file as raster image */ -#define CF_PRINT_PLDM 'z' /* z...\n - for Palladium ??? */ - -/* - * Solaris 2.X LP - BSD protocol extensions - */ -#define CF_SYSV_OPTION 'O' /* for SVR4 LP '-o' option */ -#define CF_SYSV_FEATURE '5' /* for SVR4 LP features */ -#define CF_SYSV_FORM 'f' /* for SVR4 Forms */ -#define CF_SYSV_HANDLING 'H' /* for SVR4 Handling */ -#define CF_SYSV_NOTIFICATION 'p' /* for SVR4 Notification */ -#define CF_SYSV_PAGES 'P' /* for SVR4 Pages */ -#define CF_SYSV_PRIORITY 'q' /* for SVR4 Priority */ -#define CF_SYSV_CHARSET 'S' /* for SVR4 Charset */ -#define CF_SYSV_TYPE 'T' /* for SVR4 Type */ -#define CF_SYSV_MODE 'y' /* for SVR4 Mode */ - - -typedef struct _jobfile jobfile_t; -typedef struct _job job_t; - -struct _jobfile { - char *jf_spl_path; /* df file */ - char *jf_src_path; /* source file */ - char *jf_name; /* title/name */ - char *jf_data; /* ptr to mmapped file */ - long jf_size; /* size of data */ - char jf_mmapped; /* is this mmapped or malloced */ -} ; - -struct _job { - int job_id; - char *job_printer; - char *job_server; - char *job_user; - char *job_host; - char *job_spool_dir; - jobfile_t *job_cf; - char job_df_next; - jobfile_t **job_df_list; -} ; - - -extern int job_primative(job_t *job, char option, char *value); -extern int job_svr4_primative(job_t *job, char option, char *value); -extern int job_add_data_file(job_t *job, char *path, char *title, - char type, int copies, int linked, - int delete); -extern int job_store(job_t *job); -extern void job_free(job_t *job); -extern void job_destroy(job_t *job); -extern job_t *job_create(char *printer, char *server, char *spool); -extern job_t *job_retrieve(char *xfer_file, char *spool); -extern job_t **job_list_append(job_t **list, char *printer, - char *server, char *spool); -extern int vjob_match_attribute(char *attribute, __va_list ap); -extern int vjob_cancel(job_t *job, __va_list ap); - -#ifdef __cplusplus -} -#endif - -#endif /* !_JOB_H */ diff --git a/usr/src/lib/print/libhttp-core/Makefile b/usr/src/lib/print/libhttp-core/Makefile new file mode 100644 index 0000000000..b92d620b10 --- /dev/null +++ b/usr/src/lib/print/libhttp-core/Makefile @@ -0,0 +1,56 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../../Makefile.lib + +#HDRS = papi.h +#HDRDIR = common +SUBDIRS = $(MACH) +#$(BUILD64)SUBDIRS += $(MACH64) + +all := TARGET = all +clean := TARGET = clean +clobber := TARGET = clobber +install := TARGET = install +lint := TARGET = lint + +.KEEP_STATE: + +all clean clobber install: .WAIT $(SUBDIRS) + +lint: # $(SUBDIRS) + +install_h: # $(ROOTHDRS) + +check: # $(CHECKHDRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include ../../Makefile.targ diff --git a/usr/src/cmd/lp/cmd/lpstat/Makefile b/usr/src/lib/print/libhttp-core/Makefile.com index 9e9b661703..c027f93270 100644 --- a/usr/src/cmd/lp/cmd/lpstat/Makefile +++ b/usr/src/lib/print/libhttp-core/Makefile.com @@ -17,75 +17,48 @@ # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END - - # # -# ident "%Z%%M% %I% %E% SMI" -# # Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# cmd/lp/cmd/lpstat/Makefile +# ident "%Z%%M% %I% %E% SMI" # -include ../../Makefile.lp +LIBRARY = libhttp-core.a +VERS = .1 +OBJECTS = http-addr.o http-support.o http.o -PROG= lpstat +ROOTLIBDIR = $(ROOT)/usr/lib/print -SRCS = accept.c \ - add_mounted.c \ - charset.c \ - class.c \ - device.c \ - done.c \ - form.c \ - lpstat.c \ - output.c \ - parse.c \ - printer.c \ - request.c \ - send_message.c +include ../../../Makefile.lib +include ../../../Makefile.rootfs -OBJS= $(SRCS:.c=.o) +ROOTLIBDIR= $(ROOT)/usr/lib/print +ROOTLIBDIR64= $(ROOT)/usr/lib/print/$(MACH) +LIBS = $(DYNLIB) -CPPFLAGS = -I$(LPINC) $(CPPFLAGS.master) +SRCS = $(OBJECTS:%.o = $(SRCDIR)/%.c) -LPLIBS = $(LIBACC) \ - $(LIBCLS) \ - $(LIBMSG) \ - $(LIBPRT) \ - $(LIBFRM) \ - $(LIBOAM) \ - $(LIBLP) +$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC) -SYSLIBS= -lcurses +SRCDIR = ../common +MAPFILE = $(SRCDIR)/mapfile -LDLIBS += $(LPLIBS) $(SYSLIBS) $(I18N) -z lazyload -lsecdb -z nolazyload - -POFILE= lp_cmd_lpstat.po +CFLAGS += $(CCVERBOSE) +CPPFLAGS += -I$(SRCDIR) +CPPFLAGS += -I../../libpapi-common/common +DYNFLAGS += -M $(MAPFILE) +LDLIBS += -lsocket -lnsl -lc .KEEP_STATE: -all: $(PROG) - -$(PROG): $(OBJS) - $(LINK.c) $(OBJS) -o $@ $(LDLIBS) - $(POST_PROCESS) - -install: all $(ROOTLIBLPLOCLPROG) - -clean: - $(RM) $(OBJS) - -clobber: clean - -$(RM) $(PROG) $(CLOBBERFILES) +all: $(LIBS) -strip: - $(STRIP) $(PROG) +lint: lintcheck -lint: - $(LINT.c) $(SRCS) $(LDLIBS) +$(ROOTLIBDIR): + $(INS.dir) -include ../Makefile.msg +include ../../../Makefile.targ diff --git a/usr/src/lib/print/libhttp-core/common/debug.h b/usr/src/lib/print/libhttp-core/common/debug.h new file mode 100644 index 0000000000..aebc790017 --- /dev/null +++ b/usr/src/lib/print/libhttp-core/common/debug.h @@ -0,0 +1,70 @@ +/* + * "$Id: debug.h 148 2006-04-25 16:54:17Z njacobs $ + * + * Debugging macros for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636 USA + * + * Voice: (301) 373-9600 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +#ifndef _CUPS_DEBUG_H_ +#define _CUPS_DEBUG_H_ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Include necessary headers... + */ + +# include <stdio.h> + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + * The debug macros are used if you compile with DEBUG defined. + * + * Usage: + * + * DEBUG_puts("string") + * DEBUG_printf(("format string", arg, arg, ...)); + * + * Note the extra parenthesis around the DEBUG_printf macro... + */ + +# ifdef DEBUG +# define DEBUG_puts(x) puts(x) +# define DEBUG_printf(x) printf x +# else +# define DEBUG_puts(x) +# define DEBUG_printf(x) +# endif /* DEBUG */ + +#ifdef __cplusplus +} +#endif + +#endif /* !_CUPS_DEBUG_H_ */ + +/* + * End of "$Id: debug.h 148 2006-04-25 16:54:17Z njacobs $" + */ diff --git a/usr/src/lib/print/libhttp-core/common/http-addr.c b/usr/src/lib/print/libhttp-core/common/http-addr.c new file mode 100644 index 0000000000..a872d4d3fd --- /dev/null +++ b/usr/src/lib/print/libhttp-core/common/http-addr.c @@ -0,0 +1,371 @@ +/* + * "$Id: http-addr.c 148 2006-04-25 16:54:17Z njacobs $" + * + * HTTP address routines for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2005 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636 USA + * + * Voice: (301) 373-9600 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * httpAddrAny() - Check for the "any" address. + * httpAddrEqual() - Compare two addresses. + * httpAddrLoad() - Load a host entry address into an HTTP address. + * httpAddrLocalhost() - Check for the local loopback address. + * httpAddrLookup() - Lookup the hostname associated with the address. + * httpAddrString() - Convert an IP address to a dotted string. + * httpGetHostByName() - Lookup a hostname or IP address, and return + * address records for the specified name. + */ + +/* + * Include necessary headers... + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include "http.h" +#include "debug.h" +#include "string.h" +#include <ctype.h> + + +/* + * 'httpAddrAny()' - Check for the "any" address. + */ + +int /* O - 1 if "any", 0 otherwise */ +httpAddrAny(const http_addr_t *addr) /* I - Address to check */ +{ +#ifdef AF_INET6 + if (addr->addr.sa_family == AF_INET6 && + IN6_IS_ADDR_UNSPECIFIED(&(addr->ipv6.sin6_addr))) + return (1); +#endif /* AF_INET6 */ + + if (addr->addr.sa_family == AF_INET && + ntohl(addr->ipv4.sin_addr.s_addr) == 0x00000000) + return (1); + + return (0); +} + + +/* + * 'httpAddrEqual()' - Compare two addresses. + */ + +int /* O - 1 if equal, 0 if != */ +httpAddrEqual(const http_addr_t *addr1, /* I - First address */ + const http_addr_t *addr2) /* I - Second address */ +{ + if (addr1->addr.sa_family != addr2->addr.sa_family) + return (0); + +#ifdef AF_INET6 + if (addr1->addr.sa_family == AF_INET6) + return (memcmp(&(addr1->ipv6.sin6_addr), &(addr2->ipv6.sin6_addr), 16) == 0); +#endif /* AF_INET6 */ + + return (addr1->ipv4.sin_addr.s_addr == addr2->ipv4.sin_addr.s_addr); +} + + +/* + * 'httpAddrLoad()' - Load a host entry address into an HTTP address. + */ + +void +httpAddrLoad(const struct hostent *host, /* I - Host entry */ + int port, /* I - Port number */ + int n, /* I - Index into host entry */ + http_addr_t *addr) /* O - Address to load */ +{ +#ifdef AF_INET6 + if (host->h_addrtype == AF_INET6) + { +# ifdef WIN32 + addr->ipv6.sin6_port = htons((u_short)port); +# else + addr->ipv6.sin6_port = htons(port); +# endif /* WIN32 */ + + memcpy((char *)&(addr->ipv6.sin6_addr), host->h_addr_list[n], + host->h_length); + addr->ipv6.sin6_family = AF_INET6; + } + else +#endif /* AF_INET6 */ +#ifdef AF_LOCAL + if (host->h_addrtype == AF_LOCAL) + { + addr->un.sun_family = AF_LOCAL; + strlcpy(addr->un.sun_path, host->h_addr_list[n], sizeof(addr->un.sun_path)); + } + else +#endif /* AF_LOCAL */ + if (host->h_addrtype == AF_INET) + { +# ifdef WIN32 + addr->ipv4.sin_port = htons((u_short)port); +# else + addr->ipv4.sin_port = htons(port); +# endif /* WIN32 */ + + memcpy((char *)&(addr->ipv4.sin_addr), host->h_addr_list[n], + host->h_length); + addr->ipv4.sin_family = AF_INET; + } +} + + +/* + * 'httpAddrLocalhost()' - Check for the local loopback address. + */ + +int /* O - 1 if local host, 0 otherwise */ +httpAddrLocalhost(const http_addr_t *addr) + /* I - Address to check */ +{ +#ifdef AF_INET6 + if (addr->addr.sa_family == AF_INET6 && + IN6_IS_ADDR_LOOPBACK(&(addr->ipv6.sin6_addr))) + return (1); +#endif /* AF_INET6 */ + +#ifdef AF_LOCAL + if (addr->addr.sa_family == AF_LOCAL) + return (1); +#endif /* AF_LOCAL */ + + if (addr->addr.sa_family == AF_INET && + ntohl(addr->ipv4.sin_addr.s_addr) == 0x7f000001) + return (1); + + return (0); +} + + +#ifdef __sgi +# define ADDR_CAST (struct sockaddr *) +#else +# define ADDR_CAST (char *) +#endif /* __sgi */ + + +/* + * 'httpAddrLookup()' - Lookup the hostname associated with the address. + */ + +char * /* O - Host name */ +httpAddrLookup(const http_addr_t *addr, /* I - Address to lookup */ + char *name, /* I - Host name buffer */ + int namelen) /* I - Size of name buffer */ +{ + struct hostent *host; /* Host from name service */ + + + DEBUG_printf(("httpAddrLookup(addr=%p, name=%p, namelen=%d)\n", + addr, name, namelen)); + +#ifdef AF_INET6 + if (addr->addr.sa_family == AF_INET6) + host = gethostbyaddr(ADDR_CAST &(addr->ipv6.sin6_addr), + sizeof(struct in6_addr), AF_INET6); + else +#endif /* AF_INET6 */ +#ifdef AF_LOCAL + if (addr->addr.sa_family == AF_LOCAL) + { + strlcpy(name, addr->un.sun_path, namelen); + return (name); + } + else +#endif /* AF_LOCAL */ + if (addr->addr.sa_family == AF_INET) + host = gethostbyaddr(ADDR_CAST &(addr->ipv4.sin_addr), + sizeof(struct in_addr), AF_INET); + else + host = NULL; + + if (host == NULL) + { + httpAddrString(addr, name, namelen); + return (NULL); + } + + strlcpy(name, host->h_name, namelen); + + return (name); +} + + +/* + * 'httpAddrString()' - Convert an IP address to a dotted string. + */ + +char * /* O - IP string */ +httpAddrString(const http_addr_t *addr, /* I - Address to convert */ + char *s, /* I - String buffer */ + int slen) /* I - Length of string */ +{ + DEBUG_printf(("httpAddrString(addr=%p, s=%p, slen=%d)\n", + addr, s, slen)); + +#ifdef AF_INET6 + if (addr->addr.sa_family == AF_INET6) + snprintf(s, slen, "%u.%u.%u.%u", + ntohl(addr->ipv6.sin6_addr.s6_addr32[0]), + ntohl(addr->ipv6.sin6_addr.s6_addr32[1]), + ntohl(addr->ipv6.sin6_addr.s6_addr32[2]), + ntohl(addr->ipv6.sin6_addr.s6_addr32[3])); + else +#endif /* AF_INET6 */ +#ifdef AF_LOCAL + if (addr->addr.sa_family == AF_LOCAL) + strlcpy(s, addr->un.sun_path, slen); + else +#endif /* AF_LOCAL */ + if (addr->addr.sa_family == AF_INET) + { + unsigned temp; /* Temporary address */ + + + temp = ntohl(addr->ipv4.sin_addr.s_addr); + + snprintf(s, slen, "%d.%d.%d.%d", (temp >> 24) & 255, + (temp >> 16) & 255, (temp >> 8) & 255, temp & 255); + } + else + strlcpy(s, "UNKNOWN", slen); + + DEBUG_printf(("httpAddrString: returning \"%s\"...\n", s)); + + return (s); +} + + +/* + * 'httpGetHostByName()' - Lookup a hostname or IP address, and return + * address records for the specified name. + */ + +struct hostent * /* O - Host entry */ +httpGetHostByName(const char *name) /* I - Hostname or IP address */ +{ + const char *nameptr; /* Pointer into name */ + unsigned ip[4]; /* IP address components */ + static unsigned packed_ip; /* Packed IPv4 address */ + static char *packed_ptr[2]; /* Pointer to packed address */ + static struct hostent host_ip; /* Host entry for IP/domain address */ + + + DEBUG_printf(("httpGetHostByName(name=\"%s\")\n", name)); + +#if defined(__APPLE__) + /* OS X hack to avoid it's ocassional long delay in lookupd */ + static const char sLoopback[] = "127.0.0.1"; + if (strcmp(name, "localhost") == 0) + name = sLoopback; +#endif /* __APPLE__ */ + + /* + * This function is needed because some operating systems have a + * buggy implementation of gethostbyname() that does not support + * IP addresses. If the first character of the name string is a + * number, then sscanf() is used to extract the IP components. + * We then pack the components into an IPv4 address manually, + * since the inet_aton() function is deprecated. We use the + * htonl() macro to get the right byte order for the address. + * + * We also support domain sockets when supported by the underlying + * OS... + */ + +#ifdef AF_LOCAL + if (name[0] == '/') + { + /* + * A domain socket address, so make an AF_LOCAL entry and return it... + */ + + host_ip.h_name = (char *)name; + host_ip.h_aliases = NULL; + host_ip.h_addrtype = AF_LOCAL; + host_ip.h_length = strlen(name) + 1; + host_ip.h_addr_list = packed_ptr; + packed_ptr[0] = (char *)name; + packed_ptr[1] = NULL; + + DEBUG_puts("httpGetHostByName: returning domain socket address..."); + + return (&host_ip); + } +#endif /* AF_LOCAL */ + + for (nameptr = name; isdigit(*nameptr & 255) || *nameptr == '.'; nameptr ++); + + if (!*nameptr) + { + /* + * We have an IP address; break it up and provide the host entry + * to the caller. Currently only supports IPv4 addresses, although + * it should be trivial to support IPv6 in CUPS 1.2. + */ + + if (sscanf(name, "%u.%u.%u.%u", ip, ip + 1, ip + 2, ip + 3) != 4) + return (NULL); /* Must have 4 numbers */ + + if (ip[0] > 255 || ip[1] > 255 || ip[2] > 255 || ip[3] > 255) + return (NULL); /* Invalid byte ranges! */ + + packed_ip = htonl(((((((ip[0] << 8) | ip[1]) << 8) | ip[2]) << 8) | ip[3])); + + /* + * Fill in the host entry and return it... + */ + + host_ip.h_name = (char *)name; + host_ip.h_aliases = NULL; + host_ip.h_addrtype = AF_INET; + host_ip.h_length = 4; + host_ip.h_addr_list = packed_ptr; + packed_ptr[0] = (char *)(&packed_ip); + packed_ptr[1] = NULL; + + DEBUG_puts("httpGetHostByName: returning IPv4 address..."); + + return (&host_ip); + } + else + { + /* + * Use the gethostbyname() function to get the IP address for + * the name... + */ + + DEBUG_puts("httpGetHostByName: returning domain lookup address(es)..."); + + return (gethostbyname(name)); + } +} + + +/* + * End of "$Id: http-addr.c 148 2006-04-25 16:54:17Z njacobs $". + */ diff --git a/usr/src/lib/print/libhttp-core/common/http-private.h b/usr/src/lib/print/libhttp-core/common/http-private.h new file mode 100644 index 0000000000..a11b8bbb5e --- /dev/null +++ b/usr/src/lib/print/libhttp-core/common/http-private.h @@ -0,0 +1,115 @@ +/* + * "$Id: http-private.h 148 2006-04-25 16:54:17Z njacobs $" + * + * Private HTTP definitions for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2005 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636 USA + * + * Voice: (301) 373-9600 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +#ifndef _CUPS_HTTP_PRIVATE_H_ +#define _CUPS_HTTP_PRIVATE_H_ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Include necessary headers... + */ +#ifdef __cplusplus +extern "C" { +#endif + + +# include "config.h" + + +# ifdef __sun +/* + * Define FD_SETSIZE to CUPS_MAX_FDS on Solaris to get the correct version of + * select() for large numbers of file descriptors. + */ + +#define CUPS_MAX_FDS 1024 + +# define FD_SETSIZE CUPS_MAX_FDS +# include <sys/select.h> +# endif /* __sun */ + +# include "http.h" + +# if defined HAVE_LIBSSL +/* + * The OpenSSL library provides its own SSL/TLS context structure for its + * IO and protocol management... + */ + +# include <openssl/err.h> +# include <openssl/rand.h> +# include <openssl/ssl.h> + +typedef SSL http_tls_t; + +# elif defined HAVE_GNUTLS +/* + * The GNU TLS library is more of a "bare metal" SSL/TLS library... + */ +# include <gnutls/gnutls.h> + +typedef struct +{ + gnutls_session session; /* GNU TLS session object */ + void *credentials; /* GNU TLS credentials object */ +} http_tls_t; + +# elif defined(HAVE_CDSASSL) +/* + * Darwin's Security framework provides its own SSL/TLS context structure + * for its IO and protocol management... + */ + +# include <Security/SecureTransport.h> + +typedef SSLConnectionRef http_tls_t; + +# endif /* HAVE_LIBSSL */ + +/* + * Some OS's don't have hstrerror(), most notably Solaris... + */ + +# ifndef HAVE_HSTRERROR +extern const char *cups_hstrerror(int error); +# define hstrerror cups_hstrerror +# elif defined(_AIX) || defined(__osf__) +/* + * AIX and Tru64 UNIX don't provide a prototype but do provide the function... + */ +extern const char *hstrerror(int error); +# endif /* !HAVE_HSTRERROR */ + +#ifdef __cplusplus +} +#endif + +#endif /* !_CUPS_HTTP_PRIVATE_H_ */ + +/* + * End of "$Id: http-private.h 148 2006-04-25 16:54:17Z njacobs $" + */ diff --git a/usr/src/lib/print/libhttp-core/common/http-support.c b/usr/src/lib/print/libhttp-core/common/http-support.c new file mode 100644 index 0000000000..2ef3911058 --- /dev/null +++ b/usr/src/lib/print/libhttp-core/common/http-support.c @@ -0,0 +1,379 @@ +/* + * "$Id: http-support.c 148 2006-04-25 16:54:17Z njacobs $" + * + * HTTP support routines for the Common UNIX Printing System (CUPS) scheduler. + * + * Copyright 1997-2005 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636 USA + * + * Voice: (301) 373-9600 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * httpSeparate() - Separate a Universal Resource Identifier into its + * components. + * httpSeparate2() - Separate a Universal Resource Identifier into its + * components. + * httpStatus() - Return a short string describing a HTTP status code. + * cups_hstrerror() - hstrerror() emulation function for Solaris and others... + * http_copy_decode() - Copy and decode a URI. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Include necessary headers... + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <ctype.h> +#include "string.h" + +#include "http.h" + + +/* + * Local functions... + */ + +static const char *http_copy_decode(char *dst, const char *src, + int dstsize, const char *term); + + +/* + * 'httpSeparate()' - Separate a Universal Resource Identifier into its + * components. + */ + +void +httpSeparate(const char *uri, /* I - Universal Resource Identifier */ + char *method, /* O - Method [32] (http, https, etc.) */ + char *username, /* O - Username [1024] */ + char *host, /* O - Hostname [1024] */ + int *port, /* O - Port number to use */ + char *resource) /* O - Resource/filename [1024] */ +{ + httpSeparate2(uri, method, 32, username, HTTP_MAX_URI, host, HTTP_MAX_URI, + port, resource, HTTP_MAX_URI); +} + + +/* + * 'httpSeparate2()' - Separate a Universal Resource Identifier into its + * components. + */ + +void +httpSeparate2(const char *uri, /* I - Universal Resource Identifier */ + char *method, /* O - Method (http, https, etc.) */ + int methodlen, /* I - Size of method buffer */ + char *username, /* O - Username */ + int usernamelen, /* I - Size of username buffer */ + char *host, /* O - Hostname */ + int hostlen, /* I - Size of hostname buffer */ + int *port, /* O - Port number to use */ + char *resource, /* O - Resource/filename */ + int resourcelen) /* I - Size of resource buffer */ +{ + char *ptr; /* Pointer into string... */ + const char *atsign, /* @ sign */ + *slash; /* Separator */ + + + /* + * Range check input... + */ + + if (uri == NULL || method == NULL || username == NULL || host == NULL || + port == NULL || resource == NULL) + return; + + /* + * Grab the method portion of the URI... + */ + + if (strncmp(uri, "//", 2) == 0) + { + /* + * Workaround for HP IPP client bug... + */ + + strlcpy(method, "ipp", methodlen); + } + else + { + /* + * Standard URI with method... + */ + + uri = http_copy_decode(host, uri, hostlen, ":"); + + if (*uri == ':') + uri ++; + + /* + * If the method contains a period or slash, then it's probably + * hostname/filename... + */ + + if (strchr(host, '.') != NULL || strchr(host, '/') != NULL || *uri == '\0') + { + if ((ptr = strchr(host, '/')) != NULL) + { + strlcpy(resource, ptr, resourcelen); + *ptr = '\0'; + } + else + resource[0] = '\0'; + + if (isdigit(*uri & 255)) + { + /* + * OK, we have "hostname:port[/resource]"... + */ + + *port = strtol(uri, (char **)&uri, 10); + + if (*uri == '/') + strlcpy(resource, uri, resourcelen); + } + else + *port = 631; + + strlcpy(method, "http", methodlen); + username[0] = '\0'; + return; + } + else + strlcpy(method, host, methodlen); + } + + /* + * If the method starts with less than 2 slashes then it is a local resource... + */ + + if (strncmp(uri, "//", 2) != 0) + { + strlcpy(resource, uri, resourcelen); + + username[0] = '\0'; + host[0] = '\0'; + *port = 0; + return; + } + + /* + * Grab the username, if any... + */ + + uri += 2; + + if ((slash = strchr(uri, '/')) == NULL) + slash = uri + strlen(uri); + + if ((atsign = strchr(uri, '@')) != NULL && atsign < slash) + { + /* + * Got a username:password combo... + */ + + uri = http_copy_decode(username, uri, usernamelen, "@") + 1; + } + else + username[0] = '\0'; + + /* + * Grab the hostname... + */ + + uri = http_copy_decode(host, uri, hostlen, ":/"); + + if (*uri != ':') + { + if (strcasecmp(method, "http") == 0) + *port = 80; + else if (strcasecmp(method, "https") == 0) + *port = 443; + else if (strcasecmp(method, "ipp") == 0) + *port = 631; + else if (strcasecmp(method, "lpd") == 0) + *port = 515; + else if (strcasecmp(method, "socket") == 0) /* Not registered yet... */ + *port = 9100; + else + *port = 0; + } + else + { + /* + * Parse port number... + */ + + *port = strtol(uri + 1, (char **)&uri, 10); + } + + if (*uri == '\0') + { + /* + * Hostname but no port or path... + */ + + resource[0] = '/'; + resource[1] = '\0'; + return; + } + + /* + * The remaining portion is the resource string... + */ + + http_copy_decode(resource, uri, resourcelen, ""); +} + + +/* + * 'httpStatus()' - Return a short string describing a HTTP status code. + */ + +const char * /* O - String or NULL */ +httpStatus(http_status_t status) /* I - HTTP status code */ +{ + switch (status) + { + case HTTP_CONTINUE : + return ("Continue"); + case HTTP_SWITCHING_PROTOCOLS : + return ("Switching Protocols"); + case HTTP_OK : + return ("OK"); + case HTTP_CREATED : + return ("Created"); + case HTTP_ACCEPTED : + return ("Accepted"); + case HTTP_NO_CONTENT : + return ("No Content"); + case HTTP_NOT_MODIFIED : + return ("Not Modified"); + case HTTP_BAD_REQUEST : + return ("Bad Request"); + case HTTP_UNAUTHORIZED : + return ("Unauthorized"); + case HTTP_FORBIDDEN : + return ("Forbidden"); + case HTTP_NOT_FOUND : + return ("Not Found"); + case HTTP_REQUEST_TOO_LARGE : + return ("Request Entity Too Large"); + case HTTP_URI_TOO_LONG : + return ("URI Too Long"); + case HTTP_UPGRADE_REQUIRED : + return ("Upgrade Required"); + case HTTP_NOT_IMPLEMENTED : + return ("Not Implemented"); + case HTTP_NOT_SUPPORTED : + return ("Not Supported"); + default : + return ("Unknown"); + } +} + + +#ifndef HAVE_HSTRERROR +/* + * 'cups_hstrerror()' - hstrerror() emulation function for Solaris and others... + */ + +const char * /* O - Error string */ +cups_hstrerror(int error) /* I - Error number */ +{ + static const char * const errors[] = /* Error strings */ + { + "OK", + "Host not found.", + "Try again.", + "Unrecoverable lookup error.", + "No data associated with name." + }; + + + if (error < 0 || error > 4) + return ("Unknown hostname lookup error."); + else + return (errors[error]); +} +#endif /* !HAVE_HSTRERROR */ + + +/* + * 'http_copy_decode()' - Copy and decode a URI. + */ + +static const char * /* O - New source pointer */ +http_copy_decode(char *dst, /* O - Destination buffer */ + const char *src, /* I - Source pointer */ + int dstsize, /* I - Destination size */ + const char *term) /* I - Terminating characters */ +{ + char *ptr, /* Pointer into buffer */ + *end; /* End of buffer */ + int quoted; /* Quoted character */ + + + /* + * Copy the src to the destination until we hit a terminating character + * or the end of the string. + */ + + for (ptr = dst, end = dst + dstsize - 1; *src && !strchr(term, *src); src ++) + if (ptr < end) + { + if (*src == '%' && isxdigit(src[1] & 255) && isxdigit(src[2] & 255)) + { + /* + * Grab a hex-encoded character... + */ + + src ++; + if (isalpha(*src)) + quoted = (tolower(*src) - 'a' + 10) << 4; + else + quoted = (*src - '0') << 4; + + src ++; + if (isalpha(*src)) + quoted |= tolower(*src) - 'a' + 10; + else + quoted |= *src - '0'; + + *ptr++ = quoted; + } + else + *ptr++ = *src; + } + + *ptr = '\0'; + + return (src); +} + + +/* + * End of "$Id: http-support.c 148 2006-04-25 16:54:17Z njacobs $" + */ diff --git a/usr/src/lib/print/libhttp-core/common/http.c b/usr/src/lib/print/libhttp-core/common/http.c new file mode 100644 index 0000000000..83a0790022 --- /dev/null +++ b/usr/src/lib/print/libhttp-core/common/http.c @@ -0,0 +1,2569 @@ +/* + * "$Id: http.c 148 2006-04-25 16:54:17Z njacobs $" + * + * HTTP routines for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2005 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636 USA + * + * Voice: (301) 373-9600 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * httpInitialize() - Initialize the HTTP interface library and set the + * default HTTP proxy (if any). + * httpCheck() - Check to see if there is a pending response from + * the server. + * httpClearCookie() - Clear the cookie value(s). + * httpClose() - Close an HTTP connection... + * httpConnect() - Connect to a HTTP server. + * httpConnectEncrypt() - Connect to a HTTP server using encryption. + * httpEncryption() - Set the required encryption on the link. + * httpReconnect() - Reconnect to a HTTP server... + * httpGetSubField() - Get a sub-field value. + * httpSetField() - Set the value of an HTTP header. + * httpDelete() - Send a DELETE request to the server. + * httpGet() - Send a GET request to the server. + * httpHead() - Send a HEAD request to the server. + * httpOptions() - Send an OPTIONS request to the server. + * httpPost() - Send a POST request to the server. + * httpPut() - Send a PUT request to the server. + * httpTrace() - Send an TRACE request to the server. + * httpFlush() - Flush data from a HTTP connection. + * httpRead() - Read data from a HTTP connection. + * httpSetCookie() - Set the cookie value(s)... + * httpWait() - Wait for data available on a connection. + * httpWrite() - Write data to a HTTP connection. + * httpGets() - Get a line of text from a HTTP connection. + * httpPrintf() - Print a formatted string to a HTTP connection. + * httpGetDateString() - Get a formatted date/time string from a time value. + * httpGetDateTime() - Get a time value from a formatted date/time string. + * httpUpdate() - Update the current HTTP state for incoming data. + * httpDecode64() - Base64-decode a string. + * httpDecode64_2() - Base64-decode a string. + * httpEncode64() - Base64-encode a string. + * httpEncode64_2() - Base64-encode a string. + * httpGetLength() - Get the amount of data remaining from the + * content-length or transfer-encoding fields. + * http_field() - Return the field index for a field name. + * http_send() - Send a request with all fields and the trailing + * blank line. + * http_wait() - Wait for data available on a connection. + * http_upgrade() - Force upgrade to TLS encryption. + * http_setup_ssl() - Set up SSL/TLS on a connection. + * http_shutdown_ssl() - Shut down SSL/TLS on a connection. + * http_read_ssl() - Read from a SSL/TLS connection. + * http_write_ssl() - Write to a SSL/TLS connection. + * CDSAReadFunc() - Read function for CDSA decryption code. + * CDSAWriteFunc() - Write function for CDSA encryption code. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Include necessary headers... + */ + +#include "http-private.h" + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <ctype.h> +#include "string.h" +#include <fcntl.h> +#include <errno.h> + +#include "http.h" +#include "debug.h" + +#ifndef WIN32 +# include <signal.h> +# include <sys/time.h> +# include <sys/resource.h> +#endif /* !WIN32 */ + + +/* + * Some operating systems have done away with the Fxxxx constants for + * the fcntl() call; this works around that "feature"... + */ + +#ifndef FNONBLK +# define FNONBLK O_NONBLOCK +#endif /* !FNONBLK */ + + +/* + * Local functions... + */ + +static http_field_t http_field(const char *name); +static int http_send(http_t *http, http_state_t request, + const char *uri); +static int http_wait(http_t *http, int msec); +#ifdef HAVE_SSL +static int http_upgrade(http_t *http); +static int http_setup_ssl(http_t *http); +static void http_shutdown_ssl(http_t *http); +static int http_read_ssl(http_t *http, char *buf, int len); +static int http_write_ssl(http_t *http, const char *buf, int len); +# ifdef HAVE_CDSASSL +static OSStatus CDSAReadFunc(SSLConnectionRef connection, void *data, size_t *dataLength); +static OSStatus CDSAWriteFunc(SSLConnectionRef connection, const void *data, size_t *dataLength); +# endif /* HAVE_CDSASSL */ +#endif /* HAVE_SSL */ + + +/* + * Local globals... + */ + +static const char * const http_fields[] = + { + "Accept-Language", + "Accept-Ranges", + "Authorization", + "Connection", + "Content-Encoding", + "Content-Language", + "Content-Length", + "Content-Location", + "Content-MD5", + "Content-Range", + "Content-Type", + "Content-Version", + "Date", + "Host", + "If-Modified-Since", + "If-Unmodified-since", + "Keep-Alive", + "Last-Modified", + "Link", + "Location", + "Range", + "Referer", + "Retry-After", + "Transfer-Encoding", + "Upgrade", + "User-Agent", + "WWW-Authenticate" + }; +static const char * const days[7] = + { + "Sun", + "Mon", + "Tue", + "Wed", + "Thu", + "Fri", + "Sat" + }; +static const char * const months[12] = + { + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec" + }; + +void +httpDumpData(FILE *fp, char *tag, char *buffer, int bytes) +{ + int i, j, ch; + + fprintf(fp, "%s %d(0x%x) bytes...\n", tag, bytes, bytes); + for (i = 0; i < bytes; i += 16) { + fprintf(fp, "%s ", (tag ? tag : "")); + + for (j = 0; j < 16 && (i + j) < bytes; j ++) + fprintf(fp, " %02X", buffer[i + j] & 255); + + while (j < 16) { + fprintf(fp, " "); + j++; + } + + fprintf(fp, " "); + for (j = 0; j < 16 && (i + j) < bytes; j ++) { + ch = buffer[i + j] & 255; + if (ch < ' ' || ch == 127) + ch = '.'; + putc(ch, fp); + } + putc('\n', fp); + } +} + + +/* + * 'httpInitialize()' - Initialize the HTTP interface library and set the + * default HTTP proxy (if any). + */ + +void +httpInitialize(void) +{ +#ifdef HAVE_LIBSSL +# ifndef WIN32 + struct timeval curtime; /* Current time in microseconds */ +# endif /* !WIN32 */ + int i; /* Looping var */ + unsigned char data[1024]; /* Seed data */ +#endif /* HAVE_LIBSSL */ + +#ifdef WIN32 + WSADATA winsockdata; /* WinSock data */ + static int initialized = 0; /* Has WinSock been initialized? */ + + + if (!initialized) + WSAStartup(MAKEWORD(1,1), &winsockdata); +#elif defined(HAVE_SIGSET) + sigset(SIGPIPE, SIG_IGN); +#elif defined(HAVE_SIGACTION) + struct sigaction action; /* POSIX sigaction data */ + + + /* + * Ignore SIGPIPE signals... + */ + + memset(&action, 0, sizeof(action)); + action.sa_handler = SIG_IGN; + sigaction(SIGPIPE, &action, NULL); +#else + signal(SIGPIPE, SIG_IGN); +#endif /* WIN32 */ + +#ifdef HAVE_GNUTLS + gnutls_global_init(); +#endif /* HAVE_GNUTLS */ + +#ifdef HAVE_LIBSSL + SSL_load_error_strings(); + SSL_library_init(); + + /* + * Using the current time is a dubious random seed, but on some systems + * it is the best we can do (on others, this seed isn't even used...) + */ + +#ifdef WIN32 +#else + gettimeofday(&curtime, NULL); + srand(curtime.tv_sec + curtime.tv_usec); +#endif /* WIN32 */ + + for (i = 0; i < sizeof(data); i ++) + data[i] = rand(); /* Yes, this is a poor source of random data... */ + + RAND_seed(&data, sizeof(data)); +#endif /* HAVE_LIBSSL */ +} + + +/* + * 'httpCheck()' - Check to see if there is a pending response from the server. + */ + +int /* O - 0 = no data, 1 = data available */ +httpCheck(http_t *http) /* I - HTTP connection */ +{ + return (httpWait(http, 0)); +} + + +/* + * 'httpClearCookie()' - Clear the cookie value(s). + */ + +void +httpClearCookie(http_t *http) /* I - Connection */ +{ + if (!http) + return; + + if (http->cookie) + { + free(http->cookie); + http->cookie = NULL; + } +} + + +/* + * 'httpClose()' - Close an HTTP connection... + */ + +void +httpClose(http_t *http) /* I - Connection to close */ +{ + DEBUG_printf(("httpClose(http=%p)\n", http)); + + if (!http) + return; + + if (http->input_set) + free(http->input_set); + + if (http->cookie) + free(http->cookie); + +#ifdef HAVE_SSL + if (http->tls) + http_shutdown_ssl(http); +#endif /* HAVE_SSL */ + +#ifdef WIN32 + closesocket(http->fd); +#else + close(http->fd); +#endif /* WIN32 */ + + free(http); +} + + +/* + * 'httpConnect()' - Connect to a HTTP server. + */ + +http_t * /* O - New HTTP connection */ +httpConnect(const char *host, /* I - Host to connect to */ + int port) /* I - Port number */ +{ + http_encryption_t encrypt; /* Type of encryption to use */ + + + /* + * Set the default encryption status... + */ + + if (port == 443) + encrypt = HTTP_ENCRYPT_ALWAYS; + else + encrypt = HTTP_ENCRYPT_IF_REQUESTED; + + return (httpConnectEncrypt(host, port, encrypt)); +} + + +/* + * 'httpConnectEncrypt()' - Connect to a HTTP server using encryption. + */ + +http_t * /* O - New HTTP connection */ +httpConnectEncrypt(const char *host, /* I - Host to connect to */ + int port, /* I - Port number */ + http_encryption_t encrypt) + /* I - Type of encryption to use */ +{ + int i; /* Looping var */ + http_t *http; /* New HTTP connection */ + struct hostent *hostaddr; /* Host address data */ + + + DEBUG_printf(("httpConnectEncrypt(host=\"%s\", port=%d, encrypt=%d)\n", + host ? host : "(null)", port, encrypt)); + + if (!host) + return (NULL); + + httpInitialize(); + + /* + * Lookup the host... + */ + + if ((hostaddr = httpGetHostByName(host)) == NULL) + { + /* + * This hack to make users that don't have a localhost entry in + * their hosts file or DNS happy... + */ + + if (strcasecmp(host, "localhost") != 0) + return (NULL); + else if ((hostaddr = httpGetHostByName("127.0.0.1")) == NULL) + return (NULL); + } + + /* + * Verify that it is an IPv4, IPv6, or domain address... + */ + + if ((hostaddr->h_addrtype != AF_INET || hostaddr->h_length != 4) +#ifdef AF_INET6 + && (hostaddr->h_addrtype != AF_INET6 || hostaddr->h_length != 16) +#endif /* AF_INET6 */ +#ifdef AF_LOCAL + && (hostaddr->h_addrtype != AF_LOCAL) +#endif /* AF_LOCAL */ + ) + return (NULL); + + /* + * Allocate memory for the structure... + */ + + http = calloc(sizeof(http_t), 1); + if (http == NULL) + return (NULL); + + http->version = HTTP_1_1; + http->blocking = 1; + http->activity = time(NULL); + http->fd = -1; + + /* + * Set the encryption status... + */ + + if (port == 443) /* Always use encryption for https */ + http->encryption = HTTP_ENCRYPT_ALWAYS; + else + http->encryption = encrypt; + + /* + * Loop through the addresses we have until one of them connects... + */ + + strlcpy(http->hostname, host, sizeof(http->hostname)); + + for (i = 0; hostaddr->h_addr_list[i]; i ++) + { + /* + * Load the address... + */ + + httpAddrLoad(hostaddr, port, i, &(http->hostaddr)); + + /* + * Connect to the remote system... + */ + + if (!httpReconnect(http)) + return (http); + } + + /* + * Could not connect to any known address - bail out! + */ + + free(http); + return (NULL); +} + + +/* + * 'httpEncryption()' - Set the required encryption on the link. + */ + +int /* O - -1 on error, 0 on success */ +httpEncryption(http_t *http, /* I - HTTP data */ + http_encryption_t e) /* I - New encryption preference */ +{ + DEBUG_printf(("httpEncryption(http=%p, e=%d)\n", http, e)); + +#ifdef HAVE_SSL + if (!http) + return (0); + + http->encryption = e; + + if ((http->encryption == HTTP_ENCRYPT_ALWAYS && !http->tls) || + (http->encryption == HTTP_ENCRYPT_NEVER && http->tls)) + return (httpReconnect(http)); + else if (http->encryption == HTTP_ENCRYPT_REQUIRED && !http->tls) + return (http_upgrade(http)); + else + return (0); +#else + if (e == HTTP_ENCRYPT_ALWAYS || e == HTTP_ENCRYPT_REQUIRED) + return (-1); + else + return (0); +#endif /* HAVE_SSL */ +} + + +/* + * 'httpReconnect()' - Reconnect to a HTTP server... + */ + +int /* O - 0 on success, non-zero on failure */ +httpReconnect(http_t *http) /* I - HTTP data */ +{ + int val; /* Socket option value */ + int status; /* Connect status */ + + + DEBUG_printf(("httpReconnect(http=%p)\n", http)); + + if (!http) + return (-1); + +#ifdef HAVE_SSL + if (http->tls) + http_shutdown_ssl(http); +#endif /* HAVE_SSL */ + + /* + * Close any previously open socket... + */ + + if (http->fd >= 0) +#ifdef WIN32 + closesocket(http->fd); +#else + close(http->fd); +#endif /* WIN32 */ + + /* + * Create the socket and set options to allow reuse. + */ + + if ((http->fd = socket(http->hostaddr.addr.sa_family, SOCK_STREAM, 0)) < 0) + { +#ifdef WIN32 + http->error = WSAGetLastError(); +#else + http->error = errno; +#endif /* WIN32 */ + http->status = HTTP_ERROR; + return (-1); + } + +#ifdef FD_CLOEXEC + fcntl(http->fd, F_SETFD, FD_CLOEXEC); /* Close this socket when starting * + * other processes... */ +#endif /* FD_CLOEXEC */ + + val = 1; + setsockopt(http->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val)); + +#ifdef SO_REUSEPORT + val = 1; + setsockopt(http->fd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val)); +#endif /* SO_REUSEPORT */ + + /* + * Using TCP_NODELAY improves responsiveness, especially on systems + * with a slow loopback interface... Since we write large buffers + * when sending print files and requests, there shouldn't be any + * performance penalty for this... + */ + + val = 1; +#ifdef WIN32 + setsockopt(http->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val)); +#else + setsockopt(http->fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)); +#endif /* WIN32 */ + + /* + * Connect to the server... + */ + +#ifdef AF_INET6 + if (http->hostaddr.addr.sa_family == AF_INET6) + status = connect(http->fd, (struct sockaddr *)&(http->hostaddr), + sizeof(http->hostaddr.ipv6)); + else +#endif /* AF_INET6 */ +#ifdef AF_LOCAL + if (http->hostaddr.addr.sa_family == AF_LOCAL) + status = connect(http->fd, (struct sockaddr *)&(http->hostaddr), + SUN_LEN(&(http->hostaddr.un))); + else +#endif /* AF_LOCAL */ + status = connect(http->fd, (struct sockaddr *)&(http->hostaddr), + sizeof(http->hostaddr.ipv4)); + + if (status < 0) + { +#ifdef WIN32 + http->error = WSAGetLastError(); +#else + http->error = errno; +#endif /* WIN32 */ + http->status = HTTP_ERROR; + +#ifdef WIN32 + closesocket(http->fd); +#else + close(http->fd); +#endif + + http->fd = -1; + + return (-1); + } + + http->error = 0; + http->status = HTTP_CONTINUE; + +#ifdef HAVE_SSL + if (http->encryption == HTTP_ENCRYPT_ALWAYS) + { + /* + * Always do encryption via SSL. + */ + + if (http_setup_ssl(http) != 0) + { +#ifdef WIN32 + closesocket(http->fd); +#else + close(http->fd); +#endif /* WIN32 */ + + return (-1); + } + } + else if (http->encryption == HTTP_ENCRYPT_REQUIRED) + return (http_upgrade(http)); +#endif /* HAVE_SSL */ + + return (0); +} + + +/* + * 'httpGetSubField()' - Get a sub-field value. + */ + +char * /* O - Value or NULL */ +httpGetSubField(http_t *http, /* I - HTTP data */ + http_field_t field, /* I - Field index */ + const char *name, /* I - Name of sub-field */ + char *value) /* O - Value string */ +{ + const char *fptr; /* Pointer into field */ + char temp[HTTP_MAX_VALUE], /* Temporary buffer for name */ + *ptr; /* Pointer into string buffer */ + + + DEBUG_printf(("httpGetSubField(http=%p, field=%d, name=\"%s\", value=%p)\n", + http, field, name, value)); + + if (http == NULL || + field < HTTP_FIELD_ACCEPT_LANGUAGE || + field > HTTP_FIELD_WWW_AUTHENTICATE || + name == NULL || value == NULL) + return (NULL); + + for (fptr = http->fields[field]; *fptr;) + { + /* + * Skip leading whitespace... + */ + + while (isspace(*fptr & 255)) + fptr ++; + + if (*fptr == ',') + { + fptr ++; + continue; + } + + /* + * Get the sub-field name... + */ + + for (ptr = temp; + *fptr && *fptr != '=' && !isspace(*fptr & 255) && ptr < (temp + sizeof(temp) - 1); + *ptr++ = *fptr++); + + *ptr = '\0'; + + DEBUG_printf(("httpGetSubField: name=\"%s\"\n", temp)); + + /* + * Skip trailing chars up to the '='... + */ + + while (isspace(*fptr & 255)) + fptr ++; + + if (!*fptr) + break; + + if (*fptr != '=') + continue; + + /* + * Skip = and leading whitespace... + */ + + fptr ++; + + while (isspace(*fptr & 255)) + fptr ++; + + if (*fptr == '\"') + { + /* + * Read quoted string... + */ + + for (ptr = value, fptr ++; + *fptr && *fptr != '\"' && ptr < (value + HTTP_MAX_VALUE - 1); + *ptr++ = *fptr++); + + *ptr = '\0'; + + while (*fptr && *fptr != '\"') + fptr ++; + + if (*fptr) + fptr ++; + } + else + { + /* + * Read unquoted string... + */ + + for (ptr = value; + *fptr && !isspace(*fptr & 255) && *fptr != ',' && ptr < (value + HTTP_MAX_VALUE - 1); + *ptr++ = *fptr++); + + *ptr = '\0'; + + while (*fptr && !isspace(*fptr & 255) && *fptr != ',') + fptr ++; + } + + DEBUG_printf(("httpGetSubField: value=\"%s\"\n", value)); + + /* + * See if this is the one... + */ + + if (strcmp(name, temp) == 0) + return (value); + } + + value[0] = '\0'; + + return (NULL); +} + + +/* + * 'httpSetField()' - Set the value of an HTTP header. + */ + +void +httpSetField(http_t *http, /* I - HTTP data */ + http_field_t field, /* I - Field index */ + const char *value) /* I - Value */ +{ + if (http == NULL || + field < HTTP_FIELD_ACCEPT_LANGUAGE || + field > HTTP_FIELD_WWW_AUTHENTICATE || + value == NULL) + return; + + strlcpy(http->fields[field], value, HTTP_MAX_VALUE); +} + + +/* + * 'httpDelete()' - Send a DELETE request to the server. + */ + +int /* O - Status of call (0 = success) */ +httpDelete(http_t *http, /* I - HTTP data */ + const char *uri) /* I - URI to delete */ +{ + return (http_send(http, HTTP_DELETE, uri)); +} + + +/* + * 'httpGet()' - Send a GET request to the server. + */ + +int /* O - Status of call (0 = success) */ +httpGet(http_t *http, /* I - HTTP data */ + const char *uri) /* I - URI to get */ +{ + return (http_send(http, HTTP_GET, uri)); +} + + +/* + * 'httpHead()' - Send a HEAD request to the server. + */ + +int /* O - Status of call (0 = success) */ +httpHead(http_t *http, /* I - HTTP data */ + const char *uri) /* I - URI for head */ +{ + return (http_send(http, HTTP_HEAD, uri)); +} + + +/* + * 'httpOptions()' - Send an OPTIONS request to the server. + */ + +int /* O - Status of call (0 = success) */ +httpOptions(http_t *http, /* I - HTTP data */ + const char *uri) /* I - URI for options */ +{ + return (http_send(http, HTTP_OPTIONS, uri)); +} + + +/* + * 'httpPost()' - Send a POST request to the server. + */ + +int /* O - Status of call (0 = success) */ +httpPost(http_t *http, /* I - HTTP data */ + const char *uri) /* I - URI for post */ +{ + httpGetLength(http); + + return (http_send(http, HTTP_POST, uri)); +} + + +/* + * 'httpPut()' - Send a PUT request to the server. + */ + +int /* O - Status of call (0 = success) */ +httpPut(http_t *http, /* I - HTTP data */ + const char *uri) /* I - URI to put */ +{ + httpGetLength(http); + + return (http_send(http, HTTP_PUT, uri)); +} + + +/* + * 'httpTrace()' - Send an TRACE request to the server. + */ + +int /* O - Status of call (0 = success) */ +httpTrace(http_t *http, /* I - HTTP data */ + const char *uri) /* I - URI for trace */ +{ + return (http_send(http, HTTP_TRACE, uri)); +} + + +/* + * 'httpFlush()' - Flush data from a HTTP connection. + */ + +void +httpFlush(http_t *http) /* I - HTTP data */ +{ + char buffer[8192]; /* Junk buffer */ + + + DEBUG_printf(("httpFlush(http=%p), state=%d\n", http, http->state)); + + while (httpRead(http, buffer, sizeof(buffer)) > 0); +} + + +/* + * 'httpRead()' - Read data from a HTTP connection. + */ + +int /* O - Number of bytes read */ +httpRead(http_t *http, /* I - HTTP data */ + char *buffer, /* I - Buffer for data */ + int length) /* I - Maximum number of bytes */ +{ + int bytes; /* Bytes read */ + char len[32]; /* Length string */ + + + DEBUG_printf(("httpRead(http=%p, buffer=%p, length=%d)\n", + http, buffer, length)); + + if (http == NULL || buffer == NULL) + return (-1); + + http->activity = time(NULL); + + if (length <= 0) + return (0); + + if (http->data_encoding == HTTP_ENCODE_CHUNKED && + http->data_remaining <= 0) + { + DEBUG_puts("httpRead: Getting chunk length..."); + + if (httpGets(len, sizeof(len), http) == NULL) + { + DEBUG_puts("httpRead: Could not get length!"); + return (0); + } + + http->data_remaining = strtol(len, NULL, 16); + if (http->data_remaining < 0) + { + DEBUG_puts("httpRead: Negative chunk length!"); + return (0); + } + } + + DEBUG_printf(("httpRead: data_remaining=%d\n", http->data_remaining)); + + if (http->data_remaining <= 0) + { + /* + * A zero-length chunk ends a transfer; unless we are reading POST + * data, go idle... + */ + + if (http->data_encoding == HTTP_ENCODE_CHUNKED) + httpGets(len, sizeof(len), http); + + if (http->state == HTTP_POST_RECV) + http->state ++; + else + http->state = HTTP_WAITING; + + /* + * Prevent future reads for this request... + */ + + http->data_encoding = HTTP_ENCODE_LENGTH; + + return (0); + } + else if (length > http->data_remaining) + length = http->data_remaining; + + if (http->used == 0 && length <= 256) + { + /* + * Buffer small reads for better performance... + */ + + if (!http->blocking && !httpWait(http, 1000)) + return (0); + + if (http->data_remaining > sizeof(http->buffer)) + bytes = sizeof(http->buffer); + else + bytes = http->data_remaining; + +#ifdef HAVE_SSL + if (http->tls) + bytes = http_read_ssl(http, http->buffer, bytes); + else +#endif /* HAVE_SSL */ + { + DEBUG_printf(("httpRead: reading %d bytes from socket into buffer...\n", + bytes)); + + bytes = recv(http->fd, http->buffer, bytes, 0); + + DEBUG_printf(("httpRead: read %d bytes from socket into buffer...\n", + bytes)); +#ifdef DEBUG_HTTP + httpDumpData(stdout, "httpRead:", http->buffer, bytes); +#endif + } + + if (bytes > 0) + http->used = bytes; + else if (bytes < 0) + { +#ifdef WIN32 + http->error = WSAGetLastError(); + return (-1); +#else + if (errno != EINTR) + { + http->error = errno; + return (-1); + } +#endif /* WIN32 */ + } + else + { + http->error = EPIPE; + return (0); + } + } + + if (http->used > 0) + { + if (length > http->used) + length = http->used; + + bytes = length; + + DEBUG_printf(("httpRead: grabbing %d bytes from input buffer...\n", bytes)); + + memcpy(buffer, http->buffer, length); + http->used -= length; + + if (http->used > 0) + memmove(http->buffer, http->buffer + length, http->used); + } +#ifdef HAVE_SSL + else if (http->tls) + { + if (!http->blocking && !httpWait(http, 1000)) + return (0); + + bytes = http_read_ssl(http, buffer, length); + } +#endif /* HAVE_SSL */ + else + { + if (!http->blocking && !httpWait(http, 1000)) + return (0); + + DEBUG_printf(("httpRead: reading %d bytes from socket...\n", length)); + + while ((bytes = recv(http->fd, buffer, length, 0)) < 0) + if (errno != EINTR) + break; + DEBUG_printf(("httpRead: read %d bytes from socket...\n", bytes)); + } +#ifdef DEBUG_HTTP + httpDumpData(stdout, "httpRead:", buffer, bytes); +#endif + + if (bytes > 0) + http->data_remaining -= bytes; + else if (bytes < 0) + { +#ifdef WIN32 + http->error = WSAGetLastError(); +#else + if (errno == EINTR) + bytes = 0; + else + http->error = errno; +#endif /* WIN32 */ + } + else + { + http->error = EPIPE; + return (0); + } + + if (http->data_remaining == 0) + { + if (http->data_encoding == HTTP_ENCODE_CHUNKED) + httpGets(len, sizeof(len), http); + + if (http->data_encoding != HTTP_ENCODE_CHUNKED) + { + if (http->state == HTTP_POST_RECV) + http->state ++; + else + http->state = HTTP_WAITING; + } + } + + return (bytes); +} + + +/* + * 'httpSetCookie()' - Set the cookie value(s)... + */ + +void +httpSetCookie(http_t *http, /* I - Connection */ + const char *cookie) /* I - Cookie string */ +{ + if (!http) + return; + + if (http->cookie) + free(http->cookie); + + if (cookie) + http->cookie = strdup(cookie); + else + http->cookie = NULL; +} + + +/* + * 'httpWait()' - Wait for data available on a connection. + */ + +int /* O - 1 if data is available, 0 otherwise */ +httpWait(http_t *http, /* I - HTTP data */ + int msec) /* I - Milliseconds to wait */ +{ + /* + * First see if there is data in the buffer... + */ + + if (http == NULL) + return (0); + + if (http->used) + return (1); + + /* + * If not, check the SSL/TLS buffers and do a select() on the connection... + */ + + return (http_wait(http, msec)); +} + + +/* + * 'httpWrite()' - Write data to a HTTP connection. + */ + +int /* O - Number of bytes written */ +httpWrite(http_t *http, /* I - HTTP data */ + const char *buffer, /* I - Buffer for data */ + int length) /* I - Number of bytes to write */ +{ + int tbytes, /* Total bytes sent */ + bytes; /* Bytes sent */ + + + if (http == NULL || buffer == NULL) + return (-1); + + http->activity = time(NULL); + + if (http->data_encoding == HTTP_ENCODE_CHUNKED) + { + if (httpPrintf(http, "%x\r\n", length) < 0) + return (-1); + + if (length == 0) + { + /* + * A zero-length chunk ends a transfer; unless we are sending POST + * or PUT data, go idle... + */ + + DEBUG_printf(("httpWrite: changing states from %d", http->state)); + + if (http->state == HTTP_POST_RECV) + http->state ++; + else if (http->state == HTTP_PUT_RECV) + http->state = HTTP_STATUS; + else + http->state = HTTP_WAITING; + DEBUG_printf((" to %d\n", http->state)); + + if (httpPrintf(http, "\r\n") < 0) + return (-1); + + return (0); + } + } + + tbytes = 0; + + while (length > 0) + { +#ifdef HAVE_SSL + if (http->tls) + bytes = http_write_ssl(http, buffer, length); + else +#endif /* HAVE_SSL */ + bytes = send(http->fd, buffer, length, 0); + +#ifdef DEBUG_HTTP + if (bytes >= 0) + httpDumpData(stdout, "httpWrite:", buffer, bytes); +#endif /* DEBUG */ + + + if (bytes < 0) + { +#ifdef WIN32 + if (WSAGetLastError() != http->error) + { + http->error = WSAGetLastError(); + continue; + } +#else + if (errno == EINTR) + continue; + else if (errno != http->error && errno != ECONNRESET) + { + http->error = errno; + continue; + } +#endif /* WIN32 */ + + DEBUG_puts("httpWrite: error writing data...\n"); + + return (-1); + } + + buffer += bytes; + tbytes += bytes; + length -= bytes; + if (http->data_encoding == HTTP_ENCODE_LENGTH) + http->data_remaining -= bytes; + } + + if (http->data_encoding == HTTP_ENCODE_CHUNKED) + if (httpPrintf(http, "\r\n") < 0) + return (-1); + + if (http->data_remaining == 0 && http->data_encoding == HTTP_ENCODE_LENGTH) + { + /* + * Finished with the transfer; unless we are sending POST or PUT + * data, go idle... + */ + + DEBUG_printf(("httpWrite: changing states from %d", http->state)); + + if (http->state == HTTP_POST_RECV) + http->state ++; + else if (http->state == HTTP_PUT_RECV) + http->state = HTTP_STATUS; + else + http->state = HTTP_WAITING; + + DEBUG_printf((" to %d\n", http->state)); + } + + return (tbytes); +} + + +/* + * 'httpGets()' - Get a line of text from a HTTP connection. + */ + +char * /* O - Line or NULL */ +httpGets(char *line, /* I - Line to read into */ + int length, /* I - Max length of buffer */ + http_t *http) /* I - HTTP data */ +{ + char *lineptr, /* Pointer into line */ + *bufptr, /* Pointer into input buffer */ + *bufend; /* Pointer to end of buffer */ + int bytes; /* Number of bytes read */ + + + DEBUG_printf(("httpGets(line=%p, length=%d, http=%p)\n", line, length, http)); + + if (http == NULL || line == NULL) + return (NULL); + + /* + * Pre-scan the buffer and see if there is a newline in there... + */ + +#ifdef WIN32 + WSASetLastError(0); +#else + errno = 0; +#endif /* WIN32 */ + + do + { + bufptr = http->buffer; + bufend = http->buffer + http->used; + + while (bufptr < bufend) + if (*bufptr == 0x0a) + break; + else + bufptr ++; + + if (bufptr >= bufend && http->used < HTTP_MAX_BUFFER) + { + /* + * No newline; see if there is more data to be read... + */ + + if (!http->blocking && !http_wait(http, 1000)) + return (NULL); + +#ifdef HAVE_SSL + if (http->tls) + bytes = http_read_ssl(http, bufend, HTTP_MAX_BUFFER - http->used); + else +#endif /* HAVE_SSL */ + bytes = recv(http->fd, bufend, HTTP_MAX_BUFFER - http->used, 0); + + DEBUG_printf(("httpGets: read %d bytes...\n", bytes)); +#ifdef DEBUG_HTTP + httpDumpData(stdout, "httpGets:", bufend, bytes); +#endif + + if (bytes < 0) + { + /* + * Nope, can't get a line this time... + */ + +#ifdef WIN32 + if (WSAGetLastError() != http->error) + { + http->error = WSAGetLastError(); + continue; + } + + DEBUG_printf(("httpGets: recv() error %d!\n", WSAGetLastError())); +#else + DEBUG_printf(("httpGets: recv() error %d!\n", errno)); + + if (errno == EINTR) + continue; + else if (errno != http->error) + { + http->error = errno; + continue; + } +#endif /* WIN32 */ + + return (NULL); + } + else if (bytes == 0) + { + http->error = EPIPE; + + return (NULL); + } + + /* + * Yup, update the amount used and the end pointer... + */ + + http->used += bytes; + bufend += bytes; + bufptr = bufend; + } + } + while (bufptr >= bufend && http->used < HTTP_MAX_BUFFER); + + http->activity = time(NULL); + + /* + * Read a line from the buffer... + */ + + lineptr = line; + bufptr = http->buffer; + bytes = 0; + length --; + + while (bufptr < bufend && bytes < length) + { + bytes ++; + + if (*bufptr == 0x0a) + { + bufptr ++; + break; + } + else if (*bufptr == 0x0d) + bufptr ++; + else + *lineptr++ = *bufptr++; + } + + if (bytes > 0) + { + *lineptr = '\0'; + + http->used -= bytes; + if (http->used > 0) + memmove(http->buffer, bufptr, http->used); + + DEBUG_printf(("httpGets: Returning \"%s\"\n", line)); + return (line); + } + + DEBUG_puts("httpGets: No new line available!"); + + return (NULL); +} + + +/* + * 'httpPrintf()' - Print a formatted string to a HTTP connection. + */ + +int /* O - Number of bytes written */ +httpPrintf(http_t *http, /* I - HTTP data */ + const char *format, /* I - printf-style format string */ + ...) /* I - Additional args as needed */ +{ + int bytes, /* Number of bytes to write */ + nbytes, /* Number of bytes written */ + tbytes; /* Number of bytes all together */ + char buf[HTTP_MAX_BUFFER], /* Buffer for formatted string */ + *bufptr; /* Pointer into buffer */ + va_list ap; /* Variable argument pointer */ + + + DEBUG_printf(("httpPrintf: httpPrintf(http=%p, format=\"%s\", ...)\n", http, format)); + + va_start(ap, format); + bytes = vsnprintf(buf, sizeof(buf), format, ap); + va_end(ap); + + DEBUG_printf(("httpPrintf: %s", buf)); + + for (tbytes = 0, bufptr = buf; tbytes < bytes; tbytes += nbytes, bufptr += nbytes) + { +#ifdef HAVE_SSL + if (http->tls) + nbytes = http_write_ssl(http, bufptr, bytes - tbytes); + else +#endif /* HAVE_SSL */ + nbytes = send(http->fd, bufptr, bytes - tbytes, 0); + +#ifdef DEBUG_HTTP + if (nbytes >= 0) + httpDumpData(stdout, "httpPrintf:", bufptr, nbytes); +#endif + + if (nbytes < 0) + { + nbytes = 0; + +#ifdef WIN32 + if (WSAGetLastError() != http->error) + { + http->error = WSAGetLastError(); + continue; + } +#else + if (errno == EINTR) + continue; + else if (errno != http->error) + { + http->error = errno; + continue; + } +#endif /* WIN32 */ + + return (-1); + } + } + + return (bytes); +} + + +/* + * 'httpGetDateString()' - Get a formatted date/time string from a time value. + */ + +const char * /* O - Date/time string */ +httpGetDateString(time_t t) /* I - UNIX time */ +{ + struct tm *tdate; + static char datetime[256]; + + + tdate = gmtime(&t); + snprintf(datetime, sizeof(datetime), "%s, %02d %s %d %02d:%02d:%02d GMT", + days[tdate->tm_wday], tdate->tm_mday, months[tdate->tm_mon], + tdate->tm_year + 1900, tdate->tm_hour, tdate->tm_min, tdate->tm_sec); + + return (datetime); +} + + +/* + * 'httpGetDateTime()' - Get a time value from a formatted date/time string. + */ + +time_t /* O - UNIX time */ +httpGetDateTime(const char *s) /* I - Date/time string */ +{ + int i; /* Looping var */ + struct tm tdate; /* Time/date structure */ + char mon[16]; /* Abbreviated month name */ + int day, year; /* Day of month and year */ + int hour, min, sec; /* Time */ + + + if (sscanf(s, "%*s%d%15s%d%d:%d:%d", &day, mon, &year, &hour, &min, &sec) < 6) + return (0); + + for (i = 0; i < 12; i ++) + if (strcasecmp(mon, months[i]) == 0) + break; + + if (i >= 12) + return (0); + + tdate.tm_mon = i; + tdate.tm_mday = day; + tdate.tm_year = year - 1900; + tdate.tm_hour = hour; + tdate.tm_min = min; + tdate.tm_sec = sec; + tdate.tm_isdst = 0; + + return (mktime(&tdate)); +} + + +/* + * 'httpUpdate()' - Update the current HTTP state for incoming data. + */ + +http_status_t /* O - HTTP status */ +httpUpdate(http_t *http) /* I - HTTP data */ +{ + char line[1024], /* Line from connection... */ + *value; /* Pointer to value on line */ + http_field_t field; /* Field index */ + int major, minor, /* HTTP version numbers */ + status; /* Request status */ + + + DEBUG_printf(("httpUpdate(http=%p), state=%d\n", http, http->state)); + + /* + * If we haven't issued any commands, then there is nothing to "update"... + */ + + if (http->state == HTTP_WAITING) + return (HTTP_CONTINUE); + + /* + * Grab all of the lines we can from the connection... + */ + + line[0] = '\0'; + while (httpGets(line, sizeof(line), http) != NULL) + { + DEBUG_printf(("httpUpdate: Got \"%s\"\n", line)); + + if (line[0] == '\0') + { + /* + * Blank line means the start of the data section (if any). Return + * the result code, too... + * + * If we get status 100 (HTTP_CONTINUE), then we *don't* change states. + * Instead, we just return HTTP_CONTINUE to the caller and keep on + * tryin'... + */ + + if (http->status == HTTP_CONTINUE) + return (http->status); + + if (http->status < HTTP_BAD_REQUEST) + http->digest_tries = 0; + +#ifdef HAVE_SSL + if (http->status == HTTP_SWITCHING_PROTOCOLS && !http->tls) + { + if (http_setup_ssl(http) != 0) + { +# ifdef WIN32 + closesocket(http->fd); +# else + close(http->fd); +# endif /* WIN32 */ + + return (HTTP_ERROR); + } + + return (HTTP_CONTINUE); + } +#endif /* HAVE_SSL */ + + httpGetLength(http); + + switch (http->state) + { + case HTTP_GET : + case HTTP_POST : + case HTTP_POST_RECV : + case HTTP_PUT : + http->state ++; + case HTTP_POST_SEND : + break; + + default : + http->state = HTTP_WAITING; + break; + } + + return (http->status); + } + else if (strncmp(line, "HTTP/", 5) == 0) + { + /* + * Got the beginning of a response... + */ + + if (sscanf(line, "HTTP/%d.%d%d", &major, &minor, &status) != 3) + return (HTTP_ERROR); + + http->version = (http_version_t)(major * 100 + minor); + http->status = (http_status_t)status; + } + else if ((value = strchr(line, ':')) != NULL) + { + /* + * Got a value... + */ + + *value++ = '\0'; + while (isspace(*value & 255)) + value ++; + + /* + * Be tolerants of servers that send unknown attribute fields... + */ + + if (!strcasecmp(line, "expect")) + { + /* + * "Expect: 100-continue" or similar... + */ + + http->expect = (http_status_t)atoi(value); + } + else if (!strcasecmp(line, "cookie")) + { + /* + * "Cookie: name=value[; name=value ...]" - replaces previous cookies... + */ + + httpSetCookie(http, value); + } + else if ((field = http_field(line)) == HTTP_FIELD_UNKNOWN) + { + DEBUG_printf(("httpUpdate: unknown field %s seen!\n", line)); + continue; + } + else + httpSetField(http, field, value); + } + else + { + http->status = HTTP_ERROR; + return (HTTP_ERROR); + } + } + + /* + * See if there was an error... + */ + + if (http->error == EPIPE && http->status > HTTP_CONTINUE) + return (http->status); + + if (http->error) + { + DEBUG_printf(("httpUpdate: socket error %d - %s\n", http->error, + strerror(http->error))); + http->status = HTTP_ERROR; + return (HTTP_ERROR); + } + + /* + * If we haven't already returned, then there is nothing new... + */ + + return (HTTP_CONTINUE); +} + + +/* + * 'httpDecode64()' - Base64-decode a string. + */ + +char * /* O - Decoded string */ +httpDecode64(char *out, /* I - String to write to */ + const char *in) /* I - String to read from */ +{ + int outlen; /* Output buffer length */ + + + /* + * Use the old maximum buffer size for binary compatibility... + */ + + outlen = 512; + + return (httpDecode64_2(out, &outlen, in)); +} + + +/* + * 'httpDecode64_2()' - Base64-decode a string. + */ + +char * /* O - Decoded string */ +httpDecode64_2(char *out, /* I - String to write to */ + int *outlen, /* IO - Size of output string */ + const char *in) /* I - String to read from */ +{ + int pos, /* Bit position */ + base64; /* Value of this character */ + char *outptr, /* Output pointer */ + *outend; /* End of output buffer */ + + + /* + * Range check input... + */ + + if (!out || !outlen || *outlen < 1 || !in || !*in) + return (NULL); + + /* + * Convert from base-64 to bytes... + */ + + for (outptr = out, outend = out + *outlen - 1, pos = 0; *in != '\0'; in ++) + { + /* + * Decode this character into a number from 0 to 63... + */ + + if (*in >= 'A' && *in <= 'Z') + base64 = *in - 'A'; + else if (*in >= 'a' && *in <= 'z') + base64 = *in - 'a' + 26; + else if (*in >= '0' && *in <= '9') + base64 = *in - '0' + 52; + else if (*in == '+') + base64 = 62; + else if (*in == '/') + base64 = 63; + else if (*in == '=') + break; + else + continue; + + /* + * Store the result in the appropriate chars... + */ + + switch (pos) + { + case 0 : + if (outptr < outend) + *outptr = base64 << 2; + pos ++; + break; + case 1 : + if (outptr < outend) + *outptr++ |= (base64 >> 4) & 3; + if (outptr < outend) + *outptr = (base64 << 4) & 255; + pos ++; + break; + case 2 : + if (outptr < outend) + *outptr++ |= (base64 >> 2) & 15; + if (outptr < outend) + *outptr = (base64 << 6) & 255; + pos ++; + break; + case 3 : + if (outptr < outend) + *outptr++ |= base64; + pos = 0; + break; + } + } + + *outptr = '\0'; + + /* + * Return the decoded string and size... + */ + + *outlen = (int)(outptr - out); + + return (out); +} + + +/* + * 'httpEncode64()' - Base64-encode a string. + */ + +char * /* O - Encoded string */ +httpEncode64(char *out, /* I - String to write to */ + const char *in) /* I - String to read from */ +{ + return (httpEncode64_2(out, 512, in, strlen(in))); +} + + +/* + * 'httpEncode64_2()' - Base64-encode a string. + */ + +char * /* O - Encoded string */ +httpEncode64_2(char *out, /* I - String to write to */ + int outlen, /* I - Size of output string */ + const char *in, /* I - String to read from */ + int inlen) /* I - Size of input string */ +{ + char *outptr, /* Output pointer */ + *outend; /* End of output buffer */ + static const char base64[] = /* Base64 characters... */ + { + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789" + "+/" + }; + + + /* + * Range check input... + */ + + if (!out || outlen < 1 || !in || inlen < 1) + return (NULL); + + /* + * Convert bytes to base-64... + */ + + for (outptr = out, outend = out + outlen - 1; inlen > 0; in ++, inlen --) + { + /* + * Encode the up to 3 characters as 4 Base64 numbers... + */ + + if (outptr < outend) + *outptr ++ = base64[(in[0] & 255) >> 2]; + if (outptr < outend) + *outptr ++ = base64[(((in[0] & 255) << 4) | ((in[1] & 255) >> 4)) & 63]; + + in ++; + inlen --; + if (inlen <= 0) + { + if (outptr < outend) + *outptr ++ = '='; + if (outptr < outend) + *outptr ++ = '='; + break; + } + + if (outptr < outend) + *outptr ++ = base64[(((in[0] & 255) << 2) | ((in[1] & 255) >> 6)) & 63]; + + in ++; + inlen --; + if (inlen <= 0) + { + if (outptr < outend) + *outptr ++ = '='; + break; + } + + if (outptr < outend) + *outptr ++ = base64[in[0] & 63]; + } + + *outptr = '\0'; + + /* + * Return the encoded string... + */ + + return (out); +} + + +/* + * 'httpGetLength()' - Get the amount of data remaining from the + * content-length or transfer-encoding fields. + */ + +int /* O - Content length */ +httpGetLength(http_t *http) /* I - HTTP data */ +{ + DEBUG_printf(("httpGetLength(http=%p), state=%d\n", http, http->state)); + + if (strcasecmp(http->fields[HTTP_FIELD_TRANSFER_ENCODING], "chunked") == 0) + { + DEBUG_puts("httpGetLength: chunked request!"); + + http->data_encoding = HTTP_ENCODE_CHUNKED; + http->data_remaining = 0; + } + else + { + http->data_encoding = HTTP_ENCODE_LENGTH; + + /* + * The following is a hack for HTTP servers that don't send a + * content-length or transfer-encoding field... + * + * If there is no content-length then the connection must close + * after the transfer is complete... + */ + + if (http->fields[HTTP_FIELD_CONTENT_LENGTH][0] == '\0') + http->data_remaining = 2147483647; + else + http->data_remaining = atoi(http->fields[HTTP_FIELD_CONTENT_LENGTH]); + + DEBUG_printf(("httpGetLength: content_length=%d\n", http->data_remaining)); + } + + return (http->data_remaining); +} + + +/* + * 'http_field()' - Return the field index for a field name. + */ + +static http_field_t /* O - Field index */ +http_field(const char *name) /* I - String name */ +{ + int i; /* Looping var */ + + + for (i = 0; i < HTTP_FIELD_MAX; i ++) + if (strcasecmp(name, http_fields[i]) == 0) + return ((http_field_t)i); + + return (HTTP_FIELD_UNKNOWN); +} + + +/* + * 'http_send()' - Send a request with all fields and the trailing blank line. + */ + +static int /* O - 0 on success, non-zero on error */ +http_send(http_t *http, /* I - HTTP data */ + http_state_t request, /* I - Request code */ + const char *uri) /* I - URI */ +{ + int i; /* Looping var */ + char *ptr, /* Pointer in buffer */ + buf[1024]; /* Encoded URI buffer */ + static const char * const codes[] = + { /* Request code strings */ + NULL, + "OPTIONS", + "GET", + NULL, + "HEAD", + "POST", + NULL, + NULL, + "PUT", + NULL, + "DELETE", + "TRACE", + "CLOSE" + }; + static const char hex[] = "0123456789ABCDEF"; + /* Hex digits */ + + + DEBUG_printf(("http_send(http=%p, request=HTTP_%s, uri=\"%s\")\n", + http, codes[request], uri)); + + if (http == NULL || uri == NULL) + return (-1); + + /* + * Encode the URI as needed... + */ + + for (ptr = buf; *uri != '\0' && ptr < (buf + sizeof(buf) - 1); uri ++) + if (*uri <= ' ' || *uri >= 127) + { + if (ptr < (buf + sizeof(buf) - 1)) + *ptr ++ = '%'; + if (ptr < (buf + sizeof(buf) - 1)) + *ptr ++ = hex[(*uri >> 4) & 15]; + if (ptr < (buf + sizeof(buf) - 1)) + *ptr ++ = hex[*uri & 15]; + } + else + *ptr ++ = *uri; + + *ptr = '\0'; + + /* + * See if we had an error the last time around; if so, reconnect... + */ + + if (http->status == HTTP_ERROR || http->status >= HTTP_BAD_REQUEST) + httpReconnect(http); + + /* + * Send the request header... + */ + + http->state = request; + if (request == HTTP_POST || request == HTTP_PUT) + http->state ++; + + http->status = HTTP_CONTINUE; + +#ifdef HAVE_SSL + if (http->encryption == HTTP_ENCRYPT_REQUIRED && !http->tls) + { + httpSetField(http, HTTP_FIELD_CONNECTION, "Upgrade"); + httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.0,SSL/2.0,SSL/3.0"); + } +#endif /* HAVE_SSL */ + + if (httpPrintf(http, "%s %s HTTP/1.1\r\n", codes[request], buf) < 1) + { + http->status = HTTP_ERROR; + return (-1); + } + + for (i = 0; i < HTTP_FIELD_MAX; i ++) + if (http->fields[i][0] != '\0') + { + DEBUG_printf(("%s: %s\n", http_fields[i], http->fields[i])); + + if (httpPrintf(http, "%s: %s\r\n", http_fields[i], http->fields[i]) < 1) + { + http->status = HTTP_ERROR; + return (-1); + } + } + + if (httpPrintf(http, "\r\n") < 1) + { + http->status = HTTP_ERROR; + return (-1); + } + + httpClearFields(http); + + return (0); +} + + +/* + * 'http_wait()' - Wait for data available on a connection. + */ + +static int /* O - 1 if data is available, 0 otherwise */ +http_wait(http_t *http, /* I - HTTP data */ + int msec) /* I - Milliseconds to wait */ +{ +#ifndef WIN32 + struct rlimit limit; /* Runtime limit */ +#endif /* !WIN32 */ + struct timeval timeout; /* Timeout */ + int nfds; /* Result from select() */ + int set_size; /* Size of select set */ + + + DEBUG_printf(("http_wait(http=%p, msec=%d)\n", http, msec)); + + /* + * Check the SSL/TLS buffers for data first... + */ + +#ifdef HAVE_SSL + if (http->tls) + { +# ifdef HAVE_LIBSSL + if (SSL_pending((SSL *)(http->tls))) + return (1); +# elif defined(HAVE_GNUTLS) + if (gnutls_record_check_pending(((http_tls_t *)(http->tls))->session)) + return (1); +# elif defined(HAVE_CDSASSL) + size_t bytes; /* Bytes that are available */ + + if (!SSLGetBufferedReadSize((SSLContextRef)http->tls, &bytes) && bytes > 0) + return; +# endif /* HAVE_LIBSSL */ + } +#endif /* HAVE_SSL */ + + /* + * Then try doing a select() to poll the socket... + */ + + if (!http->input_set) + { +#ifdef WIN32 + /* + * Windows has a fixed-size select() structure, different (surprise, + * surprise!) from all UNIX implementations. Just allocate this + * fixed structure... + */ + + http->input_set = calloc(1, sizeof(fd_set)); +#else + /* + * Allocate the select() input set based upon the max number of file + * descriptors available for this process... + */ + + getrlimit(RLIMIT_NOFILE, &limit); + + set_size = (limit.rlim_cur + 31) / 8 + 4; + if (set_size < sizeof(fd_set)) + set_size = sizeof(fd_set); + + http->input_set = calloc(1, set_size); +#endif /* WIN32 */ + + if (!http->input_set) + return (0); + } + + do + { + FD_SET(http->fd, http->input_set); + + if (msec >= 0) + { + timeout.tv_sec = msec / 1000; + timeout.tv_usec = (msec % 1000) * 1000; + + nfds = select(http->fd + 1, http->input_set, NULL, NULL, &timeout); + } + else + nfds = select(http->fd + 1, http->input_set, NULL, NULL, NULL); + } +#ifdef WIN32 + while (nfds < 0 && WSAGetLastError() == WSAEINTR); +#else + while (nfds < 0 && errno == EINTR); +#endif /* WIN32 */ + + FD_CLR(http->fd, http->input_set); + + return (nfds > 0); +} + + +#ifdef HAVE_SSL +/* + * 'http_upgrade()' - Force upgrade to TLS encryption. + */ + +static int /* O - Status of connection */ +http_upgrade(http_t *http) /* I - HTTP data */ +{ + int ret; /* Return value */ + http_t myhttp; /* Local copy of HTTP data */ + + + DEBUG_printf(("http_upgrade(%p)\n", http)); + + /* + * Copy the HTTP data to a local variable so we can do the OPTIONS + * request without interfering with the existing request data... + */ + + memcpy(&myhttp, http, sizeof(myhttp)); + + /* + * Send an OPTIONS request to the server, requiring SSL or TLS + * encryption on the link... + */ + + httpClearFields(&myhttp); + httpSetField(&myhttp, HTTP_FIELD_CONNECTION, "upgrade"); + httpSetField(&myhttp, HTTP_FIELD_UPGRADE, "TLS/1.0, SSL/2.0, SSL/3.0"); + + if ((ret = httpOptions(&myhttp, "*")) == 0) + { + /* + * Wait for the secure connection... + */ + + while (httpUpdate(&myhttp) == HTTP_CONTINUE); + } + + httpFlush(&myhttp); + + /* + * Copy the HTTP data back over, if any... + */ + + http->fd = myhttp.fd; + http->error = myhttp.error; + http->activity = myhttp.activity; + http->status = myhttp.status; + http->version = myhttp.version; + http->keep_alive = myhttp.keep_alive; + http->used = myhttp.used; + + if (http->used) + memcpy(http->buffer, myhttp.buffer, http->used); + + http->auth_type = myhttp.auth_type; + http->nonce_count = myhttp.nonce_count; + + memcpy(http->nonce, myhttp.nonce, sizeof(http->nonce)); + + http->tls = myhttp.tls; + http->encryption = myhttp.encryption; + + /* + * See if we actually went secure... + */ + + if (!http->tls) + { + /* + * Server does not support HTTP upgrade... + */ + + DEBUG_puts("Server does not support HTTP upgrade!"); + +# ifdef WIN32 + closesocket(http->fd); +# else + close(http->fd); +# endif + + http->fd = -1; + + return (-1); + } + else + return (ret); +} + + +/* + * 'http_setup_ssl()' - Set up SSL/TLS support on a connection. + */ + +static int /* O - Status of connection */ +http_setup_ssl(http_t *http) /* I - HTTP data */ +{ +# ifdef HAVE_LIBSSL + SSL_CTX *context; /* Context for encryption */ + SSL *conn; /* Connection for encryption */ +# elif defined(HAVE_GNUTLS) + http_tls_t *conn; /* TLS session object */ + gnutls_certificate_client_credentials *credentials; + /* TLS credentials */ +# elif defined(HAVE_CDSASSL) + SSLContextRef conn; /* Context for encryption */ + OSStatus error; /* Error info */ +# endif /* HAVE_LIBSSL */ + + + DEBUG_printf(("http_setup_ssl(http=%p)\n", http)); + +# ifdef HAVE_LIBSSL + context = SSL_CTX_new(SSLv23_client_method()); + + SSL_CTX_set_options(context, SSL_OP_NO_SSLv2); /* Only use SSLv3 or TLS */ + + conn = SSL_new(context); + + SSL_set_fd(conn, http->fd); + if (SSL_connect(conn) != 1) + { +# ifdef DEBUG + unsigned long error; /* Error code */ + + while ((error = ERR_get_error()) != 0) + printf("http_setup_ssl: %s\n", ERR_error_string(error, NULL)); +# endif /* DEBUG */ + + SSL_CTX_free(context); + SSL_free(conn); + +# ifdef WIN32 + http->error = WSAGetLastError(); +# else + http->error = errno; +# endif /* WIN32 */ + http->status = HTTP_ERROR; + + return (HTTP_ERROR); + } + +# elif defined(HAVE_GNUTLS) + conn = (http_tls_t *)malloc(sizeof(http_tls_t)); + + if (conn == NULL) + { + http->error = errno; + http->status = HTTP_ERROR; + + return (-1); + } + + credentials = (gnutls_certificate_client_credentials *) + malloc(sizeof(gnutls_certificate_client_credentials)); + if (credentials == NULL) + { + free(conn); + + http->error = errno; + http->status = HTTP_ERROR; + + return (-1); + } + + gnutls_certificate_allocate_credentials(credentials); + + gnutls_init(&(conn->session), GNUTLS_CLIENT); + gnutls_set_default_priority(conn->session); + gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, *credentials); + gnutls_transport_set_ptr(conn->session, http->fd); + + if ((gnutls_handshake(conn->session)) != GNUTLS_E_SUCCESS) + { + http->error = errno; + http->status = HTTP_ERROR; + + return (-1); + } + + conn->credentials = credentials; + +# elif defined(HAVE_CDSASSL) + error = SSLNewContext(false, &conn); + + if (!error) + error = SSLSetIOFuncs(conn, CDSAReadFunc, CDSAWriteFunc); + + if (!error) + error = SSLSetConnection(conn, (SSLConnectionRef)http->fd); + + if (!error) + error = SSLSetAllowsExpiredCerts(conn, true); + + if (!error) + error = SSLSetAllowsAnyRoot(conn, true); + + if (!error) + error = SSLHandshake(conn); + + if (error != 0) + { + http->error = error; + http->status = HTTP_ERROR; + + SSLDisposeContext(conn); + + close(http->fd); + + return (-1); + } +# endif /* HAVE_CDSASSL */ + + http->tls = conn; + return (0); +} + + +/* + * 'http_shutdown_ssl()' - Shut down SSL/TLS on a connection. + */ + +static void +http_shutdown_ssl(http_t *http) /* I - HTTP data */ +{ +# ifdef HAVE_LIBSSL + SSL_CTX *context; /* Context for encryption */ + SSL *conn; /* Connection for encryption */ + + + conn = (SSL *)(http->tls); + context = SSL_get_SSL_CTX(conn); + + SSL_shutdown(conn); + SSL_CTX_free(context); + SSL_free(conn); + +# elif defined(HAVE_GNUTLS) + http_tls_t *conn; /* Encryption session */ + gnutls_certificate_client_credentials *credentials; + /* TLS credentials */ + + + conn = (http_tls_t *)(http->tls); + credentials = (gnutls_certificate_client_credentials *)(conn->credentials); + + gnutls_bye(conn->session, GNUTLS_SHUT_RDWR); + gnutls_deinit(conn->session); + gnutls_certificate_free_credentials(*credentials); + free(credentials); + free(conn); + +# elif defined(HAVE_CDSASSL) + SSLClose((SSLContextRef)http->tls); + SSLDisposeContext((SSLContextRef)http->tls); +# endif /* HAVE_LIBSSL */ + + http->tls = NULL; +} + + +/* + * 'http_read_ssl()' - Read from a SSL/TLS connection. + */ + +static int /* O - Bytes read */ +http_read_ssl(http_t *http, /* I - HTTP data */ + char *buf, /* I - Buffer to store data */ + int len) /* I - Length of buffer */ +{ +# if defined(HAVE_LIBSSL) + return (SSL_read((SSL *)(http->tls), buf, len)); + +# elif defined(HAVE_GNUTLS) + return (gnutls_record_recv(((http_tls_t *)(http->tls))->session, buf, len)); + +# elif defined(HAVE_CDSASSL) + OSStatus error; /* Error info */ + size_t processed; /* Number of bytes processed */ + + + error = SSLRead((SSLContextRef)http->tls, buf, len, &processed); + + if (error == 0) + return (processed); + else + { + http->error = error; + + return (-1); + } +# endif /* HAVE_LIBSSL */ +} + + +/* + * 'http_write_ssl()' - Write to a SSL/TLS connection. + */ + +static int /* O - Bytes written */ +http_write_ssl(http_t *http, /* I - HTTP data */ + const char *buf, /* I - Buffer holding data */ + int len) /* I - Length of buffer */ +{ +# if defined(HAVE_LIBSSL) + return (SSL_write((SSL *)(http->tls), buf, len)); + +# elif defined(HAVE_GNUTLS) + return (gnutls_record_send(((http_tls_t *)(http->tls))->session, buf, len)); +# elif defined(HAVE_CDSASSL) + OSStatus error; /* Error info */ + size_t processed; /* Number of bytes processed */ + + + error = SSLWrite((SSLContextRef)http->tls, buf, len, &processed); + + if (error == 0) + return (processed); + else + { + http->error = error; + return (-1); + } +# endif /* HAVE_LIBSSL */ +} + + +# if defined(HAVE_CDSASSL) +/* + * 'CDSAReadFunc()' - Read function for CDSA decryption code. + */ + +static OSStatus /* O - -1 on error, 0 on success */ +CDSAReadFunc(SSLConnectionRef connection, /* I - SSL/TLS connection */ + void *data, /* I - Data buffer */ + size_t *dataLength) /* IO - Number of bytes */ +{ + ssize_t bytes; /* Number of bytes read */ + +#ifdef DEBUG_HTTP + httpDumpData(stdout, "CDSAReadFunc:", data, *dataLength); +#endif + bytes = recv((int)connection, data, *dataLength, 0); + if (bytes >= 0) + { + *dataLength = bytes; + return (0); + } + else + return (-1); +} + + +/* + * 'CDSAWriteFunc()' - Write function for CDSA encryption code. + */ + +static OSStatus /* O - -1 on error, 0 on success */ +CDSAWriteFunc(SSLConnectionRef connection, /* I - SSL/TLS connection */ + const void *data, /* I - Data buffer */ + size_t *dataLength) /* IO - Number of bytes */ +{ + ssize_t bytes; + + + bytes = write((int)connection, data, *dataLength); + if (bytes >= 0) + { + *dataLength = bytes; + return (0); + } + else + return (-1); +} +# endif /* HAVE_CDSASSL */ +#endif /* HAVE_SSL */ + + +/* + * End of "$Id: http.c 148 2006-04-25 16:54:17Z njacobs $" + */ diff --git a/usr/src/lib/print/libhttp-core/common/http.h b/usr/src/lib/print/libhttp-core/common/http.h new file mode 100644 index 0000000000..da36b461a3 --- /dev/null +++ b/usr/src/lib/print/libhttp-core/common/http.h @@ -0,0 +1,436 @@ +/* + * "$Id: http.h 148 2006-04-25 16:54:17Z njacobs $" + * + * Hyper-Text Transport Protocol definitions for the Common UNIX Printing + * System (CUPS). + * + * Copyright 1997-2005 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636 USA + * + * Voice: (301) 373-9600 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +#ifndef _CUPS_HTTP_H_ +#define _CUPS_HTTP_H_ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Include necessary headers... + */ + +# include <string.h> +# include <time.h> +# ifdef WIN32 +# include <winsock.h> +# else +# include <unistd.h> +# include <sys/time.h> +# include <sys/types.h> +# include <sys/socket.h> +# include <netdb.h> +# include <netinet/in.h> +# include <arpa/inet.h> +# include <netinet/in_systm.h> +# include <netinet/ip.h> +# if !defined(__APPLE__) || !defined(TCP_NODELAY) +# include <netinet/tcp.h> +# endif /* !__APPLE__ || !TCP_NODELAY */ +# ifdef AF_LOCAL +# include <sys/un.h> +# endif /* AF_LOCAL */ +# endif /* WIN32 */ + + +/* + * C++ magic... + */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + * Oh, the wonderful world of IPv6 compatibility. Apparently some + * implementations expose the (more logical) 32-bit address parts + * to everyone, while others only expose it to kernel code... To + * make supporting IPv6 even easier, each vendor chose different + * core structure and union names, so the same defines or code + * can't be used on all platforms. + * + * The following will likely need tweeking on new platforms that + * support IPv6 - the "s6_addr32" define maps to the 32-bit integer + * array in the in6_addr union, which is named differently on various + * platforms. + */ + +#if defined(AF_INET6) && !defined(s6_addr32) +# if defined(__sun) +# define s6_addr32 _S6_un._S6_u32 +# elif defined(__FreeBSD__) || defined(__APPLE__) +# define s6_addr32 __u6_addr.__u6_addr32 +# endif /* __sun */ +#endif /* AF_INET6 && !s6_addr32 */ + + +/* + * Limits... + */ + +# define HTTP_MAX_URI 1024 /* Max length of URI string */ +# define HTTP_MAX_HOST 256 /* Max length of hostname string */ +# define HTTP_MAX_BUFFER 2048 /* Max length of data buffer */ +# define HTTP_MAX_VALUE 256 /* Max header field value length */ + + +/* + * HTTP state values... + */ + +typedef enum /* States are server-oriented */ +{ + HTTP_WAITING, /* Waiting for command */ + HTTP_OPTIONS, /* OPTIONS command, waiting for blank line */ + HTTP_GET, /* GET command, waiting for blank line */ + HTTP_GET_SEND, /* GET command, sending data */ + HTTP_HEAD, /* HEAD command, waiting for blank line */ + HTTP_POST, /* POST command, waiting for blank line */ + HTTP_POST_RECV, /* POST command, receiving data */ + HTTP_POST_SEND, /* POST command, sending data */ + HTTP_PUT, /* PUT command, waiting for blank line */ + HTTP_PUT_RECV, /* PUT command, receiving data */ + HTTP_DELETE, /* DELETE command, waiting for blank line */ + HTTP_TRACE, /* TRACE command, waiting for blank line */ + HTTP_CLOSE, /* CLOSE command, waiting for blank line */ + HTTP_STATUS /* Command complete, sending status */ +} http_state_t; + + +/* + * HTTP version numbers... + */ + +typedef enum +{ + HTTP_0_9 = 9, /* HTTP/0.9 */ + HTTP_1_0 = 100, /* HTTP/1.0 */ + HTTP_1_1 = 101 /* HTTP/1.1 */ +} http_version_t; + + +/* + * HTTP keep-alive values... + */ + +typedef enum +{ + HTTP_KEEPALIVE_OFF = 0, + HTTP_KEEPALIVE_ON +} http_keepalive_t; + + +/* + * HTTP transfer encoding values... + */ + +typedef enum +{ + HTTP_ENCODE_LENGTH, /* Data is sent with Content-Length */ + HTTP_ENCODE_CHUNKED /* Data is chunked */ +} http_encoding_t; + + +/* + * HTTP encryption values... + */ + +typedef enum +{ + HTTP_ENCRYPT_IF_REQUESTED, /* Encrypt if requested (TLS upgrade) */ + HTTP_ENCRYPT_NEVER, /* Never encrypt */ + HTTP_ENCRYPT_REQUIRED, /* Encryption is required (TLS upgrade) */ + HTTP_ENCRYPT_ALWAYS /* Always encrypt (SSL) */ +} http_encryption_t; + + +/* + * HTTP authentication types... + */ + +typedef enum +{ + HTTP_AUTH_NONE, /* No authentication in use */ + HTTP_AUTH_BASIC, /* Basic authentication in use */ + HTTP_AUTH_MD5, /* Digest authentication in use */ + HTTP_AUTH_MD5_SESS, /* MD5-session authentication in use */ + HTTP_AUTH_MD5_INT, /* Digest authentication in use for body */ + HTTP_AUTH_MD5_SESS_INT /* MD5-session authentication in use for body */ +} http_auth_t; + + +/* + * HTTP status codes... + */ + +typedef enum +{ + HTTP_ERROR = -1, /* An error response from httpXxxx() */ + + HTTP_CONTINUE = 100, /* Everything OK, keep going... */ + HTTP_SWITCHING_PROTOCOLS, /* HTTP upgrade to TLS/SSL */ + + HTTP_OK = 200, /* OPTIONS/GET/HEAD/POST/TRACE command was successful */ + HTTP_CREATED, /* PUT command was successful */ + HTTP_ACCEPTED, /* DELETE command was successful */ + HTTP_NOT_AUTHORITATIVE, /* Information isn't authoritative */ + HTTP_NO_CONTENT, /* Successful command, no new data */ + HTTP_RESET_CONTENT, /* Content was reset/recreated */ + HTTP_PARTIAL_CONTENT, /* Only a partial file was recieved/sent */ + + HTTP_MULTIPLE_CHOICES = 300, /* Multiple files match request */ + HTTP_MOVED_PERMANENTLY, /* Document has moved permanently */ + HTTP_MOVED_TEMPORARILY, /* Document has moved temporarily */ + HTTP_SEE_OTHER, /* See this other link... */ + HTTP_NOT_MODIFIED, /* File not modified */ + HTTP_USE_PROXY, /* Must use a proxy to access this URI */ + + HTTP_BAD_REQUEST = 400, /* Bad request */ + HTTP_UNAUTHORIZED, /* Unauthorized to access host */ + HTTP_PAYMENT_REQUIRED, /* Payment required */ + HTTP_FORBIDDEN, /* Forbidden to access this URI */ + HTTP_NOT_FOUND, /* URI was not found */ + HTTP_METHOD_NOT_ALLOWED, /* Method is not allowed */ + HTTP_NOT_ACCEPTABLE, /* Not Acceptable */ + HTTP_PROXY_AUTHENTICATION, /* Proxy Authentication is Required */ + HTTP_REQUEST_TIMEOUT, /* Request timed out */ + HTTP_CONFLICT, /* Request is self-conflicting */ + HTTP_GONE, /* Server has gone away */ + HTTP_LENGTH_REQUIRED, /* A content length or encoding is required */ + HTTP_PRECONDITION, /* Precondition failed */ + HTTP_REQUEST_TOO_LARGE, /* Request entity too large */ + HTTP_URI_TOO_LONG, /* URI too long */ + HTTP_UNSUPPORTED_MEDIATYPE, /* The requested media type is unsupported */ + HTTP_UPGRADE_REQUIRED = 426, /* Upgrade to SSL/TLS required */ + + HTTP_SERVER_ERROR = 500, /* Internal server error */ + HTTP_NOT_IMPLEMENTED, /* Feature not implemented */ + HTTP_BAD_GATEWAY, /* Bad gateway */ + HTTP_SERVICE_UNAVAILABLE, /* Service is unavailable */ + HTTP_GATEWAY_TIMEOUT, /* Gateway connection timed out */ + HTTP_NOT_SUPPORTED /* HTTP version not supported */ +} http_status_t; + + +/* + * HTTP field names... + */ + +typedef enum +{ + HTTP_FIELD_UNKNOWN = -1, + HTTP_FIELD_ACCEPT_LANGUAGE, + HTTP_FIELD_ACCEPT_RANGES, + HTTP_FIELD_AUTHORIZATION, + HTTP_FIELD_CONNECTION, + HTTP_FIELD_CONTENT_ENCODING, + HTTP_FIELD_CONTENT_LANGUAGE, + HTTP_FIELD_CONTENT_LENGTH, + HTTP_FIELD_CONTENT_LOCATION, + HTTP_FIELD_CONTENT_MD5, + HTTP_FIELD_CONTENT_RANGE, + HTTP_FIELD_CONTENT_TYPE, + HTTP_FIELD_CONTENT_VERSION, + HTTP_FIELD_DATE, + HTTP_FIELD_HOST, + HTTP_FIELD_IF_MODIFIED_SINCE, + HTTP_FIELD_IF_UNMODIFIED_SINCE, + HTTP_FIELD_KEEP_ALIVE, + HTTP_FIELD_LAST_MODIFIED, + HTTP_FIELD_LINK, + HTTP_FIELD_LOCATION, + HTTP_FIELD_RANGE, + HTTP_FIELD_REFERER, + HTTP_FIELD_RETRY_AFTER, + HTTP_FIELD_TRANSFER_ENCODING, + HTTP_FIELD_UPGRADE, + HTTP_FIELD_USER_AGENT, + HTTP_FIELD_WWW_AUTHENTICATE, + HTTP_FIELD_MAX +} http_field_t; + + +/* + * HTTP address structure (makes using IPv6 a little easier and more portable.) + */ + +typedef union +{ + struct sockaddr addr; /* Base structure for family value */ + struct sockaddr_in ipv4; /* IPv4 address */ +#ifdef AF_INET6 + struct sockaddr_in6 ipv6; /* IPv6 address */ +#endif /* AF_INET6 */ +#ifdef AF_LOCAL + struct sockaddr_un un; /* Domain socket file */ +#endif /* AF_LOCAL */ + char pad[128]; /* Pad to ensure binary compatibility */ +} http_addr_t; + +/* + * HTTP connection structure... + */ + +typedef struct +{ + int fd; /* File descriptor for this socket */ + int blocking; /* To block or not to block */ + int error; /* Last error on read */ + time_t activity; /* Time since last read/write */ + http_state_t state; /* State of client */ + http_status_t status; /* Status of last request */ + http_version_t version; /* Protocol version */ + http_keepalive_t keep_alive; /* Keep-alive supported? */ + struct sockaddr_in oldaddr; /* Address of connected host */ + char hostname[HTTP_MAX_HOST], + /* Name of connected host */ + fields[HTTP_FIELD_MAX][HTTP_MAX_VALUE]; + /* Field values */ + char *data; /* Pointer to data buffer */ + http_encoding_t data_encoding; /* Chunked or not */ + int data_remaining; /* Number of bytes left */ + int used; /* Number of bytes used in buffer */ + char buffer[HTTP_MAX_BUFFER]; + /* Buffer for messages */ + int auth_type; /* Authentication in use */ + char nonce[HTTP_MAX_VALUE]; + /* Nonce value */ + int nonce_count; /* Nonce count */ + void *tls; /* TLS state information */ + http_encryption_t encryption; /* Encryption requirements */ + /**** New in CUPS 1.1.19 ****/ + fd_set *input_set; /* select() set for httpWait() */ + http_status_t expect; /* Expect: header */ + char *cookie; /* Cookie value(s) */ + /**** New in CUPS 1.1.20 ****/ + char authstring[HTTP_MAX_VALUE], + /* Current Authentication value */ + userpass[HTTP_MAX_VALUE]; + /* Username:password string */ + int digest_tries; /* Number of tries for digest auth */ + /**** New in CUPS 1.2 ****/ + http_addr_t hostaddr; /* Host address and port */ +} http_t; + + +/* + * Prototypes... + */ + +# define httpBlocking(http,b) (http)->blocking = (b) +extern int httpCheck(http_t *http); +# define httpClearFields(http) memset((http)->fields, 0, sizeof((http)->fields)),\ + httpSetField((http), HTTP_FIELD_HOST, (http)->hostname) +extern void httpClose(http_t *http); +extern http_t *httpConnect(const char *host, int port); +extern http_t *httpConnectEncrypt(const char *host, int port, + http_encryption_t encrypt); +extern int httpDelete(http_t *http, const char *uri); +extern int httpEncryption(http_t *http, http_encryption_t e); +# define httpError(http) ((http)->error) +extern void httpFlush(http_t *http); +extern int httpGet(http_t *http, const char *uri); +extern char *httpGets(char *line, int length, http_t *http); +extern const char *httpGetDateString(time_t t); +extern time_t httpGetDateTime(const char *s); +# define httpGetField(http,field) (http)->fields[field] +extern struct hostent *httpGetHostByName(const char *name); +extern char *httpGetSubField(http_t *http, http_field_t field, + const char *name, char *value); +extern int httpHead(http_t *http, const char *uri); +extern void httpInitialize(void); +extern int httpOptions(http_t *http, const char *uri); +extern int httpPost(http_t *http, const char *uri); +extern int httpPrintf(http_t *http, const char *format, ...) +# ifdef __GNUC__ +__attribute__ ((__format__ (__printf__, 2, 3))) +# endif /* __GNUC__ */ +; +extern int httpPut(http_t *http, const char *uri); +extern int httpRead(http_t *http, char *buffer, int length); +extern int httpReconnect(http_t *http); +extern void httpSeparate(const char *uri, char *method, + char *username, char *host, int *port, + char *resource); +extern void httpSetField(http_t *http, http_field_t field, + const char *value); +extern const char *httpStatus(http_status_t status); +extern int httpTrace(http_t *http, const char *uri); +extern http_status_t httpUpdate(http_t *http); +extern int httpWrite(http_t *http, const char *buffer, int length); +extern char *httpEncode64(char *out, const char *in); +extern char *httpDecode64(char *out, const char *in); +extern int httpGetLength(http_t *http); +extern char *httpMD5(const char *, const char *, const char *, + char [33]); +extern char *httpMD5Final(const char *, const char *, const char *, + char [33]); +extern char *httpMD5String(const unsigned char *, char [33]); + +/**** New in CUPS 1.1.19 ****/ +extern void httpClearCookie(http_t *http); +#define httpGetCookie(http) ((http)->cookie) +extern void httpSetCookie(http_t *http, const char *cookie); +extern int httpWait(http_t *http, int msec); + +/**** New in CUPS 1.1.21 ****/ +extern char *httpDecode64_2(char *out, int *outlen, const char *in); +extern char *httpEncode64_2(char *out, int outlen, const char *in, + int inlen); +extern void httpSeparate2(const char *uri, + char *method, int methodlen, + char *username, int usernamelen, + char *host, int hostlen, int *port, + char *resource, int resourcelen); + +/**** New in CUPS 1.2 ****/ +extern int httpAddrAny(const http_addr_t *addr); +extern int httpAddrEqual(const http_addr_t *addr1, + const http_addr_t *addr2); +extern void httpAddrLoad(const struct hostent *host, int port, + int n, http_addr_t *addr); +extern int httpAddrLocalhost(const http_addr_t *addr); +extern char *httpAddrLookup(const http_addr_t *addr, + char *name, int namelen); +extern char *httpAddrString(const http_addr_t *addr, + char *s, int slen); + + +/* + * C++ magic... + */ + +#ifdef __cplusplus +} +#endif + +#endif /* !_CUPS_HTTP_H_ */ + +/* + * End of "$Id: http.h 148 2006-04-25 16:54:17Z njacobs $" + */ diff --git a/usr/src/lib/print/libhttp-core/common/mapfile b/usr/src/lib/print/libhttp-core/common/mapfile new file mode 100644 index 0000000000..e799d3bc76 --- /dev/null +++ b/usr/src/lib/print/libhttp-core/common/mapfile @@ -0,0 +1,58 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# $Id: mapfile.in,v 1.2 2006/03/02 06:31:36 njacobs Exp $ +# + +# ident "%Z%%M% %I% %E% SMI" + +# +# Common interfaces that are most likely to be shared amongst the various +# PAPI implementations. +# + +SUNWprivate_1.0 { + global: + httpCheck ; + httpClose ; + httpConnectEncrypt ; + httpDumpData ; + httpEncode64 ; + httpEncryption ; + httpFlush ; + httpGetSubField ; + httpPost ; + httpRead ; + httpReconnect ; + httpSetField ; + httpUpdate ; + httpWait ; + httpWrite ; + + local: + * ; +} ; diff --git a/usr/src/lib/print/libhttp-core/i386/Makefile b/usr/src/lib/print/libhttp-core/i386/Makefile new file mode 100644 index 0000000000..0bc3313291 --- /dev/null +++ b/usr/src/lib/print/libhttp-core/i386/Makefile @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBDIR) $(ROOTLIBS) $(ROOTLINKS) diff --git a/usr/src/lib/print/libhttp-core/sparc/Makefile b/usr/src/lib/print/libhttp-core/sparc/Makefile new file mode 100644 index 0000000000..0bc3313291 --- /dev/null +++ b/usr/src/lib/print/libhttp-core/sparc/Makefile @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBDIR) $(ROOTLIBS) $(ROOTLINKS) diff --git a/usr/src/lib/print/libipp-core/Makefile b/usr/src/lib/print/libipp-core/Makefile new file mode 100644 index 0000000000..b92d620b10 --- /dev/null +++ b/usr/src/lib/print/libipp-core/Makefile @@ -0,0 +1,56 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../../Makefile.lib + +#HDRS = papi.h +#HDRDIR = common +SUBDIRS = $(MACH) +#$(BUILD64)SUBDIRS += $(MACH64) + +all := TARGET = all +clean := TARGET = clean +clobber := TARGET = clobber +install := TARGET = install +lint := TARGET = lint + +.KEEP_STATE: + +all clean clobber install: .WAIT $(SUBDIRS) + +lint: # $(SUBDIRS) + +install_h: # $(ROOTHDRS) + +check: # $(CHECKHDRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include ../../Makefile.targ diff --git a/usr/src/lib/print/libipp-core/Makefile.com b/usr/src/lib/print/libipp-core/Makefile.com new file mode 100644 index 0000000000..56099a4aa9 --- /dev/null +++ b/usr/src/lib/print/libipp-core/Makefile.com @@ -0,0 +1,58 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +LIBRARY = libipp-core.a +VERS = .0 +OBJECTS = ipp.o ipp_types.o read.o strings.o write.o + +include ../../../Makefile.lib +include ../../../Makefile.rootfs + +ROOTLIBDIR= $(ROOT)/usr/lib + +LIBS = $(DYNLIB) + +SRCS = $(OBJECTS:%.o = $(SRCDIR)/%.c) + +$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC) + +SRCDIR = ../common +MAPFILE = $(SRCDIR)/mapfile + +CFLAGS += $(CCVERBOSE) +CPPFLAGS += -I$(SRCDIR) +CPPFLAGS += -I../../libpapi-common/common +DYNFLAGS += -M $(MAPFILE) +LDLIBS += -lpapi-common -lc + +.KEEP_STATE: + +all: $(LIBS) + +lint: lintcheck + +include ../../../Makefile.targ diff --git a/usr/src/lib/print/libipp-core/common/ipp.c b/usr/src/lib/print/libipp-core/common/ipp.c new file mode 100644 index 0000000000..133fb0ad13 --- /dev/null +++ b/usr/src/lib/print/libipp-core/common/ipp.c @@ -0,0 +1,136 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: ipp.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdarg.h> +#include <papi.h> +#include "ipp.h" + +/* + * IPP requests/responses are represented as attribute lists. An IPP request + * attribute list will contain header information attributes: + * version-major (int) + * version-minor (int) + * request-id (int) + * operation-id (int) + * It will also contain 1 or more attribute groups (collections) + * operational-attribute-group + * ... + * this routine validates that the request falls within the guidelines of + * the protocol specification (or some other level of conformance if the + * restrictions have been specified at the top level of the request using + * a "conformance" attribute. + */ +papi_status_t +ipp_validate_request(papi_attribute_t **request, papi_attribute_t ***response) +{ + papi_attribute_t **attributes = NULL; + papi_status_t result = PAPI_OK; + char *s; + + if ((request == NULL) || (response == NULL) || (*response == NULL)) + return (PAPI_BAD_ARGUMENT); + + /* validate the operational attributes group */ + result = papiAttributeListGetCollection(request, NULL, + "operational-attributes-group", &attributes); + if (result != PAPI_OK) { + ipp_set_status(response, result, + "operational attribute group: %s", + papiStatusString(result)); + return (result); + } + + result = papiAttributeListGetString(attributes, NULL, + "attributes-charset", &s); + if (result != PAPI_OK) { + ipp_set_status(response, result, "attributes-charset: %s", + papiStatusString(result)); + return (result); + } + + result = papiAttributeListGetString(attributes, NULL, + "attributes-natural-language", &s); + if (result != PAPI_OK) { + ipp_set_status(response, result, + "attributes-natural-language: %s", + papiStatusString(result)); + return (result); + } + + return (result); +} + +/* + * Add/Modify the statuse-code and status-message in an IPP response's + * operational attributes group. + */ +void +ipp_set_status(papi_attribute_t ***message, papi_status_t status, + char *format, ...) +{ + if (message == NULL) + return; + + if (format != NULL) { + papi_attribute_t **operational = NULL; + papi_attribute_t **saved; + char mesg[256]; /* status-message is type text(255) */ + va_list ap; + + (void) papiAttributeListGetCollection(*message, NULL, + "operational-attributes-group", + &operational); + saved = operational; + + va_start(ap, format); + (void) vsnprintf(mesg, sizeof (mesg), format, ap); + va_end(ap); + + (void) papiAttributeListAddString(&operational, + PAPI_ATTR_APPEND, "status-message", mesg); + + /* + * We need to check and see if adding the status-message caused + * the operational attributes group to be relocated in memory. + * If it has been, we will need to re-add the collection to + * the message. + */ + if (saved != operational) + (void) papiAttributeListAddCollection(message, + PAPI_ATTR_REPLACE, + "operational-attributes-group", + operational); + } + + (void) papiAttributeListAddInteger(message, PAPI_ATTR_APPEND, + "status-code", status); +} diff --git a/usr/src/lib/print/libipp-core/common/ipp.h b/usr/src/lib/print/libipp-core/common/ipp.h new file mode 100644 index 0000000000..c13728e334 --- /dev/null +++ b/usr/src/lib/print/libipp-core/common/ipp.h @@ -0,0 +1,348 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +#ifndef _IPP_H +#define _IPP_H + +/* $Id: ipp.h 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdarg.h> +#include <sys/time.h> +#include <papi.h> +#include <inttypes.h> + + +typedef ssize_t (*ipp_reader_t)(void *fd, void *buffer, size_t buffer_size); +typedef ssize_t (*ipp_writer_t)(void *fd, void *buffer, size_t buffer_size); + +enum { + IPP_TYPE_UNKNOWN = 0, + IPP_TYPE_REQUEST = 1, + IPP_TYPE_RESPONSE = 2 +}; + +/* + * How closely do we conform to the spec when parsing? Do we + * a) Stop parsing only when we encounter an error that prevents us from + * continuing parsing (a server error or ridiculously malformed request)? + * b) Stop parsing when we know the server wouldn't be able to act on the + * response correctly, even if we can make sense of some of the data? + * c) Jawohl, Mein IPP Spec! + * The answer will usually be b, though a will be useful for debugging. + */ +enum { + IPP_PARSE_CONFORMANCE_RASH = 0, + IPP_PARSE_CONFORMANCE_LOOSE = 1, + IPP_PARSE_CONFORMANCE_STRICT = 2 +}; + + +/* Operation IDs */ +enum { + OPID_MIN = 0x0000, /* 0x0000 */ + OPID_RESERVED_0000 = 0x0000, /* 0x0000 */ + OPID_RESERVED_0001, /* 0x0001 */ + OPID_PRINT_JOB, /* 0x0002 */ + OPID_PRINT_URI, /* 0x0003 */ + OPID_VALIDATE_JOB, /* 0x0004 */ + OPID_CREATE_JOB, /* 0x0005 */ + OPID_SEND_DOCUMENT, /* 0x0006 */ + OPID_SEND_URI, /* 0x0007 */ + OPID_CANCEL_JOB, /* 0x0008 */ + OPID_GET_JOB_ATTRIBUTES, /* 0x0009 */ + OPID_GET_JOBS, /* 0x000a */ + OPID_GET_PRINTER_ATTRIBUTES, /* 0x000b */ + OPID_HOLD_JOB, /* 0x000c */ + OPID_RELEASE_JOB, /* 0x000d */ + OPID_RESTART_JOB, /* 0x000e */ + OPID_RESERVED_000F, /* 0x000f */ + OPID_PAUSE_PRINTER, /* 0x0010 */ + OPID_RESUME_PRINTER, /* 0x0011 */ + OPID_PURGE_JOBS, /* 0x0012 */ + OPID_SET_PRINTER_ATTRIBUTES, /* 0x0013 */ + OPID_SET_JOB_ATTRIBUTES, /* 0x0014 */ + OPID_GET_PRINTER_SUPPORTED_VALUES, /* 0x0015 */ + OPID_CREATE_PRINTER_SUBSCRIPTION, /* 0x0016 */ + OPID_CREATE_JOB_SUBSCRIPTION, /* 0x0017 */ + OPID_GET_SUBSCRIPTION_ATTRIBUTES, /* 0x0018 */ + OPID_GET_SUBSCRIPTIONS, /* 0x0019 */ + OPID_RENEW_SUBSCRIPTION, /* 0x001a */ + OPID_CANCEL_SUBSCRIPTION, /* 0x001b */ + OPID_GET_NOTIFICATIONS, /* 0x001c */ + OPID_SEND_NOTIFICATIONS, /* 0x001d */ + OPID_GET_RESOURCE_ATTRIBUTES, /* 0x001e */ + OPID_GET_RESOURCE_DATA, /* 0x001f */ + OPID_GET_RESOURCES, /* 0x0020 */ + OPID_GET_PRINT_SUPPORT_FILES, /* 0x0021 */ + OPID_ENABLE_PRINTER, /* 0x0022 */ + OPID_DISABLE_PRINTER, /* 0x0023 */ + OPID_PAUSE_PRINTER_AFTER_CURRENT_JOB, /* 0x0024 */ + OPID_HOLD_NEW_JOBS, /* 0x0025 */ + OPID_RELEASE_HELD_NEW_JOBS, /* 0x0026 */ + OPID_DEACTIVATE_PRINTER, /* 0x0027 */ + OPID_ACTIVATE_PRINTER, /* 0x0028 */ + OPID_RESTART_PRINTER, /* 0x0029 */ + OPID_SHUTDOWN_PRINTER, /* 0x002a */ + OPID_STARTUP_PRINTER, /* 0x002b */ + OPID_REPROCESS_JOB, /* 0x002c */ + OPID_CANCEL_CURRENT_JOB, /* 0x002d */ + OPID_SUSPEND_CURRENT_JOB, /* 0x002e */ + OPID_RESUME_JOB, /* 0x002f */ + OPID_PROMOTE_JOB, /* 0x0030 */ + OPID_SCHEDULE_JOB_AFTER, /* 0x0031 */ + OPID_RESERVED_MIN, /* 0x0032 */ + OPID_RESERVED_0032 = 0x0032, /* 0x0032 */ + /* ... */ + OPID_RESERVED_3FFF = 0x3fff, /* 0x3fff */ + OPID_RESERVED_MAX = 0x3fff, /* 0x3fff */ + OPID_RESERVED_VENDOR_MIN = 0x4000, /* 0x4000 */ + OPID_RESERVED_VENDOR_4000 = 0x4000, /* 0x4000 */ + /* ... */ + OPID_RESERVED_VENDOR_8FFF = 0x8fff, /* 0x8fff */ + OPID_RESERVED_VENDOR_MAX = 0x8fff, /* 0x8fff */ + OPID_MAX = 0x8fff /* 0x8fff */ +}; + +enum { + /* Delimiter Tags */ + DTAG_MIN = 0x00, /* 0x00 */ + DTAG_RESERVED_DELIMITER_00 = 0x00, /* 0x00 */ + DTAG_OPERATION_ATTRIBUTES, /* 0x01 */ + DTAG_JOB_ATTRIBUTES, /* 0x02 */ + DTAG_END_OF_ATTRIBUTES, /* 0x03 */ + DTAG_PRINTER_ATTRIBUTES, /* 0x04 */ + DTAG_UNSUPPORTED_ATTRIBUTES, /* 0x05 */ + DTAG_SUBSCRIPTION_ATTRIBUTES, /* 0x06 */ + DTAG_EVENT_NOTIFICATION_ATTRIBUTES, /* 0x07 */ + DTAG_RESERVED_DELIMITER_08, /* 0x08 */ + DTAG_RESERVED_DELIMITER_09, /* 0x09 */ + DTAG_RESERVED_DELIMITER_0A, /* 0x0a */ + DTAG_RESERVED_DELIMITER_0B, /* 0x0b */ + DTAG_RESERVED_DELIMITER_0C, /* 0x0c */ + DTAG_RESERVED_DELIMITER_0D, /* 0x0d */ + DTAG_RESERVED_DELIMITER_0E, /* 0x0e */ + DTAG_RESERVED_DELIMITER_0F, /* 0x0f */ + DTAG_MAX = 0x0f, /* 0x0f */ + + /* Value Tags */ + VTAG_MIN = 0x10, /* 0x10 */ + VTAG_UNSUPPORTED = 0x10, /* 0x10 */ + VTAG_RESERVED_DEFAULT, /* 0x11 */ + VTAG_UNKNOWN, /* 0x12 */ + VTAG_NOVALUE, /* 0x13 */ + VTAG_RESERVED_OOB_14, /* 0x14 */ + VTAG_NOT_SETTABLE, /* 0x15 */ + VTAG_DELETE_ATTRIBUTE, /* 0x16 */ + VTAG_ADMIN_DEFINE, /* 0x17 */ + VTAG_RESERVED_OOB_18, /* 0x18 */ + VTAG_RESERVED_OOB_19, /* 0x19 */ + VTAG_RESERVED_OOB_1A, /* 0x1a */ + VTAG_RESERVED_OOB_1B, /* 0x1b */ + VTAG_RESERVED_OOB_1C, /* 0x1c */ + VTAG_RESERVED_OOB_1D, /* 0x1d */ + VTAG_RESERVED_OOB_1E, /* 0x1e */ + VTAG_RESERVED_OOB_1F, /* 0x1f */ + VTAG_RESERVED_INT_GEN, /* 0x20 */ + VTAG_INTEGER, /* 0x21 */ + VTAG_BOOLEAN, /* 0x22 */ + VTAG_ENUM, /* 0x23 */ + VTAG_RESERVED_INT_24, /* 0x24 */ + VTAG_RESERVED_INT_25, /* 0x25 */ + VTAG_RESERVED_INT_26, /* 0x26 */ + VTAG_RESERVED_INT_27, /* 0x27 */ + VTAG_RESERVED_INT_28, /* 0x28 */ + VTAG_RESERVED_INT_29, /* 0x29 */ + VTAG_RESERVED_INT_2A, /* 0x2a */ + VTAG_RESERVED_INT_2B, /* 0x2b */ + VTAG_RESERVED_INT_2C, /* 0x2c */ + VTAG_RESERVED_INT_2D, /* 0x2d */ + VTAG_RESERVED_INT_2E, /* 0x2e */ + VTAG_RESERVED_INT_2F, /* 0x2f */ + VTAG_OCTET_STRING, /* 0x30 */ + VTAG_DATE_TIME, /* 0x31 */ + VTAG_RESOLUTION, /* 0x32 */ + VTAG_RANGE_OF_INTEGER, /* 0x33 */ + VTAG_BEGIN_COLLECTION, /* 0x34 */ + VTAG_TEXT_WITH_LANGUAGE, /* 0x35 */ + VTAG_NAME_WITH_LANGUAGE, /* 0x36 */ + VTAG_END_COLLECTION, /* 0x37 */ + VTAG_RESERVED_STRING_38, /* 0x38 */ + VTAG_RESERVED_STRING_39, /* 0x39 */ + VTAG_RESERVED_STRING_3A, /* 0x3a */ + VTAG_RESERVED_STRING_3B, /* 0x3b */ + VTAG_RESERVED_STRING_3C, /* 0x3c */ + VTAG_RESERVED_STRING_3D, /* 0x3d */ + VTAG_RESERVED_STRING_3E, /* 0x3e */ + VTAG_RESERVED_STRING_3F, /* 0x3f */ + VTAG_RESERVED_CHAR_GEN, /* 0x40 */ + VTAG_TEXT_WITHOUT_LANGUAGE, /* 0x41 */ + VTAG_NAME_WITHOUT_LANGUAGE, /* 0x42 */ + VTAG_RESERVED_43, /* 0x43 */ + VTAG_KEYWORD, /* 0x44 */ + VTAG_URI, /* 0x45 */ + VTAG_URI_SCHEME, /* 0x46 */ + VTAG_CHARSET, /* 0x47 */ + VTAG_NATURAL_LANGUAGE, /* 0x48 */ + VTAG_MIME_MEDIA_TYPE, /* 0x49 */ + VTAG_MEMBER_ATTR_NAME, /* 0x4a */ + VTAG_RESERVED_STRING_4B, /* 0x4b */ + VTAG_RESERVED_STRING_4C, /* 0x4c */ + VTAG_RESERVED_STRING_4D, /* 0x4d */ + VTAG_RESERVED_STRING_4E, /* 0x4e */ + VTAG_RESERVED_STRING_4F, /* 0x4f */ + VTAG_RESERVED_STRING_50, /* 0x50 */ + VTAG_RESERVED_STRING_51, /* 0x51 */ + VTAG_RESERVED_STRING_52, /* 0x52 */ + VTAG_RESERVED_STRING_53, /* 0x53 */ + VTAG_RESERVED_STRING_54, /* 0x54 */ + VTAG_RESERVED_STRING_55, /* 0x55 */ + VTAG_RESERVED_STRING_56, /* 0x56 */ + VTAG_RESERVED_STRING_57, /* 0x57 */ + VTAG_RESERVED_STRING_58, /* 0x58 */ + VTAG_RESERVED_STRING_59, /* 0x59 */ + VTAG_RESERVED_STRING_5A, /* 0x5a */ + VTAG_RESERVED_STRING_5B, /* 0x5b */ + VTAG_RESERVED_STRING_5C, /* 0x5c */ + VTAG_RESERVED_STRING_5D, /* 0x5d */ + VTAG_RESERVED_STRING_5E, /* 0x5e */ + VTAG_RESERVED_STRING_5F, /* 0x5f */ + VTAG_RESERVED_MAX = 0x5f, /* 0x5f */ + VTAG_MAX = 0x5f, /* 0x5f */ + VTAG_EXTEND = 0x7f /* 0x7f */ +}; + +/* Response codes */ +enum { + IPP_OK_MIN = 0x0000, + IPP_OK = 0x0000, /* 0x0000 */ + IPP_OK_IGNORED_ATTRIBUTES, /* 0x0001 */ + IPP_OK_CONFLICTING_ATTRIBUTES, /* 0x0002 */ + IPP_OK_IGNORED_SUBSCRIPTIONS, /* 0x0003 */ + IPP_OK_IGNORED_NOTIFICATIONS, /* 0x0004 */ + IPP_OK_TOO_MANY_EVENTS, /* 0x0005 */ + IPP_OK_BUT_CANCEL_SUBSCRIPTION, /* 0x0006 */ + IPP_OK_MAX = IPP_OK_BUT_CANCEL_SUBSCRIPTION, + + IPP_REDIR_MIN = 0x0300, + IPP_REDIR_OTHER_SIZE = 0x0300, /* 0x0300 */ + IPP_REDIR_MAX = 0x0300, + + IPP_CERR_MIN = 0x0400, + IPP_CERR_BAD_REQUEST = 0x0400, /* 0x0400 */ + IPP_CERR_FORBIDDEN, /* 0x0401 */ + IPP_CERR_NOT_AUTHENTICATED, /* 0x0402 */ + IPP_CERR_NOT_AUTHORIZED, /* 0x0403 */ + IPP_CERR_NOT_POSSIBLE, /* 0x0404 */ + IPP_CERR_TIMEOUT, /* 0x0405 */ + IPP_CERR_NOT_FOUND, /* 0x0406 */ + IPP_CERR_GONE, /* 0x0407 */ + IPP_CERR_REQUEST_ENTITY, /* 0x0408 */ + IPP_CERR_REQUEST_VALUE, /* 0x0409 */ + IPP_CERR_DOCUMENT_FORMAT, /* 0x040a */ + IPP_CERR_ATTRIBUTES, /* 0x040b */ + IPP_CERR_URI_SCHEME, /* 0x040c */ + IPP_CERR_CHARSET, /* 0x040d */ + IPP_CERR_CONFLICT, /* 0x040e */ + IPP_CERR_COMPRESSION_NOT_SUPPORTED, /* 0x040f */ + IPP_CERR_COMPRESSION_ERROR, /* 0x0410 */ + IPP_CERR_DOCUMENT_FORMAT_ERROR, /* 0x0411 */ + IPP_CERR_DOCUMENT_ACCESS_ERROR, /* 0x0412 */ + IPP_CERR_ATTRIBUTES_NOT_SETTABLE, /* 0x0413 */ + IPP_CERR_IGNORED_ALL_SUBSCRIPTIONS, /* 0x0414 */ + IPP_CERR_TOO_MANY_SUBSCRIPTIONS, /* 0x0415 */ + IPP_CERR_IGNORED_ALL_NOTIFICATIONS, /* 0x0416 */ + IPP_CERR_PRINT_SUPPORT_FILE_NOT_FOUND, /* 0x0417 */ + IPP_CERR_MAX = IPP_CERR_PRINT_SUPPORT_FILE_NOT_FOUND, + + IPP_SERR_MIN = 0x0500, + IPP_SERR_INTERNAL = 0x0500, /* 0x0500 */ + IPP_SERR_OPERATION_NOT_SUPPORTED, /* 0x0501 */ + IPP_SERR_SERVICE_UNAVAILABLE, /* 0x0502 */ + IPP_SERR_VERSION_NOT_SUPPORTED, /* 0x0503 */ + IPP_SERR_DEVICE_ERROR, /* 0x0504 */ + IPP_SERR_TEMPORARY_ERROR, /* 0x0505 */ + IPP_SERR_NOT_ACCEPTING, /* 0x0506 */ + IPP_SERR_BUSY, /* 0x0507 */ + IPP_SERR_CANCELLED, /* 0x0508 */ + IPP_SERR_MULTIPLE_DOCS_NOT_SUPPORTED, /* 0x0509 */ + IPP_SERR_PRINTER_IS_DEACTIVATED, /* 0x050a */ + IPP_SERR_MAX = IPP_SERR_PRINTER_IS_DEACTIVATED +}; + +/* Job state codes */ +enum { + IPP_JOB_STATE_PENDING = 3, + IPP_JOB_STATE_PENDING_HELD = 4, + IPP_JOB_STATE_PROCESSING = 5, + IPP_JOB_STATE_PROCESSING_STOPPED = 6, + IPP_JOB_STATE_CANCELED = 7, + IPP_JOB_STATE_ABORTED = 8, + IPP_JOB_STATE_COMPLETED = 9 +}; + +/* exported functions */ +extern papi_status_t ipp_read_message(ipp_reader_t iread, void *fd, + papi_attribute_t ***message, char type); + +extern papi_status_t ipp_write_message(ipp_writer_t iwrite, void *fd, + papi_attribute_t **message); + +/* internal functions shared between modules */ +extern void ipp_set_status(papi_attribute_t ***message, papi_status_t status, + char *format, ...); +extern papi_status_t ipp_validate_request(papi_attribute_t **request, + papi_attribute_t ***response); + +extern int ipp_severity(int16_t status); + +extern int16_t ipp_charset_supported(char *charset); + +extern void *string_to_ipp_attr_value(int8_t type, char *value); + +extern char *ipp_uri_to_printer(char *uri); +extern void *papi_attribute_to_ipp_attr(int8_t type, papi_attribute_t *attr); + +extern int8_t name_to_ipp_type(char *name); +extern char *job_template[]; +extern char *job_description[]; +extern char *printer_description[]; +extern char *ipp_tag_string(int8_t tag, char *buf, size_t bufsiz); +extern size_t min_val_len(int8_t type, char *name); +extern size_t max_val_len(int8_t type, char *name); +extern int is_keyword(char *value); + +#ifdef __cplusplus +} +#endif + +#endif /* _IPP_H */ diff --git a/usr/src/lib/print/libipp-core/common/ipp_types.c b/usr/src/lib/print/libipp-core/common/ipp_types.c new file mode 100644 index 0000000000..47fc32c259 --- /dev/null +++ b/usr/src/lib/print/libipp-core/common/ipp_types.c @@ -0,0 +1,303 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: ipp_types.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <ipp.h> +#include <errno.h> +#include <values.h> + +#ifndef MININT +#define MININT (-MAXINT - 1) +#endif + +typedef struct { + char *name; + int8_t ipp_type; + int min; + int max; +} attr_info_list_t; + +static attr_info_list_t attr_list[] = { + {"operation-attribute-group", DTAG_OPERATION_ATTRIBUTES, 0, 0}, + {"job-attribute-group", DTAG_JOB_ATTRIBUTES, 0, 0}, + {"printer-attribute-group", DTAG_PRINTER_ATTRIBUTES, 0, 0}, + {"unsupported-attribute-group", DTAG_UNSUPPORTED_ATTRIBUTES, 0, 0}, + {"subscription-attribute-group", DTAG_SUBSCRIPTION_ATTRIBUTES, 0, 0}, + {"even-notificaton-attribute-group", + DTAG_EVENT_NOTIFICATION_ATTRIBUTES, 0, 0}, + {"attributes-charset", VTAG_CHARSET, 0, 255}, + {"attributes-natural-language", VTAG_NATURAL_LANGUAGE, 0, 255}, + {"charset-configured", VTAG_CHARSET, 0, 255}, + {"charset-supported", VTAG_CHARSET, 0, 255}, + {"color-supported", VTAG_BOOLEAN, 0, 1}, + {"compression", VTAG_KEYWORD, 1, 255}, + {"compression-supported", VTAG_KEYWORD, 1, 255}, + {"copies", VTAG_INTEGER, 1, MAXINT}, + {"copies-default", VTAG_INTEGER, 1, MAXINT}, + {"copies-supported", VTAG_RANGE_OF_INTEGER, 1, MAXINT}, + {"date-at-completed", VTAG_DATE_TIME, 0, 0}, + {"date-at-creation", VTAG_DATE_TIME, 0, 0}, + {"date-at-processing", VTAG_DATE_TIME, 0, 0}, + {"detailed-status-message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023}, + {"document-access-error", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023}, + {"document-format", VTAG_MIME_MEDIA_TYPE, 0, 255}, + {"document-format-default", VTAG_MIME_MEDIA_TYPE, 0, 255}, + {"document-format-supported", VTAG_MIME_MEDIA_TYPE, 0, 255}, + {"document-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"document-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"document-natural-language", VTAG_NATURAL_LANGUAGE, 0, 255}, + {"finishing", VTAG_ENUM, 3, 31}, + {"finishing-default", VTAG_ENUM, 3, 31}, + {"finishing-supported", VTAG_ENUM, 3, 31}, + {"generated-natural-language-supported", VTAG_NATURAL_LANGUAGE, 0, 255}, + {"ipp-attribute-fidelity", VTAG_BOOLEAN, 0, 1}, + {"ipp-versions-supported", VTAG_KEYWORD, 1, 255}, + {"job-detailed-status-messages", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023}, + {"job-document-access-errors", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023}, + {"job-hold-until", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"job-hold-until-default", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"job-hold-until-supported", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"job-id", VTAG_INTEGER, 1, MAXINT}, + {"job-impressions", VTAG_INTEGER, 0, MAXINT}, + {"job-impressions-completed", VTAG_INTEGER, 0, MAXINT}, + {"job-impressions-supported", VTAG_RANGE_OF_INTEGER, 0, MAXINT}, + {"job-k-octets", VTAG_INTEGER, 0, MAXINT}, + {"job-k-octets-processed", VTAG_INTEGER, 0, MAXINT}, + {"job-k-octets-supported", VTAG_RANGE_OF_INTEGER, 0, MAXINT}, + {"job-media-sheets", VTAG_INTEGER, 0, MAXINT}, + {"job-media-sheets-completed", VTAG_INTEGER, 0, MAXINT}, + {"job-media-sheets-supported", VTAG_RANGE_OF_INTEGER, 0, MAXINT}, + {"job-message-from-operator", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127}, + {"job-more-info", VTAG_URI, 0, 1023}, + {"job-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"job-originating-user-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"job-printer-up-time", VTAG_INTEGER, 1, MAXINT}, + {"job-printer-uri", VTAG_URI, 0, 1023}, + {"job-priority", VTAG_INTEGER, 1, 100}, + {"job-priority-default", VTAG_INTEGER, 1, 100}, + {"job-priority-supported", VTAG_INTEGER, 1, 100}, + {"job-sheets", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"job-sheets-default", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"job-sheets-supported", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"job-state", VTAG_ENUM, 3, 9}, + {"job-state-message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023}, + {"job-state-reasons", VTAG_KEYWORD, 1, 255}, + {"job-uri", VTAG_URI, 0, 1023}, + {"last-document", VTAG_BOOLEAN, 0, 1}, + {"limit", VTAG_INTEGER, 1, MAXINT}, + {"media", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"media-default", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"media-supported", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127}, + {"multiple-document-handling", VTAG_KEYWORD, 1, 255}, + {"multiple-document-handling-default", VTAG_KEYWORD, 1, 255}, + {"multiple-document-handling-supported", VTAG_KEYWORD, 1, 255}, + {"multiple-document-jobs-supported", VTAG_BOOLEAN, 0, 1}, + {"multiple-operation-time-out", VTAG_INTEGER, 1, MAXINT}, + {"my-jobs", VTAG_BOOLEAN, 0, 1}, + {"natural-language-configured", VTAG_NATURAL_LANGUAGE, 0, 255}, + {"number-of-documents", VTAG_INTEGER, 0, MAXINT}, + {"number-of-intervening-jobs", VTAG_INTEGER, 0, MAXINT}, + {"number-up", VTAG_INTEGER, 1, MAXINT}, + {"number-up-default", VTAG_INTEGER, 1, MAXINT}, + {"number-up-supported", VTAG_INTEGER, 1, MAXINT}, + {"operations-supported", VTAG_ENUM, 1, 0x8FFF}, + {"orientation-requested", VTAG_ENUM, 3, 6}, + {"orientation-requested-default", VTAG_ENUM, 3, 6}, + {"orientation-requested-supported", VTAG_ENUM, 3, 6}, + {"output-device-assigned", VTAG_NAME_WITHOUT_LANGUAGE, 0, 127}, + {"page-ranges", VTAG_RANGE_OF_INTEGER, 1, MAXINT}, + {"page-ranges-supported", VTAG_BOOLEAN, 0, 1}, + {"pages-per-minute", VTAG_INTEGER, 0, MAXINT}, + {"pages-per-minute-color", VTAG_INTEGER, 0, MAXINT}, + {"pdl-override-supported", VTAG_KEYWORD, 1, 255}, + {"print-quality", VTAG_ENUM, 3, 5}, + {"print-quality-default", VTAG_ENUM, 3, 5}, + {"print-quality-supported", VTAG_ENUM, 3, 5}, + {"printer-current-time", VTAG_DATE_TIME, 0, 1}, + {"printer-driver-installer", VTAG_URI, 0, 1023}, + {"printer-id", VTAG_INTEGER, 1, MAXINT}, + {"printer-info", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127}, + {"printer-is-accepting-jobs", VTAG_BOOLEAN, 0, 1}, + {"printer-location", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127}, + {"printer-make-and-model", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127}, + {"printer-message-from-operator", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127}, + {"printer-more-info", VTAG_URI, 0, 1023}, + {"printer-more-info-manufacturer", VTAG_URI, 0, 1023}, + {"printer-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 127}, + {"printer-resolution", VTAG_RESOLUTION, 0, 0}, + {"printer-resolution-default", VTAG_RESOLUTION, 0, 0}, + {"printer-resolution-supported", VTAG_RESOLUTION, 0, 0}, + {"printer-state", VTAG_ENUM, 3, 5}, + {"printer-state-message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023}, + {"printer-state-reasons", VTAG_KEYWORD, 1, 255}, + {"printer-up-time", VTAG_INTEGER, 1, MAXINT}, + {"printer-uri", VTAG_URI, 0, 1023}, + {"printer-uri-supported", VTAG_URI, 0, 1023}, + {"queued-job-count", VTAG_INTEGER, 0, MAXINT}, + {"reference-uri-schemes-supported", VTAG_URI_SCHEME, 0, 63}, + {"requested-attributes", VTAG_KEYWORD, 1, 255}, + {"requesting-user-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, + {"sides", VTAG_KEYWORD, 1, 255}, + {"sides-default", VTAG_KEYWORD, 1, 255}, + {"sides-supported", VTAG_KEYWORD, 1, 255}, + {"status-code", VTAG_ENUM, 1, 0x7FFF}, + {"status-message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 255}, + {"time-at-completed", VTAG_INTEGER, MININT, MAXINT}, + {"time-at-creation", VTAG_INTEGER, MININT, MAXINT}, + {"time-at-processing", VTAG_INTEGER, MININT, MAXINT}, + {"uri-authentication-supported", VTAG_KEYWORD, 1, 255}, + {"uri-security-supported", VTAG_KEYWORD, 1, 255}, + {"which-jobs", VTAG_KEYWORD, 1, 255}, + {NULL, 0, 0, 0} +}; + + +static attr_info_list_t * +get_attr_info_by_name(char *name) +{ + if (name != NULL) { + int i; + + for (i = 0; attr_list[i].name != NULL; i++) + if (strcasecmp(attr_list[i].name, name) == 0) + return (&attr_list[i]); + } + + return (NULL); +} + +size_t +max_val_len(int8_t type, char *name) +{ + attr_info_list_t *t; + int result; + + switch (type) { + case VTAG_INTEGER: + case VTAG_RANGE_OF_INTEGER: + case VTAG_ENUM: + result = MAXINT; + break; + case VTAG_URI: + case VTAG_OCTET_STRING: + case VTAG_TEXT_WITHOUT_LANGUAGE: + result = 1023; + break; + case VTAG_NATURAL_LANGUAGE: + case VTAG_URI_SCHEME: + case VTAG_CHARSET: + result = 63; + break; + case VTAG_NAME_WITHOUT_LANGUAGE: + case VTAG_MIME_MEDIA_TYPE: + case VTAG_KEYWORD: + result = 255; + break; + default: + result = MAXINT; + } + +#define min(a, b) ((a < b) ? a : b) + if ((t = get_attr_info_by_name(name)) != NULL) + result = min(t->max, result); +#undef min + + return (result); +} + +size_t +min_val_len(int8_t type, char *name) +{ + attr_info_list_t *t; + int result; + + switch (type) { + case VTAG_INTEGER: + case VTAG_RANGE_OF_INTEGER: + result = MININT; + break; + case VTAG_ENUM: + result = 1; + break; + case VTAG_URI: + case VTAG_OCTET_STRING: + case VTAG_TEXT_WITHOUT_LANGUAGE: + case VTAG_MIME_MEDIA_TYPE: + case VTAG_NAME_WITHOUT_LANGUAGE: + case VTAG_URI_SCHEME: + case VTAG_CHARSET: + case VTAG_NATURAL_LANGUAGE: + result = 0; + break; + case VTAG_KEYWORD: + result = 1; + break; + default: + result = MININT; + } + +#define max(a, b) ((a > b) ? a : b) + if ((t = get_attr_info_by_name(name)) != NULL) + result = max(t->min, result); +#undef max + + return (result); +} + +int +is_keyword(char *k) +{ + /* [a-z][a-z0-9._-]* */ + if (*k < 'a' && *k > 'z') + return (0); + while (*(++k) != '\0') + if (*k < 'a' && *k > 'z' && *k < '0' && *k > '9' && + *k != '.' && *k != '_' && *k != '-') + return (0); + return (1); +} + +int8_t +name_to_ipp_type(char *name) +{ + int i; + + if (name != NULL) + for (i = 0; attr_list[i].name != NULL; i++) + if (strcasecmp(attr_list[i].name, name) == 0) + return (attr_list[i].ipp_type); + + return (0); +} diff --git a/usr/src/lib/print/libipp-core/common/mapfile b/usr/src/lib/print/libipp-core/common/mapfile new file mode 100644 index 0000000000..7911a40932 --- /dev/null +++ b/usr/src/lib/print/libipp-core/common/mapfile @@ -0,0 +1,48 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# $Id: mapfile 151 2006-04-25 16:55:34Z njacobs $ + +# ident "%Z%%M% %I% %E% SMI" +# + + +# +# Common interfaces that are most likely to be shared amongst the various +# PAPI implementations. +# + +SUNWprivate_1.0 { + global: + ipp_read_message ; + ipp_write_message ; + ipp_validate_request ; + ipp_set_status ; + + local: + * ; +} ; diff --git a/usr/src/lib/print/libipp-core/common/read.c b/usr/src/lib/print/libipp-core/common/read.c new file mode 100644 index 0000000000..8bfca1e15b --- /dev/null +++ b/usr/src/lib/print/libipp-core/common/read.c @@ -0,0 +1,666 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: read.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <alloca.h> +#include <string.h> +#include <stdarg.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <inttypes.h> + +#include <papi.h> +#include <ipp.h> + + +#define _ipp_tag_string(id) ipp_tag_string((id), buf, sizeof (buf)) + +static papi_status_t +read_name_with_language(ipp_reader_t iread, void *fd, + papi_attribute_t ***message) +{ + char *string; + uint16_t size; + + /* read the language */ + if (iread(fd, &size, 2) != 2) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "read failed: lang len\n"); + return (PAPI_BAD_REQUEST); + } + size = (uint16_t)ntohs(size); + + if ((string = alloca(size + 1)) == NULL) { + ipp_set_status(message, PAPI_TEMPORARY_ERROR, + "Memory allocation failed"); + return (PAPI_TEMPORARY_ERROR); + } + if (iread(fd, string, size) != size) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "read failed: lang\n"); + return (PAPI_BAD_REQUEST); + } + + /* read the text */ + if (iread(fd, &size, 2) != 2) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "read failed: text len\n"); + return (PAPI_BAD_REQUEST); + } + size = (uint16_t)ntohs(size); + + if ((string = alloca(size + 1)) == NULL) { + ipp_set_status(message, PAPI_TEMPORARY_ERROR, + "Memory allocation failed"); + return (PAPI_TEMPORARY_ERROR); + } + if (iread(fd, string, size) != size) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "read failed: text\n"); + return (PAPI_BAD_REQUEST); + } + + return (PAPI_OK); +} + + +static struct { + int8_t ipp_type; + int8_t size; +} type_info[] = { + { VTAG_INTEGER, 4 }, + { VTAG_ENUM, 4 }, + { VTAG_BOOLEAN, 1 }, + { VTAG_RANGE_OF_INTEGER, 8 }, + { VTAG_RESOLUTION, 9 }, + { VTAG_DATE_TIME, 11 }, + { DTAG_MIN, 0 } +}; + +/* verify that the IPP type and size are compatible */ +static int +validate_length(int8_t type, int8_t size) +{ + int i; + + for (i = 0; type_info[i].ipp_type != DTAG_MIN; i++) + if (type_info[i].ipp_type == type) + return ((type_info[i].size == size) ? 0 : -1); + return (0); +} + +/* convert tyep IPP type to a type that is marginally compatible */ +static int8_t +base_type(int8_t i) +{ + switch (i) { + case VTAG_ENUM: + case VTAG_INTEGER: + return (VTAG_INTEGER); + case VTAG_URI: + case VTAG_OCTET_STRING: + case VTAG_TEXT_WITHOUT_LANGUAGE: + case VTAG_URI_SCHEME: + case VTAG_CHARSET: + case VTAG_NATURAL_LANGUAGE: + case VTAG_MIME_MEDIA_TYPE: + case VTAG_NAME_WITHOUT_LANGUAGE: + case VTAG_KEYWORD: + return (VTAG_TEXT_WITHOUT_LANGUAGE); + case VTAG_BOOLEAN: + case VTAG_RANGE_OF_INTEGER: + case VTAG_DATE_TIME: + case VTAG_RESOLUTION: + default: + return (i); + } +} + +/* verify that the IPP type is correct for the named attribute */ +static papi_status_t +validate_type(char *name, int8_t type) +{ + int8_t t = name_to_ipp_type(name); + + if (t == 0) /* The attribute is not defined in the RFC */ + return (PAPI_NOT_FOUND); + else if (t == type) /* The supplied type matched the RFC type */ + return (PAPI_OK); + else { /* The supplied type doesn't match the RFC */ + if (base_type(t) == base_type(type)) + return (PAPI_OK); + + return (PAPI_CONFLICT); + } +} + +/* verify that the IPP value is within specification for the named attribute */ +static int +validate_value(papi_attribute_t ***message, char *name, int8_t type, ...) +{ +#define within(a, b, c) ((b >= a) && (b <= c)) + va_list ap; + int rc = -1; + int min = min_val_len(type, name), + max = max_val_len(type, name); + char buf[64]; /* For _ipp_<...>_string() */ + + va_start(ap, type); + switch (type) { + case VTAG_ENUM: + case VTAG_INTEGER: { + int32_t i = (int32_t)va_arg(ap, int32_t); + + if (within(min, i, max)) + rc = 0; + else + ipp_set_status(message, PAPI_BAD_ARGUMENT, + "%s(%s): %d: out of range (%d - %d)", name, + _ipp_tag_string(type), i, min, max); + } + break; + case VTAG_BOOLEAN: { + int8_t v = (int8_t)va_arg(ap, int); + + if (within(0, v, 1)) + rc = 0; + else + ipp_set_status(message, PAPI_BAD_ARGUMENT, + "%s(%s): %d: out of range (0 - 1)", name, + _ipp_tag_string(type), v); + } + break; + case VTAG_RANGE_OF_INTEGER: { + int32_t lower = (int32_t)va_arg(ap, int32_t); + int32_t upper = (int32_t)va_arg(ap, int32_t); + + if (within(min, lower, max) && + within(min, upper, max)) + rc = 0; + else + ipp_set_status(message, PAPI_BAD_ARGUMENT, + "%s(%s): %d - %d: out of range (%d - %d)", name, + _ipp_tag_string(type), lower, upper, min, max); + } + break; + case VTAG_URI: + case VTAG_OCTET_STRING: + case VTAG_TEXT_WITHOUT_LANGUAGE: + case VTAG_URI_SCHEME: + case VTAG_CHARSET: + case VTAG_NATURAL_LANGUAGE: + case VTAG_MIME_MEDIA_TYPE: + case VTAG_NAME_WITHOUT_LANGUAGE: { + char *v = (char *)va_arg(ap, char *); + + if (strlen(v) < max) + rc = 0; + else + ipp_set_status(message, PAPI_BAD_ARGUMENT, + "%s(%s): %s: too long (max length: %d)", name, + _ipp_tag_string(type), v, max); + } + break; + case VTAG_KEYWORD: { + char *v = (char *)va_arg(ap, char *); + + if (strlen(v) >= max) + ipp_set_status(message, PAPI_BAD_ARGUMENT, + "%s(%s): %s: too long (max length: %d)", name, + _ipp_tag_string(type), v, max); + else if (is_keyword(v) == 0) + ipp_set_status(message, PAPI_BAD_ARGUMENT, + "%s(%s): %s: invalid keyword", name, + _ipp_tag_string(type), v); + else + rc = 0; + } + break; + case VTAG_DATE_TIME: + case VTAG_RESOLUTION: + default: + rc = 0; + } + va_end(ap); + + return (rc); +#undef within +} + +/* + * read_attr_group() reads in enough of the message data to parse an entire + * attribute group. Since to determine that the group is finished you have to + * read the character that determines the type of the next group, this function + * must return that character, in order that our caller knows how to call us for + * the next group. Thus type is used both as an input parameter (the type of + * attribute group to read in) and an output parameter (the type of the next + * attribute group). + */ + +static papi_status_t +ipp_read_attribute_group(ipp_reader_t iread, void *fd, int8_t *type, + papi_attribute_t ***message) +{ + int8_t value_tag; + uint16_t name_length, value_length; + papi_attribute_t **attributes = NULL; + char *name = NULL; + int i; + char buf[64]; /* For _ipp_<...>_string() */ + + /* + * RFC2910 3.3 says we need to handle `An expected but missing + * "begin-attribute-group-tag" field. How? + */ + if (*type > DTAG_MAX) { + /* Scream bloody murder, or assign a new type? */ + ipp_set_status(message, PAPI_BAD_REQUEST, + "Bad attribute group tag 0x%.2hx (%s)", + *type, _ipp_tag_string(*type)); + return (PAPI_BAD_REQUEST); + } + + /* This loops through *values* not *attributes*! */ + for (i = 0; ; i++) { + papi_status_t valid = PAPI_OK; + if (iread(fd, &value_tag, 1) != 1) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: value tag\n"); + return (PAPI_BAD_REQUEST); + } + /* are we done with this group ? */ + if (value_tag <= DTAG_MAX) + break; + + if (iread(fd, &name_length, 2) != 2) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: name length\n"); + return (PAPI_BAD_REQUEST); + } + name_length = (uint16_t)ntohs(name_length); + + /* Not just another value for the previous attribute */ + if (name_length != 0) { + if ((name = alloca(name_length + 1)) == NULL) { + ipp_set_status(message, PAPI_TEMPORARY_ERROR, + "alloca(): failed\n"); + return (PAPI_TEMPORARY_ERROR); + } + (void) memset(name, 0, name_length + 1); + + if (iread(fd, name, name_length) != name_length) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: name\n"); + return (PAPI_BAD_REQUEST); + } + } + + valid = validate_type(name, value_tag); + if ((valid != PAPI_OK) && (valid != PAPI_NOT_FOUND)) + ipp_set_status(message, valid, "%s(%s): %s", name, + _ipp_tag_string(value_tag), + papiStatusString(valid)); + + if (iread(fd, &value_length, 2) != 2) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: value length\n"); + return (PAPI_BAD_REQUEST); + } + value_length = (uint16_t)ntohs(value_length); + + if (validate_length(value_tag, value_length) < 0) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "Bad value length (%d) for type %s", + value_length, _ipp_tag_string(value_tag)); + return (PAPI_BAD_REQUEST); + } + + switch (value_tag) { + case VTAG_INTEGER: + case VTAG_ENUM: { + int32_t v; + + if (iread(fd, &v, value_length) != value_length) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: int/enum\n"); + return (PAPI_BAD_REQUEST); + } + v = (int32_t)ntohl(v); + (void) validate_value(message, name, value_tag, v); + papiAttributeListAddInteger(&attributes, + PAPI_ATTR_APPEND, name, v); + + } + break; + case VTAG_BOOLEAN: { + int8_t v; + + if (iread(fd, &v, value_length) != value_length) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: boolean\n"); + return (PAPI_BAD_REQUEST); + } + (void) validate_value(message, name, value_tag, v); + papiAttributeListAddBoolean(&attributes, + PAPI_ATTR_APPEND, name, v); + } + break; + case VTAG_RANGE_OF_INTEGER: { + int32_t min, max; + + if (iread(fd, &min, 4) != 4) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: min\n"); + return (PAPI_BAD_REQUEST); + } + if (iread(fd, &max, 4) != 4) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: max\n"); + return (PAPI_BAD_REQUEST); + } + min = (int32_t)ntohl(min); + max = (int32_t)ntohl(max); + (void) validate_value(message, name, value_tag, + min, max); + papiAttributeListAddRange(&attributes, PAPI_ATTR_APPEND, + name, min, max); + } + break; + case VTAG_RESOLUTION: { + int32_t x, y; + int8_t units; + + if (iread(fd, &x, 4) != 4) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: x\n"); + return (PAPI_BAD_REQUEST); + } + if (iread(fd, &y, 4) != 4) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: y\n"); + return (PAPI_BAD_REQUEST); + } + if (iread(fd, &units, 1) != 1) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: units\n"); + return (PAPI_BAD_REQUEST); + } + x = (int32_t)ntohl(x); + y = (int32_t)ntohl(y); + papiAttributeListAddResolution(&attributes, + PAPI_ATTR_APPEND, name, x, y, + (papi_resolution_unit_t)units); + } + break; + case VTAG_DATE_TIME: { + struct tm tm; + time_t v; + int8_t c; + uint16_t s; + + (void) memset(&tm, 0, sizeof (tm)); + if (iread(fd, &s, 2) != 2) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: year\n"); + return (PAPI_BAD_REQUEST); + } + tm.tm_year = (uint16_t)ntohs(s) - 1900; + if (iread(fd, &c, 1) != 1) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: month\n"); + return (PAPI_BAD_REQUEST); + } + tm.tm_mon = c - 1; + if (iread(fd, &c, 1) != 1) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: day\n"); + return (PAPI_BAD_REQUEST); + } + tm.tm_mday = c; + if (iread(fd, &c, 1) != 1) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: hour\n"); + return (PAPI_BAD_REQUEST); + } + tm.tm_hour = c; + if (iread(fd, &c, 1) != 1) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: minutes\n"); + return (PAPI_BAD_REQUEST); + } + tm.tm_min = c; + if (iread(fd, &c, 1) != 1) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: seconds\n"); + return (PAPI_BAD_REQUEST); + } + tm.tm_sec = c; + if (iread(fd, &c, 1) != 1) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: decisec\n"); + return (PAPI_BAD_REQUEST); + } + /* tm.deciseconds = c; */ + if (iread(fd, &c, 1) != 1) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: utc_dir\n"); + return (PAPI_BAD_REQUEST); + } + /* tm.utc_dir = c; */ + if (iread(fd, &c, 1) != 1) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: utc_hour\n"); + return (PAPI_BAD_REQUEST); + } + /* tm.utc_hours = c; */ + if (iread(fd, &c, 1) != 1) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: utc_min\n"); + return (PAPI_BAD_REQUEST); + } + /* tm.utc_minutes = c; */ + + v = mktime(&tm); + + (void) validate_value(message, name, value_tag, v); + papiAttributeListAddDatetime(&attributes, + PAPI_ATTR_APPEND, name, v); + } + break; + case VTAG_NAME_WITH_LANGUAGE: + case VTAG_TEXT_WITH_LANGUAGE: + /* + * we are dropping this because we don't support + * name with language at this time. + */ + (void) read_name_with_language(iread, fd, message); + break; + case VTAG_NAME_WITHOUT_LANGUAGE: + case VTAG_TEXT_WITHOUT_LANGUAGE: + case VTAG_URI: + case VTAG_KEYWORD: + case VTAG_CHARSET: { + char *v; + + if ((v = calloc(1, value_length + 1)) == NULL) { + ipp_set_status(message, PAPI_TEMPORARY_ERROR, + "calloc(): failed\n"); + return (PAPI_TEMPORARY_ERROR); + } +#ifdef NOTDEF + if (iread(fd, v, value_length) != value_length) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: stringy\n"); + return (PAPI_BAD_REQUEST); + } +#else + { + int rc, i = value_length; + char *p = v; + + while ((rc = iread(fd, p, i)) != i) { + if (rc <= 0) { + ipp_set_status(message, + PAPI_BAD_REQUEST, + "bad read: stringy\n"); + return (PAPI_BAD_REQUEST); + } + i -= rc; + p += rc; + } + } +#endif + (void) validate_value(message, name, value_tag, v); + papiAttributeListAddString(&attributes, + PAPI_ATTR_APPEND, name, v); + } + break; + case VTAG_UNKNOWN: + case VTAG_NOVALUE: + case VTAG_UNSUPPORTED: + papiAttributeListAddValue(&attributes, PAPI_ATTR_EXCL, + name, PAPI_COLLECTION, NULL); + break; + default: { + char *v; + + if ((v = calloc(1, value_length + 1)) == NULL) { + ipp_set_status(message, PAPI_TEMPORARY_ERROR, + "calloc(): failed\n"); + return (PAPI_TEMPORARY_ERROR); + } + if (iread(fd, v, value_length) != value_length) { + ipp_set_status(message, PAPI_BAD_REQUEST, + "bad read: other\n"); + return (PAPI_BAD_REQUEST); + } + papiAttributeListAddString(&attributes, + PAPI_ATTR_APPEND, name, v); + } + break; + } + } + + if (attributes != NULL) { + char name[32]; + + (void) ipp_tag_string(*type, name, sizeof (name)); + papiAttributeListAddCollection(message, PAPI_ATTR_APPEND, name, + attributes); + } + + *type = value_tag; + + return (PAPI_OK); +} + + +static papi_status_t +ipp_read_header(ipp_reader_t iread, void *fd, papi_attribute_t ***message, + char type) +{ + char *attr_name = "status-code"; /* default to a response */ + char buf[8]; + int8_t c; + uint16_t s; + int32_t i; + + if ((iread == NULL) || (fd == NULL) || (message == NULL)) + return (PAPI_BAD_ARGUMENT); + + /* + * Apache 1.X uses the buffer supplied to it's read call to read in + * the chunk size when chunking is used. This causes problems + * reading the header a piece at a time, because we don't have + * enough room to read in the chunk size prior to reading the + * chunk. + */ + + if (iread(fd, buf, 8) != 8) + return (PAPI_BAD_REQUEST); + + c = buf[0]; + (void) papiAttributeListAddInteger(message, PAPI_ATTR_REPLACE, + "version-major", c); + + c = buf[1]; + (void) papiAttributeListAddInteger(message, PAPI_ATTR_REPLACE, + "version-minor", c); + + memcpy(&s, &buf[2], 2); + s = (uint16_t)ntohs(s); + if (type == IPP_TYPE_REQUEST) + attr_name = "operation-id"; + (void) papiAttributeListAddInteger(message, PAPI_ATTR_REPLACE, + attr_name, s); + + memcpy(&s, &buf[4], 4); + i = (uint32_t)ntohl(i); + (void) papiAttributeListAddInteger(message, PAPI_ATTR_REPLACE, + "request-id", i); + + return (PAPI_OK); +} + +static papi_status_t +ipp_read_attribute_groups(ipp_reader_t iread, void *fd, + papi_attribute_t ***message) +{ + papi_status_t result = PAPI_OK; + int8_t tag; + + /* start reading the attribute groups */ + if (iread(fd, &tag, 1) != 1) /* prime the pump */ + return (PAPI_BAD_REQUEST); + + while ((tag != DTAG_END_OF_ATTRIBUTES) && (result == PAPI_OK)) { + result = ipp_read_attribute_group(iread, fd, &tag, message); + } + + return (result); +} + +papi_status_t +ipp_read_message(ipp_reader_t iread, void *fd, papi_attribute_t ***message, + char type) +{ + papi_status_t result = PAPI_OK; + + if ((iread == NULL) || (fd == NULL) || (message == NULL)) + return (PAPI_BAD_ARGUMENT); + + result = ipp_read_header(iread, fd, message, type); + if (result == PAPI_OK) + result = ipp_read_attribute_groups(iread, fd, message); + + return (result); +} diff --git a/usr/src/lib/print/libipp-core/common/strings.c b/usr/src/lib/print/libipp-core/common/strings.c new file mode 100644 index 0000000000..b47449b8cc --- /dev/null +++ b/usr/src/lib/print/libipp-core/common/strings.c @@ -0,0 +1,411 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: strings.c 151 2006-04-25 16:55:34Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "ipp.h" + +static char *tag_strings[] = { + /* delimiter tags */ + "reserved-delimiter-00", + "operational-attributes-group", + "job-attributes-group", + "end-of-attributes-group", + "printer-attributes-group", + "unsupported-attributes-group", + "subscription-attributes-group", + "event-notification-attributes-group", + "reserved-delimiter-08", + "reserved-delimiter-09", + "reserved-delimiter-0a", + "reserved-delimiter-0b", + "reserved-delimiter-0c", + "reserved-delimiter-0d", + "reserved-delimiter-0e", + "reserved-delimiter-0f", + /* value tags */ + "unsupported", + "reserved-default", + "unknown", + "no-value", + "reserved-out-of-band-14", + "not-settable", + "delete-attribute", + "admin-define", + "reserved-out-of-band-18", + "reserved-out-of-band-19", + "reserved-out-of-band-1a", + "reserved-out-of-band-1b", + "reserved-out-of-band-1c", + "reserved-out-of-band-1d", + "reserved-out-of-band-1e", + "reserved-out-of-band-1f", + "reserved", + "integer", + "boolean", + "enum", + "reserved-integer-type-24", + "reserved-integer-type-25", + "reserved-integer-type-26", + "reserved-integer-type-27", + "reserved-integer-type-28", + "reserved-integer-type-29", + "reserved-integer-type-2a", + "reserved-integer-type-2b", + "reserved-integer-type-2c", + "reserved-integer-type-2d", + "reserved-integer-type-2e", + "reserved-integer-type-2f", + "octetString", + "dateTime", + "resolution", + "rangeOfInteger", + "begCollection", + "textWithLanguage", + "nameWithLanguage", + "endCollection", + "reserved-octetString-38", + "reserved-octetString-39", + "reserved-octetString-3a", + "reserved-octetString-3b", + "reserved-octetString-3c", + "reserved-octetString-3d", + "reserved-octetString-3e", + "reserved-octetString-3f", + "reserved", + "textWithoutLanguage", + "nameWithoutLanguage", + "reserved", + "keyword", + "uri", + "uriScheme", + "charset", + "naturalLanguage", + "mimeMediaType", + "memberAttrName", + "reserved-charString-4b", + "reserved-charString-4c", + "reserved-charString-4d", + "reserved-charString-4e", + "reserved-charString-4f", + "reserved-charString-50", + "reserved-charString-51", + "reserved-charString-52", + "reserved-charString-53", + "reserved-charString-54", + "reserved-charString-55", + "reserved-charString-56", + "reserved-charString-57", + "reserved-charString-58", + "reserved-charString-59", + "reserved-charString-5a", + "reserved-charString-5b", + "reserved-charString-5c", + "reserved-charString-5d", + "reserved-charString-5e", + "reserved-charString-5f", +}; + +static char *opid_strings[] = { + "reserved-0x0000", + "reserved-0x0001", + "Print-Job", + "Print-URI", + "Validate-Job", + "Create-Job", + "Send-Document", + "Send-URI", + "Cancel-Job", + "Get-Job-Attributes", + "Get-Jobs", + "Get-Printer-Attributes", + "Hold-Job", + "Release-Job", + "Restart-Job", + "reserved-0x000f", + "Pause-Printer", + "Resume-Printer", + "Purge-Jobs", + "Set-Printer-Attributes", + "Set-Job-Attributes", + "Get-Printer-Supported-Values", + "Create-Printer-Subscription", + "Create-Job-Subscription", + "Get-Subscription-Attributes", + "Get-Subscriptions", + "Renew-Subscription", + "Cancel-Subscription", + "Get-Notifications", + "Send-Notifications", + "Get-Resource-Attributes-deleted", + "Get-Resource-Data-deleted", + "Get-Resources-deleted", + "Get-Print-Support-Files", + "Disable-Printer", + "Pause-Printer-After-Current-Job", + "Hold-New-Jobs", + "Release-Held-New-Jobs", + "Deactivate-Printer", + "Activate-Printer", + "Restart-Printer", + "Shutdown-Printer", + "Startup-Printer", + "Reprocess-Job", + "Cancel-Current-Job", + "Suspend-Current-Job", + "Resume-Job", + "Promote-Job", + "Schedule-Job-After", + NULL +}; + +static char *res_opid_strings[] = { + "Microsoft-0x4000", + "CUPS-Get-Default", + "CUPS-Get-Printers", + "CUPS-Add-Printer", + "CUPS-Delete-Printer", + "CUPS-Get-Classes", + "CUPS-Add-Class", + "CUPS-Delete-Class", + "CUPS-Accept-Jobs", + "CUPS-Reject-Jobs", + "CUPS-Set-Default", + "CUPS-Get-Devices", + "CUPS-Get-PPDs", + "CUPS-Move-Job", + "CUPS-0x400e", + "CUPS-0x400f", + "Peerless-0x4010", + NULL +}; +#define KNOWN_RESERVED_MIN 0x4000 +#define KNOWN_RESERVED_MAX 0x4010 + +static char *ok_status_strings[] = { + "successful-ok", + "successful-ok-ignored-or-substituted-attributes", + "successful-ok-conflicting-attributes", + "successful-ok-ignored-subscriptions", + "successful-ok-ignored-notifications", + "successful-ok-too-many-events", + "successful-ok-but-cancel-subscription" +}; + +static char *redir_status_strings[] = { + "redirection-other-site" +}; + +static char *client_error_status_strings[] = { + "client-error-bad-request", + "client-error-forbidden", + "client-error-not-authenticated", + "client-error-not-authorized", + "client-error-not-possible", + "client-error-timeout", + "client-error-not-found", + "client-error-gone", + "client-error-request-entity-too-large", + "client-error-request-value-too-long", + "client-error-document-format-not-supported", + "client-error-attributes-or-values-not-supported", + "client-error-uri-scheme-not-supported", + "client-error-charset-not-supported", + "client-error-conflicting-attributes", + "client-error-compression-not-supported", + "client-error-compression-error", + "client-error-document-format-error", + "client-error-document-access-error", + "client-error-attributes-not-settable", + "client-error-ignored-all-subscriptions", + "client-error-too-many-subscriptions", + "client-error-ignored-all-notifications", + "client-error-print-support-file-not-found" +}; + +static char *server_error_status_strings[] = { + "server-error-internal-error", + "server-error-operation-not-supported", + "server-error-service-unavailable", + "server-error-version-not-supported", + "server-error-device-error", + "server-error-temporary-error", + "server-error-not-accepting-jobs", + "server-error-busy", + "server-error-job-canceled", + "server-error-multiple-document-jobs-not-supported", + "server-error-printer-is-deactivated" +}; + +char * +ipp_tag_string(int8_t id, char *ret, size_t len) +{ + if (id < VTAG_MAX) + (void) strlcpy(ret, tag_strings[id], len); + else if (id == VTAG_EXTEND) + (void) strlcpy(ret, "extension", len); + else + (void) snprintf(ret, len, "bogus-0x%.2x", id); + + return (ret); +} + +char * +ipp_opid_string(int16_t id, char *ret, size_t len) +{ + if (id < OPID_RESERVED_MIN) + (void) strlcpy(ret, opid_strings[id], len); + else if (id < OPID_RESERVED_VENDOR_MIN) + (void) snprintf(ret, len, "reserved-0x%.4x", id); + else if (id <= KNOWN_RESERVED_MAX) + (void) strlcpy(ret, + res_opid_strings[id - KNOWN_RESERVED_MIN], len); + else /* if (id <= OPID_RESERVED_VENDOR_MAX) */ + (void) snprintf(ret, len, "reserved-vendor-0x%.4x", id); + + return (ret); +} + +int16_t +ipp_string_opid(char *string) +{ + int i; + + for (i = 0; opid_strings[i] != NULL; i++) + if (strcasecmp(opid_strings[i], string) == 0) + return (i); + + for (i = 0; res_opid_strings[i] != NULL; i++) + if (strcasecmp(res_opid_strings[i], string) == 0) + return (0x4000 + i); + + return (-1); +} + +char * +ipp_status_string(int16_t id, char *ret, size_t len) +{ + if (id <= IPP_OK_MAX) + (void) strlcpy(ret, ok_status_strings[id], len); + else if (id >= IPP_REDIR_MIN && id <= IPP_REDIR_MAX) + (void) strlcpy(ret, + redir_status_strings[id - IPP_REDIR_MIN], len); + else if (id >= IPP_CERR_MIN && id <= IPP_CERR_MAX) + (void) strlcpy(ret, + client_error_status_strings[id - IPP_CERR_MIN], len); + else if (id >= IPP_SERR_MIN && id <= IPP_SERR_MAX) + (void) strlcpy(ret, + server_error_status_strings[id - IPP_SERR_MIN], len); + else + (void) snprintf(ret, len, "bogus-0x%.4hx", id); + + return (ret); +} + + + +/* + * attribute template handling routines + */ +char *job_template[] = { + "copies", + "finishing", + "job-hold-until", + "job-priority", + "job-sheets", + "media", + "multiple-document-handling", + "number-up", + "page-ranges-supported", + "print-quality", + "printer-resoultion", + "sides", + NULL +}; + +char *job_description[] = { + "copies-default", "copies-supported", + "finishing-default", "finishing-supported", + "job-hold-until-default", "job-hold-until-supported", + "job-priority-default", "job-priority-supported", + "job-sheets-default", "job-sheets-supported", + "media-default", "media-supported", + "multiple-document-handling-default", + "multiple-document-handling-supported", + "number-up-default", "number-up-supported", + "page-ranges-supported", + "print-quality-default", "print-quality-supported", + "printer-resoultion-default", "printer-resoultion-supported", + "sides-default", "sides-supported", + NULL +}; + +char *printer_description[] = { + "printer-uri-supported", + "uri-security-supported", + "uri-authentication-supported", + "printer-name", + "printer-location", + "printer-info", + "printer-more-info", + "printer-driver-installer", + "printer-make-and-model", + "printer-more-info-manufacturer", + "printer-state", + "printer-state-reasons", + "printer-state-message", + "ipp-versions-supported", + "multiple-document-jobs-supported", + "charset-configured", + "charset-supported", + "natural-language-configured", + "generated-natural-language-supported", + "document-format-default", + "document-format-supported", + "printer-is-accepting-jobs", + "queued-job-count", + "printer-message-from-operator", + "color-supported", + "reference-uri-schemes-supported", + "pdl-override-supported", + "printer-up-time", + "printer-current-time", + "multiple-operation-time-out", + "compression-supported", + "job-k-octets-supported", + "job-impressions-supported", + "job-media-sheets-supported", + "pages-per-minute", + "pages-per-minute-color", + NULL +}; diff --git a/usr/src/lib/print/libipp-core/common/write.c b/usr/src/lib/print/libipp-core/common/write.c new file mode 100644 index 0000000000..aef693a365 --- /dev/null +++ b/usr/src/lib/print/libipp-core/common/write.c @@ -0,0 +1,415 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: write.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <inttypes.h> + +#include <papi.h> +#include <ipp.h> + +static int8_t +papi_attribute_to_ipp_type(papi_attribute_value_type_t type) +{ + switch (type) { + case PAPI_INTEGER: + return (VTAG_INTEGER); + case PAPI_BOOLEAN: + return (VTAG_BOOLEAN); + case PAPI_RANGE: + return (VTAG_RANGE_OF_INTEGER); + case PAPI_RESOLUTION: + return (VTAG_RESOLUTION); + case PAPI_DATETIME: + return (VTAG_DATE_TIME); + case PAPI_STRING: + return (VTAG_TEXT_WITHOUT_LANGUAGE); + } + + return (0); +} + +static papi_status_t +papi_ipp_type_match(papi_attribute_value_type_t papi, int8_t ipp) +{ + switch (papi) { + case PAPI_STRING: + switch (ipp) { + case VTAG_URI: + case VTAG_OCTET_STRING: + case VTAG_TEXT_WITHOUT_LANGUAGE: + case VTAG_URI_SCHEME: + case VTAG_CHARSET: + case VTAG_NATURAL_LANGUAGE: + case VTAG_MIME_MEDIA_TYPE: + case VTAG_NAME_WITHOUT_LANGUAGE: + case VTAG_KEYWORD: + break; + default: + return (PAPI_CONFLICT); + } + break; + case PAPI_INTEGER: + switch (ipp) { + case VTAG_ENUM: + case VTAG_INTEGER: + break; + default: + return (PAPI_CONFLICT); + } + break; + case PAPI_BOOLEAN: + if (ipp != VTAG_BOOLEAN) + return (PAPI_CONFLICT); + break; + case PAPI_RANGE: + if (ipp != VTAG_RANGE_OF_INTEGER) + return (PAPI_CONFLICT); + break; + case PAPI_RESOLUTION: + if (ipp != VTAG_RESOLUTION) + return (PAPI_CONFLICT); + break; + case PAPI_DATETIME: + if (ipp != VTAG_DATE_TIME) + return (PAPI_CONFLICT); + break; + case PAPI_COLLECTION: + /* don't need to match */ + break; + } + + return (PAPI_OK); +} + +static papi_status_t +ipp_write_attribute(ipp_writer_t iwrite, void *fd, papi_attribute_t *attribute) +{ + papi_status_t status; + papi_attribute_value_t **values; + int8_t type; + int i; + char *name; + + name = attribute->name; + values = attribute->values; + + if ((type = name_to_ipp_type(name)) == 0) + type = papi_attribute_to_ipp_type(attribute->type); + + /* The types don't match, so don't send the attribute */ + if ((status = papi_ipp_type_match(attribute->type, type)) != PAPI_OK) + return (status); + + if (values == NULL) { + uint16_t length; + + type = VTAG_UNSUPPORTED; + if (iwrite(fd, &type, 1) != 1) + return (PAPI_DEVICE_ERROR); + + if (name != NULL) { /* first value gets named */ + length = (uint16_t)htons(strlen(name)); + + if (iwrite(fd, &length, 2) != 2) + return (PAPI_DEVICE_ERROR); + if (iwrite(fd, name, strlen(name)) != strlen(name)) + return (PAPI_DEVICE_ERROR); + } + + length = (uint16_t)htons(0); + if (iwrite(fd, &length, 2) != 2) + return (PAPI_DEVICE_ERROR); + + return (PAPI_OK); + } + + + + for (i = 0; values[i] != NULL; i++) { + papi_attribute_value_t *value = values[i]; + uint16_t length = 0; + + if (iwrite(fd, &type, 1) != 1) + return (PAPI_DEVICE_ERROR); + + if (name != NULL) { /* first value gets named */ + length = (uint16_t)htons(strlen(name)); + + if (iwrite(fd, &length, 2) != 2) + return (PAPI_DEVICE_ERROR); + if (iwrite(fd, name, strlen(name)) != strlen(name)) + return (PAPI_DEVICE_ERROR); + name = NULL; + } else { + length = (uint16_t)htons(0); + + if (iwrite(fd, &length, 2) != 2) + return (PAPI_DEVICE_ERROR); + } + + switch (attribute->type) { + case PAPI_STRING: { + char *v = (char *)value->string; + + if (v != NULL) { + size_t str_length = strlen(v); + + /* + * if the length is more than 16 bits can + * express, send what can be represented + * in 16 bits. IPP "strings" can only be + * that large. + */ + if (str_length > 0xFFFF) + str_length = 0xFFFF; + + length = (uint16_t)htons(str_length); + if (iwrite(fd, &length, 2) != 2) + return (PAPI_DEVICE_ERROR); + if (iwrite(fd, v, str_length) != str_length) + return (PAPI_DEVICE_ERROR); + } else + if (iwrite(fd, &length, 2) != 2) + return (PAPI_DEVICE_ERROR); + } + break; + case PAPI_BOOLEAN: { + int8_t v = (int8_t)value->boolean; + + length = (uint16_t)htons(1); + if (iwrite(fd, &length, 2) != 2) + return (PAPI_DEVICE_ERROR); + if (iwrite(fd, &v, 1) != 1) + return (PAPI_DEVICE_ERROR); + } + break; + case PAPI_INTEGER: { + int32_t v = (int32_t)value->integer; + + length = (uint16_t)htons(4); + v = (int32_t)htonl(v); + if (iwrite(fd, &length, 2) != 2) + return (PAPI_DEVICE_ERROR); + if (iwrite(fd, &v, 4) != 4) + return (PAPI_DEVICE_ERROR); + } + break; + case PAPI_RANGE: { + int32_t min = (int32_t)htonl((int)(value->range).lower), + max = (int32_t)htonl((int)(value->range).upper); + + length = (uint16_t)htons(8); + if (iwrite(fd, &length, 2) != 2) + return (PAPI_DEVICE_ERROR); + if (iwrite(fd, &min, 4) != 4) + return (PAPI_DEVICE_ERROR); + if (iwrite(fd, &max, 4) != 4) + return (PAPI_DEVICE_ERROR); + } + break; + case PAPI_RESOLUTION: { + int32_t x = (int)(value->resolution).xres, + y = (int)(value->resolution).yres; + int8_t units = (int8_t)(value->resolution).units; + + length = (uint16_t)htons(9); + x = (int32_t)htonl(x); + y = (int32_t)htonl(y); + + if (iwrite(fd, &length, 2) != 2) + return (PAPI_DEVICE_ERROR); + if (iwrite(fd, &x, 4) != 4) + return (PAPI_DEVICE_ERROR); + if (iwrite(fd, &y, 4) != 4) + return (PAPI_DEVICE_ERROR); + if (iwrite(fd, &units, 1) != 1) + return (PAPI_DEVICE_ERROR); + } + break; + case PAPI_DATETIME: { + struct tm *v = gmtime(&value->datetime); + int8_t c; + uint16_t s; + + length = (uint16_t)htons(11); + if (iwrite(fd, &length, 2) != 2) + return (PAPI_DEVICE_ERROR); + s = (uint16_t)htons(v->tm_year + 1900); + if (iwrite(fd, &s, 2) != 2) + return (PAPI_DEVICE_ERROR); + c = v->tm_mon + 1; + if (iwrite(fd, &c, 1) != 1) + return (PAPI_DEVICE_ERROR); + c = v->tm_mday; + if (iwrite(fd, &c, 1) != 1) + return (PAPI_DEVICE_ERROR); + c = v->tm_hour; + if (iwrite(fd, &c, 1) != 1) + return (PAPI_DEVICE_ERROR); + c = v->tm_min; + if (iwrite(fd, &c, 1) != 1) + return (PAPI_DEVICE_ERROR); + c = v->tm_sec; + if (iwrite(fd, &c, 1) != 1) + return (PAPI_DEVICE_ERROR); + c = /* v->deciseconds */ 0; + if (iwrite(fd, &c, 1) != 1) + return (PAPI_DEVICE_ERROR); + c = /* v->utc_dir */ 0; + if (iwrite(fd, &c, 1) != 1) + return (PAPI_DEVICE_ERROR); + c = /* v->utc_hours */ 0; + if (iwrite(fd, &c, 1) != 1) + return (PAPI_DEVICE_ERROR); + c = /* v->utc_minutes */ 0; + if (iwrite(fd, &c, 1) != 1) + return (PAPI_DEVICE_ERROR); + } + break; + default: { + /* + * If there is a value, it is not one of our + * types, so we couldn't use it anyway. We assume + * that it was an OOB type with no value + */ + length = (uint16_t)htons(0); + if (iwrite(fd, &length, 2) != 2) + return (PAPI_DEVICE_ERROR); + } + break; + } + } + + return (PAPI_OK); +} + +static papi_status_t +ipp_write_attribute_group(ipp_writer_t iwrite, void *fd, int8_t type, + papi_attribute_t **attributes) +{ + papi_status_t result = PAPI_OK; + int i; + + /* write group tag */ + if (iwrite(fd, &type, 1) != 1) + return (PAPI_DEVICE_ERROR); + + /* write values */ + for (i = 0; ((attributes[i] != NULL) && (result == PAPI_OK)); i++) + result = ipp_write_attribute(iwrite, fd, attributes[i]); + + return (result); +} + +static papi_status_t +ipp_write_attribute_groups(ipp_writer_t iwrite, void *fd, + papi_attribute_t **groups) +{ + papi_status_t result = PAPI_OK; + int8_t c; + + for (c = DTAG_MIN; c <= DTAG_MAX; c++) { + papi_status_t status; + papi_attribute_t **group = NULL; + void *iter = NULL; + char name[32]; + + (void) ipp_tag_string(c, name, sizeof (name)); + for (status = papiAttributeListGetCollection(groups, &iter, + name, &group); + ((status == PAPI_OK) && (result == PAPI_OK)); + status = papiAttributeListGetCollection(groups, &iter, + NULL, &group)) + result = ipp_write_attribute_group(iwrite, fd, + c, group); + } + + c = DTAG_END_OF_ATTRIBUTES; + if (iwrite(fd, &c, 1) != 1) + result = PAPI_DEVICE_ERROR; + + return (result); +} + +static papi_status_t +ipp_write_message_header(ipp_writer_t iwrite, void *fd, + papi_attribute_t **message) +{ + int tmp; + int8_t c; + uint16_t s; + int32_t i; + + /* write the version */ + papiAttributeListGetInteger(message, NULL, "version-major", &tmp); + c = tmp; + if (iwrite(fd, &c, 1) != 1) + return (PAPI_DEVICE_ERROR); + + papiAttributeListGetInteger(message, NULL, "version-minor", &tmp); + c = tmp; + if (iwrite(fd, &c, 1) != 1) + return (PAPI_DEVICE_ERROR); + + /* write the request/status code */ + papiAttributeListGetInteger(message, NULL, "status-code", &tmp); + papiAttributeListGetInteger(message, NULL, "operation-id", &tmp); + s = (uint16_t)htons(tmp); + if (iwrite(fd, &s, 2) != 2) + return (PAPI_DEVICE_ERROR); + + /* write the request id */ + papiAttributeListGetInteger(message, NULL, "request-id", &tmp); + i = (uint32_t)htonl(tmp); + if (iwrite(fd, &i, 4) != 4) + return (PAPI_DEVICE_ERROR); + + return (PAPI_OK); +} + +papi_status_t +ipp_write_message(ipp_writer_t iwrite, void *fd, papi_attribute_t **message) +{ + papi_status_t result; + + if ((iwrite == NULL) || (fd == NULL) || (message == NULL)) + return (PAPI_BAD_ARGUMENT); + + result = ipp_write_message_header(iwrite, fd, message); + if (result == PAPI_OK) + result = ipp_write_attribute_groups(iwrite, fd, message); + + return (result); +} diff --git a/usr/src/lib/print/libipp-core/i386/Makefile b/usr/src/lib/print/libipp-core/i386/Makefile new file mode 100644 index 0000000000..3b985583a4 --- /dev/null +++ b/usr/src/lib/print/libipp-core/i386/Makefile @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT) diff --git a/usr/src/lib/print/libipp-core/sparc/Makefile b/usr/src/lib/print/libipp-core/sparc/Makefile new file mode 100644 index 0000000000..3b985583a4 --- /dev/null +++ b/usr/src/lib/print/libipp-core/sparc/Makefile @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT) diff --git a/usr/src/lib/print/libipp-listener/Makefile b/usr/src/lib/print/libipp-listener/Makefile new file mode 100644 index 0000000000..b92d620b10 --- /dev/null +++ b/usr/src/lib/print/libipp-listener/Makefile @@ -0,0 +1,56 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../../Makefile.lib + +#HDRS = papi.h +#HDRDIR = common +SUBDIRS = $(MACH) +#$(BUILD64)SUBDIRS += $(MACH64) + +all := TARGET = all +clean := TARGET = clean +clobber := TARGET = clobber +install := TARGET = install +lint := TARGET = lint + +.KEEP_STATE: + +all clean clobber install: .WAIT $(SUBDIRS) + +lint: # $(SUBDIRS) + +install_h: # $(ROOTHDRS) + +check: # $(CHECKHDRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include ../../Makefile.targ diff --git a/usr/src/lib/print/libipp-listener/Makefile.com b/usr/src/lib/print/libipp-listener/Makefile.com new file mode 100644 index 0000000000..75672ad6d6 --- /dev/null +++ b/usr/src/lib/print/libipp-listener/Makefile.com @@ -0,0 +1,67 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +LIBRARY = libipp-listener.a +VERS = .0 +OBJECTS = \ + cancel-job.o common.o create-job.o cups-accept-jobs.o \ + cups-get-classes.o cups-get-default.o cups-get-printers.o \ + cups-move-job.o cups-reject-jobs.o disable-printer.o enable-printer.o \ + get-job-attributes.o get-jobs.o get-printer-attributes.o hold-job.o \ + ipp-listener.o pause-printer.o print-job.o purge-jobs.o release-job.o \ + restart-job.o resume-printer.o send-document.o set-job-attributes.o \ + set-printer-attributes.o validate-job.o + +include ../../../Makefile.lib +include ../../../Makefile.rootfs + +ROOTLIBDIR= $(ROOT)/usr/lib + +LIBS = $(DYNLIB) + +SRCS = $(OBJECTS:%.o = $(SRCDIR)/%.c) + +$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC) + +SRCDIR = ../common +MAPFILE = $(SRCDIR)/mapfile + +CFLAGS += $(CCVERBOSE) +CPPFLAGS += -DSOLARIS_PRIVATE_POST_0_9 +CPPFLAGS += -I$(SRCDIR) +CPPFLAGS += -I../../libpapi-common/common +CPPFLAGS += -I../../libipp-core/common +DYNFLAGS += -M $(MAPFILE) +LDLIBS += -lipp-core -lpapi -lc + +.KEEP_STATE: + +all: $(LIBS) + +lint: lintcheck + +include ../../../Makefile.targ diff --git a/usr/src/lib/print/libipp-listener/common/cancel-job.c b/usr/src/lib/print/libipp-listener/common/cancel-job.c new file mode 100644 index 0000000000..49ad1980f8 --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/cancel-job.c @@ -0,0 +1,96 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: cancel-job.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <papi.h> +#include <ipp.h> +#include <ipp-listener.h> + +papi_status_t +ipp_cancel_job(papi_service_t svc, papi_attribute_t **request, + papi_attribute_t ***response) +{ + papi_status_t status; + papi_attribute_t **operational = NULL; + + char *message = NULL; + char *queue = NULL; + int id = -1; + + /* Get operational attributes from the request */ + (void) papiAttributeListGetCollection(request, NULL, + "operational-attributes-group", &operational); + + /* + * the operational-attributes-group must contain: + * job-uri (or printer-uri/job-id) + */ + get_printer_id(operational, &queue, &id); + if (id < 0) { + ipp_set_status(response, PAPI_BAD_REQUEST, + "missing job-uri or job-id"); + return (PAPI_BAD_REQUEST); + } else if (queue == NULL) { + ipp_set_status(response, PAPI_BAD_REQUEST, + "missing printer-uri or job-uri"); + return (PAPI_BAD_REQUEST); + } + + /* + * the operational-attributes-group may contain: + * message + */ + (void) papiAttributeListGetString(operational, NULL, + "message", &message); + + status = papiJobCancel(svc, queue, id); + if (status != PAPI_OK) { + ipp_set_status(response, status, + "cancel failed: %s-%d: %s", + (queue ? queue : "(null)"), id, + ipp_svc_status_mesg(svc, status)); + } else if (message != NULL) { /* add unsupported attribute group */ + papi_attribute_t **unsupported = NULL; + + papiAttributeListAddValue(&unsupported, PAPI_ATTR_EXCL, + "message", PAPI_COLLECTION, NULL); + (void) papiAttributeListAddCollection(response, + PAPI_ATTR_REPLACE, "unsupported-attributes-group", + unsupported); + papiAttributeListFree(unsupported); + + status = PAPI_OK_SUBST; + ipp_set_status(response, status, + "unsupported attribute in request"); + } + + return (status); +} diff --git a/usr/src/lib/print/libipp-listener/common/common.c b/usr/src/lib/print/libipp-listener/common/common.c new file mode 100644 index 0000000000..c3715dc1b3 --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/common.c @@ -0,0 +1,313 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: common.c 155 2006-04-26 02:34:54Z ktou $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <errno.h> +#include <sys/types.h> +#include <unistd.h> +#include <papi.h> +#include <ipp-listener.h> + +char * +ipp_svc_status_mesg(papi_service_t svc, papi_status_t status) +{ + char *mesg = papiServiceGetStatusMessage(svc); + + if (mesg == NULL) + mesg = papiStatusString(status); + + return (mesg); +} + +char * +destination_from_printer_uri(char *uri) +{ + static char buf[64]; + char *result = NULL; + + if (uri != NULL) + result = strrchr(uri, '/'); + + if (result == NULL) + result = uri; + else + result++; + +#ifdef FORCE_LPSCHED_URI + snprintf(buf, sizeof (buf), "lpsched://localhost/printers/%s", result); + result = buf; +#endif /* FORCE_LPSCHED_URI */ + + return (result); +} + +void +get_printer_id(papi_attribute_t **attributes, char **printer, int *id) +{ + papi_status_t result; + char *job = NULL; + char *fodder; + int junk; + + if (printer == NULL) + printer = &fodder; + if (id == NULL) + id = &junk; + + *printer = NULL; + *id = -1; + + result = papiAttributeListGetString(attributes, NULL, "job-uri", &job); + if (result != PAPI_OK) { + result = papiAttributeListGetString(attributes, NULL, + "printer-uri", printer); + if (result == PAPI_OK) + papiAttributeListGetInteger(attributes, NULL, + "job-id", id); + } else { + *printer = job; + if ((job = strrchr(*printer, '/')) != NULL) { + *job = '\0'; + *id = atoi(++job); + } + } + + /* move to the last component of the name */ + if (*printer != NULL) + *printer = strrchr(*printer, '/') + 1; +} + +void +get_string_list(papi_attribute_t **attributes, char *name, char ***values) +{ + papi_status_t result; + + void *iterator = NULL; + char *value = NULL; + + for (result = papiAttributeListGetString(attributes, &iterator, + name, &value); + result == PAPI_OK; + result = papiAttributeListGetString(attributes, &iterator, + NULL, &value)) + list_append(values, value); +} + +void +add_default_attributes(papi_attribute_t ***attributes) +{ + + (void) papiAttributeListAddString(attributes, PAPI_ATTR_APPEND, + "ipp-versions-supported", "1.0"); + (void) papiAttributeListAddString(attributes, PAPI_ATTR_APPEND, + "ipp-versions-supported", "1.1"); + (void) papiAttributeListAddBoolean(attributes, PAPI_ATTR_EXCL, + "multiple-document-jobs-supported", 0); + /* + * Should be able to ask the web server if it supports SSL or TLS, but + * for now, we pick only "none" + */ + (void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL, + "uri-security-supported", "none"); + + /* + * For now, we only "none". As we support more authentication methods, + * we will need to add the associated uri for each. Valid values would + * be: + * "none", "requesting-user-name", "basic", "digest", "certificate" + * See RFC2911 page 127 for more information. + */ + (void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL, + "uri-authentication-supported", "requesting-user-name"); + (void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL, + "uri-security-supported", "none"); + /* printer-uri-supported is added in the service based attributes */ + + (void) papiAttributeListAddInteger(attributes, PAPI_ATTR_EXCL, + "multiple-operation-time-out", 60); + + /* I18N related */ + (void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL, + "charset-configured", "utf-8"); + (void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL, + "charset-supported", "utf-8"); + (void) papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE, + "natural-language-configured", "en-us"); +} + +static void +massage_printer_attributes_group(papi_attribute_t **group, char *printer_uri) +{ + if (papiAttributeListFind(group, "printer-uri-supported") != NULL) + papiAttributeListAddString(&group, PAPI_ATTR_REPLACE, + "printer-uri-supported", printer_uri); +} + +static void +massage_job_attributes_group(papi_attribute_t **group, char *printer_uri) +{ + if (papiAttributeListFind(group, "job-printer-uri") != NULL) + papiAttributeListAddString(&group, PAPI_ATTR_REPLACE, + "job-printer-uri", printer_uri); + + if (papiAttributeListFind(group, "job-printer-uri") != NULL) { + char buf[BUFSIZ]; + int32_t id = -1; + + papiAttributeListGetInteger(group, NULL, "job-id", &id); + snprintf(buf, sizeof (buf), "%s/%d", printer_uri, id); + papiAttributeListAddString(&group, PAPI_ATTR_REPLACE, + "job-uri", buf); + } +} + +/* + * This function will replace the job/printer URIs with the requested + * uri because the print service may return a URI that isn't IPP based. + */ +void +massage_response(papi_attribute_t **request, papi_attribute_t **response) +{ + papi_status_t status; + papi_attribute_t **group = NULL; + void *iter = NULL; + char *host = "localhost"; + char *path = "/printers/"; + int port = 631; + char buf[BUFSIZ]; + + (void) papiAttributeListGetString(request, NULL, "uri-host", &host); + (void) papiAttributeListGetString(request, NULL, "uri-path", &path); + (void) papiAttributeListGetInteger(request, NULL, "uri-port", &port); + + if (port == 631) + snprintf(buf, sizeof (buf), "ipp://%s%s", host, path); + else + snprintf(buf, sizeof (buf), "http://%s:%d%s", host, port, path); + + for (status = papiAttributeListGetCollection(response, &iter, + "printer-attributes-group", &group); + status == PAPI_OK; + status = papiAttributeListGetCollection(NULL, &iter, + NULL, &group)) + massage_printer_attributes_group(group, buf); + + iter = NULL; + for (status = papiAttributeListGetCollection(response, &iter, + "job-attributes-group", &group); + status == PAPI_OK; + status = papiAttributeListGetCollection(NULL, &iter, + NULL, &group)) + massage_job_attributes_group(group, buf); +} + +/* + * This walks through the locale tab and returns the installed + * locales. There must be a better way. + */ +void +add_supported_locales(papi_attribute_t ***attributes) +{ + FILE *fp; + + papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE, + "generated-natural-language-supported", "en-us"); + +#ifndef __linux__ /* this is Solaris specific */ + if ((fp = fopen("/usr/lib/locale/lcttab", "r")) != NULL) { + char buf[1024]; + + while (fgets(buf, sizeof (buf), fp) != NULL) { + char *name, *file; + int i, passed = 1; + + name = strtok(buf, " \t\n"); + + for (i = 0; ((passed == 1) && (name[i] != NULL)); i++) + if (isalpha(name[i]) != 0) + name[i] = tolower(name[i]); + else if ((name[i] == '_') || (name[i] == '-')) + name[i] = '-'; + else + passed = 0; + + if ((passed == 1) && + ((file = strtok(NULL, " \t\n")) != NULL)) { + char path[1024]; + + snprintf(path, sizeof (path), + "/usr/lib/locale/%s", file); + + if (access(path, F_OK) == 0) + papiAttributeListAddString(attributes, + PAPI_ATTR_APPEND, + "generated-natural-language-supported", + name); + } + } + } +#endif +} + +void +papi_to_ipp_printer_group(papi_attribute_t ***response, + papi_attribute_t **request, int flags, papi_printer_t p) +{ + papi_attribute_t **ipp_group = NULL; + + copy_attributes(&ipp_group, papiPrinterGetAttributeList(p)); + + /* Windows clients appear to have a problem with very large values */ + papiAttributeListDelete(&ipp_group, "lpsched-printer-ppd-contents"); + + add_default_attributes(&ipp_group); + ipp_operations_supported(&ipp_group, request); + + (void) papiAttributeListAddCollection(response, flags, + "printer-attributes-group", ipp_group); + papiAttributeListFree(ipp_group); +} + +void +papi_to_ipp_job_group(papi_attribute_t ***response, + papi_attribute_t **request, int flags, papi_job_t j) +{ + papi_attribute_t **ipp_group = NULL; + + copy_attributes(&ipp_group, papiJobGetAttributeList(j)); + + (void) papiAttributeListAddCollection(response, flags, + "job-attributes-group", ipp_group); + papiAttributeListFree(ipp_group); +} diff --git a/usr/src/lib/print/libipp-listener/common/create-job.c b/usr/src/lib/print/libipp-listener/common/create-job.c new file mode 100644 index 0000000000..996b235cea --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/create-job.c @@ -0,0 +1,108 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: create-job.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <papi.h> +#include <ipp.h> +#include <ipp-listener.h> + +papi_status_t +ipp_create_job(papi_service_t svc, papi_attribute_t **request, + papi_attribute_t ***response) +{ + papi_status_t status; + papi_job_t j = NULL; + papi_attribute_t **operational = NULL; + papi_attribute_t **job_attributes = NULL; + char *queue = NULL; + char *keys[] = { "attributes-natural-language", "attributes-charset", + "printer-uri", NULL }; + + /* Get operational attributes from the request */ + (void) papiAttributeListGetCollection(request, NULL, + "operational-attributes-group", &operational); + + /* + * The operational-attributes-group must contain: + * printer-uri + */ + get_printer_id(operational, &queue, NULL); + if (queue == NULL) { + ipp_set_status(response, status, "printer-uri: %s", + papiStatusString(status)); + return (PAPI_BAD_REQUEST); + } + + /* + * The operational-attributes-group may contain: + * job-name + * ipp-attribute-fidelity + * document-name + * compression + * document-format + * document-natural-language + * job-k-octets + * job-impressions + * job-media-sheets + * Simply copy the entire contents of the operational-attributes-group + * for the PAPI call's possible use. + */ + + /* copy the pointers only, not the elements */ + split_and_copy_attributes(keys, operational, NULL, &job_attributes); + + /* copy any job-attributes-group attributes for the PAPI call */ + if (papiAttributeListGetCollection(request, NULL, + "job-attributes-group", &operational) == PAPI_OK) + copy_attributes(&job_attributes, operational); + + /* + * request job creation, using Sun extention to PAPI. The + * functionality in this extension is expected to make the + * next revision of the PAPI. + */ + status = papiJobCreate(svc, queue, job_attributes, NULL, &j); + papiAttributeListFree(job_attributes); + if (status != PAPI_OK) { + ipp_set_status(response, status, "job creation: %s", + ipp_svc_status_mesg(svc, status)); + return (status); + } + + /* add the job attributes to the response in a job-attributes-group */ + if (j != NULL) { + papi_to_ipp_job_group(response, request, PAPI_ATTR_REPLACE, j); + papiJobFree(j); + } + + return (status); +} diff --git a/usr/src/lib/print/libipp-listener/common/cups-accept-jobs.c b/usr/src/lib/print/libipp-listener/common/cups-accept-jobs.c new file mode 100644 index 0000000000..01a91ba5fd --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/cups-accept-jobs.c @@ -0,0 +1,68 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: cups-accept-jobs.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <papi.h> +#include <ipp.h> +#include <ipp-listener.h> + +papi_status_t +cups_accept_jobs(papi_service_t svc, papi_attribute_t **request, + papi_attribute_t ***response) +{ + papi_status_t status; + papi_attribute_t **operational = NULL; + + char *queue = NULL; + + /* Get operational attributes from the request */ + (void) papiAttributeListGetCollection(request, NULL, + "operational-attributes-group", &operational); + + /* + * The operational-attributes-group must contain: + * printer-uri + */ + get_printer_id(operational, &queue, NULL); + if (queue == NULL) { + ipp_set_status(response, status, "printer-uri: %s", + papiStatusString(status)); + return (PAPI_BAD_REQUEST); + } + + if ((status = papiPrinterResume(svc, queue)) != PAPI_OK) { + ipp_set_status(response, status, "accept failed: %s: %s", + (queue ? queue : "(null)"), + ipp_svc_status_mesg(svc, status)); + } + + return (status); +} diff --git a/usr/src/lib/print/libipp-listener/common/cups-get-classes.c b/usr/src/lib/print/libipp-listener/common/cups-get-classes.c new file mode 100644 index 0000000000..a6aea61908 --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/cups-get-classes.c @@ -0,0 +1,90 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: cups-get-classes.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <papi.h> +#include <ipp.h> +#include <ipp-listener.h> + +papi_status_t +cups_get_classes(papi_service_t svc, papi_attribute_t **request, + papi_attribute_t ***response) +{ + papi_status_t status; + papi_printer_t *p = NULL; + papi_attribute_t **operational = NULL; + papi_filter_t filt; + + char **req_attrs = NULL; + int limit = 0; + + /* Get operational attributes from the request */ + (void) papiAttributeListGetCollection(request, NULL, + "operational-attributes-group", &operational); + + /* + * The operational-attributes-group may contain: + * limit + * printer-info + * printer-location + * printer-type + * printer-type-mask + * requested-attributes + */ + + papiAttributeListGetInteger(operational, NULL, "limit", &limit); + + get_string_list(operational, "requested-attributes", &req_attrs); + + /* only ask for the classes */ + filt.type = PAPI_FILTER_BITMASK; + filt.filter.bitmask.mask = ~PAPI_PRINTER_CLASS; + filt.filter.bitmask.value = PAPI_PRINTER_CLASS; + + status = papiPrintersList(svc, req_attrs, &filt, &p); + if (status != PAPI_OK) { + ipp_set_status(response, status, "query printers: %s", + ipp_svc_status_mesg(svc, status)); + papiPrinterFree(p); /* we shouldn't have a printer */ + return (status); + } + + if (p != NULL) { + int i; + + for (i = 0; p[i] != NULL; i++) + papi_to_ipp_printer_group(response, request, + PAPI_ATTR_APPEND, p[i]); + papiPrinterListFree(p); + } + + return (status); +} diff --git a/usr/src/lib/print/libipp-listener/common/cups-get-default.c b/usr/src/lib/print/libipp-listener/common/cups-get-default.c new file mode 100644 index 0000000000..0bb084ac9e --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/cups-get-default.c @@ -0,0 +1,81 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: cups-get-default.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <papi.h> +#include <ipp.h> +#include <ipp-listener.h> + +#include <config-site.h> + +papi_status_t +cups_get_default(papi_service_t svc, papi_attribute_t **request, + papi_attribute_t ***response) +{ + papi_status_t status; + papi_printer_t p = NULL; + papi_attribute_t **operational = NULL; + papi_attribute_t **printer_attributes = NULL; + + char **req_attrs = NULL; + int limit = 0; + + /* Get operational attributes from the request */ + (void) papiAttributeListGetCollection(request, NULL, + "operational-attributes-group", &operational); + + /* + * The operational-attributes-group may contain: + * requested-attributes + */ + get_string_list(operational, "requested-attributes", &req_attrs); + + status = papiPrinterQuery(svc, DEFAULT_DEST, req_attrs, NULL, &p); + if (status != PAPI_OK) { + ipp_set_status(response, status, "query default: %s", + ipp_svc_status_mesg(svc, status)); + papiPrinterFree(p); /* we shouldn't have a printer */ + return (status); + } + + /* + * add the printer attributes to the response in a + * printer-attributes-group + */ + printer_attributes = papiPrinterGetAttributeList(p); + add_default_attributes(&printer_attributes); + (void) papiAttributeListAddCollection(response, PAPI_ATTR_REPLACE, + "printer-attributes-group", printer_attributes); + + papiPrinterFree(p); + + return (status); +} diff --git a/usr/src/lib/print/libipp-listener/common/cups-get-printers.c b/usr/src/lib/print/libipp-listener/common/cups-get-printers.c new file mode 100644 index 0000000000..e883543381 --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/cups-get-printers.c @@ -0,0 +1,91 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: cups-get-printers.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <papi.h> +#include <ipp.h> +#include <ipp-listener.h> + +papi_status_t +cups_get_printers(papi_service_t svc, papi_attribute_t **request, + papi_attribute_t ***response) +{ + papi_status_t status; + papi_printer_t *p = NULL; + papi_attribute_t **operational = NULL; + papi_filter_t filt; + + char **req_attrs = NULL; + int limit = 0; + + /* Get operational attributes from the request */ + (void) papiAttributeListGetCollection(request, NULL, + "operational-attributes-group", &operational); + + /* + * The operational-attributes-group may contain: + * limit + * printer-info + * printer-location + * printer-type + * printer-type-mask + * requested-attributes + */ + + papiAttributeListGetInteger(operational, NULL, "limit", &limit); + + get_string_list(operational, "requested-attributes", &req_attrs); + + /* only ask for the classes */ + filt.type = PAPI_FILTER_BITMASK; + filt.filter.bitmask.mask = ~PAPI_PRINTER_CLASS; + filt.filter.bitmask.value = PAPI_PRINTER_LOCAL | PAPI_PRINTER_REMOTE; + + /* query the print service for printers information */ + status = papiPrintersList(svc, req_attrs, &filt, &p); + if (status != PAPI_OK) { + ipp_set_status(response, status, "query printers: %s", + ipp_svc_status_mesg(svc, status)); + papiPrinterListFree(p); /* we shouldn't have any printers */ + return (status); + } + + if (p != NULL) { + int i; + + for (i = 0; p[i] != NULL; i++) + papi_to_ipp_printer_group(response, request, + PAPI_ATTR_APPEND, p[i]); + papiPrinterListFree(p); + } + + return (status); +} diff --git a/usr/src/lib/print/libipp-listener/common/cups-move-job.c b/usr/src/lib/print/libipp-listener/common/cups-move-job.c new file mode 100644 index 0000000000..137a507f93 --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/cups-move-job.c @@ -0,0 +1,103 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: cups-move-job.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <papi.h> +#include <ipp.h> +#include <ipp-listener.h> + +papi_status_t +cups_move_job(papi_service_t svc, papi_attribute_t **request, + papi_attribute_t ***response) +{ + papi_status_t status; + papi_attribute_t **operational = NULL, **job = NULL; + + char *message = NULL; + char *job_printer_uri = NULL; + char *queue = NULL; + char *dest = NULL; + int id = -1; + + /* Get operational attributes from the request */ + (void) papiAttributeListGetCollection(request, NULL, + "operational-attributes-group", &operational); + + /* + * Get job attributes from the request + */ + status = papiAttributeListGetCollection(request, NULL, + "job-attributes-group", &job); + if (status != PAPI_OK) { + ipp_set_status(response, status, + "job-attributes-group: %s", + papiStatusString(status)); + return (status); + } + + /* + * the operational-attributes-group must contain: + * job-uri (or printer-uri/job-id) + */ + get_printer_id(operational, &queue, &id); + if (id < 0) { + ipp_set_status(response, PAPI_BAD_REQUEST, + "missing job-uri or job-id"); + return (PAPI_BAD_REQUEST); + } else if (queue == NULL) { + ipp_set_status(response, PAPI_BAD_REQUEST, + "missing printer-uri or job-uri"); + return (PAPI_BAD_REQUEST); + } + + /* + * the job-attributes-group must contain: + * job-printer-uri + */ + job_printer_uri = NULL; + (void) papiAttributeListGetString(job, NULL, + "job-printer-uri", &job_printer_uri); + if (job_printer_uri == NULL) { + ipp_set_status(response, PAPI_BAD_REQUEST, + "missing job-printer-uri"); + return (PAPI_BAD_REQUEST); + } else + dest = destination_from_printer_uri(job_printer_uri); + + if ((status = papiJobMove(svc, queue, id, dest)) != PAPI_OK) + ipp_set_status(response, status, + "move failed: %s-%d to %s: %s", + (queue ? queue : "(null)"), id, + (dest ? dest : "(null)"), + ipp_svc_status_mesg(svc, status)); + + return (status); +} diff --git a/usr/src/lib/print/libipp-listener/common/cups-reject-jobs.c b/usr/src/lib/print/libipp-listener/common/cups-reject-jobs.c new file mode 100644 index 0000000000..1a35acdf62 --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/cups-reject-jobs.c @@ -0,0 +1,68 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: cups-reject-jobs.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <papi.h> +#include <ipp.h> +#include <ipp-listener.h> + +papi_status_t +cups_reject_jobs(papi_service_t svc, papi_attribute_t **request, + papi_attribute_t ***response) +{ + papi_status_t status; + papi_attribute_t **operational = NULL; + + char *queue = NULL; + + /* Get operational attributes from the request */ + (void) papiAttributeListGetCollection(request, NULL, + "operational-attributes-group", &operational); + + /* + * The operational-attributes-group must contain: + * printer-uri + */ + get_printer_id(operational, &queue, NULL); + if (queue == NULL) { + ipp_set_status(response, status, "printer-uri: %s", + papiStatusString(status)); + return (PAPI_BAD_REQUEST); + } + + if ((status = papiPrinterPause(svc, queue, NULL)) != PAPI_OK) { + ipp_set_status(response, status, "pause failed: %s: %s", + (queue ? queue : "(null)"), + ipp_svc_status_mesg(svc, status)); + } + + return (status); +} diff --git a/usr/src/lib/print/libipp-listener/common/disable-printer.c b/usr/src/lib/print/libipp-listener/common/disable-printer.c new file mode 100644 index 0000000000..e1c2fd3b5c --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/disable-printer.c @@ -0,0 +1,77 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: disable-printer.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <papi.h> +#include <ipp.h> +#include <ipp-listener.h> + +papi_status_t +ipp_disable_printer(papi_service_t svc, papi_attribute_t **request, + papi_attribute_t ***response) +{ + papi_status_t status; + papi_attribute_t **operational = NULL; + + char *queue = NULL; + char *message = NULL; + + /* Get operational attributes from the request */ + (void) papiAttributeListGetCollection(request, NULL, + "operational-attributes-group", &operational); + + /* + * The operational-attributes-group must contain: + * printer-uri + */ + + get_printer_id(operational, &queue, NULL); + if (queue == NULL) { + ipp_set_status(response, status, "printer-uri: %s", + papiStatusString(status)); + return (PAPI_BAD_REQUEST); + } + + /* + * The operational-attributes-group may contain: + * printer-message-from-operator + */ + (void) papiAttributeListGetString(operational, NULL, + "printer-message-from-operator", &message); + + if ((status = papiPrinterDisable(svc, queue, message)) != PAPI_OK) { + ipp_set_status(response, status, "disable failed: %s: %s", + (queue ? queue : "(null)"), + ipp_svc_status_mesg(svc, status)); + } + + return (status); +} diff --git a/usr/src/lib/print/libipp-listener/common/enable-printer.c b/usr/src/lib/print/libipp-listener/common/enable-printer.c new file mode 100644 index 0000000000..0d5419d51d --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/enable-printer.c @@ -0,0 +1,68 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: enable-printer.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <papi.h> +#include <ipp.h> +#include <ipp-listener.h> + +papi_status_t +ipp_enable_printer(papi_service_t svc, papi_attribute_t **request, + papi_attribute_t ***response) +{ + papi_status_t status; + papi_attribute_t **operational = NULL; + + char *queue = NULL; + + /* Get operational attributes from the request */ + (void) papiAttributeListGetCollection(request, NULL, + "operational-attributes-group", &operational); + + /* + * The operational-attributes-group must contain: + * printer-uri + */ + get_printer_id(operational, &queue, NULL); + if (queue == NULL) { + ipp_set_status(response, status, "printer-uri: %s", + papiStatusString(status)); + return (PAPI_BAD_REQUEST); + } + + if ((status = papiPrinterEnable(svc, queue)) != PAPI_OK) { + ipp_set_status(response, status, "enable failed: %s: %s", + (queue ? queue : "(null)"), + ipp_svc_status_mesg(svc, status)); + } + + return (status); +} diff --git a/usr/src/lib/print/libipp-listener/common/get-job-attributes.c b/usr/src/lib/print/libipp-listener/common/get-job-attributes.c new file mode 100644 index 0000000000..7f74054ebe --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/get-job-attributes.c @@ -0,0 +1,89 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: get-job-attributes.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <papi.h> +#include <ipp.h> +#include <ipp-listener.h> + +papi_status_t +ipp_get_job_attributes(papi_service_t svc, papi_attribute_t **request, + papi_attribute_t ***response) +{ + papi_status_t status; + papi_job_t j = NULL; + papi_attribute_t **operational = NULL; + papi_attribute_t **job_attributes = NULL; + + char **req_attrs = NULL; + char *queue = NULL; + int id = -1; + + /* Get operational attributes from the request */ + (void) papiAttributeListGetCollection(request, NULL, + "operational-attributes-group", &operational); + + /* + * the operational-attributes-group must contain: + * job-uri (or printer-uri/job-id) + */ + get_printer_id(operational, &queue, &id); + if (id < 0) { + ipp_set_status(response, PAPI_BAD_REQUEST, + "missing job-uri or job-id"); + return (PAPI_BAD_REQUEST); + } else if (queue == NULL) { + ipp_set_status(response, PAPI_BAD_REQUEST, + "missing printer-uri or job-uri"); + return (PAPI_BAD_REQUEST); + } + + /* + * the operational-attributes-group should contain: + * requested-attributes + */ + get_string_list(operational, "requested-attributes", &req_attrs); + + if ((status = papiJobQuery(svc, queue, id, req_attrs, &j)) != PAPI_OK) { + ipp_set_status(response, status, "query job: %s", + ipp_svc_status_mesg(svc, status)); + papiJobFree(j); /* we shouldn't have a job, but just in case */ + return (status); + } + + /* add the job attributes to the response in a job-attributes-group */ + if (j != NULL) { + papi_to_ipp_job_group(response, request, PAPI_ATTR_REPLACE, j); + papiJobFree(j); + } + + return (status); +} diff --git a/usr/src/lib/print/libipp-listener/common/get-jobs.c b/usr/src/lib/print/libipp-listener/common/get-jobs.c new file mode 100644 index 0000000000..0e5e56f44c --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/get-jobs.c @@ -0,0 +1,99 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: get-jobs.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <papi.h> +#include <ipp.h> +#include <ipp-listener.h> + +papi_status_t +ipp_get_jobs(papi_service_t svc, papi_attribute_t **request, + papi_attribute_t ***response) +{ + papi_status_t status; + papi_job_t *j = NULL; + papi_attribute_t **operational = NULL; + + char **req_attrs = NULL; + char *queue = NULL; + int limit = 0; + char my_jobs = PAPI_FALSE; + char *which; + int type = 0; + + /* Get operational attributes from the request */ + (void) papiAttributeListGetCollection(request, NULL, + "operational-attributes-group", &operational); + + /* + * The operational-attributes-group must contain: + * printer-uri + */ + get_printer_id(operational, &queue, NULL); + if (queue == NULL) { + ipp_set_status(response, status, "printer-uri: %s", + papiStatusString(status)); + return (PAPI_BAD_REQUEST); + } + + /* + * The operational-attributes-group may contain: + * limit + * requested-attributes + * which-jobs + * my-jobs + */ + (void) papiAttributeListGetString(operational, NULL, + "which-jobs", &which); + (void) papiAttributeListGetBoolean(operational, NULL, + "my-jobs", &my_jobs); + (void) papiAttributeListGetInteger(operational, NULL, "limit", &limit); + get_string_list(operational, "requested-attributes", &req_attrs); + + status = papiPrinterListJobs(svc, queue, req_attrs, type, limit, &j); + if (status != PAPI_OK) { + ipp_set_status(response, status, "query jobs: %s", + ipp_svc_status_mesg(svc, status)); + return (status); + } + + /* add any job's attributes to the response in job-attribute-groups */ + if (j != NULL) { + int i; + + for (i = 0; j[i] != NULL; i++) + papi_to_ipp_job_group(response, request, + PAPI_ATTR_APPEND, j[i]); + papiJobListFree(j); + } + + return (status); +} diff --git a/usr/src/lib/print/libipp-listener/common/get-printer-attributes.c b/usr/src/lib/print/libipp-listener/common/get-printer-attributes.c new file mode 100644 index 0000000000..2f33d0039c --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/get-printer-attributes.c @@ -0,0 +1,92 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: get-printer-attributes.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <papi.h> +#include <ipp.h> +#include <ipp-listener.h> + +papi_status_t +ipp_get_printer_attributes(papi_service_t svc, papi_attribute_t **request, + papi_attribute_t ***response) +{ + papi_status_t status; + papi_printer_t p = NULL; + papi_attribute_t **operational = NULL; + papi_attribute_t **printer_attributes = NULL; + + char **req_attrs = NULL; + char *doc_fmt = NULL; + char *queue = NULL; + + /* Get operational attributes from the request */ + (void) papiAttributeListGetCollection(request, NULL, + "operational-attributes-group", &operational); + + /* + * The operational-attributes-group must contain: + * printer-uri + */ + get_printer_id(operational, &queue, NULL); + if (queue == NULL) { + ipp_set_status(response, status, "printer-uri: %s", + papiStatusString(status)); + return (PAPI_BAD_REQUEST); + } + + /* + * The operational-attributes-group may contain: + * requested-attributes + * document-format + */ + get_string_list(operational, "requested-attributes", &req_attrs); + (void) papiAttributeListGetString(operational, NULL, + "document-format", &doc_fmt); + status = papiPrinterQuery(svc, queue, req_attrs, NULL, &p); + if (status != PAPI_OK) { + ipp_set_status(response, status, "query printer: %s", + ipp_svc_status_mesg(svc, status)); + papiPrinterFree(p); /* we shouldn't have a printer */ + return (status); + } + + /* + * add the printer attributes to the response in a + * printer-attributes-group + */ + if (p != NULL) { + papi_to_ipp_printer_group(response, request, + PAPI_ATTR_REPLACE, p); + papiPrinterFree(p); + } + + return (status); +} diff --git a/usr/src/lib/print/libipp-listener/common/hold-job.c b/usr/src/lib/print/libipp-listener/common/hold-job.c new file mode 100644 index 0000000000..fcb1409df6 --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/hold-job.c @@ -0,0 +1,96 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: hold-job.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <papi.h> +#include <ipp.h> +#include <ipp-listener.h> + +papi_status_t +ipp_hold_job(papi_service_t svc, papi_attribute_t **request, + papi_attribute_t ***response) +{ + papi_status_t status; + papi_attribute_t **operational = NULL; + + char *message = NULL; + char *queue = NULL; + int id = -1; + + /* Get operational attributes from the request */ + papiAttributeListGetCollection(request, NULL, + "operational-attributes-group", &operational); + + /* + * the operational-attributes-group must contain: + * job-uri (or printer-uri/job-id) + */ + get_printer_id(operational, &queue, &id); + if (id < 0) { + ipp_set_status(response, PAPI_BAD_REQUEST, + "missing job-uri or job-id"); + return (PAPI_BAD_REQUEST); + } else if (queue == NULL) { + ipp_set_status(response, PAPI_BAD_REQUEST, + "missing printer-uri or job-uri"); + return (PAPI_BAD_REQUEST); + } + + /* + * the operational-attributes-group may contain: + * message + * job-hold-until (ingored) + */ + (void) papiAttributeListGetString(operational, NULL, + "message", &message); + + if ((status = papiJobHold(svc, queue, id)) != PAPI_OK) { + ipp_set_status(response, status, + "hold failed: %s-%d: %s", + (queue ? queue : "(null)"), id, + ipp_svc_status_mesg(svc, status)); + } else if (message != NULL) { /* add unsupported attribute group */ + papi_attribute_t **unsupported = NULL; + + papiAttributeListAddValue(&unsupported, PAPI_ATTR_EXCL, + "message", PAPI_COLLECTION, NULL); + (void) papiAttributeListAddCollection(response, + PAPI_ATTR_REPLACE, "unsupported-attributes-group", + unsupported); + papiAttributeListFree(unsupported); + + status = PAPI_OK_SUBST; + ipp_set_status(response, status, + "unsupported attribute in request"); + } + + return (status); +} diff --git a/usr/src/lib/print/libipp-listener/common/ipp-listener.c b/usr/src/lib/print/libipp-listener/common/ipp-listener.c new file mode 100644 index 0000000000..4be81c95d8 --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/ipp-listener.c @@ -0,0 +1,455 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: ipp-listener.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <netinet/in.h> +#include <assert.h> +#include <errno.h> +#include <syslog.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include <papi.h> +#include <ipp-listener.h> + +typedef papi_status_t (ipp_handler_t)(papi_service_t svc, + papi_attribute_t **request, + papi_attribute_t ***response, + ipp_reader_t iread, void *fd); + +/* + * protocol request handlers are inserted below. The handler must be + * declared extern immediately below this comment and then an entry + * must be inserted in the "handlers" table a little further down. + */ +extern ipp_handler_t ipp_print_job; +extern ipp_handler_t ipp_validate_job; +extern ipp_handler_t ipp_create_job; +extern ipp_handler_t ipp_get_printer_attributes; +extern ipp_handler_t ipp_get_jobs; +extern ipp_handler_t ipp_pause_printer; +extern ipp_handler_t ipp_resume_printer; +extern ipp_handler_t ipp_disable_printer; +extern ipp_handler_t ipp_enable_printer; +extern ipp_handler_t ipp_purge_jobs; +extern ipp_handler_t ipp_send_document; +extern ipp_handler_t ipp_cancel_job; +extern ipp_handler_t ipp_get_job_attributes; +extern ipp_handler_t ipp_release_job; +extern ipp_handler_t ipp_hold_job; +extern ipp_handler_t ipp_restart_job; +extern ipp_handler_t ipp_set_job_attributes; +extern ipp_handler_t ipp_set_printer_attributes; +extern ipp_handler_t cups_get_default; +extern ipp_handler_t cups_get_printers; +extern ipp_handler_t cups_get_classes; +extern ipp_handler_t cups_accept_jobs; +extern ipp_handler_t cups_reject_jobs; +extern ipp_handler_t cups_move_job; + +/* ARGSUSED0 */ +static papi_status_t +default_handler(papi_service_t svc, papi_attribute_t **request, + papi_attribute_t ***response, ipp_reader_t iread, void *fd) +{ + int result = (int)PAPI_INTERNAL_ERROR; + + if (response != NULL) + (void) papiAttributeListGetInteger(*response, NULL, + "status-code", &result); + + return ((papi_status_t)result); +} + +static struct { + int16_t id; + char *name; + ipp_handler_t *function; + enum { OP_REQUIRED, OP_OPTIONAL, OP_VENDOR } type; +} handlers[] = { + /* Printer Operations */ + { 0x0002, "print-job", ipp_print_job, OP_REQUIRED }, + { 0x0003, "print-uri", NULL, OP_OPTIONAL }, + { 0x0004, "validate-job", ipp_validate_job, + OP_REQUIRED }, + { 0x0005, "create-job", ipp_create_job, OP_OPTIONAL }, + { 0x000a, "get-jobs", ipp_get_jobs, OP_REQUIRED }, + { 0x000b, "get-printer-attributes", ipp_get_printer_attributes, + OP_REQUIRED }, + { 0x0010, "pause-printer", ipp_pause_printer, + OP_OPTIONAL }, + { 0x0011, "resume-printer", ipp_resume_printer, + OP_OPTIONAL }, + { 0x0012, "purge-jobs", ipp_purge_jobs, OP_OPTIONAL }, + { 0x0013, "set-printer-attributes", ipp_set_printer_attributes, + OP_OPTIONAL }, + { 0x0014, "set-job-attributes", ipp_set_job_attributes, + OP_OPTIONAL }, + { 0x0022, "enable-printer", ipp_enable_printer, + OP_OPTIONAL }, + { 0x0023, "disable-printer", ipp_disable_printer, + OP_OPTIONAL }, + /* Job Operations */ + { 0x0006, "send-document", ipp_send_document, + OP_OPTIONAL }, + { 0x0007, "send-uri", NULL, OP_OPTIONAL }, + { 0x0008, "cancel-job", ipp_cancel_job, OP_REQUIRED }, + { 0x0009, "get-job-attributes", ipp_get_job_attributes, + OP_REQUIRED }, + { 0x000c, "hold-job", ipp_hold_job, OP_OPTIONAL }, + { 0x000d, "release-job", ipp_release_job, + OP_OPTIONAL }, + { 0x000e, "restart-job", ipp_restart_job, + OP_OPTIONAL }, + /* Other Operations */ + { 0x4001, "cups-get-default", cups_get_default, + OP_VENDOR }, + { 0x4002, "cups-get-printers", cups_get_printers, + OP_VENDOR }, + { 0x4005, "cups-get-classes", cups_get_classes, + OP_VENDOR }, + { 0x4008, "cups-accept-jobs", cups_accept_jobs, + OP_VENDOR }, + { 0x4009, "cups-reject-jobs", cups_reject_jobs, + OP_VENDOR }, + { 0x400D, "cups-move-job", cups_move_job, OP_VENDOR }, + { 0, NULL, NULL, OP_VENDOR } +}; + +static int +ipp_operation_name_to_index(char *name) +{ + int i; + + for (i = 0; handlers[i].name != NULL; i++) + if (strcasecmp(name, handlers[i].name) == 0) + return (i); + + return (-1); +} + +static int +ipp_operation_id_to_index(int16_t id) +{ + int i; + + for (i = 0; handlers[i].name != NULL; i++) + if (id == handlers[i].id) + return (i); + + return (-1); +} + +static ipp_handler_t * +ipp_operation_handler(papi_attribute_t **request, papi_attribute_t ***response) +{ + int id = 0; + int index; + papi_attribute_t **ops = NULL; + papi_status_t status; + char configured = PAPI_FALSE; + + /* get the operation from the request */ + status = papiAttributeListGetInteger(request, NULL, + "operation-id", &id); + if (status != PAPI_OK) { + ipp_set_status(response, PAPI_BAD_ARGUMENT, + "no operation specified in request"); + return (default_handler); + } + + /* find the operation in the handler table */ + index = ipp_operation_id_to_index(id); +#ifdef DEBUG + if (index == -1) + fprintf(stderr, "Operation: 0x%4.4x\n", id); + else + fprintf(stderr, "Operation: 0x%4.4x(%s)\n", id, + handlers[index].name); + fflush(stderr); +#endif + + if ((index == -1) || (handlers[index].function == NULL)) { + ipp_set_status(response, PAPI_OPERATION_NOT_SUPPORTED, + "operation (0x%4.4x) not implemented by server", + id); + return (default_handler); + } + + /* find the configured operations */ + status = papiAttributeListGetCollection(request, NULL, + "operations", &ops); + if (status != PAPI_OK) { /* this should not be possible */ + ipp_set_status(response, PAPI_INTERNAL_ERROR, + "sofware error, no operations configured"); + return (default_handler); + } + + /* check if the requested operation is configured */ + status = papiAttributeListGetBoolean(ops, NULL, + handlers[index].name, &configured); + if ((status != PAPI_OK) || (configured != PAPI_TRUE)) { + ipp_set_status(response, PAPI_OPERATION_NOT_SUPPORTED, + "operation (%s 0x%4.4x) not enabled on server", + handlers[index].name, id); + return (default_handler); + } + + return (handlers[index].function); +} + +static char +type_to_boolean(char *type) +{ + char result = PAPI_FALSE; + + if ((strcasecmp(type, "true") == 0) || + (strcasecmp(type, "yes") == 0) || + (strcasecmp(type, "on") == 0) || + (strcasecmp(type, "enable") == 0)) + result = PAPI_TRUE; + + return (result); +} + +static papi_status_t +ipp_configure_required_operations(papi_attribute_t ***list, char boolean) +{ + papi_status_t result = PAPI_OK; + int i; + + for (i = 0; ((result == PAPI_OK) && (handlers[i].name != NULL)); i++) + if (handlers[i].type == OP_REQUIRED) + result = papiAttributeListAddBoolean(list, + PAPI_ATTR_REPLACE, handlers[i].name, + boolean); + + return (result); + +} + +static papi_status_t +ipp_configure_all_operations(papi_attribute_t ***list, char boolean) +{ + papi_status_t result = PAPI_OK; + int i; + + for (i = 0; ((result == PAPI_OK) && (handlers[i].name != NULL)); i++) + result = papiAttributeListAddBoolean(list, PAPI_ATTR_REPLACE, + handlers[i].name, boolean); + + return (result); +} + +papi_status_t +ipp_configure_operation(papi_attribute_t ***list, char *operation, char *type) +{ + papi_status_t result = PAPI_OPERATION_NOT_SUPPORTED; + char boolean = PAPI_FALSE; + + if ((list == NULL) || (operation == NULL) || (type == NULL)) + return (PAPI_BAD_ARGUMENT); + + boolean = type_to_boolean(type); + + if (strcasecmp(operation, "all") == 0) { + result = ipp_configure_all_operations(list, boolean); + } else if (strcasecmp(operation, "required") == 0) { + result = ipp_configure_required_operations(list, boolean); + } else if (ipp_operation_name_to_index(operation) != -1) { + result = papiAttributeListAddBoolean(list, PAPI_ATTR_REPLACE, + operation, boolean); + } + + return (result); +} + +void +ipp_operations_supported(papi_attribute_t ***list, papi_attribute_t **request) +{ + papi_attribute_t **group = NULL; + + (void) papiAttributeListGetCollection(request, NULL, + "operations", &group); + if (group != NULL) { + int i; + + for (i = 0; handlers[i].name != NULL; i++) { + char boolean = PAPI_FALSE; + (void) papiAttributeListGetBoolean(group, NULL, + handlers[i].name, &boolean); + + if (boolean == PAPI_TRUE) + (void) papiAttributeListAddInteger(list, + PAPI_ATTR_APPEND, + "operations-supported", + handlers[i].id); + } + } +} + +static papi_status_t +ipp_initialize_response(papi_attribute_t **request, + papi_attribute_t ***response) +{ + papi_attribute_t **operational = NULL; + int i; + + if ((request == NULL) || (response == NULL)) + return (PAPI_BAD_ARGUMENT); + + /* If the response was initialized, start over */ + if (*response != NULL) { + papiAttributeListFree(*response); + *response = NULL; + } + + /* Add the basic ipp header information to the response */ + (void) papiAttributeListGetInteger(request, NULL, "version-major", &i); + (void) papiAttributeListAddInteger(response, PAPI_ATTR_REPLACE, + "version-major", i); + (void) papiAttributeListGetInteger(request, NULL, "version-minor", &i); + (void) papiAttributeListAddInteger(response, PAPI_ATTR_REPLACE, + "version-minor", i); + + (void) papiAttributeListGetInteger(request, NULL, "request-id", &i); + (void) papiAttributeListAddInteger(response, PAPI_ATTR_REPLACE, + "request-id", i); + + /* Add a default operational attributes group to the response */ + (void) papiAttributeListAddString(&operational, PAPI_ATTR_EXCL, + "attributes-charset", "utf-8"); + (void) papiAttributeListAddString(&operational, PAPI_ATTR_EXCL, + "attributes-natural-language", "en-us"); + + (void) papiAttributeListAddCollection(response, PAPI_ATTR_REPLACE, + "operational-attributes-group", operational); + papiAttributeListFree(operational); + + return (PAPI_OK); +} + +static papi_status_t +print_service_connect(papi_service_t *svc, papi_attribute_t **request, + papi_attribute_t ***response) +{ + papi_status_t status; + papi_attribute_t **operational = NULL; + char *printer_uri = NULL; + char *svc_name = NULL; + char *user = NULL; + + /* Get the operational attributes group from the request */ + (void) papiAttributeListGetCollection(request, NULL, + "operational-attributes-group", &operational); + + /* get the user name */ + (void) papiAttributeListGetString(request, NULL, "default-user", &user); + (void) papiAttributeListGetString(operational, NULL, + "requesting-user-name", &user); + + /* get the printer or service name */ + get_printer_id(operational, &printer_uri, NULL); + svc_name = destination_from_printer_uri(printer_uri); + (void) papiAttributeListGetString(request, NULL, + "default-service", &svc_name); + + status = papiServiceCreate(svc, svc_name, user, NULL, NULL, + PAPI_ENCRYPT_NEVER, NULL); + if (status != PAPI_OK) { + ipp_set_status(response, status, "print service: %s", + papiStatusString(status)); + return (status); + } + + /* + * Trusted Solaris can't be trusting of intermediaries. Pass + * the socket connection to the print service to retrieve the + * sensativity label off of a multi-level port. + */ + { + int fd = -1; + + (void) papiAttributeListGetInteger(request, NULL, + "peer-socket", &fd); + if (fd != -1) + papiServiceSetPeer(*svc, fd); + } + + return (status); +} + +papi_status_t +ipp_process_request(papi_attribute_t **request, papi_attribute_t ***response, + ipp_reader_t iread, void *fd) +{ + papi_status_t result = PAPI_OK; + + ipp_initialize_response(request, response); + +#ifdef DEBUG + fprintf(stderr, "REQUEST:"); + papiAttributeListPrint(stderr, request, " %d ", getpid()); + fprintf(stderr, "\n"); +#endif + + /* verify that the request is "well-formed" */ + if ((result = ipp_validate_request(request, response)) == PAPI_OK) { + papi_service_t svc = NULL; + ipp_handler_t *handler; + + result = print_service_connect(&svc, request, response); + handler = ipp_operation_handler(request, response); + + /* process the request */ + if ((result == PAPI_OK) && (handler != NULL)) + result = (handler)(svc, request, response, iread, fd); +#ifdef DEBUG + fprintf(stderr, "RESULT: %s\n", papiStatusString(result)); +#endif + papiServiceDestroy(svc); + } + + (void) papiAttributeListAddInteger(response, PAPI_ATTR_EXCL, + "status-code", result); + massage_response(request, *response); + +#ifdef DEBUG + fprintf(stderr, "RESPONSE:"); + papiAttributeListPrint(stderr, *response, " %d ", getpid()); + fprintf(stderr, "\n"); +#endif + + return (result); +} diff --git a/usr/src/lib/print/libipp-listener/common/ipp-listener.h b/usr/src/lib/print/libipp-listener/common/ipp-listener.h new file mode 100644 index 0000000000..5a8718477e --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/ipp-listener.h @@ -0,0 +1,70 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +#ifndef _IPP_LISTENER_H +#define _IPP_LISTENER_H + +/* $Id: ipp-listener.h 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +#include <ipp.h> + +/* exported functions */ +extern papi_status_t ipp_configure_operation(papi_attribute_t ***list, + char *operation, char *type); +extern papi_status_t ipp_process_request(papi_attribute_t **request, + papi_attribute_t ***response, + ipp_reader_t iread, void *fd); + +/* shared internal functions */ +extern char *ipp_svc_status_mesg(papi_service_t svc, papi_status_t status); +extern char *destination_from_printer_uri(char *); +extern void get_printer_id(papi_attribute_t **attributes, char **printer, + int *id); +extern void ipp_operations_supported(papi_attribute_t ***list, + papi_attribute_t **request); +extern void get_string_list(papi_attribute_t **attributes, char *name, + char ***values); +extern void add_default_attributes(papi_attribute_t ***attributes); +extern void papi_to_ipp_printer_group(papi_attribute_t ***response, + papi_attribute_t **request, int flags, + papi_printer_t p); +extern void papi_to_ipp_job_group(papi_attribute_t ***response, + papi_attribute_t **request, int flags, papi_job_t j); +extern void massage_response(papi_attribute_t **request, + papi_attribute_t **response); + +#ifdef __cplusplus +} +#endif + +#endif /* _IPP_LISTENER_H */ diff --git a/usr/src/lib/print/libipp-listener/common/mapfile b/usr/src/lib/print/libipp-listener/common/mapfile new file mode 100644 index 0000000000..aa1d9a583e --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/mapfile @@ -0,0 +1,39 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# $Id: mapfile 151 2006-04-25 16:55:34Z njacobs $ +# + +# ident "%Z%%M% %I% %E% SMI" + +SUNWprivate_1.0 { + global: + ipp_configure_operation; + ipp_process_request; + local: + *; +}; diff --git a/usr/src/lib/print/libipp-listener/common/pause-printer.c b/usr/src/lib/print/libipp-listener/common/pause-printer.c new file mode 100644 index 0000000000..0afe4aadf0 --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/pause-printer.c @@ -0,0 +1,68 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: pause-printer.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <papi.h> +#include <ipp.h> +#include <ipp-listener.h> + +papi_status_t +ipp_pause_printer(papi_service_t svc, papi_attribute_t **request, + papi_attribute_t ***response) +{ + papi_status_t status; + papi_attribute_t **operational = NULL; + + char *queue = NULL; + + /* Get operational attributes from the request */ + (void) papiAttributeListGetCollection(request, NULL, + "operational-attributes-group", &operational); + + /* + * The operational-attributes-group must contain: + * printer-uri + */ + get_printer_id(operational, &queue, NULL); + if (queue == NULL) { + ipp_set_status(response, status, "printer-uri: %s", + papiStatusString(status)); + return (PAPI_BAD_REQUEST); + } + + if ((status = papiPrinterPause(svc, queue, NULL)) != PAPI_OK) { + ipp_set_status(response, status, "pause failed: %s: %s", + (queue ? queue : "(null)"), + ipp_svc_status_mesg(svc, status)); + } + + return (status); +} diff --git a/usr/src/lib/print/libipp-listener/common/print-job.c b/usr/src/lib/print/libipp-listener/common/print-job.c new file mode 100644 index 0000000000..3b24d53339 --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/print-job.c @@ -0,0 +1,123 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: print-job.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <papi.h> +#include <ipp.h> +#include <ipp-listener.h> + +papi_status_t +ipp_print_job(papi_service_t svc, papi_attribute_t **request, + papi_attribute_t ***response, ipp_reader_t iread, void *fd) +{ + papi_status_t status; + papi_stream_t s = NULL; + papi_job_t j = NULL; + papi_attribute_t **operational = NULL; + papi_attribute_t **job_attributes = NULL; + char *queue = NULL; + ssize_t rc; + char buf[BUFSIZ]; + char *keys[] = { "attributes-natural-language", "attributes-charset", + "printer-uri", NULL }; + + /* Get operational attributes from the request */ + (void) papiAttributeListGetCollection(request, NULL, + "operational-attributes-group", &operational); + + /* + * The operational-attributes-group must contain: + * printer-uri + */ + get_printer_id(operational, &queue, NULL); + if (queue == NULL) { + ipp_set_status(response, status, "printer-uri: %s", + papiStatusString(status)); + return (PAPI_BAD_REQUEST); + } + + /* + * The operational-attributes-group may contain: + * job-name + * ipp-attribute-fidelity + * document-name + * compression + * document-format + * document-natural-language + * job-k-octets + * job-impressions + * job-media-sheets + * Simply copy the entire contents of the operational-attributes-group + * for the PAPI call's possible use. + */ + split_and_copy_attributes(keys, operational, NULL, &job_attributes); + + /* copy any job-attributes-group attributes for the PAPI call */ + if (papiAttributeListGetCollection(request, NULL, + "job-attributes-group", &operational) == PAPI_OK) + copy_attributes(&job_attributes, operational); + + /* request job creation with a resulting stream that we can write to */ + status = papiJobStreamOpen(svc, queue, job_attributes, NULL, &s); + papiAttributeListFree(job_attributes); + if (status != PAPI_OK) { + ipp_set_status(response, status, "job submission: %s", + ipp_svc_status_mesg(svc, status)); + return (status); + } + + /* copy the document data from the IPP connection to the stream */ + while ((status == PAPI_OK) && ((rc = iread(fd, buf, sizeof (buf))) > 0)) + status = papiJobStreamWrite(svc, s, buf, rc); + if (status != PAPI_OK) { + ipp_set_status(response, status, "write job data: %s", + ipp_svc_status_mesg(svc, status)); + return (status); + } + + /* close the stream, committing the job */ + status = papiJobStreamClose(svc, s, &j); + if (status != PAPI_OK) { + ipp_set_status(response, status, "close job stream: %s", + ipp_svc_status_mesg(svc, status)); + papiJobFree(j); /* we shouldn't have a job, but just in case */ + return (status); + } + + /* add the job attributes to the response in a job-attributes-group */ + if (j != NULL) { + papi_to_ipp_job_group(response, request, PAPI_ATTR_REPLACE, j); + papiJobFree(j); + } + + return (status); +} diff --git a/usr/src/lib/print/libipp-listener/common/purge-jobs.c b/usr/src/lib/print/libipp-listener/common/purge-jobs.c new file mode 100644 index 0000000000..7128595844 --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/purge-jobs.c @@ -0,0 +1,71 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: purge-jobs.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <papi.h> +#include <ipp.h> +#include <ipp-listener.h> + +papi_status_t +ipp_purge_jobs(papi_service_t svc, papi_attribute_t **request, + papi_attribute_t ***response) +{ + papi_status_t status; + papi_job_t *jobs = NULL; + papi_attribute_t **operational = NULL; + + char *queue = NULL; + + /* Get operational attributes from the request */ + (void) papiAttributeListGetCollection(request, NULL, + "operational-attributes-group", &operational); + + /* + * The operational-attributes-group must contain: + * printer-uri + */ + get_printer_id(operational, &queue, NULL); + if (queue == NULL) { + ipp_set_status(response, status, "printer-uri: %s", + papiStatusString(status)); + return (PAPI_BAD_REQUEST); + } + + if ((status = papiPrinterPurgeJobs(svc, queue, &jobs)) != PAPI_OK) { + ipp_set_status(response, status, "purge failed: %s: %s", + (queue ? queue : "(null)"), + ipp_svc_status_mesg(svc, status)); + } + + papiJobListFree(jobs); + + return (status); +} diff --git a/usr/src/lib/print/libipp-listener/common/release-job.c b/usr/src/lib/print/libipp-listener/common/release-job.c new file mode 100644 index 0000000000..0ae16906a6 --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/release-job.c @@ -0,0 +1,95 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: release-job.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <papi.h> +#include <ipp.h> +#include <ipp-listener.h> + +papi_status_t +ipp_release_job(papi_service_t svc, papi_attribute_t **request, + papi_attribute_t ***response) +{ + papi_status_t status; + papi_attribute_t **operational = NULL; + + char *message = NULL; + char *queue = NULL; + int id = -1; + + /* Get operational attributes from the request */ + (void) papiAttributeListGetCollection(request, NULL, + "operational-attributes-group", &operational); + + /* + * the operational-attributes-group must contain: + * job-uri (or printer-uri/job-id) + */ + get_printer_id(operational, &queue, &id); + if (id < 0) { + ipp_set_status(response, PAPI_BAD_REQUEST, + "missing job-uri or job-id"); + return (PAPI_BAD_REQUEST); + } else if (queue == NULL) { + ipp_set_status(response, PAPI_BAD_REQUEST, + "missing printer-uri or job-uri"); + return (PAPI_BAD_REQUEST); + } + + /* + * the operational-attributes-group may contain: + * message + */ + (void) papiAttributeListGetString(operational, NULL, + "message", &message); + + if ((status = papiJobRelease(svc, queue, id)) != PAPI_OK) { + ipp_set_status(response, status, + "release failed: %s-%d: %s", + (queue ? queue : "(null)"), id, + ipp_svc_status_mesg(svc, status)); + } else if (message != NULL) { /* add unsupported attribute group */ + papi_attribute_t **unsupported = NULL; + + papiAttributeListAddValue(&unsupported, PAPI_ATTR_EXCL, + "message", PAPI_COLLECTION, NULL); + (void) papiAttributeListAddCollection(response, + PAPI_ATTR_REPLACE, "unsupported-attributes-group", + unsupported); + papiAttributeListFree(unsupported); + + status = PAPI_OK_SUBST; + ipp_set_status(response, status, + "unsupported attribute in request"); + } + + return (status); +} diff --git a/usr/src/lib/print/libipp-listener/common/restart-job.c b/usr/src/lib/print/libipp-listener/common/restart-job.c new file mode 100644 index 0000000000..d78967b0f2 --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/restart-job.c @@ -0,0 +1,106 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: restart-job.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <papi.h> +#include <ipp.h> +#include <ipp-listener.h> + +papi_status_t +ipp_restart_job(papi_service_t svc, papi_attribute_t **request, + papi_attribute_t ***response) +{ + papi_status_t status; + papi_attribute_t **operational = NULL; + + char *message = NULL; + char *hold_until = NULL; + char *queue = NULL; + int id = -1; + + /* Get operational attributes from the request */ + (void) papiAttributeListGetCollection(request, NULL, + "operational-attributes-group", &operational); + + /* + * the operational-attributes-group must contain: + * job-uri (or printer-uri/job-id) + */ + get_printer_id(operational, &queue, &id); + if (id < 0) { + ipp_set_status(response, PAPI_BAD_REQUEST, + "missing job-uri or job-id"); + return (PAPI_BAD_REQUEST); + } else if (queue == NULL) { + ipp_set_status(response, PAPI_BAD_REQUEST, + "missing printer-uri or job-uri"); + return (PAPI_BAD_REQUEST); + } + + /* + * the operational-attributes-group may contain: + * message + * job-hold-until + */ + (void) papiAttributeListGetString(operational, NULL, + "job-hold-until", &hold_until); + (void) papiAttributeListGetString(operational, NULL, + "message", &message); + + if ((status = papiJobRestart(svc, queue, id)) != PAPI_OK) { + ipp_set_status(response, status, + "restart failed: %s-%d: %s", + (queue ? queue : "(null)"), id, + ipp_svc_status_mesg(svc, status)); + } else if ((message != NULL) || (hold_until != NULL)) { + /* add unsupported attribute group */ + papi_attribute_t **unsupported = NULL; + + if (message != NULL) + (void) papiAttributeListAddValue(&unsupported, + PAPI_ATTR_EXCL, "message", + PAPI_COLLECTION, NULL); + if (hold_until != NULL) + (void) papiAttributeListAddValue(&unsupported, + PAPI_ATTR_EXCL, "hold-until", + PAPI_COLLECTION, NULL); + (void) papiAttributeListAddCollection(response, + PAPI_ATTR_REPLACE, "unsupported-attributes-group", + unsupported); + papiAttributeListFree(unsupported); + + status = PAPI_OK_SUBST; + ipp_set_status(response, status, + "unsupported attribute in request"); + } + + return (status); +} diff --git a/usr/src/lib/print/libipp-listener/common/resume-printer.c b/usr/src/lib/print/libipp-listener/common/resume-printer.c new file mode 100644 index 0000000000..8d48ee9adb --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/resume-printer.c @@ -0,0 +1,68 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: resume-printer.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <papi.h> +#include <ipp.h> +#include <ipp-listener.h> + +papi_status_t +ipp_resume_printer(papi_service_t svc, papi_attribute_t **request, + papi_attribute_t ***response) +{ + papi_status_t status; + papi_attribute_t **operational = NULL; + + char *queue = NULL; + + /* Get operational attributes from the request */ + (void) papiAttributeListGetCollection(request, NULL, + "operational-attributes-group", &operational); + + /* + * The operational-attributes-group must contain: + * printer-uri + */ + get_printer_id(operational, &queue, NULL); + if (queue == NULL) { + ipp_set_status(response, status, "printer-uri: %s", + papiStatusString(status)); + return (PAPI_BAD_REQUEST); + } + + if ((status = papiPrinterResume(svc, queue)) != PAPI_OK) { + ipp_set_status(response, status, "resume failed: %s: %s", + (queue ? queue : "(null)"), + ipp_svc_status_mesg(svc, status)); + } + + return (status); +} diff --git a/usr/src/lib/print/libipp-listener/common/send-document.c b/usr/src/lib/print/libipp-listener/common/send-document.c new file mode 100644 index 0000000000..4a4d3a4314 --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/send-document.c @@ -0,0 +1,143 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: send-document.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <papi.h> +#include <ipp.h> +#include <ipp-listener.h> + +/* + * When the PAPI supports papiJobCreate(), papiJobStreamAdd() and + * papiJobClose(), this will be much cleaner and more efficient, but in the + * meantime, we are using a private, non-standard interface to do this. + */ +papi_status_t +ipp_send_document(papi_service_t svc, papi_attribute_t **request, + papi_attribute_t ***response, ipp_reader_t iread, void *fd) +{ + papi_status_t status; + papi_stream_t s = NULL; + papi_job_t j = NULL; + papi_attribute_t **operational = NULL; + papi_attribute_t **job_attributes = NULL; + char *queue = NULL; + ssize_t rc; + int id = -1; + char buf[BUFSIZ]; + char last = PAPI_FALSE; + char *keys[] = { "attributes-natural-language", "attributes-charset", + "printer-uri", "job-id", "job-uri", "last-document", + NULL }; + + /* Get operational attributes from the request */ + (void) papiAttributeListGetCollection(request, NULL, + "operational-attributes-group", &operational); + + /* + * the operational-attributes-group must contain: + * job-uri (or printer-uri/job-id) + * last-document + */ + get_printer_id(operational, &queue, &id); + if (id < 0) { + ipp_set_status(response, PAPI_BAD_REQUEST, + "missing job-uri or job-id"); + return (PAPI_BAD_REQUEST); + } else if (queue == NULL) { + ipp_set_status(response, PAPI_BAD_REQUEST, + "missing printer-uri or job-uri"); + return (PAPI_BAD_REQUEST); + } + + status = papiAttributeListGetBoolean(operational, NULL, + "last-document", &last); + if (status != PAPI_OK) { + ipp_set_status(response, status, "last-document: %s", + papiStatusString(status)); + return (PAPI_BAD_REQUEST); + } + + /* + * the operational-attributes-group may contain: + * document-name + * compression + * document-format + * document-natural-language + * Simply copy the entire contents of the operational-attributes-group + * for the PAPI call's possible use. + */ + split_and_copy_attributes(keys, operational, NULL, &job_attributes); + + /* copy any job-attributes-group attributes for the PAPI call */ + if (papiAttributeListGetCollection(request, NULL, + "job-attributes-group", &operational) == PAPI_OK) + copy_attributes(&job_attributes, operational); + + /* create a stream to write the document data on */ + status = papiJobStreamAdd(svc, queue, id, &s); + papiAttributeListFree(job_attributes); + if (status != PAPI_OK) { + ipp_set_status(response, status, "job submission: %s", + ipp_svc_status_mesg(svc, status)); + return (status); + } + + /* copy the document data from the IPP connection to the stream */ + while ((status == PAPI_OK) && ((rc = iread(fd, buf, sizeof (buf))) > 0)) + status = papiJobStreamWrite(svc, s, buf, rc); + if (status != PAPI_OK) { + ipp_set_status(response, status, "write job data: %s", + ipp_svc_status_mesg(svc, status)); + return (status); + } + + /* close the stream */ + status = papiJobStreamClose(svc, s, &j); + if (status != PAPI_OK) { + ipp_set_status(response, status, "close job stream: %s", + ipp_svc_status_mesg(svc, status)); + papiJobFree(j); /* we shouldn't have a job, but just in case */ + return (status); + } + + /* if it's the last document, commit the job */ + if (last == PAPI_TRUE) { + status = papiJobCommit(svc, queue, id); + } + + /* add the job attributes to the response in a job-attributes-group */ + if (j != NULL) { + papi_to_ipp_job_group(response, request, PAPI_ATTR_REPLACE, j); + papiJobFree(j); + } + + return (status); +} diff --git a/usr/src/lib/print/libipp-listener/common/set-job-attributes.c b/usr/src/lib/print/libipp-listener/common/set-job-attributes.c new file mode 100644 index 0000000000..57c0b899f3 --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/set-job-attributes.c @@ -0,0 +1,90 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: set-job-attributes.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <papi.h> +#include <ipp.h> +#include <ipp-listener.h> + +papi_status_t +ipp_set_job_attributes(papi_service_t svc, papi_attribute_t **request, + papi_attribute_t ***response, ipp_reader_t iread, void *fd) +{ + papi_status_t status; + papi_stream_t s = NULL; + papi_job_t j = NULL; + papi_attribute_t **operational = NULL; + papi_attribute_t **job_attributes = NULL; + + char *queue = NULL; + int32_t id = -1; + ssize_t rc; + char buf[BUFSIZ]; + + /* Get operational attributes from the request */ + (void) papiAttributeListGetCollection(request, NULL, + "operational-attributes-group", &operational); + + /* + * The operational-attributes-group must contain: + * job-uri + */ + get_printer_id(operational, &queue, &id); + if (id < 0) { + ipp_set_status(response, PAPI_BAD_REQUEST, + "missing job-uri or job-id"); + return (PAPI_BAD_REQUEST); + } else if (queue == NULL) { + ipp_set_status(response, PAPI_BAD_REQUEST, + "missing printer-uri or job-uri"); + return (PAPI_BAD_REQUEST); + } + + /* get the job-attributes-group attributes for the PAPI call */ + papiAttributeListGetCollection(request, NULL, + "job-attributes-group", &job_attributes); + + /* request job modification */ + status = papiJobModify(svc, queue, id, job_attributes, &j); + if (status != PAPI_OK) { + ipp_set_status(response, status, "job modification: %s", + ipp_svc_status_mesg(svc, status)); + return (status); + } + + /* add the job attributes to the response in a job-attributes-group */ + if (j != NULL) { + papi_to_ipp_job_group(response, request, PAPI_ATTR_REPLACE, j); + papiJobFree(j); + } + + return (status); +} diff --git a/usr/src/lib/print/libipp-listener/common/set-printer-attributes.c b/usr/src/lib/print/libipp-listener/common/set-printer-attributes.c new file mode 100644 index 0000000000..7d80864961 --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/set-printer-attributes.c @@ -0,0 +1,83 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: set-printer-attributes.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <papi.h> +#include <ipp.h> +#include <ipp-listener.h> + +papi_status_t +ipp_set_printer_attributes(papi_service_t svc, papi_attribute_t **request, + papi_attribute_t ***response, ipp_reader_t iread, void *fd) +{ + papi_status_t status; + papi_printer_t p = NULL; + papi_attribute_t **operational = NULL; + papi_attribute_t **printer_attributes = NULL; + + char *queue = NULL; + + /* Get operational attributes from the request */ + (void) papiAttributeListGetCollection(request, NULL, + "operational-attributes-group", &operational); + + /* + * The operational-attributes-group must contain: + * printer-uri + */ + get_printer_id(operational, &queue, NULL); + if (queue == NULL) { + ipp_set_status(response, PAPI_BAD_REQUEST, + "missing printer-uri or job-uri"); + return (PAPI_BAD_REQUEST); + } + + /* get the printer-attributes-group attributes for the PAPI call */ + papiAttributeListGetCollection(request, NULL, + "printer-attributes-group", &printer_attributes); + + /* request job modification */ + status = papiPrinterModify(svc, queue, printer_attributes, &p); + if (status != PAPI_OK) { + ipp_set_status(response, status, "printer modification: %s", + ipp_svc_status_mesg(svc, status)); + return (status); + } + + /* add the job attributes to the response in a job-attributes-group */ + if (p != NULL) { + papi_to_ipp_printer_group(response, request, + PAPI_ATTR_REPLACE, p); + papiPrinterFree(p); + } + + return (status); +} diff --git a/usr/src/lib/print/libipp-listener/common/validate-job.c b/usr/src/lib/print/libipp-listener/common/validate-job.c new file mode 100644 index 0000000000..8ea72ee38b --- /dev/null +++ b/usr/src/lib/print/libipp-listener/common/validate-job.c @@ -0,0 +1,107 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: validate-job.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <papi.h> +#include <ipp.h> +#include <ipp-listener.h> + +papi_status_t +ipp_validate_job(papi_service_t svc, papi_attribute_t **request, + papi_attribute_t ***response, ipp_reader_t iread, void *fd) +{ + papi_status_t status; + papi_job_t j = NULL; + papi_attribute_t **operational = NULL; + papi_attribute_t **job_attributes = NULL; + char *queue = NULL; + char *files[] = { "/etc/syslog.conf", NULL }; + ssize_t rc; + char buf[BUFSIZ]; + char *keys[] = { "attributes-natural-language", "attributes-charset", + "printer-uri", NULL }; + + /* Get operational attributes from the request */ + (void) papiAttributeListGetCollection(request, NULL, + "operational-attributes-group", &operational); + + /* + * The operational-attributes-group must contain: + * printer-uri + */ + get_printer_id(operational, &queue, NULL); + if (queue == NULL) { + ipp_set_status(response, status, "printer-uri: %s", + papiStatusString(status)); + return (PAPI_BAD_REQUEST); + } + + /* + * The operational-attributes-group may contain: + * job-name + * ipp-attribute-fidelity + * document-name + * compression + * document-format + * document-natural-language + * job-k-octets + * job-impressions + * job-media-sheets + * Simply copy the entire contents of the operational-attributes-group + * for the PAPI call's possible use. + */ + split_and_copy_attributes(keys, operational, NULL, &job_attributes); + + /* copy any job-attributes-group attributes for the PAPI call */ + if (papiAttributeListGetCollection(request, NULL, + "job-attributes-group", &operational) == PAPI_OK) + copy_attributes(&job_attributes, operational); + + /* request job validation */ + status = papiJobValidate(svc, queue, job_attributes, NULL, files, &j); + papiAttributeListFree(job_attributes); + + if (status != PAPI_OK) { + ipp_set_status(response, status, "validating job: %s", + ipp_svc_status_mesg(svc, status)); + papiJobFree(j); /* we shouldn't have a job, but just in case */ + return (status); + } + + /* add the job attributes to the response in a job-attributes-group */ + if (j != NULL) { + papi_to_ipp_job_group(response, request, PAPI_ATTR_REPLACE, j); + papiJobFree(j); + } + + return (status); +} diff --git a/usr/src/lib/print/libipp-listener/i386/Makefile b/usr/src/lib/print/libipp-listener/i386/Makefile new file mode 100644 index 0000000000..3b985583a4 --- /dev/null +++ b/usr/src/lib/print/libipp-listener/i386/Makefile @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT) diff --git a/usr/src/lib/print/libipp-listener/sparc/Makefile b/usr/src/lib/print/libipp-listener/sparc/Makefile new file mode 100644 index 0000000000..3b985583a4 --- /dev/null +++ b/usr/src/lib/print/libipp-listener/sparc/Makefile @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT) diff --git a/usr/src/lib/print/libpapi-common/Makefile b/usr/src/lib/print/libpapi-common/Makefile new file mode 100644 index 0000000000..ef7e964b85 --- /dev/null +++ b/usr/src/lib/print/libpapi-common/Makefile @@ -0,0 +1,57 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../../Makefile.lib + +HDRS = papi.h +HDRDIR = common +SUBDIRS = $(MACH) +#$(BUILD64)SUBDIRS += $(MACH64) + +all := TARGET = all +clean := TARGET = clean +clobber := TARGET = clobber +install := TARGET = install +lint := TARGET = lint + +.KEEP_STATE: + +all clean clobber: .WAIT $(SUBDIRS) +install: .WAIT $(SUBDIRS) install_h + +lint: # $(SUBDIRS) + +install_h: $(ROOTHDRS) + +check: $(CHECKHDRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include ../../Makefile.targ diff --git a/usr/src/lib/print/libpapi-common/Makefile.com b/usr/src/lib/print/libpapi-common/Makefile.com new file mode 100644 index 0000000000..3d21ee6c40 --- /dev/null +++ b/usr/src/lib/print/libpapi-common/Makefile.com @@ -0,0 +1,57 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +LIBRARY = libpapi-common.a +VERS = .0 +OBJECTS = attribute.o common.o library.o list.o misc.o status.o uri.o + +include ../../../Makefile.lib +include ../../../Makefile.rootfs + +ROOTLIBDIR= $(ROOT)/usr/lib + +LIBS = $(DYNLIB) + +SRCS = $(OBJECTS:%.o = $(SRCDIR)/%.c) + +$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC) + +SRCDIR = ../common +MAPFILE = $(SRCDIR)/mapfile + +CFLAGS += $(CCVERBOSE) +CPPFLAGS += -I$(SRCDIR) +DYNFLAGS += -M $(MAPFILE) +LDLIBS += -lc + +.KEEP_STATE: + +all: $(LIBS) + +lint: lintcheck + +include ../../../Makefile.targ diff --git a/usr/src/cmd/lp/lib/papi/attribute.c b/usr/src/lib/print/libpapi-common/common/attribute.c index 02f5db2fc4..2b2e035cfe 100644 --- a/usr/src/cmd/lp/lib/papi/attribute.c +++ b/usr/src/lib/print/libpapi-common/common/attribute.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,19 +18,25 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * */ +/* $Id: attribute.c 157 2006-04-26 15:07:55Z ktou $ */ + #pragma ident "%Z%%M% %I% %E% SMI" /*LINTLIBRARY*/ #include <stdio.h> #include <stdlib.h> +#include <stdarg.h> #include <string.h> -#include <papi_impl.h> +#include <alloca.h> +#include <papi.h> static void papiAttributeFree(papi_attribute_t *attribute); @@ -110,31 +115,40 @@ collection_dup(papi_attribute_t **collection) /* allows a NULL collection that is "empty" or "no value" */ if (collection != NULL) { + papi_status_t status = PAPI_OK; int i; - for (i = 0; collection[i] != NULL; i++) { + for (i = 0; ((collection[i] != NULL) && (status == PAPI_OK)); + i++) { papi_attribute_t *a = collection[i]; - papiAttributeListAdd(&result, PAPI_ATTR_APPEND, a->name, - a->type, NULL); - if (a->values != NULL) { + status = papiAttributeListAddValue(&result, + PAPI_ATTR_APPEND, a->name, a->type, + NULL); + if ((status == PAPI_OK) && (a->values != NULL)) { int j; - for (j = 0; a->values[j] != NULL; j++) - papiAttributeListAdd(&result, + for (j = 0; ((a->values[j] != NULL) && + (status == PAPI_OK)); j++) + status = papiAttributeListAddValue( + &result, PAPI_ATTR_APPEND, a->name, a->type, a->values[j]); } } + if (status != PAPI_OK) { + papiAttributeListFree(result); + result = NULL; + } } return (result); } static papi_attribute_value_t * -papiAttributeValueDup(const papi_attribute_value_type_t type, - const papi_attribute_value_t *v) +papiAttributeValueDup(papi_attribute_value_type_t type, + papi_attribute_value_t *v) { papi_attribute_value_t *result = NULL; @@ -168,6 +182,9 @@ papiAttributeValueDup(const papi_attribute_value_type_t type, case PAPI_COLLECTION: result->collection = collection_dup(v->collection); break; + case PAPI_METADATA: + result->metadata = v->metadata; + break; default: /* unknown type, fail to duplicate */ free(result); result = NULL; @@ -178,7 +195,7 @@ papiAttributeValueDup(const papi_attribute_value_type_t type, } static papi_attribute_t * -papiAttributeAlloc(const char *name, papi_attribute_value_type_t type) +papiAttributeAlloc(char *name, papi_attribute_value_type_t type) { papi_attribute_t *result = NULL; @@ -191,9 +208,9 @@ papiAttributeAlloc(const char *name, papi_attribute_value_type_t type) } static papi_status_t -papiAttributeListAddValue(papi_attribute_value_t ***values, - const papi_attribute_value_type_t type, - const papi_attribute_value_t *value) +papiAttributeListAppendValue(papi_attribute_value_t ***values, + papi_attribute_value_type_t type, + papi_attribute_value_t *value) { if (values == NULL) @@ -212,9 +229,9 @@ papiAttributeListAddValue(papi_attribute_value_t ***values, } papi_status_t -papiAttributeListAdd(papi_attribute_t ***list, const int flgs, - const char *name, const papi_attribute_value_type_t type, - const papi_attribute_value_t *value) +papiAttributeListAddValue(papi_attribute_t ***list, int flgs, + char *name, papi_attribute_value_type_t type, + papi_attribute_value_t *value) { papi_status_t result; int flags = flgs; @@ -262,7 +279,7 @@ papiAttributeListAdd(papi_attribute_t ***list, const int flgs, attribute->type = type; - result = papiAttributeListAddValue(&attribute->values, type, value); + result = papiAttributeListAppendValue(&attribute->values, type, value); /* free old values if we replaced them */ if (values != NULL) @@ -272,81 +289,95 @@ papiAttributeListAdd(papi_attribute_t ***list, const int flgs, } papi_status_t -papiAttributeListAddString(papi_attribute_t ***list, const int flags, - const char *name, const char *string) +papiAttributeListAddString(papi_attribute_t ***list, int flags, + char *name, char *string) { papi_attribute_value_t v; v.string = (char *)string; - return (papiAttributeListAdd(list, flags, name, PAPI_STRING, &v)); + return (papiAttributeListAddValue(list, flags, name, PAPI_STRING, &v)); } papi_status_t -papiAttributeListAddInteger(papi_attribute_t ***list, const int flags, - const char *name, const int integer) +papiAttributeListAddInteger(papi_attribute_t ***list, int flags, + char *name, int integer) { papi_attribute_value_t v; v.integer = integer; - return (papiAttributeListAdd(list, flags, name, PAPI_INTEGER, &v)); + return (papiAttributeListAddValue(list, flags, name, PAPI_INTEGER, &v)); } papi_status_t -papiAttributeListAddBoolean(papi_attribute_t ***list, const int flags, - const char *name, const char boolean) +papiAttributeListAddBoolean(papi_attribute_t ***list, int flags, + char *name, char boolean) { papi_attribute_value_t v; v.boolean = boolean; - return (papiAttributeListAdd(list, flags, name, PAPI_BOOLEAN, &v)); + return (papiAttributeListAddValue(list, flags, name, PAPI_BOOLEAN, &v)); } papi_status_t -papiAttributeListAddRange(papi_attribute_t ***list, const int flags, - const char *name, const int lower, const int upper) +papiAttributeListAddRange(papi_attribute_t ***list, int flags, + char *name, int lower, int upper) { papi_attribute_value_t v; v.range.lower = lower; v.range.upper = upper; - return (papiAttributeListAdd(list, flags, name, PAPI_RANGE, &v)); + return (papiAttributeListAddValue(list, flags, name, PAPI_RANGE, &v)); } papi_status_t -papiAttributeListAddResolution(papi_attribute_t ***list, const int flags, - const char *name, const int xres, const int yres, - const papi_resolution_unit_t units) +papiAttributeListAddResolution(papi_attribute_t ***list, int flags, + char *name, int xres, int yres, + papi_resolution_unit_t units) { papi_attribute_value_t v; v.resolution.xres = xres; v.resolution.yres = yres; v.resolution.units = units; - return (papiAttributeListAdd(list, flags, name, PAPI_RESOLUTION, &v)); + return (papiAttributeListAddValue(list, flags, name, + PAPI_RESOLUTION, &v)); } papi_status_t -papiAttributeListAddDatetime(papi_attribute_t ***list, const int flags, - const char *name, const time_t datetime) +papiAttributeListAddDatetime(papi_attribute_t ***list, int flags, + char *name, time_t datetime) { papi_attribute_value_t v; v.datetime = datetime; - return (papiAttributeListAdd(list, flags, name, PAPI_DATETIME, &v)); + return (papiAttributeListAddValue(list, flags, name, + PAPI_DATETIME, &v)); } papi_status_t -papiAttributeListAddCollection(papi_attribute_t ***list, const int flags, - const char *name, const papi_attribute_t **collection) +papiAttributeListAddCollection(papi_attribute_t ***list, int flags, + char *name, papi_attribute_t **collection) { papi_attribute_value_t v; v.collection = (papi_attribute_t **)collection; - return (papiAttributeListAdd(list, flags, name, PAPI_COLLECTION, &v)); + return (papiAttributeListAddValue(list, flags, name, + PAPI_COLLECTION, &v)); +} + +papi_status_t +papiAttributeListAddMetadata(papi_attribute_t ***list, int flags, + char *name, papi_metadata_t metadata) +{ + papi_attribute_value_t v; + + v.metadata = metadata; + return (papiAttributeListAddValue(list, flags, name, + PAPI_METADATA, &v)); } papi_status_t -papiAttributeListDelete(papi_attribute_t ***list, const char *name) +papiAttributeListDelete(papi_attribute_t ***list, char *name) { papi_attribute_t *attribute; @@ -363,15 +394,15 @@ papiAttributeListDelete(papi_attribute_t ***list, const char *name) } papi_attribute_t * -papiAttributeListFind(papi_attribute_t **list, const char *name) +papiAttributeListFind(papi_attribute_t **list, char *name) { - if (list != NULL) { - int i; + int i; + if ((list == NULL) || (name == NULL)) + return (NULL); - for (i = 0; list[i] != NULL; i++) - if (strcasecmp(list[i]->name, name) == 0) - return ((papi_attribute_t *)list[i]); - } + for (i = 0; list[i] != NULL; i++) + if (strcasecmp(list[i]->name, name) == 0) + return ((papi_attribute_t *)list[i]); return (NULL); } @@ -396,7 +427,7 @@ papiAttributeListGetNext(papi_attribute_t **list, void **iter) papi_status_t papiAttributeListGetValue(papi_attribute_t **list, void **iter, - const char *name, papi_attribute_value_type_t type, + char *name, papi_attribute_value_type_t type, papi_attribute_value_t **value) { papi_attribute_value_t **tmp; @@ -436,7 +467,7 @@ papiAttributeListGetValue(papi_attribute_t **list, void **iter, papi_status_t papiAttributeListGetString(papi_attribute_t **list, void **iter, - const char *name, char **vptr) + char *name, char **vptr) { papi_status_t status; papi_attribute_value_t *value = NULL; @@ -454,7 +485,7 @@ papiAttributeListGetString(papi_attribute_t **list, void **iter, papi_status_t papiAttributeListGetInteger(papi_attribute_t **list, void **iter, - const char *name, int *vptr) + char *name, int *vptr) { papi_status_t status; papi_attribute_value_t *value = NULL; @@ -472,7 +503,7 @@ papiAttributeListGetInteger(papi_attribute_t **list, void **iter, papi_status_t papiAttributeListGetBoolean(papi_attribute_t **list, void **iter, - const char *name, char *vptr) + char *name, char *vptr) { papi_status_t status; papi_attribute_value_t *value = NULL; @@ -490,7 +521,7 @@ papiAttributeListGetBoolean(papi_attribute_t **list, void **iter, papi_status_t papiAttributeListGetRange(papi_attribute_t **list, void **iter, - const char *name, int *min, int *max) + char *name, int *min, int *max) { papi_status_t status; papi_attribute_value_t *value = NULL; @@ -510,7 +541,7 @@ papiAttributeListGetRange(papi_attribute_t **list, void **iter, papi_status_t papiAttributeListGetResolution(papi_attribute_t **list, void **iter, - const char *name, int *x, int *y, + char *name, int *x, int *y, papi_resolution_unit_t *units) { papi_status_t status; @@ -532,7 +563,7 @@ papiAttributeListGetResolution(papi_attribute_t **list, void **iter, papi_status_t papiAttributeListGetDatetime(papi_attribute_t **list, void **iter, - const char *name, time_t *dt) + char *name, time_t *dt) { papi_status_t status; papi_attribute_value_t *value = NULL; @@ -551,7 +582,7 @@ papiAttributeListGetDatetime(papi_attribute_t **list, void **iter, papi_status_t papiAttributeListGetCollection(papi_attribute_t **list, void **iter, - const char *name, papi_attribute_t ***collection) + char *name, papi_attribute_t ***collection) { papi_status_t status; papi_attribute_value_t *value = NULL; @@ -568,22 +599,36 @@ papiAttributeListGetCollection(papi_attribute_t **list, void **iter, return (status); } +papi_status_t +papiAttributeListGetMetadata(papi_attribute_t **list, void **iter, + char *name, papi_metadata_t *vptr) +{ + papi_status_t status; + papi_attribute_value_t *value = NULL; + + if (vptr == NULL) + return (PAPI_BAD_ARGUMENT); + + status = papiAttributeListGetValue(list, iter, name, + PAPI_METADATA, &value); + if (status == PAPI_OK) + *vptr = value->metadata; + + return (status); +} /* - * ***************************************************************************** - * * Description: The given string contains one or more attributes, in the - * following form: - * "aaaa=true bbbbb=1 ccccc=abcd" - * extract the next attribute from that string; the 'next' - * parameter should be set to zero to extract the first attribute - * in the string. + * following form: + * "aaaa=true bbbbb=1 ccccc=abcd" + * extract the next attribute from that string; the 'next' + * parameter should be set to zero to extract the first attribute + * in the string. * - * ***************************************************************************** */ static char * -_getNextAttr(const char *string, int *next) +_getNextAttr(char *string, int *next) { char *result = NULL; @@ -594,8 +639,7 @@ _getNextAttr(const char *string, int *next) char *val = NULL; int len = 0; - if ((string != NULL) && (*start != '\0')) - { + if ((string != NULL) && (*start != '\0')) { while ((*start == ' ') || (*start == '\t') || (*start == '\n')) { start++; @@ -606,11 +650,9 @@ _getNextAttr(const char *string, int *next) val = strchr(start, '='); - if ((val != NULL) && ((val[1] == '"') || (val[1] == '\''))) - { + if ((val != NULL) && ((val[1] == '"') || (val[1] == '\''))) { val = strchr(&val[2], val[1]); - if (val != NULL) - { + if (val != NULL) { nl = strchr(&val[1], '\n'); sp = strchr(&val[1], ' '); tab = strchr(&val[1], '\t'); @@ -619,36 +661,23 @@ _getNextAttr(const char *string, int *next) if ((nl != NULL) && ((sp == NULL) || ((sp != NULL) && (nl < sp))) && - ((tab == NULL) || ((tab != NULL) && (nl < tab)))) - { + ((tab == NULL) || ((tab != NULL) && (nl < tab)))) { len = nl-start; - } - else - if ((sp != NULL) && (tab != NULL) && (sp > tab)) - { + } else if ((sp != NULL) && (tab != NULL) && (sp > tab)) { len = tab-start; - } - else - if ((sp != NULL) && (sp != NULL)) - { + } else if ((sp != NULL) && (sp != NULL)) { len = sp-start; - } - else - if ((tab != NULL) && (tab != NULL)) - { + } else if ((tab != NULL) && (tab != NULL)) { len = tab-start; } - if (len == 0) - { + if (len == 0) { len = strlen(start); } - if (len > 0) - { + if (len > 0) { result = (char *)malloc(len+1); - if (result != NULL) - { + if (result != NULL) { strncpy(result, start, len); result[len] = '\0'; *next = (start-string)+len; @@ -661,12 +690,9 @@ _getNextAttr(const char *string, int *next) /* - * ***************************************************************************** - * * Description: Parse the given attribute string value and transform it into - * the papi_attribute_value_t in the papi_attribute_t structure. + * the papi_attribute_value_t in the papi_attribute_t structure. * - * ***************************************************************************** */ static papi_status_t @@ -683,15 +709,13 @@ _parseAttrValue(char *value, papi_attribute_t *attr) papi_attribute_value_t **avalues = NULL; avalues = malloc(sizeof (papi_attribute_value_t *) * 2); - if (avalues == NULL) - { + if (avalues == NULL) { result = PAPI_TEMPORARY_ERROR; return (result); } avalues[0] = malloc(sizeof (papi_attribute_value_t)); avalues[1] = NULL; - if (avalues[0] == NULL) - { + if (avalues[0] == NULL) { free(avalues); result = PAPI_TEMPORARY_ERROR; return (result); @@ -701,59 +725,41 @@ _parseAttrValue(char *value, papi_attribute_t *attr) /* * TODO - need to sort out 'resolution', 'dateandtime' & 'collection' values */ - if ((value != NULL) && (strlen(value) > 0) && (attr != NULL)) - { + if ((value != NULL) && (strlen(value) > 0) && (attr != NULL)) { len = strlen(value); - if ((len >= 2) && - (((value[0] == '"') && (value[len-1] == '"')) || - ((value[0] == '\'') && (value[len-1] == '\'')))) - { + if ((len >= 2) && (((value[0] == '"') && + (value[len-1] == '"')) || ((value[0] == '\'') && + (value[len-1] == '\'')))) { /* string value */ attr->type = PAPI_STRING; papiString = strdup(value+1); - if (papiString != NULL) - { + if (papiString != NULL) { papiString[strlen(papiString)-1] = '\0'; avalues[0]->string = papiString; - } - else - { + } else { result = PAPI_TEMPORARY_ERROR; } - } - - else - if ((strcasecmp(value, "true") == 0) || - (strcasecmp(value, "YES") == 0)) - { + } else if ((strcasecmp(value, "true") == 0) || + (strcasecmp(value, "YES") == 0)) { /* boolean = true */ attr->type = PAPI_BOOLEAN; avalues[0]->boolean = PAPI_TRUE; - } - - else - if ((strcasecmp(value, "false") == 0) || - (strcasecmp(value, "NO") == 0)) - { + } else if ((strcasecmp(value, "false") == 0) || + (strcasecmp(value, "NO") == 0)) { /* boolean = false */ attr->type = PAPI_BOOLEAN; avalues[0]->boolean = PAPI_FALSE; - } - - else - { - /* is value an integer or a range? */ + } else { + /* is value an integer or a range ? */ i = 0; attr->type = PAPI_INTEGER; tmp1 = strdup(value); while (((value[i] >= '0') && (value[i] <= '9')) || - (value[i] == '-')) - { - if (value[i] == '-') - { + (value[i] == '-')) { + if (value[i] == '-') { tmp1[i] = '\0'; tmp2 = &tmp1[i+1]; attr->type = PAPI_RANGE; @@ -762,40 +768,29 @@ _parseAttrValue(char *value, papi_attribute_t *attr) i++; } - if (strlen(value) == i) - { - if (attr->type == PAPI_RANGE) - { + if (strlen(value) == i) { + if (attr->type == PAPI_RANGE) { avalues[0]->range.lower = atoi(tmp1); avalues[0]->range.upper = atoi(tmp2); - } - else - { + } else { avalues[0]->integer = atoi(value); } - } - else - { - /* is value a resolution? */ - + } else { + /* is value a resolution ? */ i = 0; attr->type = PAPI_INTEGER; tmp1 = strdup(value); while (((value[i] >= '0') && (value[i] <= '9')) || - (value[i] == 'x')) - { - if (value[i] == 'x') - { + (value[i] == 'x')) { + if (value[i] == 'x') { tmp1[i] = '\0'; if (attr->type == PAPI_INTEGER) { tmp2 = &tmp1[i+1]; attr->type = PAPI_RESOLUTION; - } - else - { + } else { tmp3 = &tmp1[i+1]; } } @@ -803,35 +798,27 @@ _parseAttrValue(char *value, papi_attribute_t *attr) i++; } - if (strlen(value) == i) - { - if (attr->type == PAPI_RESOLUTION) - { + if (strlen(value) == i) { + if (attr->type == PAPI_RESOLUTION) { avalues[0]->resolution.xres = atoi(tmp1); avalues[0]->resolution.yres = atoi(tmp2); - if (tmp3 != NULL) - { + if (tmp3 != NULL) { avalues[0]-> - resolution.units = + resolution.units = atoi(tmp3); - } - else - { + } else { avalues[0]-> - resolution.units = - 0; + resolution.units = 0; } } } - if (attr->type != PAPI_RESOLUTION) - { + if (attr->type != PAPI_RESOLUTION) { attr->type = PAPI_STRING; avalues[0]->string = strdup(value); - if (avalues[0]->string == NULL) - { + if (avalues[0]->string == NULL) { result = PAPI_TEMPORARY_ERROR; } } @@ -839,24 +826,18 @@ _parseAttrValue(char *value, papi_attribute_t *attr) free(tmp1); } - } - else - { + } else { result = PAPI_BAD_ARGUMENT; } - if (result != PAPI_OK) - { + if (result != PAPI_OK) { i = 0; - while (avalues[i] != NULL) - { + while (avalues[i] != NULL) { free(avalues[i]); i++; } free(avalues); - } - else - { + } else { attr->values = avalues; } @@ -865,12 +846,9 @@ _parseAttrValue(char *value, papi_attribute_t *attr) /* - * ***************************************************************************** - * * Description: Parse the given attribute string and transform it into the - * papi_attribute_t structure. + * papi_attribute_t structure. * - * ***************************************************************************** */ static papi_status_t @@ -882,57 +860,49 @@ _parseAttributeString(char *attrString, papi_attribute_t *attr) char *p = NULL; papi_attribute_value_t **avalues = NULL; - if ((attrString != NULL) && (strlen(attrString) >= 3) && (attr != NULL)) - { + if ((attrString != NULL) && (strlen(attrString) >= 3) && + (attr != NULL)) { attr->name = NULL; string = strdup(attrString); - if (string != NULL) - { + if (string != NULL) { p = strchr(string, '='); - if (p != NULL) - { + if (p != NULL) { *p = '\0'; attr->name = string; p++; /* pointer to value */ result = _parseAttrValue(p, attr); - } - else - { + } else { + char value; /* boolean - no value so assume 'true' */ + if (strncasecmp(string, "no", 2) == 0) { + string += 2; + value = PAPI_FALSE; + } else + value = PAPI_TRUE; + attr->name = string; attr->type = PAPI_BOOLEAN; - avalues = - malloc( + avalues = malloc( sizeof (papi_attribute_value_t *) * 2); - if (avalues == NULL) - { + if (avalues == NULL) { result = PAPI_TEMPORARY_ERROR; - } - else - { - avalues[0] = - malloc( - sizeof (papi_attribute_value_t)); + } else { + avalues[0] = malloc( + sizeof (papi_attribute_value_t)); avalues[1] = NULL; - if (avalues[0] == NULL) - { + if (avalues[0] == NULL) { free(avalues); result = PAPI_TEMPORARY_ERROR; - } - else - { - avalues[0]->boolean = - PAPI_TRUE; + } else { + avalues[0]->boolean = value; attr->values = avalues; } } } } - } - else - { + } else { result = PAPI_BAD_ARGUMENT; } @@ -942,25 +912,24 @@ _parseAttributeString(char *attrString, papi_attribute_t *attr) papi_status_t papiAttributeListFromString(papi_attribute_t ***attrs, - const int flags, const char *string) + int flags, char *string) { papi_status_t result = PAPI_OK; - int next = 0; - char *attrString = NULL; + int next = 0; + char *attrString = NULL; papi_attribute_t attr; if ((attrs != NULL) && (string != NULL) && - ((flags & - ~(PAPI_ATTR_APPEND+PAPI_ATTR_REPLACE+PAPI_ATTR_EXCL)) == 0)) { + ((flags & ~(PAPI_ATTR_APPEND+PAPI_ATTR_REPLACE+PAPI_ATTR_EXCL)) + == 0)) { attrString = _getNextAttr(string, &next); while ((result == PAPI_OK) && (attrString != NULL)) { -printf("papiAttributeListFromString() attr='%s'\n", attrString); result = _parseAttributeString(attrString, &attr); if ((result == PAPI_OK) && (attr.name != NULL)) { /* add this attribute to the list */ if ((attr.values != NULL) && (attr.values[0] != NULL)) { - result = papiAttributeListAdd( + result = papiAttributeListAddValue( attrs, PAPI_ATTR_APPEND, attr.name, attr.type, attr.values[0]); @@ -983,131 +952,230 @@ printf("papiAttributeListFromString() attr='%s'\n", attrString); return (result); } -papi_status_t -papiAttributeListToString(const papi_attribute_t **attrs, - const char *delim, char *buffer, const size_t buflen) +static papi_status_t +papiAttributeToString(papi_attribute_t *attribute, char *delim, + char *buffer, size_t buflen) { - return (PAPI_OPERATION_NOT_SUPPORTED); + papi_attribute_value_t **values = attribute->values; + int rc, i; + + strlcat(buffer, attribute->name, buflen); + strlcat(buffer, "=", buflen); + + if (values == NULL) + return (PAPI_OK); + + for (i = 0; values[i] != NULL; i++) { + switch (attribute->type) { + case PAPI_STRING: + rc = strlcat(buffer, values[i]->string, buflen); + break; + case PAPI_INTEGER: { + char string[24]; + + snprintf(string, sizeof (string), "%d", + values[i]->integer); + rc = strlcat(buffer, string, buflen); + } + break; + case PAPI_BOOLEAN: + rc = strlcat(buffer, (values[i]->boolean ? "true" : + "false"), buflen); + break; + case PAPI_RANGE: { + char string[24]; + + snprintf(string, sizeof (string), "%d-%d", + values[i]->range.lower, values[i]->range.upper); + rc = strlcat(buffer, string, buflen); + } + break; + case PAPI_RESOLUTION: { + char string[24]; + + snprintf(string, sizeof (string), "%dx%ddp%c", + values[i]->resolution.xres, + values[i]->resolution.yres, + (values[i]->resolution.units == PAPI_RES_PER_CM + ? 'c' : 'i')); + rc = strlcat(buffer, string, buflen); + } + break; + case PAPI_DATETIME: { + struct tm *tm = localtime(&values[i]->datetime); + + if (tm != NULL) { + char string[64]; + + strftime(string, sizeof (string), "%C", tm); + rc = strlcat(buffer, string, buflen); + }} + break; + case PAPI_COLLECTION: { + char *string = alloca(buflen); +#ifdef DEBUG + char prefix[256]; + + snprintf(prefix, sizeof (prefix), "%s %s(%d) ", delim, + attribute->name, i); + + papiAttributeListToString(values[i]->collection, + prefix, string, buflen); +#else + papiAttributeListToString(values[i]->collection, + delim, string, buflen); +#endif + rc = strlcat(buffer, string, buflen); + } + break; + default: { + char string[32]; + + snprintf(string, sizeof (string), "unknown-type-0x%x", + attribute->type); + rc = strlcat(buffer, string, buflen); + } + } + if (values[i+1] != NULL) + rc = strlcat(buffer, ",", buflen); + + if (rc >= buflen) + return (PAPI_NOT_POSSIBLE); + + } + + return (PAPI_OK); } -/* for debugging, not part of the public API */ -static char * -typeString(papi_attribute_value_type_t type) +papi_status_t +papiAttributeListToString(papi_attribute_t **attrs, + char *delim, char *buffer, size_t buflen) { - switch (type) { - case PAPI_STRING: - return ("string"); - case PAPI_INTEGER: - return ("integer"); - case PAPI_BOOLEAN: - return ("boolean"); - case PAPI_RANGE: - return ("range"); - case PAPI_RESOLUTION: - return ("resolution"); - case PAPI_DATETIME: - return ("datetime"); - case PAPI_COLLECTION: - return ("collection"); + papi_status_t status = PAPI_OK; + int i; + + if ((attrs == NULL) || (buffer == NULL)) + return (PAPI_BAD_ARGUMENT); + + buffer[0] = '\0'; + if (!delim) + delim = " "; + +#ifdef DEBUG + strlcat(buffer, delim, buflen); +#endif + for (i = 0; ((attrs[i] != NULL) && (status == PAPI_OK)); i++) { + status = papiAttributeToString(attrs[i], delim, buffer, buflen); + if (attrs[i+1] != NULL) + strlcat(buffer, delim, buflen); } - return ("unknown"); + return (status); } -void papiAttributeListPrint(FILE *fp, char *prefix, papi_attribute_t **list); +static int +is_in_list(char *value, char **list) +{ + if ((list != NULL) && (value != NULL)) { + int i; -void -papiAttributePrint(FILE *fp, char *prefix, papi_attribute_t *attribute) + for (i = 0; list[i] != NULL; i++) + if (strcasecmp(value, list[i]) == 0) + return (0); + } + + return (1); +} + +static papi_status_t +copy_attribute(papi_attribute_t ***list, papi_attribute_t *attribute) { - if (attribute != NULL) { - char *name = attribute->name; + papi_status_t status; + int i = 0; - if (prefix == NULL) - prefix = ""; + if ((list == NULL) || (attribute == NULL) || + (attribute->values == NULL)) + return (PAPI_BAD_ARGUMENT); -/* - * fprintf(fp, "%s'%s' (%s) =\n", prefix, (name ? name : "(NULL)"), - * typeString(attribute->type)); - */ - if (attribute->values != NULL) { - papi_attribute_value_t **values = attribute->values; - int i; + for (status = papiAttributeListAddValue(list, PAPI_ATTR_EXCL, + attribute->name, attribute->type, + attribute->values[i]); + ((status == PAPI_OK) && (attribute->values[i] != NULL)); + status = papiAttributeListAddValue(list, PAPI_ATTR_APPEND, + attribute->name, attribute->type, + attribute->values[i])) + i++; - for (i = 0; values[i] != NULL; i++) { - fprintf(fp, "%s=", (name ? name : "(NULL)")); -/* - * if (attribute->type != PAPI_COLLECTION) - * fprintf(fp, "%s\t", prefix); - */ - switch (attribute->type) { - case PAPI_STRING: - if ((strchr(values[i]->string, ' ') - != NULL) || - (strchr(values[i]->string, '\t') - != NULL)) { - /* quote the string */ - fprintf(fp, "\"%s\"", - values[i]->string); - } else { - fprintf(fp, "%s", - values[i]->string); - } - break; - case PAPI_INTEGER: - fprintf(fp, "%d", values[i]->integer); - break; - case PAPI_BOOLEAN: - fprintf(fp, "%s", (values[i]->boolean ? - "true" : "false")); - break; - case PAPI_RANGE: - fprintf(fp, "%d-%d", - values[i]->range.lower, - values[i]->range.upper); - break; - case PAPI_RESOLUTION: - fprintf(fp, "%dx%d", - values[i]->resolution.xres, - values[i]->resolution.yres); - break; - case PAPI_DATETIME: { - struct tm *tm; - - tm = localtime(&values[i]->datetime); - if (tm != NULL) { - char buf[64]; - - strftime(buf, sizeof (buf), - "%C", tm); - fprintf(fp, "%s", buf); - }} - break; - case PAPI_COLLECTION: { - char s[64]; - - snprintf(s, sizeof (s), "%s\t", prefix); - papiAttributeListPrint(fp, s, - values[i]->collection); - } - break; - default: - fprintf(fp, "unknown"); - } - if (attribute->type != PAPI_COLLECTION) - fprintf(fp, "\n"); - } - } - } + return (status); } +void +copy_attributes(papi_attribute_t ***result, papi_attribute_t **attributes) +{ + int i; + + if ((result == NULL) || (attributes == NULL)) + return; + + for (i = 0; attributes[i] != NULL; i++) + copy_attribute(result, attributes[i]); +} void -papiAttributeListPrint(FILE *fp, char *prefix, papi_attribute_t **list) +split_and_copy_attributes(char **list, papi_attribute_t **attributes, + papi_attribute_t ***in, papi_attribute_t ***out) { - if (list != NULL) { - int i; + int i; - for (i = 0; list[i] != NULL; i++) - papiAttributePrint(fp, prefix, list[i]); + if ((list == NULL) || (attributes == NULL)) + return; + + for (i = 0; attributes[i] != NULL; i++) + if (is_in_list(attributes[i]->name, list) == 0) + copy_attribute(in, attributes[i]); + else + copy_attribute(out, attributes[i]); +} + +void +papiAttributeListPrint(FILE *fp, papi_attribute_t **attributes, + char *prefix_fmt, ...) +{ + char *prefix = NULL; + char *buffer = NULL; + char *newfmt = NULL; + void *mem; + ssize_t size = 0; + va_list ap; + + newfmt = malloc(strlen(prefix_fmt) + 2); + sprintf(newfmt, "\n%s", prefix_fmt); + + va_start(ap, prefix_fmt); + while (vsnprintf(prefix, size, newfmt, ap) > size) { + size += 1024; + mem = realloc(prefix, size); + if (!mem) goto error; + prefix = mem; + } + va_end(ap); + + if (attributes) { + size = 0; + while (papiAttributeListToString(attributes, prefix, buffer, + size) != PAPI_OK) { + size += 1024; + mem = realloc(buffer, size); + if (!mem) goto error; + buffer = mem; + } } + + fprintf(fp, "%s%s\n", prefix, buffer ? buffer : ""); + fflush(fp); + + error: + free(newfmt); + free(prefix); + free(buffer); } diff --git a/usr/src/lib/print/libpapi-common/common/common.c b/usr/src/lib/print/libpapi-common/common/common.c new file mode 100644 index 0000000000..318b1d2c83 --- /dev/null +++ b/usr/src/lib/print/libpapi-common/common/common.c @@ -0,0 +1,132 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: common.c 151 2006-04-25 16:55:34Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Shared "unsupported" function implementations that can be overridden + * by libpapi and the various print service modules (psms). + */ + +#include <stdlib.h> +#include <papi.h> + +static papi_status_t +_unsupported() +{ + return (PAPI_OPERATION_NOT_SUPPORTED); +} + +static void * +_unsupported_null_return() +{ + return (NULL); +} + +static void +_unsupported_no_return() +{ +} + +/* + * Service interfaces + */ +#pragma weak papiServiceCreate = _unsupported +#pragma weak papiServiceDestroy = _unsupported_no_return +#pragma weak papiServiceSetPeer = _unsupported +#pragma weak papiServiceSetUserName = _unsupported +#pragma weak papiServiceSetPassword = _unsupported +#pragma weak papiServiceSetEncryption = _unsupported +#pragma weak papiServiceSetAuthCB = _unsupported +#pragma weak papiServiceSetAppData = _unsupported + +#pragma weak papiServiceGetServiceName = _unsupported_null_return +#pragma weak papiServiceGetUserName = _unsupported_null_return +#pragma weak papiServiceGetPassword = _unsupported_null_return +#pragma weak papiServiceGetAppData = _unsupported_null_return + +papi_encryption_t +papiServiceGetEncryption(papi_service_t handle) +{ + return (PAPI_ENCRYPT_NEVER); +} + +#pragma weak papiServiceGetAttributeList = _unsupported_null_return +#pragma weak papiServiceGetStatusMessage = _unsupported_null_return + +/* + * Printer operations + */ +#pragma weak papiPrintersList = _unsupported +#pragma weak papiPrinterQuery = _unsupported +#pragma weak papiPrinterEnable = _unsupported +#pragma weak papiPrinterDisable = _unsupported +#pragma weak papiPrinterPause = _unsupported +#pragma weak papiPrinterResume = _unsupported +#pragma weak papiPrinterAdd = _unsupported +#pragma weak papiPrinterModify = _unsupported +#pragma weak papiPrinterRemove = _unsupported +#pragma weak papiPrinterPurgeJobs = _unsupported +#pragma weak papiPrinterListJobs = _unsupported +#pragma weak papiPrinterGetAttributeList = _unsupported_null_return +#pragma weak papiPrinterFree = _unsupported_no_return +#pragma weak papiPrinterListFree = _unsupported_no_return + +/* + * Job interfaces + */ +#pragma weak papiJobHold = _unsupported +#pragma weak papiJobRelease = _unsupported +#pragma weak papiJobRestart = _unsupported +#pragma weak papiJobPromote = _unsupported +#pragma weak papiJobModify = _unsupported +#pragma weak papiJobSubmit = _unsupported +#pragma weak papiJobSubmitByReference = _unsupported +#pragma weak papiJobValidate = _unsupported +#pragma weak papiJobStreamOpen = _unsupported +#pragma weak papiJobStreamWrite = _unsupported +#pragma weak papiJobStreamClose = _unsupported +#pragma weak papiJobQuery = _unsupported +#pragma weak papiJobMove = _unsupported +#pragma weak papiJobCancel = _unsupported +#pragma weak papiJobGetAttributeList = _unsupported_null_return +#pragma weak papiJobGetPrinterName = _unsupported_null_return +#pragma weak papiJobCreate = _unsupported +#pragma weak papiJobStreamAdd = _unsupported +#pragma weak papiJobCommit = _unsupported + +int +papiJobGetId(papi_job_t job) +{ + return (-1); +} + +#pragma weak papiJobGetJobTicket = _unsupported_null_return +#pragma weak papiJobFree = _unsupported_no_return +#pragma weak papiJobListFree = _unsupported_no_return diff --git a/usr/src/lib/print/libpapi-common/common/config-site.h b/usr/src/lib/print/libpapi-common/common/config-site.h new file mode 100644 index 0000000000..2007f4f669 --- /dev/null +++ b/usr/src/lib/print/libpapi-common/common/config-site.h @@ -0,0 +1,60 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +#ifndef _CONFIG_SITE_H +#define _CONFIG_SITE_H + +/* $Id: config-site.h.in 171 2006-05-20 06:00:32Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <config.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* the "default" destination for various commands and libraries */ +#define DEFAULT_DEST "_default" + +/* the "default" server uri to fallback to */ +#define DEFAULT_SERVICE_URI "lpsched://localhost/printers" + +/* the "default" IPP service to fallback to in the IPP psm */ +#define DEFAULT_IPP_SERVICE_URI "ipp://localhost/printers" + +/* the name of the SUID lpd-port binary that hands psm-lpd a connected socket */ +#define SUID_LPD_PORT "/usr/lib/print/lpd-port" + +/* enable/disable printer-uri in enumeration results */ +#define NEED_BROKEN_PRINTER_URI_SEMANTIC + +#ifdef __cplusplus +} +#endif + +#endif /* _CONFIG_SITE_H */ diff --git a/usr/src/lib/print/libpapi-common/common/config.h b/usr/src/lib/print/libpapi-common/common/config.h new file mode 100644 index 0000000000..280ac6d6b4 --- /dev/null +++ b/usr/src/lib/print/libpapi-common/common/config.h @@ -0,0 +1,159 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +#ifndef _CONFIG_H +#define _CONFIG_H + +/* source/libpapi-common/config.h. Generated by configure. */ +/* source/libpapi-common/config.h.in. Generated from configure.in by autoheader. */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the `dlopen' function. */ +#define HAVE_DLOPEN 1 + +/* Define to 1 if you have the `dlsym' function. */ +#define HAVE_DLSYM 1 + +/* Define to 1 if you have the `fprintf' function. */ +#define HAVE_FPRINTF 1 + +/* define if you have getipnodbyname */ +#define HAVE_GETIPNODEBYNAME 1 + +/* Define to 1 if you have the `getpassphrase' function. */ +#define HAVE_GETPASSPHRASE 1 + +/* Define to 1 if you have the `gettext' function. */ +#define HAVE_GETTEXT 1 + +/* Define to 1 if you have the <inttypes.h> header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `is_system_labeled' function. */ +#define HAVE_IS_SYSTEM_LABELED 1 + +/* Define to 1 if you have the `localtime' function. */ +#define HAVE_LOCALTIME 1 + +/* Define to 1 if you have the <memory.h> header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the <priv.h> header file. */ +#define HAVE_PRIV_H 1 + +/* define if you have rresvport_af */ +#define HAVE_RRESVPORT_AF 1 + +/* Define to 1 if you have the <ruby.h> header file. */ +/* #undef HAVE_RUBY_H */ + +/* Define to 1 if you have the `snprintf' function. */ +#define HAVE_SNPRINTF 1 + +/* Define to 1 if you have the <stdarg.h> header file. */ +#define HAVE_STDARG_H 1 + +/* Define to 1 if you have the <stdint.h> header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the <stdlib.h> header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strcmp' function. */ +#define HAVE_STRCMP 1 + +/* Define to 1 if you have the `strdup' function. */ +#define HAVE_STRDUP 1 + +/* Define to 1 if you have the `strerror' function. */ +#define HAVE_STRERROR 1 + +/* Define to 1 if you have the `strftime' function. */ +#define HAVE_STRFTIME 1 + +/* Define to 1 if you have the <strings.h> header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the <string.h> header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strlcat' function. */ +#define HAVE_STRLCAT 1 + +/* Define to 1 if you have the `strlcpy' function. */ +#define HAVE_STRLCPY 1 + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the <sys/types.h> header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the <unistd.h> header file. */ +#define HAVE_UNISTD_H 1 + +/* Name of package */ +#define PACKAGE "papi" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +#define VERSION "1.0_rc1" + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + + +#ifdef __cplusplus +} +#endif + +#endif /* _CONFIG_H */ diff --git a/usr/src/lib/print/libpapi-common/common/library.c b/usr/src/lib/print/libpapi-common/common/library.c new file mode 100644 index 0000000000..12b1ffb449 --- /dev/null +++ b/usr/src/lib/print/libpapi-common/common/library.c @@ -0,0 +1,105 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: library.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/*LINTLIBRARY*/ + +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <alloca.h> +#include <libintl.h> +#include <papi.h> + +static char *calls[] = { + /* Attribute Calls */ + "papiAttributeListAddValue", + "papiAttributeListAddBoolean", "papiAttributeListAddCollection", + "papiAttributeListAddDatetime", "papiAttributeListAddInteger", + "papiAttributeListAddMetadata", "papiAttributeListAddRange", + "papiAttributeListAddResolution", "papiAttributeListAddString", + "papiAttributeListDelete", + "papiAttributeListGetValue", "papiAttributeListGetNext", + "papiAttributeListFind", + "papiAttributeListGetBoolean", "papiAttributeListGetCollection", + "papiAttributeListGetDatetime", "papiAttributeListGetInteger", + "papiAttributeListGetMetadata", "papiAttributeListGetRange", + "papiAttributeListGetResolution", "papiAttributeListGetString", + "papiAttributeListFromString", "papiAttributeListToString", + "papiAttributeListFree", + /* Job Calls */ + "papiJobSubmit", "papiJobSubmitByReference", "papiJobValidate", + "papiJobStreamOpen", "papiJobStreamWrite", "papiJobStreamClose", + "papiJobQuery", "papiJobModify", "papiJobCancel", "papiJobPromote", + "papiJobGetAttributeList", "papiJobGetId", "papiJobGetPrinterName", + "papiJobGetJobTicket", + "papiJobFree", "papiJobListFree", + "papiJobHold", "papiJobRelease", "papiJobRestart", + /* Printer Calls */ + "papiPrintersList", "papiPrinterQuery", "papiPrinterModify", + "papiPrinterAdd", "papiPrinterRemove", + "papiPrinterPause", "papiPrinterResume", + "papiPrinterDisable", "papiPrinterEnable", + "papiPrinterPurgeJobs", "papiPrinterListJobs", + "papiPrinterGetAttributeList", + "papiPrinterFree", "papiPrinterListFree", + /* Service Calls */ + "papiServiceCreate", "papiServiceDestroy", + "papiServiceGetAppData", + "papiServiceGetEncryption", "papiServiceGetPassword", + "papiServiceGetServiceName", "papiServiceGetUserName", + "papiServiceSetAppData", "papiServiceSetAuthCB", + "papiServiceSetEncryption", "papiServiceSetPassword", + "papiServiceSetUserName", + "papiServiceGetAttributeList", "papiServiceGetStatusMessage", + /* Misc Calls */ + "papiStatusString", + "papiLibrarySupportedCall", "papiLibrarySupportedCalls", + NULL +}; + +char ** +papiLibrarySupportedCalls() +{ + return (calls); +} + +char +papiLibrarySupportedCall(const char *name) +{ + int i; + + for (i = 0; calls[i] != NULL; i++) + if (strcmp(name, calls[i]) == 0) + return (PAPI_TRUE); + + return (PAPI_FALSE); +} diff --git a/usr/src/cmd/lp/lib/papi/list.c b/usr/src/lib/print/libpapi-common/common/list.c index fb5451232f..9ed0d2ded2 100644 --- a/usr/src/cmd/lp/lib/papi/list.c +++ b/usr/src/lib/print/libpapi-common/common/list.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,11 +18,15 @@ * * CDDL HEADER END */ + /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * */ +/* $Id: list.c 146 2006-03-24 00:26:54Z njacobs $ */ + #pragma ident "%Z%%M% %I% %E% SMI" /*LINTLIBRARY*/ diff --git a/usr/src/lib/print/libpapi-common/common/mapfile b/usr/src/lib/print/libpapi-common/common/mapfile new file mode 100644 index 0000000000..81f8f0308f --- /dev/null +++ b/usr/src/lib/print/libpapi-common/common/mapfile @@ -0,0 +1,151 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# $Id: mapfile.in,v 1.2 2006/03/02 06:31:36 njacobs Exp $ +# + +# ident "%Z%%M% %I% %E% SMI" + +# +# Common interfaces that are most likely to be shared amongst the various +# PAPI implementations. +# + +SUNW_1.0 { + global: + # PAPI Attribute Calls + papiAttributeListAddValue; + papiAttributeListAddBoolean; + papiAttributeListAddCollection; + papiAttributeListAddDatetime; + papiAttributeListAddInteger; + papiAttributeListAddMetadata; + papiAttributeListAddRange; + papiAttributeListAddResolution; + papiAttributeListAddString; + papiAttributeListDelete; + papiAttributeListGetValue; + papiAttributeListGetNext; + papiAttributeListFind; + papiAttributeListGetBoolean; + papiAttributeListGetCollection; + papiAttributeListGetDatetime; + papiAttributeListGetInteger; + papiAttributeListGetMetadata; + papiAttributeListGetRange; + papiAttributeListGetResolution; + papiAttributeListGetString; + papiAttributeListFromString; + papiAttributeListToString; + papiAttributeListFree; + + # PAPI Service Calls + papiServiceCreate; + papiServiceDestroy; + papiServiceSetUserName; + papiServiceSetPassword; + papiServiceSetEncryption; + papiServiceSetAuthCB; + papiServiceSetAppData; + papiServiceGetUserName; + papiServiceGetPassword; + papiServiceGetEncryption; + papiServiceGetAppData; + papiServiceGetServiceName; + papiServiceGetAttributeList; + papiServiceGetStatusMessage; + + # PAPI Printer Calls + papiPrintersList; + papiPrinterQuery; + papiPrinterAdd; + papiPrinterModify; + papiPrinterRemove; + papiPrinterDisable; + papiPrinterEnable; + papiPrinterPause; + papiPrinterResume; + papiPrinterPurgeJobs; + papiPrinterListJobs; + papiPrinterGetAttributeList; + papiPrinterFree; + papiPrinterListFree; + + # PAPI Job Calls + papiJobSubmit; + papiJobSubmitByReference; + papiJobValidate; + papiJobStreamOpen; + papiJobStreamWrite; + papiJobStreamClose; + papiJobQuery; + papiJobModify; + papiJobMove; + papiJobCancel; + papiJobHold; + papiJobRelease; + papiJobRestart; + papiJobPromote; + papiJobGetAttributeList; + papiJobGetPrinterName; + papiJobGetId; + papiJobGetJobTicket; + papiJobFree; + papiJobListFree; + + # Misc. PAPI Calls + papiStatusString; + papiLibrarySupportedCall; + papiLibrarySupportedCalls; +}; + +SUNWprivate_1.0 { # Misc. semi-private supporting calls + global: + papiServiceSetPeer; + papiJobCreate; + papiJobStreamAdd; + papiJobCommit; + + # URI + uri_from_string; + uri_to_string; + uri_free; + # list + list_remove; + list_append; + list_concatenate; + + # extra Attribute Calls + copy_attributes; + split_and_copy_attributes; + papiAttributeListPrint; + + local: + *; +}; + +FSG_1.0 {} SUNW_1.0; diff --git a/usr/src/lib/print/libpapi-common/common/misc.c b/usr/src/lib/print/libpapi-common/common/misc.c new file mode 100644 index 0000000000..646a26e18a --- /dev/null +++ b/usr/src/lib/print/libpapi-common/common/misc.c @@ -0,0 +1,87 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: misc.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/*LINTLIBRARY*/ + +#include <string.h> +#include <papi.h> + +#include <config-site.h> + +/* + * The implementations of strlcpy() and strlcat() have been taken directly + * from OpenSolaris. The contents of this file originated from + * usr/src/lib/libc/port/gen/strlcpy.c + * usr/src/lib/libc/port/gen/strcat.c + */ + +#ifndef HAVE_STRLCPY +size_t +strlcpy(char *dst, const char *src, size_t len) +{ + size_t slen = strlen(src); + size_t copied; + + if (len == 0) + return (slen); + + if (slen >= len) + copied = len - 1; + else + copied = slen; + (void) memcpy(dst, src, copied); + dst[copied] = '\0'; + return (slen); +} +#endif + +#ifndef HAVE_STRLCAT +size_t +strlcat(char *dst, const char *src, size_t dstsize) +{ + char *df = dst; + size_t left = dstsize; + size_t l1; + size_t l2 = strlen(src); + size_t copied; + + while (left-- != 0 && *df != '\0') + df++; + l1 = df - dst; + if (dstsize == l1) + return (l1 + l2); + + copied = l1 + l2 >= dstsize ? dstsize - l1 - 1 : l2; + (void) memcpy(dst + l1, src, copied); + dst[l1+copied] = '\0'; + return (l1 + l2); +} +#endif diff --git a/usr/src/cmd/lp/lib/papi/papi.h b/usr/src/lib/print/libpapi-common/common/papi.h index 1ba622aa2a..7c1d891eb2 100644 --- a/usr/src/cmd/lp/lib/papi/papi.h +++ b/usr/src/lib/print/libpapi-common/common/papi.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,14 +18,18 @@ * * CDDL HEADER END */ + /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * */ #ifndef _PAPI_H #define _PAPI_H +/* $Id: papi.h 161 2006-05-03 04:32:59Z njacobs $ */ + #pragma ident "%Z%%M% %I% %E% SMI" #include <sys/types.h> @@ -62,7 +65,8 @@ typedef enum { PAPI_RANGE, PAPI_RESOLUTION, PAPI_DATETIME, - PAPI_COLLECTION + PAPI_COLLECTION, + PAPI_METADATA } papi_attribute_value_type_t; typedef enum { @@ -75,6 +79,15 @@ enum { /* for boolean values */ PAPI_TRUE = 1 }; +typedef enum { + PAPI_UNSUPPORTED = 0x10, + PAPI_DEFAULT = 0x11, + PAPI_UNKNOWN, + PAPI_NO_VALUE, + PAPI_NOT_SETTABLE = 0x15, + PAPI_DELETE = 0x16 +} papi_metadata_t; + #define PAPI_LIST_JOBS_OTHERS 0x0001 #define PAPI_LIST_JOBS_COMPLETED 0x0002 #define PAPI_LIST_JOBS_NOT_COMPLETED 0x0004 @@ -97,6 +110,7 @@ typedef union { } resolution; time_t datetime; /* PAPI_DATETIME value */ papi_attribute_t **collection; /* PAPI_COLLECTION value */ + papi_metadata_t metadata; /* PAPI_METADATA value */ } papi_attribute_value_t; struct papi_attribute_s { @@ -214,195 +228,218 @@ enum { /* Service related */ extern papi_status_t papiServiceCreate(papi_service_t *handle, - const char *service_name, - const char *user_name, - const char *password, - const int (*authCB)(papi_service_t svc), - const papi_encryption_t encryption, + char *service_name, char *user_name, + char *password, + int (*authCB)(papi_service_t svc, + void *app_data), + papi_encryption_t encryption, void *app_data); extern void papiServiceDestroy(papi_service_t handle); extern papi_status_t papiServiceSetUserName(papi_service_t handle, - const char *user_name); + char *user_name); extern papi_status_t papiServiceSetPassword(papi_service_t handle, - const char *password); + char *password); extern papi_status_t papiServiceSetEncryption(papi_service_t handle, - const papi_encryption_t encryption); + papi_encryption_t encryption); extern papi_status_t papiServiceSetAuthCB(papi_service_t handle, - const int (*authCB)(papi_service_t s)); + int (*authCB)(papi_service_t s, + void *app_data)); extern papi_status_t papiServiceSetAppData(papi_service_t handle, - const void *app_data); + void *app_data); extern char *papiServiceGetServiceName(papi_service_t handle); extern char *papiServiceGetUserName(papi_service_t handle); extern char *papiServiceGetPassword(papi_service_t handle); extern papi_encryption_t papiServiceGetEncryption(papi_service_t handle); extern void *papiServiceGetAppData(papi_service_t handle); +extern papi_attribute_t **papiServiceGetAttributeList(papi_service_t handle); extern char *papiServiceGetStatusMessage(papi_service_t handle); /* Attribute related */ -extern papi_status_t papiAttributeListAdd(papi_attribute_t ***attrs, - const int flags, - const char *name, - const papi_attribute_value_type_t type, - const papi_attribute_value_t *value); +extern papi_status_t papiAttributeListAddValue(papi_attribute_t ***attrs, + int flags, char *name, + papi_attribute_value_type_t type, + papi_attribute_value_t *value); extern papi_status_t papiAttributeListAddString(papi_attribute_t ***attrs, - const int flags, const char *name, - const char *string); + int flags, char *name, char *string); extern papi_status_t papiAttributeListAddInteger(papi_attribute_t ***attrs, - const int flags, const char *name, - const int integer); + int flags, char *name, int integer); extern papi_status_t papiAttributeListAddBoolean(papi_attribute_t ***attrs, - const int flags, const char *name, - const char boolean); + int flags, char *name, char boolean); extern papi_status_t papiAttributeListAddRange(papi_attribute_t ***attrs, - const int flags, const char *name, - const int lower, const int upper); + int flags, char *name, + int lower, int upper); extern papi_status_t papiAttributeListAddResolution(papi_attribute_t ***attrs, - const int flags, const char *name, - const int xres, const int yres, + int flags, char *name, + int xres, int yres, papi_resolution_unit_t units); extern papi_status_t papiAttributeListAddDatetime(papi_attribute_t ***attrs, - const int flags, const char *name, - const time_t datetime); + int flags, char *name, time_t datetime); extern papi_status_t papiAttributeListAddCollection(papi_attribute_t ***attrs, - const int flags, const char *name, - const papi_attribute_t **collection); + int flags, char *name, + papi_attribute_t **collection); +extern papi_status_t papiAttributeListAddMetadata(papi_attribute_t ***attrs, + int flags, char *name, + papi_metadata_t metadata); extern papi_status_t papiAttributeListDelete(papi_attribute_t ***attributes, - const char *name); + char *name); extern papi_status_t papiAttributeListGetValue(papi_attribute_t **list, - void **iterator, const char *name, + void **iterator, char *name, papi_attribute_value_type_t type, papi_attribute_value_t **value); extern papi_status_t papiAttributeListGetString(papi_attribute_t **list, - void **iterator, const char *name, + void **iterator, char *name, char **vptr); extern papi_status_t papiAttributeListGetInteger(papi_attribute_t **list, - void **iterator, const char *name, - int *vptr); + void **iterator, char *name, int *vptr); extern papi_status_t papiAttributeListGetBoolean(papi_attribute_t **list, - void **iterator, const char *name, + void **iterator, char *name, char *vptr); extern papi_status_t papiAttributeListGetRange(papi_attribute_t **list, - void **iterator, const char *name, + void **iterator, char *name, int *min, int *max); extern papi_status_t papiAttributeListGetResolution(papi_attribute_t **list, - void **iterator, const char *name, + void **iterator, char *name, int *x, int *y, papi_resolution_unit_t *units); extern papi_status_t papiAttributeListGetDatetime(papi_attribute_t **list, - void **iterator, const char *name, + void **iterator, char *name, time_t *dt); extern papi_status_t papiAttributeListGetCollection(papi_attribute_t **list, - void **iterator, const char *name, + void **iterator, char *name, papi_attribute_t ***collection); +extern papi_status_t papiAttributeListGetMetadata(papi_attribute_t **list, + void **iterator, char *name, + papi_metadata_t *vptr); extern papi_attribute_t *papiAttributeListFind(papi_attribute_t **list, - const char *name); + char *name); extern papi_attribute_t *papiAttributeListGetNext(papi_attribute_t **list, void **iterator); extern void papiAttributeListFree(papi_attribute_t **attributes); extern papi_status_t papiAttributeListFromString(papi_attribute_t ***attrs, - const int flags, const char *string); -extern papi_status_t papiAttributeListToString(const papi_attribute_t **attrs, - const char *delim, - char *buffer, const size_t buflen); -extern void papiAttributeListPrint - (FILE *fp, char *prefix, papi_attribute_t **list); + int flags, char *string); +extern papi_status_t papiAttributeListToString(papi_attribute_t **attrs, + char *delim, + char *buffer, size_t buflen); +extern void papiAttributeListPrint(FILE *fp, papi_attribute_t **list, + char *prefix_fmt, ...); /* Printer related */ extern papi_status_t papiPrintersList(papi_service_t handle, - const char **requested_attrs, - const papi_filter_t *filter, + char **requested_attrs, + papi_filter_t *filter, papi_printer_t **printers); -extern papi_status_t papiPrinterQuery(papi_service_t handle, const char *name, - const char **requested_attrs, - const papi_attribute_t **job_attributes, +extern papi_status_t papiPrinterQuery(papi_service_t handle, char *name, + char **requested_attrs, + papi_attribute_t **job_attributes, + papi_printer_t *printer); +extern papi_status_t papiPrinterAdd(papi_service_t handle, char *name, + papi_attribute_t **attributes, papi_printer_t *printer); -extern papi_status_t papiPrinterModify(papi_service_t handle, const char *name, - const papi_attribute_t **attributes, +extern papi_status_t papiPrinterModify(papi_service_t handle, char *name, + papi_attribute_t **attributes, papi_printer_t *printer); -extern papi_status_t papiPrinterPause(papi_service_t handle, const char *name, - const char *message); -extern papi_status_t papiPrinterResume(papi_service_t handle, const char *name); +extern papi_status_t papiPrinterRemove(papi_service_t handle, char *name); +extern papi_status_t papiPrinterDisable(papi_service_t handle, char *name, + char *message); +extern papi_status_t papiPrinterEnable(papi_service_t handle, char *name); +extern papi_status_t papiPrinterPause(papi_service_t handle, char *name, + char *message); +extern papi_status_t papiPrinterResume(papi_service_t handle, char *name); extern papi_status_t papiPrinterPurgeJobs(papi_service_t handle, - const char *name, papi_job_t **jobs); + char *name, papi_job_t **jobs); extern papi_status_t papiPrinterListJobs(papi_service_t handle, - const char *name, - const char **requested_attrs, - const int type_mask, - const int max_num_jobs, + char *name, char **requested_attrs, + int type_mask, int max_num_jobs, papi_job_t **jobs); extern papi_attribute_t **papiPrinterGetAttributeList(papi_printer_t printer); extern void papiPrinterFree(papi_printer_t printer); extern void papiPrinterListFree(papi_printer_t *printers); /* Job related */ -extern papi_status_t papiJobSubmit(papi_service_t handle, const char *printer, - const papi_attribute_t **job_attributes, - const papi_job_ticket_t *job_ticket, - const char **files, papi_job_t *job); +extern 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); extern papi_status_t papiJobSubmitByReference(papi_service_t handle, - const char *printer, - const papi_attribute_t **job_attributes, - const papi_job_ticket_t *job_ticket, - const char **files, papi_job_t *job); -extern papi_status_t papiJobValidate(papi_service_t handle, const char *printer, - const papi_attribute_t **job_attributes, - const papi_job_ticket_t *job_ticket, - const char **files, papi_job_t *job); + char *printer, + papi_attribute_t **job_attributes, + papi_job_ticket_t *job_ticket, + char **files, papi_job_t *job); +extern papi_status_t papiJobValidate(papi_service_t handle, char *printer, + papi_attribute_t **job_attributes, + papi_job_ticket_t *job_ticket, + char **files, papi_job_t *job); extern papi_status_t papiJobStreamOpen(papi_service_t handle, - const char *printer, - const papi_attribute_t **job_attributes, - const papi_job_ticket_t *job_ticket, + char *printer, + papi_attribute_t **job_attributes, + papi_job_ticket_t *job_ticket, papi_stream_t *stream); extern papi_status_t papiJobStreamWrite(papi_service_t handle, papi_stream_t stream, - const void *buffer, - const size_t buflen); + void *buffer, size_t buflen); extern papi_status_t papiJobStreamClose(papi_service_t handle, papi_stream_t stream, papi_job_t *job); -extern papi_status_t papiJobQuery(papi_service_t handle, const char *printer, - const int32_t job_id, - const char **requested_attrs, +extern papi_status_t papiJobQuery(papi_service_t handle, char *printer, + int32_t job_id, char **requested_attrs, papi_job_t *job); -extern papi_status_t papiJobModify(papi_service_t handle, const char *printer, - const int32_t job_id, - const papi_attribute_t **attributes, +extern papi_status_t papiJobModify(papi_service_t handle, char *printer, + int32_t job_id, + papi_attribute_t **attributes, papi_job_t *job); -extern papi_status_t papiJobCancel(papi_service_t handle, const char *printer, - const int32_t job_id); -extern papi_status_t papiJobHold(papi_service_t handle, const char *printer, - const int32_t job_id, - const char *hold_until, - const time_t *hold_until_time); -extern papi_status_t papiJobRelease(papi_service_t handle, const char *printer, - const int32_t job_id); -extern papi_status_t papiJobRestart(papi_service_t handle, const char *printer, - const int32_t job_id); -extern papi_attribute_t **papiJobGetAttributeList(papi_printer_t printer); -extern char *papiJobGetPrinterName(papi_printer_t printer); -extern int32_t papiJobGetId(papi_printer_t printer); -extern papi_job_ticket_t *papiJobGetJobTicket(papi_printer_t printer); +extern papi_status_t papiJobMove(papi_service_t handle, char *printer, + int32_t job_id, char *destination); +extern papi_status_t papiJobCancel(papi_service_t handle, char *printer, + int32_t job_id); +extern papi_status_t papiJobHold(papi_service_t handle, char *printer, + int32_t job_id); +extern papi_status_t papiJobRelease(papi_service_t handle, char *printer, + int32_t job_id); +extern papi_status_t papiJobRestart(papi_service_t handle, char *printer, + int32_t job_id); +extern papi_status_t papiJobPromote(papi_service_t handle, char *printer, + int32_t job_id); +extern papi_attribute_t **papiJobGetAttributeList(papi_job_t printer); +extern char *papiJobGetPrinterName(papi_job_t printer); +extern int32_t papiJobGetId(papi_job_t printer); +extern papi_job_ticket_t *papiJobGetJobTicket(papi_job_t printer); extern void papiJobFree(papi_job_t job); extern void papiJobListFree(papi_job_t *jobs); -#ifdef SOLARIS_PRIVATE_POST_1_0 +#ifdef SOLARIS_PRIVATE_POST_0_9 /* - * These have been added to support IPP create-job/send-document with PAPI v1.0 + * These have been added to support IPP create-job/send-document with PAPI v0.9 * in an IPP listener using PAPI as it's spooler interface. A future version * of the API is expected to support this type of functionality */ -extern papi_status_t papiJobCreate(papi_service_t handle, const char *printer, - const papi_attribute_t **job_attributes, - const papi_job_ticket_t *job_ticket, +extern papi_status_t papiJobCreate(papi_service_t handle, char *printer, + papi_attribute_t **job_attributes, + papi_job_ticket_t *job_ticket, papi_job_t *job); -extern papi_status_t papiJobStreamAdd(papi_service_t handle, papi_job_t job, - papi_attribute_t **document_attributes, - papi_stream_t *stream); -extern papi_status_t papiJobCommit(papi_service_t handle, papi_job_t job); -#endif /* SOLARIS_PRIVATE_POST_1_0 */ +extern papi_status_t papiJobStreamAdd(papi_service_t handle, char *printer, + int32_t id, papi_stream_t *stream); +extern papi_status_t papiJobCommit(papi_service_t handle, char *printer, + int32_t id); +extern papi_status_t papiServiceSetPeer(papi_service_t handle, int peerfd); +#endif /* SOLARIS_PRIVATE_POST_0_9 */ -extern char *papiStatusString(const papi_status_t status); +extern char *papiStatusString(papi_status_t status); + +/* + * Internal functions that aren't in the API, but are shared across + * protocol support implementations(psms) and the tightly bound + * listener library. Do not use these in your applications. + */ +extern void list_append(); +extern void list_concatenate(); +extern void list_remove(); +extern void copy_attributes(papi_attribute_t ***result, + papi_attribute_t **list); +extern void split_and_copy_attributes(char **list, + papi_attribute_t **attributes, + papi_attribute_t ***in, + papi_attribute_t ***out); #ifdef __cplusplus } diff --git a/usr/src/cmd/lp/lib/papi/status.c b/usr/src/lib/print/libpapi-common/common/status.c index 61f6d20739..897aa1322d 100644 --- a/usr/src/cmd/lp/lib/papi/status.c +++ b/usr/src/lib/print/libpapi-common/common/status.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,18 +18,19 @@ * * CDDL HEADER END */ + /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * */ -#pragma ident "%Z%%M% %I% %E% SMI" - -/*LINTLIBRARY*/ +/* $Id: status.c 146 2006-03-24 00:26:54Z njacobs $ */ +#pragma ident "%Z%%M% %I% %E% SMI" #include <stdlib.h> -#include <papi_impl.h> +#include <papi.h> #include <libintl.h> char * diff --git a/usr/src/lib/print/libpapi-common/common/uri.c b/usr/src/lib/print/libpapi-common/common/uri.c new file mode 100644 index 0000000000..9cc6f59006 --- /dev/null +++ b/usr/src/lib/print/libpapi-common/common/uri.c @@ -0,0 +1,303 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: uri.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/*LINTLIBRARY*/ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/types.h> +#include <errno.h> +#include "uri.h" + +static char * +strndup(char *string, size_t length) +{ + char *result = NULL; + + if (length > 0) { + length++; + + + if ((result = calloc(1, length)) != NULL) + (void) strlcat(result, string, length); + } + + return (result); +} + + +/* + * This will handle the following forms: + * scheme:scheme_data + * scheme://[[user[:password]@]host[:port]]/path[[#fragment]|[?query]] + */ +int +uri_from_string(char *string, uri_t **uri) +{ + char *ptr; + uri_t *u; + + if ((string == NULL) || (uri == NULL)) { + errno = EINVAL; + return (-1); + } + + /* find the scheme:scheme_part split */ + if ((ptr = strchr(string, ':')) == NULL) { + errno = EINVAL; + return (-1); + } + + if ((*uri = u = calloc(1, sizeof (*u))) == NULL) + return (-1); + + u->scheme = strndup(string, ptr - string); + + if ((ptr[1] == '/') && (ptr[2] == '/')) { + /* + * CSTYLED + * scheme://[host_part]/[path_part] + */ + char *end = NULL, *user = NULL, *host = NULL, *path = NULL; + + string = ptr + 3; /* skip the :// */ + + if ((path = end = strchr(string, '/')) == NULL) + for (end = string; *end != '\0'; end++); + + u->host_part = strndup(string, end - string); + + for (host = string; host < end; host ++) + if (*host == '@') { + /* string to host is the user part */ + u->user_part = strndup(string, host-string); + /* host+1 to end is the host part */ + u->host_part = strndup(host + 1, + end - (host+1)); + user = string; + host++; + break; + } + + if (user != NULL) { + char *password = NULL; + + for (password = user; (password < host - 1); password++) + if (*password == ':') { + u->password = strndup(password + 1, + host - password - 2); + break; + } + u->user = strndup(user, password - user); + } else + host = string; + + if (host != NULL) { + char *port = NULL; + + for (port = host; (port < path); port++) + if ((*port == ':') || (*port == '/')) + break; + + if (port < path) { + u->port = strndup(port + 1, path - port - 1); + } + + u->host = strndup(host, port - host); + } + + if (path != NULL) { + char *name = strrchr(path, '/'); + + u->path_part = strdup(path); + + if (name != NULL) { + char *query, *fragment; + + query = strrchr(name, '?'); + if ((query != NULL) && (*query != '\0')) { + u->query = strdup(query + 1); + end = query; + } else + for (end = path; *end != '\0'; end++); + + fragment = strrchr(name, '#'); + if ((fragment != NULL) && (*fragment != '\0')) { + u->fragment = strndup(fragment + 1, + end - fragment - 1); + end = fragment; + } + + u->path = strndup(path, end - path); + } + } + } else { /* scheme:scheme_part */ + u->scheme_part = strdup(&ptr[1]); + } + + return (0); +} + +int +uri_to_string(uri_t *uri, char *buffer, size_t buflen) +{ + if ((uri == NULL) || (buffer == NULL) || (buflen == 0) || + (uri->scheme == NULL) || + ((uri->password != NULL) && (uri->user == NULL)) || + ((uri->user != NULL) && (uri->host == NULL)) || + ((uri->port != NULL) && (uri->host == NULL)) || + ((uri->fragment != NULL) && (uri->path == NULL)) || + ((uri->query != NULL) && (uri->path == NULL))) { + errno = EINVAL; + return (-1); + } + + (void) memset(buffer, 0, buflen); + + if (uri->scheme_part == NULL) { + (void) snprintf(buffer, buflen, + "%s://%s%s%s%s%s%s%s%s%s%s%s%s%s", + uri->scheme, + (uri->user ? uri->user : ""), + (uri->password ? ":" : ""), + (uri->password ? uri->password : ""), + (uri->user ? "@": ""), + (uri->host ? uri->host : ""), + (uri->port ? ":" : ""), + (uri->port ? uri->port : ""), + (uri->path[0] != '/' ? "/" : ""), uri->path, + (uri->fragment ? "#" : ""), + (uri->fragment ? uri->fragment : ""), + (uri->query ? "?" : ""), + (uri->query ? uri->query : "")); + } else { + (void) snprintf(buffer, buflen, "%s:%s", uri->scheme, + uri->scheme_part); + } + + return (0); +} + +void +uri_free(uri_t *uri) +{ + if (uri != NULL) { + if (uri->scheme != NULL) + free(uri->scheme); + if (uri->scheme_part != NULL) + free(uri->scheme_part); + if (uri->user != NULL) + free(uri->user); + if (uri->password != NULL) + free(uri->password); + if (uri->host != NULL) + free(uri->host); + if (uri->port != NULL) + free(uri->port); + if (uri->path != NULL) + free(uri->path); + if (uri->fragment != NULL) + free(uri->fragment); + if (uri->query != NULL) + free(uri->query); + /* help me debug */ + if (uri->user_part != NULL) + free(uri->user_part); + if (uri->host_part != NULL) + free(uri->host_part); + if (uri->path_part != NULL) + free(uri->path_part); + free(uri); + } +} + +#ifdef DEADBEEF +static void +uri_dump(FILE *fp, uri_t *uri) +{ + if (uri != NULL) { + fprintf(fp, "URI:\n"); + if (uri->scheme != NULL) + fprintf(fp, "scheme: %s\n", uri->scheme); + if (uri->scheme_part != NULL) + fprintf(fp, "scheme_part: %s\n", uri->scheme_part); + if (uri->user != NULL) + fprintf(fp, "user: %s\n", uri->user); + if (uri->password != NULL) + fprintf(fp, "password: %s\n", uri->password); + if (uri->host != NULL) + fprintf(fp, "host: %s\n", uri->host); + if (uri->port != NULL) + fprintf(fp, "port: %s\n", uri->port); + if (uri->path != NULL) + fprintf(fp, "path: %s\n", uri->path); + if (uri->fragment != NULL) + fprintf(fp, "fragment: %s\n", uri->fragment); + if (uri->query != NULL) + fprintf(fp, "query: %s\n", uri->query); + /* help me debug */ + if (uri->user_part != NULL) + fprintf(fp, "user_part: %s\n", uri->user_part); + if (uri->host_part != NULL) + fprintf(fp, "host_part: %s\n", uri->host_part); + if (uri->path_part != NULL) + fprintf(fp, "path_part: %s\n", uri->path_part); + fflush(fp); + } +} + +int +main(int argc, char *argv[]) +{ + uri_t *u = NULL; + + if (argc != 2) { + fprintf(stderr, "Usage: %s uri\n", argv[0]); + exit(1); + } + + if (uri_from_string(argv[1], &u) == 0) { + char buf[BUFSIZ]; + + uri_dump(stdout, u); + uri_to_string(u, buf, sizeof (buf)); + fprintf(stdout, "reconstituted: %s\n", buf); + + uri_to_string(u, buf, 12); + fprintf(stdout, "reconstituted(12): %s\n", buf); + } else + printf(" failed for %s (%s)\n", argv[1], strerror(errno)); + + exit(0); +} +#endif /* DEADBEEF */ diff --git a/usr/src/lib/print/libpapi-common/common/uri.h b/usr/src/lib/print/libpapi-common/common/uri.h new file mode 100644 index 0000000000..5dd714a199 --- /dev/null +++ b/usr/src/lib/print/libpapi-common/common/uri.h @@ -0,0 +1,66 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +#ifndef _URI_H +#define _URI_H + +/* $Id: uri.h 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * scheme://[[user[:password]@]host[:port]]/path[[#fragment]|[?query]] + */ +typedef struct { + char *scheme; + char *scheme_part; + char *user; + char *password; + char *host; + char *port; + char *path; + char *fragment; + char *query; + /* really for testing, but left in */ + char *user_part; + char *host_part; + char *path_part; +} uri_t; + +extern int uri_from_string(char *string, uri_t **uri); +extern int uri_to_string(uri_t *uri, char *buffer, size_t buflen); +extern void uri_free(uri_t *uri); + +#ifdef __cplusplus +} +#endif + +#endif /* _URI_H */ diff --git a/usr/src/lib/print/libpapi-common/i386/Makefile b/usr/src/lib/print/libpapi-common/i386/Makefile new file mode 100644 index 0000000000..3b985583a4 --- /dev/null +++ b/usr/src/lib/print/libpapi-common/i386/Makefile @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT) diff --git a/usr/src/lib/print/libpapi-common/sparc/Makefile b/usr/src/lib/print/libpapi-common/sparc/Makefile new file mode 100644 index 0000000000..3b985583a4 --- /dev/null +++ b/usr/src/lib/print/libpapi-common/sparc/Makefile @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT) diff --git a/usr/src/lib/print/libpapi-dynamic/Makefile b/usr/src/lib/print/libpapi-dynamic/Makefile new file mode 100644 index 0000000000..b92d620b10 --- /dev/null +++ b/usr/src/lib/print/libpapi-dynamic/Makefile @@ -0,0 +1,56 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../../Makefile.lib + +#HDRS = papi.h +#HDRDIR = common +SUBDIRS = $(MACH) +#$(BUILD64)SUBDIRS += $(MACH64) + +all := TARGET = all +clean := TARGET = clean +clobber := TARGET = clobber +install := TARGET = install +lint := TARGET = lint + +.KEEP_STATE: + +all clean clobber install: .WAIT $(SUBDIRS) + +lint: # $(SUBDIRS) + +install_h: # $(ROOTHDRS) + +check: # $(CHECKHDRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include ../../Makefile.targ diff --git a/usr/src/lib/print/libpapi-dynamic/Makefile.com b/usr/src/lib/print/libpapi-dynamic/Makefile.com new file mode 100644 index 0000000000..ecd8cba003 --- /dev/null +++ b/usr/src/lib/print/libpapi-dynamic/Makefile.com @@ -0,0 +1,59 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +LIBRARY = libpapi.a +VERS = .0 +OBJECTS = job.o nss.o printer.o psm.o service.o + +include ../../../Makefile.lib +include ../../../Makefile.rootfs + +ROOTLIBDIR= $(ROOT)/usr/lib + +LIBS = $(DYNLIB) + +SRCS = $(OBJECTS:%.o = $(SRCDIR)/%.c) + +$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC) + +SRCDIR = ../common +MAPFILE = $(SRCDIR)/mapfile +DYNFLAGS += -M $(MAPFILE) + +CFLAGS += $(CCVERBOSE) +CPPFLAGS += -I$(SRCDIR) +CPPFLAGS += -I../../libpapi-common/common +CPPFLAGS += -DNSS_SOLARIS +LDLIBS += -lc + +.KEEP_STATE: + +all: $(LIBS) + +lint: lintcheck + +include ../../../Makefile.targ diff --git a/usr/src/lib/print/libpapi-dynamic/common/job.c b/usr/src/lib/print/libpapi-dynamic/common/job.c new file mode 100644 index 0000000000..e7bca751a0 --- /dev/null +++ b/usr/src/lib/print/libpapi-dynamic/common/job.c @@ -0,0 +1,457 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: job.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/*LINTLIBRARY*/ + +#include <stdlib.h> +#include <papi_impl.h> + +void +papiJobFree(papi_job_t job) +{ + job_t *tmp = (job_t *)job; + + if (tmp != NULL) { + void (*f)(); + + f = (void (*)())psm_sym(tmp->svc, "papiJobFree"); + if (f != NULL) + f(tmp->job); + free(tmp); + } +} + +void +papiJobListFree(papi_job_t *jobs) +{ + if (jobs != NULL) { + int i; + + for (i = 0; jobs[i] != NULL; i++) + papiJobFree(jobs[i]); + free(jobs); + } +} + +papi_attribute_t ** +papiJobGetAttributeList(papi_job_t job) +{ + papi_attribute_t **result = NULL; + job_t *j = job; + + if (job != NULL) { + papi_attribute_t **(*f)(); + + f = (papi_attribute_t **(*)())psm_sym(j->svc, + "papiJobGetAttributeList"); + if (f != NULL) + result = f(j->job); + } + + return (result); +} + +char * +papiJobGetPrinterName(papi_job_t job) +{ + char *result = NULL; + job_t *j = job; + + if (job != NULL) { + char *(*f)(); + + f = (char *(*)())psm_sym(j->svc, "papiJobGetPrinterName"); + if (f != NULL) + result = f(j->job); + } + + return (result); +} + +int32_t +papiJobGetId(papi_job_t job) +{ + int32_t result = -1; + job_t *j = job; + + if (job != NULL) { + int32_t (*f)(); + + f = (int32_t (*)())psm_sym(j->svc, "papiJobGetId"); + if (f != NULL) + result = f(j->job); + } + + return (result); +} + +papi_job_ticket_t * +papiJobGetJobTicket(papi_job_t job) +{ + papi_job_ticket_t *result = NULL; + job_t *j = job; + + if (job != NULL) { + papi_job_ticket_t *(*f)(); + + f = (papi_job_ticket_t *(*)())psm_sym(j->svc, + "papiJobGetJobTicket"); + if (f != NULL) + result = f(j->job); + } + + return (result); +} + +/* common support for papiJob{Submit|SubmitByReference|Validate} */ +static papi_status_t +_papi_job_submit_reference_or_validate(papi_service_t handle, char *printer, + papi_attribute_t **job_attributes, + papi_job_ticket_t *job_ticket, char **files, papi_job_t *job, + char *function) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + job_t *j = NULL; + papi_status_t (*f)(); + + if ((svc == NULL) || (printer == NULL) || (files == NULL) || + (job == NULL)) + return (PAPI_BAD_ARGUMENT); + + if ((result = service_connect(svc, printer)) != PAPI_OK) + return (result); + + if ((*job = j = calloc(1, sizeof (*j))) == NULL) + return (PAPI_TEMPORARY_ERROR); + + j->svc = svc; + f = (papi_status_t (*)())psm_sym(j->svc, function); + if (f != NULL) + result = f(svc->svc_handle, svc->name, job_attributes, + job_ticket, files, &j->job); + + return (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) +{ + return (_papi_job_submit_reference_or_validate(handle, printer, + job_attributes, job_ticket, files, job, + "papiJobSubmit")); +} + +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) +{ + return (_papi_job_submit_reference_or_validate(handle, printer, + job_attributes, job_ticket, files, job, + "papiJobSubmitByReference")); +} + +papi_status_t +papiJobValidate(papi_service_t handle, char *printer, + papi_attribute_t **job_attributes, + papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) +{ + return (_papi_job_submit_reference_or_validate(handle, printer, + job_attributes, job_ticket, files, job, + "papiJobValidate")); +} + +papi_status_t +papiJobStreamOpen(papi_service_t handle, char *printer, + papi_attribute_t **job_attributes, + papi_job_ticket_t *job_ticket, papi_stream_t *stream) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + papi_status_t (*f)(); + + if ((svc == NULL) || (printer == NULL) || (stream == NULL)) + return (PAPI_BAD_ARGUMENT); + + if ((result = service_connect(svc, printer)) != PAPI_OK) + return (result); + + f = (papi_status_t (*)())psm_sym(svc, "papiJobStreamOpen"); + if (f != NULL) + result = f(svc->svc_handle, svc->name, job_attributes, + job_ticket, stream); + + return (result); +} + +papi_status_t +papiJobStreamWrite(papi_service_t handle, + papi_stream_t stream, void *buffer, size_t buflen) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + papi_status_t (*f)(); + + if ((svc == NULL) || (stream == NULL) || (buffer == NULL) || + (buflen == 0)) + return (PAPI_BAD_ARGUMENT); + + f = (papi_status_t (*)())psm_sym(svc, "papiJobStreamWrite"); + if (f != NULL) + result = f(svc->svc_handle, stream, buffer, buflen); + + return (result); +} + +papi_status_t +papiJobStreamClose(papi_service_t handle, papi_stream_t stream, papi_job_t *job) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + job_t *j = NULL; + papi_status_t (*f)(); + + if ((svc == NULL) || (stream == NULL) || (job == NULL)) + return (PAPI_BAD_ARGUMENT); + + if ((*job = j = calloc(1, sizeof (*j))) == NULL) + return (PAPI_TEMPORARY_ERROR); + + j->svc = svc; + f = (papi_status_t (*)())psm_sym(j->svc, "papiJobStreamClose"); + if (f != NULL) + result = f(svc->svc_handle, stream, &j->job); + + return (result); +} + +papi_status_t +papiJobQuery(papi_service_t handle, char *printer, int32_t job_id, + char **requested_attrs, papi_job_t *job) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + job_t *j = NULL; + papi_status_t (*f)(); + + if ((svc == NULL) || (printer == NULL)) + return (PAPI_BAD_ARGUMENT); + + if ((result = service_connect(svc, printer)) != PAPI_OK) + return (result); + + if ((*job = j = calloc(1, sizeof (*j))) == NULL) + return (PAPI_TEMPORARY_ERROR); + + j->svc = svc; + f = (papi_status_t (*)())psm_sym(j->svc, "papiJobQuery"); + if (f != NULL) + result = f(svc->svc_handle, svc->name, job_id, + requested_attrs, &j->job); + + return (result); +} + +papi_status_t +papiJobMove(papi_service_t handle, char *printer, int32_t job_id, + char *destination) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + papi_status_t (*f)(); + + if ((svc == NULL) || (printer == NULL) || (job_id < 0)) + return (PAPI_BAD_ARGUMENT); + + if ((result = service_connect(svc, printer)) != PAPI_OK) + return (result); + + f = (papi_status_t (*)())psm_sym(svc, "papiJobMove"); + if (f != NULL) { + papi_attribute_t **attrs = getprinterbyname(destination, NULL); + + papiAttributeListGetString(attrs, NULL, + "printer-uri-supported", &destination); + result = f(svc->svc_handle, svc->name, job_id, destination); + papiAttributeListFree(attrs); + } + + return (result); +} + +/* common support for papiJob{Cancel|Release|Restart|Promote} */ +static papi_status_t +_papi_job_handle_printer_id(papi_service_t handle, + char *printer, int32_t job_id, char *function) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + papi_status_t (*f)(); + + if ((svc == NULL) || (printer == NULL) || (job_id < 0)) + return (PAPI_BAD_ARGUMENT); + + if ((result = service_connect(svc, printer)) != PAPI_OK) + return (result); + + f = (papi_status_t (*)())psm_sym(svc, function); + if (f != NULL) + result = f(svc->svc_handle, svc->name, job_id); + + return (result); +} + +papi_status_t +papiJobCancel(papi_service_t handle, char *printer, int32_t job_id) +{ + return (_papi_job_handle_printer_id(handle, printer, job_id, + "papiJobCancel")); +} + +papi_status_t +papiJobRelease(papi_service_t handle, char *printer, int32_t job_id) +{ + return (_papi_job_handle_printer_id(handle, printer, job_id, + "papiJobRelease")); +} + +papi_status_t +papiJobRestart(papi_service_t handle, char *printer, int32_t job_id) +{ + return (_papi_job_handle_printer_id(handle, printer, job_id, + "papiJobRestart")); +} + +papi_status_t +papiJobPromote(papi_service_t handle, char *printer, int32_t job_id) +{ + return (_papi_job_handle_printer_id(handle, printer, job_id, + "papiJobPromote")); +} + +papi_status_t +papiJobCommit(papi_service_t handle, char *printer, int32_t job_id) +{ + return (_papi_job_handle_printer_id(handle, printer, job_id, + "papiJobCommit")); +} + +papi_status_t +papiJobHold(papi_service_t handle, char *printer, int32_t job_id) +{ + return (_papi_job_handle_printer_id(handle, printer, job_id, + "papiJobHold")); +} + +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 result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + job_t *j = NULL; + papi_status_t (*f)(); + + if ((svc == NULL) || (printer == NULL) || (job_id < 0) || + (attributes == NULL)) + return (PAPI_BAD_ARGUMENT); + + if ((result = service_connect(svc, printer)) != PAPI_OK) + return (result); + + if ((*job = j = calloc(1, sizeof (*j))) == NULL) + return (PAPI_TEMPORARY_ERROR); + + j->svc = svc; + f = (papi_status_t (*)())psm_sym(j->svc, "papiJobModify"); + if (f != NULL) + result = f(svc->svc_handle, svc->name, job_id, attributes, + &j->job); + + return (result); +} + +/* + * The functions defined below are private to Solaris. They are here + * temporarily, until equivalent functionality makes it's way into the PAPI + * spec. This is expected in the next minor version after v1.0. + */ +papi_status_t +papiJobCreate(papi_service_t handle, char *printer, + papi_attribute_t **job_attributes, + papi_job_ticket_t *job_ticket, papi_job_t *job) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + job_t *j = NULL; + papi_status_t (*f)(); + + if ((svc == NULL) || (printer == NULL) || (job == NULL)) + return (PAPI_BAD_ARGUMENT); + + if ((result = service_connect(svc, printer)) != PAPI_OK) + return (result); + + if ((*job = j = calloc(1, sizeof (*j))) == NULL) + return (PAPI_TEMPORARY_ERROR); + + j->svc = svc; + f = (papi_status_t (*)())psm_sym(j->svc, "papiJobCreate"); + if (f != NULL) + result = f(svc->svc_handle, svc->name, job_attributes, + job_ticket, &j->job); + + return (result); +} + +papi_status_t +papiJobStreamAdd(papi_service_t handle, char *printer, int32_t id, + papi_stream_t *stream) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + papi_status_t (*f)(); + + if ((svc == NULL) || (printer == NULL)) + return (PAPI_BAD_ARGUMENT); + + if ((result = service_connect(svc, printer)) != PAPI_OK) + return (result); + + f = (papi_status_t (*)())psm_sym(svc, "papiJobStreamAdd"); + if (f != NULL) + result = f(svc->svc_handle, svc->name, id, stream); + + return (result); +} diff --git a/usr/src/lib/print/libpapi-dynamic/common/mapfile b/usr/src/lib/print/libpapi-dynamic/common/mapfile new file mode 100644 index 0000000000..7c6d07953c --- /dev/null +++ b/usr/src/lib/print/libpapi-dynamic/common/mapfile @@ -0,0 +1,150 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# $Id: mapfile.in,v 1.2 2006/03/02 06:31:36 njacobs Exp $ +# + +# ident "%Z%%M% %I% %E% SMI" + +# +# Common interfaces that are most likely to be shared amongst the various +# PAPI implementations. +# + +SUNW_1.0 { + global: + # PAPI Attribute Calls + papiAttributeListAddValue = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddBoolean = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddCollection = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddDatetime = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddInteger = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddMetadata = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddRange = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddResolution = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddString = FUNCTION FILTER libpapi-common.so ; + papiAttributeListDelete = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetValue = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetNext = FUNCTION FILTER libpapi-common.so ; + papiAttributeListFind = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetBoolean = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetCollection = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetDatetime = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetInteger = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetMetadata = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetRange = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetResolution = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetString = FUNCTION FILTER libpapi-common.so ; + papiAttributeListFromString = FUNCTION FILTER libpapi-common.so ; + papiAttributeListToString = FUNCTION FILTER libpapi-common.so ; + papiAttributeListFree = FUNCTION FILTER libpapi-common.so ; + + # PAPI Service Calls + papiServiceCreate ; + papiServiceDestroy ; + papiServiceSetUserName ; + papiServiceSetPassword ; + papiServiceSetEncryption ; + papiServiceSetAuthCB ; + papiServiceSetAppData ; + papiServiceGetUserName ; + papiServiceGetPassword ; + papiServiceGetEncryption ; + papiServiceGetAppData ; + papiServiceGetServiceName ; + papiServiceGetAttributeList ; + papiServiceGetStatusMessage ; + + # PAPI Printer Calls + papiPrintersList ; + papiPrinterQuery ; + papiPrinterAdd ; + papiPrinterModify ; + papiPrinterRemove ; + papiPrinterDisable ; + papiPrinterEnable ; + papiPrinterPause ; + papiPrinterResume ; + papiPrinterPurgeJobs ; + papiPrinterListJobs ; + papiPrinterGetAttributeList ; + papiPrinterFree ; + papiPrinterListFree ; + + # PAPI Job Calls + papiJobSubmit ; + papiJobSubmitByReference ; + papiJobValidate ; + papiJobStreamOpen ; + papiJobStreamWrite ; + papiJobStreamClose ; + papiJobQuery ; + papiJobModify ; + papiJobMove ; + papiJobCancel ; + papiJobHold ; + papiJobRelease ; + papiJobRestart ; + papiJobPromote ; + papiJobGetAttributeList ; + papiJobGetPrinterName ; + papiJobGetId ; + papiJobGetJobTicket ; + papiJobFree ; + papiJobListFree ; + + # Misc. PAPI Calls + papiStatusString = FUNCTION FILTER libpapi-common.so ; + papiLibrarySupportedCall = FUNCTION FILTER libpapi-common.so ; + papiLibrarySupportedCalls = FUNCTION FILTER libpapi-common.so ; +}; + +SUNWprivate_1.0 { + global: + papiServiceSetPeer ; # extension + papiJobCreate ; + papiJobStreamAdd ; + papiJobCommit ; + + # Misc. supporting calls + # URI + uri_from_string = FUNCTION FILTER libpapi-common.so ; + uri_to_string = FUNCTION FILTER libpapi-common.so ; + uri_free = FUNCTION FILTER libpapi-common.so ; + # list + list_remove = FUNCTION FILTER libpapi-common.so ; + list_append = FUNCTION FILTER libpapi-common.so ; + list_concatenate = FUNCTION FILTER libpapi-common.so ; + + # extra Attribute Calls + copy_attributes = FUNCTION FILTER libpapi-common.so ; + split_and_copy_attributes = FUNCTION FILTER libpapi-common.so ; + papiAttributeListPrint = FUNCTION FILTER libpapi-common.so ; + + local: + * ; +} ; diff --git a/usr/src/lib/print/libpapi-dynamic/common/nss.c b/usr/src/lib/print/libpapi-dynamic/common/nss.c new file mode 100644 index 0000000000..9a142827c4 --- /dev/null +++ b/usr/src/lib/print/libpapi-dynamic/common/nss.c @@ -0,0 +1,497 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: nss.c 166 2006-05-20 05:48:55Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <ctype.h> +#include <sys/types.h> +#include <syslog.h> +#include <papi.h> +#include <uri.h> +#include <papi_impl.h> +#ifdef NSS_EMULATION +#include <nss-emulation.h> +#elif NSS_SOLARIS +#include <nss_dbdefs.h> +#endif +#include <config-site.h> +#if defined(__sun) && defined(__SVR4) +#include <sys/systeminfo.h> +#endif + + +static char * +bsdaddr_to_uri(char *bsdaddr) +{ + char *result = NULL; + + if (bsdaddr != NULL) { + char *bsd[3], *tmp, *iter = NULL; + char buf[512]; + + tmp = strdup(bsdaddr); + + bsd[0] = strtok_r(tmp, ":,", &iter); + bsd[1] = strtok_r(NULL, ":,", &iter); + bsd[2] = strtok_r(NULL, ":,", &iter); + + snprintf(buf, sizeof (buf), "lpd://%s/%s%s%s", bsd[0], bsd[1], + (bsd[2] != NULL) ? "#" : "", + (bsd[2] != NULL) ? bsd[2] : ""); + + free(tmp); + + result = strdup(buf); + } + + return (result); +} + +#if defined(__sun) && defined(__SVR4) +/* + * This is an awful HACK to force the dynamic PAPI library to use the + * lpsched support when the destination apears to be a local lpsched + * queue on Solaris. + */ +static void +solaris_lpsched_shortcircuit_hack(papi_attribute_t ***list) +{ + papi_attribute_t *attribute; + uri_t *uri = NULL; + char *printer = NULL; + char hostname[BUFSIZ]; + char buf[128], buf2[128]; + + /* setting this in the calling env can be useful for debugging */ + if (getenv("DISABLE_LPSCHED_SHORTCIRCUIT") != NULL) + return; + + papiAttributeListGetString(*list, NULL, + "printer-uri-supported", &printer); + if (uri_from_string(printer, &uri) < 0) + return; + + /* already an lpsched URI ? */ + if (strcasecmp(uri->scheme, "lpsched") == 0) + return; + + sysinfo(SI_HOSTNAME, hostname, sizeof (hostname)); + if ((uri->host != NULL) && + (strncasecmp(uri->host, hostname, strlen(hostname)) != 0) && + (strncasecmp(uri->host, "localhost", 10) != 0)) + return; + + if ((printer = strrchr(uri->path, '/')) == NULL) + printer = uri->path; + else + printer++; + + /* is there an lpsched queue (printer/class) */ + snprintf(buf, sizeof (buf), "/etc/lp/interfaces/%s", printer); + snprintf(buf2, sizeof (buf2), "/etc/lp/classes/%s", printer); + if ((access(buf, F_OK) < 0) && (access(buf2, F_OK) < 0)) + return; + + snprintf(buf, sizeof (buf), "lpsched://localhost/printers/%s", printer); + papiAttributeListAddString(list, PAPI_ATTR_REPLACE, + "printer-uri-supported", buf); +} +#endif + +static void +fill_printer_uri_supported(papi_attribute_t ***list) +{ + papi_attribute_t *attribute; + char *string = NULL; + + /* do we have a printer-uri-supported */ + attribute = papiAttributeListFind(*list, "printer-uri-supported"); + if (attribute != NULL) /* we have what we need, return */ + return; + + /* do we have a printer-uri to rename */ + attribute = papiAttributeListFind(*list, "printer-uri"); + if (attribute != NULL) { /* rename it in place and return */ + free(attribute->name); + attribute->name = strdup("printer-uri-supported"); + return; + } + + /* do we have a printers.conf(4) "bsdaddr" to convert */ + papiAttributeListGetString(*list, NULL, "bsdaddr", &string); + if (string != NULL) { /* parse it, convert it, add it */ + char *uri = bsdaddr_to_uri(string); + + if (uri != NULL) { + papiAttributeListAddString(list, PAPI_ATTR_APPEND, + "printer-uri-supported", uri); + papiAttributeListDelete(list, "bsdaddr"); + free(uri); + return; + } + } + + /* do we have a printers.conf(4) "rm" (and "rp") to convert */ + papiAttributeListGetString(*list, NULL, "rm", &string); + if (string != NULL) { + char *rp = NULL; + + /* default to "printer-name", but use "rp" if we have it */ + papiAttributeListGetString(*list, NULL, "printer-name", &rp); + papiAttributeListGetString(*list, NULL, "rp", &rp); + + if (rp != NULL) { /* fill in the uri if we have the data */ + char buf[BUFSIZ]; + + snprintf(buf, sizeof (buf), "lpd://%s/printers/%s", + string, rp); + papiAttributeListAddString(list, PAPI_ATTR_APPEND, + "printer-uri-supported", strdup(buf)); + return; + } + } + + /* if were are here, we don't have a printer-uri-supported */ +} + +#ifdef NEED_BROKEN_PRINTER_URI_SEMANTIC +static void +fill_printer_uri(papi_attribute_t ***list) +{ + papi_attribute_t *attribute; + char *uri = NULL; + + if ((list == NULL) || (*list == NULL)) + return; + + /* do we have a printer-uri-supported */ + attribute = papiAttributeListFind(*list, "printer-uri"); + if (attribute != NULL) /* we have what we need, return */ + return; + + /* + * this is sufficient to fool libgnomeprintpapi, but not promote it's + * use in the future. + */ + papiAttributeListAddString(list, PAPI_ATTR_EXCL, "printer-uri", + "broken printer-uri semantic"); +} +#endif /* NEED_BROKEN_PRINTER_URI_SEMANTIC */ + +static void +cvt_all_to_member_names(papi_attribute_t ***list) +{ + papi_status_t status; + void *iter = NULL; + char *string = NULL; + + papiAttributeListGetString(*list, NULL, "member-names", &string); + if (string != NULL) /* already have a member-names */ + return; + + for (status = papiAttributeListGetString(*list, &iter, "all", &string); + status == PAPI_OK; + status = papiAttributeListGetString(*list, &iter, NULL, &string)) { + char *s_iter = NULL, *value, *tmp = strdup(string); + + for (value = strtok_r(tmp, ", \t", &s_iter); + value != NULL; + value = strtok_r(NULL, ", \t", &s_iter)) + papiAttributeListAddString(list, PAPI_ATTR_APPEND, + "member-names", value); + free(tmp); + } +} + +static papi_attribute_t ** +_cvt_nss_entry_to_printer(char *entry) +{ + char *key = NULL, + *cp, + buf[BUFSIZ]; + int in_namelist = 1, buf_pos = 0; + papi_attribute_t **list = NULL; + + if (entry == NULL) + return (NULL); + + memset(buf, 0, sizeof (buf)); + for (cp = entry; *cp != '\0'; cp++) { + switch (*cp) { + case ':': /* end of kvp */ + if (in_namelist != 0) { + papiAttributeListAddString(&list, + PAPI_ATTR_APPEND, "printer-name", buf); + in_namelist = 0; + } else if (key != NULL) + papiAttributeListAddString(&list, + PAPI_ATTR_APPEND, key, buf); + memset(buf, 0, sizeof (buf)); + buf_pos = 0; + key = NULL; + break; + case '=': /* kvp seperator */ + if (key == NULL) { + key = strdup(buf); + memset(buf, 0, sizeof (buf)); + buf_pos = 0; + } else + buf[buf_pos++] = *cp; + break; + case '|': /* namelist seperator */ + if (in_namelist != 0) { + papiAttributeListAddString(&list, + PAPI_ATTR_APPEND, "printer-name", buf); + memset(buf, 0, sizeof (buf)); + buf_pos = 0; + } else /* add it to the buffer */ + buf[buf_pos++] = *cp; + break; + case '\\': /* escape char */ + buf[buf_pos++] = *(++cp); + break; + default: + buf[buf_pos++] = *cp; + } + + } + + if (key != NULL) + papiAttributeListAddString(&list, PAPI_ATTR_APPEND, key, buf); + + /* resolve any "use" references in the configuration DB */ + key = NULL; + papiAttributeListGetString(list, NULL, "use", &key); + if (key != NULL) { + papi_attribute_t **use_attrs = getprinterbyname(key, NULL); + + list_concatenate(&list, use_attrs); + } + + fill_printer_uri_supported(&list); +#if defined(__sun) && defined(__SVR4) + solaris_lpsched_shortcircuit_hack(&list); +#endif + cvt_all_to_member_names(&list); /* convert "all" to "member-names" */ + + return (list); +} + +#if defined(NSS_SOLARIS) && !defined(NSS_EMULATION) + +#ifndef NSS_DBNAM__PRINTERS /* not in nss_dbdefs.h because it's private */ +#define NSS_DBNAM__PRINTERS "_printers" +#endif + +static DEFINE_NSS_DB_ROOT(db_root); +static DEFINE_NSS_GETENT(context); + +static char *private_ns = NULL; +static char initialized = 0; + +static void +_nss_initf_printers(p) + nss_db_params_t *p; +{ + if (private_ns != NULL) { + /* + * because we need to support a legacy interface that allows + * us to select a specific name service, we need to dummy up + * the parameters to use a private nsswitch database and set + * the * default_config entry to the name service we are + * looking into. + */ + p->name = NSS_DBNAM__PRINTERS; /* "_printers" */ + p->default_config = private_ns; + private_ns = NULL; + } else if (initialized == 0) { + /* regular behaviour */ + p->name = NSS_DBNAM_PRINTERS; /* "printers" */ + p->default_config = NSS_DEFCONF_PRINTERS; + initialized = 1; + } + syslog(LOG_DEBUG, "database: %s, services: %s", + (p->name ? p->name : "NULL"), + (p->default_config ? p->default_config : "NULL")); +} + +/* + * Return values: 0 = success, 1 = parse error, 2 = erange ... + * The structure pointer passed in is a structure in the caller's space + * wherein the field pointers would be set to areas in the buffer if + * need be. instring and buffer should be separate areas. + */ +/* ARGSUSED */ +static int +str2printer(const char *instr, int lenstr, void *ent, char *buffer, int buflen) +{ + if (lenstr + 1 > buflen) + return (NSS_STR_PARSE_ERANGE); + /* + * We copy the input string into the output buffer + */ + (void) memcpy(buffer, instr, lenstr); + buffer[lenstr] = '\0'; + + return (NSS_STR_PARSE_SUCCESS); +} +#endif /* NSS_SOLARIS */ + +int +setprinterentry(int stayopen, char *ns) +{ +#ifdef NSS_EMULATION + emul_setprinterentry(stayopen); +#elif NSS_SOLARIS + initialized = 0; + private_ns = ns; + nss_setent(&db_root, _nss_initf_printers, &context); +#endif + return (0); +} + + +int +endprinterentry(int i) +{ +#ifdef NSS_EMULATION + emul_endprinterentry(); +#elif NSS_SOLARIS + initialized = 0; + nss_endent(&db_root, _nss_initf_printers, &context); + nss_delete(&db_root); +#endif + return (0); +} + +/* ARGSUSED2 */ +papi_attribute_t ** +getprinterentry(char *ns) +{ + papi_attribute_t **result = NULL; + +#if defined(NSS_EMULATION) || defined(NSS_SOLARIS) + char buf[10240]; + nss_status_t res = NSS_NOTFOUND; + +#ifdef NSS_EMULATION + res = emul_getprinterentry_r(buf, sizeof (buf)); +#elif NSS_SOLARIS + nss_XbyY_args_t arg; + + NSS_XbyY_INIT(&arg, buf, buf, sizeof (buf), str2printer); + res = nss_getent(&db_root, _nss_initf_printers, &context, &arg); + (void) NSS_XbyY_FINI(&arg); +#endif + + if (res != NSS_SUCCESS) + buf[0] = '\0'; + + result = _cvt_nss_entry_to_printer(buf); +#ifdef NEED_BROKEN_PRINTER_URI_SEMANTIC + fill_printer_uri(&result); +#endif /* NEED_BROKEN_PRINTER_URI_SEMANTIC */ +#endif + +#ifdef DEBUG + printf("getprinterentry(%s): 0x%8.8x\n", (ns ? ns : "NULL"), result); + if (result != NULL) { + char buf[4096]; + + papiAttributeListToString(result, "\n\t", buf, sizeof (buf)); + printf("\t%s\n", buf); + } +#endif /* DEBUG */ + + return (result); +} + + +papi_attribute_t ** +getprinterbyname(char *name, char *ns) +{ + papi_attribute_t **result = NULL; + + if (strstr(name, "://") != NULL) { /* shortcut for URI form */ + papiAttributeListAddString(&result, PAPI_ATTR_APPEND, + "printer-name", name); + papiAttributeListAddString(&result, PAPI_ATTR_APPEND, + "printer-uri-supported", name); + } else if (strchr(name, ':') != NULL) { /* shortcut for POSIX form */ + char *uri = bsdaddr_to_uri(name); + + papiAttributeListAddString(&result, PAPI_ATTR_APPEND, + "printer-name", name); + if (uri != NULL) { + papiAttributeListAddString(&result, PAPI_ATTR_APPEND, + "printer-uri-supported", uri); + free(uri); + } + } else { /* anything else */ +#if defined(NSS_EMULATION) || defined(NSS_SOLARIS) + char buf[10240]; + nss_status_t res = NSS_NOTFOUND; + +#ifdef NSS_EMULATION + res = emul_getprinterbyname_r(name, buf, sizeof (buf)); +#elif NSS_SOLARIS + nss_XbyY_args_t arg; + + private_ns = ns; + NSS_XbyY_INIT(&arg, buf, buf, sizeof (buf), str2printer); + arg.key.name = name; + res = nss_search(&db_root, _nss_initf_printers, + NSS_DBOP_PRINTERS_BYNAME, &arg); + (void) NSS_XbyY_FINI(&arg); + + if (res != NSS_SUCCESS) + buf[0] = '\0'; +#endif + + result = _cvt_nss_entry_to_printer(buf); +#endif + } + +#ifdef DEBUG + printf("getprinterbyname(%s): %s = 0x%8.8x\n", (ns ? ns : "NULL"), + name, result); + if (result != NULL) { + char buf[4096]; + + papiAttributeListToString(result, "\n\t", buf, sizeof (buf)); + printf("\t%s\n", buf); + } +#endif /* DEBUG */ + + return (result); +} diff --git a/usr/src/lib/print/libpapi-dynamic/common/papi_impl.h b/usr/src/lib/print/libpapi-dynamic/common/papi_impl.h new file mode 100644 index 0000000000..be28a9de0c --- /dev/null +++ b/usr/src/lib/print/libpapi-dynamic/common/papi_impl.h @@ -0,0 +1,97 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +#ifndef _PAPI_IMPL_H +#define _PAPI_IMPL_H + +/* $Id: papi_impl.h 161 2006-05-03 04:32:59Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <papi.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#include <time.h> +#include <sys/types.h> +#include <stdarg.h> +#include <uri.h> + +/* + * Implementation specific types/prototypes/definitions follow + * + * + * Ex: + */ + +typedef struct { + papi_attribute_t **attributes; + void *so_handle; + void *svc_handle; + char *name; + char *user; + char *password; + int (*authCB)(papi_service_t svc, void *app_data); + papi_encryption_t encryption; + void *app_data; + uri_t *uri; + int peer_fd; +} service_t; + +typedef struct job { + service_t *svc; + papi_job_t *job; +} job_t; + +typedef struct { + service_t *svc; + papi_printer_t *printer; + papi_attribute_t **attributes; + char svc_is_internal; +} printer_t; + +extern papi_status_t psm_open(service_t *svc, char *name); +extern void *psm_sym(service_t *svc, char *name); +extern void psm_close(void *handle); +extern void detailed_error(service_t *svc, char *fmt, ...); +extern papi_status_t service_connect(service_t *svc, char *uri); +extern papi_attribute_t **getprinterentry(char *ns); +extern papi_attribute_t **getprinterbyname(char *name, char *ns); +extern int setprinterentry(int stayopen, char *ns); +extern int endprinterentry(int stayopen); + + + +extern void list_remove(); + +#ifdef __cplusplus +} +#endif + +#endif /* _PAPI_IMPL_H */ diff --git a/usr/src/lib/print/libpapi-dynamic/common/printer.c b/usr/src/lib/print/libpapi-dynamic/common/printer.c new file mode 100644 index 0000000000..321492703e --- /dev/null +++ b/usr/src/lib/print/libpapi-dynamic/common/printer.c @@ -0,0 +1,512 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: printer.c 151 2006-04-25 16:55:34Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/*LINTLIBRARY*/ + +#include <stdlib.h> +#include <papi_impl.h> + +void +papiPrinterFree(papi_printer_t printer) +{ + printer_t *tmp = printer; + + if (tmp != NULL) { + void (*f)(); + + f = (void (*)())psm_sym(tmp->svc, "papiPrinterFree"); + if (f != NULL) + f(tmp->printer); + if (tmp->attributes != NULL) + papiAttributeListFree(tmp->attributes); + if (tmp->svc_is_internal != 0) + papiServiceDestroy(tmp->svc); + free(tmp); + } +} + +void +papiPrinterListFree(papi_printer_t *printers) +{ + if (printers != NULL) { + int i; + + for (i = 0; printers[i] != NULL; i++) + papiPrinterFree(printers[i]); + free(printers); + } +} + +/* Enumerate a list of printers from the loaded print service. */ +static papi_status_t +printers_from_service(service_t *svc, char **requested_attrs, + papi_filter_t *filter, papi_printer_t **printers) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + papi_printer_t *svc_printers = NULL; + papi_status_t (*f)(); + + if ((svc == NULL) || (printers == NULL)) + return (PAPI_BAD_ARGUMENT); + + /* connect to the service if we are not connected */ + if ((result = service_connect(svc, svc->name)) != PAPI_OK) + return (result); + + f = (papi_status_t (*)())psm_sym(svc, "papiPrintersList"); + if (f != NULL) + result = f(svc->svc_handle, requested_attrs, filter, + &svc_printers); + + /* + * copy the resulting printer object pointers into our own + * representation of a printer object because we need the + * service context to operate against the individual printer + * objects. We free the list now because we no longer need + * it and would have no way of freeing it later. + */ + if ((result == PAPI_OK) && (svc_printers != NULL)) { + int i; + + *printers = NULL; + for (i = 0; svc_printers[i] != NULL; i++) { + printer_t *p = NULL; + + if ((p = calloc(1, sizeof (*p))) == NULL) + return (PAPI_TEMPORARY_ERROR); + + p->svc = svc; + p->printer = svc_printers[i]; + list_append(printers, p); + } + free(svc_printers); + } + + return (result); +} + +/* Get printer attributes from it's print service */ +static papi_status_t +printer_from_service(service_t *svc, printer_t *p, char **requested_attrs) +{ + papi_status_t result; + papi_service_t p_svc = NULL; + papi_printer_t printer = NULL; + char *psm = NULL; + char *uri = NULL; + + /* get the psm and uri from the attributes */ + papiAttributeListGetString(p->attributes, NULL, + "print-service-module", &psm); + papiAttributeListGetString(p->attributes, NULL, "printer-name", &uri); + papiAttributeListGetString(p->attributes, NULL, "printer-uri-supported", + &uri); + + /* contact the service for the printer */ + result = papiServiceCreate((papi_service_t *)&p_svc, psm, svc->user, + svc->password, svc->authCB, svc->encryption, + svc->app_data); + if (result != PAPI_OK) + return (result); + + /* get the printer from the service */ + result = papiPrinterQuery(p_svc, uri, requested_attrs, NULL, &printer); + if (result == PAPI_OK) { + papi_attribute_t **attributes; + + attributes = papiPrinterGetAttributeList(printer); + copy_attributes(&p->attributes, attributes); + } + papiPrinterFree(printer); + papiServiceDestroy(p_svc); + + return (result); +} + +/* are the requested attributes contained in the list */ +static int +contained(char **requested, papi_attribute_t **list) +{ + int i; + + if (requested == NULL) /* we want every possible attribute */ + return (0); + + for (i = 0; requested[i] != NULL; i++) + if (papiAttributeListFind(list, requested[i]) == NULL) + return (0); + + return (1); +} + +/* Enumerate a list of printers from the Name Service */ +static papi_status_t +printers_from_name_service(service_t *svc, char **requested_attrs, + papi_filter_t *filter, papi_printer_t **printers) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + papi_attribute_t **attrs; + + if ((svc == NULL) || (printers == NULL)) + return (PAPI_BAD_ARGUMENT); + + /* retrieve printers from the nameservice */ + while ((attrs = getprinterentry(NULL)) != NULL) { + printer_t *p = NULL; + + if ((p = calloc(1, sizeof (*p))) == NULL) + return (PAPI_TEMPORARY_ERROR); + + p->attributes = attrs; + list_append(printers, p); + } + + /* if we have printers, check if our request has been satisfied */ + if ((printers != NULL) && (*printers != NULL)) { + int i; + + /* walk through the list */ + for (i = 0; (*printers)[i] != NULL; i++) { + printer_t *p = (*printers)[i]; + + /* see if the name service satisfied the request */ + if (contained(requested_attrs, p->attributes) == 0) + printer_from_service(svc, p, requested_attrs); + } + } + + return (PAPI_OK); +} + +papi_status_t +papiPrintersList(papi_service_t handle, char **requested_attrs, + papi_filter_t *filter, papi_printer_t **printers) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + papi_printer_t *svc_printers = NULL; + papi_status_t (*f)(); + + if ((svc == NULL) || (printers == NULL)) + return (PAPI_BAD_ARGUMENT); + + if (svc->so_handle != NULL) /* connected, use the print svc */ + result = printers_from_service(svc, requested_attrs, + filter, printers); + else /* not connected, use the name svc */ + result = printers_from_name_service(svc, requested_attrs, + filter, printers); + + return (result); +} + +papi_status_t +papiPrinterQuery(papi_service_t handle, char *name, char **requested_attrs, + papi_attribute_t **job_attributes, papi_printer_t *printer) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + printer_t *p = NULL; + papi_status_t (*f)(); + + if ((svc == NULL) || (name == NULL) || (printer == NULL)) + return (PAPI_BAD_ARGUMENT); + + if ((result = service_connect(svc, name)) != PAPI_OK) + return (result); + + if ((*printer = p = calloc(1, sizeof (*p))) == NULL) + return (PAPI_TEMPORARY_ERROR); + + if ((svc->name != NULL) && (svc->svc_handle != NULL) && + (svc->uri != NULL)) { + p->svc = svc; + f = (papi_status_t (*)())psm_sym(p->svc, "papiPrinterQuery"); + if (f != NULL) + result = f(svc->svc_handle, svc->name, requested_attrs, + job_attributes, &p->printer); + } else { + setprinterentry(0, NULL); + p->attributes = getprinterbyname(name, NULL); + if (p->attributes == NULL) + result = PAPI_NOT_FOUND; + else + result = PAPI_OK; + } + + return (result); +} + +static papi_status_t +_papi_printer_disable_or_pause(papi_service_t handle, char *name, char *message, + char *function) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + papi_status_t (*f)(); + + if ((svc == NULL) || (name == NULL)) + return (PAPI_BAD_ARGUMENT); + + if ((result = service_connect(svc, name)) != PAPI_OK) + return (result); + + f = (papi_status_t (*)())psm_sym(svc, function); + if (f != NULL) + result = f(svc->svc_handle, svc->name, message); + + return (result); +} + +static papi_status_t +_papi_printer_enable_or_resume(papi_service_t handle, char *name, + char *function) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + papi_status_t (*f)(); + + if ((svc == NULL) || (name == NULL)) + return (PAPI_BAD_ARGUMENT); + + if ((result = service_connect(svc, name)) != PAPI_OK) + return (result); + + f = (papi_status_t (*)())psm_sym(svc, function); + if (f != NULL) + result = f(svc->svc_handle, svc->name); + + return (result); +} + +papi_status_t +papiPrinterDisable(papi_service_t handle, char *name, char *message) +{ + return (_papi_printer_disable_or_pause(handle, name, message, + "papiPrinterDisable")); +} + +papi_status_t +papiPrinterPause(papi_service_t handle, char *name, char *message) +{ + return (_papi_printer_disable_or_pause(handle, name, message, + "papiPrinterPause")); +} + +papi_status_t +papiPrinterEnable(papi_service_t handle, char *name) +{ + return (_papi_printer_enable_or_resume(handle, name, + "papiPrinterEnable")); +} + +papi_status_t +papiPrinterResume(papi_service_t handle, char *name) +{ + return (_papi_printer_enable_or_resume(handle, name, + "papiPrinterResume")); +} + +static papi_status_t +_papi_printer_add_or_modify(papi_service_t handle, char *name, + papi_attribute_t **attributes, papi_printer_t *printer, + char *function) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + printer_t *p = NULL; + papi_status_t (*f)(); + + if ((svc == NULL) || (name == NULL) || (attributes == NULL)) + return (PAPI_BAD_ARGUMENT); + + if ((result = service_connect(svc, name)) != PAPI_OK) + return (result); + + if ((*printer = p = calloc(1, sizeof (*p))) == NULL) + return (PAPI_TEMPORARY_ERROR); + + p->svc = svc; + f = (papi_status_t (*)())psm_sym(p->svc, function); + if (f != NULL) + result = f(svc->svc_handle, svc->name, attributes, + &p->printer); + + return (result); +} + +papi_status_t +papiPrinterAdd(papi_service_t handle, char *name, + papi_attribute_t **attributes, papi_printer_t *printer) +{ + return (_papi_printer_add_or_modify(handle, name, attributes, printer, + "papiPrinterAdd")); +} + +papi_status_t +papiPrinterModify(papi_service_t handle, char *name, + papi_attribute_t **attributes, papi_printer_t *printer) +{ + return (_papi_printer_add_or_modify(handle, name, attributes, printer, + "papiPrinterModify")); +} + + +papi_status_t +papiPrinterRemove(papi_service_t handle, char *name) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + papi_status_t (*f)(); + + if ((svc == NULL) || (name == NULL)) + return (PAPI_BAD_ARGUMENT); + + if ((result = service_connect(svc, name)) != PAPI_OK) + return (result); + + f = (papi_status_t (*)())psm_sym(svc, "papiPrinterRemove"); + if (f != NULL) + result = f(svc->svc_handle, svc->name); + + return (result); +} + +papi_status_t +papiPrinterPurgeJobs(papi_service_t handle, char *name, papi_job_t **jobs) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + papi_job_t *svc_jobs = NULL; + papi_status_t (*f)(); + + if ((svc == NULL) || (name == NULL)) + return (PAPI_BAD_ARGUMENT); + + if ((result = service_connect(svc, name)) != PAPI_OK) + return (result); + + f = (papi_status_t (*)())psm_sym(svc, "papiPrinterPurgeJobs"); + if (f != NULL) + result = f(svc->svc_handle, svc->name, &svc_jobs); + + /* + * copy the resulting job object pointers into our own + * representation of a job object because we need the + * service context to operate against the individual job + * objects. We free the list now because we no longer need + * it and would have no way of freeing it later. + */ + if ((result == PAPI_OK) && (svc_jobs != NULL) && (jobs != NULL)) { + int i; + + *jobs = NULL; + for (i = 0; svc_jobs[i] != NULL; i++) { + job_t *j = NULL; + + if ((j = calloc(1, sizeof (*j))) == NULL) + return (PAPI_TEMPORARY_ERROR); + + j->svc = svc; + j->job = svc_jobs[i]; + list_append(jobs, j); + } + free(svc_jobs); + } + + return (result); +} + +papi_status_t +papiPrinterListJobs(papi_service_t handle, char *name, char **requested_attrs, + int type_mask, int max_num_jobs, papi_job_t **jobs) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + papi_job_t *svc_jobs = NULL; + papi_status_t (*f)(); + + if ((svc == NULL) || (name == NULL) || (jobs == NULL)) + return (PAPI_BAD_ARGUMENT); + + if ((result = service_connect(svc, name)) != PAPI_OK) + return (result); + + f = (papi_status_t (*)())psm_sym(svc, "papiPrinterListJobs"); + if (f != NULL) + result = f(svc->svc_handle, svc->name, requested_attrs, + type_mask, max_num_jobs, &svc_jobs); + + /* + * copy the resulting job object pointers into our own + * representation of a job object because we need the + * service context to operate against the individual job + * objects. We free the list now because we no longer need + * it and would have no way of freeing it later. + */ + if ((result == PAPI_OK) && (svc_jobs != NULL)) { + int i; + + *jobs = NULL; + for (i = 0; svc_jobs[i] != NULL; i++) { + job_t *j = NULL; + + if ((j = calloc(1, sizeof (*j))) == NULL) + return (PAPI_TEMPORARY_ERROR); + + j->svc = svc; + j->job = svc_jobs[i]; + list_append(jobs, j); + } + free(svc_jobs); + } + + return (result); +} + +papi_attribute_t ** +papiPrinterGetAttributeList(papi_printer_t printer) +{ + papi_attribute_t **result = NULL; + printer_t *p = printer; + + if ((p != NULL) && (p->printer != NULL)) { + papi_attribute_t **(*f)(); + + f = (papi_attribute_t **(*)())psm_sym(p->svc, + "papiPrinterGetAttributeList"); + if (f != NULL) + result = f(p->printer); + } else + result = p->attributes; + + return (result); +} diff --git a/usr/src/lib/print/libpapi-dynamic/common/psm.c b/usr/src/lib/print/libpapi-dynamic/common/psm.c new file mode 100644 index 0000000000..6bc679b79e --- /dev/null +++ b/usr/src/lib/print/libpapi-dynamic/common/psm.c @@ -0,0 +1,100 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: psm.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <unistd.h> +#include <errno.h> +#include <string.h> +#include <dlfcn.h> +#include <papi_impl.h> + +#ifndef RTLD_GROUP +#define RTLD_GROUP 0 +#endif /* RTLD_GROUP */ + +#ifndef PSM_DIR +#define PSM_DIR "/usr/lib/print" +#endif + +papi_status_t +psm_open(service_t *svc, char *scheme) +{ + papi_status_t result = PAPI_OK; + char *path; + char buf[BUFSIZ]; + + if (scheme == NULL) + return (PAPI_BAD_ARGUMENT); + + if (strchr(scheme, '/') == NULL) { + snprintf(buf, sizeof (buf), PSM_DIR "/psm-%s.so", scheme); + path = buf; + } else + path = scheme; + + svc->so_handle = dlopen(path, RTLD_LAZY|RTLD_LOCAL|RTLD_GROUP); + if (svc->so_handle == NULL) { /* failed, set the result/message */ + if ((access(path, F_OK) < 0) && (errno == ENOENT)) + result = PAPI_URI_SCHEME; + else + result = PAPI_NOT_POSSIBLE; +#ifdef DEBUG + detailed_error(svc, "psm_open(%s): %s: %s", scheme, path, + dlerror()); +#endif + } + + return (result); +} + +void +psm_close(void *handle) +{ + dlclose(handle); +} + +void * +psm_sym(service_t *svc, char *name) +{ + char *error = "invalid input"; + void *func = NULL; + + if ((svc != NULL) && (svc->so_handle != NULL) && (name != NULL)) { + if ((func = dlsym(svc->so_handle, name)) == NULL) + error = dlerror(); + } +#ifdef DEBUG + if (func == NULL) + detailed_error(svc, "psm_sym(%s): %s", name, error); +#endif + + return (func); +} diff --git a/usr/src/lib/print/libpapi-dynamic/common/service.c b/usr/src/lib/print/libpapi-dynamic/common/service.c new file mode 100644 index 0000000000..9d441af90d --- /dev/null +++ b/usr/src/lib/print/libpapi-dynamic/common/service.c @@ -0,0 +1,564 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: service.c 172 2006-05-24 20:54:00Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/*LINTLIBRARY*/ + +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <alloca.h> +#include <libintl.h> +#include <papi_impl.h> +#include <config-site.h> + +static int +interposed_auth_callback(papi_service_t handle, void *app_data) +{ + int result = -1; + service_t *svc = app_data; + + if (svc != NULL) + result = svc->authCB(svc, svc->app_data); + + return (result); +} + +static char * +default_service_uri(char *fallback) +{ + char *result = NULL; + + if ((result = getenv("PAPI_SERVICE_URI")) == NULL) { + char *cups; + + if ((cups = getenv("CUPS_SERVER")) != NULL) { + char buf[BUFSIZ]; + + snprintf(buf, sizeof (buf), "ipp://%s/printers/", cups); + result = strdup(buf); + } + } + + if (result == NULL) + result = fallback; + + return (result); +} + +static char * +default_print_service() +{ + static char *result = NULL; + + if (result == NULL) { + char *service_uri = default_service_uri(DEFAULT_SERVICE_URI); + uri_t *uri = NULL; + + if (uri_from_string(service_uri, &uri) != -1) + result = strdup(uri->scheme); + + if (uri != NULL) + uri_free(uri); + } + + return (result); +} + +static papi_status_t +service_load(service_t *svc, char *name) +{ + papi_status_t result; + char *scheme = default_print_service(); + + if (svc->so_handle != NULL) /* already loaded */ + return (PAPI_OK); + + if (name == NULL) /* no info, can't load yet */ + return (PAPI_OK); + + /* Lookup the printer in the configuration DB */ + svc->attributes = getprinterbyname((char *)name, NULL); + + if (svc->attributes != NULL) { + char *tmp = NULL; + + /* Printer found (or was a URI), use the attribute data */ + papiAttributeListGetString(svc->attributes, NULL, + "printer-uri-supported", &tmp); + if (tmp != NULL) + svc->name = strdup(tmp); + + /* parse the URI and set the scheme(print service) */ + if (uri_from_string(svc->name, &svc->uri) != -1) + scheme = (svc->uri)->scheme; + + /* override the scheme if it was in the attributes */ + papiAttributeListGetString(svc->attributes, NULL, + "print-service-module", &scheme); + + } else /* not found, assume it is the actual print service name */ + scheme = name; + + result = psm_open(svc, scheme); + switch (result) { + case PAPI_OK: + break; /* no error */ + case PAPI_URI_SCHEME: + result = PAPI_NOT_FOUND; +#ifdef DEBUG + detailed_error(svc, "Unable to load service for: %s", name); +#endif + break; + default: /* set the detailed message */ + detailed_error(svc, "Unable to load service (%s) for: %s", + scheme, name); + } + + return (result); +} + +static papi_status_t +service_send_peer(service_t *svc) +{ + papi_status_t result = PAPI_OK; + + if ((svc->peer_fd != -1) && (svc->so_handle != NULL) && + (svc->svc_handle != NULL)) { + papi_status_t (*f)(); + + f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetPeer"); + + if (f != NULL) + result = f(svc->svc_handle, svc->peer_fd); + } + + return (result); +} + +papi_status_t +service_connect(service_t *svc, char *name) +{ + papi_status_t result = PAPI_NOT_POSSIBLE; + + /* if there is no print service module loaded, try and load one. */ + if (svc->so_handle == NULL) + result = service_load(svc, name); + else if ((svc->name == NULL) && (name != NULL)) + svc->name = strdup(name); + + /* + * the print service module is loaded, but we don't have a service + * handle. + */ + if (svc->so_handle != NULL) { + papi_status_t (*f)(); + + f = (papi_status_t (*)())psm_sym(svc, "papiServiceCreate"); + + if (f != NULL) { + char *user = svc->user; + char *password = svc->password; + + /* if no API user, try the URI user */ + if ((user == NULL) && (svc->uri != NULL)) + user = (svc->uri)->user; + /* if no API password, try the URI password */ + if ((password == NULL) && (svc->uri != NULL)) + password = (svc->uri)->password; + + result = f(&svc->svc_handle, svc->name, user, password, + (svc->authCB ? interposed_auth_callback + : NULL), + svc->encryption, svc); + (void) service_send_peer(svc); + } + } + + return (result); +} + +papi_status_t +papiServiceCreate(papi_service_t *handle, char *service_name, char *user_name, + char *password, + int (*authCB)(papi_service_t svc, void *app_data), + papi_encryption_t encryption, void *app_data) +{ + papi_status_t result = PAPI_NOT_POSSIBLE; + service_t *svc = NULL; + uri_t *u = NULL; + + if (handle == NULL) + return (PAPI_BAD_ARGUMENT); + + if ((*handle = svc = calloc(1, sizeof (*svc))) == NULL) + return (PAPI_TEMPORARY_ERROR); + + svc->peer_fd = -1; + + if (user_name != NULL) + svc->user = strdup(user_name); + + if (password != NULL) + svc->password = strdup(password); + + svc->encryption = encryption; + + if (authCB != NULL) + svc->authCB = authCB; + + if (app_data != NULL) + svc->app_data = app_data; + + /* If not specified, get a "default" service from the environment */ + if (service_name == NULL) + service_name = default_service_uri(NULL); + + if (service_name != NULL) { + result = service_load(svc, service_name); + /* if the psm loaded and the svc contains a URI, connect */ + if ((result == PAPI_OK) && (svc->uri != NULL)) + result = service_connect(svc, service_name); + } else + result = PAPI_OK; + + return (result); +} + +void +papiServiceDestroy(papi_service_t handle) +{ + if (handle != NULL) { + service_t *svc = handle; + + if (svc->so_handle != NULL) { + if (svc->svc_handle != NULL) { + void (*f)(); + + f = (void (*)())psm_sym(svc, + "papiServiceDestroy"); + f(svc->svc_handle); + } + psm_close(svc->so_handle); + } + if (svc->attributes != NULL) + papiAttributeListFree(svc->attributes); + if (svc->name != NULL) + free(svc->name); + if (svc->user != NULL) + free(svc->user); + if (svc->password != NULL) + free(svc->password); + if (svc->uri != NULL) + uri_free(svc->uri); + + free(handle); + } +} + +papi_status_t +papiServiceSetPeer(papi_service_t handle, int fd) +{ + papi_status_t result = PAPI_OK; + + if (handle != NULL) { + service_t *svc = handle; + + svc->peer_fd = fd; + result = service_send_peer(svc); + } else + result = PAPI_BAD_ARGUMENT; + + return (result); +} + +papi_status_t +papiServiceSetUserName(papi_service_t handle, char *user_name) +{ + papi_status_t result = PAPI_OK; + + if (handle != NULL) { + service_t *svc = handle; + papi_status_t (*f)(); + + if (svc->user != NULL) + free(svc->user); + if (user_name != NULL) + svc->user = strdup(user_name); + f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetUserName"); + if (f != NULL) + result = f(svc->svc_handle, user_name); + } else + result = PAPI_BAD_ARGUMENT; + + return (result); +} + +papi_status_t +papiServiceSetPassword(papi_service_t handle, char *password) +{ + papi_status_t result = PAPI_OK; + + if (handle != NULL) { + service_t *svc = handle; + papi_status_t (*f)(); + + if (svc->password != NULL) + free(svc->password); + if (password != NULL) + svc->password = strdup(password); + f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetPassword"); + if (f != NULL) + result = f(svc->svc_handle, password); + } else + result = PAPI_BAD_ARGUMENT; + + return (result); +} + +papi_status_t +papiServiceSetEncryption(papi_service_t handle, papi_encryption_t encryption) +{ + papi_status_t result = PAPI_OK; + + if (handle != NULL) { + service_t *svc = handle; + papi_status_t (*f)(); + + svc->encryption = encryption; + f = (papi_status_t (*)())psm_sym(svc, + "papiServiceSetEncryption"); + if (f != NULL) + result = f(svc->svc_handle, encryption); + } else + result = PAPI_BAD_ARGUMENT; + + return (result); +} + +papi_status_t +papiServiceSetAuthCB(papi_service_t handle, + int (*authCB)(papi_service_t svc, void *app_data)) +{ + papi_status_t result = PAPI_OK; + + if (handle != NULL) { + service_t *svc = handle; + papi_status_t (*f)(); + + svc->authCB = authCB; + f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetAuthCB"); + if (f != NULL) + result = f(svc->svc_handle, interposed_auth_callback); + } else + result = PAPI_BAD_ARGUMENT; + + return (result); +} + + +papi_status_t +papiServiceSetAppData(papi_service_t handle, void *app_data) +{ + papi_status_t result = PAPI_OK; + + if (handle != NULL) { + service_t *svc = handle; + papi_status_t (*f)(); + + svc->app_data = (void *)app_data; + } else + result = PAPI_BAD_ARGUMENT; + + return (result); +} + +char * +papiServiceGetServiceName(papi_service_t handle) +{ + char *result = NULL; + + if (handle != NULL) { + service_t *svc = handle; + char *(*f)(); + + f = (char *(*)())psm_sym(svc, "papiServiceGetServiceName"); + if (f != NULL) + result = f(svc->svc_handle); + if (result == NULL) + result = svc->name; + } + + return (result); +} + +char * +papiServiceGetUserName(papi_service_t handle) +{ + char *result = NULL; + + if (handle != NULL) { + service_t *svc = handle; + char *(*f)(); + + f = (char *(*)())psm_sym(svc, "papiServiceGetUserName"); + if (f != NULL) + result = f(svc->svc_handle); + if (result == NULL) + result = svc->user; + } + + return (result); +} + +char * +papiServiceGetPassword(papi_service_t handle) +{ + char *result = NULL; + + if (handle != NULL) { + service_t *svc = handle; + char *(*f)(); + + f = (char *(*)())psm_sym(svc, "papiServiceGetPassword"); + if (f != NULL) + result = f(svc->svc_handle); + if (result == NULL) + result = svc->password; + } + + return (result); +} + +papi_encryption_t +papiServiceGetEncryption(papi_service_t handle) +{ + papi_encryption_t result = PAPI_ENCRYPT_NEVER; + + if (handle != NULL) { + service_t *svc = handle; + papi_encryption_t (*f)(); + + f = (papi_encryption_t (*)())psm_sym(svc, + "papiServiceGetEncryption"); + if (f != NULL) + result = f(svc->svc_handle); + if (result == PAPI_ENCRYPT_NEVER) + result = svc->encryption; + } + + return (result); +} + +void * +papiServiceGetAppData(papi_service_t handle) +{ + void *result = NULL; + service_t *svc = handle; + + if (handle != NULL) + result = svc->app_data; + + return (result); +} + +papi_attribute_t ** +papiServiceGetAttributeList(papi_service_t handle) +{ + papi_attribute_t **result = NULL; + service_t *svc = handle; + + if (handle != NULL) { + papi_attribute_t **(*f)(); + + if (svc->so_handle == NULL) { + char *uri = default_service_uri(DEFAULT_SERVICE_URI); + + if (service_connect(svc, uri) != PAPI_OK) + return (NULL); + } + + f = (papi_attribute_t **(*)())psm_sym(svc, + "papiServiceGetAttributeList"); + if (f != NULL) + result = f(svc->svc_handle); + } else + result = svc->attributes; + + return (result); +} + +char * +papiServiceGetStatusMessage(papi_service_t handle) +{ + char *result = NULL; + service_t *svc = handle; + + if (handle != NULL) { + char *(*f)(); + + f = (char *(*)())psm_sym(svc, "papiServiceGetStatusMessage"); + if (f != NULL) + result = f(svc->svc_handle); + } + if (result == NULL) { + papiAttributeListGetString(svc->attributes, NULL, + "detailed-status-message", &result); + } + + return (result); +} + +void +detailed_error(service_t *svc, char *fmt, ...) +{ + if ((svc != NULL) && (fmt != NULL)) { + va_list ap; + size_t size; + char *message = alloca(BUFSIZ); + + va_start(ap, fmt); + /* + * fill in the message. If the buffer is too small, allocate + * one that is large enough and fill it in. + */ + if ((size = vsnprintf(message, BUFSIZ, fmt, ap)) >= BUFSIZ) + if ((message = alloca(size)) != NULL) + vsnprintf(message, size, fmt, ap); + va_end(ap); + + papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND, + "detailed-status-message", message); +#ifdef DEBUG + fprintf(stderr, "detailed_error(%s)\n", message); +#endif + } +} diff --git a/usr/src/lib/print/libpapi-dynamic/i386/Makefile b/usr/src/lib/print/libpapi-dynamic/i386/Makefile new file mode 100644 index 0000000000..3b985583a4 --- /dev/null +++ b/usr/src/lib/print/libpapi-dynamic/i386/Makefile @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT) diff --git a/usr/src/lib/print/libpapi-dynamic/sparc/Makefile b/usr/src/lib/print/libpapi-dynamic/sparc/Makefile new file mode 100644 index 0000000000..3b985583a4 --- /dev/null +++ b/usr/src/lib/print/libpapi-dynamic/sparc/Makefile @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT) diff --git a/usr/src/lib/print/libpapi-ipp/Makefile b/usr/src/lib/print/libpapi-ipp/Makefile new file mode 100644 index 0000000000..b92d620b10 --- /dev/null +++ b/usr/src/lib/print/libpapi-ipp/Makefile @@ -0,0 +1,56 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../../Makefile.lib + +#HDRS = papi.h +#HDRDIR = common +SUBDIRS = $(MACH) +#$(BUILD64)SUBDIRS += $(MACH64) + +all := TARGET = all +clean := TARGET = clean +clobber := TARGET = clobber +install := TARGET = install +lint := TARGET = lint + +.KEEP_STATE: + +all clean clobber install: .WAIT $(SUBDIRS) + +lint: # $(SUBDIRS) + +install_h: # $(ROOTHDRS) + +check: # $(CHECKHDRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include ../../Makefile.targ diff --git a/usr/src/lib/print/libpapi-ipp/Makefile.com b/usr/src/lib/print/libpapi-ipp/Makefile.com new file mode 100644 index 0000000000..12c748773d --- /dev/null +++ b/usr/src/lib/print/libpapi-ipp/Makefile.com @@ -0,0 +1,71 @@ +# +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +LIBRARY = psm-ipp.a +VERS = .1 +OBJECTS = ipp-support.o job.o printer.o service.o +ROOTLIBDIR = $(ROOT)/usr/lib/print + +include ../../../Makefile.lib +include ../../../Makefile.rootfs + +ROOTLIBDIR= $(ROOT)/usr/lib/print +ROOTLIBDIR64= $(ROOT)/usr/lib/print/$(MACH) + +EXTRALINKS= $(ROOTLIBDIR)/psm-http.so +$(EXTRALINKS): $(ROOTLINKS) + $(RM) $@; $(SYMLINK) $(LIBLINKS) $@ + +LIBS = $(DYNLIB) + +SRCS = $(OBJECTS:%.o = $(SRCDIR)/%.c) + +$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC) + +SRCDIR = ../common +MAPFILE = $(SRCDIR)/mapfile + +CFLAGS += $(CCVERBOSE) +CPPFLAGS += -I$(SRCDIR) +CPPFLAGS += -I../../libpapi-common/common +CPPFLAGS += -I../../libipp-core/common +CPPFLAGS += -I../../libhttp-core/common +DYNFLAGS += $(BDIRECT) -M $(MAPFILE) +LDLIBS += -L$(ROOTLIBDIR) -R/usr/lib/print -lhttp-core -lmd5 +LDLIBS += -lipp-core -lc + +.KEEP_STATE: + +all: $(LIBS) + +lint: lintcheck + +$(ROOTLIBDIR): + $(INS.dir) + +include ../../../Makefile.targ diff --git a/usr/src/lib/print/libpapi-ipp/common/ipp-support.c b/usr/src/lib/print/libpapi-ipp/common/ipp-support.c new file mode 100644 index 0000000000..f0f6ced38d --- /dev/null +++ b/usr/src/lib/print/libpapi-ipp/common/ipp-support.c @@ -0,0 +1,612 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: ipp-support.c 148 2006-04-25 16:54:17Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <papi_impl.h> +#include <stdlib.h> +#include <pwd.h> +#include <locale.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <md5.h> + +#include <config-site.h> + +papi_status_t +http_to_papi_status(http_status_t status) +{ + switch (status) { + case HTTP_OK: + return (PAPI_OK); + case HTTP_BAD_REQUEST: + return (PAPI_BAD_REQUEST); + case HTTP_UNAUTHORIZED: + case HTTP_FORBIDDEN: + return (PAPI_NOT_AUTHORIZED); + case HTTP_NOT_FOUND: + return (PAPI_NOT_FOUND); + case HTTP_GONE: + return (PAPI_GONE); + case HTTP_SERVICE_UNAVAILABLE: + return (PAPI_SERVICE_UNAVAILABLE); + default: + return ((papi_status_t)status); + } +} + +papi_status_t +ipp_to_papi_status(uint16_t status) +{ + switch (status) { + case IPP_OK: + return (PAPI_OK); + case IPP_OK_IGNORED_ATTRIBUTES: + return (PAPI_OK); + case IPP_OK_CONFLICTING_ATTRIBUTES: + return (PAPI_OK); + case IPP_OK_IGNORED_SUBSCRIPTIONS: + return (PAPI_OK_IGNORED_SUBSCRIPTIONS); + case IPP_OK_IGNORED_NOTIFICATIONS: + return (PAPI_OK_IGNORED_NOTIFICATIONS); + case IPP_CERR_BAD_REQUEST: + return (PAPI_BAD_REQUEST); + case IPP_CERR_FORBIDDEN: + return (PAPI_FORBIDDEN); + case IPP_CERR_NOT_AUTHENTICATED: + return (PAPI_NOT_AUTHENTICATED); + case IPP_CERR_NOT_AUTHORIZED: + return (PAPI_NOT_AUTHORIZED); + case IPP_CERR_NOT_POSSIBLE: + return (PAPI_NOT_POSSIBLE); + case IPP_CERR_TIMEOUT: + return (PAPI_TIMEOUT); + case IPP_CERR_NOT_FOUND: + return (PAPI_NOT_FOUND); + case IPP_CERR_GONE: + return (PAPI_GONE); + case IPP_CERR_REQUEST_ENTITY: + return (PAPI_REQUEST_ENTITY); + case IPP_CERR_REQUEST_VALUE: + return (PAPI_REQUEST_VALUE); + case IPP_CERR_DOCUMENT_FORMAT: + return (PAPI_DOCUMENT_FORMAT); + case IPP_CERR_ATTRIBUTES: + return (PAPI_ATTRIBUTES); + case IPP_CERR_URI_SCHEME: + return (PAPI_URI_SCHEME); + case IPP_CERR_CHARSET: + return (PAPI_CHARSET); + case IPP_CERR_CONFLICT: + return (PAPI_CONFLICT); + case IPP_CERR_COMPRESSION_NOT_SUPPORTED: + return (PAPI_COMPRESSION_NOT_SUPPORTED); + case IPP_CERR_COMPRESSION_ERROR: + return (PAPI_COMPRESSION_ERROR); + case IPP_CERR_DOCUMENT_FORMAT_ERROR: + return (PAPI_DOCUMENT_FORMAT_ERROR); + case IPP_CERR_DOCUMENT_ACCESS_ERROR: + return (PAPI_DOCUMENT_ACCESS_ERROR); + case IPP_CERR_ATTRIBUTES_NOT_SETTABLE: + return (PAPI_ATTRIBUTES_NOT_SETTABLE); + case IPP_CERR_IGNORED_ALL_SUBSCRIPTIONS: + return (PAPI_IGNORED_ALL_SUBSCRIPTIONS); + case IPP_CERR_TOO_MANY_SUBSCRIPTIONS: + return (PAPI_TOO_MANY_SUBSCRIPTIONS); + case IPP_CERR_IGNORED_ALL_NOTIFICATIONS: + return (PAPI_IGNORED_ALL_NOTIFICATIONS); + case IPP_CERR_PRINT_SUPPORT_FILE_NOT_FOUND: + return (PAPI_PRINT_SUPPORT_FILE_NOT_FOUND); + case IPP_SERR_INTERNAL: + return (PAPI_INTERNAL_ERROR); + case IPP_SERR_OPERATION_NOT_SUPPORTED: + return (PAPI_OPERATION_NOT_SUPPORTED); + case IPP_SERR_SERVICE_UNAVAILABLE: + return (PAPI_SERVICE_UNAVAILABLE); + case IPP_SERR_VERSION_NOT_SUPPORTED: + return (PAPI_VERSION_NOT_SUPPORTED); + case IPP_SERR_DEVICE_ERROR: + return (PAPI_DEVICE_ERROR); + case IPP_SERR_TEMPORARY_ERROR: + return (PAPI_TEMPORARY_ERROR); + case IPP_SERR_NOT_ACCEPTING: + return (PAPI_NOT_ACCEPTING); + case IPP_SERR_BUSY: + case IPP_SERR_CANCELLED: + default: + return (PAPI_TEMPORARY_ERROR); + } +} + +void +ipp_initialize_request(service_t *svc, papi_attribute_t ***request, + uint16_t operation) +{ + papiAttributeListAddInteger(request, PAPI_ATTR_EXCL, + "version-major", 1); + papiAttributeListAddInteger(request, PAPI_ATTR_EXCL, + "version-minor", 1); + papiAttributeListAddInteger(request, PAPI_ATTR_EXCL, + "request-id", (short)lrand48()); + papiAttributeListAddInteger(request, PAPI_ATTR_EXCL, + "operation-id", operation); +} + +void +ipp_initialize_operational_attributes(service_t *svc, papi_attribute_t ***op, + papi_attribute_t **attributes) +{ + char *charset = "utf-8"; /* default to UTF-8 encoding */ + char *language = setlocale(LC_ALL, ""); + char *user = "nobody"; + struct passwd *pw = NULL; + + /* + * All IPP requests must contain the following: + * attributes-charset (UTF-8) + * attributes-natural-language (our current locale) + * requesting-user-name (process user) + */ + papiAttributeListGetString(attributes, NULL, + "attributes-charset", &charset); + papiAttributeListAddString(op, PAPI_ATTR_EXCL, + "attributes-charset", charset); + + papiAttributeListGetString(attributes, NULL, + "attributes-natural-language", &language); + papiAttributeListAddString(op, PAPI_ATTR_EXCL, + "attributes-natural-language", language); + + if ((pw = getpwuid(getuid())) != NULL) + user = pw->pw_name; + /* + * if our euid is 0 "super user", we will allow the system supplied + * user name to be overridden, if the requestor wants to. + */ + if (geteuid() == 0) { + if (svc->user != NULL) + user = svc->user; + papiAttributeListGetString(attributes, NULL, + "requesting-user-name", &user); + } + papiAttributeListAddString(op, PAPI_ATTR_REPLACE, + "requesting-user-name", user); +} + +#ifndef OPID_CUPS_GET_DEFAULT /* for servers that will enumerate */ +#define OPID_CUPS_GET_DEFAULT 0x4001 +#endif /* OPID_CUPS_GET_DEFAULT */ + +static papi_status_t +_default_destination(service_t *svc, char **uri) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + printer_t *p = NULL; + papi_attribute_t **request = NULL, **op = NULL, **response = NULL; + char *tmp = NULL; + + if ((svc == NULL) || (uri == NULL)) + return (PAPI_BAD_ARGUMENT); + + /* we must be connected to find the default destination */ + if (svc->connection == NULL) + return (PAPI_NOT_POSSIBLE); + + if ((p = calloc(1, sizeof (*p))) == NULL) + return (PAPI_TEMPORARY_ERROR); + + ipp_initialize_request(svc, &request, OPID_CUPS_GET_DEFAULT); + ipp_initialize_operational_attributes(svc, &op, NULL); + papiAttributeListAddString(&op, PAPI_ATTR_APPEND, + "requested-attributes", "printer-uri-supported"); + papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, + "operational-attributes-group", op); + papiAttributeListFree(op); + result = ipp_send_request(svc, request, &response); + papiAttributeListFree(request); + + op = NULL; + papiAttributeListGetCollection(response, NULL, + "printer-attributes-group", &op); + + if (uri != NULL) { + char *tmp = NULL; + + papiAttributeListGetString(op, NULL, "printer-uri", &tmp); + papiAttributeListGetString(op, NULL, + "printer-uri-supported", &tmp); + if (tmp != NULL) + *uri = strdup(tmp); + } + + papiAttributeListFree(response); + + return (result); +} + +void +ipp_add_printer_uri(service_t *svc, char *name, papi_attribute_t ***op) +{ + char *uri = name; + char buf[BUFSIZ]; + uri_t *tmp = NULL; + + if (strstr(name, "://") == NULL) { /* not in URI form */ + if (strcmp(name, DEFAULT_DEST) != 0) { + /* not the "default" */ + snprintf(buf, sizeof (buf), "%s/%s", svc->name, name); + uri = buf; + } else + _default_destination(svc, &uri); + } + + papiAttributeListAddString(op, PAPI_ATTR_EXCL, "printer-uri", uri); + + /* save the printer-uri's path to be used by http POST request */ + if ((uri_from_string(uri, &tmp) == 0) && (tmp != NULL)) { + if (svc->post != NULL) + free(svc->post); + svc->post = strdup(tmp->path); + uri_free(tmp); + } +} + + +/* + * don't actually write anything, just add to the total size and return the + * size of what would be written, so we can figure out how big the request + * is going to be. + */ +static ssize_t +size_calculate(void *fd, void *buffer, size_t length) +{ + ssize_t *size = (ssize_t *)fd; + + *size += length; + return (length); +} + + +static ssize_t +build_chunk(void *fd, void *buffer, size_t length) +{ + char **s1 = fd; + + memcpy(*s1, buffer, length); + *s1 = *s1 + length; + + return (length); +} + +ssize_t +ipp_request_write(void *fd, void *buffer, size_t length) +{ + service_t *svc = (service_t *)fd; + +#ifdef DEBUG + printf("ipp_request_write(0x%8.8x, 0x%8.8x, %d)\n", fd, buffer, length); + httpDumpData(stdout, "ipp_request_write:", buffer, length); +#endif + return (httpWrite(svc->connection, buffer, length)); +} + +ssize_t +ipp_request_read(void *fd, void *buffer, size_t length) +{ + service_t *svc = (service_t *)fd; + ssize_t rc, i = length; + char *p = buffer; + + while ((rc = httpRead(svc->connection, p, i)) != i) { + if (rc == 0) + return (rc); + if (rc < 0) + return (rc); + i -= rc; + p += rc; + } +#ifdef DEBUG + printf("ipp_request_read(0x%8.8x, 0x%8.8x, %d) = %d\n", + fd, buffer, length, rc); + httpDumpData(stdout, "ipp_request_read:", buffer, length); +#endif + + return (length); +} + +papi_status_t +ipp_send_initial_request_block(service_t *svc, papi_attribute_t **request, + ssize_t file_size) +{ + papi_status_t result = PAPI_OK; + ssize_t chunk_size = 0; + char length[32]; + void *chunk, *ptr; + http_status_t status; + + /* calculate the request size */ + (void) ipp_write_message(&size_calculate, &chunk_size, request); + + /* Fill in the HTTP Header information */ + httpClearFields(svc->connection); + if (svc->transfer_encoding == TRANSFER_ENCODING_CHUNKED) + httpSetField(svc->connection, HTTP_FIELD_TRANSFER_ENCODING, + "chunked"); + else { + sprintf(length, "%lu", (unsigned long)(file_size + chunk_size)); + httpSetField(svc->connection, HTTP_FIELD_CONTENT_LENGTH, + length); + } + httpSetField(svc->connection, HTTP_FIELD_CONTENT_TYPE, + "application/ipp"); + httpSetField(svc->connection, HTTP_FIELD_AUTHORIZATION, + svc->connection->authstring); + + /* flush any state information about this connection */ + httpFlush(svc->connection); + + /* if we have don't have a POST path, use the service uri path */ + if (svc->post == NULL) + svc->post = strdup(svc->uri->path); + /* send the HTTP POST message for the IPP request */ + /* if the POST fails, return the error */ + status = httpPost(svc->connection, svc->post); + if (status != 0) + return (http_to_papi_status(status)); + + if (httpCheck(svc->connection) != 0) { + status = httpUpdate(svc->connection); + if (status != HTTP_OK) + return (http_to_papi_status(status)); + } + + /* build the request chunk */ + chunk = ptr = calloc(1, chunk_size); + result = ipp_write_message(&build_chunk, &ptr, request); +#ifdef DEBUG + printf("request: %d (0x%x) bytes\n", chunk_size, chunk_size); + httpDumpData(stdout, "request:", chunk, chunk_size); +#endif + + /* send the actual IPP request */ + if (ipp_request_write(svc, chunk, chunk_size) != chunk_size) + result = PAPI_TEMPORARY_ERROR; + free(chunk); + + if (httpCheck(svc->connection) != 0) { + status = httpUpdate(svc->connection); + if (status != HTTP_OK) + return (http_to_papi_status(status)); + } + + return (result); +} + +static int +setAuthString(service_t *svc) +{ + http_t *http; + char *user, *passphrase; + char encoded[BUFSIZ]; + + if ((svc == NULL) || (svc->connection == NULL) || (svc->name == NULL)) + return (-1); + + http = svc->connection; + + if (svc->user == NULL) { + struct passwd *p; + + if ((p = getpwuid(getuid())) != NULL) { + user = p->pw_name; + } else if ((user = getenv("LOGNAME")) == NULL) + user = getenv("USER"); + if (user == NULL) + user = "nobody"; + } else + user = svc->user; + + /* if the passphrase is not set, use the Authentication Callback */ + if (((svc->password == NULL) || (svc->password[0] == '\0')) && + (svc->authCB != NULL)) + (svc->authCB)(svc, svc->app_data); + passphrase = svc->password; + + /* if there is still no passphrase, we have to fail */ + if ((passphrase == NULL) || (passphrase[0] == '\0')) + return (-1); + + if (strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], + "Basic", 5) == 0) { + char plain[BUFSIZ]; + + snprintf(plain, sizeof (plain), "%s:%s", user, passphrase); + httpEncode64(encoded, plain); + snprintf(http->authstring, sizeof (http->authstring), + "Basic %s", encoded); + } else if (strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], + "Digest", 6) == 0) { + char realm[HTTP_MAX_VALUE]; + char nonce[HTTP_MAX_VALUE]; + char line [BUFSIZ]; + char urp[128]; + char mr[128]; + char *uri = svc->post; + + httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, + "realm", realm); + httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, + "nonce", nonce); + + snprintf(line, sizeof (line), "%s:%s:%s", user, realm, + passphrase); + md5_calc(urp, line, strlen(line)); + + snprintf(line, sizeof (line), "POST:%s", uri); + md5_calc(mr, line, strlen(line)); + + snprintf(line, sizeof (line), "%s:%s:%s", urp, mr, nonce); + md5_calc(encoded, line, strlen(line)); + + snprintf(http->authstring, sizeof (http->authstring), + "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", " + "uri=\"%s\", response=\"%s\"", user, realm, nonce, uri, + encoded); + } + + return (0); +} + +papi_status_t +ipp_status_info(service_t *svc, papi_attribute_t **response) +{ + papi_attribute_t **operational = NULL; + int32_t status = 0; + + papiAttributeListGetCollection(response, NULL, + "operational-attributes-group", &operational); + if (operational != NULL) { + char *message = NULL; + + papiAttributeListGetString(response, NULL, + "status-message", &message); + papiAttributeListAddString(&svc->attributes, PAPI_ATTR_REPLACE, + "detailed-status-message", message); + } + papiAttributeListGetInteger(response, NULL, "status-code", &status); + + return (ipp_to_papi_status(status)); +} + +papi_status_t +ipp_send_request_with_file(service_t *svc, papi_attribute_t **request, + papi_attribute_t ***response, char *file) +{ + papi_status_t result = PAPI_OK; + ssize_t size = 0; + int fd; + +#ifdef DEBUG + fprintf(stderr, "\nIPP-REQUEST: (%s)", (file ? file : "")); + papiAttributeListPrint(stderr, request, " "); + putc('\n', stderr); + fflush(stderr); +#endif + + /* + * if we are sending a file, open it and include it's size in the + * message size. + */ + if (file != NULL) { + if ((fd = open(file, O_RDONLY)) < 0) { + detailed_error(svc, "%s: %s", file, strerror(errno)); + return (PAPI_DOCUMENT_ACCESS_ERROR); + } else if (svc->transfer_encoding != + TRANSFER_ENCODING_CHUNKED) { + struct stat st; + + if (fstat(fd, &st) >= 0) + size = st.st_size; + } + } + + *response = NULL; + while (*response == NULL) { + http_status_t status = HTTP_CONTINUE; + + result = ipp_send_initial_request_block(svc, request, size); + + if (result == PAPI_OK) { + if (file != NULL) { + /* send the file contents if we have it */ + int rc; + char buf[BUFSIZ]; + + lseek(fd, 0L, SEEK_SET); + while ((rc = read(fd, buf, sizeof (buf))) > 0) { + if (ipp_request_write(svc, buf, rc) + < rc) { + break; + } + } + } + + (void) ipp_request_write(svc, "", 0); + } + + /* update our connection info */ + while (status == HTTP_CONTINUE) + status = httpUpdate(svc->connection); + + if (status == HTTP_UNAUTHORIZED) { + httpFlush(svc->connection); + if ((svc->connection->authstring[0] == '\0') && + (setAuthString(svc) == 0)) { + httpReconnect(svc->connection); + continue; + } + } else if (status == HTTP_UPGRADE_REQUIRED) { + /* + * If the transport was built with TLS support, we can + * try to use it. + */ + httpFlush(svc->connection); + httpReconnect(svc->connection); + httpEncryption(svc->connection, HTTP_ENCRYPT_REQUIRED); + continue; + } + + if (status != HTTP_OK) + return (http_to_papi_status(status)); + + /* read the IPP response */ + result = ipp_read_message(&ipp_request_read, svc, response, + IPP_TYPE_RESPONSE); + + if (result == PAPI_OK) + result = ipp_status_info(svc, *response); +#ifdef DEBUG + fprintf(stderr, "\nIPP-RESPONSE: (%s) (%s)", (file ? file : ""), + papiStatusString(result)); + papiAttributeListPrint(stderr, *response, " "); + putc('\n', stderr); + fflush(stderr); +#endif + } + + return (result); +} + +papi_status_t +ipp_send_request(service_t *svc, papi_attribute_t **request, + papi_attribute_t ***response) +{ + return (ipp_send_request_with_file(svc, request, response, NULL)); +} diff --git a/usr/src/lib/print/libpapi-ipp/common/job.c b/usr/src/lib/print/libpapi-ipp/common/job.c new file mode 100644 index 0000000000..3db5e269e2 --- /dev/null +++ b/usr/src/lib/print/libpapi-ipp/common/job.c @@ -0,0 +1,627 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: job.c 148 2006-04-25 16:54:17Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/*LINTLIBRARY*/ + +#include <stdlib.h> +#include <errno.h> +#include <string.h> +#include <papi_impl.h> + +#ifndef OPID_CUPS_MOVE_JOB +#define OPID_CUPS_MOVE_JOB 0x400D +#endif + +void +papiJobFree(papi_job_t job) +{ + job_t *tmp = (job_t *)job; + + if (tmp != NULL) { + if (tmp->attributes != NULL) + papiAttributeListFree(tmp->attributes); + free(tmp); + } +} + +void +papiJobListFree(papi_job_t *jobs) +{ + if (jobs != NULL) { + int i; + + for (i = 0; jobs[i] != NULL; i++) + papiJobFree(jobs[i]); + free(jobs); + } +} + +papi_attribute_t ** +papiJobGetAttributeList(papi_job_t job) +{ + papi_attribute_t **result = NULL; + job_t *j = job; + + if (j != NULL) + result = j->attributes; + + return (result); +} + +char * +papiJobGetPrinterName(papi_job_t job) +{ + char *result = NULL; + job_t *j = job; + + if (j != NULL) + (void) papiAttributeListGetString(j->attributes, NULL, + "printer-name", &result); + + return (result); +} + +int32_t +papiJobGetId(papi_job_t job) +{ + int32_t result = -1; + job_t *j = job; + + if (j != NULL) + (void) papiAttributeListGetInteger(j->attributes, NULL, + "job-id", &result); + + return (result); +} + +papi_job_ticket_t * +papiJobGetJobTicket(papi_job_t job) +{ + papi_job_ticket_t *result = NULL; + + return (result); +} + +static void +populate_job_request(service_t *svc, papi_attribute_t ***request, + papi_attribute_t **attributes, char *printer, uint16_t type) +{ + papi_attribute_t **operational = NULL, **job = NULL; + static char *operational_names[] = { + "job-name", "ipp-attribute-fidelity", "document-name", + "compression", "document-format", "document-natural-language", + "job-k-octets", "job-impressions", "job-media-sheets", NULL + }; + + /* create the base IPP request */ + ipp_initialize_request(svc, request, type); + + /* create an operational attributes group */ + ipp_initialize_operational_attributes(svc, &operational, NULL); + ipp_add_printer_uri(svc, printer, &operational); + + /* split up the attributes into operational and job attributes */ + split_and_copy_attributes(operational_names, attributes, + &operational, &job); + + /* add the operational attributes group to the request */ + papiAttributeListAddCollection(request, PAPI_ATTR_REPLACE, + "operational-attributes-group", operational); + papiAttributeListFree(operational); + + /* add the job attributes group to the request */ + if (job != NULL) { + papiAttributeListAddCollection(request, PAPI_ATTR_REPLACE, + "job-attributes-group", job); + papiAttributeListFree(job); + } +} + +static papi_status_t +send_document_uri(service_t *svc, char *file, papi_attribute_t **attributes, + char *printer, int32_t id, char last, uint16_t type) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + papi_attribute_t **request = NULL, **op = NULL, **response = NULL; + + /* create the base IPP request */ + ipp_initialize_request(svc, &request, type); + + /* create an operational attributes group */ + ipp_initialize_operational_attributes(svc, &op, NULL); + ipp_add_printer_uri(svc, printer, &op); + + papiAttributeListAddInteger(&op, PAPI_ATTR_REPLACE, "job-id", + id); + papiAttributeListAddString(&op, PAPI_ATTR_REPLACE, "document-name", + file); + papiAttributeListAddBoolean(&op, PAPI_ATTR_REPLACE, "last-document", + (last ? PAPI_TRUE : PAPI_FALSE)); + papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, + "operational-attributes-group", op); + papiAttributeListFree(op); + + /* send the IPP request to the server */ + result = ipp_send_request_with_file(svc, request, &response, file); + papiAttributeListFree(request); + papiAttributeListFree(response); + + return (result); +} + +typedef enum {_WITH_DATA, _BY_REFERENCE, _VALIDATE} call_type_t; + +papi_status_t +internal_job_submit(papi_service_t handle, char *printer, + papi_attribute_t **job_attributes, + papi_job_ticket_t *job_ticket, + char **files, papi_job_t *job, + call_type_t call_type) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + job_t *j = NULL; + int i; + uint16_t req_type = OPID_PRINT_JOB; + uint16_t data_type = OPID_SEND_DOCUMENT; + papi_attribute_t **request = NULL, **response = NULL; + + if ((svc == NULL) || (printer == NULL) || (job == NULL)) + return (PAPI_BAD_ARGUMENT); + + switch (call_type) { + case _BY_REFERENCE: +#ifdef SOME_DAY_WE_WILL_BE_ABLE_TO_USE_URIS_FOR_JOB_DATA + /* + * For the time being, this is disabled. There are a number + * of issues to be dealt with before we can send a URI + * across the network to the server. For example, the file + * name(s) passed in are most likely relative to the current + * hosts filesystem. They also most likely will require some + * form of authentication information to be passed with the + * URI. + */ + req_type = OPID_PRINT_URI; + req_type = OPID_SEND_URI; +#endif + /* fall-through */ + case _WITH_DATA: + if ((files == NULL) || (files[0] == NULL)) + return (PAPI_BAD_ARGUMENT); + + if (files[1] != NULL) /* more than 1 file */ + req_type = OPID_CREATE_JOB; + + break; + case _VALIDATE: + req_type = OPID_VALIDATE_JOB; + /* if we have files, validate access to them */ + if (files != NULL) { + for (i = 0; files[i] != NULL; i++) + if (access(files[i], R_OK) < 0) { + detailed_error(svc, "%s: %s", files[i], + strerror(errno)); + return (PAPI_DOCUMENT_ACCESS_ERROR); + } + files = NULL; + } + break; + } + + /* if we are already connected, use that connection. */ + if (svc->connection == NULL) + if ((result = service_connect(svc, printer)) != PAPI_OK) + return (result); + + if ((*job = j = calloc(1, sizeof (*j))) == NULL) + return (PAPI_TEMPORARY_ERROR); + + /* create IPP request */ + populate_job_request(svc, &request, job_attributes, printer, req_type); + + switch (req_type) { + case OPID_PRINT_JOB: + result = ipp_send_request_with_file(svc, request, &response, + files[0]); + break; + case OPID_CREATE_JOB: + case OPID_VALIDATE_JOB: + case OPID_PRINT_URI: + result = ipp_send_request(svc, request, &response); + break; + } + papiAttributeListFree(request); + + if (result == PAPI_OK) { + papi_attribute_t **op = NULL; + + /* retrieve the job attributes */ + papiAttributeListGetCollection(response, NULL, + "job-attributes-group", &op); + copy_attributes(&j->attributes, op); + + if (req_type == OPID_CREATE_JOB) { + int32_t id = 0; + + papiAttributeListGetInteger(j->attributes, NULL, + "job-id", &id); + /* send each document */ + for (i = 0; ((result == PAPI_OK) && (files[i] != NULL)); + i++) + result = send_document_uri(svc, files[i], + job_attributes, + printer, id, (files[i+1]?0:1), + data_type); + } + } + papiAttributeListFree(response); + + return (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) +{ + return (internal_job_submit(handle, printer, job_attributes, + job_ticket, files, job, _WITH_DATA)); +} + +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) +{ + return (internal_job_submit(handle, printer, job_attributes, + job_ticket, files, job, _BY_REFERENCE)); +} + +papi_status_t +papiJobValidate(papi_service_t handle, char *printer, + papi_attribute_t **job_attributes, + papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) +{ + return (internal_job_submit(handle, printer, job_attributes, + job_ticket, files, job, _VALIDATE)); +} + +papi_status_t +papiJobStreamOpen(papi_service_t handle, char *printer, + papi_attribute_t **job_attributes, + papi_job_ticket_t *job_ticket, papi_stream_t *stream) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + papi_attribute_t **request = NULL; + service_t *svc = handle; + + if ((svc == NULL) || (printer == NULL) || (stream == NULL)) + return (PAPI_BAD_ARGUMENT); + + /* if we are already connected, use that connection. */ + if (svc->connection == NULL) + if ((result = service_connect(svc, printer)) != PAPI_OK) + return (result); + + /* create job request */ + populate_job_request(svc, &request, job_attributes, printer, + OPID_PRINT_JOB); + + *stream = svc->connection; + + result = ipp_send_initial_request_block(svc, request, 0); + papiAttributeListFree(request); + + return (result); +} + +papi_status_t +papiJobStreamWrite(papi_service_t handle, + papi_stream_t stream, void *buffer, size_t buflen) +{ + papi_status_t result = PAPI_OK; + service_t *svc = handle; + size_t rc; + +#ifdef DEBUG + printf("papiJobStreamWrite(0x%8.8x, 0x%8.8x, 0x%8.8x, %d)\n", + handle, stream, buffer, buflen); + httpDumpData(stdout, "papiJobStreamWrite:", buffer, buflen); +#endif + + if ((svc == NULL) || (stream == NULL) || (buffer == NULL) || + (buflen == 0)) + return (PAPI_BAD_ARGUMENT); + + while ((result == PAPI_OK) && (buflen > 0)) { + rc = ipp_request_write(svc, buffer, buflen); + if (rc < 0) + result = PAPI_TEMPORARY_ERROR; + else { + buffer = (char *)buffer + rc; + buflen -= rc; + } + } + +#ifdef DEBUG + printf("papiJobStreamWrite(): %s\n", papiStatusString(result)); +#endif + + return (result); +} + +papi_status_t +papiJobStreamClose(papi_service_t handle, + papi_stream_t stream, papi_job_t *job) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + http_status_t status = HTTP_CONTINUE; + service_t *svc = handle; + papi_attribute_t **response = NULL; + job_t *j = NULL; + + if ((svc == NULL) || (stream == NULL) || (job == NULL)) + return (PAPI_BAD_ARGUMENT); + + if ((*job = j = calloc(1, sizeof (*j))) == NULL) + return (PAPI_TEMPORARY_ERROR); + + (void) ipp_request_write(svc, "", 0); + + /* update our connection info */ + while (status == HTTP_CONTINUE) + status = httpUpdate(svc->connection); + + if (status != HTTP_OK) + return (http_to_papi_status(status)); + httpWait(svc->connection, 1000); + + /* read the IPP response */ + result = ipp_read_message(&ipp_request_read, svc, &response, + IPP_TYPE_RESPONSE); + if (result == PAPI_OK) + result = ipp_status_info(svc, response); + + if (result == PAPI_OK) { + papi_attribute_t **op = NULL; + + papiAttributeListGetCollection(response, NULL, + "job-attributes-group", &op); + copy_attributes(&j->attributes, op); + } + papiAttributeListFree(response); + + return (result); +} + +papi_status_t +papiJobQuery(papi_service_t handle, char *printer, int32_t job_id, + char **requested_attrs, + papi_job_t *job) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + job_t *j = NULL; + papi_attribute_t **request = NULL, **op = NULL, **response = NULL; + + if ((svc == NULL) || (printer == NULL)) + return (PAPI_BAD_ARGUMENT); + + /* if we are already connected, use that connection. */ + if (svc->connection == NULL) + if ((result = service_connect(svc, printer)) != PAPI_OK) + return (result); + + if ((*job = j = calloc(1, sizeof (*j))) == NULL) + return (PAPI_TEMPORARY_ERROR); + + ipp_initialize_request(svc, &request, OPID_GET_JOB_ATTRIBUTES); + + ipp_initialize_operational_attributes(svc, &op, NULL); + ipp_add_printer_uri(svc, printer, &op); + + papiAttributeListAddInteger(&op, PAPI_ATTR_REPLACE, "job-id", job_id); + if (requested_attrs != NULL) { + int i; + + for (i = 0; requested_attrs[i] != NULL; i++) + papiAttributeListAddString(&op, PAPI_ATTR_APPEND, + "requested-attributes", requested_attrs[i]); + } + + papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, + "operational-attributes-group", op); + papiAttributeListFree(op); + result = ipp_send_request(svc, request, &response); + papiAttributeListFree(request); + + op = NULL; + papiAttributeListGetCollection(response, NULL, + "job-attributes-group", &op); + copy_attributes(&j->attributes, op); + papiAttributeListFree(response); + + return (result); +} + +/* papiJob{Cancel|Hold|Release|Restart|Promote} are all the same */ +static papi_status_t +_job_cancel_hold_release_restart_promote(papi_service_t handle, + char *printer, int32_t job_id, uint16_t type) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + papi_attribute_t **request = NULL, **op = NULL, **response = NULL; + + if ((svc == NULL) || (printer == NULL) || (job_id < 0)) + return (PAPI_BAD_ARGUMENT); + + /* if we are already connected, use that connection. */ + if (svc->connection == NULL) + if ((result = service_connect(svc, printer)) != PAPI_OK) + return (result); + + ipp_initialize_request(svc, &request, type); + + ipp_initialize_operational_attributes(svc, &op, NULL); + ipp_add_printer_uri(svc, printer, &op); + + papiAttributeListAddInteger(&op, PAPI_ATTR_REPLACE, "job-id", job_id); + papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, + "operational-attributes-group", op); + papiAttributeListFree(op); + result = ipp_send_request(svc, request, &response); + papiAttributeListFree(request); + papiAttributeListFree(response); + + return (result); +} + +papi_status_t +papiJobCancel(papi_service_t handle, char *printer, int32_t job_id) +{ + return (_job_cancel_hold_release_restart_promote(handle, printer, + job_id, OPID_CANCEL_JOB)); +} + + +papi_status_t +papiJobHold(papi_service_t handle, char *printer, int32_t job_id) +{ + return (_job_cancel_hold_release_restart_promote(handle, printer, + job_id, OPID_HOLD_JOB)); +} + +papi_status_t +papiJobRelease(papi_service_t handle, char *printer, int32_t job_id) +{ + return (_job_cancel_hold_release_restart_promote(handle, printer, + job_id, OPID_RELEASE_JOB)); +} + +papi_status_t +papiJobRestart(papi_service_t handle, char *printer, int32_t job_id) +{ + return (_job_cancel_hold_release_restart_promote(handle, printer, + job_id, OPID_RESTART_JOB)); +} + +papi_status_t +papiJobPromote(papi_service_t handle, char *printer, int32_t job_id) +{ + return (_job_cancel_hold_release_restart_promote(handle, printer, + job_id, OPID_PROMOTE_JOB)); +} + +papi_status_t +papiJobMove(papi_service_t handle, char *printer, int32_t job_id, + char *destination) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + papi_attribute_t **request = NULL, **op = NULL, **response = NULL; + + if ((svc == NULL) || (printer == NULL) || (job_id < 0) || + (destination == NULL)) + return (PAPI_BAD_ARGUMENT); + + /* if we are already connected, use that connection. */ + if (svc->connection == NULL) + if ((result = service_connect(svc, printer)) != PAPI_OK) + return (result); + + ipp_initialize_request(svc, &request, OPID_CUPS_MOVE_JOB); + + ipp_initialize_operational_attributes(svc, &op, NULL); + ipp_add_printer_uri(svc, printer, &op); + + papiAttributeListAddInteger(&op, PAPI_ATTR_REPLACE, "job-id", job_id); + papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, + "operational-attributes-group", op); + papiAttributeListFree(op); + + op = NULL; + papiAttributeListAddString(&op, PAPI_ATTR_EXCL, + "job-printer-uri", destination); + papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, + "job-attributes-group", op); + papiAttributeListFree(op); + + result = ipp_send_request(svc, request, &response); + papiAttributeListFree(request); + papiAttributeListFree(response); + + 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 result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + papi_attribute_t **request = NULL, **op = NULL, **response = NULL; + job_t *j = NULL; + + 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); + + /* if we are already connected, use that connection. */ + if (svc->connection == NULL) + if ((result = service_connect(svc, printer)) != PAPI_OK) + return (result); + + ipp_initialize_request(svc, &request, OPID_SET_JOB_ATTRIBUTES); + + ipp_initialize_operational_attributes(svc, &op, NULL); + ipp_add_printer_uri(svc, printer, &op); + + papiAttributeListAddInteger(&op, PAPI_ATTR_REPLACE, "job-id", job_id); + papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, + "operational-attributes-group", op); + papiAttributeListFree(op); + papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, + "job-attributes-group", attributes); + result = ipp_send_request(svc, request, &response); + papiAttributeListFree(request); + + op = NULL; + papiAttributeListGetCollection(response, NULL, + "job-attributes-group", &op); + copy_attributes(&j->attributes, op); + papiAttributeListFree(response); + + return (result); +} diff --git a/usr/src/lib/print/libpapi-ipp/common/mapfile b/usr/src/lib/print/libpapi-ipp/common/mapfile new file mode 100644 index 0000000000..ca9a53f0a4 --- /dev/null +++ b/usr/src/lib/print/libpapi-ipp/common/mapfile @@ -0,0 +1,150 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# $Id: mapfile.in,v 1.2 2006/03/02 06:31:36 njacobs Exp $ +# + +# ident "%Z%%M% %I% %E% SMI" + +# +# Common interfaces that are most likely to be shared amongst the various +# PAPI implementations. +# + +SUNW_1.0 { + global: + # PAPI Attribute Calls + papiAttributeListAddValue = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddBoolean = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddCollection = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddDatetime = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddInteger = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddMetadata = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddRange = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddResolution = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddString = FUNCTION FILTER libpapi-common.so ; + papiAttributeListDelete = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetValue = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetNext = FUNCTION FILTER libpapi-common.so ; + papiAttributeListFind = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetBoolean = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetCollection = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetDatetime = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetInteger = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetMetadata = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetRange = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetResolution = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetString = FUNCTION FILTER libpapi-common.so ; + papiAttributeListFromString = FUNCTION FILTER libpapi-common.so ; + papiAttributeListToString = FUNCTION FILTER libpapi-common.so ; + papiAttributeListFree = FUNCTION FILTER libpapi-common.so ; + + # PAPI Service Calls + papiServiceCreate ; + papiServiceDestroy ; + papiServiceSetUserName ; + papiServiceSetPassword ; + papiServiceSetEncryption ; + papiServiceSetAuthCB ; + papiServiceSetAppData ; + papiServiceGetUserName ; + papiServiceGetPassword ; + papiServiceGetEncryption ; + papiServiceGetAppData ; + papiServiceGetServiceName ; + papiServiceGetAttributeList ; + papiServiceGetStatusMessage ; + + # PAPI Printer Calls + papiPrintersList ; + papiPrinterQuery ; + papiPrinterAdd ; + papiPrinterModify ; + papiPrinterRemove ; + papiPrinterDisable ; + papiPrinterEnable ; + papiPrinterPause ; + papiPrinterResume ; + papiPrinterPurgeJobs ; + papiPrinterListJobs ; + papiPrinterGetAttributeList ; + papiPrinterFree ; + papiPrinterListFree ; + + # PAPI Job Calls + papiJobSubmit ; + papiJobSubmitByReference ; + papiJobValidate ; + papiJobStreamOpen ; + papiJobStreamWrite ; + papiJobStreamClose ; + papiJobQuery ; + papiJobModify ; + papiJobMove ; + papiJobCancel ; + papiJobHold ; + papiJobRelease ; + papiJobRestart ; + papiJobPromote ; + papiJobGetAttributeList ; + papiJobGetPrinterName ; + papiJobGetId ; + papiJobGetJobTicket ; + papiJobFree ; + papiJobListFree ; + + # Misc. PAPI Calls + papiStatusString = FUNCTION FILTER libpapi-common.so ; + papiLibrarySupportedCall = FUNCTION FILTER libpapi-common.so ; + papiLibrarySupportedCalls = FUNCTION FILTER libpapi-common.so ; +}; + +SUNWprivate_1.0 { + global: + papiServiceSetPeer = FUNCTION FILTER libpapi-common.so ; + papiJobCreate = FUNCTION FILTER libpapi-common.so ; + papiJobStreamAdd = FUNCTION FILTER libpapi-common.so ; + papiJobCommit = FUNCTION FILTER libpapi-common.so ; + + # Misc. supporting calls + # URI + uri_from_string = FUNCTION FILTER libpapi-common.so ; + uri_to_string = FUNCTION FILTER libpapi-common.so ; + uri_free = FUNCTION FILTER libpapi-common.so ; + # list + list_remove = FUNCTION FILTER libpapi-common.so ; + list_append = FUNCTION FILTER libpapi-common.so ; + list_concatenate = FUNCTION FILTER libpapi-common.so ; + + # extra Attribute Calls + copy_attributes = FUNCTION FILTER libpapi-common.so ; + split_and_copy_attributes = FUNCTION FILTER libpapi-common.so ; + papiAttributeListPrint = FUNCTION FILTER libpapi-common.so ; + + local: + * ; +} ; diff --git a/usr/src/lib/print/libpapi-ipp/common/papi_impl.h b/usr/src/lib/print/libpapi-ipp/common/papi_impl.h new file mode 100644 index 0000000000..ec298b291e --- /dev/null +++ b/usr/src/lib/print/libpapi-ipp/common/papi_impl.h @@ -0,0 +1,114 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +#ifndef _PAPI_IMPL_H +#define _PAPI_IMPL_H + +/* $Id: papi_impl.h 161 2006-05-03 04:32:59Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <papi.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#include <time.h> +#include <sys/types.h> +#include <stdarg.h> +#include <uri.h> + +#include <http.h> +#include <ipp.h> + +/* + * Implementation specific types/prototypes/definitions follow + * + * + * Ex: + */ +typedef enum { + TRANSFER_ENCODING_CHUNKED, + TRANSFER_ENCODING_LENGTH +} http_transfer_encoding_t; + +typedef struct { + papi_attribute_t **attributes; + char *name; + char *user; + char *password; + int (*authCB)(papi_service_t svc, void *app_data); + papi_encryption_t encryption; + void *app_data; + uri_t *uri; + char *post; + http_t *connection; + http_transfer_encoding_t transfer_encoding; +} service_t; + +typedef struct job { + papi_attribute_t **attributes; +} job_t; + +typedef struct { + papi_attribute_t **attributes; +} printer_t; + +/* IPP glue interfaces */ +extern ssize_t ipp_request_read(void *fd, void *buffer, size_t length); +extern ssize_t ipp_request_write(void *fd, void *buffer, size_t length); +extern papi_status_t ipp_send_request(service_t *svc, + papi_attribute_t **request, + papi_attribute_t ***response); +extern papi_status_t ipp_send_request_with_file(service_t *svc, + papi_attribute_t **request, + papi_attribute_t ***response, char *file); +extern papi_status_t ipp_send_initial_request_block(service_t *svc, + papi_attribute_t **request, ssize_t file_size); +extern papi_status_t ipp_status_info(service_t *svc, + papi_attribute_t **response); +extern void ipp_initialize_request(service_t *svc, + papi_attribute_t ***request, uint16_t type); +extern void ipp_initialize_operational_attributes(service_t *svc, + papi_attribute_t ***op, + papi_attribute_t **attributes); +extern papi_status_t ipp_to_papi_status(uint16_t status); +extern papi_status_t http_to_papi_status(http_status_t status); + +extern void ipp_add_printer_uri(service_t *svc, char *name, + papi_attribute_t ***op); + +/* service related interfaces */ +extern void detailed_error(service_t *svc, char *fmt, ...); +extern papi_status_t service_connect(service_t *svc, char *service_name); + +#ifdef __cplusplus +} +#endif + +#endif /* _PAPI_IMPL_H */ diff --git a/usr/src/lib/print/libpapi-ipp/common/printer.c b/usr/src/lib/print/libpapi-ipp/common/printer.c new file mode 100644 index 0000000000..051088becc --- /dev/null +++ b/usr/src/lib/print/libpapi-ipp/common/printer.c @@ -0,0 +1,435 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: printer.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/*LINTLIBRARY*/ + +#include <stdlib.h> +#include <papi_impl.h> + +#include <config-site.h> + +void +papiPrinterFree(papi_printer_t printer) +{ + printer_t *tmp = printer; + + if (tmp != NULL) { + if (tmp->attributes != NULL) + papiAttributeListFree(tmp->attributes); + free(tmp); + } +} + +void +papiPrinterListFree(papi_printer_t *printers) +{ + if (printers != NULL) { + int i; + + for (i = 0; printers[i] != NULL; i++) + papiPrinterFree(printers[i]); + free(printers); + } +} + +/* + * Enumeration of printers is not part of the IPP specification, so many + * servers will probably not respond back with a list of printers, but + * CUPS has implemented an extension to IPP to enumerate printers and + * classes. the Apache/mod_ipp IPP listener module available in Solaris + * implements this IPP extension, so CUPS and Solaris can provide this + * to IPP clients. + */ +#ifndef OPID_CUPS_GET_PRINTERS /* for servers that will enumerate */ +#define OPID_CUPS_GET_PRINTERS 0x4002 +#endif /* OPID_CUPS_GET_PRINTERS */ +#ifndef OPID_CUPS_DELETE_PRINTER /* for servers that can delete */ +#define OPID_CUPS_DELETE_PRINTER 0x4004 +#endif /* OPID_CUPS_DELETE_PRINTER */ +#ifndef OPID_CUPS_GET_CLASSES /* for servers that will enumerate */ +#define OPID_CUPS_GET_CLASSES 0x4005 +#endif /* OPID_CUPS_GET_CLASSES */ + +papi_status_t +papiPrintersList(papi_service_t handle, char **requested_attrs, + papi_filter_t *filter, papi_printer_t **printers) +{ + papi_status_t status, result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + papi_attribute_t **request = NULL, **op = NULL, **response = NULL; + void *iter = NULL; + + if ((svc == NULL) || (printers == NULL)) + return (PAPI_BAD_ARGUMENT); + + /* if we are already connected, use that connection. */ + if (svc->connection == NULL) + if ((result = service_connect(svc, DEFAULT_DEST)) != PAPI_OK) + return (result); + ipp_initialize_request(svc, &request, OPID_CUPS_GET_PRINTERS); + + ipp_initialize_operational_attributes(svc, &op, NULL); + + if (requested_attrs != NULL) { + int i; + + for (i = 0; requested_attrs[i] != NULL; i++) + papiAttributeListAddString(&op, PAPI_ATTR_APPEND, + "requested-attributes", requested_attrs[i]); + } + + papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, + "operational-attributes-group", op); + papiAttributeListFree(op); + result = ipp_send_request(svc, request, &response); + papiAttributeListFree(request); + + op = NULL; + for (status = papiAttributeListGetCollection(response, &iter, + "printer-attributes-group", &op); + status == PAPI_OK; + status = papiAttributeListGetCollection(response, &iter, + NULL, &op)) { + printer_t *p = NULL; + + if ((p = calloc(1, sizeof (*p))) == NULL) + return (PAPI_TEMPORARY_ERROR); + + copy_attributes(&p->attributes, op); + op = NULL; + list_append(printers, p); + } + papiAttributeListFree(response); + + return (result); +} + +papi_status_t +papiPrinterQuery(papi_service_t handle, char *name, + char **requested_attrs, + papi_attribute_t **job_attributes, + papi_printer_t *printer) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + printer_t *p = NULL; + papi_attribute_t **request = NULL, **op = NULL, **response = NULL; + + if ((svc == NULL) || (name == NULL) || (printer == NULL)) + return (PAPI_BAD_ARGUMENT); + + /* if we are already connected, use that connection. */ + if (svc->connection == NULL) + if ((result = service_connect(svc, name)) != PAPI_OK) + return (result); + + if ((*printer = p = calloc(1, sizeof (*p))) == NULL) + return (PAPI_TEMPORARY_ERROR); + + ipp_initialize_request(svc, &request, OPID_GET_PRINTER_ATTRIBUTES); + + ipp_initialize_operational_attributes(svc, &op, NULL); + ipp_add_printer_uri(svc, name, &op); + + if (requested_attrs != NULL) { + int i; + + for (i = 0; requested_attrs[i] != NULL; i++) + papiAttributeListAddString(&op, PAPI_ATTR_APPEND, + "requested-attributes", requested_attrs[i]); + } + + papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, + "operational-attributes-group", op); + papiAttributeListFree(op); + result = ipp_send_request(svc, request, &response); + papiAttributeListFree(request); + + op = NULL; + papiAttributeListGetCollection(response, NULL, + "printer-attributes-group", &op); + copy_attributes(&p->attributes, op); + papiAttributeListFree(response); + + return (result); +} + +static papi_status_t +_printer_enable_disable_pause_resume_delete(papi_service_t handle, char *name, + char *message, uint16_t type) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + papi_attribute_t **request = NULL, **op = NULL, **response = NULL; + + if ((svc == NULL) || (name == NULL)) + return (PAPI_BAD_ARGUMENT); + + /* if we are already connected, use that connection. */ + if (svc->connection == NULL) + if ((result = service_connect(svc, name)) != PAPI_OK) + return (result); + + ipp_initialize_request(svc, &request, type); + + ipp_initialize_operational_attributes(svc, &op, NULL); + ipp_add_printer_uri(svc, name, &op); + + switch (type) { + case OPID_DISABLE_PRINTER: + papiAttributeListAddString(&op, PAPI_ATTR_REPLACE, + "printer-message-from-operator", message); + break; + case OPID_PAUSE_PRINTER: + papiAttributeListAddString(&op, PAPI_ATTR_REPLACE, + "printer-state-message", message); + break; + default: /* a message value is of no use */ + break; + } + + papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, + "operational-attributes-group", op); + papiAttributeListFree(op); + result = ipp_send_request(svc, request, &response); + papiAttributeListFree(request); + papiAttributeListFree(response); + + return (result); +} + +papi_status_t +papiPrinterEnable(papi_service_t handle, char *name) +{ + return (_printer_enable_disable_pause_resume_delete(handle, name, + NULL, OPID_ENABLE_PRINTER)); +} + +papi_status_t +papiPrinterResume(papi_service_t handle, char *name) +{ + return (_printer_enable_disable_pause_resume_delete(handle, name, + NULL, OPID_RESUME_PRINTER)); +} + +papi_status_t +papiPrinterPause(papi_service_t handle, char *name, char *message) +{ + return (_printer_enable_disable_pause_resume_delete(handle, name, + message, OPID_PAUSE_PRINTER)); +} + +papi_status_t +papiPrinterDisable(papi_service_t handle, char *name, char *message) +{ + return (_printer_enable_disable_pause_resume_delete(handle, name, + message, OPID_PAUSE_PRINTER)); +} + +/* + * there is no IPP create operation, the set-printer-attibutes operation + * is the closest we have, so we will assume that the server will create + * a printer and set attributes if there is none. + */ +papi_status_t +papiPrinterAdd(papi_service_t handle, char *name, + papi_attribute_t **attributes, papi_printer_t *printer) +{ + return (papiPrinterModify(handle, name, attributes, printer)); +} + +papi_status_t +papiPrinterModify(papi_service_t handle, char *name, + papi_attribute_t **attributes, papi_printer_t *printer) +{ + papi_status_t result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + printer_t *p = NULL; + papi_attribute_t **request = NULL, **op = NULL, **response = NULL; + + if ((svc == NULL) || (name == NULL) || (printer == NULL)) + return (PAPI_BAD_ARGUMENT); + + /* if we are already connected, use that connection. */ + if (svc->connection == NULL) + if ((result = service_connect(svc, name)) != PAPI_OK) + return (result); + + if ((*printer = p = calloc(1, sizeof (*p))) == NULL) + return (PAPI_TEMPORARY_ERROR); + + ipp_initialize_request(svc, &request, OPID_SET_PRINTER_ATTRIBUTES); + + ipp_initialize_operational_attributes(svc, &op, NULL); + ipp_add_printer_uri(svc, name, &op); + + papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, + "operational-attributes-group", op); + papiAttributeListFree(op); + + papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, + "printer-attributes-group", attributes); + result = ipp_send_request(svc, request, &response); + papiAttributeListFree(request); + + op = NULL; + papiAttributeListGetCollection(response, NULL, + "printer-attributes-group", &op); + copy_attributes(&p->attributes, op); + papiAttributeListFree(response); + + return (result); +} + +papi_status_t +papiPrinterRemove(papi_service_t handle, char *name) +{ + return (_printer_enable_disable_pause_resume_delete(handle, name, + NULL, OPID_CUPS_DELETE_PRINTER)); +} + +papi_status_t +papiPrinterPurgeJobs(papi_service_t handle, char *name, + papi_job_t **jobs) +{ + papi_status_t status, result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + papi_attribute_t **request = NULL, **op = NULL, **response = NULL; + void *iter = NULL; + + + if ((svc == NULL) || (name == NULL)) + return (PAPI_BAD_ARGUMENT); + + /* if we are already connected, use that connection. */ + if (svc->connection == NULL) + if ((result = service_connect(svc, name)) != PAPI_OK) + return (result); + + ipp_initialize_request(svc, &request, OPID_PURGE_JOBS); + + ipp_initialize_operational_attributes(svc, &op, NULL); + ipp_add_printer_uri(svc, name, &op); + + papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, + "operational-attributes-group", op); + papiAttributeListFree(op); + result = ipp_send_request(svc, request, &response); + papiAttributeListFree(request); + + op = NULL; + for (status = papiAttributeListGetCollection(response, &iter, + "job-attributes-group", &op); + status == PAPI_OK; + status = papiAttributeListGetCollection(response, &iter, + NULL, &op)) { + job_t *j = NULL; + + if ((j = calloc(1, sizeof (*j))) == NULL) + return (PAPI_TEMPORARY_ERROR); + + copy_attributes(&j->attributes, op); + op = NULL; + list_append(jobs, j); + } + papiAttributeListFree(response); + + return (result); +} + +papi_status_t +papiPrinterListJobs(papi_service_t handle, char *name, + char **requested_attrs, int type_mask, + int max_num_jobs, papi_job_t **jobs) +{ + papi_status_t status, result = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + papi_attribute_t **request = NULL, **op = NULL, **response = NULL; + void *iter = NULL; + + if ((svc == NULL) || (name == NULL)) + return (PAPI_BAD_ARGUMENT); + + /* if we are already connected, use that connection. */ + if (svc->connection == NULL) + if ((result = service_connect(svc, name)) != PAPI_OK) + return (result); + + ipp_initialize_request(svc, &request, OPID_GET_JOBS); + + ipp_initialize_operational_attributes(svc, &op, NULL); + ipp_add_printer_uri(svc, name, &op); + + if (requested_attrs != NULL) { + int i; + + for (i = 0; requested_attrs[i] != NULL; i++) + papiAttributeListAddString(&op, PAPI_ATTR_APPEND, + "requested-attributes", requested_attrs[i]); + } + + papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, + "operational-attributes-group", op); + papiAttributeListFree(op); + result = ipp_send_request(svc, request, &response); + papiAttributeListFree(request); + + op = NULL; + for (status = papiAttributeListGetCollection(response, &iter, + "job-attributes-group", &op); + status == PAPI_OK; + status = papiAttributeListGetCollection(response, &iter, + NULL, &op)) { + job_t *j = NULL; + + if ((j = calloc(1, sizeof (*j))) == NULL) + return (PAPI_TEMPORARY_ERROR); + + copy_attributes(&j->attributes, op); + op = NULL; + list_append(jobs, j); + } + papiAttributeListFree(response); + + return (result); +} + +papi_attribute_t ** +papiPrinterGetAttributeList(papi_printer_t printer) +{ + papi_attribute_t **result = NULL; + printer_t *p = printer; + + if (p != NULL) + result = p->attributes; + + return (result); +} diff --git a/usr/src/lib/print/libpapi-ipp/common/service.c b/usr/src/lib/print/libpapi-ipp/common/service.c new file mode 100644 index 0000000000..e5531f1422 --- /dev/null +++ b/usr/src/lib/print/libpapi-ipp/common/service.c @@ -0,0 +1,394 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: service.c 171 2006-05-20 06:00:32Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/*LINTLIBRARY*/ + +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <alloca.h> +#include <libintl.h> +#include <papi_impl.h> + +#include <config-site.h> + +http_encryption_t +http_encryption_type(papi_encryption_t encryption) +{ + switch (encryption) { + case PAPI_ENCRYPT_IF_REQUESTED: + return (HTTP_ENCRYPT_IF_REQUESTED); + case PAPI_ENCRYPT_REQUIRED: + return (HTTP_ENCRYPT_REQUIRED); + case PAPI_ENCRYPT_ALWAYS: + return (HTTP_ENCRYPT_ALWAYS); + case PAPI_ENCRYPT_NEVER: + return (HTTP_ENCRYPT_NEVER); + default: + ; /* this should log an error */ + } + + return (HTTP_ENCRYPT_NEVER); /* should never get here */ +} + +papi_status_t +service_connect(service_t *svc, char *service_name) +{ + papi_status_t result = PAPI_OK; + int port = 631; + + if (svc == NULL) + return (PAPI_BAD_ARGUMENT); + + if (svc->connection != NULL) /* alread connected ? */ + return (PAPI_OK); + + if (svc->uri == NULL) + uri_from_string(service_name, &svc->uri); + + if ((service_name != NULL) && (svc->uri == NULL)) { + /* + * a name was supplied and it's not in URI form, we will + * try to use a "default" IPP service under the assumption + * that this is most likely a short-form printer name from + * from a papiPrinter*() or papiJob*() call and not from a + * papiServiceCreate() call. + */ + if ((service_name = getenv("PAPI_SERVICE_URI")) == NULL) { + char *cups; + + if ((cups = getenv("CUPS_SERVER")) != NULL) { + char buf[BUFSIZ]; + + snprintf(buf, sizeof (buf), + "ipp://%s/printers/", cups); + service_name = strdup(buf); + } + } + if (service_name == NULL) + service_name = DEFAULT_IPP_SERVICE_URI; + + uri_from_string(service_name, &svc->uri); + } + + if (svc->uri == NULL) + return (PAPI_NOT_POSSIBLE); + + if (svc->uri->port != NULL) + port = strtol(svc->uri->port, NULL, 10); + + svc->connection = httpConnectEncrypt(svc->uri->host, port, + http_encryption_type(svc->encryption)); + if (svc->connection == NULL) { + if (svc->uri != NULL) { + uri_free(svc->uri); + svc->uri = NULL; + } + result = PAPI_SERVICE_UNAVAILABLE; + } else if (service_name != NULL) + svc->name = strdup(service_name); + + return (result); +} + +papi_status_t +papiServiceCreate(papi_service_t *handle, char *service_name, + char *user_name, char *password, + int (*authCB)(papi_service_t svc, void *app_data), + papi_encryption_t encryption, void *app_data) +{ + papi_status_t result = PAPI_NOT_POSSIBLE; + service_t *svc = NULL; + char *encoding = getenv("HTTP_TRANSFER_ENCODING"); + + if (handle == NULL) + return (PAPI_BAD_ARGUMENT); + + if ((*handle = svc = calloc(1, sizeof (*svc))) == NULL) + return (PAPI_TEMPORARY_ERROR); + + if (user_name != NULL) + svc->user = strdup(user_name); + + if (password != NULL) + svc->password = strdup(password); + + svc->encryption = encryption; + + if (authCB != NULL) + svc->authCB = authCB; + + if (app_data != NULL) + svc->app_data = app_data; + + if ((encoding != NULL) && (strcasecmp(encoding, "content-length") == 0)) + svc->transfer_encoding = TRANSFER_ENCODING_LENGTH; + else + svc->transfer_encoding = TRANSFER_ENCODING_CHUNKED; + + if (service_name != NULL) { + result = service_connect(svc, service_name); + } else + result = PAPI_OK; + + return (result); +} + +void +papiServiceDestroy(papi_service_t handle) +{ + if (handle != NULL) { + service_t *svc = handle; + + if (svc->attributes != NULL) + papiAttributeListFree(svc->attributes); + if (svc->name != NULL) + free(svc->name); + if (svc->user != NULL) + free(svc->user); + if (svc->password != NULL) + free(svc->password); + if (svc->uri != NULL) + uri_free(svc->uri); + if (svc->post != NULL) + free(svc->post); + if (svc->connection != NULL) + httpClose(svc->connection); + + free(handle); + } +} + +papi_status_t +papiServiceSetUserName(papi_service_t handle, char *user_name) +{ + papi_status_t result = PAPI_OK; + + if (handle != NULL) { + service_t *svc = handle; + + if (svc->user != NULL) + free(svc->user); + svc->user = NULL; + if (user_name != NULL) + svc->user = strdup(user_name); + } else + result = PAPI_BAD_ARGUMENT; + + return (result); +} + +papi_status_t +papiServiceSetPassword(papi_service_t handle, char *password) +{ + papi_status_t result = PAPI_OK; + + if (handle != NULL) { + service_t *svc = handle; + + if (svc->password != NULL) + free(svc->password); + svc->password = NULL; + if (password != NULL) + svc->password = strdup(password); + } else + result = PAPI_BAD_ARGUMENT; + + return (result); +} + +papi_status_t +papiServiceSetEncryption(papi_service_t handle, + papi_encryption_t encryption) +{ + papi_status_t result = PAPI_OK; + + if (handle != NULL) { + service_t *svc = handle; + + svc->encryption = encryption; + httpEncryption(svc->connection, + (http_encryption_t)svc->encryption); + } else + result = PAPI_BAD_ARGUMENT; + + return (result); +} + +papi_status_t +papiServiceSetAuthCB(papi_service_t handle, + int (*authCB)(papi_service_t svc, void *app_data)) +{ + papi_status_t result = PAPI_OK; + + if (handle != NULL) { + service_t *svc = handle; + + svc->authCB = authCB; + } else + result = PAPI_BAD_ARGUMENT; + + return (result); +} + + +papi_status_t +papiServiceSetAppData(papi_service_t handle, void *app_data) +{ + papi_status_t result = PAPI_OK; + + if (handle != NULL) { + service_t *svc = handle; + + svc->app_data = (void *)app_data; + } else + result = PAPI_BAD_ARGUMENT; + + return (result); +} + +char * +papiServiceGetServiceName(papi_service_t handle) +{ + char *result = NULL; + + if (handle != NULL) { + service_t *svc = handle; + + result = svc->name; + } + + return (result); +} + +char * +papiServiceGetUserName(papi_service_t handle) +{ + char *result = NULL; + + if (handle != NULL) { + service_t *svc = handle; + + result = svc->user; + } + + return (result); +} + +char * +papiServiceGetPassword(papi_service_t handle) +{ + char *result = NULL; + + if (handle != NULL) { + service_t *svc = handle; + + result = svc->password; + } + + return (result); +} + +papi_encryption_t +papiServiceGetEncryption(papi_service_t handle) +{ + papi_encryption_t result = PAPI_ENCRYPT_NEVER; + + if (handle != NULL) { + service_t *svc = handle; + + result = svc->encryption; + } + + return (result); +} + +void * +papiServiceGetAppData(papi_service_t handle) +{ + void *result = NULL; + + if (handle != NULL) { + service_t *svc = handle; + + result = svc->app_data; + } + + return (result); +} + +papi_attribute_t ** +papiServiceGetAttributeList(papi_service_t handle) +{ + papi_attribute_t **result = NULL; + service_t *svc = handle; + + if (handle != NULL) + result = svc->attributes; + + return (result); +} + +char * +papiServiceGetStatusMessage(papi_service_t handle) +{ + char *result = NULL; + service_t *svc = handle; + + papiAttributeListGetString(svc->attributes, NULL, + "detailed-status-message", &result); + + return (result); +} + +void +detailed_error(service_t *svc, char *fmt, ...) +{ + if ((svc != NULL) && (fmt != NULL)) { + va_list ap; + size_t size; + char *message = alloca(BUFSIZ); + + va_start(ap, fmt); + /* + * fill in the message. If the buffer is too small, allocate + * one that is large enough and fill it in. + */ + if ((size = vsnprintf(message, BUFSIZ, fmt, ap)) >= BUFSIZ) + if ((message = alloca(size)) != NULL) + vsnprintf(message, size, fmt, ap); + va_end(ap); + + papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND, + "detailed-status-message", message); + } +} diff --git a/usr/src/lib/print/libpapi-ipp/i386/Makefile b/usr/src/lib/print/libpapi-ipp/i386/Makefile new file mode 100644 index 0000000000..39b4a998ec --- /dev/null +++ b/usr/src/lib/print/libpapi-ipp/i386/Makefile @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBDIR) $(ROOTLIBS) $(ROOTLINKS) $(EXTRALINKS) diff --git a/usr/src/lib/print/libpapi-ipp/sparc/Makefile b/usr/src/lib/print/libpapi-ipp/sparc/Makefile new file mode 100644 index 0000000000..39b4a998ec --- /dev/null +++ b/usr/src/lib/print/libpapi-ipp/sparc/Makefile @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBDIR) $(ROOTLIBS) $(ROOTLINKS) $(EXTRALINKS) diff --git a/usr/src/lib/print/libpapi-lpd/Makefile b/usr/src/lib/print/libpapi-lpd/Makefile new file mode 100644 index 0000000000..b92d620b10 --- /dev/null +++ b/usr/src/lib/print/libpapi-lpd/Makefile @@ -0,0 +1,56 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../../Makefile.lib + +#HDRS = papi.h +#HDRDIR = common +SUBDIRS = $(MACH) +#$(BUILD64)SUBDIRS += $(MACH64) + +all := TARGET = all +clean := TARGET = clean +clobber := TARGET = clobber +install := TARGET = install +lint := TARGET = lint + +.KEEP_STATE: + +all clean clobber install: .WAIT $(SUBDIRS) + +lint: # $(SUBDIRS) + +install_h: # $(ROOTHDRS) + +check: # $(CHECKHDRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include ../../Makefile.targ diff --git a/usr/src/lib/print/libpapi-lpd/Makefile.com b/usr/src/lib/print/libpapi-lpd/Makefile.com new file mode 100644 index 0000000000..eac0eddaac --- /dev/null +++ b/usr/src/lib/print/libpapi-lpd/Makefile.com @@ -0,0 +1,99 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +LIBRARY = psm-lpd.a +VERS = .1 +COMMON_OBJS = lpd-misc.o +OBJECTS = job.o library.o lpd-cancel.o lpd-job.o lpd-query.o printer.o \ + service.o $(COMMON_OBJS) + +include ../../../Makefile.lib +include ../../../Makefile.rootfs + +ROOTLIBDIR= $(ROOT)/usr/lib/print +ROOTLIBDIR64= $(ROOT)/usr/lib/print/$(MACH) + +EXTRALINKS= $(ROOTLIBDIR)/psm-rfc-1179.so +$(EXTRALINKS): $(ROOTLINKS) + $(RM) $@; $(SYMLINK) $(LIBLINKS) $@ + +LIBS = $(DYNLIB) + +SRCS = $(OBJECTS:%.o = $(SRCDIR)/%.c) + +$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC) + +SRCDIR = ../common +MAPFILE = $(SRCDIR)/mapfile + +CFLAGS += $(CCVERBOSE) +CPPFLAGS += -I$(SRCDIR) +CPPFLAGS += -I../../libpapi-common/common +DYNFLAGS += $(BDIRECT) -M $(MAPFILE) +LDLIBS += -lc + +.KEEP_STATE: + +all: $(LIBS) $(PROG) + +lint: lintcheck + +include ../../../Makefile.targ + +# +# NEEDED to build lpd-port +# +PROG = lpd-port +LPD_PORT_OBJS = lpd-port.o $(COMMON_OBJS) + +$(PROG) := LDLIBS += -lsocket -lnsl -lsendfile -lpapi + +PROG_OBJS = $(LPD_PORT_OBJS:%=pics/%) +OBJS += $(PROG_OBJS) + +NX_MAP_i386= $(SRC)/cmd/mapfile_noexdata +NX_MAP_sparc= +NX_MAP= $(NX_MAP_$(MACH)) +NES_MAPFILE= $(SRC)/cmd/mapfile_noexstk $(NX_MAP) + +LDFLAGS.cmd = \ + $(ENVLDFLAGS1) $(ENVLDFLAGS2) $(ENVLDFLAGS3) \ + $(NES_MAPFILE:%=-M%) $(PGA_MAPFILE:%=-M%) + +$(PROG): $(PROG_OBJS) + $(LINK.c) -o $@ $(PROG_OBJS) $(LDFLAGS.cmd) $(LDLIBS) + $(POST_PROCESS) + +# needed for the 'install' phase +ROOTLIBPRINTPROG = $(PROG:%=$(ROOTLIBDIR)/%) +$(ROOTLIBPRINTPROG) := FILEMODE = 04511 +$(ROOTLIBPRINTPROG) := OWNER = root + +$(ROOTLIBDIR)/%: $(ROOTLIBDIR) % + $(INS.file) +$(ROOTLIBDIR): + $(INS.dir) diff --git a/usr/src/lib/print/libpapi-lpd/common/job.c b/usr/src/lib/print/libpapi-lpd/common/job.c new file mode 100644 index 0000000000..900abb7c35 --- /dev/null +++ b/usr/src/lib/print/libpapi-lpd/common/job.c @@ -0,0 +1,298 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: job.c 155 2006-04-26 02:34:54Z ktou $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <limits.h> +#include <libintl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <papi_impl.h> +#include <uri.h> + +/* + * must copy files before leaving routine + */ +papi_status_t +papiJobSubmit(papi_service_t handle, char *name, papi_attribute_t **attributes, + papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) +{ + papi_status_t status = PAPI_OK; + service_t *svc = handle; + job_t *j = NULL; + char *metadata = NULL; + + if ((svc == NULL) || (name == NULL) || (files == NULL) || + (job == NULL)) + return (PAPI_BAD_ARGUMENT); + + if (job_ticket != NULL) { + detailed_error(svc, + gettext("papiJobSubmit: job ticket not supported")); + return (PAPI_OPERATION_NOT_SUPPORTED); + } + + if ((status = service_fill_in(svc, name)) != PAPI_OK) + return (status); + + if ((*job = j = (job_t *)calloc(1, sizeof (*j))) == NULL) { + detailed_error(svc, + gettext("calloc() failed")); + return (PAPI_TEMPORARY_ERROR); + } + + /* create a control file */ + status = lpd_job_add_attributes(svc, attributes, &metadata, + &j->attributes); + status = lpd_job_add_files(svc, attributes, files, &metadata, + &j->attributes); + + /* send the job to the server */ + status = lpd_submit_job(svc, metadata, &j->attributes, NULL); + free(metadata); + + return (status); + +} + + +papi_status_t +papiJobSubmitByReference(papi_service_t handle, char *name, + papi_attribute_t **job_attributes, + papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) +{ + return (papiJobSubmit(handle, name, job_attributes, + job_ticket, files, job)); +} + +papi_status_t +papiJobStreamOpen(papi_service_t handle, char *name, + papi_attribute_t **attributes, + papi_job_ticket_t *job_ticket, papi_stream_t *stream) +{ + papi_status_t status = PAPI_OK; + service_t *svc = handle; + char *metadata = NULL; + stream_t *s = NULL; + + if ((svc == NULL) || (name == NULL) || (stream == NULL)) + return (PAPI_BAD_ARGUMENT); + + if (job_ticket != NULL) + return (PAPI_OPERATION_NOT_SUPPORTED); + + if ((status = service_fill_in(svc, name)) != PAPI_OK) + return (status); + + /* create the stream container */ + if ((*stream = s = calloc(1, sizeof (*s))) == NULL) + return (PAPI_TEMPORARY_ERROR); + + /* create the job */ + if ((s->job = calloc(1, sizeof (*(s->job)))) == NULL) + return (PAPI_TEMPORARY_ERROR); + + /* process the attribute list */ + lpd_job_add_attributes(svc, attributes, &metadata, &s->job->attributes); + + /* if we can stream, do it */ + if ((svc->uri->fragment != NULL) && + (strcasecmp(svc->uri->fragment, "streaming") == 0)) { + char *files[] = { "standard input", NULL }; + + lpd_job_add_files(svc, attributes, files, &metadata, + &(s->job->attributes)); + status = lpd_submit_job(svc, metadata, &(s->job->attributes), + &s->fd); + } else { + char dfname[18]; + + strcpy(dfname, "/tmp/stdin-XXXXX"); + + if ((s->fd = mkstemp(dfname)) >= 0) + s->dfname = strdup(dfname); + s->job->attributes = attributes; + } + s->metadata = metadata; + + return (status); +} + + +papi_status_t +papiJobStreamWrite(papi_service_t handle, papi_stream_t stream, + void *buffer, size_t buflen) +{ + service_t *svc = handle; + stream_t *s = stream; + + if ((svc == NULL) || (stream == NULL) || (buffer == NULL) || + (buflen == 0)) + return (PAPI_BAD_ARGUMENT); + + if (write(s->fd, buffer, buflen) != buflen) + return (PAPI_DEVICE_ERROR); + + return (PAPI_OK); +} + +papi_status_t +papiJobStreamClose(papi_service_t handle, papi_stream_t stream, papi_job_t *job) +{ + papi_status_t status = PAPI_INTERNAL_ERROR; + service_t *svc = handle; + job_t *j = NULL; + stream_t *s = stream; + int ret; + + if ((svc == NULL) || (stream == NULL) || (job == NULL)) + return (PAPI_BAD_ARGUMENT); + + close(s->fd); /* close the stream */ + + if (s->dfname != NULL) { /* if it is a tmpfile, print it */ + char *files[2]; + + files[0] = s->dfname; + files[1] = NULL; + + lpd_job_add_files(svc, s->job->attributes, files, &s->metadata, + &(s->job->attributes)); + status = lpd_submit_job(svc, s->metadata, + &(s->job->attributes), NULL); + unlink(s->dfname); + free(s->dfname); + } else + status = PAPI_OK; + + if (s->metadata != NULL) + free(s->metadata); + + *job = s->job; + + return (status); +} + +papi_status_t +papiJobQuery(papi_service_t handle, char *name, int32_t job_id, + char **job_attributes, papi_job_t *job) +{ + papi_status_t status = PAPI_OK; + service_t *svc = handle; + + if ((svc == NULL) || (name == NULL) || job_id < 0) + return (PAPI_BAD_ARGUMENT); + + if ((status = service_fill_in(svc, name)) == PAPI_OK) + status = lpd_find_job_info(svc, job_id, (job_t **)job); + + return (status); +} + +papi_status_t +papiJobCancel(papi_service_t handle, char *name, int32_t job_id) +{ + papi_status_t status; + service_t *svc = handle; + + if ((svc == NULL) || (name == NULL) || (job_id < 0)) + return (PAPI_BAD_ARGUMENT); + + if ((status = service_fill_in(svc, name)) == PAPI_OK) + status = lpd_cancel_job(svc, job_id); + + return (status); +} + +papi_attribute_t ** +papiJobGetAttributeList(papi_job_t job) +{ + job_t *j = (job_t *)job; + + if (j != NULL) + return ((papi_attribute_t **)j->attributes); + + return (NULL); +} + +char * +papiJobGetPrinterName(papi_job_t job) +{ + char *result = NULL; + job_t *j = (job_t *)job; + + if (j != NULL) + papiAttributeListGetString(j->attributes, NULL, + "printer-name", &result); + + return (result); +} + +int +papiJobGetId(papi_job_t job) +{ + int result = -1; + job_t *j = (job_t *)job; + + if (j != NULL) + papiAttributeListGetInteger(j->attributes, NULL, + "job-id", &result); + + return (result); +} + +void +papiJobFree(papi_job_t job) +{ + job_t *j = (job_t *)job; + + + if (j != NULL) { + papiAttributeListFree(j->attributes); + free(j); + } +} + +void +papiJobListFree(papi_job_t *jobs) +{ + if (jobs != NULL) { + int i; + + for (i = 0; jobs[i] != NULL; i++) + papiJobFree(jobs[i]); + free(jobs); + } +} diff --git a/usr/src/lib/print/libpapi-lpd/common/library.c b/usr/src/lib/print/libpapi-lpd/common/library.c new file mode 100644 index 0000000000..de38c2bbfa --- /dev/null +++ b/usr/src/lib/print/libpapi-lpd/common/library.c @@ -0,0 +1,90 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: library.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <alloca.h> +#include <libintl.h> +#include <papi_impl.h> + +static char *calls[] = { + /* Attribute Calls */ + "papiAttributeListAdd", + "papiAttributeListAddBoolean", "papiAttributeListAddCollection", + "papiAttributeListAddDatetime", "papiAttributeListAddInteger", + "papiAttributeListAddMetadata", "papiAttributeListAddRange", + "papiAttributeListAddResolution", "papiAttributeListAddString", + "papiAttributeListDelete", + "papiAttributeListGetValue", "papiAttributeListGetNext", + "papiAttributeListFind", + "papiAttributeListGetBoolean", "papiAttributeListGetCollection", + "papiAttributeListGetDatetime", "papiAttributeListGetInteger", + "papiAttributeListGetMetadata", "papiAttributeListGetRange", + "papiAttributeListGetResolution", "papiAttributeListGetString", + "papiAttributeListFromString", "papiAttributeListToString", + "papiAttributeListFree", + /* Job Calls */ + "papiJobSubmit", "papiJobSubmitByReference", + "papiJobStreamOpen", "papiJobStreamWrite", "papiJobStreamClose", + "papiJobQuery", "papiJobCancel", + "papiJobGetAttributeList", "papiJobGetId", "papiJobGetPrinterName", + "papiJobFree", "papiJobListFree", + /* Printer Calls */ + "papiPrinterQuery", "papiPrinterPurgeJobs", "papiPrinterListJobs", + "papiPrinterGetAttributeList", "papiPrinterFree", + /* Service Calls */ + "papiServiceCreate", "papiServiceDestroy", + "papiServiceGetStatusMessage", + /* Misc Calls */ + "papiStatusString", + "papiLibrarySupportedCall", "papiLibrarySupportedCalls", + NULL +}; + +char ** +papiLibrarySupportedCalls() +{ + return (calls); +} + +char +papiLibrarySupportedCall(char *name) +{ + int i; + + for (i = 0; calls[i] != NULL; i++) + if (strcmp(name, calls[i]) == 0) + return (PAPI_TRUE); + + return (PAPI_FALSE); +} diff --git a/usr/src/lib/print/libpapi-lpd/common/lpd-cancel.c b/usr/src/lib/print/libpapi-lpd/common/lpd-cancel.c new file mode 100644 index 0000000000..3f8cd7320a --- /dev/null +++ b/usr/src/lib/print/libpapi-lpd/common/lpd-cancel.c @@ -0,0 +1,122 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: lpd-cancel.c 155 2006-04-26 02:34:54Z ktou $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#define __EXTENSIONS__ /* for strtok_r() */ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <papi_impl.h> + +papi_status_t +lpd_cancel_job(service_t *svc, int id) +{ + papi_status_t status = PAPI_INTERNAL_ERROR; + int fd; + char **list; + char buf[128]; /* this should be overkill */ + + if (svc == NULL) + return (PAPI_BAD_ARGUMENT); + + snprintf(buf, sizeof (buf), "%d", id); + list[0] = buf; + list[1] = NULL; + + if ((fd = lpd_open(svc, 'c', list, 3)) < 0) + return (PAPI_INTERNAL_ERROR); + + memset(buf, 0, sizeof (buf)); + if (fdgets(buf, sizeof (buf), fd) != NULL) { + if (buf[0] == '\0') + status = PAPI_NOT_FOUND; + else if (strstr(buf, "permission denied") != NULL) + status = PAPI_NOT_AUTHORIZED; + else if ((strstr(buf, "cancelled") != NULL) || + (strstr(buf, "removed") != NULL)) + status = PAPI_OK; + } else + status = PAPI_NOT_FOUND; + + close(fd); + + return (status); +} + +papi_status_t +lpd_purge_jobs(service_t *svc, job_t ***jobs) +{ + papi_status_t status = PAPI_INTERNAL_ERROR; + int fd; + char *queue; + char buf[256]; + + if (svc == NULL) + return (PAPI_BAD_ARGUMENT); + + if ((fd = lpd_open(svc, 'c', NULL, 3)) < 0) + return (PAPI_INTERNAL_ERROR); + + queue = queue_name_from_uri(svc->uri); + + status = PAPI_OK; + memset(buf, 0, sizeof (buf)); + while (fdgets(buf, sizeof (buf), fd) != NULL) { + /* if we canceled it, add it to the list */ + if ((strstr(buf, "cancelled") != NULL) || + (strstr(buf, "removed") != NULL)) { + job_t *job; + papi_attribute_t **attributes = NULL; + char *ptr, *iter = NULL; + int id; + + ptr = strtok_r(buf, ":", &iter); + papiAttributeListAddString(&attributes, PAPI_ATTR_EXCL, + "job-name", ptr); + id = atoi(ptr); + papiAttributeListAddInteger(&attributes, PAPI_ATTR_EXCL, + "job-id", id); + papiAttributeListAddString(&attributes, PAPI_ATTR_EXCL, + "job-printer", queue); + + if ((job = (job_t *)calloc(1, (sizeof (*job)))) + != NULL) { + job->attributes = attributes; + list_append(jobs, job); + } else + papiAttributeListFree(attributes); + } else if (strstr(buf, "permission denied") != NULL) + status = PAPI_NOT_AUTHORIZED; + } + close(fd); + + return (status); +} diff --git a/usr/src/lib/print/libpapi-lpd/common/lpd-job.c b/usr/src/lib/print/libpapi-lpd/common/lpd-job.c new file mode 100644 index 0000000000..3d36fef99d --- /dev/null +++ b/usr/src/lib/print/libpapi-lpd/common/lpd-job.c @@ -0,0 +1,551 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: lpd-job.c 157 2006-04-26 15:07:55Z ktou $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#define __EXTENSIONS__ /* for strtok_r() */ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <limits.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> +#include <pwd.h> +#include <libintl.h> +#include <papi_impl.h> + +enum { LPD_RFC, LPD_SVR4 }; + +static char +mime_type_to_rfc1179_type(char *mime) +{ + static struct { char *mime; char rfc; } cvt[] = { + { "plain/text", 'f' }, + { "application/octet-stream", 'l' }, + { "application/postscript", 'f' }, /* rfc incorrectly has 'o' */ + { "application/x-pr", 'p' }, + { "application/x-cif", 'c' }, + { "application/x-dvi", 'd' }, + { "application/x-fortran", 'r' }, + { "application/x-plot", 'g' }, + { "application/x-ditroff", 'n' }, + { "application/x-troff", 't' }, + { "application/x-raster", 'v' }, + { NULL, 0} + }; + char result = '\0'; + + if (mime != NULL) { + int i; + + for (i = 0; cvt[i].mime != NULL; i++) + if (strcasecmp(cvt[i].mime, mime) == 0) { + result = cvt[i].rfc; + break; + } + } + + return (result); +} + +static papi_status_t +add_lpd_control_line(char **metadata, char code, char *value) +{ + size_t size = 0; + char line[BUFSIZ]; + + if ((metadata == NULL) || (value == NULL)) + return (PAPI_BAD_REQUEST); + + if (*metadata != NULL) + size = strlen(*metadata); + size += strlen(value) + 3; + + if (*metadata == NULL) { + *metadata = (char *)calloc(1, size); + } else { + void *tmp; + tmp = realloc(*metadata, size); + if (tmp) + *metadata = (char *)tmp; + else + return (PAPI_TEMPORARY_ERROR); + } + + snprintf(line, sizeof (line), "%c%s\n", code, value); + strlcat(*metadata, line, size); + + return (PAPI_OK); +} + +static papi_status_t +add_svr4_control_line(char **metadata, char code, char *value) +{ + + char line[BUFSIZ]; + + if ((metadata == NULL) || (value == NULL)) + return (PAPI_BAD_REQUEST); + + snprintf(line, sizeof (line), "%c%s", code, value); + + return (add_lpd_control_line(metadata, '5', line)); +} + +static papi_status_t +add_hpux_control_line(char **metadata, char *value) +{ + + char line[BUFSIZ]; + + if ((metadata == NULL) || (value == NULL)) + return (PAPI_BAD_REQUEST); + + snprintf(line, sizeof (line), " O%s", value); + + return (add_lpd_control_line(metadata, 'N', line)); +} + +static papi_status_t +add_int_control_line(char **metadata, char code, int value, int flag) +{ + char buf[16]; + + snprintf(buf, sizeof (buf), "%d", value); + + if (flag == LPD_SVR4) + return (add_svr4_control_line(metadata, code, buf)); + else + return (add_lpd_control_line(metadata, code, buf)); +} + +static papi_status_t +lpd_add_rfc1179_attributes(service_t *svc, papi_attribute_t **attributes, + char **metadata, papi_attribute_t ***used) +{ + papi_status_t status = PAPI_OK; + char *s; + int integer; + char bool; + char host[BUFSIZ]; + char *user = "nobody"; + uid_t uid = getuid(); + struct passwd *pw; + + if (svc == NULL) + return (PAPI_BAD_REQUEST); + + /* There is nothing to do */ + if (attributes == NULL) + return (PAPI_OK); + + gethostname(host, sizeof (host)); + add_lpd_control_line(metadata, 'H', host); + papiAttributeListAddString(used, PAPI_ATTR_EXCL, + "job-originating-host-name", host); + + if ((pw = getpwuid(uid)) != NULL) + user = pw->pw_name; + if (uid == 0) + papiAttributeListGetString(svc->attributes, NULL, "username", + &user); + add_lpd_control_line(metadata, 'P', user); + papiAttributeListAddString(used, PAPI_ATTR_EXCL, + "job-originating-user-name", user); + + /* Class for Banner Page */ + s = NULL; + papiAttributeListGetString(attributes, NULL, "rfc-1179-class", &s); + if (s != NULL) { + add_lpd_control_line(metadata, 'C', s); + papiAttributeListAddString(used, PAPI_ATTR_EXCL, + "rfc-1179-class", s); + } + + /* Print Banner Page */ + s = NULL; + papiAttributeListGetString(attributes, NULL, "job-sheets", &s); + if ((s != NULL) && (strcmp(s, "standard") == 0)) { + add_lpd_control_line(metadata, 'L', user); + papiAttributeListAddString(used, PAPI_ATTR_EXCL, + "job-sheets", s); + } + + /* Jobname */ + s = NULL; + papiAttributeListGetString(attributes, NULL, "job-name", &s); + if (s != NULL) { + add_lpd_control_line(metadata, 'J', s); + papiAttributeListAddString(used, PAPI_ATTR_EXCL, + "job-name", s); + } + + /* User to mail when job is done - lpr -m */ + bool = PAPI_FALSE; + papiAttributeListGetBoolean(attributes, NULL, "rfc-1179-mail", &bool); + if (bool == PAPI_TRUE) { + add_lpd_control_line(metadata, 'M', user); + papiAttributeListAddBoolean(used, PAPI_ATTR_EXCL, + "rfc-1179-mail", bool); + } + + /* Title for pr */ + s = NULL; + papiAttributeListGetString(attributes, NULL, "pr-title", &s); + if (s != NULL) { + add_lpd_control_line(metadata, 'T', s); + papiAttributeListAddString(used, PAPI_ATTR_EXCL, + "pr-title", s); + } + + /* Indent - used with pr filter */ + integer = 0; + papiAttributeListGetInteger(attributes, NULL, "pr-indent", &integer); + if (integer >= 1) { + add_int_control_line(metadata, 'I', integer, LPD_RFC); + papiAttributeListAddInteger(used, PAPI_ATTR_EXCL, + "pr-indent", integer); + } + + /* Width - used with pr filter */ + integer = 0; + papiAttributeListGetInteger(attributes, NULL, "pr-width", &integer); + if (integer >= 1) { + add_int_control_line(metadata, 'W', integer, LPD_RFC); + papiAttributeListAddInteger(used, PAPI_ATTR_EXCL, + "pr-width", integer); + } + + /* file with Times Roman font lpr -1 */ + s = NULL; + papiAttributeListGetString(attributes, NULL, "rfc-1179-font-r", &s); + if (s != NULL) { + add_lpd_control_line(metadata, '1', s); + papiAttributeListAddString(used, PAPI_ATTR_EXCL, + "rfc-1179-font-r", s); + } + + /* file with Times Roman font lpr -2 */ + s = NULL; + papiAttributeListGetString(attributes, NULL, "rfc-1179-font-i", &s); + if (s != NULL) { + add_lpd_control_line(metadata, '2', s); + papiAttributeListAddString(used, PAPI_ATTR_EXCL, + "rfc-1179-font-i", s); + } + + /* file with Times Roman font lpr -3 */ + s = NULL; + papiAttributeListGetString(attributes, NULL, "rfc-1179-font-b", &s); + if (s != NULL) { + add_lpd_control_line(metadata, '3', s); + papiAttributeListAddString(used, PAPI_ATTR_EXCL, + "rfc-1179-font-b", s); + } + + /* file with Times Roman font lpr -4 */ + s = NULL; + papiAttributeListGetString(attributes, NULL, "rfc-1179-font-s", &s); + if (s != NULL) { + add_lpd_control_line(metadata, '4', s); + papiAttributeListAddString(used, PAPI_ATTR_EXCL, + "rfc-1179-font-s", s); + } + + return (status); +} + +/* + * lpd_add_svr4_attributes + * Solaris 2.x LP - BSD protocol extensions + */ +static papi_status_t +lpd_add_svr4_attributes(service_t *svc, papi_attribute_t **attributes, + char **metadata, papi_attribute_t ***used) +{ + char *s; + int integer; + + if (svc == NULL) + return (PAPI_BAD_REQUEST); + + /* media */ + s = NULL; + papiAttributeListGetString(attributes, NULL, "media", &s); + if (s != NULL) { + add_svr4_control_line(metadata, 'f', s); + papiAttributeListAddString(used, PAPI_ATTR_EXCL, + "media", s); + } + + /* Handling */ + s = NULL; + papiAttributeListGetString(attributes, NULL, "job_hold_until", &s); + if ((s != NULL) && (strcmp(s, "indefinite"))) { + add_svr4_control_line(metadata, 'H', "hold"); + papiAttributeListAddString(used, PAPI_ATTR_EXCL, + "media", "hold"); + } else if ((s != NULL) && (strcmp(s, "no-hold"))) { + add_svr4_control_line(metadata, 'H', "release"); + papiAttributeListAddString(used, PAPI_ATTR_EXCL, + "media", "release"); + } else if ((s != NULL) && (strcmp(s, "immediate"))) { + add_int_control_line(metadata, 'q', 0, LPD_SVR4); + papiAttributeListAddString(used, PAPI_ATTR_EXCL, + "media", "immediate"); + } + + /* Pages */ + s = NULL; + papiAttributeListGetString(attributes, NULL, "page-ranges", &s); + if (s != NULL) { + add_svr4_control_line(metadata, 'P', s); + papiAttributeListAddString(used, PAPI_ATTR_EXCL, + "page-ranges", s); + } + + /* Priority : lp -q */ + integer = -1; + papiAttributeListGetInteger(attributes, NULL, "priority", &integer); + if (integer != -1) { + add_int_control_line(metadata, 'q', integer, LPD_SVR4); + papiAttributeListAddInteger(used, PAPI_ATTR_EXCL, + "priority", integer); + } + + /* Charset : lp -S */ + s = NULL; + papiAttributeListGetString(attributes, NULL, "lp-charset", &s); + if (s != NULL) { + add_svr4_control_line(metadata, 'S', s); + papiAttributeListAddString(used, PAPI_ATTR_EXCL, + "lp-charset", s); + } + + /* Type : done when adding file */ + + /* Mode : lp -y */ + s = NULL; + papiAttributeListGetString(attributes, NULL, "lp-modes", &s); + if (s != NULL) { + add_svr4_control_line(metadata, 'y', s); + papiAttributeListAddString(used, PAPI_ATTR_EXCL, + "lp-modes", s); + } + + /* Options lp -o */ + s = NULL; + papiAttributeListGetString(attributes, NULL, "lp-options", &s); + if (s != NULL) { + add_svr4_control_line(metadata, 'o', s); + papiAttributeListAddString(used, PAPI_ATTR_EXCL, + "lp-options", s); + } + + return (PAPI_OK); +} + +papi_status_t +lpd_add_hpux_attributes(service_t *svc, papi_attribute_t **attributes, + char **metadata, papi_attribute_t ***used) +{ + char *s = NULL; + + /* Options lp -o */ + s = NULL; + papiAttributeListGetString(attributes, NULL, "lp-options", &s); + if (s != NULL) { + add_hpux_control_line(metadata, s); + papiAttributeListAddString(used, PAPI_ATTR_EXCL, + "lp-options", s); + } + + return (PAPI_OK); +} + +papi_status_t +lpd_job_add_attributes(service_t *svc, papi_attribute_t **attributes, + char **metadata, papi_attribute_t ***used) +{ + if ((svc == NULL) || (metadata == NULL)) + return (PAPI_BAD_REQUEST); + + lpd_add_rfc1179_attributes(svc, attributes, metadata, used); + + if (svc->uri->fragment != NULL) { + if ((strcasecmp(svc->uri->fragment, "solaris") == 0) || + (strcasecmp(svc->uri->fragment, "svr4") == 0)) + lpd_add_svr4_attributes(svc, attributes, metadata, + used); + else if (strcasecmp(svc->uri->fragment, "hpux") == 0) + lpd_add_hpux_attributes(svc, attributes, metadata, + used); + /* + * others could be added here: + * lprng, sco, aix, digital unix, xerox, ... + */ + } + + return (PAPI_OK); +} + +papi_status_t +lpd_job_add_files(service_t *svc, papi_attribute_t **attributes, + char **files, char **metadata, papi_attribute_t ***used) +{ + char *format = "plain/text"; + char rfc_fmt = 'l'; + int copies = 1; + char host[BUFSIZ]; + int i; + + if ((svc == NULL) || (attributes == NULL) || (files == NULL) || + (metadata == NULL)) + return (PAPI_BAD_ARGUMENT); + + papiAttributeListGetString(attributes, NULL, "document-format", + &format); + papiAttributeListAddString(used, PAPI_ATTR_EXCL, + "document-format", format); + if ((rfc_fmt = mime_type_to_rfc1179_type(format)) == '\0') { + if ((svc->uri->fragment != NULL) && + ((strcasecmp(svc->uri->fragment, "solaris") == 0) || + (strcasecmp(svc->uri->fragment, "svr4") == 0))) + add_svr4_control_line(metadata, 'T', format); + rfc_fmt = 'l'; + } + + papiAttributeListGetInteger(attributes, NULL, "copies", &copies); + if (copies < 1) + copies = 1; + papiAttributeListAddInteger(used, PAPI_ATTR_EXCL, "copies", copies); + + gethostname(host, sizeof (host)); + + for (i = 0; files[i] != NULL; i++) { + char name[BUFSIZ]; + char key; + int j; + + if ((strcmp("standard input", files[i]) != 0) && + (access(files[i], R_OK) < 0)) { + detailed_error(svc, gettext("aborting request, %s: %s"), + files[i], strerror(errno)); + return (PAPI_NOT_AUTHORIZED); + } + + if (i < 26) + key = 'A' + i; + else if (i < 52) + key = 'a' + (i - 26); + else if (i < 62) + key = '0' + (i - 52); + else { + detailed_error(svc, + gettext("too many files, truncated at 62")); + return (PAPI_OK_SUBST); + } + + snprintf(name, sizeof (name), "df%cXXX%s", key, host); + + for (j = 0; j < copies; j++) + add_lpd_control_line(metadata, rfc_fmt, name); + add_lpd_control_line(metadata, 'U', name); + add_lpd_control_line(metadata, 'N', (char *)files[i]); + } + + return (PAPI_OK); +} + +papi_status_t +lpd_submit_job(service_t *svc, char *metadata, papi_attribute_t ***attributes, + int *ofd) +{ + papi_status_t status = PAPI_INTERNAL_ERROR; + int fd; + char path[32]; + char *list[2]; + + if ((svc == NULL) || (metadata == NULL)) + return (PAPI_BAD_ARGUMENT); + + strcpy(path, "/tmp/lpd-job-XXXXXX"); + fd = mkstemp(path); + write(fd, metadata, strlen(metadata)); + close(fd); + + list[0] = path; + list[1] = NULL; + + if (((fd = lpd_open(svc, 's', list, 3)) < 0) && (errno != EBADMSG)) { + switch (errno) { + case ENOSPC: + status = PAPI_TEMPORARY_ERROR; + break; + case EIO: + status = PAPI_TEMPORARY_ERROR; + break; + case ECONNREFUSED: + status = PAPI_SERVICE_UNAVAILABLE; + break; + case ENOENT: + status = PAPI_NOT_ACCEPTING; + break; + case EBADMSG: + case EBADF: + status = PAPI_OK; + break; + default: + status = PAPI_TIMEOUT; + break; + } + } else + status = PAPI_OK; + + if (ofd != NULL) + *ofd = fd; + else + close(fd); + + /* read the ID and add it to to the job */ + if ((fd = open(path, O_RDONLY)) >= 0) { + int job_id = 0; + read(fd, &job_id, sizeof (job_id)); + papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE, + "job-id", job_id); + close(fd); + } + + unlink(path); + + return (status); +} diff --git a/usr/src/lib/print/libpapi-lpd/common/lpd-misc.c b/usr/src/lib/print/libpapi-lpd/common/lpd-misc.c new file mode 100644 index 0000000000..c41d4fd309 --- /dev/null +++ b/usr/src/lib/print/libpapi-lpd/common/lpd-misc.c @@ -0,0 +1,192 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: lpd-misc.c 155 2006-04-26 02:34:54Z ktou $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#define __EXTENSIONS__ /* for strtok_r() */ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <fcntl.h> +#include <stdarg.h> +#include <string.h> +#include <signal.h> +#include <sys/socket.h> +#include <errno.h> +#include <wait.h> +#include <stropts.h> +#include <papi_impl.h> + +#include <config-site.h> + +char * +fdgets(char *buf, size_t len, int fd) +{ + char tmp; + int count = 0; + + memset(buf, 0, len); + while ((count < len) && (read(fd, &tmp, 1) > 0)) + if ((buf[count++] = tmp) == '\n') break; + + if (count != 0) + return (buf); + return (NULL); +} + +char * +queue_name_from_uri(uri_t *uri) +{ + char *result = NULL; + + if ((uri != NULL) && (uri->path != NULL)) { + char *ptr = strrchr(uri->path, '/'); + + if (ptr == NULL) + result = uri->path; + else + result = ++ptr; + } + + return (result); +} + +static int +recvfd(int sockfd) +{ + int fd = -1; +#if defined(sun) && defined(unix) && defined(I_RECVFD) + struct strrecvfd recv_fd; + + memset(&recv_fd, NULL, sizeof (recv_fd)); + if (ioctl(sockfd, I_RECVFD, &recv_fd) == 0) + fd = recv_fd.fd; +#else + struct iovec iov[1]; + struct msghdr msg; + +#ifdef CMSG_DATA + struct cmsghdr cmp[1]; + char buf[24]; /* send/recv 2 byte protocol */ + + memset(buf, 0, sizeof (buf)); + + iov[0].iov_base = buf; + iov[0].iov_len = sizeof (buf); + + msg.msg_control = cmp; + msg.msg_controllen = sizeof (struct cmsghdr) + sizeof (int); +#else + iov[0].iov_base = NULL; + iov[0].iov_len = 0; + msg.msg_accrights = (caddr_t)&fd; + msg.msg_accrights = sizeof (fd); +#endif + msg.msg_iov = iov; + msg.msg_iovlen = 1; + msg.msg_name = NULL; + msg.msg_namelen = 0; + + if (recvmsg(sockfd, &msg, 0) < 0) + fd = -1; +#ifdef CMSG_DATA + else + fd = * (int *)CMSG_DATA(cmp); +#endif +#endif + return (fd); +} + +int +lpd_open(service_t *svc, char type, char **args, int timeout) +{ + int ac, rc = -1, fds[2]; + pid_t pid; + char *av[64], buf[BUFSIZ]; + + if ((svc == NULL) || (svc->uri == NULL)) + return (-1); + +#ifndef SUID_LPD_PORT +#define SUID_LPD_PORT "/usr/lib/print/lpd-port" +#endif + + av[0] = SUID_LPD_PORT; ac = 1; + uri_to_string(svc->uri, buf, sizeof (buf)); + av[ac++] = "-u"; + av[ac++] = strdup(buf); + + if (timeout > 0) { + snprintf(buf, sizeof (buf), "%d", timeout); + av[ac++] = "-t"; + av[ac++] = strdup(buf); + } + snprintf(buf, sizeof (buf), "-%c", type); + av[ac++] = buf; + + if (args != NULL) + while ((*args != NULL) && (ac < 62)) + av[ac++] = *args++; + + av[ac++] = NULL; + +#if defined(sun) && defined(unix) && defined(I_RECVFD) + pipe(fds); +#else + socketpair(AF_UNIX, SOCK_STREAM, 0, fds); +#endif + + switch (pid = fork()) { + case -1: /* failed */ + break; + case 0: /* child */ + dup2(fds[1], 1); + execv(av[0], &av[0]); + perror("exec"); + exit(1); + break; + default: { /* parent */ + int err, status = 0; + + while ((waitpid(pid, &status, 0) < 0) && (errno == EINTR)); + errno = WEXITSTATUS(status); + + if (errno == 0) + rc = recvfd(fds[0]); + + err = errno; + close(fds[0]); + close(fds[1]); + errno = err; + } + } + + return (rc); +} diff --git a/usr/src/lib/print/libpapi-lpd/common/lpd-port.c b/usr/src/lib/print/libpapi-lpd/common/lpd-port.c new file mode 100644 index 0000000000..2cc106652f --- /dev/null +++ b/usr/src/lib/print/libpapi-lpd/common/lpd-port.c @@ -0,0 +1,768 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: lpd-port.c 155 2006-04-26 02:34:54Z ktou $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <config-site.h> + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdarg.h> +#include <string.h> +#include <signal.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <errno.h> +#include <syslog.h> +#include <values.h> +#include <stropts.h> /* for sendfd */ +#include <sys/uio.h> /* for sendmsg stuff */ +#include <pwd.h> +#include <sys/sendfile.h> +#include <ctype.h> +#include <alloca.h> +#ifdef HAVE_PRIV_H +#include <priv.h> +#endif +#include <papi_impl.h> + +#ifndef JOB_ID_FILE +#define JOB_ID_FILE "/var/run/rfc-1179.seq" +#endif /* JOB_ID_FILE */ + +static int +sendfd(int sockfd, int fd) +{ + syslog(LOG_DEBUG, "sendfd(%d, %d)", sockfd, fd); + +#if defined(sun) && defined(unix) && defined(I_SENDFD) + return (ioctl(sockfd, I_SENDFD, fd)); +#else + struct iovec iov[1]; + struct msghdr msg; +#ifdef CMSG_DATA + struct cmsghdr cmp[1]; + char buf[2]; /* send/recv 2 byte protocol */ + + iov[0].iov_base = buf; + iov[0].iov_len = 2; + + cmp[0].cmsg_level = SOL_SOCKET; + cmp[0].cmsg_type = SCM_RIGHTS; + cmp[0].cmsg_len = sizeof (struct cmsghdr) + sizeof (int); + * (int *)CMSG_DATA(cmp) = fd; + + buf[1] = 0; + buf[0] = 0; + msg.msg_control = cmp; + msg.msg_controllen = sizeof (struct cmsghdr) + sizeof (int); +#else + iov[0].iov_base = NULL; + iov[0].iov_len = 0; + msg.msg_accrights = (caddr_t)&fd; + msg.msg_accrights = sizeof (fd); +#endif + msg.msg_iov = iov; + msg.msg_iovlen = 1; + msg.msg_name = NULL; + msg.msg_namelen = 0; + + return (sendmsg(sockfd, &msg, 0)); +#endif +} + +static void +null(int i) +{ +} + +static int +sock_connect(int sock, uri_t *uri, int timeout) +{ + struct hostent *hp; + struct servent *sp; +#if defined(HAVE_GETIPNODEBYNAME) && defined(HAVE_RRESVPORT_AF) + struct sockaddr_in6 sin; +#else + struct sockaddr_in sin; +#endif + static void (*old_handler)(); + int err, + error_num; + unsigned timo = 1; + int port = -1; + + + /* + * Get the host address and port number to connect to. + */ + if ((uri == NULL) || (uri->host == NULL)) { + return (-1); + } + + /* linux style NULL usage */ + (void) memset((char *)&sin, (int)NULL, sizeof (sin)); + +#if defined(HAVE_GETIPNODEBYNAME) && defined(HAVE_RRESVPORT_AF) + if ((hp = getipnodebyname(uri->host, AF_INET6, AI_DEFAULT, + &error_num)) == NULL) { + errno = ENOENT; + return (-1); + } + (void) memcpy((caddr_t)&sin.sin6_addr, hp->h_addr, hp->h_length); + sin.sin6_family = hp->h_addrtype; +#else + if ((hp = gethostbyname(uri->host)) == NULL) { + errno = ENOENT; + return (-1); + } + + (void) memcpy((caddr_t)&sin.sin_addr, hp->h_addr, hp->h_length); + sin.sin_family = hp->h_addrtype; +#endif + + if ((sp = getservbyname("printer", "tcp")) == NULL) { + errno = ENOENT; + return (-1); + } + + if (uri->port != NULL) + port = atoi(uri->port); + if (port < 0) + port = sp->s_port; + +#if defined(HAVE_GETIPNODEBYNAME) && defined(HAVE_RRESVPORT_AF) + sin.sin6_port = port; +#else + sin.sin_port = port; +#endif + +retry: + old_handler = signal(SIGALRM, null); + (void) alarm(timeout); + + if (connect(sock, (struct sockaddr *)&sin, sizeof (sin)) < 0) { + (void) alarm(0); + (void) signal(SIGALRM, old_handler); + + if (errno == ECONNREFUSED && timo <= 16) { + (void) sleep(timo); + timo *= 2; + goto retry; + } + + return (-1); + } + + (void) alarm(0); + (void) signal(SIGALRM, old_handler); + return (sock); +} + +static int +next_job_id() +{ + int fd, result = getpid() % 1000; + + /* gain back enough privilege to open the id file */ +#ifdef PRIV_ALLSETS + if ((priv_set(PRIV_ON, PRIV_EFFECTIVE, + PRIV_FILE_DAC_READ, PRIV_FILE_DAC_WRITE, NULL)) < 0) { + syslog(LOG_ERR, "lpd_port:next_job_id:priv_set fails: : %m"); + return (-1); + } +#else + seteuid(0); +#endif + + /* open the sequence file */ + if (((fd = open(JOB_ID_FILE, O_RDWR)) < 0) && (errno == ENOENT)) + fd = open(JOB_ID_FILE, O_CREAT|O_EXCL|O_RDWR, 0644); + + syslog(LOG_DEBUG, "sequence file fd: %d", fd); + + /* drop our privilege again */ +#ifdef PRIV_ALLSETS + /* drop file access privilege */ + priv_set(PRIV_OFF, PRIV_PERMITTED, + PRIV_FILE_DAC_READ, PRIV_FILE_DAC_WRITE, NULL); +#else + seteuid(getuid()); +#endif + + if (fd >= 0) { + /* wait for a lock on the file */ + if (lockf(fd, F_LOCK, 0) == 0) { + char buf[8]; + int next; + + /* get the current id */ + (void) memset(buf, 0, sizeof (buf)); + if (read(fd, buf, sizeof (buf)) > 0) + result = atoi(buf); + + next = ((result < 999) ? (result + 1) : 0); + + /* store the next id in the file */ + snprintf(buf, sizeof (buf), "%.3d", next); + if ((lseek(fd, 0, SEEK_SET) == 0) && + (ftruncate(fd, 0) == 0)) + write(fd, buf, strlen(buf)); + } + } + syslog(LOG_DEBUG, "next_job_id() is %d", result); + + return (result); +} + +static int +reserved_port() +{ + int result = -1; + int port; + + /* gain back enough privilege to open a reserved port */ +#ifdef PRIV_ALLSETS + if ((priv_set( + PRIV_ON, PRIV_EFFECTIVE, PRIV_NET_PRIVADDR, NULL)) != 0) { + syslog(LOG_ERR, "priv_set fails for net_privaddr %m"); + return (-1); + } +#else + seteuid(0); +#endif + +#if defined(HAVE_GETIPNODEBYNAME) && defined(HAVE_RRESVPORT_AF) + port = 0; /* set to 0, rresvport_af() will find us one. */ + result = rresvport_af(&port, AF_INET6); +#else + port = IPPORT_RESERVED - 1; + while (((result = rresvport(&port)) < 0) && (port >= 0)) + port--; +#endif + + /* drop our privilege again */ +#ifdef PRIV_ALLSETS + priv_set(PRIV_OFF, PRIV_PERMITTED, PRIV_NET_PRIVADDR, NULL); +#else + seteuid(getuid()); +#endif + + return (result); +} + +static char * +get_user_name() +{ + static struct passwd *p = NULL; + + if ((p = getpwuid(getuid())) != NULL) + return (p->pw_name); + else + return ("unknown"); +} + +static void +add_args(int ac, char **av, char *buf, size_t len) +{ + while (ac--) { + strlcat(buf, " ", len); + strlcat(buf, *(av++), len); + } +} + +static int +massage_control_data(char *data, int id) +{ + char *line, *iter = NULL; + char *ptr; + char host[BUFSIZ]; + + gethostname(host, sizeof (host)); + + for (ptr = strchr(data, '\n'); ptr != NULL; ptr = strchr(ptr, '\n')) { + ptr++; + + if (ptr[0] == 'H') { + if (strncmp(++ptr, host, strlen(host)) != 0) + return (-1); + } else if ((ptr[0] == 'P') || (ptr[0] == 'L')) { + /* check the user name */ + uid_t uid = getuid(); + struct passwd *pw; + int len; + + if (uid == 0) /* let root do what they want */ + continue; + if ((pw = getpwuid(uid)) == NULL) + return (-1); /* failed */ + len = strlen(pw->pw_name); + if ((strncmp(++ptr, pw->pw_name, len) != 0) || + (ptr[len] != '\n')) + return (-1); /* failed */ + } else if ((islower(ptr[0]) != 0) || (ptr[0] == 'U')) { + /* check/fix df?XXXhostname */ + ptr++; + + if (strlen(ptr) < 6) + return (-1); + if ((ptr[0] == 'd') && (ptr[1] == 'f') && + (ptr[3] == 'X') && (ptr[4] == 'X') && + (ptr[5] == 'X')) { + ptr[3] = '0' + (id / 100) % 10; + ptr[4] = '0' + (id / 10) % 10; + ptr[5] = '0' + id % 10; + + if (strncmp(&ptr[6], host, strlen(host)) != 0) + return (-1); + } else + return (-1); + } + } + return (1); +} + +static int +send_lpd_message(int fd, char *fmt, ...) +{ + char buf[BUFSIZ]; + size_t size; + va_list ap; + + va_start(ap, fmt); + size = vsnprintf(buf, sizeof (buf), fmt, ap); + va_end(ap); + if (size == 0) + size = 1; + + syslog(LOG_DEBUG, "lpd_messsage(%d, %s)", fd, buf); + + if (write(fd, buf, size) != size) { + errno = EIO; + return (-1); + } + + if ((read(fd, buf, 1) != 1) || (buf[0] != 0)) + return (-1); + + return (0); +} + +static int +send_data_file(int sock, char *dfname, char *name) +{ + size_t len; + off_t off = 0; + struct stat st; + char buf[32]; + int fd = -1; + + if (strcmp(name, "standard input") != 0) { + if ((fd = open(name, O_RDONLY)) < 0) + return (-1); + + if (fstat(fd, &st) < 0) + return (-1); + } else + st.st_size = MAXINT; /* should be 0 */ + + /* request data file transfer, read ack/nack */ + errno = ENOSPC; + if (send_lpd_message(sock, "\003%d %s\n", st.st_size, dfname) < 0) + return (-1); + + if (fd != -1) { + /* write the data */ + if (sendfile(sock, fd, &off, st.st_size) != st.st_size) + return (-1); + close(fd); + + /* request ack/nack after the data transfer */ + errno = EIO; + if (send_lpd_message(sock, "") < 0) + return (-1); + } + + return (0); +} + +static int +send_control_file(int sock, char *data, int id) +{ + int len; + char buf[BUFSIZ]; + char *host = "localhost"; + + len = strlen(data); + + /* request data file transfer, read ack/nack */ + errno = ENOSPC; + if (send_lpd_message(sock, "\002%d cfA%.3d%s\n", len, id, host) < 0) + return (-1); + + /* write the data */ + if (write(sock, data, len) != len) + return (-1); + + /* request ack/nack after the data transfer */ + errno = EIO; + if (send_lpd_message(sock, "") < 0) + return (-1); + + return (0); +} + + +static int +submit_job(int sock, uri_t *uri, int job_id, char *path) +{ + int current = 0; + off_t off = 0; + char *metadata = NULL; + char *ptr, *iter = NULL; + int fd, err; + int sent_files = 0; + char buf[BUFSIZ]; + size_t len; + char *printer = queue_name_from_uri(uri); + + /* read in the control file */ + if ((fd = open(path, O_RDONLY)) >= 0) { + struct stat st; + + if (fstat(fd, &st) < 0) { + close(fd); + return (-1); + } + + metadata = alloca(st.st_size + 1); + memset(metadata, 0, st.st_size + 1); + + if (read(fd, metadata, st.st_size) != st.st_size) { + close(fd); + free(metadata); + metadata = NULL; + return (-1); + } + + } else { + syslog(LOG_ERR, + "lpd-port:submit_job:open failed : %m path %s", path); + return (-1); + } + + /* massage the control file */ + if (massage_control_data(metadata, job_id) < 0) { + /* bad control data, dump the job */ + syslog(LOG_ALERT, + "bad control file, possible subversion attempt"); + } + + /* request to transfer the job */ + if (send_lpd_message(sock, "\002%s\n", printer) < 0) { + /* no such (or disabled) queue, got to love rfc-1179 */ + errno = ENOENT; + return (-1); + } + + /* send the control data */ + if (send_control_file(sock, metadata, job_id) < 0) { + err = errno; + write(sock, "\001\n", 2); /* abort */ + errno = err; + return (-1); + } + + /* walk the control file sending the data files */ + for (ptr = strtok_r(metadata, "\n", &iter); ptr != NULL; + ptr = strtok_r(NULL, "\n", &iter)) { + char *name = NULL; + + if (ptr[0] != 'U') + continue; + + name = strtok_r(NULL, "\n", &iter); + if (name[0] != 'N') + continue; + + ptr++; + name++; + + if (send_data_file(sock, ptr, name) < 0) { + err = errno; + write(sock, "\001\n", 2); /* abort */ + errno = err; + return (-1); + } + if (strcmp(name, "standard input") != 0) + sent_files++; + } + + /* write back the job-id */ + err = errno; + if ((fd = open(path, O_WRONLY)) >= 0) { + ftruncate(fd, 0); + write(fd, &job_id, sizeof (job_id)); + close(fd); + } + errno = err; + + if (sent_files != 0) { + err = errno; + close(sock); + errno = err; + } + + return (0); +} + +static int +query(int fd, uri_t *uri, int ac, char **av) +{ + char buf[BUFSIZ]; + int rc, len; + char *printer = queue_name_from_uri(uri); + + /* build the request */ + snprintf(buf, sizeof (buf), "\04%s", printer); + add_args(ac, av, buf, sizeof (buf)); + strlcat(buf, "\n", sizeof (buf)); + len = strlen(buf); + + if (((rc = write(fd, buf, len)) >= 0) && (rc != len)) { + errno = EMSGSIZE; + rc = -1; + } else + rc = 0; + + return (rc); +} + +static int +cancel(int fd, uri_t *uri, int ac, char **av) +{ + char buf[BUFSIZ]; + int rc, len; + char *printer = queue_name_from_uri(uri); + + /* build the request */ + snprintf(buf, sizeof (buf), "\05%s %s", printer, get_user_name()); + add_args(ac, av, buf, sizeof (buf)); + strlcat(buf, "\n", sizeof (buf)); + len = strlen(buf); + + if (((rc = write(fd, buf, len)) >= 0) && (rc != len)) { + errno = EMSGSIZE; + rc = -1; + } else + rc = 0; + + return (rc); +} + +static void +usage(char *program) +{ + char *name; + + setreuid(getuid(), getuid()); + + if ((name = strrchr(program, '/')) == NULL) + name = program; + else + name++; + + fprintf(stderr, "usage:\t%s -u uri [-t timeout] " + "[-s control ]\n", name); + fprintf(stderr, "\t%s -u uri [-t timeout] " + "[-c user|job ...]\n", name); + fprintf(stderr, "\t%s -u uri [-t timeout] " + "[-q user|job ...]\n", name); + exit(EINVAL); +} + +/* + * The main program temporarily loses privilege while searching the command + * line arguments. It then allocates any resources it need privilege for + * job-id, reserved port. Once it has the resources it needs, it perminently + * drops all elevated privilege. It ghen connects to the remote print service + * based on destination hostname. Doing it this way reduces the potenential + * opportunity for a breakout with elevated privilege, breakout with an + * unconnected reserved port, and exploitation of the remote print service + * by a calling program. + */ +int +main(int ac, char *av[]) +{ + enum { OP_NONE, OP_SUBMIT, OP_QUERY, OP_CANCEL } operation = OP_NONE; + int fd, c, timeout = 0, exit_code = 0; + uri_t *uri = NULL; + uid_t uid = getuid(); +#ifdef PRIV_ALLSETS + priv_set_t *saveset = NULL; +#endif + + openlog("lpd-port", LOG_PID, LOG_LPR); + +#ifdef PRIV_ALLSETS + + /* lose as much as we can perminently and temporarily drop the rest. */ + + if ((saveset = priv_str_to_set("PRIV_NET_PRIVADDR," + "PRIV_FILE_DAC_READ,PRIV_FILE_DAC_WRITE,", + ",", (const char **)NULL)) == NULL) { + syslog(LOG_ERR, + "lpd_port: priv_str_to_set saveset failed: %m\n"); + return (-1); + } + + if ((setppriv(PRIV_SET, PRIV_PERMITTED, saveset)) < 0) { + syslog(LOG_ERR, "lpd_port:setppriv:priv_set failed: %m"); + return (-1); + } + + /* + * These privileges permanently dropped in next_job_id() and + * reserved_port() + */ + + if ((setppriv(PRIV_OFF, PRIV_EFFECTIVE, saveset)) < 0) { + syslog(LOG_ERR, "lpd_port:setppriv:priv_off failed: %m"); + return (-1); + } + + priv_freeset(saveset); + + syslog(LOG_DEBUG, "using privs"); +#else + + syslog(LOG_DEBUG, "no privs"); + seteuid(uid); +#endif + + + while ((c = getopt(ac, av, "cqst:u:")) != EOF) { + switch (c) { + case 'c': + if (operation != OP_NONE) + usage(av[0]); + operation = OP_CANCEL; + break; + case 'q': + if (operation != OP_NONE) + usage(av[0]); + operation = OP_QUERY; + break; + case 's': + if (operation != OP_NONE) + usage(av[0]); + operation = OP_SUBMIT; + break; + case 't': + timeout = atoi(optarg); + break; + case 'u': + if (uri_from_string(optarg, &uri) < 0) + usage(av[0]); + break; + default: + usage(av[0]); + /* does not return */ + } + } + + if ((uri == NULL) || (timeout < 0) || (operation == OP_NONE)) + usage(av[0]); + + if ((strcasecmp(uri->scheme, "lpd") != 0) && + (strcasecmp(uri->scheme, "rfc-1179") != 0)) + usage(av[0]); + + if (operation == OP_SUBMIT) /* get a job-id if we need it */ + if ((c = next_job_id()) < 0) { + syslog(LOG_ERR, "lpd_port:main:next_job_id fails"); + return (-1); + } + + if ((fd = reserved_port()) < 0) { + syslog(LOG_ERR, "reserved_port() failed %m"); + return (errno); + } + + /* + * we no longer want or need any elevated privilege, lose it all + * permanently. + */ + + setreuid(uid, uid); + + + /* connect to the print service */ + if ((fd = sock_connect(fd, uri, timeout)) < 0) + return (errno); + + /* perform the requested operation */ + switch (operation) { + case OP_SUBMIT: /* transfer the job, close the fd */ + if (submit_job(fd, uri, c, av[optind]) < 0) + exit_code = errno; + break; + case OP_QUERY: /* send the query string, return the fd */ + if (query(fd, uri, ac - optind, &av[optind]) < 0) + exit_code = errno; + break; + case OP_CANCEL: /* send the cancel string, return the fd */ + if (cancel(fd, uri, ac - optind, &av[optind]) < 0) + exit_code = errno; + break; + default: /* This should never happen */ + exit_code = EINVAL; + } + + + /* if the operation succeeded, send the fd to our parent */ + if ((exit_code == 0) && (sendfd(1, fd) < 0)) { + char buf[BUFSIZ]; + + exit_code = errno; + + /* sendfd() failed, dump the socket data for the heck of it */ + while ((c = read(fd, buf, sizeof (buf))) > 0) + write(1, buf, c); + } + + syslog(LOG_DEBUG, "exit code: %d", exit_code); + return (exit_code); +} diff --git a/usr/src/lib/print/libpapi-lpd/common/lpd-query.c b/usr/src/lib/print/libpapi-lpd/common/lpd-query.c new file mode 100644 index 0000000000..4c1392a1d9 --- /dev/null +++ b/usr/src/lib/print/libpapi-lpd/common/lpd-query.c @@ -0,0 +1,292 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: lpd-query.c 155 2006-04-26 02:34:54Z ktou $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#define __EXTENSIONS__ /* for strtok_r() */ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/fcntl.h> +#include <time.h> +#include <ctype.h> +#include <string.h> +#include <stdarg.h> + +#include <papi_impl.h> + +static void +parse_lpd_job_entry(service_t *svc, int fd, job_t **job) +{ + char *iter = NULL; + char line[128]; + papi_attribute_t **attributes = NULL; + char *p; + int octets = 0; + + *job = NULL; + + if (fdgets(line, sizeof (line), fd) == NULL) + return; + /* + * 1st line... + * user: rank [job (ID)(host)]\n + */ + if ((p = strtok_r(line, ": ", &iter)) == NULL) /* user: ... */ + return; /* invalid format */ + papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE, + "job-originating-user-name", p); + + p = strtok_r(NULL, "\t ", &iter); /* ...rank... */ + papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE, + "number-of-intervening-jobs", atoi(p) - 1); + p = strtok_r(NULL, " ", &iter); /* ...[job ... */ + if ((p = strtok_r(NULL, "]\n", &iter)) == NULL) /* ...(id)(hostname)] */ + return; + while (isspace(*p)) p++; + papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE, + "job-id", atoi(p)); + while (isdigit(*(++p))); + while (isspace(*p)) p++; + papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE, + "job-originating-host-name", p); + + /* + * rest-o-lines + * [(num) copies of ]file size bytes\n + */ + while ((fdgets(line, sizeof (line), fd) != NULL) && (line[0] != '\n')) { + int copies, size; + char *q; + + /* find the number of copies */ + if ((p = strstr(line, "copies of")) != NULL) { + copies = atoi(line); + p += 9; + } else { + copies = 1; + p = line; + } + papiAttributeListAddInteger(&attributes, PAPI_ATTR_EXCL, + "copies", copies); + + /* eat the leading whitespace */ + while (isspace(*p) != 0) + p++; + if ((q = strstr(p, " bytes\n")) != NULL) { + /* back up to the beginning of the size */ + do { q--; } while (isdigit(*q) != 0); + + /* seperate the name and size */ + *q = '\0'; + q++; + + size = atoi(q); + + papiAttributeListAddString(&attributes, + PAPI_ATTR_APPEND, "job-name", p); + papiAttributeListAddString(&attributes, + PAPI_ATTR_APPEND, "job-file-names", p); + papiAttributeListAddInteger(&attributes, + PAPI_ATTR_APPEND, "job-file-sizes", size); + + octets += (size * copies); + } + } + + papiAttributeListAddInteger(&attributes, PAPI_ATTR_APPEND, + "job-k-octets", octets/1024); + papiAttributeListAddInteger(&attributes, PAPI_ATTR_APPEND, + "job-octets", octets); + papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND, + "printer-name", queue_name_from_uri(svc->uri)); + + if ((*job = (job_t *)calloc(1, sizeof (**job))) != NULL) + (*job)->attributes = attributes; +} + +static void +parse_lpd_job_entries(service_t *svc, int fd) +{ + job_t *job = NULL; + + do { + parse_lpd_job_entry(svc, fd, &job); + list_append(&svc->cache->jobs, job); + } while (job != NULL); + +} + + +void +parse_lpd_query(service_t *svc, int fd) +{ + papi_attribute_t **attributes = NULL; + cache_t *cache = NULL; + int state = 0x03; /* idle */ + char line[128]; + char buf[1024]; + + /* get the status line */ + if (fdgets(line, sizeof (line), fd) == NULL) + return; /* this should not happen. */ + + papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND, + "printer-name", queue_name_from_uri(svc->uri)); + + if (uri_to_string(svc->uri, buf, sizeof (buf)) == 0) + papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND, + "printer-uri-supported", buf); + + papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE, + "printer-state-reasons", line); + + if (strstr(line, "ready and printing") != NULL) + state = 0x04; /* processing */ + else if ((strstr(line, "no entries") != NULL) || + (strstr(line, "is ready") != NULL)) + state = 0x03; /* idle */ + else + state = 0x05; /* stopped */ + + papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE, + "printer-state", state); + + if ((cache = (cache_t *)calloc(1, sizeof (*cache))) == NULL) + return; + + if ((cache->printer = (printer_t *)calloc(1, sizeof (*cache->printer))) + == NULL) + return; + + cache->printer->attributes = attributes; + svc->cache = cache; + + if (fdgets(line, sizeof (line), fd) != NULL) { + /* get the jobs */ + parse_lpd_job_entries(svc, fd); + } + + time(&cache->timestamp); +} + +void +cache_update(service_t *svc) +{ + int fd; + + if (svc->cache != NULL) /* this should be time based */ + return; + + if (svc == NULL) + return; + + if ((fd = lpd_open(svc, 'q', NULL, 3)) < 0) + return; + + parse_lpd_query(svc, fd); + + close(fd); +} + +papi_status_t +lpd_find_printer_info(service_t *svc, printer_t **printer) +{ + papi_status_t result = PAPI_BAD_ARGUMENT; + + if ((svc == NULL) || (printer == NULL)) + return (PAPI_BAD_ARGUMENT); + + cache_update(svc); + + if (svc->cache != NULL) { + *printer = svc->cache->printer; + result = PAPI_OK; + } else + result = PAPI_NOT_FOUND; + + return (result); +} + +papi_status_t +lpd_find_jobs_info(service_t *svc, job_t ***jobs) +{ + papi_status_t result = PAPI_BAD_ARGUMENT; + + if (svc != NULL) { + cache_update(svc); + + if (svc->cache != NULL) { + *jobs = svc->cache->jobs; + result = PAPI_OK; + } + } + + return (result); +} + +papi_status_t +lpd_find_job_info(service_t *svc, int job_id, job_t **job) +{ + papi_status_t result = PAPI_BAD_ARGUMENT; + job_t **jobs; + + if (lpd_find_jobs_info(svc, &jobs) != PAPI_OK) { + int i; + + *job = NULL; + for (i = 0; ((*job == NULL) && (jobs[i] != NULL)); i++) { + int id = -1; + + papiAttributeListGetInteger(jobs[i]->attributes, NULL, + "job-id", &id); + if (id == job_id) + *job = jobs[i]; + } + + if (*job != NULL) + result = PAPI_OK; + } + + return (result); +} + +void +cache_free(cache_t *item) +{ + if (item != NULL) { + if (item->printer != NULL) + papiPrinterFree((papi_printer_t *)item->printer); + if (item->jobs != NULL) + papiJobListFree((papi_job_t *)item->jobs); + free(item); + } +} diff --git a/usr/src/lib/print/libpapi-lpd/common/mapfile b/usr/src/lib/print/libpapi-lpd/common/mapfile new file mode 100644 index 0000000000..d21b349ff7 --- /dev/null +++ b/usr/src/lib/print/libpapi-lpd/common/mapfile @@ -0,0 +1,150 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# $Id: mapfile.in,v 1.2 2006/03/02 06:31:36 njacobs Exp $ +# + +# ident "%Z%%M% %I% %E% SMI" + +# +# Common interfaces that are most likely to be shared amongst the various +# PAPI implementations. +# + +SUNW_1.0 { + global: + # PAPI Attribute Calls + papiAttributeListAddValue = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddBoolean = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddCollection = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddDatetime = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddInteger = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddMetadata = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddRange = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddResolution = FUNCTION FILTER libpapi-common.so ; + papiAttributeListAddString = FUNCTION FILTER libpapi-common.so ; + papiAttributeListDelete = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetValue = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetNext = FUNCTION FILTER libpapi-common.so ; + papiAttributeListFind = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetBoolean = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetCollection = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetDatetime = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetInteger = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetMetadata = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetRange = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetResolution = FUNCTION FILTER libpapi-common.so ; + papiAttributeListGetString = FUNCTION FILTER libpapi-common.so ; + papiAttributeListFromString = FUNCTION FILTER libpapi-common.so ; + papiAttributeListToString = FUNCTION FILTER libpapi-common.so ; + papiAttributeListFree = FUNCTION FILTER libpapi-common.so ; + + # PAPI Service Calls + papiServiceCreate ; + papiServiceDestroy ; + papiServiceSetUserName ; + papiServiceSetPassword ; + papiServiceSetEncryption ; + papiServiceSetAuthCB ; + papiServiceSetAppData ; + papiServiceGetUserName ; + papiServiceGetPassword ; + papiServiceGetEncryption ; + papiServiceGetAppData ; + papiServiceGetServiceName ; + papiServiceGetAttributeList ; + papiServiceGetStatusMessage ; + + # PAPI Printer Calls + papiPrintersList = FUNCTION FILTER libpapi-common.so ; + papiPrinterQuery ; + papiPrinterAdd = FUNCTION FILTER libpapi-common.so ; + papiPrinterModify = FUNCTION FILTER libpapi-common.so ; + papiPrinterRemove = FUNCTION FILTER libpapi-common.so ; + papiPrinterDisable = FUNCTION FILTER libpapi-common.so ; + papiPrinterEnable = FUNCTION FILTER libpapi-common.so ; + papiPrinterPause = FUNCTION FILTER libpapi-common.so ; + papiPrinterResume = FUNCTION FILTER libpapi-common.so ; + papiPrinterPurgeJobs ; + papiPrinterListJobs ; + papiPrinterGetAttributeList ; + papiPrinterFree ; + papiPrinterListFree ; + + # PAPI Job Calls + papiJobSubmit ; + papiJobSubmitByReference ; + papiJobValidate = FUNCTION FILTER libpapi-common.so ; + papiJobStreamOpen ; + papiJobStreamWrite ; + papiJobStreamClose ; + papiJobQuery ; + papiJobModify = FUNCTION FILTER libpapi-common.so ; + papiJobMove = FUNCTION FILTER libpapi-common.so ; + papiJobCancel ; + papiJobHold = FUNCTION FILTER libpapi-common.so ; + papiJobRelease = FUNCTION FILTER libpapi-common.so ; + papiJobRestart = FUNCTION FILTER libpapi-common.so ; + papiJobPromote = FUNCTION FILTER libpapi-common.so ; + papiJobGetAttributeList ; + papiJobGetPrinterName ; + papiJobGetId ; + papiJobGetJobTicket = FUNCTION FILTER libpapi-common.so ; + papiJobFree ; + papiJobListFree ; + + # Misc. PAPI Calls + papiStatusString = FUNCTION FILTER libpapi-common.so ; + papiLibrarySupportedCall ; + papiLibrarySupportedCalls ; +}; + +SUNWprivate_1.0 { + global: + papiServiceSetPeer = FUNCTION FILTER libpapi-common.so ; + papiJobCreate = FUNCTION FILTER libpapi-common.so ; + papiJobStreamAdd = FUNCTION FILTER libpapi-common.so ; + papiJobCommit = FUNCTION FILTER libpapi-common.so ; + + # Misc. supporting calls + # URI + uri_from_string = FUNCTION FILTER libpapi-common.so ; + uri_to_string = FUNCTION FILTER libpapi-common.so ; + uri_free = FUNCTION FILTER libpapi-common.so ; + # list + list_remove = FUNCTION FILTER libpapi-common.so ; + list_append = FUNCTION FILTER libpapi-common.so ; + list_concatenate = FUNCTION FILTER libpapi-common.so ; + + # extra Attribute Calls + copy_attributes = FUNCTION FILTER libpapi-common.so ; + split_and_copy_attributes = FUNCTION FILTER libpapi-common.so ; + papiAttributeListPrint = FUNCTION FILTER libpapi-common.so ; + + local: + * ; +} ; diff --git a/usr/src/lib/print/libpapi-lpd/common/papi_impl.h b/usr/src/lib/print/libpapi-lpd/common/papi_impl.h new file mode 100644 index 0000000000..82d955b3cb --- /dev/null +++ b/usr/src/lib/print/libpapi-lpd/common/papi_impl.h @@ -0,0 +1,111 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +#ifndef _PAPI_IMPL_H +#define _PAPI_IMPL_H + +/* $Id: papi_impl.h 161 2006-05-03 04:32:59Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <papi.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#include <time.h> +#include <sys/types.h> +#include <stdarg.h> +#include <uri.h> + +typedef struct { + papi_attribute_t **attributes; +} printer_t; + +typedef struct job { + papi_attribute_t **attributes; +} job_t; + +typedef struct stream { + job_t *job; /* describes current job */ + int fd; /* the fd to write to */ + char *metadata; /* the converted metadata */ + char *dfname; /* the stream data (if we can't stream) */ + +} stream_t; + +typedef struct { /* used for query operations only */ + time_t timestamp; + printer_t *printer; + job_t **jobs; +} cache_t; + +typedef struct { + papi_attribute_t **attributes; /* extra info */ + uri_t *uri; /* printer uri */ + cache_t *cache; /* printer/job cache */ + int (*authCB)(papi_service_t svc, void *app_data); /* unused */ + void *app_data; /* unused */ +} service_t; + + +extern papi_status_t service_fill_in(service_t *svc, char *name); +extern void detailed_error(service_t *svc, char *fmt, ...); +extern char *queue_name_from_uri(uri_t *uri); +extern char *fdgets(char *buf, size_t len, int fd); + + +/* lpd operations */ + /* open a connection to remote print service */ +extern int lpd_open(service_t *svc, char type, char **args, + int timeout); + /* job cancelation */ +extern papi_status_t lpd_purge_jobs(service_t *svc, job_t ***jobs); +extern papi_status_t lpd_cancel_job(service_t *svc, int job_id); + /* job submission */ +extern papi_status_t lpd_submit_job(service_t *svc, char *metadata, + papi_attribute_t ***attributes, int *fd); +extern papi_status_t lpd_job_add_attributes(service_t *svc, + papi_attribute_t **attributes, + char **metadata, + papi_attribute_t ***used_attributes); +extern papi_status_t lpd_job_add_files(service_t *svc, + papi_attribute_t **attributes, char **files, + char **metadata, + papi_attribute_t ***used_attributes); + /* query cache lookup routines */ +extern papi_status_t lpd_find_printer_info(service_t *svc, printer_t **result); +extern papi_status_t lpd_find_job_info(service_t *svc, int job_id, job_t **job); +extern papi_status_t lpd_find_jobs_info(service_t *svc, job_t ***jobs); + + +#ifdef __cplusplus +} +#endif + +#endif /* _PAPI_IMPL_H */ diff --git a/usr/src/lib/print/libpapi-lpd/common/printer.c b/usr/src/lib/print/libpapi-lpd/common/printer.c new file mode 100644 index 0000000000..af538c62c6 --- /dev/null +++ b/usr/src/lib/print/libpapi-lpd/common/printer.c @@ -0,0 +1,156 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: printer.c 149 2006-04-25 16:55:01Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdlib.h> +#include <strings.h> +#include <papi_impl.h> + +static int +contains(char *value, char **list) +{ + int i; + + if ((value == NULL) || (list == NULL)) + return (1); + + for (i = 0; list[i] != NULL; i++) + if (strcasecmp(value, list[i]) == 0) + return (1); + + return (0); +} + +papi_status_t +papiPrinterQuery(papi_service_t handle, char *name, + char **requested_attrs, + papi_attribute_t **job_attributes, + papi_printer_t *printer) +{ + papi_status_t status; + service_t *svc = handle; + printer_t *p = NULL; + + if ((svc == NULL) || (name == NULL) || (printer == NULL)) + return (PAPI_BAD_ARGUMENT); + + if ((status = service_fill_in(svc, name)) == PAPI_OK) { + *printer = NULL; + + if ((contains("printer-state", requested_attrs) == 1) || + (contains("printer-state-reasons", requested_attrs) == 1)) + status = lpd_find_printer_info(svc, + (printer_t **)printer); + + if ((status == PAPI_OK) && (*printer == NULL)) { + char buf[BUFSIZ]; + + *printer = p = calloc(1, sizeof (*p)); + + papiAttributeListAddString(&(p->attributes), + PAPI_ATTR_APPEND, "printer-name", + queue_name_from_uri(svc->uri)); + + if (uri_to_string(svc->uri, buf, sizeof (buf)) == 0) + papiAttributeListAddString(&(p->attributes), + PAPI_ATTR_APPEND, + "printer-uri-supported", buf); + } + } + + return (status); +} + +papi_status_t +papiPrinterPurgeJobs(papi_service_t handle, char *name, papi_job_t **jobs) +{ + papi_status_t status; + service_t *svc = handle; + + if ((svc == NULL) || (name == NULL)) + return (PAPI_BAD_ARGUMENT); + + if ((status = service_fill_in(svc, name)) == PAPI_OK) + status = lpd_purge_jobs(svc, (job_t ***)jobs); + + 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) +{ + papi_status_t status; + service_t *svc = handle; + + if ((svc == NULL) || (name == NULL) || (jobs == NULL)) + return (PAPI_BAD_ARGUMENT); + + if ((status = service_fill_in(svc, name)) == PAPI_OK) + status = lpd_find_jobs_info(svc, (job_t ***)jobs); + + return (status); +} + +papi_attribute_t ** +papiPrinterGetAttributeList(papi_printer_t printer) +{ + printer_t *p = printer; + + if (p == NULL) + return (NULL); + + return (p->attributes); +} + +void +papiPrinterFree(papi_printer_t printer) +{ + printer_t *p = printer; + + if (p != NULL) { + if (p->attributes != NULL) + papiAttributeListFree(p->attributes); + free(p); + } +} + +void +papiPrinterListFree(papi_printer_t *printers) +{ + if (printers != NULL) { + int i; + + for (i = 0; printers[i] != NULL; i++) + papiPrinterFree(printers[i]); + free(printers); + } +} diff --git a/usr/src/lib/print/libpapi-lpd/common/service.c b/usr/src/lib/print/libpapi-lpd/common/service.c new file mode 100644 index 0000000000..c39ea0cbb5 --- /dev/null +++ b/usr/src/lib/print/libpapi-lpd/common/service.c @@ -0,0 +1,299 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: service.c 163 2006-05-09 15:07:45Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdarg.h> +#include <alloca.h> +#include <uri.h> +#include <papi_impl.h> + +papi_status_t +service_fill_in(service_t *svc, char *name) +{ + papi_status_t status = PAPI_OK; + uri_t *uri = NULL; + + if (svc == NULL) + return (PAPI_BAD_ARGUMENT); + + if (name == NULL) + return (PAPI_OK); + + /* + * valid URIs are in the form: + * lpd://server[:port]/.../queue[#extensions] + * rfc-1179://server[:port]/.../queue[#extensions] + * any authentication information supplied the URI is ignored. + */ + if (uri_from_string((char *)name, &uri) != -1) { + if ((strcasecmp(uri->scheme, "lpd") == 0) || + (strcasecmp(uri->scheme, "rfc-1179") == 0)) { + if (svc->uri != NULL) + uri_free(svc->uri); + svc->uri = uri; + } else { + uri_free(uri); + status = PAPI_URI_SCHEME; + } + } + + return (status); +} + +papi_status_t +papiServiceCreate(papi_service_t *handle, char *service_name, + char *user_name, char *password, + int (*authCB)(papi_service_t svc, void *app_data), + papi_encryption_t encryption, void *app_data) +{ + papi_status_t status; + service_t *svc = NULL; + + if (handle == NULL) + return (PAPI_BAD_ARGUMENT); + + if ((*handle = svc = (service_t *)calloc(1, sizeof (*svc))) == NULL) + return (PAPI_TEMPORARY_ERROR); + + if (service_name != NULL) + papiAttributeListAddString(&svc->attributes, PAPI_ATTR_EXCL, + "service-name", service_name); + + (void) papiServiceSetUserName(svc, user_name); + (void) papiServiceSetPassword(svc, password); + (void) papiServiceSetAuthCB(svc, authCB); + (void) papiServiceSetAppData(svc, app_data); + (void) papiServiceSetEncryption(svc, encryption); + + status = service_fill_in(svc, service_name); + + return (status); +} + +void +papiServiceDestroy(papi_service_t handle) +{ + if (handle != NULL) { + service_t *svc = handle; + +#ifdef DEADBEEF + if (svc->cache != NULL) + cache_free(svc->cache); +#endif + if (svc->uri != NULL) + uri_free(svc->uri); + if (svc->attributes != NULL) + papiAttributeListFree(svc->attributes); + free(svc); + } +} + +papi_status_t +papiServiceSetUserName(papi_service_t handle, char *user_name) +{ + service_t *svc = handle; + + if (svc == NULL) + return (PAPI_BAD_ARGUMENT); + + return (papiAttributeListAddString(&svc->attributes, PAPI_ATTR_REPLACE, + "user-name", user_name)); +} + +papi_status_t +papiServiceSetPassword(papi_service_t handle, char *password) +{ + service_t *svc = handle; + + if (svc == NULL) + return (PAPI_BAD_ARGUMENT); + + return (papiAttributeListAddString(&svc->attributes, + PAPI_ATTR_REPLACE, "password", password)); +} + +papi_status_t +papiServiceSetEncryption(papi_service_t handle, + papi_encryption_t encryption) +{ + service_t *svc = handle; + + if (svc == NULL) + return (PAPI_BAD_ARGUMENT); + + return (papiAttributeListAddInteger(&svc->attributes, PAPI_ATTR_REPLACE, + "encryption", (int)encryption)); +} + +papi_status_t +papiServiceSetAuthCB(papi_service_t handle, + int (*authCB)(papi_service_t svc, void *app_data)) +{ + service_t *svc = handle; + + if (svc == NULL) + return (PAPI_BAD_ARGUMENT); + + svc->authCB = (int (*)(papi_service_t svc, void *))authCB; + + return (PAPI_OK); +} + +papi_status_t +papiServiceSetAppData(papi_service_t handle, void *app_data) +{ + service_t *svc = handle; + + if (svc == NULL) + return (PAPI_BAD_ARGUMENT); + + svc->app_data = (void *)app_data; + + return (PAPI_OK); +} + +char * +papiServiceGetServiceName(papi_service_t handle) +{ + service_t *svc = handle; + char *result = NULL; + + if (svc != NULL) + papiAttributeListGetString(svc->attributes, NULL, + "service-name", &result); + + return (result); +} + +char * +papiServiceGetUserName(papi_service_t handle) +{ + service_t *svc = handle; + char *result = NULL; + + if (svc != NULL) + papiAttributeListGetString(svc->attributes, NULL, + "user-name", &result); + + return (result); + +} + +char * +papiServiceGetPassword(papi_service_t handle) +{ + service_t *svc = handle; + char *result = NULL; + + if (svc != NULL) + papiAttributeListGetString(svc->attributes, NULL, + "password", &result); + + return (result); +} + +papi_encryption_t +papiServiceGetEncryption(papi_service_t handle) +{ + service_t *svc = handle; + papi_encryption_t result = PAPI_ENCRYPT_NEVER; + + if (svc != NULL) + papiAttributeListGetInteger(svc->attributes, NULL, + "encryption", (int *)&result); + + return (result); +} + +void * +papiServiceGetAppData(papi_service_t handle) +{ + service_t *svc = handle; + void *result = NULL; + + if (svc != NULL) { + result = svc->app_data; + } + + return (result); + +} + +papi_attribute_t ** +papiServiceGetAttributeList(papi_service_t handle) +{ + service_t *svc = handle; + papi_attribute_t **result = NULL; + + if (svc != NULL) + result = svc->attributes; + + return (result); +} + +char * +papiServiceGetStatusMessage(papi_service_t handle) +{ + service_t *svc = handle; + char *result = NULL; + + if (svc != NULL) { + papiAttributeListGetString(svc->attributes, NULL, + "detailed-status-message", &result); + } + + return (result); +} + +void +detailed_error(service_t *svc, char *fmt, ...) +{ + if ((svc != NULL) && (fmt != NULL)) { + va_list ap; + size_t size; + char *message = alloca(BUFSIZ); + + va_start(ap, fmt); + /* + * fill in the message. If the buffer is too small, allocate + * one that is large enough and fill it in. + */ + if ((size = vsnprintf(message, BUFSIZ, fmt, ap)) >= BUFSIZ) + if ((message = alloca(size)) != NULL) + vsnprintf(message, size, fmt, ap); + va_end(ap); + + papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND, + "detailed-status-message", message); + } +} diff --git a/usr/src/lib/print/libpapi-lpd/i386/Makefile b/usr/src/lib/print/libpapi-lpd/i386/Makefile new file mode 100644 index 0000000000..362f811e03 --- /dev/null +++ b/usr/src/lib/print/libpapi-lpd/i386/Makefile @@ -0,0 +1,31 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBDIR) $(ROOTLIBS) $(ROOTLINKS) $(EXTRALINKS) \ + $(ROOTLIBPRINTPROG) diff --git a/usr/src/lib/print/libpapi-lpd/sparc/Makefile b/usr/src/lib/print/libpapi-lpd/sparc/Makefile new file mode 100644 index 0000000000..362f811e03 --- /dev/null +++ b/usr/src/lib/print/libpapi-lpd/sparc/Makefile @@ -0,0 +1,31 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBDIR) $(ROOTLIBS) $(ROOTLINKS) $(EXTRALINKS) \ + $(ROOTLIBPRINTPROG) diff --git a/usr/src/lib/print/libprint/Makefile b/usr/src/lib/print/libprint/Makefile new file mode 100644 index 0000000000..55847e0be0 --- /dev/null +++ b/usr/src/lib/print/libprint/Makefile @@ -0,0 +1,54 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../../Makefile.lib + +SUBDIRS = $(MACH) +#$(BUILD64)SUBDIRS += $(MACH64) + +all := TARGET = all +clean := TARGET = clean +clobber := TARGET = clobber +install := TARGET = install +lint := TARGET = lint + +.KEEP_STATE: + +all clean clobber install: .WAIT $(SUBDIRS) + +lint: # $(SUBDIRS) + +install_h: + +check: + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include ../../Makefile.targ diff --git a/usr/src/lib/print/libprint/Makefile.com b/usr/src/lib/print/libprint/Makefile.com new file mode 100644 index 0000000000..6b7e190b11 --- /dev/null +++ b/usr/src/lib/print/libprint/Makefile.com @@ -0,0 +1,61 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +LIBRARY = libprint.a +VERS = .2 +OBJECTS = \ + job.o list.o misc.o network.o ns.o ns_bsd_addr.o ns_cmn_kvp.o \ + ns_cmn_printer.o nss_convert.o nss_ldap.o nss_printer.o nss_write.o + +include ../../../Makefile.lib +include ../../../Makefile.rootfs + +ROOTLIBDIR= $(ROOT)/usr/lib + +LIBS = $(DYNLIB) + +SRCS = $(OBJECTS:%.o = $(SRCDIR)/%.c) + +$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC) + +SRCDIR = ../common +MAPFILE = $(SRCDIR)/mapfile-vers + +CFLAGS += $(CCVERBOSE) +CPPFLAGS += -I$(SRCDIR) +CPPFLAGS += -I../../head -D_REENTRANT +DYNFLAGS += -M $(MAPFILE) +LDLIBS += -lnsl -lsocket -lc -lldap + + +.KEEP_STATE: + +all: $(LIBS) + +lint: lintcheck + +include ../../../Makefile.targ diff --git a/usr/src/lib/print/job.c b/usr/src/lib/print/libprint/common/job.c index c41dcfaf09..b379648d26 100644 --- a/usr/src/lib/print/job.c +++ b/usr/src/lib/print/libprint/common/job.c @@ -43,135 +43,15 @@ #include <libintl.h> #include <grp.h> -#include <print/job.h> -#include <print/misc.h> -#include <print/list.h> +#include <job.h> +#include <misc.h> +#include <list.h> #define MAX_RETRIES (5) - /* - * These specify important strings in the job routines - */ - -static char *_sequence_file = SEQUENCE_FILE; -static char *_data_file_prefix = DATA_FILE_PREFIX; static char *_control_file_prefix = CONTROL_FILE_PREFIX; static char *_xfer_file_prefix = XFER_FILE_PREFIX; -static char *_temp_file_prefix = TEMP_FILE_PREFIX; - - -/* - * _job_alloc_id() allocates the next request id number from the number space. - * It does this by looking for it in a sequence number file in the - * spooling directory, reading the value, incrementing the file value, and - * returning the previous file value. If the value falls beyond the number - * space, the new value will be the begining of the space. If the sequence - * file doesn't exist, the value will be the start of the number space, and - * a file will be created. If there is some other error opening or reading - * the sequence file, a -1 will be returned. - */ -static int -_job_alloc_id(char *printer, char *spool) -{ - char buf[BUFSIZ]; - int fd, - id, - rc; - - if (snprintf(buf, sizeof (buf), "%s/%s", spool, _sequence_file) - >= sizeof (buf)) { - - syslog(LOG_ERR, "_job_alloc_id: buffer overflow"); - return (-1); - } - - fd = open(buf, O_RDWR); - if ((fd < 0) && (errno == ENOENT)) - fd = open(buf, O_CREAT|O_EXCL|O_RDWR, 0664); - if (fd < 0) { - syslog(LOG_ERR, "_job_alloc_id(%s): open :%m", printer); - return (-1); - } - - if (lockf(fd, F_LOCK, 0) < 0) { - syslog(LOG_ERR, "_job_alloc_id(%s): lock :%m", printer); - return (-1); - } - - (void) memset(buf, NULL, sizeof (buf)); - if (read(fd, buf, sizeof (buf)) < 0) { - syslog(LOG_ERR, "_job_alloc_id(%s): read :%m", printer); - close(fd); - return (-1); - } - - rc = atoi(buf); - id = ((rc < JOB_ID_END) ? (rc + 1) : JOB_ID_START); - - snprintf(buf, sizeof (buf), "%.3d\n", id); - if ((lseek(fd, 0, SEEK_SET) == 0) && (ftruncate(fd, 0) == 0)) - write(fd, buf, strlen(buf)); - - syslog(LOG_DEBUG, "_job_alloc_id(%s): - id %d", printer, rc); - close(fd); - return (rc); -} - - - - -/* - * _job_alloc_file() finds an unused path name in the format: - * spool_dir/(prefix)(x)(id)hostname, where x is in [A-Za-z]. If all - * such paths are in use, the routine returns NULL. If it finds an open - * name, a newly allocated string is returned containing the path. - */ -static char * -_job_alloc_file(char *printer, char *prefix, char *spool, char *key, int id, - char *host) -{ - char hostname[128], - buf[BUFSIZ], - *path; - int key_position = 0; - - if (host == NULL) { - (void) sysinfo(SI_HOSTNAME, hostname, sizeof (hostname)); - host = hostname; - } - - if (prefix != NULL) - key_position = strlen(prefix); - - if (*key < 'A') - *key = 'A'; - else if (*key > 'Z' && *key < 'a') - *key = 'a'; - else if (*key > 'z') - return (NULL); - - if (snprintf(buf, sizeof (buf), - "%s/%s%c%.3d%s", - spool, prefix, *key, id, host) >= sizeof (buf)) { - syslog(LOG_ERR, "libprint:_job_alloc_file buffer overrun"); - return (NULL); - } - path = strrchr(buf, '/') + 1; - - while (access(buf, F_OK) == 0) { - if (++path[key_position] == '[') - path[key_position] = 'a'; - else if (path[key_position] > 'z') - return (NULL); - } - - *key = path[key_position] + 1; - - syslog(LOG_DEBUG, "_job_alloc_file(%s, %s, %c, %d): %s", printer, - prefix, *key, id, path); - return (strdup(path)); -} /* @@ -190,263 +70,6 @@ _job_unlink_data_file(jobfile_t *file) return (-1); } - -/* - * job_create() creates, initializes and returns a new job structure. Part of - * the initialization includes generating a job id, and filling in the - * printer and server information. - */ -job_t * -job_create(char *printer, char *server, char *spool) -{ - job_t *tmp; - int id; - - if ((printer == NULL) || (server == NULL) || (spool == NULL)) - return (NULL); - if ((id = _job_alloc_id(printer, spool)) == -1) - return (NULL); - - if ((tmp = (job_t *)calloc(1, sizeof (*tmp))) != NULL) { - tmp->job_id = id; - tmp->job_printer = printer; - tmp->job_server = server; - tmp->job_spool_dir = strdup(spool); - tmp->job_df_next = 'A'; - } - syslog(LOG_DEBUG, "job_create(%s, %s): %d", printer, server, - (tmp != NULL ? tmp->job_id : -1)); - return (tmp); -} - - -/* - * job_primative() appends an rfc1179(BSD printing) control message into the - * job structure's control data. If the message would extend beyond the - * memory currently allocated for control data, a new buffer is - * realloc()'d and the message is appended to the new buffer. - */ -int -job_primative(job_t *job, char option, char *value) -{ - char buf[BUFSIZ]; - char key = 'A'; - jobfile_t *cf; - - if ((job == NULL) || (value == NULL)) - return (-1); - - cf = job->job_cf; - if (cf == NULL) { - if ((cf = calloc(1, sizeof (*cf))) == NULL) { - syslog(LOG_DEBUG, "job_primative(): calloc() failed"); - return (-1); - } - cf->jf_spl_path = _job_alloc_file(job->job_printer, - _control_file_prefix, - job->job_spool_dir, &key, job->job_id, - job->job_host); - job->job_cf = cf; - } - - cf->jf_size += (strlen(value) + 2); /* (opt)(value)\n(NULL) */ - if (cf->jf_data == NULL) { - cf->jf_data = calloc(1, cf->jf_size + 1); - } else - cf->jf_data = realloc(cf->jf_data, cf->jf_size + 1); - - if (cf->jf_data == NULL) { - syslog(LOG_DEBUG, "job_primative(%d, %c, %s): alloc() failed", - job->job_id, option, value); - return (-1); - } - - if (snprintf(buf, sizeof (buf), "%c%s\n", option, value) - >= sizeof (buf)) { - syslog(LOG_ERR, "libprint:job_primative: buffer overrun"); - return (-1); - } - (void) strlcat(cf->jf_data, buf, cf->jf_size + 1); - - if (option == CF_USER) - job->job_user = strdup(value); - if (option == CF_HOST) - job->job_host = strdup(value); - - syslog(LOG_DEBUG, "job_primative(%d, %c, %s)", job->job_id, option, - value); - return (0); -} - - -/* - * job_svr4_primative() builds new arguments to call job_primative() with. - * it is strictly for use with the rfc1179 like options that were added - * to the protocol to support SVR4 printing features not supported in the - * protocol. - */ -int -job_svr4_primative(job_t *job, char option, char *value) -{ - char buf[BUFSIZ]; - - if (value == NULL) - return (-1); - - if (snprintf(buf, sizeof (buf), "%c%s", option, value) - >= sizeof (buf)) { - syslog(LOG_ERR, "libprint:job_svr4_primative: buffer overrun"); - return (-1); - } - return (job_primative(job, CF_SYSV_FEATURE, buf)); -} - - -/* - * job_add_data_file() adds a data file into a job structure. It does this - * by allocating a new temporary spooling file, adding control messages - * to the control data so the job prints and files unlink on the server. - * It copies the path passed in to the temporary file, it also adds - * the temporary file name to the job_df_list. - */ -int -job_add_data_file(job_t *job, char *path, char *title, char type, int copies, - int linked, int delete) -{ - char full_path[BUFSIZ], - *dfName; - jobfile_t *file; - struct stat st; - - errno = EINVAL; - - if ((job == NULL) || (path == NULL)) - return (-1); - - - if (access(path, R_OK) < 0) { /* can we read this file */ - int result = -1; - gid_t gid = getgid(), - egid = getegid(); - - if (gid != egid) { /* if it's set-gid, try the egid */ - (void) setgid(egid); - result = access(path, R_OK); - (void) setgid(gid); - (void) setegid(egid); - } - - if (result != 0) - return (result); - } - - if (stat(path, &st) < 0) /* stat failed */ - return (-1); - - if (S_ISREG(st.st_mode) == 0) { /* not a regular file */ - errno = EISDIR; - return (-1); - } - - if (st.st_size == 0) { /* empty file */ - errno = ESRCH; - return (-1); - } - - if ((dfName = _job_alloc_file(job->job_printer, _data_file_prefix, - job->job_spool_dir, &(job->job_df_next), - job->job_id, job->job_host)) == NULL) { - errno = ENFILE; - return (-1); - } - - if ((file = (jobfile_t *)calloc(1, sizeof (*file))) == NULL) { - job->job_df_next--; - return (-1); - } - - if (linked == 0) { - file->jf_size = map_in_file(path, &file->jf_data, 1); - file->jf_mmapped = 1; - } else - file->jf_size = access(path, R_OK); - - if (file->jf_size < 0) { - free(file); - job->job_df_next--; - return (-1); - } - - (void) memset(full_path, NULL, sizeof (full_path)); - if (path[0] != '/') { - int rc = 0; - - /* - * getcwd() makes use of the effective uid/gid. - * Set them to job owner uid/gid. - */ - rc = initgroups(job->job_user, getgid()); - if (rc != 0) { - syslog(LOG_DEBUG, "job_add_data_file(): failed " - "to initgroups() (errno: %d)", errno); - } - rc = seteuid(getuid()); - if (rc != 0) { - syslog(LOG_DEBUG, "job_add_data_file(): failed " - "to seteuid() to uid (errno: %d)", errno); - } - rc = setegid(getgid()); - if (rc != 0) { - syslog(LOG_DEBUG, "job_add_data_file(): failed " - "to setegid() to gid (errno: %d)", errno); - } - - (void) getcwd(full_path, sizeof (full_path)); - - /* set back euid/egid to previous values */ - rc = seteuid(0); - if (rc != 0) { - syslog(LOG_DEBUG, "job_add_data_file(): failed " - "to reset euid (errno: %d)", errno); - } - rc = initgroups("root", 1); - if (rc != 0) { - syslog(LOG_DEBUG, "job_add_data_file(): failed " - "to reset groups (errno: %d)", errno); - } - - (void) strlcat(full_path, "/", sizeof (full_path)); - } - if (strlcat(full_path, path, - sizeof (full_path)) >= sizeof (full_path)) { - syslog(LOG_ERR, "job_add_data_file:buffer overflow"); - return (-1); - } - - file->jf_spl_path = strdup(dfName); - file->jf_src_path = strdup(full_path); - file->jf_name = strdup((title?title:path)); - - job->job_df_list = (jobfile_t **)list_append((void **) - job->job_df_list, - (void *)file); - - if (type == CF_PRINT_PR) - (void) job_primative(job, CF_TITLE, (title ? title : path)); - while (copies--) - (void) job_primative(job, type, dfName); - (void) job_primative(job, CF_UNLINK, dfName); - if (delete != 0) - (void) job_primative(job, CF_UNLINK, full_path); - (void) job_primative(job, CF_SOURCE_NAME, (title?title:path)); - - syslog(LOG_DEBUG, "job_add_data_file((%d, %s, %s), %s, %s, %d, %d, %d)", - job->job_id, job->job_printer, job->job_server, path, - ((title != NULL) ? title : "NULL"), type, copies, linked); - return (linked ? st.st_size : file->jf_size); -} - - /* * */ @@ -565,137 +188,7 @@ job_destroy(job_t *job) job_free(job); } - -/* - * _vjob_store_df() moves a data file from memory to disk. Called by - * list_iterate(). - */ -static int -_vjob_store_df(jobfile_t *file) -{ - if ((file->jf_data == NULL) && (file->jf_size == 0) && - (symlink(file->jf_src_path, file->jf_spl_path) == 0)) - return (0); - if (file->jf_data != NULL) - return (write_buffer(file->jf_spl_path, file->jf_data, - file->jf_size)); - else - return (copy_file(file->jf_src_path, file->jf_spl_path)); -} - - -/* - * job_create_binding_file() finds and opens a temporary binding file locking - * the file then renaming it to the real name returning the open fd. - */ static int -job_create_binding_file(job_t *job, char **xfile) -{ - int fd; - char *tmp, - *src, - *dst; - char key = 'A'; - int msize; - - /* get a temp file name */ - if ((tmp = _job_alloc_file(job->job_printer, _temp_file_prefix, - job->job_spool_dir, &key, - job->job_id, job->job_host)) == NULL) - return (-1); - key = 'A'; - /* get a binding file name */ - if ((*xfile = _job_alloc_file(job->job_printer, _xfer_file_prefix, - job->job_spool_dir, &key, - job->job_id, job->job_host)) == NULL) - return (-1); - - - msize = strlen(job->job_spool_dir) + strlen(tmp) + 3; - if ((src = calloc(1, msize)) == NULL) { - syslog(LOG_DEBUG, "job_create_binding_file(): calloc(src)"); - return (-1); - } - snprintf(src, msize, "%s/%s", job->job_spool_dir, tmp); - - msize = strlen(job->job_spool_dir) + strlen(*xfile) + 3; - if ((dst = calloc(1, msize)) == NULL) { - syslog(LOG_DEBUG, "job_create_binding_file(): calloc(dst)"); - free(src); - return (-1); - } - snprintf(dst, msize, "%s/%s", job->job_spool_dir, *xfile); - - /* - * open the tmp file, lock it, and rename it so are guaranteed to - * have it. - */ - if ((fd = get_lock(src, 0)) < 0) { - syslog(LOG_ERR, "creating binding file (%s): %m", src); - } else if (rename(src, dst) < 0) { - syslog(LOG_DEBUG, "rename binding file(%s,%s): %m", src, dst); - close(fd); - fd = -1; - } - free(tmp); - free(src); - free(dst); - return (fd); -} - - -/* - * job_store() makes a disk copy of a job structure. - */ -int -job_store(job_t *job) -{ - char buf[BUFSIZ]; - int lock; - jobfile_t *cf; - syslog(LOG_DEBUG, "job_store(%d, %s, %s)", job->job_id, - job->job_printer, job->job_server); - - cf = job->job_cf; - - /* create the control_file */ - if (snprintf(buf, sizeof (buf), "%s/%s", job->job_spool_dir, - cf->jf_spl_path) >= sizeof (buf)) { - syslog(LOG_ERR, "job_store: buffer overrun"); - return (-1); - } - - if (write_buffer(buf, cf->jf_data, strlen(cf->jf_data)) < 0) { - (void) unlink(cf->jf_src_path); - return (-1); - } - - /* - * create and lock the binding file, so nobody has access to the job - * while it is being created. - */ - if ((lock = job_create_binding_file(job, &cf->jf_src_path)) < 0) - return (-1); - - /* add the binding information */ - if (snprintf(buf, sizeof (buf), "%s:%s\n", job->job_server, - job->job_printer) >= sizeof (buf)) { - syslog(LOG_ERR, "job_store: buffer overrun"); - return (-1); - } - - if (write(lock, buf, strlen(buf)) < 0) - return (-1); - - - /* store the data files */ - (void) list_iterate((void **)job->job_df_list, (VFUNC_T)_vjob_store_df); - - close(lock); /* release the lock */ - return (0); -} - -int get_job_from_cfile(jobfile_t *file, char *cFile, char *xFile, job_t *tmp) { jobfile_t *file1; diff --git a/usr/src/lib/print/libprint/common/job.h b/usr/src/lib/print/libprint/common/job.h new file mode 100644 index 0000000000..932d993a16 --- /dev/null +++ b/usr/src/lib/print/libprint/common/job.h @@ -0,0 +1,138 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _JOB_H +#define _JOB_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/va_list.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Sequence number space + */ +#define JOB_ID_START 0 +#define JOB_ID_END 999 + +/* + * Job related files + */ +#define SEQUENCE_FILE ".seq" /* sequence numbers */ +#define TEMP_FILE_PREFIX "tf" /* printer:server */ +#define XFER_FILE_PREFIX "xf" /* printer:server */ +#define CONTROL_FILE_PREFIX "cf" /* job control data */ +#define DATA_FILE_PREFIX "df" /* job data file */ + +/* + * RFC-1179 Control File Primatives + */ +#define CF_CLASS 'C' /* C(ClassName)\n - for banner page */ +#define CF_HOST 'H' /* H(Hostname)\n - host submitting job */ +#define CF_INDENT 'I' /* I(indent)\n - # of spaces for 'f' */ +#define CF_JOBNAME 'J' /* J(Jobname)\n - name of job for banner */ +#define CF_PRINT_BANNER 'L' /* L[User]\n - User name on burst page */ +#define CF_MAIL 'M' /* M(user)\n - User to mail when done */ +#define CF_SOURCE_NAME 'N' /* N(name)\n - source of data file */ +#define CF_USER 'P' /* P(name)\n - requesting user */ +#define CF_SYMLINK 'S' /* S(device) (inode)\n - foget it */ +#define CF_TITLE 'T' /* T(title)\n - for pr */ +#define CF_UNLINK 'U' /* U(file)\n - unlink file */ +#define CF_WIDTH 'W' /* W(width)\n - column width */ +#define CF_FONT_TROFF_R '1' /* 1(file)\n - file with Times Roman font */ +#define CF_FONT_TROFF_I '2' /* 2(file)\n - file with Times Italic font */ +#define CF_FONT_TROFF_B '3' /* 3(file)\n - file with Times Bold font */ +#define CF_FONT_TROFF_S '4' /* 4(file)\n - file with Times Special font */ +#define CF_PRINT_CIF 'c' /* c(file)\n - print/plot file as CIF data */ +#define CF_PRINT_DVI 'd' /* d(file)\n - print file as DVI data */ +#define CF_PRINT_ASCII 'f' /* f(file)\n - print file as ASCII */ +#define CF_PRINT_PLOT 'g' /* g(file)\n - print file as plot data */ +#define CF_KERBERIZED 'k' /* k...\n - for Kerberos */ +#define CF_PRINT_RAW 'l' /* l(file)\n - print file dammit */ +#define CF_PRINT_DROFF 'n' /* n(file)\n - print file as ditroff output */ +#define CF_PRINT_PS 'o' /* o(file)\n - print file as PostScript */ +#define CF_PRINT_PR 'p' /* p(file)\n - print file thru "pr" */ +#define CF_PRINT_FORT 'r' /* r(file)\n - print file as fortran */ +#define CF_PRINT_TROFF 't' /* n(file)\n - print file as troff output */ +#define CF_PRINT_RAS 'v' /* v(file)\n - print file as raster image */ +#define CF_PRINT_PLDM 'z' /* z...\n - for Palladium ??? */ + +/* + * Solaris 2.X LP - BSD protocol extensions + */ +#define CF_SYSV_OPTION 'O' /* for SVR4 LP '-o' option */ +#define CF_SYSV_FEATURE '5' /* for SVR4 LP features */ +#define CF_SYSV_FORM 'f' /* for SVR4 Forms */ +#define CF_SYSV_HANDLING 'H' /* for SVR4 Handling */ +#define CF_SYSV_NOTIFICATION 'p' /* for SVR4 Notification */ +#define CF_SYSV_PAGES 'P' /* for SVR4 Pages */ +#define CF_SYSV_PRIORITY 'q' /* for SVR4 Priority */ +#define CF_SYSV_CHARSET 'S' /* for SVR4 Charset */ +#define CF_SYSV_TYPE 'T' /* for SVR4 Type */ +#define CF_SYSV_MODE 'y' /* for SVR4 Mode */ + + +typedef struct _jobfile jobfile_t; +typedef struct _job job_t; + +struct _jobfile { + char *jf_spl_path; /* df file */ + char *jf_src_path; /* source file */ + char *jf_name; /* title/name */ + char *jf_data; /* ptr to mmapped file */ + long jf_size; /* size of data */ + char jf_mmapped; /* is this mmapped or malloced */ +}; + +struct _job { + int job_id; + char *job_printer; + char *job_server; + char *job_user; + char *job_host; + char *job_spool_dir; + jobfile_t *job_cf; + char job_df_next; + jobfile_t **job_df_list; +}; + + +extern int job_store(job_t *job); +extern void job_free(job_t *job); +extern void job_destroy(job_t *job); +extern job_t *job_retrieve(char *xfer_file, char *spool); +extern job_t **job_list_append(job_t **list, char *printer, + char *server, char *spool); +extern int vjob_match_attribute(char *attribute, __va_list ap); +extern int vjob_cancel(job_t *job, __va_list ap); + +#ifdef __cplusplus +} +#endif + +#endif /* !_JOB_H */ diff --git a/usr/src/lib/print/list.c b/usr/src/lib/print/libprint/common/list.c index 1ca4b79f9c..fd90e58130 100644 --- a/usr/src/lib/print/list.c +++ b/usr/src/lib/print/libprint/common/list.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1994, 1995, 1996, 1998 by Sun Microsystems, Inc. - * All Rights Reserved + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -37,7 +36,7 @@ #include <stdlib.h> #include <strings.h> -#include <print/list.h> +#include <list.h> static int _list_increment = 64; /* just so It can be tuned with adb(1) */ diff --git a/usr/src/lib/print/list.h b/usr/src/lib/print/libprint/common/list.h index d9e83bfa3c..cb9b62df78 100644 --- a/usr/src/lib/print/list.h +++ b/usr/src/lib/print/libprint/common/list.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,12 +19,12 @@ * CDDL HEADER END */ /* - * Copyright (c) 1998 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #ifndef _LIST_H -#define _LIST_H +#define _LIST_H #pragma ident "%Z%%M% %I% %E% SMI" diff --git a/usr/src/lib/print/llib-lprint b/usr/src/lib/print/libprint/common/llib-lprint index 2dc1ad9911..6d89824e36 100644 --- a/usr/src/lib/print/llib-lprint +++ b/usr/src/lib/print/libprint/common/llib-lprint @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -78,11 +77,6 @@ struct _job { jobfile_t **job_df_list; }; -int job_primative(job_t *job, char option, char *value); -int job_svr4_primative(job_t *job, char option, char *value); -int job_add_data_file(job_t *job, char *path, char *title, - char type, int copies, int linked, - int delete); int job_store(job_t *job); void job_free(job_t *job); void job_destroy(job_t *job); @@ -102,8 +96,6 @@ void * list_locate(void **, int (*)(void *, void *), void *); int list_iterate(void **, int (*)(void *, __va_list), ...); char * get_user_name(void); -char *long_date(void); -char *short_date(void); int check_client_spool(char *printer); int get_lock(char *name, int write_pid); uid_t get_user_id(void); diff --git a/usr/src/lib/print/mapfile-vers b/usr/src/lib/print/libprint/common/mapfile-vers index 0c1168eaa2..8cf667fb92 100644 --- a/usr/src/lib/print/mapfile-vers +++ b/usr/src/lib/print/libprint/common/mapfile-vers @@ -1,15 +1,9 @@ # -#ident "%Z%%M% %I% %E% SMI" -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -24,6 +18,12 @@ # # CDDL HEADER END # +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# # Generic interface definition for usr/src/lib/print. # # For information regarding the establishment of versioned definitions see: @@ -72,13 +72,8 @@ SUNWprivate_2.1 { list_locate; list_iterate; - job_primative; # job support - job_svr4_primative; - job_add_data_file; - job_store; - job_free; + job_free; # job support job_destroy; - job_create; job_retrieve; job_list_append; vjob_match_attribute; @@ -94,9 +89,7 @@ SUNWprivate_2.1 { net_response; net_send_file; - long_date; # misc support - short_date; - check_client_spool; + check_client_spool; # misc support get_lock; get_user_id; get_user_name; @@ -108,7 +101,6 @@ SUNWprivate_2.1 { map_in_file; write_buffer; start_daemon; - kill_process; files_put_printer; # required for ns_put_printer() nis_put_printer; diff --git a/usr/src/lib/print/misc.c b/usr/src/lib/print/libprint/common/misc.c index 5985766203..f9d7e4e966 100644 --- a/usr/src/lib/print/misc.c +++ b/usr/src/lib/print/libprint/common/misc.c @@ -41,39 +41,11 @@ #include <syslog.h> #include <errno.h> -#include <print/misc.h> -#include <print/job.h> -#include <print/list.h> +#include <misc.h> +#include <job.h> +#include <list.h> -char * -long_date() -{ - static char longDate[64]; - time_t curr; - struct tm *tm; - - memset(longDate, 0, sizeof (longDate)); - (void) time(&curr); - if ((tm = localtime(&curr)) != NULL) - (void) strftime(longDate, sizeof (longDate), "%b %d %R %Y", tm); - return (longDate); -} - -char * -short_date() -{ - static char shortDate[64]; - time_t curr; - struct tm *tm; - - memset(shortDate, 0, sizeof (shortDate)); - (void) time(&curr); - if ((tm = localtime(&curr)) != NULL) - (void) strftime(shortDate, sizeof (shortDate), "%b %d %R", tm); - return (shortDate); -} - /* * info about spool directory that we validate and fix */ @@ -390,7 +362,7 @@ start_daemon(int do_fork) if (lock < 0) return; if (do_fork == 0) { - (void) execle("/usr/bin/lp", MASTER_NAME, NULL, NULL); + (void) execle("/usr/lib/print/printd", MASTER_NAME, NULL, NULL); syslog(LOG_ERR, "start_daemon() - execl: %m"); exit(-1); } else @@ -402,7 +374,8 @@ start_daemon(int do_fork) case 0: break; default: - (void) execl("/usr/bin/lp", MASTER_NAME, NULL); + (void) execl("/usr/lib/print/printd", MASTER_NAME, + NULL); syslog(LOG_ERR, "start_daemon() - execl: %m"); exit(-1); /* NOTREACHED */ diff --git a/usr/src/lib/print/misc.h b/usr/src/lib/print/libprint/common/misc.h index 0e3165e51b..5821794557 100644 --- a/usr/src/lib/print/misc.h +++ b/usr/src/lib/print/libprint/common/misc.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 1998-2002 by Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -34,27 +33,25 @@ extern "C" { #endif /* Protocol Defined Requests */ -#define PRINT_REQUEST 1 /* \1printer\n */ -#define XFER_REQUEST 2 /* \2printer\n */ -#define XFER_CLEANUP 1 /* \1 */ -#define XFER_CONTROL 2 /* \2size name\n */ -#define XFER_DATA 3 /* \3size name\n */ +#define PRINT_REQUEST 1 /* \1printer\n */ +#define XFER_REQUEST 2 /* \2printer\n */ +#define XFER_CLEANUP 1 /* \1 */ +#define XFER_CONTROL 2 /* \2size name\n */ +#define XFER_DATA 3 /* \3size name\n */ -#define SHOW_QUEUE_SHORT_REQUEST 3 /* \3printer [users|jobs ...]\n */ -#define SHOW_QUEUE_LONG_REQUEST 4 /* \4printer [users|jobs ...]\n */ -#define REMOVE_REQUEST 5 /* \5printer person [users|jobs ...]\n */ +#define SHOW_QUEUE_SHORT_REQUEST 3 /* \3printer [users|jobs ...]\n */ +#define SHOW_QUEUE_LONG_REQUEST 4 /* \4printer [users|jobs ...]\n */ +#define REMOVE_REQUEST 5 /* \5printer person [users|jobs ...]\n */ -#define ACK_BYTE 0 -#define NACK_BYTE 1 +#define ACK_BYTE 0 +#define NACK_BYTE 1 -#define MASTER_NAME "printd" -#define MASTER_LOCK "/var/spool/print/.printd.lock" -#define SPOOL_DIR "/var/spool/print" -#define TBL_NAME "printers.conf" +#define MASTER_NAME "printd" +#define MASTER_LOCK "/var/spool/print/.printd.lock" +#define SPOOL_DIR "/var/spool/print" +#define TBL_NAME "printers.conf" -extern char *long_date(); -extern char *short_date(); extern int check_client_spool(char *printer); extern int get_lock(char *name, int write_pid); extern uid_t get_user_id(); @@ -73,4 +70,4 @@ extern int kill_process(char *file); } #endif -#endif /* _MISC_H */ +#endif /* _MISC_H */ diff --git a/usr/src/lib/print/network.c b/usr/src/lib/print/libprint/common/network.c index 6358e0d44f..109b44a7d5 100644 --- a/usr/src/lib/print/network.c +++ b/usr/src/lib/print/libprint/common/network.c @@ -45,8 +45,8 @@ #include <syslog.h> #include <sys/utsname.h> -#include <print/network.h> -#include <print/misc.h> +#include <network.h> +#include <misc.h> static int read_wait_time_sec = 60; static int write_wait_time_sec = 10; diff --git a/usr/src/lib/print/network.h b/usr/src/lib/print/libprint/common/network.h index 15a92301c0..ee88e421d0 100644 --- a/usr/src/lib/print/network.h +++ b/usr/src/lib/print/libprint/common/network.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,12 +19,12 @@ * CDDL HEADER END */ /* - * Copyright (c) 1998 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #ifndef _NETWORK_H -#define _NETWORK_H +#define _NETWORK_H #pragma ident "%Z%%M% %I% %E% SMI" diff --git a/usr/src/lib/print/ns.c b/usr/src/lib/print/libprint/common/ns.c index 7b4ec92f8b..fd0a54bd33 100644 --- a/usr/src/lib/print/ns.c +++ b/usr/src/lib/print/libprint/common/ns.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 1994-2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -38,9 +37,9 @@ #include <nss_dbdefs.h> #include <syslog.h> -#include <print/ns.h> -#include <print/list.h> -#include <print/misc.h> +#include <ns.h> +#include <list.h> +#include <misc.h> /* diff --git a/usr/src/lib/print/ns.h b/usr/src/lib/print/libprint/common/ns.h index 6614e3fad2..6614e3fad2 100644 --- a/usr/src/lib/print/ns.h +++ b/usr/src/lib/print/libprint/common/ns.h diff --git a/usr/src/lib/print/ns_bsd_addr.c b/usr/src/lib/print/libprint/common/ns_bsd_addr.c index 43d1b7d671..c908d4375c 100644 --- a/usr/src/lib/print/ns_bsd_addr.c +++ b/usr/src/lib/print/libprint/common/ns_bsd_addr.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 1994-2002 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -36,9 +35,9 @@ #include <string.h> #include <syslog.h> -#include <print/ns.h> -#include <print/list.h> -#include <print/misc.h> +#include <ns.h> +#include <list.h> +#include <misc.h> /* * Manipulate bsd_addr structures diff --git a/usr/src/lib/print/ns_cmn_kvp.c b/usr/src/lib/print/libprint/common/ns_cmn_kvp.c index dd6f30c870..3fdacd7e5d 100644 --- a/usr/src/lib/print/ns_cmn_kvp.c +++ b/usr/src/lib/print/libprint/common/ns_cmn_kvp.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 1994-2002 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -35,8 +34,8 @@ #include <stdarg.h> #include <string.h> -#include <print/ns.h> -#include <print/list.h> +#include <ns.h> +#include <list.h> /* * Commonly Used routines... diff --git a/usr/src/lib/print/ns_cmn_printer.c b/usr/src/lib/print/libprint/common/ns_cmn_printer.c index a6a8a89ae4..25e344b3c4 100644 --- a/usr/src/lib/print/ns_cmn_printer.c +++ b/usr/src/lib/print/libprint/common/ns_cmn_printer.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 1994-2002 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -36,8 +35,8 @@ #include <string.h> #include <syslog.h> -#include <print/ns.h> -#include <print/list.h> +#include <ns.h> +#include <list.h> extern void ns_kvp_destroy(ns_kvp_t *); diff --git a/usr/src/lib/print/nss_convert.c b/usr/src/lib/print/libprint/common/nss_convert.c index e7e29294c1..fae5610b98 100644 --- a/usr/src/lib/print/nss_convert.c +++ b/usr/src/lib/print/libprint/common/nss_convert.c @@ -38,9 +38,9 @@ #include <stdarg.h> #include <syslog.h> -#include <print/ns.h> -#include <print/list.h> -#include <print/misc.h> +#include <ns.h> +#include <list.h> +#include <misc.h> #define ESCAPE_CHARS "\\\n=:" /* \, \n, =, : */ diff --git a/usr/src/lib/print/nss_ldap.c b/usr/src/lib/print/libprint/common/nss_ldap.c index 661eef9396..887babc740 100644 --- a/usr/src/lib/print/nss_ldap.c +++ b/usr/src/lib/print/libprint/common/nss_ldap.c @@ -39,9 +39,9 @@ #include <libintl.h> #include <netdb.h> /* for rcmd() */ -#include <print/ns.h> -#include <print/list.h> -#include <print/misc.h> +#include <ns.h> +#include <list.h> +#include <misc.h> #define LDAP_REFERRALS #include <lber.h> diff --git a/usr/src/lib/print/nss_printer.c b/usr/src/lib/print/libprint/common/nss_printer.c index 95a774ff2e..326ba9699e 100644 --- a/usr/src/lib/print/nss_printer.c +++ b/usr/src/lib/print/libprint/common/nss_printer.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (C) 1998 by Sun Microsystems, Inc - * All Rights Reserved + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" diff --git a/usr/src/lib/print/nss_write.c b/usr/src/lib/print/libprint/common/nss_write.c index 8637919e9a..77f894be5a 100644 --- a/usr/src/lib/print/nss_write.c +++ b/usr/src/lib/print/libprint/common/nss_write.c @@ -39,9 +39,9 @@ #include <libintl.h> #include <netdb.h> /* for rcmd() */ -#include <print/ns.h> -#include <print/list.h> -#include <print/misc.h> +#include <ns.h> +#include <list.h> +#include <misc.h> /* escaped chars include delimiters and shell meta characters */ #define ESCAPE_CHARS "\\\n=: `&;|>^$()<*?[" diff --git a/usr/src/lib/print/sunPrinter.at.conf.txt b/usr/src/lib/print/libprint/common/sunPrinter.at.conf.txt index 0cac14ae95..0cac14ae95 100644 --- a/usr/src/lib/print/sunPrinter.at.conf.txt +++ b/usr/src/lib/print/libprint/common/sunPrinter.at.conf.txt diff --git a/usr/src/lib/print/sunPrinter.oc.conf.txt b/usr/src/lib/print/libprint/common/sunPrinter.oc.conf.txt index 77f365819d..77f365819d 100644 --- a/usr/src/lib/print/sunPrinter.oc.conf.txt +++ b/usr/src/lib/print/libprint/common/sunPrinter.oc.conf.txt diff --git a/usr/src/lib/print/libprint/i386/Makefile b/usr/src/lib/print/libprint/i386/Makefile new file mode 100644 index 0000000000..3b985583a4 --- /dev/null +++ b/usr/src/lib/print/libprint/i386/Makefile @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT) diff --git a/usr/src/lib/print/libprint/sparc/Makefile b/usr/src/lib/print/libprint/sparc/Makefile new file mode 100644 index 0000000000..3b985583a4 --- /dev/null +++ b/usr/src/lib/print/libprint/sparc/Makefile @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT) diff --git a/usr/src/lib/print/mod_ipp/Makefile b/usr/src/lib/print/mod_ipp/Makefile new file mode 100644 index 0000000000..8531fb213f --- /dev/null +++ b/usr/src/lib/print/mod_ipp/Makefile @@ -0,0 +1,100 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +LIBRARY = mod_ipp.a +VERS = +OBJECTS = mod_ipp.o + +include ../../Makefile.lib +include ../../Makefile.rootfs + +APACHEMODDIR = $(ROOT)/usr/apache/libexec +APACHECONFDIR = $(ROOT)/etc/apache +LISTENERDIR = $(ROOT)/var/lp/ipp-listener + +ROOTDIRS = $(ROOT)/usr/apache $(APACHEMODDIR) $(APACHECONFDIR) \ + $(ROOT)/var/lp $(LISTENERDIR) + +$(ROOT)/var/lp:= DIRMODE = 775 +$(ROOT)/var/lp:= FILEMODE = 775 +$(ROOT)/var/lp:= OWNER = lp +$(ROOT)/var/lp:= GROUP = lp + +LIBS = $(DYNLIB) + +SRCS = $(OBJECTS:%.o = %.c) + +MMAPFILE = mapfile + +CFLAGS += $(CCVERBOSE) +CPPFLAGS += -I../libipp-listener/common +CPPFLAGS += -I../libipp-core/common +CPPFLAGS += -I/usr/apache/include +CPPFLAGS += -DEAPI +ZDEFS = $(ZNODEFS) +DYNFLAGS += -M$(MMAPFILE) +LDLIBS += -lipp-listener -lipp-core -lpapi -lc + +# SMF manifest +MANIFEST= ipp-listener.xml +ROOTMANIFESTDIR= $(ROOT)/var/svc/manifest/application/print +ROOTMANIFEST= $(MANIFEST:%=$(ROOTMANIFESTDIR)/%) +$(ROOTMANIFEST) := FILEMODE= 444 + +# Apache module +$(APACHEMODDIR)/$(LIBLINKS): $(ROOTDIRS) + +# Apache config +APACHECONFFILE= $(APACHECONFDIR)/httpd-standalone-ipp.conf +$(APACHECONFFILE) := FILEMODE= 644 +LISTENERFILE= $(LISTENERDIR)/index.html +$(LISTENERFILE) := FILEMODE= 444 + +$(ROOT)/var/lp:= OWNER = lp +$(ROOT)/var/lp:= GROUP = lp +$(ROOT)/var/lp:= FILEMODE = 0775 + +$(APACHEMODDIR)/$(LIBLINKS):= FILEMODE = 0555 + +$(ROOTMANIFESTDIR)/% $(APACHEMODDIR)/% $(APACHECONFDIR)/% $(LISTENERDIR)/%: % + $(INS.file) + +$(ROOTDIRS): + $(INS.dir) + +.KEEP_STATE: + +all: $(LIBS) + +install: all $(APACHEMODDIR)/$(LIBLINKS) $(APACHECONFFILE) \ + $(LISTENERFILE) $(ROOTMANIFEST) + +install_h: + +lint: + +include ../../Makefile.targ diff --git a/usr/src/lib/print/mod_ipp/httpd-standalone-ipp.conf b/usr/src/lib/print/mod_ipp/httpd-standalone-ipp.conf new file mode 100644 index 0000000000..07a4b8dc11 --- /dev/null +++ b/usr/src/lib/print/mod_ipp/httpd-standalone-ipp.conf @@ -0,0 +1,341 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# "$Id: httpd-standalone-ipp.conf,v 1.4 2006/03/24 00:26:54 njacobs Exp $" +# + +# ident "%Z%%M% %I% %E% SMI" + +## +## httpd-standalone-ipp.conf -- Apache HTTP server configuration file for +## an Internet Print Protocol (IPP) listener +## + +# +# Based upon the NCSA server configuration files originally by Rob McCool. +# +# This is the main Apache server configuration file. It contains the +# configuration directives that give the server its instructions. +# See <URL:http://www.apache.org/docs/> for detailed information about +# the directives. mod_ipp specific directives are described in the +# mod_ipp(4) man page. +# + +### Section 1: Global Environment +# +# The directives in this section affect the overall operation of Apache, +# such as the number of concurrent requests it can handle or where it +# can find its configuration files. +# + +# +# ServerType is either inetd, or standalone. Inetd mode is only supported on +# Unix platforms. +# +ServerType standalone + +# +# ServerRoot: The top of the directory tree under which the server's +# configuration, error, and log files are kept. +# +# NOTE! If you intend to place this on an NFS (or otherwise network) +# mounted filesystem then please read the LockFile documentation +# (available at <URL:http://www.apache.org/docs/mod/core.html#lockfile>); +# you will save yourself a lot of trouble. +# +ServerRoot "/usr/apache" + +# +# The LockFile directive sets the path to the lockfile used when Apache +# is compiled with either USE_FCNTL_SERIALIZED_ACCEPT or +# USE_FLOCK_SERIALIZED_ACCEPT. This directive should normally be left at +# its default value. The main reason for changing it is if the logs +# directory is NFS mounted, since the lockfile MUST BE STORED ON A LOCAL +# DISK. The PID of the main server process is automatically appended to +# the filename. +# +#LockFile /var/run/httpd.lock +LockFile /var/run/httpd-standalone-ipp.lock + +# +# PidFile: The file in which the server should record its process +# identification number when it starts. +# +PidFile /var/run/httpd-standalone-ipp.pid + +# +# ScoreBoardFile: File used to store internal server process information. +# Not all architectures require this. But if yours does (you'll know because +# this file will be created when you run Apache) then you *must* ensure that +# no two invocations of Apache share the same scoreboard file. +# +ScoreBoardFile /var/run/httpd-standalone-ipp.scoreboard + +# +# In the standard configuration, the server will process httpd.conf (this +# file, specified by the -f command line option), srm.conf, and access.conf +# in that order. The latter two files are now distributed empty, as it is +# recommended that all directives be kept in a single file for simplicity. +# The commented-out values below are the built-in defaults. You can have the +# server ignore these files altogether by using "/dev/null" (for Unix) or +# "nul" (for Win32) for the arguments to the directives. +# +#ResourceConfig conf/srm.conf +#AccessConfig conf/access.conf + +# +# Timeout: The number of seconds before receives and sends time out. +# +Timeout 300 + +# +# KeepAlive: Whether or not to allow persistent connections (more than +# one request per connection). Set to "Off" to deactivate. +# +KeepAlive On + +# +# MaxKeepAliveRequests: The maximum number of requests to allow +# during a persistent connection. Set to 0 to allow an unlimited amount. +# We recommend you leave this number high, for maximum performance. +# +MaxKeepAliveRequests 100 + +# +# KeepAliveTimeout: Number of seconds to wait for the next request from the +# same client on the same connection. +# +KeepAliveTimeout 15 + +# +# Server-pool size regulation. Rather than making you guess how many +# server processes you need, Apache dynamically adapts to the load it +# sees --- that is, it tries to maintain enough server processes to +# handle the current load, plus a few spare servers to handle transient +# load spikes (e.g., multiple simultaneous requests from a single +# Netscape browser). +# +# It does this by periodically checking how many servers are waiting +# for a request. If there are fewer than MinSpareServers, it creates +# a new spare. If there are more than MaxSpareServers, some of the +# spares die off. The default values are probably OK for most sites. +# +MinSpareServers 1 +MaxSpareServers 2 + +# +# Number of servers to start initially --- should be a reasonable ballpark +# figure. +# +StartServers 1 + +# +# Limit on total number of servers running, i.e., limit on the number +# of clients who can simultaneously connect --- if this limit is ever +# reached, clients will be LOCKED OUT, so it should NOT BE SET TOO LOW. +# It is intended mainly as a brake to keep a runaway server from taking +# the system with it as it spirals down... +# +MaxClients 150 + +# +# MaxRequestsPerChild: the number of requests each child process is +# allowed to process before the child dies. The child will exit so +# as to avoid problems after prolonged use when Apache (and maybe the +# libraries it uses) leak memory or other resources. On most systems, this +# isn't really needed, but a few (such as Solaris) do have notable leaks +# in the libraries. For these platforms, set to something like 10000 +# or so; a setting of 0 means unlimited. +# +# NOTE: This value does not include keepalive requests after the initial +# request per connection. For example, if a child process handles +# an initial request and 10 subsequent "keptalive" requests, it +# would only count as 1 request towards this limit. +# +MaxRequestsPerChild 10 + +# +# Dynamic Shared Object (DSO) Support +# +# To be able to use the functionality of a module which was built as a DSO you +# have to place corresponding `LoadModule' lines at this location so the +# directives contained in it are actually available _before_ they are used. +# Please read the file http://httpd.apache.org/docs/dso.html for more +# details about the DSO mechanism and run `httpd -l' for the list of already +# built-in (statically linked and thus always available) modules in your httpd +# binary. +# +# Note: The order in which modules are loaded is important. Don't change +# the order below without expert advice. +# +LoadModule access_module libexec/mod_access.so +LoadModule alias_module libexec/mod_alias.so +LoadModule auth_module libexec/mod_auth.so +LoadModule mime_module libexec/mod_mime.so +LoadModule mime_magic_module libexec/mod_mime_magic.so +LoadModule ipp_module libexec/mod_ipp.so + +# Reconstruction of the complete module list from all available modules +# (static and shared ones) to achieve correct module execution order. +# [WHENEVER YOU CHANGE THE LOADMODULE SECTION ABOVE UPDATE THIS, TOO] +ClearModuleList +AddModule mod_access.c +AddModule mod_alias.c +AddModule mod_auth.c +AddModule mod_mime.c +AddModule mod_mime_magic.c +AddModule mod_ipp.c +AddModule mod_so.c + +### Section 2: 'Main' server configuration +# +# The directives in this section set up the values used by the 'main' +# server, which responds to any requests that aren't handled by a +# <VirtualHost> definition. These values also provide defaults for +# any <VirtualHost> containers you may define later in the file. +# +# All of these directives may appear inside <VirtualHost> containers, +# in which case these default settings will be overridden for the +# virtual host being defined. +# + +# +# If your ServerType directive (set earlier in the 'Global Environment' +# section) is set to "inetd", the next few directives don't have any +# effect since their settings are defined by the inetd configuration. +# Skip ahead to the ServerAdmin directive. +# + +# +# Port: The port to which the standalone server listens. For +# ports < 1023, you will need httpd to be run as root initially. +# +Port 631 + +# +# If you wish httpd to run as a different user or group, you must run +# httpd as root initially and it will switch. +# +# User/Group: The name (or #number) of the user/group to run httpd as. +# . On SCO (ODT 3) use "User nouser" and "Group nogroup". +# . On HPUX you may not be able to use shared memory as nobody, and the +# suggested workaround is to create a user www and use that user. +# NOTE that some kernels refuse to setgid(Group) or semctl(IPC_SET) +# when the value of (unsigned)Group is above 60000; +# don't use Group nobody on these systems! +# +User lp +Group lp + +# +# ServerAdmin: Your address, where problems with the server should be +# e-mailed. This address appears on some server-generated pages, such +# as error documents. +# +ServerAdmin lp@localhost + +# +# ServerName allows you to set a host name which is sent back to clients for +# your server if it's different than the one the program would get (i.e., use +# "www" instead of the host's real name). +# +# Note: You cannot just invent host names and hope they work. The name you +# define here must be a valid DNS name for your host. If you don't understand +# this, ask your network administrator. +# If your host doesn't have a registered DNS name, enter its IP address here. +# You will have to access it by its address (e.g., http://123.45.67.89/) +# anyway, and this will make redirections work in a sensible way. +# +# 127.0.0.1 is the TCP/IP local loop-back address, often named localhost. Your +# machine always knows itself by this address. If you use Apache strictly for +# local testing and development, you may use 127.0.0.1 as the server name. +# +#Servername printserver.some_company.com + +DefaultType application/ipp + +ErrorLog /var/lp/logs/ipp-errors +LogLevel warn + +DocumentRoot /var/lp/ipp-listener + +# Allow passing PPD files from this service as well +Alias /etc/lp/ppd/ /etc/lp/ppd/ +<Directory /etc/lp/ppd> + SetHandler send-as-is + <LimitExcept GET> + Deny from all + </LimitExcept> +</Directory> + +# mod_ipp specific configuration +<IfModule mod_ipp.c> + + <Location /> + # ipp-conformance automatic # default + # ipp-default-user nobody + ipp-default-service lpsched + # + # By default, only turn on operations that are not + # likely to cause real problems when the user can't + # be trusted. + # + ipp-operation all off + ipp-operation print-job on + ipp-operation validate-job on + ipp-operation create-job on + ipp-operation get-jobs on + ipp-operation get-printer-attributes on + ipp-operation send-document on + ipp-operation cancel-job on + ipp-operation get-job-attributes on + ipp-operation cups-get-default on + ipp-operation cups-get-printers on + ipp-operation cups-get-classes on + ipp-operation cups-move-job on + + # redirect non-IPP requests + ErrorDocument 404 /index.html + </Location> + + <Location /admin> + # ipp-conformance automatic # default + # ipp-default-user nobody + ipp-default-service lpsched + + ipp-operation all on + + AuthType Basic + AuthName "IPP Server" + AuthUserFile /etc/ipp-users + Require valid-user + + # redirect non-IPP requests + ErrorDocument 404 /index.html + </Location> +</IfModule> + diff --git a/usr/src/lib/print/mod_ipp/index.html b/usr/src/lib/print/mod_ipp/index.html new file mode 100644 index 0000000000..15f680c666 --- /dev/null +++ b/usr/src/lib/print/mod_ipp/index.html @@ -0,0 +1,44 @@ +<!-- + + CDDL HEADER START + + The contents of this file are subject to the terms of the + Common Development and Distribution License (the "License"). + You may not use this file except in compliance with the License. + + You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + or http://www.opensolaris.org/os/licensing. + See the License for the specific language governing permissions + and limitations under the License. + + When distributing Covered Code, include this CDDL HEADER in each + file and include the License file at usr/src/OPENSOLARIS.LICENSE. + If applicable, add the following below this CDDL HEADER, with the + fields enclosed by brackets "[]" replaced with your own identifying + information: Portions Copyright [yyyy] [name of copyright owner] + + CDDL HEADER END + + + Copyright 2006 Sun Microsystems, Inc. All rights reserved. + Use is subject to license terms. + + ident "%Z%%M% %I% %E% SMI" +--> +<html> +<body> +The Internet Print Protocol (IPP) requires that all protocol requests be +encapsulated in HTTP and that all HTTP protocol requests be POST requests with +a Content-Type of "application/ipp". Since your request did not meet this +criteria, it has been ignored by the IPP listener. You will be redirected to +the +<a href=http://docs.sun.com/db?q=%22Internet+Print+Protocol%22&p=prod%2Fsolaris> +<b>Solaris®</b> AnswerBook +</a> +so that you can learn more about the Internet Print Protocol Listener. +<p> +If you would like more information about the Internet Print Protocol itself, +please visit <a href=http://www.pwg.org/ipp>http://www.pwg.org/ipp/</a>. +</body> +</html> +<meta HTTP-EQUIV=REFRESH CONTENT=10;URL=http://docs.sun.com/db?q=%22Internet+Print+Protocol%22&p=prod%2Fsolaris> diff --git a/usr/src/lib/print/mod_ipp/ipp-listener.xml b/usr/src/lib/print/mod_ipp/ipp-listener.xml new file mode 100644 index 0000000000..5f45219775 --- /dev/null +++ b/usr/src/lib/print/mod_ipp/ipp-listener.xml @@ -0,0 +1,73 @@ +<?xml version="1.0"?> +<!-- +CDDL HEADER START + +The contents of this file are subject to the terms of the +Common Development and Distribution License (the "License"). +You may not use this file except in compliance with the License. + +You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +or http://www.opensolaris.org/os/licensing. +See the License for the specific language governing permissions +and limitations under the License. + +When distributing Covered Code, include this CDDL HEADER in each +file and include the License file at usr/src/OPENSOLARIS.LICENSE. +If applicable, add the following below this CDDL HEADER, with the +fields enclosed by brackets "[]" replaced with your own identifying +information: Portions Copyright [yyyy] [name of copyright owner] + +CDDL HEADER END +--> +<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1"> +<!-- + Copyright 2006 Sun Microsystems, Inc. All rights reserved. + Use is subject to license terms. + + pragma ident "%Z%%M% %I% %E% SMI" +--> + +<service_bundle type='manifest' name='SUNWipplr:ipp-listener'> + +<service + name='application/print/ipp-listener' + type='service' + version='1'> + + <dependency name='print-service' + grouping='require_any' + restart_on='refresh' + type='service'> + <service_fmri value='svc:/application/print/server' /> + </dependency> + + <exec_method + type='method' + name='start' + exec='/usr/apache/bin/httpd -f /etc/apache/httpd-standalone-ipp.conf' + timeout_seconds='10' /> + + <exec_method + type='method' + name='stop' + exec='/bin/pkill -f httpd-standalone-ipp.conf' + timeout_seconds='5' /> + + <instance name='default' enabled='true' /> + + <stability value='Unstable' /> + + <template> + <common_name> + <loctext xml:lang='C'> + Internet Print Protocol Listening Service + </loctext> + </common_name> + <documentation> + <manpage title='mod_ipp' section='4' + manpath='/usr/share/man' /> + </documentation> + </template> +</service> + +</service_bundle> diff --git a/usr/src/lib/print/mod_ipp/mapfile b/usr/src/lib/print/mod_ipp/mapfile new file mode 100644 index 0000000000..d9db50bca9 --- /dev/null +++ b/usr/src/lib/print/mod_ipp/mapfile @@ -0,0 +1,39 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# $Id: mapfile 149 2006-04-25 16:55:01Z njacobs $ +# + +# ident "%Z%%M% %I% %E% SMI" + +SUNWprivate_1.0 { + global: + ipp_module; + + local: + *; +}; diff --git a/usr/src/lib/print/mod_ipp/mod_ipp.c b/usr/src/lib/print/mod_ipp/mod_ipp.c new file mode 100644 index 0000000000..2d9ece2287 --- /dev/null +++ b/usr/src/lib/print/mod_ipp/mod_ipp.c @@ -0,0 +1,552 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: mod_ipp.c 149 2006-04-25 16:55:01Z njacobs $ */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Internet Printing Protocol (IPP) module for Apache. + */ + +#include "ap_config.h" + +#include <stdio.h> +#include <time.h> +#include <sys/time.h> +#include <values.h> +#include <libintl.h> +#include <alloca.h> + +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_protocol.h" +#include "http_log.h" +#include "http_main.h" +#include "papi.h" +#ifndef APACHE_RELEASE /* appears to only exist in Apache 1.X */ +#define APACHE2 +#include "apr_compat.h" +#endif + +#include <papi.h> +#include <ipp-listener.h> + +#ifndef APACHE2 +module MODULE_VAR_EXPORT ipp_module; +#else +module AP_MODULE_DECLARE_DATA ipp_module; +#endif + +#ifndef AP_INIT_TAKE1 /* Apache 2.X has this, but 1.3.X does not */ +#define AP_INIT_NO_ARGS(directive, action, arg, where, mesg) \ + { directive, action, arg, where, NO_ARGS, mesg } +#define AP_INIT_TAKE1(directive, action, arg, where, mesg) \ + { directive, action, arg, where, TAKE1, mesg } +#define AP_INIT_TAKE2(directive, action, arg, where, mesg) \ + { directive, action, arg, where, TAKE2, mesg } +#endif + +typedef struct { + int conformance; + char *default_user; + char *default_svc; + papi_attribute_t **operations; +} IPPListenerConfig; + +#ifdef DEBUG +void +dump_buffer(FILE *fp, char *tag, char *buffer, int bytes) +{ + int i, j, ch; + + fprintf(fp, "%s %d(0x%x) bytes\n", (tag ? tag : ""), bytes, bytes); + for (i = 0; i < bytes; i += 16) { + fprintf(fp, "%s ", (tag ? tag : "")); + + for (j = 0; j < 16 && (i + j) < bytes; j ++) + fprintf(fp, " %02X", buffer[i + j] & 255); + + while (j < 16) { + fprintf(fp, " "); + j++; + } + + fprintf(fp, " "); + for (j = 0; j < 16 && (i + j) < bytes; j ++) { + ch = buffer[i + j] & 255; + if (ch < ' ' || ch == 127) + ch = '.'; + putc(ch, fp); + } + putc('\n', fp); + } + fflush(fp); +} +#endif + +static ssize_t +read_data(void *fd, void *buf, size_t siz) +{ + ssize_t len_read; + request_rec *ap_r = (request_rec *)fd; + + len_read = ap_get_client_block(ap_r, buf, siz); +#ifndef APACHE2 + ap_reset_timeout(ap_r); +#endif + +#ifdef DEBUG + fprintf(stderr, "read_data(0x%8.8x, 0x%8.8x, %d): %d", + fd, buf, siz, len_read); + if (len_read < 0) + fprintf(stderr, ": %s", strerror(errno)); + putc('\n', stderr); + dump_buffer(stderr, "read_data:", buf, len_read); +#endif + + return (len_read); +} + +static ssize_t +write_data(void *fd, void *buf, size_t siz) +{ + ssize_t len_written; + request_rec *ap_r = (request_rec *)fd; + +#ifndef APACHE2 + ap_reset_timeout(ap_r); +#endif +#ifdef DEBUG + dump_buffer(stderr, "write_data:", buf, siz); +#endif + len_written = ap_rwrite(buf, siz, ap_r); + + return (len_written); +} + +static void +discard_data(request_rec *r) +{ +#ifdef APACHE2 + (void) ap_discard_request_body(r); +#else + /* + * This is taken from ap_discard_request_body(). The reason we can't + * just use it in Apache 1.3 is that it does various timeout things we + * don't want it to do. Apache 2.0 doesn't do that, so we can safely + * use the normal function. + */ + if (r->read_chunked || r->remaining > 0) { + char dumpbuf[HUGE_STRING_LEN]; + int i; + + do { + i = ap_get_client_block(r, dumpbuf, HUGE_STRING_LEN); +#ifdef DEBUG + dump_buffer(stderr, "discarded", dumpbuf, i); +#endif + } while (i > 0); + } +#endif +} + +void _log_rerror(const char *file, int line, int level, request_rec *r, + const char *fmt, ...) +{ + va_list args; + size_t size; + char *message = alloca(BUFSIZ); + + va_start(args, fmt); + /* + * fill in the message. If the buffer is too small, allocate + * one that is large enough and fill it in. + */ + if ((size = vsnprintf(message, BUFSIZ, fmt, args)) >= BUFSIZ) + if ((message = alloca(size)) != NULL) + vsnprintf(message, size, fmt, args); + va_end(args); + +#ifdef APACHE2 + ap_log_rerror(file, line, level, NULL, r, message); +#else + ap_log_rerror(file, line, level, r, message); +#endif +} + +static int +ipp_handler(request_rec *r) +{ + papi_attribute_t **request = NULL, **response = NULL; + IPPListenerConfig *config; + papi_status_t status; + int ret; + + /* Really, IPP is all POST requests */ + if (r->method_number != M_POST) + return (DECLINED); + +#ifndef APACHE2 + /* + * An IPP request must have a MIME type of "application/ipp" + * (RFC-2910, Section 4, page 19). If it doesn't match this + * MIME type, we should decline the request and let someone else + * try and handle it. + */ + if (r->headers_in != NULL) { + char *mime_type = (char *)ap_table_get(r->headers_in, + "Content-Type"); + + if ((mime_type == NULL) || + (strcasecmp(mime_type, "application/ipp") != 0)) + return (DECLINED); + } +#endif + /* CHUNKED_DECHUNK might not work right for IPP? */ + if ((ret = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)) != OK) + return (ret); + + if (!ap_should_client_block(r)) + return (HTTP_INTERNAL_SERVER_ERROR); + +#ifndef APACHE2 + ap_soft_timeout("ipp_module: read/reply request ", r); +#endif + /* read the IPP request off the network */ + status = ipp_read_message(read_data, r, &request, IPP_TYPE_REQUEST); + + if (status != PAPI_OK) + _log_rerror(APLOG_MARK, APLOG_ERR, r, + "read failed: %s\n", papiStatusString(status)); +#ifdef DEBUG + papiAttributeListPrint(stderr, request, "request (%d) ", getpid()); +#endif + + (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL, + "originating-host", (char *) +#ifdef APACHE2 + ap_get_remote_host + (r->connection, r->per_dir_config, REMOTE_NAME, NULL)); +#else + ap_get_remote_host + (r->connection, r->per_dir_config, REMOTE_NAME)); +#endif + + (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL, + "uri-port", ap_get_server_port(r)); + if (r->headers_in != NULL) { + char *host = (char *)ap_table_get(r->headers_in, "Host"); + + if ((host == NULL) || (host[0] == '\0')) + host = (char *)ap_get_server_name(r); + + (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL, + "uri-host", host); + } + (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL, + "uri-path", r->uri); + + config = ap_get_module_config(r->per_dir_config, &ipp_module); + if (config != NULL) { + (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL, + "conformance", config->conformance); + (void) papiAttributeListAddCollection(&request, PAPI_ATTR_EXCL, + "operations", config->operations); + if (config->default_user != NULL) + (void) papiAttributeListAddString(&request, + PAPI_ATTR_EXCL, "default-user", + config->default_user); + if (config->default_svc != NULL) + (void) papiAttributeListAddString(&request, + PAPI_ATTR_EXCL, "default-service", + config->default_svc); + } + + /* + * For Trusted Solaris, pass the fd number of the socket connection + * to the backend so the it can be forwarded to the backend print + * service to retrieve the sensativity label off of a multi-level + * port. + */ + (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL, + "peer-socket", ap_bfileno(r->connection->client, B_RD)); + + /* process the request */ + status = ipp_process_request(request, &response, read_data, r); + if (status != PAPI_OK) { + errno = 0; + _log_rerror(APLOG_MARK, APLOG_ERR, r, + "request failed: %s\n", papiStatusString(status)); + discard_data(r); + } +#ifdef DEBUG + fprintf(stderr, "processing result: %s\n", papiStatusString(status)); + papiAttributeListPrint(stderr, response, "response (%d) ", getpid()); +#endif + + /* + * If the client is using chunking and we have not yet received the + * final "0" sized chunk, we need to discard any data that may + * remain in the post request. + */ + if ((r->read_chunked != 0) && + (ap_table_get(r->headers_in, "Content-Length") == NULL)) + discard_data(r); + + /* write an IPP response back to the network */ + r->content_type = "application/ipp"; + +#ifndef APACHE2 + ap_send_http_header(r); +#endif + + status = ipp_write_message(write_data, r, response); + if (status != PAPI_OK) + _log_rerror(APLOG_MARK, APLOG_ERR, r, + "write failed: %s\n", papiStatusString(status)); +#ifdef DEBUG + fprintf(stderr, "write result: %s\n", papiStatusString(status)); + fflush(stderr); +#endif + + papiAttributeListFree(request); + papiAttributeListFree(response); + +#ifndef APACHE2 + ap_kill_timeout(r); + if (ap_rflush(r) < 0) + _log_rerror(APLOG_MARK, APLOG_ERR, r, + "flush failed, response may not have been sent"); +#endif + + return (OK); +} + + +/*ARGSUSED1*/ +static void * +create_ipp_dir_config( +#ifndef APACHE2 + pool *p, +#else + apr_pool_t *p, +#endif + char *dirspec) +{ + IPPListenerConfig *config = +#ifndef APACHE2 + ap_pcalloc(p, sizeof (*config)); +#else + apr_pcalloc(p, sizeof (*config)); +#endif + + if (config != NULL) { + (void) memset(config, 0, sizeof (*config)); + config->conformance = IPP_PARSE_CONFORMANCE_RASH; + config->default_user = NULL; + config->default_svc = NULL; + (void) ipp_configure_operation(&config->operations, "required", + "enable"); + } + + return (config); +} + +/*ARGSUSED0*/ +static const char * +ipp_conformance(cmd_parms *cmd, void *cfg, const char *arg) +{ + IPPListenerConfig *config = (IPPListenerConfig *)cfg; + + if (strncasecmp(arg, "automatic", 4) == 0) { + config->conformance = IPP_PARSE_CONFORMANCE_RASH; + } else if (strcasecmp(arg, "1.0") == 0) { + config->conformance = IPP_PARSE_CONFORMANCE_LOOSE; + } else if (strcasecmp(arg, "1.1") == 0) { + config->conformance = IPP_PARSE_CONFORMANCE_STRICT; + } else { + return ("unknown conformance, try (automatic/1.0/1.1)"); + } + + return (NULL); +} + +/*ARGSUSED0*/ +static const char * +ipp_operation(cmd_parms *cmd, void *cfg, char *op, char *toggle) +{ + IPPListenerConfig *config = (IPPListenerConfig *)cfg; + papi_status_t status; + + status = ipp_configure_operation(&config->operations, op, toggle); + switch (status) { + case PAPI_OK: + return (NULL); + case PAPI_BAD_ARGUMENT: + return (gettext("internal error (invalid argument)")); + default: + return (papiStatusString(status)); + } + + /* NOTREACHED */ + /* return (gettext("contact your software vendor")); */ +} + +static const char * +ipp_default_user(cmd_parms *cmd, void *cfg, const char *arg) +{ + IPPListenerConfig *config = (IPPListenerConfig *)cfg; + + config->default_user = (char *)arg; + + return (NULL); +} + +static const char * +ipp_default_svc(cmd_parms *cmd, void *cfg, const char *arg) +{ + IPPListenerConfig *config = (IPPListenerConfig *)cfg; + + config->default_svc = (char *)arg; + + return (NULL); +} + +#ifdef DEBUG +/*ARGSUSED0*/ +static const char * +ipp_module_hang(cmd_parms *cmd, void *cfg) +{ + static int i = 1; + + /* wait so we can attach a debugger, assign i = 0, and step through */ + while (i); + + return (NULL); +} +#endif /* DEBUG */ + +static const command_rec ipp_cmds[] = +{ + AP_INIT_TAKE1("ipp-conformance", ipp_conformance, NULL, ACCESS_CONF, + "IPP protocol conformance (loose/strict)"), + AP_INIT_TAKE2("ipp-operation", ipp_operation, NULL, ACCESS_CONF, + "IPP protocol operations to enable/disable)"), + AP_INIT_TAKE1("ipp-default-user", ipp_default_user, NULL, ACCESS_CONF, + "default user for various operations"), + AP_INIT_TAKE1("ipp-default-service", ipp_default_svc, NULL, ACCESS_CONF, + "default service for various operations"), +#ifdef DEBUG + AP_INIT_NO_ARGS("ipp-module-hang", ipp_module_hang, NULL, ACCESS_CONF, + "hang the module until we can attach a debugger (no args)"), +#endif + { NULL } +}; + +#ifdef APACHE2 +/*ARGSUSED0*/ +static const char * +ipp_method(const request_rec *r) +{ + return ("ipp"); +} + +/*ARGSUSED0*/ +static unsigned short +ipp_port(const request_rec *r) +{ + return (631); +} + +/* Dispatch list for API hooks */ +/*ARGSUSED0*/ +static void +ipp_register_hooks(apr_pool_t *p) +{ + static const char * const modules[] = { "mod_dir.c", NULL }; + + /* Need to make sure we don't get directory listings by accident */ + ap_hook_handler(ipp_handler, NULL, modules, APR_HOOK_MIDDLE); + ap_hook_default_port(ipp_port, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_http_method(ipp_method, NULL, NULL, APR_HOOK_MIDDLE); +} + +module AP_MODULE_DECLARE_DATA ipp_module = { + STANDARD20_MODULE_STUFF, + create_ipp_dir_config, /* create per-dir config */ + NULL, /* merge per-dir config */ + NULL, /* create per-server config */ + NULL, /* merge per-server config */ + ipp_cmds, /* table of config commands */ + ipp_register_hooks /* register hooks */ +}; + +#else /* Apache 1.X */ + +/* Dispatch list of content handlers */ +static const handler_rec ipp_handlers[] = { + /* + * This handler association causes all IPP request with the + * correct MIME type to call the protocol handler. + */ + { "application/ipp", ipp_handler }, + /* + * This hander association is causes everything to go through the IPP + * protocol request handler. This is necessary because client POST + * request may be for something outside of the normal printer-uri + * space. + */ + { "*/*", ipp_handler }, + + { NULL, NULL } +}; + + +module MODULE_VAR_EXPORT ipp_module = { + STANDARD_MODULE_STUFF, + NULL, /* module initializer */ + create_ipp_dir_config, /* create per-dir config structures */ + NULL, /* merge per-dir config structures */ + NULL, /* create per-server config structures */ + NULL, /* merge per-server config structures */ + ipp_cmds, /* table of config file commands */ + ipp_handlers, /* [#8] MIME-typed-dispatched handlers */ + NULL, /* [#1] URI to filename translation */ + NULL, /* [#4] validate user id from request */ + NULL, /* [#5] check if the user is ok _here_ */ + NULL, /* [#3] check access by host address */ + NULL, /* [#6] determine MIME type */ + NULL, /* [#7] pre-run fixups */ + NULL, /* [#9] log a transaction */ + NULL, /* [#2] header parser */ + NULL, /* child_init */ + NULL, /* child_exit */ + NULL /* [#0] post read-request */ +}; +#endif diff --git a/usr/src/pkgdefs/Makefile b/usr/src/pkgdefs/Makefile index 2458e078d9..e1c007168e 100644 --- a/usr/src/pkgdefs/Makefile +++ b/usr/src/pkgdefs/Makefile @@ -203,6 +203,9 @@ COMMON_SUBDIRS= \ SUNWipfr \ SUNWipfu \ SUNWipoib \ + SUNWippcore \ + SUNWipplr \ + SUNWipplu \ SUNWixgb \ SUNWkrbr \ SUNWkrbu \ @@ -210,6 +213,8 @@ COMMON_SUBDIRS= \ SUNWllc \ SUNWllcr\ SUNWlldap \ + SUNWlp-cmds \ + SUNWlpr-cmds \ SUNWkey \ SUNWloc \ SUNWmdar \ @@ -245,6 +250,7 @@ COMMON_SUBDIRS= \ SUNWypr \ SUNWypu \ SUNWpamsc \ + SUNWpapi \ SUNWpcelx \ SUNWpcmci \ SUNWpcmcu \ @@ -275,6 +281,8 @@ COMMON_SUBDIRS= \ SUNWpppgS \ SUNWpsdpr \ SUNWpsf \ + SUNWpsm-ipp \ + SUNWpsm-lpd \ SUNWpmu \ SUNWpsr \ SUNWpsu \ diff --git a/usr/src/pkgdefs/SUNWippcore/Makefile b/usr/src/pkgdefs/SUNWippcore/Makefile new file mode 100644 index 0000000000..830ffbdf70 --- /dev/null +++ b/usr/src/pkgdefs/SUNWippcore/Makefile @@ -0,0 +1,49 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +DATAFILES=depend copyright +CLEANFILES += action + +ACTION=grep SUNWpapi depend > /dev/null || \ + ( chmod 666 depend; \ + echo "P SUNWpapi Free Standards Group Open Printing API" >> depend; \ + chmod 444 depend ); + +.KEEP_STATE: + +all: $(FILES) action +install: all pkg + +# action is a pseudotarget denoting completed work on the depend file +action: depend + $(ACTION) + touch $@ + +include ../Makefile.targ +include ../Makefile.prtarg diff --git a/usr/src/pkgdefs/SUNWippcore/pkginfo.tmpl b/usr/src/pkgdefs/SUNWippcore/pkginfo.tmpl new file mode 100644 index 0000000000..80f135c1cf --- /dev/null +++ b/usr/src/pkgdefs/SUNWippcore/pkginfo.tmpl @@ -0,0 +1,57 @@ +# +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# This required package information file describes characteristics of the +# package, such as package abbreviation, full package name, package version, +# and package architecture. +# +PKG="SUNWippcore" +NAME="Internet Printing Protocol(IPP) core libraries, (usr)" +ARCH="ISA" +# this should be changed to ONVERS when ON catches up to the version number +VERSION="13.1,REV=0.0.0" +SUNW_PRODNAME="SunOS" +SUNW_PRODVERS="RELEASE/VERSION" +SUNW_PKGTYPE="usr" +MAXINST="1000" +CATEGORY="system" +DESC="Internet Print Protocol (IPP) encoding/decoding/operation support" +VENDOR="Sun Microsystems, Inc." +HOTLINE="Please contact your local service provider" +EMAIL="" +CLASSES="none" +BASEDIR=/ +SUNW_PKGVERS="1.0" +SUNW_PKG_ALLZONES="true" +SUNW_PKG_HOLLOW="false" +SUNW_PKG_THISZONE="false" +#VSTOCK="<reserved by Release Engineering for package part #>" +#ISTATES="<developer defined>" +#RSTATES='<developer defined>' +#ULIMIT="<developer defined>" +#ORDER="<developer defined>" +#PSTAMP="<developer defined>" +#INTONLY="<developer defined>" diff --git a/usr/src/pkgdefs/SUNWippcore/prototype_com b/usr/src/pkgdefs/SUNWippcore/prototype_com new file mode 100644 index 0000000000..c170f87963 --- /dev/null +++ b/usr/src/pkgdefs/SUNWippcore/prototype_com @@ -0,0 +1,52 @@ +# +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# packaging files +i pkginfo +i copyright +i depend +# +# SUNWippcore - Sun Open Printing - IPP libraries +# +d none usr 0755 root sys +d none usr/lib 0755 root bin +# IPP read/write/marshal/unmarshal +f none usr/lib/libipp-core.so.0 0755 root bin +s none usr/lib/libipp-core.so=./libipp-core.so.0 +# IPP operations +f none usr/lib/libipp-listener.so.0 0755 root bin +s none usr/lib/libipp-listener.so=./libipp-listener.so.0 + diff --git a/usr/src/pkgdefs/SUNWippcore/prototype_i386 b/usr/src/pkgdefs/SUNWippcore/prototype_i386 new file mode 100644 index 0000000000..ec7308930a --- /dev/null +++ b/usr/src/pkgdefs/SUNWippcore/prototype_i386 @@ -0,0 +1,50 @@ +# +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# +# Include ISA independent files (prototype_com) +# +!include prototype_com +# +# +# +# List files which are I386 specific here +# +# source locations relative to the prototype file +# +# +# SUNWippcore +# diff --git a/usr/src/pkgdefs/SUNWippcore/prototype_sparc b/usr/src/pkgdefs/SUNWippcore/prototype_sparc new file mode 100644 index 0000000000..d63ead3dda --- /dev/null +++ b/usr/src/pkgdefs/SUNWippcore/prototype_sparc @@ -0,0 +1,50 @@ +# +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# +# Include ISA independent files (prototype_com) +# +!include prototype_com +# +# +# +# List files which are SPARC specific here +# +# source locations relative to the prototype file +# +# +# SUNWippcore +# diff --git a/usr/src/pkgdefs/SUNWipplr/Makefile b/usr/src/pkgdefs/SUNWipplr/Makefile new file mode 100644 index 0000000000..eafb15d98a --- /dev/null +++ b/usr/src/pkgdefs/SUNWipplr/Makefile @@ -0,0 +1,51 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +DATAFILES=depend copyright i.manifest r.manifest i.preserve + +TMPLFILES += preremove +CLEANFILES += action + +ACTION=grep SUNWapchr depend > /dev/null || \ + ( chmod 666 depend; \ + echo "P SUNWapchr Apache (root) files" >> depend; \ + chmod 444 depend ); + +.KEEP_STATE: + +all: $(FILES) action +install: all pkg + +# action is a pseudotarget denoting completed work on the depend file +action: depend + $(ACTION) + touch $@ + +include ../Makefile.targ +include ../Makefile.prtarg diff --git a/usr/src/pkgdefs/SUNWipplr/pkginfo.tmpl b/usr/src/pkgdefs/SUNWipplr/pkginfo.tmpl new file mode 100644 index 0000000000..b0fe1ca73c --- /dev/null +++ b/usr/src/pkgdefs/SUNWipplr/pkginfo.tmpl @@ -0,0 +1,57 @@ +# +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# This required package information file describes characteristics of the +# package, such as package abbreviation, full package name, package version, +# and package architecture. +# +PKG="SUNWipplr" +NAME="Internet Printing Protocol(IPP) listener, (root)" +ARCH="ISA" +# this should be changed to ONVERS when ON catches up to the version number +VERSION="13.1,REV=0.0.0" +SUNW_PRODNAME="SunOS" +SUNW_PRODVERS="RELEASE/VERSION" +SUNW_PKGTYPE="root" +MAXINST="1000" +CATEGORY="system" +DESC="Internet Printing Protocol(IPP) Apache configuration for service module" +VENDOR="Sun Microsystems, Inc." +HOTLINE="Please contact your local service provider" +EMAIL="" +CLASSES="none preserve manifest" +BASEDIR=/ +SUNW_PKGVERS="1.0" +SUNW_PKG_ALLZONES="true" +SUNW_PKG_HOLLOW="false" +SUNW_PKG_THISZONE="false" +#VSTOCK="<reserved by Release Engineering for package part #>" +#ISTATES="<developer defined>" +#RSTATES='<developer defined>' +#ULIMIT="<developer defined>" +#ORDER="<developer defined>" +#PSTAMP="<developer defined>" +#INTONLY="<developer defined>" diff --git a/usr/src/pkgdefs/SUNWipplr/preremove.tmpl b/usr/src/pkgdefs/SUNWipplr/preremove.tmpl new file mode 100644 index 0000000000..fafd44d99e --- /dev/null +++ b/usr/src/pkgdefs/SUNWipplr/preremove.tmpl @@ -0,0 +1,41 @@ +#!/bin/sh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# pragma ident "%Z%%M% %I% %E% SMI" +# + +# If we are removing a "local" version of the package, disable the listener. + +[ "${PKG_INSTALL_ROOT:-/}" = "/" ] || exit 0 + +svcprop -q svc:/application/print/ipp-listener:default || exit 0 + +/usr/sbin/svcadm disable svc:/application/print/ipp-listener + +if [ $? -ne 0 ]; then + exit 1 +fi + +exit 0 diff --git a/usr/src/pkgdefs/SUNWipplr/prototype_com b/usr/src/pkgdefs/SUNWipplr/prototype_com new file mode 100644 index 0000000000..0bd888421b --- /dev/null +++ b/usr/src/pkgdefs/SUNWipplr/prototype_com @@ -0,0 +1,60 @@ +# +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# packaging files +i pkginfo +i copyright +i depend +i preremove +i i.preserve +i i.manifest +i r.manifest +# +# SUNWipplr - Sun Open Print Apache IPP Listener root files +# +d none etc 0755 root sys +d none etc/apache 0755 root bin +e preserve etc/apache/httpd-standalone-ipp.conf 0644 root bin +# smf(5) manifest for IPP Listener +d none var 755 root sys +d none var/lp 775 lp lp +d none var/lp/ipp-listener 755 root bin +f none var/lp/ipp-listener/index.html 444 root bin +d none var/svc 755 root sys +d none var/svc/manifest 755 root sys +d none var/svc/manifest/application 755 root sys +d none var/svc/manifest/application/print 755 root sys +f manifest var/svc/manifest/application/print/ipp-listener.xml 0444 root sys diff --git a/usr/src/pkgdefs/SUNWipplr/prototype_i386 b/usr/src/pkgdefs/SUNWipplr/prototype_i386 new file mode 100644 index 0000000000..91f70a1724 --- /dev/null +++ b/usr/src/pkgdefs/SUNWipplr/prototype_i386 @@ -0,0 +1,50 @@ +# +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# +# Include ISA independent files (prototype_com) +# +!include prototype_com +# +# +# +# List files which are I386 specific here +# +# source locations relative to the prototype file +# +# +# SUNWipplr +# diff --git a/usr/src/pkgdefs/SUNWipplr/prototype_sparc b/usr/src/pkgdefs/SUNWipplr/prototype_sparc new file mode 100644 index 0000000000..40316b4cd5 --- /dev/null +++ b/usr/src/pkgdefs/SUNWipplr/prototype_sparc @@ -0,0 +1,50 @@ +# +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# +# Include ISA independent files (prototype_com) +# +!include prototype_com +# +# +# +# List files which are SPARC specific here +# +# source locations relative to the prototype file +# +# +# SUNWipplr +# diff --git a/usr/src/pkgdefs/SUNWipplu/Makefile b/usr/src/pkgdefs/SUNWipplu/Makefile new file mode 100644 index 0000000000..2300581ce5 --- /dev/null +++ b/usr/src/pkgdefs/SUNWipplu/Makefile @@ -0,0 +1,50 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +DATAFILES=depend copyright +CLEANFILES += action + +ACTION=grep SUNWpapi depend > /dev/null || \ + ( chmod 666 depend; \ + echo "P SUNWpapi Free Standards Group Open Printing API" >> depend; \ + echo "P SUNWippcore Sun Open Print IPP Core libraries" >> depend; \ + chmod 444 depend ); + +.KEEP_STATE: + +all: $(FILES) action +install: all pkg + +# action is a pseudotarget denoting completed work on the depend file +action: depend + $(ACTION) + touch $@ + +include ../Makefile.targ +include ../Makefile.prtarg diff --git a/usr/src/pkgdefs/SUNWipplu/pkginfo.tmpl b/usr/src/pkgdefs/SUNWipplu/pkginfo.tmpl new file mode 100644 index 0000000000..a07f6c449e --- /dev/null +++ b/usr/src/pkgdefs/SUNWipplu/pkginfo.tmpl @@ -0,0 +1,57 @@ +# +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# This required package information file describes characteristics of the +# package, such as package abbreviation, full package name, package version, +# and package architecture. +# +PKG="SUNWipplu" +NAME="Internet Printing Protocol(IPP) listener module (/usr)" +ARCH="ISA" +# this should be changed to ONVERS when ON catches up to the version number +VERSION="13.1,REV=0.0.0" +SUNW_PRODNAME="SunOS" +SUNW_PRODVERS="RELEASE/VERSION" +SUNW_PKGTYPE="usr" +MAXINST="1000" +CATEGORY="system" +DESC="Internet Printing Protocol(IPP) Apache module for listening service" +VENDOR="Sun Microsystems, Inc." +HOTLINE="Please contact your local service provider" +EMAIL="" +CLASSES="none" +BASEDIR=/ +SUNW_PKGVERS="1.0" +SUNW_PKG_ALLZONES="true" +SUNW_PKG_HOLLOW="false" +SUNW_PKG_THISZONE="false" +#VSTOCK="<reserved by Release Engineering for package part #>" +#ISTATES="<developer defined>" +#RSTATES='<developer defined>' +#ULIMIT="<developer defined>" +#ORDER="<developer defined>" +#PSTAMP="<developer defined>" +#INTONLY="<developer defined>" diff --git a/usr/src/pkgdefs/SUNWipplu/prototype_com b/usr/src/pkgdefs/SUNWipplu/prototype_com new file mode 100644 index 0000000000..5d313b7b05 --- /dev/null +++ b/usr/src/pkgdefs/SUNWipplu/prototype_com @@ -0,0 +1,48 @@ +# +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# packaging files +i pkginfo +i copyright +i depend +# +# SUNWipplu - Sun Open Print Apache IPP Listener /usr files +# +d none usr 0755 root sys +d none usr/apache 0755 root bin +d none usr/apache/libexec 0755 root bin +# Apache/IPP Listener glue code +f none usr/apache/libexec/mod_ipp.so 0555 root bin diff --git a/usr/src/pkgdefs/SUNWipplu/prototype_i386 b/usr/src/pkgdefs/SUNWipplu/prototype_i386 new file mode 100644 index 0000000000..629330616b --- /dev/null +++ b/usr/src/pkgdefs/SUNWipplu/prototype_i386 @@ -0,0 +1,50 @@ +# +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# +# Include ISA independent files (prototype_com) +# +!include prototype_com +# +# +# +# List files which are I386 specific here +# +# source locations relative to the prototype file +# +# +# SUNWipplu +# diff --git a/usr/src/pkgdefs/SUNWipplu/prototype_sparc b/usr/src/pkgdefs/SUNWipplu/prototype_sparc new file mode 100644 index 0000000000..b0e58c0feb --- /dev/null +++ b/usr/src/pkgdefs/SUNWipplu/prototype_sparc @@ -0,0 +1,50 @@ +# +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# +# Include ISA independent files (prototype_com) +# +!include prototype_com +# +# +# +# List files which are SPARC specific here +# +# source locations relative to the prototype file +# +# +# SUNWipplu +# diff --git a/usr/src/pkgdefs/SUNWlp-cmds/Makefile b/usr/src/pkgdefs/SUNWlp-cmds/Makefile new file mode 100644 index 0000000000..830ffbdf70 --- /dev/null +++ b/usr/src/pkgdefs/SUNWlp-cmds/Makefile @@ -0,0 +1,49 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +DATAFILES=depend copyright +CLEANFILES += action + +ACTION=grep SUNWpapi depend > /dev/null || \ + ( chmod 666 depend; \ + echo "P SUNWpapi Free Standards Group Open Printing API" >> depend; \ + chmod 444 depend ); + +.KEEP_STATE: + +all: $(FILES) action +install: all pkg + +# action is a pseudotarget denoting completed work on the depend file +action: depend + $(ACTION) + touch $@ + +include ../Makefile.targ +include ../Makefile.prtarg diff --git a/usr/src/pkgdefs/SUNWlp-cmds/pkginfo.tmpl b/usr/src/pkgdefs/SUNWlp-cmds/pkginfo.tmpl new file mode 100644 index 0000000000..1eec27a3fc --- /dev/null +++ b/usr/src/pkgdefs/SUNWlp-cmds/pkginfo.tmpl @@ -0,0 +1,59 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +# +# This required package information file describes characteristics of the +# package, such as package abbreviation, full package name, package version, +# and package architecture. +# +PKG="SUNWlp-cmds" +NAME="System V LP commands" +ARCH="ISA" +VERSION="ONVERS,REV=0.0.0" +SUNW_PRODNAME="SunOS" +SUNW_PRODVERS="RELEASE/VERSION" +SUNW_PKGTYPE="usr" +MAXINST="1000" +CATEGORY="system" +DESC="System V LP commands using the FSG OpenPrinting API (PAPI)" +VENDOR="Sun Microsystems, Inc." +HOTLINE="Please contact your local service provider" +EMAIL="" +CLASSES="none" +BASEDIR=/ +SUNW_PKGVERS="1.0" +SUNW_PKG_ALLZONES="true" +SUNW_PKG_HOLLOW="false" +SUNW_PKG_THISZONE="false" +#VSTOCK="<reserved by Release Engineering for package part #>" +#ISTATES="<developer defined>" +#RSTATES='<developer defined>' +#ULIMIT="<developer defined>" +#ORDER="<developer defined>" +#PSTAMP="<developer defined>" +#INTONLY="<developer defined>" diff --git a/usr/src/pkgdefs/SUNWlp-cmds/prototype_com b/usr/src/pkgdefs/SUNWlp-cmds/prototype_com new file mode 100644 index 0000000000..08613b5ab5 --- /dev/null +++ b/usr/src/pkgdefs/SUNWlp-cmds/prototype_com @@ -0,0 +1,64 @@ +# +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# packaging files +i pkginfo +i copyright +i depend +# +# source locations relative to the prototype file +# +# SUNWpapi-lp-cmds +# +d none usr 755 root sys +d none usr/bin 755 root bin +f none usr/bin/cancel 0555 root bin +f none usr/bin/disable 0555 root bin +f none usr/bin/enable 0555 root bin +f none usr/bin/lp 0555 root bin +f none usr/bin/lpstat 0555 root bin +d none usr/lib 755 root bin +s none usr/lib/accept=../sbin/accept +s none usr/lib/lpmove=../sbin/lpmove +s none usr/lib/reject=../sbin/reject +d none usr/sbin 755 root bin +f none usr/sbin/accept 0555 root bin +f none usr/sbin/lpmove 0555 root bin +f none usr/sbin/reject 0555 root bin diff --git a/usr/src/pkgdefs/SUNWlp-cmds/prototype_i386 b/usr/src/pkgdefs/SUNWlp-cmds/prototype_i386 new file mode 100644 index 0000000000..fc0351d75f --- /dev/null +++ b/usr/src/pkgdefs/SUNWlp-cmds/prototype_i386 @@ -0,0 +1,52 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# +# Include ISA independent files (prototype_com) +# +!include prototype_com +# +# +# +# List files which are I386 specific here +# +# source locations relative to the prototype file +# +# +# SUNWpapi-lp-cmds +# diff --git a/usr/src/pkgdefs/SUNWlp-cmds/prototype_sparc b/usr/src/pkgdefs/SUNWlp-cmds/prototype_sparc new file mode 100644 index 0000000000..a520804be7 --- /dev/null +++ b/usr/src/pkgdefs/SUNWlp-cmds/prototype_sparc @@ -0,0 +1,53 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# +# Include ISA independent files (prototype_com) +# +!include prototype_com +# +# +# +# List files which are SPARC specific here +# +# source locations relative to the prototype file +# +# +# SUNWpapi-lp-cmds +# diff --git a/usr/src/pkgdefs/SUNWlpr-cmds/Makefile b/usr/src/pkgdefs/SUNWlpr-cmds/Makefile new file mode 100644 index 0000000000..830ffbdf70 --- /dev/null +++ b/usr/src/pkgdefs/SUNWlpr-cmds/Makefile @@ -0,0 +1,49 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +DATAFILES=depend copyright +CLEANFILES += action + +ACTION=grep SUNWpapi depend > /dev/null || \ + ( chmod 666 depend; \ + echo "P SUNWpapi Free Standards Group Open Printing API" >> depend; \ + chmod 444 depend ); + +.KEEP_STATE: + +all: $(FILES) action +install: all pkg + +# action is a pseudotarget denoting completed work on the depend file +action: depend + $(ACTION) + touch $@ + +include ../Makefile.targ +include ../Makefile.prtarg diff --git a/usr/src/pkgdefs/SUNWlpr-cmds/pkginfo.tmpl b/usr/src/pkgdefs/SUNWlpr-cmds/pkginfo.tmpl new file mode 100644 index 0000000000..38f6ab861e --- /dev/null +++ b/usr/src/pkgdefs/SUNWlpr-cmds/pkginfo.tmpl @@ -0,0 +1,58 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# +# This required package information file describes characteristics of the +# package, such as package abbreviation, full package name, package version, +# and package architecture. +# +PKG="SUNWlpr-cmds" +NAME="Berkeley LPR commands" +ARCH="ISA" +VERSION="ONVERS,REV=0.0.0" +SUNW_PRODNAME="SunOS" +SUNW_PRODVERS="RELEASE/VERSION" +SUNW_PKGTYPE="usr" +MAXINST="1000" +CATEGORY="system" +DESC="Berkeley LPR commands using the FSG OpenPrinting API (PAPI)" +VENDOR="Sun Microsystems, Inc." +HOTLINE="Please contact your local service provider" +EMAIL="" +CLASSES="none" +BASEDIR=/ +SUNW_PKGVERS="1.0" +SUNW_PKG_ALLZONES="true" +SUNW_PKG_HOLLOW="false" +SUNW_PKG_THISZONE="false" +#VSTOCK="<reserved by Release Engineering for package part #>" +#ISTATES="<developer defined>" +#RSTATES='<developer defined>' +#ULIMIT="<developer defined>" +#ORDER="<developer defined>" +#PSTAMP="<developer defined>" +#INTONLY="<developer defined>" diff --git a/usr/src/pkgdefs/SUNWlpr-cmds/prototype_com b/usr/src/pkgdefs/SUNWlpr-cmds/prototype_com new file mode 100644 index 0000000000..124d7c7480 --- /dev/null +++ b/usr/src/pkgdefs/SUNWlpr-cmds/prototype_com @@ -0,0 +1,53 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# packaging files +i pkginfo +i copyright +i depend +# +# source locations relative to the prototype file +# +# SUNWpapi-lpr-cmds +# +d none usr 755 root sys +d none usr/bin 755 root bin +f none usr/bin/lpc 0555 root bin +f none usr/bin/lpq 0555 root bin +f none usr/bin/lpr 0555 root bin +f none usr/bin/lprm 0555 root bin diff --git a/usr/src/pkgdefs/SUNWlpr-cmds/prototype_i386 b/usr/src/pkgdefs/SUNWlpr-cmds/prototype_i386 new file mode 100644 index 0000000000..e033491157 --- /dev/null +++ b/usr/src/pkgdefs/SUNWlpr-cmds/prototype_i386 @@ -0,0 +1,52 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# +# Include ISA independent files (prototype_com) +# +!include prototype_com +# +# +# +# List files which are I386 specific here +# +# source locations relative to the prototype file +# +# +# SUNWpapi-lpr-cmds +# diff --git a/usr/src/pkgdefs/SUNWlpr-cmds/prototype_sparc b/usr/src/pkgdefs/SUNWlpr-cmds/prototype_sparc new file mode 100644 index 0000000000..39517853b2 --- /dev/null +++ b/usr/src/pkgdefs/SUNWlpr-cmds/prototype_sparc @@ -0,0 +1,52 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# +# Include ISA independent files (prototype_com) +# +!include prototype_com +# +# +# +# List files which are SPARC specific here +# +# source locations relative to the prototype file +# +# +# SUNWpapi-lpr-cmds +# diff --git a/usr/src/pkgdefs/SUNWpapi/Makefile b/usr/src/pkgdefs/SUNWpapi/Makefile new file mode 100644 index 0000000000..d4b6746b7a --- /dev/null +++ b/usr/src/pkgdefs/SUNWpapi/Makefile @@ -0,0 +1,39 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +DATAFILES=depend copyright +CLEANFILES += action + +.KEEP_STATE: + +all: $(FILES) +install: all pkg + +include ../Makefile.targ +include ../Makefile.prtarg diff --git a/usr/src/pkgdefs/SUNWpapi/pkginfo.tmpl b/usr/src/pkgdefs/SUNWpapi/pkginfo.tmpl new file mode 100644 index 0000000000..fe0a3fd84b --- /dev/null +++ b/usr/src/pkgdefs/SUNWpapi/pkginfo.tmpl @@ -0,0 +1,56 @@ +# +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# This required package information file describes characteristics of the +# package, such as package abbreviation, full package name, package version, +# and package architecture. +# +PKG="SUNWpapi" +NAME="Free Standards Group Open Printing API" +ARCH="ISA" +VERSION="ONVERS,REV=0.0.0" +SUNW_PRODNAME="SunOS" +SUNW_PRODVERS="RELEASE/VERSION" +SUNW_PKGTYPE="usr" +MAXINST="1000" +CATEGORY="system" +DESC="Free Standards Group Open Printing API, Draft v0.9" +VENDOR="Sun Microsystems, Inc." +HOTLINE="Please contact your local service provider" +EMAIL="" +CLASSES="none" +BASEDIR=/ +SUNW_PKGVERS="1.0" +SUNW_PKG_ALLZONES="true" +SUNW_PKG_HOLLOW="false" +SUNW_PKG_THISZONE="false" +#VSTOCK="<reserved by Release Engineering for package part #>" +#ISTATES="<developer defined>" +#RSTATES='<developer defined>' +#ULIMIT="<developer defined>" +#ORDER="<developer defined>" +#PSTAMP="<developer defined>" +#INTONLY="<developer defined>" diff --git a/usr/src/pkgdefs/SUNWpapi/prototype_com b/usr/src/pkgdefs/SUNWpapi/prototype_com new file mode 100644 index 0000000000..0949f900fd --- /dev/null +++ b/usr/src/pkgdefs/SUNWpapi/prototype_com @@ -0,0 +1,53 @@ +# +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# packaging files +i pkginfo +i copyright +i depend +# +# source locations relative to the prototype file +# +# SUNWpapi +# +d none usr 755 root sys +d none usr/lib 755 root bin +s none usr/lib/libpapi.so=./libpapi.so.0 +f none usr/lib/libpapi.so.0 0755 root bin +s none usr/lib/libpapi-common.so=./libpapi-common.so.0 +f none usr/lib/libpapi-common.so.0 0755 root bin +d none usr/include 755 root bin +f none usr/include/papi.h 644 root bin diff --git a/usr/src/pkgdefs/SUNWpapi/prototype_i386 b/usr/src/pkgdefs/SUNWpapi/prototype_i386 new file mode 100644 index 0000000000..0b1ae232f0 --- /dev/null +++ b/usr/src/pkgdefs/SUNWpapi/prototype_i386 @@ -0,0 +1,50 @@ +# +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# +# Include ISA independent files (prototype_com) +# +!include prototype_com +# +# +# +# List files which are I386 specific here +# +# source locations relative to the prototype file +# +# +# SUNWpapi +# diff --git a/usr/src/pkgdefs/SUNWpapi/prototype_sparc b/usr/src/pkgdefs/SUNWpapi/prototype_sparc new file mode 100644 index 0000000000..631fb3e1f7 --- /dev/null +++ b/usr/src/pkgdefs/SUNWpapi/prototype_sparc @@ -0,0 +1,50 @@ +# +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# +# Include ISA independent files (prototype_com) +# +!include prototype_com +# +# +# +# List files which are SPARC specific here +# +# source locations relative to the prototype file +# +# +# SUNWpapi +# diff --git a/usr/src/pkgdefs/SUNWpcr/pkginfo.tmpl b/usr/src/pkgdefs/SUNWpcr/pkginfo.tmpl index 0930e92e86..3ccaf669cb 100644 --- a/usr/src/pkgdefs/SUNWpcr/pkginfo.tmpl +++ b/usr/src/pkgdefs/SUNWpcr/pkginfo.tmpl @@ -34,6 +34,7 @@ PKG="SUNWpcr" NAME="Solaris Print - Client, (root)" ARCH="ISA" +# this should be changed to ONVERS when ON catches up to the version number VERSION="13.1,REV=0.0.0" SUNW_PRODNAME="SunOS" SUNW_PRODVERS="RELEASE/VERSION" diff --git a/usr/src/pkgdefs/SUNWpcu/Makefile b/usr/src/pkgdefs/SUNWpcu/Makefile index 89e50717d1..e19a81f92d 100644 --- a/usr/src/pkgdefs/SUNWpcu/Makefile +++ b/usr/src/pkgdefs/SUNWpcu/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -20,11 +19,11 @@ # CDDL HEADER END # # -#ident "%Z%%M% %I% %E% SMI" -# -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +#ident "%Z%%M% %I% %E% SMI" +# include ../Makefile.com diff --git a/usr/src/pkgdefs/SUNWpcu/pkginfo.tmpl b/usr/src/pkgdefs/SUNWpcu/pkginfo.tmpl index ea875d4e90..2165dc8f2e 100644 --- a/usr/src/pkgdefs/SUNWpcu/pkginfo.tmpl +++ b/usr/src/pkgdefs/SUNWpcu/pkginfo.tmpl @@ -34,6 +34,7 @@ PKG="SUNWpcu" NAME="Solaris Print - Client, (usr)" ARCH="ISA" +# this should be changed to ONVERS when ON catches up to the version number VERSION="13.1,REV=0.0.0" SUNW_PRODNAME="SunOS" SUNW_PRODVERS="RELEASE/VERSION" diff --git a/usr/src/pkgdefs/SUNWpcu/prototype_com b/usr/src/pkgdefs/SUNWpcu/prototype_com index ca766ef935..7819733540 100644 --- a/usr/src/pkgdefs/SUNWpcu/prototype_com +++ b/usr/src/pkgdefs/SUNWpcu/prototype_com @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -45,24 +44,13 @@ i preremove # d none usr 0755 root sys d none usr/bin 0755 root bin -f none usr/bin/cancel 4511 root lp -s none usr/bin/disable=../sbin/accept -s none usr/bin/enable=../sbin/accept -f none usr/bin/lp 4511 root lp -f none usr/bin/lpc 555 root lp f none usr/bin/lpget 0511 root lp -s none usr/bin/lpq=lpstat -s none usr/bin/lpr=lp -s none usr/bin/lprm=cancel f none usr/bin/lpset 4511 root lp -f none usr/bin/lpstat 4511 root lp f none usr/bin/lptest 555 root lp d none usr/lib 0755 root bin -s none usr/lib/accept=../sbin/accept f none usr/lib/libprint.so.2 0755 root bin s none usr/lib/libprint.so=./libprint.so.2 s none usr/lib/lpadmin=../sbin/lpadmin -s none usr/lib/lpmove=../sbin/lpmove s none usr/lib/lpsystem=../sbin/lpsystem d none usr/lib/print 0755 root lp d none usr/lib/print/bsd-adaptor 0755 root lp @@ -75,11 +63,7 @@ f none usr/lib/print/in.lpd 0555 root bin f none usr/lib/print/conv_fix 0555 root lp f none usr/lib/print/conv_lp 0555 root lp f none usr/lib/print/conv_lpd 0555 root lp -s none usr/lib/print/printd=../../bin/lp -s none usr/lib/reject=../sbin/accept +f none usr/lib/print/printd 0555 root bin d none usr/sbin 0755 root bin -f none usr/sbin/accept 0555 root lp f none usr/sbin/lpadmin 0555 root lp -f none usr/sbin/lpmove 4511 root lp f none usr/sbin/lpsystem 0555 root lp -s none usr/sbin/reject=../sbin/accept diff --git a/usr/src/pkgdefs/SUNWpsf/pkginfo.tmpl b/usr/src/pkgdefs/SUNWpsf/pkginfo.tmpl index 7f88714e47..26edac2f7e 100644 --- a/usr/src/pkgdefs/SUNWpsf/pkginfo.tmpl +++ b/usr/src/pkgdefs/SUNWpsf/pkginfo.tmpl @@ -34,6 +34,7 @@ PKG="SUNWpsf" NAME="PostScript filters - (Usr)" ARCH="ISA" +# this should be changed to ONVERS when ON catches up to the version number VERSION="13.1,REV=0.0.0" SUNW_PRODNAME="SunOS" SUNW_PRODVERS="RELEASE/VERSION" diff --git a/usr/src/pkgdefs/SUNWpsm-ipp/Makefile b/usr/src/pkgdefs/SUNWpsm-ipp/Makefile new file mode 100644 index 0000000000..2300581ce5 --- /dev/null +++ b/usr/src/pkgdefs/SUNWpsm-ipp/Makefile @@ -0,0 +1,50 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +DATAFILES=depend copyright +CLEANFILES += action + +ACTION=grep SUNWpapi depend > /dev/null || \ + ( chmod 666 depend; \ + echo "P SUNWpapi Free Standards Group Open Printing API" >> depend; \ + echo "P SUNWippcore Sun Open Print IPP Core libraries" >> depend; \ + chmod 444 depend ); + +.KEEP_STATE: + +all: $(FILES) action +install: all pkg + +# action is a pseudotarget denoting completed work on the depend file +action: depend + $(ACTION) + touch $@ + +include ../Makefile.targ +include ../Makefile.prtarg diff --git a/usr/src/pkgdefs/SUNWpsm-ipp/pkginfo.tmpl b/usr/src/pkgdefs/SUNWpsm-ipp/pkginfo.tmpl new file mode 100644 index 0000000000..142ec31882 --- /dev/null +++ b/usr/src/pkgdefs/SUNWpsm-ipp/pkginfo.tmpl @@ -0,0 +1,56 @@ +# +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# This required package information file describes characteristics of the +# package, such as package abbreviation, full package name, package version, +# and package architecture. +# +PKG="SUNWpsm-ipp" +NAME="Free Standards Group Open Printing API IPP Print Service Module" +ARCH="ISA" +VERSION="ONVERS,REV=0.0.0" +SUNW_PRODNAME="SunOS" +SUNW_PRODVERS="RELEASE/VERSION" +SUNW_PKGTYPE="usr" +MAXINST="1000" +CATEGORY="system" +DESC="Client side support for communicating with IPP based print servers" +VENDOR="Sun Microsystems, Inc." +HOTLINE="Please contact your local service provider" +EMAIL="" +CLASSES="none" +BASEDIR=/ +SUNW_PKGVERS="1.0" +SUNW_PKG_ALLZONES="true" +SUNW_PKG_HOLLOW="false" +SUNW_PKG_THISZONE="false" +#VSTOCK="<reserved by Release Engineering for package part #>" +#ISTATES="<developer defined>" +#RSTATES='<developer defined>' +#ULIMIT="<developer defined>" +#ORDER="<developer defined>" +#PSTAMP="<developer defined>" +#INTONLY="<developer defined>" diff --git a/usr/src/pkgdefs/SUNWpsm-ipp/prototype_com b/usr/src/pkgdefs/SUNWpsm-ipp/prototype_com new file mode 100644 index 0000000000..7ba7ad8f6b --- /dev/null +++ b/usr/src/pkgdefs/SUNWpsm-ipp/prototype_com @@ -0,0 +1,53 @@ +# +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# packaging files +i pkginfo +i copyright +i depend +# +# source locations relative to the prototype file +# +# SUNWpsm-ipp +# +d none usr 755 root sys +d none usr/lib 755 root bin +d none usr/lib/print 755 root lp +s none usr/lib/print/psm-http.so=./psm-ipp.so +s none usr/lib/print/psm-ipp.so=./psm-ipp.so.1 +f none usr/lib/print/psm-ipp.so.1 0755 root bin +s none usr/lib/print/libhttp-core.so=./libhttp-core.so.1 +f none usr/lib/print/libhttp-core.so.1 0755 root bin diff --git a/usr/src/pkgdefs/SUNWpsm-ipp/prototype_i386 b/usr/src/pkgdefs/SUNWpsm-ipp/prototype_i386 new file mode 100644 index 0000000000..ab88f4de24 --- /dev/null +++ b/usr/src/pkgdefs/SUNWpsm-ipp/prototype_i386 @@ -0,0 +1,50 @@ +# +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# +# Include ISA independent files (prototype_com) +# +!include prototype_com +# +# +# +# List files which are I386 specific here +# +# source locations relative to the prototype file +# +# +# SUNWpsm-ipp +# diff --git a/usr/src/pkgdefs/SUNWpsm-ipp/prototype_sparc b/usr/src/pkgdefs/SUNWpsm-ipp/prototype_sparc new file mode 100644 index 0000000000..e71982c894 --- /dev/null +++ b/usr/src/pkgdefs/SUNWpsm-ipp/prototype_sparc @@ -0,0 +1,50 @@ +# +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# +# Include ISA independent files (prototype_com) +# +!include prototype_com +# +# +# +# List files which are SPARC specific here +# +# source locations relative to the prototype file +# +# +# SUNWpsm-ipp +# diff --git a/usr/src/pkgdefs/SUNWpsm-lpd/Makefile b/usr/src/pkgdefs/SUNWpsm-lpd/Makefile new file mode 100644 index 0000000000..830ffbdf70 --- /dev/null +++ b/usr/src/pkgdefs/SUNWpsm-lpd/Makefile @@ -0,0 +1,49 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +DATAFILES=depend copyright +CLEANFILES += action + +ACTION=grep SUNWpapi depend > /dev/null || \ + ( chmod 666 depend; \ + echo "P SUNWpapi Free Standards Group Open Printing API" >> depend; \ + chmod 444 depend ); + +.KEEP_STATE: + +all: $(FILES) action +install: all pkg + +# action is a pseudotarget denoting completed work on the depend file +action: depend + $(ACTION) + touch $@ + +include ../Makefile.targ +include ../Makefile.prtarg diff --git a/usr/src/pkgdefs/SUNWpsm-lpd/pkginfo.tmpl b/usr/src/pkgdefs/SUNWpsm-lpd/pkginfo.tmpl new file mode 100644 index 0000000000..8040882278 --- /dev/null +++ b/usr/src/pkgdefs/SUNWpsm-lpd/pkginfo.tmpl @@ -0,0 +1,56 @@ +# +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# This required package information file describes characteristics of the +# package, such as package abbreviation, full package name, package version, +# and package architecture. +# +PKG="SUNWpsm-lpd" +NAME="Free Standards Group Open Printing API RFC-1179 Print Service Module" +ARCH="ISA" +VERSION="ONVERS,REV=0.0.0" +SUNW_PRODNAME="SunOS" +SUNW_PRODVERS="RELEASE/VERSION" +SUNW_PKGTYPE="usr" +MAXINST="1000" +CATEGORY="system" +DESC="Client side support for communicating with RFC-1179 based print servers" +VENDOR="Sun Microsystems, Inc." +HOTLINE="Please contact your local service provider" +EMAIL="" +CLASSES="none" +BASEDIR=/ +SUNW_PKGVERS="1.0" +SUNW_PKG_ALLZONES="true" +SUNW_PKG_HOLLOW="false" +SUNW_PKG_THISZONE="false" +#VSTOCK="<reserved by Release Engineering for package part #>" +#ISTATES="<developer defined>" +#RSTATES='<developer defined>' +#ULIMIT="<developer defined>" +#ORDER="<developer defined>" +#PSTAMP="<developer defined>" +#INTONLY="<developer defined>" diff --git a/usr/src/pkgdefs/SUNWpsm-lpd/prototype_com b/usr/src/pkgdefs/SUNWpsm-lpd/prototype_com new file mode 100644 index 0000000000..c64d0aafc4 --- /dev/null +++ b/usr/src/pkgdefs/SUNWpsm-lpd/prototype_com @@ -0,0 +1,52 @@ +# +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# packaging files +i pkginfo +i copyright +i depend +# +# source locations relative to the prototype file +# +# SUNWpsm-lpd +# +d none usr 755 root sys +d none usr/lib 755 root bin +d none usr/lib/print 755 root lp +f none usr/lib/print/lpd-port 4511 root bin +s none usr/lib/print/psm-rfc-1179.so=./psm-lpd.so +s none usr/lib/print/psm-lpd.so=./psm-lpd.so.1 +f none usr/lib/print/psm-lpd.so.1 0755 root bin diff --git a/usr/src/pkgdefs/SUNWpsm-lpd/prototype_i386 b/usr/src/pkgdefs/SUNWpsm-lpd/prototype_i386 new file mode 100644 index 0000000000..0b1ae232f0 --- /dev/null +++ b/usr/src/pkgdefs/SUNWpsm-lpd/prototype_i386 @@ -0,0 +1,50 @@ +# +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# +# Include ISA independent files (prototype_com) +# +!include prototype_com +# +# +# +# List files which are I386 specific here +# +# source locations relative to the prototype file +# +# +# SUNWpapi +# diff --git a/usr/src/pkgdefs/SUNWpsm-lpd/prototype_sparc b/usr/src/pkgdefs/SUNWpsm-lpd/prototype_sparc new file mode 100644 index 0000000000..631fb3e1f7 --- /dev/null +++ b/usr/src/pkgdefs/SUNWpsm-lpd/prototype_sparc @@ -0,0 +1,50 @@ +# +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# +# Include ISA independent files (prototype_com) +# +!include prototype_com +# +# +# +# List files which are SPARC specific here +# +# source locations relative to the prototype file +# +# +# SUNWpapi +# diff --git a/usr/src/pkgdefs/SUNWpsr/pkginfo.tmpl b/usr/src/pkgdefs/SUNWpsr/pkginfo.tmpl index e6210c9877..f27008d5d6 100644 --- a/usr/src/pkgdefs/SUNWpsr/pkginfo.tmpl +++ b/usr/src/pkgdefs/SUNWpsr/pkginfo.tmpl @@ -34,6 +34,7 @@ PKG="SUNWpsr" NAME="Solaris Print - LP Server, (root)" ARCH="ISA" +# this should be changed to ONVERS when ON catches up to the version number VERSION="13.1,REV=0.0.0" SUNW_PRODNAME="SunOS" SUNW_PRODVERS="RELEASE/VERSION" diff --git a/usr/src/pkgdefs/SUNWpsu/pkginfo.tmpl b/usr/src/pkgdefs/SUNWpsu/pkginfo.tmpl index bb547bec40..100f32127a 100644 --- a/usr/src/pkgdefs/SUNWpsu/pkginfo.tmpl +++ b/usr/src/pkgdefs/SUNWpsu/pkginfo.tmpl @@ -34,6 +34,7 @@ PKG="SUNWpsu" NAME="Solaris Print - LP Server, (usr)" ARCH="ISA" +# this should be changed to ONVERS when ON catches up to the version number VERSION="13.1,REV=0.0.0" SUNW_PRODNAME="SunOS" SUNW_PRODVERS="RELEASE/VERSION" diff --git a/usr/src/pkgdefs/SUNWpsu/prototype_com b/usr/src/pkgdefs/SUNWpsu/prototype_com index 514a48c435..bfa9bb7d81 100644 --- a/usr/src/pkgdefs/SUNWpsu/prototype_com +++ b/usr/src/pkgdefs/SUNWpsu/prototype_com @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -63,14 +62,7 @@ f none usr/lib/lp/model/uri 555 root lp # commands that only talk to lpsched d none usr/lib/lp/local 755 root lp f none usr/lib/lp/local/lpsched 555 root lp -f none usr/lib/lp/local/lp 555 root lp -f none usr/lib/lp/local/lpstat 555 root lp -f none usr/lib/lp/local/accept 555 root lp -s none usr/lib/lp/local/disable=./accept -s none usr/lib/lp/local/enable=./accept -s none usr/lib/lp/local/reject=./accept f none usr/lib/lp/local/lpadmin 555 root lp -f none usr/lib/lp/local/lpmove 555 root lp f none usr/lib/lp/local/lpsystem 555 root lp f none usr/lib/lp/local/lpshut 555 root lp # links maintianed for convenience diff --git a/usr/src/pkgdefs/SUNWscplp/pkginfo.tmpl b/usr/src/pkgdefs/SUNWscplp/pkginfo.tmpl index 1cfbc29f3b..c4d6b839df 100644 --- a/usr/src/pkgdefs/SUNWscplp/pkginfo.tmpl +++ b/usr/src/pkgdefs/SUNWscplp/pkginfo.tmpl @@ -34,6 +34,7 @@ PKG="SUNWscplp" NAME="Solaris Print - Source Compatibility, (Usr)" ARCH="ISA" +# this should be changed to ONVERS when ON catches up to the version number VERSION="13.1,REV=0.0.0" SUNW_PRODNAME="SunOS" SUNW_PRODVERS="RELEASE/VERSION" |