Index: ossp-pkg/rc/00TODO RCS File: /v/ossp/cvs/ossp-pkg/rc/00TODO,v rcsdiff -q -kk '-r1.22' '-r1.23' -u '/v/ossp/cvs/ossp-pkg/rc/00TODO,v' 2>/dev/null --- 00TODO 2002/04/11 16:52:45 1.22 +++ 00TODO 2002/04/24 16:47:07 1.23 @@ -10,6 +10,9 @@ Give example semantics of a common scenario. No error semantics in pseudocode. +Known bugs + Not multithreaded (too many potentials for race conditions or overwrite) + Document Refs, pri, user, group, ci, go only in normal (not special) sections. Index: ossp-pkg/rc/Makefile.in RCS File: /v/ossp/cvs/ossp-pkg/rc/Makefile.in,v rcsdiff -q -kk '-r1.23' '-r1.24' -u '/v/ossp/cvs/ossp-pkg/rc/Makefile.in,v' 2>/dev/null --- Makefile.in 2002/04/23 12:30:29 1.23 +++ Makefile.in 2002/04/24 16:47:07 1.24 @@ -105,6 +105,7 @@ $(PROG_NAME): $(OBJS) # $(LIBTOOL) --mode=link --quiet $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) + $(CHMOD) 755 rc_test.sh > /dev/null 2>&1 rc.1: rc.pod VS=`$(SHTOOL) version -lc -dshort rc_version.c`; \ @@ -146,8 +147,7 @@ $(RM) shtool check: test -test: rc - $(CHMOD) 755 rc_test.sh > /dev/null 2>&1 +test: $(PROG_NAME) ./rc_test.sh .PHONY: install uninstall clean distclean realclean check test Index: ossp-pkg/rc/rc.c RCS File: /v/ossp/cvs/ossp-pkg/rc/rc.c,v rcsdiff -q -kk '-r1.21' '-r1.22' -u '/v/ossp/cvs/ossp-pkg/rc/rc.c,v' 2>/dev/null --- rc.c 2002/04/22 15:22:39 1.21 +++ rc.c 2002/04/24 16:47:07 1.22 @@ -27,41 +27,72 @@ ** rc.c: Run-command processor ISO C source file */ -#include #include -#include "rc.h" -#include "rc_const.h" -#include "rc_private.h" +#include "rc.h" /* Public interfaces */ +#include "rc_const.h" /* Englisch string constants */ +#include "rc_config.h" /* For RC_XXX_VAL definitions */ +/************************************************ +* rcIntro(void) * +* Introduction to rc: help, usage, or version * +************************************************/ +rc_return_t rcIntro(void) +{ + ex_t Except; + + ex_try { /* Basic checks of version, usage, and help options */ + if (configGetval(RC_VER_VAL)) + fprintf(stdout, "OSSP rc %s\n", RC_VERSION); + if (configGetval(RC_USE_VAL)) + clioptPrintusage(); + if (configGetval(RC_HLP_VAL)) + clioptPrintusage(); /* FIXME Replace with real help FIXME */ + } + ex_catch(Except) { + rethrow; + } + + return(RC_THROW(RC_OK)); +} + +/************************************************ +* main(int, char **) * +* Main rc control block * +************************************************/ int main(int argc, char *argv[]) { ex_t Except; + rc_t *pRc = NULL; ex_try { - configConstruct(); - configLoad(argc, argv); - /* Processing the runcommands */ -/* procOpen(szRcfilist, szFuncfilist, szTmpfile); - procConf(szEnvass, szSecdef, szSecref, szSecparm); - procParse(); - procSec(szUmask, szUser, szGroup); - procEval(szSection1, szSection2, ...); - configDestruct();*/ + configNew(); /* Construct a new configuration */ + configLoad(argc, argv); /* Read configuration from cli, env, and conf */ + configDebug(); /* FIXME Remove FIXME */ + rcIntro(); /* Test for usage, help, and version options */ + +/* pRc = procNew(); + procReadrc(pRc); + procReadfuncs(pRc); + procReadtmp(pRc); + for (i = 0; i < clioptGetseclen; procSection(pRc, configGetsec(i))); + procParse(pRc); /- Script generation -/ + procOut(pRc); /- [Execute|Evaluate|Print] script -/ + + procDelete(pRc);*/ + configDelete(); } ex_catch(Except) { - if ((int)Except.ex_value == RC_CNF_VRS) - fprintf(stdout, "This is OSSP rc, version %s\n", RC_VERSION); - - fprintf(stderr, "Class '%s' threw exception %d in %s:%s():%d.\n",\ - (char *)Except.ex_class, (int)Except.ex_value,\ - Except.ex_file, Except.ex_func, Except.ex_line); + if ((rc_return_t)Except.ex_value == RC_ERR_USE) { + clioptPrintusage(); + } + else + fprintf(stderr, "Class '%s' threw exception %d in %s:%s():%d.\n",\ + (char *)Except.ex_class, (int)Except.ex_value,\ + Except.ex_file, Except.ex_func, Except.ex_line); exit(1); /* Failure */ } -fprintf(stderr, configSummarize()); -configDestruct(); /* FIXME Remove, allow first scope */ -TRACE("No exceptions caught\n"); exit(0); /* Success */ } Index: ossp-pkg/rc/rc.h RCS File: /v/ossp/cvs/ossp-pkg/rc/rc.h,v rcsdiff -q -kk '-r1.21' '-r1.22' -u '/v/ossp/cvs/ossp-pkg/rc/rc.h,v' 2>/dev/null --- rc.h 2002/04/23 12:30:29 1.21 +++ rc.h 2002/04/24 16:47:07 1.22 @@ -45,10 +45,9 @@ #include "rc_private.h" -/* RC return codes */ +/* Rc return codes */ typedef enum { RC_OK, /* Success */ - RC_CNF_VRS, /* User requested version */ RC_ERR_USE, /* Usage error */ RC_ERR_MEM, /* Memory error */ RC_ERR_SYS, /* System error (see errno) */ @@ -56,38 +55,57 @@ RC_ERR_INT /* Internal error */ } rc_return_t; +/* Rc class */ +typedef void *rc_t; + +/* Rc script type */ +typedef char *rc_script_t; + +/* Main function prototypes */ +rc_return_t rcIntro(void); + /* Option function prototypes */ -rc_return_t optionProcess(void); -rc_return_t optionProcess(void); +/*rc_return_t optionProcess(void); +rc_return_t optionProcess(void);*/ /* Config function prototypes */ -rc_return_t configConstruct(void); +rc_return_t configNew(void); rc_return_t configLoad(int, char **); -rc_return_t configDestruct(void); +rc_return_t configDelete(void); +const char *configSummarize(void); +void configDebug(void); /* FIXME Remove */ /* Config accessor prototypes */ const char *configGetval(rc_opt_t); const char *configGetname(rc_opt_t); -const char *configSummarize(void); +const char *configGetrcfile(void); +const char *configGetsec(int); /* Command line function prototypes */ -rc_return_t clioptConstruct(void); +rc_return_t clioptNew(void); +rc_return_t clioptPrintusage(void); /*FIXME rc_return_t clioptRemnode(rc_bintup_t **); rc_return_t clioptRemallimp(rc_bintup_t **); rc_return_t clioptRemall(void); rc_return_t clioptAppnode(const char *, const char *);*/ rc_return_t clioptProcess(int, const char *); -rc_return_t clioptParse(int, char **); -rc_return_t clioptDestruct(void); +rc_return_t clioptParseopt(int, char **); +rc_return_t clioptParserc(void); +rc_return_t clioptParsesec(void); +rc_return_t clioptDelete(void); /* Command line accessor prototypes */ const char *clioptGetval(rc_opt_t); const char *clioptGetrcfile(void); -const char *clioptGetsec(void); +const char **clioptGetsec(void); +int clioptGetseclen(void); +rc_return_t clioptSetval(rc_opt_t, const char *); +rc_return_t clioptSetrcfile(const char *); +rc_return_t clioptSetsec(const char **); /* Option function prototypes */ - /*FIXME rc_return_t optConstruct(rc_opt_t **); - rc_return_t optDestruct(rc_opt_t **);*/ + /*FIXME rc_return_t optNew(rc_opt_t **); + rc_return_t optDelete(rc_opt_t **);*/ /* Option accessor prototypes */ /*FIXME rc_return_t optGetname(rc_opt_t *, char **); Index: ossp-pkg/rc/rc_cliopt.c RCS File: /v/ossp/cvs/ossp-pkg/rc/rc_cliopt.c,v rcsdiff -q -kk '-r1.6' '-r1.7' -u '/v/ossp/cvs/ossp-pkg/rc/rc_cliopt.c,v' 2>/dev/null --- rc_cliopt.c 2002/04/23 12:30:29 1.6 +++ rc_cliopt.c 2002/04/24 16:47:07 1.7 @@ -27,25 +27,66 @@ ** rc_cliopt.c: Run-command processor ISO C source file */ -#include #include #include #include "rc.h" #include "rc_const.h" #include "rc_config.h" -#include "popt.h" /* OSSP popt options library*/ +#include "popt.h" /* OSSP popt options library */ -static char *m_pszOptuples[RC_NUMOPTS]; /* Option name value tuples */ -static char *m_szRcfile = NULL; /* rc file */ -static char *m_szSec = NULL; /* Section names */ +static char *m_pszOptuples[RC_NUMOPTS]; /* Option name value tuples */ +static char *m_szRcfile = NULL; /* rc file */ +static char **m_pszSec = NULL; /* Section names */ +static popt_context m_Optcon; /* Context for parsing options */ + +static struct popt_option m_pOptable[] = { + /* Long options with short keys but no arguments */ + {RC_USE_NAME, '?', POPT_ARG_NONE, 0, RC_USE_VAL, RC_USE_DESC, NULL}, + {RC_DBG_NAME, 'd', POPT_ARG_NONE, 0, RC_DBG_VAL, RC_DBG_DESC, NULL}, + {RC_VER_NAME, 'V', POPT_ARG_NONE, 0, RC_VER_VAL, RC_VER_DESC, NULL}, + {RC_EVL_NAME, 'e', POPT_ARG_NONE, 0, RC_EVL_VAL, RC_EVL_DESC, NULL}, + {RC_HLP_NAME, 'h', POPT_ARG_NONE, 0, RC_HLP_VAL, RC_HLP_DESC, NULL}, + {RC_INF_NAME, 'i', POPT_ARG_NONE, 0, RC_INF_VAL, RC_INF_DESC, NULL}, + {RC_LBL_NAME, 'l', POPT_ARG_NONE, 0, RC_LBL_VAL, RC_LBL_DESC, NULL}, + {RC_PRN_NAME, 'p', POPT_ARG_NONE, 0, RC_PRN_VAL, RC_PRN_DESC, NULL}, + {RC_SIL_NAME, 's', POPT_ARG_NONE, 0, RC_SIL_VAL, RC_SIL_DESC, NULL}, + {RC_RAW_NAME, 'r', POPT_ARG_NONE, 0, RC_RAW_VAL, RC_RAW_DESC, NULL}, + {RC_VRB_NAME, 'v', POPT_ARG_NONE, 0, RC_VRB_VAL, RC_VRB_DESC, NULL}, + {RC_EXC_NAME, 'x', POPT_ARG_NONE, 0, RC_EXC_VAL, RC_EXC_DESC, NULL}, + + /* Single argument long options with short keys */ + {RC_LOC_NAME, 'L', POPT_ARG_STRING, 0, RC_LOC_VAL, RC_LOC_DESC, "regx"}, + {RC_CNF_NAME, 'c', POPT_ARG_STRING, 0, RC_CNF_VAL, RC_CNF_DESC, "path"}, + {RC_FNC_NAME, 'f', POPT_ARG_STRING, 0, RC_FNC_VAL, RC_FNC_DESC, "path"}, + {RC_QRY_NAME, 'q', POPT_ARG_STRING, 0, RC_QRY_VAL, RC_QRY_DESC, "varx"}, + {RC_TMP_NAME, 't', POPT_ARG_STRING, 0, RC_TMP_VAL, RC_TMP_DESC, "path"}, + + /* Single argument long options without short keys */ + {RC_OWN_NAME, 0, POPT_ARG_STRING, 0, RC_OWN_VAL, RC_OWN_DESC, "user"}, + {RC_GRP_NAME, 0, POPT_ARG_STRING, 0, RC_GRP_VAL, RC_GRP_DESC, "group"}, + {RC_MSK_NAME, 0, POPT_ARG_INT, 0, RC_MSK_VAL, RC_MSK_DESC, "umask"}, + {RC_ASS_NAME, 0, POPT_ARG_STRING, 0, RC_ASS_VAL, RC_ASS_DESC, "regx"}, + {RC_DEF_NAME, 0, POPT_ARG_STRING, 0, RC_DEF_VAL, RC_DEF_DESC, "regx"}, + {RC_REF_NAME, 0, POPT_ARG_STRING, 0, RC_REF_VAL, RC_REF_DESC, "regx"}, + {RC_PRM_NAME, 0, POPT_ARG_STRING, 0, RC_PRM_VAL, RC_PRM_DESC, "regx"}, + {RC_TRM_NAME, 0, POPT_ARG_STRING, 0, RC_TRM_VAL, RC_TRM_DESC, "regx"}, + {RC_NCF_NAME, 0, POPT_ARG_STRING, 0, RC_NCF_VAL, RC_NCF_DESC, "name"}, + {RC_CMN_NAME, 0, POPT_ARG_STRING, 0, RC_CMN_VAL, RC_CMN_DESC, "name"}, + {RC_DFL_NAME, 0, POPT_ARG_STRING, 0, RC_DFL_VAL, RC_DFL_DESC, "name"}, + {RC_ERR_NAME, 0, POPT_ARG_STRING, 0, RC_ERR_VAL, RC_ERR_DESC, "name"}, + + /* Special stuff */ + POPT_AUTOHELP + {NULL, 0, 0, NULL, 0} +}; /*************************************** -* clioptConstruct(void) * +* clioptNew(void) * * Construct a command line option * ***************************************/ -rc_return_t clioptConstruct(void) +rc_return_t clioptNew(void) { /* assert(s_pBintab == NULL); */ /* Error if constructed already */ /* s_pBintab = malloc(sizeof(*s_pBintab));*/ /* Allocate a cliopt instance */ @@ -53,19 +94,30 @@ return(RC_THROW(RC_ERR_MEM)); s_pBintab->pOptlist = malloc(sizeof(*s_pBintab->pOptlist));*/ -/*FIXME optConstruct((rc_opt_t **)&s_pBintab->pOptlist->pvData);FIXME*/ +/*FIXME optNew((rc_opt_t **)&s_pBintab->pOptlist->pvData);FIXME*/ /* s_pBintab->pOptlist->pvData = NULL; s_pBintab->pOptlist->pvNext = NULL;*/ memset(m_pszOptuples, NULL, sizeof(m_pszOptuples)); -TRACE("cliopt constructed.\n"); return(RC_THROW(RC_OK)); } /*************************************** -* clioptGetval(rc_opt_t) * -* Command line option accessor * +* clioptPrintusage() * +* Print usage to command line stderr * +***************************************/ +rc_return_t clioptPrintusage(void) +{ + popt_printusage(m_Optcon, stderr, 0); + + return(RC_THROW(RC_OK)); +} + +/*************************************** +* clioptGetXXX() * +* clioptSetXXX() * +* Command line option accessors * ***************************************/ const char *clioptGetval(rc_opt_t Optname) { @@ -75,22 +127,77 @@ return((const char *)m_pszOptuples[Optname]); } -/*************************************** -* clioptGetrcfile(void) * -* Command line rc file accessor * -***************************************/ const char *clioptGetrcfile(void) { + if (!m_szRcfile) + RC_THROW(RC_ERR_USE); + return((const char *)m_szRcfile); } -/*************************************** -* clioptGetsec(void) * -* Command line section accessor * -***************************************/ -const char *clioptGetsec(void) +const char **clioptGetsec(void) { - return((const char *)m_szSec); + if (!m_pszSec) + RC_THROW(RC_ERR_USE); + + return((const char **)m_pszSec); +} + +int clioptGetseclen(void) +{ + int i = 0; + + if (!m_pszSec) + RC_THROW(RC_ERR_USE); + + for (i = 0; m_pszSec[i]; i++); + return(i); +} + +rc_return_t clioptSetval(rc_opt_t Optname, const char *kszOptval) +{ + if (!(Optname < RC_NUMOPTS)) /* Validate option range */ + return(RC_THROW(RC_ERR_USE)); + if (!(kszOptval)) /* Validate string value */ + return(RC_THROW(RC_ERR_USE)); + + if (!(m_pszOptuples[Optname] = strdup(kszOptval))) + return(RC_THROW(RC_ERR_MEM)); + return(RC_THROW(RC_OK)); +} + +rc_return_t clioptSetrcfile(const char *kszRc) +{ + if (m_szRcfile) /* Forbid overwriting */ + return(RC_THROW(RC_ERR_USE)); /* an existing rcfile */ + else if (kszRc) + m_szRcfile = strdup(kszRc); + else + return(RC_THROW(RC_ERR_USE)); /* Incoming string is NULL? */ + + return(RC_THROW(RC_OK)); +} + +rc_return_t clioptSetsec(const char *pkszSec[]) +{ + int i = 0; + + if (m_pszSec) /* Forbid overwriting */ + return(RC_THROW(RC_ERR_USE)); /* an existing rcfile */ + else if (pkszSec) { + for (i = 0; pkszSec[i]; i++); /* Count the sections */ + m_pszSec = malloc(sizeof (char **) * i + 1); /* Allocate using i */ + + for (i = 0; pkszSec[i]; i++) { + m_pszSec[i] = malloc(strlen(pkszSec[i])); + memcpy(m_pszSec[i], pkszSec[i], strlen(pkszSec[i])); + } + m_pszSec[i] = NULL; /* Used later for finding the end of array */ + } + else + return(RC_THROW(RC_ERR_USE)); /* Incoming sections are NULL? */ + + return(RC_THROW(RC_OK)); } /*************************************** @@ -99,73 +206,72 @@ * processing the corresponding option * * and update option table accordingly * ***************************************/ -rc_return_t clioptProcess(int cliOption, const char *szArg) +rc_return_t clioptProcess(int cliOption, const char *kszArg) { switch (cliOption) { /* Begin concrete (digital) options */ case RC_USE_VAL: - m_pszOptuples[cliOption] = strdup("1"); /* Usage */ - return(RC_THROW(RC_ERR_USE)); + clioptSetval(cliOption, "1"); break; /* Usage */ case RC_DBG_VAL: - m_pszOptuples[cliOption] = strdup("1"); break; /* Debug */ + clioptSetval(cliOption, "1"); break; /* Debug */ case RC_VER_VAL: - m_pszOptuples[cliOption] = strdup("1"); break; /* Version */ + clioptSetval(cliOption, "1"); break; /* Version */ case RC_EVL_VAL: - m_pszOptuples[cliOption] = strdup("1"); break; /* Eval */ + clioptSetval(cliOption, "1"); break; /* Eval */ case RC_HLP_VAL: - m_pszOptuples[cliOption] = strdup("1"); break; /* Help */ + clioptSetval(cliOption, "1"); break; /* Help */ case RC_INF_VAL: - m_pszOptuples[cliOption] = strdup("1"); break; /* Info */ + clioptSetval(cliOption, "1"); break; /* Info */ case RC_LBL_VAL: - m_pszOptuples[cliOption] = strdup("1"); break; /* Label */ + clioptSetval(cliOption, "1"); break; /* Label */ case RC_PRN_VAL: - m_pszOptuples[cliOption] = strdup("1"); break; /* Print */ + clioptSetval(cliOption, "1"); break; /* Print */ case RC_SIL_VAL: - m_pszOptuples[cliOption] = strdup("1"); break; /* Silent */ + clioptSetval(cliOption, "1"); break; /* Silent */ case RC_RAW_VAL: - m_pszOptuples[cliOption] = strdup("1"); break; /* Raw */ + clioptSetval(cliOption, "1"); break; /* Raw */ case RC_VRB_VAL: - m_pszOptuples[cliOption] = strdup("1"); break; /* Verbose */ + clioptSetval(cliOption, "1"); break; /* Verbose */ case RC_EXC_VAL: - m_pszOptuples[cliOption] = strdup("1"); break; /* Exec */ + clioptSetval(cliOption, "1"); break; /* Exec */ /* Begin abstract (nondigital) options */ case RC_LOC_VAL: - m_pszOptuples[cliOption] = strdup(szArg); break; /* Locations */ + clioptSetval(cliOption, kszArg); break; /* Locations */ case RC_CNF_VAL: - m_pszOptuples[cliOption] = strdup(szArg); break; /* Conf file */ + clioptSetval(cliOption, kszArg); break; /* Conf file */ case RC_FNC_VAL: - m_pszOptuples[cliOption] = strdup(szArg); break; /* Func file */ + clioptSetval(cliOption, kszArg); break; /* Func file */ case RC_QRY_VAL: - m_pszOptuples[cliOption] = strdup(szArg); break; /* Format */ + clioptSetval(cliOption, kszArg); break; /* Format */ case RC_TMP_VAL: - m_pszOptuples[cliOption] = strdup(szArg); break; /* Temp dir */ + clioptSetval(cliOption, kszArg); break; /* Temp dir */ case RC_OWN_VAL: - m_pszOptuples[cliOption] = strdup(szArg); break; /* User name */ + clioptSetval(cliOption, kszArg); break; /* User name */ case RC_GRP_VAL: - m_pszOptuples[cliOption] = strdup(szArg); break; /* Group name */ + clioptSetval(cliOption, kszArg); break; /* Group name */ case RC_MSK_VAL: - m_pszOptuples[cliOption] = strdup(szArg); break; /* Umask */ + clioptSetval(cliOption, kszArg); break; /* Umask */ case RC_ASS_VAL: - m_pszOptuples[cliOption] = strdup(szArg); break; /* Assignregex */ + clioptSetval(cliOption, kszArg); break; /* Assignregex */ case RC_DEF_VAL: - m_pszOptuples[cliOption] = strdup(szArg); break; /* Labelregex */ + clioptSetval(cliOption, kszArg); break; /* Labelregex */ case RC_REF_VAL: - m_pszOptuples[cliOption] = strdup(szArg); break; /* Refregex */ + clioptSetval(cliOption, kszArg); break; /* Refregex */ case RC_PRM_VAL: - m_pszOptuples[cliOption] = strdup(szArg); break; /* Paramregex */ + clioptSetval(cliOption, kszArg); break; /* Paramregex */ case RC_TRM_VAL: - m_pszOptuples[cliOption] = strdup(szArg); break; /* Termregex */ + clioptSetval(cliOption, kszArg); break; /* Termregex */ case RC_NCF_VAL: - m_pszOptuples[cliOption] = strdup(szArg); break; /* Configname */ + clioptSetval(cliOption, kszArg); break; /* Configname */ case RC_CMN_VAL: - m_pszOptuples[cliOption] = strdup(szArg); break; /* Commonname */ + clioptSetval(cliOption, kszArg); break; /* Commonname */ case RC_DFL_VAL: - m_pszOptuples[cliOption] = strdup(szArg); break; /* Defaultname */ + clioptSetval(cliOption, kszArg); break; /* Defaultname */ case RC_ERR_VAL: - m_pszOptuples[cliOption] = strdup(szArg); break; /* Errorname */ + clioptSetval(cliOption, kszArg); break; /* Errorname */ default : break; } @@ -173,112 +279,91 @@ } /*************************************** -* clioptParse(int, char **) * +* clioptParseopt(int, char **) * * Parse command line options * ***************************************/ -rc_return_t clioptParse(int argc, char *argv[]) +rc_return_t clioptParseopt(int argc, char *argv[]) { - static struct popt_option optionsTable[] = { - /* Long options with short keys but no arguments */ - {RC_USE_NAME, '?', POPT_ARG_NONE, 0, RC_USE_VAL, RC_USE_DESC, NULL}, - {RC_DBG_NAME, 'd', POPT_ARG_NONE, 0, RC_DBG_VAL, RC_DBG_DESC, NULL}, - {RC_VER_NAME, 'V', POPT_ARG_NONE, 0, RC_VER_VAL, RC_VER_DESC, NULL}, - {RC_EVL_NAME, 'e', POPT_ARG_NONE, 0, RC_EVL_VAL, RC_EVL_DESC, NULL}, - {RC_HLP_NAME, 'h', POPT_ARG_NONE, 0, RC_HLP_VAL, RC_HLP_DESC, NULL}, - {RC_INF_NAME, 'i', POPT_ARG_NONE, 0, RC_INF_VAL, RC_INF_DESC, NULL}, - {RC_LBL_NAME, 'l', POPT_ARG_NONE, 0, RC_LBL_VAL, RC_LBL_DESC, NULL}, - {RC_PRN_NAME, 'p', POPT_ARG_NONE, 0, RC_PRN_VAL, RC_PRN_DESC, NULL}, - {RC_SIL_NAME, 's', POPT_ARG_NONE, 0, RC_SIL_VAL, RC_SIL_DESC, NULL}, - {RC_RAW_NAME, 'r', POPT_ARG_NONE, 0, RC_RAW_VAL, RC_RAW_DESC, NULL}, - {RC_VRB_NAME, 'v', POPT_ARG_NONE, 0, RC_VRB_VAL, RC_VRB_DESC, NULL}, - {RC_EXC_NAME, 'x', POPT_ARG_NONE, 0, RC_EXC_VAL, RC_EXC_DESC, NULL}, - - /* Single argument long options with short keys */ - {RC_LOC_NAME, 'L', POPT_ARG_STRING, 0, RC_LOC_VAL, RC_LOC_DESC, "regx"}, - {RC_CNF_NAME, 'c', POPT_ARG_STRING, 0, RC_CNF_VAL, RC_CNF_DESC, "path"}, - {RC_FNC_NAME, 'f', POPT_ARG_STRING, 0, RC_FNC_VAL, RC_FNC_DESC, "path"}, - {RC_QRY_NAME, 'q', POPT_ARG_STRING, 0, RC_QRY_VAL, RC_QRY_DESC, "varx"}, - {RC_TMP_NAME, 't', POPT_ARG_STRING, 0, RC_TMP_VAL, RC_TMP_DESC, "path"}, - - /* Single argument long options without short keys */ - {RC_OWN_NAME, 0, POPT_ARG_STRING, 0, RC_OWN_VAL, RC_OWN_DESC, "user"}, - {RC_GRP_NAME, 0, POPT_ARG_STRING, 0, RC_GRP_VAL, RC_GRP_DESC, "group"}, - {RC_MSK_NAME, 0, POPT_ARG_INT, 0, RC_MSK_VAL, RC_MSK_DESC, "umask"}, - {RC_ASS_NAME, 0, POPT_ARG_STRING, 0, RC_ASS_VAL, RC_ASS_DESC, "regx"}, - {RC_DEF_NAME, 0, POPT_ARG_STRING, 0, RC_DEF_VAL, RC_DEF_DESC, "regx"}, - {RC_REF_NAME, 0, POPT_ARG_STRING, 0, RC_REF_VAL, RC_REF_DESC, "regx"}, - {RC_PRM_NAME, 0, POPT_ARG_STRING, 0, RC_PRM_VAL, RC_PRM_DESC, "regx"}, - {RC_TRM_NAME, 0, POPT_ARG_STRING, 0, RC_TRM_VAL, RC_TRM_DESC, "regx"}, - {RC_NCF_NAME, 0, POPT_ARG_STRING, 0, RC_NCF_VAL, RC_NCF_DESC, "name"}, - {RC_CMN_NAME, 0, POPT_ARG_STRING, 0, RC_CMN_VAL, RC_CMN_DESC, "name"}, - {RC_DFL_NAME, 0, POPT_ARG_STRING, 0, RC_DFL_VAL, RC_DFL_DESC, "name"}, - {RC_ERR_NAME, 0, POPT_ARG_STRING, 0, RC_ERR_VAL, RC_ERR_DESC, "name"}, - - /* Special stuff */ - POPT_AUTOHELP - {NULL, 0, 0, NULL, 0} - }; - ex_t Except; - char cliOpt = 0; /* For argument parsing */ - char *szCLIBuf = NULL; - popt_context optCon; /* Context for parsing options */ - - optCon = popt_getcontext(NULL, argc, (const char **)argv, optionsTable, 0); - popt_setotheroptionhelp(optCon, "[options] "); - - if (argc < 3) { - fprintf(stderr, "Please enter at least one rcfile and section.\n"); - popt_printusage(optCon, stderr, 0); + char cliOpt = 0; /* For argument parsing */ + + m_Optcon = popt_getcontext(NULL, argc, (const char **)argv, m_pOptable, 0); + popt_setotheroptionhelp(m_Optcon, " "); + + if (argc < 2) { /* Allow the user to enter just one option, -h z.B. */ + fprintf(stderr, RC_LST_TEXT); + popt_printusage(m_Optcon, stderr, 0); return(RC_THROW(RC_ERR_USE)); } /* Now do options processing */ - while ((cliOpt = popt_getnextopt(optCon)) >= 0) { /* Loop, each time */ - ex_try { /* eating a new option */ - clioptProcess(cliOpt, popt_getoptarg(optCon)); + while ((cliOpt = popt_getnextopt(m_Optcon)) >= 0) {/* Loop, each time */ + ex_try { /* eating a new option */ + clioptProcess(cliOpt, popt_getoptarg(m_Optcon)); } - ex_catch(Except) { - if ((rc_return_t)Except.ex_value == RC_ERR_USE) { - popt_printusage(optCon, stderr, 0); - rethrow; - } - else { /* Some error condition probably deserves attention */ - fprintf(stderr, "Class '%s' threw exception %d in %s:%s():\ - %d.\n", (char *)Except.ex_class, *(int *)Except.ex_value,\ - Except.ex_file, Except.ex_func, Except.ex_line); - rethrow; - } + ex_catch(Except) { /* Error condition probably deserves attention */ +/* FIXME Examine the following line *(int *) for a potential segfault prob */ + fprintf(stderr, "Class '%s' threw exception %d in %s:%s():\ + %d.\n", (char *)Except.ex_class, *(int *)Except.ex_value,\ + Except.ex_file, Except.ex_func, Except.ex_line); + rethrow; } } - /* At this point we should be finished parsing options, so now we use */ - /* popt as a transport to read the user specified rcfile and sections. */ - szCLIBuf = (char *)popt_getarg(optCon); - if ((szCLIBuf == NULL)) { - fprintf(stderr, "Please enter at least one rcfile and section.\n"); - popt_printusage(optCon, stderr, 0); - return(RC_THROW(RC_ERR_USE)); - } - if (cliOpt < -1) { /* An error occurred during option processing */ fprintf(stderr, "%s: %s\n", - popt_badoption(optCon, POPT_BADOPTION_NOALIAS), + popt_badoption(m_Optcon, POPT_BADOPTION_NOALIAS), popt_strerror(cliOpt)); return(RC_THROW(RC_ERR_INT)); } - fprintf(stderr, "Run these commands: %s\n", szCLIBuf); - popt_freecontext(optCon); return(RC_THROW(RC_OK)); } /*************************************** -* clioptDestruct(void) * +* clioptParserc(void) * +* Parse command line rc file * +***************************************/ +rc_return_t clioptParserc(void) +{ + ex_t Except; + + /* Use popt as a transport to read the user specified rcfile */ + ex_try { /* Retrieve exactly one rc file name from the command line */ + clioptSetrcfile(popt_getarg(m_Optcon)); /* No file check here */ + } + ex_catch(Except) { + rethrow; /* Our generic response */ + } + + return(RC_THROW(RC_OK)); +} + +/*************************************** +* clioptParsesec(void) * +* Parse command line sections * +***************************************/ +rc_return_t clioptParsesec(void) +{ + ex_t Except; + + /* Use popt as a transport to read the user specified sections */ + ex_try { /* Retrieve one or more sections from the command line */ + clioptSetsec(popt_getargs(m_Optcon)); + } + ex_catch(Except) { + rethrow; /* Our generic response */ + } + + return(RC_THROW(RC_OK)); +} + +/*************************************** +* clioptDelete(void) * * Destruct a command line option * ***************************************/ -rc_return_t clioptDestruct(void) +rc_return_t clioptDelete(void) { int i = 0; /* ex_t Except; @@ -286,7 +371,7 @@ assert(s_pBintab);*/ /* Error if not constructed */ /* ex_try { clioptRemall();*/ /* Removes ALL list nodes */ -/*FIXME optDestruct((rc_opt_t **)&s_pBintab->pOptlist->pvData);FIXME*/ +/*FIXME optDelete((rc_opt_t **)&s_pBintab->pOptlist->pvData);FIXME*/ /* free(s_pBintab->pOptlist);*/ /* Deallocate option list */ /* free(s_pBintab);*/ /* Deallocate cliopt and */ /* s_pBintab = NULL;*/ /* clear its reference */ @@ -295,6 +380,7 @@ rethrow; }*/ + popt_freecontext(m_Optcon); /* Free the popt context */ for (i = 0; i < RC_NUMOPTS; i++) { /* Free the tuples themselves */ if (m_pszOptuples[i]) { free(m_pszOptuples[i]); @@ -304,14 +390,18 @@ if (m_szRcfile) /* Free the rc file arg */ free(m_szRcfile); - if (m_szSec) /* Free the section name arg */ - free(m_szSec); + if (m_pszSec) { /* Free the section name arg */ + for (i = 0; m_pszSec[i]; i++) { + free(m_pszSec[i]); + m_pszSec[i] = NULL; + } + free(m_pszSec); + } /* FIXME BEGIN DEBUG */ for (i = 0; i < RC_NUMOPTS; i++) if (m_pszOptuples[i]) TRACE("Problem! Destructor failed!\n"); -TRACE("cliopt destructed.\n"); /* FIXME END DEBUG */ return(RC_THROW(RC_OK)); Index: ossp-pkg/rc/rc_config.c RCS File: /v/ossp/cvs/ossp-pkg/rc/rc_config.c,v rcsdiff -q -kk '-r1.13' '-r1.14' -u '/v/ossp/cvs/ossp-pkg/rc/rc_config.c,v' 2>/dev/null --- rc_config.c 2002/04/23 12:30:29 1.13 +++ rc_config.c 2002/04/24 16:47:07 1.14 @@ -27,12 +27,11 @@ ** rc_config.c: Run-command processor ISO C source file */ -#include #include #include #include "rc.h" -#include "str.h" +#include "rc_config.h" #include "rc_const.h" /* String constants */ static int m_nLocks = 0; /* Server locks, not thread-safe FIXME */ @@ -40,16 +39,46 @@ /*************************************** -* configConstruct(void) * +* configDebug(void) * +* Debug a configuration * +* Warning: There is no error checking * +* or debugging of this * +* debugger block * +***************************************/ +void configDebug(void) +{ + int i = 0; + ex_t Except; + char *szTemp = NULL; + + fprintf(stderr, "Run command file: %s\n", configGetrcfile()); + + szTemp = (char *)configGetsec(i); + fprintf(stderr, "Sections:"); + while (szTemp) { + fprintf(stderr, " %s", szTemp); + ex_try { + szTemp = (char *)configGetsec(++i); + } + ex_catch(Except) { + break; + } + } + + fprintf(stderr, "\n%s", configSummarize()); +} + +/*************************************** +* configNew(void) * * Construct a configuration * ***************************************/ -rc_return_t configConstruct(void) +rc_return_t configNew(void) { ex_t Except; if (m_nLocks == 0) { /* If we don't have one yet */ ex_try { /* then construct a new one */ - clioptConstruct(); /* Member cliopt instance */ + clioptNew(); /* Member cliopt instance */ } ex_catch(Except) { rethrow; @@ -112,6 +141,52 @@ return(NULL); /* Not reached */ } +const char *configGetrcfile(void) +{ + ex_t Except; + + if (m_nLocks) { /* Make sure config exists */ + ex_try { + /* Because (1) only one rc file can be specified and */ + /* (2) it must be specified on the command line, */ + /* we don't bother checking the environment or conf file */ + /* contrary to the behaviour of Getval earlier */ + return (clioptGetrcfile()); + } + ex_catch(Except) { + rethrow; + } + } + else { + RC_THROW(RC_ERR_USE); + } + return(NULL); /* Not reached */ +} + +const char *configGetsec(int nIndex) +{ + ex_t Except; + char **pszSectemp = NULL; + + if (m_nLocks && nIndex < clioptGetseclen()) {/* Make sure config exists */ + ex_try { /* FIXME Might need to check */ + pszSectemp = (char **)clioptGetsec();/* FIXME env, conf, configs */ + if (pszSectemp[nIndex]) + return(pszSectemp[nIndex]); + else { + RC_THROW(RC_ERR_USE); + } + } + ex_catch(Except) { + rethrow; + } + } + else { + RC_THROW(RC_ERR_USE); + } + return(NULL); /* Not reached */ +} + /*************************************** * configSummarize(void) * * Configuration summary * @@ -120,24 +195,39 @@ { ex_t Except; int i = 0; - int bCaught = FALSE; + char *szTemp = NULL; - while (!bCaught) { + m_szSummary = malloc(NULL); + for (i = 0; i < RC_NUMOPTS; i++) + { ex_try { /* FIXME Not threadsafe, wrap with crit section */ - if (configGetval(i)) { /* FIXME Is realloc portable here? */ - /* FIXME Unportable kludge to ensure storage FIXME */ - m_szSummary = realloc(m_szSummary, sizeof("OptionXXis") + \ - sizeof(configGetname(i)) + sizeof(configGetval(i) + 8)); - if (!(strcmp(configGetval(i), "1"))) - str_concat(m_szSummary, "Option ", configGetname(i), " is on.\n"); - else - str_concat(m_szSummary, "Option ", configGetname(i), " is ", configGetval(i), ".\n"); + if (configGetval(i) == NULL); /* NOP */ + else if (!(strcmp(configGetval(i), "1"))) { + szTemp = malloc(strlen(m_szSummary) + strlen(configGetval(i))); + strcpy(szTemp, m_szSummary); + strcat(szTemp, "Option "); + strcat(szTemp, configGetname(i)); + strcat(szTemp, " is on.\n"); + if (m_szSummary) + free(m_szSummary); + m_szSummary = szTemp; + } + else { + szTemp = malloc(strlen(m_szSummary) + strlen(configGetval(i))); + strcpy(szTemp, m_szSummary); + strcat(szTemp, "Option "); + strcat(szTemp, configGetname(i)); + strcat(szTemp, " is "); + strcat(szTemp, configGetval(i)); + strcat(szTemp, ".\n"); + if (m_szSummary) + free(m_szSummary); + m_szSummary = szTemp; } - } /* FIXME Not threadsafe, wrap with crit section */ - ex_catch(Except) { /* Breaks the otherwise endless loop above */ - bCaught = TRUE; + } /* FIXME Not threadsafe, wrap with crit section */ + ex_catch(Except) { /* Breaks the otherwise endless loop above */ + rethrow; } - i++; } return ((const char *)m_szSummary); @@ -151,16 +241,12 @@ { ex_t Except; - ex_try { /* Parse option groups in order of priority */ - clioptParse(argc, argv); /* Command line options */ -/* envoptParse(m_nLocks->pOpt);*/ /* Environment options */ -/* cnfoptParse(m_nLocks->pOpt);*/ /* Configfile options */ - } - ex_catch(Except) { - rethrow; - } - - ex_try { + ex_try { /* Parse option groups in order of priority */ + clioptParseopt(argc, argv); /* Command line options */ + clioptParserc(); /* Command line rc file */ + clioptParsesec(); /* Command line sections */ +/* envoptParse(m_nLocks->pOpt);*/ /* Environment options */ +/* cnfoptParse(m_nLocks->pOpt);*/ /* Configfile options */ } ex_catch(Except) { rethrow; @@ -170,16 +256,16 @@ } /*************************************** -* configDestruct(void) * +* configDelete(void) * * Destruct a configuration * ***************************************/ -rc_return_t configDestruct(void) +rc_return_t configDelete(void) { ex_t Except; if (--m_nLocks == 0) { /* If m_nLocks is 0, deallocate */ ex_try { /* FIXME, not thread-safe */ - clioptDestruct(); + clioptDelete(); if (m_szSummary) free(m_szSummary); } Index: ossp-pkg/rc/rc_const.h RCS File: /v/ossp/cvs/ossp-pkg/rc/rc_const.h,v rcsdiff -q -kk '-r1.4' '-r1.5' -u '/v/ossp/cvs/ossp-pkg/rc/rc_const.h,v' 2>/dev/null --- rc_const.h 2002/04/11 16:52:45 1.4 +++ rc_const.h 2002/04/24 16:47:07 1.5 @@ -30,7 +30,12 @@ #ifndef __OSSPRC_CONST_H__ #define __OSSPRC_CONST_H__ -/* Option descriptions used with popt */ +/* Generic text, should include newline termination */ +#define RC_NON_TEXT "No options exist.\n" +#define RC_LST_TEXT "Please enter just one rcfile and at least one section.\n" +#define RC_SUM_TEXT "Option argument summary.\n" + +/* Option descriptions used with popt, should not include termination */ #define RC_USE_DESC "Print a short usage summary, then exit." #define RC_DBG_DESC "Don't remove temporary files, and write debug messages to stderr." #define RC_VER_DESC "Print the version and copyright, then exit." Index: ossp-pkg/rc/rc_opt.c RCS File: /v/ossp/cvs/ossp-pkg/rc/rc_opt.c,v rcsdiff -q -kk '-r1.3' '-r1.4' -u '/v/ossp/cvs/ossp-pkg/rc/rc_opt.c,v' 2>/dev/null --- rc_opt.c 2002/04/11 16:52:45 1.3 +++ rc_opt.c 2002/04/24 16:47:07 1.4 @@ -78,21 +78,21 @@ * optSetXXXX(rc_opt_t *, const char *) * * Option accessors * ***************************************/ -rc_return_t optSetname(rc_opt_t *pOption, const char *cszName) +rc_return_t optSetname(rc_opt_t *pOption, const char *kszName) { if (pOption->szName) /* Guard against leaks */ free(pOption->szName); /* if resetting name */ - if (!(pOption->szName = strdup(cszName))) /* Set name of option */ + if (!(pOption->szName = strdup(kszName))) /* Set name of option */ return(RC_THROW(RC_ERR_MEM)); else return(RC_THROW(RC_OK)); } -rc_return_t optSetval(rc_opt_t *pOption, const char *cszVal) +rc_return_t optSetval(rc_opt_t *pOption, const char *kszVal) { if (pOption->szVal) /* Guard against leaks */ free(pOption->szVal); /* if resetting value */ - if (!(pOption->szVal = strdup(cszVal))) /* Set value of option */ + if (!(pOption->szVal = strdup(kszVal))) /* Set value of option */ return(RC_THROW(RC_ERR_MEM)); else return(RC_THROW(RC_OK));