summaryrefslogtreecommitdiff
path: root/usr/src/cmd/print/lpstat/sysv-functions.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/print/lpstat/sysv-functions.c')
-rw-r--r--usr/src/cmd/print/lpstat/sysv-functions.c619
1 files changed, 619 insertions, 0 deletions
diff --git a/usr/src/cmd/print/lpstat/sysv-functions.c b/usr/src/cmd/print/lpstat/sysv-functions.c
new file mode 100644
index 0000000000..35520fddd3
--- /dev/null
+++ b/usr/src/cmd/print/lpstat/sysv-functions.c
@@ -0,0 +1,619 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 1998-2001 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <sys/wait.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <errno.h>
+#include <unistd.h>
+#include <syslog.h>
+#ifndef SUNOS_4
+#include <libintl.h>
+#endif
+
+#include <print/ns.h>
+#include <print/list.h>
+#include <print/misc.h>
+#include <print/job.h>
+#include <print/network.h>
+
+#include "parse.h"
+#include "sysv-functions.h"
+
+extern char *getenv(const char *);
+
+static print_queue_t **_queue_list = NULL;
+
+static int sysv_displayLocalLPSTAT(char *pname, char *aname);
+
+#define ALL "all"
+static int
+compair_user(char *full, char *user, char *host)
+{
+ char *u1,
+ *h1;
+
+ if (full == NULL)
+ return (0);
+
+ if ((strcmp(full, ALL) == 0) || strcmp(full, user) == 0)
+ return (0);
+ if ((u1 = strchr(full, '!')) == NULL)
+ return (-1);
+ h1 = strcdup(full, '!');
+ u1++;
+ if (((strcmp(u1, ALL) == 0) || (strcmp(u1, user) == 0)) &&
+ (strcmp(h1, host) == 0)) {
+ free(h1);
+ return (0);
+ }
+ if (((strcmp(h1, ALL) == 0) || (strcmp(h1, host) == 0)) &&
+ (strcmp(u1, user) == 0)) {
+ free(h1);
+ return (0);
+ }
+ free(h1);
+ return (-1);
+}
+
+
+static int
+compair_queue_binding(print_queue_t *queue, ns_bsd_addr_t *binding)
+{
+ if ((queue == NULL) || (binding == NULL))
+ return (-1);
+ if ((strcmp(queue->binding->printer, binding->printer) == 0) &&
+ (strcmp(queue->binding->server, binding->server) == 0))
+ return (0);
+ return (-1);
+}
+
+
+
+static char *
+get_queue_buffer(ns_bsd_addr_t *binding)
+{
+ char *q = NULL,
+ *p = NULL,
+ *server,
+ *printer;
+ int nd,
+ rc,
+ count = 0,
+ q_size = 0,
+ p_left = 0;
+
+ server = binding->server;
+ printer = binding->printer;
+
+ if ((nd = net_open(server, 15)) < 0) {
+ char err[128];
+
+ (void) snprintf(err, sizeof (err),
+ gettext("server %s not responding\n\n"),
+ server);
+ return (strdup(err));
+ }
+
+ rc = net_printf(nd, "%c%s \n", SHOW_QUEUE_LONG_REQUEST, printer);
+ if (rc < 0)
+ syslog(LOG_ERR, "net_printf() failed: %m");
+
+ do {
+ p += count;
+ if ((p_left -= count) < 10) {
+ char *t;
+
+#ifdef SUNOS_4
+ if (q == NULL) {
+ p = q = malloc(BUFSIZ);
+ (void) memset(p, NULL, BUFSIZ);
+ q_size = BUFSIZ;
+ } else {
+ q_size += BUFSIZ;
+ t = malloc(q_size);
+ (void) memset(t, NULL, q_size);
+ strcpy(t, q);
+ free(q);
+ p = t + (p - q);
+ q = t;
+ }
+#else
+ if ((t = (char *)realloc(q, q_size += BUFSIZ)) != q) {
+ p = t + (p - q);
+ q = t;
+ }
+#endif
+ p_left += BUFSIZ;
+ (void) memset(p, NULL, p_left);
+ }
+ } while ((count = net_read(nd, p, p_left)) > 0);
+
+ (void) net_close(nd);
+
+ return (q);
+}
+
+
+
+print_queue_t *
+sysv_get_queue(ns_bsd_addr_t *binding, int local)
+{
+ print_queue_t *qp = NULL;
+ char *buf;
+
+ if (_queue_list != NULL) /* did we already get it ? */
+ if ((qp = (print_queue_t *)list_locate((void **)_queue_list,
+ (COMP_T)compair_queue_binding, binding)) != NULL)
+ return (qp);
+
+ if (local == 0)
+ buf = (char *)get_queue_buffer(binding);
+ else
+ buf = strdup("no entries\n");
+
+ if (buf != NULL) {
+ qp = parse_bsd_queue(binding, buf, strlen(buf));
+ _queue_list = (print_queue_t **)list_append((void **)
+ _queue_list, (void *)qp);
+ }
+ return (qp);
+}
+
+
+
+
+
+
+ /*
+ * SYSV (lpstat) specific routines
+ */
+
+static int
+vJobfile_size(jobfile_t *file)
+{
+ if (file != NULL)
+ return (file->jf_size);
+ return (0);
+}
+
+
+void
+vsysv_queue_entry(job_t *job, va_list ap)
+{
+ char id[128],
+ user[128],
+ *printer = va_arg(ap, char *),
+ *in_user = va_arg(ap, char *);
+ int in_id = va_arg(ap, int),
+ verbose = va_arg(ap, int),
+ *rank = va_arg(ap, int *),
+ size = 0;
+
+ if ((in_id != -1) && (in_id != job->job_id))
+ return;
+ if (compair_user(in_user, job->job_user, job->job_host) != 0)
+ return;
+
+ (void) sprintf(id, "%.16s-%-5d", printer, job->job_id);
+ (void) snprintf(user, sizeof (user), "%s@%s", job->job_user,
+ job->job_host);
+ size = list_iterate((void **)job->job_df_list, (VFUNC_T)vJobfile_size);
+ if (*rank >= 0)
+ (void) printf("%d ", (*rank)++);
+ (void) printf("%-*s %-*s %*d %s%s", (*rank >= 0 ? 20 : 22), id, 15,
+ user, 7, size, (*rank >= 0 ? "" : " "), short_date());
+ if (verbose == 0) {
+ if (*rank == 1)
+ (void) printf(" on %s", printer);
+ (void) printf("\n");
+ } else
+ (void) printf("\n\t%s %s\n",
+ ((*rank > 1) ? "on" : "assigned"), printer);
+}
+
+
+#define OLD_LPSTAT "/usr/lib/lp/local/lpstat" /* for -c -f -S */
+#ifdef OLD_LPSTAT
+static int
+local_printer(char *name)
+{
+ char buf[128];
+
+ (void) snprintf(buf, sizeof (buf),
+ "/etc/lp/printers/%s/configuration", name);
+ return (access(buf, F_OK));
+}
+
+static int
+local_class(char *name)
+{
+ char buf[128];
+
+ (void) snprintf(buf, sizeof (buf),
+ "/etc/lp/classes/%s", name);
+ return (access(buf, F_OK));
+}
+
+int
+sysv_local_status(char *option, char *arg, int verbose,
+ int description, char *invalid)
+{
+ pid_t stat;
+
+ if (access(OLD_LPSTAT, F_OK) == 0) {
+ char buf[BUFSIZ];
+
+ /*
+ * Need the fflush to preserve output order when
+ * output re-directed to a file. Close of old lpstat
+ * flushes buffers causing old lpstat output to preceed
+ * all other output to the file.
+ */
+ (void) fflush(stdout);
+ (void) fflush(stderr);
+ (void) snprintf(buf, sizeof (buf),
+ "%s %s %s%s%s", OLD_LPSTAT, option,
+ (arg ? arg : ""), (verbose ? " -l" : ""),
+ (description ? " -D" : ""));
+ stat = system(buf);
+ if (WIFEXITED(stat)) {
+ return (WEXITSTATUS(stat));
+ } else {
+ if (stat == -1)
+ return (errno);
+ else
+ return (ENOMSG);
+ }
+ } else
+ (void) printf("%s", invalid);
+
+ return (0);
+}
+#endif
+
+
+int
+sysv_queue_state(print_queue_t *qp, char *printer, int verbose, int description)
+{
+#ifdef OLD_LPSTAT
+ pid_t stat;
+
+ if ((local_printer(printer) == 0) && (access(OLD_LPSTAT, F_OK) == 0)) {
+ char buf[BUFSIZ];
+
+ /* see sysv_local_status for reason for fflush */
+ (void) fflush(stdout);
+ (void) fflush(stderr);
+ (void) snprintf(buf, sizeof (buf),
+ "%s -p %s%s%s", OLD_LPSTAT, printer,
+ (verbose ? " -l" : ""), (description ? " -D" : ""));
+ stat = system(buf);
+ if (WIFEXITED(stat)) {
+ return (WEXITSTATUS(stat));
+ } else {
+ if (stat == -1)
+ return (errno);
+ else
+ return (ENOMSG);
+ }
+
+
+ }
+#endif
+
+ (void) printf(gettext("printer %s "), printer);
+ switch (qp->state) {
+ case IDLE:
+ (void) printf(gettext("is idle. "));
+ break;
+ case PRINTING:
+ (void) printf(gettext("now printing %s-%d. "), printer,
+ qp->jobs[0]->job_id);
+ break;
+ case FAULTED:
+ (void) printf(gettext("faulted printing %s-%d. "), printer,
+ (qp->jobs != NULL ? qp->jobs[0]->job_id : 0));
+ break;
+ case RAW:
+ (void) printf(gettext("unknown state. "));
+ break;
+ default:
+ (void) printf(gettext("disabled. "));
+ }
+ (void) printf(gettext("enabled since %s. available.\n"), long_date());
+ if (qp->state == FAULTED)
+ (void) printf("\t%s\n", qp->status);
+ if (description != 0) {
+ ns_printer_t *pobj;
+ char *desc;
+
+ if (((pobj = ns_printer_get_name(qp->binding->printer, NULL))
+ != NULL) &&
+ ((desc = ns_get_value(NS_KEY_DESCRIPTION, pobj)) != NULL))
+ (void) printf(gettext("\tDescription: %s\n"), desc);
+ else
+ (void) printf(gettext("\tDescription: %s@%s\n"),
+ qp->binding->printer, qp->binding->server);
+ }
+ if (verbose != 0)
+ (void) printf(
+ gettext("\tRemote Name: %s\n\tRemote Server: %s\n"),
+ qp->binding->printer, qp->binding->server);
+
+ return (0);
+}
+
+
+int
+sysv_accept(ns_bsd_addr_t *binding)
+{
+#ifdef OLD_LPSTAT
+ int result = 0;
+
+ if (((local_printer(binding->printer) == 0) ||
+ (local_class(binding->printer) == 0)) &&
+ (access(OLD_LPSTAT, F_OK) == 0)) {
+ /*
+ * Locally attached printer, so display its accept state using
+ * the old lpstat utility.
+ */
+ result = sysv_displayLocalLPSTAT(binding->printer,
+ binding->pname);
+ return (result);
+ }
+#endif
+
+
+ if (binding->pname != NULL)
+ (void) printf(gettext("%s accepting requests since %s\n"),
+ binding->pname, long_date());
+ else
+ (void) printf(gettext("%s accepting requests since %s\n"),
+ binding->printer, long_date());
+
+ return (0);
+}
+
+
+
+#ifdef OLD_LPSTAT
+/*
+ * FUNCTION: sysv_displayLocalLPSTAT()
+ *
+ * DESCRIPTION: This function uses the old lpstat (/usr/lib/lp/local/lpstat)
+ * utility to display the accepting state (-a option) for locally
+ * attached printers.
+ * If an alias name is given then the output from lpstat is
+ * captured and modified to show the alias name instead of the
+ * printer's real name. Note: this is done because the old lpstat
+ * can not handle alias names.
+ *
+ * PARAMETERS:
+ * Input: char *pname - printers real name
+ * char *aname - printers alias name
+ *
+ * RETURNS: 0 = completed okay, otherwise error
+ *
+ */
+
+static int
+sysv_displayLocalLPSTAT(char *pname, char *aname)
+
+{
+ int result = ENOMSG;
+ char buf[BUFSIZ];
+ FILE *fd = NULL;
+ char *tmp = NULL;
+
+ /* see sysv_local_status for reason for fflush */
+ (void) fflush(stdout);
+ (void) fflush(stderr);
+
+ if (((pname != NULL) && (aname != NULL)) &&
+ (strcmp(pname, aname) != 0))
+ {
+ /*
+ * This is a request to display status of an aliased local
+ * printer, so capture the output from the local lpstat for the
+ * real printer and then display that output with the alias
+ * name instead of the real name.
+ */
+
+ (void) snprintf(buf, sizeof (buf), "%s -a %s",
+ OLD_LPSTAT, pname);
+
+ /* execute the local lpstat utility and display output */
+
+ fd = popen(buf, "r");
+ if (fd != NULL)
+ {
+ tmp = fgets(buf, sizeof (buf), fd);
+ if (tmp != NULL)
+ {
+ result = 0;
+
+ if (strncmp(buf, pname, strlen(pname)) == 0)
+ {
+ printf("%s", aname);
+ printf("%s", &(buf[strlen(pname)]));
+
+ tmp = fgets(buf, sizeof (buf), fd);
+ }
+
+ /*
+ * finish reading and displaying the
+ * output from the lpstat utility
+ */
+
+ while (tmp != NULL)
+ {
+ printf("%s", buf);
+ tmp = fgets(buf, sizeof (buf), fd);
+ }
+ }
+
+ (void) pclose(fd);
+ }
+ }
+
+ else
+ if (pname != NULL)
+ {
+ /*
+ * Not an alias so directly display output from the
+ * local lpstat utility
+ */
+ (void) snprintf(buf, sizeof (buf), "%s -a %s",
+ OLD_LPSTAT, pname);
+ result = system(buf);
+
+ if (WIFEXITED(result))
+ {
+ result = WEXITSTATUS(result);
+ }
+ else
+ if (result == -1)
+ {
+ result = errno;
+ }
+ else
+ {
+ result = ENOMSG;
+ }
+ }
+
+ return (result);
+} /* sysv_displayLocalLPSTAT */
+#endif
+
+
+
+int
+sysv_system(ns_bsd_addr_t *binding)
+{
+ char *host;
+ char *printer;
+ pid_t stat;
+
+ if (binding->pname)
+ printer = binding->pname;
+ else
+ printer = binding->printer;
+ host = binding->server;
+#ifdef OLD_LPSTAT
+
+ if ((local_printer(printer) == 0) && (access(OLD_LPSTAT, F_OK) == 0)) {
+ char buf[BUFSIZ];
+
+ /* see sysv_local_status for reason for fflush */
+ (void) fflush(stdout);
+ (void) fflush(stderr);
+ (void) snprintf(buf, sizeof (buf),
+ "%s -v %s", OLD_LPSTAT, printer);
+ stat = system(buf);
+
+ if (WIFEXITED(stat)) {
+ return (WEXITSTATUS(stat));
+ } else {
+ if (stat == -1)
+ return (errno);
+ else
+ return (ENOMSG);
+ }
+ } else
+#endif
+ if (printer && host) {
+ if (strcmp(printer, binding->printer) == 0)
+ (void) printf(gettext("system for %s: %s\n"), printer,
+ host);
+ else
+ (void) printf(
+ gettext("system for %s: %s (as printer %s)\n"),
+ printer, host, binding->printer);
+ }
+
+ return (0);
+}
+
+
+void
+sysv_running()
+{
+ int lock;
+ struct stat st;
+
+ lock = stat("/usr/spool/lp/SCHEDLOCK", &st);
+ if (lock < 0)
+ (void) printf(gettext("scheduler is not running\n"));
+ else
+ (void) printf(gettext("scheduler is running\n"));
+}
+
+
+void
+sysv_default()
+{
+ char *printer;
+
+ if ((printer = getenv((const char *)"LPDEST")) == NULL)
+ printer = getenv((const char *)"PRINTER");
+ if (printer == NULL) {
+ ns_printer_t *p;
+
+ if ((p = ns_printer_get_name(NS_NAME_DEFAULT, NULL)) != NULL) {
+ printer = ns_get_value(NS_KEY_USE, p);
+ /*
+ * Fall back to the printer name out of
+ * the "bsdaddr" attribute
+ */
+ if (printer == NULL) {
+ ns_bsd_addr_t *a =
+ ns_get_value(NS_KEY_BSDADDR, p);
+ if ((a != NULL) && (a->printer != NULL)) {
+ static char buf[64];
+ (void) snprintf(buf, sizeof (buf), "%s",
+ a->printer);
+ printer = buf;
+ }
+ }
+ }
+ }
+ if (printer != NULL)
+ (void) printf(gettext("system default destination: %s\n"),
+ printer);
+ else
+ (void) printf(gettext("no system default destination\n"));
+}