static int cap_ack(struct Client *source_p, const char *caplist) { const char *cl = caplist; struct capabilities *cap = NULL; int neg = 0; /* * Coming from the client, this generally indicates that the client * is using a new backwards-incompatible protocol feature. As such, * it does not require further response from the server. */ while (cl) { /* walk through the capabilities list... */ if (!(cap = find_cap(&cl, &neg)) || /* look up capability... */ (neg ? (source_p->localClient->cap_active & cap->cap) : !(source_p->localClient->cap_active & cap->cap))) /* uh... */ continue; if (neg) /* set or clear the active capability... */ source_p->localClient->cap_active &= ~cap->cap; else source_p->localClient->cap_active |= cap->cap; } return 0; }
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_ack(struct Client *source_p, const char *caplist) { const char *cl = caplist; struct capabilities *cap = NULL; int neg = 0; /* * Coming from the client, this generally indicates that the client * is using a new backwards-incompatible protocol feature. As such, * it does not require further response from the server. */ while (cl) { /* Walk through the capabilities list... */ if (!(cap = find_cap(&cl, &neg)) || /* Look up capability... */ (neg ? (source_p->connection->cap_client & cap->cap) : !(source_p->connection->cap_client & cap->cap))) /* uh... */ continue; /* Set or clear the active capability... */ if (neg) { if (cap->flags & CAPFL_STICKY) continue; /* but don't clear sticky capabilities */ source_p->connection->cap_active &= ~cap->cap; } else { if (cap->flags & CAPFL_PROHIBIT) continue; /* and don't set prohibited ones */ source_p->connection->cap_active |= cap->cap; } } return 0; }