Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
dCache
cta
Commits
1faed310
Commit
1faed310
authored
Feb 15, 2016
by
Steven Murray
Browse files
Cross ported the new Syslog and String Logger classes
parent
e6dca0d7
Changes
21
Hide whitespace changes
Inline
Side-by-side
common/Configuration.cpp
View file @
1faed310
...
...
@@ -118,7 +118,7 @@ const std::string& cta::common::Configuration::getConfEntString(
log
::
Param
(
"key"
,
key
),
log
::
Param
(
"value"
,
entIt
->
second
),
log
::
Param
(
"source"
,
m_fileName
)};
(
*
log
)(
LOG_
INFO
,
"Configuration entry"
,
params
);
(
*
log
)(
log
::
INFO
,
"Configuration entry"
,
params
);
}
return
entIt
->
second
;
}
...
...
@@ -130,7 +130,7 @@ const std::string& cta::common::Configuration::getConfEntString(
log
::
Param
(
"key"
,
key
),
log
::
Param
(
"value"
,
defaultValue
),
log
::
Param
(
"source"
,
"DEFAULT"
)};
(
*
log
)(
LOG_
INFO
,
"Configuration entry"
,
params
);
(
*
log
)(
log
::
INFO
,
"Configuration entry"
,
params
);
}
// Unlock and return default
pthread_rwlock_unlock
(
&
m_lock
);
...
...
@@ -144,7 +144,7 @@ const std::string& cta::common::Configuration::getConfEntString(
log
::
Param
(
"key"
,
key
),
log
::
Param
(
"value"
,
defaultValue
),
log
::
Param
(
"source"
,
"DEFAULT"
)};
(
*
log
)(
LOG_
INFO
,
"Configuration entry"
,
params
);
(
*
log
)(
log
::
INFO
,
"Configuration entry"
,
params
);
}
}
catch
(...)
{
// release the lock
...
...
@@ -196,7 +196,7 @@ const std::string& cta::common::Configuration::getConfEntString(
log
::
Param
(
"key"
,
key
),
log
::
Param
(
"value"
,
entIt
->
second
),
log
::
Param
(
"source"
,
m_fileName
)};
(
*
log
)(
LOG_
INFO
,
"Configuration entry"
,
params
);
(
*
log
)(
log
::
INFO
,
"Configuration entry"
,
params
);
}
// release the lock
...
...
common/Configuration.hpp
View file @
1faed310
...
...
@@ -137,7 +137,7 @@ namespace cta { namespace common {
log
::
Param
(
"key"
,
key
),
log
::
Param
(
"value"
,
defaultValue
),
log
::
Param
(
"source"
,
"DEFAULT"
)};
(
*
log
)(
LOG_
INFO
,
"Configuration entry"
,
params
);
(
*
log
)(
log
::
INFO
,
"Configuration entry"
,
params
);
}
return
defaultValue
;
}
...
...
@@ -162,7 +162,7 @@ namespace cta { namespace common {
log
::
Param
(
"key"
,
key
),
log
::
Param
(
"value"
,
value
),
log
::
Param
(
"source"
,
m_fileName
)};
(
*
log
)(
LOG_
INFO
,
"Configuration entry"
,
params
);
(
*
log
)(
log
::
INFO
,
"Configuration entry"
,
params
);
}
return
value
;
...
...
@@ -204,7 +204,7 @@ namespace cta { namespace common {
log
::
Param
(
"key"
,
key
),
log
::
Param
(
"value"
,
value
),
log
::
Param
(
"source"
,
m_fileName
)};
(
*
log
)(
LOG_
INFO
,
"Configuration entry"
,
params
);
(
*
log
)(
log
::
INFO
,
"Configuration entry"
,
params
);
}
return
value
;
...
...
common/log/Constants.hpp
0 → 100644
View file @
1faed310
/******************************************************************************
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Interface to the CASTOR logging system
*
* @author Castor Dev team, castor-dev@cern.ch
*****************************************************************************/
#pragma once
#include
<string>
namespace
cta
{
namespace
log
{
/**
* The default path of the socket to which the logging system should write.
*/
const
std
::
string
SOCKET_NAME
=
"/var/run/ctalog.sock"
;
const
int
EMERG
=
0
;
// system is unusable
const
int
ALERT
=
1
;
// action must be taken immediately
const
int
CRIT
=
2
;
// critical conditions
const
int
ERR
=
3
;
// error conditions
const
int
WARNING
=
4
;
// warning conditions
const
int
NOTICE
=
5
;
// normal but signification condition
const
int
INFO
=
6
;
// informational
const
int
DEBUG
=
7
;
// debug-level messages
/**
* It is a convention of CTA to use syslog level of LOG_NOTICE to label
* user errors.
*/
const
int
USERERR
=
NOTICE
;
}
// namespace log
}
// namespace cta
common/log/DummyLogger.cpp
View file @
1faed310
/*
* The CERN Tape Archive (CTA) project
* Copyright (C) 2015 CERN
/*******************************************************************************
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Interface to the CASTOR logging system
*
* @author Castor Dev team, castor-dev@cern.ch
******************************************************************************/
#include
"common/log/DummyLogger.hpp"
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
cta
::
log
::
DummyLogger
::
DummyLogger
(
const
std
::
string
&
programName
)
:
Logger
(
programName
)
{
}
cta
::
log
::
DummyLogger
::
DummyLogger
(
const
std
::
string
&
programName
)
:
Logger
(
programName
)
{
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
cta
::
log
::
DummyLogger
::~
DummyLogger
()
{
}
cta
::
log
::
DummyLogger
::~
DummyLogger
()
throw
()
{
}
//------------------------------------------------------------------------------
// prepareForFork
//------------------------------------------------------------------------------
void
cta
::
log
::
DummyLogger
::
prepareForFork
()
{}
void
cta
::
log
::
DummyLogger
::
prepareForFork
()
{
}
//------------------------------------------------------------------------------
// operator()
...
...
@@ -40,4 +48,5 @@ void cta::log::DummyLogger::prepareForFork() {}
void
cta
::
log
::
DummyLogger
::
operator
()
(
const
int
priority
,
const
std
::
string
&
msg
,
const
std
::
list
<
Param
>
&
params
)
{}
const
std
::
list
<
Param
>
&
params
)
throw
()
{
}
common/log/DummyLogger.hpp
View file @
1faed310
/*
* The CERN Tape Archive (CTA) project
* Copyright (C) 2015 CERN
/******************************************************************************
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
* Interface to the CASTOR logging system
*
* @author Castor Dev team, castor-dev@cern.ch
*****************************************************************************/
#pragma once
#include
"common/log/Logger.hpp"
#include
<map>
#include
<pthread.h>
#include
<syslog.h>
#include
<sys/time.h>
namespace
cta
{
namespace
log
{
namespace
cta
{
namespace
log
{
/**
* A dummy logger class whose implementation of the API of the CASTOR logging
...
...
@@ -50,7 +52,7 @@ public:
/**
* Destructor.
*/
~
DummyLogger
();
~
DummyLogger
()
throw
()
;
/**
* Prepares the logger object for a call to fork().
...
...
@@ -70,10 +72,10 @@ public:
void
operator
()
(
const
int
priority
,
const
std
::
string
&
msg
,
const
std
::
list
<
Param
>
&
params
=
std
::
list
<
Param
>
());
const
std
::
list
<
Param
>
&
params
=
std
::
list
<
Param
>
())
throw
()
;
};
// class DummyLogger
}
// namespace log
}
// namespace ca
stor
}
// namespace c
t
a
common/log/LogContext.cpp
View file @
1faed310
...
...
@@ -29,10 +29,10 @@
#include
<algorithm>
#include
<bfd.h>
cta
::
log
::
LogContext
::
LogContext
(
cta
::
log
::
Logger
&
logger
)
:
cta
::
log
::
LogContext
::
LogContext
(
Logger
&
logger
)
throw
()
:
m_log
(
logger
)
{}
void
cta
::
log
::
LogContext
::
pushOrReplace
(
const
Param
&
param
)
{
void
cta
::
log
::
LogContext
::
pushOrReplace
(
const
Param
&
param
)
throw
()
{
ParamNameMatcher
match
(
param
.
getName
());
std
::
list
<
Param
>::
iterator
i
=
std
::
find_if
(
m_params
.
begin
(),
m_params
.
end
(),
match
);
...
...
@@ -43,17 +43,17 @@ void cta::log::LogContext::pushOrReplace(const Param& param) {
}
}
void
cta
::
log
::
LogContext
::
erase
(
const
std
::
string
&
paramName
)
{
void
cta
::
log
::
LogContext
::
erase
(
const
std
::
string
&
paramName
)
throw
()
{
ParamNameMatcher
match
(
paramName
);
m_params
.
erase
(
std
::
remove_if
(
m_params
.
begin
(),
m_params
.
end
(),
match
),
m_params
.
end
());
}
void
cta
::
log
::
LogContext
::
log
(
const
int
priority
,
const
std
::
string
&
msg
)
{
void
cta
::
log
::
LogContext
::
log
(
const
int
priority
,
const
std
::
string
&
msg
)
throw
()
{
m_log
(
priority
,
msg
,
m_params
);
}
void
cta
::
log
::
LogContext
::
logBacktrace
(
const
int
priority
,
const
std
::
string
&
backtrace
)
{
const
std
::
string
&
backtrace
)
throw
()
{
// Sanity check to prevent substr from throwing exceptions
if
(
!
backtrace
.
size
())
return
;
...
...
@@ -84,12 +84,12 @@ void cta::log::LogContext::logBacktrace(const int priority,
cta
::
log
::
LogContext
::
ScopedParam
::
ScopedParam
(
LogContext
&
context
,
const
Param
&
param
)
:
const
Param
&
param
)
throw
()
:
m_context
(
context
),
m_name
(
param
.
getName
())
{
m_context
.
pushOrReplace
(
param
);
}
cta
::
log
::
LogContext
::
ScopedParam
::~
ScopedParam
()
{
cta
::
log
::
LogContext
::
ScopedParam
::~
ScopedParam
()
throw
()
{
m_context
.
erase
(
m_name
);
}
...
...
common/log/LogContext.hpp
View file @
1faed310
/*
* The CERN Tape Archive (CTA) project
* Copyright (C) 2015 CERN
/******************************************************************************
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Interface to the CASTOR logging system
*
* @author Castor Dev team, castor-dev@cern.ch
*****************************************************************************/
#pragma once
#include
<ostream>
#include
"common/log/Logger.hpp"
namespace
cta
{
namespace
log
{
#include
<ostream>
namespace
cta
{
namespace
log
{
/**
* Container for a set of parameters to be used repetitively in logs. The
...
...
@@ -37,7 +44,8 @@ public:
* @param programName The name of the program to be prepended to every log
* message.
*/
LogContext
(
cta
::
log
::
Logger
&
logger
);
LogContext
(
cta
::
log
::
Logger
&
logger
)
throw
();
/**
* Destructor.
...
...
@@ -55,13 +63,13 @@ public:
* name. Does not throw exceptions (fails silently).
* @param param
*/
void
pushOrReplace
(
const
Param
&
param
);
void
pushOrReplace
(
const
Param
&
param
)
throw
()
;
/**
* Removes a parameter from the list.
* @param paramName value of param.getName();
*/
void
erase
(
const
std
::
string
&
paramName
);
void
erase
(
const
std
::
string
&
paramName
)
throw
()
;
/**
* Writes a message into the CASTOR logging system. Note that no exception
...
...
@@ -78,7 +86,7 @@ public:
*/
virtual
void
log
(
const
int
priority
,
const
std
::
string
&
msg
);
const
std
::
string
&
msg
)
throw
()
;
/**
* Logs a multiline backtrace as multiple entries in the logs, without
...
...
@@ -88,7 +96,7 @@ public:
*/
virtual
void
logBacktrace
(
const
int
priority
,
const
std
::
string
&
backtrace
);
const
std
::
string
&
backtrace
)
throw
()
;
/**
* Small introspection function to help in tests
...
...
@@ -113,8 +121,8 @@ public:
*/
class
ScopedParam
{
public:
ScopedParam
(
LogContext
&
context
,
const
Param
&
param
);
~
ScopedParam
();
ScopedParam
(
LogContext
&
context
,
const
Param
&
param
)
throw
()
;
~
ScopedParam
()
throw
()
;
private:
LogContext
&
m_context
;
std
::
string
m_name
;
...
...
@@ -147,4 +155,4 @@ class ScopedParamContainer{
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
LogContext
&
lc
);
}
// namespace log
}
// namespace ca
stor
}
// namespace c
t
a
common/log/LogContextTest.cpp
View file @
1faed310
/*
* The CERN Tape Archive (CTA) project
* Copyright (C) 2015 CERN
/******************************************************************************
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Interface to the CASTOR logging system
*
* @author Castor Dev team, castor-dev@cern.ch
*****************************************************************************/
#include
"common/log/DummyLogger.hpp"
#include
"common/log/StringLogger.hpp"
#include
"common/log/LogContext.hpp"
#include
"common/log/StringLogger.hpp"
#include
<gtest/gtest.h>
...
...
@@ -26,7 +31,7 @@ using namespace cta::log;
namespace
unitTests
{
TEST
(
cta_log_LogContextTest
,
additionScopedRemove
)
{
DummyLogger
dl
(
"ca
stor
_log_LogContextTest"
);
DummyLogger
dl
(
"c
t
a_log_LogContextTest"
);
LogContext
lc
(
dl
);
lc
.
pushOrReplace
(
Param
(
"MigrationRequestId"
,
123
));
ASSERT_EQ
(
1U
,
lc
.
size
());
...
...
@@ -34,7 +39,7 @@ namespace unitTests {
// Create an anonymous variable (for its scope)
LogContext
::
ScopedParam
sp
(
lc
,
Param
(
"NSFILEID"
,
12345
));
ASSERT_EQ
(
2U
,
lc
.
size
());
lc
.
log
(
LOG_
DEBUG
,
"Two params message"
);
lc
.
log
(
DEBUG
,
"Two params message"
);
{
// Test that we do not allow duplicate params
LogContext
::
ScopedParam
sp
(
lc
,
Param
(
"NSFILEID"
,
123456
));
...
...
@@ -44,27 +49,27 @@ namespace unitTests {
}
}
ASSERT_EQ
(
1U
,
lc
.
size
());
lc
.
log
(
LOG_
DEBUG
,
"One param message"
);
lc
.
log
(
DEBUG
,
"One param message"
);
lc
.
erase
(
"MigrationRequestId"
);
ASSERT_EQ
(
0U
,
lc
.
size
());
}
TEST
(
cta_log_LogContextTest
,
paramsFound
)
{
StringLogger
sl
(
"ca
stor
_log_LogContextTest"
);
StringLogger
sl
(
"c
t
a_log_LogContextTest"
,
DEBUG
);
LogContext
lc
(
sl
);
lc
.
pushOrReplace
(
Param
(
"MigrationRequestId"
,
123
));
lc
.
log
(
LOG_
INFO
,
"First log"
);
lc
.
log
(
INFO
,
"First log"
);
std
::
string
first
=
sl
.
getLog
();
ASSERT_NE
(
std
::
string
::
npos
,
first
.
find
(
"MigrationRequestId"
));
{
LogContext
::
ScopedParam
sp
(
lc
,
Param
(
"NSFILEID"
,
12345
));
lc
.
log
(
LOG_
INFO
,
"Second log"
);
lc
.
log
(
INFO
,
"Second log"
);
}
std
::
string
second
=
sl
.
getLog
();
ASSERT_NE
(
std
::
string
::
npos
,
second
.
find
(
"NSFILEID"
));
// We expect the NSFILEID parameter to show up only once (i.e, not after
// offset, which marks the end of its first occurrence).
lc
.
log
(
LOG_
INFO
,
"Third log"
);
lc
.
log
(
INFO
,
"Third log"
);
std
::
string
third
=
sl
.
getLog
();
size_t
offset
=
third
.
find
(
"NSFILEID"
)
+
strlen
(
"NSFILEID"
);
ASSERT_EQ
(
std
::
string
::
npos
,
third
.
find
(
"NSFILEID"
,
offset
));
...
...
common/log/Logger.hpp
View file @
1faed310
/*
* The CERN Tape Archive (CTA) project
* Copyright (C) 2015 CERN
/******************************************************************************
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
* Interface to the CASTOR logging system
*
* @author Castor Dev team, castor-dev@cern.ch
*****************************************************************************/
#pragma once
// I
nclude
Files
#i
nclude
"common/log/Constants.hpp"
#include
"common/log/Param.hpp"
#include
"common/exception/Exception.hpp"
#include
<list>
#include
<map>
#include
<pthread.h>
#include
<syslog.h>
#include
<sys/time.h>
/**
* It is a convention of C
T
A to use syslog level of LOG_NOTICE to label
* It is a convention of CA
STOR
to use syslog level of LOG_NOTICE to label
* user errors. This macro helps enforce that convention and document it in
* the code.
*/
#define LOG_USERERR LOG_NOTICE
namespace
cta
{
namespace
log
{
namespace
cta
{
namespace
log
{
/**
* Abstract class representing the API of the CASTOR logging system.
...
...
@@ -82,7 +84,6 @@ namespace cta { namespace log {
class
Logger
{
public:
CTA_GENERATE_EXCEPTION_CLASS
(
InvalidArgument
);
/**
* Constructor
*
...
...
@@ -120,7 +121,7 @@ public:
*
* @param priority the priority of the message as defined by the syslog API.
* @param msg the message.
* @param params
the
parameters of the message.
* @param params
optional
parameters of the message.
*/
virtual
void
operator
()
(
const
int
priority
,
...
...
@@ -137,5 +138,5 @@ protected:
};
// class Logger
}
// namespace log
}
// namespace ca
stor
}
// namespace c
t
a
common/log/Message.hpp
View file @
1faed310
...
...
@@ -27,7 +27,7 @@
// Include Files
#include
<string>
namespace
ca
stor
{
namespace
c
t
a
{
namespace
log
{
...
...
@@ -43,5 +43,5 @@ namespace castor {
}
// end of namespace log
}
// end of namespace ca
stor
}
// end of namespace c
t
a
common/log/Param.cpp
View file @
1faed310
...
...
@@ -22,6 +22,7 @@
*****************************************************************************/
#include
"common/log/Param.hpp"
#include
<cstdio>
//------------------------------------------------------------------------------
...
...
common/log/Param.hpp
View file @
1faed310
/*
* The CERN Tape Archive (CTA) project
* Copyright (C) 2015 CERN
/******************************************************************************
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of