head 1.61; access; symbols OSSP_RC_0_7_3:1.61 OSSP_RC_0_7_2:1.61 OSSP_RC_0_7_1:1.60 OSSP_RC_ALPHA_06:1.40 OSSP_RC_EXBROKEN:1.35; locks; strict; comment @ * @; 1.61 date 2003.07.08.15.09.50; author mlelstv; state Exp; branches; next 1.60; 1.60 date 2003.07.07.13.30.51; author ms; state Exp; branches; next 1.59; 1.59 date 2003.07.07.12.55.42; author ms; state Exp; branches; next 1.58; 1.58 date 2003.07.01.13.26.25; author ms; state Exp; branches; next 1.57; 1.57 date 2003.06.30.16.32.53; author ms; state Exp; branches; next 1.56; 1.56 date 2003.06.30.16.25.54; author ms; state Exp; branches; next 1.55; 1.55 date 2003.06.30.16.14.58; author ms; state Exp; branches; next 1.54; 1.54 date 2003.06.30.15.58.49; author ms; state Exp; branches; next 1.53; 1.53 date 2003.06.30.15.27.38; author ms; state Exp; branches; next 1.52; 1.52 date 2003.06.30.15.09.46; author ms; state Exp; branches; next 1.51; 1.51 date 2003.06.30.14.43.36; author ms; state Exp; branches; next 1.50; 1.50 date 2003.06.27.14.26.13; author ms; state Exp; branches; next 1.49; 1.49 date 2003.06.27.10.15.19; author ms; state Exp; branches; next 1.48; 1.48 date 2003.06.26.18.45.14; author ms; state Exp; branches; next 1.47; 1.47 date 2003.06.23.11.27.53; author ms; state Exp; branches; next 1.46; 1.46 date 2003.06.18.14.35.29; author ms; state Exp; branches; next 1.45; 1.45 date 2003.06.13.18.33.07; author ms; state Exp; branches; next 1.44; 1.44 date 2003.06.12.14.24.32; author ms; state Exp; branches; next 1.43; 1.43 date 2003.06.12.13.27.44; author ms; state Exp; branches; next 1.42; 1.42 date 2003.06.11.16.18.48; author ms; state Exp; branches; next 1.41; 1.41 date 2003.06.03.15.26.52; author ms; state Exp; branches; next 1.40; 1.40 date 2003.05.28.15.09.29; author ms; state Exp; branches; next 1.39; 1.39 date 2003.05.28.14.40.25; author ms; state Exp; branches; next 1.38; 1.38 date 2003.05.27.13.00.22; author ms; state Exp; branches; next 1.37; 1.37 date 2003.05.26.16.24.08; author ms; state Exp; branches; next 1.36; 1.36 date 2003.05.26.16.03.57; author ms; state Exp; branches; next 1.35; 1.35 date 2003.05.26.11.36.16; author ms; state Exp; branches; next 1.34; 1.34 date 2003.05.26.08.10.37; author ms; state Exp; branches; next 1.33; 1.33 date 2003.05.23.14.14.09; author ms; state Exp; branches; next 1.32; 1.32 date 2003.05.22.14.46.33; author ms; state Exp; branches; next 1.31; 1.31 date 2003.05.21.15.24.07; author ms; state Exp; branches; next 1.30; 1.30 date 2003.05.21.15.16.41; author ms; state Exp; branches; next 1.29; 1.29 date 2003.05.21.12.49.21; author ms; state Exp; branches; next 1.28; 1.28 date 2003.05.20.17.14.17; author ms; state Exp; branches; next 1.27; 1.27 date 2003.05.20.15.06.42; author ms; state Exp; branches; next 1.26; 1.26 date 2003.05.20.11.47.51; author ms; state Exp; branches; next 1.25; 1.25 date 2003.05.19.19.04.22; author ms; state Exp; branches; next 1.24; 1.24 date 2003.05.16.18.43.30; author ms; state Exp; branches; next 1.23; 1.23 date 2003.05.15.22.22.30; author ms; state Exp; branches; next 1.22; 1.22 date 2003.05.15.12.49.11; author ms; state Exp; branches; next 1.21; 1.21 date 2003.05.14.16.36.28; author ms; state Exp; branches; next 1.20; 1.20 date 2003.05.12.16.17.47; author ms; state Exp; branches; next 1.19; 1.19 date 2003.05.12.15.43.32; author ms; state Exp; branches; next 1.18; 1.18 date 2003.04.03.12.05.14; author ms; state Exp; branches; next 1.17; 1.17 date 2002.08.02.20.09.59; author ms; state Exp; branches; next 1.16; 1.16 date 2002.08.01.15.54.45; author ms; state Exp; branches; next 1.15; 1.15 date 2002.08.01.15.16.25; author ms; state Exp; branches; next 1.14; 1.14 date 2002.07.30.16.36.41; author ms; state Exp; branches; next 1.13; 1.13 date 2002.07.10.19.03.58; author ms; state Exp; branches; next 1.12; 1.12 date 2002.07.05.12.54.56; author ms; state Exp; branches; next 1.11; 1.11 date 2002.07.02.18.03.17; author ms; state Exp; branches; next 1.10; 1.10 date 2002.07.01.15.03.33; author ms; state Exp; branches; next 1.9; 1.9 date 2002.06.28.18.23.10; author ms; state Exp; branches; next 1.8; 1.8 date 2002.06.28.17.43.23; author ms; state Exp; branches; next 1.7; 1.7 date 2002.06.28.14.20.23; author ms; state Exp; branches; next 1.6; 1.6 date 2002.06.27.15.35.58; author ms; state Exp; branches; next 1.5; 1.5 date 2002.06.26.14.42.53; author ms; state Exp; branches; next 1.4; 1.4 date 2002.06.26.14.11.16; author ms; state Exp; branches; next 1.3; 1.3 date 2002.05.22.14.32.20; author ms; state Exp; branches; next 1.2; 1.2 date 2002.05.13.16.57.00; author ms; state Exp; branches; next 1.1; 1.1 date 2002.04.25.16.17.57; author ms; state Exp; branches; next ; desc @@ 1.61 log @flush audit comments and changes @ text @/* 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 ** ** 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 /* Standard system headers */ #include /* For reading rc files */ #include /* For reading rc files */ #include /* For string manipulation */ #include /* For signal(3) */ #include /* For waitpid(2) and fork(2) */ #include "rc.h" /* Public interfaces */ #include "rc_const.h" /* String and value const */ #include "rc_config.h" /* Option definitions */ /************************************************ * procNew(void) * * Construct a processor * ************************************************/ rc_proc_t *procNew(void) { ex_t Except; rc_proc_t *pNewrc = NULL; ex_try { pNewrc = malloc(sizeof(rc_proc_t)); pNewrc->m_pList = listNew(); /* Construct a rcfile list */ listPopulate(pNewrc->m_pList, configGetrcfile()); /* Prepopulate list */ pNewrc->m_pScriptfunc = scriptNew(); /* Construct a functions script */ pNewrc->m_pScriptcnf = scriptNew(); /* Construct a config script */ } ex_catch(Except) rethrow; return(pNewrc); } /************************************************ * procPopulate(rc_proc_t *) * * Populate the processor with run commands * ************************************************/ rc_return_t procPopulate(rc_proc_t *pRc) { int nSect = 0; int nFdfunc = -1; int nRet = 0; int nRcs = 0; ex_t Except; char *sBuf = NULL; rc_file_t *pRcfile = NULL; rc_section_t *pSec = NULL; rc_section_t *pCom = NULL; short nTotalsecs = vectorCount(configGetsecs()); assert(pRc->m_pList->m_ppFilevec); sBuf = (char *)calloc(1, RC_READ_BUFSIZE); /* Open the func file if it exists in the configuration */ if (configGetval(RC_FNC_VAL)) { /* FIXME: Funcfile data does not belong in config section data! */ if ((nFdfunc = open(configGetval(RC_FNC_VAL), O_RDONLY)) >= 0) { /* Read data from the func file */ while ((nRet = read(nFdfunc, sBuf, RC_READ_BUFSIZE)) > 0) scriptnAppend(pRc->m_pScriptfunc, sBuf, nRet); if (nRet == -1) /* Handle read errors */ RC_THROW(RC_ERR_IO); scriptnAppend(pRc->m_pScriptfunc, "\n", strlen("\n")); close(nFdfunc); /* Close Func file handle */ } else RC_THROW(RC_ERR_FNC); } /* Iteratively read possibly globbed rc files */ for (nRcs = 0; nRcs < pRc->m_pList->m_nFiles; nRcs++) { if (!pRc->m_pList->m_ppFilevec[nRcs]) RC_THROW(RC_ERR_INT); /* Rcfile vector is missing its tail */ pRcfile = rcfileNew(pRc->m_pList->m_ppFilevec[nRcs]->m_szName); rcfileParse(pRcfile); try { /* If it exists, append config section unconditionally */ pSec = rcfileGetsec(pRcfile, configGetval(RC_NCF_VAL)); if (pSec) { /* Only operate if the section lookup succeeds */ scriptAdd(pRc->m_pScriptcnf, sectionGetscript(pSec)); scriptnAppend(pRc->m_pScriptcnf, "\n", strlen ("\n")); } for (nSect = 0; nSect < nTotalsecs; nSect++) { /* Iterate over */ /* Extract a section from the temp script, and append it */ pSec = rcfileGetsec(pRcfile, configGetsecs()[nSect]); if (pSec) { /* Append common section only if the target section matches */ pCom = rcfileGetsec(pRcfile, configGetval(RC_CMN_VAL)); if (pCom) /* Only append if the common lookup succeeds */ rcfileAppendsec(pRc->m_pList->m_ppFilevec[nRcs], pCom); /* Only copy if the section lookup succeeds */ rcfileAppendsec(pRc->m_pList->m_ppFilevec[nRcs], pSec); } else if (configGetval(RC_DBG_VAL)) /* Only show if debug set */ fprintf(stderr, "#Warning: Missing section '%s' in %s!\n",\ configGetsecs()[nSect], pRc->m_pList->m_ppFilevec[nRcs]->m_szName); } } catch(Except) rethrow; /* Replace rcfile in the list with combined sections */ rcfileDelete(pRc->m_pList->m_ppFilevec[nRcs]); pRc->m_pList->m_ppFilevec[nRcs] = pRcfile; pRcfile = NULL; } /* Memory cleanups */ if (sBuf) { free(sBuf); sBuf = NULL; } return(RC_THROW(RC_OK)); } /******************************************* * procRun(rc_proc_t *) * * Run the processed run-command script * * Exec - Fork and execute each command * * Eval - Print machine evaluatable format * * Print - Print human readable format * *******************************************/ rc_return_t procRun(rc_proc_t *pRc) { /* FIXME mlelstv - mode switch should be an enum * set to one of the four modes * and be tested with a switch() */ if (configGetval(RC_EVL_VAL)) /* Evaluate */ return(procEval(pRc)); else if (configGetval(RC_EXC_VAL)) /* Execute */ return(procExec(pRc)); else if (configGetval(RC_PRN_VAL)) /* Print */ return(procPrint(pRc)); else if (configGetval(RC_PAR_VAL)) /* Parse */ return(procParse(pRc)); else return(RC_ERR_INT); /* Run mode was not correctly set */ } /************************************************ * procEval(rc_proc_t *) * * Evaluate the run-command script * ************************************************/ rc_return_t procEval(rc_proc_t *pRc) { short nSecs = 0; /* Section index */ short nTotalsecs = vectorCount(configGetsecs()); /* Sections */ short nRcs = 0; /* Rc index */ int nTmp = 0; /* Generic index */ size_t nTmpname = 0; /* Temp name size */ size_t nBytes = 0; /* Size in bytes */ char *szTmp = NULL; /* Generic temporary string */ char *szTmpfile = NULL; /* Path of temporary file */ char *szVerbose = NULL; /* Used when handling verbose mode */ rc_section_t **ppSectmp = NULL; /* Used with priority scheduling */ rc_script_t *pFatscript = NULL; /* To build a comprehensive script */ /* Allocate a block of section pointers to use temporarily */ ppSectmp = calloc(pRc->m_pList->m_nFiles, sizeof(rc_section_t *)); pFatscript = scriptNew(); scriptnAppend(pFatscript, RC_BANG_STR, strlen(RC_BANG_STR)); /* Shebang */ /* Conditionally output initial notice in verbal mode */ if (configGetval(RC_VRB_VAL)) { szVerbose = malloc((strlen(RC_VST_TEXT) + 2) * sizeof (char)); sprintf(szVerbose, "%s", RC_VST_TEXT); strcat(szVerbose, "\n"); scriptnAppend(pFatscript, szVerbose, strlen(szVerbose)); free(szVerbose); szVerbose = NULL; } /* Conditionally print funcs section notice in verbal mode */ if (configGetval(RC_VRB_VAL)) { szVerbose = malloc((strlen(RC_EVF_TEXT) + 2) * sizeof (char)); sprintf(szVerbose, "%s", RC_EVF_TEXT); strcat(szVerbose, "\n"); scriptnAppend(pFatscript, szVerbose, strlen(szVerbose)); free(szVerbose); szVerbose = NULL; } scriptAdd(pFatscript, pRc->m_pScriptfunc); for (nSecs = 0; nSecs < nTotalsecs; nSecs++) { for (nRcs = 0; nRcs < pRc->m_pList->m_nFiles; nRcs++) { for (nTmp = 0; nTmp < pRc->m_pList->m_ppFilevec[nRcs]->m_nSecs && \ strcmp(pRc->m_pList->m_ppFilevec[nRcs]->m_ppSecvec[nTmp]->m_szName, \ configGetsecs()[nSecs]); nTmp++); if (nTmp < pRc->m_pList->m_ppFilevec[nRcs]->m_nSecs) ppSectmp[nRcs] = pRc->m_pList->m_ppFilevec[nRcs]->m_ppSecvec[nTmp]; else ppSectmp[nRcs] = NULL; } qsort((void *)ppSectmp, (size_t)pRc->m_pList->m_nFiles, \ sizeof(rc_section_t *), priCompare); for (nTmp = 0; nTmp < pRc->m_pList->m_nFiles && ppSectmp[nTmp]; nTmp++) { if (configGetval(RC_VRB_VAL)) { /* Conditionally evaluate config section notice in verbal mode */ nBytes = (strlen(RC_EVN_TEXT) + strlen(RC_DEF_NCF) + \ strlen(sectionGetparent(ppSectmp[nTmp])) + 2) * sizeof (char); szVerbose = malloc(nBytes); sprintf(szVerbose, RC_EVN_TEXT, RC_DEF_NCF, sectionGetparent(ppSectmp[nTmp])); strcat(szVerbose, "\n"); scriptnAppend(pFatscript, szVerbose, strlen(szVerbose)); free(szVerbose); szVerbose = NULL; } scriptAdd(pFatscript, pRc->m_pScriptcnf); /* Examine our list, and try to take the corresponding */ /* common section data from it to add to your script */ { rc_section_t *pComsec = NULL; pComsec = rcfileGetsec(listGetrcfile(pRc->m_pList, \ ppSectmp[nTmp]->m_szParent), configGetval(RC_CMN_VAL)); if (pComsec) { /* Do we have a common section to load? */ if (configGetval(RC_VRB_VAL)) { szTmp = (char *)sectionGetname(pComsec); nBytes = (strlen(RC_EVN_TEXT) + strlen(szTmp) + \ strlen (sectionGetparent(pComsec)) + \ strlen(RC_ECHO_STR) + strlen("\"\"") + 1) * \ sizeof (char); szVerbose = malloc(nBytes); sprintf(szVerbose, RC_EVN_TEXT, szTmp, sectionGetparent(pComsec)); strcat(szVerbose, "\n"); scriptnAppend(pFatscript, szVerbose, strlen(szVerbose)); free(szVerbose); szVerbose = NULL; } scriptAdd(pFatscript, sectionGetscript(pComsec)); } } /* Conditionally print each section notice in verbal mode */ if (configGetval(RC_VRB_VAL)) { szTmp = (char *)sectionGetname(ppSectmp[nTmp]); nBytes = (strlen(RC_EVN_TEXT) + strlen(szTmp) + 2) * sizeof (char); szVerbose = malloc(nBytes); sprintf(szVerbose, RC_EVN_TEXT, szTmp, sectionGetparent(ppSectmp[nTmp])); strcat(szVerbose, "\n"); scriptnAppend(pFatscript, szVerbose, strlen(szVerbose)); free(szVerbose); szVerbose = NULL; } if ((szTmp = (char *)sectionGetlogin(ppSectmp[nTmp])) != NULL) { scriptnAppend(pFatscript, "#su ", strlen("#su ")); scriptnAppend(pFatscript, szTmp, strlen(szTmp)); } else scriptnAppend(pFatscript, "#exit ", strlen("#exit ")); scriptnAppend(pFatscript, "\n", strlen("\n")); scriptAdd(pFatscript, sectionGetscript(ppSectmp[nTmp])); } } free(ppSectmp); ppSectmp = NULL; szTmpfile = (char *)configGetval(RC_TMP_VAL); nTmpname = (strlen(szTmpfile) + strlen(RC_EVL_TMP) + \ strlen(RC_EVL_SUF) + 1) * sizeof(char); if (*(szTmpfile + (strlen(szTmpfile) - 1) * sizeof(char)) != '/') nTmpname += sizeof(char); szTmpfile = malloc(nTmpname); strcpy(szTmpfile, configGetval(RC_TMP_VAL)); if (*(szTmpfile + (strlen(szTmpfile) - 1) * sizeof(char)) != '/') strcat(szTmpfile, "/"); strcat(szTmpfile, RC_EVL_TMP); mktemp(szTmpfile); strcat(szTmpfile, RC_EVL_SUF); scriptWrite(pFatscript, szTmpfile); /* Write the whole script out */ /* Conditionally don't remove the temp file (see constants) */ if (configGetval(RC_DBG_VAL)) fprintf(stdout, RC_EVL_DBG, szTmpfile); else fprintf(stdout, RC_EVL_OUT, szTmpfile, szTmpfile); /* Cleanup eval processing crap */ free(szTmpfile); szTmpfile = NULL; scriptDelete(pFatscript); pFatscript = NULL; return(RC_THROW(RC_OK)); } /************************************************ * procExec(rc_proc_t *) * * Execute the run-command script * ************************************************/ rc_return_t procExec(rc_proc_t *pRc) { short nRcs = 0; /* Rc index */ short nSecs = 0; /* Section index */ short nTotalsecs = vectorCount(configGetsecs()); /* Sections */ rc_section_t **ppSectmp = NULL; /* Used with priority scheduling */ int nRunuid = -1; /* The current user id */ int nSectuid = -1; /* The section's user id */ int nTmp = 0; /* Generic temporary index */ int nStat = 0; /* Status forked child */ pid_t Pidexec = -1; /* Spawning before execv(3) */ char *pszVec[RC_EXEC_MAXARGS]; /* For passing in to execv(3) */ char *szTmp = NULL; /* Generic temporary string */ char *szFunc = NULL; /* Stores func script text */ char *szCnf = NULL; /* Stores config script text */ char *szExec = NULL; /* Used only during exec mode */ char *szVerbose = NULL; /* Used when handling verbose mode */ /* This block does nothing more than implement the feature, */ /* that allows rc to run unprivileged (as long as no privileged */ /* code is used in the script sections to be executed */ for (nSecs = 0; nSecs < nTotalsecs; nSecs++) { for (nTmp = 0; nTmp < pRc->m_pList->m_nFiles; nTmp++) { if (pRc->m_pList->m_ppFilevec[nTmp]->m_ppSecvec && \ pRc->m_pList->m_ppFilevec[nTmp]->m_ppSecvec[nSecs]) { nRunuid = getuid(); nSectuid = pRc->m_pList->m_ppFilevec[nTmp]->m_ppSecvec[nSecs]->m_nUid; /* See if root user status is needed, and bail out if so */ if (nRunuid != 0 && nSectuid != -1 && nRunuid != nSectuid) { fprintf(stderr, RC_RUT_TEXT); return(RC_THROW(RC_ERR_USE)); } } } } /* Allocate a block of section pointers to use temporarily */ ppSectmp = calloc(pRc->m_pList->m_nFiles, sizeof(rc_section_t *)); szFunc = (char *)scriptGetdata(pRc->m_pScriptfunc); szCnf = (char *)scriptGetdata(pRc->m_pScriptcnf); for (nSecs = 0; nSecs < nTotalsecs; nSecs++) { for (nRcs = 0; nRcs < pRc->m_pList->m_nFiles; nRcs++) { for (nTmp = 0; nTmp < pRc->m_pList->m_ppFilevec[nRcs]->m_nSecs && \ strcmp(pRc->m_pList->m_ppFilevec[nRcs]->m_ppSecvec[nTmp]->m_szName, \ configGetsecs()[nSecs]); nTmp++); if (nTmp < pRc->m_pList->m_ppFilevec[nRcs]->m_nSecs) ppSectmp[nRcs] = pRc->m_pList->m_ppFilevec[nRcs]->m_ppSecvec[nTmp]; else ppSectmp[nRcs] = NULL; } qsort((void *)ppSectmp, (size_t)pRc->m_pList->m_nFiles, sizeof(rc_section_t *), priCompare); pszVec[0] = "/bin/sh"; /* Run the bourne shell over the following */ pszVec[1] = "-c"; /* Append script code of the sections */ pszVec[3] = NULL; /* Add a NULL to mark the end of the chain */ nTmp = 0; /* Count from zero until however many sections we have */ while (nTmp < pRc->m_pList->m_nFiles && ppSectmp[nTmp]) { /* Conditionally print config and other section notices in verbal mode */ if (configGetval(RC_VRB_VAL)) { /* Verbose mode is active */ size_t nSizverb = 0; size_t nPrescr = 0; size_t nSecverb = 0; size_t nSection = 0; /* Allocate space just for string to prepare for verbose */ nSizverb = (strlen(RC_EXN_TEXT) + strlen(RC_DEF_NCF) + \ strlen(sectionGetparent(ppSectmp[nTmp])) + strlen(RC_ECHO_STR) + \ strlen("\"\"") + 1) * sizeof (char); szVerbose = malloc(nSizverb); sprintf(szVerbose, RC_EXN_TEXT, RC_DEF_NCF, sectionGetparent(ppSectmp[nTmp])); /* Allocate space for entire string to execvp(3) */ nPrescr = (strlen(RC_VST_TEXT) + strlen(RC_EXF_TEXT) + \ strlen(szVerbose) + strlen(szFunc) + strlen(szCnf) + \ strlen(RC_BANG_STR) + 1) * sizeof (char); szExec = malloc(nSizverb + nPrescr); strcpy(szExec, RC_BANG_STR); /* Start out with the bang string */ strcat(szExec, RC_ECHO_STR); /* Continue with the echo string */ strcat(szExec, "\""); /* Append a quote next to the echo */ strcat(szExec, RC_VST_TEXT); /* Continue with the start text */ if (strlen(szFunc) > 0) { strcat(szExec, "\n"); /* Stick a newline inbetween */ strcat(szExec, RC_EXF_TEXT); /* Continue with the func text */ } strcat(szExec, "\";"); /* Finalize the verbosity notice */ strcat(szExec, szFunc); /* Continue with the funcs script code */ strcat(szExec, RC_ECHO_STR); /* Continue with the echo string */ strcat(szExec, "\""); /* Append a quote next to the echo */ strcat(szExec, szVerbose); /* Continue with the config text */ strcat(szExec, "\";"); /* Finalize the verbosity notice */ strcat(szExec, szCnf); /* Then with the config script code */ /* Examine our list, and try to take the corresponding */ /* common section data from it to add to your script */ { rc_section_t *pComsec = NULL; pComsec = rcfileGetsec(listGetrcfile(pRc->m_pList, \ ppSectmp[nTmp]->m_szParent), configGetval(RC_CMN_VAL)); if (pComsec) { /* If we have a common section to load, */ szTmp = (char *)sectionGetname(pComsec); nSecverb = (strlen(RC_EXN_TEXT) + strlen(szTmp) + \ strlen (sectionGetparent(pComsec)) + \ strlen(RC_ECHO_STR) + strlen("\"\"") + 1) * \ sizeof (char); realloc(szVerbose, nSecverb); sprintf(szVerbose, RC_EXN_TEXT, szTmp, sectionGetparent(pComsec)); nSection = (strlen(szTmp) + 1) * sizeof (char); realloc(szExec, nSizverb + nPrescr + nSecverb + nSection); strcat(szExec, RC_ECHO_STR); /* Start out with the echo string */ strcat(szExec, "\""); /* Append a quote next to the echo */ strcat(szExec, szVerbose); /* Continue with the common text */ strcat(szExec, "\";"); /* Finalize the verbosity notice */ strcat(szExec, sectionGetdata(pComsec)); /* load it */ } } /* Build last set of verbose data for the actual script */ szTmp = (char *)sectionGetname(ppSectmp[nTmp]); nSecverb = (strlen(RC_EXN_TEXT) + strlen(szTmp) * 2 \ + strlen(RC_ECHO_STR) + strlen("\"\"") + 1) * sizeof (char); realloc(szVerbose, nSecverb); sprintf(szVerbose, RC_EXN_TEXT, szTmp, sectionGetparent(ppSectmp[nTmp])); nSection = (strlen(szTmp) + strlen(sectionGetdata(ppSectmp[nTmp])) + 1) * sizeof (char); realloc(szExec, nSizverb + nPrescr + nSecverb + nSection); szTmp = (char *)sectionGetdata(ppSectmp[nTmp]); strcat(szExec, RC_ECHO_STR); /* Start out with the echo string */ strcat(szExec, "\""); /* Append a quote next to the echo */ strcat(szExec, szVerbose); /* Continue with the verboseity text */ strcat(szExec, "\";"); /* Finalize the verbosity notice */ strcat(szExec, szTmp); /* Then with the new script code */ pszVec[2] = szExec; /* Launch the new process image now */ free(szVerbose); szVerbose = NULL; /* Spawn the section shell code */ switch (Pidexec = fork()) { case -1: /* Broken */ return(RC_THROW(RC_ERR_INT)); break; /* Huh? */ case 0: /* Child, runs script code through bourne shell */ nSectuid = sectionGetuid(ppSectmp[nTmp]); if (nSectuid >= 0 && getuid() != nSectuid) if (setuid(nSectuid) != 0) return(RC_THROW(RC_ERR_ROOT)); if (execvp(*pszVec, pszVec) == -1) return(RC_THROW(RC_ERR_INT)); break; default: /* Parent, blocks until child returns */ waitpid(Pidexec, &nStat, WUNTRACED); if ((nStat = WEXITSTATUS(nStat)) != 0) return(nStat); break; } if (szExec) { free(szExec); /* Cleanup after exec */ szExec = NULL; } } else { /* Verbose mode is off */ szTmp = (char *)sectionGetdata(ppSectmp[nTmp]); szExec = malloc((strlen(szFunc) + strlen(szCnf) + \ strlen(szTmp) + 1) * sizeof(char)); strcpy(szExec, RC_BANG_STR); /* Start out with the shebang string */ strcat(szExec, szFunc); /* Continue with just the funcs script code */ strcat(szExec, szCnf); /* Continue with just the config script code */ /* Examine our list, and try to take the corresponding */ /* common section data from it to add to your script */ { rc_section_t *pComsec = NULL; pComsec = rcfileGetsec(listGetrcfile(pRc->m_pList, \ ppSectmp[nTmp]->m_szParent), configGetval(RC_CMN_VAL)); if (pComsec) /* If we have a common section to load, */ strcat(szExec, sectionGetdata(pComsec)); /* load it */ } strcat(szExec, szTmp); /* And build a section onto the command chain */ pszVec[2] = szExec; /* Actually launch the new process image now */ /* Spawn the section shell code */ switch (Pidexec = fork()){ case -1: /* Broken */ return(RC_THROW(RC_ERR_INT)); break; /* Huh? */ case 0: /* Child, runs script code through bourne shell */ nSectuid = sectionGetuid(ppSectmp[nTmp]); if (nSectuid >= 0 && getuid() != nSectuid) if (setuid(nSectuid) != 0) return(RC_THROW(RC_ERR_ROOT)); if (execvp(*pszVec, pszVec) == -1) return(RC_THROW(RC_ERR_INT)); break; default: /* Parent, blocks until child returns */ waitpid(Pidexec, &nStat, WUNTRACED); if ((nStat = WEXITSTATUS(nStat)) != 0) return(nStat); break; } free(szExec); /* Cleanup after exec */ szExec = NULL; } nTmp++; /* Next rc script */ } } free(ppSectmp); ppSectmp = NULL; return(RC_THROW(RC_OK)); } /************************************************ * procPrint(rc_proc_t *) * * Print the run-command script * ************************************************/ rc_return_t procPrint(rc_proc_t *pRc) { size_t nBytes = 0; /* Size in bytes */ int nTmp = 0; /* Generic index */ short nRcs = 0; /* Rc index */ short nSecs = 0; /* Section index */ short nTotalsecs = vectorCount(configGetsecs()); /* Sections */ rc_section_t **ppSectmp = NULL; /* Used with priority scheduling */ char *szVerbose = NULL; /* Used when handling verbose mode */ char *szTmp = NULL; /* Generic temporary string */ /* Allocate a block of section pointers to use as a temporary */ ppSectmp = calloc(pRc->m_pList->m_nFiles, sizeof(rc_section_t *)); /* Conditionally output initial notice in verbal mode */ if (configGetval(RC_VRB_VAL)) fprintf(stderr, "%s\n", RC_VST_TEXT); /* Conditionally print funcs section notice in verbal mode */ if (configGetval(RC_VRB_VAL)) fprintf(stderr, "%s\n", RC_PNF_TEXT); scriptDump(pRc->m_pScriptfunc); /* Dump the funcs script */ for (nSecs = 0; nSecs < nTotalsecs; nSecs++) { for (nRcs = 0; nRcs < pRc->m_pList->m_nFiles; nRcs++) { for (nTmp = 0; nTmp < pRc->m_pList->m_ppFilevec[nRcs]->m_nSecs && \ strcmp(pRc->m_pList->m_ppFilevec[nRcs]->m_ppSecvec[nTmp]->m_szName, \ configGetsecs()[nSecs]); nTmp++); if (nTmp < pRc->m_pList->m_ppFilevec[nRcs]->m_nSecs) ppSectmp[nRcs] = pRc->m_pList->m_ppFilevec[nRcs]->m_ppSecvec[nTmp]; else ppSectmp[nRcs] = NULL; } qsort((void *)ppSectmp, (size_t)pRc->m_pList->m_nFiles, sizeof(rc_section_t *), priCompare); for (nTmp = 0; nTmp < pRc->m_pList->m_nFiles && ppSectmp[nTmp]; nTmp++) { if (configGetval(RC_VRB_VAL)) { /* Conditionally print config section notice in verbal mode */ nBytes = (strlen(RC_PRN_TEXT) + strlen(RC_DEF_NCF) + \ strlen(sectionGetparent(ppSectmp[nTmp])) + 2) * sizeof (char); szVerbose = malloc(nBytes); sprintf(szVerbose, RC_PRN_TEXT, RC_DEF_NCF, sectionGetparent(ppSectmp[nTmp])); strcat(szVerbose, "\n"); fprintf(stderr, szVerbose); free(szVerbose); szVerbose = NULL; } scriptDump(pRc->m_pScriptcnf); /* Dump the config script */ /* Examine our list, and try to take the corresponding */ /* common section data from it to add to your script */ { rc_section_t *pComsec = NULL; pComsec = rcfileGetsec(listGetrcfile(pRc->m_pList, \ ppSectmp[nTmp]->m_szParent), configGetval(RC_CMN_VAL)); if (pComsec) { /* Do we have a common section to load? */ if (configGetval(RC_VRB_VAL)) { szTmp = (char *)sectionGetname(pComsec); nBytes = (strlen(RC_PRN_TEXT) + strlen(szTmp) + \ strlen (sectionGetparent(pComsec)) + \ strlen(RC_ECHO_STR) + strlen("\"\"") + 1) * \ sizeof (char); szVerbose = malloc(nBytes); sprintf(szVerbose, RC_PRN_TEXT, szTmp, sectionGetparent(pComsec)); strcat(szVerbose, "\n"); fprintf(stderr, "%s", szVerbose); free(szVerbose); szVerbose = NULL; } sectionDump(pComsec); } } if (configGetval(RC_VRB_VAL)) { /* Conditionally print each section notice in verbal mode */ szTmp = (char *)sectionGetname(ppSectmp[nTmp]); nBytes = (strlen(RC_PRN_TEXT) + strlen(szTmp) + 2) * sizeof (char); szVerbose = malloc(nBytes); sprintf(szVerbose, RC_PRN_TEXT, szTmp, sectionGetparent(ppSectmp[nTmp])); strcat(szVerbose, "\n"); fprintf(stderr, "%s", szVerbose); free(szVerbose); szVerbose = NULL; } sectionDump(ppSectmp[nTmp]); } } free(ppSectmp); ppSectmp = NULL; return(RC_THROW(RC_OK)); } /************************************************ * procParse(rc_proc_t *) * * Parse the run-command script * ************************************************/ rc_return_t procParse(rc_proc_t *pRc) { rc_section_t **ppSectmp = NULL; /* Used with priority scheduling */ int nTmp = 0; /* Generic index */ short nRcs = 0; /* Rc index */ short nSecs = 0; /* Section index */ short nTotalsecs = vectorCount(configGetsecs()); /* Sections */ /* Allocate a block of section pointers to use as a temporary */ ppSectmp = calloc(pRc->m_pList->m_nFiles, sizeof(rc_section_t *)); fprintf(stderr, "file %s, section %s\n", pRc->m_pList->m_ppFilevec[nRcs]->m_szName, RC_DEF_NCF); for (nSecs = 0; nSecs < nTotalsecs; nSecs++) { for (nRcs = 0; nRcs < pRc->m_pList->m_nFiles; nRcs++) { for (nTmp = 0; nTmp < pRc->m_pList->m_ppFilevec[nRcs]->m_nSecs && \ strcmp(pRc->m_pList->m_ppFilevec[nRcs]->m_ppSecvec[nTmp]->m_szName, \ configGetsecs()[nSecs]); nTmp++); if (nTmp < pRc->m_pList->m_ppFilevec[nRcs]->m_nSecs) ppSectmp[nRcs] = pRc->m_pList->m_ppFilevec[nRcs]->m_ppSecvec[nTmp]; else ppSectmp[nRcs] = NULL; } qsort((void *)ppSectmp, (size_t)pRc->m_pList->m_nFiles, sizeof(rc_section_t *), priCompare); for (nTmp = 0; nTmp < pRc->m_pList->m_nFiles && ppSectmp[nTmp]; nTmp++) fprintf(stderr, "section %s\n", ppSectmp[nTmp]->m_szName); } free(ppSectmp); ppSectmp = NULL; return(RC_THROW(RC_OK)); } /************************************************ * procDelete(rc_proc_t *) * * Destruct a processor * ************************************************/ rc_return_t procDelete(rc_proc_t *pRc) { int nRcs = pRc->m_pList->m_nFiles; scriptDelete(pRc->m_pScriptcnf); /* Destroy the config script */ pRc->m_pScriptcnf = NULL; scriptDelete(pRc->m_pScriptfunc); /* Destroy the funcs script */ pRc->m_pScriptfunc = NULL; /* Destroy the rcfile objects */ while (nRcs-- > 0) if (rcfileExists(pRc->m_pList->m_ppFilevec[nRcs])) { rcfileDelete(pRc->m_pList->m_ppFilevec[nRcs]); pRc->m_pList->m_ppFilevec[nRcs] = NULL; } free(pRc->m_pList->m_ppFilevec); pRc->m_pList->m_ppFilevec = NULL; listDelete(pRc->m_pList); /* Destroy the rcfile list */ pRc->m_pList = NULL; free(pRc); /* Free the processor itself */ pRc = NULL; return(RC_THROW(RC_OK)); } @ 1.60 log @More header corrections and improvements. @ text @d94 1 a94 1 scriptnAppend(pRc->m_pScriptfunc, "\n", sizeof("\n")); d136 2 a137 1 /* Attach our rcfile in the list */ d160 4 @ 1.59 log @Correct and update copyrights and source headers. @ text @d1 1 a1 1 /* OSSP rc - Run-command processor d6 1 a6 1 ** This file is part of OSSP rc, a portable Run-command processor d27 1 a27 1 ** rc_proc.c: Run-command processor ISO C source file @ 1.58 log @Processor separation, removing logic from generic procRun method and implementing procEval, procExec, procPrint, and procParse methods. @ text @d2 3 a4 3 ** Copyright (c) 2002 Ralf S. Engelschall ** Copyright (c) 2002 Cable & Wireless Deutschland GmbH ** Copyright (c) 2002 The OSSP Project @ 1.57 log @Bugfix eval mode config handling logic, and implement eval mode common handling logic. @ text @d150 21 d172 2 a173 2 * procRun(rc_proc_t *) * * Run the processed run-command script * d175 1 a175 1 rc_return_t procRun(rc_proc_t *pRc) d177 46 a222 47 int nTmp = 0; /* Generic index */ size_t nBytes = 0; /* Size in bytes */ int nTmpname = 0; /* Temp file name size */ int nRcs = 0; /* Rc index */ int nSecs = 0; /* Section index */ int nSectuid = -1; /* The section's user id */ int nRunuid = -1; /* The current user id */ pid_t Pidexec = -1; /* When spawning before execv(3) */ char *szTmpfile = NULL; /* Path of temporary file */ char *szTmp = NULL; /* Generic temporary string */ char *szFunc = NULL; /* Stores func script text */ char *szCnf = NULL; /* Stores config script text */ char *szExec = NULL; /* Used only during exec mode */ char *szVerbose = NULL; /* Used when handling verbose mode */ char *pszVec[RC_EXEC_MAXARGS]; /* For passing in to execv(3) */ rc_script_t *pFatscript = NULL; /* To build a comprehensive script */ rc_section_t **ppSectmp = NULL; /* Used with priority scheduling */ short nTotalsecs = vectorCount(configGetsecs()); /* Sections */ /****************************************************/ /* 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 */ /* Allocate a block of section pointers to use temporarily */ ppSectmp = calloc(pRc->m_pList->m_nFiles, sizeof(rc_section_t *)); pFatscript = scriptNew(); scriptnAppend(pFatscript, RC_BANG_STR, strlen(RC_BANG_STR)); /* Shebang */ /* Conditionally output initial notice in verbal mode */ if (configGetval(RC_VRB_VAL)) { szVerbose = malloc((strlen(RC_VST_TEXT) + 2) * sizeof (char)); sprintf(szVerbose, "%s", RC_VST_TEXT); strcat(szVerbose, "\n"); scriptnAppend(pFatscript, szVerbose, strlen(szVerbose)); free(szVerbose); szVerbose = NULL; } /* Conditionally print funcs section notice in verbal mode */ if (configGetval(RC_VRB_VAL)) { szVerbose = malloc((strlen(RC_EVF_TEXT) + 2) * sizeof (char)); sprintf(szVerbose, "%s", RC_EVF_TEXT); strcat(szVerbose, "\n"); scriptnAppend(pFatscript, szVerbose, strlen(szVerbose)); free(szVerbose); szVerbose = NULL; d224 13 a236 10 scriptAdd(pFatscript, pRc->m_pScriptfunc); for (nSecs = 0; nSecs < nTotalsecs; nSecs++) { for (nRcs = 0; nRcs < pRc->m_pList->m_nFiles; nRcs++) { for (nTmp = 0; nTmp < pRc->m_pList->m_ppFilevec[nRcs]->m_nSecs && \ strcmp(pRc->m_pList->m_ppFilevec[nRcs]->m_ppSecvec[nTmp]->m_szName, \ configGetsecs()[nSecs]); nTmp++); if (nTmp < pRc->m_pList->m_ppFilevec[nRcs]->m_nSecs) ppSectmp[nRcs] = pRc->m_pList->m_ppFilevec[nRcs]->m_ppSecvec[nTmp]; else ppSectmp[nRcs] = NULL; d238 1 a238 15 qsort((void *)ppSectmp, (size_t)pRc->m_pList->m_nFiles, \ sizeof(rc_section_t *), priCompare); for (nTmp = 0; nTmp < pRc->m_pList->m_nFiles && ppSectmp[nTmp]; nTmp++) { if (configGetval(RC_VRB_VAL)) { /* Conditionally evaluate config section notice in verbal mode */ nBytes = (strlen(RC_EVN_TEXT) + strlen(RC_DEF_NCF) + \ strlen(sectionGetparent(ppSectmp[nTmp])) + 2) * sizeof (char); szVerbose = malloc(nBytes); sprintf(szVerbose, RC_EVN_TEXT, RC_DEF_NCF, sectionGetparent(ppSectmp[nTmp])); strcat(szVerbose, "\n"); scriptnAppend(pFatscript, szVerbose, strlen(szVerbose)); free(szVerbose); szVerbose = NULL; } scriptAdd(pFatscript, pRc->m_pScriptcnf); d240 19 a258 21 /* Examine our list, and try to take the corresponding */ /* common section data from it to add to your script */ { rc_section_t *pComsec = NULL; pComsec = rcfileGetsec(listGetrcfile(pRc->m_pList, \ ppSectmp[nTmp]->m_szParent), configGetval(RC_CMN_VAL)); if (pComsec) { /* Do we have a common section to load? */ if (configGetval(RC_VRB_VAL)) { szTmp = (char *)sectionGetname(pComsec); nBytes = (strlen(RC_EVN_TEXT) + strlen(szTmp) + \ strlen (sectionGetparent(pComsec)) + \ strlen(RC_ECHO_STR) + strlen("\"\"") + 1) * \ sizeof (char); szVerbose = malloc(nBytes); sprintf(szVerbose, RC_EVN_TEXT, szTmp, sectionGetparent(pComsec)); strcat(szVerbose, "\n"); scriptnAppend(pFatscript, szVerbose, strlen(szVerbose)); free(szVerbose); szVerbose = NULL; } scriptAdd(pFatscript, sectionGetscript(pComsec)); d260 1 d262 1 d264 14 a277 19 /* Conditionally print each section notice in verbal mode */ if (configGetval(RC_VRB_VAL)) { szTmp = (char *)sectionGetname(ppSectmp[nTmp]); nBytes = (strlen(RC_EVN_TEXT) + strlen(szTmp) + 2) * sizeof (char); szVerbose = malloc(nBytes); sprintf(szVerbose, RC_EVN_TEXT, szTmp, sectionGetparent(ppSectmp[nTmp])); strcat(szVerbose, "\n"); scriptnAppend(pFatscript, szVerbose, strlen(szVerbose)); free(szVerbose); szVerbose = NULL; } if ((szTmp = (char *)sectionGetlogin(ppSectmp[nTmp])) != NULL) { scriptnAppend(pFatscript, "#su ", strlen("#su ")); scriptnAppend(pFatscript, szTmp, strlen(szTmp)); } else scriptnAppend(pFatscript, "#exit ", strlen("#exit ")); scriptnAppend(pFatscript, "\n", strlen("\n")); scriptAdd(pFatscript, sectionGetscript(ppSectmp[nTmp])); d279 4 d284 29 a312 2 free(ppSectmp); ppSectmp = NULL; d314 2 a315 28 szTmpfile = (char *)configGetval(RC_TMP_VAL); nTmpname = (strlen(szTmpfile) + strlen(RC_EVL_TMP) + \ strlen(RC_EVL_SUF) + 1) * sizeof(char); if (*(szTmpfile + (strlen(szTmpfile) - 1) * sizeof(char)) != '/') nTmpname += sizeof(char); szTmpfile = malloc(nTmpname); strcpy(szTmpfile, configGetval(RC_TMP_VAL)); if (*(szTmpfile + (strlen(szTmpfile) - 1) * sizeof(char)) != '/') strcat(szTmpfile, "/"); strcat(szTmpfile, RC_EVL_TMP); mktemp(szTmpfile); strcat(szTmpfile, RC_EVL_SUF); scriptWrite(pFatscript, szTmpfile); /* Write the whole script out */ /* Conditionally don't remove the temp file (see constants) */ if (configGetval(RC_DBG_VAL)) fprintf(stdout, RC_EVL_DBG, szTmpfile); else fprintf(stdout, RC_EVL_OUT, szTmpfile, szTmpfile); /* Cleanup eval processing crap */ free(szTmpfile); szTmpfile = NULL; scriptDelete(pFatscript); pFatscript = NULL; } else if (configGetval(RC_EXC_VAL)) { /* Execute */ int nStat; /* Used for reporting status on return of a forked child */ d317 37 a353 14 /* This block does nothing more than implement the feature, */ /* that allows rc to run unprivileged (as long as no privileged */ /* code is used in the script sections to be executed */ for (nSecs = 0; nSecs < nTotalsecs; nSecs++) { for (nTmp = 0; nTmp < pRc->m_pList->m_nFiles; nTmp++) { if (pRc->m_pList->m_ppFilevec[nTmp]->m_ppSecvec && \ pRc->m_pList->m_ppFilevec[nTmp]->m_ppSecvec[nSecs]) { nRunuid = getuid(); nSectuid = pRc->m_pList->m_ppFilevec[nTmp]->m_ppSecvec[nSecs]->m_nUid; /* See if root user status is needed, and bail out if so */ if (nRunuid != 0 && nSectuid != -1 && nRunuid != nSectuid) { fprintf(stderr, RC_RUT_TEXT); return(RC_THROW(RC_ERR_USE)); } d357 50 a406 49 /* Allocate a block of section pointers to use temporarily */ ppSectmp = calloc(pRc->m_pList->m_nFiles, sizeof(rc_section_t *)); szFunc = (char *)scriptGetdata(pRc->m_pScriptfunc); szCnf = (char *)scriptGetdata(pRc->m_pScriptcnf); for (nSecs = 0; nSecs < nTotalsecs; nSecs++) { for (nRcs = 0; nRcs < pRc->m_pList->m_nFiles; nRcs++) { for (nTmp = 0; nTmp < pRc->m_pList->m_ppFilevec[nRcs]->m_nSecs && \ strcmp(pRc->m_pList->m_ppFilevec[nRcs]->m_ppSecvec[nTmp]->m_szName, \ configGetsecs()[nSecs]); nTmp++); if (nTmp < pRc->m_pList->m_ppFilevec[nRcs]->m_nSecs) ppSectmp[nRcs] = pRc->m_pList->m_ppFilevec[nRcs]->m_ppSecvec[nTmp]; else ppSectmp[nRcs] = NULL; } qsort((void *)ppSectmp, (size_t)pRc->m_pList->m_nFiles, sizeof(rc_section_t *), priCompare); pszVec[0] = "/bin/sh"; /* Run the bourne shell over the following */ pszVec[1] = "-c"; /* Append script code of the sections */ pszVec[3] = NULL; /* Add a NULL to mark the end of the chain */ nTmp = 0; /* Count from zero until however many sections we have */ while (nTmp < pRc->m_pList->m_nFiles && ppSectmp[nTmp]) { /* Conditionally print config and other section notices in verbal mode */ if (configGetval(RC_VRB_VAL)) { /* Verbose mode is active */ size_t nSizverb = 0; size_t nPrescr = 0; size_t nSecverb = 0; size_t nSection = 0; /* Allocate space just for string to prepare for verbose */ nSizverb = (strlen(RC_EXN_TEXT) + strlen(RC_DEF_NCF) + \ strlen(sectionGetparent(ppSectmp[nTmp])) + strlen(RC_ECHO_STR) + \ strlen("\"\"") + 1) * sizeof (char); szVerbose = malloc(nSizverb); sprintf(szVerbose, RC_EXN_TEXT, RC_DEF_NCF, sectionGetparent(ppSectmp[nTmp])); /* Allocate space for entire string to execvp(3) */ nPrescr = (strlen(RC_VST_TEXT) + strlen(RC_EXF_TEXT) + \ strlen(szVerbose) + strlen(szFunc) + strlen(szCnf) + \ strlen(RC_BANG_STR) + 1) * sizeof (char); szExec = malloc(nSizverb + nPrescr); strcpy(szExec, RC_BANG_STR); /* Start out with the bang string */ strcat(szExec, RC_ECHO_STR); /* Continue with the echo string */ strcat(szExec, "\""); /* Append a quote next to the echo */ strcat(szExec, RC_VST_TEXT); /* Continue with the start text */ if (strlen(szFunc) > 0) { strcat(szExec, "\n"); /* Stick a newline inbetween */ strcat(szExec, RC_EXF_TEXT); /* Continue with the func text */ } d408 7 a414 31 strcat(szExec, "\";"); /* Finalize the verbosity notice */ strcat(szExec, szFunc); /* Continue with the funcs script code */ strcat(szExec, RC_ECHO_STR); /* Continue with the echo string */ strcat(szExec, "\""); /* Append a quote next to the echo */ strcat(szExec, szVerbose); /* Continue with the config text */ strcat(szExec, "\";"); /* Finalize the verbosity notice */ strcat(szExec, szCnf); /* Then with the config script code */ /* Examine our list, and try to take the corresponding */ /* common section data from it to add to your script */ { rc_section_t *pComsec = NULL; pComsec = rcfileGetsec(listGetrcfile(pRc->m_pList, \ ppSectmp[nTmp]->m_szParent), configGetval(RC_CMN_VAL)); if (pComsec) { /* If we have a common section to load, */ szTmp = (char *)sectionGetname(pComsec); nSecverb = (strlen(RC_EXN_TEXT) + strlen(szTmp) + \ strlen (sectionGetparent(pComsec)) + \ strlen(RC_ECHO_STR) + strlen("\"\"") + 1) * \ sizeof (char); realloc(szVerbose, nSecverb); sprintf(szVerbose, RC_EXN_TEXT, szTmp, sectionGetparent(pComsec)); nSection = (strlen(szTmp) + 1) * sizeof (char); realloc(szExec, nSizverb + nPrescr + nSecverb + nSection); strcat(szExec, RC_ECHO_STR); /* Start out with the echo string */ strcat(szExec, "\""); /* Append a quote next to the echo */ strcat(szExec, szVerbose); /* Continue with the common text */ strcat(szExec, "\";"); /* Finalize the verbosity notice */ strcat(szExec, sectionGetdata(pComsec)); /* load it */ } } d416 21 a436 41 /* Build last set of verbose data for the actual script */ szTmp = (char *)sectionGetname(ppSectmp[nTmp]); nSecverb = (strlen(RC_EXN_TEXT) + strlen(szTmp) * 2 \ + strlen(RC_ECHO_STR) + strlen("\"\"") + 1) * sizeof (char); realloc(szVerbose, nSecverb); sprintf(szVerbose, RC_EXN_TEXT, szTmp, sectionGetparent(ppSectmp[nTmp])); nSection = (strlen(szTmp) + strlen(sectionGetdata(ppSectmp[nTmp])) + 1) * sizeof (char); realloc(szExec, nSizverb + nPrescr + nSecverb + nSection); szTmp = (char *)sectionGetdata(ppSectmp[nTmp]); strcat(szExec, RC_ECHO_STR); /* Start out with the echo string */ strcat(szExec, "\""); /* Append a quote next to the echo */ strcat(szExec, szVerbose); /* Continue with the verboseity text */ strcat(szExec, "\";"); /* Finalize the verbosity notice */ strcat(szExec, szTmp); /* Then with the new script code */ pszVec[2] = szExec; /* Launch the new process image now */ free(szVerbose); szVerbose = NULL; /* Spawn the section shell code */ switch (Pidexec = fork()) { case -1: /* Broken */ return(RC_THROW(RC_ERR_INT)); break; /* Huh? */ case 0: /* Child, runs script code through bourne shell */ nSectuid = sectionGetuid(ppSectmp[nTmp]); if (nSectuid >= 0 && getuid() != nSectuid) if (setuid(nSectuid) != 0) return(RC_THROW(RC_ERR_ROOT)); if (execvp(*pszVec, pszVec) == -1) return(RC_THROW(RC_ERR_INT)); break; default: /* Parent, blocks until child returns */ waitpid(Pidexec, &nStat, WUNTRACED); if ((nStat = WEXITSTATUS(nStat)) != 0) return(nStat); break; } if (szExec) { free(szExec); /* Cleanup after exec */ szExec = NULL; a438 17 else { /* Verbose mode is off */ szTmp = (char *)sectionGetdata(ppSectmp[nTmp]); szExec = malloc((strlen(szFunc) + strlen(szCnf) + \ strlen(szTmp) + 1) * sizeof(char)); strcpy(szExec, RC_BANG_STR); /* Start out with the shebang string */ strcat(szExec, szFunc); /* Continue with just the funcs script code */ strcat(szExec, szCnf); /* Continue with just the config script code */ /* Examine our list, and try to take the corresponding */ /* common section data from it to add to your script */ { rc_section_t *pComsec = NULL; pComsec = rcfileGetsec(listGetrcfile(pRc->m_pList, \ ppSectmp[nTmp]->m_szParent), configGetval(RC_CMN_VAL)); if (pComsec) /* If we have a common section to load, */ strcat(szExec, sectionGetdata(pComsec)); /* load it */ } d440 30 a469 6 strcat(szExec, szTmp); /* And build a section onto the command chain */ pszVec[2] = szExec; /* Actually launch the new process image now */ /* Spawn the section shell code */ switch (Pidexec = fork()){ case -1: /* Broken */ d471 8 a478 15 break; /* Huh? */ case 0: /* Child, runs script code through bourne shell */ nSectuid = sectionGetuid(ppSectmp[nTmp]); if (nSectuid >= 0 && getuid() != nSectuid) if (setuid(nSectuid) != 0) return(RC_THROW(RC_ERR_ROOT)); if (execvp(*pszVec, pszVec) == -1) return(RC_THROW(RC_ERR_INT)); break; default: /* Parent, blocks until child returns */ waitpid(Pidexec, &nStat, WUNTRACED); if ((nStat = WEXITSTATUS(nStat)) != 0) return(nStat); break; } a481 27 nTmp++; /* Next rc script */ } } free(ppSectmp); ppSectmp = NULL; } else if (configGetval(RC_PRN_VAL)) { /* Print */ /* Allocate a block of section pointers to use as a temporary */ ppSectmp = calloc(pRc->m_pList->m_nFiles, sizeof(rc_section_t *)); /* Conditionally output initial notice in verbal mode */ if (configGetval(RC_VRB_VAL)) fprintf(stderr, "%s\n", RC_VST_TEXT); /* Conditionally print funcs section notice in verbal mode */ if (configGetval(RC_VRB_VAL)) fprintf(stderr, "%s\n", RC_PNF_TEXT); scriptDump(pRc->m_pScriptfunc); /* Dump the funcs script */ for (nSecs = 0; nSecs < nTotalsecs; nSecs++) { for (nRcs = 0; nRcs < pRc->m_pList->m_nFiles; nRcs++) { for (nTmp = 0; nTmp < pRc->m_pList->m_ppFilevec[nRcs]->m_nSecs && \ strcmp(pRc->m_pList->m_ppFilevec[nRcs]->m_ppSecvec[nTmp]->m_szName, \ configGetsecs()[nSecs]); nTmp++); if (nTmp < pRc->m_pList->m_ppFilevec[nRcs]->m_nSecs) ppSectmp[nRcs] = pRc->m_pList->m_ppFilevec[nRcs]->m_ppSecvec[nTmp]; else ppSectmp[nRcs] = NULL; d483 7 a489 14 qsort((void *)ppSectmp, (size_t)pRc->m_pList->m_nFiles, sizeof(rc_section_t *), priCompare); for (nTmp = 0; nTmp < pRc->m_pList->m_nFiles && ppSectmp[nTmp]; nTmp++) { if (configGetval(RC_VRB_VAL)) { /* Conditionally print config section notice in verbal mode */ nBytes = (strlen(RC_PRN_TEXT) + strlen(RC_DEF_NCF) + \ strlen(sectionGetparent(ppSectmp[nTmp])) + 2) * sizeof (char); szVerbose = malloc(nBytes); sprintf(szVerbose, RC_PRN_TEXT, RC_DEF_NCF, sectionGetparent(ppSectmp[nTmp])); strcat(szVerbose, "\n"); fprintf(stderr, szVerbose); free(szVerbose); szVerbose = NULL; } scriptDump(pRc->m_pScriptcnf); /* Dump the config script */ d497 2 a498 16 if (pComsec) { /* Do we have a common section to load? */ if (configGetval(RC_VRB_VAL)) { szTmp = (char *)sectionGetname(pComsec); nBytes = (strlen(RC_PRN_TEXT) + strlen(szTmp) + \ strlen (sectionGetparent(pComsec)) + \ strlen(RC_ECHO_STR) + strlen("\"\"") + 1) * \ sizeof (char); szVerbose = malloc(nBytes); sprintf(szVerbose, RC_PRN_TEXT, szTmp, sectionGetparent(pComsec)); strcat(szVerbose, "\n"); fprintf(stderr, "%s", szVerbose); free(szVerbose); szVerbose = NULL; } sectionDump(pComsec); } d501 21 a521 10 if (configGetval(RC_VRB_VAL)) { /* Conditionally print each section notice in verbal mode */ szTmp = (char *)sectionGetname(ppSectmp[nTmp]); nBytes = (strlen(RC_PRN_TEXT) + strlen(szTmp) + 2) * sizeof (char); szVerbose = malloc(nBytes); sprintf(szVerbose, RC_PRN_TEXT, szTmp, sectionGetparent(ppSectmp[nTmp])); strcat(szVerbose, "\n"); fprintf(stderr, "%s", szVerbose); free(szVerbose); szVerbose = NULL; d523 2 a524 1 sectionDump(ppSectmp[nTmp]); d526 1 a527 2 free(ppSectmp); ppSectmp = NULL; d529 55 a583 13 else if (configGetval(RC_PAR_VAL)) { /* Parse names */ /* Allocate a block of section pointers to use as a temporary */ ppSectmp = calloc(pRc->m_pList->m_nFiles, sizeof(rc_section_t *)); fprintf(stderr, "file %s, section %s\n", pRc->m_pList->m_ppFilevec[nRcs]->m_szName, RC_DEF_NCF); for (nSecs = 0; nSecs < nTotalsecs; nSecs++) { for (nRcs = 0; nRcs < pRc->m_pList->m_nFiles; nRcs++) { for (nTmp = 0; nTmp < pRc->m_pList->m_ppFilevec[nRcs]->m_nSecs && \ strcmp(pRc->m_pList->m_ppFilevec[nRcs]->m_ppSecvec[nTmp]->m_szName, \ configGetsecs()[nSecs]); nTmp++); if (nTmp < pRc->m_pList->m_ppFilevec[nRcs]->m_nSecs) ppSectmp[nRcs] = pRc->m_pList->m_ppFilevec[nRcs]->m_ppSecvec[nTmp]; else ppSectmp[nRcs] = NULL; d585 70 a654 3 qsort((void *)ppSectmp, (size_t)pRc->m_pList->m_nFiles, sizeof(rc_section_t *), priCompare); for (nTmp = 0; nTmp < pRc->m_pList->m_nFiles && ppSectmp[nTmp]; nTmp++) fprintf(stderr, "section %s\n", ppSectmp[nTmp]->m_szName); d656 3 a658 2 free(ppSectmp); ppSectmp = NULL; d660 2 a661 2 else /* Something is wrong here */ return(RC_THROW(RC_ERR_INT)); @ 1.56 log @Repair and improve config section handling in eval run mode. @ text @a217 1 /* Conditionally print config section notice in verbal mode */ d219 2 a220 2 /* Conditionally print config section notice in verbal mode */ nBytes = (strlen(RC_PRN_TEXT) + strlen(RC_DEF_NCF) + \ d223 1 a223 1 sprintf(szVerbose, RC_PRN_TEXT, RC_DEF_NCF, sectionGetparent(ppSectmp[nTmp])); d231 24 d545 1 a545 1 nBytes = (strlen(RC_EXN_TEXT) + strlen(szTmp) + \ d556 1 a556 1 sectionDump(pComsec); @ 1.55 log @Implement common section handling in print run mode. @ text @a204 11 /* Conditionally print config section notice in verbal mode */ if (configGetval(RC_VRB_VAL)) { nBytes = (strlen(RC_EVN_TEXT) + strlen(RC_DEF_NCF) * 2 + 2) * sizeof (char); szVerbose = malloc(nBytes); sprintf(szVerbose, RC_EVN_TEXT, RC_DEF_NCF, RC_DEF_NCF); strcat(szVerbose, "\n"); scriptnAppend(pFatscript, szVerbose, strlen(szVerbose)); free(szVerbose); szVerbose = NULL; } scriptAdd(pFatscript, pRc->m_pScriptcnf); d218 14 a245 1 scriptnAppend(pFatscript, "\n", strlen("\n")); d247 3 @ 1.54 log @Repaired print run mode before adding %common logic. @ text @d363 4 a366 2 nSecverb = (strlen(RC_EXN_TEXT) + strlen(szTmp) * 2 \ + strlen(RC_ECHO_STR) + strlen("\"\"") + 1) * sizeof (char); d507 24 @ 1.53 log @Add RC_ERR_ROOT error, and improve error handling during forked child op failures. @ text @a170 1 rc_script_t *pBangscript = NULL; /* Common script with the shebang */ d325 3 a327 2 nSizverb = (strlen(RC_EXN_TEXT) + strlen(RC_DEF_NCF) * 2 \ + strlen(RC_ECHO_STR) + strlen("\"\"") + 1) * sizeof (char); a471 4 pBangscript = scriptNew(); scriptnAppend(pBangscript, RC_BANG_STR, strlen(RC_BANG_STR)); scriptDump(pBangscript); /* Dump the shebang */ scriptDelete(pBangscript); a479 11 /* Conditionally print config section notice in verbal mode */ if (configGetval(RC_VRB_VAL)) { nBytes = (strlen(RC_PRN_TEXT) + strlen(RC_DEF_NCF) * 2 + 2) * sizeof (char); szVerbose = malloc(nBytes); sprintf(szVerbose, RC_PRN_TEXT, RC_DEF_NCF, RC_DEF_NCF); strcat(szVerbose, "\n"); fprintf(stderr, szVerbose); free(szVerbose); szVerbose = NULL; } scriptDump(pRc->m_pScriptcnf); /* Dump the config script */ a492 1 /* Conditionally print each section notice in verbal mode */ d494 14 d509 1 a509 1 nBytes = (strlen(RC_PRN_TEXT) + strlen(szTmp) + 1) * sizeof (char); d512 1 @ 1.52 log @Fix some verbose mode print run definitions, and fix error handling by using correct value 0 for RC_OK. @ text @d279 2 d397 1 a397 1 switch (Pidexec = fork()){ d405 1 a405 1 return(RC_THROW(RC_ERR_INT)); d410 3 a412 1 waitpid(Pidexec, NULL, WUNTRACED); d450 1 a450 1 return(RC_THROW(RC_ERR_INT)); d455 3 a457 1 waitpid(Pidexec, NULL, WUNTRACED); @ 1.51 log @Replace references to scriptAppend with scriptAdd, and change name of scriptAppend to scriptnAppend to avoid surprises. Also, debug minimal memory overallocation in scriptnAppend. @ text @d476 1 a476 1 fprintf(stderr, "%s\n", RC_EVF_TEXT); d480 1 a480 1 nBytes = (strlen(RC_EVN_TEXT) + strlen(RC_DEF_NCF) * 2 + 2) * sizeof (char); d482 1 a482 1 sprintf(szVerbose, RC_EVN_TEXT, RC_DEF_NCF, RC_DEF_NCF); @ 1.50 log @Implement common section parsing and running on execution mode. @ text @d91 1 a91 1 scriptAppend(pRc->m_pScriptfunc, sBuf, nRet); d94 1 a94 1 scriptAppend(pRc->m_pScriptfunc, "\n", sizeof("\n")); d113 2 a114 2 scriptAppend(pRc->m_pScriptcnf, sectionGetdata(pSec), strlen(sectionGetdata(pSec))); scriptAppend(pRc->m_pScriptcnf, "\n", strlen ("\n")); d186 1 a186 1 scriptAppend(pFatscript, RC_BANG_STR, strlen(RC_BANG_STR)); /* Shebang */ d192 1 a192 1 scriptAppend(pFatscript, szVerbose, strlen(szVerbose)); d201 1 a201 1 scriptAppend(pFatscript, szVerbose, strlen(szVerbose)); d212 1 a212 1 scriptAppend(pFatscript, szVerbose, strlen(szVerbose)); d237 1 a237 1 scriptAppend(pFatscript, szVerbose, strlen(szVerbose)); d242 3 a244 3 scriptAppend(pFatscript, "#su ", strlen("#su ")); scriptAppend(pFatscript, szTmp, strlen(szTmp)); scriptAppend(pFatscript, "\n", strlen("\n") + 1); d246 1 a246 2 szTmp = (char *)sectionGetdata(ppSectmp[nTmp]); scriptAppend(pFatscript, szTmp, strlen(szTmp) + 1); d467 1 a467 1 scriptAppend(pBangscript, RC_BANG_STR, (strlen(RC_BANG_STR) + 1) * sizeof (char)); @ 1.49 log @Fix a deallocation name bug, and change common-related names to config to avoid similar problems. @ text @d208 1 a208 1 nBytes = (strlen(RC_EVN_TEXT) + strlen(RC_CFG_TEXT) * 2 + 2) * sizeof (char); d210 1 a210 1 sprintf(szVerbose, RC_EVN_TEXT, RC_CFG_TEXT, RC_CFG_TEXT); d235 1 a235 1 sprintf(szVerbose, RC_EVN_TEXT, szTmp, szTmp); d325 1 a325 1 nSizverb = (strlen(RC_EXN_TEXT) + strlen(RC_CFG_TEXT) * 2 \ d328 1 a328 1 sprintf(szVerbose, RC_EXN_TEXT, RC_CFG_TEXT, RC_CFG_TEXT); d340 6 a345 2 strcat(szExec, "\n"); /* Stick a newline inbetween */ strcat(szExec, RC_EXF_TEXT); /* Continue with the func text */ d353 24 d381 4 a384 1 sprintf(szVerbose, RC_EXN_TEXT, szTmp, szTmp); a385 2 nSection = (strlen(szTmp) + 1) * sizeof (char); realloc(szExec, nSizverb + nPrescr + nSecverb + nSection); d424 11 d481 1 a481 1 nBytes = (strlen(RC_EVN_TEXT) + strlen(RC_CFG_TEXT) * 2 + 2) * sizeof (char); d483 1 a483 1 sprintf(szVerbose, RC_EVN_TEXT, RC_CFG_TEXT, RC_CFG_TEXT); d508 1 a508 1 sprintf(szVerbose, RC_PRN_TEXT, szTmp, szTmp); d522 1 a522 1 fprintf(stderr, "file %s, section %s\n", pRc->m_pList->m_ppFilevec[nRcs]->m_szName, RC_CFG_TEXT); @ 1.48 log @Break off before fully implementing common section run ops, but after reorganization of class data, and additional member functions for section and script manipulation. @ text @d56 1 a56 1 pNewrc->m_pScriptcom = scriptNew(); /* Construct a common script */ d113 2 a114 2 scriptAppend(pRc->m_pScriptcom, sectionGetdata(pSec), strlen(sectionGetdata(pSec))); scriptAppend(pRc->m_pScriptcom, "\n", strlen ("\n")); d167 1 a167 1 char *szCom = NULL; /* Stores common script text */ d206 1 a206 1 /* Conditionally print common section notice in verbal mode */ d216 1 a216 1 scriptAdd(pFatscript, pRc->m_pScriptcom); d300 1 a300 1 szCom = (char *)scriptGetdata(pRc->m_pScriptcom); d317 1 a317 1 /* Conditionally print common and other section notices in verbal mode */ d332 1 a332 1 strlen(szVerbose) + strlen(szFunc) + strlen(szCom) + \ d346 1 a346 1 strcat(szExec, szVerbose); /* Continue with the common text */ d348 1 a348 1 strcat(szExec, szCom); /* Then with the common script code */ d390 1 a390 1 szExec = malloc((strlen(szFunc) + strlen(szCom) + \ d394 1 a394 1 strcat(szExec, szCom); /* Continue with just the common script code */ d439 1 a439 1 /* Conditionally print common section notice in verbal mode */ d449 1 a449 1 scriptDump(pRc->m_pScriptcom); /* Dump the common script */ d514 2 a515 2 scriptDelete(pRc->m_pScriptcom); /* Destroy the common script */ pRc->m_pScriptcom = NULL; d517 1 a517 1 pRc->m_pScriptcom = NULL; @ 1.47 log @Do not remove eval mode temp files when the debugging option is active. @ text @a70 1 int nFdrc = -1; d77 1 a77 2 char *szLocex = NULL; rc_script_t *pTempscript = NULL; d79 1 d95 1 d107 2 a108 28 /* Build the location path name */ if (!configGetval(RC_LOC_VAL)) { szLocex = NULL; szLocex = 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)) != '/') { szLocex = malloc(strlen(configGetval(RC_LOC_VAL)) + \ sizeof (char) + \ strlen("rc.") + \ strlen(pRc->m_pList->m_ppFilevec[nRcs]->m_szName) + \ sizeof (char)); strcpy(szLocex, configGetval(RC_LOC_VAL)); strcat(szLocex, "/"); strcat(szLocex, "rc."); /* FIXME: Make the prefix configurable */ strcat(szLocex, pRc->m_pList->m_ppFilevec[nRcs]->m_szName); } else { szLocex = malloc(strlen(configGetval(RC_LOC_VAL)) + \ strlen("rc.") + \ strlen(pRc->m_pList->m_ppFilevec[nRcs]->m_szName) + \ sizeof (char)); strcpy(szLocex, configGetval(RC_LOC_VAL)); strcat(szLocex, "rc."); /* FIXME: Make the prefix configurable */ strcat(szLocex, pRc->m_pList->m_ppFilevec[nRcs]->m_szName); } } d110 2 a111 15 /* 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 common section if it exists */ pSec = scriptSection(pTempscript, configGetval(RC_NCF_VAL)); a114 2 sectionDelete(pSec); /* Cleanup */ pSec = NULL; /* Cleanup */ d119 7 a125 3 pSec = scriptSection(pTempscript, configGetsecs()[nSect]); if (pSec) /* Only copy if the section lookup succeeds */ d127 1 a130 5 if (pSec) { /* Cleanup iterative section string */ sectionDelete(pSec); pSec = NULL; } d136 3 a138 6 /* Clean up our crap */ scriptDelete(pTempscript); /* Temp script */ pTempscript = NULL; free(szLocex); /* Temp Location + Rcfile */ szLocex = NULL; close(nFdrc); /* Close Rc file handle */ a140 2 close(nFdfunc); /* Close Func file handle */ d205 1 a205 2 scriptAppend(pFatscript, scriptTostring(pRc->m_pScriptfunc), \ strlen(scriptTostring(pRc->m_pScriptfunc))); d208 1 a208 1 nBytes = (strlen(RC_EVN_TEXT) + strlen(RC_CMN_TEXT) * 2 + 2) * sizeof (char); d210 1 a210 1 sprintf(szVerbose, RC_EVN_TEXT, RC_CMN_TEXT, RC_CMN_TEXT); d216 1 a216 2 scriptAppend(pFatscript, scriptTostring(pRc->m_pScriptcom), \ strlen(scriptTostring(pRc->m_pScriptcom))); d299 2 a300 2 szFunc = (char *)scriptTostring(pRc->m_pScriptfunc); szCom = (char *)scriptTostring(pRc->m_pScriptcom); d318 1 a318 1 if (configGetval(RC_VRB_VAL)) { d325 1 a325 1 nSizverb = (strlen(RC_EXN_TEXT) + strlen(RC_CMN_TEXT) * 2 \ d328 1 a328 1 sprintf(szVerbose, RC_EXN_TEXT, RC_CMN_TEXT, RC_CMN_TEXT); d343 1 a343 1 strcat(szExec, szFunc); /* Continue with the common script code */ d348 1 a348 1 strcat(szExec, szCom); /* Then with the funcs script code */ d388 1 a388 1 else { d441 1 a441 1 nBytes = (strlen(RC_EVN_TEXT) + strlen(RC_CMN_TEXT) * 2 + 2) * sizeof (char); d443 1 a443 1 sprintf(szVerbose, RC_EVN_TEXT, RC_CMN_TEXT, RC_CMN_TEXT); d482 1 a482 1 fprintf(stderr, "file %s, section %s\n", pRc->m_pList->m_ppFilevec[nRcs]->m_szName, RC_CMN_TEXT); @ 1.46 log @Removed analyzer class, removed label class, implemented list class, implemented file class, cleanup and restructure. @ text @d314 8 a321 1 fprintf(stdout, RC_EVL_OUT, szTmpfile, szTmpfile); @ 1.45 log @Sweeping cleanups. Reduced the analyzer to almost nothing. Removed unused method prototypes. Added 'parse' mode option that doesn't work yet. Removed procReadtmp. Change the way we build path names from the locations directory. @ text @d53 4 a56 4 pNewrc->m_pAnal = analNew(); /* Construct a configuration analyser */ analRcs (pNewrc->m_pAnal, configGetrcfile()); /* Preprocess analysis */ pNewrc->m_pScriptcom = scriptNew(); /* Construct a run-command script */ pNewrc->m_ppLabvec = calloc(pNewrc->m_pAnal->m_nRcs, sizeof(rc_label_t *)); d74 1 a74 1 int nRc = 0; a77 1 rc_section_t *pSec = NULL; d80 1 d83 1 a83 1 assert(*pRc->m_pAnal->m_pszRcs); d88 1 a88 1 /* FIXME: Funcfile data does not belong in config section data! */ d92 1 a92 1 scriptAppend(pRc->m_pScriptcom, sBuf, nRet); d95 1 a95 1 scriptAppend(pRc->m_pScriptcom, "\n", sizeof(char)); d102 1 a102 1 for (nRc = 0; nRc < pRc->m_pAnal->m_nRcs; nRc++) d104 2 a105 4 assert(*pRc->m_pAnal->m_pszRcs); /* Construct a new label */ pRc->m_ppLabvec[nRc] = labelNew(pRc->m_pAnal->m_pszRcs[nRc]); d118 1 a118 1 strlen(pRc->m_pAnal->m_pszRcs[nRc]) + \ d123 1 a123 1 strcat(szLocex, pRc->m_pAnal->m_pszRcs[nRc]); d128 1 a128 1 strlen(pRc->m_pAnal->m_pszRcs[nRc]) + \ d132 1 a132 1 strcat(szLocex, pRc->m_pAnal->m_pszRcs[nRc]); d163 1 a163 1 labelAppendsec(pRc->m_ppLabvec[nRc], pSec); d166 1 a166 1 configGetsecs()[nSect], pRc->m_pAnal->m_pszRcs[nRc]); d212 1 d230 1 a230 1 ppSectmp = calloc(pRc->m_pAnal->m_nRcs, sizeof(rc_section_t *)); d233 20 d255 1 a255 1 nBytes = (strlen(RC_PRN_TEXT) + strlen(RC_CMN_TEXT) * 2 + 1) * sizeof (char); d257 2 a258 1 sprintf(szVerbose, RC_PRN_TEXT, RC_CMN_TEXT, RC_CMN_TEXT); d261 1 d266 6 a271 8 for (nRcs = 0; nRcs < pRc->m_pAnal->m_nRcs; nRcs++) { nTmp = 0; while (nTmp < pRc->m_ppLabvec[nRcs]->m_nSecs && \ strcmp(pRc->m_ppLabvec[nRcs]->m_ppSecvec[nTmp]->m_szName, \ configGetsecs()[nSecs])) nTmp++; if (nTmp < pRc->m_ppLabvec[nRcs]->m_nSecs) ppSectmp[nRcs] = pRc->m_ppLabvec[nRcs]->m_ppSecvec[nTmp]; d275 1 a275 1 qsort((void *)ppSectmp, (size_t)pRc->m_pAnal->m_nRcs, \ d277 1 a277 2 nTmp = 0; while (nTmp < pRc->m_pAnal->m_nRcs && ppSectmp[nTmp]) { d281 1 a281 1 nBytes = (strlen(RC_EVN_TEXT) + strlen(szTmp) + 1) * sizeof (char); d284 1 d287 1 a295 1 nTmp++; d325 3 a327 3 for (nTmp = 0; nTmp < pRc->m_pAnal->m_nRcs; nTmp++) { if (pRc->m_ppLabvec[nTmp]->m_ppSecvec && \ pRc->m_ppLabvec[nTmp]->m_ppSecvec[nSecs]) { d329 1 a329 1 nSectuid = pRc->m_ppLabvec[nTmp]->m_ppSecvec[nSecs]->m_nUid; d339 3 a341 2 ppSectmp = calloc(pRc->m_pAnal->m_nRcs, sizeof(rc_section_t *)); szCom = (char *)scriptTostring(pRc->m_pScriptcom); d343 6 a348 8 for (nRcs = 0; nRcs < pRc->m_pAnal->m_nRcs; nRcs++) { nTmp = 0; while (nTmp < pRc->m_ppLabvec[nRcs]->m_nSecs && \ strcmp(pRc->m_ppLabvec[nRcs]->m_ppSecvec[nTmp]->m_szName, \ configGetsecs()[nSecs])) nTmp++; if (nTmp < pRc->m_ppLabvec[nRcs]->m_nSecs) ppSectmp[nRcs] = pRc->m_ppLabvec[nRcs]->m_ppSecvec[nTmp]; d352 1 a352 1 qsort((void *)ppSectmp, (size_t)pRc->m_pAnal->m_nRcs, sizeof(rc_section_t *), priCompare); d357 1 a357 1 while (nTmp < pRc->m_pAnal->m_nRcs && ppSectmp[nTmp]) { d360 2 a361 2 size_t nComverb = 0; size_t nCommon = 0; d364 3 a366 1 nComverb = (strlen(RC_EXN_TEXT) + strlen(RC_CMN_TEXT) * 2 \ d368 1 a368 1 szVerbose = malloc(nComverb); d370 7 a376 2 nCommon = (strlen(szCom) + strlen(RC_BANG_STR) + 1) * sizeof (char); szExec = malloc(nComverb + nCommon); d380 10 a389 3 strcat(szExec, szVerbose); /* Continue with the verboseity text */ strcat(szExec, "\""); /* Finalize the verbosity notice */ strcat(szExec, szCom); /* Then with the common script code */ d397 1 a397 1 realloc(szExec, nComverb + nCommon + nSecverb + nSection); d401 1 a401 1 strcat(szExec, "\""); /* Finalize the verbosity notice */ d431 7 a437 5 szExec = malloc((strlen(szCom) + strlen(szTmp) + 1) * sizeof(char)); strcpy(szExec, RC_BANG_STR); /* Start out with the shebang string */ strcat(szExec, szCom); /* Continue with just the common script code */ strcat(szExec, szTmp); /* And build a section onto the command chain */ pszVec[2] = szExec; /* Actually launch the new process image now */ d467 1 a467 1 ppSectmp = calloc(pRc->m_pAnal->m_nRcs, sizeof(rc_section_t *)); d470 10 d482 1 a482 1 nBytes = (strlen(RC_PRN_TEXT) + strlen(RC_CMN_TEXT) * 2 + 1) * sizeof (char); d484 3 a486 2 sprintf(szVerbose, RC_PRN_TEXT, RC_CMN_TEXT, RC_CMN_TEXT); scriptAppend(pBangscript, szVerbose, (strlen(szVerbose) + 1) * sizeof (char)); d488 1 d490 2 a491 3 scriptDump(pBangscript); /* Dump the common script with shebang */ scriptDump(pRc->m_pScriptcom); /* Dump the rest of the common script */ scriptDelete(pBangscript); d493 6 a498 8 for (nRcs = 0; nRcs < pRc->m_pAnal->m_nRcs; nRcs++) { nTmp = 0; while (nTmp < pRc->m_ppLabvec[nRcs]->m_nSecs && \ strcmp(pRc->m_ppLabvec[nRcs]->m_ppSecvec[nTmp]->m_szName, \ configGetsecs()[nSecs])) nTmp++; if (nTmp < pRc->m_ppLabvec[nRcs]->m_nSecs) ppSectmp[nRcs] = pRc->m_ppLabvec[nRcs]->m_ppSecvec[nTmp]; d502 2 a503 3 qsort((void *)ppSectmp, (size_t)pRc->m_pAnal->m_nRcs, sizeof(rc_section_t *), priCompare); nTmp = 0; while (nTmp < pRc->m_pAnal->m_nRcs && ppSectmp[nTmp]) { d512 1 a514 1 nTmp++; d522 2 a523 2 ppSectmp = calloc(pRc->m_pAnal->m_nRcs, sizeof(rc_section_t *)); fprintf(stderr, "file %s, section %s\n", pRc->m_ppLabvec[nRcs]->m_szName, RC_CMN_TEXT); d525 6 a530 9 for (nRcs = 0; nRcs < pRc->m_pAnal->m_nRcs; nRcs++) { nTmp = 0; while (nTmp < pRc->m_ppLabvec[nRcs]->m_nSecs && \ strcmp(pRc->m_ppLabvec[nRcs]->m_ppSecvec[nTmp]->m_szName, \ configGetsecs()[nSecs])) { nTmp++; } if (nTmp < pRc->m_ppLabvec[nRcs]->m_nSecs) ppSectmp[nRcs] = pRc->m_ppLabvec[nRcs]->m_ppSecvec[nTmp]; d534 2 a535 3 qsort((void *)ppSectmp, (size_t)pRc->m_pAnal->m_nRcs, sizeof(rc_section_t *), priCompare); nTmp = 0; while (nTmp < pRc->m_pAnal->m_nRcs && ppSectmp[nTmp]) { a536 2 nTmp++; } d553 1 a553 1 int nRcs = pRc->m_pAnal->m_nRcs; d555 16 a570 11 /* Destroy the label vector */ while (nRcs-- > 0) { if (pRc->m_ppLabvec[nRcs]) { labelDelete(pRc->m_ppLabvec[nRcs]); pRc->m_ppLabvec[nRcs] = NULL; } } free(pRc->m_ppLabvec); pRc->m_ppLabvec = NULL; scriptDelete(pRc->m_pScriptcom); /* Destroy the script */ analDelete(pRc->m_pAnal); /* Destroy the analyser */ d572 1 @ 1.44 log @Fix shebang handling. @ text @d48 1 d51 9 a59 5 pNewrc = malloc(sizeof(rc_proc_t)); pNewrc->m_pAnal = analNew(); /* Construct a configuration analyser */ analParse(pNewrc->m_pAnal); /* Preprocess the anal configuration */ pNewrc->m_pScriptcom = scriptNew(); /* Construct a run-command script */ pNewrc->m_ppLabvec = calloc(pNewrc->m_pAnal->m_nRcs, sizeof(rc_label_t *)); a64 11 * 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)); } /************************************************ d81 1 d87 3 a89 2 if (pRc->m_pAnal->m_szFuncs) { if ((nFdfunc = open(pRc->m_pAnal->m_szFuncs, O_RDONLY)) >= 0) { d91 1 a91 1 while ((nRet = read(nFdfunc, sBuf, RC_READ_BUFSIZE)) > 0) { a92 1 } a104 1 assert(pRc->m_pAnal->m_szLocs); d109 21 a129 2 /* Build the path name */ szLocex = (char *)malloc(strlen(pRc->m_pAnal->m_szLocs) + \ d131 6 a136 4 strlen("rc.") + 1); strcpy(szLocex, pRc->m_pAnal->m_szLocs); strcat(szLocex, "rc."); /* FIXME: Make the prefix configurable */ strcat(szLocex, pRc->m_pAnal->m_pszRcs[nRc]); d151 1 a151 1 /* Append config section if it exists */ d155 1 a155 1 scriptAppend(pRc->m_pScriptcom, "\n", sizeof(char)); d160 1 a160 1 for (nSect = 0; nSect < pRc->m_pAnal->m_nSecs; nSect++) { /* Iterate over */ d162 1 a162 1 pSec = scriptSection(pTempscript, pRc->m_pAnal->m_pszSecs[nSect]); d168 1 a168 2 pRc->m_pAnal->m_pszSecs[nSect],\ pRc->m_pAnal->m_pszRcs[nRc]); d221 1 d244 1 a244 1 for (nSecs = 0; nSecs < pRc->m_pAnal->m_nSecs; nSecs++) { d249 1 a249 1 pRc->m_pAnal->m_pszSecs[nSecs])) d305 1 a305 1 for (nSecs = 0; nSecs < pRc->m_pAnal->m_nSecs; nSecs++) { d322 1 a322 1 for (nSecs = 0; nSecs < pRc->m_pAnal->m_nSecs; nSecs++) { d327 1 a327 1 pRc->m_pAnal->m_pszSecs[nSecs])) d447 1 a447 1 for (nSecs = 0; nSecs < pRc->m_pAnal->m_nSecs; nSecs++) { d452 1 a452 1 pRc->m_pAnal->m_pszSecs[nSecs])) d472 27 @ 1.43 log @Complete verbose mode implementation. @ text @a90 3 /* Stick on the starting shell id line */ scriptAppend(pRc->m_pScriptcom, "#! /bin/sh\n", strlen("#! /bin/sh\n")); d190 17 a206 16 int nTmp = 0; /* Generic index */ size_t nBytes = 0; /* Size in bytes */ int nTmpname = 0; /* Temp file name size */ int nRcs = 0; /* Rc index */ int nSecs = 0; /* Section index */ int nSectuid = -1; /* The section's user id */ int nRunuid = -1; /* The current user id */ pid_t Pidexec = -1; /* When spawning before execv(3) */ char *szTmpfile = NULL; /* Path of temporary file */ char *szTmp = NULL; /* Generic temporary string */ char *szCom = NULL; /* Stores common script text */ char *szExec = NULL; /* Used only during exec mode */ char *szVerbose = NULL; /* Used when handling verbose mode */ char *pszVec[RC_EXEC_MAXARGS]; /* For passing in to execv(3) */ rc_script_t *pFatscript = NULL; /* To build a comprehensive script */ rc_section_t **ppSectmp = NULL; /* Used with priority scheduling */ d218 1 d335 1 a335 1 nCommon = (strlen(szCom) + 1) * sizeof (char); d337 2 a338 1 strcpy(szExec, RC_ECHO_STR); /* Start out with the echo string */ d385 2 a386 1 strcpy(szExec, szCom); /* Start out with just the common script code */ d419 2 d426 1 a426 1 fprintf(stderr, "%s", szVerbose); d429 3 a431 1 scriptDump(pRc->m_pScriptcom); /* Dump the common script */ @ 1.42 log @Implement limited verbosity on eval modus, and begin mergin the label object and the section object. @ text @d194 1 d205 1 d219 11 a229 2 /* Allocate the command chain string to execute with execv(3) */ pFatscript = scriptCopy(pRc->m_pScriptcom); d246 1 a247 2 size_t nBytes = 0; char *szVerbose = NULL; d250 1 a250 1 szVerbose = malloc (nBytes); d326 33 a358 6 szTmp = (char *)sectionGetdata(ppSectmp[nTmp]); szExec = malloc(strlen(szCom) * sizeof(char) + \ (strlen(szTmp) + 1) * sizeof(char)); strcpy(szExec, szCom); /* Start out with just the common script code */ strcat(szExec, szTmp); /* And build a section onto the command chain */ pszVec[2] = szExec; /* Actually launch the new process image now */ d360 11 a370 9 /* Spawn the section shell code */ switch (Pidexec = fork()){ case -1: /* Broken */ return(RC_THROW(RC_ERR_INT)); break; /* Huh? */ case 0: /* Child, runs script code through bourne shell */ nSectuid = sectionGetuid(ppSectmp[nTmp]); if (nSectuid >= 0 && getuid() != nSectuid) if (setuid(nSectuid) != 0) d372 20 a391 1 if (execvp(*pszVec, pszVec) == -1) d393 15 a407 4 break; default: /* Parent, blocks until child returns */ waitpid(Pidexec, NULL, WUNTRACED); break; d409 1 a409 4 free(szExec); /* Cleanup after exec */ szExec = NULL; nTmp++; d418 8 d442 9 @ 1.41 log @Fixed non terminal section bug causing segfault in processor @ text @d235 10 @ 1.40 log @Fix incorrect variable name m_szRcs, bug fix analyzer rc list algorythm. @ text @d273 2 a274 1 if (pRc->m_ppLabvec[nTmp]->m_ppSecvec) { @ 1.39 log @Bug fix memory problems found by Solaris. @ text @d88 1 a88 1 assert(*pRc->m_pAnal->m_szRcs); d112 2 a113 2 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 */ d116 1 a116 1 pRc->m_ppLabvec[nRc] = labelNew(pRc->m_pAnal->m_szRcs[nRc]); d120 1 a120 1 strlen(pRc->m_pAnal->m_szRcs[nRc]) + \ d124 1 a124 1 strcat(szLocex, pRc->m_pAnal->m_szRcs[nRc]); d157 1 a157 1 pRc->m_pAnal->m_szRcs[nRc]); @ 1.38 log @Bugfix eval mode temp file name creation, and scrap the nonportable BSD call to strnstr(3). @ text @d119 3 a121 1 szLocex = (char *)malloc(strlen(pRc->m_pAnal->m_szLocs) + strlen(pRc->m_pAnal->m_szRcs[nRc]) + 2); @ 1.37 log @Fix logic to avoid false positives when comparing sections of unequal lengths. @ text @d254 1 a254 1 *(szTmpfile + (strlen(szTmpfile)) * sizeof(char)) = '/'; @ 1.36 log @Preliminary exception handling repairs. @ text @d150 1 a150 1 if (pSec) { /* Only copy if the section lookup succeeds */ a151 1 } @ 1.35 log @Make a fancy broken ex box, and prepare to debug exception handling. @ text @a136 11 /* SEGFAULT SEGFAULT SEGFAULT SEGFAULT SEGFAULT SEGFAULT SEGFAULT SEGFAULT */ /* */ /* CVS TAG OSSP_RC_EXBROKEN */ /* */ /* FIXME: Move this throw macro inside the following if block to see magic */ /* */ /* SEGFAULT SEGFAULT SEGFAULT SEGFAULT SEGFAULT SEGFAULT SEGFAULT SEGFAULT */ /* RC_THROW(RC_ERR_USE); */ @ 1.34 log @Implement unpriviledged rc exec mode with safety checks. @ text @d137 11 @ 1.33 log @Mostly finish setuid(2) work in section parsing of userid, and exec mode. @ text @d267 14 a280 12 /* FIXME FIXME FIXME FIXME */ /* For however many labels */ /* For however many sections in this label */ /* If the we must setuid(2) */ /* If yes, are we root? */ /* If no, then report error and exit */ /* for (nTmp = 0; ; nTmp++) { if () nRunuid = getuid(); if (nRunuid != 0 && nRunuid != nSectuid) { fprintf(stderr, RC_RUT_TEXT); return(RC_THROW(RC_ERR_USE)); d282 1 a282 1 }*/ @ 1.32 log @Half finish the per-user process logic, leading up to coding the fork(2) and waitpid(2). @ text @d30 10 a39 11 #include /* Standard system headers */ #include /* For reading rc files */ #include /* For reading rc files */ #include /* For string manipulation */ /* FIXME: Remove */ #include #include "rc.h" /* Public interfaces */ #include "rc_const.h" /* String and value const */ #include "rc_config.h" /* Option definitions */ d196 3 d267 14 d307 1 a307 1 pszVec[2] = szExec; /* Actually launch the new process image now */ d309 16 a324 4 /* FIXME: Put the fork in here! */ if (execvp(*pszVec, pszVec) == -1) { /* launch */ TRACE("Bad, execvp for common script in child returned -1"); return(RC_THROW(RC_ERR_INT)); @ 1.31 log @Fix parsing of func file, and do not read if the func file doesn't exist. @ text @d199 1 d267 1 a267 4 /* Allocate the command chain string to execute with execv(3) */ szTmp = (char *)scriptTostring(pRc->m_pScriptcom); szExec = malloc((strlen(szTmp) + 1) * sizeof(char)); strcpy(szExec, szTmp); d281 4 a284 1 nTmp = 0; d287 14 a300 3 szExec = realloc(szExec, (strlen(szExec) + 1) * sizeof(char) + \ (strlen(szTmp) + 1) * sizeof(char)); strcat(szExec, szTmp); /* Build onto the command chain */ a305 10 /* Actually launch the new process image now */ pszVec[0] = "/bin/sh"; pszVec[1] = "-c"; pszVec[2] = szExec; pszVec[3] = NULL; /* Add a NULL to mark the end of the chain */ if (execvp(*pszVec, pszVec) == -1) { /* launch */ TRACE("Bad, execvp for common script in child returned -1"); return(RC_THROW(RC_ERR_INT)); } @ 1.30 log @Bug fix recent eval mode addition, and add login name parsing to eval mode. @ text @d78 2 a79 2 int nFdrc = 0; int nFdfunc = 0; d92 3 d97 10 a106 1 if ((nFdfunc = open(pRc->m_pAnal->m_szFuncs, O_RDONLY)) < 0) { a107 9 } } /* Stick on the starting shell id line */ scriptAppend(pRc->m_pScriptcom, "#! /bin/sh\n", strlen("#! /bin/sh\n")); /* Read data from the func file */ while ((nRet = read(nFdfunc, sBuf, RC_READ_BUFSIZE)) > 0) { scriptAppend(pRc->m_pScriptcom, sBuf, nRet); a108 3 scriptAppend(pRc->m_pScriptcom, "\n", sizeof(char)); if (nRet == -1) /* Handle read errors */ RC_THROW(RC_ERR_IO); @ 1.29 log @Implement eval mode. @ text @d227 2 a228 1 qsort((void *)ppSectmp, (size_t)pRc->m_pAnal->m_nRcs, sizeof(rc_section_t *), priCompare); d231 5 d247 2 d251 2 @ 1.28 log @Put priority scheduling back in, safeguard priCompare logic against invalid parameters, generally complete the print mode and exec mode processor operations for milestone one. @ text @d94 1 a94 1 if ((nFdfunc = open(pRc->m_pAnal->m_szFuncs, O_RDONLY)) == -1) { d102 3 a104 10 /* 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_pScriptcom, sBuf, nRet); } scriptAppend(pRc->m_pScriptcom, "\n", sizeof(char)); if (nRet == -1) /* Handle read errors */ RC_THROW(RC_ERR_IO); d106 3 d193 10 a202 7 int nTmp = 0; /* Generic index */ int nRcs = 0; /* Rc index */ int nSecs = 0; /* Section index */ char *szTmp = NULL; /* Generic temporary string */ char *szExec = NULL; /* Used only during exec mode */ char *pszVec[RC_EXEC_MAXARGS]; /* For passing in to execv(3) */ rc_section_t **ppSectmp = NULL; /* Used with priority scheduling */ d210 43 a252 2 if (configGetval(RC_EVL_VAL)) /* Evaluate */ fprintf(stderr, "Error: Evaluate is not implemented yet.\n"); /* FIX */ d254 1 a254 1 /* Allocate a block of section pointers to use as a temporary */ @ 1.27 log @Implement rc label ordered command printing and execution. @ text @d197 7 a203 9 int nTmp = 0; int nRcs = 0; int nSecs = 0; char *pszVec[RC_EXEC_MAXARGS]; /* Conditionally sort the section vector according to explicit priority if (!strcmp(configGetrcfile(), RC_GLOB_WILD)) { qsort((void *)pRc->m_ppSectvec, (size_t)nTotsecs, sizeof (rc_section_t *), priCompare); } */ d214 32 d248 1 a248 1 pszVec[2] = (char *)scriptTostring(pRc->m_pScriptcom); a253 15 for (nSecs = 0; nSecs < pRc->m_pAnal->m_nSecs; nSecs++) for (nRcs = 0; nRcs < pRc->m_pAnal->m_nRcs; nRcs++) { nTmp = 0; while (nTmp < pRc->m_ppLabvec[nRcs]->m_nSecs && \ strcmp(pRc->m_ppLabvec[nRcs]->m_ppSecvec[nTmp]->m_szName, \ pRc->m_pAnal->m_pszSecs[nSecs])) nTmp++; if (nTmp < pRc->m_ppLabvec[nRcs]->m_nSecs) { pszVec[2] = (char *)sectionGetdata(pRc->m_ppLabvec[nRcs]->m_ppSecvec[nTmp]); if (execvp(*pszVec, pszVec) == -1) { /* launch */ TRACE("Bad, execvp for subsection in child returned -1"); return(RC_THROW(RC_ERR_INT)); } } } d256 4 a259 2 scriptDump(pRc->m_pScriptcom); for (nSecs = 0; nSecs < pRc->m_pAnal->m_nSecs; nSecs++) d267 3 a269 1 sectionDump(pRc->m_ppLabvec[nRcs]->m_ppSecvec[nTmp]); d271 9 @ 1.26 log @Use new label class and back out sorting until finding a better algorythm that considers order according to new label and section semantics. @ text @d126 1 d151 1 a151 2 for (nSect = 0; pRc->m_pAnal->m_pszSecs[nSect]; nSect++) { /* Iterate over */ d155 3 a157 2 if (pSec) /* Only copy if the section lookup succeeds */ labelAppendsec(pRc->m_ppLabvec[nRc], sectionCopy(pSec)); d163 1 a163 1 if (pSec) /* Cleanup iterative section string */ d165 2 d197 1 d213 1 a213 1 if (configGetval(RC_EVL_VAL)) /* Evaluate */ d215 1 a215 1 else if (configGetval(RC_EXC_VAL)) { /* Execute */ d220 1 a220 1 if (execvp(*pszVec, pszVec) == -1) { /* launch */ d224 10 a233 5 for (nRcs = 0; nRcs < pRc->m_pAnal->m_nRcs; nRcs++) { for (nSecs = 0; nSecs < pRc->m_pAnal->m_nSecs; nSecs++) { if (pRc->m_ppLabvec[nRcs]->m_ppSecvec[nSecs]) { pszVec[2] = (char *)sectionGetdata(pRc->m_ppLabvec[nRcs]->m_ppSecvec[nSecs]); if (execvp(*pszVec, pszVec) == -1) { /* launch */ a238 1 } d240 1 a240 1 else if (configGetval(RC_PRN_VAL)) { /* Print */ d242 9 a250 4 for (nRcs = 0; nRcs < pRc->m_pAnal->m_nRcs; nRcs++) { for (nSecs = 0; nSecs < pRc->m_pAnal->m_nSecs; nSecs++) { if (pRc->m_ppLabvec[nRcs]->m_ppSecvec && pRc->m_ppLabvec[nRcs]->m_ppSecvec[nSecs]) sectionDump(pRc->m_ppLabvec[nRcs]->m_ppSecvec[nSecs]); a251 1 } @ 1.25 log @Extend priority scheduling feature to --exec mode block. @ text @a48 1 /* int nIter = 0;*/ d55 1 a55 6 /* Logic needed for multiple run-command section combination with priorities */ pNewrc->m_ppSectvec = calloc(pNewrc->m_pAnal->m_nRcs *\ pNewrc->m_pAnal->m_nSecs, sizeof(rc_section_t *)); /* for (nIter = 0; nIter < pNewrc->m_pAnal->m_nRcs; nIter++) pNewrc->m_ppSectvec[nIter] = sectionNew();*/ d77 1 a77 1 int i = 0; d81 1 a81 1 int nIter = 0; d115 1 a115 1 for (nIter = 0; nIter < pRc->m_pAnal->m_nRcs; nIter++) d120 3 d124 1 a124 1 szLocex = (char *)malloc(strlen(pRc->m_pAnal->m_szLocs) + strlen(pRc->m_pAnal->m_szRcs[nIter]) + 2); d126 1 a126 1 strcat(szLocex, pRc->m_pAnal->m_szRcs[nIter]); d150 2 a151 1 for (i = 0; pRc->m_pAnal->m_pszSecs[i]; i++) { /* Iterate over */ d153 1 a153 1 pSec = scriptSection(pTempscript, pRc->m_pAnal->m_pszSecs[i]); d156 1 a156 1 pRc->m_ppSectvec[pRc->m_pAnal->m_nSecs * nIter + i] = sectionCopy(pSec); d159 2 a160 2 pRc->m_pAnal->m_pszSecs[i],\ pRc->m_pAnal->m_szRcs[nIter]); d194 2 a195 2 int nIter = 0; int nTotsecs = pRc->m_pAnal->m_nRcs * pRc->m_pAnal->m_nSecs; d198 1 a198 1 /* Conditionally sort the section vector according to explicit priority */ d201 1 a201 1 } d220 8 a227 6 for (nIter = 0; nIter < nTotsecs; nIter++) { if (pRc->m_ppSectvec[nIter]) { pszVec[2] = (char *)sectionGetdata(pRc->m_ppSectvec[nIter]); if (execvp(*pszVec, pszVec) == -1) { /* launch */ TRACE("Bad, execvp for subsection in child returned -1"); return(RC_THROW(RC_ERR_INT)); d234 5 a238 3 for (nIter = 0; nIter < nTotsecs; nIter++) { if (pRc->m_ppSectvec[nIter]) sectionDump(pRc->m_ppSectvec[nIter]); d253 1 a253 1 int nSecvec = pRc->m_pAnal->m_nRcs * pRc->m_pAnal->m_nSecs; d255 5 a259 5 /* Destroy the section vector */ while (nSecvec-- > 0) { if (pRc->m_ppSectvec[nSecvec]) { sectionDelete(pRc->m_ppSectvec[nSecvec]); pRc->m_ppSectvec[nSecvec] = NULL; d262 2 a263 2 free(pRc->m_ppSectvec); pRc->m_ppSectvec = NULL; @ 1.24 log @Added section login accessors for user name handling during print op, implemented user id and user name parsing in section and script objects. @ text @d39 1 d200 5 d214 17 a230 6 pszVec[0] = "/bin/sh"; pszVec[1] = "-c"; pszVec[2] = (char *)scriptTostring(pRc->m_pScriptcom); 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"); a232 1 qsort((void *)pRc->m_ppSectvec, (size_t)nTotsecs, sizeof (rc_section_t *), priCompare); @ 1.23 log @Implement priority scheduling with qsort(3) and priCompare(), adhere to naming standard, and bugfix. @ text @a151 1 /* FIXME: Swap nested rcfile/section logic loops for section/rcfile ordering */ @ 1.22 log @Add sectionCopy(), sectionDump(), and vectorCount(), and change the processor object's script vector to a section vector. @ text @d196 2 a197 1 int nIter = 0; d217 1 d219 1 a219 1 for (nIter = 0; nIter < pRc->m_pAnal->m_nRcs * pRc->m_pAnal->m_nSecs; nIter++) d222 1 @ 1.21 log @Correctly use section accessors, split script to common and section vector objects, add sectionSetndata (with n length sections), and wrap script dump logic for NULL pointer safety. @ text @d48 1 a48 1 int nIter = 0; d57 4 a60 3 pNewrc->m_ppScriptvec = malloc(sizeof(rc_script_t *) * pNewrc->m_pAnal->m_nRcs); for (nIter = 0; nIter < pNewrc->m_pAnal->m_nRcs; nIter++) pNewrc->m_ppScriptvec[nIter] = scriptNew(); d157 2 a158 5 if (pSec) { /* Only call if the section lookup succeeds */ scriptAppend(pRc->m_ppScriptvec[nIter], sectionGetdata(pSec), sectionGetlen(pSec) - 1); scriptAppend(pRc->m_ppScriptvec[nIter], "\n", sizeof(char)); } d217 3 a219 4 for (nIter = 0; nIter < pRc->m_pAnal->m_nRcs; nIter++) { if (*pRc->m_ppScriptvec[nIter]) scriptDump(pRc->m_ppScriptvec[nIter]); } d233 1 a233 1 int nIter = 0; d235 5 a239 5 /* Destroy the script vector */ for (nIter = pRc->m_pAnal->m_nRcs - 1; nIter >= 0 ; nIter--) { if (pRc->m_ppScriptvec[nIter]) { scriptDelete(pRc->m_ppScriptvec[nIter]); pRc->m_ppScriptvec[nIter] = NULL; d242 2 a243 2 free(pRc->m_ppScriptvec); pRc->m_ppScriptvec = NULL; @ 1.20 log @Bug fix before starting again with user and priority parsing and exec efforts. @ text @d48 1 a52 1 pNewrc->m_pScript = scriptNew(); /* Construct a run-command script */ d54 6 d81 5 a85 6 int i = 0; int nFdrc = 0; int nFdfunc = 0; int nRet = 0; int nRept = 0; int nIter = 0; a91 1 rc_script_t **ppParts = NULL; d104 1 a104 1 scriptAppend(pRc->m_pScript, "#! /bin/sh\n", strlen("#! /bin/sh\n")); d111 1 a111 1 scriptAppend(pRc->m_pScript, sBuf, nRet); d113 1 a113 1 scriptAppend(pRc->m_pScript, "\n", sizeof(char)); a117 5 /* 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(); d145 2 a146 2 scriptAppend(pRc->m_pScript, sectionGetdata(pSec), strlen(sectionGetdata(pSec))); scriptAppend(pRc->m_pScript, "\n", sizeof(char)); d157 1 a157 1 scriptAppend(pRc->m_pScript, sectionGetdata(pSec), d159 1 a159 1 scriptAppend(pRc->m_pScript, "\n", sizeof(char)); a183 10 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; } d198 1 d207 1 a207 1 if (configGetval(RC_EVL_VAL)) /* Evaluate */ d209 1 a209 1 else if (configGetval(RC_EXC_VAL)) { /* Execute */ d212 1 a212 1 pszVec[2] = (char *)scriptTostring(pRc->m_pScript); d214 1 a214 1 if (execvp(*pszVec, pszVec) == -1) /* launch */ d217 8 a224 3 else if (configGetval(RC_PRN_VAL)) /* Print */ scriptDump(pRc->m_pScript); else /* Something is wrong here */ d236 14 a249 3 scriptDelete(pRc->m_pScript); /* Destroy the script */ analDelete(pRc->m_pAnal); /* Destroy the analyser */ free(pRc); /* Free the processor itself */ @ 1.19 log @Bugfix the analyser and processor. @ text @d146 2 a147 2 scriptAppend(ppParts[nIter], sectionGetdata(pSec), strlen(sectionGetdata(pSec))); scriptAppend(ppParts[nIter], "\n", sizeof(char)); @ 1.18 log @Bring rc back to life, corrected the processor and script object memory problems, and made small changes to test suite. @ text @d158 1 a158 1 scriptAppend(ppParts[nIter], sectionGetdata(pSec), @ 1.17 log @Intermediate priority implementation flush. Build is broken. @ text @d155 1 a155 1 szSec = scriptSection(pTempscript, pRc->m_pAnal->m_pszSecs[i]); d157 3 a159 2 if (szSec) { /* Only call if the section lookup succeeds */ scriptAppend(ppParts[nIter], szSec, strlen(szSec)); d162 1 a162 5 /* if (szSec) { -* Only call if the section lookup succeeds *- scriptAppend(pRc->m_pScript, szSec, strlen(szSec)); scriptAppend(pRc->m_pScript, "\n", sizeof(char)); } else if (configGetval(RC_DBG_VAL)) -* Only show if debug set *- d165 1 a165 1 pRc->m_pAnal->m_szRcs[nIter]);*/ d167 2 a168 4 if (szSec) { /* Cleanup iterative section string */ free(szSec); szSec = NULL; } d190 1 @ 1.16 log @Found a new rc_ex bug, and couldn't fix it so I put in a hacky workaround. @ text @d79 1 d83 5 a87 4 char *sBuf = NULL; char *szSec = NULL; char *szLocex = NULL; rc_script_t *pTempscript = NULL; d114 5 d120 1 a120 1 for (nIter = 0; pRc->m_pAnal->m_szRcs[nIter]; nIter++) d144 6 a149 6 szSec = scriptSection(pTempscript, configGetval(RC_NCF_VAL)); if (szSec) { /* Only operate if the section lookup succeeds */ scriptAppend(pRc->m_pScript, szSec, strlen(szSec)); scriptAppend(pRc->m_pScript, "\n", sizeof(char)); free(szSec); /* Cleanup */ szSec = NULL; /* Cleanup */ d152 1 d158 4 d165 1 a165 1 else if (configGetval(RC_DBG_VAL)) /* Only show if debug set */ d168 1 a168 1 pRc->m_pAnal->m_szRcs[nIter]); d190 9 @ 1.15 log @Okay okay, unfortunately it doesn't segfault anymore. I can put back in the original code, but I still think there's a rc_ex problem. @ text @a201 1 d210 1 a210 2 else if (configGetval(RC_PRN_VAL)) /* Print */ d212 1 a212 2 else /* Something is wrong here */ @ 1.14 log @Implemented command execution mode, and now OSSP rc is dangerous to use because it will actually execute code. Test suite is adjusted accordingly. @ text @d216 1 a216 3 fprintf(stderr, "Error: Placeholder, until problem with ex_ is fixed.\n"); /* FIXME!!: Ralf, following segfaults in ex */ /* return(RC_THROW(RC_ERR_INT));*/ @ 1.13 log @Correct and generally improve mixing of sections and parsing the labels. @ text @d192 9 a200 2 /* This will evaluate, execute, or print the script to stdout */ if (configGetval(RC_EVL_VAL)) /* Evaluate */ d202 11 a212 3 else if (configGetval(RC_EXC_VAL)) /* Execute */ fprintf(stderr, "Error: Execute is not implemented yet.\n"); /* FIX */ else if (configGetval(RC_PRN_VAL)) /* Print */ d214 2 a215 1 else /* Something is wrong here, there is */ d218 1 a218 1 /* return(RC_THROW(RC_ERR_INT));*/ /* probably no default in the config */ @ 1.12 log @Resolve some null pointer and ex_ bugs, and clean up --print output. @ text @d97 3 d107 1 d136 9 d149 1 a149 1 if (szSec) /* Only call append if the section lookup succeeds */ d151 2 d158 1 a158 1 if (szSec) { /* Cleanup section string */ @ 1.11 log @Daily dump, start processing sections with regular expressions. @ text @d184 4 a187 2 else return(RC_THROW(RC_ERR_INT)); /* Not reached */ @ 1.10 log @Wrote configInfo, removed config debugging, prepared procRun for eval/exec/print logic, and improved test conditions. @ text @d80 2 d131 16 a146 12 for (i = 0; pRc->m_pAnal->m_pszSecs[i]; i++) { /* Iterate over secvec */ /* Extract a section from the temp script, and append it */ szSec = scriptSection(pTempscript, pRc->m_pAnal->m_pszSecs[i]); if (szSec) /* Only call append if the section lookup succeeded */ scriptAppend(pRc->m_pScript, szSec, strlen(szSec)); else if (configGetval(RC_DBG_VAL)) /* Only show when debug is set */ fprintf(stderr, "#Warning: Missing section '%s' in %s!\n", pRc->m_pAnal->m_pszSecs[i], pRc->m_pAnal->m_szRcs[nIter]); if (szSec) { /* Cleanup section string */ free(szSec); szSec = NULL; d149 2 @ 1.9 log @Cleaned main program block and consolidated error handling into rcError(). Also made output of missing section warnings optional according to --debug flag. @ text @d169 9 a177 5 if (configGetval(RC_DBG_VAL)) /* Dump the running config table */ configDebug(); /* if debug switch is turned on */ /* This will print the script to a hardcoded dump device, probably stderr */ scriptDump(pRc->m_pScript); @ 1.8 log @Improved section parsing and added back most error condition logic. All combinations of wildcard globbing, multiple section parsing, and error handling now work (except for a problem relating to or using ex). @ text @d135 1 a135 1 else @ 1.7 log @Fixed memory bound violation and added section parsing logic. @ text @d75 1 a86 1 pTempscript = scriptNew(); d91 1 a91 2 /* RC_THROW(RC_ERR_IO);*/ fprintf(stderr, "Problem with procPopulate open(2) of %s\n", pRc->m_pAnal->m_szFuncs); d103 1 a103 2 TRACE("Problem with procPopulate read(2)"); /* RC_THROW(RC_ERR_IO);*/ d109 4 d118 2 a119 4 if ((nFdrc = open(szLocex, O_RDONLY)) == -1) { /* RC_THROW(RC_ERR_IO);*/ fprintf(stderr, "Problem with procPopulate open(2) of %s\n", szLocex); } d122 1 d125 1 d127 1 a127 2 TRACE("Problem with procPopulate read(2)"); /* RC_THROW(RC_ERR_IO);*/ d129 14 a142 3 /* Extract a section from the temp script, and append it to other one */ szSec = scriptSection(pTempscript, "start"); /* Extract section */ scriptAppend(pRc->m_pScript, szSec, strlen(szSec)); /* Append section */ d144 4 a147 1 free(szLocex); /* Free our temporarily constructed Location + Rcfile */ a154 1 scriptDelete(pTempscript); a157 4 } if (szSec) { free(szSec); szSec = NULL; @ 1.6 log @Added 'all' wildcard rcfile globbing and removed location hardcoding and rcfile prefix hardcoding. @ text @d79 2 a80 1 char *szBuf = NULL; d82 1 d85 2 a86 1 szBuf = (char *)calloc(0, RC_READ_BUFSIZE); d96 13 a108 1 /* Keep reading possibly globbed rc files until there are none left */ d121 3 a123 14 /* 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, szBuf, RC_READ_BUFSIZE)) > 0) scriptAppend(pRc->m_pScript, szBuf, nRet); if (nRet == -1) /* Handle read errors */ TRACE("Problem with procPopulate read(2)"); /* RC_THROW(RC_ERR_IO);*/ } /* Read data from the rc file */ while ((nRet = read(nFdrc, szBuf, RC_READ_BUFSIZE)) > 0) scriptAppend(pRc->m_pScript, szBuf, nRet); d128 4 d140 8 a147 3 if (szBuf) { free(szBuf); szBuf = NULL; d180 1 @ 1.5 log @Relocate debug config dumping logic and clean up terminal option handling. @ text @d78 1 d80 1 d82 1 a82 7 char *szFucka = NULL; /* FIXME: Do not hardcode location or prefix! */ szFucka = (char *)malloc(strlen(pRc->m_pAnal->m_szRcs) + 8); strcpy(szFucka, "rcfiles/rc."); strcat(szFucka, pRc->m_pAnal->m_szRcs); d85 6 a90 4 /* Open the rc file unconditionally */ if ((nFdrc = open(szFucka, O_RDONLY)) == -1) { /* RC_THROW(RC_ERR_IO);*/ TRACE("Problem with procPopulate open(2)"); d93 9 a101 3 /* Open the func file if it belongs to the configuration */ if (pRc->m_pAnal->m_szFuncs) { if ((nFdfunc = open(pRc->m_pAnal->m_szFuncs, O_RDONLY)) == -1) { d103 12 a114 1 TRACE("Problem with procPopulate open(2)"); d116 3 a118 2 /* Read data from the func file */ while ((nRet = read(nFdfunc, szBuf, RC_READ_BUFSIZE)) > 0) d123 4 d129 1 a129 10 /* Read data from the rc file */ while ((nRet = read(nFdrc, szBuf, RC_READ_BUFSIZE)) > 0) scriptAppend(pRc->m_pScript, szBuf, nRet); if (nRet == -1) /* Handle read errors */ TRACE("Problem with procPopulate read(2)"); /* RC_THROW(RC_ERR_IO);*/ /* Filehandle cleanups */ close(nFdrc); close(nFdfunc); a131 4 if (szFucka) { free(szFucka); szFucka = NULL; } a145 1 d149 1 @ 1.4 log @Intermediate committal, lots of additions, compiles and works very limited. @ text @d39 1 d139 4 @ 1.3 log @Minor logic corrections, but mostly cleanup before continuing. @ text @d30 4 a33 1 #include d35 4 a38 1 #include "rc.h" /* Public interfaces */ d50 4 d69 75 d149 3 a151 1 free(pRc); @ 1.2 log @Flush minor work. Building successfuly again. @ text @d32 1 a32 1 #include "rc.h" /* Public interfaces */ @ 1.1 log @Begin processor pieces. @ text @d39 1 a39 1 rc_t *procNew(void) d41 1 a41 1 rc_t *pNewrc = NULL; d43 1 a43 1 pNewrc = malloc(sizeof(rc_t)); d48 1 a48 1 * procReadtmp(rc_t *, char *) * d51 1 a51 1 rc_return_t procReadtmp(rc_t *pRc, char *szTmpname) d59 1 a59 1 * procDelete(rc_t *) * d62 1 a62 1 rc_return_t procDelete(rc_t *pRc) @