OSSP CVS Repository

ossp - ossp-pkg/rc/rc_script.c 1.5
Not logged in
[Honeypot]  [Browse]  [Directory]  [Home]  [Login
[Reports]  [Search]  [Ticket]  [Timeline
  [Raw

ossp-pkg/rc/rc_script.c 1.5
/*  OSSP rc - Run-command processor
**  Copyright (c) 2002 Ralf S. Engelschall
**  Copyright (c) 2002 Cable & Wireless Deutschland GmbH
**  Copyright (c) 2002 The OSSP Project <http://www.ossp.org/>
**
**  This file is part of OSSP rc, a portable Run-command processor
**  which can be found at http://www.ossp.org/pkg/lib/rc/
**
**  Permission to use, copy, modify, and distribute this software for
**  any purpose with or without fee is hereby granted, provided that
**  the above copyright notice and this permission notice appear in all
**  copies.
**
**  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
**  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
**  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
**  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
**  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
**  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
**  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
**  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
**  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
**  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
**  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
**  SUCH DAMAGE.
**
**  rc_script.c: Run-command processor ISO C source file
*/

#include <stdlib.h>
#include <string.h>

#include "rc.h"         /* Public Rc interface      */
#include "rc_pcre.h"    /* For section parsing      */
#include "rc_config.h"  /* For configuration access */


/************************************************
* scriptNew(void)                               *
* Construct a script                            *
************************************************/
rc_script_t *scriptNew(void)
{
    rc_script_t *pScript = NULL;

    pScript = (rc_script_t *)malloc(sizeof(rc_script_t));
    *pScript = NULL;

    return(pScript);
}

/************************************************
* scriptAppend(rc_script_t *, char *, size_t)   *
* Append text to a script                       *
************************************************/
rc_return_t scriptAppend(rc_script_t *pScript, char *szInbuf, size_t Size)
{
    int nResize     = 0;
    void *pvRealloc = NULL;

    assert(pScript); /* Script parameter must be valid */

    if (!szInbuf) {
TRACE("Problem with appendScript");
/*        return(RC_THROW(RC_ERR_USE));*/
    }

    /* Short circuit in case of dumb noop call */
    if (Size == 0) {
        return(RC_THROW(RC_OK));
    }

    /* Add 2 to end of nResize to ensure that a \0 precedes any strings */
    nResize = (*pScript != NULL ? strlen(*pScript) : 0) + Size + 2;
    /* Don't trust realloc(3) in this case */
    if ((pvRealloc = calloc(1, (size_t)nResize)) == NULL) {
TRACE("Problem with appendScript");
/*        return(RC_THROW(RC_ERR_MEM));*/
    }

    /* Coerce strings into one Script again */
    if (*pScript) {
        strcpy(pvRealloc, *pScript);
        strncat(pvRealloc, szInbuf, Size);
    }
    else
        strncpy(pvRealloc, szInbuf, Size);

    /* Cleanup and deallocate memory */
    if (*pScript) {
        free(*pScript);
        *pScript = NULL;
    }
    *pScript = pvRealloc;

    return(RC_THROW(RC_OK));
}

/************************************************
* scriptSection(rc_script_t *, const char *)    *
* Parse a script for a given section            *
************************************************/
char *scriptSection(rc_script_t *pScript, const char *kszSecname)
{
    char *szTempout    = NULL;
    char *piLabstart   = NULL;
    char *piLabend     = NULL;
    char *piStart      = NULL;
    char *piEnd        = NULL;
    int nOffset        = 0;
    int nFound         = 0;
    int nVecsize       = 0;
    int nSubstrings    = 0;
    int *pnVec         = NULL;
    const int kiRegopt = 0;
    const char *kszErr = NULL;

    pcre *pRegex       = NULL;  /* Perl Compatible Regular Expression */
    pcre_extra *pExtra = NULL;  /* Used for studying an expression    */

    assert(pScript);            /* Check for a valid incoming script  */
    assert(configGetval(RC_DEF_VAL));

    if (!kszSecname)    /* If we get a NULL section label, give a NULL result */
        return (NULL);  /* This might be useful in some loop constructs */

    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);

    /* 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 */

    /* 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);

    piLabend = *pScript;    /* Start piLabstart pointing to the script object */
    while (nFound > 1) {    /* Loop as long as we have more sections */
        piLabstart = piLabend + *(pnVec + 2 * RC_SEC_SUB);  /* Seclabel start */
        piLabend += *(pnVec + 1);   /* Find end of section label */

        /* Test the substring. If it matches our label, generate a subscript */
        if (!strncmp(piLabstart , kszSecname, sizeof(kszSecname))) {
            piStart = strstr(piLabend, "\n") + sizeof(char); /* Wrap to start */

            /* See if more sections follow or if this is the last one */
            if (pcre_exec(pRegex, pExtra, piLabend, strlen(*pScript), 0, 0, pnVec, nVecsize) > 0)
                piEnd = piLabend + *pnVec;
            else /* Doch, last section in file */
                piEnd = piLabend + strlen(*pScript);

            szTempout = malloc(piEnd - piStart + sizeof(char));
            strncpy(szTempout, piStart, piEnd - piStart);
            *(szTempout + (piEnd - piStart)) = NULL;    /* Terminate outgoing */
            return(szTempout);  /* Section found, so return the text */
        }

        /* Get ready for the next round of matching */
        nFound = pcre_exec(pRegex, pExtra, piLabend,\
            strlen(piLabend), 0, 0, pnVec, nVecsize);
    }

    /* Under correct conditions, the section subscript was returned in loop */
    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 */

    return(NULL);                           /* Probably not found */
}

/************************************************
* scriptDump(rc_script_t *)                    *
* Print a script to standard out                *
************************************************/
rc_return_t scriptDump(rc_script_t *pScript)
{
    fprintf(stdout, "\n**************** Dumpskripte ****************\n");
    fprintf(stdout, "%s\n", *pScript);
    fprintf(stdout, "**************** Dumpskripte ****************\n\n");

    return(RC_THROW(RC_OK));
}

/************************************************
* scriptDelete(rc_script_t *)                   *
* Destruct a script                             *
************************************************/
rc_return_t scriptDelete(rc_script_t *pScript)
{
    if (*pScript)
        free(*pScript);
    else {
TRACE("Empty script created, unused, then destroyed");
/*        RC_THROW(RC_WRN_NUL);*/
    }
    free(pScript);

    return(RC_THROW(RC_OK));
}


CVSTrac 2.0.1