diff options
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" |