Index: ossp-pkg/rc/00TODO RCS File: /v/ossp/cvs/ossp-pkg/rc/00TODO,v rcsdiff -q -kk '-r1.48' '-r1.49' -u '/v/ossp/cvs/ossp-pkg/rc/00TODO,v' 2>/dev/null --- 00TODO 2003/06/23 11:29:44 1.48 +++ 00TODO 2003/06/26 18:45:14 1.49 @@ -64,6 +64,7 @@ Make rc_section_t correspond to rc_section.c with own operators. Make consistent, sectionGetdata and scriptTostring should have same names Add printVerbal() to section class, removing 'if (configGetval(RC_VRB_VAL))' + Allow multiple identical section names (having different -u values) Implementation Correct assertion, sanity check, and if () checks according to one standard. Index: ossp-pkg/rc/rc.h RCS File: /v/ossp/cvs/ossp-pkg/rc/rc.h,v rcsdiff -q -kk '-r1.50' '-r1.51' -u '/v/ossp/cvs/ossp-pkg/rc/rc.h,v' 2>/dev/null --- rc.h 2003/06/23 16:09:47 1.50 +++ rc.h 2003/06/26 18:45:14 1.51 @@ -107,15 +107,19 @@ /* Script function prototypes */ rc_script_t *scriptNew(void); rc_script_t *scriptCopy(rc_script_t *); +rc_return_t scriptAdd(rc_script_t *, rc_script_t *); rc_return_t scriptAppend(rc_script_t *, const char *, size_t); rc_section_t *scriptSection(rc_script_t *, const char *); rc_return_t scriptDump(rc_script_t *); rc_return_t scriptWrite(rc_script_t *, const char *); -const char *scriptTostring(rc_script_t *); +const char *scriptGetdata(rc_script_t *); +rc_return_t scriptSetdata(rc_script_t *, const char *); rc_return_t scriptDelete(rc_script_t *); /* Rcfile function prototypes */ rc_file_t *rcfileNew(const char *); +rc_return_t rcfileParse(rc_file_t *); +rc_section_t *rcfileGetsec(rc_file_t *, const char *); rc_return_t rcfileAppendsec(rc_file_t *, rc_section_t *); const char *rcfileGetname(rc_file_t *); rc_return_t rcfileSetname(rc_file_t *, const char *); @@ -128,6 +132,7 @@ const int sectionGetpri(rc_section_t *); const int sectionGetuid(rc_section_t *); const char *sectionGetname(rc_section_t *); +const char *sectionGetparent(rc_section_t *); const char *sectionGetlabel(rc_section_t *); const char *sectionGetlogin(rc_section_t *); const char *sectionGetdata(rc_section_t *); @@ -135,6 +140,7 @@ rc_return_t sectionSetpri(rc_section_t *, long); rc_return_t sectionSetuid(rc_section_t *, long); rc_return_t sectionSetname(rc_section_t *, const char *); +rc_return_t sectionSetparent(rc_section_t *, const char *); rc_return_t sectionSetlabel(rc_section_t *, const char *); rc_return_t sectionSetlogin(rc_section_t *, const char *); rc_return_t sectionSetdata(rc_section_t *, const char *); Index: ossp-pkg/rc/rc.pod RCS File: /v/ossp/cvs/ossp-pkg/rc/rc.pod,v rcsdiff -q -kk '-r1.42' '-r1.43' -u '/v/ossp/cvs/ossp-pkg/rc/rc.pod,v' 2>/dev/null --- rc.pod 2003/06/23 17:22:41 1.42 +++ rc.pod 2003/06/26 18:45:14 1.43 @@ -114,7 +114,7 @@ specify the location of the configuration file. If omitted, C<$OSSP_RC_CONF> will be examined. If absent, F will be used. If no F exists at all, then only command line and environment specified -options will override the defaults built-in to OSSP rc. +options will override B's default values. =item B<-e>|B<--eval> Index: ossp-pkg/rc/rc_config.c RCS File: /v/ossp/cvs/ossp-pkg/rc/rc_config.c,v rcsdiff -q -kk '-r1.35' '-r1.36' -u '/v/ossp/cvs/ossp-pkg/rc/rc_config.c,v' 2>/dev/null --- rc_config.c 2003/06/23 17:41:00 1.35 +++ rc_config.c 2003/06/26 18:45:14 1.36 @@ -341,9 +341,10 @@ if (!configGetval(RC_NCF_VAL)) clioptSetval(RC_NCF_VAL, RC_DEF_NCF); + if (!configGetval(RC_CMN_VAL)) + clioptSetval(RC_CMN_VAL, RC_DEF_CMN); -/* if (!configGetval(RC_CMN_VAL)) - if (!configGetval(RC_DFL_VAL)) +/* if (!configGetval(RC_DFL_VAL)) if (!configGetval(RC_ERR_VAL))*/ } catch(Except) Index: ossp-pkg/rc/rc_const.h RCS File: /v/ossp/cvs/ossp-pkg/rc/rc_const.h,v rcsdiff -q -kk '-r1.28' '-r1.29' -u '/v/ossp/cvs/ossp-pkg/rc/rc_const.h,v' 2>/dev/null --- rc_const.h 2003/06/23 16:09:47 1.28 +++ rc_const.h 2003/06/26 18:45:14 1.29 @@ -41,14 +41,14 @@ /* Generic text, should not include newline termination */ #define RC_VST_TEXT "# Start of run command script operations." #define RC_EVF_TEXT "# Evaluating code from functions file." -#define RC_EVN_TEXT "# Evaluating section %s of script %s." +#define RC_EVN_TEXT "# Evaluating section %s of rcfile %s." #define RC_EXF_TEXT "# Executing code from functions file." -#define RC_EXN_TEXT "# Executing section %s of script %s." +#define RC_EXN_TEXT "# Executing section %s of rcfile %s." #define RC_PNF_TEXT "# Printing code from functions file." -#define RC_PRN_TEXT "# Printing section %s of script %s." +#define RC_PRN_TEXT "# Printing section %s of rcfile %s." /* Single word user text, should not include termination */ -#define RC_CMN_TEXT "common" +#define RC_CFG_TEXT "config" /* Option descriptions used with popt, should not include termination */ #define RC_USE_DESC "Print a short usage summary, then exit." @@ -146,6 +146,7 @@ #define RC_DEF_TMP "/tmp" /* Temporary directory name */ #define RC_DEF_DEF "^%(\\w+)[ \t]*(.*?)\\n(.*?)^$" /* Section definition */ #define RC_DEF_NCF "config" /* Config section name */ +#define RC_DEF_CMN "common" /* Common section name */ #define RC_DEF_UIG "-u" /* Section user string */ #define RC_DEF_UID -1 /* Section user value */ #define RC_DEF_PRG "-p" /* Section priority string */ Index: ossp-pkg/rc/rc_file.c RCS File: /v/ossp/cvs/ossp-pkg/rc/rc_file.c,v rcsdiff -q -kk '-r1.1' '-r1.2' -u '/v/ossp/cvs/ossp-pkg/rc/rc_file.c,v' 2>/dev/null --- rc_file.c 2003/06/18 14:35:29 1.1 +++ rc_file.c 2003/06/26 18:45:14 1.2 @@ -27,10 +27,17 @@ ** rc_file.c: Run-command processor ISO C source file */ -#include /* For string copy and such data ops */ -#include /* For memory ops */ - -#include "rc.h" /* Public Rc interface */ +#include /* For string copy and such data ops */ +#include /* For memory ops */ +#include /* For reading rc files */ +#include /* For reading rc files */ +#include /* For isspace(3) */ +#include /* For getpwuid(3) */ + +#include "rc.h" /* Public Rc interface */ +#include "rc_const.h" /* For configuration defaults */ +#include "rc_config.h" /* Option definitions */ +#include "rc_pcre.h" /* For section parsing */ /************************************************ @@ -41,8 +48,8 @@ { rc_file_t *pRcfile = NULL; - pRcfile = (rc_file_t *)calloc(1, sizeof(rc_file_t)); /* Allocate and clear */ - if (!pRcfile) /* Ensure storage */ + pRcfile = (rc_file_t *)calloc(1, sizeof(rc_file_t)); /* Allocate and clear */ + if (!pRcfile) /* Ensure storage */ RC_THROW(RC_ERR_MEM); if (szName) { @@ -52,26 +59,282 @@ else pRcfile->m_szName = NULL; - /* Default values */ - pRcfile->m_nSecs = -1; - pRcfile->m_ppSecvec = NULL; + /* Start section array with one empty allocated tail item */ + pRcfile->m_nSecs = 0; + pRcfile->m_ppSecvec = malloc(sizeof(rc_section_t *)); + *pRcfile->m_ppSecvec = NULL; return(pRcfile); } /**************************************************** +* rcfileParse(rc_file_t *) * +* Parse rcfile contents, initialize any sections * +****************************************************/ +rc_return_t rcfileParse(rc_file_t *pRcf) +{ + rc_script_t *pScript = NULL; + char *szLocex = NULL; + char *sBuf = NULL; + int nFdrc = -1; + int nRet = 0; + + if (pRcf->m_nSecs > 0) + RC_THROW(RC_ERR_USE); /* Only virgin rcfiles can be parsed */ + + /* Build the location path name */ + if (!configGetval(RC_LOC_VAL)) /* Config should have */ + RC_THROW(RC_ERR_INT); /* given a locs default */ + else { /* Only enter block with valid string, strdup can't handle NULL */ + if (*(configGetval(RC_LOC_VAL) + strlen(configGetval(RC_LOC_VAL)) - sizeof (char)) != '/') { + szLocex = malloc(strlen(configGetval(RC_LOC_VAL)) + \ + sizeof (char) + \ + strlen("rc.") + \ + strlen(pRcf->m_szName) + \ + sizeof (char)); + strcpy(szLocex, configGetval(RC_LOC_VAL)); + strcat(szLocex, "/"); + strcat(szLocex, "rc."); /* FIXME: Make the prefix configurable */ + strcat(szLocex, pRcf->m_szName); + } + else { + szLocex = malloc(strlen(configGetval(RC_LOC_VAL)) + \ + strlen("rc.") + \ + strlen(pRcf->m_szName) + \ + sizeof (char)); + strcpy(szLocex, configGetval(RC_LOC_VAL)); + strcat(szLocex, "rc."); /* FIXME: Make the prefix configurable */ + strcat(szLocex, pRcf->m_szName); + } + } + + /* Open the rc file unconditionally */ + if ((nFdrc = open(szLocex, O_RDONLY)) == -1) + RC_THROW(RC_ERR_RCF); + + /* Read data from the rcfile into a temporary script */ + pScript = scriptNew(); + sBuf = (char *)calloc(1, RC_READ_BUFSIZE); + while ((nRet = read(nFdrc, sBuf, RC_READ_BUFSIZE)) > 0) + scriptAppend(pScript, sBuf, nRet); + + if (nRet == -1) /* Handle read errors */ + RC_THROW(RC_ERR_IO); + + { /* Extract sections from script, and neatly place in rcfile */ + rc_section_t *pSec = NULL; + char *piSecname = NULL; + int nLabsize = 0; + int nPribytes = 0; + char *piSubtemp = NULL; /* To find priority and userid in substrings */ + char *piBlocend = NULL; /* Misnomer used to control section looping */ + char *piStart = NULL; + char *piEnd = NULL; + char *piSep = NULL; + char *szUser = NULL; + char *szName = NULL; + char *szTemp = NULL; /* Holds temporarily the pri and user strings */ + struct passwd *pPwd = NULL; + long nPri = 0; + long nUid = 0; + int nUserbytes = 0; + int nTmp = 0; + int nOffset = 0; + int nFound = 0; + int nVecsize = 0; + int nSubstrings = 0; + int *pnVec = NULL; + const char *kszErr = NULL; + const int kiRegopt = PCRE_DOTALL | PCRE_MULTILINE; + /*const int kiRegopt = PCRE_DOTALL | PCRE_MULTILINE | PCRE_UNGREEDY;*/ + + pcre *pRegex = NULL; /* Perl Compatible Regular Expression */ + pcre_extra *pExtra = NULL; /* Used for studying an expression */ + + if ((pRegex = pcre_compile(configGetval(RC_DEF_VAL), kiRegopt, &kszErr, &nOffset, NULL)) == NULL) + RC_THROW(RC_ERR_SYS); + + pExtra = pcre_study(pRegex, 0, &kszErr); /* Study the FSM */ + if (kszErr) { /* Variable contains a string reference in case of errors */ + free(pRegex); + RC_THROW(RC_ERR_SYS); + } + + if (pcre_fullinfo(pRegex, pExtra, PCRE_INFO_CAPTURECOUNT, &nSubstrings)) + RC_THROW(RC_ERR_SYS); + + /***********************************************************************/ + /* Reminder: PCRE writes vectors to help identify substrings. */ + /* That means that in the following code we can */ + /* execute a compiled PCRE regex (ab)(\s)(.*)$ */ + /* */ + /* piBlocend + pnVec[0] = 'start of whole matched string' */ + /* piBlocend + pnVec[1] = 'end of whole matched string' */ + /* piBlocend + pnVec[2] = 'start of first substring (ab)' */ + /* piBlocend + pnVec[3] = 'end of first substring (ab)' */ + /* piBlocend + pnVec[4] = 'start of second substring (\s)' */ + /* piBlocend + pnVec[5] = 'end of second substring (\s)' */ + /* piBlocend + pnVec[6] = 'start of third substring (.*)' */ + /* piBlocend + pnVec[7] = 'end of third substring (.*)' */ + /***********************************************************************/ + + /* Use multiples of six, because PCRE needs 2x multiples of three */ + nVecsize = 6 * (nSubstrings > 0 ? nSubstrings : 1); + nVecsize *= RC_GOOD_MEASURE; /* Add redundancy factor for error margin */ + /* pAwesome += RC_GOOD_VIBRATIONS;*/ /* Add good vibes for super action */ + + /* Filter the rc file for the section label, do it here the first time */ + pnVec = calloc(nVecsize, sizeof(int)); /* 2/3 vec 1/3 scrapinfo */ + nFound = pcre_exec(pRegex, pExtra, *pScript,\ + strlen(*pScript), 0, 0, pnVec, nVecsize); + + piBlocend = *pScript; /* Start piBlocend pointing to the script object */ + while (nFound > 1) { /* Loop as long as we have more sections */ + piSecname = piBlocend + *(pnVec + 2); + nLabsize = *(pnVec + 3) - *(pnVec + 2); + + /* Handle the section name and body */ + piStart = piBlocend + *(pnVec + 6); + piEnd = piBlocend + *(pnVec + 7); + szName = malloc((nLabsize + 1) * sizeof (char)); + strncpy(szName, piSecname, nLabsize); + *(szName + nLabsize * sizeof (char)) = '\0'; + pSec = sectionNew(szName); + free(szName); /* Get rid of the temporary, actually */ + szName = NULL; /* just for making a new section string */ + sectionSetndata(pSec, piStart, piEnd - piStart); + + /* Handle the section parent */ + sectionSetparent(pSec, pRcf->m_szName); + + /* FIXME: Implement --ParseSectionParam for extra gravy */ + /* Handle the section priority */ + piStart = piBlocend + *(pnVec + 4); + piEnd = piBlocend + *(pnVec + 5); + nPribytes = piEnd - piStart; + szTemp = malloc(nPribytes + sizeof (char)); + strncpy(szTemp, piStart, nPribytes); + *(szTemp + nPribytes) = '\0'; + piSubtemp = strstr(szTemp, RC_DEF_PRG); + if (piSubtemp) { /* Priority pattern found */ + for (nTmp = (int)piSubtemp + strlen(RC_DEF_PRG); \ + isspace(*(char *)nTmp); nTmp += sizeof (char)); /* Strip */ + nPri = strtol((char *)nTmp, &piSep, 10); + if ((char *)nTmp == piSep) /* No priority number follows */ + RC_THROW(RC_ERR_USE); /* which is an error */ + else + sectionSetpri(pSec, nPri); /* Found a priority value */ + } + else /* Fallback to default value */ + sectionSetpri(pSec, RC_DEF_PRI); + + /* Handle the section userid */ + piSubtemp = strstr(szTemp, RC_DEF_UIG); + if (piSubtemp) { /* Userid pattern found */ + for (nTmp = (int)piSubtemp + strlen(RC_DEF_UIG); \ + isspace(*(char *)nTmp); nTmp += sizeof (char)); /* Strip */ + nUid = strtol((char *)nTmp, &piSep, 10); + if ((char *)nTmp == piSep) /* No userid number follows */ + { + nUserbytes = strspn((strcspn(piSep, " \t\n") * sizeof (char) + piSep), " \t\n"); + nUserbytes = (strlen(piSep) - nUserbytes) * sizeof (char); + szUser = malloc(nUserbytes + sizeof (char)); + if (!szUser) + RC_THROW(RC_ERR_MEM); + strncpy(szUser, (const char *)nTmp, nUserbytes); + *(szUser + nUserbytes) = '\0'; + strtok(szUser, " \t\n"); + pPwd = getpwnam(szUser); + if (pPwd) { + sectionSetuid(pSec, pPwd->pw_uid); /* Set to given */ + sectionSetlogin(pSec, szUser); /* uid and login */ + } + else + sectionSetuid(pSec, RC_DEF_UID); /* Set to default */ + free(szUser); + } + else { + pPwd = getpwuid(nUid); + if (pPwd) { + sectionSetuid(pSec, nUid); /* Found a value */ + sectionSetlogin(pSec, pPwd->pw_name); /* uid and login */ + } + else + sectionSetuid(pSec, RC_DEF_UID); /* Set to default */ + } + } + else /* Fallback to default value */ + sectionSetuid(pSec, RC_DEF_UID); + + /* Cleanup */ + free(szTemp); + szTemp = NULL; + + /* Copy a new section to that found in the script object */ + pRcf->m_ppSecvec = realloc(pRcf->m_ppSecvec, sizeof(rc_section_t *) \ + * (pRcf->m_nSecs + 2)); + pRcf->m_ppSecvec[pRcf->m_nSecs] = sectionCopy(pSec); + pRcf->m_ppSecvec[pRcf->m_nSecs + 1] = NULL; + pRcf->m_nSecs++; + + /* Clean up our temporary section */ + sectionDelete(pSec); + pSec = NULL; + + /* Find end of section block */ + piBlocend += *(pnVec + 1); + + /* Try to match another section */ + nFound = pcre_exec(pRegex, pExtra, piBlocend,\ + strlen(piBlocend), 0, 0, pnVec, nVecsize); + } + + /* Handle errors */ + if (nFound == 1) /* User gave no klammern */ + RC_THROW(RC_ERR_USE); /* so complain about it */ + else if (nFound < PCRE_ERROR_NOMATCH) /* Generic problem so */ + RC_THROW(RC_ERR_SYS); /* return an error */ + } + + /* Deallocate and clean */ + scriptDelete(pScript); + pScript = NULL; + free(szLocex); + szLocex = NULL; + free(sBuf); + sBuf = NULL; + close(nFdrc); + + return(RC_OK); +} + +/**************************************************** +* rcfileGetsec(rc_file_t *, const char *) * +* Get a section from the rcfile, and return it * +****************************************************/ +rc_section_t *rcfileGetsec(rc_file_t *pRcf, const char *szSec) +{ + int nIter = 0; + + /* Return the section if it is found */ + for (nIter = 0; nIter < pRcf->m_nSecs; nIter++) { + if (!strcmp(pRcf->m_ppSecvec[nIter]->m_szName, szSec)) + return(pRcf->m_ppSecvec[nIter]); + } + + return NULL; +} + +/**************************************************** * rcfileAppendsec(rc_file_t *, rc_section_t *) * * Append a section to this rcfile * ****************************************************/ rc_return_t rcfileAppendsec(rc_file_t *pRcfile, rc_section_t *pInsec) { - assert(pRcfile); /* Rcfile parameter must be valid */ - if (!pInsec) /* Check sanity */ - return(RC_THROW(RC_ERR_USE)); - - /* When appending to a brand new rcfile, reset the object key (m_nSecs) */ - if (pRcfile->m_nSecs == -1) - pRcfile->m_nSecs = 0; + assert(pRcfile && pInsec); /* Parameters must be valid */ + + /* Grow the number of sections */ + pRcfile->m_nSecs++; /* First make our vector larger to hold one more section */ pRcfile->m_ppSecvec = realloc(pRcfile->m_ppSecvec, sizeof(rc_section_t *) \ @@ -83,6 +346,13 @@ pRcfile->m_ppSecvec[pRcfile->m_nSecs]->m_nPri = pInsec->m_nPri; pRcfile->m_ppSecvec[pRcfile->m_nSecs]->m_nUid = pInsec->m_nUid; + /* Deep copy of parent */ + if (pInsec->m_szParent) { + pRcfile->m_ppSecvec[pRcfile->m_nSecs]->m_szParent = \ + malloc((strlen(pInsec->m_szParent) + sizeof(char)) * sizeof(char)); + strcpy(pRcfile->m_ppSecvec[pRcfile->m_nSecs]->m_szParent, pInsec->m_szParent); + } + /* Deep copy of user name */ if (pInsec->m_szLogin) { pRcfile->m_ppSecvec[pRcfile->m_nSecs]->m_szLogin = \ @@ -91,14 +361,8 @@ } /* Deep copy of section text */ - if (pInsec->m_szData) { - pRcfile->m_ppSecvec[pRcfile->m_nSecs]->m_szData = \ - malloc((strlen(pInsec->m_szData) + sizeof(char)) * sizeof(char)); - strcpy(pRcfile->m_ppSecvec[pRcfile->m_nSecs]->m_szData, pInsec->m_szData); - } - - /* Finally increment section count */ - pRcfile->m_nSecs++; + if (scriptGetdata(pInsec->m_pData)) + scriptSetdata(pRcfile->m_ppSecvec[pRcfile->m_nSecs]->m_pData, pInsec->m_pData); return(RC_THROW(RC_OK)); } @@ -156,26 +420,24 @@ { int nSecs = pRcfile->m_nSecs; + assert(pRcfile); /* Stupidity check */ + /* Cleanup our junk */ - if (pRcfile) { - pRcfile->m_nSecs = 0; /* Blank the section count */ - if (pRcfile->m_szName) { /* Destroy the rc name */ - free(pRcfile->m_szName); - pRcfile->m_szName = NULL; - } - while (nSecs-- > 0) { /* Destroy the section vector */ - if (pRcfile->m_ppSecvec[nSecs]) { - sectionDelete(pRcfile->m_ppSecvec[nSecs]); - pRcfile->m_ppSecvec[nSecs] = NULL; - } + pRcfile->m_nSecs = 0; /* Blank the section count */ + if (pRcfile->m_szName) { /* Destroy the rc name */ + free(pRcfile->m_szName); + pRcfile->m_szName = NULL; + } + while (--nSecs >= 0) { /* Destroy the section vector */ + if (pRcfile->m_ppSecvec[nSecs]) { + sectionDelete(pRcfile->m_ppSecvec[nSecs]); + pRcfile->m_ppSecvec[nSecs] = NULL; } - free(pRcfile->m_ppSecvec); - pRcfile->m_ppSecvec = NULL; - free(pRcfile); - pRcfile = NULL; } - else /* Dumbass passed an empty rcfile object */ - assert(FALSE); + free(pRcfile->m_ppSecvec); + pRcfile->m_ppSecvec = NULL; + free(pRcfile); + pRcfile = NULL; return(RC_THROW(RC_OK)); } Index: ossp-pkg/rc/rc_private.h RCS File: /v/ossp/cvs/ossp-pkg/rc/rc_private.h,v rcsdiff -q -kk '-r1.33' '-r1.34' -u '/v/ossp/cvs/ossp-pkg/rc/rc_private.h,v' 2>/dev/null --- rc_private.h 2003/06/18 14:35:29 1.33 +++ rc_private.h 2003/06/26 18:45:14 1.34 @@ -80,9 +80,10 @@ typedef struct { int m_nPri; int m_nUid; + char *m_szParent; char *m_szName; char *m_szLogin; - char *m_szData; + rc_script_t *m_pData; } rc_section_t; /* Rcfile class */ Index: ossp-pkg/rc/rc_proc.c RCS File: /v/ossp/cvs/ossp-pkg/rc/rc_proc.c,v rcsdiff -q -kk '-r1.47' '-r1.48' -u '/v/ossp/cvs/ossp-pkg/rc/rc_proc.c,v' 2>/dev/null --- rc_proc.c 2003/06/23 11:27:53 1.47 +++ rc_proc.c 2003/06/26 18:45:14 1.48 @@ -68,16 +68,15 @@ rc_return_t procPopulate(rc_proc_t *pRc) { int nSect = 0; - int nFdrc = -1; int nFdfunc = -1; int nRet = 0; int nRcs = 0; ex_t Except; char *sBuf = NULL; - char *szLocex = NULL; - rc_script_t *pTempscript = NULL; + rc_file_t *pRcfile = NULL; rc_section_t *pSec = NULL; + rc_section_t *pCom = NULL; short nTotalsecs = vectorCount(configGetsecs()); assert(pRc->m_pList->m_ppFilevec); @@ -93,6 +92,7 @@ if (nRet == -1) /* Handle read errors */ RC_THROW(RC_ERR_IO); scriptAppend(pRc->m_pScriptfunc, "\n", sizeof("\n")); + close(nFdfunc); /* Close Func file handle */ } else RC_THROW(RC_ERR_FNC); @@ -104,86 +104,40 @@ if (!pRc->m_pList->m_ppFilevec[nRcs]) RC_THROW(RC_ERR_INT); /* Rcfile vector is missing its tail */ - /* Build the location path name */ - if (!configGetval(RC_LOC_VAL)) { - szLocex = NULL; - szLocex = strdup("./"); /* FIXME: Relocate default val */ - RC_THROW(RC_ERR_INT); /* Config should have given a locs default */ - } - else { /* Only enter block with valid string, strdup can't handle NULL */ - if (*(configGetval(RC_LOC_VAL) + strlen(configGetval(RC_LOC_VAL)) - sizeof (char)) != '/') { - szLocex = malloc(strlen(configGetval(RC_LOC_VAL)) + \ - sizeof (char) + \ - strlen("rc.") + \ - strlen(pRc->m_pList->m_ppFilevec[nRcs]->m_szName) + \ - sizeof (char)); - strcpy(szLocex, configGetval(RC_LOC_VAL)); - strcat(szLocex, "/"); - strcat(szLocex, "rc."); /* FIXME: Make the prefix configurable */ - strcat(szLocex, pRc->m_pList->m_ppFilevec[nRcs]->m_szName); - } - else { - szLocex = malloc(strlen(configGetval(RC_LOC_VAL)) + \ - strlen("rc.") + \ - strlen(pRc->m_pList->m_ppFilevec[nRcs]->m_szName) + \ - sizeof (char)); - strcpy(szLocex, configGetval(RC_LOC_VAL)); - strcat(szLocex, "rc."); /* FIXME: Make the prefix configurable */ - strcat(szLocex, pRc->m_pList->m_ppFilevec[nRcs]->m_szName); - } - } + pRcfile = rcfileNew(pRc->m_pList->m_ppFilevec[nRcs]->m_szName); + rcfileParse(pRcfile); - /* Open the rc file unconditionally */ - if ((nFdrc = open(szLocex, O_RDONLY)) == -1) - RC_THROW(RC_ERR_RCF); - - /* Read data from the rc file into a temporary script */ - pTempscript = scriptNew(); - while ((nRet = read(nFdrc, sBuf, RC_READ_BUFSIZE)) > 0) - scriptAppend(pTempscript, sBuf, nRet); - - if (nRet == -1) /* Handle read errors */ - RC_THROW(RC_ERR_IO); - - try { - /* Append common section if it exists */ - pSec = scriptSection(pTempscript, configGetval(RC_NCF_VAL)); + try { /* If it exists, append config section unconditionally */ + pSec = rcfileGetsec(pRcfile, configGetval(RC_NCF_VAL)); if (pSec) { /* Only operate if the section lookup succeeds */ scriptAppend(pRc->m_pScriptcom, sectionGetdata(pSec), strlen(sectionGetdata(pSec))); scriptAppend(pRc->m_pScriptcom, "\n", strlen ("\n")); - sectionDelete(pSec); /* Cleanup */ - pSec = NULL; /* Cleanup */ } for (nSect = 0; nSect < nTotalsecs; nSect++) { /* Iterate over */ /* Extract a section from the temp script, and append it */ - pSec = scriptSection(pTempscript, configGetsecs()[nSect]); - - if (pSec) /* Only copy if the section lookup succeeds */ + pSec = rcfileGetsec(pRcfile, configGetsecs()[nSect]); + if (pSec) { + /* Append common section only if the target section matches */ + pCom = rcfileGetsec(pRcfile, configGetval(RC_CMN_VAL)); + if (pCom) /* Only append if the common lookup succeeds */ + rcfileAppendsec(pRc->m_pList->m_ppFilevec[nRcs], pCom); + /* Only copy if the section lookup succeeds */ rcfileAppendsec(pRc->m_pList->m_ppFilevec[nRcs], pSec); + } else if (configGetval(RC_DBG_VAL)) /* Only show if debug set */ fprintf(stderr, "#Warning: Missing section '%s' in %s!\n",\ configGetsecs()[nSect], pRc->m_pList->m_ppFilevec[nRcs]->m_szName); - - if (pSec) { /* Cleanup iterative section string */ - sectionDelete(pSec); - pSec = NULL; - } } } catch(Except) rethrow; - /* Clean up our crap */ - scriptDelete(pTempscript); /* Temp script */ - pTempscript = NULL; - free(szLocex); /* Temp Location + Rcfile */ - szLocex = NULL; - close(nFdrc); /* Close Rc file handle */ + /* Attach our rcfile in the list */ + pRc->m_pList->m_ppFilevec[nRcs] = pRcfile; + pRcfile = NULL; } - close(nFdfunc); /* Close Func file handle */ - /* Memory cleanups */ if (sBuf) { free(sBuf); @@ -248,20 +202,18 @@ free(szVerbose); szVerbose = NULL; } - scriptAppend(pFatscript, scriptTostring(pRc->m_pScriptfunc), \ - strlen(scriptTostring(pRc->m_pScriptfunc))); + scriptAdd(pFatscript, pRc->m_pScriptfunc); /* Conditionally print common section notice in verbal mode */ if (configGetval(RC_VRB_VAL)) { - nBytes = (strlen(RC_EVN_TEXT) + strlen(RC_CMN_TEXT) * 2 + 2) * sizeof (char); + nBytes = (strlen(RC_EVN_TEXT) + strlen(RC_CFG_TEXT) * 2 + 2) * sizeof (char); szVerbose = malloc(nBytes); - sprintf(szVerbose, RC_EVN_TEXT, RC_CMN_TEXT, RC_CMN_TEXT); + sprintf(szVerbose, RC_EVN_TEXT, RC_CFG_TEXT, RC_CFG_TEXT); strcat(szVerbose, "\n"); scriptAppend(pFatscript, szVerbose, strlen(szVerbose)); free(szVerbose); szVerbose = NULL; } - scriptAppend(pFatscript, scriptTostring(pRc->m_pScriptcom), \ - strlen(scriptTostring(pRc->m_pScriptcom))); + scriptAdd(pFatscript, pRc->m_pScriptcom); for (nSecs = 0; nSecs < nTotalsecs; nSecs++) { for (nRcs = 0; nRcs < pRc->m_pList->m_nFiles; nRcs++) { for (nTmp = 0; nTmp < pRc->m_pList->m_ppFilevec[nRcs]->m_nSecs && \ @@ -344,8 +296,8 @@ } /* Allocate a block of section pointers to use temporarily */ ppSectmp = calloc(pRc->m_pList->m_nFiles, sizeof(rc_section_t *)); - szFunc = (char *)scriptTostring(pRc->m_pScriptfunc); - szCom = (char *)scriptTostring(pRc->m_pScriptcom); + szFunc = (char *)scriptGetdata(pRc->m_pScriptfunc); + szCom = (char *)scriptGetdata(pRc->m_pScriptcom); for (nSecs = 0; nSecs < nTotalsecs; nSecs++) { for (nRcs = 0; nRcs < pRc->m_pList->m_nFiles; nRcs++) { for (nTmp = 0; nTmp < pRc->m_pList->m_ppFilevec[nRcs]->m_nSecs && \ @@ -363,17 +315,17 @@ nTmp = 0; /* Count from zero until however many sections we have */ while (nTmp < pRc->m_pList->m_nFiles && ppSectmp[nTmp]) { /* Conditionally print common and other section notices in verbal mode */ - if (configGetval(RC_VRB_VAL)) { + if (configGetval(RC_VRB_VAL)) { /* Verbose mode is active */ size_t nSizverb = 0; size_t nPrescr = 0; size_t nSecverb = 0; size_t nSection = 0; /* Allocate space just for string to prepare for verbose */ - nSizverb = (strlen(RC_EXN_TEXT) + strlen(RC_CMN_TEXT) * 2 \ + nSizverb = (strlen(RC_EXN_TEXT) + strlen(RC_CFG_TEXT) * 2 \ + strlen(RC_ECHO_STR) + strlen("\"\"") + 1) * sizeof (char); szVerbose = malloc(nSizverb); - sprintf(szVerbose, RC_EXN_TEXT, RC_CMN_TEXT, RC_CMN_TEXT); + sprintf(szVerbose, RC_EXN_TEXT, RC_CFG_TEXT, RC_CFG_TEXT); /* Allocate space for entire string to execvp(3) */ nPrescr = (strlen(RC_VST_TEXT) + strlen(RC_EXF_TEXT) + \ @@ -388,12 +340,12 @@ strcat(szExec, "\n"); /* Stick a newline inbetween */ strcat(szExec, RC_EXF_TEXT); /* Continue with the func text */ strcat(szExec, "\";"); /* Finalize the verbosity notice */ - strcat(szExec, szFunc); /* Continue with the common script code */ + strcat(szExec, szFunc); /* Continue with the funcs script code */ strcat(szExec, RC_ECHO_STR); /* Continue with the echo string */ strcat(szExec, "\""); /* Append a quote next to the echo */ strcat(szExec, szVerbose); /* Continue with the common text */ strcat(szExec, "\";"); /* Finalize the verbosity notice */ - strcat(szExec, szCom); /* Then with the funcs script code */ + strcat(szExec, szCom); /* Then with the common script code */ szTmp = (char *)sectionGetname(ppSectmp[nTmp]); nSecverb = (strlen(RC_EXN_TEXT) + strlen(szTmp) * 2 \ + strlen(RC_ECHO_STR) + strlen("\"\"") + 1) * sizeof (char); @@ -433,7 +385,7 @@ szExec = NULL; } } - else { + else { /* Verbose mode is off */ szTmp = (char *)sectionGetdata(ppSectmp[nTmp]); szExec = malloc((strlen(szFunc) + strlen(szCom) + \ strlen(szTmp) + 1) * sizeof(char)); @@ -486,9 +438,9 @@ scriptDump(pRc->m_pScriptfunc); /* Dump the funcs script */ /* Conditionally print common section notice in verbal mode */ if (configGetval(RC_VRB_VAL)) { - nBytes = (strlen(RC_EVN_TEXT) + strlen(RC_CMN_TEXT) * 2 + 2) * sizeof (char); + nBytes = (strlen(RC_EVN_TEXT) + strlen(RC_CFG_TEXT) * 2 + 2) * sizeof (char); szVerbose = malloc(nBytes); - sprintf(szVerbose, RC_EVN_TEXT, RC_CMN_TEXT, RC_CMN_TEXT); + sprintf(szVerbose, RC_EVN_TEXT, RC_CFG_TEXT, RC_CFG_TEXT); strcat(szVerbose, "\n"); fprintf(stderr, szVerbose); free(szVerbose); @@ -527,7 +479,7 @@ else if (configGetval(RC_PAR_VAL)) { /* Parse names */ /* Allocate a block of section pointers to use as a temporary */ ppSectmp = calloc(pRc->m_pList->m_nFiles, sizeof(rc_section_t *)); - fprintf(stderr, "file %s, section %s\n", pRc->m_pList->m_ppFilevec[nRcs]->m_szName, RC_CMN_TEXT); + fprintf(stderr, "file %s, section %s\n", pRc->m_pList->m_ppFilevec[nRcs]->m_szName, RC_CFG_TEXT); for (nSecs = 0; nSecs < nTotalsecs; nSecs++) { for (nRcs = 0; nRcs < pRc->m_pList->m_nFiles; nRcs++) { for (nTmp = 0; nTmp < pRc->m_pList->m_ppFilevec[nRcs]->m_nSecs && \ Index: ossp-pkg/rc/rc_script.c RCS File: /v/ossp/cvs/ossp-pkg/rc/rc_script.c,v rcsdiff -q -kk '-r1.31' '-r1.32' -u '/v/ossp/cvs/ossp-pkg/rc/rc_script.c,v' 2>/dev/null --- rc_script.c 2003/06/18 14:35:29 1.31 +++ rc_script.c 2003/06/26 18:45:14 1.32 @@ -50,9 +50,9 @@ pNew = (rc_script_t *)malloc(sizeof(rc_script_t)); if (pNew) { - *pNew = malloc((strlen(scriptTostring(pOrig)) + 1) * sizeof(char)); + *pNew = malloc((strlen(scriptGetdata(pOrig)) + 1) * sizeof(char)); if (*pNew) - strcpy(*pNew, scriptTostring(pOrig)); + strcpy(*pNew, scriptGetdata(pOrig)); else RC_THROW(RC_ERR_MEM); } @@ -85,6 +85,36 @@ } /**************************************************** +* scriptAdd(rc_script_t *, rc_script_t *) * +* Add one script to another * +****************************************************/ +rc_return_t scriptAdd(rc_script_t *pDest, rc_script_t *pSource) +{ + int nResize = 0; + void *pvRealloc = NULL; + + assert(pDest && pSource); /* Parameters must be valid */ + + /* Add 2 chars to ensure that a \0 precedes any strings */ + nResize = strlen(*pDest) + strlen(*pSource) + sizeof (char) * 2; + /* Don't trust realloc(3) in this case */ + if ((pvRealloc = calloc(1, (size_t)nResize)) == NULL) + return(RC_THROW(RC_ERR_MEM)); + + strcpy(pvRealloc, *pDest); + strcat(pvRealloc, *pSource); + + /* Cleanup and deallocate */ + if (*pDest) { + free(*pDest); + *pDest = NULL; + } + + *pDest = pvRealloc; /* Put the new data in */ + return(RC_THROW(RC_OK)); +} + +/**************************************************** * scriptAppend(rc_script_t *, const char *, size_t) * * Append text to a script * ****************************************************/ @@ -138,8 +168,8 @@ char *szUser = NULL; char *szTemp = NULL; /* Holds temporarily the pri and user strings */ struct passwd *pPwd = NULL; - long nPri = 0; - long nUid = 0; + long nPri = 0; + long nUid = 0; int nUserbytes = 0; int nTmp = 0; int nOffset = 0; @@ -291,19 +321,35 @@ } /************************************************ -* scriptTostring(rc_script_t *) * +* scriptGetdata(rc_script_t *) * * Return the private script data as a string * ************************************************/ -const char *scriptTostring(rc_script_t *pScript) +const char *scriptGetdata(rc_script_t *pScript) { + assert(pScript); + /* Don't remove this! It encapsulates the script object, */ /* which might not be a simple string */ - if (pScript && *pScript) - return(*pScript); - else - RC_THROW(RC_ERR_USE); /* Script was never constructed */ + return(*pScript); +} - return(NULL); /* Not reached */ +/************************************************ +* scriptSetdata(rc_script_t *, const char *) * +* Set the private script data from a string * +************************************************/ +rc_return_t scriptSetdata(rc_script_t *pScript, const char *kszIn) +{ + assert(pScript && kszIn); /* Avoid idiots */ + + if (*pScript) { + free(*pScript); + *pScript = NULL; + } + + *pScript = malloc((strlen(kszIn) + 1) * sizeof(char)); + strcpy(*pScript, kszIn); + + return(RC_THROW(RC_OK)); } /************************************************ @@ -315,7 +361,7 @@ /* Don't remove this! It encapsulates the script object, */ /* which might not be a simple string */ if (pScript) { - fprintf(stdout, "%s", scriptTostring(pScript)); + fprintf(stdout, "%s", scriptGetdata(pScript)); return(RC_THROW(RC_OK)); } else @@ -340,7 +386,7 @@ /* Don't remove this! It encapsulates the script object, */ /* which might not be a simple string */ if (pStream) { - fprintf(pStream, "%s", scriptTostring(pScript)); + fprintf(pStream, "%s", scriptGetdata(pScript)); fclose(pStream); return(RC_THROW(RC_OK)); } Index: ossp-pkg/rc/rc_sect.c RCS File: /v/ossp/cvs/ossp-pkg/rc/rc_sect.c,v rcsdiff -q -kk '-r1.14' '-r1.15' -u '/v/ossp/cvs/ossp-pkg/rc/rc_sect.c,v' 2>/dev/null --- rc_sect.c 2003/06/18 14:35:29 1.14 +++ rc_sect.c 2003/06/26 18:45:14 1.15 @@ -50,6 +50,7 @@ if (pSec) { pSec->m_szName = malloc((strlen(szName) + 1) * sizeof(char)); strcpy(pSec->m_szName, szName); + pSec->m_pData = scriptNew(); } else RC_THROW(RC_ERR_MEM); @@ -66,9 +67,23 @@ rc_section_t *pSec = NULL; /* Today is a rain and no coffee day */ - pSec = (rc_section_t *)malloc(sizeof(rc_section_t)); - pSec->m_nPri = pOrigsec->m_nPri; - pSec->m_nUid = pOrigsec->m_nUid; + pSec = (rc_section_t *)calloc(1, sizeof(rc_section_t)); + pSec->m_nPri = pOrigsec->m_nPri; + pSec->m_nUid = pOrigsec->m_nUid; + + /* Deep copy of section name */ + if (pOrigsec->m_szName) { + pSec->m_szName = malloc((strlen(pOrigsec->m_szName) + sizeof(char))\ + * sizeof(char)); + strcpy(pSec->m_szName, pOrigsec->m_szName); + } + + /* Deep copy of parent name */ + if (pOrigsec->m_szParent) { + pSec->m_szParent = malloc((strlen(pOrigsec->m_szParent) + sizeof(char))\ + * sizeof(char)); + strcpy(pSec->m_szParent, pOrigsec->m_szParent); + } /* Deep copy of user name */ if (pOrigsec->m_szLogin) { @@ -78,10 +93,10 @@ } /* Deep copy of section text */ - if (pOrigsec->m_szData) { - pSec->m_szData = malloc((strlen(pOrigsec->m_szData) + sizeof(char))\ - * sizeof(char)); - strcpy(pSec->m_szData, pOrigsec->m_szData); + if (scriptGetdata(pOrigsec->m_pData)) { + if (!pSec->m_pData) + pSec->m_pData = scriptNew(); + scriptSetdata(pSec->m_pData, scriptGetdata(pOrigsec->m_pData)); } if (!pSec) @@ -124,6 +139,16 @@ return(0); /* Not reached */ } +const char *sectionGetparent(rc_section_t *pSec) +{ /* Parent rcfile name of section, used for display during verbose */ + if (pSec) + return(pSec->m_szParent); + else + RC_THROW(RC_ERR_USE); + + return(0); /* Not reached */ +} + const char *sectionGetlogin(rc_section_t *pSec) { /* User name of section, used for display during print */ if (pSec) @@ -136,8 +161,8 @@ const char *sectionGetdata(rc_section_t *pSec) { /* Data of section, this is the script body of the particular section */ - if (pSec && pSec->m_szData) - return(pSec->m_szData); + if (pSec && scriptGetdata(pSec->m_pData)) + return(scriptGetdata(pSec->m_pData)); else RC_THROW(RC_ERR_USE); @@ -179,6 +204,17 @@ return(RC_THROW(RC_ERR_USE)); } +rc_return_t sectionSetparent(rc_section_t *pSec, const char *szName) +{ /* Parent rcfile name of section, used for display during verbose */ + if (pSec) { + pSec->m_szParent = malloc((strlen(szName) + 1) * sizeof (char)); + strcpy(pSec->m_szParent, szName); + return(RC_THROW(RC_OK)); + } + + return(RC_THROW(RC_ERR_USE)); +} + rc_return_t sectionSetlogin(rc_section_t *pSec, const char *szLogin) { /* User name of section, used for display during print */ if (pSec) { @@ -190,44 +226,40 @@ return(RC_THROW(RC_ERR_USE)); } -rc_return_t sectionSetdata(rc_section_t *pSec, const char *kszScript) +rc_return_t sectionSetdata(rc_section_t *pSec, const char *kszIn) { /* Data of section, this is the script body of the particular section */ - if (pSec) { - size_t nBytes = (strlen(kszScript) + sizeof(char)) * sizeof(char); - if (pSec->m_szData) { /* The section data is already in use */ - free(pSec->m_szData); - pSec->m_szData = malloc(nBytes); - strcpy(pSec->m_szData, kszScript); - } - else { /* Set the data the usual way */ - pSec->m_szData = malloc(nBytes); - strcpy(pSec->m_szData, kszScript); - } - return(RC_THROW(RC_OK)); + + assert(pSec && kszIn); + + if (scriptGetdata(pSec->m_pData)) { /* The section data is already in use */ + scriptDelete(pSec->m_pData); + pSec->m_pData = NULL; } - return(RC_THROW(RC_ERR_USE)); + scriptSetdata(pSec->m_pData, kszIn); + return(RC_THROW(RC_OK)); } -rc_return_t sectionSetndata(rc_section_t *pSec, const char *kszScript, size_t Len) +rc_return_t sectionSetndata(rc_section_t *pSec, const char *kszIn, size_t Len) { /* Data of section, this is the script body of the particular section */ - if (pSec) { - size_t nBytes = (Len + 1) * sizeof(char); /* Set size */ - if (pSec->m_szData) { /* The section data is already in use */ - free(pSec->m_szData); - pSec->m_szData = malloc(nBytes); - strncpy(pSec->m_szData, kszScript, Len); - *(pSec->m_szData + Len) = '\0'; /* Terminate outgoing */ - } - else { /* Set the data the usual way */ - pSec->m_szData = malloc(nBytes); - strncpy(pSec->m_szData, kszScript, Len); - *(pSec->m_szData + Len) = '\0'; /* Terminate outgoing */ - } - return(RC_THROW(RC_OK)); + + char *szTemp = NULL; + size_t nBytes = (Len + 1) * sizeof(char); /* Set size */ + + assert(pSec && kszIn); /* Dummy detector */ + + if (pSec->m_pData) { /* The section data is already in use */ + scriptDelete(pSec->m_pData); } - return(RC_THROW(RC_ERR_USE)); + pSec->m_pData = scriptNew(); + szTemp = malloc(nBytes); + strncpy(szTemp, kszIn, Len); + *(szTemp + Len) = '\0'; /* Terminate outgoing */ + scriptSetdata(pSec->m_pData, szTemp); /* Finish the job */ + free(szTemp); /* Deallocate */ + szTemp = NULL; + return(RC_THROW(RC_OK)); } /************************************************ @@ -281,12 +313,18 @@ { /* Cleanup our junk */ if (pSec) { - if (pSec->m_szData) - free(pSec->m_szData); - if (pSec->m_szName) + if (pSec->m_pData) { + scriptDelete(pSec->m_pData); + pSec->m_pData = NULL; + } + if (pSec->m_szName) { free(pSec->m_szName); - if (pSec->m_szLogin) + pSec->m_szName = NULL; + } + if (pSec->m_szLogin) { free(pSec->m_szLogin); + pSec->m_szLogin = NULL; + } free(pSec); } else /* Dumbass passed an empty section object */ Index: ossp-pkg/rc/rc_test/rc.ntp RCS File: /v/ossp/cvs/ossp-pkg/rc/rc_test/rc.ntp,v rcsdiff -q -kk '-r1.8' '-r1.9' -u '/v/ossp/cvs/ossp-pkg/rc/rc_test/rc.ntp,v' 2>/dev/null --- rc.ntp 2003/05/28 18:26:48 1.8 +++ rc.ntp 2003/06/26 18:45:15 1.9 @@ -2,6 +2,12 @@ echo "Run commands NTP starting" +%config + echo "Starting ntp config section" + +%common + echo "Dis ist de commun sektion von ntp" + %test echo "Just an echo to test ntp" Index: ossp-pkg/rc/rc_test/rc.zebra RCS File: /v/ossp/cvs/ossp-pkg/rc/rc_test/rc.zebra,v rcsdiff -q -kk '-r1.7' '-r1.8' -u '/v/ossp/cvs/ossp-pkg/rc/rc_test/rc.zebra,v' 2>/dev/null --- rc.zebra 2003/06/03 15:28:09 1.7 +++ rc.zebra 2003/06/26 18:45:15 1.8 @@ -13,7 +13,7 @@ echo %test - echo "First" + echo "First line in zebra test" echo "Biff borchert echo to test zebra"