/* * 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 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 #include "stdio.h" #include "errno.h" #include "string.h" #include "sys/types.h" #include "sys/stat.h" #include "stdlib.h" #include "lp.h" #include "access.h" #include "form.h" #include "msgs.h" #define WHO_AM_I I_AM_LPFORMS #include "oam.h" #define OPT_LIST "f:F:xlLA:u:W:Q:P:d" #define TMPDIR "/usr/tmp" typedef int (*Action)(); #if defined(__STDC__) static int add_form ( char * , FILE * , FALERT * , char * ); static int add_alert ( char * , FILE * , FALERT * , char * ); static int delete_form ( char * ); static int list_form ( char * ); static int list_alert ( char * ); static int list_both ( char * ); static int any_alert ( char * , FILE * , FALERT * ); 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 () { (void) printf (gettext( "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 main(int argc, char *argv[]) { 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; char stroptsw[] = "-X"; Action action = 0; FILE *input = 0; FORM fbuf; FALERT alert = { (char *)0, -1, -1 }; struct stat statbuf; (void) setlocale (LC_ALL, ""); #if !defined(TEXT_DOMAIN) #define TEXT_DOMAIN "SYS_TEST" #endif (void) textdomain(TEXT_DOMAIN); if (!is_user_admin()) { LP_ERRMSG (ERROR, E_LP_NOTADM); exit (1); } opterr = 0; while ((c = getopt(argc, argv, OPT_LIST)) != -1) { /* * 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. */ (void)strtol (optarg, &rest, 10); if (!rest || (!*rest && rest != optarg)) break; /*FALLTHROUGH*/ case 'f': case 'F': case 'A': case 'u': if (!*optarg) { stroptsw[1] = c; LP_ERRMSG1 (ERROR, E_LP_NULLARG, stroptsw); exit (1); } if (*optarg == '-') { stroptsw[1] = c; LP_ERRMSG1 (ERROR, E_LP_OPTARG, stroptsw); exit (1); } break; } switch (c) { case 'f': if (form) LP_ERRMSG1 (WARNING, E_LP_2MANY, 'f'); form = optarg; if (!syn_name(form)) { LP_ERRMSG1 (ERROR, E_LP_NOTNAME, form); exit (1); } else if (!*form) form = NAME_ALL; break; case 'F': if (input) LP_ERRMSG1 (WARNING, E_LP_2MANY, 'F'); if (!(input = fopen(optarg, "r"))) { LP_ERRMSG1 (ERROR, E_FOR_OPEN, optarg); exit (1); } action = set_action(add_form, "-F"); break; case 'A': if (STREQU(NAME_LIST, optarg)) action = set_action(list_alert, "\"-A list\""); else if (STREQU(NAME_QUIET, optarg)) action = set_action(quiet_alert, "\"-A quiet\""); else { if (STREQU(MAIL, optarg) || STREQU(WRITE, optarg)) alert.shcmd = makestr(optarg, " ", getname(), (char *)0); else alert.shcmd = strdup(optarg); action = set_action(add_alert, "-A"); } break; case 'Q': if (alert.Q != -1) LP_ERRMSG1 (WARNING, E_LP_2MANY, 'Q'); if (STREQU(NAME_ANY, optarg)) alert.Q = 1; else { alert.Q = strtol(optarg, &rest, 10); if (alert.Q < 0) { LP_ERRMSG1 (ERROR, E_LP_NEGARG, 'Q'); exit (1); } if (rest && *rest) { LP_ERRMSG1 (ERROR, E_LP_GARBNMB, 'Q'); exit (1); } if (alert.Q == 0) { LP_ERRMSG1 (ERROR, E_LP_ZEROARG, 'Q'); exit (1); } } action = set_action(add_alert, "-Q"); break; case 'W': if (alert.W != -1) LP_ERRMSG1 (WARNING, E_LP_2MANY, 'W'); if (STREQU(NAME_ONCE, optarg)) alert.W = 0; else { alert.W = strtol(optarg, &rest, 10); if (alert.W < 0) { LP_ERRMSG1 (ERROR, E_LP_NEGARG, 'W'); exit (1); } if (rest && *rest) { LP_ERRMSG1 (ERROR, E_LP_GARBNMB, 'W'); exit (1); } } action = set_action(add_alert, "-W"); break; case 'u': if (u) LP_ERRMSG1 (WARNING, E_LP_2MANY, 'u'); u = strdup(optarg); action = set_action(add_form, "-u"); break; case 'x': action = set_action(delete_form, "-x"); break; case 'L': L = 1; action = set_action(list_form, "-L"); break; case 'l': action = set_action(list_form, "-l"); break; case 'd': d = 1; action = set_action(add_form, "-d"); break; case 'P': if (P) LP_ERRMSG1 (WARNING, E_LP_2MANY, 'P'); action = set_action(add_form, "-P"); P = strdup(optarg); break; default: if (optopt == '?') { usage (); exit (0); } stroptsw[1] = optopt; if (strchr(OPT_LIST, optopt)) LP_ERRMSG1 (ERROR, E_LP_OPTARG, stroptsw); else LP_ERRMSG1 (ERROR, E_LP_OPTION, stroptsw); exit (1); } } if (!form) { LP_ERRMSG (ERROR, E_FOR_FORMNAME); exit (1); } if (STREQU(NAME_ANY, form)) action = set_action(any_alert, "\"-f any\""); if (optind < argc && STREQU(argv[optind], "-")) { action = set_action(add_form, "-"); input = stdin; optind++; } if (optind < argc) LP_ERRMSG1 (WARNING, E_FOR_EXTRAARG, argv[optind]); if (!action) { LP_ERRMSG (ERROR, E_FOR_NOACT); exit (1); } if (action == any_alert && STREQU(alert.shcmd, NAME_NONE)) { LP_ERRMSG (WARNING, E_FOR_ANYDEL); 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 ( ( action == add_form && !alert.shcmd && (alert.Q != -1 || alert.W != -1) && !STREQU(NAME_ALL, form) && getform(form, &fbuf, (FALERT *)0, (FILE **)0) != 0 ) || action == any_alert && !alert.shcmd ) { LP_ERRMSG (ERROR, E_FOR_NOSHCMDERR); return (1); } if (P && (! STREQU(P,form))) { while (P && (cnt++ < 2)) { /* * two times should do it unless user has edited * files directly */ if (getform(P, &fbuf, (FALERT *)0, (FILE **)0) != -1) { if (!fbuf.paper) { LP_ERRMSG3(ERROR, E_FOR_ALSO_SEP_FORM, form, P, P); return (1); } else if (!STREQU(fbuf.paper, P)) P = Strdup(fbuf.paper); else break; /* we found a good paper */ } else { int result; int saveD; saveD = d; d = 1; result = ((*action)(P, NULL, &alert, u)); d = saveD; return (result ? result : ((*action)(form, input, &alert, u))); } } } if (d && !P) P = Strdup(form); return ((*action)(form, input, &alert, u)); } /** ** add_alert() ** add_form() **/ /* * "add_alert()" exists just to simplify the checking of mixed * options in "set_action()". */ static int #if defined(__STDC__) add_alert ( char * form, FILE * input, FALERT * p_new_alert, char * u ) #else add_alert (form, input, new_alert, u) char * form; FILE * input; FALERT * p_new_alert; char * u; #endif { return (add_form(form, input, p_new_alert, u)); } static int #if defined(__STDC__) add_form ( char * form, FILE * input, FALERT * p_new_alert, char * u ) #else add_form (form, input, new_alert, u) char * form; FILE * input; FALERT * p_new_alert; char * u; #endif { int fld; int which_set[FO_MAX]; int new_form = 0; int nform; int return_code; char * all_list[] = { NAME_ALL, 0 }; char ** u_allow = 0; char ** u_deny = 0; FILE * align_fp = 0; FORM fbuf; FORM new_fbuf; FALERT alert; /* * 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) { for (fld = 0; fld < FO_MAX; fld++) which_set[fld] = 0; if (rdform(form, &new_fbuf, fileno(input), onerror, which_set) == -1) { LP_ERRMSG2 (ERROR, E_FOR_UNKNOWN, "(input)", PERROR); return (1); } for (fld = 0; fld < FO_MAX; fld++) if (which_set[fld]) break; if (fld >= FO_MAX) LP_ERRMSG (WARNING, E_FOR_EMPTYFILE); /* * Read the alignment pattern (if any) into a temporary * file so that it can be used for (potentially) many * forms. */ if (which_set[FO_ALIGN]) { size_t n; char buf[BUFSIZ]; if ((align_fp = tmpfile()) == NULL) { LP_ERRMSG (ERROR, E_FOR_CTMPFILE); exit (1); } while ((n = fread(buf, 1, BUFSIZ, input))) fwrite (buf, 1, n, align_fp); } } /* * Parse the user allow/deny list (if any). */ if (u) { char * cp; char * type; type = strtok(u, ":"); cp = strtok((char *)0, ":"); if (STREQU(type, NAME_ALLOW) && cp) { if (!(u_allow = getlist(cp, LP_WS, LP_SEP))) LP_ERRMSG1 ( WARNING, E_LP_MISSING, NAME_ALLOW ); } else if (STREQU(type, NAME_DENY) && cp) { if (!(u_deny = getlist(cp, LP_WS, LP_SEP))) LP_ERRMSG1 ( WARNING, E_LP_MISSING, NAME_DENY ); } else { LP_ERRMSG (ERROR, E_LP_UALLOWDENY); 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) { /* * If we are adding/changing a single form, set * the loop control to get us out. */ if (!STREQU(NAME_ALL, form)) return_code = 0; nform++; if (P) { memset ((char *)&fbuf, 0, sizeof(FORM)); fbuf.name = strdup(form); fbuf.plen.val = DPLEN; fbuf.plen.sc = 0; fbuf.pwid.val = DPWIDTH; fbuf.pwid.sc = 0; fbuf.lpi.val = DLPITCH; fbuf.lpi.sc = 0; fbuf.cpi.val = DCPITCH; fbuf.cpi.sc = 0; fbuf.np = DNP; fbuf.chset = strdup(DCHSET); fbuf.mandatory = 0; fbuf.rcolor = strdup(DRCOLOR); fbuf.conttype = strdup(DCONTYP); fbuf.paper = P; fbuf.isDefault = d; alert.shcmd = 0; alert.W = alert.Q = -1; new_form = 1; } else if (getform(form, &fbuf, &alert, (FILE **)0) == -1) switch (errno) { case ENOENT: /* * This is a problem only if it occurs * immediately on trying to get ``all''. */ if (STREQU(NAME_ALL, form)) { if (nform > 1) return_code = 0; else { LP_ERRMSG (ERROR, E_FOR_NOFORMS); return_code = 1; } continue; } /* * We're adding a new form, * so set up default values. */ memset ((char *)&fbuf, 0, sizeof(FORM)); fbuf.name = strdup(form); fbuf.plen.val = DPLEN; fbuf.plen.sc = 0; fbuf.pwid.val = DPWIDTH; fbuf.pwid.sc = 0; fbuf.lpi.val = DLPITCH; fbuf.lpi.sc = 0; fbuf.cpi.val = DCPITCH; fbuf.cpi.sc = 0; fbuf.np = DNP; fbuf.chset = strdup(DCHSET); fbuf.mandatory = 0; fbuf.rcolor = strdup(DRCOLOR); fbuf.conttype = strdup(DCONTYP); alert.shcmd = 0; alert.W = alert.Q = -1; 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. */ LP_ERRMSG2 (ERROR, E_LP_GETFORM, form, PERROR); return_code = 1; continue; } /* * Copy just those items that were given in the input. */ if (!input && new_form && !P) { LP_ERRMSG1 (ERROR, E_LP_NOFORM, form); return (1); } if (input) for (fld = 0; fld < FO_MAX; fld++) if (which_set[fld]) switch(fld) { case FO_PLEN: fbuf.plen = new_fbuf.plen; break; case FO_PWID: fbuf.pwid = new_fbuf.pwid; break; case FO_CPI: fbuf.cpi = new_fbuf.cpi; break; case FO_LPI: fbuf.lpi = new_fbuf.lpi; break; case FO_NP: fbuf.np = new_fbuf.np; break; case FO_CHSET: fbuf.chset = new_fbuf.chset; fbuf.mandatory = new_fbuf.mandatory; break; case FO_RCOLOR: fbuf.rcolor = new_fbuf.rcolor; break; case FO_CMT: fbuf.comment = new_fbuf.comment; break; case FO_ALIGN: fbuf.conttype = new_fbuf.conttype; rewind (align_fp); break; case FO_PAPER: fbuf.paper = new_fbuf.paper; fbuf.isDefault = new_fbuf.isDefault; 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 ( !alert.shcmd && !p_new_alert->shcmd && (p_new_alert->W != -1 || p_new_alert->Q != -1) ) LP_ERRMSG1 (WARNING, E_FOR_NOSHCMDWARN, fbuf.name); else { if (p_new_alert->shcmd) alert.shcmd = 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; } /* * Create/update the form. */ #define P_FBUF (new_form || input? &fbuf : (FORM *)0) if (putform(fbuf.name, P_FBUF, &alert, &align_fp) == -1) { LP_ERRMSG2 (ERROR, E_LP_PUTFORM, fbuf.name, PERROR); return_code = 1; continue; } /* * Allow/deny users. */ if (new_form && allow_user_form(all_list, fbuf.name) == -1) { LP_ERRMSG1 (ERROR, E_LP_ACCESSINFO, PERROR); return_code = 1; continue; } if (u_allow && allow_user_form(u_allow, fbuf.name) == -1) { LP_ERRMSG1 (ERROR, E_LP_ACCESSINFO, PERROR); return_code = 1; continue; } if (u_deny && deny_user_form(u_deny, fbuf.name) == -1) { LP_ERRMSG1 (ERROR, E_LP_ACCESSINFO, PERROR); return_code = 1; continue; } notify_spooler (S_LOAD_FORM, R_LOAD_FORM, fbuf.name); } if (align_fp) close_lpfile (align_fp); return (return_code); } /** ** list_form() ** list_alert() ** list_both() **/ #if defined(__STDC__) static int list ( char * , void (*)() ); static void _list_form ( FORM * , FALERT * , FILE * ); static void _list_alert ( FORM * , FALERT * ); static void _list_both ( FORM * , FALERT * , FILE * ); #else static int list(); static void _list_form(); static void _list_alert(); static void _list_both(); #endif static int #if defined(__STDC__) list_form ( char *form ) #else list_form (form) char *form; #endif { return (list(form, _list_form)); } static int #if defined(__STDC__) list_alert ( char *form ) #else list_alert (form) char *form; #endif { return (list(form, _list_alert)); } static int #if defined(__STDC__) list_both ( char *form ) #else list_both (form) char *form; #endif { return (list(form, _list_both)); } static int #if defined(__STDC__) list ( char *form, void (*subaction)() ) #else list (form, subaction) char *form; void (*subaction)(); #endif { FORM fbuf; FALERT alert; FILE * align_fp; char *nl; if (STREQU(NAME_ALL, form)) { nl = ""; while (getform(form, &fbuf, &alert, &align_fp) == 0) { printf (gettext("%sForm name: %s\n"), nl, fbuf.name); (*subaction) (&fbuf, &alert, align_fp); 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. */ LP_ERRMSG2 (ERROR, E_LP_GETFORM, form, PERROR); return (1); } } else { if (getform(form, &fbuf, &alert, &align_fp) == 0) { (*subaction) (&fbuf, &alert, align_fp); return (0); } switch (errno) { case ENOENT: LP_ERRMSG1 (ERROR, E_LP_NOFORM, form); return (1); default: LP_ERRMSG2 (ERROR, E_LP_GETFORM, form, PERROR); return (1); } } } /** ** _list_form() **/ static void #if defined(__STDC__) _list_form ( FORM * pf, FALERT * palert, FILE * align_fp ) #else _list_form (pf, palert, align_fp) FORM * pf; FALERT * palert; FILE * align_fp; #endif { size_t n; char buf[BUFSIZ]; int which_set[FO_MAX]; int fld,whichVal; whichVal = (pf->paper && (L == 0) ? 0 : 1); for (fld = 0; fld < FO_MAX; fld++) which_set[fld] = whichVal; if (!align_fp) which_set[FO_ALIGN] = 0; if (pf->paper) which_set[FO_PAPER] = 1; wrform (pf->name, pf, 1, onerror, which_set); if (align_fp) while ((n = fread(buf, 1, BUFSIZ, align_fp))) write (1, buf, n); } /** ** _list_alert() **/ static void #if defined(__STDC__) _list_alert ( FORM * ignore, FALERT * palert ) #else _list_alert (ignore, palert) FORM * ignore; FALERT * palert; #endif { printalert (stdout, palert, 0); } /** ** _list_both() **/ static void #if defined(__STDC__) _list_both ( FORM * pf, FALERT * palert, FILE * align_fp ) #else _list_both (pf, palert, align_fp) FORM * pf; FALERT * palert; FILE * align_fp; #endif { _list_alert (pf, palert); _list_form (pf, palert, align_fp); } /** ** any_alert() **/ static int #if defined(__STDC__) any_alert ( char * form, FILE * ignore, FALERT * p_new_alert ) #else any_alert (form, ignore, p_new_alert) char * form; FILE * ignore; FALERT * p_new_alert; #endif { FORM fbuf; FALERT alert; while (getform(NAME_ALL, &fbuf, &alert, (FILE **)0) == 0) if (!alert.shcmd) if (putform(fbuf.name, (FORM *)0, p_new_alert, (FILE **)0) == -1) { LP_ERRMSG2 (ERROR, E_LP_PUTFORM, fbuf.name, PERROR); 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__) delete_form ( char *form ) #else delete_form (form) char *form; #endif { return (dq(form, _delete_form)); } static int #if defined(__STDC__) quiet_alert ( char * form ) #else quiet_alert (form) char * form; #endif { return (dq(form, _quiet_alert)); } static int #if defined(__STDC__) dq ( char *form, int (*subaction)() ) #else dq (form, subaction) char *form; int (*subaction)(); #endif { FORM fbuf; if (STREQU(NAME_ANY, form) || STREQU(NAME_NONE, form)) { LP_ERRMSG (ERROR, E_FOR_ANYNONE); exit (1); } if (STREQU(NAME_ALL, form)) { while (getform(form, &fbuf, (FALERT *)0, (FILE **)0) == 0) if ((*subaction)(fbuf.name) == 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. */ LP_ERRMSG2 (ERROR, E_LP_GETFORM, form, PERROR); return (1); } } else { if (getform(form, &fbuf, (FALERT *)0, (FILE **)0) == 0) return ((*subaction)(fbuf.name)); switch (errno) { case ENOENT: LP_ERRMSG1 (ERROR, E_LP_NOFORM, form); return (1); default: LP_ERRMSG2 (ERROR, E_LP_GETFORM, form, PERROR); return (1); } } } static int #if defined(__STDC__) _delete_form ( char *form ) #else _delete_form (form) char *form; #endif { switch (notify_spooler(S_UNLOAD_FORM, R_UNLOAD_FORM, form)) { case -1: if (anyrequests()) { LP_ERRMSG (ERROR, E_FOR_MOPENREQX); return (1); } /*FALLTHROUGH*/ case MNODEST: if (delform(form) == -1) { if (errno == ENOENT) { LP_ERRMSG1 (ERROR, E_LP_NOFORM, form); return (1); } else { LP_ERRMSG2 ( ERROR, E_FOR_UNKNOWN, form, PERROR ); return (1); } } break; case MOK: if (delform(form) == -1) { LP_ERRMSG (ERROR, E_FOR_DELSTRANGE); return (1); } break; } return (0); } static int #if defined(__STDC__) _quiet_alert ( char * form ) #else _quiet_alert (form) 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); size = putmessage (NULL, S_QUIET_ALERT, form, QA_FORM); msgbuf = malloc(size); putmessage (msgbuf, S_QUIET_ALERT, form, QA_FORM); if (msend(msgbuf) == -1) { LP_ERRMSG (ERROR, E_LP_MSEND); mclose (); return (1); } if (mrecv(msgbuf, size) == -1) { LP_ERRMSG (ERROR, E_LP_MRECV); mclose (); return (1); } mtype = getmessage(msgbuf, R_QUIET_ALERT, &status); free (msgbuf); mclose (); if (mtype != R_QUIET_ALERT) { LP_ERRMSG (ERROR, E_LP_BADREPLY); return (1); } switch (status) { case MOK: break; case MNODEST: /* not quite, but not a lie either */ case MERRDEST: LP_ERRMSG1 (WARNING, E_LP_NOQUIET, form); break; case MNOPERM: /* taken care of up front */ default: LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status); return (1); /*NOTREACHED*/ } return (0); } /** ** set_action() - CHECK FOR AMBIGUOUS ACTIONS **/ static Action #if defined(__STDC__) set_action ( Action action, char * option ) #else set_action (action, option) Action action; char * option; #endif { static Action prev_action = 0; static char * prev_option; if ( action == list_form && prev_action == list_alert || action == list_alert && prev_action == list_form ) action = list_both; else if ( action == add_form && prev_action == add_alert || action == add_alert && prev_action == add_form ) action = add_form; else if ( action == any_alert && prev_action == add_alert || action == add_alert && prev_action == any_alert ) action = any_alert; else if (prev_action && prev_action != action) { LP_ERRMSG2 (ERROR, E_LP_AMBIG, option, prev_option); exit (1); } OK: prev_action = action; prev_option = option; return (action); } /** ** notify_spooler() - NOTIFY SPOOLER OF ACTION ON FORMS DB **/ static int #if defined(__STDC__) notify_spooler ( int sendmsg, int replymsg, char * form ) #else notify_spooler (sendmsg, replymsg, form) 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); size = putmessage((char *)0, sendmsg, form); msgbuf = malloc(size); putmessage (msgbuf, sendmsg, form); if (msend(msgbuf) == -1) { LP_ERRMSG (ERROR, E_LP_MSEND); mclose (); exit (1); } if (mrecv(msgbuf, size) == -1) { LP_ERRMSG (ERROR, E_LP_MRECV); mclose (); exit (1); } mclose (); mtype = getmessage(msgbuf, replymsg, &status); free (msgbuf); if (mtype != replymsg) { LP_ERRMSG (ERROR, E_LP_BADREPLY); exit (1); } if (status == MOK) return (MOK); if (sendmsg == S_LOAD_FORM) switch (status) { case MNOSPACE: LP_ERRMSG (ERROR, E_FOR_NOSPACE); break; case MNOPERM: LP_ERRMSG (ERROR, E_LP_NOTADM); 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: LP_ERRMSG1 (ERROR, E_LP_BADSTATUS, status); break; } if (sendmsg == S_UNLOAD_FORM) switch (status) { case MBUSY: LP_ERRMSG1 (ERROR, E_FOR_FORMBUSY, form); break; case MNODEST: return (MNODEST); case MNOPERM: LP_ERRMSG (ERROR, E_LP_NOTADM); break; default: LP_ERRMSG (ERROR, E_LP_BADSTATUS); break; } exit (1); } /** ** onerror() **/ static int #if defined(__STDC__) onerror ( int Errno, int lp_errno, int linenum ) #else onerror (Errno, lp_errno, linenum) int Errno; int lp_errno; int linenum; #endif { static int nerrors = 0; if (Errno == EBADF) { switch (lp_errno) { case LP_EBADSDN: LP_ERRMSG1 (WARNING, E_FOR_BADSCALE, linenum); break; case LP_EBADINT: LP_ERRMSG1 (WARNING, E_FOR_BADINT, linenum); break; case LP_EBADNAME: LP_ERRMSG1 (WARNING, E_FOR_NOTNAME, linenum); break; case LP_EBADARG: LP_ERRMSG1 (WARNING, E_FOR_BADCHSETQUALIFIER, linenum); break; case LP_ETRAILIN: LP_ERRMSG1 (WARNING, E_FOR_TRAILIN, linenum); break; case LP_EBADCTYPE: LP_ERRMSG1 (WARNING, E_FOR_NOTCTYPE, linenum); break; case LP_EBADHDR: LP_ERRMSG1 (WARNING, E_FOR_BADHDR, linenum); break; } if (nerrors++ >= 5) { LP_ERRMSG (ERROR, E_LP_GARBAGE); return (-1); } return (0); } else { LP_ERRMSG2 (ERROR, E_FOR_UNKNOWN, "(stdin)", PERROR); return (-1); } }