Migrate capability negotiation code to new dynamic capability management API.
This needs a lot of testing, obviously.
This commit is contained in:
parent
ec3a9055f2
commit
346fba9252
7 changed files with 175 additions and 309 deletions
|
@ -28,6 +28,7 @@
|
|||
#define INCLUDED_serv_h
|
||||
|
||||
#include "config.h"
|
||||
#include "capability.h"
|
||||
|
||||
/*
|
||||
* The number of seconds between calls to try_connections(). Fiddle with
|
||||
|
@ -47,40 +48,35 @@ struct server_conf;
|
|||
struct Channel;
|
||||
|
||||
/* Capabilities */
|
||||
struct Capability
|
||||
{
|
||||
const char *name; /* name of capability */
|
||||
unsigned int cap; /* mask value */
|
||||
unsigned int required; /* 1 if required, 0 if not */
|
||||
};
|
||||
extern struct CapabilityIndex *serv_capindex;
|
||||
|
||||
#define CAP_CAP 0x00001 /* received a CAP to begin with */
|
||||
#define CAP_QS 0x00002 /* Can handle quit storm removal */
|
||||
#define CAP_EX 0x00004 /* Can do channel +e exemptions */
|
||||
#define CAP_CHW 0x00008 /* Can do channel wall @# */
|
||||
#define CAP_IE 0x00010 /* Can do invite exceptions */
|
||||
#define CAP_KLN 0x00040 /* Can do KLINE message */
|
||||
#define CAP_ZIP 0x00100 /* Can do ZIPlinks */
|
||||
#define CAP_KNOCK 0x00400 /* supports KNOCK */
|
||||
#define CAP_TB 0x00800 /* supports TBURST */
|
||||
#define CAP_UNKLN 0x01000 /* supports remote unkline */
|
||||
#define CAP_CLUSTER 0x02000 /* supports cluster stuff */
|
||||
#define CAP_ENCAP 0x04000 /* supports ENCAP */
|
||||
#define CAP_TS6 0x08000 /* supports TS6 or above */
|
||||
#define CAP_SERVICE 0x10000
|
||||
#define CAP_RSFNC 0x20000 /* rserv FNC */
|
||||
#define CAP_SAVE 0x40000 /* supports SAVE (nick collision FNC) */
|
||||
#define CAP_EUID 0x80000 /* supports EUID (ext UID + nonencap CHGHOST) */
|
||||
#define CAP_EOPMOD 0x100000 /* supports EOPMOD (ext +z + ext topic) */
|
||||
#define CAP_BAN 0x200000 /* supports propagated bans */
|
||||
#define CAP_MLOCK 0x400000 /* supports MLOCK messages */
|
||||
/*
|
||||
* XXX: this is kind of ugly, but this allows us to have backwards
|
||||
* API-compatibility.
|
||||
*/
|
||||
extern unsigned int CAP_CAP; /* received a CAP to begin with */
|
||||
extern unsigned int CAP_QS; /* Can handle quit storm removal */
|
||||
extern unsigned int CAP_EX; /* Can do channel +e exemptions */
|
||||
extern unsigned int CAP_CHW; /* Can do channel wall @# */
|
||||
extern unsigned int CAP_IE; /* Can do invite exceptions */
|
||||
extern unsigned int CAP_KLN; /* Can do KLINE message */
|
||||
extern unsigned int CAP_ZIP; /* Can do ZIPlinks */
|
||||
extern unsigned int CAP_KNOCK; /* supports KNOCK */
|
||||
extern unsigned int CAP_TB; /* supports TBURST */
|
||||
extern unsigned int CAP_UNKLN; /* supports remote unkline */
|
||||
extern unsigned int CAP_CLUSTER; /* supports cluster stuff */
|
||||
extern unsigned int CAP_ENCAP; /* supports ENCAP */
|
||||
extern unsigned int CAP_TS6; /* supports TS6 or above */
|
||||
extern unsigned int CAP_SERVICE; /* supports services */
|
||||
extern unsigned int CAP_RSFNC; /* rserv FNC */
|
||||
extern unsigned int CAP_SAVE; /* supports SAVE (nick collision FNC) */
|
||||
extern unsigned int CAP_EUID; /* supports EUID (ext UID + nonencap CHGHOST) */
|
||||
extern unsigned int CAP_EOPMOD; /* supports EOPMOD (ext +z + ext topic) */
|
||||
extern unsigned int CAP_BAN; /* supports propagated bans */
|
||||
extern unsigned int CAP_MLOCK; /* supports MLOCK messages */
|
||||
|
||||
#define CAP_MASK (CAP_QS | CAP_EX | CAP_CHW | \
|
||||
CAP_IE | CAP_KLN | CAP_SERVICE |\
|
||||
CAP_CLUSTER | CAP_ENCAP | \
|
||||
CAP_ZIP | CAP_KNOCK | CAP_UNKLN | \
|
||||
CAP_RSFNC | CAP_SAVE | CAP_EUID | CAP_EOPMOD | \
|
||||
CAP_BAN | CAP_MLOCK)
|
||||
/* XXX: added for backwards compatibility. --nenolod */
|
||||
#define CAP_MASK (capability_index_mask(serv_capindex) & ~(CAP_TS6 | CAP_CAP))
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
#define CAP_ZIP_SUPPORTED CAP_ZIP
|
||||
|
@ -103,8 +99,6 @@ struct Capability
|
|||
* because all servers that we talk to already do TS, and the kludged
|
||||
* extra argument to "PASS" takes care of checking that. -orabidoo
|
||||
*/
|
||||
extern struct Capability captab[];
|
||||
|
||||
extern int MaxClientCount; /* GLOBAL - highest number of clients */
|
||||
extern int MaxConnectionCount; /* GLOBAL - highest number of connections */
|
||||
|
||||
|
@ -117,11 +111,12 @@ extern int refresh_user_links;
|
|||
#define HUNTED_ISME 0 /* if this server should execute the command */
|
||||
#define HUNTED_PASS 1 /* if message passed onwards successfully */
|
||||
|
||||
extern void init_builtin_capabs(void);
|
||||
|
||||
extern int hunt_server(struct Client *client_pt,
|
||||
struct Client *source_pt,
|
||||
const char *command, int server, int parc, const char **parv);
|
||||
extern void send_capabilities(struct Client *, int);
|
||||
extern void send_capabilities(struct Client *, unsigned int);
|
||||
extern const char *show_capabilities(struct Client *client);
|
||||
extern void try_connections(void *unused);
|
||||
|
||||
|
|
|
@ -109,6 +109,7 @@ mr_server(struct Client *client_p, struct Client *source_p, int parc, const char
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef NOTYET
|
||||
/* check to ensure any "required" caps are set. --nenolod */
|
||||
for (cap = captab; cap->name; cap++)
|
||||
{
|
||||
|
@ -125,6 +126,7 @@ mr_server(struct Client *client_p, struct Client *source_p, int parc, const char
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Now we just have to call check_server and everything should be
|
||||
* check for us... -A1kmm. */
|
||||
|
|
|
@ -56,7 +56,6 @@ DECLARE_MODULE_AV1(capab, NULL, NULL, capab_clist, NULL, NULL, "$Revision: 1295
|
|||
static int
|
||||
mr_capab(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
|
||||
{
|
||||
struct Capability *cap;
|
||||
int i;
|
||||
char *p;
|
||||
char *s;
|
||||
|
@ -84,16 +83,7 @@ mr_capab(struct Client *client_p, struct Client *source_p, int parc, const char
|
|||
{
|
||||
char *t = LOCAL_COPY(parv[i]);
|
||||
for (s = rb_strtok_r(t, " ", &p); s; s = rb_strtok_r(NULL, " ", &p))
|
||||
{
|
||||
for (cap = captab; cap->name; cap++)
|
||||
{
|
||||
if(!irccmp(cap->name, s))
|
||||
{
|
||||
client_p->localClient->caps |= cap->cap;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
client_p->localClient->caps |= capability_get(serv_capindex, s);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -103,7 +93,6 @@ static int
|
|||
me_gcap(struct Client *client_p, struct Client *source_p,
|
||||
int parc, const char *parv[])
|
||||
{
|
||||
struct Capability *cap;
|
||||
char *t = LOCAL_COPY(parv[1]);
|
||||
char *s;
|
||||
char *p;
|
||||
|
@ -121,16 +110,7 @@ me_gcap(struct Client *client_p, struct Client *source_p,
|
|||
source_p->serv->fullcaps = rb_strdup(parv[1]);
|
||||
|
||||
for (s = rb_strtok_r(t, " ", &p); s; s = rb_strtok_r(NULL, " ", &p))
|
||||
{
|
||||
for (cap = captab; cap->name; cap++)
|
||||
{
|
||||
if(!irccmp(cap->name, s))
|
||||
{
|
||||
source_p->serv->caps |= cap->cap;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
source_p->serv->caps |= capability_get(serv_capindex, s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
268
src/channel.c
268
src/channel.c
|
@ -50,16 +50,6 @@ static rb_bh *ban_heap;
|
|||
static rb_bh *topic_heap;
|
||||
static rb_bh *member_heap;
|
||||
|
||||
static int channel_capabs[] = { CAP_EX, CAP_IE,
|
||||
CAP_SERVICE,
|
||||
CAP_TS6
|
||||
};
|
||||
|
||||
#define NCHCAPS (sizeof(channel_capabs)/sizeof(int))
|
||||
#define NCHCAP_COMBOS (1 << NCHCAPS)
|
||||
|
||||
static struct ChCapCombo chcap_combos[NCHCAP_COMBOS];
|
||||
|
||||
static void free_topic(struct Channel *chptr);
|
||||
|
||||
static int h_can_join;
|
||||
|
@ -1198,102 +1188,6 @@ channel_modes(struct Channel *chptr, struct Client *client_p)
|
|||
return final;
|
||||
}
|
||||
|
||||
/* Now lets do some stuff to keep track of what combinations of
|
||||
* servers exist...
|
||||
* Note that the number of combinations doubles each time you add
|
||||
* something to this list. Each one is only quick if no servers use that
|
||||
* combination, but if the numbers get too high here MODE will get too
|
||||
* slow. I suggest if you get more than 7 here, you consider getting rid
|
||||
* of some and merging or something. If it wasn't for irc+cs we would
|
||||
* probably not even need to bother about most of these, but unfortunately
|
||||
* we do. -A1kmm
|
||||
*/
|
||||
|
||||
/* void init_chcap_usage_counts(void)
|
||||
*
|
||||
* Inputs - none
|
||||
* Output - none
|
||||
* Side-effects - Initialises the usage counts to zero. Fills in the
|
||||
* chcap_yes and chcap_no combination tables.
|
||||
*/
|
||||
void
|
||||
init_chcap_usage_counts(void)
|
||||
{
|
||||
unsigned long m, c, y, n;
|
||||
|
||||
memset(chcap_combos, 0, sizeof(chcap_combos));
|
||||
|
||||
/* For every possible combination */
|
||||
for (m = 0; m < NCHCAP_COMBOS; m++)
|
||||
{
|
||||
/* Check each capab */
|
||||
for (c = y = n = 0; c < NCHCAPS; c++)
|
||||
{
|
||||
if((m & (1 << c)) == 0)
|
||||
n |= channel_capabs[c];
|
||||
else
|
||||
y |= channel_capabs[c];
|
||||
}
|
||||
chcap_combos[m].cap_yes = y;
|
||||
chcap_combos[m].cap_no = n;
|
||||
}
|
||||
}
|
||||
|
||||
/* void set_chcap_usage_counts(struct Client *serv_p)
|
||||
* Input: serv_p; The client whose capabs to register.
|
||||
* Output: none
|
||||
* Side-effects: Increments the usage counts for the correct capab
|
||||
* combination.
|
||||
*/
|
||||
void
|
||||
set_chcap_usage_counts(struct Client *serv_p)
|
||||
{
|
||||
int n;
|
||||
|
||||
for (n = 0; n < NCHCAP_COMBOS; n++)
|
||||
{
|
||||
if(IsCapable(serv_p, chcap_combos[n].cap_yes) &&
|
||||
NotCapable(serv_p, chcap_combos[n].cap_no))
|
||||
{
|
||||
chcap_combos[n].count++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* This should be impossible -A1kmm. */
|
||||
s_assert(0);
|
||||
}
|
||||
|
||||
/* void set_chcap_usage_counts(struct Client *serv_p)
|
||||
*
|
||||
* Inputs - serv_p; The client whose capabs to register.
|
||||
* Output - none
|
||||
* Side-effects - Decrements the usage counts for the correct capab
|
||||
* combination.
|
||||
*/
|
||||
void
|
||||
unset_chcap_usage_counts(struct Client *serv_p)
|
||||
{
|
||||
int n;
|
||||
|
||||
for (n = 0; n < NCHCAP_COMBOS; n++)
|
||||
{
|
||||
if(IsCapable(serv_p, chcap_combos[n].cap_yes) &&
|
||||
NotCapable(serv_p, chcap_combos[n].cap_no))
|
||||
{
|
||||
/* Hopefully capabs can't change dynamically or anything... */
|
||||
s_assert(chcap_combos[n].count > 0);
|
||||
|
||||
if(chcap_combos[n].count > 0)
|
||||
chcap_combos[n].count--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* This should be impossible -A1kmm. */
|
||||
s_assert(0);
|
||||
}
|
||||
|
||||
/* void send_cap_mode_changes(struct Client *client_p,
|
||||
* struct Client *source_p,
|
||||
* struct Channel *chptr, int cap, int nocap)
|
||||
|
@ -1305,6 +1199,9 @@ unset_chcap_usage_counts(struct Client *serv_p)
|
|||
* Reverted back to my original design, except that we now keep a count
|
||||
* of the number of servers which each combination as an optimisation, so
|
||||
* the capabs combinations which are not needed are not worked out. -A1kmm
|
||||
*
|
||||
* Removed most code here because we don't need to be compatible with ircd
|
||||
* 2.8.21+CSr and stuff. --nenolod
|
||||
*/
|
||||
void
|
||||
send_cap_mode_changes(struct Client *client_p, struct Client *source_p,
|
||||
|
@ -1315,106 +1212,97 @@ send_cap_mode_changes(struct Client *client_p, struct Client *source_p,
|
|||
int i, mbl, pbl, nc, mc, preflen, len;
|
||||
char *pbuf;
|
||||
const char *arg;
|
||||
int dir;
|
||||
int j;
|
||||
int cap;
|
||||
int nocap;
|
||||
int dir;
|
||||
int arglen;
|
||||
|
||||
/* Now send to servers... */
|
||||
for (j = 0; j < NCHCAP_COMBOS; j++)
|
||||
mc = 0;
|
||||
nc = 0;
|
||||
pbl = 0;
|
||||
parabuf[0] = 0;
|
||||
pbuf = parabuf;
|
||||
dir = MODE_QUERY;
|
||||
|
||||
mbl = preflen = rb_sprintf(modebuf, ":%s TMODE %ld %s ",
|
||||
use_id(source_p), (long) chptr->channelts,
|
||||
chptr->chname);
|
||||
|
||||
/* loop the list of - modes we have */
|
||||
for (i = 0; i < mode_count; i++)
|
||||
{
|
||||
if(chcap_combos[j].count == 0)
|
||||
/* if they dont support the cap we need, or they do support a cap they
|
||||
* cant have, then dont add it to the modebuf.. that way they wont see
|
||||
* the mode
|
||||
*/
|
||||
if (mode_changes[i].letter == 0)
|
||||
continue;
|
||||
|
||||
mc = 0;
|
||||
nc = 0;
|
||||
pbl = 0;
|
||||
parabuf[0] = 0;
|
||||
pbuf = parabuf;
|
||||
dir = MODE_QUERY;
|
||||
cap = mode_changes[i].caps;
|
||||
nocap = mode_changes[i].nocaps;
|
||||
|
||||
cap = chcap_combos[j].cap_yes;
|
||||
nocap = chcap_combos[j].cap_no;
|
||||
if (!EmptyString(mode_changes[i].id))
|
||||
arg = mode_changes[i].id;
|
||||
else
|
||||
arg = mode_changes[i].arg;
|
||||
|
||||
mbl = preflen = rb_sprintf(modebuf, ":%s TMODE %ld %s ",
|
||||
use_id(source_p), (long) chptr->channelts,
|
||||
chptr->chname);
|
||||
|
||||
/* loop the list of - modes we have */
|
||||
for (i = 0; i < mode_count; i++)
|
||||
if(arg)
|
||||
{
|
||||
/* if they dont support the cap we need, or they do support a cap they
|
||||
* cant have, then dont add it to the modebuf.. that way they wont see
|
||||
* the mode
|
||||
*/
|
||||
if((mode_changes[i].letter == 0) ||
|
||||
((cap & mode_changes[i].caps) != mode_changes[i].caps)
|
||||
|| ((nocap & mode_changes[i].nocaps) != mode_changes[i].nocaps))
|
||||
arglen = strlen(arg);
|
||||
|
||||
/* dont even think about it! --fl */
|
||||
if(arglen > MODEBUFLEN - 5)
|
||||
continue;
|
||||
|
||||
if(!EmptyString(mode_changes[i].id))
|
||||
arg = mode_changes[i].id;
|
||||
else
|
||||
arg = mode_changes[i].arg;
|
||||
|
||||
if(arg)
|
||||
{
|
||||
arglen = strlen(arg);
|
||||
|
||||
/* dont even think about it! --fl */
|
||||
if(arglen > MODEBUFLEN - 5)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if we're creeping past the buf size, we need to send it and make
|
||||
* another line for the other modes
|
||||
* XXX - this could give away server topology with uids being
|
||||
* different lengths, but not much we can do, except possibly break
|
||||
* them as if they were the longest of the nick or uid at all times,
|
||||
* which even then won't work as we don't always know the uid -A1kmm.
|
||||
*/
|
||||
if(arg && ((mc == MAXMODEPARAMSSERV) ||
|
||||
((mbl + pbl + arglen + 4) > (BUFSIZE - 3))))
|
||||
{
|
||||
if(nc != 0)
|
||||
sendto_server(client_p, chptr, cap, nocap,
|
||||
"%s %s", modebuf, parabuf);
|
||||
nc = 0;
|
||||
mc = 0;
|
||||
|
||||
mbl = preflen;
|
||||
pbl = 0;
|
||||
pbuf = parabuf;
|
||||
parabuf[0] = 0;
|
||||
dir = MODE_QUERY;
|
||||
}
|
||||
|
||||
if(dir != mode_changes[i].dir)
|
||||
{
|
||||
modebuf[mbl++] = (mode_changes[i].dir == MODE_ADD) ? '+' : '-';
|
||||
dir = mode_changes[i].dir;
|
||||
}
|
||||
|
||||
modebuf[mbl++] = mode_changes[i].letter;
|
||||
modebuf[mbl] = 0;
|
||||
nc++;
|
||||
|
||||
if(arg != NULL)
|
||||
{
|
||||
len = rb_sprintf(pbuf, "%s ", arg);
|
||||
pbuf += len;
|
||||
pbl += len;
|
||||
mc++;
|
||||
}
|
||||
}
|
||||
|
||||
if(pbl && parabuf[pbl - 1] == ' ')
|
||||
parabuf[pbl - 1] = 0;
|
||||
/* if we're creeping past the buf size, we need to send it and make
|
||||
* another line for the other modes
|
||||
* XXX - this could give away server topology with uids being
|
||||
* different lengths, but not much we can do, except possibly break
|
||||
* them as if they were the longest of the nick or uid at all times,
|
||||
* which even then won't work as we don't always know the uid -A1kmm.
|
||||
*/
|
||||
if(arg && ((mc == MAXMODEPARAMSSERV) ||
|
||||
((mbl + pbl + arglen + 4) > (BUFSIZE - 3))))
|
||||
{
|
||||
if(nc != 0)
|
||||
sendto_server(client_p, chptr, cap, nocap,
|
||||
"%s %s", modebuf, parabuf);
|
||||
nc = 0;
|
||||
mc = 0;
|
||||
|
||||
if(nc != 0)
|
||||
sendto_server(client_p, chptr, cap, nocap, "%s %s", modebuf, parabuf);
|
||||
mbl = preflen;
|
||||
pbl = 0;
|
||||
pbuf = parabuf;
|
||||
parabuf[0] = 0;
|
||||
dir = MODE_QUERY;
|
||||
}
|
||||
|
||||
if(dir != mode_changes[i].dir)
|
||||
{
|
||||
modebuf[mbl++] = (mode_changes[i].dir == MODE_ADD) ? '+' : '-';
|
||||
dir = mode_changes[i].dir;
|
||||
}
|
||||
|
||||
modebuf[mbl++] = mode_changes[i].letter;
|
||||
modebuf[mbl] = 0;
|
||||
nc++;
|
||||
|
||||
if(arg != NULL)
|
||||
{
|
||||
len = rb_sprintf(pbuf, "%s ", arg);
|
||||
pbuf += len;
|
||||
pbl += len;
|
||||
mc++;
|
||||
}
|
||||
}
|
||||
|
||||
if(pbl && parabuf[pbl - 1] == ' ')
|
||||
parabuf[pbl - 1] = 0;
|
||||
|
||||
if(nc != 0)
|
||||
sendto_server(client_p, chptr, cap, nocap, "%s %s", modebuf, parabuf);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1326,7 +1326,6 @@ exit_local_server(struct Client *client_p, struct Client *source_p, struct Clien
|
|||
rb_dlinkDelete(&source_p->localClient->tnode, &serv_list);
|
||||
rb_dlinkFindDestroy(source_p, &global_serv_list);
|
||||
|
||||
unset_chcap_usage_counts(source_p);
|
||||
sendk = source_p->localClient->sendK;
|
||||
recvk = source_p->localClient->receiveK;
|
||||
|
||||
|
|
10
src/ircd.c
10
src/ircd.c
|
@ -112,7 +112,7 @@ int zlib_ok = 1;
|
|||
int testing_conf = 0;
|
||||
time_t startup_time;
|
||||
|
||||
int default_server_capabs = CAP_MASK;
|
||||
int default_server_capabs;
|
||||
|
||||
int splitmode;
|
||||
int splitchecking;
|
||||
|
@ -584,9 +584,6 @@ main(int argc, char *argv[])
|
|||
memset(&AdminInfo, 0, sizeof(AdminInfo));
|
||||
memset(&ServerStats, 0, sizeof(struct ServerStatistics));
|
||||
|
||||
/* Initialise the channel capability usage counts... */
|
||||
init_chcap_usage_counts();
|
||||
|
||||
if(printVersion)
|
||||
{
|
||||
printf("ircd: version %s(%s)\n", ircd_version, serno);
|
||||
|
@ -597,8 +594,6 @@ main(int argc, char *argv[])
|
|||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
setup_signals();
|
||||
|
||||
if (testing_conf)
|
||||
|
@ -637,6 +632,9 @@ main(int argc, char *argv[])
|
|||
|
||||
seed_random(NULL);
|
||||
|
||||
init_builtin_capabs();
|
||||
default_server_capabs = CAP_MASK;
|
||||
|
||||
init_main_logfile();
|
||||
newconf_init();
|
||||
init_s_conf();
|
||||
|
|
108
src/s_serv.c
108
src/s_serv.c
|
@ -54,6 +54,7 @@
|
|||
#include "msg.h"
|
||||
#include "reject.h"
|
||||
#include "sslproc.h"
|
||||
#include "capability.h"
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
#define INADDR_NONE ((unsigned int) 0xffffffff)
|
||||
|
@ -70,28 +71,56 @@ static char buf[BUFSIZE];
|
|||
* because all servers that we talk to already do TS, and the kludged
|
||||
* extra argument to "PASS" takes care of checking that. -orabidoo
|
||||
*/
|
||||
struct Capability captab[] = {
|
||||
/* name cap */
|
||||
{ "QS", CAP_QS },
|
||||
{ "EX", CAP_EX },
|
||||
{ "CHW", CAP_CHW},
|
||||
{ "IE", CAP_IE},
|
||||
{ "KLN", CAP_KLN},
|
||||
{ "KNOCK", CAP_KNOCK},
|
||||
{ "ZIP", CAP_ZIP},
|
||||
{ "TB", CAP_TB},
|
||||
{ "UNKLN", CAP_UNKLN},
|
||||
{ "CLUSTER", CAP_CLUSTER},
|
||||
{ "ENCAP", CAP_ENCAP },
|
||||
{ "SERVICES", CAP_SERVICE },
|
||||
{ "RSFNC", CAP_RSFNC },
|
||||
{ "SAVE", CAP_SAVE },
|
||||
{ "EUID", CAP_EUID },
|
||||
{ "EOPMOD", CAP_EOPMOD },
|
||||
{ "BAN", CAP_BAN },
|
||||
{ "MLOCK", CAP_MLOCK },
|
||||
{0, 0}
|
||||
};
|
||||
struct CapabilityIndex *serv_capindex = NULL;
|
||||
|
||||
unsigned int CAP_CAP;
|
||||
unsigned int CAP_QS;
|
||||
unsigned int CAP_EX;
|
||||
unsigned int CAP_CHW;
|
||||
unsigned int CAP_IE;
|
||||
unsigned int CAP_KLN;
|
||||
unsigned int CAP_ZIP;
|
||||
unsigned int CAP_KNOCK;
|
||||
unsigned int CAP_TB;
|
||||
unsigned int CAP_UNKLN;
|
||||
unsigned int CAP_CLUSTER;
|
||||
unsigned int CAP_ENCAP;
|
||||
unsigned int CAP_TS6;
|
||||
unsigned int CAP_SERVICE;
|
||||
unsigned int CAP_RSFNC;
|
||||
unsigned int CAP_SAVE;
|
||||
unsigned int CAP_EUID;
|
||||
unsigned int CAP_EOPMOD;
|
||||
unsigned int CAP_BAN;
|
||||
unsigned int CAP_MLOCK;
|
||||
|
||||
/*
|
||||
* initialize our builtin capability table. --nenolod
|
||||
*/
|
||||
void
|
||||
init_builtin_capabs(void)
|
||||
{
|
||||
serv_capindex = capability_index_create();
|
||||
|
||||
CAP_QS = capability_put(serv_capindex, "QS");
|
||||
CAP_EX = capability_put(serv_capindex, "EX");
|
||||
CAP_CHW = capability_put(serv_capindex, "CHW");
|
||||
CAP_IE = capability_put(serv_capindex, "IE");
|
||||
CAP_KLN = capability_put(serv_capindex, "KLN");
|
||||
CAP_KNOCK = capability_put(serv_capindex, "KNOCK");
|
||||
CAP_ZIP = capability_put(serv_capindex, "ZIP");
|
||||
CAP_TB = capability_put(serv_capindex, "TB");
|
||||
CAP_UNKLN = capability_put(serv_capindex, "UNKLN");
|
||||
CAP_CLUSTER = capability_put(serv_capindex, "CLUSTER");
|
||||
CAP_ENCAP = capability_put(serv_capindex, "ENCAP");
|
||||
CAP_SERVICE = capability_put(serv_capindex, "SERVICES");
|
||||
CAP_RSFNC = capability_put(serv_capindex, "RSFNC");
|
||||
CAP_SAVE = capability_put(serv_capindex, "SAVE");
|
||||
CAP_EUID = capability_put(serv_capindex, "EUID");
|
||||
CAP_EOPMOD = capability_put(serv_capindex, "EOPMOD");
|
||||
CAP_BAN = capability_put(serv_capindex, "BAN");
|
||||
CAP_MLOCK = capability_put(serv_capindex, "MLOCK");
|
||||
}
|
||||
|
||||
static CNCB serv_connect_callback;
|
||||
static CNCB serv_connect_ssl_callback;
|
||||
|
@ -380,28 +409,9 @@ check_server(const char *name, struct Client *client_p)
|
|||
*
|
||||
*/
|
||||
void
|
||||
send_capabilities(struct Client *client_p, int cap_can_send)
|
||||
send_capabilities(struct Client *client_p, unsigned int cap_can_send)
|
||||
{
|
||||
struct Capability *cap;
|
||||
char msgbuf[BUFSIZE];
|
||||
char *t;
|
||||
int tl;
|
||||
|
||||
t = msgbuf;
|
||||
|
||||
for (cap = captab; cap->name; ++cap)
|
||||
{
|
||||
if(cap->cap & cap_can_send)
|
||||
{
|
||||
tl = rb_sprintf(t, "%s ", cap->name);
|
||||
t += tl;
|
||||
}
|
||||
}
|
||||
|
||||
t--;
|
||||
*t = '\0';
|
||||
|
||||
sendto_one(client_p, "CAPAB :%s", msgbuf);
|
||||
sendto_one(client_p, "CAPAB :%s", capability_index_list(serv_capindex, cap_can_send));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -693,7 +703,8 @@ const char *
|
|||
show_capabilities(struct Client *target_p)
|
||||
{
|
||||
static char msgbuf[BUFSIZE];
|
||||
struct Capability *cap;
|
||||
|
||||
*msgbuf = '\0';
|
||||
|
||||
if(has_id(target_p))
|
||||
rb_strlcpy(msgbuf, " TS6", sizeof(msgbuf));
|
||||
|
@ -704,11 +715,7 @@ show_capabilities(struct Client *target_p)
|
|||
if(!IsServer(target_p) || !target_p->serv->caps) /* short circuit if no caps */
|
||||
return msgbuf + 1;
|
||||
|
||||
for (cap = captab; cap->cap; ++cap)
|
||||
{
|
||||
if(cap->cap & target_p->serv->caps)
|
||||
rb_snprintf_append(msgbuf, sizeof(msgbuf), " %s", cap->name);
|
||||
}
|
||||
rb_strlcat(msgbuf, capability_index_list(serv_capindex, target_p->serv->caps), sizeof(msgbuf));
|
||||
|
||||
return msgbuf + 1;
|
||||
}
|
||||
|
@ -804,9 +811,6 @@ server_estab(struct Client *client_p)
|
|||
|
||||
SetServer(client_p);
|
||||
|
||||
/* Update the capability combination usage counts */
|
||||
set_chcap_usage_counts(client_p);
|
||||
|
||||
rb_dlinkAdd(client_p, &client_p->lnode, &me.serv->servers);
|
||||
rb_dlinkMoveNode(&client_p->localClient->tnode, &unknown_list, &serv_list);
|
||||
rb_dlinkAddTailAlloc(client_p, &global_serv_list);
|
||||
|
|
Loading…
Reference in a new issue