diff options
Diffstat (limited to 'usr/src/cmd/print/bsd-sysv-commands')
-rw-r--r-- | usr/src/cmd/print/bsd-sysv-commands/Makefile | 110 | ||||
-rw-r--r-- | usr/src/cmd/print/bsd-sysv-commands/accept.c | 117 | ||||
-rw-r--r-- | usr/src/cmd/print/bsd-sysv-commands/cancel.c | 255 | ||||
-rw-r--r-- | usr/src/cmd/print/bsd-sysv-commands/common.c | 678 | ||||
-rw-r--r-- | usr/src/cmd/print/bsd-sysv-commands/common.h | 70 | ||||
-rw-r--r-- | usr/src/cmd/print/bsd-sysv-commands/disable.c | 163 | ||||
-rw-r--r-- | usr/src/cmd/print/bsd-sysv-commands/enable.c | 117 | ||||
-rw-r--r-- | usr/src/cmd/print/bsd-sysv-commands/in.lpd.c | 786 | ||||
-rw-r--r-- | usr/src/cmd/print/bsd-sysv-commands/lp.c | 334 | ||||
-rw-r--r-- | usr/src/cmd/print/bsd-sysv-commands/lpc.c | 561 | ||||
-rw-r--r-- | usr/src/cmd/print/bsd-sysv-commands/lpmove.c | 210 | ||||
-rw-r--r-- | usr/src/cmd/print/bsd-sysv-commands/lpq.c | 134 | ||||
-rw-r--r-- | usr/src/cmd/print/bsd-sysv-commands/lpr.c | 276 | ||||
-rw-r--r-- | usr/src/cmd/print/bsd-sysv-commands/lprm.c | 101 | ||||
-rw-r--r-- | usr/src/cmd/print/bsd-sysv-commands/lpstat.c | 1444 | ||||
-rw-r--r-- | usr/src/cmd/print/bsd-sysv-commands/reject.c | 122 | ||||
-rw-r--r-- | usr/src/cmd/print/bsd-sysv-commands/rfc1179.xml | 110 |
17 files changed, 5588 insertions, 0 deletions
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..ee6131c805 --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/Makefile @@ -0,0 +1,110 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# + +include ../Makefile.sp + +UCBPROGS = lpr lpq lprm lpc +BINPROGS = lp lpstat cancel enable disable $(UCBPROGS) +SBINPROGS = accept reject lpmove + +LIBPRINTPROGS = in.lpd + +LIBLPPROGS = $(BINPROGS) $(SBINPROGS) + + +OBJS = $(BINPROGS:=.o) $(SBINPROGS:=.o) $(LIBPRINTPROGS:=.o) common.o + +ROOTLIBLPBIN=$(ROOTLIBLP)/bin + +ROOTBINPROGS = $(BINPROGS:%=$(ROOTBIN)/%) +ROOTUSRSBINPROGS = $(SBINPROGS:%=$(ROOTUSRSBIN)/%) +ROOTLIBPRINTPROGS = $(LIBPRINTPROGS:%=$(ROOTLIBPRINT)/%) +ROOTLIBLPPROGS = $(LIBLPPROGS:%=$(ROOTLIBLPBIN)/%) + + +FILEMODE = 0555 + +include ../../Makefile.cmd + +MANIFEST= rfc1179.xml +ROOTMANIFESTDIR= $(ROOTSVCAPPLICATIONPRINT) +$(ROOTMANIFEST) := FILEMODE= 444 + +LPLIB = $(SRC)/cmd/lp/lib +LIBLP = $(LPLIB)/lp/liblp.a +CFLAGS += $(CCVERBOSE) +CPPFLAGS += -I. +CPPFLAGS += -I../../../lib/print/libpapi-common/common +CPPFLAGS += -I$(ROOT)/usr/include +CPPFLAGS += -I../../lp/include +LDLIBS += $(LIBLP) -lpapi -lc +in.lpd:= CFLAGS += -DSOLARIS_PRIVATE_POST_0_9 +in.lpd:= LDLIBS += -lnsl -lsocket + +CERRWARN += -_gcc=-Wno-unused-variable +CERRWARN += -_gcc=-Wno-uninitialized + +all: $(BINPROGS) $(SBINPROGS) + +# each program needs common.o as well +$(BINPROGS) $(SBINPROGS) $(LIBPRINTPROGS): $(BINPROGS:%=%.c) $(SBINPROGS:%=%.c) $(LIBPRINTPROGS:%=%.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) % + +$(ROOTLIBLPBIN)/%: % + $(INS.file) + +$(ROOTUCBSYMLINKS): + $(RM) $@; $(SYMLINK) ../bin/$(@F) $@ + +# usr/lib links +ROOTUSRLIBSYMLINKS = $(SBINPROGS:%=$(ROOTLIB)/%) +$(ROOTLIB)/%: $(ROOTLIB) % + +$(ROOTUSRLIBSYMLINKS): + $(RM) $@; $(SYMLINK) ../sbin/$(@F) $@ + +.KEEP_STATE: + +install: $(ROOTLIBLPPROGS) \ + $(ROOTLIBPRINT) $(ROOTLIBPRINTPROGS) $(ROOTMANIFEST) \ + $(ROOTUCBSYMLINKS) $(ROOTUSRLIBSYMLINKS) + +check: $(CHKMANIFEST) + +clean: + $(RM) $(OBJS) + +CLOBBERFILES += $(BINPROGS) $(SBINPROGS) $(LIBPRINTPROGS) + +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..74f392c9c3 --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/accept.c @@ -0,0 +1,117 @@ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: accept.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#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) { + printf(gettext( + "Destination \"%s\" now accepting requests\n"), + printer); + } else if (status == PAPI_NOT_ACCEPTING) { + fprintf(stderr, gettext( + "Destination \"%s\" was already " + "accepting requests.\n"), printer); + exit_status = 1; + } else { + if (status == PAPI_OPERATION_NOT_SUPPORTED) { + fprintf(stderr, + verbose_papi_message(svc, status)); + } else { + 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..23359d9b5e --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/cancel.c @@ -0,0 +1,255 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL 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) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + * + */ + +/* $Id: cancel.c 147 2006-04-25 16:51:06Z njacobs $ */ + + +#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); +} + +static int32_t +get_job_id_requested(papi_job_t job) { + int32_t rid = -1; + + papi_attribute_t **list = papiJobGetAttributeList(job); + papiAttributeListGetInteger(list, NULL, + "job-id-requested", &rid); + + return (rid); +} + +int +cancel_jobs_for_user(char *user, papi_encryption_t encryption, char *pname) { + + papi_status_t status; + papi_service_t svc = NULL; + char **printers = NULL; + int i, exit_code; + + if (pname == NULL) { + status = papiServiceCreate(&svc, NULL, NULL, NULL, + cli_auth_callback, encryption, NULL); + printers = interest_list(svc); + papiServiceDestroy(svc); + } else { + list_append(&printers, strdup(pname)); + } + + if (printers == NULL) + exit(0); + + for (i = 0; printers[i] != NULL; i++) { + char *printer = printers[i]; + + 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); + } + exit_code = berkeley_cancel_request(svc, stdout, printer, 1, + &user); + + papiServiceDestroy(svc); + if (exit_code != 0) + break; + } + free(printers); + return (exit_code); +} + +int +main(int ac, char *av[]) +{ + int exit_code = 0; + char *user = NULL; + papi_encryption_t encryption = PAPI_ENCRYPT_NEVER; + int c; + int32_t rid = -1; + int first_dest = 0; + + + (void) setlocale(LC_ALL, ""); + (void) textdomain("SUNW_OST_OSCMD"); + + if (ac == 1) + usage(av[0]); + + 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; + + status = papiServiceCreate(&svc, av[c], NULL, NULL, + cli_auth_callback, encryption, NULL); + if (status != PAPI_OK) { + if (first_dest == 0) { + (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); + } + } else { + first_dest = 1; + printer = av[c]; + } + +#define OUT ((status == PAPI_OK) ? stdout : stderr) + + if (id != -1) { /* it's a job */ + char *mesg = gettext("cancelled"); + + /* + * Check if the job-id is job-id-requested + * or job-id. If it is job-id-requested then find + * corresponding job-id and send it to cancel + */ + rid = job_to_be_queried(svc, printer, id); + if (rid < 0) { + /* + * Either it is a remote job which cannot be + * cancelled based on job-id or job-id is + * not found + */ + exit_code = 1; + fprintf(OUT, "%s-%d: %s\n", + printer, id, gettext("not-found")); + } else { + status = papiJobCancel(svc, printer, rid); + if (status == PAPI_NOT_AUTHORIZED) { + mesg = papiStatusString(status); + exit_code = 1; + } else if (status != PAPI_OK) { + mesg = gettext( + verbose_papi_message( + svc, status)); + exit_code = 1; + } + fprintf(OUT, "%s-%d: %s\n", printer, id, mesg); + } + + } else { /* it's a printer */ + if (user == NULL) { + + /* Remove first job from printer */ + + status = papiPrinterListJobs(svc, printer, + NULL, NULL, 0, &jobs); + + if (status != PAPI_OK) { + fprintf(stderr, gettext( + "ListJobs %s: %s\n"), printer, + verbose_papi_message(svc, status)); + exit_code = 1; + } + + if (jobs != NULL && *jobs != NULL) { + char *mesg = gettext("cancelled"); + id = papiJobGetId(*jobs); + + status = papiJobCancel(svc, + printer, id); + + if (status == PAPI_NOT_AUTHORIZED) { + mesg = papiStatusString(status); + exit_code = 1; + } else if (status != PAPI_OK) { + mesg = gettext( + verbose_papi_message( + svc, status)); + exit_code = 1; + } + /* + * If job-id-requested exists for this + * job-id then that should be displayed + */ + rid = get_job_id_requested(*jobs); + if (rid >= 0) + fprintf(OUT, "%s-%d: %s\n", + printer, rid, mesg); + else + fprintf(OUT, "%s-%d: %s\n", + printer, id, mesg); + } + papiJobListFree(jobs); + + } else { + /* Purging user's print jobs */ + exit_code = cancel_jobs_for_user(user, + encryption, printer); + } + } + papiServiceDestroy(svc); + } + + if (optind == ac) + exit_code = cancel_jobs_for_user(user, encryption, NULL); + + 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..5df4e3b9b7 --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/common.c @@ -0,0 +1,678 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: common.c 162 2006-05-08 14:17:44Z njacobs $ */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.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); +} + +/* + * return 0 : argument passed is job-id && job-id matches + * or argument passed is user + */ +static int +match_job_rid(int id, int ac, char *av[]) +{ + int i; + + for (i = 0; i < ac; i++) + if (isdigit(av[i][0]) != 0) { + if (id == atoi(av[i])) + /* job-id match */ + return (0); + } else + /* argument passed is user */ + return (0); + return (-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} +}; + +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); +} + +/* + * 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) || + (state == 0x06) || + (state == 0x07) || + (state == 0x08)) /* 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) papiAttributeListGetInteger(list, NULL, + "job-id-requested", &id); + (void) papiAttributeListGetString(list, NULL, + "job-originating-user-name", &user); + (void) papiAttributeListGetString(list, NULL, + "job-originating-host-name", &host); + + /* 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 = -1; + int rid = -1; + char *user = ""; + char *mesg = gettext("cancelled"); + int i = 0; + + papiAttributeListGetInteger(list, NULL, + "job-id", &id); + papiAttributeListGetInteger(list, NULL, + "job-id-requested", &rid); + 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) && + (match_job(rid, user, ac, av) < 0)) + return; + + /* + * A remote lpd job should be cancelled only based on + * job-id-requested + */ + if (rid != -1) { + if (match_job_rid(rid, ac, av) == -1) + /* job-id mismatch */ + return; + } + + status = papiJobCancel(svc, printer, id); + if (status != PAPI_OK) + mesg = papiStatusString(status); + + if (rid != -1) + fprintf(fp, "%s-%d: %s\n", printer, rid, mesg); + else + 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-id", + "job-originating-user-name", "job-id-requested", + "job-originating-host-name", + "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", + "job-id-requested", 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, char *prefetch, int len, + 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); + + if (len > 0) + status = papiJobStreamWrite(svc, stream, prefetch, len); + + 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); +} + +/* + * is_postscript() will detect if the file passed in contains postscript + * data. A one is returned if the file contains postscript, zero is returned + * if the file is not postscript, and -1 is returned if an error occurs + */ +#define PS_MAGIC "%!" +#define PC_PS_MAGIC "^D%!" +int +is_postscript_stream(int fd, char *buf, int *len) +{ + if ((*len = read(fd, buf, *len)) < 0) { + close(fd); + return (-1); + } + + if ((strncmp(buf, PS_MAGIC, sizeof (PS_MAGIC) - 1) == 0) || + (strncmp(buf, PC_PS_MAGIC, sizeof (PC_PS_MAGIC) - 1) == 0)) + return (1); + else + return (0); +} + +int +is_postscript(const char *file) +{ + int rc = -1; + int fd; + + if ((fd = open(file, O_RDONLY)) >= 0) { + char buf[3]; + int len = sizeof (buf); + + rc = is_postscript_stream(fd, buf, &len); + close(fd); + } + + return (rc); +} + +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); +} + +int32_t +job_to_be_queried(papi_service_t svc, char *printer, int32_t id) +{ + papi_job_t *jobs = NULL; + papi_status_t status; + int ret = -1; + char *jattrs[] = { "job-id", + "job-id-requested", NULL }; + + status = papiPrinterListJobs(svc, printer, jattrs, PAPI_LIST_JOBS_ALL, + 0, &jobs); + + if (status != PAPI_OK) { + fprintf(stderr, gettext("Failed to query service for %s: %s\n"), + printer, verbose_papi_message(svc, status)); + return (-1); + } + + if (jobs != NULL) { + int i = 0; + + for (i = 0; jobs[i] != NULL; i++) { + int32_t rid = -1; + int32_t jid = -1; + papi_attribute_t **list = + papiJobGetAttributeList(jobs[i]); + + papiAttributeListGetInteger(list, NULL, + "job-id-requested", &rid); + papiAttributeListGetInteger(list, NULL, + "job-id", &jid); + + /* + * check if id matches with either rid or jid + */ + if (rid == id) { + /* get the actual id and return it */ + papiAttributeListGetInteger(list, NULL, + "job-id", &id); + return (id); + } else if (id == jid) { + if (rid != -1) { + /* + * It is a remote lpd job + * can be cancelled only + * using rid + */ + ret = -1; + } else { + /* + * its local or + * remote ipp job + */ + return (id); + } + } + } + return (ret); + } + return (id); +} 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..a729930bd5 --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/common.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 2009 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 $ */ + +#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, + char *prefetch, int len, + papi_attribute_t **list, papi_job_t *job); + +extern char **interest_list(papi_service_t svc); +extern char *localhostname(); +extern char *lp_type_to_mime_type(char *lp_type); +extern int is_postscript(const char *file); +extern int is_postscript_stream(int fd, char *buf, int *len); + +extern int cli_auth_callback(papi_service_t svc, void *app_data); + +extern int32_t job_to_be_queried(papi_service_t svc, char *printer, int32_t id); + +#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..0b3cb71f0c --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/disable.c @@ -0,0 +1,163 @@ + +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: disable.c 146 2006-03-24 00:26:54Z njacobs $ */ + + +#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 & 0x082A) { /* If state is RS_ACTIVE */ + 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) { + printf(gettext("printer \"%s\" now disabled\n"), + printer); + } else if (status == PAPI_NOT_ACCEPTING) { + fprintf(stderr, gettext( + "Destination \"%s\" was already disabled.\n"), + printer); + exit_status = 1; + } else { + /* The operation is not supported in lpd protocol */ + if (status == PAPI_OPERATION_NOT_SUPPORTED) { + fprintf(stderr, + verbose_papi_message(svc, status)); + } else { + 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..c197337e1e --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/enable.c @@ -0,0 +1,117 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: enable.c 146 2006-03-24 00:26:54Z njacobs $ */ + + +#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) { + printf(gettext("printer \"%s\" now enabled\n"), + printer); + } else if (status == PAPI_NOT_ACCEPTING) { + fprintf(stderr, gettext( + "Destination \"%s\" was already enabled.\n"), + printer); + exit_status = 1; + } else { + /* The operation is not supported in lpd protocol */ + if (status == PAPI_OPERATION_NOT_SUPPORTED) { + fprintf(stderr, + verbose_papi_message(svc, status)); + } else { + 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..1b058ac291 --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/in.lpd.c @@ -0,0 +1,786 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: in.lpd.c 170 2006-05-20 05:58:49Z njacobs $ */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <stdarg.h> +#include <string.h> +#include <ctype.h> +#include <errno.h> +#include <syslog.h> +#include <libintl.h> +#include <pwd.h> +#include <grp.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <sys/systeminfo.h> + +#include <papi.h> +#include <uri.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. + */ + +static char * +remote_host_name(FILE *fp) +{ + struct hostent *hp; + struct sockaddr_in6 peer; + socklen_t peer_len = sizeof (peer); + int fd = fileno(fp); + int error_num; + char tmp_buf[INET6_ADDRSTRLEN]; + char *hostname; + + /* who is our peer ? */ + if (getpeername(fd, (struct sockaddr *)&peer, &peer_len) < 0) { + if ((errno != ENOTSOCK) && (errno != EINVAL)) + return (NULL); + else + return (strdup("localhost")); + } + + /* get their name or return a string containing their address */ + if ((hp = getipnodebyaddr((const char *)&peer.sin6_addr, + sizeof (struct in6_addr), AF_INET6, + &error_num)) == NULL) { + return (strdup(inet_ntop(peer.sin6_family, + &peer.sin6_addr, tmp_buf, sizeof (tmp_buf)))); + } + + hostname = strdup(hp->h_name); + if (is_localhost(hp->h_name) != 0) + return (strdup("localhost")); + + /* It must be someone else */ + return (hostname); +} + +static 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); + exit(1); +} + +static void +cleanup(char ***files, char **cf) +{ + if (*files != NULL) { + int i; + + for (i = 0; (*files)[i] != NULL; i++) { + (void) unlink((*files)[i]); + free((*files)[i]); + } + free(*files); + *files = NULL; + } + + if (*cf != NULL) { + free(*cf); + *cf = NULL; + } +} + +static papi_attribute_t ** +parse_cf(papi_service_t svc, char *cf, char **files) +{ + papi_attribute_t **list = NULL; + char previous = NULL; + char *entry; + int copies_set = 0; + int copies = 0; + + for (entry = strtok(cf, "\n"); entry != NULL; + entry = strtok(NULL, "\n")) { + char *format = NULL; + + /* count the copies */ + if ((entry[0] >= 'a') && (entry[0] <= 'z') && + (copies_set == 0) && (previous == entry[0])) + copies++; + else if ((previous >= 'a') && (previous <= 'z')) + copies_set = 1; + previous = entry[0]; + + /* process the control message */ + switch (entry[0]) { + /* RFC-1179 options */ + case 'J': /* RFC-1179 Banner Job Name */ + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "job-name", ++entry); + break; + case 'C': /* RFC-1179 Banner Class Name */ + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "rfc-1179-class", ++entry); + break; + case 'L': /* RFC-1179 Banner toggle */ + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "job-sheets", "standard"); + break; + case 'T': /* RFC-1179 Title (pr) */ + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "pr-title", ++entry); + break; + case 'H': /* RFC-1179 Host */ + /* + * use the host as known by us, not by them + * + * papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + * "job-originating-host-name", ++entry); + */ + break; + case 'P': /* RFC-1179 User */ + ++entry; + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "job-originating-user-name", entry); + papiServiceSetUserName(svc, entry); + break; + case 'M': /* RFC-1179 Mail to User */ + papiAttributeListAddBoolean(&list, PAPI_ATTR_EXCL, + "rfc-1179-mail", 1); + break; + case 'W': /* RFC-1179 Width (pr) */ + papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL, + "pr-width", atoi(++entry)); + break; + case 'I': /* RFC-1179 Indent (pr) */ + papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL, + "pr-indent", atoi(++entry)); + break; + case 'N': /* RFC-1179 Filename */ + /* could have HPUX extension embedded */ + if (entry[1] != ' ') { /* real pathname */ +#ifdef DEBUG + papiAttributeListAddString(&list, + PAPI_ATTR_EXCL, + "flist", ++entry); +#endif + } else if (entry[2] == 'O') /* HPUX lp -o options */ + papiAttributeListFromString(&list, + PAPI_ATTR_APPEND, ++entry); + break; + case 'U': /* RFC-1179 Unlink */ + break; /* ignored */ + case '1': /* RFC-1179 TROFF Font R */ + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "rfc-1179-font-r", ++entry); + break; + case '2': /* RFC-1179 TROFF Font I */ + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "rfc-1179-font-i", ++entry); + break; + case '3': /* RFC-1179 TROFF Font B */ + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "rfc-1179-font-b", ++entry); + break; + case '4': /* RFC-1179 TROFF Font S */ + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "rfc-1179-font-s", ++entry); + break; + case 'f': /* RFC-1179 ASCII file (print) */ + format = "text/plain"; + if (is_postscript(files[0]) == 1) + format = "application/postscript"; + break; + case 'l': /* RFC-1179 CATV file (print) */ + format = "application/octet-stream"; + if (is_postscript(files[0]) == 1) + format = "application/postscript"; + break; + case 'o': /* RFC-1179 Postscript file (print) */ + format = "application/postscript"; + break; + case 'p': /* RFC-1179 PR file (print) */ + format = "application/x-pr"; + papiAttributeListAddBoolean(&list, PAPI_ATTR_EXCL, + "pr-filter", 1); + break; + case 't': /* RFC-1179 TROFF file (print) */ + format = "application/x-troff"; + break; + case 'n': /* RFC-1179 DITROFF file (print) */ + format = "application/x-ditroff"; + break; + case 'd': /* RFC-1179 DVI file (print) */ + format = "application/x-dvi"; + break; + case 'g': /* RFC-1179 GRAPH file (print) */ + format = "application/x-plot"; + break; + case 'c': /* RFC-1179 CIF file (print) */ + format = "application/x-cif"; + break; + case 'v': /* RFC-1179 RASTER file (print) */ + format = "application/x-raster"; + break; + case 'r': /* RFC-1179 FORTRAN file (print) */ + format = "application/x-fortran"; + break; + /* Sun Solaris Extensions */ + case 'O': + ++entry; + { + int rd, wr; + + for (rd = wr = 0; entry[rd] != '\0'; rd++) { + if (entry[rd] == '"') + continue; + if (rd != wr) + entry[wr] = entry[rd]; + wr++; + } + entry[wr] = '\0'; + + papiAttributeListFromString(&list, + PAPI_ATTR_APPEND, entry); + } + break; + case '5': + ++entry; + switch (entry[0]) { + case 'f': /* Solaris form */ + papiAttributeListAddString(&list, + PAPI_ATTR_EXCL, + "form", ++entry); + break; + case 'H': /* Solaris handling */ + ++entry; + if (strcasecmp(entry, "hold") == 0) + papiAttributeListAddString(&list, + PAPI_ATTR_EXCL, + "job-hold-until", "indefinite"); + else if (strcasecmp(entry, "immediate") == 0) + papiAttributeListAddString(&list, + PAPI_ATTR_EXCL, + "job-hold-until", "no-hold"); + else + papiAttributeListAddString(&list, + PAPI_ATTR_EXCL, + "job-hold-until", entry); + break; + case 'p': /* Solaris notification */ + papiAttributeListAddBoolean(&list, + PAPI_ATTR_EXCL, "rfc-1179-mail", 1); + break; + case 'P': { /* Solaris page list */ + char buf[BUFSIZ]; + + snprintf(buf, sizeof (buf), "page-ranges=%s", + ++entry); + papiAttributeListFromString(&list, + PAPI_ATTR_EXCL, buf); + } + break; + case 'q': { /* Solaris priority */ + int i = atoi(++entry); + + i = 100 - (i * 2.5); + if ((i < 1) || (i > 100)) + i = 50; + papiAttributeListAddInteger(&list, + PAPI_ATTR_EXCL, "job-priority", i); + } + break; + case 'S': /* Solaris character set */ + papiAttributeListAddString(&list, + PAPI_ATTR_EXCL, "lp-charset", + ++entry); + break; + case 'T': /* Solaris type */ + format = lp_type_to_mime_type(++entry); + break; + case 'y': /* Solaris mode */ + papiAttributeListAddString(&list, + PAPI_ATTR_APPEND, "lp-modes", ++entry); + break; + default: + syslog(LOG_INFO|LOG_DEBUG, + "Warning: cf message (%s) ignored", + entry); + break; + } + break; + /* Undefined Extensions: SCO, Ultrix, AIX, ... */ + + default: + syslog(LOG_INFO|LOG_DEBUG, + "Warning: cf message (%s) ignored", entry); + break; + } + + if (format != NULL) + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "document-format", format); + } + + papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL, + "copies", ++copies); + papiAttributeListAddString(&list, PAPI_ATTR_EXCL, + "job-sheets", "none"); + + return (list); +} + +static papi_status_t +submit_job(papi_service_t svc, FILE *ifp, char *printer, int rid, char *cf, + char **files) +{ + papi_attribute_t **list = NULL; + papi_status_t status; + papi_job_t job = NULL; + char *format = ""; + + if ((list = parse_cf(svc, cf, files)) != NULL) { + /* use the host as known by us, not by them */ + char *host = remote_host_name(ifp); + + if (host != NULL) { + papiAttributeListAddString(&list, PAPI_ATTR_REPLACE, + "job-originating-host-name", host); + free(host); + } + if (rid >= 0) { + papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL, + "job-id-requested", rid); + } + } + + status = papiJobSubmit(svc, printer, list, NULL, files, &job); + syslog(LOG_DEBUG, "submit: %s", papiStatusString(status)); + if (status != PAPI_OK) { + char *tmp = papiServiceGetStatusMessage(svc); + + syslog(LOG_DEBUG, "submit-detail: %s", tmp ? tmp : "none"); + } + papiJobFree(job); + + return (status); +} + +static char * +receive_control_file(papi_service_t svc, FILE *ifp, FILE *ofp, int size) +{ + char *ptr, *cf_data; + + if ((ptr = cf_data = calloc(1, size + 1)) == NULL) { + NACK(ofp); + return (NULL); + } else + ACK(ofp); + + while (size > 0) { + int rc; + + if (((rc = fread(ptr, 1, size, ifp)) == 0) && + (feof(ifp) != 0)) { + free(cf_data); + return (NULL); + } else { + ptr += rc; + size -= rc; + } + } + syslog(LOG_DEBUG, "cf_data(%s)", cf_data); + + if (fgetc(ifp) != 0) { + free(cf_data); + return (NULL); + } + ACK(ofp); + + return (cf_data); +} + +static char * +receive_data_file(FILE *ifp, FILE *ofp, int size) +{ + char file[] = "lpdXXXXXX"; + char buf[BUFSIZ]; + int fd; + + if ((fd = mkstemp(file)) < 0) { + NACK(ofp); + return (NULL); + } else + ACK(ofp); + + while (size > 0) { + int rc = ((size > BUFSIZ) ? BUFSIZ : size); + + if (((rc = fread(buf, 1, rc, ifp)) == 0) && + (feof(ifp) != 0)) { + close(fd); + unlink(file); + return (NULL); + } else { + char *ptr = buf; + + while (rc > 0) { + int wrc = write(fd, ptr, rc); + + if (wrc < 0) { + close(fd); + unlink(file); + return (NULL); + } + + ptr += wrc; + size -= wrc; + rc -= wrc; + } + } + } + close(fd); + if (fgetc(ifp) != 0) { + unlink(file); + return (NULL); + } + ACK(ofp); + + return (strdup(file)); +} + +static papi_status_t +berkeley_receive_files(papi_service_t svc, FILE *ifp, FILE *ofp, char *printer) +{ + papi_status_t status = PAPI_OK; + char *file, **files = NULL; /* the job data files */ + char *cf = NULL; + int rid = 0; + char buf[BUFSIZ]; + + while (fgets(buf, sizeof (buf), ifp) != NULL) { + int size; + + syslog(LOG_DEBUG, "XFER CMD: (%d)%s\n", buf[0], &buf[1]); +#ifdef DEBUG /* translate [1-3]... messages to \[1-3] to run by hand */ + if ((buf[0] > '0') && (buf[0] < '4')) + buf[0] -= '0'; +#endif + switch (buf[0]) { + case 0x01: /* Abort */ + cleanup(&files, &cf); + break; + case 0x02: { /* Receive control file */ + if (((cf = strchr(buf, ' ')) != NULL) && + (strlen(cf) > 4)) { + while ((*cf != NULL) && (isdigit(*cf) == 0)) + cf++; + rid = atoi(cf); + } + cf = receive_control_file(svc, ifp, ofp, atoi(&buf[1])); + if (cf == NULL) { + cleanup(&files, &cf); + return (PAPI_BAD_REQUEST); + } else if (files != NULL) { + status = submit_job(svc, ifp, printer, rid, cf, + files); + cleanup(&files, &cf); + } + } + break; + case 0x03: { /* Receive data file */ + file = receive_data_file(ifp, ofp, atoi(&buf[1])); + if (file == NULL) { + cleanup(&files, &cf); + return (PAPI_TEMPORARY_ERROR); + } + list_append(&files, file); + } + break; + default: + cleanup(&files, &cf); + fatal(ofp, "protocol screwup"); + break; + } + } + + if ((cf != NULL) && (files != NULL)) + status = submit_job(svc, ifp, printer, rid, cf, files); + + cleanup(&files, &cf); + + return (status); +} + +static papi_status_t +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-jobs", 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-jobs", &accepting); + + if (accepting == PAPI_TRUE) { + ACK(ofp); + status = berkeley_receive_files(svc, ifp, ofp, printer); + } else + NACK(ofp); + + papiPrinterFree(p); + } else + NACK(ofp); + + return (status); +} + +static int +cyclical_service_check(char *svc_name) +{ + papi_attribute_t **list; + uri_t *uri = NULL; + char *s = NULL; + + /* was there a printer? */ + if (svc_name == NULL) + return (0); + + if ((list = getprinterbyname(svc_name, NULL)) == NULL) + return (0); /* if it doesnt' resolve, we will fail later */ + + papiAttributeListGetString(list, NULL, "printer-uri-supported", &s); + if ((s == NULL) || (strcasecmp(svc_name, s) != 0)) + return (0); /* they don't match */ + + /* is it in uri form? */ + if (uri_from_string(s, &uri) < 0) + return (0); + + if ((uri == NULL) || (uri->scheme == NULL) || (uri->host == NULL)) { + uri_free(uri); + return (0); + } + + /* is it in lpd form? */ + if (strcasecmp(uri->scheme, "lpd") != 0) { + uri_free(uri); + return (0); + } + + /* is it the local host? */ + if (is_localhost(uri->host) != 0) { + uri_free(uri); + return (0); + } + + uri_free(uri); + return (1); +} + + +/* + * 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; + FILE *ofp = stdout; + int c; + char buf[BUFSIZ]; + char **args; + char *printer; + char *run_dir = "/var/run/in.lpd"; + char *run_user = NULL; + struct passwd *pw = NULL; + + (void) chdir("/tmp"); /* run in /tmp by default */ + openlog("bsd-gw", LOG_PID, LOG_LPR); + + while ((c = getopt(ac, av, "Ed:u:")) != EOF) + switch (c) { + case 'E': + encryption = PAPI_ENCRYPT_ALWAYS; + break; + case 'd': /* run where they tell you */ + run_dir = optarg; + break; + case 'u': /* run as */ + run_user = optarg; + break; + default: + ; + } + + if (run_user != NULL) /* get the requested user info */ + pw = getpwnam(run_user); + + if (run_dir != NULL) { /* setup the run_dir */ + (void) mkdir(run_dir, 0700); + if (pw != NULL) + (void) chown(run_dir, pw->pw_uid, pw->pw_gid); + } + + if (pw != NULL) { /* run as the requested user */ + syslog(LOG_DEBUG, "name: %s, uid: %d, gid: %d", + pw->pw_name, pw->pw_uid, pw->pw_gid); + initgroups(pw->pw_name, pw->pw_gid); + setgid(pw->pw_gid); + setuid(pw->pw_uid); + } + + if (run_dir != NULL) /* move to the run_dir */ + if (chdir(run_dir) < 0) { + syslog(LOG_DEBUG, "failed to chdir(%s)", run_dir); + exit(1); + } + + syslog(LOG_DEBUG, "$CWD = %s", getwd(NULL)); + + if (fgets(buf, sizeof (buf), ifp) == NULL) { + if (feof(ifp) == 0) + syslog(LOG_ERR, "Error reading from connection: %s", + strerror(errno)); + exit(1); + } + + syslog(LOG_DEBUG, "CMD: (%d)%s\n", buf[0], &buf[1]); + +#ifdef DEBUG /* translate [1-5]... messages to \[1-5] to run by hand */ + if ((buf[0] > '0') && (buf[0] < '6')) + buf[0] -= '0'; +#endif + + 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); + } + + if (cyclical_service_check(printer) != 0) { + fatal(ofp, "%s is cyclical\n", 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); + } + + /* + * 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. + */ + (void) papiServiceSetPeer(svc, fileno(ifp)); + + switch (buf[0]) { + case '\1': /* restart printer */ + ACK(ofp); /* there is no equivalent */ + break; + case '\2': /* transfer job(s) */ + status = 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 *user = *args++; + char *host = remote_host_name(ifp); + int count; + + if (host != NULL) { + char buf[BUFSIZ]; + + snprintf(buf, sizeof (buf), "%s@%s", user, host); + status = papiServiceSetUserName(svc, buf); + } else + status = papiServiceSetUserName(svc, user); + + 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)); + if (status != PAPI_OK) + 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..9ec5d0fed2 --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/lp.c @@ -0,0 +1,334 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL 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) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + * + */ + +/* $Id: lp.c 179 2006-07-17 18:24:07Z njacobs $ */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <locale.h> +#include <libintl.h> +#include <papi.h> +#include "common.h" +#include <pwd.h> +#include <grp.h> +#include <sys/types.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); +} + +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 prefetch[3]; + int prefetch_len = sizeof (prefetch); + char *printer = NULL; + char b = PAPI_TRUE; + int copy = 0; + int silent = 0; + int dump = 0; + int validate = 0; + int modify = -1; + int c; + uid_t ruid; + struct passwd *pw; + + (void) setlocale(LC_ALL, ""); + (void) textdomain("SUNW_OST_OSCMD"); + + ruid = getuid(); + if ((pw = getpwuid(ruid)) != NULL) + (void) initgroups(pw->pw_name, pw->pw_gid); + (void) setuid(ruid); + + + 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, "immediate") == 0) + papiAttributeListAddString(&list, + PAPI_ATTR_EXCL, + "job-hold-until", "no-hold"); + else + papiAttributeListAddString(&list, + PAPI_ATTR_EXCL, + "job-hold-until", optarg); + break; + case 'P': { /* page list */ + char buf[BUFSIZ]; + + snprintf(buf, sizeof (buf), "page-ranges=%s", optarg); + papiAttributeListFromString(&list, + PAPI_ATTR_EXCL, buf); + } + 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, + "form", 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 = 100 - (i * 2.5); + if ((i < 1) || (i > 100)) { + fprintf(stderr, gettext("UX:lp: ")); + fprintf(stderr, gettext("ERROR: ")); + fprintf(stderr, gettext("Bad priority" + " value \"%s\"."), optarg); + fprintf(stderr, gettext("\n ")); + fprintf(stderr, gettext("TO FIX")); + fprintf(stderr, gettext(": ")); + fprintf(stderr, gettext("Use an integer value" + " from 0 to 39.")); + fprintf(stderr, gettext("\n")); + exit(1); + } + papiAttributeListAddInteger(&list, PAPI_ATTR_EXCL, + "job-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 (((optind + 1) == ac) && (strcmp(av[optind], "-") == 0)) + optind = ac; + + if (modify == -1) { + char *document_format = "text/plain"; + + if (optind != ac) { + /* get the mime type of the file data */ +#ifdef MAGIC_MIME + magic_t ms = NULL; + + if ((ms = magic_open(MAGIC_MIME)) != NULL) { + document_format = magic_file(ms, av[optind]); + magic_close(ms); + } +#else + if (is_postscript(av[optind]) == 1) + document_format = "application/postscript"; +#endif + } else { + if (is_postscript_stream(0, prefetch, &prefetch_len) + == 1) + document_format = "application/postscript"; + } + + 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 (dump != 0) { + printf("requesting attributes:\n"); + papiAttributeListPrint(stdout, list, "\t"); + printf("\n"); + } + + if (modify != -1) + status = papiJobModify(svc, printer, modify, list, &job); + else if (optind == ac) /* no file list, use stdin */ + status = jobSubmitSTDIN(svc, printer, prefetch, prefetch_len, + 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)) { + int32_t id = -1; + + if (printer == NULL) + papiAttributeListGetString(list, NULL, + "printer-name", &printer); + + papiAttributeListGetInteger(list, NULL, + "job-id-requested", &id); + if (id == -1) { + papiAttributeListGetInteger(list, NULL, "job-id", &id); + } + + printf(gettext("request id is %s-%d "), printer, 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..a4a89e77cc --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/lpc.c @@ -0,0 +1,561 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: lpc.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#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]; + char *idstr = args[2]; + int32_t id; + + if (destination == NULL || idstr == NULL) { + fprintf(stderr, gettext("Usage: topq (destination) (id)\n")); + return (-1); + } + id = atoi(idstr); + + 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 (((ac == 0) && (num_args == 1)) || + ((printer != NULL) && strcmp(printer, "all") == 0)) + rc = process_all(handler, av, num_args); + else if (num_args < ac) { + int i; + char *argv[4]; + + memset(argv, 0, sizeof (argv)); + argv[0] = av[0]; + + if (strcmp(av[0], "topq") == 0) { + argv[1] = av[1]; + for (i = 2; i <= ac; i++) { + argv[2] = av[i]; + process_one(handler, argv, num_args); + } + } else + for (i = 1; i <= ac; i++) { + argv[1] = av[i]; + process_one(handler, argv, num_args); + } + } else + rc = process_one(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++); + else + continue; + + if (ac > 0) + (void) process(ac - 1, 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(ac - optind - 1, &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..15cb076ef1 --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/lpmove.c @@ -0,0 +1,210 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL 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) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + */ + +/* $Id: lpmove.c 146 2006-03-24 00:26:54Z njacobs $ */ + +#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, 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 = papiPrinterPause(svc, printer, message); + if (status != PAPI_OK) { + /* + * If the user is denied the permission + * to disable then return appropriate msg + */ + char *result = NULL; + + result = papiServiceGetStatusMessage(svc); + + if (result != NULL) { + /* + * Check if user is denied + * the permission + */ + if (strstr(result, "permission denied") + != NULL) { + /* + * user is denied + * permission + */ + fprintf(stderr, "UX:lpmove: "); + fprintf(stderr, + gettext("ERROR: ")); + fprintf(stderr, gettext("You " + "aren't allowed to do" + " that.")); + fprintf(stderr, "\n\t"); + fprintf(stderr, + gettext("TO FIX")); + fprintf(stderr, ": "); + fprintf(stderr, gettext("You " + "must be logged in as " + "\"lp\" or \"root\".")); + fprintf(stderr, "\n"); + exit_code = 1; + } else { + fprintf(stderr, gettext( + "Reject %s: %s\n"), + printer, + verbose_papi_message( + svc, status)); + exit_code = 1; + } + } else { + fprintf(stderr, gettext( + "Reject %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..547e0df36f --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/lpr.c @@ -0,0 +1,276 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 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; + char prefetch[3]; + int prefetch_len = sizeof (prefetch); + 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 = "text/plain"; + 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 ((printer == NULL) && + ((printer = getenv("PRINTER")) == NULL) && + ((printer = getenv("LPDEST")) == NULL)) + printer = DEFAULT_DEST; + + if (((optind + 1) == ac) && (strcmp(av[optind], "-") == 0)) + optind = ac; + + if (optind != ac) { + /* get the mime type of the file data */ +#ifdef MAGIC_MIME + magic_t ms; + + if ((ms = magic_open(MAGIC_MIME)) != NULL) { + document_format = magic_file(ms, av[optind]); + magic_close(ms); + } +#else + if (is_postscript(av[optind]) == 1) + document_format = "application/postscript"; +#endif + } else { + if (is_postscript_stream(0, prefetch, &prefetch_len) == 1) + document_format = "application/postscript"; + } + + 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, prefetch, prefetch_len, + 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..6f666bcc03 --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/lpstat.c @@ -0,0 +1,1444 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: lpstat.c 173 2006-05-25 04:52:06Z njacobs $ */ + + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <locale.h> +#include <libintl.h> +#include <ctype.h> +#include <pwd.h> +#include <papi.h> +#include <uri.h> +#include "common.h" +#include "lp.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) +{ + 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")); + } else + printf(gettext("scheduler is running\n")); + papiServiceDestroy(svc); + + return (0); +} + +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 void +print_description(papi_attribute_t **list, char *printer_name) +{ + char *str = ""; + + (void) papiAttributeListGetString(list, NULL, + "printer-info", &str); + + /* + * If no printer-info is read then + * by default the printer-info is <printer-name>@<server> + */ + if (str[0] == '\0') { + char *uri = NULL; + uri_t *u = NULL; + + (void) papiAttributeListGetString(list, 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)) + printf(gettext("\tDescription:\n")); + else + printf(gettext("\tDescription: %s@%s\n"), + printer_name, u->host); + + uri_free(u); + } else + printf(gettext("\tDescription:\n")); + } else + printf(gettext("\tDescription: %s\n"), str); +} + +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?u->host:"localhost", 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 int +get_remote_hostname(papi_attribute_t **attrs, char **host) +{ + char *uri = NULL; + uri_t *u; + char *nodename; + + *host = NULL; + (void) papiAttributeListGetString(attrs, NULL, + "job-originating-host-name", host); + (void) papiAttributeListGetString(attrs, NULL, + "printer-uri-supported", &uri); + if (*host == NULL) { + if (uri != NULL) { + if (uri_from_string(uri, &u) == 0) { + if (u->host == NULL) { + uri_free(u); + return (0); + } + *host = strdup(u->host); + uri_free(u); + } else { + return (0); + } + } else { + return (0); + } + } + nodename = localhostname(); + if ((strcasecmp(*host, "localhost") == 0) || + (strcasecmp(*host, nodename) == 0)) { + return (0); + } + return (1); +} + +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; + papi_job_t *j = 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("is idle. enabled")); + break; + case 0x04: /* processing */ + case 0x06: /* faulted printing */ + status = papiPrinterListJobs(svc, name, NULL, + 0, 0, &j); + + if (status == PAPI_OK) { + if (j != NULL) { + int i = 0; + int32_t jobid = 0; + int32_t jstate = 0; + + for (i = 0; j[i] != NULL; ++i) { + papi_attribute_t **attr = + papiJobGetAttributeList(j[i]); + + papiAttributeListGetInteger(attr, + NULL, "job-state", &jstate); + papiAttributeListGetInteger(attr, + NULL, "job-id", &jobid); + /* + * For lpd protocol "job-id-requested" + * should be read. + */ + papiAttributeListGetInteger(attr, + NULL, "job-id-requested", &jobid); + + /* + * When lpd protocol is used job-state + * cannot be retrieved, therefore + * job-state will be 0. + * When ipp protocol is used, the + * active/printing job-state will be + * RS_PRINTING (0x0008) post s10u5. + * For pre-s10u5 job-state will be + * RS_ACTIVE (0x05). So print only when + * the job-state is RS_PRINTING (0x0008) + * or RS_ACTIVE (0x05) or 0 + */ + if ((jstate == 0x0008) || + (jstate == 0x05) || + (jstate == 0)) { + if (pstat == 0x04) + printf(gettext + ("now printing"\ + " %s-%d. enabled"), + name, jobid); + if (pstat == 0x06) + printf(gettext + ("faulted printing"\ + " %s-%d. enabled"), + name, jobid); + break; + } + } + papiJobListFree(j); + } + } + break; + case 0x05: /* stopped */ + printf(gettext("disabled")); + break; + case 0x07: /* faulted printer */ + printf(gettext("faulted. enabled")); + break; + case 0x08: /* waiting for auto retry */ + printf(gettext("waiting for auto-retry.")); + break; + default: + printf(gettext("unknown state(0x%x)."), pstat); + break; + } + + if (pstat == 0x08) + printf(gettext(" available.\n")); + else { + (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) || + (pstat == 0x06) || + (pstat == 0x07) || + (pstat == 0x08)) { + 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; + char *host = NULL; + + if ((get_remote_hostname(attrs, &host)) != 0) { + (void) printf( + gettext("\tRemote Name: %s\n\tRemote Server: " + "%s\n"), name, host); + free(host); + return (0); + } + 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"); + + /* Display the printer description */ + print_description(attrs, name); + + str = ""; + iter = NULL; + (void) papiAttributeListGetString(attrs, &iter, + "lpsched-printer-type", &str); + printf(gettext("\tPrinter types: %s"), str); + while (papiAttributeListGetString(attrs, &iter, NULL, &str) + == PAPI_OK) + printf(", %s", str); + printf("\n"); + + 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); + if ((strcasecmp(str, "none")) == 0) + str = gettext("page never printed"); + else if (strcasecmp(str, "optional") == 0) + str = gettext("not required"); + else + str = gettext("required"); + + printf(gettext("\tBanner %s\n"), str); + + + 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) + /* Display printer description */ + print_description(attrs, name); + 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, i = 0; + papi_status_t status; + papi_service_t svc = NULL; + char **list = getlist(name, LP_WS, LP_SEP); + + if (list == NULL) { + list = (char **)malloc(sizeof (char *)); + list[0] = name; + } + + /* + * The for loop executes once for every printer + * entry in list. If list is NULL that implies + * name is also NULL, the loop runs only one time. + */ + + for (i = 0; name == NULL || list[i] != NULL; i++) { + name = list[i]; + + status = papiServiceCreate(&svc, name, NULL, NULL, + cli_auth_callback, encryption, NULL); + if (status != PAPI_OK) { + if (status == PAPI_NOT_FOUND) + fprintf(stderr, + gettext("%s: unknown printer\n"), + name ? name : "(NULL)"); + else + fprintf(stderr, gettext( + "Failed to contact service for %s: %s\n"), + name ? name : "(NULL)", + verbose_papi_message(svc, status)); + papiServiceDestroy(svc); + result--; + continue; + } + + 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); + result--; + continue; + } + + if (printer != NULL) + result += report(svc, name, printer, verbose, + description); + + papiPrinterFree(printer); + } + + papiServiceDestroy(svc); + + if (name == NULL) + break; + } + + freelist(list); + + 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(char *printer, 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"; + char *host = NULL; + int32_t size = 0; + int32_t jstate = 0; + char User[50]; + + char *destination = "unknown"; + int32_t id = -1; + static int check = 0; + static char *uri = NULL; + static char *puri = NULL; /* printer-uri */ + static char *pname = NULL; /* printer-name */ + + (void) papiAttributeListGetString(attrs, NULL, + "job-originating-user-name", &user); + + if ((users != NULL) && (match_user(user, users) < 0)) + return (0); + + (void) papiAttributeListGetString(attrs, NULL, + "job-originating-host-name", &host); + + /* + * When lpstat is called for multiple printers + * internally the function 'report_job' gets + * called multiple times with different printer-names. + * The following block of code handles the case when lpstat is + * executed for multiple printers. In other words when 'report_job' + * is called multiple times for different printers for + * one lpstat command + * For e.g: lpstat printer1 printer2 printer3 + */ + if (pname == NULL) { + /* + * When lpstat is queried for the first time + * pname is NULL so this part of the code gets executed. + * Read the attribute "job-printer-uri" + * first time + */ + (void) papiAttributeListGetString(attrs, NULL, + "job-printer-uri", &uri); + + if (printer != NULL) { + /* + * Set pname to the printer that is being + * queried so that this can be used later + * if 'report_job' is called multiple times for + * different printers for one lpstat command + */ + pname = printer; + } + + if (uri != NULL) { + /* + * Set puri so that "job-printer-uri" corresponding + * to a particular printer can be used later when + * lpstat is queried for the same printer as + * "job-printer-uri" for a printer is read just once. + */ + puri = strdup(uri); + } + } else { + /* + * This part of the code will get executed when + * 'report_job' is called more than once for the same + * lpstat command + */ + if (printer != NULL) { + if (strcasecmp(pname, printer) != 0) { + /* + * Read the job-printer-uri as + * it will be different for + * different printers + */ + uri = NULL; + (void) papiAttributeListGetString(attrs, + NULL, "job-printer-uri", &uri); + pname = printer; + if (uri != NULL) + puri = strdup(uri); + else + puri = NULL; + } else { + /* + * Same printer queried twice + * uri should be the same as + * already read in the previous call + * to 'report_job'. + * For the same printer 'job-printer-uri' + * is read just once because only in the + * first call it contains the host information + */ + uri = puri; + } + } + } + + if (host) { + /* Check if it is local printer or remote printer */ + uri_t *u = NULL; + + 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)) { + + if (strcasecmp(host, nodename) == 0) { + /* + * Request submitted locally + * for the local queue. + * Hostname will not be displayed + */ + snprintf(User, sizeof (User), "%s", + user); + } + else + snprintf(User, sizeof (User), "%s@%s", + user, host); + } else if (uri != NULL) { + /* + * It's a remote printer. + * In case of remote printers hostname is + * always displayed. + */ + snprintf(User, sizeof (User), "%s@%s", + user, host); + } + uri_free(u); + } else { + /* + * If attribute "job-printer-uri" + * cannot be read + * by default append the hostname + */ + snprintf(User, sizeof (User), "%s@%s", user, host); + } + } else { + /* + * When print server is s10u4 and ipp service is used + * "job-originating-hostname" attribute is not set + * So get the host information from the uri + */ + uri_t *u = NULL; + if ((uri != NULL) && (uri_from_string(uri, &u) == 0)) { + if ((u != NULL) && (u->host != NULL)) + snprintf(User, sizeof (User), "%s@%s", + user, u->host); + else + snprintf(User, sizeof (User), "%s", user); + + uri_free(u); + } else + snprintf(User, sizeof (User), "%s", user); + } + (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); + (void) papiAttributeListGetInteger(attrs, NULL, + "job-id-requested", &id); + + + snprintf(request, sizeof (request), "%s-%d", printer, 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 == 0x0001) + printf(gettext(" being held")); + else if (jstate == 0x0800) + printf(gettext(" notifying user")); + else if (jstate == 0x0040) + printf(gettext(" cancelled")); + else if (jstate == 0x0010) + printf(gettext(" finished printing")); + else if (jstate == 0x0008) + printf(gettext(" on %s"), destination); + else if (jstate == 0x2000) + printf(gettext(" held by admin")); + else if (jstate == 0x0002) + printf(gettext(" being filtered")); + else if (jstate == 0x0004) + printf(gettext(" filtered")); + else if (jstate == 0x0020) + printf(gettext(" held for change")); + + if (verbose == 1) { + char *form = NULL; + + (void) papiAttributeListGetString(attrs, NULL, + "output-device-assigned", &destination); + printf("\n\t assigned %s", destination); + + (void) papiAttributeListGetString(attrs, NULL, "form", &form); + if (form != NULL) + printf(", form %s", form); + } else if (verbose > 1) { + printf("\n"); + papiAttributeListPrint(stdout, attrs, "\t"); + } + + printf("\n"); + + return (0); +} + +static int +job_query(char *request, int (*report)(char *, 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 = request; + int32_t id = -1; + int flag1 = 0; + int flag = 1; + int print_flag = 0; + + do { + status = papiServiceCreate(&svc, printer, NULL, NULL, + cli_auth_callback, encryption, NULL); + + if ((status == PAPI_OK) && (printer != NULL)) + print_flag = 1; + + /* <name>-# printer name does not exist */ + if (status != PAPI_OK) { + /* + * Check if <name>-# is a request-id + * Once this check is done flag1 is set + */ + if (flag1 == 1) + break; + + get_printer_id(printer, &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(printer, + jobs[i], show_rank, + verbose); + } + + papiJobListFree(jobs); + } else { /* a job */ + papi_job_t job = NULL; + + /* Once a job has been found stop processing */ + flag = 0; + + /* + * Job-id could be the job-id requested + * Check if it is job-id or job-id-requested + */ + id = job_to_be_queried(svc, printer, id); + + if (id >= 0) + status = papiJobQuery(svc, printer, id, + NULL, &job); + else + /* id not found */ + status = PAPI_NOT_FOUND; + + if (status != PAPI_OK) { + if (!print_flag) + 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(printer, job, + show_rank, verbose); + + papiJobFree(job); + } + + if (flag) { + id = -1; + get_printer_id(printer, &printer, &id); + if (id == -1) + flag = 0; + else + flag1 = 1; + } + } while (flag); + + 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++) { + if ((av[c][0] == '-') && (av[c][1] == 'l') && + (isalpha(av[c][2]) != 0)) { + /* preserve old "-l[po...]" behavior */ + argv[c] = &av[c][1]; + argv[c][0] = '-'; + verbose = 1; + + } else + 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) { /* 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 '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 'R': /* set "rank" flag in first pass */ + 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 '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..2952bafba6 --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/reject.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 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +/* $Id: reject.c 146 2006-03-24 00:26:54Z njacobs $ */ + + +#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) { + printf(gettext( + "Destination \"%s\" will no longer " + "accept requests\n"), printer); + } else if (status == PAPI_NOT_ACCEPTING) { + fprintf(stderr, gettext( + "Destination \"%s\" was already not " + "accepting requests.\n"), printer); + exit_status = 1; + } else { + /* The operation is not supported in lpd protocol */ + if (status == PAPI_OPERATION_NOT_SUPPORTED) { + fprintf(stderr, + verbose_papi_message(svc, status)); + } else { + 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/bsd-sysv-commands/rfc1179.xml b/usr/src/cmd/print/bsd-sysv-commands/rfc1179.xml new file mode 100644 index 0000000000..b6783bca28 --- /dev/null +++ b/usr/src/cmd/print/bsd-sysv-commands/rfc1179.xml @@ -0,0 +1,110 @@ +<?xml version='1.0'?> +<!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'> + +<!-- + CDDL HEADER START + + The contents of this file are subject to the terms of the + Common Development and Distribution License (the "License"). + You may not use this file except in compliance with the License. + + You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + or http://www.opensolaris.org/os/licensing. + See the License for the specific language governing permissions + and limitations under the License. + + When distributing Covered Code, include this CDDL HEADER in each + file and include the License file at usr/src/OPENSOLARIS.LICENSE. + If applicable, add the following below this CDDL HEADER, with the + fields enclosed by brackets "[]" replaced with your own identifying + information: Portions Copyright [yyyy] [name of copyright owner] + + CDDL HEADER END + + Copyright 2009 Sun Microsystems, Inc. All rights reserved. + Use is subject to license terms. + + NOTE: This service manifest is not editable; its contents will + be overwritten by package or patch operations, including + operating system upgrade. Make customizations in a different + file. +--> + +<service_bundle type='manifest' name='SUNWpsr:rfc1179'> + +<service + name='application/print/rfc1179' + type='service' + version='1'> + + <create_default_instance enabled='false' /> + + <restarter> + <service_fmri value='svc:/network/inetd:default' /> + </restarter> + + <dependency + name='lpsched' + grouping='require_all' + restart_on='refresh' + type='service'> + <service_fmri value='svc:/application/print/server' /> + </dependency> + + <exec_method + type='method' + name='inetd_start' + exec='/usr/lib/print/in.lpd -u lp -d /var/run/in.lpd' + timeout_seconds='0'> + <method_context> + <method_credential user='root' group='lp' /> + </method_context> + </exec_method> + + + <exec_method + type='method' + name='inetd_disable' + exec=':kill' + timeout_seconds='0'> + </exec_method> + + <property_group name='inetd' type='framework'> + <stability value='Evolving' /> + <propval name='endpoint_type' type='astring' value='stream' /> + <propval name='name' type='astring' value='printer' /> + <propval name='wait' type='boolean' value='false' /> + <propval name='isrpc' type='boolean' value='false' /> + <propval name='proto' type='astring' value='tcp6' /> + </property_group> + + <property_group name='general' type='framework'> + <!-- to start/stop rfc1179 listening --> + <propval name='action_authorization' type='astring' + value='solaris.print.admin' /> + <propval name='value_authorization' type='astring' + value='solaris.print.admin' /> + </property_group> + + <property_group name='firewall_context' type='com.sun,fw_definition'> + <propval name='ipf_method' type='astring' + value='/lib/svc/method/print-svc ipfilter svc:/application/print/server:default' /> + </property_group> + + <stability value='Unstable' /> + + <template> + <common_name> + <loctext xml:lang='C'> + BSD print protocol adapter + </loctext> + </common_name> + <documentation> + <manpage title='in.lpd' section='1M' + manpath='/usr/share/man' /> + </documentation> + </template> + +</service> + +</service_bundle> |