/* 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(const char *) *
* Construct a section *
************************************************/
rc_section_t *sectionNew(const char *szName)
{
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) {
pSec->m_szName = malloc((strlen(szName) + 1) * sizeof(char));
strcpy(pSec->m_szName, szName);
}
else
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;
/* Deep copy of user name */
if (pOrigsec->m_szLogin) {
pSec->m_szLogin = malloc((strlen(pOrigsec->m_szLogin) + sizeof(char))\
* sizeof(char));
strcpy(pSec->m_szLogin, pOrigsec->m_szLogin);
}
/* Deep copy of section text */
if (pOrigsec->m_szData) {
pSec->m_szData = malloc((strlen(pOrigsec->m_szData) + sizeof(char))\
* sizeof(char));
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 *sectionGetlogin(rc_section_t *pSec)
{ /* User name of section, used for display during print */
if (pSec)
return(pSec->m_szLogin);
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 sectionSetlogin(rc_section_t *pSec, const char *szLogin)
{ /* User name of section, used for display during print */
if (pSec) {
pSec->m_szLogin = malloc((strlen(szLogin) + 1) * sizeof (char));
strcpy(pSec->m_szLogin, szLogin);
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, "#su %s\n", sectionGetlogin(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);
if (pSec->m_szName)
free(pSec->m_szName);
if (pSec->m_szLogin)
free(pSec->m_szLogin);
free(pSec);
}
else /* Dumbass passed an empty section object */
assert(FALSE);
return(RC_THROW(RC_OK));
}