805 lines
19 KiB
C
Executable File
805 lines
19 KiB
C
Executable File
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
||
/* All Rights Reserved */
|
||
|
||
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
||
/* The copyright notice above does not evidence any */
|
||
/* actual or intended publication of such source code. */
|
||
|
||
#ident "@(#)main.c 1.6 92/07/14 SMI" /* SVr4.0 1.9 */
|
||
|
||
|
||
/*
|
||
* fmtmsg.c
|
||
*
|
||
* Contains:
|
||
* fmtmsg Command that writes a message in the standard
|
||
* message format. May in future make these
|
||
* messages available for logging.
|
||
*/
|
||
|
||
|
||
/*
|
||
* Header files used:
|
||
* <stdio.h> C Standard I/O function definitions
|
||
* <string.h> C string-handling definitions
|
||
* <errno.h> UNIX error-code "errno" definitions
|
||
* <fmtmsg.h> Standard Message definitions
|
||
*/
|
||
|
||
#include <stdio.h>
|
||
#include <string.h>
|
||
#include <errno.h>
|
||
#include <fmtmsg.h>
|
||
|
||
|
||
/*
|
||
* Externals referenced:
|
||
* strtol Function that converts char strings to "long"
|
||
* fmtmsg Function that writes a message in standard format
|
||
* getenv Function that extracts an environment variable's
|
||
* value
|
||
* malloc Allocate memory from the memory pool
|
||
* free Frees allocated memory
|
||
* getopt Function that extracts arguments from the command-
|
||
* optarg Points to option's argument (from getopt())
|
||
* optind Option's argument index (from getopt())
|
||
* opterr FLAG, write error if invalid option (for getopt())
|
||
* line.
|
||
* exit Exits the command
|
||
*/
|
||
|
||
extern long strtol();
|
||
extern int fmtmsg();
|
||
extern char *getenv();
|
||
extern void *malloc();
|
||
extern void free();
|
||
extern int getopt();
|
||
extern char *optarg;
|
||
extern int optind;
|
||
extern int opterr;
|
||
extern void exit();
|
||
|
||
/*
|
||
* Local definitions
|
||
*/
|
||
|
||
/*
|
||
* Local constants
|
||
*/
|
||
|
||
|
||
/*
|
||
* Boolean constants
|
||
* TRUE Boolean value for "true" (any bits on)
|
||
* FALSE Boolean value for "false" (all bits off)
|
||
*/
|
||
|
||
#ifndef FALSE
|
||
#define FALSE (0)
|
||
#endif
|
||
|
||
#ifndef TRUE
|
||
#define TRUE (1)
|
||
#endif
|
||
|
||
|
||
#define CLASS (MM_PRINT|MM_SOFT|MM_NRECOV|MM_UTIL)
|
||
#define BIGUSAGE "fmtmsg [-a action] [-c class] [-l label] [-s severity] [-t tag]\n [-u subclass[,subclass[,...]]] [text]\n"
|
||
|
||
|
||
/*
|
||
* Local data-type definitions
|
||
*/
|
||
|
||
/*
|
||
* Structure used for tables containing keywords and integer values
|
||
*/
|
||
|
||
struct sev_info {
|
||
char *keyword;
|
||
int value;
|
||
};
|
||
|
||
|
||
/*
|
||
* Structure used for tables containing keywords, long values
|
||
*/
|
||
|
||
struct class_info {
|
||
char *keyword;
|
||
long value;
|
||
long conflict;
|
||
};
|
||
|
||
|
||
/*
|
||
* Severity string structure
|
||
*
|
||
* struct sevstr
|
||
* sevvalue Value of the severity-level being defined
|
||
* sevkywd Keyword identifying the severity
|
||
* sevprptr Pointer to the string associated with the value
|
||
* sevnext Pointer to the next value in the list.
|
||
*/
|
||
|
||
struct sevstr {
|
||
int sevvalue;
|
||
char *sevkywd;
|
||
char *sevprstr;
|
||
struct sevstr *sevnext;
|
||
};
|
||
|
||
|
||
/*
|
||
* Local static data
|
||
*/
|
||
|
||
|
||
/*
|
||
* Table contains the keywords for the classes of a message
|
||
*/
|
||
|
||
static struct class_info classes[] = {
|
||
|
||
{"hard", MM_HARD, MM_SOFT|MM_FIRM}, /* hardware */
|
||
{"soft", MM_SOFT, MM_HARD|MM_FIRM}, /* software */
|
||
{"firm", MM_FIRM, MM_SOFT|MM_FIRM}, /* firmware */
|
||
|
||
{(char *) NULL, 0L, 0L} /* end of list */
|
||
|
||
};
|
||
|
||
|
||
/*
|
||
* Table contains the keywords for the subclasses for a message
|
||
*/
|
||
|
||
static struct class_info subclasses[] = {
|
||
|
||
{"appl", MM_APPL, MM_UTIL|MM_OPSYS}, /* Application */
|
||
{"util", MM_UTIL, MM_APPL|MM_OPSYS}, /* Utility */
|
||
{"opsys", MM_OPSYS, MM_APPL|MM_UTIL}, /* Operating System */
|
||
|
||
{"recov", MM_RECOVER, MM_NRECOV}, /* Recoverable */
|
||
{"nrecov", MM_NRECOV, MM_RECOVER}, /* Non-recoverable */
|
||
|
||
{"print", MM_PRINT, 0L}, /* Write message to stderr */
|
||
{"console", MM_CONSOLE, 0L}, /* Write message on /dev/console */
|
||
{(char *) NULL, 0L, 0L} /* End of list */
|
||
|
||
};
|
||
|
||
|
||
/*
|
||
* Table contains the keywords for the standard severities of a message.
|
||
* User may supply more through the SEV_LEVEL environment variable.
|
||
*/
|
||
|
||
static struct sev_info severities[] = {
|
||
{"halt", MM_HALT}, /* halt */
|
||
{"error", MM_ERROR}, /* error */
|
||
{"warn", MM_WARNING}, /* warn */
|
||
{"info", MM_INFO}, /* info */
|
||
{(char *) NULL, 0} /* end of list */
|
||
};
|
||
|
||
|
||
/*
|
||
* Buffers used by the command
|
||
*/
|
||
|
||
static char labelbuf[128]; /* Buf for message label */
|
||
static char msgbuf[256]; /* Buf for messages */
|
||
|
||
/*
|
||
* static char *exttok(str, delims)
|
||
* char *str
|
||
* char *delims
|
||
*
|
||
* This function examines the string pointed to by "str", looking
|
||
* for the first occurrence of any of the characters in the string
|
||
* whose address is "delims". It returns the address of that
|
||
* character or (char *) NULL if there was nothing to search.
|
||
*
|
||
* Arguments:
|
||
* str Address of the string to search
|
||
* delims Address of the string containing delimiters
|
||
*
|
||
* Returns: char *
|
||
* Returns the address of the first occurrence of any of the characters
|
||
* in "delim" in the string "str" (incl '\0'). If there was nothing
|
||
* to search, the function returns (char *) NULL.
|
||
*
|
||
* Notes:
|
||
* - This function is needed because strtok() can't be used inside a
|
||
* function. Besides, strtok() is destructive in the string, which
|
||
* is undesirable in many circumstances.
|
||
* - This function understands escaped delimiters as non-delimiters.
|
||
* Delimiters are escaped by preceding them with '\' characters.
|
||
* The '\' character also must be escaped.
|
||
*/
|
||
|
||
static char *
|
||
exttok(tok, delims)
|
||
char *tok; /* Ptr to the token we're parsing */
|
||
char *delims; /* Ptr to string with delimiters */
|
||
{
|
||
|
||
/* Automatic Data */
|
||
char *tokend; /* Ptr to the end of the token */
|
||
char *p, *q; /* Temp pointers */
|
||
int done; /* Loop control flag */
|
||
|
||
|
||
/* Algorithm:
|
||
* 1. Get the starting address (new string or where we
|
||
* left off). If nothing to search, return (char *) NULL
|
||
* 2. Find the end of the string
|
||
* 3. Look for the first unescaped delimiter closest to the
|
||
* beginning of the string
|
||
* 4. Remember where we left off
|
||
* 5. Return a pointer to the delimiter we found
|
||
*/
|
||
|
||
/* Begin at the beginning, if any */
|
||
if (tok == (char *) NULL) {
|
||
return ((char *) NULL);
|
||
}
|
||
|
||
/* Find end of the token string */
|
||
tokend = tok + strlen(tok);
|
||
|
||
/* Look for the 1st occurrence of any delimiter */
|
||
for (p = delims ; *p != '\0' ; p++) {
|
||
for (q = strchr(tok, *p) ; q && (q != tok) && (*(q-1) == '\\') ; q = strchr(q+1, *p)) ;
|
||
if (q && (q < tokend)) tokend = q;
|
||
}
|
||
|
||
/* Done */
|
||
return(tokend);
|
||
}
|
||
|
||
/*
|
||
* char *noesc(str)
|
||
*
|
||
* This function squeezes out all of the escaped character sequences
|
||
* from the string <str>. It returns a pointer to that string.
|
||
*
|
||
* Arguments:
|
||
* str char *
|
||
* The string that is to have its escaped characters removed.
|
||
*
|
||
* Returns: char *
|
||
* This function returns its argument <str> always.
|
||
*
|
||
* Notes:
|
||
* This function potentially modifies the string it is given.
|
||
*/
|
||
|
||
char *
|
||
noesc(str)
|
||
char *str; /* String to remove escaped characters from */
|
||
{
|
||
char *p; /* Temp string pointer */
|
||
char *q; /* Temp string pointer */
|
||
|
||
/* Look for an escaped character */
|
||
p = str;
|
||
while (*p && (*p != '\\')) p++;
|
||
|
||
|
||
/*
|
||
* If there was at least one, squeeze them out
|
||
* Otherwise, don't touch the argument string
|
||
*/
|
||
|
||
if (*p) {
|
||
q = p++;
|
||
while (*q++ = *p++) if (*p == '\\') p++;
|
||
}
|
||
|
||
/* Finished. Return our argument */
|
||
return(str);
|
||
}
|
||
|
||
/*
|
||
* struct sevstr *getauxsevs(ptr)
|
||
*
|
||
* Parses a string that is in the format of the severity definitions.
|
||
* Returns a pointer to a (malloc'd) structure that contains the
|
||
* definition, or (struct sevstr *) NULL if none was parsed.
|
||
*
|
||
* Arguments:
|
||
* ptr char *
|
||
* References the string from which data is to be extracted.
|
||
* If (char *) NULL, continue where we left off. Otherwise,
|
||
* start with the string referenced by ptr.
|
||
*
|
||
* Returns: struct sevstr *
|
||
* A pointer to a malloc'd structure containing the severity definition
|
||
* parsed from string, or (struct sevstr *) NULL if none.
|
||
*
|
||
* Notes:
|
||
* - This function is destructive to the string referenced by its argument.
|
||
*/
|
||
|
||
|
||
/* Static data */
|
||
static char *leftoff = (char *) NULL;
|
||
|
||
static struct sevstr *
|
||
getauxsevs(ptr)
|
||
char *ptr;
|
||
{
|
||
|
||
/* Automatic data */
|
||
char *current; /* Ptr to current sev def'n */
|
||
char *tokend; /* Ptr to end of current sev def'n */
|
||
char *kywd; /* Ptr to extracted kywd */
|
||
char *valstr; /* Ptr to extracted sev value */
|
||
char *prstr; /* Ptr to extracted print str */
|
||
char *p; /* Temp pointer */
|
||
int val; /* Converted severity value */
|
||
int done; /* Flag, sev def'n found and ok? */
|
||
struct sevstr *rtnval; /* Value to return */
|
||
|
||
|
||
/* Start anew or start where we left off? */
|
||
current = (ptr == (char *) NULL) ? leftoff : ptr;
|
||
|
||
|
||
/* If nothing to parse, return (char *) NULL */
|
||
if (current == (char *) NULL) {
|
||
return ((struct sevstr *) NULL);
|
||
}
|
||
|
||
|
||
/*
|
||
* Look through the string "current" for a token of the form
|
||
* <kywd>,<sev>,<printstring> delimited by ':' or '\0'
|
||
*/
|
||
|
||
/* Loop initializations */
|
||
done = FALSE;
|
||
rtnval = (struct sevstr *) NULL;
|
||
while (!done) {
|
||
|
||
/* Eat leading junk */
|
||
while (*(tokend = exttok(current, ":,")) == ':') {
|
||
current = tokend + 1;
|
||
}
|
||
|
||
/* If we've found a <kywd>,... */
|
||
if (*tokend == ',') {
|
||
kywd = current;
|
||
*tokend = '\0';
|
||
|
||
/* Look for <kywd>,<sev>,... */
|
||
current = tokend + 1;
|
||
if (*(tokend = exttok(current, ":,")) == ',') {
|
||
valstr = current;
|
||
*tokend = '\0';
|
||
current = tokend+1;
|
||
prstr = current;
|
||
|
||
/* Make sure <sev> > 4 */
|
||
val = (int) strtol(noesc(valstr), &p, 0);
|
||
if ((val > 4) && (p == tokend)) {
|
||
|
||
/*
|
||
* Found <kywd>,<sev>,<printstring>.
|
||
* remember where we left off
|
||
*/
|
||
|
||
if (*(tokend = exttok(current, ":")) == ':') {
|
||
*tokend = '\0';
|
||
leftoff = tokend + 1;
|
||
} else leftoff = (char *) NULL;
|
||
|
||
/* Alloc structure to contain severity definition */
|
||
if (rtnval = (struct sevstr *) malloc(sizeof(struct sevstr))) {
|
||
|
||
/* Fill in structure */
|
||
rtnval->sevkywd = noesc(kywd);
|
||
rtnval->sevvalue = val;
|
||
rtnval->sevprstr = noesc(prstr);
|
||
rtnval->sevnext = (struct sevstr *) NULL;
|
||
}
|
||
|
||
done = TRUE;
|
||
|
||
} else {
|
||
|
||
/* Invalid severity value, eat thru end of token */
|
||
current = tokend;
|
||
if (*(tokend = exttok(prstr, ":")) == ':')
|
||
current++;
|
||
}
|
||
|
||
} else {
|
||
|
||
/* Invalid severity definition, eat thru end of token */
|
||
current = tokend;
|
||
if (*tokend == ':')
|
||
current++;
|
||
}
|
||
|
||
} else {
|
||
|
||
/* End of string found */
|
||
done = TRUE;
|
||
leftoff = (char *) NULL;
|
||
}
|
||
|
||
} /* while (!done) */
|
||
|
||
/* Finished */
|
||
return(rtnval);
|
||
}
|
||
|
||
/*
|
||
* fmtmsg [-a action] [-c classification] [-l label] [-s severity] [-t tag]
|
||
* [-u subclass[,subclass[,...]]] [text]
|
||
*
|
||
* Function:
|
||
* Writes a message in the standard format. Typically used by shell
|
||
* scripts to write error messages to the user.
|
||
*
|
||
* Arguments:
|
||
* text String that is the text of the message
|
||
*
|
||
* Options:
|
||
* -a action String that describes user action to take to
|
||
* correct the situation
|
||
* -c classification Keyword that identifies the type of the message
|
||
* -l label String that identifies the source of the message
|
||
* -s severity Keyword that identifies the severity of the message
|
||
* -t tag String that identifies the message (use unclear)
|
||
* -u sub_classes Comma-list of keywords that refines the type of
|
||
* the message
|
||
*
|
||
* Environment Variables Used:
|
||
* MSGVERB Defines the pieces of a message the user expects
|
||
* to see. It is a list of keywords separated by
|
||
* colons (':').
|
||
* SEV_LEVEL Defines a list of auxiliary severity keywords, values,
|
||
* and print-strings. It is a list of fields separated
|
||
* by colons (':'). Each field consists of three
|
||
* elements, keyword, value (in octal, hex, or decimal),
|
||
* and print-string, separated by commas (',').
|
||
*
|
||
* Needs:
|
||
*
|
||
* Open Issues:
|
||
*/
|
||
|
||
main(argc, argv)
|
||
int argc; /* Argument count */
|
||
char *argv[]; /* Pointers to arguments */
|
||
{
|
||
|
||
/* Local automatic data */
|
||
|
||
long class; /* Classification (built) */
|
||
|
||
int severity; /* User specified severity */
|
||
int msgrtn; /* Value returned by fmtmsg() */
|
||
int optchar; /* Opt char on cmdline */
|
||
int exitval; /* Value to return */
|
||
|
||
int found; /* FLAG, kywd found yet? */
|
||
int errflg; /* FLAG, error seen in cmd */
|
||
int a_seen; /* FLAG, -a option seen */
|
||
int c_seen; /* FLAG, -c option seen */
|
||
int l_seen; /* FLAG, -l option seen */
|
||
int s_seen; /* FLAG, -s option seen */
|
||
int t_seen; /* FLAG, -t option seen */
|
||
int u_seen; /* FLAG, -u option seen */
|
||
int text_seen; /* FLAG, text seen */
|
||
|
||
char *text; /* Ptr to user's text */
|
||
char *label; /* Ptr to user's label */
|
||
char *tag; /* Ptr to user's tag */
|
||
char *action; /* Ptr to user's action str */
|
||
char *sstr; /* Ptr to -s (severity) arg */
|
||
char *ustr; /* Ptr to -u (subclass) arg */
|
||
char *cstr; /* Ptr to -c (class) arg */
|
||
char *sevstrval; /* Ptr to SEV_LEVEL argument */
|
||
char *sevval; /* Ptr to temp SEV_LEVEL arg */
|
||
char *tokenptr; /* Ptr to current token */
|
||
char *cmdname; /* Ptr to base command name */
|
||
char *p; /* Multipurpose ptr */
|
||
|
||
struct class_info *class_info; /* Ptr to class/subclass info structure */
|
||
struct sev_info *sev_info; /* Ptr to severity info struct */
|
||
struct sevstr *penvsev; /* Ptr to SEV_LEVEL values */
|
||
|
||
|
||
|
||
/*
|
||
* fmtmsg
|
||
*/
|
||
|
||
|
||
/* Initializations */
|
||
|
||
|
||
/* Extract the base command name from the command */
|
||
if ((p = strrchr(argv[0], '/')) == (char *) NULL)
|
||
cmdname = argv[0];
|
||
else
|
||
cmdname = p+1;
|
||
|
||
/* Build the label for messages from "fmtmsg" */
|
||
(void) sprintf(labelbuf, "UX:%s", cmdname);
|
||
|
||
|
||
/*
|
||
* Extract arguments from the command line
|
||
*/
|
||
|
||
/* Initializations */
|
||
|
||
opterr = 0; /* Disable messages from getopt() */
|
||
errflg = FALSE; /* No errors seen yet */
|
||
|
||
a_seen = FALSE; /* No action (-a) text seen yet */
|
||
c_seen = FALSE; /* No classification (-c) seen yet */
|
||
l_seen = FALSE; /* No label (-l) seen yet */
|
||
s_seen = FALSE; /* No severity (-s) seen yet */
|
||
t_seen = FALSE; /* No tag (-t) seen yet */
|
||
u_seen = FALSE; /* No subclass (-u) seen yet */
|
||
text_seen = FALSE; /* No text seen yet */
|
||
|
||
|
||
/*
|
||
* If only the command name was used, write out a usage string to
|
||
* the standard output file.
|
||
*/
|
||
|
||
if (argc == 1) {
|
||
(void) fputs(BIGUSAGE, stderr);
|
||
exit(0);
|
||
}
|
||
|
||
|
||
/* Parce command line */
|
||
while (((optchar = getopt(argc, argv, "a:c:l:s:t:u:")) != EOF) &&
|
||
!errflg) {
|
||
|
||
switch(optchar) {
|
||
|
||
case 'a': /* -a actiontext */
|
||
if (!a_seen) {
|
||
action = optarg;
|
||
a_seen = TRUE;
|
||
} else errflg = TRUE;
|
||
break;
|
||
|
||
case 'c': /* -c classification */
|
||
if (!c_seen) {
|
||
cstr = optarg;
|
||
c_seen = TRUE;
|
||
} else errflg = TRUE;
|
||
break;
|
||
|
||
case 'l': /* -l label */
|
||
if (!l_seen) {
|
||
label = optarg;
|
||
l_seen = TRUE;
|
||
} else errflg = TRUE;
|
||
break;
|
||
|
||
case 's': /* -s severity */
|
||
if (!s_seen) {
|
||
sstr = optarg;
|
||
s_seen = TRUE;
|
||
} else errflg = TRUE;
|
||
break;
|
||
|
||
case 't': /* -t tag */
|
||
if (!t_seen) {
|
||
tag = optarg;
|
||
t_seen = TRUE;
|
||
} else errflg = TRUE;
|
||
break;
|
||
|
||
case 'u': /* -u subclasslist */
|
||
if (!u_seen) {
|
||
ustr = optarg;
|
||
u_seen = TRUE;
|
||
} else errflg = TRUE;
|
||
break;
|
||
|
||
case '?': /* -? or unknown option */
|
||
default:
|
||
errflg = TRUE;
|
||
break;
|
||
|
||
} /* esac */
|
||
}
|
||
|
||
|
||
/* Get the text */
|
||
if (!errflg) {
|
||
if (argc == (optind+1)) {
|
||
text = argv[optind];
|
||
text_seen = TRUE;
|
||
}
|
||
else if (argc != optind) {
|
||
errflg = TRUE;
|
||
}
|
||
}
|
||
|
||
|
||
/* Report syntax errors */
|
||
if (errflg) {
|
||
(void) fputs(BIGUSAGE, stderr);
|
||
exit(1);
|
||
}
|
||
|
||
|
||
/*
|
||
* Classification.
|
||
*/
|
||
|
||
class = 0L;
|
||
if (c_seen) {
|
||
|
||
/* Search for keyword in list */
|
||
for (class_info = &classes[0] ;
|
||
(class_info->keyword != (char *) NULL) &&
|
||
(strcmp(cstr, class_info->keyword)) ;
|
||
class_info++) ;
|
||
|
||
/* If invalid (keyword unknown), write a message and exit */
|
||
if (class_info->keyword == (char *) NULL) {
|
||
(void) sprintf(msgbuf, "Invalid class: %s", cstr);
|
||
(void) fmtmsg(CLASS, labelbuf, MM_ERROR, msgbuf,
|
||
MM_NULLACT, MM_NULLTAG);
|
||
exit(1);
|
||
}
|
||
|
||
/* Save classification */
|
||
class = class_info->value;
|
||
|
||
}
|
||
|
||
|
||
/*
|
||
* Subclassification.
|
||
*/
|
||
|
||
if (u_seen) {
|
||
|
||
errflg = FALSE;
|
||
p = strcpy(malloc((unsigned int) strlen(ustr)+1), ustr);
|
||
if ((tokenptr = strtok(p, ",")) == (char *) NULL) errflg = TRUE;
|
||
else do {
|
||
|
||
/* Got a keyword. Look for it in keyword list */
|
||
for (class_info = subclasses ;
|
||
(class_info->keyword != (char *) NULL) &&
|
||
(strcmp(tokenptr, class_info->keyword) != 0) ;
|
||
class_info++) ;
|
||
|
||
/* If found in list and no conflict, remember in class */
|
||
if ((class_info->keyword != (char *) NULL) && ((class & class_info->conflict) == 0L))
|
||
class |= class_info->value;
|
||
else
|
||
errflg = TRUE;
|
||
|
||
} while (!errflg && ((tokenptr = strtok((char *) NULL, ",")) != (char *) NULL)) ;
|
||
|
||
if (errflg) {
|
||
(void) sprintf(msgbuf, "Invalid subclass: %s", ustr);
|
||
(void) fmtmsg(CLASS, labelbuf, MM_ERROR, msgbuf,
|
||
MM_NULLACT, MM_NULLTAG);
|
||
exit(1);
|
||
}
|
||
|
||
}
|
||
|
||
if (!c_seen & !u_seen) class = MM_NULLMC;
|
||
|
||
|
||
|
||
/*
|
||
* Severity.
|
||
*/
|
||
|
||
if (s_seen) {
|
||
|
||
/* If the severity is specified as a number, use that value */
|
||
severity = strtol(sstr, &p, 10);
|
||
if (*p || (strlen(sstr) == 0)) {
|
||
|
||
/* Look for the standard severities */
|
||
for (sev_info = severities ;
|
||
(sev_info->keyword != (char *) NULL) &&
|
||
(strcmp(sstr, sev_info->keyword)) ;
|
||
sev_info++) ;
|
||
|
||
/*
|
||
* If the "severity" argument is one of the standard keywords,
|
||
* remember it for fmtmsg(). Otherwise, look at the SEV_LEVEL
|
||
* environment variable for severity extensions.
|
||
*/
|
||
|
||
/* If the keyword is one of the standard ones, save severity */
|
||
if (sev_info->keyword != (char *) NULL) severity = sev_info->value;
|
||
|
||
else {
|
||
|
||
/*
|
||
* Severity keyword may be one of the extended set, if any.
|
||
*/
|
||
|
||
/* Get the value of the SEV_LEVEL environment variable */
|
||
found = FALSE;
|
||
if ((sevstrval = getenv(SEV_LEVEL)) != (char *) NULL) {
|
||
sevval = (char *) malloc((unsigned int) strlen(sevstrval)+1);
|
||
penvsev = getauxsevs(strcpy(sevval, sevstrval));
|
||
if (penvsev != (struct sevstr *) NULL) do {
|
||
if (strcmp(penvsev->sevkywd, sstr) == 0) {
|
||
severity = penvsev->sevvalue;
|
||
found = TRUE;
|
||
}
|
||
else {
|
||
free(penvsev);
|
||
penvsev = getauxsevs((char *) NULL);
|
||
}
|
||
} while (!found && (penvsev != (struct sevstr *) NULL));
|
||
|
||
if (found) free(penvsev);
|
||
free(sevval);
|
||
}
|
||
|
||
if (!found) {
|
||
(void) sprintf(msgbuf, "Invalid severity: %s", sstr);
|
||
(void) fmtmsg(CLASS, labelbuf, MM_ERROR, msgbuf,
|
||
MM_NULLACT, MM_NULLTAG);
|
||
exit(1);
|
||
}
|
||
|
||
} /* <severity> is not one of the standard severities */
|
||
|
||
} /* <severity> is not numeric */
|
||
|
||
} /* if (s_seen) */
|
||
|
||
else severity = MM_NULLSEV;
|
||
|
||
|
||
/*
|
||
* Other options
|
||
*/
|
||
|
||
if (!a_seen) action = MM_NULLACT;
|
||
if (!l_seen) label = MM_NULLLBL;
|
||
if (!t_seen) tag = MM_NULLTAG;
|
||
if (!text_seen) text = MM_NULLTXT;
|
||
|
||
|
||
/*
|
||
* Write the message
|
||
*/
|
||
|
||
msgrtn = fmtmsg(class, label, severity, text, action ,tag);
|
||
|
||
|
||
/*
|
||
* Return appropriate value to the shell (or wherever)
|
||
*/
|
||
|
||
exitval = 0;
|
||
if (msgrtn == MM_NOTOK) exitval = 32;
|
||
else {
|
||
if (msgrtn & MM_NOMSG) exitval += 2;
|
||
if (msgrtn & MM_NOCON) exitval += 4;
|
||
}
|
||
|
||
exit(exitval);
|
||
return(exitval);
|
||
}
|