/* 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 "rc.h" /* Public interfaces */ #include "rc_const.h" /* String constants */ #include "rc_config.h" /* Configuration interface */ #include "rc_anal.h" /* Anal specific headers */ /************************************************ * 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 **ppInst, const char *kszName) { ex_t Except; assert(!(*ppInst)->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 */ (*ppInst)->m_pszRcs = malloc(sizeof(char **)); if (strcmp(kszName, RC_GLOB_WILD)) { (*ppInst)->m_pszRcs = malloc(sizeof(*((*ppInst)->m_pszRcs)) * 2); (*ppInst)->m_pszRcs[0] = strdup(kszName); (*ppInst)->m_pszRcs[0] = strdup(kszName); (*ppInst)->m_pszRcs[1] = NULL; (*ppInst)->m_nRcs = 1; /* We handle just one rc file */ } else { /* Wildcard rcfile indicates we must glob the locs directories */ try { analGloblocs(ppInst); } catch(Except) rethrow; } } return(RC_THROW(RC_OK)); } /************************************************ * private analTmp(rc_anal_t **, const char *) * * Read a temp file to analyze * ************************************************/ rc_return_t analTmp(rc_anal_t **ppInst, const char *kszName) { if (!kszName) { (*ppInst)->m_szTmp = NULL; /* RC_THROW(RC_WRN_NUL);*/ } else { /* Only enter block with valid string, strdup can't handle NULL */ (*ppInst)->m_szTmp = strdup(kszName); } return(RC_THROW(RC_OK)); } /************************************************ * private analFuncs(rc_anal_t **, const char *) * * Read a functions file to analyse * ************************************************/ rc_return_t analFuncs(rc_anal_t **ppInst, const char *kszName) { if (!kszName) { (*ppInst)->m_szFuncs = NULL; /* RC_THROW(RC_WRN_NUL);*/ } else { /* Only enter block with valid string, strdup can't handle NULL */ (*ppInst)->m_szFuncs = strdup(kszName); } return(RC_THROW(RC_OK)); } /************************************************ * private analLocs(rc_anal_t **, const char *) * * Read a location path expression to analyse * ************************************************/ rc_return_t analLocs(rc_anal_t **ppInst, const char *kszPathexpr) { if (!kszPathexpr) { (*ppInst)->m_szLocs = NULL; (*ppInst)->m_szLocs = strdup("./"); /* FIXME: Relocate default val */ /* RC_THROW(RC_WRN_NUL);*/ /* FIXME: ex_ Illegal instruction - core dumped */ } else { /* Only enter block with valid string, strdup can't handle NULL */ if (*(kszPathexpr + strlen(kszPathexpr)) != '/') { (*ppInst)->m_szLocs = malloc(strlen(kszPathexpr) + 2 * sizeof(char)); strcpy((*ppInst)->m_szLocs, kszPathexpr); if ((char)*((*ppInst)->m_szLocs + strlen((*ppInst)->m_szLocs) - 1) != '/') strcat((*ppInst)->m_szLocs, "/"); } else (*ppInst)->m_szLocs = strdup(kszPathexpr); } return(RC_THROW(RC_OK)); } /************************************************ * private analSecs(rc_anal_t **, const char **) * * Read a sections vector to analyse * ************************************************/ rc_return_t analSecs(rc_anal_t **ppInst, const char **pkszVector) { ex_t Except; if (!pkszVector) { RC_THROW(RC_WRN_NUL); } ex_try { /* Sections are a vector, so we must copy accordingly */ (*ppInst)->m_pszSecs = vectorCopy(pkszVector); (*ppInst)->m_nSecs = vectorCount(pkszVector); } ex_catch(Except) rethrow; return(RC_THROW(RC_OK)); } /*************************************************************** * int analFileselect(struct dirent *Direntry) * * Calculate whether a directory entry belongs to a defined set * ***************************************************************/ int analFileselect(struct dirent *Direntry) { if ((Direntry->d_name != NULL) && (strncmp(Direntry->d_name, "rc.", 3) == 0)) return (TRUE); else if ((strcmp(Direntry->d_name, ".") == 0) || (strcmp(Direntry->d_name, "..") == 0)) return (FALSE); else /* Catchall returns false for all not met set conditions */ return (FALSE); } /************************************************ * analGloblocs(rc_anal_t **ppInst) * * Glob all files of the location directories * ************************************************/ rc_return_t analGloblocs(rc_anal_t **ppInst) { DIR *pLocdir = NULL; struct dirent *pDirent = NULL; int nCount = 0; /* How many globbed files we find */ int nIter = 0; /* Used to step through found files */ assert(*ppInst); /* Sanity check */ /* First just learn how many globbed files we have */ if ((pLocdir = opendir((*ppInst)->m_szLocs)) == 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 */ (*ppInst)->m_pszRcs = malloc(sizeof(*((*ppInst)->m_pszRcs)) * (nCount + 1)); /* Loop through file index setting rc file names according to dirent */ if ((pLocdir = opendir((*ppInst)->m_szLocs)) == NULL) return(RC_THROW(RC_ERR_DIR)); for (pDirent = readdir(pLocdir); pDirent; pDirent = readdir(pLocdir)) { if (!strncmp(pDirent->d_name, "rc.", 3)) { (*ppInst)->m_pszRcs[nIter] = strdup(pDirent->d_name + \ strlen("rc.") * sizeof(char)); nIter++; } } closedir(pLocdir); (*ppInst)->m_pszRcs[nIter] = NULL; /* Terminate */ (*ppInst)->m_nRcs = nCount; /* Store how many globbed files there are */ return(RC_THROW(RC_OK)); } /************************************************ * analParse(rc_anal_t *) * * Parse the analyzed configuration data * ************************************************/ rc_return_t analParse(rc_anal_t *pInst) { ex_t Except; assert(pInst); /* Verify sanity */ ex_try { /* Read in data from the main configuration */ analLocs (&pInst, configGetval(RC_LOC_VAL)); analRcs (&pInst, configGetrcfile()); analTmp (&pInst, configGetval(RC_TMP_VAL)); analFuncs(&pInst, configGetval(RC_FNC_VAL)); analSecs (&pInst, configGetsecs()); } ex_catch(Except) rethrow; 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); if (pInst->m_szTmp) /* Temp file name */ free(pInst->m_szTmp); if (pInst->m_szFuncs) /* Function file names */ free(pInst->m_szFuncs); if (pInst->m_szLocs) /* Location path names */ free(pInst->m_szLocs); if (pInst->m_pszSecs) /* Section names */ vectorDel(pInst->m_pszSecs); free(pInst); return(RC_THROW(RC_OK)); }