OSSP CVS Repository

ossp - Difference in ossp-pkg/rc/rc_file.c versions 1.1 and 1.2
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [History

ossp-pkg/rc/rc_file.c 1.1 -> 1.2

--- 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 <string.h> /* For string copy and such data ops */
-#include <stdlib.h> /* For memory ops */
-
-#include "rc.h"     /* Public Rc interface */
+#include <string.h>     /* For string copy and such data ops */
+#include <stdlib.h>     /* For memory ops             */
+#include <fcntl.h>      /* For reading rc files       */
+#include <unistd.h>     /* For reading rc files       */
+#include <ctype.h>      /* For isspace(3)             */
+#include <pwd.h>        /* 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));
 }

CVSTrac 2.0.1