/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtNetwork module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qlocalserver.h"
#include "qlocalserver_p.h"
#include "qlocalsocket.h"
#include "qlocalsocket_p.h"
#include "qnet_unix_p.h"
#include "qtemporarydir.h"

#include <sys/socket.h>
#include <sys/un.h>

#include <qdebug.h>
#include <qdir.h>
#include <qdatetime.h>

#ifdef Q_OS_VXWORKS
#  include <selectLib.h>
#endif

QT_BEGIN_NAMESPACE

void QLocalServerPrivate::init()
{
}

bool QLocalServerPrivate::removeServer(const QString &name)
{
    QString fileName;
    if (name.startsWith(QLatin1Char('/'))) {
        fileName = name;
    } else {
        fileName = QDir::cleanPath(QDir::tempPath());
        fileName += QLatin1Char('/') + name;
    }
    if (QFile::exists(fileName))
        return QFile::remove(fileName);
    else
        return true;
}

bool QLocalServerPrivate::listen(const QString &requestedServerName)
{
    Q_Q(QLocalServer);

    // determine the full server path
    if (requestedServerName.startsWith(QLatin1Char('/'))) {
        fullServerName = requestedServerName;
    } else {
        fullServerName = QDir::cleanPath(QDir::tempPath());
        fullServerName += QLatin1Char('/') + requestedServerName;
    }
    serverName = requestedServerName;

    QByteArray encodedTempPath;
    const QByteArray encodedFullServerName = QFile::encodeName(fullServerName);
    QScopedPointer<QTemporaryDir> tempDir;

    // Check any of the flags
    if (socketOptions & QLocalServer::WorldAccessOption) {
        QFileInfo serverNameFileInfo(fullServerName);
        tempDir.reset(new QTemporaryDir(serverNameFileInfo.absolutePath() + QLatin1Char('/')));
        if (!tempDir->isValid()) {
            setError(QLatin1String("QLocalServer::listen"));
            return false;
        }
        encodedTempPath = QFile::encodeName(tempDir->path() + QLatin1String("/s"));
    }

    // create the unix socket
    listenSocket = qt_safe_socket(PF_UNIX, SOCK_STREAM, 0);
    if (-1 == listenSocket) {
        setError(QLatin1String("QLocalServer::listen"));
        closeServer();
        return false;
    }

    // Construct the unix address
    struct ::sockaddr_un addr;
    addr.sun_family = PF_UNIX;
    if (sizeof(addr.sun_path) < (uint)encodedFullServerName.size() + 1) {
        setError(QLatin1String("QLocalServer::listen"));
        closeServer();
        return false;
    }

    if (socketOptions & QLocalServer::WorldAccessOption) {
        if (sizeof(addr.sun_path) < (uint)encodedTempPath.size() + 1) {
            setError(QLatin1String("QLocalServer::listen"));
            closeServer();
            return false;
        }
        ::memcpy(addr.sun_path, encodedTempPath.constData(),
                 encodedTempPath.size() + 1);
    } else {
        ::memcpy(addr.sun_path, encodedFullServerName.constData(),
                 encodedFullServerName.size() + 1);
    }

    // bind
    if(-1 == QT_SOCKET_BIND(listenSocket, (sockaddr *)&addr, sizeof(sockaddr_un))) {
        setError(QLatin1String("QLocalServer::listen"));
        // if address is in use already, just close the socket, but do not delete the file
        if(errno == EADDRINUSE)
            QT_CLOSE(listenSocket);
        // otherwise, close the socket and delete the file
        else
            closeServer();
        listenSocket = -1;
        return false;
    }

    // listen for connections
    if (-1 == qt_safe_listen(listenSocket, 50)) {
        setError(QLatin1String("QLocalServer::listen"));
        closeServer();
        listenSocket = -1;
        if (error != QAbstractSocket::AddressInUseError)
            QFile::remove(fullServerName);
        return false;
    }

    if (socketOptions & QLocalServer::WorldAccessOption) {
        mode_t mode = 000;

        if (socketOptions & QLocalServer::UserAccessOption)
            mode |= S_IRWXU;

        if (socketOptions & QLocalServer::GroupAccessOption)
            mode |= S_IRWXG;

        if (socketOptions & QLocalServer::OtherAccessOption)
            mode |= S_IRWXO;

        if (::chmod(encodedTempPath.constData(), mode) == -1) {
            setError(QLatin1String("QLocalServer::listen"));
            closeServer();
            return false;
        }

        if (::rename(encodedTempPath.constData(), encodedFullServerName.constData()) == -1) {
            setError(QLatin1String("QLocalServer::listen"));
            closeServer();
            return false;
        }
    }

    Q_ASSERT(!socketNotifier);
    socketNotifier = new QSocketNotifier(listenSocket,
                                         QSocketNotifier::Read, q);
    q->connect(socketNotifier, SIGNAL(activated(QSocketDescriptor)),
               q, SLOT(_q_onNewConnection()));
    socketNotifier->setEnabled(maxPendingConnections > 0);
    return true;
}

bool QLocalServerPrivate::listen(qintptr socketDescriptor)
{
    Q_Q(QLocalServer);

    // Attach to the localsocket
    listenSocket = socketDescriptor;

    ::fcntl(listenSocket, F_SETFD, FD_CLOEXEC);
    ::fcntl(listenSocket, F_SETFL, ::fcntl(listenSocket, F_GETFL) | O_NONBLOCK);

#ifdef Q_OS_LINUX
    struct ::sockaddr_un addr;
    QT_SOCKLEN_T len = sizeof(addr);
    memset(&addr, 0, sizeof(addr));
    if (0 == ::getsockname(listenSocket, (sockaddr *)&addr, &len)) {
        // check for absract sockets
        if (addr.sun_family == PF_UNIX && addr.sun_path[0] == 0) {
            addr.sun_path[0] = '@';
        }
        QString name = QString::fromLatin1(addr.sun_path);
        if (!name.isEmpty()) {
            fullServerName = name;
            serverName = fullServerName.mid(fullServerName.lastIndexOf(QLatin1Char('/')) + 1);
            if (serverName.isEmpty()) {
                serverName = fullServerName;
            }
        }
    }
#else
    serverName.clear();
    fullServerName.clear();
#endif

    Q_ASSERT(!socketNotifier);
    socketNotifier = new QSocketNotifier(listenSocket,
                                         QSocketNotifier::Read, q);
    q->connect(socketNotifier, SIGNAL(activated(QSocketDescriptor)),
               q, SLOT(_q_onNewConnection()));
    socketNotifier->setEnabled(maxPendingConnections > 0);
    return true;
}

/*!
    \internal

    \sa QLocalServer::closeServer()
 */
void QLocalServerPrivate::closeServer()
{
    if (socketNotifier) {
        socketNotifier->setEnabled(false); // Otherwise, closed socket is checked before deleter runs
        socketNotifier->deleteLater();
        socketNotifier = nullptr;
    }

    if (-1 != listenSocket)
        QT_CLOSE(listenSocket);
    listenSocket = -1;

    if (!fullServerName.isEmpty())
        QFile::remove(fullServerName);
}

/*!
    \internal

    We have received a notification that we can read on the listen socket.
    Accept the new socket.
 */
void QLocalServerPrivate::_q_onNewConnection()
{
    Q_Q(QLocalServer);
    if (-1 == listenSocket)
        return;

    ::sockaddr_un addr;
    QT_SOCKLEN_T length = sizeof(sockaddr_un);
    int connectedSocket = qt_safe_accept(listenSocket, (sockaddr *)&addr, &length);
    if(-1 == connectedSocket) {
        setError(QLatin1String("QLocalSocket::activated"));
        closeServer();
    } else {
        socketNotifier->setEnabled(pendingConnections.size()
                                   <= maxPendingConnections);
        q->incomingConnection(connectedSocket);
    }
}

void QLocalServerPrivate::waitForNewConnection(int msec, bool *timedOut)
{
    pollfd pfd = qt_make_pollfd(listenSocket, POLLIN);

    switch (qt_poll_msecs(&pfd, 1, msec)) {
    case 0:
        if (timedOut)
            *timedOut = true;

        return;
        break;
    default:
        if ((pfd.revents & POLLNVAL) == 0) {
            _q_onNewConnection();
            return;
        }

        errno = EBADF;
        Q_FALLTHROUGH();
    case -1:
        setError(QLatin1String("QLocalServer::waitForNewConnection"));
        closeServer();
        break;
    }
}

void QLocalServerPrivate::setError(const QString &function)
{
    if (EAGAIN == errno)
        return;

    switch (errno) {
    case EACCES:
        errorString = QLocalServer::tr("%1: Permission denied").arg(function);
        error = QAbstractSocket::SocketAccessError;
        break;
    case ELOOP:
    case ENOENT:
    case ENAMETOOLONG:
    case EROFS:
    case ENOTDIR:
        errorString = QLocalServer::tr("%1: Name error").arg(function);
        error = QAbstractSocket::HostNotFoundError;
        break;
    case EADDRINUSE:
        errorString = QLocalServer::tr("%1: Address in use").arg(function);
        error = QAbstractSocket::AddressInUseError;
        break;

    default:
        errorString = QLocalServer::tr("%1: Unknown error %2")
                      .arg(function).arg(errno);
        error = QAbstractSocket::UnknownSocketError;
#if defined QLOCALSERVER_DEBUG
        qWarning() << errorString << "fullServerName:" << fullServerName;
#endif
    }
}

QT_END_NAMESPACE
