mirror of
https://github.com/WinampDesktop/winamp.git
synced 2024-09-24 15:54:12 +00:00
710 lines
32 KiB
C++
710 lines
32 KiB
C++
#pragma once
|
|
#ifndef config_H_
|
|
#define config_H_
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <map>
|
|
#include <list>
|
|
#include <set>
|
|
#include <stdlib.h>
|
|
#include "unicode/uniFile.h"
|
|
#include "stl/stringUtils.h"
|
|
#include "threading/thread.h"
|
|
#include "metrics.h"
|
|
|
|
#define DEFAULT_SOURCE_STREAM 1
|
|
#define DEFAULT_CLIENT_STREAM_ID 1
|
|
#define DEFAULT_YP_ADDRESS "yp.shoutcast.com"
|
|
|
|
#ifdef _WIN32
|
|
#define DEFAULT_LOG "%temp%\\sc_serv.log"
|
|
#define DEFAULT_LOGW L"%temp%\\sc_serv.log"
|
|
#else
|
|
#define DEFAULT_LOG "/tmp/sc_serv.log"
|
|
#endif
|
|
#define DEFAULT_FLASH_POLICY_FILE "crossdomain.xml"
|
|
|
|
/*
|
|
|
|
Each option has a map associated with a member. Let's take an option called foobar
|
|
|
|
std::map<size_t,int> m_foobar;
|
|
|
|
For single options (non-multi options) the map only has a single element. We use a map
|
|
so we can treat all options, multi or not, in the same fashion
|
|
|
|
The value of the option is assigned via the assign_<name> method. subIndex is only used
|
|
for multi options (zero based). The value is always passed as a string and is converted
|
|
automatically internally
|
|
|
|
inline void assign_foobar(int subIndex,const uniString::utf8 &value)
|
|
|
|
The value of the option is retrieved as a string via the fetch_<name> method. The value
|
|
is fetched as a native type via native_fetch_<name> method. subIndex is used to select a
|
|
particular entry in a multi option. It's ignored for regular options
|
|
|
|
uniString::utf8 fetch_foobar(int subIndex)
|
|
int native_fetch_foobar(int subIndex)
|
|
|
|
A shorthand is provided via the _<name> method. It returns the same value as native_fetch_<name>
|
|
|
|
const int _foobar()
|
|
|
|
The number of elements for the option is returned by the count_<name> method. For single options
|
|
this is always one
|
|
|
|
size_t count_foobar()
|
|
|
|
The multi_<name> method returns true if the option is a multi option
|
|
|
|
bool multi_foobar()
|
|
|
|
The def_<name> method returns the default value for the option as a string
|
|
|
|
utf8 def_foobar()
|
|
|
|
All the proceeding options are private, and not protected by a mutex.
|
|
There are two public methods for accessing methods that provide mutex
|
|
protection. The value of the options is <name>() and the default value
|
|
is provided by <name>_Default()
|
|
|
|
const int foobar()
|
|
const int foobar_Default()
|
|
|
|
All of this is created automatically via the OPT and OPT_MULTI macros below
|
|
|
|
|
|
In the optMap table we associated all these functions with the actual name of the option
|
|
as it appears in the config file. In addition there is a change function associated with
|
|
each option that is fired when the option is changed.
|
|
*/
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
///////// crazy macros to provide uniform assign/fetch functions for each option
|
|
|
|
/*
|
|
Create a single option of type "tipe" with the name "name" and a default value of "def"
|
|
*/
|
|
#define OPT(tipe,name,def)\
|
|
private:\
|
|
std::map<size_t,tipe> m_##name;\
|
|
inline void assign_##name(const uniString::utf8 &value, const size_t subIndex = DEFAULT_CLIENT_STREAM_ID) throw() { assignMulti(m_##name, subIndex, value); }\
|
|
uniString::utf8 fetch_##name(const size_t subIndex = DEFAULT_CLIENT_STREAM_ID, size_t *fetchByPos = 0) const throw() { return revert(fetchMulti(m_##name, subIndex, def, fetchByPos)); }\
|
|
tipe native_fetch_##name(const size_t subIndex = DEFAULT_CLIENT_STREAM_ID, size_t *fetchByPos = 0) const throw() { return fetchMulti(m_##name, subIndex, def, fetchByPos); }\
|
|
const tipe _##name() const throw() { return fetchMulti(m_##name, DEFAULT_CLIENT_STREAM_ID, def, 0); }\
|
|
size_t count_##name() const throw() { return 1; }\
|
|
bool multi_##name() const throw() { return false; }\
|
|
uniString::utf8 def_##name() const throw() { return revert(def); }\
|
|
public:\
|
|
const tipe name() const throw() { return fetchMulti(m_##name, DEFAULT_CLIENT_STREAM_ID, def, 0); }\
|
|
const tipe name##_Default() const throw() { return def; }
|
|
|
|
// for options that can have multiple instances (like encoders and broadcast points)
|
|
/*
|
|
The option has the type "tipe" with the name "name" and a default value of "def"
|
|
*/
|
|
#define OPT_MULTI(tipe,name,def)\
|
|
private:\
|
|
std::map<size_t, tipe> m_##name;\
|
|
inline void assign_##name(const uniString::utf8 &value, const size_t subIndex) throw() { assignMulti(m_##name, subIndex, value); }\
|
|
inline void native_assign_##name(const size_t subIndex, const tipe &value) throw() { native_assignMulti(m_##name, subIndex, value); }\
|
|
uniString::utf8 fetch_##name(const size_t subIndex, size_t *fetchByPos = 0) const throw() { return revert(fetchMulti(m_##name, subIndex, def, fetchByPos)); }\
|
|
tipe native_fetch_##name(const size_t subIndex) const throw() { return fetchMulti(m_##name, subIndex, def, 0); }\
|
|
const tipe _##name(const std::vector<tipe>::size_type i) const throw() { return fetchMulti(m_##name, i, def, 0); }\
|
|
bool multi_##name() const throw() { return true; }\
|
|
uniString::utf8 def_##name() const throw() { return revert(def); }\
|
|
public:\
|
|
const bool read_##name(const size_t subIndex) const throw() { return (m_##name.find(subIndex) != m_##name.end()); }\
|
|
void unread_##name(const size_t subIndex) { native_assignMulti(m_##name, subIndex, name##_Default()); }\
|
|
const tipe name(const size_t subIndex) const throw() { return fetchMulti(m_##name, subIndex, def, 0); }\
|
|
size_t count_##name() const throw() { return m_##name.size(); }\
|
|
const std::map<size_t, tipe>& name##_map() const { return m_##name; } \
|
|
const tipe name##_Default() const throw() { return def; }
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// global configuration
|
|
class config
|
|
{
|
|
public:
|
|
// stream specifications from config file.
|
|
#pragma pack(push, 1)
|
|
struct streamConfig
|
|
{
|
|
#pragma pack(push, 1)
|
|
class urlObj
|
|
{
|
|
private:
|
|
uniString::utf8 m_url;
|
|
uniString::utf8 m_server;
|
|
uniString::utf8 m_path;
|
|
u_short m_port;
|
|
|
|
static uniString::utf8 parse(const uniString::utf8 &url, uniString::utf8 &server,
|
|
u_short &port, uniString::utf8 &path) throw(std::exception);
|
|
|
|
public:
|
|
explicit urlObj(const uniString::utf8 &url) throw(std::exception)
|
|
{
|
|
if (!url.empty())
|
|
{
|
|
set(url);
|
|
}
|
|
else
|
|
{
|
|
clear();
|
|
}
|
|
}
|
|
urlObj& operator=(const uniString::utf8 &url) throw(std::exception)
|
|
{
|
|
set(url);
|
|
return *this;
|
|
}
|
|
const uniString::utf8 &url() const throw() { return m_url; }
|
|
const uniString::utf8 &server() const throw() { return m_server; }
|
|
const uniString::utf8 &path() const throw() { return m_path; }
|
|
const u_short port() const throw() { return m_port; }
|
|
bool isSet() const throw() { return !m_url.empty(); }
|
|
void set(const uniString::utf8 &url) throw(std::exception)
|
|
{
|
|
m_url = parse(url, m_server, m_port, m_path);
|
|
}
|
|
void clear() throw()
|
|
{
|
|
m_url.clear();
|
|
m_port = 0;
|
|
}
|
|
};
|
|
#pragma pack(pop)
|
|
|
|
uniString::utf8 m_authHash;
|
|
uniString::utf8 m_urlPath; // url that clients use to connect
|
|
uniString::utf8 m_adminPassword; // per stream admin password
|
|
uniString::utf8 m_password; // per stream source password
|
|
uniString::utf8 m_publicServer; // per stream source public flag
|
|
size_t m_streamID;
|
|
int m_maxStreamUser; // per stream user limit
|
|
int m_maxStreamBitrate; // per stream max bitrate limit
|
|
int m_minStreamBitrate; // per stream min bitrate limit
|
|
urlObj m_relayUrl; // if this is a relay, then this is set to the source url
|
|
urlObj m_backupUrl; // if there is a backup, then this is set to the backup url
|
|
bool m_allowRelay; // per stream relay allowed flag
|
|
bool m_allowPublicRelay; // per stream relay public flag
|
|
|
|
streamConfig() throw() : m_streamID(DEFAULT_CLIENT_STREAM_ID), m_maxStreamUser(0),
|
|
m_maxStreamBitrate(0), m_minStreamBitrate(0),
|
|
m_relayUrl((uniString::utf8)""), m_backupUrl((uniString::utf8)""),
|
|
m_allowRelay(true), m_allowPublicRelay(true) {}
|
|
|
|
streamConfig(const size_t id, const uniString::utf8 &authHash, const uniString::utf8 &url,
|
|
const uniString::utf8 &relayUrl, const uniString::utf8 &backupUrl,
|
|
const int maxStreamUser, const int maxStreamBitrate, const int minStreamBitrate,
|
|
const uniString::utf8 &adminPassword, const uniString::utf8 &password,
|
|
const uniString::utf8 &publicServer, const bool allowRelay,
|
|
const bool allowPublicRelay) throw(std::exception)
|
|
: m_authHash(authHash), m_urlPath(url), m_adminPassword(adminPassword), m_password(password),
|
|
m_publicServer(publicServer), m_streamID(id), m_maxStreamUser(maxStreamUser),
|
|
m_maxStreamBitrate(maxStreamBitrate), m_minStreamBitrate(minStreamBitrate), m_relayUrl(relayUrl),
|
|
m_backupUrl(backupUrl), m_allowRelay(allowRelay), m_allowPublicRelay(allowPublicRelay) {}
|
|
};
|
|
#pragma pack(pop)
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
///// functions to convert types to and from unicode strings
|
|
template<typename T> inline static void convert(const uniString::utf8 &v,T &r) throw() { r = v; }
|
|
#ifdef _WIN64
|
|
inline static void convert(const uniString::utf8 &v,size_t &r) throw() { r = atoi((const char *)v.c_str()); }
|
|
#endif
|
|
inline static void convert(const uniString::utf8 &v, int &r) throw() { r = atoi((const char *)v.c_str()); }
|
|
inline static void convert(const uniString::utf8 &v, unsigned int &r) throw() { r = atoi((const char *)v.c_str()); }
|
|
inline static void convert(const uniString::utf8 &v, unsigned long &r) throw() { r = atol((const char *)v.c_str()); }
|
|
inline static void convert(const uniString::utf8 &v, unsigned short &r) throw() { r = (unsigned short)atoi((const char *)v.c_str()); }
|
|
inline static void convert(const uniString::utf8 &v, short &r) throw() { r = (short)atoi((const char *)v.c_str()); }
|
|
inline static void convert(const uniString::utf8 &v, bool &r) throw() { r = (atoi((const char *)v.c_str()) ? true : false); }
|
|
inline static void convert(const uniString::utf8 &v, double &r) throw() { r = atof((const char *)v.c_str()); }
|
|
|
|
template<typename T> inline static uniString::utf8 revert(const T &r) throw() { return r; }
|
|
#ifdef _WIN64
|
|
inline static uniString::utf8 revert(size_t r) throw() { return stringUtil::tos(r); }
|
|
#endif
|
|
inline static uniString::utf8 revert(int r) throw() { return stringUtil::tos(r); }
|
|
inline static uniString::utf8 revert(unsigned int r) throw() { return stringUtil::tos(r); }
|
|
inline static uniString::utf8 revert(unsigned long r) throw() { return stringUtil::tos(r); }
|
|
inline static uniString::utf8 revert(unsigned short r) throw() { return stringUtil::tos(r); }
|
|
inline static uniString::utf8 revert(short r) throw() { return stringUtil::tos(r); }
|
|
inline static uniString::utf8 revert(bool r) throw() { return (r ? "1" : "0"); }
|
|
inline static uniString::utf8 revert(double r) throw() { return stringUtil::tos(r); }
|
|
////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
private:
|
|
mutable AOL_namespace::mutex m_lock; // api may write to config, so we need a lock
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////
|
|
//// tables and functions so we can read and write options in a generic manner based
|
|
/// on the names that are used in the config file
|
|
typedef void (config::*assignFunc_t)(const uniString::utf8 &, const size_t subIndex);
|
|
typedef uniString::utf8 (config::*fetchFunc_t)(const size_t subIndex, size_t *fetchByPos) const;
|
|
typedef size_t (config::*countFunc_t)() const;
|
|
typedef bool (config::*multiFunc_t)() const;
|
|
typedef uniString::utf8 (config::*defaultFunc_t)() const;
|
|
|
|
struct accessor_t
|
|
{
|
|
assignFunc_t m_assignFunc;
|
|
fetchFunc_t m_fetchFunc;
|
|
countFunc_t m_countFunc;
|
|
multiFunc_t m_multiFunc;
|
|
defaultFunc_t m_defaultFunc;
|
|
|
|
accessor_t(assignFunc_t af, fetchFunc_t ff, countFunc_t cf, multiFunc_t mf, defaultFunc_t df) throw()
|
|
: m_assignFunc(af), m_fetchFunc(ff), m_countFunc(cf), m_multiFunc(mf), m_defaultFunc(df) {}
|
|
|
|
accessor_t() throw() : m_assignFunc(0), m_fetchFunc(0), m_countFunc(0), m_multiFunc(0), m_defaultFunc(0) {}
|
|
};
|
|
public:
|
|
typedef std::map<uniString::utf8,accessor_t> optMap_t;
|
|
//////////////////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// takes an option map (container) and returns the value at the index (i) if it exists,
|
|
// otherwise it returns the default value (defaultValue). Value returned as native type
|
|
template<typename T,typename D>
|
|
static T fetchMulti(const std::map<size_t,T> &container, const typename std::vector<T>::size_type &subIndex,
|
|
const D defaultValue, size_t *fetchByPos) throw()
|
|
{
|
|
if (!fetchByPos)
|
|
{
|
|
typename std::map<size_t,T>::const_iterator i = container.find(subIndex);
|
|
if (i != container.end())
|
|
{
|
|
return (*i).second;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// there's cases where we need to get the value
|
|
// effectively by it's position in the map so
|
|
// for the moment we'll just look through (bad
|
|
// for speed but it's not a commonly used mode).
|
|
typename std::vector<T>::size_type pos = 0;
|
|
for (typename std::map<size_t,T>::const_iterator i = container.begin(); i != container.end(); ++i, pos++)
|
|
{
|
|
if (pos == subIndex)
|
|
{
|
|
*fetchByPos = (*i).first;
|
|
return (*i).second;
|
|
}
|
|
}
|
|
}
|
|
return defaultValue;
|
|
}
|
|
private:
|
|
// assign map index. Expand with default value as needed. Value is specified as a string and converted as needed
|
|
template<typename T>
|
|
static void assignMulti(std::map<size_t,T> &container, const typename std::vector<T>::size_type subIndex, const uniString::utf8 &value) throw()
|
|
{
|
|
T vtmp;
|
|
convert(value, vtmp);
|
|
container[subIndex] = vtmp;
|
|
}
|
|
|
|
// same as assignMulti, but you can provide the native type instead of a string
|
|
template<typename T>
|
|
static void native_assignMulti(std::map<size_t,T> &container, const typename std::vector<T>::size_type subIndex, const T &value) throw()
|
|
{
|
|
container[subIndex] = value;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// radionomy metrics
|
|
OPT(bool,adMetricsDebug,false)
|
|
OPT(size_t,metricsMaxQueue,80000)
|
|
|
|
OPT(bool,authDebug,false)
|
|
|
|
public:
|
|
friend void metrics::metrics_apply(config &conf);
|
|
|
|
private:
|
|
optMap_t m_optMap;
|
|
|
|
// we can't log during startup because the loggers don't exist
|
|
std::vector<uniString::utf8> m_deferredWarnLogMessages; // log warning messages from startup
|
|
std::vector<uniString::utf8> m_deferredErrorLogMessages; // log error messages from startup
|
|
|
|
// deferred options are those that weren't set because they can't take effect immediately
|
|
// they are used when writing out the new config file.
|
|
std::map<uniString::utf8,uniString::utf8> m_deferredOptions;
|
|
|
|
OPT(size_t,configRewrite,0)
|
|
OPT(uniFile::filenameType,confFile,"")
|
|
|
|
OPT(uniFile::filenameType,logFile,DEFAULT_LOG) // file for logging
|
|
OPT(uniFile::filenameType,realLogFile,DEFAULT_LOG) // file for logging
|
|
|
|
OPT(bool,screenLog,true) // log to screen
|
|
OPT(bool,log,true) // do I log?
|
|
OPT(int,logRotates,5) // hwo many backups to keep when doing a log rotate?
|
|
OPT(bool,logArchive,false) // backup rotated files which would otherwise be deleted
|
|
OPT(int,rotateInterval,86400) // interval between log file rotations (24 hours)
|
|
// if set to 0 then we won't rotate any of the files
|
|
|
|
OPT(int,portBase,8000) // listen port
|
|
OPT(int,publicPort,-1) // listen port for firehose - workaround for firehose hosts running on port 8000
|
|
// but need to effectively be seen as bound to port 80 - allowing all to work ok
|
|
OPT(int,portLegacy,-1) // legacy port override/disable
|
|
OPT(uniString::utf8,alternatePorts,(uniString::utf8)"") // alternate port(s) for client only connections - comma separated string
|
|
OPT(bool,nameLookups,false) // do internet reverse lookups
|
|
|
|
OPT(uniString::utf8,sslCertificateFile,"");
|
|
OPT(uniString::utf8,sslCertificateKeyFile,"");
|
|
|
|
OPT(int,autoDumpTime,30) // how long before an idle connection is dumped (in seconds). Zero means no timeout
|
|
OPT(int,maxHeaderLineSize,4096) // maximum size of an HTTP header line. Default is pretty arbitrary right now
|
|
// but should be at least as big as a u-vox packet, since we have to anaylize
|
|
// initial data bytes to determine protocol and type of connectee (source or client)
|
|
OPT(int,maxHeaderLineCount,100) // max headers lines in HTTP style exchange
|
|
OPT(uniString::utf8,password,(uniString::utf8)""); // password for broadcaster to connect
|
|
OPT(uniString::utf8,adminPassword,(uniString::utf8)""); // administrator password
|
|
|
|
// buffer configuration options
|
|
OPT(int,bufferType,1) // 0 - fixed, 1 - adaptive
|
|
OPT(size_t,fixedBufferSize,524288) // size of buffer if fixed (gives ~32 seconds ~ 128kbps, 44.1kHz)
|
|
OPT(double,adaptiveBufferSize,16) // size of adaptive buffer in seconds
|
|
OPT(size_t,bufferHardLimit,16777216) // no more than this give or take a factor of two
|
|
|
|
OPT(unsigned short,metaInterval,16384) // metadata interval for shoutcast 1
|
|
OPT_MULTI(unsigned short,stream_metaInterval,16384) // per-stream override
|
|
|
|
// special intro and backup files
|
|
OPT(uniFile::filenameType,introFile,"")
|
|
OPT(uniFile::filenameType,backupFile,"")
|
|
OPT(uniFile::filenameType,backupTitle,"")
|
|
OPT(int,backupLoop,0)
|
|
OPT(int,maxSpecialFileSize,30000000)
|
|
|
|
OPT(int,adTestFileLoop,1)
|
|
OPT(uniFile::filenameType,adTestFile,"")
|
|
OPT(uniFile::filenameType,adTestFile2,"")
|
|
OPT(uniFile::filenameType,adTestFile3,"")
|
|
OPT(uniFile::filenameType,adTestFile4,"")
|
|
|
|
OPT(uniFile::filenameType,artworkFile,"")
|
|
std::map<size_t, uniString::utf8> m_artworkBody;
|
|
|
|
OPT(uniString::utf8,uvoxCipherKey,uniString::utf8("foobar"))
|
|
|
|
// w3c logs
|
|
OPT(bool,w3cEnable,true)
|
|
OPT(uniString::utf8,w3cLog,uniString::utf8("sc_w3c.log"))
|
|
|
|
OPT(uniString::utf8,pidFile,uniString::utf8("sc_serv_$.pid"))
|
|
|
|
// relaying
|
|
OPT(bool,allowRelay,true) // can other servers relay us. Based on Shoutcast user agent, not reliable
|
|
OPT(bool,allowPublicRelay,true) // relays can list themselves in yp
|
|
|
|
OPT(short,maxHTTPRedirects,5) // max times we can redirect (http 3xx)
|
|
OPT(int,relayReconnectTime,5) // seconds to reconnect on relay failure
|
|
OPT(int,relayConnectRetries,0) // number of times we retry a relay request before throwing it away
|
|
// which if set as zero will keep retrying (excluding bitrate blocks)
|
|
|
|
////// stream configs
|
|
OPT_MULTI(size_t,stream_ID,DEFAULT_CLIENT_STREAM_ID)
|
|
OPT_MULTI(uniString::utf8,stream_authHash,(uniString::utf8)"")
|
|
OPT_MULTI(uniString::utf8,stream_path,(uniString::utf8)"")
|
|
OPT_MULTI(uniString::utf8,stream_relayURL,(uniString::utf8)"")
|
|
OPT_MULTI(uniString::utf8,stream_backupURL,(uniString::utf8)"")
|
|
|
|
OPT_MULTI(uniString::utf8,stream_password,(uniString::utf8)"")
|
|
OPT_MULTI(uniString::utf8,stream_adminPassword,(uniString::utf8)"")
|
|
|
|
OPT_MULTI(uniString::utf8,stream_publicServer,(uniString::utf8)"") // if "always" or "never" overrides public flag from source
|
|
OPT_MULTI(bool,stream_allowRelay,true) // can other servers relay us. Based on Shoutcast user agent, not reliable
|
|
OPT_MULTI(bool,stream_allowPublicRelay,true) // relays can list themselves in yp
|
|
|
|
OPT_MULTI(int,stream_maxUser,0) // if set to a value greater than zero then we have per stream limits
|
|
OPT_MULTI(int,stream_maxBitrate,0) // if set to a value greater than zero then we have per stream limits
|
|
OPT_MULTI(int,stream_minBitrate,0) // if set to a value greater than zero then we have per stream limits
|
|
OPT_MULTI(bool,stream_ripOnly,false) // only addrs in rip file may connect
|
|
OPT_MULTI(int,stream_autoDumpTime,30) // how long before an idle connection is dumped (in seconds). Zero means no timeout
|
|
OPT_MULTI(int,stream_autoDumpSourceTime,7) // how long before an idle source connection is dumped (in seconds). Zero means no timeout
|
|
OPT_MULTI(bool,stream_autoDumpUsers,false) // if true, then users are dumped if source disconnects
|
|
OPT_MULTI(size_t,stream_listenerTime,0) // max time in minutes you can listen. 0 means no limit
|
|
|
|
OPT_MULTI(int,stream_songHistory,10) // max song history to preserve
|
|
OPT_MULTI(uniString::utf8,stream_uvoxCipherKey,(uniString::utf8)"")
|
|
|
|
OPT_MULTI(uniFile::filenameType,stream_logFile,""); // file for per mount logging
|
|
|
|
OPT_MULTI(int,stream_adTestFileLoop,1)
|
|
OPT_MULTI(uniFile::filenameType,stream_adTestFile,"")
|
|
OPT_MULTI(uniFile::filenameType,stream_adTestFile2,"")
|
|
OPT_MULTI(uniFile::filenameType,stream_adTestFile3,"")
|
|
OPT_MULTI(uniFile::filenameType,stream_adTestFile4,"")
|
|
OPT_MULTI(uniFile::filenameType,stream_introFile,"")
|
|
OPT_MULTI(uniFile::filenameType,stream_backupFile,"")
|
|
OPT_MULTI(uniFile::filenameType,stream_backupTitle,"")
|
|
OPT_MULTI(int,stream_backupLoop,0)
|
|
|
|
OPT_MULTI(int,stream_rateLimitWait,0)
|
|
|
|
OPT_MULTI(uniFile::filenameType,stream_artworkFile,"")
|
|
|
|
OPT_MULTI(uniFile::filenameType,stream_banFile,"")
|
|
OPT_MULTI(uniFile::filenameType,stream_ripFile,"")
|
|
OPT_MULTI(uniFile::filenameType,stream_agentFile,"")
|
|
OPT_MULTI(uniString::utf8,stream_w3cLog,(uniString::utf8)"")
|
|
|
|
OPT_MULTI(uniString::utf8,stream_hideStats,(uniString::utf8)"") // hide /stats & /statistics as well as /index and /played public facing pages
|
|
OPT_MULTI(uniString::utf8,stream_redirectUrl,(uniString::utf8)"") // used with hideStats=all or if the stream version isn't specified
|
|
OPT_MULTI(uniString::utf8,stream_movedUrl,(uniString::utf8)"") // used to redirect a deemed dead stream (just in case)
|
|
|
|
OPT(bool,requireStreamConfigs,false) // if true, then sources can only connect if stream configs have been defined
|
|
OPT(uniString::utf8,userId,"")
|
|
OPT(uniString::utf8,licenceId,"")
|
|
|
|
// flash policy
|
|
OPT(int,flashPolicyServerPort,-1) // listen on port 843 for flash policy server request
|
|
OPT(uniFile::filenameType,flashPolicyFile,DEFAULT_FLASH_POLICY_FILE)
|
|
uniString::utf8 m_crossdomainStr; // used to hold a cached copy of the crossdomain.xml file
|
|
uniString::utf8 m_crossdomainStrGZ; // used to hold a cached copy of the gzipped crossdomain.xml file
|
|
uniString::utf8 m_shoutcastSWFStr; // used to hold a cached copy of the shoutcast.swf file
|
|
uniString::utf8 m_shoutcastSWFStrGZ; // used to hold a cached copy of the gzipped shoutcast.swf file
|
|
uniString::utf8 m_usedAlternatePorts; // used to hold a copy of the valid alternate ports in use
|
|
|
|
////// yp
|
|
OPT(int,ypTimeout,30) // yp timeout interval for requests
|
|
OPT(uniString::utf8,ypAddr,DEFAULT_YP_ADDRESS)
|
|
OPT(int,ypPort,80)
|
|
OPT(uniString::utf8,ypPath,"/yp2")
|
|
OPT(int,ypMaxRetries,10) // number of times we retry a yp request before throwing it away
|
|
OPT(int,ypReportInterval,5 * 60) // never touch any slower than this
|
|
OPT(int,ypMinReportInterval,10) // never touch any faster than this
|
|
OPT(uniString::utf8,publicServer,"default") // if "always" or "never" overrides public flag from source
|
|
|
|
//// cdn behaviour
|
|
OPT(uniString::utf8,cdn,"") // if 'on' or 'always' then we enable all of the cdn modes (including YP pings for private streams)
|
|
// but use it to determine opt-in (via 'on') or opt-out (via 'always')
|
|
OPT_MULTI(int,cdn_master,-1) // this and the option below is used to control the behaviour of things
|
|
OPT_MULTI(int,cdn_slave,-1)
|
|
|
|
//// stats
|
|
OPT(int,maxUser,512) // max clients
|
|
OPT(int,minBitrate,0) // min bitrate of source connections - if zero / not set then there is no limit
|
|
OPT(int,maxBitrate,0) // max bitrate of source connections - if zero / not set then there is no limit
|
|
OPT(uniString::utf8,hideStats,"") // hide /stats & /statistics as well as /index and /played public facing pages
|
|
OPT(uniString::utf8,redirectUrl,"") // used with hideStats=all or if the stream version isn't specified
|
|
|
|
/// client behaviour
|
|
OPT(size_t,listenerTime,0) // max time in minutes you can listen. 0 means no limit
|
|
OPT(bool,autoDumpUsers,false) // if true, then users are dumped if source disconnects
|
|
OPT(uniString::utf8,srcIP,"") // bind addr for sources
|
|
OPT(uniString::utf8,destIP,"") // bind addr for clients
|
|
OPT(uniString::utf8,publicIP,"") // public address to use for the YP listing if the bind addr is not appropriate
|
|
OPT(uniString::utf8,titleFormat,"") // modifies icy-name
|
|
OPT(uniString::utf8,urlFormat,"") // modifies icy-url
|
|
|
|
//// banning
|
|
OPT(uniFile::filenameType,banFile,"sc_serv.ban")
|
|
OPT(bool,saveBanListOnExit,true) // save on exiting
|
|
|
|
//// rip
|
|
OPT(uniFile::filenameType,ripFile,"sc_serv.rip")
|
|
OPT(bool,saveRipListOnExit,true) // save on exiting
|
|
OPT(bool,ripOnly,false) // only addrs in rip file may connect
|
|
OPT(uniFile::filenameType,adminFile,"sc_serv.admin")
|
|
|
|
/// agent
|
|
OPT(uniFile::filenameType,agentFile,"sc_serv.agent")
|
|
OPT(bool,saveAgentListOnExit,true) // save on exiting
|
|
OPT(bool,blockEmptyUserAgent,false) // if true, block the client connection if there is no user agent specified
|
|
|
|
//// debugging
|
|
OPT(bool,webClientDebug,false)
|
|
OPT(bool,yp2Debug,false)
|
|
OPT(bool,shoutcastSourceDebug,false)
|
|
OPT(bool,uvox2SourceDebug,false)
|
|
OPT(bool,HTTPSourceDebug,false)
|
|
OPT(bool,streamDataDebug,false)
|
|
OPT(bool,microServerDebug,false)
|
|
OPT(bool,httpStyleDebug,false)
|
|
OPT(bool,shoutcast1ClientDebug,false)
|
|
OPT(bool,shoutcast2ClientDebug,false)
|
|
OPT(bool,HTTPClientDebug,false)
|
|
OPT(bool,flvClientDebug,false)
|
|
OPT(bool,m4aClientDebug,false)
|
|
|
|
OPT(bool,relayDebug,false)
|
|
OPT(bool,relayShoutcastDebug,false)
|
|
OPT(bool,relayUvoxDebug,false)
|
|
OPT(bool,statsDebug,false)
|
|
OPT(bool,threadRunnerDebug,false)
|
|
|
|
OPT(bool,logClients,true)
|
|
|
|
OPT(int,songHistory,20) // max song history to preserve
|
|
|
|
/// misc nonsense
|
|
OPT(uniString::utf8,unique,"$") // subsitution string for file names to mimic old sc_serv conf file behaviour
|
|
OPT(uniString::utf8,include,"") // include file placeholder
|
|
OPT(int,cpuCount,0) // cpu usage. zero is default
|
|
OPT(bool,clacks,true) // need i say more...?
|
|
OPT(bool,startInactive,false) // used to not start the relays on startup
|
|
OPT(bool,rateLimit,true); // if we do frame rate limiting or not
|
|
OPT(int,rateLimitWait,5); // if we do frame rate limiting, how many seconds before we enforce it fully
|
|
OPT(bool,useXFF,true); // if we use XFF (if available) for the listener address (and related actions)
|
|
OPT(bool,forceShortSends,false);// used for debugging streaming issues by introducing forced delays into sends
|
|
OPT(bool,adminNoWrap,false); // used for defaulting the admin listener page mode for wrapping or not
|
|
// wrapping the listener output list which might be handy for some users
|
|
|
|
// used for customising the css of the index.html and admin pages
|
|
OPT(uniFile::filenameType,adminCSSFile,"v2")
|
|
uniString::utf8 m_styleCustomStr; // used to hold a cached copy of the custom css file
|
|
uniString::utf8 m_styleCustomStrGZ; // used to hold a cached copy of the gzipped custom css file
|
|
uniString::utf8 m_styleCustomHeader; // used to hold a cached copy of the gzipped custom css file
|
|
uniString::utf8 m_styleCustomHeaderGZ; // used to hold a cached copy of the gzipped custom css file
|
|
time_t m_styleCustomHeaderTime; // used to control the cache handling
|
|
|
|
OPT(uniFile::filenameType,faviconFile,"")
|
|
OPT(uniFile::filenameType,faviconFileMimeType,"image/x-icon")
|
|
uniString::utf8 m_faviconBody;
|
|
uniString::utf8 m_faviconHeader;
|
|
uniString::utf8 m_faviconBodyGZ; // gzipped version
|
|
uniString::utf8 m_faviconHeaderGZ; // gzipped version
|
|
time_t m_favIconTime; // used to control the cache handling
|
|
|
|
// used for returning robots.txt
|
|
OPT(uniFile::filenameType,robotstxtFile,"")
|
|
uniString::utf8 m_robotsTxtBody;
|
|
uniString::utf8 m_robotsTxtHeader;
|
|
uniString::utf8 m_robotsTxtBodyGZ; // gzipped version
|
|
uniString::utf8 m_robotsTxtHeaderGZ; // gzipped version
|
|
|
|
uniString::utf8 m_certPath;
|
|
uniString::utf8 m_certFileBody;
|
|
|
|
const bool _load(const uniFile::filenameType &file, const uniString::utf8 &uniqueStr, const bool parent) throw();
|
|
int promptConfigFile() throw();
|
|
|
|
bool editConfigFileEntry(size_t sid, const uniFile::filenameType &filename,
|
|
const uniString::utf8 &authhash, const uniString::utf8 ¶m,
|
|
bool add, bool &handled, bool &idHandled, bool parent) throw();
|
|
|
|
// used for legacy handling of the relayport and relayserver options to sid=1
|
|
uniString::utf8 m_legacyRelayPort;
|
|
uniString::utf8 m_legacyRelayServer;
|
|
|
|
streamConfig& getPerStreamConfig(streamConfig& stream, const size_t sid, const bool useParent = true);
|
|
|
|
public:
|
|
config() throw();
|
|
~config() throw();
|
|
|
|
static std::string logSectionName();
|
|
|
|
uniString::utf8 getCrossDomainFile(const bool compressed) throw();
|
|
uniString::utf8 getIndexCSS(const bool compressed) throw();
|
|
uniString::utf8 getShoutcastSWF(const bool compressed) throw();
|
|
|
|
const uniString::utf8 getStreamRedirectURL(const size_t streamID, const bool isStats, const bool homeSet,
|
|
const bool compress, const bool force = false) const throw();
|
|
|
|
int getRateLimitWait(const size_t streamID) const throw();
|
|
|
|
const int isBitrateDisallowed(const size_t streamID, const int bitrate, int &streamMinBitrate, int &streamMaxBitrate) const throw();
|
|
|
|
unsigned short getMetaInterval(const size_t streamID) const throw();
|
|
int getBackupLoop(const size_t streamID) const throw();
|
|
size_t getSongHistorySize(const size_t streamID) const throw();
|
|
const int getAutoDumpTime(const size_t streamID = DEFAULT_SOURCE_STREAM) const throw();
|
|
|
|
const int getCPUCount() const throw();
|
|
|
|
const std::vector<streamConfig> getRelayList();
|
|
const std::vector<streamConfig> getBackupUrl(const size_t streamID) throw(std::exception);
|
|
const uniString::utf8 getStreamHideStats(const size_t streamID) const;
|
|
|
|
typedef std::map<size_t, config::streamConfig> streams_t;
|
|
void getStreamConfigs(streams_t& streams, const bool useParent = true);
|
|
const bool getStreamConfig(streamConfig& stream, const size_t streamID);
|
|
|
|
// handle updating stream configs on the fly (as applicable)
|
|
#define AUTH_HASH 0x1
|
|
#define URL_PATH 0x2
|
|
#define RELAY_URL 0x4
|
|
#define MAX_USER 0x8
|
|
#define SOURCE_PWD 0x10
|
|
#define ADMIN_PWD 0x20
|
|
#define PUBLIC_SRV 0x40
|
|
#define ALLOW_RELAY 0x80
|
|
#define ALLOW_PUBLIC_RELAY 0x100
|
|
#define RIP_ONLY 0x200
|
|
#define DUMP_TIME 0x400
|
|
#define DUMP_USER 0x800
|
|
#define LIST_TIME 0x1000
|
|
#define SONG_HIST 0x2000
|
|
#define CIPHER_KEY 0x4000
|
|
#define INTRO_FILE 0x8000
|
|
#define BACKUP_FILE 0x10000
|
|
#define BAN_FILE 0x20000
|
|
#define RIP_FILE 0x40000
|
|
#define W3C_FILE 0x80000
|
|
#define MAX_BITRATE 0x100000
|
|
#define BACKUP_URL 0x200000
|
|
#define HIDE_STATS 0x400000
|
|
#define MOVED_URL 0x800000
|
|
#define AGENT_FILE 0x1000000
|
|
#define CDN_MASTER 0x2000000
|
|
#define CDN_SLAVE 0x4000000
|
|
#define ARTWORK_FILE 0x8000000
|
|
#define BACKUP_LOOP 0x10000000
|
|
#define BACKUP_TITLE 0x20000000
|
|
#define MIN_BITRATE 0x40000000
|
|
#define AD_TEST_FILE 0x80000000
|
|
#define AD_TEST_FILE_LOOP 0x100000000ULL
|
|
#define RATE_LIMIT_WAIT 0x200000000ULL
|
|
#define METAINTERVAL 0x400000000ULL
|
|
#define AD_TEST_FILE_2 0x800000000ULL
|
|
#define AD_TEST_FILE_3 0x1000000000ULL
|
|
#define AD_TEST_FILE_4 0x2000000000ULL
|
|
|
|
void addStreamConfig(config &readConfig, config::streamConfig) throw(std::exception);
|
|
__uint64 updateStreamConfig(config &readConfig, config::streamConfig update) throw(std::exception);
|
|
void removeStreamConfig(config::streamConfig) throw(std::exception);
|
|
|
|
// deals with configuring all of the per-stream passwords, etc
|
|
static bool setupPasswords(const config::streams_t &) throw(std::exception);
|
|
|
|
void setOption(uniString::utf8 key, uniString::utf8 value) throw(std::exception);
|
|
|
|
bool load(const uniFile::filenameType &file, bool load = true) throw();
|
|
bool rewriteConfigurationFile(bool minimal = true, bool messages = false, bool setup = false) const throw(std::exception); // throw on I/O error
|
|
uniString::utf8 dumpConfigFile() throw();
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
const std::vector<uniString::utf8>& deferredWarnLogMessages() const throw() { stackLock sml(m_lock); return m_deferredWarnLogMessages; }
|
|
const std::vector<uniString::utf8>& deferredErrorLogMessages() const throw() { stackLock sml(m_lock); return m_deferredErrorLogMessages; }
|
|
|
|
void clearDeferredWarnLogMessages() throw() { stackLock sml(m_lock); m_deferredWarnLogMessages.clear(); }
|
|
void clearDeferredErrorLogMessages() throw() { stackLock sml(m_lock); m_deferredErrorLogMessages.clear(); }
|
|
|
|
/////////// interface for service templates
|
|
const std::vector<uniString::utf8> fromArgs(const std::vector<uniString::utf8> &cl) throw();
|
|
bool getConsoleLogging() const throw();
|
|
const uniFile::filenameType getFileLog() const throw();
|
|
static uniString::utf8 getSystemLogConfigString() throw();
|
|
static uniString::utf8 getVersionBuildStrings() throw();
|
|
////////////////////////////////////////////////////////////////////////////
|
|
};
|
|
|
|
#undef OPT
|
|
#undef OPT_MULTI
|
|
|
|
#endif
|