#ifndef _H_DEBUGSUPPORT
#define _H_DEBUGSUPPORT
#include <security_utilities/debugging.h>
#include <security_utilities/threading.h>
#include <security_utilities/globalizer.h>
#include <cstdarg>
#include <set>
namespace Security {
namespace Debug {
class Name {
public:
static const int maxLength = 12;
Name(const char *s)
{ strncpy(mName, s, maxLength-1); mName[maxLength-1] = '\0'; }
Name(const char *start, const char *end)
{
intptr_t length = end - start; if (length >= maxLength) length = maxLength - 1;
memcpy(mName, start, length); memset(mName + length, 0, maxLength - length);
}
operator const char *() const { return mName; }
bool operator < (const Name &other) const
{ return memcmp(mName, other.mName, maxLength) < 0; }
bool operator == (const Name &other) const
{ return memcmp(mName, other.mName, maxLength) == 0; }
private:
char mName[maxLength]; };
class Target {
public:
Target();
virtual ~Target();
static Target &get();
void setFromEnvironment();
public:
class Sink {
public:
virtual ~Sink();
virtual void put(const char *buffer, unsigned int length) = 0;
virtual void dump(const char *buffer);
virtual void configure(const char *argument);
const bool needsDate;
protected:
Sink(bool nd = true) : needsDate(nd) { }
};
void to(Sink *sink);
void to(const char *filename);
void to(int syslogPriority);
void to(FILE *openFile);
void configure(); void configure(const char *options);
public:
void message(const char *scope, const char *format, va_list args);
bool debugging(const char *scope);
void dump(const char *format, va_list args);
bool dump(const char *scope);
protected:
class Selector {
public:
Selector();
void operator = (const char *config);
bool operator () (const char *name) const;
private:
bool useSet; bool negate; set<Name> enableSet; };
protected:
class PerThread {
public:
PerThread() { id = ++lastUsed; }
unsigned int id;
private:
static unsigned int lastUsed; };
ThreadNexus<PerThread> perThread;
protected:
static const size_t messageConstructionSize = 512;
Selector logSelector; Selector dumpSelector;
bool showScope; bool showScopeRight; bool showThread; bool showProc; bool showDate; size_t dumpLimit;
static const size_t maxProgNameLength = 20; static const size_t procLength = 14; static char progName[];
Sink *sink;
static terminate_handler previousTerminator; static void terminator();
static Target *singleton;
};
class FileSink : public Target::Sink {
public:
FileSink(FILE *f) : Sink(true), file(f) { }
void put(const char *, unsigned int);
void dump(const char *text);
void configure(const char *);
private:
FILE *file;
};
class SyslogSink : public Target::Sink {
public:
SyslogSink(int pri)
: Sink(false), priority(pri), dumpBase(dumpBuffer), dumpPtr(dumpBuffer) { }
void put(const char *, unsigned int);
void dump(const char *text);
void configure(const char *);
private:
int priority;
static const size_t dumpBufferSize = 1024; char dumpBuffer[dumpBufferSize];
char *dumpBase, *dumpPtr;
};
} }
#endif //_H_DEBUGSUPPORT