static int cap_ls(struct Client *source_p, const char *caplist) { if (IsUnknown(source_p)) /* registration hasn't completed; suspend it... */ source_p->localClient->registration |= REG_NEED_CAP; return send_caplist(source_p, 0, 0, "LS"); /* send list of capabilities */ }
static int cap_req(struct Client *source_p, const char *caplist) { const char *cl = caplist; struct capabilities *cap = NULL; unsigned int set = 0, rem = 0; unsigned int cs = source_p->localClient->cap_client; /* capability set */ unsigned int as = source_p->localClient->cap_active; /* active set */ int neg = 0; if (IsUnknown(source_p)) /* registration hasn't completed; suspend it... */ source_p->localClient->registration |= REG_NEED_CAP; while (cl) { /* walk through the capabilities list... */ if (!(cap = find_cap(&cl, &neg)) /* look up capability... */ || (!neg && (cap->flags & CAPFL_PROHIBIT)) /* is it prohibited? */ || (neg && (cap->flags & CAPFL_STICKY))) { /* is it sticky? */ sendto_one(source_p, ":%s CAP %s NAK :%s", me.name, source_p->name[0] ? source_p->name : "*", caplist); return 0; /* can't complete requested op... */ } if (neg) { /* set or clear the capability... */ rem |= cap->cap; set &= ~cap->cap; cs &= ~cap->cap; if (!(cap->flags & CAPFL_PROTO)) as &= ~cap->cap; } else { rem &= ~cap->cap; set |= cap->cap; cs |= cap->cap; if (!(cap->flags & CAPFL_PROTO)) as |= cap->cap; } } /* Notify client of accepted changes and copy over results. */ send_caplist(source_p, set, rem, "ACK"); source_p->localClient->cap_client = cs; source_p->localClient->cap_active = as; return 0; }
static int cap_clear(struct Client *source_p, const char *caplist) { unsigned int cleared = 0; for (unsigned int ii = 0; ii < CAPAB_LIST_LEN; ++ii) { const struct capabilities *cap = &capab_list[ii]; /* Only clear active non-sticky capabilities. */ if (!(source_p->connection->cap_client & cap->cap) || (cap->flags & CAPFL_STICKY)) continue; cleared |= cap->cap; source_p->connection->cap_client &= ~cap->cap; if (!(cap->flags & CAPFL_PROTO)) source_p->connection->cap_active &= ~cap->cap; } return send_caplist(source_p, NULL, &cleared, "ACK"); }
static int cap_clear(struct Client *sptr, const char *caplist) { struct capabilities *cap; unsigned int ii; unsigned int cleared = 0; for (ii = 0; ii < CAPAB_LIST_LEN; ++ii) { cap = &capab_list[ii]; /* Only clear active non-sticky capabilities. */ if (!(sptr->localClient->cap_active & cap->cap) || (cap->flags & CAPFL_STICKY)) continue; cleared |= cap->cap; sptr->localClient->cap_client &= ~cap->cap; if (!(cap->flags & CAPFL_PROTO)) sptr->localClient->cap_active &= ~cap->cap; } return send_caplist(sptr, 0, cleared, "ACK"); }
static int cap_list(struct Client *source_p, const char *caplist) { /* Send the list of the client's capabilities */ return send_caplist(source_p, source_p->localClient->cap_client, 0, "LIST"); }
static int cap_list(struct Client *source_p, const char *caplist) { /* Send the list of the client's capabilities */ return send_caplist(source_p, &source_p->connection->cap_client, NULL, "LIST"); }