/* 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_sect.c: Run-command processor ISO C source file */ #include /* For string copy and such data ops */ #include /* For memory ops */ #include "rc.h" /* Public Rc interface */ /************************************************ * sectionNew(void) * * Construct a section * ************************************************/ rc_section_t *sectionNew(void) { rc_section_t *pSec = NULL; /* Among other things, they make great coffee at Cable & Wireless */ /* This code would probably have more bugs if the coffee was not as good */ pSec = (rc_section_t *)calloc(1, sizeof(rc_section_t)); if (!pSec) RC_THROW(RC_ERR_MEM); return(pSec); } /************************************************ * sectionCopy(rc_section_t *) * * Opaque copy constructor * ************************************************/ rc_section_t *sectionCopy(rc_section_t *pOrigsec) { rc_section_t *pSec = NULL; /* Today is a rain and no coffee day */ pSec = (rc_section_t *)malloc(sizeof(rc_section_t)); pSec->m_nPri = pOrigsec->m_nPri; pSec->m_nUid = pOrigsec->m_nUid; pSec->m_Bytes = pOrigsec->m_Bytes; pSec->m_szData = malloc(strlen(pOrigsec->m_szData) * sizeof(char) + 1); strcpy(pSec->m_szData, pOrigsec->m_szData); if (!pSec) RC_THROW(RC_ERR_MEM); return(pSec); } /************************************************ * sectionGetXXX(rc_section_t *) * * Accessor methods * ************************************************/ const int sectionGetpri(rc_section_t *pSec) { /* Priority of section, used to order sections during exec|eval|print */ if (pSec) return(pSec->m_nPri); else RC_THROW(RC_ERR_USE); return(0); /* Not reached */ } const int sectionGetuid(rc_section_t *pSec) { /* Userid of section, used with setuid during exec or eval */ if (pSec) return(pSec->m_nUid); else RC_THROW(RC_ERR_USE); return(0); /* Not reached */ } const char *sectionGetdata(rc_section_t *pSec) { /* Data of section, this is the script body of the particular section */ if (pSec && pSec->m_szData) return(pSec->m_szData); else RC_THROW(RC_ERR_USE); return(0); /* Not reached */ } size_t sectionGetlen(rc_section_t *pSec) { /* Data length of section, length of a script body of a particular section */ if (pSec) return(pSec->m_Bytes); else RC_THROW(RC_ERR_USE); return(0); /* Not reached */ } /************************************************ * sectionSetXXX(rc_section_t *) * * Accessor methods * ************************************************/ rc_return_t sectionSetpri(rc_section_t *pSec, long nPriority) { /* Priority of section, used to order sections during exec|eval|print */ if (pSec) { pSec->m_nPri = nPriority; return(RC_THROW(RC_OK)); } return(RC_THROW(RC_ERR_USE)); } rc_return_t sectionSetuid(rc_section_t *pSec, long nUserid) { /* Userid of section, used with setuid during exec or eval */ if (pSec) { pSec->m_nUid = nUserid; return(RC_THROW(RC_OK)); } return(RC_THROW(RC_ERR_USE)); } rc_return_t sectionSetdata(rc_section_t *pSec, const char *kszScript) { /* Data of section, this is the script body of the particular section */ if (pSec) { pSec->m_Bytes = strlen(kszScript) * sizeof(char) + sizeof(char); if (pSec->m_szData) { /* The section data is already in use */ free(pSec->m_szData); pSec->m_szData = malloc(pSec->m_Bytes); strcpy(pSec->m_szData, kszScript); } else { /* Set the data the usual way */ pSec->m_szData = malloc(pSec->m_Bytes); strcpy(pSec->m_szData, kszScript); } return(RC_THROW(RC_OK)); } return(RC_THROW(RC_ERR_USE)); } rc_return_t sectionSetndata(rc_section_t *pSec, const char *kszScript, size_t Len) { /* Data of section, this is the script body of the particular section */ if (pSec) { pSec->m_Bytes = Len * sizeof(char) + sizeof(char); /* Set size */ if (pSec->m_szData) { /* The section data is already in use */ free(pSec->m_szData); pSec->m_szData = malloc(pSec->m_Bytes); strncpy(pSec->m_szData, kszScript, Len); *(pSec->m_szData + Len) = NULL; /* Terminate outgoing */ } else { /* Set the data the usual way */ pSec->m_szData = malloc(pSec->m_Bytes); strncpy(pSec->m_szData, kszScript, Len); *(pSec->m_szData + Len) = NULL; /* Terminate outgoing */ } return(RC_THROW(RC_OK)); } return(RC_THROW(RC_ERR_USE)); } /************************************************ * sectionDump(rc_section_t *) * * Print a section to standard out * ************************************************/ rc_return_t sectionDump(rc_section_t *pSec) { if (pSec) { fprintf(stdout, "%s", sectionGetdata(pSec)); return(RC_THROW(RC_OK)); } else return(RC_THROW(RC_ERR_USE)); } /************************************************ * sectionDelete(rc_section_t *) * * Destruct a section * ************************************************/ rc_return_t sectionDelete(rc_section_t *pSec) { /* Cleanup our junk */ if (pSec) { if (pSec->m_szData) free(pSec->m_szData); free(pSec); } else /* Dumbass passed an empty section object */ assert(FALSE); return(RC_THROW(RC_OK)); }