Example #1
0
void relay_private_notice(struct Client* sptr, const char* name, const char* text)
{
  struct Client* acptr;
  assert(0 != sptr);
  assert(0 != name);
  assert(0 != text);

  if (0 == (acptr = FindUser(name)))
    return;
  if (IsOnlyreg(acptr) && !IsRegnick(sptr)) {
	  send_reply(sptr, RPL_MSGONLYREG, cli_name(acptr));
	  return;
  }

  if (!IsChannelService(acptr))
  {
    if (check_target_limit(sptr, acptr, cli_name(acptr), 0))
    {
      return;
    }
    if (is_silenced(sptr, acptr))
    {
      send_reply(sptr, ERR_SILENCED, cli_name(acptr));
      return;
    }
  }
    
  /*
   * deliver the message
   */
  if (MyUser(acptr))
    add_target(acptr, sptr);

  sendcmdto_one(sptr, CMD_NOTICE, acptr, "%C :%s", acptr, text);
}
Example #2
0
/*
 * m_wallvoices - local generic message handler
 */
int m_wallvoices(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  struct Channel *chptr;

  assert(0 != cptr);
  assert(cptr == sptr);

  ClrFlag(sptr, FLAG_TS8);

  if (parc < 2 || EmptyString(parv[1]))
    return send_reply(sptr, ERR_NORECIPIENT, "WALLVOICES");

  if (parc < 3 || EmptyString(parv[parc - 1]))
    return send_reply(sptr, ERR_NOTEXTTOSEND);

  if (IsChannelName(parv[1]) && (chptr = FindChannel(parv[1]))) {
    if (client_can_send_to_channel(sptr, chptr, 0)) {
      if ((chptr->mode.mode & MODE_NOPRIVMSGS) &&
          check_target_limit(sptr, chptr, chptr->chname, 0))
        return 0;
      RevealDelayedJoinIfNeeded(sptr, chptr);
      sendcmdto_channel_butone(sptr, CMD_WALLVOICES, chptr, cptr,
			       SKIP_DEAF | SKIP_BURST | SKIP_NONVOICES, 
			       "%H :+ %s", chptr, parv[parc - 1]);
    }
    else
      send_reply(sptr, ERR_CANNOTSENDTOCHAN, parv[1]);
  }
  else
    send_reply(sptr, ERR_NOSUCHCHANNEL, parv[1]);

  return 0;
}
Example #3
0
/** Handle a WALLVOICES message from a local client.
 *
 * \a parv has the following elements:
 * \li \a parv[1] is the name of the channel to which to send
 * \li \a parv[\a parc - 1] is the message to send
 *
 * See @ref m_functions for discussion of the arguments.
 * @param[in] cptr Client that sent us the message.
 * @param[in] sptr Original source of message.
 * @param[in] parc Number of arguments.
 * @param[in] parv Argument vector.
 */
int m_wallvoices(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  struct Channel *chptr;
  const char *ch;

  assert(0 != cptr);
  assert(cptr == sptr);

  if (parc < 2 || EmptyString(parv[1]))
    return send_reply(sptr, ERR_NORECIPIENT, "WALLVOICES");

  if (parc < 3 || EmptyString(parv[parc - 1]))
    return send_reply(sptr, ERR_NOTEXTTOSEND);

  if (IsChannelName(parv[1]) && (chptr = FindChannel(parv[1]))) {
    if (client_can_send_to_channel(sptr, chptr, 0) && !(chptr->mode.mode & MODE_NONOTICE)) {
      if ((chptr->mode.mode & MODE_NOPRIVMSGS) &&
          check_target_limit(sptr, chptr, chptr->chname, 0))
        return 0;

#if 0
      /* +cC checks */
      if (chptr->mode.mode & MODE_NOCOLOUR)
        for (ch=parv[parc - 1];*ch;ch++)
          if (*ch==2 || *ch==3 || *ch==22 || *ch==27 || *ch==31) {
            return 0;
          }

      if ((chptr->mode.mode & MODE_NOCTCP) && ircd_strncmp(parv[parc - 1],"\001ACTION ",8))
        for (ch=parv[parc - 1];*ch;)
          if (*ch++==1) {
            return 0;
          }
#endif
      RevealDelayedJoinIfNeeded(sptr, chptr);
      sendcmdto_channel(sptr, CMD_WALLVOICES, chptr, cptr,
                        SKIP_DEAF | SKIP_BURST | SKIP_NONVOICES,
                        "%H :+ %s", chptr, parv[parc - 1]);
    }
    else
      send_reply(sptr, ERR_CANNOTSENDTOCHAN, parv[1]);
  }
  else
    send_reply(sptr, ERR_NOSUCHCHANNEL, parv[1]);

  return 0;
}
Example #4
0
void relay_channel_notice(struct Client* sptr, const char* name, const char* text)
{
  struct Channel* chptr;
  assert(0 != sptr);
  assert(0 != name);
  assert(0 != text);

  if (0 == (chptr = FindChannel(name)))
    return;
  /*
   * This first: Almost never a server/service
   */
  if (!client_can_send_to_channel(sptr, chptr))
    return;

  if ((chptr->mode.mode & MODE_NOPRIVMSGS) &&
      check_target_limit(sptr, chptr, chptr->chname, 0))
    return;  

  sendcmdto_channel_butone(sptr, CMD_NOTICE, chptr, cli_from(sptr),
			   SKIP_DEAF | SKIP_BURST, "%H :%s", chptr, text);
}
/** Handle a JOIN message from a client connection.
 * See @ref m_functions for discussion of the arguments.
 * @param[in] cptr Client that sent us the message.
 * @param[in] sptr Original source of message.
 * @param[in] parc Number of arguments.
 * @param[in] parv Argument vector.
 */
int m_join(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
{
  struct Channel *chptr;
  struct JoinBuf join;
  struct JoinBuf create;
  struct Gline *gline;
  char *p = 0;
  char *chanlist;
  char *name;
  char *keys;

  if (parc < 2 || *parv[1] == '\0')
    return need_more_params(sptr, "JOIN");

  joinbuf_init(&join, sptr, cptr, JOINBUF_TYPE_JOIN, 0, 0);
  joinbuf_init(&create, sptr, cptr, JOINBUF_TYPE_CREATE, 0, TStime());

  chanlist = last0(cptr, sptr, parv[1]); /* find last "JOIN 0" */

  keys = parv[2]; /* remember where keys are */

  for (name = ircd_strtok(&p, chanlist, ","); name;
       name = ircd_strtok(&p, 0, ",")) {
    char *key = 0;

    /* If we have any more keys, take the first for this channel. */
    if (!BadPtr(keys)
        && (keys = strchr(key = keys, ',')))
      *keys++ = '\0';

    /* Empty keys are the same as no keys. */
    if (key && !key[0])
      key = 0;

    if (!IsChannelName(name) || !strIsIrcCh(name))
    {
      /* bad channel name */
      send_reply(sptr, ERR_NOSUCHCHANNEL, name);
      continue;
    }

    if (cli_user(sptr)->joined >= feature_int(FEAT_MAXCHANNELSPERUSER)
	&& !HasPriv(sptr, PRIV_CHAN_LIMIT)) {
      send_reply(sptr, ERR_TOOMANYCHANNELS, name);
      break; /* no point processing the other channels */
    }

    /* BADCHANed channel */
    if ((gline = gline_find(name, GLINE_BADCHAN | GLINE_EXACT)) &&
	GlineIsActive(gline) && !IsAnOper(sptr)) {
      send_reply(sptr, ERR_BANNEDFROMCHAN, name);
      continue;
    }

    if (!(chptr = FindChannel(name))) {
      if (((name[0] == '&') && !feature_bool(FEAT_LOCAL_CHANNELS))
          || strlen(name) > IRCD_MIN(CHANNELLEN, feature_int(FEAT_CHANNELLEN))) {
        send_reply(sptr, ERR_NOSUCHCHANNEL, name);
        continue;
      }

      if (!(chptr = get_channel(sptr, name, CGT_CREATE)))
        continue;

      /* Try to add the new channel as a recent target for the user. */
      if (check_target_limit(sptr, chptr, chptr->chname, 0)) {
        chptr->members = 0;
        destruct_channel(chptr);
        continue;
      }

      joinbuf_join(&create, chptr, CHFL_CHANOP | CHFL_CHANNEL_MANAGER);
    } else if (find_member_link(chptr, sptr)) {
      continue; /* already on channel */
    } else if (check_target_limit(sptr, chptr, chptr->chname, 0)) {
      continue;
    } else {
      int flags = CHFL_DEOPPED;
      int err = 0;

      /* Check Apass/Upass -- since we only ever look at a single
       * "key" per channel now, this hampers brute force attacks. */
      if (key && !strcmp(key, chptr->mode.apass))
        flags = CHFL_CHANOP | CHFL_CHANNEL_MANAGER;
      else if (key && !strcmp(key, chptr->mode.upass))
        flags = CHFL_CHANOP;
      else if (chptr->users == 0 && !chptr->mode.apass[0]) {
        /* Joining a zombie channel (zannel): give ops and increment TS. */
        flags = CHFL_CHANOP;
        chptr->creationtime++;
      } else if (IsInvited(sptr, chptr)) {
        /* Invites bypass these other checks. */
      } else if (chptr->mode.mode & MODE_INVITEONLY)
        err = ERR_INVITEONLYCHAN;
      else if (chptr->mode.limit && (chptr->users >= chptr->mode.limit))
        err = ERR_CHANNELISFULL;
      else if ((chptr->mode.mode & MODE_REGONLY) && !IsAccount(sptr))
        err = ERR_NEEDREGGEDNICK;
      else if (find_ban(sptr, chptr->banlist))
        err = ERR_BANNEDFROMCHAN;
      else if (*chptr->mode.key && (!key || strcmp(key, chptr->mode.key)))
        err = ERR_BADCHANNELKEY;

      /* An oper with WALK_LCHAN privilege can join a local channel
       * he otherwise could not join by using "OVERRIDE" as the key.
       * This will generate a HACK(4) notice, but fails if the oper
       * could normally join the channel. */
      if (IsLocalChannel(chptr->chname)
          && HasPriv(sptr, PRIV_WALK_LCHAN)
          && !(flags & CHFL_CHANOP)
          && key && !strcmp(key, "OVERRIDE"))
      {
        switch (err) {
        case 0:
          if (strcmp(chptr->mode.key, "OVERRIDE")
              && strcmp(chptr->mode.apass, "OVERRIDE")
              && strcmp(chptr->mode.upass, "OVERRIDE")) {
            send_reply(sptr, ERR_DONTCHEAT, chptr->chname);
            continue;
          }
          break;
        case ERR_INVITEONLYCHAN: err = 'i'; break;
        case ERR_CHANNELISFULL:  err = 'l'; break;
        case ERR_BANNEDFROMCHAN: err = 'b'; break;
        case ERR_BADCHANNELKEY:  err = 'k'; break;
        case ERR_NEEDREGGEDNICK: err = 'r'; break;
        default: err = '?'; break;
        }
        /* send accountability notice */
        if (err)
          sendto_opmask_butone(0, SNO_HACK4, "OPER JOIN: %C JOIN %H "
                               "(overriding +%c)", sptr, chptr, err);
        err = 0;
      }

      /* Is there some reason the user may not join? */
      if (err) {
        switch(err) {
          case ERR_NEEDREGGEDNICK:
            send_reply(sptr, 
                       ERR_NEEDREGGEDNICK, 
                       chptr->chname, 
                       feature_str(FEAT_URLREG));            
            break;
          default:
            send_reply(sptr, err, chptr->chname);
            break;
        }
        continue;
      }

      joinbuf_join(&join, chptr, flags);
      if (flags & CHFL_CHANOP) {
        struct ModeBuf mbuf;
	/* Always let the server op him: this is needed on a net with older servers
	   because they 'destruct' channels immediately when they become empty without
	   sending out a DESTRUCT message. As a result, they would always bounce a mode
	   (as HACK(2)) when the user ops himself.
           (There is also no particularly good reason to have the user op himself.)
        */
	modebuf_init(&mbuf, &me, cptr, chptr, MODEBUF_DEST_SERVER);
	modebuf_mode_client(&mbuf, MODE_ADD | MODE_CHANOP, sptr,
                            chptr->mode.apass[0] ? ((flags & CHFL_CHANNEL_MANAGER) ? 0 : 1) : MAXOPLEVEL);
	modebuf_flush(&mbuf);
      }
    }

    del_invite(sptr, chptr);

    if (chptr->topic[0]) {
      send_reply(sptr, RPL_TOPIC, chptr->chname, chptr->topic);
      send_reply(sptr, RPL_TOPICWHOTIME, chptr->chname, chptr->topic_nick,
		 chptr->topic_time);
    }

    do_names(sptr, chptr, NAMES_ALL|NAMES_EON); /* send /names list */
  }

  joinbuf_flush(&join); /* must be first, if there's a JOIN 0 */
  joinbuf_flush(&create);

  return 0;
}
/*
 * m_invite - generic message handler
 *
 *   parv[0] - sender prefix
 *   parv[1] - user to invite
 *   parv[2] - channel name
 *
 * - INVITE now is accepted only if who does it is chanop (this of course
 *   implies that channel must exist and he must be on it).
 *
 * - On the other side it IS processed even if channel is NOT invite only
 *   leaving room for other enhancements like inviting banned ppl.  -- Nemesi
 *
 * - Invite with no parameters now lists the channels you are invited to.
 *                                                         - Isomer 23 Oct 99
 */
int m_invite(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  struct Client *acptr;
  struct Channel *chptr;
  
  if (parc < 2 ) { 
    /*
     * list the channels you have an invite to.
     */
    struct SLink *lp;
    for (lp = cli_user(sptr)->invited; lp; lp = lp->next)
      send_reply(cptr, RPL_INVITELIST, lp->value.chptr->chname);
    send_reply(cptr, RPL_ENDOFINVITELIST);
    return 0;
  }
  
  if (parc < 3 || EmptyString(parv[2]))
    return need_more_params(sptr, "INVITE");

  if (!(acptr = FindUser(parv[1]))) {
    send_reply(sptr, ERR_NOSUCHNICK, parv[1]);
    return 0;
  }

  if (is_silenced(sptr, acptr))
    return 0;

  if (!IsChannelName(parv[2])
      || !strIsIrcCh(parv[2])
      || !(chptr = FindChannel(parv[2]))) {
    send_reply(sptr, ERR_NOSUCHCHANNEL, parv[2]);
    return 0;
  }

  if (!find_channel_member(sptr, chptr)) {
    send_reply(sptr, ERR_NOTONCHANNEL, chptr->chname);
    return 0;
  }

  if (find_channel_member(acptr, chptr)) {
    send_reply(sptr, ERR_USERONCHANNEL, cli_name(acptr), chptr->chname);
    return 0;
  }

  if (!is_chan_op(sptr, chptr)) {
    send_reply(sptr, ERR_CHANOPRIVSNEEDED, chptr->chname);
    return 0;
  }

  /* If we get here, it was a VALID and meaningful INVITE */

  if (check_target_limit(sptr, acptr, cli_name(acptr), 0))
    return 0;

  send_reply(sptr, RPL_INVITING, cli_name(acptr), chptr->chname);

  if (cli_user(acptr)->away)
    send_reply(sptr, RPL_AWAY, cli_name(acptr), cli_user(acptr)->away);

  if (MyConnect(acptr)) {
    add_invite(acptr, chptr);
    sendcmdto_one(sptr, CMD_INVITE, acptr, "%s %H", cli_name(acptr), chptr);
  } else if (!IsLocalChannel(chptr->chname)) {
    sendcmdto_one(sptr, CMD_INVITE, acptr, "%s %H %Tu", cli_name(acptr), chptr,
                  chptr->creationtime);
  }

  if (!IsLocalChannel(chptr->chname) || MyConnect(acptr)) {
    if (feature_bool(FEAT_ANNOUNCE_INVITES)) {
      /* Announce to channel operators. */
      sendcmdto_channel_butserv_butone(&his, get_error_numeric(RPL_ISSUEDINVITE)->str,
                                       NULL, chptr, sptr, SKIP_NONOPS,
                                       "%H %C %C :%C has been invited by %C",
                                       chptr, acptr, sptr, acptr, sptr);
      /* Announce to servers with channel operators. */
      sendcmdto_channel_servers_butone(sptr, NULL, TOK_INVITE, chptr, acptr, SKIP_NONOPS,
                                       "%s %H %Tu", cli_name(acptr),
                                       chptr, chptr->creationtime);
    }
  }

  return 0;
}
Example #7
0
void do_join(struct Client *cptr, struct Client *sptr, struct JoinBuf *join,
             struct JoinBuf *create, char *chan, char *key, int level)
{
  struct Channel *chptr;
  struct Gline *gline;

  /* BADCHANed channel */
  if ((gline = gline_find(chan, GLINE_BADCHAN | GLINE_EXACT)) &&
      GlineIsActive(gline) && !IsAnOper(sptr)) {
    send_reply(sptr, ERR_BANNEDFROMCHAN, chan);
    return;
  }

  /* Bouncy +L joins */
  if (level > feature_int(FEAT_MAX_BOUNCE)) {
    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :*** Couldn't join %s ! - Redirection (+L) setting was too bouncy", sptr, chan);
    return;
  }

  if (!(chptr = FindChannel(chan))) {
    if (((chan[0] == '&') && !feature_bool(FEAT_LOCAL_CHANNELS))
        || strlen(chan) > IRCD_MIN(CHANNELLEN, feature_int(FEAT_CHANNELLEN))) {
      send_reply(sptr, ERR_NOSUCHCHANNEL, chan);
      return;
    }

    if (feature_bool(FEAT_CHANNEL_CREATE_IRCOPONLY) && !IsAnOper(sptr) && !IsChannelService(sptr)) {
      send_reply(sptr, ERR_NOSUCHCHANNEL, chan);
      return;
    }

    if (!(chptr = get_channel(sptr, chan, CGT_CREATE)))
      return;

    /* Try to add the new channel as a recent target for the user. */
    if (check_target_limit(sptr, chptr, chptr->chname, 0)) {
      chptr->members = 0;
      destruct_channel(chptr);
      return;
    }

    joinbuf_join(create, chptr, CHFL_CHANOP | CHFL_CHANNEL_MANAGER);
  } else if (find_member_link(chptr, sptr)) {
    return; /* already on channel */
  } else if (check_target_limit(sptr, chptr, chptr->chname, 0)) {
    return;
  } else {
    int flags = CHFL_DEOPPED;
    int err = 0;
    int excepted = 0;
    int exceptkli = 0;
    struct Ban *ban = NULL;

    if (*chptr->mode.redir && (*chptr->mode.redir != '\0')) {
      if (chptr->users >= chptr->mode.limit) {
        if (IsNoLink(sptr))
          send_reply(sptr, ERR_LINKCHAN, chptr->chname, chptr->mode.redir);
        else if (!IsChannelName(chptr->mode.redir) || !strIsIrcCh(chptr->mode.redir))
          send_reply(sptr, ERR_NOSUCHCHANNEL, chptr->mode.redir);
        else {
          send_reply(sptr, ERR_LINKSET, chptr->chname, chptr->chname, chptr->mode.redir);
          do_join(cptr, sptr, join, create, chptr->mode.redir, key, level+1);
        }
        return;
      }
    }

    if (find_ban(sptr, chptr->exceptlist, EBAN_EXCEPTLIST, 0)) {
      if (feature_bool(FEAT_CHMODE_e_CHMODEEXCEPTION))
        exceptkli = 1;
      excepted = 1;
    }

    /* Check Apass/Upass -- since we only ever look at a single
     * "key" per channel now, this hampers brute force attacks. */
    if (feature_bool(FEAT_CHMODE_Z_STRICT) && (chptr->mode.exmode & EXMODE_SSLONLY) && !IsSSL(sptr))
      err = ERR_SSLONLYCHAN;
    else if (key && !strcmp(key, chptr->mode.apass))
      flags = CHFL_CHANOP | CHFL_CHANNEL_MANAGER;
    else if (key && !strcmp(key, chptr->mode.upass))
      flags = CHFL_CHANOP;
    else if (chptr->users == 0 && !chptr->mode.apass[0] && !(chptr->mode.exmode & EXMODE_PERSIST)) {
      /* Joining a zombie channel (zannel): give ops and increment TS. */
      flags = CHFL_CHANOP;
      chptr->creationtime++;
    } else if (IsXtraOp(sptr)) {
      /* XtraOp bypasses all other checks. */
    } else if ((chptr->mode.exmode & EXMODE_SSLONLY) && !IsSSL(sptr))
      err = ERR_SSLONLYCHAN;
    else if (IsInvited(sptr, chptr)) {
      /* Invites bypass these other checks. */
    } else if (*chptr->mode.key && (!key || strcmp(key, chptr->mode.key)) && !exceptkli)
      err = ERR_BADCHANNELKEY;
    else if (*chptr->mode.key && feature_bool(FEAT_FLEXIBLEKEYS) && (key && !strcmp(key, chptr->mode.key))) {
      /* Assume key checked by previous condition was found to be correct
         and allow join because FEAT_FLEXIBLEKEYS was enabled */
    } else if ((chptr->mode.mode & MODE_INVITEONLY) && !exceptkli)
      err = ERR_INVITEONLYCHAN;
    else if (chptr->mode.limit && (chptr->users >= chptr->mode.limit) && !exceptkli)
      err = ERR_CHANNELISFULL;
    else if ((chptr->mode.mode & MODE_REGONLY) && !IsAccount(sptr))
      err = ERR_NEEDREGGEDNICK;
    else if ((chptr->mode.exmode & EXMODE_ADMINONLY) && !IsAdmin(sptr))
      err = ERR_ADMINONLYCHAN;
    else if ((chptr->mode.exmode & EXMODE_OPERONLY) && !IsAnOper(sptr))
      err = ERR_OPERONLYCHAN;
    else if ((ban = find_ban(sptr, chptr->banlist, EBAN_NONE, 0)) && !excepted)
      err = ERR_BANNEDFROMCHAN;

    /* An oper with WALK_LCHAN privilege can join a local channel
     * he otherwise could not join by using "OVERRIDE" as the key.
     * This will generate a HACK(4) notice, but fails if the oper
     * could normally join the channel. */
    if (IsLocalChannel(chptr->chname)
        && HasPriv(sptr, PRIV_WALK_LCHAN)
        && !(flags & CHFL_CHANOP)
        && key && !strcmp(key, "OVERRIDE"))
    {
      switch (err) {
      case 0:
        if (strcmp(chptr->mode.key, "OVERRIDE")
            && strcmp(chptr->mode.apass, "OVERRIDE")
            && strcmp(chptr->mode.upass, "OVERRIDE")) {
          send_reply(sptr, ERR_DONTCHEAT, chptr->chname);
          return;
        }
        break;
      case ERR_INVITEONLYCHAN: err = 'i'; break;
      case ERR_CHANNELISFULL:  err = 'l'; break;
      case ERR_BANNEDFROMCHAN: err = 'b'; break;
      case ERR_BADCHANNELKEY:  err = 'k'; break;
      case ERR_NEEDREGGEDNICK: err = 'r'; break;
      case ERR_ADMINONLYCHAN:  err = 'a'; break;
      case ERR_OPERONLYCHAN:   err = 'O'; break;
      case ERR_SSLONLYCHAN:    err = 'Z'; break;
      default: err = '?'; break;
      }
      /* send accountability notice */
      if (err)
        sendto_opmask_butone(0, SNO_HACK4, "OPER JOIN: %C JOIN %H "
                             "(overriding +%c)", sptr, chptr, err);
      err = 0;
    }

    /* Is there some reason the user may not join? */
    if (err) {
      switch(err) {
        case ERR_NEEDREGGEDNICK:
          send_reply(sptr,
                     ERR_NEEDREGGEDNICK,
                     chptr->chname,
                     feature_str(FEAT_URLREG));
          break;
        default:
          send_reply(sptr, err, chptr->chname);
          break;
      }
      return;
    }

    joinbuf_join(join, chptr, flags);
    if (flags & CHFL_CHANOP) {
      struct ModeBuf mbuf;
      /* Always let the server op him: this is needed on a net with older servers
         because they 'destruct' channels immediately when they become empty without
         sending out a DESTRUCT message. As a result, they would always bounce a mode
         (as HACK(2)) when the user ops himself.
         (There is also no particularly good reason to have the user op himself.)
      */
      modebuf_init(&mbuf, &me, cptr, chptr, MODEBUF_DEST_SERVER);
      modebuf_mode_client(&mbuf, MODE_ADD | MODE_CHANOP, sptr,
                          chptr->mode.apass[0] ? ((flags & CHFL_CHANNEL_MANAGER) ? 0 : 1) : MAXOPLEVEL);
      modebuf_flush(&mbuf);
    }
  }

  del_invite(sptr, chptr);

  if (chptr->topic[0]) {
    send_reply(sptr, RPL_TOPIC, chptr->chname, chptr->topic);
    send_reply(sptr, RPL_TOPICWHOTIME, chptr->chname, chptr->topic_nick,
               chptr->topic_time);
  }

  do_names(sptr, chptr, NAMES_ALL|NAMES_EON); /* send /names list */
}
Example #8
0
void relay_private_message(struct Client *cptr, struct Client* sptr, const char* name, const char* text)
{
  struct Client* acptr;
  static char *pmsg = NULL;
  static int last_length = 0;
  int len;

  assert(0 != sptr);
  assert(0 != name);
  assert(0 != text);

  if (0 == (acptr = FindUser(name))) {
    send_reply(sptr, ERR_NOSUCHNICK, name);
    return;
  }
  if (IsOnlyreg(acptr) && !IsRegnick(sptr)) {
	  send_reply(sptr, RPL_MSGONLYREG, cli_name(acptr));
	  return;
  }

  if (!IsChannelService(acptr))
  {
    if (check_target_limit(sptr, acptr, cli_name(acptr), 0))
    {
      return;
    }
    if (is_silenced(sptr, acptr))
    {
      send_reply(sptr, ERR_SILENCED, cli_name(acptr));
      return;
    }
  }

  if (MyUser(cptr) && !es_representante(cptr)) {
	if ((len = strlen(text)+1) > last_length)
	{
		if (pmsg)
			free(pmsg);
		pmsg = (char *)MyMalloc(sizeof(char)*len);
		last_length = len;
	}
	strcpy(pmsg, text);
	correct_colors(pmsg);

    if (process_badwords(pmsg, BADWORDS_QUERY) != NULL)
      return;
  }

  /*
   * send away message if user away
   */
  if (cli_user(acptr) && cli_user(acptr)->away)
    send_reply(sptr, RPL_AWAY, cli_name(acptr), cli_user(acptr)->away);
  /*
   * deliver the message
   */
  if (MyUser(acptr))
    add_target(acptr, sptr);

  sendcmdto_one(sptr, CMD_PRIVATE, acptr, "%C :%s", acptr, text);
}
Example #9
0
void relay_channel_message(struct Client* sptr, const char* name, const char* text)
{
  struct Channel* chptr;
  struct Membership *member;
  assert(0 != sptr);
  assert(0 != name);
  assert(0 != text);

  if (0 == (chptr = FindChannel(name))) {
    send_reply(sptr, ERR_NOSUCHCHANNEL, name);
    return;
  }
  /*
   * This first: Almost never a server/service
   */
  if (!client_can_send_to_channel(sptr, chptr) && !(cli_flags(sptr) & FLAGS_CHSERV)) {
    send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname);
    return;
  }

  /* Los ctcps empiezan con el ASCII numero 1 */
  if ((strlen(text) > 1) && (chptr->rhmode.mode & RHMODE_NOCTCP) &&
      (text[0] == 1) && (strncasecmp(text+1, ACTION_STR, ACTION_STR_LEN)))
  {
	member = find_member_link(chptr, sptr);
	if (!member || (!es_representante(sptr) && !IsPreoper(sptr) && !IsVoicedOrOpped(member)))
	{
	  send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname);
	  return;
	}
  }

  if ((chptr->mode.mode & MODE_NOPRIVMSGS) &&
      check_target_limit(sptr, chptr, chptr->chname, 0))
    return;

	/* Parseo de los colores en el texto a un canal si tiene +c */
  if (MyUser(sptr) && !es_representante(sptr)) {
	  int flags = 0;
	  char *texto_procesado;

	  if (chptr->rhmode.mode & (RHMODE_NOCOLOR | RHMODE_BADWORDS))
		  member = find_member_link(chptr, sptr);

	  if (chptr->rhmode.mode & RHMODE_NOCOLOR) {
		  if (member && !IsVoicedOrOpped(member)) {
			  int len = strlen(text);
			  correct_colors((char *)text);
			  if (len != strlen(text))
			  {
				send_reply(sptr, ERR_NOCOLORSCHAN, chptr->chname);
			  }
		  }
	  }

	  if (chptr->rhmode.mode & RHMODE_BADWORDS)
	  {
		  if (member) {
			  if (!(member->status & (CHFL_CHANOP | CHFL_OWNER | CHFL_HALFOP)))
				flags = (BADWORDS_CHANNEL | BADWORDS_CHANPRIO);
		  } else
			  flags = (BADWORDS_CHANNEL | BADWORDS_CHANPRIO);
	  }
	  else
		  flags = (BADWORDS_CHANPRIO);

	  if ((texto_procesado = process_badwords(text, flags)) != NULL)
	  {
		sendcmdto_channel_butone(sptr, CMD_PRIVATE, chptr, cli_from(sptr),
		    SKIP_DEAF | SKIP_BURST, "%H :%s", chptr, texto_procesado);
		return;
	  }
  }

  sendcmdto_channel_butone(sptr, CMD_PRIVATE, chptr, cli_from(sptr),
			   SKIP_DEAF | SKIP_BURST, "%H :%s", chptr, text);
}