lpfilter.c revision ace1a5f11236a072fca1b5e0ea1416a083a9f2aa
/*
* 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 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <locale.h>
#include "lp.h"
#include "access.h"
#include "filters.h"
#include "msgs.h"
#define WHO_AM_I I_AM_LPFILTER
#include "oam.h"
#define OPT_LIST "f:F:ixl"
int add_filter(),
list_filter();
static void alert_spooler(),
static char *opt();
/*
* Unfortunately, the LP requirements show the listing of a filter
* to be in a different order than the stored filter table. We can't
* change the stored version because it's the same as UNISON uses.
* So, we can't reuse the "FL_..." #defines found in "filters.h".
* But the following have similar use.
*/
# define FL_IGN_P 8
# define FL_PTYPS_P 2
# define FL_PRTRS_P 3
# define FL_ITYPS_P 0
# define FL_NAME_P 7
# define FL_OTYPS_P 1
# define FL_TYPE_P 4
# define FL_CMD_P 5
# define FL_TMPS_P 6
#define TABLE 0
#define TABLE_I 1
static struct headings {
char *v;
short len;
#define ENTRY(X) X, sizeof(X)-1
ENTRY("Input types:"),
ENTRY("Output types:"),
ENTRY("Printer types:"),
ENTRY("Printers:"),
ENTRY("Filter type:"),
ENTRY("Command:"),
ENTRY("Options:"),
ENTRY(""),
ENTRY("")
};
/**
** usage()
**/
void usage ()
{
"usage:\n"
"\n"
" (add or change filter)\n"
" lpfilter -f filter-name {-F path-name | -}\n"
"\n"
" (restore delivered filter)\n"
" lpfilter -f filter-name -i\n"
"\n"
" (list a filter)\n"
" lpfilter -f filter-name -l\n"
"\n"
" (list all filters)\n"
" lpfilter -f \"all\" -l\n"
"\n"
" (delete filter)\n"
" lpfilter -f filter-name -x\n"));
return;
}
/**
** main()
**/
int argc;
char *argv[];
{
extern int optind,
getopt();
extern char *optarg;
int c,
(*action)(),
(*newaction)();
char *filter,
*p;
#if !defined(TEXT_DOMAIN)
#define TEXT_DOMAIN "SYS_TEST"
#endif
(void) textdomain(TEXT_DOMAIN);
if (!is_user_admin()) {
exit (1);
}
action = 0;
input = 0;
filter = 0;
opterr = 0;
case 'f':
if (filter)
if (
) {
exit (1);
exit (1);
} else if (!*filter)
break;
case 'F':
if (input)
exit (1);
}
goto Check;
case 'i':
goto Check;
case 'x':
goto Check;
case 'l':
);
exit (1);
}
break;
default:
if (optopt == '?') {
usage ();
exit (0);
}
else
exit (1);
}
if (action) {
exit (1);
} else {
action = add_filter;
optind++;
}
if (!filter) {
exit (1);
}
if (!action) {
exit (1);
}
}
/**
** add_filter()
**/
char *filter;
{
*store,
*ps;
register int fld;
register char *p;
*file;
int line,
ret;
/*
* First we read in the input and parse it into a filter,
* storing it in the filter buffer "flbuf". Keep track of
* which fields have been given, to avoid overwriting unchanged
* fields later.
*/
if (!input)
real_fields[fld] = 0;
line = bad_headings = 0;
line++;
if (!*p || *p == '#')
continue;
if (
&& CS_STRNEQU(
p,
)
) {
break;
}
if (bad_headings++ >= 5) {
return (1);
}
} else switch (fld) {
case FL_IGN_P:
case FL_NAME_P:
break;
case FL_CMD_P:
break;
case FL_TYPE_P:
break;
case FL_PTYPS_P:
break;
case FL_ITYPS_P:
break;
case FL_OTYPS_P:
break;
case FL_PRTRS_P:
break;
case FL_TMPS_P:
char **temp;
} else
break;
}
}
return (1);
}
/*
* We have the input stored, now get the current copy of the
* filter(s). If no filter exists, we create it.
*/
/*
* Adding ``all'' means changing all filters to reflect
* the information in the input. We'll preload the
* filters so that we know how many there are.
*/
if (
) {
switch (errno) {
case ENOENT:
break;
default:
break;
}
return (1);
}
if (!store) {
return (1);
}
switch (errno) {
case ENOENT:
);
return (1);
}
break;
default:
return (1);
}
} else {
if (!store) {
return (1);
}
} else
switch (errno) {
case ENOENT:
/*
* We must be adding a new filter, so
* set up default values. Check that
* we'll have something reasonable to add.
*/
pf->printer_types = 0;
pf->input_types = 0;
pf->output_types = 0;
return (1);
}
break;
default:
return (1);
}
}
at_least_one = ret = 0;
case FL_IGN_P:
case FL_NAME_P:
break;
case FL_CMD_P:
break;
case FL_TYPE_P:
break;
case FL_PTYPS_P:
break;
case FL_ITYPS_P:
break;
case FL_OTYPS_P:
break;
case FL_PRTRS_P:
break;
case FL_TMPS_P:
break;
}
case LP_ETEMPLATE:
break;
case LP_EKEYWORD:
break;
case LP_EPATTERN:
break;
case LP_EREGEX:
{
char * why;
extern int regerrno;
switch (regerrno) {
case 11:
why = "range endpoint too large";
break;
case 16:
why = "bad number";
break;
case 25:
why = "\"\\digit\" out of range";
break;
case 36:
why = "illegal or missing delimiter";
break;
case 41:
why = "no remembered search string";
break;
case 42:
why = "\\(...\\) imbalance";
break;
case 43:
why = "too many \\(";
break;
case 44:
why = "more than 2 numbers given in \\{...\\}";
break;
case 45:
why = "} expected after \\";
break;
case 46:
why = "first number exceeds second in \\{...\\}";
break;
case 49:
why = "[...] imbalance";
break;
case 50:
why = "regular expression overflow";
break;
}
break;
}
case LP_ERESULT:
break;
case LP_ENOMEM:
break;
} else
ret = 1;
break;
} else
at_least_one = 1;
}
if (at_least_one)
(void)alert_spooler ();
return (ret);
}
/**
** reload_filter()
**/
int reload_filter (filter)
char *filter;
{
*store,
*ps;
char *factory_file;
int ret,
/*
* ``Manually'' load the archived filters, so that a call
* to "getfilter()" will read from them instead of the regular
* table.
*/
if (
) {
switch (errno) {
case ENOENT:
break;
default:
break;
}
return (1);
}
if (!store) {
return (1);
}
switch (errno) {
case ENOENT:
);
return (1);
}
break;
default:
return (1);
}
} else {
if (!store) {
return (1);
}
case ENOENT:
return (1);
default:
return (1);
}
}
/*
* Having stored the archived filter(s) in our own area, clear
* the currently loaded table so that the subsequent calls to
* "putfilter()" will read in the regular table.
*/
trash_filters ();
at_least_one = ret = 0;
ret = 1;
break;
} else
at_least_one = 1;
if (at_least_one)
(void)alert_spooler ();
return (ret);
}
/**
** delete_filter()
**/
int delete_filter (filter)
char *filter;
{
case ENOENT:
return (1);
default:
return (1);
}
(void)alert_spooler ();
return (0);
}
/**
** list_filter()
**/
static void _list_filter();
int list_filter (filter)
char *filter;
{
char *nl;
nl = "";
_list_filter (pf);
nl = "\n";
}
switch (errno) {
case ENOENT:
return (0);
default:
return (1);
}
} else {
_list_filter (pf);
return (0);
}
switch (errno) {
case ENOENT:
return (1);
default:
return (1);
}
}
}
static void _list_filter (pf)
{
register char **pp,
*sep;
register int fld;
char * head;
case FL_IGN_P:
case FL_NAME_P:
break;
case FL_CMD_P:
printf (
"%s %s\n",
);
break;
case FL_TYPE_P:
printf (
"%s %s\n",
);
break;
case FL_PTYPS_P:
goto Lists;
case FL_ITYPS_P:
goto Lists;
case FL_OTYPS_P:
goto Lists;
case FL_PRTRS_P:
printf ("\n");
break;
case FL_TMPS_P:
printlist_qsep = 1;
break;
}
return;
}
/**
** opt() - GENERATE OPTION FROM FUNCTION NAME
**/
int (*fnc)();
{
if (fnc == add_filter)
return ("-F");
else if (fnc == reload_filter)
return ("-i");
else if (fnc == list_filter)
return ("-l");
else if (fnc == delete_filter)
return ("-x");
else
return ("-?");
}
/**
** alert_spooler() - TELL SPOOLER TO LOAD FILTER TABLE
**/
static void alert_spooler ()
{
int mtype;
short status;
/*
* If the attempt to open a message queue to the
* Spooler fails, assume it isn't running and just
* return--don't say anything, `cause the user may
* know. Any other failure deserves an error message.
*/
if (mopen() == -1)
return;
goto Error;
goto Error;
if (mtype != R_LOAD_FILTER_TABLE) {
(void)mclose ();
exit (1);
}
goto NoError;
return;
}
/**
** same_complaints() - PRINT COMMON ERROR MESSAGES
**/
char *table;
int type;
{
switch (errno) {
case EACCES:
);
else
);
break;
case EAGAIN:
case EDEADLK:
break;
default:
);
break;
}
return;
}