Compare commits

..

10 Commits

Author SHA1 Message Date
Kevin Easton
eaf6456854 Improve efficiency of m_3cat() algorithm
Use exact memcpy() instead of repeated strcat().
2019-12-28 17:30:01 +11:00
Kevin Easton
4f63d48929 Remove duplicate global definitions
This fixes compiling with gcc-10.

Reported by ixz.
2019-12-28 17:20:30 +11:00
Kevin Easton
9fe7de361e Minor fixes and improvements to channel_stats()
Show total channel memory use for /CHANST -ALL (previously it just showed the size of a single channel struct).

Fix stray cyan-coloured [ for /CHANST -ALL.

Fix display of "Channel created" and "in memory", which were displayed the wrong way around.
2019-08-27 16:29:40 +10:00
Kevin Easton
960e2d8087 Reformat and simplify channel_stats() and make_channel() 2019-08-27 15:36:29 +10:00
Kevin Easton
ddfbec0b4b Remove queueing of wildcard CSETs and fix use-after-free with queued CSETs
A queued CSET is one that is set before the matching channel is joined.  The CSetList is allocated and linked to
the cset_queue list.

The use-after-free bug was caused because the CSetList wasn't removed from the cset_queue after it was attached
to a joined channel.  If the channel is parted, it eventually ages out of the Whowas-Chan-List and the CSetList
is freed, but there is now a dangling pointer to it in the cset_queue.  This is fixed by removing the CSetList
from the cset_queue when it is attached to a channel, so the net result of /CSET #chan ; /JOIN #chan is the same
as doing the reverse.

Queued wildcard CSETs never worked properly - the queued CSET with the wildcard name would end up attached to any
subsequent matching channel that was joined.  Channel names with wildcards in them are legal anyway, so the best
medium-term solution (pending a full redesign of the whole CSET command) is to just enforce that queued CSETs are
always literal channel names, not wildcards.
2019-08-03 01:09:21 +10:00
Kevin Easton
f714e3e951 Combine cset_variable_case1() and cset_variable_casedef() into cset_variable_range()
There's no point having two functions that two essentially the same thing.  Also implement
cset_variable_noargs() as a call to cset_variable_range().
2019-07-18 14:17:04 +10:00
Kevin Easton
e0ad103153 Simplify cset_variable_casedef()
This should make no functional change.
2019-07-17 16:29:53 +10:00
Kevin Easton
43ace65cb3 Simplifications to cset_variable()
Remove some unnecessary variables and reorder the code slightly. This should have no functional change.
2019-07-13 01:14:15 +10:00
Kevin Easton
e347375cb3 Very minor simplification/cleanup of is_channel() 2019-07-08 17:34:08 +10:00
Kevin Easton
b9803e69d1 Avoid reading an uninitialized byte in dgets()
This was caused by an off-by-one error in the case when a line exceeded the buffer size provided to
dgets().  Found with valgrind.
2019-06-27 17:37:35 +10:00
11 changed files with 208 additions and 328 deletions

View File

@@ -1,5 +1,11 @@
[Changes 1.2.2]
* Remove duplicate global definitions to fix compiling with gcc 10.
Reported by ixz. (caf)
* Remove queueing of wildcard CSETs and fix use-after-free with queued
CSETs. (caf)
* Bump MAXPARA (maximum protocol message arguments) to 20 as per EPIC5. (caf)
* Correctly handle a last argument prefixed with : for any protocol message,

View File

@@ -321,7 +321,7 @@ extern int cpu_saver;
extern struct sockaddr_foobar local_ip_address;
int BX_is_channel (char *);
int BX_is_channel (const char *);
void BX_irc_exit (int, char *, char *, ...);
void BX_beep_em (int);
void got_initial_version (char *);

View File

@@ -404,7 +404,7 @@ extern Function_ptr *global;
#define add_completion_type (*(int (*)(char *, int , enum completion ))global[ADD_COMPLETION_TYPE])
/* names.c */
#define is_channel (*(int (*)(char *))global[IS_CHANNEL])
#define is_channel (*(int (*)(const char *))global[IS_CHANNEL])
#define make_channel (*(char *(*)(char *))global[MAKE_CHANNEL])
#define is_chanop (*(int (*)(char *, char *))global[IS_CHANOP])
#define is_halfop (*(int (*)(char *, char *))global[IS_HALFOP])

View File

@@ -118,7 +118,6 @@ extern int doing_notice;
static void oper_password_received (char *, char *);
int no_hook_notify = 0;
int load_depth = -1;
extern char cx_function[];

View File

@@ -325,156 +325,58 @@ static void set_cset_var_value(CSetList *tmp, int var_index, char *value)
CSetList *check_cset_queue(char *channel, int add)
{
CSetList *c = NULL;
int found = 0;
if (!strchr(channel, '*') && !(c = (CSetList *)find_in_list((List **)&cset_queue, channel, 0)))
CSetList *c = (CSetList *)find_in_list((List **)&cset_queue, channel, 0);
if (!c && add)
{
if (!add)
{
for (c = cset_queue; c; c = c->next)
if (!my_stricmp(c->channel, channel) || wild_match(c->channel, channel))
return c;
return NULL;
}
c = create_csets_for_channel(channel);
add_to_list((List **)&cset_queue, (List *)c);
found++;
}
if (c)
return c;
if (add && !found)
{
for (c = cset_queue; c; c = c->next)
if (!my_stricmp(c->channel, channel))
return c;
c = create_csets_for_channel(channel);
c->next = cset_queue;
cset_queue = c;
return c;
}
return NULL;
}
static inline void cset_variable_case1(char *channel, int var_index, char *args)
return c;
}
static inline void cset_variable_range(char *channel, int cnt, int var_index, char *args)
{
ChannelList *chan = NULL;
int tmp = 0;
int count = 0;
/*
* implement a queue for channels that don't exist... later...
* go home if user doesn't have any channels.
*/
if (current_window->server != -1)
{
for (chan = get_server_channels(current_window->server); chan; chan = chan->next)
{
tmp = var_index;
if (wild_match(channel, chan->channel))
{
set_cset_var_value(chan->csets, tmp, args);
count++;
}
}
}
/* no channel match. lets check the queue */
/* if (!count)*/
{
CSetList *c = NULL;
if (!count)
check_cset_queue(channel, 1);
for (c = cset_queue; c; c = c->next)
{
tmp = var_index;
if (!my_stricmp(channel, c->channel) || wild_match(channel, c->channel))
{
set_cset_var_value(c, tmp, args);
count++;
}
}
if (!count)
say("CSET_VARIABLE: No match in cset queue for %s", channel);
}
}
static inline void cset_variable_casedef(char *channel, int cnt, int var_index, char *args)
{
ChannelList *chan = NULL;
int tmp, tmp2;
int i;
int count = 0;
if (current_window->server != -1)
{
for (chan = get_server_channels(current_window->server); chan; chan = chan->next)
{
tmp = var_index;
tmp2 = cnt;
if (wild_match(channel, chan->channel))
{
for (tmp2 += tmp; tmp < tmp2; tmp++)
set_cset_var_value(chan->csets, tmp, empty_string);
for (i = var_index; i < var_index + cnt; i++)
set_cset_var_value(chan->csets, i, args);
count++;
}
}
}
/* if (!count) */
{
CSetList *c = NULL;
if (!count)
check_cset_queue(channel, 1);
for (c = cset_queue; c; c = c->next)
{
tmp = var_index;
tmp2 = cnt;
if (!my_stricmp(channel, c->channel) || wild_match(channel, c->channel))
{
for (tmp2 +=tmp; tmp < tmp2; tmp++)
set_cset_var_value(c, tmp, empty_string);
for (i = var_index; i < var_index + cnt; i++)
{
set_cset_var_value(c, i, args);
count++;
}
}
}
if (!count)
say("CSET_VARIABLE: No match in cset queue for %s", channel);
return;
}
}
static inline void cset_variable_noargs(char *channel)
{
int var_index = 0;
ChannelList *chan = NULL;
int count = 0;
if (current_window->server != -1)
{
for (chan = get_server_channels(current_window->server); chan; chan = chan->next)
{
if (wild_match(channel, chan->channel))
{
for (var_index = 0; var_index < NUMBER_OF_CSETS; var_index++)
set_cset_var_value(chan->csets, var_index, empty_string);
count++;
}
}
}
/* if (!count) */
{
CSetList *c = NULL;
if (!count)
check_cset_queue(channel, 1);
for (c = cset_queue; c; c = c->next)
{
if (!wild_match(channel, c->channel))
continue;
for (var_index = 0; var_index < NUMBER_OF_CSETS; var_index++)
set_cset_var_value(c, var_index, empty_string);
count++;
}
if (!count)
say("CSET_VARIABLE: No match in cset queue for %s", channel ? channel : empty_string);
return;
}
/* Show the current value of every cset */
cset_variable_range(channel, NUMBER_OF_CSETS, 0, "");
}
char *set_cset(char *var, ChannelList *chan, char *value)
@@ -568,49 +470,45 @@ int var_index, cnt = 0;
BUILT_IN_COMMAND(cset_variable)
{
char *var, *channel = NULL;
int no_args = 1, cnt, var_index, hook = 1;
int cnt, var_index;
if (from_server != -1 && current_window->server != -1)
{
if (args && *args && (is_channel(args) || *args == '*'))
channel = next_arg(args, &args);
else
channel = get_current_channel_by_refnum(0);
}
else if (args && *args && (is_channel(args) || *args == '*'))
channel = next_arg(args, &args);
if (!channel)
return;
if ((var = next_arg(args, &args)) != NULL)
var = next_arg(args, &args);
if (!var)
{
cset_variable_noargs(channel);
return;
}
if (*var == '-')
{
var++;
args = NULL;
}
var_index = find_cset_variable(cset_array, var, &cnt);
if (hook)
if (cnt == 0)
{
switch (cnt)
{
case 0:
say("No such variable \"%s\"", var);
return;
case 1:
cset_variable_case1(channel, var_index, args);
return;
default:
say("%s is ambiguous", var);
cset_variable_casedef(channel, cnt, var_index, args);
return;
}
if (cnt > 1)
{
say("Variable \"%s\" is ambiguous", var);
args = "";
}
}
if (no_args)
cset_variable_noargs(channel);
cset_variable_range(channel, cnt, var_index, args);
}
CSetList *create_csets_for_channel(char *channel)
@@ -624,14 +522,9 @@ CSetList *create_csets_for_channel(char *channel)
ircpanic("Variable [%d] (%s) is out of order.", i, cset_array[i].name);
#endif
if (check_cset_queue(channel, 0))
{
if ((tmp = (CSetList *)find_in_list((List **)&cset_queue, channel, 0)))
if ((tmp = (CSetList *)remove_from_list((List **)&cset_queue, channel)))
return tmp;
for (tmp = cset_queue; tmp; tmp = tmp->next)
if (!my_stricmp(tmp->channel, channel) || wild_match(tmp->channel, channel))
return tmp;
}
tmp = (CSetList *) new_malloc(sizeof(CSetList));
/* use default settings. */
tmp->set_aop = get_int_var(AOP_VAR);

View File

@@ -274,27 +274,27 @@ char *BX_m_s3cat_s (char **one, const char *maybe, const char *ifthere)
char *BX_m_3cat(char **one, const char *two, const char *three)
{
int len = 0;
size_t one_len = 0, two_len = 0, three_len = 0;
char *str;
if (*one)
len = strlen(*one);
one_len = strlen(*one);
if (two)
len += strlen(two);
two_len = strlen(two);
if (three)
len += strlen(three);
len += 1;
three_len = strlen(three);
str = (char *)new_malloc(len);
str = new_malloc(one_len + two_len + three_len + 1);
if (*one)
strcpy(str, *one);
memcpy(str, *one, one_len);
if (two)
strcat(str, two);
memcpy(str + one_len, two, two_len);
if (three)
strcat(str, three);
memcpy(str + one_len + two_len, three, three_len);
str[one_len + two_len + three_len] = 0;
new_free(one);
return ((*one = str));
return (*one = str);
}
/* upper()

View File

@@ -484,7 +484,6 @@ BUILT_IN_COMMAND(channel_stats)
{
ChannelList *new = NULL;
char *channel = NULL;
WhowasChanList *new1 = NULL;
int numircops = 0;
int usershere = 0;
int usersaway = 0;
@@ -493,51 +492,33 @@ int chanunop = 0;
char *ircops = NULL;
int server = -1;
int max_hops = 0;
NickList *l;
unsigned long nick_mem = 0,
ban_mem = 0;
unsigned long nick_mem = 0;
unsigned long ban_mem = 0;
BanList *b;
if (args && *args)
{
channel = next_arg(args, &args);
if (my_strnicmp(channel, "-ALL", strlen(channel)))
{
if (!(channel = make_channel(channel)))
return;
if (!(new = prepare_command(&server, channel, PC_SILENT)))
if ((channel && !(new1 = check_whowas_chan_buffer(channel, -1, 0))))
return;
}
else
{
if (!my_strnicmp(channel, "-ALL", strlen(channel)))
{
/* Accumulate stats from all joined channels on server */
int stats_ops= 0, stats_dops = 0, stats_bans = 0, stats_unbans = 0;
int stats_topics = 0, stats_kicks = 0, stats_pubs = 0, stats_parts = 0;
int stats_signoffs = 0, stats_joins = 0;
int total_nicks = 0, max_nicks = 0, total_bans = 0, max_bans = 0;
int stats_sops = 0, stats_sdops = 0, stats_sbans = 0, stats_sunbans = 0;
NickList *l;
BanList *b;
unsigned long chan_mem = 0;
channel = NULL;
if (from_server != -1)
{
for (new = get_server_channels(from_server); new; new = new->next)
{
if (!channel)
malloc_strcpy(&channel, new->channel);
else
{
malloc_strcat(&channel, ",");
malloc_strcat(&channel, new->channel);
}
m_s3cat(&channel, ",", new->channel);
for (l = next_nicklist(new, NULL); l; l = next_nicklist(new, l))
{
if (nick_isaway(l))
@@ -583,50 +564,59 @@ BanList *b;
stats_sunbans += new->stats_sunbans;
}
}
if (!ircops)
malloc_strcat(&ircops, empty_string);
if (do_hook(CHANNEL_STATS_LIST, "%s %s %s %lu %lu %lu %lu %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %d %s",
if (do_hook(CHANNEL_STATS_LIST,
"%s %s %s %lu %lu %lu %lu %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %d %s",
channel, empty_string, empty_string,
nick_mem + chan_mem + ban_mem, nick_mem,
(unsigned long)sizeof(ChannelList),ban_mem,
chan_mem, ban_mem,
stats_ops, stats_dops, stats_bans, stats_unbans,
stats_topics, stats_kicks, stats_pubs, stats_parts,
stats_signoffs, stats_joins, total_bans, max_bans,
stats_sops, stats_sdops, stats_sbans, stats_sunbans,
usershere, usersaway, chanops, chanunop, total_nicks, max_nicks,
numircops, max_hops, ircops))
numircops, max_hops, ircops ? ircops : ""))
{
put_it("%s", convert_output_format("$G %CInformation for channels %K: %W$0", "%s", channel));
put_it("%s", convert_output_format(" MEM usage%K:%w Total%K:%w %c$0 bytes %K[%cNicks $1 b Chan $2 b Bans $3 b%K]", "%d %d %d %d", (int)(nick_mem+chan_mem+ban_mem), (int)nick_mem, (int)sizeof(ChannelList), (int)ban_mem));
put_it("%s", convert_output_format(" MEM usage%K:%w Total%K:%w %c$0 bytes %K[%cNicks $1 b Chan $2 b Bans $3 b%K]", "%d %d %d %d", (int)(nick_mem + chan_mem + ban_mem), (int)nick_mem, (int)chan_mem, (int)ban_mem));
put_it("%s", convert_output_format("Ops %K[%W$[-5]0%K]%w De-Ops %K[%W$[-5]1%K]%w Bans %K[%W$[-5]2%K]%w Unbans %K[%W$[-5]3%K]%w", "%u %u %u %u", stats_ops, stats_dops, stats_bans, stats_unbans));
put_it("%s", convert_output_format("Topics %K[%W$[-5]0%K]%w Kicks %K[%W$[-5]1%K]%w Publics %K[%W$[-5]2%K]%w Parts %K[%W$[-5]3%K]%w", "%u %u %u %u", stats_topics, stats_kicks, stats_pubs, stats_parts));
put_it("%s", convert_output_format("Signoffs %C[%W$[-5]0%K]%w Joins %K[%W$[-5]1%K]%w TotalBans %K[%W$[-5]2%K]%w MaxBans %K[%W$[-5]3%K]%w", "%u %u %u %u", stats_signoffs, stats_joins, total_bans, max_bans));
put_it("%s", convert_output_format("Signoffs %K[%W$[-5]0%K]%w Joins %K[%W$[-5]1%K]%w TotalBans %K[%W$[-5]2%K]%w MaxBans %K[%W$[-5]3%K]%w", "%u %u %u %u", stats_signoffs, stats_joins, total_bans, max_bans));
put_it("%s", convert_output_format("ServOps %K[%W$[-5]0%K]%w ServDeop %K[%W$[-5]1%K]%w ServBans %K[%W$[-5]2%K]%w ServUB %K[%W$[-5]3%K]%w", "%u %u %u %u", stats_sops, stats_sdops,stats_sbans, stats_sunbans));
put_it("%s", convert_output_format("Users Here %K[%W$[-5]0%K]%w Users Away %K[%W$[-5]1%K]%w Opped %K[%W$[-5]2%K]%w Unopped %K[%W$[-5]3%K]%w", "%u %u %u %u", usershere, usersaway, chanops, chanunop));
put_it("%s", convert_output_format("TotalNicks %K[%W$[-5]0%K]%w MaxNicks %K[%W$[-5]1%K]%w ServerHops %K[%W$[-5]2%K]%w", "%d %d %d", total_nicks,max_nicks, max_hops));
put_it("%s", convert_output_format("IRCops %K[%W$[3]0%K]%w$1-", "%d %s", numircops, ircops));
put_it("%s", convert_output_format("IRCops %K[%W$[3]0%K]%w$1-", "%d %s", numircops, ircops ? ircops : ""));
}
new_free(&ircops);
new_free(&channel);
return;
}
}
else
channel = make_channel(channel);
new = prepare_command(&server, channel, PC_SILENT);
if (!new)
{
if (!(new = prepare_command(&server, channel, PC_SILENT)))
if ((channel && !(new1 = check_whowas_chan_buffer(channel, -1, 0))))
if (channel)
{
WhowasChanList *whowas_chan = check_whowas_chan_buffer(channel, -1, 0);
if (!whowas_chan)
{
bitchsay("No stats available for %s", channel);
return;
}
if (!new && new1)
new = new1->channellist;
if (!new)
new = whowas_chan->channellist;
}
else
{
bitchsay("Try joining a channel first");
return;
}
if (new)
{
}
for (l = next_nicklist(new, NULL); l; l = next_nicklist(new, l))
{
nick_mem += sizeof(NickList);
@@ -650,11 +640,10 @@ put_it("%s", convert_output_format("IRCops %K[%W$[3]0%K]%w$1-", "%d %s", num
}
for (b = new->bans; b; b = b->next)
ban_mem += sizeof(BanList);
}
if (!ircops)
malloc_strcat(&ircops, empty_string);
if (do_hook(CHANNEL_STATS_LIST, "%s %s %s %ld %ld %ld %ld %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %d %s",
new->channel, my_ctime(new->channel_create.tv_sec), convert_time(now-new->join_time.tv_sec),
if (do_hook(CHANNEL_STATS_LIST,
"%s %s %s %ld %ld %ld %ld %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %d %s",
new->channel, my_ctime(new->channel_create.tv_sec), convert_time(time_since(&new->join_time)),
nick_mem+sizeof(ChannelList)+ban_mem, nick_mem,
(unsigned long)sizeof(ChannelList),ban_mem,
new->stats_ops, new->stats_dops, new->stats_bans, new->stats_unbans,
@@ -662,11 +651,10 @@ put_it("%s", convert_output_format("IRCops %K[%W$[3]0%K]%w$1-", "%d %s", num
new->stats_signoffs, new->stats_joins, new->totalbans, new->maxbans,
new->stats_sops, new->stats_sdops,new->stats_sbans, new->stats_sunbans,
usershere, usersaway, chanops, chanunop,new->totalnicks,new->maxnicks,
numircops, max_hops, ircops))
numircops, max_hops, ircops ? ircops : ""))
{
put_it("%s", convert_output_format("$G %CInformation for channel %K: %W$0", "%s", new->channel));
put_it("%s", convert_output_format("$G %CChannel created %K: %W$0 $1 $2 $3%n in memory %W$4-", "%s %s", convert_time(now-new->channel_create.tv_sec), my_ctime(new->join_time.tv_sec)));
put_it("%s", convert_output_format("$G %CChannel created %K: %W$4-%n in memory %W$0 $1 $2 $3", "%s %s", convert_time(time_since(&new->join_time)), my_ctime(new->channel_create.tv_sec)));
put_it("%s", convert_output_format(" MEM usage%K:%w Total%K:%w %c$0 bytes %K[%cNicks $1 b Chan $2 b Bans $3 b%K]", "%d %d %d %d", (int)(nick_mem+sizeof(ChannelList)+ban_mem), (int)nick_mem, (int)sizeof(ChannelList), (int)ban_mem));
put_it("%s", convert_output_format("Ops %K[%W$[-5]0%K]%w De-Ops %K[%W$[-5]1%K]%w Bans %K[%W$[-5]2%K]%w Unbans %K[%W$[-5]3%K]%w", "%u %u %u %u", new->stats_ops, new->stats_dops, new->stats_bans, new->stats_unbans));
put_it("%s", convert_output_format("Topics %K[%W$[-5]0%K]%w Kicks %K[%W$[-5]1%K]%w Publics %K[%W$[-5]2%K]%w Parts %K[%W$[-5]3%K]%w", "%u %u %u %u", new->stats_topics, new->stats_kicks, new->stats_pubs, new->stats_parts));
@@ -674,7 +662,7 @@ put_it("%s", convert_output_format("Signoffs %K[%W$[-5]0%K]%w Joins %K[%
put_it("%s", convert_output_format("ServOps %K[%W$[-5]0%K]%w ServDeop %K[%W$[-5]1%K]%w ServBans %K[%W$[-5]2%K]%w ServUB %K[%W$[-5]3%K]%w", "%u %u %u %u", new->stats_sops, new->stats_sdops,new->stats_sbans, new->stats_sunbans));
put_it("%s", convert_output_format("Users Here %K[%W$[-5]0%K]%w Users Away %K[%W$[-5]1%K]%w Opped %K[%W$[-5]2%K]%w Unopped %K[%W$[-5]3%K]%w", "%u %u %u %u", usershere, usersaway, chanops, chanunop));
put_it("%s", convert_output_format("TotalNicks %K[%W$[-5]0%K]%w MaxNicks %K[%W$[-5]1%K]%w ServerHops %K[%W$[-5]2%K]%w", "%d %d %d", new->totalnicks,new->maxnicks, max_hops));
put_it("%s", convert_output_format("IRCops %K[%W$[3]0%K]%w$1-", "%d %s", numircops, ircops));
put_it("%s", convert_output_format("IRCops %K[%W$[3]0%K]%w$1-", "%d %s", numircops, ircops ? ircops : ""));
put_it("%s", convert_output_format(" %CThere is %R$0%C limit and limit checking is %R$1-", "%s %s", new->limit ? ltoa(new->limit): "no", new->tog_limit?"Enabled":"Disabled"));
put_it("%s", convert_output_format(" %CIdle user check is %K[%R$0-%K]", "%s", new->check_idle?"Enabled":"Disabled"));
@@ -682,7 +670,6 @@ put_it("%s", convert_output_format(" %CIdle user check is %K[%R$0-%K]", "%s", n
/* wtf is do_scan in the channel struct */
}
new_free(&ircops);
}
void update_stats(int what, NickList *nick, ChannelList *chan, int splitter)
@@ -4677,13 +4664,14 @@ ChannelList *chan = NULL;
char *BX_make_channel (char *chan)
{
static char buffer[IRCD_BUFFER_SIZE+1];
*buffer = 0;
if (!chan)
return NULL;
if (*chan != '#' && *chan != '&' && *chan != '+' && *chan != '!')
snprintf(buffer, IRCD_BUFFER_SIZE-2, "#%s", chan);
snprintf(buffer, sizeof buffer, "#%s", chan);
else
strlcpy(buffer, chan, sizeof buffer);
return buffer;
}

View File

@@ -77,7 +77,7 @@ extern int BX_read_sockets();
extern int identd;
extern int doing_notice;
int (*serv_open_func) (int, unsigned long, int);
extern int (*serv_open_func) (int, unsigned long, int);
extern int (*serv_output_func) (int, int, char *, int);
extern int (*serv_input_func) (int, char *, int, int, int);
extern int (*serv_close_func) (int, unsigned long, int);

View File

@@ -349,19 +349,16 @@ int BX_dgets (char *str, int des, int buffer, int buffersize, void *ssl_fd)
/*
* Slurp up the data that is available into 'str'.
*/
while (ioe->read_pos < ioe->write_pos)
while (ioe->read_pos < ioe->write_pos && cnt < (buffersize - 1))
{
if (((str[cnt] = ioe->buffer[ioe->read_pos++])) == '\n')
break;
cnt++;
if (cnt >= buffersize-1)
if ((str[cnt++] = ioe->buffer[ioe->read_pos++]) == '\n')
break;
}
/*
* Terminate it
*/
str[cnt + 1] = 0;
str[cnt] = 0;
/*
* If we end in a newline, then all is well.
@@ -369,8 +366,8 @@ int BX_dgets (char *str, int des, int buffer, int buffersize, void *ssl_fd)
* The caller then would need to do a strlen() to get
* the amount of data.
*/
if (str[cnt] == '\n')
return cnt;
if (cnt > 0 && str[cnt - 1] == '\n')
return cnt - 1;
else
return 0;
}

View File

@@ -66,7 +66,6 @@ void show_server_map (void);
int stats_k_grep (char **);
void who_handlekill (char *, char *, char *);
void handle_tracekill (int, char *, char *, char *);
int no_hook_notify;
extern AJoinList *ajoin_list;
void remove_from_server_list (int);

View File

@@ -285,15 +285,13 @@ int annoy_kicks(int list_type, char *to, char *from, char *ptr, NickList *nick)
* begins with MULTI_CHANNEL and has no '*', or STRING_CHANNEL, then its a
* channel
*/
int BX_is_channel(char *to)
int BX_is_channel(const char *to)
{
if (!to || !*to)
return 0;
return ( (to) && ((*to == MULTI_CHANNEL)
|| (*to == STRING_CHANNEL)
|| (*to == ID_CHANNEL)
|| (*to == LOCAL_CHANNEL)));
return to &&
(*to == MULTI_CHANNEL ||
*to == STRING_CHANNEL ||
*to == ID_CHANNEL ||
*to == LOCAL_CHANNEL);
}