summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Sirainen <cras@irssi.org>2000-06-04 14:52:47 +0000
committercras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564>2000-06-04 14:52:47 +0000
commita7f5540cba46869fda6b3da42199bb85bd6dab8b (patch)
treee769eb1a127a6706865b470273eb561f6ae72d68
parentee46dc71ab5fe607851bcc29f836d7f4a3d00a3e (diff)
downloadirssi-a7f5540cba46869fda6b3da42199bb85bd6dab8b.zip
/IRCNET command.
PARAM_FLAG_NOQUOTES flag for cmd_get_params() git-svn-id: http://svn.irssi.org/repos/irssi/trunk@290 dbcabf3a-b0e7-0310-adc4-f8d773084564
-rw-r--r--docs/manual.txt4
-rw-r--r--src/core/commands.c22
-rw-r--r--src/core/commands.h4
-rw-r--r--src/fe-common/irc/Makefile.am1
-rw-r--r--src/fe-common/irc/fe-channels.c10
-rw-r--r--src/fe-common/irc/fe-common-irc.c5
-rw-r--r--src/fe-common/irc/fe-irc-server.c22
-rw-r--r--src/fe-common/irc/module-formats.c6
-rw-r--r--src/fe-common/irc/module-formats.h6
-rw-r--r--src/irc/core/ircnet-setup.c91
-rw-r--r--src/irc/core/ircnet-setup.h9
-rw-r--r--src/irc/core/netsplit.c2
-rw-r--r--src/irc/core/server-setup.c53
-rw-r--r--src/irc/dcc/dcc-files.c3
-rw-r--r--src/irc/dcc/dcc.c3
15 files changed, 173 insertions, 68 deletions
diff --git a/docs/manual.txt b/docs/manual.txt
index f7f922d7..2cde9a97 100644
--- a/docs/manual.txt
+++ b/docs/manual.txt
@@ -362,7 +362,7 @@
/IRCNET ADD [-kicks <count>] [-msgs <count>] [-modes <count>]
[-whois <count>] [-cmdspeed <ms>] [-cmdmax <count>]
- [-nick <nick>] [-user <user>] [-name <name>]
+ [-nick <nick>] [-user <user>] [-realname <name>]
[-host <host>] <name>
-kicks: Maximum number of nicks in one /KICK command
@@ -371,7 +371,7 @@
-whois: Maximum number of nicks in one /WHOIS command
-cmdspeed: Same as /SET cmd_queue_speed, see section 3.1
-cmdmax: Same as /SET cmd_max_at_once, see section 3.1
- -nick, -user, -name: Specify what nick/username/realname to use
+ -nick, -user, -realname: Specify what nick/user/name to use
-host: Specify what host name to use, if you have multiple
/IRCNET REMOVE <name>
diff --git a/src/core/commands.c b/src/core/commands.c
index 1a05e7a3..e4c7a5ff 100644
--- a/src/core/commands.c
+++ b/src/core/commands.c
@@ -352,13 +352,17 @@ char *cmd_get_params(const char *data, int count, ...)
va_start(args, count);
/* get the length of the arguments in string */
- old = datad = g_strdup(data);
- if (count & PARAM_FLAG_MULTIARGS)
- get_multi_args(&datad, TRUE, args);
- else if (count & PARAM_FLAG_OPTARGS)
- get_opt_args(&datad);
- len = (int) (datad-old);
- g_free(old);
+ if ((count & (PARAM_FLAG_MULTIARGS|PARAM_FLAG_OPTARGS)) == 0)
+ len = 0;
+ else {
+ old = datad = g_strdup(data);
+ if (count & PARAM_FLAG_MULTIARGS)
+ get_multi_args(&datad, TRUE, args);
+ else
+ get_opt_args(&datad);
+ len = (int) (datad-old);
+ g_free(old);
+ }
/* send the text to custom functions to handle - skip arguments */
old = datad = cmd_get_callfuncs(data+len, &count, &args);
@@ -392,7 +396,9 @@ char *cmd_get_params(const char *data, int count, ...)
/* get rest */
arg = datad;
} else {
- arg = cmd_get_quoted_param(&datad);
+ arg = (count & PARAM_FLAG_NOQUOTES) ?
+ cmd_get_param(&datad) :
+ cmd_get_quoted_param(&datad);
}
str = (char **) va_arg(args, char **);
diff --git a/src/core/commands.h b/src/core/commands.h
index dcff89c2..74f66e45 100644
--- a/src/core/commands.h
+++ b/src/core/commands.h
@@ -36,7 +36,9 @@ void command_runsub(const char *cmd, const char *data, void *p1, void *p2);
/* count can have these flags: */
#define PARAM_WITHOUT_FLAGS(a) ((a) & 0x00ffffff)
-/* cmd_get_params() */
+/* don't check for quotes - "arg1 arg2" is NOT treated as one argument */
+#define PARAM_FLAG_NOQUOTES 0x01000000
+/* final argument gets all the rest of the arguments */
#define PARAM_FLAG_GETREST 0x02000000
/* optional arguments (-cmd -cmd2 -cmd3) */
#define PARAM_FLAG_OPTARGS 0x04000000
diff --git a/src/fe-common/irc/Makefile.am b/src/fe-common/irc/Makefile.am
index 662caf9d..7c59e0d4 100644
--- a/src/fe-common/irc/Makefile.am
+++ b/src/fe-common/irc/Makefile.am
@@ -16,6 +16,7 @@ libfe_common_irc_la_SOURCES = \
fe-channels.c \
fe-irc-commands.c \
fe-irc-server.c \
+ fe-ircnet.c \
fe-ctcp.c \
fe-events.c \
fe-events-numeric.c \
diff --git a/src/fe-common/irc/fe-channels.c b/src/fe-common/irc/fe-channels.c
index 0d566fd7..1859ae7b 100644
--- a/src/fe-common/irc/fe-channels.c
+++ b/src/fe-common/irc/fe-channels.c
@@ -157,13 +157,13 @@ static void cmd_channel_list(void)
g_string_truncate(str, 0);
if (rec->autojoin)
- g_string_append(str, "autojoin ");
+ g_string_append(str, "autojoin, ");
if (rec->botmasks != NULL && *rec->botmasks != '\0')
- g_string_sprintfa(str, "bots: %s ", rec->botmasks);
+ g_string_sprintfa(str, "bots: %s, ", rec->botmasks);
if (rec->autosendcmd != NULL && *rec->autosendcmd != '\0')
- g_string_sprintfa(str, "botcmd: %s ", rec->autosendcmd);
+ g_string_sprintfa(str, "botcmd: %s, ", rec->autosendcmd);
- if (str->len > 0) g_string_truncate(str, str->len-1);
+ if (str->len > 1) g_string_truncate(str, str->len-1);
printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_CHANSETUP_LINE,
rec->name, rec->ircnet == NULL ? "" : rec->ircnet,
rec->password == NULL ? "" : rec->password, str->str);
@@ -242,8 +242,8 @@ void fe_channels_init(void)
signal_add_last("server disconnected", (SIGNAL_FUNC) sig_disconnected);
command_bind("wjoin", NULL, (SIGNAL_FUNC) cmd_wjoin);
- command_bind("channel ", NULL, (SIGNAL_FUNC) cmd_channel_list_joined);
command_bind("channel", NULL, (SIGNAL_FUNC) cmd_channel);
+ command_bind("channel ", NULL, (SIGNAL_FUNC) cmd_channel_list_joined);
command_bind("channel add", NULL, (SIGNAL_FUNC) cmd_channel_add);
command_bind("channel remove", NULL, (SIGNAL_FUNC) cmd_channel_remove);
command_bind("channel list", NULL, (SIGNAL_FUNC) cmd_channel_list);
diff --git a/src/fe-common/irc/fe-common-irc.c b/src/fe-common/irc/fe-common-irc.c
index 63430a69..7125dab5 100644
--- a/src/fe-common/irc/fe-common-irc.c
+++ b/src/fe-common/irc/fe-common-irc.c
@@ -40,6 +40,9 @@ void fe_channels_deinit(void);
void fe_irc_commands_init(void);
void fe_irc_commands_deinit(void);
+void fe_ircnet_init(void);
+void fe_ircnet_deinit(void);
+
void fe_irc_server_init(void);
void fe_irc_server_deinit(void);
@@ -100,6 +103,7 @@ void fe_common_irc_init(void)
fe_channels_init();
fe_irc_commands_init();
+ fe_ircnet_init();
fe_irc_server_init();
fe_ctcp_init();
fe_events_init();
@@ -119,6 +123,7 @@ void fe_common_irc_deinit(void)
fe_channels_deinit();
fe_irc_commands_deinit();
+ fe_ircnet_deinit();
fe_irc_server_deinit();
fe_ctcp_deinit();
fe_events_deinit();
diff --git a/src/fe-common/irc/fe-irc-server.c b/src/fe-common/irc/fe-irc-server.c
index ee0978d7..24c662b4 100644
--- a/src/fe-common/irc/fe-irc-server.c
+++ b/src/fe-common/irc/fe-irc-server.c
@@ -101,14 +101,20 @@ static void server_add(const char *data)
if (*portarg != '\0') rec->port = atoi(portarg);
if (stristr(args, "-ircnet")) g_free_and_null(rec->ircnet);
if (*password != '\0') g_free_and_null(rec->password);
- if (stristr(args, "-host")) g_free_and_null(rec->own_host);
+ if (stristr(args, "-host")) {
+ g_free_and_null(rec->own_host);
+ rec->own_ip = NULL;
+ }
}
if (stristr(args, "-auto")) rec->autoconnect = TRUE;
if (stristr(args, "-noauto")) rec->autoconnect = FALSE;
if (*ircnet != '\0') rec->ircnet = g_strdup(ircnet);
if (*password != '\0' && strcmp(password, "-") != 0) rec->password = g_strdup(password);
- if (*host != '\0') rec->own_host = g_strdup(host);
+ if (*host != '\0') {
+ rec->own_host = g_strdup(host);
+ rec->own_ip = NULL;
+ }
if (*cmdspeed != '\0') rec->cmd_queue_speed = atoi(cmdspeed);
if (*cmdmax != '\0') rec->max_cmds_at_once = atoi(cmdmax);
@@ -151,15 +157,17 @@ static void server_list(const char *data)
g_string_truncate(str, 0);
if (rec->password != NULL)
- g_string_append(str, "(pass) ");
+ g_string_append(str, "(pass), ");
if (rec->autoconnect)
- g_string_append(str, "autoconnect ");
+ g_string_append(str, "autoconnect, ");
if (rec->max_cmds_at_once > 0)
- g_string_sprintfa(str, "cmdmax: %d ", rec->max_cmds_at_once);
+ g_string_sprintfa(str, "cmdmax: %d, ", rec->max_cmds_at_once);
if (rec->cmd_queue_speed > 0)
- g_string_sprintfa(str, "cmdspeed: %d ", rec->cmd_queue_speed);
+ g_string_sprintfa(str, "cmdspeed: %d, ", rec->cmd_queue_speed);
if (rec->own_host != NULL)
- g_string_sprintfa(str, "host: %s ", rec->own_host);
+ g_string_sprintfa(str, "host: %s, ", rec->own_host);
+
+ if (str->len > 1) g_string_truncate(str, str->len-2);
printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_SETUPSERVER_LINE,
rec->address, rec->port,
rec->ircnet == NULL ? "" : rec->ircnet,
diff --git a/src/fe-common/irc/module-formats.c b/src/fe-common/irc/module-formats.c
index f09f50a4..c20089ff 100644
--- a/src/fe-common/irc/module-formats.c
+++ b/src/fe-common/irc/module-formats.c
@@ -47,6 +47,12 @@ FORMAT_REC fecommon_irc_formats[] = {
{ "netsplits_header", "Nick Channel Server Splitted server", 0 },
{ "netsplits_line", "$[9]0 $[10]1 $[20]2 $3", 4, { 0, 0, 0, 0 } },
{ "netsplits_footer", "", 0 },
+ { "ircnet_added", "Ircnet $0 saved", 1, { 0 } },
+ { "ircnet_removed", "Ircnet $0 removed", 1, { 0 } },
+ { "ircnet_not_found", "Ircnet $0 not found", 1, { 0 } },
+ { "ircnet_header", "Ircnets:", 0 },
+ { "ircnet_line", "$0: $1", 2, { 0, 0 } },
+ { "ircnet_footer", "", 0 },
/* ---- */
{ NULL, "Channels", 0 },
diff --git a/src/fe-common/irc/module-formats.h b/src/fe-common/irc/module-formats.h
index 56521f47..d4210461 100644
--- a/src/fe-common/irc/module-formats.h
+++ b/src/fe-common/irc/module-formats.h
@@ -25,6 +25,12 @@ enum {
IRCTXT_NETSPLITS_HEADER,
IRCTXT_NETSPLITS_LINE,
IRCTXT_NETSPLITS_FOOTER,
+ IRCTXT_IRCNET_ADDED,
+ IRCTXT_IRCNET_REMOVED,
+ IRCTXT_IRCNET_NOT_FOUND,
+ IRCTXT_IRCNET_HEADER,
+ IRCTXT_IRCNET_LINE,
+ IRCTXT_IRCNET_FOOTER,
IRCTXT_FILL_2,
diff --git a/src/irc/core/ircnet-setup.c b/src/irc/core/ircnet-setup.c
index 8296a7e8..bd913705 100644
--- a/src/irc/core/ircnet-setup.c
+++ b/src/irc/core/ircnet-setup.c
@@ -29,6 +29,64 @@
GSList *ircnets; /* list of available ircnets */
+static void ircnet_config_add(IRCNET_REC *ircnet)
+{
+ CONFIG_NODE *node;
+
+ node = iconfig_node_traverse("ircnets", TRUE);
+ iconfig_node_set_str(node, ircnet->name, NULL);
+ node = config_node_section(node, ircnet->name, NODE_TYPE_BLOCK);
+
+ iconfig_node_set_str(node, "nick", ircnet->nick);
+ iconfig_node_set_str(node, "username", ircnet->username);
+ iconfig_node_set_str(node, "realname", ircnet->realname);
+ iconfig_node_set_str(node, "host", ircnet->own_host);
+
+ if (ircnet->max_cmds_at_once > 0)
+ config_node_set_int(node, "cmdmax", ircnet->max_cmds_at_once);
+ if (ircnet->cmd_queue_speed > 0)
+ config_node_set_int(node, "cmdspeed", ircnet->cmd_queue_speed);
+
+ if (ircnet->max_kicks > 0)
+ config_node_set_int(node, "max_kicks", ircnet->max_kicks);
+ if (ircnet->max_msgs > 0)
+ config_node_set_int(node, "max_msgs", ircnet->max_msgs);
+ if (ircnet->max_modes > 0)
+ config_node_set_int(node, "max_modes", ircnet->max_modes);
+ if (ircnet->max_whois > 0)
+ config_node_set_int(node, "max_whois", ircnet->max_whois);
+
+}
+
+static void ircnet_config_remove(IRCNET_REC *ircnet)
+{
+ CONFIG_NODE *node;
+
+ node = iconfig_node_traverse("ircnets", FALSE);
+ if (node != NULL) iconfig_node_set_str(node, ircnet->name, NULL);
+}
+
+void ircnet_create(IRCNET_REC *ircnet)
+{
+ if (g_slist_find(ircnets, ircnet) == NULL)
+ ircnets = g_slist_append(ircnets, ircnet);
+
+ ircnet_config_add(ircnet);
+}
+
+void ircnet_destroy(IRCNET_REC *ircnet)
+{
+ ircnet_config_remove(ircnet);
+ ircnets = g_slist_remove(ircnets, ircnet);
+
+ g_free(ircnet->name);
+ g_free_not_null(ircnet->nick);
+ g_free_not_null(ircnet->username);
+ g_free_not_null(ircnet->realname);
+ g_free_not_null(ircnet->own_host);
+ g_free(ircnet);
+}
+
/* Find the irc network by name */
IRCNET_REC *ircnet_find(const char *name)
{
@@ -46,42 +104,29 @@ IRCNET_REC *ircnet_find(const char *name)
return NULL;
}
-static void ircnet_destroy(IRCNET_REC *rec)
-{
- ircnets = g_slist_remove(ircnets, rec);
-
- g_free(rec->name);
- if (rec->nick != NULL) g_free(rec->nick);
- if (rec->username != NULL) g_free(rec->username);
- if (rec->realname != NULL) g_free(rec->realname);
- g_free(rec);
-}
-
static IRCNET_REC *ircnet_add(CONFIG_NODE *node)
{
IRCNET_REC *rec;
- char *name, *nick, *username, *realname;
g_return_val_if_fail(node != NULL, NULL);
+ if (node->key == NULL) return NULL;
+
+ rec = g_new0(IRCNET_REC, 1);
- name = config_node_get_str(node, "name", NULL);
- if (name == NULL) return NULL;
+ rec->name = g_strdup(node->key);
+ rec->nick = g_strdup(config_node_get_str(node, "nick", NULL));
+ rec->username = g_strdup(config_node_get_str(node, "username", NULL));
+ rec->realname = g_strdup(config_node_get_str(node, "realname", NULL));
+ rec->own_host = g_strdup(config_node_get_str(node, "host", NULL));
- nick = config_node_get_str(node, "nick", NULL);
- username = config_node_get_str(node, "username", NULL);
- realname = config_node_get_str(node, "realname", NULL);
+ rec->max_cmds_at_once = config_node_get_int(node, "cmdmax", 0);
+ rec->cmd_queue_speed = config_node_get_int(node, "cmdspeed", 0);
- rec = g_new0(IRCNET_REC, 1);
rec->max_kicks = config_node_get_int(node, "max_kicks", 0);
rec->max_msgs = config_node_get_int(node, "max_msgs", 0);
rec->max_modes = config_node_get_int(node, "max_modes", 0);
rec->max_whois = config_node_get_int(node, "max_whois", 0);
- rec->name = g_strdup(name);
- rec->nick = (nick == NULL || *nick == '\0') ? NULL : g_strdup(nick);
- rec->username = (username == NULL || *username == '\0') ? NULL : g_strdup(username);
- rec->realname = (realname == NULL || *realname == '\0') ? NULL : g_strdup(realname);
-
ircnets = g_slist_append(ircnets, rec);
return rec;
}
diff --git a/src/irc/core/ircnet-setup.h b/src/irc/core/ircnet-setup.h
index dea530fb..2b82f171 100644
--- a/src/irc/core/ircnet-setup.h
+++ b/src/irc/core/ircnet-setup.h
@@ -8,12 +8,21 @@ typedef struct {
char *username;
char *realname;
+ char *own_host; /* address to use when connecting this server */
+ IPADDR *own_ip; /* resolved own_address if not NULL */
+
+ int max_cmds_at_once;
+ int cmd_queue_speed;
+
/* max. number of kicks/msgs/mode/whois per command */
int max_kicks, max_msgs, max_modes, max_whois;
} IRCNET_REC;
extern GSList *ircnets; /* list of available ircnets */
+void ircnet_create(IRCNET_REC *ircnet);
+void ircnet_destroy(IRCNET_REC *ircnet);
+
/* Find the irc network by name */
IRCNET_REC *ircnet_find(const char *name);
diff --git a/src/irc/core/netsplit.c b/src/irc/core/netsplit.c
index 5d7d3bf3..bfa40c3c 100644
--- a/src/irc/core/netsplit.c
+++ b/src/irc/core/netsplit.c
@@ -203,7 +203,7 @@ int quitmsg_is_split(const char *msg)
/* get the two hosts */
ok = FALSE;
- params = cmd_get_params(msg, 2, &host1, &host2);
+ params = cmd_get_params(msg, 2 | PARAM_FLAG_NOQUOTES, &host1, &host2);
if (g_strcasecmp(host1, host2) != 0) { /* hosts can't be same.. */
/* check that domain length is 2 or 3 */
p = strrchr(host1, '.');
diff --git a/src/irc/core/server-setup.c b/src/irc/core/server-setup.c
index 603d7142..66c0a932 100644
--- a/src/irc/core/server-setup.c
+++ b/src/irc/core/server-setup.c
@@ -49,6 +49,30 @@ static void get_source_host_ip(void)
}
}
+static void conn_set_ip(IRC_SERVER_CONNECT_REC *conn, IPADDR **own_ip, const char *own_host)
+{
+ IPADDR ip;
+
+ if (*own_ip != NULL) {
+ /* use already resolved IP */
+ if (conn->own_ip == NULL)
+ conn->own_ip = g_new(IPADDR, 1);
+ memcpy(conn->own_ip, *own_ip, sizeof(IPADDR));
+ return;
+ }
+
+
+ /* resolve the IP and use it */
+ if (net_gethostbyname(own_host, &ip) == 0) {
+ if (conn->own_ip == NULL)
+ conn->own_ip = g_new(IPADDR, 1);
+ memcpy(conn->own_ip, &ip, sizeof(IPADDR));
+
+ *own_ip = g_new(IPADDR, 1);
+ memcpy(*own_ip, &ip, sizeof(IPADDR));
+ }
+}
+
/* Create server connection record. `address' is required, rest can be NULL */
static IRC_SERVER_CONNECT_REC *
create_addr_conn(const char *address, int port, const char *password,
@@ -91,25 +115,8 @@ create_addr_conn(const char *address, int port, const char *password,
sserver = server_setup_find(address, -1);
if (sserver == NULL) return conn;
- if (sserver->own_ip != NULL) {
- /* use already resolved IP */
- if (conn->own_ip == NULL)
- conn->own_ip = g_new(IPADDR, 1);
- memcpy(conn->own_ip, sserver->own_ip, sizeof(IPADDR));
- } else if (sserver->own_host != NULL) {
- /* resolve the IP and use it */
- IPADDR ip;
-
- if (net_gethostbyname(sserver->own_host, &ip) == 0) {
- if (conn->own_ip == NULL)
- conn->own_ip = g_new(IPADDR, 1);
- memcpy(conn->own_ip, &ip, sizeof(IPADDR));
-
- sserver->own_ip = g_new(IPADDR, 1);
- memcpy(sserver->own_ip, &ip, sizeof(IPADDR));
- }
- }
-
+ if (sserver->own_host != NULL)
+ conn_set_ip(conn, &sserver->own_ip, sserver->own_host);
sserver->last_connect = time(NULL);
if (sserver->ircnet) conn->ircnet = g_strdup(sserver->ircnet);
@@ -141,6 +148,14 @@ create_addr_conn(const char *address, int port, const char *password,
if (ircnet->max_modes > 0) conn->max_modes = ircnet->max_modes;
if (ircnet->max_whois > 0) conn->max_whois = ircnet->max_whois;
+ if (ircnet->max_cmds_at_once > 0 && sserver->max_cmds_at_once <= 0)
+ conn->max_cmds_at_once = ircnet->max_cmds_at_once;
+ if (ircnet->cmd_queue_speed > 0 && sserver->cmd_queue_speed <= 0)
+ conn->cmd_queue_speed = ircnet->cmd_queue_speed;
+
+ if (sserver->own_host == NULL && ircnet->own_host != NULL)
+ conn_set_ip(conn, &ircnet->own_ip, ircnet->own_host);
+
return conn;
}
diff --git a/src/irc/dcc/dcc-files.c b/src/irc/dcc/dcc-files.c
index 2fb8d0b4..e2dc732d 100644
--- a/src/irc/dcc/dcc-files.c
+++ b/src/irc/dcc/dcc-files.c
@@ -272,7 +272,8 @@ static void dcc_ctcp_msg(const char *data, IRC_SERVER_REC *server,
g_return_if_fail(data != NULL);
g_return_if_fail(sender != NULL);
- params = cmd_get_params(data, 4, &type, &arg, &portstr, &sizestr);
+ params = cmd_get_params(data, 4 | PARAM_FLAG_NOQUOTES,
+ &type, &arg, &portstr, &sizestr);
port = atoi(portstr);
size = atol(sizestr);
diff --git a/src/irc/dcc/dcc.c b/src/irc/dcc/dcc.c
index ae6fd586..4f418555 100644
--- a/src/irc/dcc/dcc.c
+++ b/src/irc/dcc/dcc.c
@@ -287,7 +287,8 @@ static void dcc_ctcp_msg(char *data, IRC_SERVER_REC *server, char *sender, char
g_return_if_fail(data != NULL);
g_return_if_fail(sender != NULL);
- params = cmd_get_params(data, 5, &type, &arg, &addrstr, &portstr, &sizestr);
+ params = cmd_get_params(data, 5 | PARAM_FLAG_NOQUOTES,
+ &type, &arg, &addrstr, &portstr, &sizestr);
if (sscanf(portstr, "%d", &port) != 1) port = 0;
if (sscanf(sizestr, "%lu", &size) != 1) size = 0;