/* OSSP rc - Run-command processor ** Copyright (c) 2002 Ralf S. Engelschall ** Copyright (c) 2002 Cable & Wireless Deutschland GmbH ** Copyright (c) 2002 The OSSP Project ** ** 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_anal.c: Run-command processor ISO C source file */ #include #include #include #include "rc.h" /* Public interfaces */ #include "rc_const.h" /* String constants */ #include "rc_config.h" /* Configuration interface */ /************************************************ * analNew(void) * * Construct a new analyser * ************************************************/ rc_anal_t *analNew(void) { rc_anal_t *pNew = NULL; /* Allocate storage for 1 anal object */ pNew = calloc(1, sizeof(rc_anal_t)); return(pNew); } /************************************************ * private analRcs(rc_anal_t *, const char *) * * Read a rc file identifier to analyse * ************************************************/ rc_return_t analRcs(rc_anal_t *pInst, const char *kszName) { ex_t Except; assert(!(pInst)->m_pszRcs); /* Rcs 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_pszRcs = malloc(sizeof(char **)); if (strcmp(kszName, RC_GLOB_WILD)) { pInst->m_pszRcs = malloc(sizeof(*(pInst->m_pszRcs)) * 2); pInst->m_pszRcs[0] = strdup(kszName); pInst->m_pszRcs[0] = strdup(kszName); pInst->m_pszRcs[1] = NULL; pInst->m_nRcs = 1; /* We handle just one rc file */ } else { /* Wildcard rcfile indicates we must glob the locs directories */ try { analGloblocs(pInst); } catch(Except) rethrow; } } return(RC_THROW(RC_OK)); } /************************************************ * analGloblocs(rc_anal_t *pInst) * * Glob all files of the location directories * ************************************************/ rc_return_t analGloblocs(rc_anal_t *pInst) { 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_DIR)); for (pDirent = readdir(pLocdir); pDirent; pDirent = readdir(pLocdir)) if (!strncmp(pDirent->d_name, "rc.", 3)) nCount++; closedir(pLocdir); if (nCount == 0) /* Check out the health of this directory listing */ return(RC_THROW(RC_ERR_DIR)); else /* Allocate for the string array to hold directory entry names */ pInst->m_pszRcs = malloc(sizeof(pInst->m_pszRcs) * (nCount + 1)); /* Loop through file index setting rc file names according to dirent */ if ((pLocdir = opendir(szLocations)) == NULL) return(RC_THROW(RC_ERR_DIR)); for (pDirent = readdir(pLocdir); pDirent; pDirent = readdir(pLocdir)) { if (!strncmp(pDirent->d_name, "rc.", 3)) { pInst->m_pszRcs[nIter] = strdup(pDirent->d_name + \ strlen("rc.") * sizeof(char)); nIter++; } } closedir(pLocdir); pInst->m_pszRcs[nIter] = NULL; /* Terminate */ pInst->m_nRcs = nCount; /* Store how many globbed files there are */ return(RC_THROW(RC_OK)); } /************************************************ * analDelete(rc_anal_t *) * * Destruct an analyser * ************************************************/ rc_return_t analDelete(rc_anal_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_pszRcs && pInst->m_pszRcs[nIter]) while (pInst->m_pszRcs[nIter]) /* Rc file names */ free(pInst->m_pszRcs[nIter++]); if (pInst->m_pszRcs) /* Rc file name index */ free(pInst->m_pszRcs); free(pInst); return(RC_THROW(RC_OK)); }