/*
* 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 */
#include <locale.h>
#include "stdio.h"
#include "errno.h"
#include "string.h"
#include "stdlib.h"
#include "lp.h"
#include "access.h"
#include "form.h"
#include "msgs.h"
#include "oam.h"
typedef int (*Action)();
#if defined(__STDC__)
static int delete_form ( char * );
static int list_form ( char * );
static int list_alert ( char * );
static int list_both ( char * );
static int quiet_alert ( char * );
static int notify_spooler ( int , int , char * );
static int onerror ( int , int , int );
static Action set_action ( int (*)() , char * );
#else
static int add_form();
static int add_alert();
static int delete_form();
static int list_form();
static int list_alert();
static int list_both();
static int any_alert();
static int quiet_alert();
static int notify_spooler();
static int onerror();
static Action set_action();
#endif
/**
** usage()
**/
void usage ()
{
"usage:\n"
"\n"
" (add or change form)\n"
" lpforms -f form-name [options]\n"
" [-F path-name | - | -P paper [-d] | -d ] (form definition)\n"
" -F path-name (initialize from file)\n"
" - (initialize from stdin)\n"
" -P paper [-d] (initialize with paper (as default))\n"
" -d (create form with paper of same name)\n"
" [-u allow:user-list | deny:user-list] (who's allowed to use)\n"
" [-A mail | write | shell-command] (alert definition)\n"
" [-Q threshold] (# needed for alert)\n"
" [-W interval] (minutes between alerts)\n"
"\n"
" (list form)\n"
" lpforms -f form-name -l\n"
" lpforms -f form-name -L (verbose for -P forms)\n"
"\n"
" (delete form)\n"
" lpforms -f form-name -x\n"
"\n"
" (define alert for forms with no alert yet)\n"
" lpforms -f any -A {mail | write | shell-command}\n"
"\n"
" (define alert for all forms)\n"
" lpforms -f all -A {mail | write | shell-command}\n"
"\n"
" (examine alerting)\n"
" lpforms -f form-name -A list\n"
"\n"
" (stop alerting)\n"
" lpforms -f form-name -A quiet (temporarily)\n"
" lpforms -f form-name -A none (for good)"
"\n"
));
return;
}
static char *P = NULL;
static int d = 0;
static int L = 0;
/**
** main()
**/
int
{
extern int optind;
extern int opterr;
extern int optopt;
extern char * optarg;
int c;
int cnt = 0;
char * form = 0;
char * u = 0;
char * cp;
char * rest;
#if !defined(TEXT_DOMAIN)
#endif
(void) textdomain(TEXT_DOMAIN);
if (!is_user_admin()) {
exit (1);
}
opterr = 0;
/*
* These options take values; "getopt()" passes values
* that begin with a dash without checking if they're
* options. If a value is missing, we want to complain
* about it.
*/
switch (c) {
case 'W':
case 'Q':
/*
* These options take numeric values, which might
* be negative. Negative values are handled later,
* but here we just screen them.
*/
break;
/*FALLTHROUGH*/
case 'f':
case 'F':
case 'A':
case 'u':
if (!*optarg) {
stroptsw[1] = c;
exit (1);
}
if (*optarg == '-') {
stroptsw[1] = c;
exit (1);
}
break;
}
switch (c) {
case 'f':
if (form)
exit (1);
} else if (!*form)
break;
case 'F':
if (input)
exit (1);
}
break;
case 'A':
else {
else
}
break;
case 'Q':
if (alert.Q != -1)
alert.Q = 1;
else {
if (alert.Q < 0) {
exit (1);
}
exit (1);
}
if (alert.Q == 0) {
exit (1);
}
}
break;
case 'W':
if (alert.W != -1)
alert.W = 0;
else {
if (alert.W < 0) {
exit (1);
}
exit (1);
}
}
break;
case 'u':
if (u)
break;
case 'x':
break;
case 'L':
L = 1;
break;
case 'l':
break;
case 'd':
d = 1;
break;
case 'P':
if (P)
break;
default:
if (optopt == '?') {
usage ();
exit (0);
}
else
exit (1);
}
}
if (!form) {
exit (1);
}
optind++;
}
if (!action) {
exit (1);
}
exit (0);
}
/*
* We must have a shell command for the alert if:
*
* (1) we're adding a new form and the -W or -Q options
* have been given, or
*
* (2) the -f any option was given.
*/
if (
(
)
) {
return (1);
}
while (P && (cnt++ < 2)) {
/*
* two times should do it unless user has edited
* files directly
*/
form, P, P);
return (1);
else
break; /* we found a good paper */
} else {
int result;
int saveD;
saveD = d;
d = 1;
d = saveD;
}
}
}
if (d && !P)
}
/**
** add_alert()
** add_form()
**/
/*
* "add_alert()" exists just to simplify the checking of mixed
* options in "set_action()".
*/
static int
#if defined(__STDC__)
char * form,
char * u
)
#else
char * form;
char * u;
#endif
{
}
static int
#if defined(__STDC__)
add_form (
char * form,
char * u
)
#else
char * form;
char * u;
#endif
{
int fld;
int new_form = 0;
int nform;
int return_code;
char ** u_allow = 0;
char ** u_deny = 0;
/*
* Read the input configuration (if any) and parse it into a form,
* storing it in the form buffer "fbuf". Keep track of
* which fields have been given, to avoid overwriting unchanged
* fields later.
*/
if (input) {
which_set) == -1) {
return (1);
}
break;
/*
* Read the alignment pattern (if any) into a temporary
* file so that it can be used for (potentially) many
* forms.
*/
size_t n;
exit (1);
}
}
}
/*
*/
if (u) {
char * cp;
char * type;
);
);
} else {
exit (1);
}
}
/*
* The following loop gets either a particular form or
* all forms (one at a time). The value of "return_code"
* controls the loop and is also the value to use in the
* "return()" at the end.
*/
nform = 0;
return_code = -1;
while (return_code == -1) {
/*
* the loop control to get us out.
*/
return_code = 0;
nform++;
if (P) {
new_form = 1;
switch (errno) {
case ENOENT:
/*
* This is a problem only if it occurs
* immediately on trying to get ``all''.
*/
if (nform > 1)
return_code = 0;
else {
return_code = 1;
}
continue;
}
/*
* We're adding a new form,
* so set up default values.
*/
new_form = 1;
break;
default:
/*
* Don't know if we'll have a good name
* in the "all" case on getting here, so
* punt on naming the form in the error
* message.
*/
return_code = 1;
continue;
}
/*
* Copy just those items that were given in the input.
*/
return (1);
}
if (input)
case FO_PLEN:
break;
case FO_PWID:
break;
case FO_CPI:
break;
case FO_LPI:
break;
case FO_NP:
break;
case FO_CHSET:
break;
case FO_RCOLOR:
break;
case FO_CMT:
break;
case FO_ALIGN:
break;
case FO_PAPER:
break;
}
/*
* Set just those alert elements that were given.
* However, complain about those form(s) that don't have
* a shell command yet, and none was given, yet -W or -Q
* were given.
*/
if (
)
else {
if (p_new_alert->shcmd)
if (p_new_alert->Q != -1)
alert.Q = p_new_alert->Q;
if (p_new_alert->W != -1)
alert.W = p_new_alert->W;
}
/*
*/
return_code = 1;
continue;
}
/*
*/
return_code = 1;
continue;
}
return_code = 1;
continue;
}
return_code = 1;
continue;
}
}
if (align_fp)
return (return_code);
}
/**
** list_form()
** list_alert()
** list_both()
**/
#if defined(__STDC__)
static int list ( char * , void (*)() );
#else
static int list();
static void _list_form();
static void _list_alert();
static void _list_both();
#endif
static int
#if defined(__STDC__)
char *form
)
#else
char *form;
#endif
{
}
static int
#if defined(__STDC__)
char *form
)
#else
char *form;
#endif
{
}
static int
#if defined(__STDC__)
char *form
)
#else
char *form;
#endif
{
}
static int
#if defined(__STDC__)
list (
char *form,
void (*subaction)()
)
#else
char *form;
void (*subaction)();
#endif
{
char *nl;
nl = "";
nl = "\n";
}
switch (errno) {
case ENOENT:
return (0);
default:
/*
* Don't know if we'll have a good name
* in the "all" case on getting here, so
* punt on naming the form in the error
* message.
*/
return (1);
}
} else {
return (0);
}
switch (errno) {
case ENOENT:
return (1);
default:
return (1);
}
}
}
/**
** _list_form()
**/
static void
#if defined(__STDC__)
)
#else
#endif
{
size_t n;
if (!align_fp)
if (align_fp)
}
/**
** _list_alert()
**/
static void
#if defined(__STDC__)
)
#else
#endif
{
}
/**
** _list_both()
**/
static void
#if defined(__STDC__)
)
#else
#endif
{
}
/**
** any_alert()
**/
static int
#if defined(__STDC__)
char * form,
)
#else
char * form;
#endif
{
return (1);
}
return (0);
}
/**
** delete_form()
** quiet_alert()
**/
#if defined(__STDC__)
static int dq ( char * , int (*)() );
static int _delete_form ( char * );
static int _quiet_alert ( char * );
#else
static int dq();
static int _delete_form();
static int _quiet_alert();
#endif
static int
#if defined(__STDC__)
char *form
)
#else
char *form;
#endif
{
}
static int
#if defined(__STDC__)
char * form
)
#else
char * form;
#endif
{
}
static int
#if defined(__STDC__)
dq (
char *form,
int (*subaction)()
)
#else
char *form;
int (*subaction)();
#endif
{
exit (1);
}
return (1);
switch (errno) {
case ENOENT:
return (0);
default:
/*
* Don't know if we'll have a good name
* in the "all" case on getting here, so
* punt on naming the form in the error
* message.
*/
return (1);
}
} else {
switch (errno) {
case ENOENT:
return (1);
default:
return (1);
}
}
}
static int
#if defined(__STDC__)
char *form
)
#else
char *form;
#endif
{
case -1:
if (anyrequests()) {
return (1);
}
/*FALLTHROUGH*/
case MNODEST:
return (1);
} else {
form,
);
return (1);
}
}
break;
case MOK:
return (1);
}
break;
}
return (0);
}
static int
#if defined(__STDC__)
char * form
)
#else
char * form;
#endif
{
char *msgbuf;
int mtype;
int size;
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 (0);
mclose ();
return (1);
}
mclose ();
return (1);
}
mclose ();
if (mtype != R_QUIET_ALERT) {
return (1);
}
switch (status) {
case MOK:
break;
case MNODEST: /* not quite, but not a lie either */
case MERRDEST:
break;
case MNOPERM: /* taken care of up front */
default:
return (1);
/*NOTREACHED*/
}
return (0);
}
/**
** set_action() - CHECK FOR AMBIGUOUS ACTIONS
**/
static Action
#if defined(__STDC__)
char * option
)
#else
char * option;
#endif
{
static char * prev_option;
if (
)
else if (
)
else if (
)
exit (1);
}
return (action);
}
/**
** notify_spooler() - NOTIFY SPOOLER OF ACTION ON FORMS DB
**/
static int
#if defined(__STDC__)
int sendmsg,
int replymsg,
char * form
)
#else
int sendmsg;
int replymsg;
char * form;
#endif
{
char * msgbuf;
int mtype;
int size;
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 (-1);
mclose ();
exit (1);
}
mclose ();
exit (1);
}
mclose ();
exit (1);
}
return (MOK);
if (sendmsg == S_LOAD_FORM)
switch (status) {
case MNOSPACE:
break;
case MNOPERM:
break;
/*
* The following two error conditions should have
* already been trapped, so treat them as bad status
* should they occur.
*/
case MNODEST:
case MERRDEST:
default:
break;
}
if (sendmsg == S_UNLOAD_FORM)
switch (status) {
case MBUSY:
break;
case MNODEST:
return (MNODEST);
case MNOPERM:
break;
default:
break;
}
exit (1);
}
/**
** onerror()
**/
static int
#if defined(__STDC__)
onerror (
int Errno,
int lp_errno,
int linenum
)
#else
int Errno;
int lp_errno;
int linenum;
#endif
{
static int nerrors = 0;
switch (lp_errno) {
case LP_EBADSDN:
break;
case LP_EBADINT:
break;
case LP_EBADNAME:
break;
case LP_EBADARG:
break;
case LP_ETRAILIN:
break;
case LP_EBADCTYPE:
break;
case LP_EBADHDR:
break;
}
if (nerrors++ >= 5) {
return (-1);
}
return (0);
} else {
return (-1);
}
}