<commit_before>#ifndef RECURSE_REQUEST_HPP
#define RECURSE_REQUEST_HPP

#include <QTcpSocket>
#include <QHash>

class Request
{

public:
    //!
    //! \brief data
    //! client request buffer data
    //!
    QString data;

    //!
    //! \brief socket
    //! underlying client socket
    //!
    QTcpSocket *socket;

    //!
    //! \brief body_parsed
    //! Data to be filled by body parsing middleware
    //!
    QHash<QString, QVariant> body_parsed;

    //!
    //! \brief body
    //!
    QString body;

    //!
    //! \brief method
    //! HTTP method, eg: GET
    //!
    QString method;

    //!
    //! \brief protocol
    //! Request protocol, eg: HTTP
    //!
    QString protocol;

    //!
    //! \brief secure
    //! Shorthand for protocol == "HTTPS" to check if a requet was issued via TLS
    //!
    bool secure = protocol == "HTTPS";

    //!
    //! \brief url
    //! HTTP request url, eg: /helloworld
    //!
    QString url;

    //!
    //! \brief length
    //! HTTP request Content-Length
    //!
    qint64 length = 0;

    //!
    //! \brief ip
    //! Client ip address
    //!
    QHostAddress ip;

    //!
    //! \brief cookies
    //! HTTP cookies in key/value form
    //!
    QHash<QString, QString> cookies;

    //!
    //! \brief hostname
    //! HTTP hostname from "Host" HTTP header
    //!
    QString hostname;

    //!
    //! \brief get
    //! Return HTTP request header specified by the key
    //!
    //! \param QString case-insensitive key of the header
    //! \return QString header value
    //!
    QString get(const QString &key)
    {
        return m_header[key.toLower()];
    }

    //!
    //! \brief parse
    //! parse data from request
    //!
    //! \param QString request
    //! \return true on success, false otherwise, considered bad request
    //!
    bool parse(QString request);

private:
    //!
    //! \brief header
    //! HTTP request headers, eg: header["content-type"] = "text/plain"
    //!
    QHash<QString, QString> m_header;

    //!
    //! \brief httpRx
    //! match HTTP request line
    //!
    QRegExp httpRx = QRegExp("^(?=[A-Z]).* \\/.* HTTP\\/[0-9]\\.[0-9]\\r\\n");
};

inline bool Request::parse(QString request)
{
    // buffer all data
    this->data += request;

    // Save client ip address
    this->ip = this->socket->peerAddress();

    // if no header is present, just append all data to request.body
    if (!this->data.contains(httpRx))
    {
        this->body.append(this->data);
        return true;
    }

    QStringList data_list = this->data.split("\r\n");
    bool is_body = false;

    for (int i = 0; i < data_list.size(); ++i)
    {
        if (is_body)
        {
            this->body.append(data_list.at(i));
            this->length += this->body.size();
            continue;
        }

        QStringList entity_item = data_list.at(i).split(":");

        if (entity_item.length() < 2 && entity_item.at(0).size() < 1 && !is_body)
        {
            is_body = true;
            continue;
        }
        else if (i == 0 && entity_item.length() < 2)
        {
            QStringList first_line = entity_item.at(0).split(" ");
            this->method = first_line.at(0);
            this->url = first_line.at(1).trimmed();
            this->protocol = first_line.at(2).trimmed();
            continue;
        }

        m_header[entity_item.at(0).toLower()] = entity_item.at(1).trimmed().toLower();
    }

    if (m_header.contains("host"))
        this->hostname = m_header["host"];

    qDebug() << "this->object populated: "
             << this->method << this->url << m_header << this->protocol << this->body
             << this->hostname << this->ip
             << this->length;

    // extract cookies
    // eg: USER_TOKEN=Yes;test=val
    if (m_header.contains("cookie"))
    {
        for (const QString &cookie : this->get("cookie").split(";"))
        {
            int split = cookie.trimmed().indexOf("=");
            if (split == -1)
                continue;

            QString key = cookie.left(split).trimmed();
            if (!key.size())
                continue;

            QString value = cookie.mid(split + 1).trimmed();

            this->cookies[key.toLower()] = value.toLower();
        }

        qDebug() << "cookies:\n" << this->cookies << "\n";
    }

    return true;
}

#endif
<commit_msg>add query string extraction from url<commit_after>#ifndef RECURSE_REQUEST_HPP
#define RECURSE_REQUEST_HPP

#include <QTcpSocket>
#include <QHash>
#include <QUrl>
#include <QUrlQuery>

class Request
{

public:
    //!
    //! \brief data
    //! client request buffer data
    //!
    QString data;

    //!
    //! \brief socket
    //! underlying client socket
    //!
    QTcpSocket *socket;

    //!
    //! \brief body_parsed
    //! Data to be filled by body parsing middleware
    //!
    QHash<QString, QVariant> body_parsed;

    //!
    //! \brief body
    //!
    QString body;

    //!
    //! \brief method
    //! HTTP method, eg: GET
    //!
    QString method;

    //!
    //! \brief protocol
    //! Request protocol, eg: HTTP
    //!
    QString protocol;

    //!
    //! \brief secure
    //! Shorthand for protocol == "HTTPS" to check if a requet was issued via TLS
    //!
    bool secure = protocol == "HTTPS";

    //!
    //! \brief url
    //! HTTP request url, eg: /helloworld
    //!
    QUrl url;

    //!
    //! \brief query
    //!
    QUrlQuery query;

    //!
    //! \brief length
    //! HTTP request Content-Length
    //!
    qint64 length = 0;

    //!
    //! \brief ip
    //! Client ip address
    //!
    QHostAddress ip;

    //!
    //! \brief cookies
    //! HTTP cookies in key/value form
    //!
    QHash<QString, QString> cookies;

    //!
    //! \brief hostname
    //! HTTP hostname from "Host" HTTP header
    //!
    QString hostname;

    //!
    //! \brief get
    //! Return HTTP request header specified by the key
    //!
    //! \param QString case-insensitive key of the header
    //! \return QString header value
    //!
    QString get(const QString &key)
    {
        return m_header[key.toLower()];
    }

    //!
    //! \brief parse
    //! parse data from request
    //!
    //! \param QString request
    //! \return true on success, false otherwise, considered bad request
    //!
    bool parse(QString request);

private:
    //!
    //! \brief header
    //! HTTP request headers, eg: header["content-type"] = "text/plain"
    //!
    QHash<QString, QString> m_header;

    //!
    //! \brief httpRx
    //! match HTTP request line
    //!
    QRegExp httpRx = QRegExp("^(?=[A-Z]).* \\/.* HTTP\\/[0-9]\\.[0-9]\\r\\n");
};

inline bool Request::parse(QString request)
{
    // buffer all data
    this->data += request;

    // Save client ip address
    this->ip = this->socket->peerAddress();

    // if no header is present, just append all data to request.body
    if (!this->data.contains(httpRx))
    {
        this->body.append(this->data);
        return true;
    }

    QStringList data_list = this->data.split("\r\n");
    bool is_body = false;

    for (int i = 0; i < data_list.size(); ++i)
    {
        if (is_body)
        {
            this->body.append(data_list.at(i));
            this->length += this->body.size();
            continue;
        }

        QStringList entity_item = data_list.at(i).split(":");

        if (entity_item.length() < 2 && entity_item.at(0).size() < 1 && !is_body)
        {
            is_body = true;
            continue;
        }
        else if (i == 0 && entity_item.length() < 2)
        {
            QStringList first_line = entity_item.at(0).split(" ");
            this->method = first_line.at(0);
            this->url = first_line.at(1).trimmed();
            this->query.setQuery(this->url.query());
            this->protocol = first_line.at(2).trimmed();
            continue;
        }

        m_header[entity_item.at(0).toLower()] = entity_item.at(1).trimmed().toLower();
    }

    if (m_header.contains("host"))
        this->hostname = m_header["host"];

    qDebug() << "this->object populated: "
             << this->method << this->url << m_header << this->protocol << this->body
             << this->hostname << this->ip
             << this->length;

    // extract cookies
    // eg: USER_TOKEN=Yes;test=val
    if (m_header.contains("cookie"))
    {
        for (const QString &cookie : this->get("cookie").split(";"))
        {
            int split = cookie.trimmed().indexOf("=");
            if (split == -1)
                continue;

            QString key = cookie.left(split).trimmed();
            if (!key.size())
                continue;

            QString value = cookie.mid(split + 1).trimmed();

            this->cookies[key.toLower()] = value.toLower();
        }

        qDebug() << "cookies:\n" << this->cookies << "\n";
    }

    return true;
}

#endif
<|endoftext|>


<commit_before>#include <vector>
#include <map>
#include <cstring>
#include <algorithm>
#include <iostream>

#include "alloc.hpp"
#include "safemacros.h"

#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>

namespace aL4nin
{
    template <>
    struct meta<int>
    {
        int* allocate(std::size_t elems)
        {
            return new int[elems];
        }
    };

    template <>
    meta<int>& get_meta<int>(std::size_t)
    {
        static meta<int> m;
        return m;
    }
}

// metadata entry defines the
// marking method:
// a) bitpattern (up to 31 bits representing pointers to follow)
// b) freestyle procedural marker
//     - uncommitted arrays must zero out object data before setting marker
//     - concurrency in data <--> metadata access???

// let's fix some hard conventions
// - T* is non-null collectable pointer that is to be followed
// - nullable<T> is a possibly NULL pointer that should be followed
// - T& is a non-assignable, non-null reference that is to be followed
// - const T is a non-assignable non-null reference that is to be followed
// - const nullable<T> is a non-assignable, possibly NULL pointer that should be followed
// - references to builtin basic types are not followed
// - non<T> is a pointer that will not be followed
// - const non<T> is a non-assignable pointer that will not be followed
// - thresholded<T, N> is like nullable but does not follow <= N

#define WRAP(TYPE, MODIFIER) \
    MODIFIER ## _WRAPPER(TYPE)

#define BARE_WRAPPER(TYPE) TYPE
#define _WRAPPER(TYPE) BARE_WRAPPER(TYPE)
#define NULLABLE_WRAPPER(TYPE) nullable<TYPE>
#define NON_WRAPPER(TYPE) non<TYPE>
#define NULLABLE_WRAPPER(TYPE) nullable<TYPE>

template <typename T>
struct nullable
{
    T* real;
    nullable(T* real)
        : real(real)
        {}
};

template <typename T>
struct non
{
    T real;
    non(const T& real)
        : real(real)
        {}
};

WRAP(int, NON) hh(42);
WRAP(int, /*BARE*/) hh1;
WRAP(int, NULLABLE) hh2(0);

struct foo
{
    foo& f;
    foo() : f(*this)
        {}
    void bar()
        {
///            int i(&foo::f);
        }

};

// Anatomy of the WORLD.
//
// The world is the part of the process memory that the GC
// is interested in. It is completely subdivided in clusters.
// The first cluster of the world is special.
// Every other cluster is subdivided into 2^p pages. The size
// of a page must match a (supported) VM page size.
// The number of pages a cluster consists of (2^p) is dependent
// on the cluster, so the world must store the ps in the special
// cluster in order to be able to find the cluster boundaries.
// At the start of each cluster we find the metaobjects.
// The metaobject at displacement 0 (into the cluster) is
// special, describing the metaobjects themselves, i.e. it is
// a meta-metaobject.
// Metaobjects are just additional information that is factored
// out of the objects or can add information about the validity
// and GC-properties of a group of objects.

// Note: later I may introduce a multiworld, which may be
// a linked list of worlds.

// Checker templates
//
template <unsigned>
struct IsZero;

template <>
struct IsZero<0>
{};

template <unsigned long DIVISOR, unsigned long DIVIDEND>
struct Divides : IsZero<DIVIDEND % DIVISOR>
{};

// World: define the layout of a world in the memory
// and subdivide in pages. Provide info about the
// location and size.
// NUMPAGES: how many pages should this world hold
// BASE: where should this world be located in the memory
// PAGE: bits needed to address a byte in a page. i.e.
//       pagesize == 2^PAGE bytes
//
template <unsigned NUMPAGES, unsigned BASE, unsigned PAGE>
struct World
{
    enum { PageSize = 1 << PAGE };

    struct Page
    {
        char raw[PageSize];
    };

    Page pages[NUMPAGES];

    static void* start(void)
        {
            Divides<PageSize, BASE> c1;
            return reinterpret_cast<void*>(BASE);
        }

    static size_t size(void)
        {
            return PageSize * NUMPAGES;
        }

    void protectPageRW(unsigned pagenum)
        {
            protectClusterRW(pagenum, 1);
        }

    void protectClusterRW(unsigned from_pagenum, unsigned ps)
        {
            if (0 != mprotect(pages + from_pagenum, PageSize * ps, PROT_NONE))
                perror("mprotect");
        }

    void* operator new(size_t s, int hdl)
        {
            void* here(mmap(start(),
                            s,
                            PROT_READ | PROT_WRITE,
                            MAP_SHARED,
                            hdl,
                            0));
            if (MAP_FAILED == here)
                perror("mmap");

            assert(s == size());
            assert(here == start());
            assert(sysconf(_SC_PAGESIZE) == PageSize);

            return here;
        }
};

// MISC ideas
// allocation: tell a cluster to allocate an obj of a certain
// metadata "class". returns a cluster address, which may be the
// same as the current cluster or pointer to a new cluster with
// the object being in there. In this case the pointer must be
// stored away for the next allocation request.

// GC: use a posix message queue to tell which thread stack ranges
// must be mprotected. This way the threads can be starved out
// systematically.

// RawObj2Meta is intended to return a pointer for an object
// living in the world, that describes its allocation and collection
// behaviour.
// PAGE: number of bits needed to address a byte in a VM-page
// CLUSTER: how many bits are needed to address a page in a VM cluster of pages
// SCALE: how many bytes together have the same metadata info (2^SCALE bytes)
//   ##!! not true: SCALE simply tells us how much "denser" metaobjects are
//        compared to objects. I.e. 32*8byte (cons cells) together share the same
//        metaobject, and the metaobject is 8bytes then SCALE is 5 because
//        2^5==32.
//
// Theory of operation:
//   Find the lowest address in the cluster and scale down the displacement
//   of the object to the appropriate metaobject.

template <unsigned long PAGE, unsigned long CLUSTER, unsigned long SCALE>
inline void* RawObj2Meta(void* obj)
{
    typedef unsigned long sptr_t;
    register sptr_t o(reinterpret_cast<sptr_t>(obj));
    enum
        {
            pat = (1 << PAGE + CLUSTER) - 1
        };

    register sptr_t b(o & ~static_cast<sptr_t>(pat));
    register sptr_t d(o & static_cast<sptr_t>(pat));
    return reinterpret_cast<void*>(b + (d >> SCALE));
}

template <unsigned NUMPAGES, unsigned BASE, unsigned PAGE>
struct ClusteredWorld : World<NUMPAGES, BASE, PAGE>
{
    template <unsigned long CLUSTER, unsigned long SCALE>
    struct Cluster
    {
        static inline void* Raw2Meta(void* obj)
        {
            return RawObj2Meta<PAGE, CLUSTER, SCALE>(obj);
        }
    };
};

#include "alloc.cpp"

using namespace std;
using namespace aL4nin;

namespace aL4nin
{
    template <>
    meta<void>* object_meta<void>(void* p)
    {
        if (!p)
            return 0;

        static meta<void> me;
        return &me;
    }

    template <>
    struct meta<std::_Rb_tree_node<std::pair<const int, int> > >
    {
        typedef std::_Rb_tree_node<std::pair<const int, int> > payload;

        payload* allocate(std::size_t elems)
        {
            return new payload[elems];
        }
    };

    template <>
    meta<std::_Rb_tree_node<std::pair<const int, int> > >& get_meta<std::_Rb_tree_node<std::pair<const int, int> > >(std::size_t)
    {
        static meta<std::_Rb_tree_node<std::pair<const int, int> > > m;
        return m;
    }

    struct cons : pair<void*, void*>
    {};

    template <>
    struct meta<cons>
    {
        enum { bits = 32 };

        cons* objects;
        bool bitmap[bits];
        bool marks[bits];

        meta(void)
            {
                memset(this, 0, sizeof *this);
            }

        cons* allocate(std::size_t)
            {
                if (!objects)
                {
                    objects = new cons[bits];
                    *bitmap = true;
                    return objects;
                }

                bool* end(bitmap + meta<cons>::bits);
                bool* freebit(find(bitmap, end, 0));
                if (freebit == end)
                    return 0;

                *freebit = true;

                return objects + (freebit - bitmap);
            }

        void mark(const cons* p PLUS_VERBOSITY_ARG())
            {
                // simple minded!
                int i(bits - 1);
                for (const cons* my(objects + i);
                     i >= 0;
                     --my, --i)
                {
                    if (bitmap[i] && p == my)
                    {
                        VERBOSE("identified as cons");
                        if (marks[i])
                        {
                            VERBOSE("already marked");
                            return /*true*/;
                        }

                        marks[i] = true;
                        if (object_meta(p->first))
                        {
                            object_meta(p->first)->mark(p->first PASS_VERBOSE);
                        }

                        if (object_meta(p->second))
                        {
                            object_meta(p->second)->mark(p->second PASS_VERBOSE);
                        }

                        return /*true*/;
                    }
                }

                VERBOSE_ABORT("not a cons");
            }
    };

    template <>
    meta<cons>& get_meta<cons>(std::size_t)
    {
        static meta<cons> m;

        if (find(m.bitmap, m.bitmap + meta<cons>::bits, 0))
            return m;

        abort();
    }

    void* rooty(0);

    void collect(VERBOSITY_ARG())
    {
        VERBOSE("starting");

        // do we need meta<void>
        // or can we safely assume
        // to know the exact meta type?
        // probably not: if a slot is just declared
        // <object> we never know the metadata
        meta<void>* m(object_meta(rooty));
        if (m)
            m->mark(rooty PASS_VERBOSE);
        /// if (m.trymark(rooty.first)) ...;

        VERBOSE("done");
    }

    void meta<void>::mark(void* p PLUS_VERBOSITY_ARG())
    {
        // look whether it is a cons
        VERBOSE("trying to mark: " << p);
        // hack!
        meta<cons>& m(get_meta<cons>(1));
        m.mark(static_cast<cons*>(p) PASS_VERBOSE);
    }
}

// http://www.opengroup.org/onlinepubs/007908799/xsh/sigaction.html
// http://www.gnu.org/software/libc/manual/html_node/Sigaction-Function-Example.html
// http://www.opengroup.org/onlinepubs/000095399/basedefs/signal.h.html
void yummy(int, siginfo_t *, void *);
void yummy(int, siginfo_t* indo, void *)
{
    printf("gggg\n");
    abort();
}

void wummy(int, siginfo_t *, void *);
void wummy(int, siginfo_t* indo, void *)
{
    printf("Solaris:gggg\n");
    abort();
}

int main(void)
{
    vector<int, alloc<int> > v(3);
    map<int, int, less<int>, alloc<int> > m;
    m.insert(make_pair(1, 42));

    cons* c(alloc<cons>().allocate(1));
    c->first = c;
    c->second = 0;
    rooty = c;

    collect(true);

    int hdl(shm_open("/blubber",
                     O_RDWR | O_CREAT,
                     S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP));

    perror("shm_open");

#   ifdef __APPLE__
    typedef ClusteredWorld<100, 0xFF000000UL, 12> world;
#   else
    typedef ClusteredWorld<100, 0xFF000000UL, 13> world;
#   endif

    int tr(ftruncate(hdl, world::size()));
    if (tr == -1)
        perror("ftruncate");

    world* w(new(hdl) world);
    void* area(w);

    if (MAP_FAILED == area)
        perror("mmap");

    w->protectPageRW(0);

    struct sigaction act, oact;
    memset(&act, 0, sizeof act);
    sigemptyset(&act.sa_mask);
    act.sa_flags = SA_SIGINFO;

#   ifdef __APPLE__
    act.sa_sigaction = yummy;
    if (sigaction(SIGBUS, &act, &oact))
#   else
    act.sa_sigaction = wummy;
    if (sigaction(SIGSEGV, &act, &oact))
#   endif
        perror("sigaction");

    {
        for (int i(0); i < 100; i += 4)
        {
            char* p((char*)area + i);
            printf("i: %d, o: %p, m: %p\n", i, p, world::Cluster<4, 3>::Raw2Meta(p));
            *p = 0;
        }

        for (int i(10000); i < 10100; i += 4)
        {
            char* p((char*)area + i);
            printf("i: %d, o: %p, m: %p\n", i, p, world::Cluster<4, 3>::Raw2Meta(p));
            *p = 0;
        }

        sleep(3);
        int um(munmap(area, world::size()));
        if (um == -1)
            perror("munmap");
    }

    int ul(shm_unlink("/blubber"));
    if (ul == -1)
        perror("shm_unlink");

}
<commit_msg>print some info about the fault unfortunately it does not work inside gdb :-(<commit_after>#include <vector>
#include <map>
#include <cstring>
#include <algorithm>
#include <iostream>

#include "alloc.hpp"
#include "safemacros.h"

#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>

namespace aL4nin
{
    template <>
    struct meta<int>
    {
        int* allocate(std::size_t elems)
        {
            return new int[elems];
        }
    };

    template <>
    meta<int>& get_meta<int>(std::size_t)
    {
        static meta<int> m;
        return m;
    }
}

// metadata entry defines the
// marking method:
// a) bitpattern (up to 31 bits representing pointers to follow)
// b) freestyle procedural marker
//     - uncommitted arrays must zero out object data before setting marker
//     - concurrency in data <--> metadata access???

// let's fix some hard conventions
// - T* is non-null collectable pointer that is to be followed
// - nullable<T> is a possibly NULL pointer that should be followed
// - T& is a non-assignable, non-null reference that is to be followed
// - const T is a non-assignable non-null reference that is to be followed
// - const nullable<T> is a non-assignable, possibly NULL pointer that should be followed
// - references to builtin basic types are not followed
// - non<T> is a pointer that will not be followed
// - const non<T> is a non-assignable pointer that will not be followed
// - thresholded<T, N> is like nullable but does not follow <= N

#define WRAP(TYPE, MODIFIER) \
    MODIFIER ## _WRAPPER(TYPE)

#define BARE_WRAPPER(TYPE) TYPE
#define _WRAPPER(TYPE) BARE_WRAPPER(TYPE)
#define NULLABLE_WRAPPER(TYPE) nullable<TYPE>
#define NON_WRAPPER(TYPE) non<TYPE>
#define NULLABLE_WRAPPER(TYPE) nullable<TYPE>

template <typename T>
struct nullable
{
    T* real;
    nullable(T* real)
        : real(real)
        {}
};

template <typename T>
struct non
{
    T real;
    non(const T& real)
        : real(real)
        {}
};

WRAP(int, NON) hh(42);
WRAP(int, /*BARE*/) hh1;
WRAP(int, NULLABLE) hh2(0);

struct foo
{
    foo& f;
    foo() : f(*this)
        {}
    void bar()
        {
///            int i(&foo::f);
        }

};

// Anatomy of the WORLD.
//
// The world is the part of the process memory that the GC
// is interested in. It is completely subdivided in clusters.
// The first cluster of the world is special.
// Every other cluster is subdivided into 2^p pages. The size
// of a page must match a (supported) VM page size.
// The number of pages a cluster consists of (2^p) is dependent
// on the cluster, so the world must store the ps in the special
// cluster in order to be able to find the cluster boundaries.
// At the start of each cluster we find the metaobjects.
// The metaobject at displacement 0 (into the cluster) is
// special, describing the metaobjects themselves, i.e. it is
// a meta-metaobject.
// Metaobjects are just additional information that is factored
// out of the objects or can add information about the validity
// and GC-properties of a group of objects.

// Note: later I may introduce a multiworld, which may be
// a linked list of worlds.

// Checker templates
//
template <unsigned>
struct IsZero;

template <>
struct IsZero<0>
{};

template <unsigned long DIVISOR, unsigned long DIVIDEND>
struct Divides : IsZero<DIVIDEND % DIVISOR>
{};

// World: define the layout of a world in the memory
// and subdivide in pages. Provide info about the
// location and size.
// NUMPAGES: how many pages should this world hold
// BASE: where should this world be located in the memory
// PAGE: bits needed to address a byte in a page. i.e.
//       pagesize == 2^PAGE bytes
//
template <unsigned NUMPAGES, unsigned BASE, unsigned PAGE>
struct World
{
    enum { PageSize = 1 << PAGE };

    struct Page
    {
        char raw[PageSize];
    };

    Page pages[NUMPAGES];

    static void* start(void)
        {
            Divides<PageSize, BASE> c1;
            return reinterpret_cast<void*>(BASE);
        }

    static size_t size(void)
        {
            return PageSize * NUMPAGES;
        }

    void protectPageRW(unsigned pagenum)
        {
            protectClusterRW(pagenum, 1);
        }

    void protectClusterRW(unsigned from_pagenum, unsigned ps)
        {
            if (0 != mprotect(pages + from_pagenum, PageSize * ps, PROT_NONE))
                perror("mprotect");
        }

    void* operator new(size_t s, int hdl)
        {
            void* here(mmap(start(),
                            s,
                            PROT_READ | PROT_WRITE,
                            MAP_SHARED,
                            hdl,
                            0));
            if (MAP_FAILED == here)
                perror("mmap");

            assert(s == size());
            assert(here == start());
            assert(sysconf(_SC_PAGESIZE) == PageSize);

            return here;
        }
};

// MISC ideas
// allocation: tell a cluster to allocate an obj of a certain
// metadata "class". returns a cluster address, which may be the
// same as the current cluster or pointer to a new cluster with
// the object being in there. In this case the pointer must be
// stored away for the next allocation request.

// GC: use a posix message queue to tell which thread stack ranges
// must be mprotected. This way the threads can be starved out
// systematically.

// RawObj2Meta is intended to return a pointer for an object
// living in the world, that describes its allocation and collection
// behaviour.
// PAGE: number of bits needed to address a byte in a VM-page
// CLUSTER: how many bits are needed to address a page in a VM cluster of pages
// SCALE: how many bytes together have the same metadata info (2^SCALE bytes)
//   ##!! not true: SCALE simply tells us how much "denser" metaobjects are
//        compared to objects. I.e. 32*8byte (cons cells) together share the same
//        metaobject, and the metaobject is 8bytes then SCALE is 5 because
//        2^5==32.
//
// Theory of operation:
//   Find the lowest address in the cluster and scale down the displacement
//   of the object to the appropriate metaobject.

template <unsigned long PAGE, unsigned long CLUSTER, unsigned long SCALE>
inline void* RawObj2Meta(void* obj)
{
    typedef unsigned long sptr_t;
    register sptr_t o(reinterpret_cast<sptr_t>(obj));
    enum
        {
            pat = (1 << PAGE + CLUSTER) - 1
        };

    register sptr_t b(o & ~static_cast<sptr_t>(pat));
    register sptr_t d(o & static_cast<sptr_t>(pat));
    return reinterpret_cast<void*>(b + (d >> SCALE));
}

template <unsigned NUMPAGES, unsigned BASE, unsigned PAGE>
struct ClusteredWorld : World<NUMPAGES, BASE, PAGE>
{
    template <unsigned long CLUSTER, unsigned long SCALE>
    struct Cluster
    {
        static inline void* Raw2Meta(void* obj)
        {
            return RawObj2Meta<PAGE, CLUSTER, SCALE>(obj);
        }
    };
};

#include "alloc.cpp"

using namespace std;
using namespace aL4nin;

namespace aL4nin
{
    template <>
    meta<void>* object_meta<void>(void* p)
    {
        if (!p)
            return 0;

        static meta<void> me;
        return &me;
    }

    template <>
    struct meta<std::_Rb_tree_node<std::pair<const int, int> > >
    {
        typedef std::_Rb_tree_node<std::pair<const int, int> > payload;

        payload* allocate(std::size_t elems)
        {
            return new payload[elems];
        }
    };

    template <>
    meta<std::_Rb_tree_node<std::pair<const int, int> > >& get_meta<std::_Rb_tree_node<std::pair<const int, int> > >(std::size_t)
    {
        static meta<std::_Rb_tree_node<std::pair<const int, int> > > m;
        return m;
    }

    struct cons : pair<void*, void*>
    {};

    template <>
    struct meta<cons>
    {
        enum { bits = 32 };

        cons* objects;
        bool bitmap[bits];
        bool marks[bits];

        meta(void)
            {
                memset(this, 0, sizeof *this);
            }

        cons* allocate(std::size_t)
            {
                if (!objects)
                {
                    objects = new cons[bits];
                    *bitmap = true;
                    return objects;
                }

                bool* end(bitmap + meta<cons>::bits);
                bool* freebit(find(bitmap, end, 0));
                if (freebit == end)
                    return 0;

                *freebit = true;

                return objects + (freebit - bitmap);
            }

        void mark(const cons* p PLUS_VERBOSITY_ARG())
            {
                // simple minded!
                int i(bits - 1);
                for (const cons* my(objects + i);
                     i >= 0;
                     --my, --i)
                {
                    if (bitmap[i] && p == my)
                    {
                        VERBOSE("identified as cons");
                        if (marks[i])
                        {
                            VERBOSE("already marked");
                            return /*true*/;
                        }

                        marks[i] = true;
                        if (object_meta(p->first))
                        {
                            object_meta(p->first)->mark(p->first PASS_VERBOSE);
                        }

                        if (object_meta(p->second))
                        {
                            object_meta(p->second)->mark(p->second PASS_VERBOSE);
                        }

                        return /*true*/;
                    }
                }

                VERBOSE_ABORT("not a cons");
            }
    };

    template <>
    meta<cons>& get_meta<cons>(std::size_t)
    {
        static meta<cons> m;

        if (find(m.bitmap, m.bitmap + meta<cons>::bits, 0))
            return m;

        abort();
    }

    void* rooty(0);

    void collect(VERBOSITY_ARG())
    {
        VERBOSE("starting");

        // do we need meta<void>
        // or can we safely assume
        // to know the exact meta type?
        // probably not: if a slot is just declared
        // <object> we never know the metadata
        meta<void>* m(object_meta(rooty));
        if (m)
            m->mark(rooty PASS_VERBOSE);
        /// if (m.trymark(rooty.first)) ...;

        VERBOSE("done");
    }

    void meta<void>::mark(void* p PLUS_VERBOSITY_ARG())
    {
        // look whether it is a cons
        VERBOSE("trying to mark: " << p);
        // hack!
        meta<cons>& m(get_meta<cons>(1));
        m.mark(static_cast<cons*>(p) PASS_VERBOSE);
    }
}

// http://www.opengroup.org/onlinepubs/007908799/xsh/sigaction.html
// http://www.gnu.org/software/libc/manual/html_node/Sigaction-Function-Example.html
// http://www.opengroup.org/onlinepubs/000095399/basedefs/signal.h.html
void yummy(int, siginfo_t *, void *);
void yummy(int, siginfo_t* indo, void *)
{
    printf("gggg\n");
    abort();
}

void wummy(int, siginfo_t *, void *);
void wummy(int what, siginfo_t* info, void *)
{
    printf("Solaris: handling\n");

    if (!info)
    {
        printf("info == 0!\n");
        abort();
    }

    switch  (what)
    {
        case SIGSEGV:
        {
            printf("SIGSEGV\n");
            switch  (info->si_code)
            {
                case SEGV_MAPERR:
                    printf("MAPERR\n");
                    break;
                case SEGV_ACCERR:
                    printf("MAPERR\n");
                    break;
            }
            printf("info->si_addr = %p\n", info->si_addr);
        }
    }

    abort();
}

int main(void)
{
    vector<int, alloc<int> > v(3);
    map<int, int, less<int>, alloc<int> > m;
    m.insert(make_pair(1, 42));

    cons* c(alloc<cons>().allocate(1));
    c->first = c;
    c->second = 0;
    rooty = c;

    collect(true);

    int hdl(shm_open("/blubber",
                     O_RDWR | O_CREAT,
                     S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP));

    perror("shm_open");

#   ifdef __APPLE__
    typedef ClusteredWorld<100, 0xFF000000UL, 12> world;
#   else
    typedef ClusteredWorld<100, 0xFF000000UL, 13> world;
#   endif

    int tr(ftruncate(hdl, world::size()));
    if (tr == -1)
        perror("ftruncate");

    world* w(new(hdl) world);
    void* area(w);

    if (MAP_FAILED == area)
        perror("mmap");

    w->protectPageRW(0);

    struct sigaction act, oact;
    memset(&act, 0, sizeof act);
    sigemptyset(&act.sa_mask);
    act.sa_flags = SA_SIGINFO;

#   ifdef __APPLE__
    act.sa_sigaction = yummy;
    if (sigaction(SIGBUS, &act, &oact))
#   else
    act.sa_sigaction = wummy;
    if (sigaction(SIGSEGV, &act, &oact))
#   endif
        perror("sigaction");

    {
        for (int i(0); i < 100; i += 4)
        {
            char* p((char*)area + i);
            printf("i: %d, o: %p, m: %p\n", i, p, world::Cluster<4, 3>::Raw2Meta(p));
            *p = 0;
        }

        for (int i(10000); i < 10100; i += 4)
        {
            char* p((char*)area + i);
            printf("i: %d, o: %p, m: %p\n", i, p, world::Cluster<4, 3>::Raw2Meta(p));
            *p = 0;
        }

        sleep(3);
        int um(munmap(area, world::size()));
        if (um == -1)
            perror("munmap");
    }

    int ul(shm_unlink("/blubber"));
    if (ul == -1)
        perror("shm_unlink");

}
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <list>
#include <sstream>

#define VERSION "1.0.0"

std::string path;
std::string base;
std::string prog;

// Windows compilers will normally set this, otherwise Windows compilation can
// be forced by explicitly setting -DOS_WIN
#ifdef _WIN32
#define OS_WIN
#endif

#define RESET   "\033[0m"
#define BOLD    "\033[1m"

#ifdef OS_WIN

// Use implementation of realpath based on GetFullPathNameA by Nach M. S.
#include "realpath.h"

#define SEPARATOR '\\'
#define VOL_SEP ':'

#else

#define SEPARATOR '/'
#define VOL_SEP '\0'

#endif

bool resolveSymlinks = false;
bool isAbsolute = false;

enum HelpLevel {
    HelpLevelShort,
    HelpLevelLong
};

bool isRelative(const std::string &path)
{
    return (path.at(0) != SEPARATOR);
}

std::string volumePart(const std::string &path)
{
    std::string result;
    if (VOL_SEP && path.at(1) == VOL_SEP)
    {
        result = path.substr(0, 2);
    }
    return result;
}

std::string pathPart(const std::string &path)
{
    std::string result = path;
    if (VOL_SEP && (path.at(1) == VOL_SEP))
    {
        result = path.substr(2);
    }
    return result;
}

void printHelp(HelpLevel helpLevel = HelpLevelShort)
{
    if (helpLevel == HelpLevelShort)
    {
        std::cerr << "Usage: " << prog << " [-h] | [-s] path [relative_path]" << std::endl;
    }
    else
    {
        std::cerr << "\n"
                     BOLD "SYNOPSIS\n" RESET
                     "\n"
                     "       " << prog << " [-h] | [-s] path [relative_path]\n"
                     "\n"
                     BOLD "DESCRIPTION\n" RESET
                     "\n"
                     "    Returns " BOLD "path" RESET " resolved to canonical form, that is with \"..\", \".\" and\n"
                     "    doubled-seperators \"" << SEPARATOR << SEPARATOR << "\" replaced where possible so as to form\n"
                     "    the simplest result that still specifies the same path.\n"
                     "\n"
                     "    In the two-argument form, returns the " BOLD "path" RESET " in the first argument resolved\n"
                     "    as relative to the " BOLD "relative_path" RESET " in the second argument.\n"
                     "\n"
                     "    If the path/s could be resolved resolvr returns EXIT_SUCCESS and outputs the\n"
                     "    resolved path, otherwise it returns EXIT_FAILURE.\n"
                     "\n"
                     BOLD "OPTIONS\n" RESET
                     "\n"
                     BOLD "    -s\n" RESET
                     "        In the default case this program only does string manipulation, and does not\n"
                     "        reference the file system at all.  With -s symlinks are resolved and paths\n"
                     "        are checked on the file system.  See PATH RESOLUTION below.\n"
                     "\n"
                     BOLD "    -h\n" RESET
                     "        Print this help and exit with EXIT_SUCCESS.\n"
                     "\n"
                     BOLD "PLATFORMS\n" RESET
                     "\n"
                     "    If -s is specified then this program will resolve symlinks to their targets, and\n"
                     "    will fail with EXIT_FAILURE if the target path does not exist.  In the case of\n"
                     "    -s the " BOLD "second argument is ignored" RESET " and the current directory is assumed\n"
                     "    as the base for any relative path.\n"
                     "\n"
                     "    On Windows uses \"\\\" as the path separator character, on all other platforms\n"
                     "    the \"/\" character.\n"
                     "\n"
                     BOLD "PATH RESOLUTION\n" RESET
                     "\n"
                     "    In the -s case path resolution is as per the realpath C library function as here:\n"
                     "\n"
                     "      http://pubs.opengroup.org/onlinepubs/9699919799/functions/realpath.html\n"
                     "\n"
                     "    so in the -s case this tool is really just a simple wrapper around realpath (on\n"
                     "    those systems that provide it).\n"
                     "\n"
                     "    Some systems (not Mac OSX or Windows) have command line versions of realpath or an\n"
                     "    equivalent in readlink -f which will return a canonical path.\n"
                     "\n"
                     "    If shell versions of realpath are available this program in the -s case is equivalent\n"
                     "    to the bash shell code:\n"
                     "\n"
                     "        realpath \"$2/$1\"\n"
                     "\n"
                     BOLD "CREDIT\n" RESET
                     "\n"
                     "    Written by Sarah Smith 2013.\n"
                     "\n"
                     "    Windows implementation of \"realpath\" is by Nach M. S. as described here:\n"
                     "\n"
                     "      http://sourceforge.net/p/mingw/patches/256/"
                     << std::endl;
    }
}

int main(int argc, char *argv[])
{
    std::list<std::string> args;
    for (int i = 0; i < argc; ++i)
    {
        args.push_back( std::string( argv[i] ));
    }

    prog = args.front();
    args.pop_front();

    while (args.size() > 0)
    {
        std::string opt = args.front();
        args.pop_front();
        if (opt == "-h")
        {
            printHelp(HelpLevelLong);
            exit( EXIT_SUCCESS );
        }
        else if (opt == "-s")
        {
            resolveSymlinks = true;
        }
        else if (path.size() == 0)
        {
            path = opt;
        }
        else if (base.size() == 0)
        {
            base = opt;
        }
        else
        {
            std::cerr << "Ignoring extra arguments.  (Do you need to quote or escape spaces?)" << std::endl;
            printHelp();
        }
    }
    if (path.size() == 0)
    {
        printHelp();
        exit( EXIT_FAILURE );
    }

    std::string volPart = volumePart(path);
    if (volPart.size() > 0)
        path = pathPart(path);

    if (base.size() > 0)
        path = base + SEPARATOR + path;

    isAbsolute = !isRelative(path);

    std::cerr << "resolving \"" << path << "\"\n";

    if (resolveSymlinks)
    {
        // Note in this case we ignore the relative_path "base" argument
        char *resolved = realpath( path.c_str(), NULL );
        path = resolved;
        free( resolved );
    }
    else
    {
        std::stringstream ss(path);
        std::string item;
        std::list<std::string> pathParts;
        while (std::getline(ss, item, SEPARATOR))
        {
            // drop empty parts (from eg "//") and 'dots' from eg "/./"
            if (item.size() == 0 || item == ".") continue;
            // go up a dir on "/../" parts if not at beginning of a path
            if (item == ".." && pathParts.size() > 0)
            {
                pathParts.pop_back();
                continue;
            }
            // in all other cases accumulate to the resulting path
            pathParts.push_back(item);
        }
        path.clear();
        if (pathParts.size() == 0)
        {
            path = isAbsolute ? SEPARATOR : '.';
        }
        else
        {
            if (isAbsolute)
                path = SEPARATOR;
            path = path + pathParts.front();
            pathParts.pop_front();
            std::list<std::string>::const_iterator it = pathParts.begin();
            for ( ; it != pathParts.end(); ++it)
            {
                path = path + SEPARATOR + *it;
            }
        }
    }

    if (volPart.size() > 0)
        path = volPart + path;

    std::cout << path << std::endl;
}
<commit_msg>Compile on Linux.<commit_after>#include <iostream>
#include <string>
#include <list>
#include <sstream>

#include <stdlib.h>

#define VERSION "1.0.0"

std::string path;
std::string base;
std::string prog;

// Windows compilers will normally set this, otherwise Windows compilation can
// be forced by explicitly setting -DOS_WIN
#ifdef _WIN32
#define OS_WIN
#endif

#define RESET   "\033[0m"
#define BOLD    "\033[1m"

#ifdef OS_WIN

// Use implementation of realpath based on GetFullPathNameA by Nach M. S.
#include "realpath.h"

#define SEPARATOR '\\'
#define VOL_SEP ':'

#else

#define SEPARATOR '/'
#define VOL_SEP '\0'

#endif

bool resolveSymlinks = false;
bool isAbsolute = false;

enum HelpLevel {
    HelpLevelShort,
    HelpLevelLong
};

bool isRelative(const std::string &path)
{
    return (path.at(0) != SEPARATOR);
}

std::string volumePart(const std::string &path)
{
    std::string result;
    if (VOL_SEP && path.at(1) == VOL_SEP)
    {
        result = path.substr(0, 2);
    }
    return result;
}

std::string pathPart(const std::string &path)
{
    std::string result = path;
    if (VOL_SEP && (path.at(1) == VOL_SEP))
    {
        result = path.substr(2);
    }
    return result;
}

void printHelp(HelpLevel helpLevel = HelpLevelShort)
{
    if (helpLevel == HelpLevelShort)
    {
        std::cerr << "Usage: " << prog << " [-h] | [-s] path [relative_path]" << std::endl;
    }
    else
    {
        std::cerr << "\n"
                     BOLD "SYNOPSIS\n" RESET
                     "\n"
                     "       " << prog << " [-h] | [-s] path [relative_path]\n"
                     "\n"
                     BOLD "DESCRIPTION\n" RESET
                     "\n"
                     "    Returns " BOLD "path" RESET " resolved to canonical form, that is with \"..\", \".\" and\n"
                     "    doubled-seperators \"" << SEPARATOR << SEPARATOR << "\" replaced where possible so as to form\n"
                     "    the simplest result that still specifies the same path.\n"
                     "\n"
                     "    In the two-argument form, returns the " BOLD "path" RESET " in the first argument resolved\n"
                     "    as relative to the " BOLD "relative_path" RESET " in the second argument.\n"
                     "\n"
                     "    If the path/s could be resolved resolvr returns EXIT_SUCCESS and outputs the\n"
                     "    resolved path, otherwise it returns EXIT_FAILURE.\n"
                     "\n"
                     BOLD "OPTIONS\n" RESET
                     "\n"
                     BOLD "    -s\n" RESET
                     "        In the default case this program only does string manipulation, and does not\n"
                     "        reference the file system at all.  With -s symlinks are resolved and paths\n"
                     "        are checked on the file system.  See PATH RESOLUTION below.\n"
                     "\n"
                     BOLD "    -h\n" RESET
                     "        Print this help and exit with EXIT_SUCCESS.\n"
                     "\n"
                     BOLD "PLATFORMS\n" RESET
                     "\n"
                     "    If -s is specified then this program will resolve symlinks to their targets, and\n"
                     "    will fail with EXIT_FAILURE if the target path does not exist.  In the case of\n"
                     "    -s the " BOLD "second argument is ignored" RESET " and the current directory is assumed\n"
                     "    as the base for any relative path.\n"
                     "\n"
                     "    On Windows uses \"\\\" as the path separator character, on all other platforms\n"
                     "    the \"/\" character.\n"
                     "\n"
                     BOLD "PATH RESOLUTION\n" RESET
                     "\n"
                     "    In the -s case path resolution is as per the realpath C library function as here:\n"
                     "\n"
                     "      http://pubs.opengroup.org/onlinepubs/9699919799/functions/realpath.html\n"
                     "\n"
                     "    so in the -s case this tool is really just a simple wrapper around realpath (on\n"
                     "    those systems that provide it).\n"
                     "\n"
                     "    Some systems (not Mac OSX or Windows) have command line versions of realpath or an\n"
                     "    equivalent in readlink -f which will return a canonical path.\n"
                     "\n"
                     "    If shell versions of realpath are available this program in the -s case is equivalent\n"
                     "    to the bash shell code:\n"
                     "\n"
                     "        realpath \"$2/$1\"\n"
                     "\n"
                     BOLD "CREDIT\n" RESET
                     "\n"
                     "    Written by Sarah Smith 2013.\n"
                     "\n"
                     "    Windows implementation of \"realpath\" is by Nach M. S. as described here:\n"
                     "\n"
                     "      http://sourceforge.net/p/mingw/patches/256/"
                     << std::endl;
    }
}

int main(int argc, char *argv[])
{
    std::list<std::string> args;
    for (int i = 0; i < argc; ++i)
    {
        args.push_back( std::string( argv[i] ));
    }

    prog = args.front();
    args.pop_front();

    while (args.size() > 0)
    {
        std::string opt = args.front();
        args.pop_front();
        if (opt == "-h")
        {
            printHelp(HelpLevelLong);
            exit( EXIT_SUCCESS );
        }
        else if (opt == "-s")
        {
            resolveSymlinks = true;
        }
        else if (path.size() == 0)
        {
            path = opt;
        }
        else if (base.size() == 0)
        {
            base = opt;
        }
        else
        {
            std::cerr << "Ignoring extra arguments.  (Do you need to quote or escape spaces?)" << std::endl;
            printHelp();
        }
    }
    if (path.size() == 0)
    {
        printHelp();
        exit( EXIT_FAILURE );
    }

    std::string volPart = volumePart(path);
    if (volPart.size() > 0)
        path = pathPart(path);

    if (base.size() > 0)
        path = base + SEPARATOR + path;

    isAbsolute = !isRelative(path);

    std::cerr << "resolving \"" << path << "\"\n";

    if (resolveSymlinks)
    {
        // Note in this case we ignore the relative_path "base" argument
        char *resolved = realpath( path.c_str(), NULL );
        path = resolved;
        free( resolved );
    }
    else
    {
        std::stringstream ss(path);
        std::string item;
        std::list<std::string> pathParts;
        while (std::getline(ss, item, SEPARATOR))
        {
            // drop empty parts (from eg "//") and 'dots' from eg "/./"
            if (item.size() == 0 || item == ".") continue;
            // go up a dir on "/../" parts if not at beginning of a path
            if (item == ".." && pathParts.size() > 0)
            {
                pathParts.pop_back();
                continue;
            }
            // in all other cases accumulate to the resulting path
            pathParts.push_back(item);
        }
        path.clear();
        if (pathParts.size() == 0)
        {
            path = isAbsolute ? SEPARATOR : '.';
        }
        else
        {
            if (isAbsolute)
                path = SEPARATOR;
            path = path + pathParts.front();
            pathParts.pop_front();
            std::list<std::string>::const_iterator it = pathParts.begin();
            for ( ; it != pathParts.end(); ++it)
            {
                path = path + SEPARATOR + *it;
            }
        }
    }

    if (volPart.size() > 0)
        path = volPart + path;

    std::cout << path << std::endl;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: appdata.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: as $ $Date: 2000-11-08 14:25:41 $
 *
 *  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 _CACHESTR_HXX //autogen
#include <tools/cachestr.hxx>
#endif
#ifndef _SV_CONFIG_HXX //autogen
#include <vcl/config.hxx>
#endif
#ifndef _INETSTRM_HXX //autogen
#include <svtools/inetstrm.hxx>
#endif
#ifndef _SFXSTRITEM_HXX //autogen
#include <svtools/stritem.hxx>
#endif

#define _SVSTDARR_STRINGS
#include <svtools/svstdarr.hxx>
#include <vos/mutex.hxx>

#include <vcl/menu.hxx>

#ifndef _LOGINERR_HXX
#include <svtools/loginerr.hxx>
#endif
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif
#ifndef _DATETIMEITEM_HXX //autogen
#include <svtools/dateitem.hxx>
#endif
#ifndef _SV_MENU_HXX
#include <vcl/menu.hxx>
#endif
#ifndef _SV_WRKWIN_HXX
#include <vcl/wrkwin.hxx>
#endif

#include "viewfrm.hxx"
#include "appdata.hxx"
#include "dispatch.hxx"
#include "event.hxx"
#include "sfxtypes.hxx"
#include "sfxdir.hxx"
#include "doctempl.hxx"
#include "dataurl.hxx"
#include "arrdecl.hxx"
#include "docfac.hxx"
#include "picklist.hxx"
#include "docfile.hxx"
#include "request.hxx"
#include "referers.hxx"
#include "app.hrc"
#include "sfxresid.hxx"
#include "objshimp.hxx"
#if SUPD<613//MUSTINI
#include "inimgr.hxx"
#endif
#include "ucbhelp.hxx"
#include "appuno.hxx"

SfxAppData_Impl::SfxAppData_Impl( SfxApplication* pApp ) :
        pAppCfg (0),
        pProgress(0),
        pPool(0),
        pFactArr(0),
        pDdeService( 0 ),
        pDocTopics( 0 ),
        pEventConfig(0),
        nAsynchronCalls(0),
        pVerbs(0),
        nBasicCallLevel(0),
        nRescheduleLocks(0),
        nInReschedule(0),
        pInitLinkList(0),
        pMatcher( 0 ),
        pSfxPlugInObjectShellFactory( 0 ),
        pDefFocusWin( 0 ),
        pSfxFrameObjectFactoryPtr( 0 ),
        pStopButtonTimer( 0 ),
        pCancelMgr( 0 ),
        nDocModalMode(0),
        pDisabledSlotList( 0 ),
        pFilterIni( 0 ),
        pSfxPluginObjectFactoryPtr( 0 ),
        pTemplateCommon( 0 ),
        pLabelResMgr( 0 ),
        pTopFrames( new SfxFrameArr_Impl ),
        pSecureURLs(0),
        nAutoTabPageId(0),
        nExecutingSID( 0 ),
        pNewMenu( 0 ),
        pAutoPilotMenu( 0 ),
        pAppDispatch(NULL),
        pTriggerTopic(0),
        pDdeService2(0),
        pMiscConfig(0),
        pThisDocument(0),
        bPlugged(sal_False),
        bOLEResize(sal_False),
        bDirectAliveCount(sal_False),
        bInQuit(sal_False),
        bInvalidateOnUnlock(sal_False),
        bBean( sal_False ),
        bMinimized( sal_False ),
        bInvisible( sal_False ),
        bInException( sal_False ),
        nAppEvent( 0 ),
        pTemplates( 0 ),
        pSaveOptions( 0 ),
        pUndoOptions( 0 ),
        pHelpOptions( 0 )
{
    StartListening( *pApp );
}

SfxAppData_Impl::~SfxAppData_Impl()
{
#ifdef DBG_UTIL
    delete pTopFrames;
    delete pCancelMgr;
    delete pFilterIni;
    delete pSecureURLs;
#endif
}

IMPL_STATIC_LINK( SfxAppData_Impl, CreateDocumentTemplates, void*, EMPTYARG)
{
    pThis->GetDocumentTemplates();
    return 0;
}

void SfxAppData_Impl::UpdateApplicationSettings( sal_Bool bDontHide )
{
    AllSettings aAllSet = Application::GetSettings();
    StyleSettings aStyleSet = aAllSet.GetStyleSettings();
    sal_uInt32 nStyleOptions = aStyleSet.GetOptions();
    if ( bDontHide )
        nStyleOptions &= ~STYLE_OPTION_HIDEDISABLED;
    else
        nStyleOptions |= STYLE_OPTION_HIDEDISABLED;
    aStyleSet.SetOptions( nStyleOptions );
    aAllSet.SetStyleSettings( aStyleSet );
    Application::SetSettings( aAllSet );
}

SfxDocumentTemplates* SfxAppData_Impl::GetDocumentTemplates()
{
    if ( !pTemplates )
    {
        pTemplates = new SfxDocumentTemplates;
        pTemplates->Construct();
    }

    return pTemplates;
}

void SfxAppData_Impl::Notify( SfxBroadcaster &rBC, const SfxHint &rHint )
{
#if SUPD<613//MUSTINI
    const SfxIniManagerHint* pIniManHint = PTR_CAST(SfxIniManagerHint, &rHint);
    if ( pIniManHint && pIniManHint->GetIniKey() == SFX_KEY_DONTHIDE_DISABLEDENTRIES )
    {
        sal_Bool bDontHide = (sal_Bool)(sal_uInt16)pIniManHint->GetNewValue().ToInt32();
        UpdateApplicationSettings( bDontHide );
    }
#endif
}

<commit_msg>Added bServer.<commit_after>/*************************************************************************
 *
 *  $RCSfile: appdata.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: sb $ $Date: 2000-11-09 12:59:19 $
 *
 *  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 _CACHESTR_HXX //autogen
#include <tools/cachestr.hxx>
#endif
#ifndef _SV_CONFIG_HXX //autogen
#include <vcl/config.hxx>
#endif
#ifndef _INETSTRM_HXX //autogen
#include <svtools/inetstrm.hxx>
#endif
#ifndef _SFXSTRITEM_HXX //autogen
#include <svtools/stritem.hxx>
#endif

#define _SVSTDARR_STRINGS
#include <svtools/svstdarr.hxx>
#include <vos/mutex.hxx>

#include <vcl/menu.hxx>

#ifndef _LOGINERR_HXX
#include <svtools/loginerr.hxx>
#endif
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif
#ifndef _DATETIMEITEM_HXX //autogen
#include <svtools/dateitem.hxx>
#endif
#ifndef _SV_MENU_HXX
#include <vcl/menu.hxx>
#endif
#ifndef _SV_WRKWIN_HXX
#include <vcl/wrkwin.hxx>
#endif

#include "viewfrm.hxx"
#include "appdata.hxx"
#include "dispatch.hxx"
#include "event.hxx"
#include "sfxtypes.hxx"
#include "sfxdir.hxx"
#include "doctempl.hxx"
#include "dataurl.hxx"
#include "arrdecl.hxx"
#include "docfac.hxx"
#include "picklist.hxx"
#include "docfile.hxx"
#include "request.hxx"
#include "referers.hxx"
#include "app.hrc"
#include "sfxresid.hxx"
#include "objshimp.hxx"
#if SUPD<613//MUSTINI
#include "inimgr.hxx"
#endif
#include "ucbhelp.hxx"
#include "appuno.hxx"

SfxAppData_Impl::SfxAppData_Impl( SfxApplication* pApp ) :
        bServer( false ),
        pAppCfg (0),
        pProgress(0),
        pPool(0),
        pFactArr(0),
        pDdeService( 0 ),
        pDocTopics( 0 ),
        pEventConfig(0),
        nAsynchronCalls(0),
        pVerbs(0),
        nBasicCallLevel(0),
        nRescheduleLocks(0),
        nInReschedule(0),
        pInitLinkList(0),
        pMatcher( 0 ),
        pSfxPlugInObjectShellFactory( 0 ),
        pDefFocusWin( 0 ),
        pSfxFrameObjectFactoryPtr( 0 ),
        pStopButtonTimer( 0 ),
        pCancelMgr( 0 ),
        nDocModalMode(0),
        pDisabledSlotList( 0 ),
        pFilterIni( 0 ),
        pSfxPluginObjectFactoryPtr( 0 ),
        pTemplateCommon( 0 ),
        pLabelResMgr( 0 ),
        pTopFrames( new SfxFrameArr_Impl ),
        pSecureURLs(0),
        nAutoTabPageId(0),
        nExecutingSID( 0 ),
        pNewMenu( 0 ),
        pAutoPilotMenu( 0 ),
        pAppDispatch(NULL),
        pTriggerTopic(0),
        pDdeService2(0),
        pMiscConfig(0),
        pThisDocument(0),
        bPlugged(sal_False),
        bOLEResize(sal_False),
        bDirectAliveCount(sal_False),
        bInQuit(sal_False),
        bInvalidateOnUnlock(sal_False),
        bBean( sal_False ),
        bMinimized( sal_False ),
        bInvisible( sal_False ),
        bInException( sal_False ),
        nAppEvent( 0 ),
        pTemplates( 0 ),
        pSaveOptions( 0 ),
        pUndoOptions( 0 ),
        pHelpOptions( 0 )
{
    StartListening( *pApp );
}

SfxAppData_Impl::~SfxAppData_Impl()
{
#ifdef DBG_UTIL
    delete pTopFrames;
    delete pCancelMgr;
    delete pFilterIni;
    delete pSecureURLs;
#endif
}

IMPL_STATIC_LINK( SfxAppData_Impl, CreateDocumentTemplates, void*, EMPTYARG)
{
    pThis->GetDocumentTemplates();
    return 0;
}

void SfxAppData_Impl::UpdateApplicationSettings( sal_Bool bDontHide )
{
    AllSettings aAllSet = Application::GetSettings();
    StyleSettings aStyleSet = aAllSet.GetStyleSettings();
    sal_uInt32 nStyleOptions = aStyleSet.GetOptions();
    if ( bDontHide )
        nStyleOptions &= ~STYLE_OPTION_HIDEDISABLED;
    else
        nStyleOptions |= STYLE_OPTION_HIDEDISABLED;
    aStyleSet.SetOptions( nStyleOptions );
    aAllSet.SetStyleSettings( aStyleSet );
    Application::SetSettings( aAllSet );
}

SfxDocumentTemplates* SfxAppData_Impl::GetDocumentTemplates()
{
    if ( !pTemplates )
    {
        pTemplates = new SfxDocumentTemplates;
        pTemplates->Construct();
    }

    return pTemplates;
}

void SfxAppData_Impl::Notify( SfxBroadcaster &rBC, const SfxHint &rHint )
{
#if SUPD<613//MUSTINI
    const SfxIniManagerHint* pIniManHint = PTR_CAST(SfxIniManagerHint, &rHint);
    if ( pIniManHint && pIniManHint->GetIniKey() == SFX_KEY_DONTHIDE_DISABLEDENTRIES )
    {
        sal_Bool bDontHide = (sal_Bool)(sal_uInt16)pIniManHint->GetNewValue().ToInt32();
        UpdateApplicationSettings( bDontHide );
    }
#endif
}

<|endoftext|>


<commit_before>
#include "infrastructure/breakpad.h"
#include "breakpad\exception_handler.h"
#include "infrastructure/format.h"

// Delegate back to breakpad
static bool HandleCrashCallbackDelegate(const wchar_t* dump_path,
	const wchar_t* minidump_id,
	void* context,
	EXCEPTION_POINTERS* exinfo,
	MDRawAssertionInfo* assertion,
	bool succeeded) {
	auto breakpad = (Breakpad*)context;

	auto msg = fmt::format(L"Sorry! TemplePlus seems to have crashed. A crash report was written to {}\\{}.dmp.\n\n"
		L"If you want to report this issue, please make sure to attach this file.",
		dump_path,
		minidump_id);

	// Now starts the tedious work of reporting on this crash, heh.
	MessageBox(NULL, msg.c_str(), L"TemplePlus Crashed - Oops!", MB_OK);

	return false;
}

Breakpad::Breakpad(const std::wstring &crashDumpFolder)
{
	using google_breakpad::ExceptionHandler;

	CreateDirectory(crashDumpFolder.c_str(), nullptr);

	mHandler.reset(new ExceptionHandler(
		crashDumpFolder.c_str(),
		nullptr,
		HandleCrashCallbackDelegate,
		this,
		ExceptionHandler::HANDLER_ALL
	));

}

Breakpad::~Breakpad()
{
}
<commit_msg>Added more guidance for crash reporting<commit_after>
#include "infrastructure/breakpad.h"
#include "breakpad\exception_handler.h"
#include "infrastructure/format.h"

// Delegate back to breakpad
static bool HandleCrashCallbackDelegate(const wchar_t* dump_path,
	const wchar_t* minidump_id,
	void* context,
	EXCEPTION_POINTERS* exinfo,
	MDRawAssertionInfo* assertion,
	bool succeeded) {
	auto breakpad = (Breakpad*)context;

	auto msg = fmt::format(L"Sorry! TemplePlus seems to have crashed. A crash report was written to {}\\{}.dmp.\n\n"
		L"If you want to report this issue, please make sure to attach this file.\nPlease also attach your savegame file from your ToEE folder under modules\\ToEE\\Save. Be sure to include the .tfaf, .tfai and .gsi files.",
		dump_path,
		minidump_id);

	// Now starts the tedious work of reporting on this crash, heh.
	MessageBox(NULL, msg.c_str(), L"TemplePlus Crashed - Oops!", MB_OK);

	return false;
}

Breakpad::Breakpad(const std::wstring &crashDumpFolder)
{
	using google_breakpad::ExceptionHandler;

	CreateDirectory(crashDumpFolder.c_str(), nullptr);

	mHandler.reset(new ExceptionHandler(
		crashDumpFolder.c_str(),
		nullptr,
		HandleCrashCallbackDelegate,
		this,
		ExceptionHandler::HANDLER_ALL
	));

}

Breakpad::~Breakpad()
{
}
<|endoftext|>


<commit_before><commit_msg>coverity#708146 Uninitialized scalar field<commit_after><|endoftext|>


<commit_before>/* Copyright 2009 SPARTA, Inc., dba Cobham Analytic Solutions
 *
 * This file is part of WATCHER.
 *
 *     WATCHER is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU Affero General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     WATCHER 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 Affero General Public License for more details.
 *
 *     You should have received a copy of the GNU Affero General Public License
 *     along with Watcher.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * @file sendNodePropertiesMessage.cpp
 * @author Geoff Lawler <geoff.lawler@cobham.com>
 * @date 2009-09-04
 */

/**
 * @page sendsendNodePropertiesMessage
 *
 * sendNodePropertiesMessage sends a node properties message. So there's that.
 */
#include <errno.h>
#include <stdlib.h>
#include <getopt.h>
#include <string>

#include <boost/asio.hpp>
#include <boost/lexical_cast.hpp>

#include "logger.h"
#include <libwatcher/client.h>
#include <libwatcher/colors.h>
#include <libwatcher/sendMessageHandler.h>
#include <libwatcher/nodePropertiesMessage.h>

using namespace std;
using namespace watcher;
using namespace watcher::event;
using namespace boost;

#ifndef SYSCONFDIR
#define SYSCONFDIR "/usr/local/etc"
#endif

DECLARE_GLOBAL_LOGGER("sendNodePropertiesMessage");

void usage(const char *progName)
{
    fprintf(stderr, "Usage: %s [args]\n", basename(progName));
    fprintf(stderr, "Args:\n");
    fprintf(stderr, "   -s, --server=address        The address of the node running watcherd.\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "Optional args:\n");
    fprintf(stderr, "   -n, --node=address          The node to modify, if empty the local node's address is used.\n");
    fprintf(stderr, "   -l, --layer=layer           The layer to apply these properties to. string, e.g. \"hierachy\". \n");
    fprintf(stderr, "\n");
    fprintf(stderr, "   -a, --shape=shape           The shape to make the node. One of: circle, triangle, square, torus, teapot.\n");
    fprintf(stderr, "   -e, --effect=effect         The effect to apply to the node, one of: flash, spin, sparkle.\n");
    fprintf(stderr, "                                  This agrument can be used multiple times. Not all GUIs support all effects.\n");
    fprintf(stderr, "   -P, --property=prop         Tell the daemon that this node has a certain property, one of\n");
    fprintf(stderr, "                                  leafnode, neighborhoor, regional, root, attacker, victim. This argument can be used\n");
    fprintf(stderr, "                                  more than once.\n");
    // fprintf(stderr, "   -x, --expiration=seconds    How long in seconds to apply the properties. 0==forever, default forever.\n");
    fprintf(stderr, "   -c, --color=color           Set the node's color to color. Color can be string, e.g. \"blue\", or \n");
    fprintf(stderr, "                                   hex RRGGBBAA (red, green, blue, alpha) value, \"0xff00ff64\"\n");
    fprintf(stderr, "   -z, --size=float            How large (or small) to make the node relative to other nodes.\n");
    fprintf(stderr, "   -T, --timestamp=ms          Optionally specify a timestamp for this event\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "   -r, --logProps              log.properties file, which controls logging for this program\n");
    fprintf(stderr, "                                    Default value is watcher.log.props in the system config directory.\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "   -h, --help                  Show this message\n");

    exit(EXIT_FAILURE);
}

int main(int argc, char **argv)
{
    TRACE_ENTER();

    int c;
    Color color(colors::red);
    string server, logProps(SYSCONFDIR "/watcher.log.props");

    NodePropertiesMessagePtr message(new NodePropertiesMessage);

    bool colorSet=false;

    while (true)
    {
        int option_index = 0;
        static struct option long_options[] = {
            {"server", required_argument, 0, 's'},
            {"node", required_argument, 0, 'n'},
            {"layer", required_argument, 0, 'l'},
            {"shape", required_argument, 0, 'a'},
            {"effect", required_argument, 0, 'e'},
            {"property", required_argument, 0, 'P'},
            // {"expiration", required_argument, 0, 'x'},
            {"color", required_argument, 0, 'c'},
            {"size", required_argument, 0, 'z'},
            {"logProps", required_argument, 0, 'r'},
            {"timestamp", required_argument, 0, 'T'},
            {"help", no_argument, 0, 'h'},
            {0, 0, 0, 0}
        };

        c = getopt_long(argc, argv, "s:n:l:a:e:p:x:c:z:r:hHT:?", long_options, &option_index);

        if (c == -1)
            break;

        switch(c)
        {
            case 's': server=optarg;
                      break;
            case 'n':
                      {
                          boost::system::error_code e;
                          message->fromNodeID=asio::ip::address::from_string(optarg, e);
                          if (e)
                          {
                              fprintf(stderr, "\nI did not understand the \"node\" argument: %s. It should be a host address.\n\n", optarg);
                              usage(argv[0]);
                          }
                      }
                      break;
            case 'l': message->layer=optarg;
                      break;
            case 'a': {
                          bool success=NodePropertiesMessage::stringToNodeShape(optarg, message->shape);
                          if (!success) {
                              fprintf(stderr, "Unable to parse shape argument \"%s\".\n\n", optarg);
                              usage(argv[0]);
                          }
                          message->useShape=true;
                      }
                      break;
            case 'e': {
                          NodePropertiesMessage::DisplayEffect e;
                          bool success=NodePropertiesMessage::stringToDisplayEffect(optarg, e);
                          if (!success) {
                              fprintf(stderr, "Unable to parse effect argument \"%s\".\n\n", optarg);
                              usage(argv[0]);
                          }
                          message->displayEffects.push_back(e);
                      }
                      break;
            case 'p': {
                          NodePropertiesMessage::NodeProperty p;
                          bool success=NodePropertiesMessage::stringToNodeProperty(optarg, p);
                          if (!success) {
                              fprintf(stderr, "Unable to parse property argument \"%s\".\n\n", optarg);
                              usage(argv[0]);
                          }
                          message->nodeProperties.push_back(p);
                      }
                      break;
            // case 'x': {
            //               try
            //               {
            //                   message->expiration=lexical_cast<Timestamp>(optarg); break;
            //               }
            //               catch (const boost::bad_lexical_cast &e)
            //               {
            //                   fprintf(stderr, "\nBad expiration argument: %s. It needs to be a number\n\n", optarg);
            //                   usage(argv[0]);
            //               }
            //           }
            //           break;
            case 'c': {
                          bool val=message->color.fromString(optarg);
                          if (!val)
                          {
                              printf("\nBad color argument: %s. Needs to be in ROYGBIV or \"0x12345678\" format.\n\n", optarg);
                              usage(argv[0]);
                          }
                          message->useColor=true;
                      }
                      break;
            case 'z': {
                          try
                          {
                              message->size=lexical_cast<float>(optarg); break;
                          }
                          catch (const boost::bad_lexical_cast &e)
                          {
                              fprintf(stderr, "\nBad size argument: %s. It needs to be a floating point number.\n\n", optarg);
                              usage(argv[0]);
                          }
                          if (message->size<0.0) {
                              fprintf(stderr, "\nBad size argument: %s. It needs to be a positive floating point number.\n\n", optarg);
                              usage(argv[0]);
                          }
                      }
                      break;
            case 'r': logProps=optarg;
                      break;
            case 'T':
				message->timestamp=lexical_cast<Timestamp>(optarg); break;
				break;
            case 'h':
            case 'H':
            case '?':
            default:
                      usage(argv[0]);
                      break;
        }
    }

    if (server=="") {
        fprintf(stderr, "\n\nserver is a required argument.\n\n");
        usage(argv[0]);
    }

    //
    // Now do some actual work.
    //
    LOAD_LOG_PROPS(logProps);

    watcher::Client client(server);
    LOG_INFO("Connecting to " << server << " and sending message.");
    client.addMessageHandler(SingleMessageHandler::create());

    if(!client.sendMessage(message))
    {
        LOG_ERROR("Error sending node properties message: " << *message);
        TRACE_EXIT_RET(EXIT_FAILURE);
        return EXIT_FAILURE;
    }

    client.wait();

    TRACE_EXIT_RET(EXIT_SUCCESS);
    return EXIT_SUCCESS;
}

<commit_msg>add label argument to set nodes label in the GUI<commit_after>/* Copyright 2009 SPARTA, Inc., dba Cobham Analytic Solutions
 *
 * This file is part of WATCHER.
 *
 *     WATCHER is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU Affero General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     WATCHER 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 Affero General Public License for more details.
 *
 *     You should have received a copy of the GNU Affero General Public License
 *     along with Watcher.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * @file sendNodePropertiesMessage.cpp
 * @author Geoff Lawler <geoff.lawler@cobham.com>
 * @date 2009-09-04
 */

/**
 * @page sendsendNodePropertiesMessage
 *
 * sendNodePropertiesMessage sends a node properties message. So there's that.
 */
#include <errno.h>
#include <stdlib.h>
#include <getopt.h>
#include <string>

#include <boost/asio.hpp>
#include <boost/lexical_cast.hpp>

#include "logger.h"
#include <libwatcher/client.h>
#include <libwatcher/colors.h>
#include <libwatcher/sendMessageHandler.h>
#include <libwatcher/nodePropertiesMessage.h>

using namespace std;
using namespace watcher;
using namespace watcher::event;
using namespace boost;

#ifndef SYSCONFDIR
#define SYSCONFDIR "/usr/local/etc"
#endif

DECLARE_GLOBAL_LOGGER("sendNodePropertiesMessage");

void usage(const char *progName)
{
    fprintf(stderr, "Usage: %s [args]\n", basename(progName));
    fprintf(stderr, "Args:\n");
    fprintf(stderr, "   -s, --server=address        The address of the node running watcherd.\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "Optional args:\n");
    fprintf(stderr, "   -n, --node=address          The node to modify, if empty the local node's address is used.\n");
    fprintf(stderr, "   -l, --layer=layer           The layer to apply these properties to. string, e.g. \"hierachy\". \n");
    fprintf(stderr, "\n");
    fprintf(stderr, "   -a, --shape=shape           The shape to make the node. One of: circle, triangle, square, torus, teapot.\n");
    fprintf(stderr, "   -e, --effect=effect         The effect to apply to the node, one of: flash, spin, sparkle.\n");
    fprintf(stderr, "                                  This agrument can be used multiple times. Not all GUIs support all effects.\n");
    fprintf(stderr, "   -P, --property=prop         Tell the daemon that this node has a certain property, one of\n");
    fprintf(stderr, "                                  leafnode, neighborhoor, regional, root, attacker, victim. This argument can be used\n");
    fprintf(stderr, "                                  more than once.\n");
    // fprintf(stderr, "   -x, --expiration=seconds    How long in seconds to apply the properties. 0==forever, default forever.\n");
    fprintf(stderr, "   -c, --color=color           Set the node's color to color. Color can be string, e.g. \"blue\", or \n");
    fprintf(stderr, "                                   hex RRGGBBAA (red, green, blue, alpha) value, \"0xff00ff64\"\n");
    fprintf(stderr, "   -L, --label=string          The label attached to the node\n");
    fprintf(stderr, "   -z, --size=float            How large (or small) to make the node relative to other nodes.\n");
    fprintf(stderr, "   -T, --timestamp=ms          Optionally specify a timestamp for this event\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "   -r, --logProps              log.properties file, which controls logging for this program\n");
    fprintf(stderr, "                                    Default value is watcher.log.props in the system config directory.\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "   -h, --help                  Show this message\n");

    exit(EXIT_FAILURE);
}

int main(int argc, char **argv)
{
    TRACE_ENTER();

    int c;
    Color color(colors::red);
    string server, logProps(SYSCONFDIR "/watcher.log.props");

    NodePropertiesMessagePtr message(new NodePropertiesMessage);

    bool colorSet=false;

    while (true)
    {
        int option_index = 0;
        static struct option long_options[] = {
            {"server", required_argument, 0, 's'},
            {"node", required_argument, 0, 'n'},
            {"layer", required_argument, 0, 'l'},
            {"shape", required_argument, 0, 'a'},
            {"effect", required_argument, 0, 'e'},
            {"property", required_argument, 0, 'P'},
            // {"expiration", required_argument, 0, 'x'},
            {"color", required_argument, 0, 'c'},
            {"label", required_argument, 0, 'L'},
            {"size", required_argument, 0, 'z'},
            {"logProps", required_argument, 0, 'r'},
            {"timestamp", required_argument, 0, 'T'},
            {"help", no_argument, 0, 'h'},
            {0, 0, 0, 0}
        };

        c = getopt_long(argc, argv, "s:n:l:a:e:p:x:c:n:z:r:hHT:?", long_options, &option_index);

        if (c == -1)
            break;

        switch(c)
        {
            case 's': server=optarg;
                      break;
            case 'n':
                      {
                          boost::system::error_code e;
                          message->fromNodeID=asio::ip::address::from_string(optarg, e);
                          if (e)
                          {
                              fprintf(stderr, "\nI did not understand the \"node\" argument: %s. It should be a host address.\n\n", optarg);
                              usage(argv[0]);
                          }
                      }
                      break;
            case 'l': message->layer=optarg;
                      break;
            case 'a': {
                          bool success=NodePropertiesMessage::stringToNodeShape(optarg, message->shape);
                          if (!success) {
                              fprintf(stderr, "Unable to parse shape argument \"%s\".\n\n", optarg);
                              usage(argv[0]);
                          }
                          message->useShape=true;
                      }
                      break;
            case 'e': {
                          NodePropertiesMessage::DisplayEffect e;
                          bool success=NodePropertiesMessage::stringToDisplayEffect(optarg, e);
                          if (!success) {
                              fprintf(stderr, "Unable to parse effect argument \"%s\".\n\n", optarg);
                              usage(argv[0]);
                          }
                          message->displayEffects.push_back(e);
                      }
                      break;
            case 'p': {
                          NodePropertiesMessage::NodeProperty p;
                          bool success=NodePropertiesMessage::stringToNodeProperty(optarg, p);
                          if (!success) {
                              fprintf(stderr, "Unable to parse property argument \"%s\".\n\n", optarg);
                              usage(argv[0]);
                          }
                          message->nodeProperties.push_back(p);
                      }
                      break;
            // case 'x': {
            //               try
            //               {
            //                   message->expiration=lexical_cast<Timestamp>(optarg); break;
            //               }
            //               catch (const boost::bad_lexical_cast &e)
            //               {
            //                   fprintf(stderr, "\nBad expiration argument: %s. It needs to be a number\n\n", optarg);
            //                   usage(argv[0]);
            //               }
            //           }
            //           break;
            case 'c': {
                          bool val=message->color.fromString(optarg);
                          if (!val)
                          {
                              printf("\nBad color argument: %s. Needs to be in ROYGBIV or \"0x12345678\" format.\n\n", optarg);
                              usage(argv[0]);
                          }
                          message->useColor=true;
                      }
                      break;
            case 'L': message->label=string(optarg);
                      break;
            case 'z': {
                          try
                          {
                              message->size=lexical_cast<float>(optarg); break;
                          }
                          catch (const boost::bad_lexical_cast &e)
                          {
                              fprintf(stderr, "\nBad size argument: %s. It needs to be a floating point number.\n\n", optarg);
                              usage(argv[0]);
                          }
                          if (message->size<0.0) {
                              fprintf(stderr, "\nBad size argument: %s. It needs to be a positive floating point number.\n\n", optarg);
                              usage(argv[0]);
                          }
                      }
                      break;
            case 'r': logProps=optarg;
                      break;
            case 'T':
				message->timestamp=lexical_cast<Timestamp>(optarg); break;
				break;
            case 'h':
            case 'H':
            case '?':
            default:
                      usage(argv[0]);
                      break;
        }
    }

    if (server=="") {
        fprintf(stderr, "\n\nserver is a required argument.\n\n");
        usage(argv[0]);
    }

    //
    // Now do some actual work.
    //
    LOAD_LOG_PROPS(logProps);

    watcher::Client client(server);
    LOG_INFO("Connecting to " << server << " and sending message.");
    client.addMessageHandler(SingleMessageHandler::create());

    if(!client.sendMessage(message))
    {
        LOG_ERROR("Error sending node properties message: " << *message);
        TRACE_EXIT_RET(EXIT_FAILURE);
        return EXIT_FAILURE;
    }

    client.wait();

    TRACE_EXIT_RET(EXIT_SUCCESS);
    return EXIT_SUCCESS;
}

<|endoftext|>


<commit_before>
/*
 * This file is part of cryptopp-bindings-api.
 *
 * (c) Stephen Berquet <stephen.berquet@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#include "src/exception/api_exception.h"
#include "api_block_cipher_abstract.h"
#include <sstream>

NAMESPACE_BEGIN(CryptoppApi)

BlockCipherAbstract::BlockCipherAbstract()
    : m_encryptor(NULL)
    , m_decryptor(NULL)
    , m_name("")
{
}

void BlockCipherAbstract::setCryptoppObjects(CryptoPP::BlockCipher *encryptor, CryptoPP::BlockCipher *decryptor)
{
    m_encryptor = encryptor;
    m_decryptor = decryptor;
}

const char *BlockCipherAbstract::getName() const
{
    return m_name.c_str();
}

size_t BlockCipherAbstract::getBlockSize() const
{
    return m_encryptor->BlockSize();
}

bool BlockCipherAbstract::isValidKeyLength(size_t length) const
{
    return m_encryptor->IsValidKeyLength(length);
}

void BlockCipherAbstract::setKey(const byte *key, const size_t keyLength)
{
    SymmetricKeyAbstract::setKey(key, keyLength);

    // copy key
    byte keyCopy[keyLength];
    memcpy(keyCopy, key, keyLength);

    m_encryptor->SetKey(keyCopy, keyLength);
    m_decryptor->SetKey(keyCopy, keyLength);
}

void BlockCipherAbstract::setName(const std::string name)
{
    m_name.assign(name);
}

void BlockCipherAbstract::encrypt(const byte *input, byte *output, const size_t length)
{
    size_t blockSize = getBlockSize();

    // data size must be a multiple of the block size
    if (0 != length % blockSize) {
        std::stringstream msg;
        msg << "data size (" << length << ") is not a multiple of block size (" << blockSize << ")";
        throw Exception(msg.str());
    }

    // verify that the key is valid
    hasValidKey(true);

    // encrypt each blocks
    int blocks = length / blockSize;

    for (int i = 0; i < blocks; i++) {
        m_encryptor->ProcessAndXorBlock(&input[i * blockSize], NULL, &output[i * blockSize]);
    }
}

void BlockCipherAbstract::decrypt(const byte *input, byte *output, const size_t length)
{
    size_t blockSize = getBlockSize();

    // data size must be a multiple of the block size
    if (0 != length % blockSize) {
        std::stringstream msg;
        msg << "data size (" << length << ") is not a multiple of block size (" << blockSize << ")";
        throw Exception(msg.str());
    }

    // verify that the key is valid
    hasValidKey(true);

    // decrypt each blocks
    int blocks = length / blockSize;

    for (int i = 0; i < blocks; i++) {
        m_decryptor->ProcessAndXorBlock(&input[i * blockSize], NULL, &output[i * blockSize]);
    }
}

void BlockCipherAbstract::encryptBlock(const byte *block, byte *output, const size_t length)
{
    size_t blockSize = getBlockSize();

    // data size must be exactly equals to the block size
    if (length != blockSize) {
        std::stringstream msg;
        msg << "data size (" << length << ") is not equal to cipher block size (" << blockSize << ")";
        throw Exception(msg.str());
    }

    // verify that the key is valid
    hasValidKey(true);

    m_encryptor->ProcessAndXorBlock(block, NULL, output);
}

void BlockCipherAbstract::decryptBlock(const byte *block, byte *output, const size_t length)
{
    size_t blockSize = getBlockSize();

    // data size must be exactly equals to the block size
    if (length != blockSize) {
        std::stringstream msg;
        msg << "data size (" << length << ") is not equal to cipher block size (" << blockSize << ")";
        throw Exception(msg.str());
    }

    // verify that the key is valid
    hasValidKey(true);

    m_decryptor->ProcessAndXorBlock(block, NULL, output);
}

NAMESPACE_END
<commit_msg>keys are now copied before set it to cryptopp objects<commit_after>
/*
 * This file is part of cryptopp-bindings-api.
 *
 * (c) Stephen Berquet <stephen.berquet@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#include "src/exception/api_exception.h"
#include "api_block_cipher_abstract.h"
#include <sstream>

NAMESPACE_BEGIN(CryptoppApi)

BlockCipherAbstract::BlockCipherAbstract()
    : m_encryptor(NULL)
    , m_decryptor(NULL)
    , m_name("")
{
}

void BlockCipherAbstract::setCryptoppObjects(CryptoPP::BlockCipher *encryptor, CryptoPP::BlockCipher *decryptor)
{
    m_encryptor = encryptor;
    m_decryptor = decryptor;
}

const char *BlockCipherAbstract::getName() const
{
    return m_name.c_str();
}

size_t BlockCipherAbstract::getBlockSize() const
{
    return m_encryptor->BlockSize();
}

bool BlockCipherAbstract::isValidKeyLength(size_t length) const
{
    return m_encryptor->IsValidKeyLength(length);
}

void BlockCipherAbstract::setKey(const byte *key, const size_t keyLength)
{
    SymmetricKeyAbstract::setKey(key, keyLength);

    // copy key
    byte keyCopy[keyLength];
    getKey(keyCopy);

    m_encryptor->SetKey(keyCopy, keyLength);
    m_decryptor->SetKey(keyCopy, keyLength);
}

void BlockCipherAbstract::setName(const std::string name)
{
    m_name.assign(name);
}

void BlockCipherAbstract::encrypt(const byte *input, byte *output, const size_t length)
{
    size_t blockSize = getBlockSize();

    // data size must be a multiple of the block size
    if (0 != length % blockSize) {
        std::stringstream msg;
        msg << "data size (" << length << ") is not a multiple of block size (" << blockSize << ")";
        throw Exception(msg.str());
    }

    // verify that the key is valid
    hasValidKey(true);

    // encrypt each blocks
    int blocks = length / blockSize;

    for (int i = 0; i < blocks; i++) {
        m_encryptor->ProcessAndXorBlock(&input[i * blockSize], NULL, &output[i * blockSize]);
    }
}

void BlockCipherAbstract::decrypt(const byte *input, byte *output, const size_t length)
{
    size_t blockSize = getBlockSize();

    // data size must be a multiple of the block size
    if (0 != length % blockSize) {
        std::stringstream msg;
        msg << "data size (" << length << ") is not a multiple of block size (" << blockSize << ")";
        throw Exception(msg.str());
    }

    // verify that the key is valid
    hasValidKey(true);

    // decrypt each blocks
    int blocks = length / blockSize;

    for (int i = 0; i < blocks; i++) {
        m_decryptor->ProcessAndXorBlock(&input[i * blockSize], NULL, &output[i * blockSize]);
    }
}

void BlockCipherAbstract::encryptBlock(const byte *block, byte *output, const size_t length)
{
    size_t blockSize = getBlockSize();

    // data size must be exactly equals to the block size
    if (length != blockSize) {
        std::stringstream msg;
        msg << "data size (" << length << ") is not equal to cipher block size (" << blockSize << ")";
        throw Exception(msg.str());
    }

    // verify that the key is valid
    hasValidKey(true);

    m_encryptor->ProcessAndXorBlock(block, NULL, output);
}

void BlockCipherAbstract::decryptBlock(const byte *block, byte *output, const size_t length)
{
    size_t blockSize = getBlockSize();

    // data size must be exactly equals to the block size
    if (length != blockSize) {
        std::stringstream msg;
        msg << "data size (" << length << ") is not equal to cipher block size (" << blockSize << ")";
        throw Exception(msg.str());
    }

    // verify that the key is valid
    hasValidKey(true);

    m_decryptor->ProcessAndXorBlock(block, NULL, output);
}

NAMESPACE_END
<|endoftext|>