コード例 #1
0
ファイル: m_svsmode.c プロジェクト: mindspeaker/oftc-hybrid
/*! \brief SVSMODE command handler (called by services)
 *
 * \param client_p Pointer to allocated Client struct with physical connection
 *                 to this server, i.e. with an open socket connected.
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = sender prefix
 *      - parv[1] = nickname
 *      - parv[2] = TS (or mode, depending on svs version)
 *      - parv[3] = mode (or services id if old svs version)
 *      - parv[4] = optional argument (services id)
 */
static void
ms_svsmode(struct Client *client_p, struct Client *source_p,
           int parc, char *parv[])
{
  struct Client *target_p = NULL;
  int what = MODE_ADD;
  unsigned int flag = 0, setflags = 0;
  char *m = NULL, *modes = NULL, *extarg = NULL;
  time_t ts = 0;

  if (!HasFlag(source_p, FLAGS_SERVICE))
    return;

  if ((parc >= 4) && ((*parv[3] == '+') || (*parv[3] == '-')))
  {
    ts     = atol(parv[2]);
    modes  = parv[3];
    extarg = (parc > 4) ? parv[4] : NULL;
  }
  else
  {
    modes  = parv[2];
    extarg = (parc > 3) ? parv[3] : NULL;
  }

  if ((target_p = find_person(client_p, parv[1])) == NULL)
    return;

  if (ts && (ts != target_p->tsinfo))
    return;

  setflags = target_p->umodes;

  for (m = modes; *m; ++m)
  {
    switch (*m)
    {
      case '+':
        what = MODE_ADD;
        break;

      case '-':
        what = MODE_DEL;
        break;

      case 'x':
        if (what == MODE_ADD && extarg)
          user_set_hostmask(target_p, extarg);

        break;

      case 'd':
        if (!EmptyString(extarg))
          strlcpy(target_p->svid, extarg, sizeof(target_p->svid));

        break;

      case 'o':
        if (what == MODE_DEL && HasUMode(target_p, UMODE_OPER))
        {
          ClearOper(target_p);
          Count.oper--;

          if (MyConnect(target_p))
          {
            dlink_node *dm = NULL;

            detach_conf(target_p, OPER_TYPE);
            ClrOFlag(target_p);
            DelUMode(target_p, ConfigFileEntry.oper_only_umodes);

            if ((dm = dlinkFindDelete(&oper_list, target_p)) != NULL)
              free_dlink_node(dm);
          }
        }

        break;

      case 'i':
        if (what == MODE_ADD && !HasUMode(target_p, UMODE_INVISIBLE))
        {
          AddUMode(target_p, UMODE_INVISIBLE);
          ++Count.invisi;
        }

        if (what == MODE_DEL && HasUMode(target_p, UMODE_INVISIBLE))
        {
          DelUMode(target_p, UMODE_INVISIBLE);
          --Count.invisi;
        }

        break;

      case ' ':
      case '\n':
      case '\r':
      case '\t':
        break;

      default:
        if ((flag = user_modes[(unsigned char) * m]))
          execute_callback(umode_cb, client_p, target_p, what, flag);

        break;
    }
  }

  if (extarg)
  {
    sendto_server(client_p, CAP_TS6, NOCAPS,
                  ":%s SVSMODE %s %lu %s %s", ID(source_p),
                  ID(target_p), (unsigned long)target_p->tsinfo, modes, extarg);
    sendto_server(client_p, NOCAPS, CAP_TS6,
                  ":%s SVSMODE %s %lu %s %s", source_p->name,
                  target_p->name, (unsigned long)target_p->tsinfo, modes, extarg);
  }
  else
  {
    sendto_server(client_p, CAP_TS6, NOCAPS,
                  ":%s SVSMODE %s %lu %s", ID(source_p),
                  ID(target_p), (unsigned long)target_p->tsinfo, modes);
    sendto_server(client_p, NOCAPS, CAP_TS6,
                  ":%s SVSMODE %s %lu %s", source_p->name,
                  target_p->name, (unsigned long)target_p->tsinfo, modes);
  }

  if (MyConnect(target_p) && (setflags != target_p->umodes))
  {
    char modebuf[IRCD_BUFSIZE];

    send_umode(target_p, target_p, setflags, 0xffffffff, modebuf);
  }
}
コード例 #2
0
ファイル: m_svsmode.c プロジェクト: nask0/ircd-hybrid
/*! \brief SVSMODE command handler
 *
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = command
 *      - parv[1] = nickname
 *      - parv[2] = TS
 *      - parv[3] = mode
 *      - parv[4] = optional argument (services account, vhost)
 */
static int
ms_svsmode(struct Client *source_p, int parc, char *parv[])
{
  const struct user_modes *tab = NULL;
  struct Client *target_p = NULL;
  int what = MODE_ADD;
  unsigned int setmodes = 0;
  const char *modes = NULL, *extarg = NULL;
  time_t ts = 0;

  if (!HasFlag(source_p, FLAGS_SERVICE))
    return 0;

  ts     = atol(parv[2]);
  modes  = parv[3];
  extarg = (parc > 4) ? parv[4] : NULL;

  if ((target_p = find_person(source_p, parv[1])) == NULL)
    return 0;

  if (ts && (ts != target_p->tsinfo))
    return 0;

  setmodes = target_p->umodes;

  for (const char *m = modes; *m; ++m)
  {
    switch (*m)
    {
      case '+':
        what = MODE_ADD;
        break;
      case '-':
        what = MODE_DEL;
        break;

      case 'd':
        if (!EmptyString(extarg))
          strlcpy(target_p->account, extarg, sizeof(target_p->account));
        break;

      case 'x':
        if (!EmptyString(extarg) && valid_hostname(extarg))
          user_set_hostmask(target_p, extarg, what);
        break;

      case 'o':
        if (what == MODE_DEL && HasUMode(target_p, UMODE_OPER))
        {
          ClearOper(target_p);
          --Count.oper;

          if (MyConnect(target_p))
          {
            dlink_node *node = NULL;

            detach_conf(target_p, CONF_OPER);
            ClrOFlag(target_p);
            DelUMode(target_p, ConfigGeneral.oper_only_umodes);

            if ((node = dlinkFindDelete(&oper_list, target_p)))
              free_dlink_node(node);
          }
        }

        break;

      case 'i':
        if (what == MODE_ADD && !HasUMode(target_p, UMODE_INVISIBLE))
        {
          AddUMode(target_p, UMODE_INVISIBLE);
          ++Count.invisi;
        }

        if (what == MODE_DEL && HasUMode(target_p, UMODE_INVISIBLE))
        {
          DelUMode(target_p, UMODE_INVISIBLE);
          --Count.invisi;
        }

        break;

      case 'S':  /* Only servers may set +S in a burst */
      case 'W':  /* Only servers may set +W in a burst */
        break;

      default:
        if ((tab = umode_map[(unsigned char)*m]))
        {
          if (what == MODE_ADD)
            AddUMode(target_p, tab->flag);
          else
            DelUMode(target_p, tab->flag);
        }

        break;
    }
  }

  if (extarg)
    sendto_server(source_p, 0, 0, ":%s SVSMODE %s %lu %s %s",
                  source_p->id,
                  target_p->id, (unsigned long)target_p->tsinfo, modes, extarg);
  else
    sendto_server(source_p, 0, 0, ":%s SVSMODE %s %lu %s",
                  source_p->id,
                  target_p->id, (unsigned long)target_p->tsinfo, modes);

  if (MyConnect(target_p) && (setmodes != target_p->umodes))
  {
    char modebuf[IRCD_BUFSIZE] = "";

    send_umode(target_p, target_p, setmodes, modebuf);
  }

  return 0;
}
コード例 #3
0
ファイル: m_mode.c プロジェクト: jmdh/ircd-hybrid
/* set_user_mode()
 *
 * added 15/10/91 By Darren Reed.
 * parv[0] - command
 * parv[1] - username to change mode for
 * parv[2] - modes to change
 */
static void
set_user_mode(struct Client *source_p, const int parc, char *parv[])
{
  const struct user_modes *tab = NULL;
  const unsigned int setmodes = source_p->umodes;
  const struct Client *target_p = NULL;
  int what = MODE_ADD, badmode = 0;

  if ((target_p = find_person(source_p, parv[1])) == NULL)
  {
    if (MyConnect(source_p))
      sendto_one_numeric(source_p, &me, ERR_NOSUCHCHANNEL, parv[1]);
    return;
  }

  if (source_p != target_p)
  {
     sendto_one_numeric(source_p, &me, ERR_USERSDONTMATCH);
     return;
  }

  if (parc < 3)
  {
    char buf[IRCD_BUFSIZE] = "";
    char *m = buf;

    *m++ = '+';
    for (tab = umode_tab; tab->c; ++tab)
      if (HasUMode(source_p, tab->flag))
        *m++ = tab->c;
    *m = '\0';

    sendto_one_numeric(source_p, &me, RPL_UMODEIS, buf);
    return;
  }

  /* Parse user mode change string */
  for (const char *m = parv[2]; *m; ++m)
  {
    switch (*m)
    {
      case '+':
        what = MODE_ADD;
        break;
      case '-':
        what = MODE_DEL;
        break;
      case 'o':
        if (what == MODE_ADD)
        {
          if (!MyConnect(source_p) && !HasUMode(source_p, UMODE_OPER))
          {
            ++Count.oper;
            SetOper(source_p);
          }
        }
        else
        {
          if (!HasUMode(source_p, UMODE_OPER))
            break;

          ClearOper(source_p);
          --Count.oper;

          if (MyConnect(source_p))
          {
            dlink_node *node = NULL;

            detach_conf(source_p, CONF_OPER);
            ClrOFlag(source_p);
            DelUMode(source_p, ConfigGeneral.oper_only_umodes);

            if ((node = dlinkFindDelete(&oper_list, source_p)))
              free_dlink_node(node);
          }
        }

        break;

      case 'S':  /* Only servers may set +S in a burst */
      case 'W':  /* Only servers may set +W in a burst */
      case 'r':  /* Only services may set +r */
      case 'x':  /* Only services may set +x */
        break;

      default:
        if ((tab = umode_map[(unsigned char)*m]))
        {
          if (MyConnect(source_p) && !HasUMode(source_p, UMODE_OPER) &&
              (ConfigGeneral.oper_only_umodes & tab->flag))
            badmode = 1;
          else
          {
            if (what == MODE_ADD)
              AddUMode(source_p, tab->flag);
            else
              DelUMode(source_p, tab->flag);
          }
        }
        else if (MyConnect(source_p))
          badmode = 1;

        break;
    }
  }

  if (badmode)
    sendto_one_numeric(source_p, &me, ERR_UMODEUNKNOWNFLAG);

  if (MyConnect(source_p) && HasUMode(source_p, UMODE_ADMIN) &&
      !HasOFlag(source_p, OPER_FLAG_ADMIN))
  {
    sendto_one_notice(source_p, &me, ":*** You have no admin flag;");
    DelUMode(source_p, UMODE_ADMIN);
  }

  if (!(setmodes & UMODE_INVISIBLE) && HasUMode(source_p, UMODE_INVISIBLE))
    ++Count.invisi;
  if ((setmodes & UMODE_INVISIBLE) && !HasUMode(source_p, UMODE_INVISIBLE))
    --Count.invisi;

  /*
   * Compare new modes with old modes and send string which will cause
   * servers to update correctly.
   */
  send_umode_out(source_p, setmodes);
}