OSSP CVS Repository

ossp - ossp-pkg/rc/rc_sect.c 1.10
Not logged in
[Honeypot]  [Browse]  [Directory]  [Home]  [Login
[Reports]  [Search]  [Ticket]  [Timeline
  [Raw

ossp-pkg/rc/rc_sect.c 1.10
/*  OSSP rc - Run-command processor
**  Copyright (c) 2002 Ralf S. Engelschall
**  Copyright (c) 2002 Cable & Wireless Deutschland GmbH
**  Copyright (c) 2002 The OSSP Project <http://www.ossp.org/>
**
**  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 <string.h> /* For string copy and such data ops */
#include <stdlib.h> /* For memory ops */
#include <unistd.h> /* For mktemp(3)  */
#include <fcntl.h>  /* For open(2)    */

#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)
{
    const char *szLogin = NULL;

    if (pSec) {
        if ((szLogin = sectionGetlogin(pSec)) != NULL)
            fprintf(stdout, "#su %s\n", szLogin);
        fprintf(stdout, "%s", sectionGetdata(pSec));
        return(RC_THROW(RC_OK));
    }
    else
        return(RC_THROW(RC_ERR_USE));
}

/************************************************
* sectionWrite(rc_section_t *, const char *)    *
* Print a section to a file                     *
************************************************/
rc_return_t sectionWrite(rc_section_t *pSec, const char *szPath)
{
    int nFdtmp = open(szPath, O_WRONLY | O_CREAT, 0600);
    FILE *pStream = NULL;

    /* Initial sanity checks */
    if (!pSec || nFdtmp < 0)
        return(RC_THROW(RC_ERR_USE));
    else
        pStream = fdopen(nFdtmp, "w");

    if (pStream) {
        fprintf(pStream, "#su %s\n", sectionGetlogin(pSec));
        fprintf(pStream, "%s", sectionGetdata(pSec));
        fclose(pStream);
        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));
}


CVSTrac 2.0.1