/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <log4cxx/net/syslogappender.h>
#include <log4cxx/helpers/loglog.h>
#include <log4cxx/helpers/stringhelper.h>
#include <log4cxx/helpers/datagramsocket.h>
#include <log4cxx/spi/loggingevent.h>
#include <log4cxx/level.h>
#include <log4cxx/helpers/transcoder.h>
#if !defined(LOG4CXX)
    #define LOG4CXX 1
#endif
#include <log4cxx/private/log4cxx_private.h>

#if LOG4CXX_HAVE_SYSLOG
    #include <syslog.h>
#else
    /* facility codes */
    #define   LOG_KERN (0<<3)   /* kernel messages */
    #define   LOG_USER (1<<3)   /* random user-level messages */
    #define   LOG_MAIL (2<<3)   /* mail system */
    #define   LOG_DAEMON  (3<<3)   /* system daemons */
    #define   LOG_AUTH (4<<3)   /* security/authorization messages */
    #define   LOG_SYSLOG  (5<<3)   /* messages generated internally by syslogd */
    #define   LOG_LPR     (6<<3)   /* line printer subsystem */
    #define   LOG_NEWS (7<<3)   /* network news subsystem */
    #define   LOG_UUCP (8<<3)   /* UUCP subsystem */
    #define   LOG_CRON (9<<3)   /* clock daemon */
    #define   LOG_AUTHPRIV   (10<<3)  /* security/authorization messages (private) */
    #define   LOG_FTP     (11<<3)  /* ftp daemon */

    /* other codes through 15 reserved for system use */
    #define   LOG_LOCAL0  (16<<3)  /* reserved for local use */
    #define   LOG_LOCAL1  (17<<3)  /* reserved for local use */
    #define   LOG_LOCAL2  (18<<3)  /* reserved for local use */
    #define   LOG_LOCAL3  (19<<3)  /* reserved for local use */
    #define   LOG_LOCAL4  (20<<3)  /* reserved for local use */
    #define   LOG_LOCAL5  (21<<3)  /* reserved for local use */
    #define   LOG_LOCAL6  (22<<3)  /* reserved for local use */
    #define   LOG_LOCAL7  (23<<3)  /* reserved for local use */
#endif

#define LOG_UNDEF -1

using namespace log4cxx;
using namespace log4cxx::helpers;
using namespace log4cxx::net;

IMPLEMENT_LOG4CXX_OBJECT(SyslogAppender)

SyslogAppender::SyslogAppender()
    : syslogFacility(LOG_USER), facilityPrinting(false), sw(0)
{
    this->initSyslogFacilityStr();

}

SyslogAppender::SyslogAppender(const LayoutPtr& layout1,
                               int syslogFacility1)
    : syslogFacility(syslogFacility1), facilityPrinting(false), sw(0)
{
    this->layout = layout1;
    this->initSyslogFacilityStr();
}

SyslogAppender::SyslogAppender(const LayoutPtr& layout1,
                               const LogString& syslogHost1, int syslogFacility1)
    : syslogFacility(syslogFacility1), facilityPrinting(false), sw(0)
{
    this->layout = layout1;
    this->initSyslogFacilityStr();
    setSyslogHost(syslogHost1);
}

SyslogAppender::~SyslogAppender()
{
    finalize();
}

/** Release any resources held by this SyslogAppender.*/
void SyslogAppender::close()
{
    closed = true;

    if (sw != 0)
    {
        delete sw;
        sw = 0;
    }
}

void SyslogAppender::initSyslogFacilityStr()
{
    facilityStr = getFacilityString(this->syslogFacility);

    if (facilityStr.empty())
    {
        Pool p;
        LogString msg(LOG4CXX_STR("\""));
        StringHelper::toString(syslogFacility, p, msg);
        msg.append(LOG4CXX_STR("\" is an unknown syslog facility. Defaulting to \"USER\"."));
        LogLog::error(msg);
        this->syslogFacility = LOG_USER;
        facilityStr = LOG4CXX_STR("user:");
    }
    else
    {
        facilityStr += LOG4CXX_STR(":");
    }
}

/**
Returns the specified syslog facility as a lower-case String,
e.g. "kern", "user", etc.
*/
LogString SyslogAppender::getFacilityString(
    int syslogFacility)
{
    switch (syslogFacility)
    {
        case LOG_KERN:
            return LOG4CXX_STR("kern");

        case LOG_USER:
            return LOG4CXX_STR("user");

        case LOG_MAIL:
            return LOG4CXX_STR("mail");

        case LOG_DAEMON:
            return LOG4CXX_STR("daemon");

        case LOG_AUTH:
            return LOG4CXX_STR("auth");

        case LOG_SYSLOG:
            return LOG4CXX_STR("syslog");

        case LOG_LPR:
            return LOG4CXX_STR("lpr");

        case LOG_NEWS:
            return LOG4CXX_STR("news");

        case LOG_UUCP:
            return LOG4CXX_STR("uucp");

        case LOG_CRON:
            return LOG4CXX_STR("cron");
#ifdef LOG_AUTHPRIV

        case LOG_AUTHPRIV:
            return LOG4CXX_STR("authpriv");
#endif
#ifdef LOG_FTP

        case LOG_FTP:
            return LOG4CXX_STR("ftp");
#endif

        case LOG_LOCAL0:
            return LOG4CXX_STR("local0");

        case LOG_LOCAL1:
            return LOG4CXX_STR("local1");

        case LOG_LOCAL2:
            return LOG4CXX_STR("local2");

        case LOG_LOCAL3:
            return LOG4CXX_STR("local3");

        case LOG_LOCAL4:
            return LOG4CXX_STR("local4");

        case LOG_LOCAL5:
            return LOG4CXX_STR("local5");

        case LOG_LOCAL6:
            return LOG4CXX_STR("local6");

        case LOG_LOCAL7:
            return LOG4CXX_STR("local7");

        default:
            return LogString();
    }
}

int SyslogAppender::getFacility(
    const LogString& s)
{
    if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("KERN"), LOG4CXX_STR("kern")))
    {
        return LOG_KERN;
    }
    else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("USER"), LOG4CXX_STR("user")))
    {
        return LOG_USER;
    }
    else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("MAIL"), LOG4CXX_STR("mail")))
    {
        return LOG_MAIL;
    }
    else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("DAEMON"), LOG4CXX_STR("daemon")))
    {
        return LOG_DAEMON;
    }
    else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("AUTH"), LOG4CXX_STR("auth")))
    {
        return LOG_AUTH;
    }
    else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("SYSLOG"), LOG4CXX_STR("syslog")))
    {
        return LOG_SYSLOG;
    }
    else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("LPR"), LOG4CXX_STR("lpr")))
    {
        return LOG_LPR;
    }
    else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("NEWS"), LOG4CXX_STR("news")))
    {
        return LOG_NEWS;
    }
    else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("UUCP"), LOG4CXX_STR("uucp")))
    {
        return LOG_UUCP;
    }
    else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("CRON"), LOG4CXX_STR("cron")))
    {
        return LOG_CRON;
    }

#ifdef LOG_AUTHPRIV
    else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("AUTHPRIV"), LOG4CXX_STR("authpriv")))
    {
        return LOG_AUTHPRIV;
    }

#endif
#ifdef LOG_FTP
    else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("FTP"), LOG4CXX_STR("ftp")))
    {
        return LOG_FTP;
    }

#endif
    else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("LOCAL0"), LOG4CXX_STR("local0")))
    {
        return LOG_LOCAL0;
    }
    else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("LOCAL1"), LOG4CXX_STR("local1")))
    {
        return LOG_LOCAL1;
    }
    else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("LOCAL2"), LOG4CXX_STR("local2")))
    {
        return LOG_LOCAL2;
    }
    else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("LOCAL3"), LOG4CXX_STR("local3")))
    {
        return LOG_LOCAL3;
    }
    else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("LOCAL4"), LOG4CXX_STR("local4")))
    {
        return LOG_LOCAL4;
    }
    else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("LOCAL5"), LOG4CXX_STR("local5")))
    {
        return LOG_LOCAL5;
    }
    else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("LOCAL6"), LOG4CXX_STR("local6")))
    {
        return LOG_LOCAL6;
    }
    else if (StringHelper::equalsIgnoreCase(s, LOG4CXX_STR("LOCAL7"), LOG4CXX_STR("local7")))
    {
        return LOG_LOCAL7;
    }
    else
    {
        return LOG_UNDEF;
    }
}

void SyslogAppender::append(const spi::LoggingEventPtr& event, Pool& p)
{
    if  (!isAsSevereAsThreshold(event->getLevel()))
    {
        return;
    }

    LogString msg;
    layout->format(msg, event, p);

    // On the local host, we can directly use the system function 'syslog'
    // if it is available
#if LOG4CXX_HAVE_SYSLOG

    if (sw == 0)
    {
        std::string sbuf;
        Transcoder::encode(msg, sbuf);

        // use of "%s" to avoid a security hole
        ::syslog(syslogFacility | event->getLevel()->getSyslogEquivalent(),
                 "%s", sbuf.c_str());

        return;
    }

#endif

    // We must not attempt to append if sw is null.
    if (sw == 0)
    {
        errorHandler->error(LOG4CXX_STR("No syslog host is set for SyslogAppedender named \"") +
                            this->name + LOG4CXX_STR("\"."));
        return;
    }

    LogString sbuf(1, 0x3C /* '<' */);
    StringHelper::toString((syslogFacility | event->getLevel()->getSyslogEquivalent()), p, sbuf);
    sbuf.append(1, (logchar) 0x3E /* '>' */);

    if (facilityPrinting)
    {
        sbuf.append(facilityStr);
    }

    sbuf.append(msg);
    sw->write(sbuf);
}

void SyslogAppender::activateOptions(Pool&)
{
}

void SyslogAppender::setOption(const LogString& option, const LogString& value)
{
    if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("SYSLOGHOST"), LOG4CXX_STR("sysloghost")))
    {
        setSyslogHost(value);
    }
    else if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("FACILITY"), LOG4CXX_STR("facility")))
    {
        setFacility(value);
    }
    else
    {
        AppenderSkeleton::setOption(option, value);
    }
}

void SyslogAppender::setSyslogHost(const LogString& syslogHost1)
{
    if (this->sw != 0)
    {
        delete this->sw;
        this->sw = 0;
    }

    LogString slHost = syslogHost1;
    int slHostPort = -1;

    LogString::size_type colonPos = 0;
    colonPos = slHost.rfind(':');

    if (colonPos != LogString::npos)
    {
        slHostPort = StringHelper::toInt(slHost.substr(colonPos + 1));
        // Erase the :port part of the host name
        slHost.erase( colonPos );
    }

    // On the local host, we can directly use the system function 'syslog'
    // if it is available (cf. append)
#if LOG4CXX_HAVE_SYSLOG

    if (syslogHost1 != LOG4CXX_STR("localhost") && syslogHost1 != LOG4CXX_STR("127.0.0.1")
            && !syslogHost1.empty())
#endif
        if (slHostPort >= 0)
        {
            this->sw = new SyslogWriter(slHost, slHostPort);
        }
        else
        {
            this->sw = new SyslogWriter(slHost);
        }

    this->syslogHost = slHost;
    this->syslogHostPort = slHostPort;
}


void SyslogAppender::setFacility(const LogString& facilityName)
{
    if (facilityName.empty())
    {
        return;
    }

    syslogFacility = getFacility(facilityName);

    if (syslogFacility == LOG_UNDEF)
    {
        LogLog::error(LOG4CXX_STR("[") + facilityName +
                      LOG4CXX_STR("] is an unknown syslog facility. Defaulting to [USER]."));
        syslogFacility = LOG_USER;
    }

    this->initSyslogFacilityStr();
}

