コード例 #1
0
ファイル: m_banlink.c プロジェクト: wirelesspt/unreal
int mode_is_ok(aClient *sptr, aChannel *chptr, char *para, int checkt, int what)
{
	if ((checkt == EXCHK_ACCESS) || (checkt == EXCHK_ACCESS_ERR))
	{
		if (!is_chanowner(sptr, chptr))
		{
			if (checkt == EXCHK_ACCESS_ERR)
				sendto_one(sptr, err_str(ERR_CHANOWNPRIVNEEDED), me.name, sptr->name, chptr->chname);
			return 0;
		} else {
			return 1;
		}
	} else
	if (checkt == EXCHK_PARAM)
	{
		if (!para) 
		{
			sendto_one(sptr, ":%s NOTICE %s :chanmode +B requires a channel as parameter", me.name, sptr->name);
			return 0;
		}
		if (strlen(para) > 32) 
		{
                        sendto_one(sptr, ":%s NOTICE %s :invalid parameter for chanmode +B", me.name, sptr->name);
                        return 0;
		}
		if (!IsChannelName(para))
		{
			sendto_one(sptr, ":%s NOTICE %s :invalid parameter for chanmode +B", me.name, sptr->name);
			return 0;
		}
		return 1;
	}
	return 0;
}
コード例 #2
0
ファイル: kdparse.c プロジェクト: Cloudxtreme/ircd-ratbox
void
parse_resv_file(FBFILE *file)
{
  char *reason_field;
  char *host_field;
  char line[BUFSIZE];
  char *p;

  while(fbgets(line, sizeof(line), file))
  {
    if((p = strchr(line, '\n')))
      *p = '\0';

    if((*line == '\0') || (line[0] == '#'))
      continue;

    if((host_field = getfield(line)) == NULL)
      continue;

    if((reason_field = getfield(NULL)) == NULL)
      continue;

    if(IsChannelName(host_field))
      create_resv(host_field, reason_field, RESV_CHANNEL);
    else if(clean_resv_nick(host_field))
      create_resv(host_field, reason_field, RESV_NICK);
  }
}
コード例 #3
0
ファイル: m_list.c プロジェクト: ShutterQuick/charybdis
/* m_list()
 *      parv[1] = channel
 *
 * XXX - With SAFELIST, do we really need to continue pacing?
 *       In theory, the server cannot be lagged by this. --nenolod
 */
static int m_list(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	static time_t last_used = 0L;

	if (source_p->localClient->safelist_data != NULL)
	{
		sendto_one_notice(source_p, ":/LIST aborted");
		safelist_client_release(source_p);
		return 0;
	}

	if (parc < 2 || !IsChannelName(parv[1]))
	{
		/* pace this due to the sheer traffic involved */
		if (((last_used + ConfigFileEntry.pace_wait) > rb_current_time()))
		{
			sendto_one(source_p, form_str(RPL_LOAD2HI), me.name, source_p->name, "LIST");
			sendto_one(source_p, form_str(RPL_LISTEND), me.name, source_p->name);
			return 0;
		}
		else
			last_used = rb_current_time();
	}

	return mo_list(client_p, source_p, parc, parv);
}
コード例 #4
0
ファイル: m_wallvoices.c プロジェクト: Compy/Undernet-IRCU
/*
 * 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;
}
コード例 #5
0
ファイル: m_join.c プロジェクト: evilnet/nefarious2
/** 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 JoinBuf join;
  struct JoinBuf create;
  char *p = 0;
  char *chanlist;
  char *name;
  char *keys;

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

  if (!IsAnOper(sptr) && IsRestrictJoin(sptr)) {
    send_reply(sptr, ERR_BANNEDFROMCHAN, parv[1]);
    return 0;
  }

  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 >= get_client_maxchans(sptr)
	&& !HasPriv(sptr, PRIV_CHAN_LIMIT)) {
      send_reply(sptr, ERR_TOOMANYCHANNELS, name);
      break; /* no point processing the other channels */
    }

    do_join(cptr, sptr, &join, &create, name, key, 0);
  }

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

  return 0;
}
コード例 #6
0
void
parse_resv_file(FILE * file)
{
	struct ConfItem *aconf;
	char *reason_field;
	char *host_field;
	char line[BUFSIZE];
	char *p;

	while (fgets(line, sizeof(line), file))
	{
		if((p = strpbrk(line, "\r\n")))
			*p = '\0';

		if((*line == '\0') || (line[0] == '#'))
			continue;

		host_field = getfield(line);
		if(EmptyString(host_field))
			continue;

		reason_field = getfield(NULL);
		if(EmptyString(reason_field))
			continue;

		if(IsChannelName(host_field))
		{
			if(hash_find_resv(host_field))
				continue;

			aconf = make_conf();
			aconf->status = CONF_RESV_CHANNEL;
			aconf->port = 0;

			DupString(aconf->name, host_field);
			DupString(aconf->passwd, reason_field);
			add_to_resv_hash(aconf->name, aconf);
		}
		else if(clean_resv_nick(host_field))
		{
			if(find_nick_resv(host_field))
				continue;

			aconf = make_conf();
			aconf->status = CONF_RESV_NICK;
			aconf->port = 0;

			DupString(aconf->name, host_field);
			DupString(aconf->passwd, reason_field);
			dlinkAddAlloc(aconf, &resv_conf_list);
		}
	}
}
コード例 #7
0
ファイル: m_topic.c プロジェクト: mojadita/ircd
/** Handle a local user's attempt to get or set a channel topic.
 *
 * \a parv has the following elements:
 * \li \a parv[1] is the channel name
 * \li \a parv[\a parc - 1] is the topic (if \a parc > 2)
 *
 * 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_topic(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  struct Channel *chptr;
  char *topic = 0, *name, *p = 0;

  if (parc < 2)
    return need_more_params(sptr, "TOPIC");

  if (parc > 2)
    topic = parv[parc - 1];

  for (; (name = ircd_strtok(&p, parv[1], ",")); parv[1] = 0)
  {
    chptr = 0;
    /* Does the channel exist */
    if (!IsChannelName(name) || !(chptr = FindChannel(name)))
    {
    	send_reply(sptr,ERR_NOSUCHCHANNEL,name);
    	continue;
    }
    /* Trying to check a topic outside a secret channel */
    if ((topic || SecretChannel(chptr)) && !find_channel_member(sptr, chptr))
    {
      send_reply(sptr, ERR_NOTONCHANNEL, chptr->chname);
      continue;
    }

    /* only asking for topic */
    if (!topic)
    {
      if (chptr->topic[0] == '\0')
	send_reply(sptr, RPL_NOTOPIC, chptr->chname);
      else
      {
	send_reply(sptr, RPL_TOPIC, chptr->chname, chptr->topic);
	send_reply(sptr, RPL_TOPICWHOTIME, chptr->chname, chptr->topic_nick,
		   chptr->topic_time);
      }
    }
#if defined(DDB) || defined(SERVICES)
    else if ((chptr->mode.mode & MODE_TOPICLIMIT) &&
             !(is_chan_owner(sptr, chptr) || is_chan_op(sptr, chptr)))
#else
    else if ((chptr->mode.mode & MODE_TOPICLIMIT) && !is_chan_op(sptr, chptr))
#endif
      send_reply(sptr, ERR_CHANOPRIVSNEEDED, chptr->chname);
    else if (!client_can_send_to_channel(sptr, chptr, 1))
      send_reply(sptr, ERR_CANNOTSENDTOCHAN, chptr->chname);
    else
      do_settopic(sptr,cptr,chptr,topic,0);
  }
  return 0;
}
コード例 #8
0
ファイル: m_opmode.c プロジェクト: mojadita/ircd
/** Handle an OPMODE message from an operator.
 *
 * \a parv has the same elements as for m_mode().
 *
 * 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 mo_opmode(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  struct Channel *chptr = 0;
  struct ModeBuf mbuf;
  char *chname;
  const char *qreason;
  int force = 0;

  if (!feature_bool(FEAT_CONFIG_OPERCMDS))
    return send_reply(sptr, ERR_DISABLED, "OPMODE");

  if (parc < 3)
    return need_more_params(sptr, "OPMODE");

  chname = parv[1];
  if (*chname == '!')
  {
    chname++;
    if (!HasPriv(sptr, IsLocalChannel(chname) ? PRIV_FORCE_LOCAL_OPMODE
                                              : PRIV_FORCE_OPMODE))
      return send_reply(sptr, ERR_NOPRIVILEGES);
    force = 1;
  }

  if (!HasPriv(sptr,
	       IsLocalChannel(chname) ? PRIV_LOCAL_OPMODE : PRIV_OPMODE))
    return send_reply(sptr, ERR_NOPRIVILEGES);

  if (!IsChannelName(chname) || !(chptr = FindChannel(chname)))
    return send_reply(sptr, ERR_NOSUCHCHANNEL, chname);

  if (!force && (qreason = find_quarantine(chptr->chname)))
    return send_reply(sptr, ERR_QUARANTINED, chptr->chname, qreason);

  modebuf_init(&mbuf, sptr, cptr, chptr,
	       (MODEBUF_DEST_CHANNEL | /* Send MODE to channel */
		MODEBUF_DEST_SERVER  | /* And to server */
		MODEBUF_DEST_OPMODE  | /* Use OPMODE */
		MODEBUF_DEST_HACK4   | /* Generate a HACK(4) notice */
		MODEBUF_DEST_LOG));    /* Log the mode changes to OPATH */

  mode_parse(&mbuf, cptr, sptr, chptr, parc - 2, parv + 2,
	     (MODE_PARSE_SET |    /* set the modes on the channel */
	      MODE_PARSE_FORCE),  /* And force them to be accepted */
	      NULL);

  modebuf_flush(&mbuf); /* flush the modes */

  return 0;
}
コード例 #9
0
ファイル: s_numeric.c プロジェクト: DamnIO/DamnIRCd
/** Forwards a numeric message from a remote server.
 * @param numeric Value of numeric message.
 * @param nnn If non-zero, treat parv[1] as a numnick; else as a client name.
 * @param cptr Client that originated the numeric.
 * @param sptr Peer that sent us the numeric.
 * @param parc Count of valid arguments in \a parv.
 * @param parv Argument list.
 * @return Zero (always).
 */
int do_numeric(int numeric, int nnn, struct Client *cptr, struct Client *sptr,
    int parc, char *parv[])
{
  struct Client *acptr = 0;
  struct Channel *achptr = 0;
  char num[4];

  /* Avoid trash, we need it to come from a server and have a target  */
  if ((parc < 2) || !IsServer(sptr))
    return 0;

  /* Who should receive this message ? Will we do something with it ?
     Note that we use findUser functions, so the target can't be neither
     a server, nor a channel (?) nor a list of targets (?) .. u2.10
     should never generate numeric replies to non-users anyway
     Ahem... it can be a channel actually, csc bots use it :\ --Nem */

  if (IsChannelName(parv[1]))
    achptr = FindChannel(parv[1]);
  else
    acptr = (nnn) ? (findNUser(parv[1])) : (FindUser(parv[1]));

  if (((!acptr) || (cli_from(acptr) == cptr)) && !achptr)
    return 0;

  /* Remap low number numerics, not that I understand WHY.. --Nemesi  */
  /* numerics below 100 talk about the current 'connection', you're not
   * connected to a remote server so it doesn't make sense to send them
   * remotely - but the information they contain may be useful, so we
   * remap them up.  Weird, but true.  -- Isomer */
  if (numeric < 100)
    numeric += 100;

  ircd_snprintf(0, num, sizeof(num), "%03d", numeric);

  /* Since 2.10.10.pl14 we rewrite numerics from remote servers to appear to
   * come from the local server
   */
  if (acptr)
    sendcmdto_one((feature_bool(FEAT_HIS_REWRITE) && !IsOper(acptr)) ?
                    &me : sptr,
                  num, num, acptr, "%C %s", acptr, parv[2]);
  else
    sendcmdto_channel_butone(feature_bool(FEAT_HIS_REWRITE) ? &me : sptr,
                             num, num, achptr, cptr, SKIP_DEAF | SKIP_BURST,
                             '\0', "%H %s", achptr, parv[2]);
  return 0;
}
コード例 #10
0
ファイル: m_wallvoices.c プロジェクト: mojadita/ircd
/** 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;
}
コード例 #11
0
ファイル: m_message.c プロジェクト: Cloudxtreme/ircd-3
static void
m_notice(struct Client *client_p,
         struct Client *source_p, int parc, char *parv[])
{
  char equiv[NICKLEN + 1];

  cluster_prefix(client_p, parc, parv, 0, 0, 0);
  if (strchr(parv[1], ','))
  	cluster_prefix(client_p, parc, parv, 1, 0, 3);
  else
  	cluster_prefix(client_p, parc, parv, 1, IsChannelName(parv[1]), 0);

  if (parc > 1)
    if (parv[1][0] && get_equiv_nick(parv[1], equiv))
      parv[1] = equiv;

  m_message(NOTICE, "NOTICE", client_p, source_p, parc, parv);
}
コード例 #12
0
ファイル: m_topic.c プロジェクト: dequis/elemental-ircd
/*
 * ms_topic
 *      parv[1] = channel name
 *	parv[2] = topic_info
 *	parv[3] = topic_info time
 *	parv[4] = new channel topic
 *
 * Let servers always set a topic
 */
static int
ms_topic(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
    struct Channel *chptr = NULL;

    if(IsChannelName(parv[1])) {
        if((chptr = find_channel(parv[1])) == NULL)
            return 0;

        set_channel_topic(chptr, parv[4], parv[2], atoi(parv[3]));

        sendto_channel_local(ALL_MEMBERS, chptr, ":%s TOPIC %s :%s",
                             source_p->name, parv[1],
                             chptr->topic == NULL ? "" : chptr->topic);
    }

    return 0;
}
コード例 #13
0
ファイル: m_clearmode.c プロジェクト: aboutnet/ircu-abnet
/*
 * ms_clearmode - server message handler
 *
 * parv[0] = Send prefix
 * parv[1] = Channel name
 * parv[2] = Control string
 */
int
ms_clearmode(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  struct Channel *chptr;

  if (parc < 3)
    return need_more_params(sptr, "CLEARMODE");

  if (!IsPrivileged(sptr)) {
    protocol_violation(sptr,"No privileges on source for CLEARMODE, desync?");
    return send_reply(sptr, ERR_NOPRIVILEGES);
  }

  if (!IsChannelName(parv[1]) || IsLocalChannel(parv[1]) ||
      !(chptr = FindChannel(parv[1])))
    return send_reply(sptr, ERR_NOSUCHCHANNEL, parv[1]);

  return do_clearmode(cptr, sptr, chptr, parv[2]);
}
コード例 #14
0
ファイル: m_topic.c プロジェクト: Cloudxtreme/ircd-ratbox
/*
 * ms_topic
 *      parv[0] = sender prefix
 *      parv[1] = channel name
 *	parv[2] = topic_info
 *	parv[3] = topic_info time
 *	parv[4] = new channel topic
 *
 * Let servers always set a topic
 */
static void ms_topic(struct Client *client_p,
                    struct Client *source_p,
                    int parc,
                    char *parv[])
{
  struct Channel *chptr = NULL;
  
  if (!IsServer(source_p))
  {
    m_topic(client_p, source_p, parc, parv);
    return;
  }

  if( parc < 5 )
    return;

  if (parv[1] && IsChannelName(parv[1]))
    {
      if ((chptr = hash_find_channel(parv[1])) == NULL)
	return;
      
      set_channel_topic(chptr, parv[4], parv[2], atoi(parv[3]));

      if(ConfigServerHide.hide_servers)
	{
	  sendto_channel_local(ALL_MEMBERS,
			       chptr, ":%s TOPIC %s :%s",
			       me.name,
			       parv[1],
			       chptr->topic == NULL ? "" : chptr->topic);

	}
      else
	{
	  sendto_channel_local(ALL_MEMBERS,
			       chptr, ":%s TOPIC %s :%s",
			       source_p->name,
			       parv[1], chptr->topic == NULL ? "" : chptr->topic);
	}
    }
}
コード例 #15
0
ファイル: m_topic.c プロジェクト: mojadita/ircd
/** Handle a remote user's attempt to set a channel topic.
 * \a parv has the following elements:
 * \li \a parv[1] is the channel name
 * \li \a parv[2] is the channel creation timestamp (optional)
 * \li \a parv[2] is the topic's timestamp (optional)
 * \li \a parv[\a parc - 1] is the topic
 *
 * 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 ms_topic(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  struct Channel *chptr;
  char *topic = 0, *name, *p = 0;
  time_t ts = 0;

  if (parc < 3)
    return need_more_params(sptr, "TOPIC");

  topic = parv[parc - 1];

  for (; (name = ircd_strtok(&p, parv[1], ",")); parv[1] = 0)
  {
    chptr = 0;
    /* Does the channel exist */
    if (!IsChannelName(name) || !(chptr = FindChannel(name)))
    {
    	send_reply(sptr,ERR_NOSUCHCHANNEL,name);
    	continue;
    }

    /* Ignore requests for topics from remote servers */
    if (IsLocalChannel(name) && !MyUser(sptr))
    {
      protocol_violation(sptr,"Topic request");
      continue;
    }

    /* If existing channel is older or has newer topic, ignore */
    if (parc > 3 && (ts = atoi(parv[2])) && chptr->creationtime < ts)
      continue;

    ts = 0; /* Default to the current time if no topic_time is passed. */
    if (parc > 4 && (ts = atoi(parv[3])) && chptr->topic_time > ts)
      continue;

    do_settopic(sptr,cptr,chptr,topic, ts);
  }
  return 0;
}
コード例 #16
0
ファイル: m_message.c プロジェクト: Cloudxtreme/ircd-3
static void
m_privmsg(struct Client *client_p,
          struct Client *source_p, int parc, char *parv[])
{
  char equiv[NICKLEN + 1];
  
  cluster_prefix(client_p, parc, parv, 0, 0, 0);
  if (strchr(parv[1], ','))
  	cluster_prefix(client_p, parc, parv, 1, 0, 3);
  else
  	cluster_prefix(client_p, parc, parv, 1, IsChannelName(parv[1]), 0);

  /* servers have no reason to send privmsgs, yet sometimes there is cause
   * for a notice.. (for example remote kline replies) --fl_
   */
  if (!IsPerson(source_p))
    return;

  if (parc > 1)
    if (parv[1][0] && get_equiv_nick(parv[1], equiv))
      parv[1] = equiv;

  m_message(PRIVMSG, "PRIVMSG", client_p, source_p, parc, parv);
}
コード例 #17
0
ファイル: hash.c プロジェクト: NX-Andro/x3
struct chanNode *
AddChannel(const char *name, time_t time_, const char *modes, char *banlist, char *exemptlist)
{
    struct chanNode *cNode;
    char new_modes[MAXLEN], *argv[MAXNUMPARAMS];
    unsigned int nn;

    if (!IsChannelName(name)) {
        log_module(MAIN_LOG, LOG_ERROR, "Somebody asked to add channel '%s', which isn't a channel name!", name);
        return NULL;
    }
    if (!modes)
        modes = "";

    safestrncpy(new_modes, modes, sizeof(new_modes));
    nn = split_line(new_modes, 0, ArrayLength(argv), argv);
    if (!(cNode = GetChannel(name))) {
        cNode = calloc(1, sizeof(*cNode) + strlen(name));
        strcpy(cNode->name, name);
        banList_init(&cNode->banlist);
        exemptList_init(&cNode->exemptlist);
        modeList_init(&cNode->members);
        mod_chanmode(NULL, cNode, argv, nn, MCP_FROM_SERVER);
        dict_insert(channels, cNode->name, cNode);
        cNode->timestamp = time_;
        rel_age = 1;
    } else if (cNode->timestamp > time_) {
        wipeout_channel(cNode, time_, argv, nn);
        rel_age = 1;
    } else if (cNode->timestamp == time_) {
        mod_chanmode(NULL, cNode, argv, nn, MCP_FROM_SERVER);
        rel_age = 0;
    } else {
        rel_age = -1;
    }

    /* rel_age is the relative ages of our channel data versus what is
     * in a BURST command.  1 means ours is younger, 0 means both are
     * the same age, -1 means ours is older. */

    /* if it's a new or updated channel, make callbacks */
    if (rel_age > 0)
        for (nn=0; nn<ncf_used; nn++)
            ncf_list[nn](cNode, ncf_list_extra[nn]);

    /* go through list of bans and add each one */
    if (banlist && (rel_age >= 0)) {
        for (nn=0; banlist[nn];) {
            char *ban = banlist + nn;
            struct banNode *bn;
            while (banlist[nn] != ' ' && banlist[nn])
                nn++;
            while (banlist[nn] == ' ')
                banlist[nn++] = 0;
            bn = calloc(1, sizeof(*bn));
            safestrncpy(bn->ban, ban, sizeof(bn->ban));
            safestrncpy(bn->who, "<unknown>", sizeof(bn->who));
            bn->set = now;
            banList_append(&cNode->banlist, bn);
        }
    }

    /* go through list of exempts and add each one */
    if (exemptlist && (rel_age >= 0)) {
        for (nn=0; exemptlist[nn];) {
            char *exempt = exemptlist + nn;
            struct exemptNode *en;
            while (exemptlist[nn] != ' ' && exemptlist[nn])
                nn++;
            while (exemptlist[nn] == ' ')
                exemptlist[nn++] = 0;
            en = calloc(1, sizeof(*en));
            safestrncpy(en->exempt, exempt, sizeof(en->exempt));
            safestrncpy(en->who, "<unknown>", sizeof(en->who));
            en->set = now;
            exemptList_append(&cNode->exemptlist, en);
        }
    }

    return cNode;
}
コード例 #18
0
/** Handle a JOIN message from a server 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 ms_join(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
{
  struct Membership *member;
  struct Channel *chptr;
  struct JoinBuf join;
  unsigned int flags;
  time_t creation = 0;
  char *p = 0;
  char *chanlist;
  char *name;

  if (IsServer(sptr))
  {
    return protocol_violation(cptr,
                              "%s tried to JOIN %s, duh!",
                              cli_name(sptr),
                              (parc < 2 || *parv[1] == '\0') ? "a channel" :
                                                               parv[1]
                              );
  }

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

  if (parc > 2 && parv[2])
    creation = atoi(parv[2]);

  joinbuf_init(&join, sptr, cptr, JOINBUF_TYPE_JOIN, 0, 0);

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

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

    flags = CHFL_DEOPPED;

    if (IsLocalChannel(name) || !IsChannelName(name))
    {
      protocol_violation(cptr, "%s tried to join %s", cli_name(sptr), name);
      continue;
    }

    if (!(chptr = FindChannel(name)))
    {
      /* No channel exists, so create one */
      if (!(chptr = get_channel(sptr, name, CGT_CREATE)))
      {
        protocol_violation(sptr,"couldn't get channel %s for %s",
        		   name,cli_name(sptr));
      	continue;
      }
      flags |= HasFlag(sptr, FLAG_TS8) ? CHFL_SERVOPOK : 0;

      chptr->creationtime = creation;
    }
    else { /* We have a valid channel? */
      if ((member = find_member_link(chptr, sptr)))
      {
	/* It is impossible to get here --Run */
	if (!IsZombie(member)) /* already on channel */
	  continue;

	flags = member->status & (CHFL_DEOPPED | CHFL_SERVOPOK);
	remove_user_from_channel(sptr, chptr);
	chptr = FindChannel(name);
      }
      else
        flags |= HasFlag(sptr, FLAG_TS8) ? CHFL_SERVOPOK : 0;
      /* Always copy the timestamp when it is older, that is the only way to
         ensure network-wide synchronization of creation times.
         We now also copy a creation time that only 1 second younger...
         this is needed because the timestamp must be incremented
         by one when someone joins an existing, but empty, channel.
         However, this is only necessary when the channel is still
         empty (also here) and when this channel doesn't have +A set.

         To prevent this from allowing net-rides on the channel, we
         clear all modes from the channel.

         (Scenario for a net ride: c1 - s1 - s2 - c2, with c1 the only
         user in the channel; c1 parts and rejoins, gaining ops.
         Before s2 sees c1's part, c2 joins the channel and parts
         immediately.  s1 sees c1 part, c1 create, c2 join, c2 part;
         c2's join resets the timestamp.  s2 sees c2 join, c2 part, c1
         part, c1 create; but since s2 sees the channel as a zannel or
         non-existent, it does not bounce the create with the newer
         timestamp.)
      */
      if (creation && (creation < chptr->creationtime ||
		       (!chptr->mode.apass[0] && chptr->users == 0))) {
        struct Membership *member;
        struct ModeBuf mbuf;

	chptr->creationtime = creation;
        /* Wipe out the current modes on the channel. */
        modebuf_init(&mbuf, sptr, cptr, chptr, MODEBUF_DEST_CHANNEL | MODEBUF_DEST_HACK3);

        modebuf_mode(&mbuf, MODE_DEL | chptr->mode.mode);
        chptr->mode.mode &= MODE_BURSTADDED | MODE_WASDELJOINS;

        if (chptr->mode.limit) {
          modebuf_mode_uint(&mbuf, MODE_DEL | MODE_LIMIT, chptr->mode.limit);
          chptr->mode.limit = 0;
        }

        if (chptr->mode.key[0]) {
          modebuf_mode_string(&mbuf, MODE_DEL | MODE_KEY, chptr->mode.key, 0);
          chptr->mode.key[0] = '\0';
        }

        if (chptr->mode.upass[0]) {
          modebuf_mode_string(&mbuf, MODE_DEL | MODE_UPASS, chptr->mode.upass, 0);
          chptr->mode.upass[0] = '\0';
        }

        if (chptr->mode.apass[0]) {
          modebuf_mode_string(&mbuf, MODE_DEL | MODE_APASS, chptr->mode.apass, 0);
          chptr->mode.apass[0] = '\0';
        }

        for (member = chptr->members; member; member = member->next_member)
        {
          if (IsChanOp(member)) {
            modebuf_mode_client(&mbuf, MODE_DEL | MODE_CHANOP, member->user, OpLevel(member));
	    member->status &= ~CHFL_CHANOP;
	  }
          if (HasVoice(member)) {
            modebuf_mode_client(&mbuf, MODE_DEL | MODE_VOICE, member->user, OpLevel(member));
	    member->status &= ~CHFL_VOICE;
          }
        }
        modebuf_flush(&mbuf);
      }
    }

    joinbuf_join(&join, chptr, flags);
  }

  joinbuf_flush(&join); /* flush joins... */

  return 0;
}
コード例 #19
0
/*
 * m_topic
 *      parv[0] = sender prefix
 *      parv[1] = channel name
 *	parv[2] = new topic, if setting topic
 */
static int
m_topic(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct Channel *chptr = NULL;
	struct membership *msptr;
	char *p = NULL;

	if((p = strchr(parv[1], ',')))
		*p = '\0';

	if(MyClient(source_p) && !IsFloodDone(source_p))
		flood_endgrace(source_p);

	if(!IsChannelName(parv[1]))
	{
		sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
				   form_str(ERR_NOSUCHCHANNEL), parv[1]);
		return 0;
	}

	chptr = find_channel(parv[1]);

	if(chptr == NULL)
	{
		sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
				form_str(ERR_NOSUCHCHANNEL), parv[1]);
		return 0;
	}

	/* setting topic */
	if(parc > 2)
	{
		msptr = find_channel_membership(chptr, source_p);

		if(msptr == NULL)
		{
			sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
					form_str(ERR_NOTONCHANNEL), parv[1]);
			return 0;
		}

		if((chptr->mode.mode & MODE_TOPICLIMIT) == 0 || is_chanop(msptr) || !MyClient(source_p))
		{
			char topic_info[USERHOST_REPLYLEN];
			ircsprintf(topic_info, "%s!%s@%s",
					source_p->name, source_p->username, source_p->host);
			set_channel_topic(chptr, parv[2], topic_info, CurrentTime);

			sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
					":%s TOPIC %s :%s",
					use_id(source_p), chptr->chname,
					chptr->topic == NULL ? "" : chptr->topic);
			sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
					":%s TOPIC %s :%s",
					source_p->name, chptr->chname,
					chptr->topic == NULL ? "" : chptr->topic);
			sendto_channel_local(ALL_MEMBERS,
					chptr, ":%s!%s@%s TOPIC %s :%s",
					source_p->name, source_p->username,
					source_p->host, chptr->chname,
					chptr->topic == NULL ? "" : chptr->topic);
		}
		else
			sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
					me.name, source_p->name, parv[1]);
	}
	else if(MyClient(source_p))
	{
		if(!IsMember(source_p, chptr) && SecretChannel(chptr))
		{
			sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
					form_str(ERR_NOTONCHANNEL), parv[1]);
			return 0;
		}
		if(chptr->topic == NULL)
			sendto_one(source_p, form_str(RPL_NOTOPIC),
					me.name, source_p->name, parv[1]);
		else
		{
			sendto_one(source_p, form_str(RPL_TOPIC),
					me.name, source_p->name, chptr->chname, chptr->topic);

			sendto_one(source_p, form_str(RPL_TOPICWHOTIME),
					me.name, source_p->name, chptr->chname,
					chptr->topic_info, chptr->topic_time);
		}
	}

	return 0;
}
コード例 #20
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;
}
コード例 #21
0
/** 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;
}
コード例 #22
0
ファイル: m_ban.c プロジェクト: AbstractBeliefs/charybdis
/* ms_ban()
 *
 * parv[1] - type
 * parv[2] - username mask or *
 * parv[3] - hostname mask
 * parv[4] - creation TS
 * parv[5] - duration (relative to creation)
 * parv[6] - lifetime (relative to creation)
 * parv[7] - oper or *
 * parv[8] - reason (possibly with |operreason)
 */
static int
ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	rb_dlink_node *ptr;
	struct ConfItem *aconf;
	unsigned int ntype;
	const char *oper, *stype;
	time_t now, created, hold, lifetime;
	char *p;
	int act;
	int valid;

	now = rb_current_time();
	if (strlen(parv[1]) != 1)
	{
		sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
				"Unknown BAN type %s from %s",
				parv[1], source_p->name);
		return 0;
	}
	switch (parv[1][0])
	{
		case 'K':
			ntype = CONF_KILL;
			stype = "K-Line";
			break;
		case 'X':
			ntype = CONF_XLINE;
			stype = "X-Line";
			break;
		case 'R':
			ntype = IsChannelName(parv[3]) ? CONF_RESV_CHANNEL :
				CONF_RESV_NICK;
			stype = "RESV";
			break;
		default:
			sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
					"Unknown BAN type %s from %s",
					parv[1], source_p->name);
			return 0;
	}
	created = atol(parv[4]);
	hold = created + atoi(parv[5]);
	lifetime = created + atoi(parv[6]);
	if (!strcmp(parv[7], "*"))
		oper = IsServer(source_p) ? source_p->name : get_oper_name(source_p);
	else
		oper = parv[7];
	ptr = find_prop_ban(ntype, parv[2], parv[3]);
	if (ptr != NULL)
	{
		/* We already know about this ban mask. */
		aconf = ptr->data;
		if (aconf->created > created ||
				(aconf->created == created &&
				 aconf->lifetime >= lifetime))
		{
			if (IsPerson(source_p))
				sendto_one_notice(source_p,
						":Your %s [%s%s%s] has been superseded",
						stype,
						aconf->user ? aconf->user : "",
						aconf->user ? "@" : "",
						aconf->host);
			return 0;
		}
		/* act indicates if something happened (from the oper's
		 * point of view). This is the case if the ban was
		 * previously active (not deleted) or if the new ban
		 * is not a removal and not already expired.
		 */
		act = !(aconf->status & CONF_ILLEGAL) || (hold != created &&
				hold > now);
		if (lifetime > aconf->lifetime)
			aconf->lifetime = lifetime;
		/* already expired, hmm */
		if (aconf->lifetime <= now)
			return 0;
		/* Deactivate, it will be reactivated later if appropriate. */
		deactivate_conf(aconf, ptr, now);
		rb_free(aconf->user);
		aconf->user = NULL;
		rb_free(aconf->host);
		aconf->host = NULL;
		operhash_delete(aconf->info.oper);
		aconf->info.oper = NULL;
		rb_free(aconf->passwd);
		aconf->passwd = NULL;
		rb_free(aconf->spasswd);
		aconf->spasswd = NULL;
	}
	else
	{
		/* New ban mask. */
		aconf = make_conf();
		aconf->status = CONF_ILLEGAL | ntype;
		aconf->lifetime = lifetime;
		rb_dlinkAddAlloc(aconf, &prop_bans);
		act = hold != created && hold > now;
	}
	aconf->flags &= ~CONF_FLAGS_MYOPER;
	aconf->flags |= CONF_FLAGS_TEMPORARY;
	aconf->user = ntype == CONF_KILL ? rb_strdup(parv[2]) : NULL;
	aconf->host = rb_strdup(parv[3]);
	aconf->info.oper = operhash_add(oper);
	aconf->created = created;
	aconf->hold = hold;
	if (ntype != CONF_KILL || (p = strchr(parv[parc - 1], '|')) == NULL)
		aconf->passwd = rb_strdup(parv[parc - 1]);
	else
	{
		aconf->passwd = rb_strndup(parv[parc - 1], p - parv[parc - 1] + 1);
		aconf->spasswd = rb_strdup(p + 1);
	}
	/* The ban is fully filled in and in the prop_bans list
	 * but still deactivated. Now determine if it should be activated
	 * and send the server notices.
	 */
	/* We only reject *@* and the like here.
	 * Otherwise malformed bans are fairly harmless and can be removed.
	 */
	switch (ntype)
	{
		case CONF_KILL:
			valid = valid_wild_card(aconf->user, aconf->host);
			break;
		case CONF_RESV_CHANNEL:
			valid = 1;
			break;
		default:
			valid = valid_wild_card_simple(aconf->host);
			break;
	}
	if (act && hold != created && !valid)
	{
		sendto_realops_snomask(SNO_GENERAL, L_ALL,
				       "Ignoring global %d min. %s from %s%s%s for [%s%s%s]: too few non-wildcard characters",
				       (int)((hold - now) / 60),
				       stype,
				       IsServer(source_p) ? source_p->name : get_oper_name(source_p),
				       strcmp(parv[7], "*") ? " on behalf of " : "",
				       strcmp(parv[7], "*") ? parv[7] : "",
				       aconf->user ? aconf->user : "",
				       aconf->user ? "@" : "",
				       aconf->host);
		if(IsPerson(source_p))
			sendto_one_notice(source_p,
					":Your %s [%s%s%s] has too few non-wildcard characters",
					stype,
					aconf->user ? aconf->user : "",
					aconf->user ? "@" : "",
					aconf->host);
		/* Propagate it, but do not apply it locally. */
	}
	else if (act && hold != created)
	{
		/* Keep the notices in sync with modules/m_kline.c etc. */
		sendto_realops_snomask(SNO_GENERAL, L_ALL,
				       "%s added global %d min. %s%s%s for [%s%s%s] [%s]",
				       IsServer(source_p) ? source_p->name : get_oper_name(source_p),
				       (int)((hold - now) / 60),
				       stype,
				       strcmp(parv[7], "*") ? " from " : "",
				       strcmp(parv[7], "*") ? parv[7] : "",
				       aconf->user ? aconf->user : "",
				       aconf->user ? "@" : "",
				       aconf->host,
				       parv[parc - 1]);
		ilog(L_KLINE, "%s %s %d %s%s%s %s", parv[1],
				IsServer(source_p) ? source_p->name : get_oper_name(source_p),
				(int)((hold - now) / 60),
				aconf->user ? aconf->user : "",
				aconf->user ? " " : "",
				aconf->host,
				parv[parc - 1]);
		aconf->status &= ~CONF_ILLEGAL;
	}
	else if (act)
	{
		sendto_realops_snomask(SNO_GENERAL, L_ALL,
				"%s has removed the global %s for: [%s%s%s]%s%s",
				IsServer(source_p) ? source_p->name : get_oper_name(source_p),
				stype,
				aconf->user ? aconf->user : "",
				aconf->user ? "@" : "",
				aconf->host,
				strcmp(parv[7], "*") ? " on behalf of " : "",
				strcmp(parv[7], "*") ? parv[7] : "");
		ilog(L_KLINE, "U%s %s %s%s %s", parv[1],
				IsServer(source_p) ? source_p->name : get_oper_name(source_p),
				aconf->user ? aconf->user : "",
				aconf->user ? " " : "",
				aconf->host);
	}
	/* If CONF_ILLEGAL is still set at this point, remove entries from the
	 * reject cache (for klines and xlines).
	 * If CONF_ILLEGAL is not set, add the ban to the type-specific data
	 * structure and take action on matched clients/channels.
	 */
	switch (ntype)
	{
		case CONF_KILL:
			if (aconf->status & CONF_ILLEGAL)
				remove_reject_mask(aconf->user, aconf->host);
			else
			{
				add_conf_by_address(aconf->host, CONF_KILL, aconf->user, NULL, aconf);
				if(ConfigFileEntry.kline_delay ||
						(IsServer(source_p) &&
						 !HasSentEob(source_p)))
				{
					if(kline_queued == 0)
					{
						rb_event_addonce("check_klines", check_klines_event, NULL,
							ConfigFileEntry.kline_delay ?
								ConfigFileEntry.kline_delay : 1);
						kline_queued = 1;
					}
				}
				else
					check_klines();
			}
			break;
		case CONF_XLINE:
			if (aconf->status & CONF_ILLEGAL)
				remove_reject_mask(aconf->host, NULL);
			else
			{
				rb_dlinkAddAlloc(aconf, &xline_conf_list);
				check_xlines();
			}
			break;
		case CONF_RESV_CHANNEL:
			if (!(aconf->status & CONF_ILLEGAL))
			{
				add_to_resv_hash(aconf->host, aconf);
				resv_chan_forcepart(aconf->host, aconf->passwd, hold - now);
			}
			break;
		case CONF_RESV_NICK:
			if (!(aconf->status & CONF_ILLEGAL))
				rb_dlinkAddAlloc(aconf, &resv_conf_list);
			break;
	}
	sendto_server(client_p, NULL, CAP_BAN|CAP_TS6, NOCAPS,
			":%s BAN %s %s %s %s %s %s %s :%s",
			source_p->id,
			parv[1],
			parv[2],
			parv[3],
			parv[4],
			parv[5],
			parv[6],
			parv[7],
			parv[parc - 1]);
	return 0;
}
コード例 #23
0
ファイル: m_sajoin.c プロジェクト: cyocom/Technokats-Website
/* m_sajoin() - Lamego - Wed Jul 21 20:04:48 1999
   Copied off PTlink IRCd (C) PTlink coders team.
   Coded for Sadmin by Stskeeps
   also Modified by NiQuiL ([email protected])
	parv[0] - sender
	parv[1] - nick to make join
	parv[2] - channel(s) to join
*/
DLLFUNC CMD_FUNC(m_sajoin)
{
	aClient *acptr;
	char jbuf[BUFSIZE];
	int did_anything = 0;

	if (!IsSAdmin(sptr) && !IsULine(sptr))
	{
	 sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
	 return 0;
	}

	if (parc < 3)
	{
	 sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "SAJOIN");
	 return 0;
	}

	if (!(acptr = find_person(parv[1], NULL)))
	{
		sendto_one(sptr, err_str(ERR_NOSUCHNICK), me.name, parv[0], parv[1]);
		return 0;
	}
	if (MyClient(acptr))
	{
		char *name, *p = NULL;
		int i, parted = 0;
	
		*jbuf = 0;

		/* Now works like m_join */
		for (i = 0, name = strtoken(&p, parv[2], ","); name; name = strtoken(&p,
		     NULL, ","))
		{
			aChannel *chptr;
			Membership *lp;

			if (strlen(name) > CHANNELLEN)
				name[CHANNELLEN] = 0;
			clean_channelname(name);
			if (*name == '0' && !atoi(name))
			{
				(void)strcpy(jbuf, "0");
				i = 1;
				parted = 1;
				continue;
			}
			if (check_channelmask(sptr, cptr, name) == -1 || *name == '0' ||
			    !IsChannelName(name))
			{
				sendto_one(sptr,
				    err_str(ERR_NOSUCHCHANNEL), me.name,
				    parv[0], name);
				continue;
			}

			chptr = get_channel(acptr, name, 0);
			if (!parted && chptr && (lp = find_membership_link(acptr->user->channel, chptr)))
			{
				sendto_one(sptr, err_str(ERR_USERONCHANNEL), me.name, parv[0], 
					   parv[1], name);
				continue;
			}
			if (*jbuf)
				(void)strlcat(jbuf, ",", sizeof jbuf);
			(void)strlncat(jbuf, name, sizeof jbuf, sizeof(jbuf) - i - 1);
			i += strlen(name) + 1;
		}
		if (!*jbuf)
			return -1;
		i = 0;
		strcpy(parv[2], jbuf);
		*jbuf = 0;
		for (name = strtoken(&p, parv[2], ","); name; name = strtoken(&p, NULL, ","))
		{
			int flags;
			aChannel *chptr;
			Membership *lp;

			if (*name == '0' && !atoi(name))
			{
				did_anything = 1;
				while ((lp = acptr->user->channel))
				{
					chptr = lp->chptr;
					sendto_channel_butserv(chptr, acptr,
					    ":%s PART %s :%s", acptr->name, chptr->chname,
					    "Left all channels");
					if (MyConnect(acptr))
						RunHook4(HOOKTYPE_LOCAL_PART, acptr, acptr, chptr,
							 "Left all channels");
					remove_user_from_channel(acptr, chptr);
				}
				sendto_serv_butone_token(acptr, acptr->name,
				    MSG_JOIN, TOK_JOIN, "0");
				strcpy(jbuf, "0");
				i = 1;
				continue;
			}
			flags = (ChannelExists(name)) ? CHFL_DEOPPED : CHFL_CHANOP;
			chptr = get_channel(acptr, name, CREATE);
			if (chptr && (lp = find_membership_link(acptr->user->channel, chptr)))
				continue;
			if ((chptr->mode.mode & MODE_ONLYSECURE) && !IsSecure(acptr))
			{
				sendnotice(sptr, "You cannot SAJOIN %s to %s because the channel is +z and the user is not connected via SSL",
					acptr->name, chptr->chname);
				continue;
			}
			join_channel(chptr, acptr, acptr, flags);
			did_anything = 1;
			if (*jbuf)
				(void)strlcat(jbuf, ",", sizeof jbuf);
			(void)strlncat(jbuf, name, sizeof jbuf, sizeof(jbuf) - i - 1);
			i += strlen(name) + 1;
		}
		
		if (did_anything)
		{
			sendnotice(acptr, "*** You were forced to join %s", jbuf);
			sendto_realops("%s used SAJOIN to make %s join %s", sptr->name, acptr->name,
				       jbuf);
			sendto_serv_butone(&me, ":%s GLOBOPS :%s used SAJOIN to make %s join %s",
					   me.name, sptr->name, acptr->name, jbuf);
			/* Logging function added by XeRXeS */
			ircd_log(LOG_SACMDS,"SAJOIN: %s used SAJOIN to make %s join %s",
				sptr->name, parv[1], jbuf);
		}
	}
	else
	{
		sendto_one(acptr, ":%s SAJOIN %s %s", parv[0],
		    parv[1], parv[2]);

		/* Logging function added by XeRXeS */
		ircd_log(LOG_SACMDS,"SAJOIN: %s used SAJOIN to make %s join %s",
			sptr->name, parv[1], parv[2]);
	}

	return 0;
}
コード例 #24
0
ファイル: m_testline.c プロジェクト: Cloudxtreme/ircd-ratbox
static int
mo_testline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct ConfItem *aconf;
	struct ConfItem *resv_p;
	struct rb_sockaddr_storage ip;
	const char *name = NULL;
	const char *username = NULL;
	const char *host = NULL;
	char *mask;
	char *p;
	int host_mask;
	int type;

	mask = LOCAL_COPY(parv[1]);

	if(IsChannelName(mask))
	{
		resv_p = hash_find_resv(mask);
		if(resv_p != NULL)
		{
			sendto_one(source_p, form_str(RPL_TESTLINE),
				   me.name, source_p->name,
				   (resv_p->flags & CONF_FLAGS_TEMPORARY) ? 'q' : 'Q',
				   (resv_p->flags & CONF_FLAGS_TEMPORARY) ? (long)((resv_p->hold -
										    rb_current_time
										    ()) / 60) : 0L,
				   resv_p->host, resv_p->passwd);
			/* this is a false positive, so make sure it isn't counted in stats q
			 * --nenolod
			 */
			resv_p->port--;
		}
		else
			sendto_one(source_p, form_str(RPL_NOTESTLINE),
				   me.name, source_p->name, parv[1]);
		return 0;
	}

	if((p = strchr(mask, '!')))
	{
		*p++ = '\0';
		name = mask;
		mask = p;

		if(EmptyString(mask))
			return 0;
	}

	if((p = strchr(mask, '@')))
	{
		*p++ = '\0';
		username = mask;
		host = p;

		if(EmptyString(host))
			return 0;
	}
	else
		host = mask;

	/* parses as an IP, check for a dline */
	if((type = parse_netmask(host, (struct sockaddr *)&ip, &host_mask)) != HM_HOST)
	{
		aconf = find_dline((struct sockaddr *)&ip);

		if(aconf && aconf->status & CONF_DLINE)
		{
			sendto_one(source_p, form_str(RPL_TESTLINE),
				   me.name, source_p->name,
				   (aconf->flags & CONF_FLAGS_TEMPORARY) ? 'd' : 'D',
				   (aconf->flags & CONF_FLAGS_TEMPORARY) ?
				   (long)((aconf->hold - rb_current_time()) / 60) : 0L,
				   aconf->host, aconf->passwd);

			return 0;
		}
	}

	/* now look for a matching I/K/G */
	if((aconf = find_address_conf(host, NULL, username ? username : "******",
				      (type != HM_HOST) ? (struct sockaddr *)&ip : NULL,
				      (type != HM_HOST) ? (
#ifdef RB_IPV6
										(type ==
										 HM_IPV6) ? AF_INET6
										:
#endif
										AF_INET) : 0)))
	{
		static char buf[HOSTLEN + USERLEN + 2];

		if(aconf->status & CONF_KILL)
		{
			rb_snprintf(buf, sizeof(buf), "%s@%s", aconf->user, aconf->host);
			sendto_one(source_p, form_str(RPL_TESTLINE),
				   me.name, source_p->name,
				   (aconf->flags & CONF_FLAGS_TEMPORARY) ? 'k' : 'K',
				   (aconf->flags & CONF_FLAGS_TEMPORARY) ?
				   (long)((aconf->hold - rb_current_time()) / 60) : 0L,
				   buf, aconf->passwd);
			return 0;
		}
		else if(aconf->status & CONF_GLINE)
		{
			rb_snprintf(buf, sizeof(buf), "%s@%s", aconf->user, aconf->host);
			sendto_one(source_p, form_str(RPL_TESTLINE),
				   me.name, source_p->name,
				   'G', (long)((aconf->hold - rb_current_time()) / 60),
				   buf, aconf->passwd);
			return 0;
		}
	}

	/* they asked us to check a nick, so hunt for resvs.. */
	if(name && (resv_p = find_nick_resv(name)))
	{
		sendto_one(source_p, form_str(RPL_TESTLINE),
			   me.name, source_p->name,
			   (resv_p->flags & CONF_FLAGS_TEMPORARY) ? 'q' : 'Q',
			   (resv_p->flags & CONF_FLAGS_TEMPORARY) ? (long)((resv_p->hold -
									    rb_current_time()) /
									   60) : 0L, resv_p->host,
			   resv_p->passwd);

		/* this is a false positive, so make sure it isn't counted in stats q
		 * --nenolod
		 */
		resv_p->port--;
		return 0;
	}

	/* no matching resv, we can print the I: if it exists */
	if(aconf && aconf->status & CONF_CLIENT)
	{
		sendto_one_numeric(source_p, RPL_STATSILINE, form_str(RPL_STATSILINE),
				   aconf->info.name, show_iline_prefix(source_p, aconf,
								       aconf->user), aconf->host,
				   aconf->port, get_class_name(aconf));
		return 0;
	}

	/* nothing matches.. */
	sendto_one(source_p, form_str(RPL_NOTESTLINE), me.name, source_p->name, parv[1]);
	return 0;
}
コード例 #25
0
void CMAlign::ReadMAlign()
{
	FILE* GCGFile;
	char* pch="Multiple Sequence Alignment GCG format (*.gcg or *.msf)\0*.gcg\0*.msf\0\0";
	CFileDialog aFileDlg( true, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT|OFN_EXPLORER|OFN_ENABLESIZING, NULL, NULL );
	aFileDlg.m_ofn.lpstrFilter=pch;
	char aString[80];
	vector <bool> bAssigned;
	bool bReadChannelName=false;
	if(aFileDlg.DoModal()==IDOK)
	{
		m_sMAlignFileName=aFileDlg.GetPathName();
		GCGFile=fopen(m_sMAlignFileName,"r");
		m_nNumOfSeq=0;
		while(!feof(GCGFile))
		{
			fscanf(GCGFile,"%s",aString);
			if(strcmp(aString,"Name:")==0)
			{
				fscanf(GCGFile,"%s",aString);
				m_nNumOfSeq++;
				bAssigned.push_back(false);
				m_vectsSeqNames.push_back(aString);
			}
			if(strcmp(aString,"//")==0)
			{
				while(!feof(GCGFile))
				{
					for(int i=0;i<m_nNumOfSeq;i++)					
					{
						if(!bReadChannelName)fscanf(GCGFile,"%s",aString);
						bReadChannelName=false;
						for(int j=0;j<5;j++)
						{
							if(!feof(GCGFile))
							{
								fscanf(GCGFile,"%s",aString);
								if(IsChannelName(aString))
								{
									j=5;
									bReadChannelName=true;
								}
								else
								{
									if(!(bAssigned[i]))
									{
										m_vectsSequence.push_back(aString);
										bAssigned[i]=true;
									}
									else
									{
										m_vectsSequence[i].append(aString);
									}
								}
							}
						}
					}
				}			
			}
		}
	}
	PositionConversion();
	OutputMAlign();
}
コード例 #26
0
ファイル: m_knock.c プロジェクト: CustomIRCd/elemental-ircd
/* m_knock
 *    parv[1] = channel
 *
 *  The KNOCK command has the following syntax:
 *   :<sender> KNOCK <channel>
 *
 *  If a user is not banned from the channel they can use the KNOCK
 *  command to have the server NOTICE the channel operators notifying
 *  they would like to join.  Helpful if the channel is invite-only, the
 *  key is forgotten, or the channel is full (INVITE can bypass each one
 *  of these conditions.  Concept by Dianora <*****@*****.**> and written by
 *  <anonymous>
 */
static int
m_knock(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
    struct Channel *chptr;
    char *p, *name;

    if(MyClient(source_p) && ConfigChannel.use_knock == 0) {
        sendto_one(source_p, form_str(ERR_KNOCKDISABLED),
                   me.name, source_p->name);
        return 0;
    }

    name = LOCAL_COPY(parv[1]);

    /* dont allow one knock to multiple chans */
    if((p = strchr(name, ',')))
        *p = '\0';

    if(!IsChannelName(name)) {
        sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
                           form_str(ERR_NOSUCHCHANNEL), name);
        return 0;
    }

    if((chptr = find_channel(name)) == NULL) {
        sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
                           form_str(ERR_NOSUCHCHANNEL), name);
        return 0;
    }

    if(IsMember(source_p, chptr)) {
        if(MyClient(source_p))
            sendto_one(source_p, form_str(ERR_KNOCKONCHAN),
                       me.name, source_p->name, name);
        return 0;
    }

    if(!((chptr->mode.mode & MODE_INVITEONLY) || (*chptr->mode.key) ||
         (chptr->mode.limit &&
          rb_dlink_list_length(&chptr->members) >= (unsigned long)chptr->mode.limit))) {
        sendto_one_numeric(source_p, ERR_CHANOPEN,
                           form_str(ERR_CHANOPEN), name);
        return 0;
    }

    /* cant knock to a +p channel */
    if(HiddenChannel(chptr)) {
        sendto_one_numeric(source_p, ERR_CANNOTSENDTOCHAN,
                           form_str(ERR_CANNOTSENDTOCHAN), name, "channel does not accept knocks");
        return 0;
    }


    if(MyClient(source_p)) {
        /* don't allow a knock if the user is banned */
        if(is_banned(chptr, source_p, NULL, NULL, NULL) == CHFL_BAN ||
           is_quieted(chptr, source_p, NULL, NULL, NULL) == CHFL_BAN) {
            sendto_one_numeric(source_p, ERR_CANNOTSENDTOCHAN,
                               form_str(ERR_CANNOTSENDTOCHAN), name, "you are banned from this channel");
            return 0;
        }

        /* local flood protection:
         * allow one knock per user per knock_delay
         * allow one knock per channel per knock_delay_channel
         */
        if(!IsOper(source_p) &&
           (source_p->localClient->last_knock + ConfigChannel.knock_delay) > rb_current_time()) {
            sendto_one(source_p, form_str(ERR_TOOMANYKNOCK),
                       me.name, source_p->name, name, "user");
            return 0;
        } else if((chptr->last_knock + ConfigChannel.knock_delay_channel) > rb_current_time()) {
            sendto_one(source_p, form_str(ERR_TOOMANYKNOCK),
                       me.name, source_p->name, name, "channel");
            return 0;
        }

        /* ok, we actually can send the knock, tell client */
        source_p->localClient->last_knock = rb_current_time();

        sendto_one(source_p, form_str(RPL_KNOCKDLVR),
                   me.name, source_p->name, name);
    }

    chptr->last_knock = rb_current_time();

    if(ConfigChannel.use_knock)
        sendto_channel_local(chptr->mode.mode & MODE_FREEINVITE ? ALL_MEMBERS : ONLY_CHANOPS,
                             chptr, form_str(RPL_KNOCK),
                             me.name, name, name, source_p->name,
                             source_p->username, source_p->host);

    sendto_server(client_p, chptr, CAP_KNOCK|CAP_TS6, NOCAPS,
                  ":%s KNOCK %s", use_id(source_p), name);
    sendto_server(client_p, chptr, CAP_KNOCK, CAP_TS6,
                  ":%s KNOCK %s", source_p->name, name);
    return 0;
}
コード例 #27
0
ファイル: m_testline.c プロジェクト: viatsko/charybdis
static int
mo_testline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct ConfItem *aconf;
	struct ConfItem *resv_p;
	struct rb_sockaddr_storage ip;
	char user_trunc[USERLEN + 1], notildeuser_trunc[USERLEN + 1];
	const char *name = NULL;
	const char *username = NULL;
	const char *host = NULL;
	char *mask;
	char *p;
	int host_mask;
	int type;
	int duration;
	char *puser, *phost, *reason, *operreason;
	char reasonbuf[BUFSIZE];

	mask = LOCAL_COPY(parv[1]);

	if (IsChannelName(mask))
	{
		resv_p = hash_find_resv(mask);
		if (resv_p != NULL)
		{
			sendto_one(source_p, form_str(RPL_TESTLINE),
					me.name, source_p->name,
					resv_p->hold ? 'q' : 'Q',
					resv_p->hold ? (long) ((resv_p->hold - rb_current_time()) / 60) : 0L,
					resv_p->host, resv_p->passwd);
			/* this is a false positive, so make sure it isn't counted in stats q
			 * --nenolod
			 */
			resv_p->port--;
		}
		else
			sendto_one(source_p, form_str(RPL_NOTESTLINE),
					me.name, source_p->name, parv[1]);
		return 0;
	}

	if((p = strchr(mask, '!')))
	{
		*p++ = '\0';
		name = mask;
		mask = p;

		if(EmptyString(mask))
			return 0;
	}

	if((p = strchr(mask, '@')))
	{
		*p++ = '\0';
		username = mask;
		host = p;

		if(EmptyString(host))
			return 0;
	}
	else
		host = mask;

	/* parses as an IP, check for a dline */
	if((type = parse_netmask(host, &ip, &host_mask)) != HM_HOST)
	{
#ifdef RB_IPV6
		if(type == HM_IPV6)
			aconf = find_dline((struct sockaddr *)&ip, AF_INET6);
		else
#endif
			aconf = find_dline((struct sockaddr *)&ip, AF_INET);

		if(aconf && aconf->status & CONF_DLINE)
		{
			get_printable_kline(source_p, aconf, &phost, &reason, &puser, &operreason);
			snprintf(reasonbuf, sizeof(reasonbuf), "%s%s%s", reason,
				operreason ? "|" : "", operreason ? operreason : "");
			sendto_one(source_p, form_str(RPL_TESTLINE),
				me.name, source_p->name,
				(aconf->flags & CONF_FLAGS_TEMPORARY) ? 'd' : 'D',
				(aconf->flags & CONF_FLAGS_TEMPORARY) ?
				 (long) ((aconf->hold - rb_current_time()) / 60) : 0L,
				phost, reasonbuf);

			return 0;
		}
		/* Otherwise, aconf is an exempt{} */
		if(aconf == NULL &&
				(duration = is_reject_ip((struct sockaddr *)&ip)))
			sendto_one(source_p, form_str(RPL_TESTLINE),
					me.name, source_p->name,
					'!',
					duration / 60L,
					host, "Reject cache");
		if(aconf == NULL &&
				(duration = is_throttle_ip((struct sockaddr *)&ip)))
			sendto_one(source_p, form_str(RPL_TESTLINE),
					me.name, source_p->name,
					'!',
					duration / 60L,
					host, "Throttled");
	}

	if (username != NULL)
	{
		rb_strlcpy(user_trunc, username, sizeof user_trunc);
		rb_strlcpy(notildeuser_trunc, *username == '~' ? username + 1 : username, sizeof notildeuser_trunc);
	}
	else
	{
		rb_strlcpy(user_trunc, "dummy", sizeof user_trunc);
		rb_strlcpy(notildeuser_trunc, "dummy", sizeof notildeuser_trunc);
	}
	/* now look for a matching I/K/G */
	if((aconf = find_address_conf(host, NULL, user_trunc, notildeuser_trunc,
				(type != HM_HOST) ? (struct sockaddr *)&ip : NULL,
				(type != HM_HOST) ? (
#ifdef RB_IPV6
				 (type == HM_IPV6) ? AF_INET6 :
#endif
				  AF_INET) : 0, NULL)))
	{
		static char buf[HOSTLEN+USERLEN+2];

		if(aconf->status & CONF_KILL)
		{
			get_printable_kline(source_p, aconf, &phost, &reason, &puser, &operreason);
			snprintf(buf, sizeof(buf), "%s@%s",
					puser, phost);
			snprintf(reasonbuf, sizeof(reasonbuf), "%s%s%s", reason,
				operreason ? "|" : "", operreason ? operreason : "");
			sendto_one(source_p, form_str(RPL_TESTLINE),
				me.name, source_p->name,
				(aconf->flags & CONF_FLAGS_TEMPORARY) ? 'k' : 'K',
				(aconf->flags & CONF_FLAGS_TEMPORARY) ?
				 (long) ((aconf->hold - rb_current_time()) / 60) : 0L,
				buf, reasonbuf);
			return 0;
		}
	}

	/* they asked us to check a nick, so hunt for resvs.. */
	if(name && (resv_p = find_nick_resv(name)))
	{
		sendto_one(source_p, form_str(RPL_TESTLINE),
				me.name, source_p->name,
				resv_p->hold ? 'q' : 'Q',
				resv_p->hold ? (long) ((resv_p->hold - rb_current_time()) / 60) : 0L,
				resv_p->host, resv_p->passwd);

		/* this is a false positive, so make sure it isn't counted in stats q
		 * --nenolod
		 */
		resv_p->port--;
		return 0;
	}

	/* no matching resv, we can print the I: if it exists */
	if(aconf && aconf->status & CONF_CLIENT)
	{
		sendto_one_numeric(source_p, RPL_STATSILINE, form_str(RPL_STATSILINE),
				aconf->info.name, EmptyString(aconf->spasswd) ? "<NULL>" : aconf->spasswd,
				show_iline_prefix(source_p, aconf, aconf->user),
				aconf->host, aconf->port, aconf->className);
		return 0;
	}

	/* nothing matches.. */
	sendto_one(source_p, form_str(RPL_NOTESTLINE),
			me.name, source_p->name, parv[1]);
	return 0;
}
コード例 #28
0
/*
** m_who
**      parv[0] = sender prefix
**      parv[1] = nickname mask list
**      parv[2] = additional selection flag, only 'o' for now.
*/
int     m_who(struct Client *cptr,
              struct Client *sptr,
              int parc,
              char *parv[])
{
  struct Client *acptr;
  char  *mask = parc > 1 ? parv[1] : NULL;
  Link  *lp;
  struct Channel *chptr;
  struct Channel *mychannel = NULL;
  char  *channame = NULL;
  int   oper = parc > 2 ? (*parv[2] == 'o' ): 0; /* Show OPERS only */
  int   member;
  int   maxmatches = 500;

  mychannel = NullChn;
  if (sptr->user)
    if ((lp = sptr->user->channel))
      mychannel = lp->value.chptr;

  /*
  **  Following code is some ugly hacking to preserve the
  **  functions of the old implementation. (Also, people
  **  will complain when they try to use masks like "12tes*"
  **  and get people on channel 12 ;) --msa
  */
  if (mask)
    {
      if (!strcmp(mask, "**"))
        mask = NULL;
      else if (*mask == (char) 0)
        mask = NULL;
      else
        (void)collapse(mask);
    }
  if (!mask || (*mask == (char) 0))
    {
      if (!HasUmode(sptr,UMODE_USER_AUSPEX))
        {
          sendto_one(sptr, form_str(RPL_ENDOFWHO), me.name, parv[0],
                     EmptyString(mask) ?  "*" : mask);
          return 0;
        }
    }
  else if ((*(mask+1) == (char) 0) && (*mask == '*'))
    {
      if (!mychannel)
        {
          sendto_one(sptr, form_str(RPL_ENDOFWHO), me.name, parv[0],
                     EmptyString(mask) ?  "*" : mask);
          return 0;
        }
      channame = mychannel->chname;
    }
  else
    channame = mask;

  if (IsChannelName(channame))
    {
      /*
       * List all users on a given channel
       */
      if (!oper || SeesOpers(sptr)) /* If you're doing an oper search, you need SeesOpers() */
	{
	  chptr = hash_find_channel(channame, NULL);
	  if (chptr)
	    {
	      member = IsMember(sptr, chptr) || IsLogger(sptr, chptr) || HasUmode(sptr,UMODE_USER_AUSPEX);
	      if (member || !SecretChannel(chptr))
		for (lp = chptr->members; lp; lp = lp->next)
		  {
		    if (oper && !HasUmode(lp->value.cptr,UMODE_OPER))
		      continue;
		    if (IsInvisible(lp->value.cptr) && !member)
		      continue;
		    do_who(sptr, lp->value.cptr, chptr, lp);
		  }
	    }
	}
    }
  else if (mask && 
           ((acptr = find_client(mask, NULL)) != NULL) &&
           IsPerson(acptr) && (!oper || (HasUmode(acptr,UMODE_OPER) && SeesOpers(sptr))))
    {
      int isinvis = 0;
      struct Channel *ch2ptr = NULL;

      isinvis = IsInvisible(acptr);
      for (lp = acptr->user->channel; lp; lp = lp->next)
        {
          chptr = lp->value.chptr;
          member = IsMember(sptr, chptr) || HasUmode(sptr,UMODE_USER_AUSPEX);
          if (isinvis && !member)
            continue;
          if (member || (!isinvis && PubChannel(chptr)))
            {
              ch2ptr = chptr;
              break;
            }
        }
      do_who(sptr, acptr, ch2ptr, NULL);
    }
  else if (!oper || SeesOpers(sptr))
    for (acptr = GlobalClientList; acptr; acptr = acptr->next)
    {
      struct Channel *ch2ptr = NULL;
      int       showperson, isinvis;

      if (!IsPerson(acptr))
        continue;
      if (oper && !HasUmode(acptr,UMODE_OPER))
        continue;
      
      showperson = 0;
      /*
       * Show user if they are on the same channel, or not
       * invisible and on a non secret channel (if any).
       * Do this before brute force match on all relevant fields
       * since these are less cpu intensive (I hope :-) and should
       * provide better/more shortcuts - avalon
       */
      isinvis = IsInvisible(acptr);
      for (lp = acptr->user->channel; lp; lp = lp->next)
        {
          chptr = lp->value.chptr;
          member = IsMember(sptr, chptr) || HasUmode(sptr, UMODE_USER_AUSPEX);
          if (isinvis && !member)
            continue;
          if (member || (!isinvis && PubChannel(chptr)))
            {
              ch2ptr = chptr;
              showperson = 1;
              break;
            }
          if (HiddenChannel(chptr) && !SecretChannel(chptr) &&
              !isinvis)
            showperson = 1;
        }
      if (!acptr->user->channel && !isinvis)
        showperson = 1;
        
      if ((HasUmode(sptr,UMODE_USER_AUSPEX) || showperson) &&
          (!mask ||
           match(mask, acptr->name) ||
           match(mask, acptr->username) ||
           match(mask, acptr->host) ||
           (HasUmode(sptr, UMODE_AUSPEX) && match(mask, acptr->user->server)) ||
           match(mask, acptr->info)))
        {
          do_who(sptr, acptr, ch2ptr, NULL);
          if (!HasUmode(sptr,UMODE_USER_AUSPEX) && !--maxmatches)
            {
              sendto_one(sptr, form_str(RPL_ENDOFWHO), me.name, parv[0],
                         EmptyString(mask) ?  "*" : mask);
              return 0;
            }
        }
    }

  sendto_one(sptr, form_str(RPL_ENDOFWHO), me.name, parv[0],
             EmptyString(mask) ?  "*" : mask);
  return 0;
}
コード例 #29
0
/* Join a channel, ignoring forwards, +ib, etc. It notifes source_p of any errors joining
 * NB: this assumes a local user.
 */
void user_join_override(struct Client * client_p, struct Client * source_p, struct Client * target_p, const char * channels)
{
	static char jbuf[BUFSIZE];
	struct ConfItem *aconf;
	struct Channel *chptr = NULL;
	char *name;
	const char *modes;
	char *p = NULL;
	int flags;
	char *chanlist;

	jbuf[0] = '\0';

	if(channels == NULL)
		return;

	/* rebuild the list of channels theyre supposed to be joining. */
	chanlist = LOCAL_COPY(channels);
	for(name = rb_strtok_r(chanlist, ",", &p); name; name = rb_strtok_r(NULL, ",", &p))
	{
		/* check the length and name of channel is ok */
		if(!check_channel_name_loc(target_p, name) || (strlen(name) > LOC_CHANNELLEN))
		{
			sendto_one_numeric(source_p, ERR_BADCHANNAME,
					   form_str(ERR_BADCHANNAME), (unsigned char *) name);
			continue;
		}

		/* join 0 parts all channels */
		if(*name == '0' && (name[1] == ',' || name[1] == '\0') && name == chanlist)
		{
			(void) strcpy(jbuf, "0");
			continue;
		}

		/* check it begins with # or & */
		else if(!IsChannelName(name))
		{
			sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
					   form_str(ERR_NOSUCHCHANNEL), name);
			continue;
		}

		/* see if its resv'd */
		if(!IsExemptResv(target_p) && (aconf = hash_find_resv(name)))
		{
			sendto_one_numeric(source_p, ERR_BADCHANNAME,
					   form_str(ERR_BADCHANNAME), name);

			/* dont update tracking for jupe exempt users, these
			 * are likely to be spamtrap leaves
			 */
			if(IsExemptJupe(source_p))
				aconf->port--;

			continue;
		}

		if(splitmode && !IsOper(target_p) && (*name != '&') &&
		   ConfigChannel.no_join_on_split)
		{
			sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
				   me.name, source_p->name, name);
			continue;
		}

		if(*jbuf)
			(void) strcat(jbuf, ",");
		(void) rb_strlcat(jbuf, name, sizeof(jbuf));
	}

	for(name = rb_strtok_r(jbuf, ",", &p); name; name = rb_strtok_r(NULL, ",", &p))
	{
		/* JOIN 0 simply parts all channels the user is in */
		if(*name == '0' && !atoi(name))
		{
			if(target_p->user->channel.head == NULL)
				continue;

			do_join_0(&me, target_p);
			continue;
		}
		
		if((chptr = find_channel(name)) != NULL)
		{
			if(IsMember(target_p, chptr))
			{
				/* debugging is fun... */
				sendto_one_notice(source_p, ":*** Notice -- %s is already in %s",
					 target_p->name, chptr->chname);
				return;
			}

			add_user_to_channel(chptr, target_p, CHFL_PEON);
			if (chptr->mode.join_num && rb_current_time() - chptr->join_delta >= chptr->mode.join_time)
			{
				chptr->join_count = 0;
				chptr->join_delta = rb_current_time();
			}
			chptr->join_count++;

			sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN :%s",
					     target_p->name, target_p->username,
					     target_p->host, chptr->chname);

			sendto_server(target_p, chptr, CAP_TS6, NOCAPS,
				      ":%s JOIN %ld %s +",
				      get_id(target_p, client_p), (long) chptr->channelts,
				      chptr->chname);

			del_invite(chptr, target_p);

			if(chptr->topic != NULL)
			{
				sendto_one(target_p, form_str(RPL_TOPIC), me.name,
				   target_p->name, chptr->chname, chptr->topic);
				sendto_one(target_p, form_str(RPL_TOPICWHOTIME),
					   me.name, source_p->name, chptr->chname,
					   chptr->topic_info, chptr->topic_time);
			}

			channel_member_names(chptr, target_p, 1);
		}
		else
		{
			hook_data_channel_activity hook_info;
			char statusmodes[5] = "";

			if(!check_channel_name(name))
			{
				sendto_one(source_p, form_str(ERR_BADCHANNAME), me.name,
					   source_p->name, (unsigned char *) name);
				return;
			}

			/* channel name must begin with & or # */
			if(!IsChannelName(name))
			{
				sendto_one(source_p, form_str(ERR_BADCHANNAME), me.name,
					   source_p->name, (unsigned char *) name);
				return;
			}

			/* name can't be longer than CHANNELLEN */
			if(strlen(name) > CHANNELLEN)
			{
				sendto_one_notice(source_p, ":Channel name is too long");
				return;
			}

			chptr = get_or_create_channel(target_p, name, NULL);

			flags = CHFL_CHANOP;
			
			add_user_to_channel(chptr, target_p, flags);
			if (chptr->mode.join_num &&
					rb_current_time() - chptr->join_delta >= chptr->mode.join_time)
			{
				chptr->join_count = 0;
				chptr->join_delta = rb_current_time();
			}
			chptr->join_count++;
			
			sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN :%s",
					     target_p->name, target_p->username,
					     target_p->host, chptr->chname);
		
				chptr->mode.mode |= MODE_TOPICLIMIT;
				chptr->mode.mode |= MODE_NOPRIVMSGS;

			modes = channel_modes(chptr, &me);
			sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s %s",
					     me.name, chptr->chname, modes);

			strcat(statusmodes, "@");

			sendto_server(target_p, chptr, CAP_TS6, NOCAPS,
				      ":%s SJOIN %ld %s %s :%s%s",
				      me.id, (long) chptr->channelts,
				      chptr->chname, modes, statusmodes,
				      get_id(target_p, client_p));

			target_p->localClient->last_join_time = rb_current_time();
			channel_member_names(chptr, target_p, 1);

			/* Call channel join hooks */
			hook_info.client = source_p;
			hook_info.chptr = chptr;
			hook_info.key = chptr->mode.key;
			call_hook(h_channel_join, &hook_info);

			/* we do this to let the oper know that a channel was created, this will be
			 * seen from the server handling the command instead of the server that
			 * the oper is on.
			 */
			sendto_one_notice(source_p, ":*** Notice -- Creating channel %s", chptr->chname);
		}
	}		


	return;
}
コード例 #30
0
ファイル: m_topic.c プロジェクト: Cloudxtreme/ircd-seven
/*
 * m_topic
 *      parv[1] = channel name
 *	parv[2] = new topic, if setting topic
 */
static int
m_topic(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct Channel *chptr = NULL;
	struct membership *msptr;
	char *p = NULL;
	const char *name;
	int operspy = 0;

	if((p = strchr(parv[1], ',')))
		*p = '\0';

	name = parv[1];

	if(IsOperAuspex(source_p) && parv[1][0] == '!')
	{
		name++;
		operspy = 1;

		if(EmptyString(name))
		{
			sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
					me.name, source_p->name, "TOPIC");
			return 0;
		}
	}

	if(MyClient(source_p) && !IsFloodDone(source_p))
		flood_endgrace(source_p);

	if(!IsChannelName(name))
	{
		sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
				   form_str(ERR_NOSUCHCHANNEL), name);
		return 0;
	}

	chptr = find_channel(name);

	if(chptr == NULL)
	{
		sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
				form_str(ERR_NOSUCHCHANNEL), name);
		return 0;
	}

	/* setting topic */
	if(parc > 2)
	{
		char topic_info[USERHOST_REPLYLEN];
		char topic[BUFSIZE];

		msptr = find_channel_membership(chptr, source_p);

		if(msptr == NULL)
		{
			sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
					form_str(ERR_NOTONCHANNEL), name);
			return 0;
		}

		if(MyClient(source_p) && !is_chanop_voiced(msptr) &&
				!IsOper(source_p) &&
				!add_channel_target(source_p, chptr))
		{
			sendto_one(source_p, form_str(ERR_TARGCHANGE),
				   me.name, source_p->name, chptr->chname);
			return 0;
		}

		if(MyClient(source_p) && !(((chptr->mode.mode & MODE_TOPICLIMIT) == 0 ||
					is_chanop(msptr)) &&
				 can_send(chptr, source_p, msptr)))
		{
			if(IsOverride(source_p))
				sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
						"%s is overriding TOPIC on [%s]",
						get_oper_name(source_p), chptr->chname);
			else
			{
				sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
						get_id(&me, source_p),
						get_id(source_p, source_p), name);
				return 0;
			}
		}

		rb_strlcpy(topic, parv[2], BUFSIZE);
		strip_colour(topic);

		rb_sprintf(topic_info, "%s!%s@%s",
				source_p->name, source_p->username, source_p->host);
		set_channel_topic(chptr, topic, topic_info, rb_current_time());

		sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
				":%s TOPIC %s :%s",
				use_id(source_p), chptr->chname,
				chptr->topic == NULL ? "" : chptr->topic);
		sendto_channel_local(ALL_MEMBERS,
				chptr, ":%s!%s@%s TOPIC %s :%s",
				source_p->name, source_p->username,
				source_p->host, chptr->chname,
				chptr->topic == NULL ? "" : chptr->topic);
	}
	else if(MyClient(source_p))
	{
		if(operspy)
			report_operspy(source_p, "TOPIC", chptr->chname);
		if(!IsMember(source_p, chptr) && SecretChannel(chptr) &&
				!operspy)
		{
			sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
					form_str(ERR_NOTONCHANNEL), name);
			return 0;
		}
		if(chptr->topic == NULL)
			sendto_one(source_p, form_str(RPL_NOTOPIC),
					me.name, source_p->name, name);
		else
		{
			sendto_one(source_p, form_str(RPL_TOPIC),
					me.name, source_p->name, chptr->chname, chptr->topic);

			sendto_one(source_p, form_str(RPL_TOPICWHOTIME),
					me.name, source_p->name, chptr->chname,
					chptr->topic_info, chptr->topic_time);
		}
	}

	return 0;
}