/*
**  L2 - OSSP Logging Library
**  Copyright (c) 2001 The OSSP Project (http://www.ossp.org/)
**  Copyright (c) 2001 Cable & Wireless Deutschland (http://www.cw.com/de/)
**
**  This file is part of OSSP L2, a flexible logging library which
**  can be found at http://www.ossp.org/pkg/l2/. 
**
**  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.
**
**  l2_epreuve.c: channel-level test code
**
*/
    
#include "l2.h"
#include "l2_p.h"
#include <syslog.h>

#define L2_HEXBASE          16
#define L2_COMMANDARG        0
#define L2_BUFSIZEARG        1
#define L2_FILEARG           2
#define L2_MESSAGEARG        3
#define L2_VONBUFSTRING      " in L2_buffer.\n"
#define L2_VONFILESTRING     " von L2_file Kanal.\n"
#define L2_VONL2LIB          " L2Lib"
#define L2_VONSYSLOGSTRING   " von L2_syslog Kanal.\n"

void throwup(char *);
int trybuf(char **);
int trysyslog(char **);
int tryfile(char **);

/*--------------------------------------------------------*/
/* void throwup(char *pszError)                           */
/* Quick exception kludge                                 */
/*--------------------------------------------------------*/
void throwup(char *pszError)
{
    fprintf(stderr, pszError);
    exit(1);
}

/*--------------------------------------------------------*/
/* void trybuf(char *pszArgs[])                           */
/* Test logic for the buffer channel handler              */
/*--------------------------------------------------------*/
int trybuf(char *pszArgs[])
{
    int iRet                       = 0;    /* for checking return value  */
    int iMsgSize                   = 0;    /* holds the message size     */
    char *pszMsgIn                 = NULL; /* string we pass to ch_write */
    l2_channel_t *pMyBChannel      = NULL; /* handle to channel instance */
    l2_handler_t *g_pBufferHandler = &l2_handler_buffer;

    fprintf(stdout, "Trying buffer channel handler...\n");

    pMyBChannel = l2_channel_create(g_pBufferHandler);
    if (pMyBChannel == NULL)
        return 1;

    /* Params "size", <Buffer size> */
    iRet = l2_channel_configure(pMyBChannel, "size",\
        strtol(pszArgs[L2_BUFSIZEARG], NULL, L2_HEXBASE));
    if (iRet != L2_OK)
        return 1;

    iRet = l2_channel_open(pMyBChannel);
    if (iRet != L2_OK)
        return 1;

    /* Need to add extra bytes to string length to allow for the text we add */
    iMsgSize = strlen(pszArgs[L2_MESSAGEARG]);
    pszMsgIn = malloc(iMsgSize);
    strcpy(pszMsgIn, pszArgs[L2_MESSAGEARG]);
    iRet = l2_channel_write(pMyBChannel, pszMsgIn, iMsgSize);
    if (iRet != L2_OK)
        return 1;
    free(pszMsgIn);

    /* We are breaking an opaque data type to examine its contents by   */
    /* casting it. ANSI C allows this hack, but it's not good practice. */
    fprintf(stderr, "0x%X octets Speichersize.\n",\
        (int)(*((char **)pMyBChannel->context.vp + 2)));
    fprintf(stderr, *(char **)pMyBChannel->context.vp);
    fprintf(stderr, " von de Buffer\n");

    iRet = l2_channel_flush(pMyBChannel);
    if (iRet != L2_OK)
        return 1;

    iRet = l2_channel_close(pMyBChannel);
    if (iRet != L2_OK)
        return 1;

    iRet = l2_channel_destroy(pMyBChannel);
    if (iRet != L2_OK)
        return 1;

    return 0; /* All stages of execution completed successfully */
}

/*--------------------------------------------------------*/
/* void trysyslog(char *pszArgs[])                        */
/* Test logic for the syslog channel handler              */
/*--------------------------------------------------------*/
int trysyslog(char *pszArgs[])
{
    int iRet                       = 0;
    int iMsgSize                   = 0;
    char *pszMsgIn                 = NULL;
    l2_channel_t *pMySChannel      = NULL;
    l2_handler_t *g_pSLogHandler   = &l2_handler_syslog;

    fprintf(stdout, "Trying syslog channel handler...\n");

    pMySChannel = l2_channel_create(g_pSLogHandler);
    if (pMySChannel == NULL)
        return 1;

    /* Params "ident", <String>, "logopts", <LOG_?>, "facility", <LOG_?> */
    /*        "priority", <LOG_?>, "maskpriority", <LOG_?>               */
    iRet = l2_channel_configure(pMySChannel, "ident", L2_VONL2LIB,\
        "logopts", (LOG_PID|LOG_CONS), "facility", LOG_USER, "priority",\
        (LOG_CRIT|LOG_ALERT|LOG_NOTICE), "maskpriority", 0xFFFFFFFF);
    if (iRet != L2_OK)
        return 1;

    iRet = l2_channel_open(pMySChannel);
    if (iRet != L2_OK)
        return 1;

    /* Need to add n bytes to string length to allow for the text we add */
    iMsgSize = strlen(pszArgs[L2_MESSAGEARG]) + strlen(L2_VONSYSLOGSTRING);
    pszMsgIn = malloc(iMsgSize);
    strcpy(pszMsgIn, pszArgs[L2_MESSAGEARG]);
    strcat(pszMsgIn, L2_VONSYSLOGSTRING);
    iRet = l2_channel_write(pMySChannel, pszMsgIn, iMsgSize);
    if (iRet != L2_OK)
        return 1;
    free(pszMsgIn);

    iRet = l2_channel_flush(pMySChannel);
    if (iRet != L2_OK)
        return 1;

    iRet = l2_channel_close(pMySChannel);
    if (iRet != L2_OK)
        return 1;

    iRet = l2_channel_destroy(pMySChannel);
    if (iRet != L2_OK)
        return 1;

    return 0; /* All stages of execution completed successfully */
}

/*--------------------------------------------------------*/
/* void tryfile(char *pszArgs[])                          */
/* Test logic for the file channel handler                */
/*--------------------------------------------------------*/
int tryfile(char *pszArgs[])
{
    int iRet                       = 0;
    int iMsgSize                   = 0;
    char *pszMsgIn                 = NULL;
    l2_channel_t *pMyFChannel      = NULL;
    l2_handler_t *g_pFileHandler   = &l2_handler_file;

    fprintf(stdout, "Trying file channel handler...\n");

    pMyFChannel = l2_channel_create(g_pFileHandler);
    if (pMyFChannel == NULL)
        return 1;

    /* Params "path", <File path>, "append", <TRUE/FALSE>, "perm", <0xValue> */
    iRet = l2_channel_configure(pMyFChannel, "path", pszArgs[L2_FILEARG],\
        "append", TRUE, "perm", 0x755);
    if (iRet != L2_OK)
        return 1;

    iRet = l2_channel_open(pMyFChannel);
    if (iRet != L2_OK)
        return 1;

    /* Need to add n bytes to string length to allow for the text we add */
    iMsgSize = strlen(pszArgs[L2_MESSAGEARG]) + strlen(L2_VONFILESTRING);
    pszMsgIn = malloc(iMsgSize);
    strcpy(pszMsgIn, pszArgs[L2_MESSAGEARG]);
    strcat(pszMsgIn, L2_VONFILESTRING);
    iRet = l2_channel_write(pMyFChannel, pszMsgIn, iMsgSize);
    if (iRet != L2_OK)
        return 1;
    free(pszMsgIn);

    iRet = l2_channel_flush(pMyFChannel);
    if (iRet != L2_OK)
        return 1;

    iRet = l2_channel_close(pMyFChannel);
    if (iRet != L2_OK)
        return 1;

    iRet = l2_channel_destroy(pMyFChannel);
    if (iRet != L2_OK)
        return 1;

    return 0; /* All stages of execution completed successfully */
}

/*--------------------------------------------------------*/
/* int main(int argc, char *argv[])                       */
/* Main program code                                      */
/*--------------------------------------------------------*/
int main(int argc, char *argv[])
{
    if (argc < 4)
    {
        fprintf(stdout, "Usage:   %s 0xbufsize file string\n"\
            "Example: %s 2F myoutfile DontPutAnySpacesInThisString\n",\
            *argv, *argv);
        exit(1);
    }

    if (trybuf(argv))
    {
        throwup("Buffer channel handler failed!\n");
        exit(1);
    }

    if (trysyslog(argv))
    {
        throwup("Syslog channel handler failed!\n");
        exit(1);
    }

    if (tryfile(argv))
    {
        throwup("File channel handler failed!\n");
        exit(1);
    }

    fprintf(stdout, "Success, exiting.\n");
    return 0;
}
