Files
seta75D d6fe8fe829 Init
2021-10-11 22:19:34 -03:00

1962 lines
58 KiB
C

static char sccsid[] = "@(#)42 1.1 src/bldenv/sbtools/libsb/interface.c, bldprocess, bos412, GOLDA411a 4/29/93 12:21:33";
/*
* Copyright (c) 1990, 1991, 1992
* Open Software Foundation, Inc.
*
* Permission is hereby granted to use, copy, modify and freely distribute
* the software in this file and its documentation for any purpose without
* fee, provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation. Further, provided that the name of Open
* Software Foundation, Inc. ("OSF") not be used in advertising or
* publicity pertaining to distribution of the software without prior
* written permission from OSF. OSF makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*/
/*
* ODE 2.1.1
*/
/******************************************************************************
** Open Software Foundation **
** Cambridge, MA **
** Randy Barbano, Damon Poole, Martha Hester **
** December 1990 **
*******************************************************************************
**
** Description: These functions provide a common user interface for the
** ODE tools. They parse the command line, provide an interface to
** the information, and provide a common way of printing out messages.
**
** functions:
** ui_init (int, ** char, int, * struct) int
** ui_set_progname (* char) int
** init_htable ( int, ** char) int
** hvalue (* char) unsigned
** init_one (* struct, * char, int) void
** load_htable (int, * struct) void
** test_conflicts (* struct) void
** match_pattern (* char) * struct
** hvalue
** hvalue
** rc_file_options (int, ** char, * char, * int, *** char) BOOLEAN
** get_local_rcfile (* char, * char, * char) BOOLEAN
** ui_print (int, * char, va_list) void
** get_dotsbx_options (* char, * char, * int, *** char) BOOLEAN
** ui_print
** get_options (* struct, * char) * char
** next_token (** char, * char) BOOLEAN
** skip_white_space (** char) void
** ui_print
** load_options (int, ** char, int, * struct) int
** built_ins (* char) * char
** special_case (* char) BOOLEAN
** ui_unset (* char) int
** match_pattern
** ui_print
** entry_pattern (* char, * struct, int) * char
** match_pattern
** load_entry (* struct, * struct, ** char, * char, int, * int) void
** load_min_args (* struct, ** char, ** struct, int, * int, * int) void
** match_arg_list (* char, * char) BOOLEAN
** in_arg_list (* struct, * char) BOOLEAN
** load_max_args (* struct, ** char, ** struct, int, * int, * int) void
** match_arg_list
** in_arg_list
** ui_unset
** set_duplicates (* struct, ** struct, * char) void
** match_entry (* struct, * char, ** struct) void
** print_htable () void
** ui_print
** print_internals (* struct, * struct, * struct, int) void
** ui_print
** ui_restore_progname () int
** ui_load (* char, int, va_list) int
** built_ins
** special_case
** match_pattern
** ui_print
** load_entry
** ui_unset
** set_duplicates
** ui_is_set (* char) BOOLEAN
** match_pattern
** ui_print
** ui_entry_cnt (* char) int
** match_pattern
** ui_print
** ui_arg_cnt (* char, int) int
** ui_print
** match_pattern
** ui_entry_value (* char, int) * char
** ui_print
** match_pattern
** ui_arg_value (* char, int, int) * char
** ui_print
** match_pattern
** arg_value (* struct, int, int) * char
** ui_print
** ui_entries_to_argv (* char, *** char) int
** match_pattern
** ui_print
** ui_args_to_argv (* char, int, *** char) int
** ui_print
** match_pattern
** ui_ver_switch () * char
** ui_print
** ui_is_auto () BOOLEAN
** ui_is_info () BOOLEAN
** ui_ver_level () int
**
*/
# include "ui.h"
int ui_init ( argc, argv, initct, init )
/*
* Initialize ui with the argv passed in as well as any switches
* appearing in the rc file. This procedure must be called before
* any of the other library procedures are called. This replaces
* the old call to parse_cmd_line.
* Returns ERROR if not successful, OK otherwise.
*/
int argc; /* the number of command line arugments */
char ** argv; /* strings with each argument */
int initct; /* count of lines to initialize */
UIINIT * init; /* initialization information */
{
char ** arglist; /* list of rc file arguments */
int argct; /* rc file arg count */
from_ui_load = FALSE;
ui_set_progname ( "ui_init" );
init_htable ( argc, argv );
load_htable ( initct, init );
if ( rc_file_options ( argc, argv, &argct, &arglist ))
load_options ( argct, arglist, initct, init );
load_options ( argc - 1, argv + 1, initct, init );
print_htable ();
ui_restore_progname ();
return ( OK );
} /* ui init */
ui_set_progname ( newname )
/*
* Put the newname into progname after having saved the
* initial value.
*/
char * newname; /* new name of progname */
{
save_progname = progname;
progname = newname;
} /* ui set_progname */
ui_restore_progname ()
/*
* Puts previous progname back into progname.
*/
{
progname = save_progname;
} /* ui restore progname */
static init_htable ( argc, argv )
/*
* Initializes the entire hash table with default values.
* Also loads the know options.
*/
int argc; /* the number of command line arugments */
char ** argv; /* strings with each argument */
{
HTABLE * hptr; /* points to one entry */
int ct; /* misc counter */
auto_pos = hvalue ( AUTO_OP );
info_pos = hvalue ( INFO_OP );
if (( argc > 1 ) && streq ( argv[1], DEBUG_OP ))
verbosity = VDEBUG; /* a way to get inside interface info */
else if (( argc > 1 ) && streq ( argv[1], VERBOSE_OP ))
verbosity = VDETAIL;
else
verbosity = VNORMAL;
if (( htbl = (HTABLE *) malloc (sizeof ( HTABLE ) * HTABLESIZE)) == NULL )
uquit ( ERROR, FALSE, "sys: cannot create space for user interface.\n" );
for ( ct = 0; ct < HTABLESIZE; ct++ ) {
hptr = htbl + ct;
hptr->pattern = salloc ( EMPTY_STRING );
hptr->entry = NULL;
hptr->arg_list = NULL;
hptr->entry_list = NULL;
hptr->next_pattern = NULL;
hptr->num_entries = hptr->num_args = 0;
} /* for */
init_one ( htbl + auto_pos, AUTO_OP, 0 );
init_one ( htbl + info_pos, INFO_OP, 0 );
init_one ( htbl + hvalue ( RC_OP), RC_OP, 1 );
init_one ( htbl + hvalue ( SB_RC_OP), SB_RC_OP, 1 );
} /* init htable */
static unsigned hvalue ( string )
/*
* Calculates the hash value of the string.
*/
char * string; /* string to get value of */
{
unsigned hashval; /* cumulative value */
for ( hashval = 0; *string != NUL; string++ )
hashval = *string + 31 * hashval;
return ( hashval % HTABLESIZE );
} /* hvalue */
static void init_one ( hptr, pattern, argct )
/*
* Initializes a single hash table entry.
*/
HTABLE * hptr; /* points to one entry */
char * pattern; /* pattern to match */
int argct; /* args allowed or needed */
{
hptr->pattern = salloc ( pattern );
hptr->duplicates = OVERWRITE;
hptr->max_entries = 1;
hptr->min_args = hptr->max_args = argct;
if ( argct == 0 )
hptr->legal_args = salloc ( EMPTY_STRING );
else
hptr->legal_args = salloc ( ARGS_OP );
} /* init one */
static void load_htable ( initct, init )
/*
* loads the initial values into the hash table. The
* build-in values are already loaded.
*/
int initct; /* count of lines to initialize */
UIINIT * init; /* initialization information */
{
HTABLE * hptr; /* points to one entry */
UIINIT * iptr; /* points to initialization information */
int ct; /* misc counter */
for ( ct = 0; ct < initct; ct++ ) {
iptr = init + ct;
test_conflicts ( iptr );
if (( hptr = match_pattern ( iptr->pattern )) != NULL )
uquit ( ERROR, FALSE,
"internal error: program has duplicate patterns: %s.\n",
iptr->pattern );
hptr = htbl + hvalue ( iptr->pattern );
if ( ! streq ( hptr->pattern, EMPTY_STRING )) {
while ( hptr->next_pattern != NULL )
hptr = hptr->next_pattern;
hptr->next_pattern = ( HTABLE * ) malloc ( sizeof ( HTABLE ));
hptr = hptr->next_pattern;
hptr->entry = NULL;
hptr->entry_list = NULL;
hptr->arg_list = NULL;
hptr->next_pattern = NULL;
hptr->num_entries = hptr->num_args = 0;
} /* if */
hptr->pattern = iptr->pattern;
hptr->duplicates = iptr->duplicates;
hptr->max_entries = iptr->max_entries;
hptr->min_args = iptr->min_args;
hptr->max_args = iptr->max_args;
hptr->legal_args = iptr->legal_args;
} /* for */
} /* load htable */
static void test_conflicts ( iptr )
/*
* Tests user entered intialization array to make sure it is
* legal.
*/
UIINIT * iptr; /* points to initialization information */
{
if ( *(iptr->pattern) == NUL )
uquit ( ERROR, FALSE, "internal error: UIINIT pattern set to NULL.\n" );
if ( iptr->max_entries < 1 && iptr->max_entries != UNLIMITED )
uquit ( ERROR, FALSE,
"internal error: UIINIT %s max_enties < 1.\n", iptr->pattern );
if ( iptr->duplicates < TOGGLE || iptr->duplicates > ACCUM )
uquit ( ERROR, FALSE,
"internal error: UIINIT %s duplicates out of range.\n", iptr->pattern );
if ( iptr->min_args < 0 )
uquit ( ERROR, FALSE,
"internal error: UIINIT %s min_args < 0.\n", iptr->pattern );
if ( iptr->max_args < UNLIMITED )
uquit ( ERROR, FALSE,
"internal error: UIINIT %s max_args < 0.\n", iptr->pattern );
if ( iptr->min_args > iptr->max_args && iptr-> max_args != UNLIMITED )
uquit ( ERROR, FALSE,
"internal error: UIINIT %s max_args < min_args.\n", iptr->pattern );
if ( iptr->legal_args == NULL )
uquit ( ERROR, FALSE,
"internal error: UIINIT %s legal_args set to NULL.\n", iptr->pattern );
if ( iptr->max_args == 0 && iptr->duplicates == ACCUM )
uquit ( ERROR, FALSE,
"internal error: UIINIT %s max_args = 0 && duplicates = ACCUM.\n",
iptr->pattern );
if ( iptr->max_entries != 1 && iptr->duplicates == TOGGLE )
uquit ( ERROR, FALSE,
"internal error: UIINIT %s max_entires != 1 && duplicates = TOGGLE.\n",
iptr->pattern );
if ( iptr->max_entries > 1 && *(iptr->pattern) != '!' &&
( strpbrk ( iptr->pattern, "*?[" ) == NULL ))
uquit ( ERROR, FALSE,
"internal error: UIINIT unique pattern %s allows max_entires > 1.\n",
iptr->pattern );
} /* test conflicts */
static HTABLE * match_pattern ( pattern )
/*
* Finds the match to the pattern in the hash table.
* Returns a pointer to the table entry; NULL if none found.
*/
char * pattern; /* pattern to match in table */
{
HTABLE * hptr; /* points to one entry */
hptr = htbl + hvalue ( pattern );
while ( hptr != NULL ) {
if ( streq ( hptr->pattern, pattern ))
break;
hptr = hptr->next_pattern;
} /* while */
return ( hptr );
} /* match pattern */
static BOOLEAN rc_file_options ( argc, argv, rc_argc, rc_argv )
/*
* Determine the rc file to parse for default options.
*/
int argc; /* the number of command line arugments */
char ** argv; /* command line arguments */
int * rc_argc; /* the number of rc file options */
char *** rc_argv; /* strings with each argument */
{
char ** argv_ptr, /* agrv traveler */
* rc_file_name, /* name of rc file */
* nameonly; /* in case more than name given */
int argn; /* misc counter */
BOOLEAN alt_rc = FALSE; /* misc boolean */
/* Check to see if a different .sandboxrc file should be used. */
argv_ptr = argv + 1;
if ( ( nameonly = strrchr ( *argv, SLASH )) != NULL )
nameonly++;
else
nameonly = *argv;
for ( argn = 1; argn < argc; argn++ ) {
if ( streq ( *argv_ptr, RC_OP )) {
alt_rc = TRUE;
break;
} /* if */
argv_ptr++;
} /* end for */
if ( alt_rc ) {
if ( access ( *(++argv_ptr), R_OK ) == OK )
rc_file_name = *argv_ptr;
else if ( ! get_local_rcfile ( *argv_ptr, &rc_file_name, EMPTY_STRING )) {
ui_print ( VDEBUG, "Could not find rc file : %s\n", *argv_ptr );
return ( FALSE );
} /* else if */
} /* if */
else if ( ! get_local_rcfile ( nameonly, &rc_file_name, RCEXT )) {
if ( ! get_default_usr_rcfile ( &rc_file_name, FALSE ))
return ( FALSE );
} /* else if */
ui_print ( VDETAIL, "Reading rc file : %s\n", rc_file_name );
return ( get_dotsbx_options ( rc_file_name, nameonly, rc_argc, rc_argv ));
} /* rc file options */
static BOOLEAN get_local_rcfile ( cname, rcfile, ext )
/*
* Builds path and searches for existence of rc file with same
* name as program calling routine.
* Returns TRUE if local name is found; FALSE otherwise.
*/
char * cname, /* command name */
** rcfile, /* string to hold name of file */
* ext; /* extension to end of file name */
{
char trcfile [ PATH_LEN ], /* temporary holder */
* env_input; /* holds values from getenv */
if (( env_input = getenv ( "HOME" )) == NULL )
return ( FALSE );
if ( streq ( ext, EMPTY_STRING ))
concat ( trcfile, PATH_LEN, env_input, "/", cname, ext, NULL );
else
concat ( trcfile, PATH_LEN, env_input, "/.", cname, ext, NULL );
if ( access ( trcfile, R_OK ) != OK ) {
*rcfile = NULL;
return ( FALSE );
} /* if */
*rcfile = salloc ( trcfile );
return ( TRUE );
} /* get local rcfile */
void ui_print ( va_alist )
/*
* This procedure takes the in va_alist and parses out the
* pieces it needs then passes the rest to a regular print
* routine. It provides a standard printing routine for
* the ODE commands.
*/
va_dcl
{
va_list arglist; /* variable length arg list */
int msg_verbosity; /* print on verbosity level */
char * msg_format; /* printf formatting */
static char * outfmt[] = { /* leader for output */
"", /* VALWAYS */
">> FATAL ERROR", /* VFATAL */
"", /* VQUIET */
">> WARNING", /* VWARN */
"", /* VNORMAL */
">> DIAGNOSTIC", /* VDIAG */
"> ", /* VDETAIL */
">> DEBUG INFO" /* VDEBUG */
};
static FILE * outfile[] = { /* placement of output */
stdout, /* VALWAYS */
stderr, /* VFATAL */
stdout, /* VQUIET */
stderr, /* VWARN */
stdout, /* VNORMAL */
stderr, /* VDIAG */
stdout, /* VDETAIL */
stderr /* VDEBUG */
};
static int last_ver = VNORMAL; /* former verbosity level */
fflush ( stdout );
va_start ( arglist );
msg_verbosity = va_arg ( arglist, int );
if (( msg_verbosity <= verbosity ) ||
( msg_verbosity == VCONT && last_ver <= verbosity )) {
msg_format = va_arg ( arglist, char * );
if ( msg_verbosity == VFATAL || msg_verbosity == VWARN ||
msg_verbosity == VDIAG || msg_verbosity == VDEBUG )
fprintf ( outfile[msg_verbosity], "%s in %s:\n>> ",
outfmt[msg_verbosity], progname );
if ( msg_verbosity == VDETAIL )
fprintf ( outfile[msg_verbosity], "%s", outfmt[msg_verbosity] );
if ( msg_verbosity == VCONT ) {
if ( last_ver == VFATAL || last_ver == VWARN ||
last_ver == VDIAG || last_ver == VDEBUG )
fprintf ( outfile[last_ver], ">> " );
else if ( last_ver == VDETAIL )
fprintf ( outfile[last_ver], "> " );
vfprintf ( outfile[last_ver], msg_format, arglist );
} /* if */
else
vfprintf ( outfile[msg_verbosity], msg_format, arglist );
} /* if */
if ( msg_verbosity != VCONT )
last_ver = msg_verbosity;
va_end ( arglist );
}
static BOOLEAN get_dotsbx_options ( rc_file_name, command, rcargc, rcargv )
/*
* Reads the options from the .sandboxrc file
* Returns TRUE if file was read.
*/
char * rc_file_name; /* name of rc file to parse */
char * command; /* name of command to look for */
int * rcargc; /* option count */
char *** rcargv; /* list of options */
{
FILE * rcfile; /* ptr to rc file */
char * options, /* list of options found in sandbox */
token [ TOKEN_LENGTH ]; /* holds each option */
int alloc_arg = 10, /* available arguments */
ct; /* misc counter */
if (( rcfile = fopen ( rc_file_name, READ )) == NULL ) {
ui_print ( VWARN, "could not open %s.\n", rc_file_name );
return ( FALSE );
} /* if */
options = get_options ( rcfile, command );
if ( options == NULL || *options == NUL )
return ( FALSE ); /* return immediately if options is empty */
if (( *rcargv = (char **) calloc ( 10, sizeof (char *))) == NULL ) {
ui_print ( VWARN, "could not calloc space for rc file options.\n" );
return ( FALSE );
} /* if */
*rcargc = 0; /* Allocate 10 args, realloc later if more needed. */
do {
if ( ! next_token ( &options, token ))
return ( FALSE );
if ( *token == NUL || *token == SPACE )
break;
rm_newline ( token );
if ( *rcargc >= alloc_arg ) {
alloc_arg += 10;
if (( *rcargv = (char **) realloc
( *rcargv, sizeof (char *) * alloc_arg )) == NULL )
return ( FALSE );
} /* if */
if (( (*rcargv)[*rcargc] = salloc ( token )) == NULL )
return ( FALSE );
(*rcargc)++;
} while ( TRUE );
ui_print ( VDEBUG, "Tokens are:\n" );
for ( ct = 0; ct < *rcargc; ct++ )
ui_print ( VCONT, "%s\n", (*rcargv)[ct] );
fclose ( rcfile );
return ( TRUE );
} /* get dotsbx options */
static char * get_options ( rc_file, command )
/*
* Generic procedure to find the options associated with a
* command in a given file.
*/
FILE * rc_file; /* file to read from */
char * command; /* command to search for */
{
char * ptr, /* misc pointer to each line */
* field,
buf [ PATH_LEN ], /* misc string */
options [ PATH_LEN ],
options2 [ PATH_LEN ];
*options = NUL;
while ( fgets ( buf, PATH_LEN, rc_file ) != NULL ) {
if (( ptr = index ( buf, '#' )) != NULL ) /* Check for comment. */
*ptr = NUL;
ptr = buf;
field = nxtarg ( &ptr, WHITESPACE );
if ( *field == NUL )
continue;
/* For every line which matches the desired command,
* add the list of options to the end of the options string. */
if ( gmatch ( command, field )) {
concat ( options2, PATH_LEN, options, " ", ptr, NULL );
strcpy ( options, options2 );
} /* if */
} /* while */
ptr = options + strlen ( options ) - 1;
return ( salloc ( options ));
} /* get options */
static BOOLEAN next_token ( str, token )
/*
* This function extracts the next token from the string.
* Returns TRUE if there is not an illegal token.
*/
char ** str; /* string to parse */
char token[]; /* token to fill */
{
char * env;
int ct, /* misc counter */
expand,
braces;
if ( *str != NULL )
skip_white_space ( str );
if ( *str == NULL || **str == NUL || **str == NEWLINE ) {
*token = NUL;
return ( TRUE );
} /* if */
/* If a '$' is encountered, the remainder of the token is an
* environment variable and needs to be expanded. Strip off
* the '$' and record the fact that it needs to be expanded. */
expand = FALSE;
braces = FALSE;
if ( **str == '$' ) {
expand = TRUE;
(*str)++;
if ( **str == '{' ) {
braces = TRUE;
(*str)++;
} /* if */
} /* if */
/* A token is either all of the characters within quotes or all of
* the characters between two areas of whitespace. */
ct = 0;
if ( **str == '"' ) {
(*str)++;
while ( **str != NUL && **str != '"' ) {
if ( ct >= TOKEN_LENGTH ) {
ui_print ( VWARN, "token too long: %s.\n", *str );
return ( FALSE );
} /* if */
token[ct++] = *(*str)++;
} /* while */
if ( **str == '"' )
(*str)++;
} /* if */
else if ( braces ) {
(*str)++;
while ( **str != NUL && **str != '}' ) {
if( ct >= TOKEN_LENGTH ) {
ui_print ( VWARN, "token too long: %s.\n", *str );
return ( FALSE );
} /* if */
token[ct++] = *(*str)++;
} /* while */
if(**str == '}')
(*str)++;
} /* else if */
else {
while ( ! WHITESPACEFN ( *str ) && **str != NUL ) {
if( ct >= TOKEN_LENGTH ) {
ui_print ( VWARN, "token too long: %s.\n", *str );
return ( FALSE );
} /* if */
token[ct++] = *(*str)++;
} /* while */
} /* else */
if ( ct < TOKEN_LENGTH )
token[ct] = NUL;
/* If a '$' was encountered earlier, expand the token. */
if ( expand ) {
env = getenv ( token );
if ( strlen ( env ) > TOKEN_LENGTH ) {
ui_print ( VWARN, "Environment variable too long: %s\n", env );
return ( FALSE );
} /* if */
else
strcpy ( token, env );
if ( token == NULL )
token = salloc ( EMPTY_STRING );
} /* endif */
return ( TRUE );
} /* next token */
static void skip_white_space ( str )
/* advance to none white space */
char ** str;
{
while ( WHITESPACEFN (*str) && **str != NUL )
(*str)++;
} /* skip white space */
static int load_options ( usrct, usr_list, initct, init )
/*
* Enters the arg_list into the ui information table. First
* the build in's and special cases are checked, then the user
* entries. Then load them according to type: first time,
* toggles, repeats of overwrite and accums.
* Returns ERROR if there is a failure; OK otherwise.
*/
int usrct; /* number of arguments to parse */
char ** usr_list; /* list of arguments */
int initct; /* count of lines to initialize */
UIINIT * init; /* initialization information */
{
HTABLE * hptr; /* points to one table pattern */
ENTRY_SET * eptr = NULL; /* points to entry */
char * opt, /* points to option */
* pattern; /* pattern to match option */
int ct = 0; /* count of arg list being parsed */
while ( ct < usrct ) {
opt = *(usr_list + ct);
if (( pattern = built_ins ( opt )) == NULL ) {
if ( special_case ( opt )) { /* try build in, special case before user */
ct++;
continue;
} /* if */
if (( pattern = entry_pattern ( opt, init, initct )) == NULL )
uiquit ( ERROR, TRUE, "No such option: %s.\n", opt );
} /* if */
if (( hptr = match_pattern ( pattern )) == NULL )
uquit ( ERROR, FALSE, "Program error in ui function load_options.\n" );
if ( hptr->num_entries == 0 )
load_entry ( hptr, NULL, usr_list, opt, usrct, &ct );
else if ( hptr->duplicates == TOGGLE )
ui_unset ( pattern );
else {
set_duplicates ( hptr, &eptr, opt );
load_entry ( hptr, eptr, usr_list, opt, usrct, &ct );
} /* else */
ct++;
} /* while */
} /* load options */
static char * built_ins ( opt )
/*
* Checks to see if the opt matches one of the built-in
* patterns.
* Returns pointer to pattern if found; else NULL.
*/
char * opt; /* option to check */
{
if ( streq ( opt, AUTO_OP ))
return ( salloc ( AUTO_OP ));
if ( streq ( opt, INFO_OP ))
return ( salloc ( INFO_OP ));
if ( streq ( opt, RC_OP ))
return ( salloc ( RC_OP ));
if ( streq ( opt, SB_RC_OP ))
return ( salloc ( SB_RC_OP ));
return ( NULL );
} /* built ins */
static char * entry_pattern ( entry, patlist, patct )
/*
* Finds pattern to match entry in pattern list. Purpose is to
* search patlist in same order as program provided it.
* Returns pointer to pattern if found; else NULL.
*/
char * entry; /* entry to match */
UIINIT * patlist; /* pattern list to search through */
int patct; /* number of patterns in list */
{
UIINIT * pptr; /* points to pattern list */
int ct; /* misc counter */
for ( ct = 0; ct < patct; ct++ ) {
pptr = patlist + ct;
if ( gmatch ( entry, pptr->pattern ))
return ( pptr->pattern );
} /* for */
return ( NULL );
} /* entry pattern */
static BOOLEAN special_case ( opt )
/*
* Checks option against internal, special values. If there
* is a match, it carries out the appropriate action.
* Returns TRUE if opt matches a special case.
*/
char * opt; /* option to check */
{
if ( streq ( opt, QUIET_OP ))
verbosity = VQUIET;
else if ( streq ( opt, NORMAL_OP ))
verbosity = VNORMAL;
else if ( streq ( opt, VERBOSE_OP ))
verbosity = VDETAIL;
else if ( streq ( opt, DEBUG_OP ))
verbosity = VDEBUG;
else if ( streq ( opt, NOAUTO_OP )) {
if ( ui_unset ( AUTO_OP ) != OK )
ui_print ( VWARN, "Error in program; unable to unset %s.\n", AUTO_OP );
} /* else if */
else if ( streq ( opt, USAGE_OP )) {
ui_restore_progname ();
print_usage ();
exit ( OK );
} /* else if */
else if ( streq ( opt, REV_OP ) || streq ( opt, VERSION_OP ) ) {
ui_restore_progname ();
ui_print_revision ();
exit ( OK );
} /* else if */
else
return ( FALSE );
return ( TRUE );
} /* special case */
int set_ver ( opt )
/*
* Allows setting of verbosity. This is a temporary function.
* Returns OK if verbosity level is legal, else ERROR.
*/
char * opt; /* option to check */
{
if ( streq ( opt, QUIET_OP ))
verbosity = VQUIET;
else if ( streq ( opt, NORMAL_OP ))
verbosity = VNORMAL;
else if ( streq ( opt, VERBOSE_OP ))
verbosity = VDETAIL;
else if ( streq ( opt, DEBUG_OP ))
verbosity = VDEBUG;
else
return ( ERROR );
return ( OK );
} /* set ver */
int ui_unset ( pattern )
/*
* Unsets the ui information for pattern. Sets the pattern
* back to its initialized state.
* Returns ERROR if there is no such pattern; OK otherwise.
*/
char * pattern; /* pattern to match in table */
{
HTABLE * hptr; /* points to one table pattern */
if (( hptr = match_pattern ( pattern )) == NULL )
return ( ERROR );
hptr->entry = NULL;
hptr->arg_list = NULL;
hptr->entry_list = NULL;
hptr->next_pattern = NULL;
hptr->num_entries = hptr->num_args = 0;
return ( OK );
} /* ui unset */
static int load_entry ( hptr, eptr, usrlist, entry, usrct, pct )
/*
* Puts entry into place indicated by hptr and eptr.
*/
HTABLE * hptr; /* points to table pattern to fill */
ENTRY_SET * eptr; /* points to entry to load */
char ** usrlist; /* list of user supplied arguments */
char * entry; /* points to user supplied entry */
int usrct, /* number of user supplied arguments */
* pct; /* pointer to count of user list */
{
(hptr->num_entries)++;
if ( hptr->num_entries > hptr->max_entries &&
hptr->max_entries != UNLIMITED ) {
uiquit ( ERROR, TRUE, "More than %d entr%s for option: %s.\n",
hptr->max_entries, hptr->max_entries > 1 ? "ies" : "y", hptr->pattern );
return ( ERROR );
} /* if */
if ( eptr == NULL ) {
hptr->entry = entry;
if ( load_min_args ( hptr, usrlist, &(hptr->arg_list), usrct,
&(hptr->num_args), pct ) == ERROR )
return ( ERROR );
load_max_args ( hptr, usrlist, &(hptr->arg_list), usrct,
&(hptr->num_args), pct );
} /* if */
else {
eptr->entry = entry;
if ( load_min_args ( hptr, usrlist, &(eptr->arg_list), usrct,
&(eptr->num_args), pct ) == ERROR )
return ( ERROR );
load_max_args ( hptr, usrlist, &(eptr->arg_list), usrct,
&(eptr->num_args), pct );
return ( ERROR );
} /* else */
return ( OK );
} /* load entry */
uiquit ( va_alist )
/* This procedure takes a variable length argument list and
prints out the name of the function that failed, the error
message, usage if asked for, and then, if it is not a from
ui_load error, exits with the code entered. This program
is actually uquit with a check for ui_load added. */
va_dcl
{
va_list args; /* see vprintf(3) and varargs(5) for details */
int status, /* status to exit with */
usage; /* do you print usage */
char * fmt; /* format string */
fflush ( stdout );
va_start ( args );
status = va_arg ( args, int ); /* gets the first argument and type */
usage = va_arg ( args, int ); /* gets the second argument and type */
fmt = va_arg ( args, char * );
if ( from_ui_load )
fprintf ( stderr, "ERROR: " );
else {
ui_restore_progname ();
fprintf ( stderr, ">> FATAL ERROR in %s:\n ", progname );
} /* if */
vfprintf ( stderr, fmt, args ); /* print out error message */
if ( usage )
print_usage ();
va_end ( args );
if ( ! from_ui_load )
exit ( status );
} /* uiquit */
static int load_min_args ( hptr, usrlist, arglist, usrct, argct, pcount )
/*
* This function attempts to load the minimum number of required
* arguments into the entry.
*/
HTABLE * hptr; /* points to one table pattern */
char ** usrlist; /* list of user supplied arguments */
ARG_SET ** arglist; /* place to put argument list */
int usrct, /* the number of user arugments */
* argct, /* running total of arguments for entry */
* pcount; /* counts current usrlist */
{
ARG_SET * argptr; /* points to additonal args */
if ( *arglist != NULL ) {
argptr = *arglist;
while ( argptr->next_arg != NULL ) /* bring argptr to end of arglist */
argptr = argptr->next_arg;
} /* if */
while ( *argct < hptr->min_args ) { /* get min number fields */
if ( *pcount + 1 < usrct )
(*pcount)++;
else {
uiquit ( ERROR, TRUE, "option %s requires %d argument%s.\n",
hptr->pattern, hptr->min_args, hptr->min_args == 1 ? "" : "s" );
return ( ERROR );
} /* else */
if ( ! match_arg_list ( *(usrlist + *pcount), hptr->legal_args )) {
uiquit ( ERROR, TRUE,
"argument: %s, not in %s's list of legal arguments. List is:\n\t%s\n",
*(usrlist + *pcount), hptr->pattern, hptr->legal_args );
return ( ERROR );
} /* if */
if ( in_arg_list ( *arglist, *(usrlist + *pcount)))
continue;
if ( *arglist == NULL ) {
*arglist = ( ARG_SET * ) malloc ( sizeof ( ARG_SET ));
argptr = *arglist;
} /* if */
else {
argptr->next_arg = ( ARG_SET * ) malloc ( sizeof ( ARG_SET ));
argptr = argptr->next_arg;
} /* else */
argptr->arg = *(usrlist + *pcount);
argptr->next_arg = NULL;
(*argct)++;
} /* while */
return ( OK );
} /* load min args */
static BOOLEAN match_arg_list ( arg, list )
/*
* Tests the argument to see if it is in the legal list.
* Returns TRUE if it is; FALSE otherwise.
*/
char * arg, /* argument to check */
* list; /* space separated list to check against */
{
char copy [ PATH_LEN ], /* don't touch original list */
* listptr, /* points to copy of list */
* token; /* holds each match from list */
strcpy ( copy, list );
listptr = copy;
while ( (*(token = nxtarg ( &listptr, WHITESPACE ))) != NUL ) {
if ( gmatch ( arg, token ))
return ( TRUE );
} /* while */
return ( FALSE );
} /* match arg list */
static BOOLEAN in_arg_list ( list, arg )
/*
* Checks to see if arg is already in list.
* Returns TRUE if arg is in list.
*/
ARG_SET * list; /* list of args to check */
char * arg; /* argument to check for */
{
while ( list != NULL ) {
if ( streq ( list->arg, arg ))
return ( TRUE );
list = list->next_arg;
} /* while */
return ( FALSE );
} /* in arg list */
static void load_max_args ( hptr, usrlist, arglist, usrct, argct, pcount )
/*
* This function attempts to load up to the maximum number of
* required arguments into the entry.
*/
HTABLE * hptr; /* points to one table pattern */
char ** usrlist; /* list of user supplied arguments */
ARG_SET ** arglist; /* place to put argument list */
int usrct, /* the number of user arugments */
* argct, /* running total of arguments for entry */
* pcount; /* counts current usrlist */
{
ARG_SET * argptr; /* points to additonal args */
BOOLEAN in = TRUE; /* misc boolean */
if ( *arglist != NULL ) {
argptr = *arglist;
while ( argptr->next_arg != NULL ) /* bring argptr to end of arglist */
argptr = argptr->next_arg;
} /* if */
while ((( hptr->max_args == UNLIMITED ) || ( *argct < hptr->max_args )) &&
in ) {
if ( *pcount + 1 < usrct ) {
(*pcount)++;
if (! (in = match_arg_list (*(usrlist + *pcount), hptr->legal_args )))
(*pcount)--;
else {
if ( in_arg_list ( *arglist, *(usrlist + *pcount)))
continue;
if ( *arglist == NULL ) {
*arglist = ( ARG_SET * ) malloc ( sizeof ( ARG_SET ));
argptr = *arglist;
} /* if */
else {
argptr->next_arg = ( ARG_SET * ) malloc ( sizeof ( ARG_SET ));
argptr = argptr->next_arg;
} /* else */
argptr->arg = *(usrlist + *pcount);
argptr->next_arg = NULL;
(*argct)++;
} /* else */
} /* if */
else
in = FALSE;
} /* while */
} /* load max args */
static int set_duplicates ( hptr, eeptr, entry )
/*
* Sets counts and pointers appropriately for handling OVERWRITE
* and ACCUM duplicates.
*/
HTABLE * hptr; /* points to one table pattern */
ENTRY_SET ** eeptr; /* points to entry ptr */
char * entry; /* points to entry */
{
if ( hptr->max_entries == 1 ) {
if ( ! streq ( hptr->entry, entry )) {
if ( streq ( ARGS_OP, hptr->pattern ))
uiquit ( ERROR, TRUE, "Only 1 argument allowed.\n" );
else
uiquit ( ERROR, TRUE, "More than 1 entry for option: %s.\n",
hptr->pattern );
return ( ERROR );
} /* if */
hptr->num_entries = 0;
if ( hptr->duplicates != ACCUM ) { /* overwrite existing entry */
hptr->num_args = 0;
hptr->arg_list = NULL;
} /* else */
else if ( ! streq ( hptr->entry, entry )) {
hptr->num_args = 0; /* can't accum different entry */
hptr->arg_list = NULL;
} /* else if */
} /* if */
else {
match_entry ( hptr, entry, eeptr );
if ( hptr->duplicates == OVERWRITE ) {
if ( *eeptr == NULL ) {
hptr->num_args = 0;
hptr->arg_list = NULL;
} /* if */
else {
(*eeptr)->num_args = 0;
(*eeptr)->arg_list = NULL;
} /* else */
} /* if */
} /* else */
return ( OK );
} /* set duplicates */
static void match_entry ( hptr, entry, eeptr )
/*
* Finds matching entry and set the eptr to it. If there is
* no entry yet or the new entry matches the first entry in
* the apattern, return eeptr as NULL. If the new entry matches
* an existing entry, return a pointer to that entry. Finally,
* if the entry does not exist, create space for it.
*/
HTABLE * hptr; /* points to one table pattern */
char * entry; /* option to actually match */
ENTRY_SET ** eeptr; /* points to entry */
{
*eeptr = NULL;
if ( hptr->entry == NULL )
return;
if ( streq ( hptr->entry, entry )) { /* entry already in place */
(hptr->num_entries)--; /* subtract entry as it will be added later */
return;
} /* if */
if ( hptr->entry_list == NULL ) {
hptr->entry_list = ( ENTRY_SET * ) malloc ( sizeof ( ENTRY_SET ));
*eeptr = hptr->entry_list;
} /* if */
else {
*eeptr = hptr->entry_list;
if ( streq ( (*eeptr)->entry, entry )) {
(hptr->num_entries)--;
return;
} /* if */
while ( (*eeptr)->next_entry != NULL ) {
*eeptr = (*eeptr)->next_entry;
if ( streq ( (*eeptr)->entry, entry )) {
(hptr->num_entries)--;
return;
} /* if */
} /* while */
(*eeptr)->next_entry = ( ENTRY_SET * ) malloc ( sizeof ( ENTRY_SET ));
*eeptr = (*eeptr)->next_entry;
} /* else */
(*eeptr)->num_args = 0;
(*eeptr)->arg_list = NULL;
(*eeptr)->next_entry = NULL;
} /* match entry */
static void print_htable ()
/*
* Prints out the initialized portion of the hash table.
*/
{
HTABLE * hptr; /* points to each table entry */
ARG_SET * aptr; /* points to args */
ENTRY_SET * eptr; /* points to entries */
int ct; /* misc counter */
ui_print ( VDEBUG, "Contents of interface table:\n" );
for ( ct = 0; ct < HTABLESIZE; ct++ ) {
hptr = htbl + ct;
aptr = hptr->arg_list;
eptr = hptr->entry_list;
if ( *(hptr->pattern) != NUL ) {
print_internals ( hptr, aptr, eptr, ct );
hptr = hptr->next_pattern;
while ( hptr != NULL ) {
aptr = hptr->arg_list;
eptr = hptr->entry_list;
print_internals ( hptr, aptr, eptr, -1 );
hptr = hptr->next_pattern;
} /* while */
} /* if */
} /* for */
ui_print ( VCONT, "vl=%d; ap=%d; ip=%d.\n", verbosity, auto_pos, info_pos );
} /* print htable */
static void print_internals ( hptr, aptr, eptr, ct )
/*
* Prints out internals of a single hash table entry.
*/
HTABLE * hptr; /* points to table entry */
ARG_SET * aptr; /* points to args */
ENTRY_SET * eptr; /* points to entries */
int ct; /* table entry */
{
if ( ct == -1 )
ui_print ( VCONT, " %s: maxe=%d; dup=%d; mina=%d; maxa=%d; a=%s.\n",
hptr->pattern, hptr->max_entries, hptr->duplicates,
hptr->min_args, hptr->max_args, hptr->legal_args );
else
ui_print ( VCONT, "%-2d: %s: maxe=%d; dup=%d; mina=%d; maxa=%d; a=%s.\n",
ct, hptr->pattern, hptr->max_entries, hptr->duplicates,
hptr->min_args, hptr->max_args, hptr->legal_args );
if ( hptr->num_entries > 0 ) {
ui_print ( VCONT, " e=%s; numa=%d; nume=%d.\n",
hptr->entry, hptr->num_args, hptr->num_entries );
while ( aptr != NULL ) {
ui_print ( VCONT, " arg: %s.\n", aptr->arg );
aptr = aptr->next_arg;
} /* while */
while ( eptr != NULL ) {
aptr = eptr->arg_list;
ui_print ( VCONT, " e=%s: numa=%d.\n", eptr->entry, eptr->num_args );
while ( aptr != NULL ) {
ui_print ( VCONT, " arg: %s\n", aptr->arg );
aptr = aptr->next_arg;
} /* while */
eptr = eptr->next_entry;
} /* while */
} /* if */
} /* print internals */
int ui_load ( va_alist )
/*
* Looks for exact match to pattern and loads the table
* entry. It peals off the first two arguments to get the
* pattern to match and the arg count. It then creates a
* **char list of the rest of the arguments and passes this
* to the functions that load entries.
* Returns OK if it is successful, else ERROR.
*/
va_dcl
{
HTABLE * hptr; /* points to one pattern */
va_list arglist; /* variable length arg list */
char * pattern, /* pattern to match in table */
* match, /* misc string ptr */
** vlist; /* holds list of arguments from arglist */
int argct, /* number of arguments to parse */
ct, /* dummy counter */
rvalue = OK; /* return value */
from_ui_load = TRUE;
fflush ( stdout );
va_start ( arglist );
pattern = va_arg ( arglist, char * ); /* load first two fields */
argct = va_arg ( arglist, int );
if (( match = built_ins ( pattern )) == NULL ) {
if ( special_case ( pattern )) { /* try built in, special case */
va_end ( arglist );
from_ui_load = FALSE;
return ( rvalue );
} /* if */
pattern = salloc ( pattern );
} /* if */
else
pattern = match;
if (( hptr = match_pattern ( pattern )) == NULL ) {
ui_print ( VDEBUG, "pattern: %s, not in entry table.\n", pattern );
rvalue = ERROR;
} /* if */
if ( rvalue != ERROR && hptr->max_entries != 1 ) {
ui_print ( VDEBUG, "cannot ui_load pattern: %s, with max_entries: %d.\n",
pattern, hptr->max_entries );
rvalue = ERROR;
} /* if */
if ( rvalue != ERROR ) {
if ( argct > 0 ) {
argct++; /* account for pattern */
if (( vlist = ( char ** ) calloc ( argct, sizeof ( char * ))) == NULL )
uquit ( ERROR, FALSE, "sys: could not calloc space for vlist.\n" );
*vlist = pattern;
for ( ct = 1; ct < argct; ct++ )
*(vlist + ct) = salloc ( va_arg ( arglist, char * ));
} /* if */
ct = 0;
if ( hptr->num_entries == 0 ) {
if ( load_entry ( hptr, NULL, vlist, pattern, argct, &ct ) == ERROR )
rvalue = ERROR;
} /* if */
else if ( hptr->duplicates == TOGGLE ) {
if ( ui_unset ( pattern ) == ERROR )
rvalue = ERROR;
} /* else if */
else {
if ( set_duplicates ( hptr, NULL, pattern ) == ERROR )
rvalue = ERROR;
else if ( load_entry ( hptr, NULL, vlist, pattern, argct, &ct ) == ERROR )
rvalue = ERROR;
} /* else */
} /* if */
va_end ( arglist );
from_ui_load = FALSE;
return ( rvalue );
} /* ui load */
BOOLEAN ui_is_set ( pattern )
/*
* Returns TRUE if pattern's entry is set; FALSE otherwise.
*/
char * pattern; /* pattern to match in table */
{
HTABLE * hptr; /* points to one pattern */
if (( hptr = match_pattern ( pattern )) == NULL ) {
ui_print ( VDEBUG, "pattern: %s, not in entry table.\n", pattern );
return ( FALSE );
} /* if */
return ( hptr->num_entries != 0 );
} /* ui is set */
int ui_entry_cnt ( pattern )
/*
* Returns number of entries which match pattern; 0 if no entries
* matched the pattern; ERROR if no such pattern.
*/
char * pattern; /* pattern to match in table */
{
HTABLE * hptr; /* points to one pattern */
if (( hptr = match_pattern ( pattern )) == NULL ) {
ui_print ( VDEBUG, "pattern: %s, not in entry table.\n", pattern );
return ( ERROR );
} /* if */
return ( hptr->num_entries );
} /* ui entry cnt */
int ui_arg_cnt ( pattern, entry_num )
/*
* Returns number of arguments in entry; 0 if no entries matched
* the pattern; ERROR if no such pattern or entry_num.
*/
char * pattern; /* pattern to match in table */
int entry_num; /* entry number of matching pattern */
{
HTABLE * hptr; /* points to one pattern */
ENTRY_SET * eptr; /* points to one entry */
int ct; /* misc counter */
if ( entry_num < 1 ) {
ui_print ( VDEBUG, "entry number: %d, is less than 1.\n", entry_num );
return ( ERROR );
} /* if */
if (( hptr = match_pattern ( pattern )) == NULL ) {
ui_print ( VDEBUG, "pattern: %s, not in entry table.\n", pattern );
return ( ERROR );
} /* if */
if ( hptr->num_entries == 0 )
return ( 0 ); /* can use this to check for existence of match */
if ( entry_num == 1 )
return ( hptr->num_args );
if ( entry_num > hptr->num_entries ) {
ui_print ( VDEBUG,
"entry number: %d, greater than number of entries: %d.\n",
entry_num, hptr->num_entries );
return ( ERROR );
} /* if */
eptr = hptr->entry_list;
for ( ct = 2; ct < entry_num; ct++ )
eptr = eptr->next_entry;
return ( eptr->num_args );
} /* ui arg cnt */
char * ui_entry_value ( pattern, entry_num )
/*
* Value of a particular entry of a particular pattern.
* Returns pointer to string; NULL if no such pattern or entry_num
* or pattern not matched.
*/
char * pattern; /* pattern to match in table */
int entry_num; /* entry number of matching pattern */
{
HTABLE * hptr; /* points to one pattern */
ENTRY_SET * eptr; /* points to one entry */
int ct; /* misc counter */
if ( entry_num < 1 ) {
ui_print ( VDEBUG, "entry number: %d, is less than 1.\n", entry_num );
return ( NULL );
} /* if */
if (( hptr = match_pattern ( pattern )) == NULL ) {
ui_print ( VDEBUG, "pattern: %s, not in entry table.\n", pattern );
return ( NULL );
} /* if */
if ( hptr->num_entries == 0 )
return ( NULL ); /* can use this to check for existence of match */
if ( entry_num == 1 )
return ( hptr->entry );
if ( entry_num > hptr->num_entries ) {
ui_print ( VDEBUG,
"entry number: %d, greater than number of entries: %d.\n",
entry_num, hptr->num_entries );
return ( NULL );
} /* if */
eptr = hptr->entry_list;
for ( ct = 2; ct < entry_num; ct++ )
eptr = eptr->next_entry;
return ( eptr->entry );
} /* ui entry value */
char * ui_arg_value ( pattern, entry_num, arg_num )
/*
* Value of a particular argument of a particular entry.
* Returns pointer to string; NULL if no such pattern, entry_num,
* or arg_num, also NULL if pattern not matched.
*/
char * pattern; /* pattern to match in table */
int entry_num; /* entry number of matching pattern */
int arg_num; /* argument number of entry */
{
HTABLE * hptr; /* points to one pattern */
ENTRY_SET * eptr; /* points to one entry */
int ct; /* misc counter */
if ( entry_num < 1 ) {
ui_print ( VDEBUG, "entry number: %d, is less than 1.\n", entry_num );
return ( NULL );
} /* if */
if ( arg_num < 1 ) {
ui_print ( VDEBUG, "argument number: %d, is less than 1.\n", arg_num );
return ( NULL );
} /* if */
if (( hptr = match_pattern ( pattern )) == NULL ) {
ui_print ( VDEBUG, "pattern: %s, not in entry table.\n", pattern );
return ( NULL );
} /* if */
if ( hptr->num_entries == 0 )
return ( NULL );
if ( entry_num == 1 )
return ( arg_value ( hptr->arg_list, arg_num, hptr->num_args ));
if ( entry_num > hptr->num_entries ) {
ui_print ( VDEBUG,
"entry number: %d, greater than number of entries: %d.\n",
entry_num, hptr->num_entries );
return ( NULL );
} /* if */
eptr = hptr->entry_list;
for ( ct = 2; ct < entry_num; ct++ )
eptr = eptr->next_entry;
return ( arg_value ( eptr->arg_list, arg_num, eptr->num_args ));
} /* ui arg value */
static char * arg_value ( arglist, argnum, maxargs )
/*
* Finds the argument in the arglist specified by the argnum.
* Returns pointer to this string; NULL if if cannot find string
* for any reason.
*/
ARG_SET * arglist; /* list of args to run down */
int argnum, /* argument number to reach */
maxargs; /* maximum arguments available */
{
int ct; /* misc counter */
if ( argnum > maxargs ) {
ui_print ( VDEBUG,
"argument number: %d, greater than number of argument: %d.\n",
argnum, maxargs );
return ( NULL );
} /* if */
for ( ct = 1; ct < argnum; ct++ )
arglist = arglist->next_arg;
return ( arglist->arg );
} /* arg value */
int ui_entries_to_argv ( pattern, entries )
/*
* Place all entries for a pattern into a char ** list.
* Returns number of entries put in "entries"; 0 if no
* entries; ERROR if no such pattern or entry.
*/
char * pattern; /* pattern to match in table */
char *** entries; /* list to hold entries */
{
HTABLE * hptr; /* points to one pattern */
ENTRY_SET * eptr; /* points to one entry */
int ct; /* misc counter */
if (( hptr = match_pattern ( pattern )) == NULL ) {
ui_print ( VDEBUG, "pattern: %s, not in entry table.\n", pattern );
return ( ERROR );
} /* if */
if ( hptr->num_entries == 0 )
return ( 0 );
if (( *entries = ( char ** ) calloc ( hptr->num_entries, sizeof ( char * )))
== NULL )
uquit ( ERROR, FALSE, "sys: could not calloc space for entry argv list.\n");
**entries = hptr->entry;
eptr = hptr->entry_list;
for ( ct = 1; ct < hptr->num_entries; ct++ ) {
*(*entries + ct) = eptr->entry;
eptr = eptr->next_entry;
} /* for */
return ( hptr->num_entries );
} /* ui entries to argv */
int ui_args_to_argv ( pattern, entry_num, arguments )
/*
* Place all arguments for a particular entry of a pattern into
* a char ** list.
* Returns number of arguments put in "arguments"; 0 if no
* arguments; ERROR if no such pattern or entry_num.
*/
char * pattern; /* pattern to match in table */
int entry_num; /* entry number of matching pattern */
char *** arguments; /* list to hold argument */
{
HTABLE * hptr; /* points to one pattern */
ENTRY_SET * eptr; /* points to one entry */
ARG_SET * aptr; /* points to one argument */
int total, /* misc integer */
ct; /* misc counter */
if ( entry_num < 1 ) {
ui_print ( VDEBUG, "entry number: %d, is less than 1.\n", entry_num );
return ( ERROR );
} /* if */
if (( hptr = match_pattern ( pattern )) == NULL ) {
ui_print ( VDEBUG, "pattern: %s, not in entry table.\n", pattern );
return ( ERROR );
} /* if */
if ( hptr->num_entries == 0 )
return ( 0 );
if ( entry_num == 1 ) {
aptr = hptr->arg_list;
total = hptr->num_args;
} /* if */
else {
if ( entry_num > hptr->num_entries ) {
ui_print ( VDEBUG,
"entry number: %d, greater than number of entries: %d.\n",
entry_num, hptr->num_entries );
return ( ERROR );
} /* if */
eptr = hptr->entry_list;
for ( ct = 2; ct < entry_num; ct++ )
eptr = eptr->next_entry;
aptr = eptr->arg_list;
total = eptr->num_args;
} /* else */
if ( total == 0 )
return ( 0 );
if (( *arguments = ( char ** ) calloc ( total, sizeof ( char * ))) == NULL )
uquit ( ERROR, FALSE, "could not calloc space for argument argv list.\n" );
for ( ct = 0; ct < total; ct++ ) {
*(*arguments + ct) = aptr->arg;
aptr = aptr->next_arg;
} /* for */
return ( total );
} /* ui args to argv */
char * ui_ver_switch ( )
/*
* Returns a command line switch, "string", corresponding to
* the current verbosity level.
*/
{
switch ( verbosity ) {
case VQUIET : return ( salloc ( QUIET_OP ));
case VNORMAL : return ( salloc ( NORMAL_OP ));
case VDETAIL : return ( salloc ( VERBOSE_OP ));
case VDEBUG : return ( salloc ( DEBUG_OP ));
default : ui_print ( VFATAL, "illegal level of verbosity: %d.\n",
verbosity );
return ( NULL );
} /* switch */
} /* ui verbose switch */
BOOLEAN ui_is_auto ()
/*
* Shortcut function.
* Returns is -auto set?
*/
{
return ( (htbl+auto_pos)->num_entries != 0 );
} /* ui is auto */
BOOLEAN ui_is_info ()
/*
* Shortcut function.
* Returns is -info set?
*/
{
return ( (htbl+info_pos)->num_entries != 0 );
} /* ui is info */
int ui_ver_level ()
/*
* Returns the current verbosity level as an integer level.
*/
{
return ( verbosity );
} /* ui ver level */
ui_print_revision ( )
{
ui_print ( VALWAYS, "program : %s\nrelease : %s\nlibsb : %s\n",
progname, BUILD_VERSION, BUILD_DATE );
}