mirror of
https://github.com/osmarks/ngircd.git
synced 2024-12-13 02:10:27 +00:00
"multi-prefix" capability 1/2: implement complete CAP infrastructure
Now ngIRCd is able to handle "CAP LS", "CAP REQ", "CAP LIST", and "CAP CLEAR" commands. "multi-prefix" can be set/unset, but has no functionality - yet!
This commit is contained in:
parent
f0a9dbe3ad
commit
1d7e99531a
@ -20,6 +20,8 @@
|
|||||||
#define CLIENT_CAP_PENDING 1 /* Capability negotiation pending */
|
#define CLIENT_CAP_PENDING 1 /* Capability negotiation pending */
|
||||||
#define CLIENT_CAP_SUPPORTED 2 /* Client supports IRC capabilities */
|
#define CLIENT_CAP_SUPPORTED 2 /* Client supports IRC capabilities */
|
||||||
|
|
||||||
|
#define CLIENT_CAP_MULTI_PREFIX 4 /* multi-prefix */
|
||||||
|
|
||||||
GLOBAL int Client_Cap PARAMS((CLIENT *Client));
|
GLOBAL int Client_Cap PARAMS((CLIENT *Client));
|
||||||
|
|
||||||
GLOBAL void Client_CapSet PARAMS((CLIENT *Client, int Cap));
|
GLOBAL void Client_CapSet PARAMS((CLIENT *Client, int Cap));
|
||||||
|
@ -42,6 +42,8 @@ bool Handle_CAP_END PARAMS((CLIENT *Client));
|
|||||||
|
|
||||||
void Set_CAP_Negotiation PARAMS((CLIENT *Client));
|
void Set_CAP_Negotiation PARAMS((CLIENT *Client));
|
||||||
|
|
||||||
|
int Parse_CAP PARAMS((int Capabilities, char *Args));
|
||||||
|
char *Get_CAP_String PARAMS((int Capabilities));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler for the IRCv3 "CAP" command.
|
* Handler for the IRCv3 "CAP" command.
|
||||||
@ -101,7 +103,9 @@ Handle_CAP_LS(CLIENT *Client, UNUSED char *Arg)
|
|||||||
|
|
||||||
Set_CAP_Negotiation(Client);
|
Set_CAP_Negotiation(Client);
|
||||||
|
|
||||||
return IRC_WriteStrClient(Client, "CAP %s LS :", Client_ID(Client));
|
return IRC_WriteStrClient(Client,
|
||||||
|
"CAP %s LS :multi-prefix",
|
||||||
|
Client_ID(Client));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -116,7 +120,8 @@ Handle_CAP_LIST(CLIENT *Client, UNUSED char *Arg)
|
|||||||
{
|
{
|
||||||
assert(Client != NULL);
|
assert(Client != NULL);
|
||||||
|
|
||||||
return IRC_WriteStrClient(Client, "CAP %s LIST :", Client_ID(Client));
|
return IRC_WriteStrClient(Client, "CAP %s LIST :%s", Client_ID(Client),
|
||||||
|
Get_CAP_String(Client_Cap(Client)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -129,13 +134,22 @@ Handle_CAP_LIST(CLIENT *Client, UNUSED char *Arg)
|
|||||||
bool
|
bool
|
||||||
Handle_CAP_REQ(CLIENT *Client, char *Arg)
|
Handle_CAP_REQ(CLIENT *Client, char *Arg)
|
||||||
{
|
{
|
||||||
|
int new_cap;
|
||||||
|
|
||||||
assert(Client != NULL);
|
assert(Client != NULL);
|
||||||
assert(Arg != NULL);
|
assert(Arg != NULL);
|
||||||
|
|
||||||
Set_CAP_Negotiation(Client);
|
Set_CAP_Negotiation(Client);
|
||||||
|
|
||||||
|
new_cap = Parse_CAP(Client_Cap(Client), Arg);
|
||||||
|
|
||||||
|
if (new_cap < 0)
|
||||||
return IRC_WriteStrClient(Client, "CAP %s NAK :%s",
|
return IRC_WriteStrClient(Client, "CAP %s NAK :%s",
|
||||||
Client_ID(Client), Arg);
|
Client_ID(Client), Arg);
|
||||||
|
|
||||||
|
Client_CapSet(Client, new_cap);
|
||||||
|
return IRC_WriteStrClient(Client, "CAP %s ACK :%s",
|
||||||
|
Client_ID(Client), Arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -163,9 +177,16 @@ Handle_CAP_ACK(CLIENT *Client, char *Arg)
|
|||||||
bool
|
bool
|
||||||
Handle_CAP_CLEAR(CLIENT *Client)
|
Handle_CAP_CLEAR(CLIENT *Client)
|
||||||
{
|
{
|
||||||
|
int cap_old;
|
||||||
|
|
||||||
assert(Client != NULL);
|
assert(Client != NULL);
|
||||||
|
|
||||||
return IRC_WriteStrClient(Client, "CAP %s ACK :", Client_ID(Client));
|
cap_old = Client_Cap(Client);
|
||||||
|
if (cap_old & CLIENT_CAP_MULTI_PREFIX)
|
||||||
|
Client_CapDel(Client, CLIENT_CAP_MULTI_PREFIX);
|
||||||
|
|
||||||
|
return IRC_WriteStrClient(Client, "CAP %s ACK :%s", Client_ID(Client),
|
||||||
|
Get_CAP_String(cap_old));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -207,4 +228,64 @@ Set_CAP_Negotiation(CLIENT *Client)
|
|||||||
Client_CapAdd(Client, CLIENT_CAP_SUPPORTED);
|
Client_CapAdd(Client, CLIENT_CAP_SUPPORTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse capability string and return numeric flag value.
|
||||||
|
*
|
||||||
|
* @param Args The string containing space-separated capability names.
|
||||||
|
* @return Changed capability flags or 0 on error.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
Parse_CAP(int Capabilities, char *Args)
|
||||||
|
{
|
||||||
|
static char tmp[COMMAND_LEN];
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
assert(Args != NULL);
|
||||||
|
|
||||||
|
strlcpy(tmp, Args, sizeof(tmp));
|
||||||
|
|
||||||
|
ptr = strtok(tmp, " ");
|
||||||
|
while (ptr) {
|
||||||
|
if (*ptr == '-') {
|
||||||
|
/* drop capabilities */
|
||||||
|
ptr++;
|
||||||
|
if (strcmp(ptr, "multi-prefix") == 0)
|
||||||
|
Capabilities &= ~CLIENT_CAP_MULTI_PREFIX;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
/* request capabilities */
|
||||||
|
if (strcmp(ptr, "multi-prefix") == 0)
|
||||||
|
Capabilities |= CLIENT_CAP_MULTI_PREFIX;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ptr = strtok(NULL, " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Capabilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return textual representation of capability flags.
|
||||||
|
*
|
||||||
|
* Please note: this function returns a pointer to a global buffer and
|
||||||
|
* therefore isn't thread safe!
|
||||||
|
*
|
||||||
|
* @param Capabilities Capability flags (bitmask).
|
||||||
|
* @return Pointer to textual representation.
|
||||||
|
*/
|
||||||
|
char
|
||||||
|
*Get_CAP_String(int Capabilities)
|
||||||
|
{
|
||||||
|
static char txt[COMMAND_LEN];
|
||||||
|
|
||||||
|
txt[0] = '\0';
|
||||||
|
|
||||||
|
if (Capabilities & CLIENT_CAP_MULTI_PREFIX)
|
||||||
|
strlcat(txt, "multi-prefix ", sizeof(txt));
|
||||||
|
|
||||||
|
return txt;
|
||||||
|
}
|
||||||
|
|
||||||
/* -eof- */
|
/* -eof- */
|
||||||
|
Loading…
Reference in New Issue
Block a user