<commit_before>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Copyright (c) 2011-2012 Litecoin Developers
// Copyright (c) 2014 CosineCoin Developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "irc.h"
#include "net.h"
#include "strlcpy.h"
#include "base58.h"

using namespace std;
using namespace boost;

int nGotIRCAddresses = 0;

void ThreadIRCSeed2(void* parg);
extern volatile bool fRequestShutdown;

#pragma pack(push, 1)
/***************************************************************************************************
*
*
***************************************************************************************************/
struct ircaddr {
    struct in_addr ip;
    short port;
};
#pragma pack(pop)

/***************************************************************************************************
*
*
***************************************************************************************************/
string EncodeAddress(const CService& addr) {
    struct ircaddr tmp;
    if (addr.GetInAddr(&tmp.ip))
    {
        tmp.port = htons(addr.GetPort());

        vector<unsigned char> vch(UBEGIN(tmp), UEND(tmp));
        return string("u") + EncodeBase58Check(vch);
    }
    return "";
}

/***************************************************************************************************
*
*
***************************************************************************************************/
bool DecodeAddress(string str, CService& addr) {
    vector<unsigned char> vch;
    if (!DecodeBase58Check(str.substr(1), vch))
        return false;

    struct ircaddr tmp;
    if (vch.size() != sizeof(tmp))
        return false;
    memcpy(&tmp, &vch[0], sizeof(tmp));

    addr = CService(tmp.ip, ntohs(tmp.port));
    return true;
}

/***************************************************************************************************
*
*
***************************************************************************************************/
static bool Send(SOCKET hSocket, const char* pszSend) {
    if (strstr(pszSend, "PONG") != pszSend)
        printf("IRC SENDING: %s\n", pszSend);
    const char* psz = pszSend;
    const char* pszEnd = psz + strlen(psz);
    while (psz < pszEnd)
    {
        int ret = send(hSocket, psz, pszEnd - psz, MSG_NOSIGNAL);
        if (ret < 0)
            return false;
        psz += ret;
    }
    return true;
}

/***************************************************************************************************
*
*
***************************************************************************************************/
bool RecvLineIRC(SOCKET hSocket, string& strLine) {
    loop
    {
        bool fRet = RecvLine(hSocket, strLine);
        if (fRet)
        {
            if (fRequestShutdown)
                return false;
            vector<string> vWords;
            ParseString(strLine, ' ', vWords);
            if (vWords.size() >= 1 && vWords[0] == "PING")
            {
                strLine[1] = 'O';
                strLine += '\r';
                Send(hSocket, strLine.c_str());
                continue;
            }
        }
        return fRet;
    }
}

/***************************************************************************************************
*
*
***************************************************************************************************/
int RecvUntil(SOCKET hSocket, const char* psz1, const char* psz2=NULL, const char* psz3=NULL, const char* psz4=NULL) {
    loop
    {
        string strLine;
        strLine.reserve(10000);
        if (!RecvLineIRC(hSocket, strLine))
            return 0;
        printf("IRC %s\n", strLine.c_str());
        if (psz1 && strLine.find(psz1) != string::npos)
            return 1;
        if (psz2 && strLine.find(psz2) != string::npos)
            return 2;
        if (psz3 && strLine.find(psz3) != string::npos)
            return 3;
        if (psz4 && strLine.find(psz4) != string::npos)
            return 4;
    }
}

/***************************************************************************************************
*
*
***************************************************************************************************/
bool Wait(int nSeconds) {
    if (fRequestShutdown)
        return false;
    printf("IRC waiting %d seconds to reconnect\n", nSeconds);
    for (int i = 0; i < nSeconds; i++)
    {
        if (fRequestShutdown)
            return false;
        usleep(1000000);
    }
    return true;
}

/***************************************************************************************************
*
*
***************************************************************************************************/
bool RecvCodeLine(SOCKET hSocket, const char* psz1, string& strRet) {
    strRet.clear();
    loop
    {
        string strLine;
        if (!RecvLineIRC(hSocket, strLine))
            return false;

        vector<string> vWords;
        ParseString(strLine, ' ', vWords);
        if (vWords.size() < 2)
            continue;

        if (vWords[1] == psz1)
        {
            printf("IRC %s\n", strLine.c_str());
            strRet = strLine;
            return true;
        }
    }
}

/***************************************************************************************************
*
*
***************************************************************************************************/
bool GetIPFromIRC(SOCKET hSocket, string strMyName, CNetAddr& ipRet) {
    Send(hSocket, strprintf("USERHOST %s\r", strMyName.c_str()).c_str());

    string strLine;
    if (!RecvCodeLine(hSocket, "302", strLine))
        return false;

    vector<string> vWords;
    ParseString(strLine, ' ', vWords);
    if (vWords.size() < 4)
        return false;

    string str = vWords[3];
    if (str.rfind("@") == string::npos)
        return false;
    string strHost = str.substr(str.rfind("@")+1);

    // Hybrid IRC used by lfnet always returns IP when you userhost yourself,
    // but in case another IRC is ever used this should work.
    printf("GetIPFromIRC() got userhost %s\n", strHost.c_str());
    CNetAddr addr(strHost, true);
    if (!addr.IsValid())
        return false;
    ipRet = addr;

    return true;
}

/***************************************************************************************************
*
*
***************************************************************************************************/
void ThreadIRCSeed() {
    //IMPLEMENT_RANDOMIZE_STACK(ThreadIRCSeed(parg));

    // Make this thread recognisable as the IRC seeding thread
    RenameThread("bitcoin-ircseed");

    try
    {
        ThreadIRCSeed2(NULL);
    }
    catch (std::exception& e) {
        PrintExceptionContinue(&e, "ThreadIRCSeed()");
    } catch (...) {
        PrintExceptionContinue(NULL, "ThreadIRCSeed()");
    }
    printf("ThreadIRCSeed exited\n");
}

/***************************************************************************************************
*
*
***************************************************************************************************/
void ThreadIRCSeed2(void* parg) {
    /* Dont advertise on IRC if we don't allow incoming connections */
    if (mapArgs.count("-connect") || fNoListen)
        return;

    if (!GetBoolArg("-irc", false))
        return;

    printf("ThreadIRCSeed started\n");
    int nErrorWait = 10;
    int nRetryWait = 10;

    while (!fRequestShutdown)
    {
        CService addrConnect("92.243.23.21", 6667); // irc.lfnet.org

        CService addrIRC("irc.lfnet.org", 6667, true);
        if(addrIRC.IsValid()) {
			printf("Set IRC server irc.lfnet.org\n");
            addrConnect = addrIRC;
		}

        SOCKET hSocket;
        if (!ConnectSocket(addrConnect, hSocket))
        {
            printf("IRC connect failed\n");
            nErrorWait = nErrorWait * 11 / 10;
            if (Wait(nErrorWait += 60))
                continue;
            else
                return;
        }

        if (!RecvUntil(hSocket, "Found your hostname", "using your IP address instead", "Couldn't look up your hostname", "ignoring hostname"))
        {
            closesocket(hSocket);
            hSocket = INVALID_SOCKET;
            nErrorWait = nErrorWait * 11 / 10;
            if (Wait(nErrorWait += 60))
                continue;
            else
                return;
        }

        CNetAddr addrIPv4("1.2.3.4"); // arbitrary IPv4 address to make GetLocal prefer IPv4 addresses
        CService addrLocal;
        string strMyName;
        if (GetLocal(addrLocal, &addrIPv4))
            strMyName = EncodeAddress(GetLocalAddress(&addrConnect));
        if (strMyName == "")
            strMyName = strprintf("x%u", (unsigned int)GetRand(1000000000));

        Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str());
        Send(hSocket, strprintf("USER %s 8 * : %s\r", strMyName.c_str(), strMyName.c_str()).c_str());

        int nRet = RecvUntil(hSocket, " 004 ", " 433 ");
        if (nRet != 1)
        {
            closesocket(hSocket);
            hSocket = INVALID_SOCKET;
            if (nRet == 2)
            {
                printf("IRC name already in use\n");
                Wait(10);
                continue;
            }
            nErrorWait = nErrorWait * 11 / 10;
            if (Wait(nErrorWait += 60))
                continue;
            else
                return;
        }
        usleep(500000);

        // Get our external IP from the IRC server and re-nick before joining the channel
        CNetAddr addrFromIRC;
        if (GetIPFromIRC(hSocket, strMyName, addrFromIRC))
        {
            printf("GetIPFromIRC() returned %s\n", addrFromIRC.ToString().c_str());
            if (addrFromIRC.IsRoutable())
            {
                // IRC lets you to re-nick
                AddLocal(addrFromIRC, LOCAL_IRC);
                strMyName = EncodeAddress(GetLocalAddress(&addrConnect));
                Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str());
            }
        }

        if (fTestNet) {
            Send(hSocket, "JOIN #cosinecoinTEST1\r");
            Send(hSocket, "WHO #cosinecoinTEST2\r");
        } else {
            // randomly join #cosinecoin00-#cosinecoin99
            int channel_number = GetRandInt(100);
            channel_number = 0; // Litecoin: for now, just use one channel
            Send(hSocket, strprintf("JOIN #cosinecoin%02d\r", channel_number).c_str());
            Send(hSocket, strprintf("WHO #cosinecoin%02d\r", channel_number).c_str());
        }

        int64 nStart = GetTime();
        string strLine;
        strLine.reserve(10000);
        while (!fRequestShutdown && RecvLineIRC(hSocket, strLine))
        {
            if (strLine.empty() || strLine.size() > 900 || strLine[0] != ':')
                continue;

            vector<string> vWords;
            ParseString(strLine, ' ', vWords);
            if (vWords.size() < 2)
                continue;

            char pszName[10000];
            pszName[0] = '\0';

            if (vWords[1] == "352" && vWords.size() >= 8)
            {
                // index 7 is limited to 16 characters
                // could get full length name at index 10, but would be different from join messages
                strlcpy(pszName, vWords[7].c_str(), sizeof(pszName));
                printf("IRC got who\n");
            }

            if (vWords[1] == "JOIN" && vWords[0].size() > 1)
            {
                // :username!username@50000007.F000000B.90000002.IP JOIN :#channelname
                strlcpy(pszName, vWords[0].c_str() + 1, sizeof(pszName));
                if (strchr(pszName, '!'))
                    *strchr(pszName, '!') = '\0';
                printf("IRC got join\n");
            }

            if (pszName[0] == 'u')
            {
                CAddress addr;
                if (DecodeAddress(pszName, addr))
                {
                    addr.nTime = GetAdjustedTime();
                    if (addrman.Add(addr, addrConnect, 51 * 60))
                        printf("IRC got new address: %s\n", addr.ToString().c_str());
                    nGotIRCAddresses++;
                }
                else
                {
                    printf("IRC decode failed\n");
                }
            }
        }
        closesocket(hSocket);
        hSocket = INVALID_SOCKET;

        if (GetTime() - nStart > 20 * 60)
        {
            nErrorWait /= 3;
            nRetryWait /= 3;
        }

        nRetryWait = nRetryWait * 11 / 10;
        if (!Wait(nRetryWait += 60))
            return;
    }
}

/***************************************************************************************************
*
*
***************************************************************************************************/
#ifdef TEST
int main(int argc, char *argv[])
{
    WSADATA wsadata;
    if (WSAStartup(MAKEWORD(2,2), &wsadata) != NO_ERROR)
    {
        printf("Error at WSAStartup()\n");
        return false;
    }

    ThreadIRCSeed(NULL);

    WSACleanup();
    return 0;
}
#endif

<commit_msg>trying something new with irc<commit_after>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Copyright (c) 2011-2012 Litecoin Developers
// Copyright (c) 2014 CosineCoin Developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <netdb.h>
#include "irc.h"
#include "net.h"
#include "strlcpy.h"
#include "base58.h"

using namespace std;
using namespace boost;

int nGotIRCAddresses = 0;

void ThreadIRCSeed2(void* parg);
extern volatile bool fRequestShutdown;

#pragma pack(push, 1)
/***************************************************************************************************
*
*
***************************************************************************************************/
struct ircaddr {
    struct in_addr ip;
    short port;
};
#pragma pack(pop)

/***************************************************************************************************
*
*
***************************************************************************************************/
string EncodeAddress(const CService& addr) {
    struct ircaddr tmp;
    if (addr.GetInAddr(&tmp.ip))
    {
        tmp.port = htons(addr.GetPort());

        vector<unsigned char> vch(UBEGIN(tmp), UEND(tmp));
        return string("u") + EncodeBase58Check(vch);
    }
    return "";
}

/***************************************************************************************************
*
*
***************************************************************************************************/
bool DecodeAddress(string str, CService& addr) {
    vector<unsigned char> vch;
    if (!DecodeBase58Check(str.substr(1), vch))
        return false;

    struct ircaddr tmp;
    if (vch.size() != sizeof(tmp))
        return false;
    memcpy(&tmp, &vch[0], sizeof(tmp));

    addr = CService(tmp.ip, ntohs(tmp.port));
    return true;
}

/***************************************************************************************************
*
*
***************************************************************************************************/
static bool Send(SOCKET hSocket, const char* pszSend) {
    if (strstr(pszSend, "PONG") != pszSend)
        printf("IRC SENDING: %s\n", pszSend);
    const char* psz = pszSend;
    const char* pszEnd = psz + strlen(psz);
    while (psz < pszEnd)
    {
        int ret = send(hSocket, psz, pszEnd - psz, MSG_NOSIGNAL);
        if (ret < 0)
            return false;
        psz += ret;
    }
    return true;
}

/***************************************************************************************************
*
*
***************************************************************************************************/
bool RecvLineIRC(SOCKET hSocket, string& strLine) {
    loop
    {
        bool fRet = RecvLine(hSocket, strLine);
        if (fRet)
        {
            if (fRequestShutdown)
                return false;
            vector<string> vWords;
            ParseString(strLine, ' ', vWords);
            if (vWords.size() >= 1 && vWords[0] == "PING")
            {
                strLine[1] = 'O';
                strLine += '\r';
                Send(hSocket, strLine.c_str());
                continue;
            }
        }
        return fRet;
    }
}

/***************************************************************************************************
*
*
***************************************************************************************************/
int RecvUntil(SOCKET hSocket, const char* psz1, const char* psz2=NULL, const char* psz3=NULL, const char* psz4=NULL) {
    loop
    {
        string strLine;
        strLine.reserve(10000);
        if (!RecvLineIRC(hSocket, strLine))
            return 0;
        printf("IRC %s\n", strLine.c_str());
        if (psz1 && strLine.find(psz1) != string::npos)
            return 1;
        if (psz2 && strLine.find(psz2) != string::npos)
            return 2;
        if (psz3 && strLine.find(psz3) != string::npos)
            return 3;
        if (psz4 && strLine.find(psz4) != string::npos)
            return 4;
    }
}

/***************************************************************************************************
*
*
***************************************************************************************************/
bool Wait(int nSeconds) {
    if (fRequestShutdown)
        return false;
    printf("IRC waiting %d seconds to reconnect\n", nSeconds);
    for (int i = 0; i < nSeconds; i++)
    {
        if (fRequestShutdown)
            return false;
        usleep(1000000);
    }
    return true;
}

/***************************************************************************************************
*
*
***************************************************************************************************/
bool RecvCodeLine(SOCKET hSocket, const char* psz1, string& strRet) {
    strRet.clear();
    loop
    {
        string strLine;
        if (!RecvLineIRC(hSocket, strLine))
            return false;

        vector<string> vWords;
        ParseString(strLine, ' ', vWords);
        if (vWords.size() < 2)
            continue;

        if (vWords[1] == psz1)
        {
            printf("IRC %s\n", strLine.c_str());
            strRet = strLine;
            return true;
        }
    }
}

/***************************************************************************************************
*
*
***************************************************************************************************/
bool GetIPFromIRC(SOCKET hSocket, string strMyName, CNetAddr& ipRet) {
    Send(hSocket, strprintf("USERHOST %s\r", strMyName.c_str()).c_str());

    string strLine;
    if (!RecvCodeLine(hSocket, "302", strLine))
        return false;

    vector<string> vWords;
    ParseString(strLine, ' ', vWords);
    if (vWords.size() < 4)
        return false;

    string str = vWords[3];
    if (str.rfind("@") == string::npos)
        return false;
    string strHost = str.substr(str.rfind("@")+1);

    // Hybrid IRC used by lfnet always returns IP when you userhost yourself,
    // but in case another IRC is ever used this should work.
    printf("GetIPFromIRC() got userhost %s\n", strHost.c_str());
    CNetAddr addr(strHost, true);
    if (!addr.IsValid())
        return false;
    ipRet = addr;

    return true;
}

/***************************************************************************************************
*
*
***************************************************************************************************/
void ThreadIRCSeed() {
    //IMPLEMENT_RANDOMIZE_STACK(ThreadIRCSeed(parg));

    // Make this thread recognisable as the IRC seeding thread
    RenameThread("bitcoin-ircseed");

    try
    {
        ThreadIRCSeed2(NULL);
    }
    catch (std::exception& e) {
        PrintExceptionContinue(&e, "ThreadIRCSeed()");
    } catch (...) {
        PrintExceptionContinue(NULL, "ThreadIRCSeed()");
    }
    printf("ThreadIRCSeed exited\n");
}

/***************************************************************************************************
*
*
***************************************************************************************************/
void ThreadIRCSeed2(void* parg) {
    /* Dont advertise on IRC if we don't allow incoming connections */
    if (mapArgs.count("-connect") || fNoListen)
        return;

    if (!GetBoolArg("-irc", false))
        return;

    printf("ThreadIRCSeed started\n");
    int nErrorWait = 10;
    int nRetryWait = 10;

	struct hostent entries;
	struct hostent *result;
	int index = -1;
	int len = 0;
	int err = 0;
	int rc = 0;
	char *buf = NULL;

    while(!fRequestShutdown) {
		if(index < 0) {
			while((rc = gethostbyname_r("irc.lfnet.org", &entries, buf, len, &result, &err)) == ERANGE) {
				/* expand buf */
				len *= 2;
				buf = (char *)realloc(buf, len);
				if(NULL == buf) {
					printf("Memory allocation error during IRC DNS resolution\n");
					Wait(10);
					continue;
				}
			}
			if(0 != rc || NULL == result) {
				printf("Failed to resolve IRC server irc.lfnet.org\n");
				Wait(10);
				continue;
			}
		}

		if(++index >= entries.h_length) {
			index = -1;
			printf("Exhausted all irc IP entries, starting over in 10 seconds\n");
			Wait(10);
			continue;
		}

        //CService addrConnect("92.243.23.21", 6667); // irc.lfnet.org
		struct in_addr *ipptr = (struct in_addr *)entries.h_addr_list[index];
		printf("Trying IRC server %s\n", inet_ntoa(*ipptr));
		CService addrConnect(inet_ntoa(*ipptr), 6667);

        //CService addrIRC("irc.lfnet.org", 6667, true);
        //if(addrIRC.IsValid()) {
		//	printf("Set IRC server irc.lfnet.org\n");
        //    addrConnect = addrIRC;
		//}

        SOCKET hSocket;
        if (!ConnectSocket(addrConnect, hSocket))
        {
            printf("IRC connect failed\n");
            nErrorWait = nErrorWait * 11 / 10;
            if (Wait(nErrorWait += 60))
                continue;
            else
                return;
        }

        if (!RecvUntil(hSocket, "Found your hostname", "using your IP address instead", "Couldn't look up your hostname", "ignoring hostname"))
        {
            closesocket(hSocket);
            hSocket = INVALID_SOCKET;
            nErrorWait = nErrorWait * 11 / 10;
            if (Wait(nErrorWait += 60))
                continue;
            else
                return;
        }

        CNetAddr addrIPv4("1.2.3.4"); // arbitrary IPv4 address to make GetLocal prefer IPv4 addresses
        CService addrLocal;
        string strMyName;
        if (GetLocal(addrLocal, &addrIPv4))
            strMyName = EncodeAddress(GetLocalAddress(&addrConnect));
        if (strMyName == "")
            strMyName = strprintf("x%u", (unsigned int)GetRand(1000000000));

        Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str());
        Send(hSocket, strprintf("USER %s 8 * : %s\r", strMyName.c_str(), strMyName.c_str()).c_str());

        int nRet = RecvUntil(hSocket, " 004 ", " 433 ");
        if (nRet != 1)
        {
            closesocket(hSocket);
            hSocket = INVALID_SOCKET;
            if (nRet == 2)
            {
                printf("IRC name already in use\n");
                Wait(10);
                continue;
            }
            nErrorWait = nErrorWait * 11 / 10;
            if (Wait(nErrorWait += 60))
                continue;
            else
                return;
        }
        usleep(500000);

        // Get our external IP from the IRC server and re-nick before joining the channel
        CNetAddr addrFromIRC;
        if (GetIPFromIRC(hSocket, strMyName, addrFromIRC))
        {
            printf("GetIPFromIRC() returned %s\n", addrFromIRC.ToString().c_str());
            if (addrFromIRC.IsRoutable())
            {
                // IRC lets you to re-nick
                AddLocal(addrFromIRC, LOCAL_IRC);
                strMyName = EncodeAddress(GetLocalAddress(&addrConnect));
                Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str());
            }
        }

        if (fTestNet) {
            Send(hSocket, "JOIN #cosinecoinTEST1\r");
            Send(hSocket, "WHO #cosinecoinTEST2\r");
        } else {
            // randomly join #cosinecoin00-#cosinecoin99
            int channel_number = GetRandInt(100);
            channel_number = 0; // Litecoin: for now, just use one channel
            Send(hSocket, strprintf("JOIN #cosinecoin%02d\r", channel_number).c_str());
            Send(hSocket, strprintf("WHO #cosinecoin%02d\r", channel_number).c_str());
        }

        int64 nStart = GetTime();
        string strLine;
        strLine.reserve(10000);
        while (!fRequestShutdown && RecvLineIRC(hSocket, strLine))
        {
            if (strLine.empty() || strLine.size() > 900 || strLine[0] != ':')
                continue;

            vector<string> vWords;
            ParseString(strLine, ' ', vWords);
            if (vWords.size() < 2)
                continue;

            char pszName[10000];
            pszName[0] = '\0';

            if (vWords[1] == "352" && vWords.size() >= 8)
            {
                // index 7 is limited to 16 characters
                // could get full length name at index 10, but would be different from join messages
                strlcpy(pszName, vWords[7].c_str(), sizeof(pszName));
                printf("IRC got who\n");
            }

            if (vWords[1] == "JOIN" && vWords[0].size() > 1)
            {
                // :username!username@50000007.F000000B.90000002.IP JOIN :#channelname
                strlcpy(pszName, vWords[0].c_str() + 1, sizeof(pszName));
                if (strchr(pszName, '!'))
                    *strchr(pszName, '!') = '\0';
                printf("IRC got join\n");
            }

            if (pszName[0] == 'u')
            {
                CAddress addr;
                if (DecodeAddress(pszName, addr))
                {
                    addr.nTime = GetAdjustedTime();
                    if (addrman.Add(addr, addrConnect, 51 * 60))
                        printf("IRC got new address: %s\n", addr.ToString().c_str());
                    nGotIRCAddresses++;
                }
                else
                {
                    printf("IRC decode failed\n");
                }
            }
        }
        closesocket(hSocket);
        hSocket = INVALID_SOCKET;

        if (GetTime() - nStart > 20 * 60)
        {
            nErrorWait /= 3;
            nRetryWait /= 3;
        }

        nRetryWait = nRetryWait * 11 / 10;
        if (!Wait(nRetryWait += 60))
            return;
    }

	if(buf)
		free(buf);
}

/***************************************************************************************************
*
*
***************************************************************************************************/
#ifdef TEST
int main(int argc, char *argv[])
{
    WSADATA wsadata;
    if (WSAStartup(MAKEWORD(2,2), &wsadata) != NO_ERROR)
    {
        printf("Error at WSAStartup()\n");
        return false;
    }

    ThreadIRCSeed(NULL);

    WSACleanup();
    return 0;
}
#endif

<|endoftext|>


<commit_before>/*
 *  Author(s):
 *  - Chris  Kilner <ckilner@aldebaran-robotics.com>
 *  - Cedric Gestes <gestes@aldebaran-robotics.com>
 *
 *  Copyright (C) 2010, 2011 Aldebaran Robotics
 */

#include <qi/log.hpp>
#include <qi/os.hpp>
#include <list>
#include <map>

#include <qi/log/consoleloghandler.hpp>

#include <boost/thread/thread.hpp>
#include <boost/thread/condition_variable.hpp>
#include <boost/lockfree/fifo.hpp>
#include <boost/function.hpp>

#define RTLOG_BUFFERS (128)

#define CAT_SIZE 64
#define FILE_SIZE 128
#define FUNC_SIZE 64
#define LOG_SIZE 2048

namespace qi {
  namespace log {
    static LogLevel _glVerbosity = qi::log::info;
    static bool _glContext = false;
    static bool _glSyncLog = false;

    typedef struct sPrivateLog
    {
      LogLevel _logLevel;
      char     _category[CAT_SIZE];
      char     _file[FILE_SIZE];
      char     _function[FUNC_SIZE];
      int      _line;
      char     _log[LOG_SIZE];
    } privateLog;

    static privateLog             rtLogBuffer[RTLOG_BUFFERS];
    static volatile unsigned long rtLogPush = 0;

    static ConsoleLogHandler gConsoleLogHandler;

    static class rtLog
    {
    public:
      inline rtLog();
      inline ~rtLog();

      void run();
      void printLog();

    public:
      bool                       rtLogInit;
      boost::thread              rtLogThread;
      boost::mutex               rtLogWriteLock;
      boost::condition_variable  rtLogReadyCond;

      boost::lockfree::fifo<privateLog*>     logs;
      std::map<std::string, logFuncHandler > logHandlers;
    } rtLogInstance;

    void rtLog::printLog()
    {
      privateLog* pl;
      while (logs.dequeue(&pl))
      {
        boost::mutex::scoped_lock lock(rtLogWriteLock);
        if (!logHandlers.empty())
        {
          std::map<std::string, logFuncHandler >::iterator it;
          for (it = logHandlers.begin();
               it != logHandlers.end(); ++it)
          {
            (*it).second(pl->_logLevel,
                         pl->_category,
                         pl->_log,
                         pl->_file,
                         pl->_function,
                         pl->_line);
          }
        }
      }
    }

    void rtLog::run()
    {
      while (rtLogInit)
      {
        {
          boost::mutex::scoped_lock lock(rtLogWriteLock);
          rtLogReadyCond.wait(lock);
        }

        printLog();
      }
    };

    inline rtLog::rtLog()
    {
      rtLogInit = true;
      rtLogThread = boost::thread(&rtLog::run, &rtLogInstance);
    };

    inline rtLog::~rtLog()
    {
      if (!rtLogInit)
        return;

      rtLogInit = false;

      rtLogReadyCond.notify_one();
      if (rtLogThread.joinable())
      {
        rtLogThread.join();
      }

      printLog();
    }

    static void my_strcpy(char *dst, const char *src, int len) {
      if (!src)
        src = "(null)";
     #ifdef _MSV_VER
      strncpy_s(dst, len, src, _TRUNCATE);
     #else
      strncpy(dst, src, len);
      dst[len - 1] = 0;
     #endif
    }

    void log(const LogLevel    verb,
             const char       *category,
             const char       *msg,
             const char       *file,
             const char       *fct,
             const int         line)

    {
      if (!rtLogInstance.rtLogInit)
        return;

      int tmpRtLogPush = ++rtLogPush % RTLOG_BUFFERS;
      privateLog* pl = &(rtLogBuffer[tmpRtLogPush]);

      pl->_logLevel = verb;
      pl->_line = line;

      my_strcpy(pl->_category, category, CAT_SIZE);
      my_strcpy(pl->_file, file, FILE_SIZE);
      my_strcpy(pl->_function, fct, FUNC_SIZE);
      my_strcpy(pl->_log, msg, LOG_SIZE);

      if (_glSyncLog)
      {
        if (!rtLogInstance.logHandlers.empty())
        {
          std::map<std::string, logFuncHandler >::iterator it;
          for (it = rtLogInstance.logHandlers.begin();
               it != rtLogInstance.logHandlers.end(); ++it)
          {
            (*it).second(pl->_logLevel,
                         pl->_category,
                         pl->_log,
                         pl->_file,
                         pl->_function,
                         pl->_line);
          }
        }
      }
      else
      {
        rtLogInstance.logs.enqueue(pl);
        rtLogInstance.rtLogReadyCond.notify_one();
      }
    }

    void consoleLogHandler(const LogLevel    verb,
                           const char       *category,
                           const char       *msg,
                           const char       *file,
                           const char       *fct,
                           const int         line)
    {
      gConsoleLogHandler.log(verb, category, msg, file, fct, line);
    }

    static class LogHandlerInit
    {
    public:
      LogHandlerInit()
      {
        addLogHandler(consoleLogHandler, "consoleloghandler");
      }
    } gLogHandlerInit;

    void addLogHandler(logFuncHandler fct, const std::string& name)
    {
      {
        boost::mutex::scoped_lock l(rtLogInstance.rtLogWriteLock);
        rtLogInstance.logHandlers[name] = fct;
      }
    }

    void removeLogHandler(const std::string& name)
    {
      {
        boost::mutex::scoped_lock l(rtLogInstance.rtLogWriteLock);
        rtLogInstance.logHandlers.erase(name);
      }
    }

    const LogLevel stringToLogLevel(const char* verb)
    {
      std::string v(verb);
      if (v == "silent")
        return qi::log::silent;
      if (v == "fatal")
        return qi::log::fatal;
      if (v == "error")
        return qi::log::error;
      if (v == "warning")
        return qi::log::warning;
      if (v == "info")
        return qi::log::info;
      if (v == "verbose")
        return qi::log::verbose;
      if (v == "debug")
        return qi::log::debug;
      return qi::log::info;
    }

    const char *logLevelToString(const LogLevel verb)
    {
      static const char *sverb[] = {
        "[SILENT]", // never shown
        "[FATAL]",
        "[ERROR]",
        "[WARN ]",
        "[INFO ]",
        "[VERB ]",
        "[DEBUG]"
      };
      return sverb[verb];
    }

    void setVerbosity(const LogLevel lv)
    {
      const char *verbose = std::getenv("VERBOSE");

      if (verbose)
        _glVerbosity = (LogLevel)atoi(verbose);
      else
        _glVerbosity = lv;
    };

    LogLevel getVerbosity()
    {
      return _glVerbosity;
    };

    void setContext(bool ctx)
    {
      const char *context = std::getenv("CONTEXT");

      if (context)
        _glContext = (atoi(context) > 0 ? true : false);
      else
        _glContext = ctx;
    };

    bool getContext()
    {
      return _glContext;
    };

    void setSyncLog(bool sync)
    {
      _glSyncLog = sync;
    };

  } // namespace log
} // namespace qi

<commit_msg>Fix issue #4374 nice race condition fix in rtLog dtor<commit_after>/*
 *  Author(s):
 *  - Chris  Kilner <ckilner@aldebaran-robotics.com>
 *  - Cedric Gestes <gestes@aldebaran-robotics.com>
 *
 *  Copyright (C) 2010, 2011 Aldebaran Robotics
 */

#include <qi/log.hpp>
#include <qi/os.hpp>
#include <list>
#include <map>

#include <qi/log/consoleloghandler.hpp>

#include <boost/thread/thread.hpp>
#include <boost/thread/condition_variable.hpp>
#include <boost/lockfree/fifo.hpp>
#include <boost/function.hpp>

#define RTLOG_BUFFERS (128)

#define CAT_SIZE 64
#define FILE_SIZE 128
#define FUNC_SIZE 64
#define LOG_SIZE 2048

namespace qi {
  namespace log {
    static LogLevel _glVerbosity = qi::log::info;
    static bool _glContext = false;
    static bool _glSyncLog = false;

    typedef struct sPrivateLog
    {
      LogLevel _logLevel;
      char     _category[CAT_SIZE];
      char     _file[FILE_SIZE];
      char     _function[FUNC_SIZE];
      int      _line;
      char     _log[LOG_SIZE];
    } privateLog;

    static privateLog             rtLogBuffer[RTLOG_BUFFERS];
    static volatile unsigned long rtLogPush = 0;

    static ConsoleLogHandler gConsoleLogHandler;

    static class rtLog
    {
    public:
      inline rtLog();
      inline ~rtLog();

      void run();
      void printLog();

    public:
      bool                       rtLogInit;
      boost::thread              rtLogThread;
      boost::mutex               rtLogWriteLock;
      boost::condition_variable  rtLogReadyCond;

      boost::lockfree::fifo<privateLog*>     logs;
      std::map<std::string, logFuncHandler > logHandlers;
    } rtLogInstance;

    void rtLog::printLog()
    {
      privateLog* pl;
      while (logs.dequeue(&pl))
      {
        boost::mutex::scoped_lock lock(rtLogWriteLock);
        if (!logHandlers.empty())
        {
          std::map<std::string, logFuncHandler >::iterator it;
          for (it = logHandlers.begin();
               it != logHandlers.end(); ++it)
          {
            (*it).second(pl->_logLevel,
                         pl->_category,
                         pl->_log,
                         pl->_file,
                         pl->_function,
                         pl->_line);
          }
        }
      }
    }

    void rtLog::run()
    {
      while (rtLogInit)
      {
        {
          boost::mutex::scoped_lock lock(rtLogWriteLock);
          rtLogReadyCond.wait(lock);
        }

        printLog();
      }
    };

    inline rtLog::rtLog()
    {
      rtLogInit = true;
      rtLogThread = boost::thread(&rtLog::run, &rtLogInstance);
    };

    inline rtLog::~rtLog()
    {
      if (!rtLogInit)
        return;

      rtLogInit = false;

      rtLogThread.interrupt();
      rtLogThread.join();

      printLog();
    }

    static void my_strcpy(char *dst, const char *src, int len) {
      if (!src)
        src = "(null)";
     #ifdef _MSV_VER
      strncpy_s(dst, len, src, _TRUNCATE);
     #else
      strncpy(dst, src, len);
      dst[len - 1] = 0;
     #endif
    }

    void log(const LogLevel    verb,
             const char       *category,
             const char       *msg,
             const char       *file,
             const char       *fct,
             const int         line)

    {
      if (!rtLogInstance.rtLogInit)
        return;

      int tmpRtLogPush = ++rtLogPush % RTLOG_BUFFERS;
      privateLog* pl = &(rtLogBuffer[tmpRtLogPush]);

      pl->_logLevel = verb;
      pl->_line = line;

      my_strcpy(pl->_category, category, CAT_SIZE);
      my_strcpy(pl->_file, file, FILE_SIZE);
      my_strcpy(pl->_function, fct, FUNC_SIZE);
      my_strcpy(pl->_log, msg, LOG_SIZE);

      if (_glSyncLog)
      {
        if (!rtLogInstance.logHandlers.empty())
        {
          std::map<std::string, logFuncHandler >::iterator it;
          for (it = rtLogInstance.logHandlers.begin();
               it != rtLogInstance.logHandlers.end(); ++it)
          {
            (*it).second(pl->_logLevel,
                         pl->_category,
                         pl->_log,
                         pl->_file,
                         pl->_function,
                         pl->_line);
          }
        }
      }
      else
      {
        rtLogInstance.logs.enqueue(pl);
        rtLogInstance.rtLogReadyCond.notify_one();
      }
    }

    void consoleLogHandler(const LogLevel    verb,
                           const char       *category,
                           const char       *msg,
                           const char       *file,
                           const char       *fct,
                           const int         line)
    {
      gConsoleLogHandler.log(verb, category, msg, file, fct, line);
    }

    static class LogHandlerInit
    {
    public:
      LogHandlerInit()
      {
        addLogHandler(consoleLogHandler, "consoleloghandler");
      }
    } gLogHandlerInit;

    void addLogHandler(logFuncHandler fct, const std::string& name)
    {
      {
        boost::mutex::scoped_lock l(rtLogInstance.rtLogWriteLock);
        rtLogInstance.logHandlers[name] = fct;
      }
    }

    void removeLogHandler(const std::string& name)
    {
      {
        boost::mutex::scoped_lock l(rtLogInstance.rtLogWriteLock);
        rtLogInstance.logHandlers.erase(name);
      }
    }

    const LogLevel stringToLogLevel(const char* verb)
    {
      std::string v(verb);
      if (v == "silent")
        return qi::log::silent;
      if (v == "fatal")
        return qi::log::fatal;
      if (v == "error")
        return qi::log::error;
      if (v == "warning")
        return qi::log::warning;
      if (v == "info")
        return qi::log::info;
      if (v == "verbose")
        return qi::log::verbose;
      if (v == "debug")
        return qi::log::debug;
      return qi::log::info;
    }

    const char *logLevelToString(const LogLevel verb)
    {
      static const char *sverb[] = {
        "[SILENT]", // never shown
        "[FATAL]",
        "[ERROR]",
        "[WARN ]",
        "[INFO ]",
        "[VERB ]",
        "[DEBUG]"
      };
      return sverb[verb];
    }

    void setVerbosity(const LogLevel lv)
    {
      const char *verbose = std::getenv("VERBOSE");

      if (verbose)
        _glVerbosity = (LogLevel)atoi(verbose);
      else
        _glVerbosity = lv;
    };

    LogLevel getVerbosity()
    {
      return _glVerbosity;
    };

    void setContext(bool ctx)
    {
      const char *context = std::getenv("CONTEXT");

      if (context)
        _glContext = (atoi(context) > 0 ? true : false);
      else
        _glContext = ctx;
    };

    bool getContext()
    {
      return _glContext;
    };

    void setSyncLog(bool sync)
    {
      _glSyncLog = sync;
    };

  } // namespace log
} // namespace qi

<|endoftext|>


<commit_before>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Sergio Checa Blanco
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
*/

#include "shell_parser_tree.h"

#include <iostream>

#define LOAD_CLI_CMD(cmdStr, text, func)                                \
    do {                                                                \
        cli::CliCmd* cliCmd = new cli::CliCmd{text, func};              \
        if (!commands.loadCommand(cmdStr, cliCmd)) delete cliCmd;       \
    } while(0);

static bool gStop = false;

static std::vector<std::string> tokenize(const std::string& input);

static void help(const std::string& args);
static void exit(const std::string& args);

int main()
{
    cli::CliCmdTree commands;

    LOAD_CLI_CMD("help", "Help", &::help);
    LOAD_CLI_CMD("quit", "Exit", (void(*)(const std::string&))&::exit);
    LOAD_CLI_CMD("exit", "Exit", (void(*)(const std::string&))&::exit);

    std::string line;

    while (!gStop && !std::cin.eof()) {
        std::cout << "shellapp> ";
        std::getline(std::cin, line);

        if (!line.empty()) {
            auto tokens = tokenize(line);
            for (auto const& completion : commands.execute(tokens[0]))
                std::cout << tokens[0] << completion << std::endl;
        }
    }

    return 0;
}

std::vector<std::string> tokenize(const std::string& input)
{
    std::vector<std::string> tokens;
    size_t len = input.length();
    size_t pos = 0;
    size_t next = 0;

    do {
        next = input.find_first_of(' ', pos);
        if (next-pos > 0 && pos < len)
            tokens.push_back(input.substr(pos, next-pos));
        pos = next + 1;
    } while (next != std::string::npos);

    return tokens;
}

//====================================================================
//
// Definition of command handlers
//
//====================================================================

void help(const std::string& args)
{
    std::cout << "Help" << std::endl;
}

void exit(const std::string& args)
{
    std::cout << "Bye!" << std::endl;
    gStop = true;
}
<commit_msg>shell: Rename exit function into quit<commit_after>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Sergio Checa Blanco
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
*/

#include "shell_parser_tree.h"

#include <iostream>

#define LOAD_CLI_CMD(cmdStr, text, func)                                \
    do {                                                                \
        cli::CliCmd* cliCmd = new cli::CliCmd{text, func};              \
        if (!commands.loadCommand(cmdStr, cliCmd)) delete cliCmd;       \
    } while(0);

static bool gStop = false;

static std::vector<std::string> tokenize(const std::string& input);

static void help(const std::string& args);
static void quit(const std::string& args);

int main()
{
    cli::CliCmdTree commands;

    LOAD_CLI_CMD("help", "Help", &::help);
    LOAD_CLI_CMD("quit", "Exit", &::quit);
    LOAD_CLI_CMD("exit", "Exit", &::quit);

    std::string line;

    while (!gStop && !std::cin.eof()) {
        std::cout << "shellapp> ";
        std::getline(std::cin, line);

        if (!line.empty()) {
            auto tokens = tokenize(line);
            for (auto const& completion : commands.execute(tokens[0]))
                std::cout << tokens[0] << completion << std::endl;
        }
    }

    return 0;
}

std::vector<std::string> tokenize(const std::string& input)
{
    std::vector<std::string> tokens;
    size_t len = input.length();
    size_t pos = 0;
    size_t next = 0;

    do {
        next = input.find_first_of(' ', pos);
        if (next-pos > 0 && pos < len)
            tokens.push_back(input.substr(pos, next-pos));
        pos = next + 1;
    } while (next != std::string::npos);

    return tokens;
}

//====================================================================
//
// Definition of command handlers
//
//====================================================================

void help(const std::string& args)
{
    std::cout << "Help" << std::endl;
}

void quit(const std::string& args)
{
    std::cout << "Bye!" << std::endl;
    gStop = true;
}
<|endoftext|>


<commit_before> /**
 * Copyright (C) 2014 Lantern
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "natty.h"
#include "peer_connection_client.h"

#include "talk/base/thread.h"

class NattySocket : public talk_base::PhysicalSocketServer {
 public:
  NattySocket(talk_base::Thread* thread)
      : thread_(thread), natty_(NULL), client_(NULL) {}
  virtual ~NattySocket() {}

  void set_client(PeerConnectionClient* client) { client_ = client; }
  void set_natty(Natty* natty) { natty_ = natty; }
  Natty* get_natty() { return natty_; }

  virtual bool Wait(int cms, bool process_io) {
    //if (!natty_->connection_active() ||
    if (client_ == NULL) {
        //client_ == NULL || !client_->is_connected()) {
      printf("quitting..\n");
      thread_->Quit();
    }
    return talk_base::PhysicalSocketServer::Wait(-1,
                                                 process_io);
  }

 protected:
  talk_base::Thread* thread_;
  Natty* natty_;
  PeerConnectionClient* client_;
};

int main(int argc, char* argv[]) {
  PeerConnectionClient client;
  talk_base::Thread* thread = talk_base::Thread::Current();
  talk_base::scoped_refptr<Natty> natty(
      new talk_base::RefCountedObject<Natty>(&client, thread));

  NattySocket socket_server(thread);
  //talk_base::PhysicalSocketServer* pss = new talk_base::PhysicalSocketServer();
  thread->set_socketserver(&socket_server);
  //thread->set_socketserver(pss);

  socket_server.set_client(natty->GetClient());
  socket_server.set_natty(natty);

  natty->SetupSocketServer();
  thread->Run();

  return 0;
}

<commit_msg>accept server port parameters<commit_after> /**
 * Copyright (C) 2014 Lantern
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "natty.h"
#include "peer_connection_client.h"

#include "talk/base/thread.h"
#include "flagdefs.h"

const uint16 kDefaultServerPort = 8888;

class NattySocket : public talk_base::PhysicalSocketServer {
 public:
  NattySocket(talk_base::Thread* thread)
      : thread_(thread), natty_(NULL), client_(NULL) {}
  virtual ~NattySocket() {}

  void set_client(PeerConnectionClient* client) { client_ = client; }
  void set_natty(Natty* natty) { natty_ = natty; }
  Natty* get_natty() { return natty_; }

  virtual bool Wait(int cms, bool process_io) {
    //if (!natty_->connection_active() ||
    if (client_ == NULL) {
        //client_ == NULL || !client_->is_connected()) {
      printf("quitting..\n");
      thread_->Quit();
    }
    return talk_base::PhysicalSocketServer::Wait(-1,
                                                 process_io);
  }

 protected:
  talk_base::Thread* thread_;
  Natty* natty_;
  PeerConnectionClient* client_;
};

int main(int argc, char* argv[]) {

  FlagList::SetFlagsFromCommandLine(&argc, argv, true);
  if (FLAG_help) {
    FlagList::Print(NULL, false);
    return 0;
  }

  // Abort if the user specifies a port that is outside the allowed
  // range [1, 65535].
  if ((FLAG_port < 1) || (FLAG_port > 65535)) {
    printf("Error: %i is not a valid port.\n", FLAG_port);
    return -1;
  }

  PeerConnectionClient client;
  talk_base::Thread* thread = talk_base::Thread::Current();
  talk_base::scoped_refptr<Natty> natty(
      new talk_base::RefCountedObject<Natty>(&client, thread, FLAG_server, FLAG_port));

  NattySocket socket_server(thread);
  //talk_base::PhysicalSocketServer* pss = new talk_base::PhysicalSocketServer();
  thread->set_socketserver(&socket_server);
  //thread->set_socketserver(pss);

  socket_server.set_client(natty->GetClient());
  socket_server.set_natty(natty);

  natty->SetupSocketServer();
  thread->Run();

  return 0;
}

<|endoftext|>


<commit_before>#include "nan.h"
using namespace v8;

#include "runas.h"

namespace {

NAN_METHOD(Runas) {
  NanScope();

  if (!args[0]->IsString() || !args[1]->IsArray() || !args[2]->IsObject())
    return NanThrowTypeError("Bad argument");

  std::string command(*String::Utf8Value(args[0]));
  std::vector<std::string> c_args;

  Handle<Array> v_args = Handle<Array>::Cast(args[1]);
  uint32_t length = v_args->Length();

  c_args.reserve(length);
  for (uint32_t i = 0; i < length; ++i) {
    std::string arg(*String::Utf8Value(v_args->Get(i)));
    c_args.push_back(arg);
  }

  Handle<Object> v_options = args[2]->ToObject();
  int options = runas::OPTION_NONE;
  if (v_options->Get(NanNew<String>("hide"))->BooleanValue())
    options |= runas::OPTION_HIDE;
  if (v_options->Get(NanNew<String>("admin"))->BooleanValue())
    options |= runas::OPTION_ADMIN;

  std::string std_input;
  Handle<Value> v_stdin = v_options->Get(NanNew<String>("stdin"));
  if (!v_stdin->IsUndefined())
    std_input = *String::Utf8Value(v_stdin);

  std::string std_output;
  int code = -1;
  runas::Runas(command, c_args, std_input, &std_output, options, &code);
  NanReturnValue(NanNew<Integer>(code));
}

void Init(Handle<Object> exports) {
  NODE_SET_METHOD(exports, "runas", Runas);
}

}  // namespace

NODE_MODULE(runas, Init)
<commit_msg>Add "stdout" option in JS<commit_after>#include "nan.h"
using namespace v8;

#include "runas.h"

namespace {

NAN_METHOD(Runas) {
  NanScope();

  if (!args[0]->IsString() || !args[1]->IsArray() || !args[2]->IsObject())
    return NanThrowTypeError("Bad argument");

  std::string command(*String::Utf8Value(args[0]));
  std::vector<std::string> c_args;

  Handle<Array> v_args = Handle<Array>::Cast(args[1]);
  uint32_t length = v_args->Length();

  c_args.reserve(length);
  for (uint32_t i = 0; i < length; ++i) {
    std::string arg(*String::Utf8Value(v_args->Get(i)));
    c_args.push_back(arg);
  }

  Handle<Object> v_options = args[2]->ToObject();
  int options = runas::OPTION_NONE;
  if (v_options->Get(NanNew<String>("hide"))->BooleanValue())
    options |= runas::OPTION_HIDE;
  if (v_options->Get(NanNew<String>("admin"))->BooleanValue())
    options |= runas::OPTION_ADMIN;

  std::string std_input;
  Handle<Value> v_stdin = v_options->Get(NanNew<String>("stdin"));
  if (!v_stdin->IsUndefined())
    std_input = *String::Utf8Value(v_stdin);

  std::string std_output;
  bool need_stdout = v_options->Get(NanNew<String>("stdout"))->BooleanValue();

  int code = -1;
  runas::Runas(command, c_args, std_input, need_stdout ? &std_output : NULL, options, &code);

  if (need_stdout && code == 0)
    NanReturnValue(NanNew<String>(std_output.data(), std_output.size()));
  else
    NanReturnValue(NanNew<Integer>(code));
}

void Init(Handle<Object> exports) {
  NODE_SET_METHOD(exports, "runas", Runas);
}

}  // namespace

NODE_MODULE(runas, Init)
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: EnumPropertyHdl.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: sab $ $Date: 2001-03-16 14:37:07 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

#ifndef _XMLOFF_ENUMPROPERTYHANDLER_HXX
#include <EnumPropertyHdl.hxx>
#endif

#ifndef _XMLOFF_XMLUCONV_HXX
#include "xmluconv.hxx"
#endif

#ifndef _COMPHELPER_EXTRACT_HXX_
#include <comphelper/extract.hxx>
#endif

#ifndef _RTL_USTRING_
#include <rtl/ustring>
#endif

#ifndef _RTL_USTRBUF_HXX_
#include <rtl/ustrbuf.hxx>
#endif

/*
#ifndef _VCL_VCLENUM_HXX
#include <vcl/vclenum.hxx>
#endif

#ifndef _SOLAR_H
#include <tools/solar.h>
#endif

#ifndef _INC_LIMITS
#include <limits.h>
#endif

#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
#include <toolkit/unohlp.hxx>
#endif
*/

#ifndef _COM_SUN_STAR_UNO_ANY_HXX_
#include <com/sun/star/uno/Any.hxx>
#endif

using namespace ::rtl;
using namespace ::com::sun::star::uno;

///////////////////////////////////////////////////////////////////////////////
//
// class XMLEnumPropertyHdl
//

XMLEnumPropertyHdl::~XMLEnumPropertyHdl()
{
    // Nothing to do
}

sal_Bool XMLEnumPropertyHdl::importXML( const OUString& rStrImpValue, Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const
{
    USHORT nValue = 0;

    if( SvXMLUnitConverter::convertEnum( nValue, rStrImpValue, mpEnumMap ) )
    {
        switch( mrType.getTypeClass() )
        {
        case TypeClass_ENUM:
            rValue = ::cppu::int2enum( nValue, mrType );
            break;
        case TypeClass_LONG:
            rValue <<= (sal_Int32) nValue;
            break;
        case TypeClass_SHORT:
            rValue <<= (sal_Int16) nValue;
            break;
        case TypeClass_BYTE:
            rValue <<= (sal_Int8) nValue;
            break;
        default:
            DBG_ERROR( "Wrong type for enum property handler!" );
            return sal_False;
        }
        return sal_True;
    }

    return sal_False;
}

sal_Bool XMLEnumPropertyHdl::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const
{
    sal_Int32 nValue;
    if(!(rValue >>= nValue ))
        if(!::cppu::enum2int(nValue, rValue) )
            return sal_False;

    OUStringBuffer aOut;

    if(!SvXMLUnitConverter::convertEnum( aOut, nValue, mpEnumMap ))
        return sal_False;

    rStrExpValue = aOut.makeStringAndClear();
    return sal_True;
}

<commit_msg>INTEGRATION: CWS ooo19126 (1.3.642); FILE MERGED 2005/09/05 14:39:10 rt 1.3.642.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: EnumPropertyHdl.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 14:23:00 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

#ifndef _XMLOFF_ENUMPROPERTYHANDLER_HXX
#include <EnumPropertyHdl.hxx>
#endif

#ifndef _XMLOFF_XMLUCONV_HXX
#include "xmluconv.hxx"
#endif

#ifndef _COMPHELPER_EXTRACT_HXX_
#include <comphelper/extract.hxx>
#endif

#ifndef _RTL_USTRING_
#include <rtl/ustring>
#endif

#ifndef _RTL_USTRBUF_HXX_
#include <rtl/ustrbuf.hxx>
#endif

/*
#ifndef _VCL_VCLENUM_HXX
#include <vcl/vclenum.hxx>
#endif

#ifndef _SOLAR_H
#include <tools/solar.h>
#endif

#ifndef _INC_LIMITS
#include <limits.h>
#endif

#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
#include <toolkit/unohlp.hxx>
#endif
*/

#ifndef _COM_SUN_STAR_UNO_ANY_HXX_
#include <com/sun/star/uno/Any.hxx>
#endif

using namespace ::rtl;
using namespace ::com::sun::star::uno;

///////////////////////////////////////////////////////////////////////////////
//
// class XMLEnumPropertyHdl
//

XMLEnumPropertyHdl::~XMLEnumPropertyHdl()
{
    // Nothing to do
}

sal_Bool XMLEnumPropertyHdl::importXML( const OUString& rStrImpValue, Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const
{
    USHORT nValue = 0;

    if( SvXMLUnitConverter::convertEnum( nValue, rStrImpValue, mpEnumMap ) )
    {
        switch( mrType.getTypeClass() )
        {
        case TypeClass_ENUM:
            rValue = ::cppu::int2enum( nValue, mrType );
            break;
        case TypeClass_LONG:
            rValue <<= (sal_Int32) nValue;
            break;
        case TypeClass_SHORT:
            rValue <<= (sal_Int16) nValue;
            break;
        case TypeClass_BYTE:
            rValue <<= (sal_Int8) nValue;
            break;
        default:
            DBG_ERROR( "Wrong type for enum property handler!" );
            return sal_False;
        }
        return sal_True;
    }

    return sal_False;
}

sal_Bool XMLEnumPropertyHdl::exportXML( OUString& rStrExpValue, const Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const
{
    sal_Int32 nValue;
    if(!(rValue >>= nValue ))
        if(!::cppu::enum2int(nValue, rValue) )
            return sal_False;

    OUStringBuffer aOut;

    if(!SvXMLUnitConverter::convertEnum( aOut, nValue, mpEnumMap ))
        return sal_False;

    rStrExpValue = aOut.makeStringAndClear();
    return sal_True;
}

<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include "brandes.h"
#include "graph.h"
#include "utils.h"

int main(int argc, char* argv[])
{
    if (argc != 4) {
        std::cerr << "[ERROR] "
                  << "Invalid parameters!" << std::endl;
        return -1;
    }

    int threads = std::stoi(argv[1]);

    std::ifstream in_file;
    std::ofstream out_file;

    in_file.open(argv[2]);
    out_file.open(argv[3]);

    if (!in_file.good()) {
        std::cerr << "[ERROR] "
                  << "Error while opening input file" << std::endl;
        return -1;
    }

    if (!out_file.good()) {
        std::cerr << "[ERROR] "
                  << "Error while opening output file" << std::endl;
        return -1;
    }

    Graph<int> g;
    loadGraph(in_file, g);
    in_file.close();

    Brandes<int> brandes(g);
    brandes.run(threads);

    for (auto p : brandes.get_result_vector()) {
        out_file << p.first << " " << p.second << std::endl;
    }
    out_file.close();
}
<commit_msg>Add some error logging<commit_after>#include <iostream>
#include <fstream>
#include <string>
#include "brandes.h"
#include "graph.h"
#include "utils.h"

int main(int argc, char* argv[])
{
    if (argc != 4) {
        std::cerr << "Invalid parameters!" << std::endl
                  << "Usage: " << argv[0] << " [number of threads] [input file] [output file]" << std::endl;

        return -1;
    }

    int threads = std::stoi(argv[1]);

    if (threads <= 0) {
        std::cerr << "Number of threads must be more than 0" << std::endl;
        return -1;
    }

    std::ifstream in_file;
    std::ofstream out_file;

    in_file.open(argv[2]);
    out_file.open(argv[3]);

    if (!in_file.good()) {
        std::cerr << "[ERROR] "
                  << "Error while opening input file" << std::endl;
        return -1;
    }

    if (!out_file.good()) {
        std::cerr << "[ERROR] "
                  << "Error while opening output file" << std::endl;
        return -1;
    }

    Graph<int> g;
    loadGraph(in_file, g);
    in_file.close();

    Brandes<int> brandes(g);
    brandes.run(threads);

    for (auto p : brandes.get_result_vector()) {
        out_file << p.first << " " << p.second << std::endl;
    }
    out_file.close();
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: multisigdemo.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-05-18 10:01:39 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <stdio.h>
#include "util.hxx"

#include <rtl/ustring.hxx>
#include <cppuhelper/servicefactory.hxx>

#include <xmlsecurity/biginteger.hxx>
#include <xmlsecurity/xmlsignaturehelper.hxx>

#include <tools/date.hxx>
#include <tools/time.hxx>

using namespace ::com::sun::star;

long denyVerifyHandler( void *, void * )
{
    return  0;
}

long startVerifyHandler( void *, void * )
{
    return QueryVerifySignature();
}

int SAL_CALL main( int argc, char **argv )
{
    if( argc < 5 )
    {
        fprintf( stderr, "Usage: %s <signature file 1> <signature file 2> <xml stream file> <binary stream file> [<cryptoken>]\n" , argv[0] ) ;
        return -1 ;
    }

    uno::Reference< lang::XMultiServiceFactory > xMSF = CreateDemoServiceFactory();

    rtl::OUString aSIGFileName = rtl::OUString::createFromAscii(argv[1]);
    rtl::OUString aSIGFileName2 = rtl::OUString::createFromAscii(argv[2]);
    rtl::OUString aXMLFileName = rtl::OUString::createFromAscii(argv[3]);
    rtl::OUString aBINFileName = rtl::OUString::createFromAscii(argv[4]);
    rtl::OUString aCryptoToken;
    if ( argc >= 7 )
        aCryptoToken = rtl::OUString::createFromAscii(argv[6]);

    sal_Int32 nSecurityId;
    uno::Reference< io::XOutputStream > xOutputStream;
    uno::Reference< io::XInputStream > xInputStream;
    bool bDone;
    SignatureInformations signatureInformations;
    uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler> xDocumentHandler;

    // -------- START -------

    XMLSignatureHelper aSignatureHelper( xMSF );

    bool bInit = aSignatureHelper.Init( aCryptoToken );
    if ( !bInit )
    {
        fprintf( stderr, "Error initializing security context!\n" );
        return -1;
    }

    fprintf( stdout, "\n\nTEST MISSION 1: Create the first signature file\n");

    aSignatureHelper.StartMission();

    /*
     * select a private key certificate
     */
    uno::Reference< xml::crypto::XSecurityEnvironment > xSecurityEnvironment = aSignatureHelper.GetSecurityEnvironment();
    uno::Sequence< uno::Reference< ::com::sun::star::security::XCertificate > > xPersonalCerts = xSecurityEnvironment->getPersonalCertificates() ;

    fprintf( stdout, "\nPlease select two certificates:\n" );

    for ( int nSig = 0; nSig < 2; nSig++ )
    {
        // New security ID for signature...
        nSecurityId = aSignatureHelper.GetNewSecurityId();

        // Select certificate...
        uno::Reference< ::com::sun::star::security::XCertificate > xPersonalCert = getCertificateFromEnvironment( xSecurityEnvironment, true );
        aSignatureHelper.SetX509Certificate( nSecurityId, xPersonalCert->getIssuerName(), bigIntegerToNumericString( xPersonalCert->getSerialNumber()));
        aSignatureHelper.AddForSigning( nSecurityId, aXMLFileName, aXMLFileName, sal_False );
        aSignatureHelper.AddForSigning( nSecurityId, aBINFileName, aBINFileName, sal_True );
        aSignatureHelper.SetDateTime( nSecurityId, Date(), Time() );
    }
    /*
     * creates signature
     */
    xOutputStream = OpenOutputStream( aSIGFileName );
    bDone = aSignatureHelper.CreateAndWriteSignature( xOutputStream );
    if ( !bDone )
        fprintf( stderr, "\nSTATUS MISSION 1: Error creating Signature!\n" );
    else
        fprintf( stdout, "\nSTATUS MISSION 1: Signature successfully created!\n" );

    aSignatureHelper.EndMission();

    fprintf( stdout, "\n\nTEST MISSION 2: Transfer the second signature to a new signature file\n");

    /*
     * You can use an uninitialized SignatureHelper to perform this mission.
     */

    /*
     * configures the start-verify handler. Don't need to verify for transfering...
     */
    aSignatureHelper.SetStartVerifySignatureHdl( Link( NULL, denyVerifyHandler ) );
    aSignatureHelper.StartMission();

    xInputStream = OpenInputStream( aSIGFileName );
    bDone = aSignatureHelper.ReadAndVerifySignature( xInputStream );
    xInputStream->closeInput();

    if ( !bDone )
        fprintf( stderr, "\nSTATUS MISSION 2: Error in reading Signature!\n" );
    else
        fprintf( stdout, "\nSTATUS MISSION 2: Signature successfully transfered!\n" );

    /*
     * get all signature information
     */
    signatureInformations = aSignatureHelper.GetSignatureInformations();

    /*
     * write the first signature into the second signature file.
     */

    xOutputStream = OpenOutputStream( aSIGFileName2 );
    xDocumentHandler = aSignatureHelper.CreateDocumentHandlerWithHeader( xOutputStream);
    aSignatureHelper.ExportSignature( xDocumentHandler, signatureInformations[1]);
    aSignatureHelper.CloseDocumentHandler( xDocumentHandler);
    aSignatureHelper.EndMission();

    fprintf( stdout, "\n\nTEST MISSION 3: Insert a new signature to the first signature file\n");

    aSignatureHelper.StartMission();

    nSecurityId = aSignatureHelper.GetNewSecurityId();

    // Select certificate...
    uno::Reference< ::com::sun::star::security::XCertificate > xPersonalCert = getCertificateFromEnvironment( xSecurityEnvironment, true );
    aSignatureHelper.SetX509Certificate( nSecurityId, xPersonalCert->getIssuerName(), bigIntegerToNumericString( xPersonalCert->getSerialNumber()));
    aSignatureHelper.AddForSigning( nSecurityId, aXMLFileName, aXMLFileName, sal_False );
    aSignatureHelper.AddForSigning( nSecurityId, aBINFileName, aBINFileName, sal_True );
    aSignatureHelper.SetDateTime( nSecurityId, Date(), Time() );

    xOutputStream = OpenOutputStream( aSIGFileName );
    xDocumentHandler = aSignatureHelper.CreateDocumentHandlerWithHeader( xOutputStream);

    aSignatureHelper.ExportSignature( xDocumentHandler, signatureInformations[0]);
    bDone = aSignatureHelper.CreateAndWriteSignature( xDocumentHandler );
    aSignatureHelper.ExportSignature( xDocumentHandler, signatureInformations[1]);
    aSignatureHelper.CloseDocumentHandler( xDocumentHandler);

    if ( !bDone )
        fprintf( stderr, "\nSTATUS MISSION 3: Error creating Signature!\n" );
    else
        fprintf( stdout, "\nSTATUS MISSION 3: Signature successfully created!\n" );

    aSignatureHelper.EndMission();

    fprintf( stdout, "\n\nTEST MISSION 4 : Verify the first signature file\n");

    aSignatureHelper.SetStartVerifySignatureHdl( Link( NULL, startVerifyHandler ) );

    aSignatureHelper.StartMission();

    xInputStream = OpenInputStream( aSIGFileName );
    bDone = aSignatureHelper.ReadAndVerifySignature( xInputStream );
    xInputStream->closeInput();

    if ( !bDone )
        fprintf( stderr, "\nSTATUS MISSION 4: Error verifying Signatures!\n" );
    else
        fprintf( stdout, "\nSTATUS MISSION 4: All choosen Signatures veryfied successfully!\n" );

    aSignatureHelper.EndMission();

    QueryPrintSignatureDetails( aSignatureHelper.GetSignatureInformations(), aSignatureHelper.GetSecurityEnvironment() );

    fprintf( stdout, "\n\nTEST MISSION 5: Verify the second signature file\n");

    aSignatureHelper.StartMission();

    xInputStream = OpenInputStream( aSIGFileName2 );
    bDone = aSignatureHelper.ReadAndVerifySignature( xInputStream );
    xInputStream->closeInput();

    if ( !bDone )
        fprintf( stderr, "\nSTATUS MISSION 5: Error verifying Signatures!\n" );
    else
        fprintf( stdout, "\nSTATUS MISSION 5: All choosen Signatures veryfied successfully!\n" );

    aSignatureHelper.EndMission();

    QueryPrintSignatureDetails( aSignatureHelper.GetSignatureInformations(), aSignatureHelper.GetSecurityEnvironment() );

    return 0;
}
<commit_msg>INTEGRATION: CWS ooo19126 (1.5.38); FILE MERGED 2005/09/05 17:02:07 rt 1.5.38.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: multisigdemo.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 17:37:57 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include <stdio.h>
#include "util.hxx"

#include <rtl/ustring.hxx>
#include <cppuhelper/servicefactory.hxx>

#include <xmlsecurity/biginteger.hxx>
#include <xmlsecurity/xmlsignaturehelper.hxx>

#include <tools/date.hxx>
#include <tools/time.hxx>

using namespace ::com::sun::star;

long denyVerifyHandler( void *, void * )
{
    return  0;
}

long startVerifyHandler( void *, void * )
{
    return QueryVerifySignature();
}

int SAL_CALL main( int argc, char **argv )
{
    if( argc < 5 )
    {
        fprintf( stderr, "Usage: %s <signature file 1> <signature file 2> <xml stream file> <binary stream file> [<cryptoken>]\n" , argv[0] ) ;
        return -1 ;
    }

    uno::Reference< lang::XMultiServiceFactory > xMSF = CreateDemoServiceFactory();

    rtl::OUString aSIGFileName = rtl::OUString::createFromAscii(argv[1]);
    rtl::OUString aSIGFileName2 = rtl::OUString::createFromAscii(argv[2]);
    rtl::OUString aXMLFileName = rtl::OUString::createFromAscii(argv[3]);
    rtl::OUString aBINFileName = rtl::OUString::createFromAscii(argv[4]);
    rtl::OUString aCryptoToken;
    if ( argc >= 7 )
        aCryptoToken = rtl::OUString::createFromAscii(argv[6]);

    sal_Int32 nSecurityId;
    uno::Reference< io::XOutputStream > xOutputStream;
    uno::Reference< io::XInputStream > xInputStream;
    bool bDone;
    SignatureInformations signatureInformations;
    uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler> xDocumentHandler;

    // -------- START -------

    XMLSignatureHelper aSignatureHelper( xMSF );

    bool bInit = aSignatureHelper.Init( aCryptoToken );
    if ( !bInit )
    {
        fprintf( stderr, "Error initializing security context!\n" );
        return -1;
    }

    fprintf( stdout, "\n\nTEST MISSION 1: Create the first signature file\n");

    aSignatureHelper.StartMission();

    /*
     * select a private key certificate
     */
    uno::Reference< xml::crypto::XSecurityEnvironment > xSecurityEnvironment = aSignatureHelper.GetSecurityEnvironment();
    uno::Sequence< uno::Reference< ::com::sun::star::security::XCertificate > > xPersonalCerts = xSecurityEnvironment->getPersonalCertificates() ;

    fprintf( stdout, "\nPlease select two certificates:\n" );

    for ( int nSig = 0; nSig < 2; nSig++ )
    {
        // New security ID for signature...
        nSecurityId = aSignatureHelper.GetNewSecurityId();

        // Select certificate...
        uno::Reference< ::com::sun::star::security::XCertificate > xPersonalCert = getCertificateFromEnvironment( xSecurityEnvironment, true );
        aSignatureHelper.SetX509Certificate( nSecurityId, xPersonalCert->getIssuerName(), bigIntegerToNumericString( xPersonalCert->getSerialNumber()));
        aSignatureHelper.AddForSigning( nSecurityId, aXMLFileName, aXMLFileName, sal_False );
        aSignatureHelper.AddForSigning( nSecurityId, aBINFileName, aBINFileName, sal_True );
        aSignatureHelper.SetDateTime( nSecurityId, Date(), Time() );
    }
    /*
     * creates signature
     */
    xOutputStream = OpenOutputStream( aSIGFileName );
    bDone = aSignatureHelper.CreateAndWriteSignature( xOutputStream );
    if ( !bDone )
        fprintf( stderr, "\nSTATUS MISSION 1: Error creating Signature!\n" );
    else
        fprintf( stdout, "\nSTATUS MISSION 1: Signature successfully created!\n" );

    aSignatureHelper.EndMission();

    fprintf( stdout, "\n\nTEST MISSION 2: Transfer the second signature to a new signature file\n");

    /*
     * You can use an uninitialized SignatureHelper to perform this mission.
     */

    /*
     * configures the start-verify handler. Don't need to verify for transfering...
     */
    aSignatureHelper.SetStartVerifySignatureHdl( Link( NULL, denyVerifyHandler ) );
    aSignatureHelper.StartMission();

    xInputStream = OpenInputStream( aSIGFileName );
    bDone = aSignatureHelper.ReadAndVerifySignature( xInputStream );
    xInputStream->closeInput();

    if ( !bDone )
        fprintf( stderr, "\nSTATUS MISSION 2: Error in reading Signature!\n" );
    else
        fprintf( stdout, "\nSTATUS MISSION 2: Signature successfully transfered!\n" );

    /*
     * get all signature information
     */
    signatureInformations = aSignatureHelper.GetSignatureInformations();

    /*
     * write the first signature into the second signature file.
     */

    xOutputStream = OpenOutputStream( aSIGFileName2 );
    xDocumentHandler = aSignatureHelper.CreateDocumentHandlerWithHeader( xOutputStream);
    aSignatureHelper.ExportSignature( xDocumentHandler, signatureInformations[1]);
    aSignatureHelper.CloseDocumentHandler( xDocumentHandler);
    aSignatureHelper.EndMission();

    fprintf( stdout, "\n\nTEST MISSION 3: Insert a new signature to the first signature file\n");

    aSignatureHelper.StartMission();

    nSecurityId = aSignatureHelper.GetNewSecurityId();

    // Select certificate...
    uno::Reference< ::com::sun::star::security::XCertificate > xPersonalCert = getCertificateFromEnvironment( xSecurityEnvironment, true );
    aSignatureHelper.SetX509Certificate( nSecurityId, xPersonalCert->getIssuerName(), bigIntegerToNumericString( xPersonalCert->getSerialNumber()));
    aSignatureHelper.AddForSigning( nSecurityId, aXMLFileName, aXMLFileName, sal_False );
    aSignatureHelper.AddForSigning( nSecurityId, aBINFileName, aBINFileName, sal_True );
    aSignatureHelper.SetDateTime( nSecurityId, Date(), Time() );

    xOutputStream = OpenOutputStream( aSIGFileName );
    xDocumentHandler = aSignatureHelper.CreateDocumentHandlerWithHeader( xOutputStream);

    aSignatureHelper.ExportSignature( xDocumentHandler, signatureInformations[0]);
    bDone = aSignatureHelper.CreateAndWriteSignature( xDocumentHandler );
    aSignatureHelper.ExportSignature( xDocumentHandler, signatureInformations[1]);
    aSignatureHelper.CloseDocumentHandler( xDocumentHandler);

    if ( !bDone )
        fprintf( stderr, "\nSTATUS MISSION 3: Error creating Signature!\n" );
    else
        fprintf( stdout, "\nSTATUS MISSION 3: Signature successfully created!\n" );

    aSignatureHelper.EndMission();

    fprintf( stdout, "\n\nTEST MISSION 4 : Verify the first signature file\n");

    aSignatureHelper.SetStartVerifySignatureHdl( Link( NULL, startVerifyHandler ) );

    aSignatureHelper.StartMission();

    xInputStream = OpenInputStream( aSIGFileName );
    bDone = aSignatureHelper.ReadAndVerifySignature( xInputStream );
    xInputStream->closeInput();

    if ( !bDone )
        fprintf( stderr, "\nSTATUS MISSION 4: Error verifying Signatures!\n" );
    else
        fprintf( stdout, "\nSTATUS MISSION 4: All choosen Signatures veryfied successfully!\n" );

    aSignatureHelper.EndMission();

    QueryPrintSignatureDetails( aSignatureHelper.GetSignatureInformations(), aSignatureHelper.GetSecurityEnvironment() );

    fprintf( stdout, "\n\nTEST MISSION 5: Verify the second signature file\n");

    aSignatureHelper.StartMission();

    xInputStream = OpenInputStream( aSIGFileName2 );
    bDone = aSignatureHelper.ReadAndVerifySignature( xInputStream );
    xInputStream->closeInput();

    if ( !bDone )
        fprintf( stderr, "\nSTATUS MISSION 5: Error verifying Signatures!\n" );
    else
        fprintf( stdout, "\nSTATUS MISSION 5: All choosen Signatures veryfied successfully!\n" );

    aSignatureHelper.EndMission();

    QueryPrintSignatureDetails( aSignatureHelper.GetSignatureInformations(), aSignatureHelper.GetSecurityEnvironment() );

    return 0;
}
<|endoftext|>


<commit_before>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "shell/android/native_viewport_application_loader.h"

#include "mojo/public/cpp/application/application_impl.h"
#include "services/native_viewport/native_viewport_impl.h"

namespace mojo {
namespace shell {

NativeViewportApplicationLoader::NativeViewportApplicationLoader()
    : gpu_state_(new gles2::GpuImpl::State) {
}

NativeViewportApplicationLoader::~NativeViewportApplicationLoader() {
}

void NativeViewportApplicationLoader::Load(ApplicationManager* manager,
                                           const GURL& url,
                                           ScopedMessagePipeHandle shell_handle,
                                           LoadCallback callback) {
  DCHECK(shell_handle.is_valid());
  app_.reset(new ApplicationImpl(this, shell_handle.Pass()));
}

void NativeViewportApplicationLoader::OnApplicationError(
    ApplicationManager* manager,
    const GURL& url) {
}

bool NativeViewportApplicationLoader::ConfigureIncomingConnection(
    mojo::ApplicationConnection* connection) {
  connection->AddService<NativeViewport>(this);
  connection->AddService<Gpu>(this);
  return true;
}

void NativeViewportApplicationLoader::Create(
    ApplicationConnection* connection,
    InterfaceRequest<NativeViewport> request) {
  BindToRequest(new native_viewport::NativeViewportImpl(app_.get(), false),
                &request);
}

void NativeViewportApplicationLoader::Create(
    ApplicationConnection* connection,
    InterfaceRequest<Gpu> request) {
  new gles2::GpuImpl(request.Pass(), gpu_state_);
}

}  // namespace shell
}  // namespace mojo
<commit_msg>Fix surfaces_app on Android<commit_after>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "shell/android/native_viewport_application_loader.h"

#include "mojo/public/cpp/application/application_impl.h"
#include "services/native_viewport/native_viewport_impl.h"

namespace mojo {
namespace shell {

NativeViewportApplicationLoader::NativeViewportApplicationLoader() {
}

NativeViewportApplicationLoader::~NativeViewportApplicationLoader() {
}

void NativeViewportApplicationLoader::Load(ApplicationManager* manager,
                                           const GURL& url,
                                           ScopedMessagePipeHandle shell_handle,
                                           LoadCallback callback) {
  DCHECK(shell_handle.is_valid());
  app_.reset(new ApplicationImpl(this, shell_handle.Pass()));
}

void NativeViewportApplicationLoader::OnApplicationError(
    ApplicationManager* manager,
    const GURL& url) {
}

bool NativeViewportApplicationLoader::ConfigureIncomingConnection(
    mojo::ApplicationConnection* connection) {
  connection->AddService<NativeViewport>(this);
  connection->AddService<Gpu>(this);
  return true;
}

void NativeViewportApplicationLoader::Create(
    ApplicationConnection* connection,
    InterfaceRequest<NativeViewport> request) {
  BindToRequest(new native_viewport::NativeViewportImpl(app_.get(), false),
                &request);
}

void NativeViewportApplicationLoader::Create(
    ApplicationConnection* connection,
    InterfaceRequest<Gpu> request) {
  if (!gpu_state_)
    gpu_state_ = new gles2::GpuImpl::State;
  new gles2::GpuImpl(request.Pass(), gpu_state_);
}

}  // namespace shell
}  // namespace mojo
<|endoftext|>


<commit_before>//===-- ClangHost.cpp -------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "ClangHost.h"

#include "clang/Basic/Version.h"
#include "clang/Config/config.h"

#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Threading.h"

#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"

#include <string>

using namespace lldb_private;

static bool VerifyClangPath(const llvm::Twine &clang_path) {
  if (FileSystem::Instance().IsDirectory(clang_path))
    return true;
  Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
  if (log)
    log->Printf("VerifyClangPath(): "
                "failed to stat clang resource directory at \"%s\"",
                clang_path.str().c_str());
  return false;
}

///
/// This will compute the clang resource directory assuming that clang was
/// installed with the same prefix as lldb.
///
static bool DefaultComputeClangResourceDirectory(FileSpec &lldb_shlib_spec,
                                         FileSpec &file_spec, bool verify) {
  std::string raw_path = lldb_shlib_spec.GetPath();
  llvm::StringRef parent_dir = llvm::sys::path::parent_path(raw_path);

  llvm::SmallString<256> clang_dir(parent_dir);
  llvm::SmallString<32> relative_path;
  llvm::sys::path::append(relative_path, "lib", "lldb", "clang");

  llvm::sys::path::append(clang_dir, relative_path);
  if (!verify || VerifyClangPath(clang_dir)) {
    file_spec.GetDirectory().SetString(clang_dir);
    return true;
  }

  return HostInfo::ComputePathRelativeToLibrary(file_spec, relative_path);
}

bool lldb_private::ComputeClangResourceDirectory(FileSpec &lldb_shlib_spec,
                                         FileSpec &file_spec, bool verify) {
#if !defined(__APPLE__)
  return DefaultComputeClangResourceDirectory(lldb_shlib_spec, file_spec,
                                              verify);
#else
  std::string raw_path = lldb_shlib_spec.GetPath();

  auto rev_it = llvm::sys::path::rbegin(raw_path);
  auto r_end = llvm::sys::path::rend(raw_path);

  // Check for a Posix-style build of LLDB.
  while (rev_it != r_end) {
    if (*rev_it == "LLDB.framework")
      break;
    ++rev_it;
  }

  // We found a non-framework build of LLDB
  if (rev_it == r_end)
    return DefaultComputeClangResourceDirectory(lldb_shlib_spec, file_spec,
                                                verify);

  // Inside Xcode and in Xcode toolchains LLDB is always in lockstep
  // with the Swift compiler, so it can reuse its Clang resource
  // directory. This allows LLDB and the Swift compiler to share the
  // same Clang module cache.
  llvm::SmallString<256> clang_path;
  const char *swift_clang_resource_dir = "usr/lib/swift/clang";
  auto parent = std::next(rev_it);
  if (parent != r_end && *parent == "SharedFrameworks") {
    // This is the top-level LLDB in the Xcode.app bundle.
    // E.g., "Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A"
    raw_path.resize(parent - r_end);
    llvm::sys::path::append(clang_path, raw_path,
                            "Developer/Toolchains/XcodeDefault.xctoolchain",
                            swift_clang_resource_dir);
    if (!verify || VerifyClangPath(clang_path)) {
      file_spec.SetFile(clang_path.c_str(), FileSpec::Style::native);
      FileSystem::Instance().Resolve(file_spec);
      return true;
    }
  } else if (parent != r_end && *parent == "PrivateFrameworks" &&
             std::distance(parent, r_end) > 2) {
    ++parent;
    ++parent;
    if (*parent == "System") {
      // This is LLDB inside an Xcode toolchain.
      // E.g., "Xcode.app/Contents/Developer/Toolchains/"               \
      //       "My.xctoolchain/System/Library/PrivateFrameworks/LLDB.framework"
      raw_path.resize(parent - r_end);
      llvm::sys::path::append(clang_path, raw_path, swift_clang_resource_dir);
      if (!verify || VerifyClangPath(clang_path)) {
        file_spec.SetFile(clang_path.c_str(), FileSpec::Style::native);
        FileSystem::Instance().Resolve(file_spec);
        return true;
      }
      raw_path = lldb_shlib_spec.GetPath();
    }
    raw_path.resize(rev_it - r_end);
  } else {
    raw_path.resize(rev_it - r_end);
  }

  // Fall back to the Clang resource directory inside the framework.
  raw_path.append("LLDB.framework/Resources/Clang");
  file_spec.SetFile(raw_path.c_str(), FileSpec::Style::native);
  FileSystem::Instance().Resolve(file_spec);
  return true;
#endif // __APPLE__
}

FileSpec lldb_private::GetClangResourceDir() {
  static FileSpec g_cached_resource_dir;
  static llvm::once_flag g_once_flag;
  llvm::call_once(g_once_flag, []() {
    if (FileSpec lldb_file_spec = HostInfo::GetShlibDir())
      ComputeClangResourceDirectory(lldb_file_spec, g_cached_resource_dir,
                                    true);
    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
    if (log)
      log->Printf("GetClangResourceDir() => '%s'",
                  g_cached_resource_dir.GetPath().c_str());
  });
  return g_cached_resource_dir;
}
<commit_msg>Update the macOS implementation of ComputeClangResourceDirectory to comply with the more pedantic TestPaths.py<commit_after>//===-- ClangHost.cpp -------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "ClangHost.h"

#include "clang/Basic/Version.h"
#include "clang/Config/config.h"

#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Threading.h"

#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"

#include <string>

using namespace lldb_private;

static bool VerifyClangPath(const llvm::Twine &clang_path) {
  if (FileSystem::Instance().IsDirectory(clang_path))
    return true;
  Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
  if (log)
    log->Printf("VerifyClangPath(): "
                "failed to stat clang resource directory at \"%s\"",
                clang_path.str().c_str());
  return false;
}

///
/// This will compute the clang resource directory assuming that clang was
/// installed with the same prefix as lldb.
///
static bool DefaultComputeClangResourceDirectory(FileSpec &lldb_shlib_spec,
                                         FileSpec &file_spec, bool verify) {
  std::string raw_path = lldb_shlib_spec.GetPath();
  llvm::StringRef parent_dir = llvm::sys::path::parent_path(raw_path);

  llvm::SmallString<256> clang_dir(parent_dir);
  llvm::SmallString<32> relative_path;
  llvm::sys::path::append(relative_path, "lib", "lldb", "clang");

  llvm::sys::path::append(clang_dir, relative_path);
  if (!verify || VerifyClangPath(clang_dir)) {
    file_spec.GetDirectory().SetString(clang_dir);
    return true;
  }

  return HostInfo::ComputePathRelativeToLibrary(file_spec, relative_path);
}

bool lldb_private::ComputeClangResourceDirectory(FileSpec &lldb_shlib_spec,
                                         FileSpec &file_spec, bool verify) {
#if !defined(__APPLE__)
  return DefaultComputeClangResourceDirectory(lldb_shlib_spec, file_spec,
                                              verify);
#else
  std::string raw_path = lldb_shlib_spec.GetPath();

  auto rev_it = llvm::sys::path::rbegin(raw_path);
  auto r_end = llvm::sys::path::rend(raw_path);

  // Check for a Posix-style build of LLDB.
  while (rev_it != r_end) {
    if (*rev_it == "LLDB.framework")
      break;
    ++rev_it;
  }

  // We found a non-framework build of LLDB
  if (rev_it == r_end)
    return DefaultComputeClangResourceDirectory(lldb_shlib_spec, file_spec,
                                                verify);

  // Inside Xcode and in Xcode toolchains LLDB is always in lockstep
  // with the Swift compiler, so it can reuse its Clang resource
  // directory. This allows LLDB and the Swift compiler to share the
  // same Clang module cache.
  llvm::SmallString<256> clang_path;
  const char *swift_clang_resource_dir = "usr/lib/swift/clang";
  auto parent = std::next(rev_it);
  if (parent != r_end && *parent == "SharedFrameworks") {
    // This is the top-level LLDB in the Xcode.app bundle.
    // E.g., "Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A"
    raw_path.resize(parent - r_end);
    llvm::sys::path::append(clang_path, raw_path,
                            "Developer/Toolchains/XcodeDefault.xctoolchain",
                            swift_clang_resource_dir);
    if (!verify || VerifyClangPath(clang_path)) {
      file_spec.GetDirectory().SetString(clang_path.c_str());
      FileSystem::Instance().Resolve(file_spec);
      return true;
    }
  } else if (parent != r_end && *parent == "PrivateFrameworks" &&
             std::distance(parent, r_end) > 2) {
    ++parent;
    ++parent;
    if (*parent == "System") {
      // This is LLDB inside an Xcode toolchain.
      // E.g., "Xcode.app/Contents/Developer/Toolchains/"               \
      //       "My.xctoolchain/System/Library/PrivateFrameworks/LLDB.framework"
      raw_path.resize(parent - r_end);
      llvm::sys::path::append(clang_path, raw_path, swift_clang_resource_dir);
      if (!verify || VerifyClangPath(clang_path)) {
        file_spec.GetDirectory().SetString(clang_path.c_str());
        FileSystem::Instance().Resolve(file_spec);
        return true;
      }
      raw_path = lldb_shlib_spec.GetPath();
    }
    raw_path.resize(rev_it - r_end);
  } else {
    raw_path.resize(rev_it - r_end);
  }

  // Fall back to the Clang resource directory inside the framework.
  raw_path.append("LLDB.framework/Resources/Clang");
  file_spec.GetDirectory().SetString(raw_path.c_str());
  FileSystem::Instance().Resolve(file_spec);
  return true;
#endif // __APPLE__
}

FileSpec lldb_private::GetClangResourceDir() {
  static FileSpec g_cached_resource_dir;
  static llvm::once_flag g_once_flag;
  llvm::call_once(g_once_flag, []() {
    if (FileSpec lldb_file_spec = HostInfo::GetShlibDir())
      ComputeClangResourceDirectory(lldb_file_spec, g_cached_resource_dir,
                                    true);
    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
    if (log)
      log->Printf("GetClangResourceDir() => '%s'",
                  g_cached_resource_dir.GetPath().c_str());
  });
  return g_cached_resource_dir;
}
<|endoftext|>