/*
* 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
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include "stdio.h"
#include "string.h"
#include "pwd.h"
#include "errno.h"
#include "lp.h"
#include "printers.h"
#include "form.h"
#include "class.h"
#include "oam.h"
#include "lpadmin.h"
extern PRINTER *printer_pointer;
extern PWHEEL *pwheel_pointer;
void chkopts2(),
chkopts3();
static void chksys();
char **f_allow,
**f_deny,
**u_allow,
**u_deny,
**p_add,
**p_remove;
short daisy = 0;
static int root_can_write();
static char *unpack_sdn();
static char ** bad_list;
#if defined(__STDC__)
static unsigned long sum_chkprinter ( char ** , char * , char * , char * , char * , char * );
#else
static unsigned long sum_chkprinter();
static int isPPD();
#endif
/**
** chkopts() -- CHECK LEGALITY OF COMMAND LINE OPTIONS
**/
void chkopts ()
{
short isfAuto = 0;
/*
* Check -d.
*/
if (d) {
if (
a || c || f || P || j || m || M || t || p || r || u || x
#if defined(DIRECT_ACCESS)
|| C
#endif
#ifdef LP_USE_PAPI_ATTR
|| n_opt
#endif
|| strlen(modifications)
) {
done (1);
}
if (
*d
&& !isprinter(d)
&& !isclass(d)
) {
done (1);
}
return;
}
/*
* Check -x.
*/
if (x) {
if ( /* MR bl88-02718 */
A || a || c || f || P || j || m || M || t || p || r || u || d
#if defined(DIRECT_ACCESS)
|| C
#endif
#ifdef LP_USE_PAPI_ATTR
|| n_opt
#endif
|| strlen(modifications)
) {
done (1);
}
if (
&& !isprinter(x)
&& !isclass(x)
) {
done (1);
}
return;
}
/*
* Problems common to both -p and -S (-S alone).
*/
done (1);
}
/*
* Check -S.
*/
if (!p && S) {
if (
M || t || a || f || P || c || r || e || i || m || H || h
|| l || v || I || T || D || F || u || U || j || o
#ifdef LP_USE_PAPI_ATTR
|| n_opt
#endif
) {
done (1);
}
if (!A && W == -1 && Q == -1) {
done (1);
}
if (S[0] && S[1])
chkopts3(1);
return;
}
/*
* At this point we must have a printer (-p option).
*/
if (!p) {
done (1);
}
done (1);
}
/*
* Mount but nothing to mount?
*/
if (M && (!f && !S)) {
done (1);
}
/*
* -Q isn't allowed with -p.
*/
if (Q != -1) {
done (1);
}
/*
* Fault recovery.
*/
if (
F
&& !STREQU(F, NAME_BEGINNING)
&& (
!STREQU(F, NAME_CONTINUE)
|| j
&& STREQU(F, NAME_CONTINUE)
)
) {
#if defined(J_OPTION)
if (j)
else
#endif
done (1);
}
#if defined(J_OPTION)
/*
* The -j option is used only with the -F option.
*/
if (j) {
if (M || t || a || f || P || c || r || e || i || m || H || h ||
#ifdef LP_USE_PAPI_ATTR
n_opt ||
#endif
l || v || I || T || D || u || U || o) {
done (1);
}
if (j && !F) {
done (1);
}
return;
}
#endif
#if defined(DIRECT_ACCESS)
/*
* -C is only used to modify -u
*/
if (C && !u) {
done (1);
}
#endif
/*
* The -a option needs the -M and -f options,
* Also, -ofilebreak is used only with -a.
*/
if (a && (!M || !f)) {
done (1);
}
if (filebreak && !a)
/*
* The "-p all" case is restricted to certain options.
*/
if (
&& (
a || h || l || M || t || D || e || f || P || H || s
#ifdef LP_USE_PAPI_ATTR
|| n_opt
#endif
|| i || I || m || S || T || u || U || v || banner != -1
)
) {
done (1);
}
/*
* Allow giving -v or -U option as way of making
* remote printer into local printer.
* Note: "!s" here means the user has not given the -s;
* later it means the user gave -s local-system.
*/
if (!s && (v || U))
s = Local_System;
/*
* Be careful about checking "s" before getting here.
* We want "s == 0" to mean this is a local printer; however,
* if the user wants to change a remote printer to a local
* printer, we have to have "s == Local_System" long enough
* to get into "chkopts2()" where a special check is made.
* After "chkopts2()", "s == 0" means local.
*/
/*
* If old printer, make sure it exists. If new printer,
* check that the name is okay, and that enough is given.
* (This stuff has been moved to "chkopts2()".)
*/
chkopts2(1);
if (!s) {
/*
* Only one of -i, -m, -e.
*/
if ((i && e) || (m && e) || (i && m)) {
done (1);
}
/*
* Check -e arg.
*/
if (e) {
if (!isprinter(e)) {
done (1);
}
if (strcmp(e, p) == 0) {
done (1);
}
}
/*
* Check -m arg.
*/
if (m && !ismodel(m)) {
done (1);
}
#ifdef LP_USE_PAPI_ATTR
/*
* Check -n arg. The ppd file exists.
*/
done (1);
}
#endif
/*
* Need exactly one of -h or -l (but will default -h).
*/
if (h && l) {
done (1);
}
if (!h && !l)
h = 1;
/*
* Check -c and -r.
*/
if (c && r && strcmp(c, r) == 0) {
done (1);
}
/*
* Are we creating a class with the same name as a printer?
*/
if (c) {
if (STREQU(c, p)) {
done (1);
}
if (isprinter(c)) {
done (1);
}
}
if (v && (is_printer_uri(v) < 0)) {
/*
* The device must be writeable by root.
*/
if (v && root_can_write(v) == -1)
done (1);
}
/*
* Can't have both device and dial-out.
*/
if (v && U) {
done (1);
}
} else
if (
A || a || e || H || h || i || l || m || ( t && !M) || ( M && !t)
|| o || U || v || Q != -1 || W != -1
#ifdef LP_USE_PAPI_ATTR
|| n_opt
#endif
) {
done(1);
}
/*
* We need the printer type for some things, and the boolean
* "daisy" (from Terminfo) for other things.
*/
if (!T && oldp)
T = oldp->printer_types;
if (T) {
short a_daisy;
char ** pt;
done (1);
}
done (1);
}
/*
* All the printer types had better agree on whether the
* printer takes print wheels!
*/
if (daisy == -1)
daisy = 0;
if (a_daisy == -1)
done (1);
}
}
}
if (!T) {
done (1);
}
/*
* Check -o cpi=, -o lpi=, -o length=, -o width=
*/
unsigned long rc;
if (bad_list)
INFO,
);
} else {
done(1);
}
}
/*
* Check -I (old or new):
*/
if (T && lenlist(T) > 1) {
if (
I && BADILIST(I)
) {
done (1);
}
}
/*
* MOUNT:
* Only one print wheel can be mounted at a time.
*/
if (M && S && S[0] && S[1])
/*
* NO MOUNT:
* If the printer takes print wheels, the -S argument
* should be a simple list; otherwise, it must be a
* mapping list. (EXCEPT: In either case, "none" alone
* means delete the existing list.)
*/
if (S && !M) {
register char **item,
*cp;
/*
* For us to be here, "daisy" must have been set.
* (-S requires knowing printer type (T), and knowing
* T caused call to "tidbit()" to set "daisy").
*/
if (daisy) {
done (1);
}
done (1);
}
}
} else {
register int die = 0;
done (1);
}
*cp = 0;
done (1);
}
die = 1;
} else {
if (bad_list)
INFO,
*item,
);
}
*cp++ = '=';
done (1);
}
}
if (die) {
done (1);
}
}
}
if (P) {
int createForm = 0;
char **plist;
done (1);
}
} else
createForm = 1;
if (*P == '~') { /* removing types of papers */
P++;
} else { /* adding types of papers */
if (createForm) {
"lpforms -f %s -d\n", *plist);
}
}
}
if (!f && !M) { /* make paper allowed on printer too */
strlen(": "));
isfAuto = 1;
}
}
/*
* NO MOUNT:
* The -f option restricts the forms that can be used with
* the printer.
* - check each allowed form to see if it'll work
* on the printer
*/
if (f && !M) {
**pf;
register int die = 0;
while (*pf) {
if ((!isfAuto) &&
&& verify_form(*pf) < 0
)
die = 1;
pf++;
}
if (die) {
done (1);
}
} else
while (*pf) {
if ((!isfAuto) &&
) {
E_ADM_ICKFORM, *pf, p);
die = 1;
}
pf++;
}
}
if (die) {
done (1);
}
} else
} else {
done (1);
}
}
/*
* The -u option is setting use restrictions on printers.
*/
if (u) {
} else {
done (1);
}
}
return;
}
/**
** root_can_write() - CHECK THAT "root" CAN SENSIBLY WRITE TO PATH
**/
char *path;
{
return (-1);
}
/*
* If the device is a symlink (and it is not a root owned symlink),
* verify that the owner matches the destination owner.
*/
return (-1);
}
done(1);
}
}
if (lp_uid == -1) {
endpwent ();
if (ppw)
else
lp_uid = 0;
}
return (0);
}
/**
** unpack_sdn() - TURN SCALED TYPE INTO char* TYPE
**/
{
register char *cp;
extern char *malloc();
cp = 0;
return (cp);
}
/**
** verify_form() - SEE IF PRINTER CAN HANDLE FORM
**/
char *form;
{
register char *cpi_f,
*lpi_f,
*width_f,
*length_f,
*chset;
register int rc = 0;
register unsigned long checks;
if (!paperAllowed) {
&paperDenied);
}
gettext("printer doesn't support paper type"));
rc = -1;
}
}
else {
if (
&& !daisy
&& !search_cslist(
)
)
else
chset = 0;
if ((checks = sum_chkprinter(
T,
))) {
rc = -1;
rc = -2;
}
} else {
if (bad_list)
INFO,
);
}
}
if (paperAllowed)
return (rc);
}
}
if (paperAllowed)
done (1);
}
return (rc);
}
/*
Second phase of parsing for -p option.
In a seperate routine so we can call it from other
routines. This is used when any or all are used as
a printer name. main() loops over each printer, and
must call this function for each printer found.
*/
void
int called_from_chkopts;
{
/*
Only do the getprinter() if we are not being called
from lpadmin.c. Otherwise we mess up our arena for
"all" processing.
*/
if (!called_from_chkopts)
done(1);
}
if (oldp) {
if (
!c && !d && !f && !P && !M && !t && !r && !u && !x && !A
&& !strlen(modifications)
) {
done (1);
}
/*
* For the case "-s local-system", we need to keep
* "s != 0" long enough to get here, where it keeps
* us from taking the old value. After this, we make
* "s == 0" to indicate this is a local printer.
*/
if (s && s != Local_System)
chksys(s);
if (s == Local_System)
s = 0;
/*
* A remote printer converted to a local printer
* requires device or dial info.
*/
done (1);
}
} else {
if (getclass(p)) {
done (1);
}
if (!syn_name(p)) {
done (1);
}
if (s == Local_System)
s = 0;
if (s)
chksys(s);
#ifdef LP_USE_PAPI_ATTR
/*
* New printer - if no model and a PPD file is defined then
* use 'standard_foomatic' otherwise use
* the 'standard' model.
*/
if (!(e || i || m) && !s) {
m = STANDARD_FOOMATIC;
} else {
m = STANDARD;
}
}
#else
/*
* New printer - if no model, use standard
*/
if (!(e || i || m) && !s)
m = STANDARD;
#endif
/*
* A new printer requires device or dial info.
*/
if (!v && !U && !s) {
done (1);
}
/*
* Can't quiet a new printer,
* can't list the alerting for a new printer.
*/
if (
A
) {
done (1);
}
/*
* New printer - if no input types given, assume "simple".
*/
if (!I) {
}
}
}
/*
Second phase of parsing for -S option.
In a seperate routine so we can call it from other
routines. This is used when any or all are used as
a print wheel name. main() loops over each print wheel,
and must call this function for each print wheel found.
*/
void
int called_from_chkopts;
{
/*
Only do the getpwheel() if we are not being called
from lpadmin.c. Otherwise we mess up our arena for
"all" processing.
*/
if (!called_from_chkopts)
else
if (!oldS) {
if (!syn_name(*S)) {
done (1);
}
/*
* Can't quiet a new print wheel,
* can't list the alerting for a new print wheel.
*/
if (
A
) {
done (1);
}
}
}
static void
chksys(s)
char *s;
{
char *cp;
done(1);
}
*cp = '\0';
if (cp)
*cp = '!';
return;
}
/**
** sum_chkprinter() - CHECK TERMINFO STUFF FOR A LIST OF PRINTER TYPES
**/
#include "lp.set.h"
static unsigned long
#if defined(__STDC__)
char ** types,
char * cpi,
char * lpi,
char * len,
char * wid,
char * cs
)
#else
char ** types;
char * cpi;
char * lpi;
char * len;
char * wid;
char * cs;
#endif
{
char ** pt;
unsigned long worst = 0;
unsigned long this = 0;
/*
* Check each printer type, to see if any won't work with
* the attributes requested. However, return ``success''
* if at least one type works. Keep a list of the failed
* types for the caller to report.
*/
bad_list = 0;
if (this != 0)
}
return (worst);
else
return (0);
}
/*
* Function: isPPD()
*
* Description: Check that the given PPD file exists. The argument given can
* either be a relative path or a full path to the file.
*
* Returns: 1 = PPD file found
* 0 = PPD file not found
*/
static int
{
int result = 0;
if (*ppd_file == '/') {
} else {
}
/*
* now check the file exists
*/
result = 1;
} else {
/*
* files does not exist so append .gz and check if
* that exist
*/
result = 1;
}
}
}
}
}
return (result);
} /* isPPD() */