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;
}
示例#3
0
文件: m_cap.c 项目: Adam-/ircd-hybrid
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;
}