Do not use C macros for configuration files.

This commit is contained in:
Jan Vidar Krey 2010-04-15 19:49:23 +02:00
parent 51c5b6169c
commit 201acad409
5 changed files with 1325 additions and 445 deletions

View File

@ -29,101 +29,52 @@
#define INT_MIN (-0x7fffffff - 1)
#endif
#define CFG_APPLY_BOOLEAN(KEY, TARGET) \
if (strcmp(KEY, key) == 0) \
{ \
if (strlen(data) == 1 && (data[0] == '1')) TARGET = 1; \
else if (strlen(data) == 1 && (data[0] == '0')) TARGET = 0; \
else if (strncasecmp(data, "true", 4) == 0) TARGET = 1; \
else if (strncasecmp(data, "false", 5) == 0) TARGET = 0; \
else if (strncasecmp(data, "yes", 3) == 0) TARGET = 1; \
else if (strncasecmp(data, "no", 2) == 0) TARGET = 0; \
else if (strncasecmp(data, "on", 2) == 0) TARGET = 1; \
else if (strncasecmp(data, "off", 3) == 0) TARGET = 0; \
else\
{ \
LOG_FATAL("Configuration error on line %d: '%s' must be either '1' or '0'", line_count, key); \
return -1; \
} \
return 0; \
}
#define CFG_APPLY_STRING(KEY, TARGET) \
if (strcmp(KEY, key) == 0) \
{ \
TARGET = hub_strdup(data); \
return 0; \
}
#define CFG_APPLY_INTEGER(KEY, TARGET) \
if (strcmp(KEY, key) == 0) \
{ \
char* endptr; \
int val; \
errno = 0; \
val = strtol(data, &endptr, 10); \
if (((errno == ERANGE && (val == INT_MAX || val == INT_MIN)) || (errno != 0 && val == 0)) || endptr == data) { \
LOG_FATAL("Configuration error on line %d: '%s' must be a number", line_count, key); \
return -1; \
} \
TARGET = val; \
return 0; \
}
#define DEFAULT_STRING(KEY, VALUE) \
{ \
if (config->KEY == 0) \
config->KEY = hub_strdup(VALUE); \
static int apply_boolean(const char* key, const char* data, int* target)
{
if (strlen(data) == 1 && (data[0] == '1')) *target = 1;
else if (strlen(data) == 1 && (data[0] == '0')) *target = 0;
else if (strncasecmp(data, "true", 4) == 0) *target = 1;
else if (strncasecmp(data, "false", 5) == 0) *target = 0;
else if (strncasecmp(data, "yes", 3) == 0) *target = 1;
else if (strncasecmp(data, "no", 2) == 0) *target = 0;
else if (strncasecmp(data, "on", 2) == 0) *target = 1;
else if (strncasecmp(data, "off", 3) == 0) *target = 0;
else
return 0;
return 1;
}
#define DEFAULT_INTEGER(KEY, VALUE) \
{ \
if (config->KEY == 0) \
config->KEY = VALUE; \
static int apply_string(const char* key, const char* data, char** target, char* regexp)
{
(void) regexp;
// FIXME: Add regexp checks for correct data
if (*target)
hub_free(*target);
*target = hub_strdup(data);
return 1;
}
#define DEFAULT_BOOLEAN(KEY, VALUE) \
config->KEY = config->KEY & 0x000000ff;
static int apply_integer(const char* key, const char* data, int* target, int* min, int* max)
{
char* endptr;
int val;
errno = 0;
val = strtol(data, &endptr, 10);
#define GET_STR(NAME) CFG_APPLY_STRING ( #NAME , config->NAME )
#define GET_INT(NAME) CFG_APPLY_INTEGER( #NAME , config->NAME )
#define GET_BOOL(NAME) CFG_APPLY_BOOLEAN( #NAME , config->NAME )
#define IGNORED(NAME) \
if (strcmp(#NAME, key) == 0) \
{ \
LOG_WARN("Configuration option %s deprecated and ingnored.", key); \
return 0; \
}
if (((errno == ERANGE && (val == INT_MAX || val == INT_MIN)) || (errno != 0 && val == 0)) || endptr == data)
return 0;
#define DUMP_STR(NAME, DEFAULT) \
if (ignore_defaults) \
{ \
if (strcmp(config->NAME, DEFAULT) != 0) \
fprintf(stdout, "%s = \"%s\"\n", #NAME , config->NAME); \
} \
else \
fprintf(stdout, "%s = \"%s\"\n", #NAME , config->NAME); \
#define DUMP_INT(NAME, DEFAULT) \
if (ignore_defaults) \
{ \
if (config->NAME != DEFAULT) \
fprintf(stdout, "%s = %d\n", #NAME , config->NAME); \
} \
else \
fprintf(stdout, "%s = %d\n", #NAME , config->NAME); \
if (min && val < *min)
return 0;
#define DUMP_BOOL(NAME, DEFAULT) \
if (ignore_defaults) \
{ \
if (config->NAME != DEFAULT) \
fprintf(stdout, "%s = %s\n", #NAME , (config->NAME ? "yes" : "no")); \
} \
else \
fprintf(stdout, "%s = %s\n", #NAME , (config->NAME ? "yes" : "no"));
if (max && val > *max)
return 0;
*target = val;
return 1;
}
#include "gen_config.c"

View File

@ -20,8 +20,7 @@ open GENHEAD, ">gen_config.h" || die "Unable to write header file";
print GENHEAD "/* THIS FILE IS AUTOGENERATED - DO NOT CHANGE IT! */\n\nstruct hub_config\n{\n";
foreach my $p ($tree->root->children("option"))
{
my @data = ($p->att("type"), $p->att("name"), $p->att("default"), $p->att("advanced"), $p->children_text("short"), $p->children_text("description"), $p->children_text("since"), $p->children_text("example"));
write_c_header(@data);
write_c_header(get_data($p));
}
print GENHEAD "};\n\n";
@ -38,7 +37,8 @@ foreach my $p ($tree->root->children("option"))
print GENIMPL "}\n\n";
# apply function
print GENIMPL "static int apply_config(struct hub_config* config, char* key, char* data, int line_count)\n{\n";
print GENIMPL "static int apply_config(struct hub_config* config, char* key, char* data, int line_count)\n{\n\tint max = 0;\n\tint min = 0;\n\n";
foreach my $p ($tree->root->children("option"))
{
write_c_impl_apply(get_data($p));
@ -105,29 +105,92 @@ sub write_c_impl_defaults(@)
{
my @output = @_;
my ($type, $name, $default, $advanced, $short, $desc, $since, $example) = @output;
my $prefix = "";
my $suffix = "";
print GENIMPL "\t";
print GENIMPL "DEFAULT_INTEGER" if ($type eq "int");
print GENIMPL "DEFAULT_BOOLEAN" if ($type eq "boolean");
print GENIMPL "\tconfig->$name = ";
if ($type =~ /(string|file|message)/)
{
print GENIMPL "DEFAULT_STRING ";
$default = "\"" . $default . "\"";
$prefix = "hub_strdup(\"";
$suffix = "\")"
}
print GENIMPL "(" . $name . ", " . $default . ");\n";
print GENIMPL $prefix . $default . $suffix . ";\n";
}
sub write_c_impl_apply(@)
{
my @output = @_;
my ($type, $name, $default, $advanced, $short, $desc, $since, $example) = @output;
my ($type, $name, $default, $advanced, $short, $desc, $since, $example, $p) = @output;
print GENIMPL "\t";
print GENIMPL "GET_INT " if ($type eq "int");
print GENIMPL "GET_BOOL" if ($type eq "boolean");
print GENIMPL "GET_STR " if ($type =~ /(string|file|message)/);
print GENIMPL "(" . $name . ");\n";
my $min;
my $max;
my $regexp;
if (defined $p)
{
$min = $p->att("min");
$max = $p->att("max");
$regexp = $p->att("regexp");
print "'check' is defined for option $name";
print ", min=$min" if (defined $min);
print ", max=$max" if (defined $max);
print ", regexp=\"$regexp\"" if (defined $regexp);
print "\n";
}
print GENIMPL "\tif (!strcmp(key, \"" . $name . "\"))\n\t{\n";
if ($type eq "int")
{
if (defined $min)
{
print GENIMPL "\t\tmin = $min;\n"
}
if (defined $max)
{
print GENIMPL "\t\tmax = $max;\n"
}
print GENIMPL "\t\tif (!apply_integer(key, data, &config->$name, ";
if (defined $min)
{
print GENIMPL "&min";
}
else
{
print GENIMPL "0";
}
print GENIMPL ", ";
if (defined $max)
{
print GENIMPL "&max";
}
else
{
print GENIMPL "0";
}
print GENIMPL "))\n";
}
elsif ($type eq "boolean")
{
print GENIMPL "\t\tif (!apply_boolean(key, data, &config->$name))\n";
}
elsif ($type =~ /(string|file|message)/)
{
print GENIMPL "\t\tif (!apply_string(key, data, &config->$name, (char*) \"\"))\n";
}
print GENIMPL "\t\t{\n" .
"\t\t\tLOG_ERROR(\"Configuration parse error on line %d\", line_count);\n" .
"\t\t\treturn -1;\n" .
"\t\t}\n" .
"\t\treturn 0;\n" .
"\t}\n\n";
}
sub write_c_impl_free(@)
@ -135,30 +198,44 @@ sub write_c_impl_free(@)
my @output = @_;
my ($type, $name, $default, $advanced, $short, $desc, $since, $example) = @output;
print GENIMPL "\thub_free(config->" . $name . ");\n" if ($type =~ /(string|file|message)/)
if ($type =~ /(string|file|message)/)
{
print GENIMPL "\thub_free(config->" . $name . ");\n\n"
}
}
sub write_c_impl_dump(@)
{
my @output = @_;
my ($type, $name, $default, $advanced, $short, $desc, $since, $example) = @output;
my $out;
my $val = "config->$name";
my $test = "config->$name != $default";
print GENIMPL "\t";
print GENIMPL "DUMP_INT " if ($type eq "int");
print GENIMPL "DUMP_BOOL" if ($type eq "boolean");
if ($type =~ /(string|file|message)/)
if ($type eq "int")
{
print GENIMPL "DUMP_STR";
$default = "\"" . $default . "\"";
$out = "%d";
}
print GENIMPL "(" . $name . ", " . $default . ");\n"
elsif ($type eq "boolean")
{
$out = "%s";
$val = "config->$name ? \"yes\" : \"no\"";
}
elsif ($type =~ /(string|file|message)/)
{
$out = "\\\"%s\\\"";
$test = "strcmp(config->$name, \"$default\") != 0";
}
print GENIMPL "\tif (!ignore_defaults || $test)\n";
print GENIMPL "\t\tfprintf(stdout, \"$name = $out\\n\", $val);\n\n";
}
sub get_data($)
{
my $p = shift;
my @data = ($p->att("type"), $p->att("name"), $p->att("default"), $p->att("advanced"), $p->children_text("short"), $p->children_text("description"), $p->children_text("since"), $p->children_text("example"));
my $check = $p->first_child_matches("check");
my @data = ($p->att("type"), $p->att("name"), $p->att("default"), $p->att("advanced"), $p->children_text("short"), $p->children_text("description"), $p->children_text("since"), $p->children_text("example"), $check);
return @data;
}

View File

@ -1,5 +1,14 @@
<?xml version='1.0' standalone="yes" ?>
<config>
<option name="hub_enabled" type="boolean" default="1">
<short>Is server enabled</short>
<description>
Use this to disable the hub for a while.
</description>
<since>0.1.3</since>
</option>
<option name="server_port" type="int" default="1511">
<check min="1" max="65535" />
<since>0.1.0</since>
@ -60,14 +69,6 @@
<since>0.3.0</since>
</option>
<option name="hub_enabled" type="boolean" default="1">
<short>Is server enabled</short>
<description>
Use this to disable the hub for a while.
</description>
<since>0.1.3</since>
</option>
<option name="show_banner" type="boolean" default="1">
<short>Show banner on connect</short>
<description>
@ -86,7 +87,7 @@
</option>
<option name="max_users" type="int" default="500">
<check min="1" />
<check min="1" max="1048576" />
<short>Maximum number of users allowed on the hub</short>
<description>
The maximum amount of users allowed on the hub.
@ -327,7 +328,7 @@
</option>
<option name="flood_ctl_interval" type="int" default="0">
<check min="0" max="60" />
<check min="1" max="60" />
<short>Time interval in seconds for flood control check.</short>
<description>
This is the time interval that will be used for all flood control calculations.

File diff suppressed because it is too large Load Diff

View File

@ -2,85 +2,3 @@
struct hub_config
{
int server_port; /*<<< Server port to bind to (default: 1511) */
char* server_bind_addr; /*<<< Server bind address (default: any) */
int server_listen_backlog; /*<<< Server listen backlog (default: 50) */
char* server_alt_ports; /*<<< Comma separated list of alternative ports to listen to (default: ) */
int hub_enabled; /*<<< Is server enabled (default: 1) */
int show_banner; /*<<< Show banner on connect (default: 1) */
int show_banner_sys_info; /*<<< Show banner on connect (default: 1) */
int max_users; /*<<< Maximum number of users allowed on the hub (default: 500) */
int registered_users_only; /*<<< Allow registered users only (default: 0) */
int obsolete_clients; /*<<< Support obsolete clients using a ADC protocol prior to 1.0 (default: 0) */
int chat_only; /*<<< Allow chat only operation on hub (default: 0) */
int chat_is_privileged; /*<<< Allow chat for operators and above only (default: 0) */
char* hub_name; /*<<< Name of hub (default: uhub) */
char* hub_description; /*<<< Short hub description, topic or subject. (default: no description) */
int max_recv_buffer; /*<<< Max read buffer before parse, per user (default: 4096) */
int max_send_buffer; /*<<< Max send buffer before disconnect, per user (default: 131072) */
int max_send_buffer_soft; /*<<< Max send buffer before message drops, per user (default: 98304) */
int low_bandwidth_mode; /*<<< Enable bandwidth saving measures (default: 0) */
int max_chat_history; /*<<< Number of chat messages kept in history (default: 20) */
int max_logout_log; /*<<< Number of log entries for people leaving the hub (default: 20) */
int limit_max_hubs_user; /*<<< Max concurrent hubs as a guest user (default: 10) */
int limit_max_hubs_reg; /*<<< Max concurrent hubs as a registered user (default: 10) */
int limit_max_hubs_op; /*<<< Max concurrent hubs as a operator (or admin) (default: 10) */
int limit_max_hubs; /*<<< Max total hub connections allowed, user/reg/op combined. (default: 25) */
int limit_min_hubs_user; /*<<< Minimum concurrent hubs as a guest user (default: 0) */
int limit_min_hubs_reg; /*<<< Minimum concurrent hubs as a registered user (default: 0) */
int limit_min_hubs_op; /*<<< Minimum concurrent hubs as a operator (or admin) (default: 0) */
int limit_min_share; /*<<< Limit minimum share size in megabytes (default: 0) */
int limit_max_share; /*<<< Limit maximum share size in megabytes (default: 0) */
int limit_min_slots; /*<<< Limit minimum number of upload slots open per user (default: 0) */
int limit_max_slots; /*<<< Limit minimum number of upload slots open per user (default: 0) */
int flood_ctl_interval; /*<<< Time interval in seconds for flood control check. (default: 0) */
int flood_ctl_chat; /*<<< Max chat messages allowed in time interval (default: 0) */
int flood_ctl_connect; /*<<< Max connections requests allowed in time interval (default: 0) */
int flood_ctl_search; /*<<< Max search requests allowed in time interval (default: 0) */
int flood_ctl_update; /*<<< Max updates allowed in time interval (default: 0) */
int flood_ctl_extras; /*<<< Max extra messages allowed in time interval (default: 0) */
int tls_enable; /*<<< Enable SSL/TLS support (default: 0) */
int tls_require; /*<<< If SSL/TLS enabled, should it be required (default: 0) (default: 0) */
char* tls_certificate; /*<<< Certificate file (default: ) */
char* tls_private_key; /*<<< Private key file (default: ) */
char* file_motd; /*<<< File containing the 'message of the day (default: ) */
char* file_acl; /*<<< File containing access control lists (default: ) */
char* file_rules; /*<<< File containing hub rules (default: ) */
char* msg_hub_full; /*<<< "Hub is full" */
char* msg_hub_disabled; /*<<< "Hub is disabled" */
char* msg_hub_registered_users_only; /*<<< "Hub is for registered users only" */
char* msg_inf_error_nick_missing; /*<<< "No nickname given" */
char* msg_inf_error_nick_multiple; /*<<< "Multiple nicknames given" */
char* msg_inf_error_nick_invalid; /*<<< "Nickname is invalid" */
char* msg_inf_error_nick_long; /*<<< "Nickname too long" */
char* msg_inf_error_nick_short; /*<<< "Nickname too short" */
char* msg_inf_error_nick_spaces; /*<<< "Nickname cannot start with spaces" */
char* msg_inf_error_nick_bad_chars; /*<<< "Nickname contains invalid characters" */
char* msg_inf_error_nick_not_utf8; /*<<< "Nickname is not valid UTF-8" */
char* msg_inf_error_nick_taken; /*<<< "Nickname is already in use" */
char* msg_inf_error_nick_restricted; /*<<< "Nickname cannot be used on this hub" */
char* msg_inf_error_cid_invalid; /*<<< "CID is not valid" */
char* msg_inf_error_cid_missing; /*<<< "CID is not specified" */
char* msg_inf_error_cid_taken; /*<<< "CID is taken" */
char* msg_inf_error_pid_missing; /*<<< "PID is not specified" */
char* msg_inf_error_pid_invalid; /*<<< "PID is invalid" */
char* msg_ban_permanently; /*<<< "Banned permanently" */
char* msg_ban_temporarily; /*<<< "Banned temporarily" */
char* msg_auth_invalid_password; /*<<< "Password is wrong" */
char* msg_auth_user_not_found; /*<<< "User not found in password database" */
char* msg_error_no_memory; /*<<< "No memory" */
char* msg_user_share_size_low; /*<<< "User is not sharing enough" */
char* msg_user_share_size_high; /*<<< "User is sharing too much" */
char* msg_user_slots_low; /*<<< "User have too few upload slots." */
char* msg_user_slots_high; /*<<< "User have too many upload slots." */
char* msg_user_hub_limit_low; /*<<< "User is on too few hubs." */
char* msg_user_hub_limit_high; /*<<< "User is on too many hubs." */
char* msg_user_flood_chat; /*<<< "Chat flood detected, messages are dropped." */
char* msg_user_flood_connect; /*<<< "Connect flood detected, connection refused." */
char* msg_user_flood_search; /*<<< "Search flood detected, search is stopped." */
char* msg_user_flood_update; /*<<< "Update flood detected." */
char* msg_user_flood_extras; /*<<< "Flood detected." */
char* msg_proto_no_common_hash; /*<<< "No common hash algorithm." */
char* msg_proto_obsolete_adc0; /*<<< "Client is using an obsolete ADC protocol version." */
};