OSSP CVS Repository

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

ossp-pkg/rc/rc_proc.c 1.20
/*  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_proc.c: Run-command processor ISO C source file
*/

#include <stdlib.h>     /* Standard system headers  */
#include <fcntl.h>      /* For reading rc files     */
#include <unistd.h>     /* For reading rc files     */
#include <string.h>     /* For string manipulation  */

/* FIXME: Remove */
#include <sys/stat.h>

#include "rc.h"         /* Public interfaces        */
#include "rc_config.h"  /* Option definitions       */


/************************************************
* procNew(void)                                 *
* Construct a processor                         *
************************************************/
rc_proc_t *procNew(void)
{
    rc_proc_t *pNewrc = NULL;

    pNewrc = malloc(sizeof(rc_proc_t));
    pNewrc->m_pAnal = analNew();        /* Construct a configuration analyser */
    pNewrc->m_pScript = scriptNew();    /* Construct a run-command script     */
    analParse(pNewrc->m_pAnal);         /* Preprocess the anal configuration  */

    return(pNewrc);
}

/************************************************
* procReadtmp(rc_proc_t *, const char *)        *
* Open and store a temp file                    *
************************************************/
rc_return_t procReadtmp(rc_proc_t *pRc, const char *szTmpname)
{
    fprintf(stderr, "%s!!!\n", szTmpname);

    return(RC_THROW(RC_OK));
}

/************************************************
* procPopulate(rc_proc_t *)                     *
* Populate the processor with run commands      *
************************************************/
rc_return_t procPopulate(rc_proc_t *pRc)
{
    int i         = 0;
    int nFdrc     = 0;
    int nFdfunc   = 0;
    int nRet      = 0;
    int nRept     = 0;
    int nIter     = 0;
    ex_t Except;

    char         *sBuf        = NULL;
    rc_section_t *pSec        = NULL;
    char         *szLocex     = NULL;
    rc_script_t  *pTempscript = NULL;
    rc_script_t  **ppParts    = NULL;

    assert(*pRc->m_pAnal->m_szRcs);
    sBuf = (char *)calloc(1, RC_READ_BUFSIZE);

    /* Open the func file if it exists in the configuration */
    if (pRc->m_pAnal->m_szFuncs) {
        if ((nFdfunc = open(pRc->m_pAnal->m_szFuncs, O_RDONLY)) == -1) {
            RC_THROW(RC_ERR_FNC);
        }
    }

    /* Stick on the starting shell id line */
    scriptAppend(pRc->m_pScript, "#! /bin/sh\n", strlen("#! /bin/sh\n"));

    /* Read the func file if it was opened successfully */
    /* We unfortunately make the assumption that 0 is an invalid filedesc */
    if (nFdfunc) {
        /* Read data from the func file */
        while ((nRet = read(nFdfunc, sBuf, RC_READ_BUFSIZE)) > 0) {
            scriptAppend(pRc->m_pScript, sBuf, nRet);
        }
        scriptAppend(pRc->m_pScript, "\n", sizeof(char));
        if (nRet == -1) /* Handle read errors */
            RC_THROW(RC_ERR_IO);
    }

    /* Logic needed for multiple section combination with priorities */
    ppParts = malloc(sizeof(rc_script_t *) * pRc->m_pAnal->m_nRcs);
    for (nRept = 0; nRept < pRc->m_pAnal->m_nRcs; nRept++)
        ppParts[nRept] = scriptNew();

    /* Iteratively read possibly globbed rc files */
    for (nIter = 0; nIter < pRc->m_pAnal->m_nRcs; nIter++)
    {
        assert(*pRc->m_pAnal->m_szRcs); /* If one of these assertions fail, */
        assert(pRc->m_pAnal->m_szLocs); /* you've probably seen the ex_ bug */

        /* Build the path name */
        szLocex = (char *)malloc(strlen(pRc->m_pAnal->m_szLocs) + strlen(pRc->m_pAnal->m_szRcs[nIter]) + 2);
        strcpy(szLocex, pRc->m_pAnal->m_szLocs);
        strcat(szLocex, pRc->m_pAnal->m_szRcs[nIter]);

        /* 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 config section if it exists */
            pSec = scriptSection(pTempscript, configGetval(RC_NCF_VAL));
            if (pSec) { /* Only operate if the section lookup succeeds */
                scriptAppend(pRc->m_pScript, sectionGetdata(pSec), strlen(sectionGetdata(pSec)));
                scriptAppend(pRc->m_pScript, "\n", sizeof(char));
                sectionDelete(pSec);    /* Cleanup */
                pSec = NULL;            /* Cleanup */
            }

/* FIXME: Swap nested rcfile/section logic loops for section/rcfile ordering */
            for (i = 0; pRc->m_pAnal->m_pszSecs[i]; i++) { /* Iterate over */
                /* Extract a section from the temp script, and append it */
                pSec = scriptSection(pTempscript, pRc->m_pAnal->m_pszSecs[i]);

                if (pSec) { /* Only call if the section lookup succeeds */
                    scriptAppend(pRc->m_pScript, sectionGetdata(pSec),
                        sectionGetlen(pSec) - 1);
                    scriptAppend(pRc->m_pScript, "\n", sizeof(char));
                }
                else if (configGetval(RC_DBG_VAL)) /* Only show if debug set */
                    fprintf(stderr, "#Warning: Missing section '%s' in %s!\n",\
                        pRc->m_pAnal->m_pszSecs[i],\
                        pRc->m_pAnal->m_szRcs[nIter]);

                if (pSec)   /* Cleanup iterative section string */
                    sectionDelete(pSec);
            }
        }
        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 */
    }

    close(nFdfunc);     /* Close Func file handle */

    /* Memory cleanups */
    if (ppParts) {
        for (nRept = pRc->m_pAnal->m_nRcs - 1; nRept >= 0 ; nRept--) {
            if (ppParts[nRept]) {
                free(ppParts[nRept]);
                ppParts[nRept] = NULL;
            }
        }
        free(ppParts);
        ppParts = NULL;
    }
    if (sBuf) {
        free(sBuf);
        sBuf = NULL;
    }

    return(RC_THROW(RC_OK));
}

/************************************************
* procRun(rc_proc_t *)                          *
* Run the processed run-command script          *
************************************************/
rc_return_t procRun(rc_proc_t *pRc)
{
    char *pszVec[RC_EXEC_MAXARGS];

    /****************************************************/
    /* This will execute, evaluate, or print the script */
    /* Exec  - Fork and execute each command            */
    /* Eval  - Print machine evaluatable format         */
    /* Print - Print human readable format              */
    /****************************************************/
    if (configGetval(RC_EVL_VAL))        /* Evaluate */
        fprintf(stderr, "Error: Evaluate is not implemented yet.\n"); /* FIX */
    else if (configGetval(RC_EXC_VAL)) { /* Execute  */
            pszVec[0] = "/bin/sh";
            pszVec[1] = "-c";
            pszVec[2] = (char *)scriptTostring(pRc->m_pScript);
            pszVec[3] = NULL;   /* Add a NULL to mark the end of the chain */
        if (execvp(*pszVec, pszVec) == -1)  /* launch                   */
            TRACE("Bad, execvp in child returned -1");
    }
    else if (configGetval(RC_PRN_VAL))   /* Print */
        scriptDump(pRc->m_pScript);
    else                                        /* Something is wrong here */
        return(RC_THROW(RC_ERR_INT));

    return(RC_THROW(RC_OK));
}

/************************************************
* procDelete(rc_proc_t *)                       *
* Destruct a processor                          *
************************************************/
rc_return_t procDelete(rc_proc_t *pRc)
{
    scriptDelete(pRc->m_pScript);   /* Destroy the script        */
    analDelete(pRc->m_pAnal);       /* Destroy the analyser      */
    free(pRc);                      /* Free the processor itself */

    return(RC_THROW(RC_OK));
}


CVSTrac 2.0.1