OSSP CVS Repository

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

ossp-pkg/rc/rc_list.c 1.5
/*  OSSP rc - Run-Command Processor
**  Copyright (c) 2002-2003 Ralf S. Engelschall
**  Copyright (c) 2002-2003 Cable & Wireless Deutschland GmbH
**  Copyright (c) 2002-2003 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_list.c: Run-Command Processor ISO C source file
*/

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

#include "rc.h"         /* Public interfaces        */
#include "rc_const.h"   /* String constants         */
#include "rc_config.h"  /* Configuration interface  */


/************************************************
* listNew(void)                                 *
* Construct a new rcfile list                   *
************************************************/
rc_list_t *listNew(void)
{
    rc_list_t *pNew = NULL;

    /* Allocate storage for one list object */
    pNew = calloc(1, sizeof(rc_list_t));
    return(pNew);
}

/**************************************************
* private listPopulate(rc_list_t *, const char *) *
* Read the rcfile identifier and analyse it       *
**************************************************/
rc_return_t listPopulate(rc_list_t *pInst, const char *kszName)
{
    ex_t Except;

    assert(pInst); /* Verify sanity */
    assert(!pInst->m_ppFilevec); /* Rcfiles should be NULL until we set them */

    if (!kszName)
        return(RC_THROW(RC_ERR_RCF));
    else { /* Only enter block with valid string, strdup can't handle NULL */
        pInst->m_ppFilevec = malloc(sizeof (rc_file_t *));
        if (strcmp(kszName, RC_GLOB_WILD)) {
            pInst->m_ppFilevec[0] = rcfileNew(kszName);  /* For an object  */
            pInst->m_ppFilevec[1] = rcfileNew(NULL);     /* For the tail   */
            pInst->m_nFiles = 1;             /* We handle just one rc file */
        }
        else { /* Wildcard rcfile indicates to glob the locs directories  */
            try {
                DIR *pLocdir = NULL;
                struct dirent *pDirent = NULL;
                char *szLocations = NULL;   /* Locations of run command files */
                int nCount = 0;             /* How many globbed files we find */
                int nIter = 0;              /* Used to step through found files */

                assert(pInst); /* Sanity check */

                /* Build the location path name */
                if (!configGetval(RC_LOC_VAL)) {
                    szLocations = NULL;
                    szLocations = 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)) != '/') {
                        szLocations = malloc(strlen(configGetval(RC_LOC_VAL)) + \
                                             sizeof (char) + \
                                             sizeof (char));
                        strcpy(szLocations, configGetval(RC_LOC_VAL));
                        strcat(szLocations, "/");
                    }
                    else
                        szLocations = strdup(configGetval(RC_LOC_VAL));
                }

                /* First just learn how many globbed files we have */
                if ((pLocdir = opendir(szLocations)) == NULL)
                    return(RC_THROW(RC_ERR_LOC));
                for (pDirent = readdir(pLocdir); pDirent; pDirent = readdir(pLocdir))
                    if (!strncmp(pDirent->d_name, "rc.", strlen("rc.")))
                        nCount++;
                closedir(pLocdir);

                /* Prepare resources before entering rcfile allocation loop */
                if (nCount == 0) /* Check out the health of this directory listing */
                    return(RC_THROW(RC_ERR_LOC));
                nIter = 0; /* Used in the next for block, so initialize */
                pInst->m_ppFilevec = calloc(nCount + 1, sizeof (rc_file_t *));
                if (!pInst->m_ppFilevec) /* Guard against memory overruns */
                    return(RC_THROW(RC_ERR_MEM));
                if ((pLocdir = opendir(szLocations)) == NULL)
                    return(RC_THROW(RC_ERR_LOC));

                /* Loop through file index setting rc file names according to dirent */
                for (pDirent = readdir(pLocdir); pDirent; pDirent = readdir(pLocdir))
                    if (!strncmp(pDirent->d_name, "rc.", strlen("rc.")))
                        pInst->m_ppFilevec[nIter++] = rcfileNew(pDirent->d_name + strlen("rc.") * sizeof (char));

                /* Clean up our used resources and prepare to exit */
                pInst->m_ppFilevec[nIter] = rcfileNew(NULL); /* Make the tail */
                pInst->m_nFiles = nIter;      /* Store how many globbed files */
                assert(nCount == nIter);    /* Be cautious, ensure numbers */
                free(szLocations);          /* Cleanup our temp */
                szLocations = NULL;         /* locations string */
                closedir(pLocdir);
            }
            catch(Except)
                rethrow;
        }
    }

    return(RC_THROW(RC_OK));
}

/************************************************
* listGetrcfile(rc_list_t *, const char *)      *
* Searches the rcfile list and returns the file *
* matching the given name                       *
************************************************/
rc_file_t *listGetrcfile(rc_list_t *pInst, const char *kszName)
{
    int nIter = 0;

    assert(pInst && kszName); /* Dummy check */

    /* Iterate through list, searching for a rcfile matching the given name */
    for (nIter = 0; nIter < pInst->m_nFiles && \
        strcmp(pInst->m_ppFilevec[nIter]->m_szName, kszName); nIter++);
    if (nIter < pInst->m_nFiles)
        return(pInst->m_ppFilevec[nIter]);  /* Name of rcfile in list matched */
    else
        return(NULL);                       /* Name did not match any rcfile  */
}

/************************************************
* listDelete(rc_list_t *)                       *
* Destruct a rcfile list                        *
************************************************/
rc_return_t listDelete(rc_list_t *pInst)
{
/* FIXME: It could be that pInst needs to be a double pointer to */
/*        be properly used in destruction. Otherwise members are */
/*        just copies of the stack parameters passed in.         */
    int nIter = 0;

    assert(pInst);  /* Verify sanity */

    if (pInst->m_ppFilevec) {
        for (nIter = 0; nIter <= pInst->m_nFiles; nIter++) {
            if (pInst->m_ppFilevec[nIter]) {
                free(pInst->m_ppFilevec[nIter]); /* Deallocate a rcfile */
                pInst->m_ppFilevec[nIter] = NULL;
            }
        }
        free(pInst->m_ppFilevec);       /* Deallocate the rcfile vector */
        pInst->m_ppFilevec = NULL;
    }

    free(pInst);                        /* Deallocate the list itself   */
    pInst = NULL;

    return(RC_THROW(RC_OK));
}


CVSTrac 2.0.1