#include "s_serv.h"
#include "s_user.h"
#include "send.h"
+#include "s_conf.h"
+#include "hash.h"
typedef int (*bqcmp)(const void *, const void *);
-static int m_cap(struct Client *, struct Client *, int, const char **);
+static int m_cap(struct MsgBuf *, struct Client *, struct Client *, int, const char **);
static int modinit(void);
struct Message cap_msgtab = {
- "CAP", 0, 0, 0, MFLG_SLOW,
+ "CAP", 0, 0, 0, 0,
{{m_cap, 2}, {m_cap, 2}, mg_ignore, mg_ignore, mg_ignore, {m_cap, 2}}
};
int namelen;
} clicap_list[] = {
_CLICAP("multi-prefix", CLICAP_MULTI_PREFIX, 0, 0, 0),
- _CLICAP("sasl", CLICAP_SASL, 0, 0, 0),
- _CLICAP("sasl-reauth", CLICAP_SASL_REAUTH, 0, CLICAP_SASL, 0),
+ _CLICAP("sasl", CLICAP_SASL, 0, 0, CLICAP_FLAGS_STICKY),
_CLICAP("account-notify", CLICAP_ACCOUNT_NOTIFY, 0, 0, 0),
_CLICAP("extended-join", CLICAP_EXTENDED_JOIN, 0, 0, 0),
_CLICAP("away-notify", CLICAP_AWAY_NOTIFY, 0, 0, 0),
_CLICAP("tls", CLICAP_TLS, 0, 0, 0),
+ _CLICAP("userhost-in-names", CLICAP_USERHOST_IN_NAMES, 0, 0, 0),
+ _CLICAP("cap-notify", CLICAP_CAP_NOTIFY, 0, 0, 0),
+ _CLICAP("chghost", CLICAP_CHGHOST, 0, 0, 0),
};
#define CLICAP_LIST_LEN (sizeof(clicap_list) / sizeof(struct clicap))
int curlen, mlen;
size_t i;
- mlen = rb_sprintf(buf, ":%s CAP %s %s",
+ mlen = sprintf(buf, ":%s CAP %s %s",
me.name,
EmptyString(source_p->name) ? "*" : source_p->name,
subcmd);
continue;
}
+ if (clicap_list[i].cap_serv == CLICAP_SASL)
+ {
+ struct Client *agent_p = NULL;
+
+ if (!ConfigFileEntry.sasl_service)
+ continue;
+
+ agent_p = find_named_client(ConfigFileEntry.sasl_service);
+ if (agent_p == NULL || !IsService(agent_p))
+ continue;
+ }
+
/* \r\n\0, possible "-~=", space, " *" */
if(buflen + clicap_list[i].namelen >= BUFSIZE - 10)
{
{
*p++ = '-';
buflen++;
-
- /* needs a client ack */
- if(clicap_list[i].cap_cli &&
- IsCapable(source_p, clicap_list[i].cap_cli))
- {
- *p++ = '~';
- buflen++;
- }
- }
- else
- {
- if(clicap_list[i].flags & CLICAP_FLAGS_STICKY)
- {
- *p++ = '=';
- buflen++;
- }
-
- /* if we're doing an LS, then we only send this if
- * they havent ack'd
- */
- if(clicap_list[i].cap_cli &&
- (!flags || !IsCapable(source_p, clicap_list[i].cap_cli)))
- {
- *p++ = '~';
- buflen++;
- }
}
- curlen = rb_sprintf(p, "%s ", clicap_list[i].name);
+ curlen = sprintf(p, "%s ", clicap_list[i].name);
p += curlen;
buflen += curlen;
}
if(source_p->name[0] && source_p->flags & FLAGS_SENTUSER)
{
- char buf[USERLEN+1];
- rb_strlcpy(buf, source_p->username, sizeof(buf));
- register_local_user(source_p, source_p, buf);
+ register_local_user(source_p, source_p);
}
}
if(EmptyString(arg))
return;
- buflen = rb_snprintf(buf, sizeof(buf), ":%s CAP %s ACK",
+ buflen = snprintf(buf, sizeof(buf), ":%s CAP %s ACK",
me.name, EmptyString(source_p->name) ? "*" : source_p->name);
pbuf[0][0] = '\0';
}
else
{
- if(cap->cap_required_serv && !(capadd & cap->cap_required_serv == cap->cap_required_serv || IsCapable(source_p, cap->required_serv)))
+ if(cap->cap_required_serv && !((capadd & cap->cap_required_serv) == cap->cap_required_serv || IsCapable(source_p, cap->cap_required_serv)))
{
finished = 0;
break;
}
- if(cap->flags & CLICAP_FLAGS_STICKY)
+ if (cap->cap_serv == CLICAP_SASL)
{
- strcat(pbuf[i], "=");
- plen++;
+ struct Client *agent_p = NULL;
+
+ if (!ConfigFileEntry.sasl_service)
+ {
+ finished = 0;
+ break;
+ }
+
+ agent_p = find_named_client(ConfigFileEntry.sasl_service);
+ if (agent_p == NULL || !IsService(agent_p))
+ {
+ finished = 0;
+ break;
+ }
}
capadd |= cap->cap_serv;
}
strcat(pbuf[i], cap->name);
- strcat(pbuf[i], " ");
- plen += (cap->namelen + 1);
+ if (!finished) {
+ strcat(pbuf[i], " ");
+ plen += (cap->namelen + 1);
+ }
}
if(!finished)
}
static int
-m_cap(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+m_cap(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
struct clicap_cmd *cmd;