/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL 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
{
char *name;
else
name++;
"[-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 *
{
return (buf);
}
static char *
{
if (attributes != NULL)
"printer-name", &result);
return (result);
}
static int
{
papi_printer_t p = NULL;
encryption, NULL);
if (p != NULL)
name = printer_name(p);
}
else
papiPrinterFree(p);
return (0);
}
static int
{
encryption, NULL);
} else
return (0);
}
static char *
{
papi_printer_t p = NULL;
"device-uri", &result);
papiPrinterFree(p);
}
return (result);
}
static void
{
"printer-info", &str);
/*
* If no printer-info is read then
* by default the printer-info is <printer-name>@<server>
*/
if (str[0] == '\0') {
"printer-uri-supported", &uri);
else
printer_name, u->host);
uri_free(u);
} else
} else
}
NULL };
/* ARGSUSED2 */
static int
int verbose, int description)
{
"printer-name", &name);
"printer-uri-supported", &name);
}
return (-1);
"printer-uri-supported", &uri);
return (0);
return (0);
}
uri_free(u);
}
return (0);
}
"printer-uri-supported", "printer-is-accepting-jobs",
"printer-up-time", "printer-state-time",
/* ARGSUSED2 */
static int
int verbose, int description)
{
"printer-name", &name);
"printer-uri-supported", &name);
}
return (-1);
"printer-is-accepting-jobs", &boolean);
"printer-up-time", &curr);
"printer-state-time", &curr);
"lpsched-reject-date", &curr);
} else {
"lpsched-reject-reason", &reason);
}
return (0);
}
"member-names", NULL };
/* ARGSUSED2 */
static int
int verbose, int description)
{
"member-names", &member);
return (0);
"printer-name", &name);
"printer-uri-supported", &name);
}
return (-1);
== PAPI_OK)
return (0);
}
static int
{
uri_t *u;
char *nodename;
"job-originating-host-name", host);
"printer-uri-supported", &uri);
if (uri_from_string(uri, &u) == 0) {
uri_free(u);
return (0);
}
uri_free(u);
} else {
return (0);
}
} else {
return (0);
}
}
nodename = localhostname();
return (0);
}
return (1);
}
"printer-uri-supported", "printer-state",
"printer-up-time", "printer-state-time",
"lpsched-disable-date", "printer-state-reasons",
"lpsched-disable-reason", NULL };
/* ARGSUSED2 */
static int
int verbose, int description)
{
papi_job_t *j = NULL;
"member-names", &member);
return (0);
"printer-name", &name);
"printer-uri-supported", &name);
}
return (-1);
"printer-state", &pstat);
switch (pstat) {
case 0x03: /* idle */
break;
case 0x04: /* processing */
case 0x06: /* faulted printing */
0, 0, &j);
if (j != NULL) {
int i = 0;
for (i = 0; j[i] != NULL; ++i) {
papiJobGetAttributeList(j[i]);
/*
* For lpd protocol "job-id-requested"
* should be read.
*/
/*
* When lpd protocol is used job-state
* cannot be retrieved, therefore
* job-state will be 0.
* When ipp protocol is used, the
* 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)
("now printing"\
" %s-%d. enabled"),
if (pstat == 0x06)
("faulted printing"\
" %s-%d. enabled"),
break;
}
}
papiJobListFree(j);
}
}
break;
case 0x05: /* stopped */
break;
case 0x07: /* faulted printer */
break;
case 0x08: /* waiting for auto retry */
break;
default:
break;
}
if (pstat == 0x08)
else {
"printer-up-time", &curr);
"printer-state-time", &curr);
"lpsched-disable-date", &curr);
}
if ((pstat == 0x05) ||
(pstat == 0x06) ||
(pstat == 0x07) ||
(pstat == 0x08)) {
"printer-state-reasons", &reason);
"lpsched-disable-reason", &reason);
}
if (verbose == 1) {
void *iter;
char *str;
(void) printf(
gettext("\tRemote Name: %s\n\tRemote Server: "
return (0);
}
str = "";
"form-ready", &str);
str = "";
"document-format-supported", &str);
== PAPI_OK)
printf("\n");
/* Display the printer description */
str = "";
"lpsched-printer-type", &str);
== PAPI_OK)
printf("\n");
str = "";
"lpsched-dial-info", &str);
str = "";
"lpsched-interface-script", &str);
"ppd-file-uri", &str);
"lpsched-ppd-source-path", &str);
"lpsched-fault-alert-command", &str);
str = "";
"lpsched-fault-recovery", &str);
str = "(all)";
"requesting-user-name-allowed", &str);
"requesting-user-name-denied", &str);
}
str = "none";
"form-supported", &str);
str = "";
"media-supported", &str);
str = "";
"job-sheets-supported", &str);
else
str = "";
"lpsched-print-wheels", &str);
str = "";
"lpsched-options", &str);
printf("\n");
}
} else if (description == 1)
/* Display printer description */
else if (verbose > 1)
if (verbose > 0)
printf("\n");
return (0);
}
static int
int, int), papi_encryption_t encryption,
int verbose, int description)
{
int result = 0, i = 0;
}
/*
* 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.
*/
if (status == PAPI_NOT_FOUND)
gettext("%s: unknown printer\n"),
else
"Failed to contact service for %s: %s\n"),
result--;
continue;
}
int i;
}
} else {
/*
* Limit the query to only required data
* to reduce the need to go remote for
* information.
*/
if (report == report_device)
else if (report == report_class)
else if (report == report_accepting)
"Failed to get printer info for %s: %s\n"),
result--;
continue;
}
}
break;
}
return (result);
}
static int
{
int i;
return (0);
}
return (-1);
}
static int
{
static int check = 0;
"job-originating-user-name", &user);
return (0);
"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
*/
/*
* 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
*/
"job-printer-uri", &uri);
/*
* 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
*/
}
/*
* 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.
*/
}
} else {
/*
* This part of the code will get executed when
* 'report_job' is called more than once for the same
* lpstat command
*/
/*
* Read the job-printer-uri as
* it will be different for
* different printers
*/
(void) papiAttributeListGetString(attrs,
else
} 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
*/
}
}
}
if (host) {
/* Check if it is local printer or remote printer */
/*
* Request submitted locally
* for the local queue.
* Hostname will not be displayed
*/
user);
}
else
/*
* It's a remote printer.
* In case of remote printers hostname is
* always displayed.
*/
}
uri_free(u);
} else {
/*
* If attribute "job-printer-uri"
* cannot be read
* by default append the hostname
*/
}
} 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
*/
else
uri_free(u);
} else
}
"job-printer-uri", &destination);
"printer-name", &destination);
"job-id", &id);
"job-id-requested", &id);
if (show_rank != 0) {
"number-of-intervening-jobs", &rank);
rank++;
printf("%3d %-21s %-14s %7ld %s",
} else
"job-state", &jstate);
if (jstate == 0x0001)
else if (jstate == 0x0800)
else if (jstate == 0x0040)
else if (jstate == 0x0010)
else if (jstate == 0x0008)
else if (jstate == 0x2000)
else if (jstate == 0x0002)
else if (jstate == 0x0004)
else if (jstate == 0x0020)
if (verbose == 1) {
"output-device-assigned", &destination);
} else if (verbose > 1) {
printf("\n");
}
printf("\n");
return (0);
}
static int
{
int result = 0;
int flag1 = 0;
int print_flag = 0;
do {
print_flag = 1;
/* <name>-# printer name does not exist */
/*
* Check if <name>-# is a request-id
* Once this check is done flag1 is set
*/
if (flag1 == 1)
break;
"Failed to contact service for %s: %s\n"),
return (-1);
}
}
int i;
}
0, 0, &jobs);
"Failed to get job list: %s\n"),
return (-1);
}
int i;
verbose);
}
} else { /* a job */
/* 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
*/
if (id >= 0)
else
/* id not found */
if (!print_flag)
"Failed to get job"\
" info for %s: %s\n"),
return (-1);
}
}
if (flag) {
id = -1;
if (id == -1)
flag = 0;
else
flag1 = 1;
}
} while (flag);
return (result);
}
static int
{
"form-supported", &form);
if (verbose != 0) {
"form-supported-detail", &detail);
}
}
}
return (0);
}
static int
{
"pw-supported", &pw);
if (verbose != 0) {
"pw-supported-extra", &info);
}
}
}
return (0);
}
static int
{
int result = 0;
encryption, NULL);
return (-1);
}
if (verbose > 1) {
printf("\n");
printf("\n");
}
}
return (result);
}
int
{
int exit_code = 0;
int rank = 0;
int verbose = 0;
int description = 0;
int c;
char **argv;
(void) textdomain("SUNW_OST_OSCMD");
for (c = 0; c < ac; c++) {
/* preserve old "-l[po...]" behavior */
argv[c][0] = '-';
verbose = 1;
} else
}
argv[c++] = "--";
ac = c;
/* preprocess argument list looking for '-l' or '-R' so it can trail */
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 */
optind--;
}
switch (c) {
case 'l':
optarg = "1";
break;
case 'D':
description = 1;
break;
case 'R':
rank = 1;
break;
case 'E':
break;
default:
break;
}
}
optind = 1;
/* process command line arguments */
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 */
optind--;
}
switch (c) {
case 'a':
encryption, verbose, 0);
break;
case 'c':
encryption, verbose, 0);
break;
case 'p':
break;
case 'd':
break;
case 'r':
break;
case 'u':
}
break;
case 'v':
encryption, verbose, 0);
break;
case 'R': /* set "rank" flag in first pass */
case 'o':
break;
case 'f':
break;
case 'S':
break;
case 's':
encryption, verbose, 0);
encryption, verbose, 0);
break;
case 't':
encryption, verbose, 0);
encryption, verbose, 0);
encryption, verbose, 0);
encryption, verbose, 0);
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:
}
}
ac--;
}
} else {
}
if (exit_code != 0)
exit_code = 1;
return (exit_code);
}