コード例 #1
0
ファイル: m_mode.c プロジェクト: KSoute/oftc-hybrid
/*
 * ms_tmode()
 *
 * inputs	- parv[0] = UID
 *		  parv[1] = TS
 *		  parv[2] = channel name
 *		  parv[3] = modestring
 */
static void
ms_tmode(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
{
  struct Channel *chptr = NULL;
  struct Membership *member = NULL;

  if ((chptr = hash_find_channel(parv[2])) == NULL)
  {
    sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
               ID_or_name(&me, client_p), ID_or_name(source_p, client_p), parv[2]);
    return;
  }

  if (atol(parv[1]) > chptr->channelts)
    return;

  if (IsServer(source_p))
    set_channel_mode(client_p, source_p, chptr, NULL, parc - 3, parv + 3, chptr->chname);
  else
  {
    member = find_channel_link(source_p, chptr);

    /* XXX are we sure we just want to bail here? */
    if (has_member_flags(member, CHFL_DEOPPED))
      return;

    set_channel_mode(client_p, source_p, chptr, member, parc - 3, parv + 3, chptr->chname);
  }
}
コード例 #2
0
static void 
ms_cburst(struct Client *client_p, struct Client *source_p,
          int parc, char *parv[])
{
  char *name;
  char *nick;
  const char *key;
  struct Channel *chptr;

  if (parc < 2 || *parv[1] == '\0' )
     return;

  name = parv[1];

  if (parc > 2)
    nick = parv[2];
  else
    nick = NULL;

  if (parc > 3)
    key = parv[3];
  else
    key = "";

#ifdef DEBUGLL
  sendto_realops_flags(UMODE_ALL, L_ALL, "CBURST called by %s for %s %s %s",
                       client_p->name, name, nick ? nick : "", key ? key : "");
#endif
  if ((chptr = hash_find_channel(name)) == NULL)
  {
    if ((!nick) || (nick && *nick != '!'))
    {
      chptr = get_or_create_channel(source_p, name, NULL);
      chptr->channelts = (time_t)(-1); /* highest possible TS so its always
					* over-ruled
                                        */
    }
    else if(nick && *nick=='!')
    {
      sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
                 me.name, nick+1, name);
      return;
    }
  }

  if (IsCapable(client_p,CAP_LL))
  {
    burst_channel(client_p,chptr);

    if (nick)
      sendto_one(client_p, ":%s LLJOIN %s %s %s",
                 me.name, name, nick, key);
  }
  else
  {
    sendto_realops_flags(UMODE_ALL, L_ALL,
                         "*** CBURST request received from non LL capable server! [%s]",
                         client_p->name);
    }
}
コード例 #3
0
ファイル: hash.c プロジェクト: BackupTheBerlios/phoenixfn-svn
/*
 * add_to_channel_hash_table
 */
void add_to_channel_hash_table(const char* name, struct Channel* chptr)
{
  struct Channel *achptr;
  unsigned int hashv;
  assert(0 != name);
  assert(0 != chptr);

  if ((achptr = hash_find_channel(name, NULL)))
    {
      sendto_ops_flag(UMODE_DEBUG, "WTF: Already got %s in hash table but something tried to add it again, dumping core",
		      name);
      logprintf(L_WARN, "WTF: Already got %s in hash table but something tried to add it again, dumping core",
	  name);
      flush_connections(0);
      abort();
    }
  hashv = hash_channel_name(name);
  if ((channelTable[hashv].links == 0) && (channelTable[hashv].list != NULL))
    {
      sendto_ops_flag(UMODE_DEBUG, "WTF: channelTable[%d].links == 0 but list not NULL. Whacking list...",
		      hashv);
      logprintf(L_WARN, "WTF: channelTable[%d].links == 0 but list not NULL. Whacking list...",
	  hashv);
      channelTable[hashv].list = NULL;
    }
  chptr->hnextch = (struct Channel*) channelTable[hashv].list;
  channelTable[hashv].list = (void*) chptr;
  ++channelTable[hashv].links;
  ++channelTable[hashv].hits;
}
コード例 #4
0
ファイル: m_list.c プロジェクト: Cloudxtreme/ircd-3
/*
 * list_named_channel
 * inputs       - pointer to client requesting list
 * output       - 0/1
 * side effects	- list all channels to source_p
 */
static int list_named_channel(struct Client *source_p,char *name)
{
  struct Channel *chptr;
  char id_and_topic[TOPICLEN+NICKLEN+6]; /* <!!>, space and null */
  char *p;
#ifdef VCHANS
  dlink_node *ptr;
  struct Channel *root_chptr;
  struct Channel *tmpchptr;
#endif

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

  while (*name == ',')
    name++;
  if ((p = strchr(name,',')) != NULL)
    *p = '\0';
  if (!*name)
    return;

  chptr = hash_find_channel(name);
  if (chptr == NULL)
    {
      sendto_one(source_p, form_str(source_p,ERR_NOSUCHNICK),me.name, source_p->name, name);
      sendto_one(source_p, form_str(source_p,RPL_LISTEND), me.name, source_p->name);
      return 0;
    }

#ifdef VCHANS
  if (HasVchans(chptr))
    ircsprintf(id_and_topic, "<!%s> %s", pick_vchan_id(chptr), chptr->topic == NULL ? "" : chptr->topic );
  else
#endif
    ircsprintf(id_and_topic, "%s", chptr->topic == NULL ? "" : chptr->topic);

  if (ShowChannel(source_p, chptr))
    sendto_one(source_p, form_str(source_p,RPL_LIST), me.name, source_p->name,
               chptr->chname, chptr->users, id_and_topic);
      
  /* Deal with subvchans */
 
#ifdef VCHANS
  for (ptr = chptr->vchan_list.head; ptr; ptr = ptr->next)
    {
      tmpchptr = ptr->data;

      if (ShowChannel(source_p, tmpchptr))
	{
          root_chptr = find_bchan(tmpchptr);
          ircsprintf(id_and_topic, "<!%s> %s", pick_vchan_id(tmpchptr), tmpchptr->topic == NULL ? "" : chptr->topic);
          sendto_one(source_p, form_str(source_p,RPL_LIST), me.name, source_p->name,
                     root_chptr->chname, tmpchptr->users, id_and_topic);
        }
    }
#endif
  
  sendto_one(source_p, form_str(source_p,RPL_LISTEND), me.name, source_p->name);
  return 0;
}
コード例 #5
0
ファイル: m_mode.c プロジェクト: diegoagudo/ptlink.ircd
/*
 * m_mode - MODE command handler
 * parv[0] - sender
 * parv[1] - channel
 */
int m_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
{
  struct Channel* chptr;
  static char     modebuf[MODEBUFLEN];
  static char     parabuf[MODEBUFLEN];
  char *mename = me.name;

  if(sptr->user && sptr->user->vlink)
    mename = sptr->user->vlink->name;
     
  /* Now, try to find the channel in question */
  if (parc > 1)
    {
      if( IsChanPrefix(parv[1][0]) )
        {
          /* Don't do any of this stuff at all
           * unless it looks like a channel name 
           */

          if (!check_channel_name(parv[1]))
            { 
              sendto_one(sptr, form_str(ERR_BADCHANNAME),
                         mename, parv[0], (unsigned char *)parv[1]);
              return 0;
            }

          chptr = hash_find_channel(parv[1], NullChn);
          if (!chptr)
            return user_mode(cptr, sptr, parc, parv);
        }
      else
        {
          /* if here, it has to be a non-channel name */
          return user_mode(cptr, sptr, parc, parv);
        }
    }
  else
    {
      sendto_one(sptr, form_str(ERR_NEEDMOREPARAMS),
                 mename, parv[0], "MODE");
      return 0;
    }

  if (parc < 3)
    {
      *modebuf = *parabuf = '\0';
      modebuf[1] = '\0';
      channel_modes(sptr, modebuf, parabuf, chptr, 0);
      sendto_one(sptr, form_str(RPL_CHANNELMODEIS), mename, parv[0],
                 chptr->chname, modebuf, parabuf);
      sendto_one(sptr, form_str(RPL_CREATIONTIME), mename, parv[0],
                 chptr->chname, chptr->channelts);
      return 0;
    }

  set_channel_mode(cptr, sptr, chptr, parc - 2, parv + 2);

  return 0;
}
コード例 #6
0
ファイル: m_topic.c プロジェクト: jmaurice/ircd-hybrid
static void
ms_topic(struct Client *client_p, struct Client *source_p,
         int parc, char *parv[])
{
  struct Channel *chptr = NULL;
  const char *from, *to;
  char topic_info[USERHOST_REPLYLEN];

  if (IsCapable(source_p->from, CAP_TS6) && HasID(source_p))
  {
    from = me.id;
    to = source_p->id;
  }
  else
  {
    from = me.name;
    to = source_p->name;
  }

  if (EmptyString(parv[1]))
  {
    sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
               from, to, "TOPIC");
    return;
  }

  if ((chptr = hash_find_channel(parv[1])) == NULL)
  {
    sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
               from, to, parv[1]);
    return;
  }

  if (!IsClient(source_p))
    strlcpy(topic_info, source_p->name, sizeof(topic_info));
  else
    snprintf(topic_info, sizeof(topic_info), "%s!%s@%s", source_p->name,
             source_p->username, source_p->host);
  set_channel_topic(chptr, parv[2], topic_info, CurrentTime, 0);

  sendto_server(client_p, CAP_TS6, NOCAPS, ":%s TOPIC %s :%s",
                ID(source_p), chptr->chname,
                chptr->topic);
  sendto_server(client_p, NOCAPS, CAP_TS6, ":%s TOPIC %s :%s",
                source_p->name, chptr->chname,
                chptr->topic);

  if (!IsClient(source_p))
    sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s TOPIC %s :%s",
                         source_p->name,
                         chptr->chname, chptr->topic);

  else
    sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s!%s@%s TOPIC %s :%s",
                         source_p->name,
                         source_p->username,
                         source_p->host,
                         chptr->chname, chptr->topic);
}
コード例 #7
0
ファイル: m_part.c プロジェクト: KSoute/oftc-hybrid
/* part_one_client()
 *
 * inputs	- pointer to server
 * 		- pointer to source client to remove
 *		- char pointer of name of channel to remove from
 * output	- none
 * side effects	- remove ONE client given the channel name 
 */
static void
part_one_client(struct Client *client_p, struct Client *source_p,
                const char *name, char *reason)
{
  struct Channel *chptr = NULL;
  struct Membership *ms = NULL;

  if ((chptr = hash_find_channel(name)) == NULL)
  {
    sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
               me.name, source_p->name, name);
    return;
  }

  if ((ms = find_channel_link(source_p, chptr)) == NULL)
  {
    sendto_one(source_p, form_str(ERR_NOTONCHANNEL),
               me.name, source_p->name, name);
    return;
  }

  if (MyConnect(source_p) && !IsOper(source_p))
    check_spambot_warning(source_p, NULL);

  /*
   *  Remove user from the old channel (if any)
   *  only allow /part reasons in -m chans
   */
  if(msg_has_colors(reason) && (chptr->mode.mode & MODE_NOCOLOR)) 
    reason = strip_color(reason); 
  
  if (reason[0] && (!MyConnect(source_p) ||
      ((can_send(chptr, source_p, ms) &&
       (source_p->firsttime + ConfigFileEntry.anti_spam_exit_message_time)
        < CurrentTime))))
  {
    sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
                  ":%s PART %s :%s", ID(source_p), chptr->chname,
                  reason);
    sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
                  ":%s PART %s :%s", source_p->name, chptr->chname,
                  reason);
    sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s!%s@%s PART %s :%s",
                         source_p->name, source_p->username,
                         source_p->host, chptr->chname, reason);
  }
  else
  {
    sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
                  ":%s PART %s", ID(source_p), chptr->chname);
    sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
                  ":%s PART %s", source_p->name, chptr->chname);
    sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s!%s@%s PART %s",
                         source_p->name, source_p->username,
                         source_p->host, chptr->chname);
  }

  remove_user_from_channel(ms);
}
コード例 #8
0
ファイル: m_mode.c プロジェクト: jmdh/ircd-hybrid
/*! \brief MODE command handler
 *
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = command
 *      - parv[1] = channel or nick name
 *      - parv[2] = modes to be added or removed
 */
static int
m_mode(struct Client *source_p, int parc, char *parv[])
{
  struct Channel *chptr = NULL;

  if (EmptyString(parv[1]))
  {
    sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "MODE");
    return 0;
  }

  /* Now, try to find the channel in question */
  if (!IsChanPrefix(*parv[1]))
  {
    /* If here, it has to be a non-channel name */
    set_user_mode(source_p, parc, parv);
    return 0;
  }

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

  /* Now known the channel exists */
  if (parc < 3)
  {
    char modebuf[MODEBUFLEN] = "";
    char parabuf[MODEBUFLEN] = "";

    channel_modes(chptr, source_p, modebuf, parabuf);
    sendto_one_numeric(source_p, &me, RPL_CHANNELMODEIS, chptr->name, modebuf, parabuf);
    sendto_one_numeric(source_p, &me, RPL_CREATIONTIME, chptr->name, chptr->creationtime);
    return 0;
  }

  /*
   * bounce all modes from people we deop on sjoin
   * servers have always gotten away with murder,
   * including telnet servers *g* - Dianora
   */
  if (IsServer(source_p) || HasFlag(source_p, FLAGS_SERVICE))
    set_channel_mode(source_p, chptr, NULL, parc - 2, parv + 2);
  else
  {
    struct Membership *member = find_channel_link(source_p, chptr);

    /* Finish the flood grace period... */
    if (MyClient(source_p) && !IsFloodDone(source_p))
      if (!((parc == 3) && (parv[2][0] == 'b') && (parv[2][1] == '\0')))
        flood_endgrace(source_p);

    set_channel_mode(source_p, chptr, member, parc - 2, parv + 2);
  }

  return 0;
}
コード例 #9
0
ファイル: parse.c プロジェクト: ircd-hybrid/ircd-hybrid
/*
 *
 *      parc    number of arguments ('sender' counted as one!)
 *      parv[0] pointer to 'sender' (may point to empty string) (not used)
 *      parv[1]..parv[parc-1]
 *              pointers to additional parameters, this is a NULL
 *              terminated list (parv[parc] == NULL).
 *
 * *WARNING*
 *      Numerics are mostly error reports. If there is something
 *      wrong with the message, just *DROP* it! Don't even think of
 *      sending back a neat error message -- big danger of creating
 *      a ping pong error message...
 *
 * Rewritten by Nemesi, Jan 1999, to support numeric nicks in parv[1]
 *
 * Called when we get a numeric message from a remote _server_ and we are
 * supposed to forward it somewhere. Note that we always ignore numerics sent
 * to 'me' and simply drop the message if we can't handle with this properly:
 * the savvy approach is NEVER generate an error in response to an... error :)
 */
static void
parse_handle_numeric(unsigned int numeric, struct Client *source_p, int parc, char *parv[])
{
  struct Client *target_p = NULL;
  struct Channel *chptr = NULL;

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

  /*
   * 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 (IsChanPrefix(*parv[1]))
    chptr = hash_find_channel(parv[1]);
  else
    target_p = find_person(source_p, parv[1]);

  if ((target_p == NULL || target_p->from == source_p->from) && chptr == NULL)
    return;

  /*
   * 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;

  if (target_p)
  {
    /* Fake it for server hiding, if it's our client */
    if ((ConfigServerHide.hide_servers || IsHidden(source_p)) && MyConnect(target_p) &&
        !HasUMode(target_p, UMODE_OPER))
      sendto_one_numeric(target_p, &me, numeric | SND_EXPLICIT, "%s", parv[2]);
    else
      sendto_one_numeric(target_p, source_p, numeric | SND_EXPLICIT, "%s", parv[2]);
  }
  else
    sendto_channel_butone(source_p, source_p, chptr, 0, "%u %s %s",
                          numeric, chptr->name, parv[2]);
}
コード例 #10
0
ファイル: m_part.c プロジェクト: BackupTheBerlios/shadowircd
/*
 * part_one_client
 *
 * inputs	- pointer to server
 * 		- pointer to source client to remove
 *		- char pointer of name of channel to remove from
 * output	- none
 * side effects	- remove ONE client given the channel name 
 */
static void
part_one_client(struct Client *client_p, struct Client *source_p, char *name, char *reason)
{
	struct Channel *chptr;
	struct membership *msptr;

	if((chptr = hash_find_channel(name)) == NULL)
	{
		sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), me.name, source_p->name, name);
		return;
	}

	msptr = find_channel_membership(chptr, source_p);
	if(msptr == NULL)
	{
		sendto_one(source_p, form_str(ERR_NOTONCHANNEL), me.name, source_p->name, name);
		return;
	}
	if(MyConnect(source_p) && !IsOper(source_p) && 
	   !IsExemptSpambot(source_p))
		check_spambot_warning(source_p, NULL);

	/*
	 *  Remove user from the old channel (if any)
	 *  only allow /part reasons in -m chans
	 */
	if(reason[0] && (is_chanop(msptr) || !MyConnect(source_p) ||
			 ((can_send(chptr, source_p, msptr) > 0 &&
			   (source_p->firsttime + ConfigFileEntry.anti_spam_exit_message_time)
			   < CurrentTime))))
	{
		sendto_server(client_p, chptr, NOCAPS, NOCAPS,
			      ":%s PART %s :%s", source_p->name, chptr->chname, reason);

		sendto_channel_local(ALL_MEMBERS,
				     chptr, ":%s!%s@%s PART %s :%s",
				     source_p->name,
				     source_p->username, source_p->host, chptr->chname, reason);
	}
	else
	{
		sendto_server(client_p, chptr, NOCAPS, NOCAPS,
			      ":%s PART %s", source_p->name, chptr->chname);

		sendto_channel_local(ALL_MEMBERS,
				     chptr, ":%s!%s@%s PART %s",
				     source_p->name,
				     source_p->username, source_p->host, chptr->chname);
	}
	remove_user_from_channel(msptr);
}
コード例 #11
0
ファイル: m_names.c プロジェクト: ircd-hybrid/ircd-hybrid
/*! \brief NAMES command handler
 *
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = command
 *      - parv[1] = channel name
 */
static int
m_names(struct Client *source_p, int parc, char *parv[])
{
  const char *const para = parc > 1 ? parv[1] : NULL;

  if (!EmptyString(para))
  {
    struct Channel *chptr = hash_find_channel(para);
    if (chptr)
      channel_member_names(source_p, chptr, true);
    else
      sendto_one_numeric(source_p, &me, RPL_ENDOFNAMES, para);
  }
  else
    sendto_one_numeric(source_p, &me, RPL_ENDOFNAMES, "*");

  return 0;
}
コード例 #12
0
ファイル: m_tmode.c プロジェクト: chipyzs/ircd-hybrid
/*! \brief TMODE command handler
 *
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = command
 *      - parv[1] = timestamp
 *      - parv[2] = channel name
 *      - parv[3] = modes to be added or removed
 */
static int
ms_tmode(struct Client *source_p, int parc, char *parv[])
{
  struct Channel *chptr = NULL;

  assert(!MyClient(source_p));

  if ((chptr = hash_find_channel(parv[2])) == NULL)
  {
    sendto_one_numeric(source_p, &me, ERR_NOSUCHCHANNEL, parv[2]);
    return 0;
  }

  if (strtoimax(parv[1], NULL, 10) > chptr->creationtime)
    return 0;

  set_channel_mode(source_p, chptr, NULL, parc - 3, parv + 3);
  return 0;
}
コード例 #13
0
ファイル: m_topic.c プロジェクト: Cloudxtreme/ircd-hybrid
/*! \brief TOPIC command handler
 *
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = command
 *      - parv[1] = channel name
 *      - parv[2] = topic text
 */
static int
ms_topic(struct Client *source_p, int parc, char *parv[])
{
  struct Channel *chptr = NULL;
  char topic_info[USERHOST_REPLYLEN];

  if (EmptyString(parv[1]))
  {
    sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "TOPIC");
    return 0;
  }

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

  if (!IsClient(source_p))
    strlcpy(topic_info, source_p->name, sizeof(topic_info));
  else
    snprintf(topic_info, sizeof(topic_info), "%s!%s@%s", source_p->name,
             source_p->username, source_p->host);
  channel_set_topic(chptr, parv[2], topic_info, CurrentTime, 0);

  sendto_server(source_p, 0, 0, ":%s TOPIC %s :%s",
                source_p->id, chptr->name,
                chptr->topic);

  if (!IsClient(source_p))
    sendto_channel_local(0, chptr, ":%s TOPIC %s :%s",
                        (IsHidden(source_p) || ConfigServerHide.hide_servers) ? me.name : source_p->name,
                         chptr->name, chptr->topic);

  else
    sendto_channel_local(0, chptr, ":%s!%s@%s TOPIC %s :%s",
                         source_p->name,
                         source_p->username,
                         source_p->host,
                         chptr->name, chptr->topic);
  return 0;
}
コード例 #14
0
/* ms_tburst()
 * 
 *      parv[0] = sender prefix
 *      parv[1] = channel timestamp
 *      parv[2] = channel
 *      parv[3] = topic timestamp
 *      parv[4] = topic setter
 *      parv[5] = topic
 */
static void
ms_tburst(struct Client *client_p, struct Client *source_p,
          int parc, char *parv[])
{
  struct Channel *chptr;
  time_t newchannelts = atol(parv[1]);
  time_t newtopicts = atol(parv[3]);

  if((chptr = hash_find_channel(parv[2])))
  {
    /* Don't allow newly created channels to change the topic ever,
     * only change the topic if we are on the old channel TS with
     * a new topic_time. -metalrock
     */
    if (chptr->channelts > newchannelts)
      return;
    else if (chptr->topic == NULL || (chptr->topic_time > newtopicts))
      set_topic(source_p, chptr, newtopicts, parv[4], parv[5]);
  }
}
コード例 #15
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);
	}
    }
}
コード例 #16
0
ファイル: m_drop.c プロジェクト: Adam-/oftc-hybrid
/*
** ms_drop
**      parv[0] = sender prefix
**      parv[1] = channel
**      parv[2] = channel password (key)
**
**      "drop" a channel from consideration on a lazy link
*/
static void
ms_drop(struct Client *client_p, struct Client *source_p,
	int parc, char *parv[])
{
  char *name;
  struct Channel *chptr;

  if(parc < 2 || *parv[1] == '\0')
    return;

  name = parv[1];

#ifdef DEBUGLL
  sendto_realops(UMODE_ALL, "DROP called by %s for %s", client_p->name, name );
#endif

  if((chptr=hash_find_channel(name)) == NULL)
    return;

  if(client_p->localClient->serverMask) /* JIC */
    chptr->lazyLinkChannelExists &= ~client_p->localClient->serverMask;
  return;
}
コード例 #17
0
ファイル: m_tburst.c プロジェクト: KSoute/oftc-hybrid
static void
ms_tb(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
{
  struct Channel *chptr;
  time_t tb_topicts = atol(tb_topicts_str);
  char *tb_whoset = NULL;
  char *tb_topic = NULL;

  if ((chptr = hash_find_channel(tb_channel)) == NULL)
    return;

  if (parc == 5)
  {
    tb_whoset = parv[3];
    tb_topic = parv[4];
  }
  else
  {
    tb_whoset = source_p->name;
    tb_topic = parv[3];
  }

  set_topic(source_p, chptr, tb_topicts, tb_whoset, tb_topic);
}
コード例 #18
0
ファイル: m_ojoin.c プロジェクト: BackupTheBerlios/shadowircd
/* mo_ojoin()
 *      parv[0] = sender prefix
 *      parv[1] = channels separated by commas (#ifdef OJOIN_MULTIJOIN)
 */
static void
mo_ojoin(struct Client *client_p, struct Client *source_p,
         int parc, char *parv[])
{
    struct Channel *chptr;
    char *name = parv[1], modeletter;
#ifdef OJOIN_MULTIJOIN
    char *t;
#endif
    short move_me = 1;
    unsigned int tmp_flags;

    /* admins only */
    if (!IsAdmin(source_p))
    {
        sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
                   me.name, source_p->name);
        return;
    }

#ifdef OJOIN_MULTIJOIN
    for (name = strtoken (&t, name, ","); name;
            name = strtoken (&t, NULL, ","))
    {
#endif

        move_me = 1;

        switch (*name)
        {
#ifndef DISABLE_CHAN_OWNER
        case '!':
            tmp_flags = CHFL_CHANOWNER;
            modeletter = 'u';
            name++;
            break;
#endif
        case '@':
            tmp_flags = CHFL_CHANOP;
            modeletter = 'o';
            name++;
            break;
        case '+':
            tmp_flags = CHFL_VOICE;
            modeletter = 'v';
            name++;
            break;
        case '%':
            tmp_flags = CHFL_HALFOP;
            modeletter = 'h';
            name++;
            break;
        case '#':
        case '&':
            tmp_flags = 0;
            modeletter = '\0';
            break;

        /* We're not joining a channel, or we don't know the mode,
        * what ARE we joining? */
        default:
            sendto_one (source_p, form_str(ERR_NOSUCHCHANNEL),
                        me.name, source_p->name, name);

#ifdef OJOIN_MULTIJOIN
            continue;
#else
            return;
#endif
        }

        /* Error checking here */

        if ((chptr = hash_find_channel(name)) == NULL)
        {
            sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
                       me.name, source_p->name, name);
        }

        else if (IsMember(source_p, chptr))
        {
            sendto_one(source_p, ":%s NOTICE %s :Please part %s before using OJOIN",
                       me.name, source_p->name, name);
        }

        else
        {
            if (move_me == 1)
                name--;

            add_user_to_channel(chptr, source_p, tmp_flags);

            if (chptr->chname[0] == '#')
            {
                sendto_server(client_p, CAP_TS6, NOCAPS,
                              ":%s SJOIN %lu %s + :%c%s",
                              me.id, (unsigned long)chptr->channelts, chptr->chname,
                              (modeletter != '\0') ? *name : ' ',
                              source_p->id);
                sendto_server(client_p, NOCAPS, CAP_TS6,
                              ":%s SJOIN %lu %s + :%c%s", me.name,
                              (unsigned long)chptr->channelts,
                              chptr->chname, (modeletter != '\0') ? *name : ' ',
                              source_p->name);
            }

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

            if (modeletter != '\0')
            {
                sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +%c %s",
                                     me.name, chptr->chname, modeletter, source_p->name);
            }

            /* send the topic... */
            if (chptr->topic != NULL)
            {
                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);
            }

            source_p->localClient->last_join_time = CurrentTime;
            channel_member_names(source_p, chptr, 1);
        }
#ifdef OJOIN_MULTIJOIN
    }
#endif
}
コード例 #19
0
ファイル: m_bmask.c プロジェクト: caivega/ircd-hybrid
/*! \brief BMASK command handler
 *
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = command
 *      - parv[1] = timestamp
 *      - parv[2] = channel name
 *      - parv[3] = type of ban to add ('b' 'I' or 'e')
 *      - parv[4] = space delimited list of masks to add
 */
static int
ms_bmask(struct Client *source_p, int parc, char *parv[])
{
  char modebuf[IRCD_BUFSIZE] = "";
  char parabuf[IRCD_BUFSIZE] = "";
  char banbuf[IRCD_BUFSIZE] = "";
  struct Channel *chptr = NULL;
  char *s, *t, *mbuf, *pbuf;
  unsigned int mode_type = 0;
  int mlen = 0, tlen = 0;
  int modecount = 0;

  if ((chptr = hash_find_channel(parv[2])) == NULL)
    return 0;

  /* TS is higher, drop it. */
  if (atol(parv[1]) > chptr->channelts)
    return 0;

  switch (*parv[3])
  {
    case 'b':
      mode_type = CHFL_BAN;
      break;
    case 'e':
      mode_type = CHFL_EXCEPTION;
      break;
    case 'I':
      mode_type = CHFL_INVEX;
      break;
    default:
      return 0;
  }

  strlcpy(banbuf, parv[4], sizeof(banbuf));
  s = banbuf;

  mlen = snprintf(modebuf, sizeof(modebuf), ":%s MODE %s +",
                  (IsHidden(source_p) || ConfigServerHide.hide_servers) ? me.name : source_p->name,
                  chptr->chname);
  mbuf = modebuf + mlen;
  pbuf = parabuf;

  do
  {
    if ((t = strchr(s, ' ')))
      *t++ = '\0';
    tlen = strlen(s);

    /* I don't even want to begin parsing this.. */
    if (tlen > MODEBUFLEN)
      break;

    if (tlen && *s != ':' && add_id(source_p, chptr, s, mode_type))
    {
      /* this new one wont fit.. */
      if (mbuf - modebuf + 2 + pbuf - parabuf + tlen > IRCD_BUFSIZE - 2 ||
          modecount >= MAXMODEPARAMS)
      {
        *mbuf = *(pbuf - 1) = '\0';

        sendto_channel_local(ALL_MEMBERS, 0, chptr, "%s %s", modebuf, parabuf);
        mbuf = modebuf + mlen;
        pbuf = parabuf;
        modecount = 0;
      }

      *mbuf++ = *parv[3];
      pbuf += sprintf(pbuf, "%s ", s);
      ++modecount;
    }

    s = t;
  } while (s);

  if (modecount)
  {
    *mbuf = *(pbuf - 1) = '\0';
    sendto_channel_local(ALL_MEMBERS, 0, chptr, "%s %s", modebuf, parabuf);
  }

  sendto_server(source_p, NOCAPS, NOCAPS, ":%s BMASK %lu %s %s :%s",
                source_p->id, (unsigned long)chptr->channelts, chptr->chname,
                parv[3], parv[4]);
  return 0;
}
コード例 #20
0
/*
** m_list
**      parv[0] = sender prefix
**      parv[1] = channel
*/
int     m_list(struct Client *cptr,
               struct Client *sptr,
               int parc,
               char *parv[])
{
  struct Channel *chptr;
  char  *name, *p = NULL;
  /* anti flooding code,
   * I did have this in parse.c with a table lookup
   * but I think this will be less inefficient doing it in each
   * function that absolutely needs it
   *
   * -Dianora
   */
  static time_t last_used=0L;
  int i,j,minusers;
  minusers = HasUmode(sptr,UMODE_USER_AUSPEX) ? 0 : MIN_USERS_FOR_LIST;

  /* throw away non local list requests that do get here -Dianora */
  if(!MyConnect(sptr))
    return 0;

  if(!NoFloodProtection(sptr))
    {
      if(IsHoneypot(sptr) || (((last_used + PACE_WAIT) > CurrentTime) && (!IsDoingList(sptr))))
        {
          sendto_one(sptr,form_str(RPL_LOAD2HI),me.name,parv[0],"LIST");
	  sendto_one(sptr,form_str(RPL_LISTEND),me.name,parv[0]);
          return 0;
        }
      else
        last_used = CurrentTime;
    }

  /* right.. if we are already involved in a "blocked" /list, we will simply
     continue where we left off */
  if (IsDoingList(sptr)) {
    if (sptr->listprogress != -1) {
      for (i=sptr->listprogress; i<CH_MAX; i++) {
        int progress2 = sptr->listprogress2;
        for (j=0, chptr=(struct Channel*)(hash_get_channel_block(i).list);
             (chptr) && (j<hash_get_channel_block(i).links); chptr=chptr->hnextch, j++) {
          if (j<progress2) continue;  /* wind up to listprogress2 */

          /* Safety check */
          if (!sptr->user)
            continue;

          /* If it's secret, and none of the overriding conditions are true, don't send it */
          if (SecretChannel(chptr) && !HasUmode(sptr,UMODE_USER_AUSPEX) && !IsMember(sptr, chptr) && !IsLogger(sptr, chptr))
            continue;

          if (chptr->users < minusers)
            continue;
          sendto_one(sptr, form_str(RPL_LIST), me.name, parv[0],
                     chptr->chname, chptr->users, chptr->topic);

          if (IsSendqPopped(sptr))
            {
              sptr->listprogress=i;
              sptr->listprogress2=j;
              return 0;
            }
        }
        sptr->listprogress2 = 0;
      }
    }
    sendto_one(sptr, form_str(RPL_LISTEND), me.name, parv[0]);
    if (IsSendqPopped(sptr)) { /* popped with the RPL_LISTEND code. d0h */
      sptr->listprogress = -1;
      return 0;
    }
    ClearDoingList(sptr);   /* yupo, its over */
    return 0;
    
  }

  /* Grr, mIRC -- jilles */
  if (parc == 2 && !strcmp(parv[1], "<10000"))
  {
#if 0 /* discussed #hyperion 20050807, considered unnecessary and confusing */
    sendto_one(sptr, ":%s NOTICE %s :Your client is buggy, it sends LIST <10000 even though we don't advertise ELIST=U in 005. Please upgrade or contact the developers.", me.name, parv[0]);
#endif
    parc--;
  }
  
  sendto_one(sptr, form_str(RPL_LISTSTART), me.name, parv[0]);

  if (parc < 2 || BadPtr(parv[1]))
    {
      SetDoingList(sptr);     /* only set if its a full list */
      ClearSendqPop(sptr);    /* just to make sure */
      /* we'll do this by looking through each hash table bucket */
      for (i=0; i<CH_MAX; i++) {
        for (j=0, chptr = (struct Channel*)(hash_get_channel_block(i).list);
             (chptr) && (j<hash_get_channel_block(i).links); chptr = chptr->hnextch, j++) {

          /* Safety check */
          if (!sptr->user)
            continue;

          /* If it's secret, and none of the overriding conditions are true, don't send it */
          if (SecretChannel(chptr) && !HasUmode(sptr,UMODE_USER_AUSPEX) && !IsMember(sptr, chptr) && !IsLogger(sptr, chptr))
            continue;

          if (chptr->users < minusers)
            continue;
          sendto_one(sptr, form_str(RPL_LIST), me.name, parv[0],
                     chptr->chname, chptr->users, chptr->topic);

          if (IsSendqPopped(sptr))
            {
              sptr->listprogress=i;
              sptr->listprogress2=j;
              return 0;
            }
        }
      }

      sendto_one(sptr, form_str(RPL_LISTEND), me.name, parv[0]);
      if (IsSendqPopped(sptr)) {
        sptr->listprogress=-1;
        return 0;
      }
      ClearDoingList(sptr);   /* yupo, its over */
      return 0;
    }   

  p = strchr(parv[1],',');
  if(p)
    *p = '\0';
  name = parv[1]; /* strtoken(&p, parv[1], ","); */

  /* while(name) */
  if(name)
    {
      chptr = hash_find_channel(name, NullChn);
      if (chptr && ShowChannel(sptr, chptr) && sptr->user)
        sendto_one(sptr, form_str(RPL_LIST), me.name, parv[0],
                   name, chptr->users, chptr->topic);
      /*      name = strtoken(&p, (char *)NULL, ","); */
    }
  sendto_one(sptr, form_str(RPL_LISTEND), me.name, parv[0]);
  return 0;
}
コード例 #21
0
ファイル: m_clearchan.c プロジェクト: Cloudxtreme/ircd-3
/*
** mo_clearchan
**      parv[0] = sender prefix
**      parv[1] = channel
*/
static void mo_clearchan(struct Client *client_p, struct Client *source_p,
                        int parc, char *parv[])
{
  struct Channel *chptr, *root_chptr;
  int on_vchan = 0;

  /* admins only */
  if (!IsOperAdmin(source_p))
    {
      sendto_one(source_p, ":%s NOTICE %s :You have no A flag", me.name, parv[0]);
      return;
    }

  /* XXX - we might not have CBURSTed this channel if we are a lazylink
   * yet. */
  chptr= hash_find_channel(parv[1]);
  root_chptr = chptr;

#ifdef VCHANS
  if (chptr && parc > 2 && parv[2][0] == '!')
    {
      chptr = find_vchan(chptr, parv[2]);
      if (root_chptr != chptr)
        on_vchan++;
    }
#endif

  if( chptr == NULL )
    {
      sendto_one(source_p, form_str(source_p,ERR_NOSUCHCHANNEL),
		 me.name, parv[0], parv[1]);
      return;
    }

  if(IsMember(source_p, chptr))
    {
      sendto_one(source_p, ":%s NOTICE %s :*** Please part %s before using CLEARCHAN",
                 me.name, source_p->name, parv[1]);
      return;
    }

  if (!on_vchan)
    {
     sendto_wallops_flags(FLAGS_WALLOP, &me, 
              "CLEARCHAN called for [%s] by %s!%s@%s",
              parv[1], source_p->name, source_p->username, source_p->host);
     sendto_server(NULL, source_p, NULL, NOCAPS, NOCAPS, LL_ICLIENT,
                   ":%s WALLOPS :CLEARCHAN called for [%s] by %s!%s@%s",
                   me.name, parv[1], source_p->name, source_p->username,
                   source_p->host);
     ilog(L_NOTICE, "CLEARCHAN called for [%s] by %s!%s@%s",
         parv[1], source_p->name, source_p->username, source_p->host);
    }
  else
    {
     sendto_wallops_flags(FLAGS_WALLOP, &me,
              "CLEARCHAN called for [%s %s] by %s!%s@%s",
              parv[1], parv[2], source_p->name, source_p->username,
              source_p->host);
     sendto_server(NULL, source_p, NULL, NOCAPS, NOCAPS, LL_ICLIENT,
                   ":%s WALLOPS :CLEARCHAN called for [%s %s] by %s!%s@%s",
                   me.name, parv[1], parv[2], source_p->name,
                   source_p->username, source_p->host);
     ilog(L_NOTICE, "CLEARCHAN called for [%s %s] by %s!%s@%s",
         parv[1], parv[2], source_p->name, source_p->username, source_p->host);
    }

  /* Kill all the modes we have about the channel.. making everyone a peon */  
  remove_our_modes(0, chptr, root_chptr, source_p);
  
  /* SJOIN the user to give them ops, and lock the channel */

  sendto_server(client_p, source_p, chptr, NOCAPS, NOCAPS,
                LL_ICLIENT, ":%s SJOIN %lu %s +ntsi :@%s",
                me.name, (unsigned long) (chptr->channelts - 1),
                chptr->chname, source_p->name);
  sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN %s",
                       source_p->name,
                       source_p->username,
                       source_p->host,
                       root_chptr->chname);
  sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +o %s",
                       me.name, chptr->chname, source_p->name);

  add_user_to_channel(chptr, source_p, CHFL_CHANOP);

  /* Take the TS down by 1, so we don't see the channel taken over
   * again. */
  if (chptr->channelts)
    chptr->channelts--;
  
#ifdef VCHANS
  if (on_vchan)
    add_vchan_to_client_cache(source_p,root_chptr,chptr);
#endif

  chptr->mode.mode =
    MODE_SECRET | MODE_TOPICLIMIT | MODE_INVITEONLY | MODE_NOPRIVMSGS;
  free_topic(chptr);
  chptr->mode.key[0] = 0;

  /* Kick the users out and join the oper */
  kick_list(client_p, source_p, chptr, &chptr->peons, chptr->chname);

}
コード例 #22
0
ファイル: m_mode.c プロジェクト: BackupTheBerlios/shadowircd
/*
 * m_mode - MODE command handler
 * parv[0] - sender
 * parv[1] - channel
 */
static void
m_mode(struct Client *client_p, struct Client *source_p,
       int parc, char *parv[])
{
  struct Channel *chptr = NULL;
  struct Membership *member;
  static char modebuf[MODEBUFLEN];
  static char parabuf[MODEBUFLEN];

  if (parv[1][0] == '\0')
  {
    sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
               me.name, source_p->name, "MODE");
    return;
  }

  /* Now, try to find the channel in question */
  if (!IsChanPrefix(parv[1][0]))
  {
    /* if here, it has to be a non-channel name */
    set_user_mode(client_p, source_p, parc, parv);
    return;
  }

  if (!check_channel_name(parv[1]))
  { 
    sendto_one(source_p, form_str(ERR_BADCHANNAME),
               me.name, source_p->name, parv[1]);
    return;
  }

  chptr = hash_find_channel(parv[1]);

  if (chptr == NULL)
  {
      /* if chptr isn't found locally, it =could= exist
       * on the uplink. So ask.
       */
      
      /* LazyLinks */
      /* only send a mode upstream if a local client sent this request
       * -davidt
       */
      if (MyClient(source_p) && !ServerInfo.hub && uplink &&
	   IsCapable(uplink, CAP_LL))
	{
	  sendto_one(uplink, ":%s MODE %s %s",
                     ID_or_name(source_p, uplink),
		     parv[1], (parv[2] ? parv[2] : ""));
	  return;
	}
      else
	{
	  sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
		     me.name, parv[0], parv[1]);
	  return;
	}
    }

  /* Now known the channel exists */
  if (parc < 3)
  {
    channel_modes(chptr, source_p, modebuf, parabuf);
    sendto_one(source_p, form_str(RPL_CHANNELMODEIS),
               me.name, parv[0], parv[1], modebuf, parabuf);
    sendto_one(source_p, form_str(RPL_CREATIONTIME),
               me.name, parv[0], parv[1], chptr->channelts);
  }
  /* bounce all modes from people we deop on sjoin
   * servers have always gotten away with murder,
   * including telnet servers *g* - Dianora
   *
   * XXX Is it worth the bother to make an ms_mode() ? - Dianora
   */
  else if (IsServer(source_p))
  {
    set_channel_mode(client_p, source_p, chptr, NULL, parc - 2, parv + 2,
                     chptr->chname);
  }
  else
  {
    member = find_channel_link(source_p, chptr);

    if (!has_member_flags(member, CHFL_DEOPPED))
    {
      /* Finish the flood grace period... */
      if (MyClient(source_p) && !IsFloodDone(source_p))
      {
        if (!((parc == 3) && (parv[2][0] == 'b') && (parv[2][1] == '\0')))
          flood_endgrace(source_p);
      }

      set_channel_mode(client_p, source_p, chptr, member, parc - 2, parv + 2,
                       chptr->chname);
    }
  }
}
コード例 #23
0
ファイル: m_omode.c プロジェクト: Cloudxtreme/ircd-ratbox
/*
 * m_omode - MODE command handler
 * parv[0] - sender
 * parv[1] - channel
 */
static void
m_omode(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
{
	struct Channel *chptr = NULL;
	struct membership *msptr;
	static char modebuf[MODEBUFLEN];
	static char parabuf[MODEBUFLEN];
	int n = 2;

	if(EmptyString(parv[1]))
	{
		sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
			   me.name, parv[0], "MODE");
		return;
	}

	/* Now, try to find the channel in question */
	if(!IsChanPrefix(parv[1][0]))
	{
		/* if here, it has to be a non-channel name */
		user_mode(client_p, source_p, parc, parv);
		return;
	}

	if(!check_channel_name(parv[1]))
	{
		sendto_one(source_p, form_str(ERR_BADCHANNAME),
			   me.name, parv[0], (unsigned char *) parv[1]);
		return;
	}

	chptr = hash_find_channel(parv[1]);

	if(chptr == NULL)
	{
		sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), me.name, parv[0], parv[1]);
		return;
	}

	sendto_wallops_flags(UMODE_WALLOP, &me, 
			     "OMODE called for [%s] by %s!%s@%s",
			     parv[1], source_p->name, source_p->username, source_p->host);
	ilog(L_NOTICE, "OMODE called for [%s] by %s!%s@%s",
	     parv[1], source_p->name, source_p->username, source_p->host);

	if(*chptr->chname != '&')
		sendto_server(NULL, NULL, NOCAPS, NOCAPS, 
			      ":%s WALLOPS :OMODE called for [%s] by %s!%s@%s",
			      me.name, parv[1], source_p->name, source_p->username,
			      source_p->host);

	/* Now know the channel exists */
	if(parc < n + 1)
	{
		channel_modes(chptr, source_p, modebuf, parabuf);
		sendto_one(source_p, form_str(RPL_CHANNELMODEIS),
			   me.name, parv[0], parv[1], modebuf, parabuf);

		sendto_one(source_p, form_str(RPL_CREATIONTIME),
			   me.name, parv[0], parv[1], chptr->channelts);
	}
	else if(IsServer(source_p))
	{
		set_channel_mode(client_p, source_p, chptr, NULL,
				 parc - n, parv + n, chptr->chname);
	}
	else
	{
		msptr = find_channel_membership(chptr, source_p);

		set_channel_mode(client_p, source_p->servptr, chptr, msptr, 
				 parc - n, parv + n, chptr->chname);
	}
}
コード例 #24
0
ファイル: m_lljoin.c プロジェクト: Cloudxtreme/ircd-ratbox
/*
 * m_lljoin
 *      parv[0] = sender prefix
 *      parv[1] = channel
 *      parv[2] = nick ("!nick" == cjoin)
 *      parv[3] = vchan/key (optional)
 *      parv[4] = key (optional)
 *
 * If a lljoin is received, from our uplink, join
 * the requested client to the given channel, or ignore it
 * if there is an error.
 *
 *   Ok, the way this works. Leaf client tries to join a channel, 
 * it doesn't exist so the join does a cburst request on behalf of the
 * client, and aborts that join. The cburst sjoin's the channel if it
 * exists on the hub, and sends back an LLJOIN to the leaf. Thats where
 * this is now..
 *
 */
static void ms_lljoin(struct Client *client_p,
                     struct Client *source_p,
                     int parc,
                     char *parv[])
{
  char *chname = NULL;
  char *nick = NULL;
  char *key = NULL;
  char *vkey = NULL;
  int  flags;
  int  i;
  struct Client *target_p;
  struct Channel *chptr, *vchan_chptr, *root_vchan;
#ifdef VCHANS
  int cjoin = 0;
  int  vc_ts;
  char *pvc = NULL;
#endif

  if(uplink && !IsCapable(uplink,CAP_LL))
    {
      sendto_realops_flags(FLAGS_ALL, L_ALL,
			   "*** LLJOIN requested from non LL server %s",
			   client_p->name);
      return;
    }

  chname = parv[1];
  if(chname == NULL)
    return;

  nick = parv[2];
  if(nick == NULL)
    return;

#ifdef VCHANS
  if (nick[0] == '!')
  {
    cjoin = 1;
    nick++;
  }
 
  if(parc > 4)
  {
    key = parv[4];
    vkey = parv[3];
  }
#endif
  else if(parc >3)
  {
    key = vkey = parv[3];
  }

  flags = 0;

  target_p = find_client(nick);

  if( !target_p || !target_p->user )
    return;

  if( !MyClient(target_p) )
    return;

  chptr = hash_find_channel(chname);

#ifdef VCHANS
  if (cjoin)
  {
    if(!chptr) /* Uhm, bad! */
    {
      sendto_realops_flags(FLAGS_ALL, L_ALL,
        "LLJOIN %s %s called by %s, but root chan doesn't exist!",
        chname, nick, client_p->name);
      return;
    }
    flags = CHFL_CHANOP;

    if(! (vchan_chptr = cjoin_channel(chptr, target_p, chname)))
      return;

    root_vchan = chptr;
    chptr = vchan_chptr;
  }
  else
#endif
  {
#ifdef VCHANS
    if (chptr)
    {
      vchan_chptr = select_vchan(chptr, target_p, vkey, chname);
    }
    else
#endif
    {
      chptr = vchan_chptr = get_or_create_channel(target_p, chname, NULL);
      flags = CHFL_CHANOP;
    }
   
#ifdef VCHANS
    if (vchan_chptr != chptr)
    {
      root_vchan = chptr;
      chptr = vchan_chptr;
    }
    else
#endif
      root_vchan = chptr;

    if(!chptr || !root_vchan)
      return;

    if (chptr->users == 0)
      flags = CHFL_CHANOP;
    else
      flags = 0;

    /* XXX in m_join.c :( */
    /* check_spambot_warning(target_p, chname); */

    /* They _could_ join a channel twice due to lag */
    if(chptr)
    {
      if (IsMember(target_p, chptr))    /* already a member, ignore this */
        return;
    }
    else
    {
      sendto_one(target_p, form_str(ERR_UNAVAILRESOURCE),
                 me.name, nick, root_vchan->chname);
      return;
    }

    if( (i = can_join(target_p, chptr, key)) )
    {
      sendto_one(target_p,
                 form_str(i), me.name, nick, root_vchan->chname);
      return;
    }
  }

  if ((target_p->user->joined >= ConfigChannel.max_chans_per_user) &&
      (!IsOper(target_p) || (target_p->user->joined >= 
                             ConfigChannel.max_chans_per_user*3)))
    {
      sendto_one(target_p, form_str(ERR_TOOMANYCHANNELS),
		 me.name, nick, root_vchan->chname );
      return; 
    }
  
  if(flags == CHFL_CHANOP)
    {
      chptr->channelts = CurrentTime;
      /*
       * XXX - this is a rather ugly hack.
       *
       * Unfortunately, there's no way to pass
       * the fact that it is a vchan through SJOIN...
       */
      /* Prevent users creating a fake vchan */
#ifdef VCHANS
      if (chname[0] == '#' && chname[1] == '#')
        {
          if ((pvc = strrchr(chname+3, '_')))
          {
            /*
             * OK, name matches possible vchan:
             * ##channel_blah
             */
            pvc++; /*  point pvc after last _ */
            vc_ts = atol(pvc);
            /*
             * if blah is the same as the TS, up the TS
             * by one, to prevent this channel being
             * seen as a vchan
             */
            if (vc_ts == CurrentTime)
              chptr->channelts++;
          }
        }
#endif

      sendto_one(uplink,
		 ":%s SJOIN %lu %s + :@%s",
		 me.name,
		 (unsigned long) chptr->channelts,
		 chptr->chname,
		 nick);
    }

  /* a user can create a channel with halfops..? */
#if 0
  else if ((flags == CHFL_HALFOP) && (IsCapable(uplink, CAP_HOPS)))
    {
      sendto_one(uplink,
		 ":%s SJOIN %lu %s + :%%%s",
		 me.name,
		 (unsigned long) chptr->channelts,
		 chptr->chname,
		 nick);
    }
#endif
  else
    {
      sendto_one(uplink,
		 ":%s SJOIN %lu %s + :%s",
		 me.name,
		 (unsigned long) chptr->channelts,
		 chptr->chname,
		 nick);
    }

  add_user_to_channel(chptr, target_p, flags);

#ifdef VCHANS
  if ( chptr != root_vchan )
    add_vchan_to_client_cache(target_p,root_vchan,chptr);
#endif
 
  sendto_channel_local(ALL_MEMBERS, chptr,
		       ":%s!%s@%s JOIN :%s",
		       target_p->name,
		       target_p->username,
		       target_p->host,
		       root_vchan->chname);
  
  if( flags & CHFL_CHANOP )
  {
    chptr->mode.mode |= MODE_TOPICLIMIT;
    chptr->mode.mode |= MODE_NOPRIVMSGS;
      
    sendto_channel_local(ALL_MEMBERS,chptr,
                         ":%s MODE %s +nt",
                         me.name, root_vchan->chname);
    sendto_one(uplink, 
               ":%s MODE %s +nt",
               me.name, chptr->chname);
  }

  channel_member_names(target_p, chptr, chname, 1);
}
コード例 #25
0
ファイル: m_mode.c プロジェクト: BackupTheBerlios/shadowircd
/*
 * ms_bmask()
 *
 * inputs	- parv[0] = SID
 *		  parv[1] = TS
 *		  parv[2] = channel name
 *		  parv[3] = type of ban to add ('b' 'I' or 'e')
 *		  parv[4] = space delimited list of masks to add
 * outputs	- none
 * side effects	- propgates unchanged bmask line to CAP_TS6 servers,
 *		  sends plain modes to the others.  nothing is sent
 *		  to the server the issuing server is connected through
 */
static void
ms_bmask(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
{
  static char modebuf[BUFSIZE];
  static char parabuf[BUFSIZE];
  static char banbuf[BUFSIZE];
  struct Channel *chptr;
  char *s, *t, *mbuf, *pbuf;
  long mode_type;
  int mlen;
  int plen = 0;
  int tlen;
  int modecount = 0;
  int needcap = NOCAPS;

  if(!IsChanPrefix(parv[2][0]) || !check_channel_name(parv[2]))
    return;

  if((chptr = hash_find_channel(parv[2])) == NULL)
    return;

  /* TS is higher, drop it. */
  if(atol(parv[1]) > chptr->channelts)
    return;

  switch(parv[3][0])
  {
    case 'b':
      mode_type = CHFL_BAN;
      break;

    case 'e':
      mode_type = CHFL_EXCEPTION;
      needcap = CAP_EX;
      break;

    case 'I':
      mode_type = CHFL_INVEX;
      needcap = CAP_IE;
      break;

    /* maybe we should just blindly propagate this? */
    default:
      return; 
  }

  parabuf[0] = '\0';
  s = banbuf;
  strlcpy(s, parv[4], sizeof(banbuf));

  /* only need to construct one buffer, for non-ts6 servers */
  mlen = ircsprintf(modebuf, ":%s MODE %s +",
                    source_p->name, chptr->chname);
  mbuf = modebuf + mlen;
  pbuf = parabuf;

  if((t = strchr(s, ' ')) != NULL)
    *t++ = '\0';

  while(s != NULL)
  {
    tlen = strlen(s);

    /* I dont even want to begin parsing this.. */
    if(tlen > MODEBUFLEN)
      break;

    if(tlen && add_id(source_p, chptr, s, mode_type))
    {
      /* this new one wont fit.. */
      if(mlen + MAXMODEPARAMS + plen + tlen > BUFSIZE - 4 ||
         modecount >= MAXMODEPARAMS)
      {
        *mbuf = '\0';
        *(pbuf - 1) = '\0';
        sendto_channel_local(ALL_MEMBERS, chptr, "%s %s",
                             modebuf, parabuf);
        sendto_server(client_p, NULL, chptr, needcap, CAP_TS6, NOFLAGS,
                      "%s %s",
                      modebuf, parabuf);

        mbuf = modebuf + mlen;
        pbuf = parabuf;
        plen = modecount = 0;
      }

      *mbuf++ = parv[3][0];
      plen = ircsprintf(pbuf, "%s ", s);
      pbuf += plen;
      modecount++;
    }

    s = t;

    if(s != NULL)
    {
      /* trailing space marking the end. */
      if(*s == '\0')
        break;

      if((t = strchr(s, ' ')) != NULL)
        *t++ = '\0';
    }
  }

  if(modecount)
  {
    *mbuf = *(pbuf - 1) = '\0';
    sendto_channel_local(ALL_MEMBERS, chptr, "%s %s", modebuf, parabuf);
    sendto_server(client_p, NULL, chptr, needcap, CAP_TS6, NOFLAGS,
                  "%s %s", modebuf, parabuf);
  }

  /* assumption here is that since the server sent BMASK, they are TS6, so they have an ID */
  sendto_server(client_p, NULL, chptr, CAP_TS6|needcap, NOCAPS, NOFLAGS,
                ":%s BMASK %lu %s %s :%s",
                 source_p->id, (unsigned long)chptr->channelts, chptr->chname,
                 parv[3], parv[4]);
}
コード例 #26
0
ファイル: m_message.c プロジェクト: Indjov/ircd-hybrid
/* build_target_list()
 *
 * inputs	- pointer to given source (oper/client etc.)
 *		- pointer to list of nicks/channels
 *		- pointer to table to place results
 *		- pointer to text (only used if source_p is an oper)
 * output	- number of valid entities
 * side effects	- target_table is modified to contain a list of
 *		  pointers to channels or clients
 *		  if source client is an oper
 *		  all the classic old bizzare oper privmsg tricks
 *		  are parsed and sent as is, if prefixed with $
 *		  to disambiguate.
 *
 */
static int
build_target_list(int p_or_n, const char *command, struct Client *source_p,
                  char *nicks_channels, const char *text)
{
  int type = 0;
  char *p = NULL, *nick = NULL;
  char *target_list = NULL;
  struct Channel *chptr = NULL;
  struct Client *target_p = NULL;

  target_list = nicks_channels;

  ntargets = 0;

  for (nick = strtoken(&p, target_list, ","); nick;
       nick = strtoken(&p,        NULL, ","))
  {
    const char *with_prefix = NULL;

    /*
     * Channels are privmsg'd a lot more than other clients, moved up
     * here plain old channel msg?
     */
    if (IsChanPrefix(*nick))
    {
      if ((chptr = hash_find_channel(nick)))
      {
        if (!duplicate_ptr(chptr))
        {
          if (ntargets >= ConfigGeneral.max_targets)
          {
            sendto_one_numeric(source_p, &me, ERR_TOOMANYTARGETS,
                               nick, ConfigGeneral.max_targets);
            return 1;
          }

          targets[ntargets].ptr = chptr;
          targets[ntargets++].type = ENTITY_CHANNEL;
        }
      }
      else
      {
        if (p_or_n != NOTICE)
          sendto_one_numeric(source_p, &me, ERR_NOSUCHNICK, nick);
      }

      continue;
    }

    /* Look for a PRIVMSG/NOTICE to another client */
    if ((target_p = find_person(source_p, nick)))
    {
      if (!duplicate_ptr(target_p))
      {
        if (ntargets >= ConfigGeneral.max_targets)
        {
          sendto_one_numeric(source_p, &me, ERR_TOOMANYTARGETS,
                             nick, ConfigGeneral.max_targets);
          return 1;
        }

        targets[ntargets].ptr = target_p;
        targets[ntargets].type = ENTITY_CLIENT;
        targets[ntargets++].flags = 0;
      }

      continue;
    }

    /* @#channel or +#channel message ? */
    type = 0;
    with_prefix = nick;

    /* Allow %+@ if someone wants to do that */
    while (1)
    {
      if (*nick == '@')
        type |= CHFL_CHANOP;
      else if (*nick == '%')
        type |= CHFL_CHANOP | CHFL_HALFOP;
      else if (*nick == '+')
        type |= CHFL_CHANOP | CHFL_HALFOP | CHFL_VOICE;
      else
        break;
      ++nick;
    }

    if (type)
    {
      if (EmptyString(nick))  /* If it's a '\0' dump it, there is no recipient */
      {
        sendto_one_numeric(source_p, &me, ERR_NORECIPIENT, command);
        continue;
      }

      /*
       * At this point, nick+1 should be a channel name i.e. #foo or &foo
       * if the channel is found, fine, if not report an error
       */
      if ((chptr = hash_find_channel(nick)))
      {
        if (IsClient(source_p) && !HasFlag(source_p, FLAGS_SERVICE))
        {
          if (!has_member_flags(find_channel_link(source_p, chptr),
                                CHFL_CHANOP|CHFL_HALFOP|CHFL_VOICE))
          {
            sendto_one_numeric(source_p, &me, ERR_CHANOPRIVSNEEDED, with_prefix);
            return -1;
          }
        }

        if (!duplicate_ptr(chptr))
        {
          if (ntargets >= ConfigGeneral.max_targets)
          {
            sendto_one_numeric(source_p, &me, ERR_TOOMANYTARGETS,
                               nick, ConfigGeneral.max_targets);
            return 1;
          }

          targets[ntargets].ptr = chptr;
          targets[ntargets].type = ENTITY_CHANOPS_ON_CHANNEL;
          targets[ntargets++].flags = type;
        }
      }
      else
      {
        if (p_or_n != NOTICE)
          sendto_one_numeric(source_p, &me, ERR_NOSUCHNICK, nick);
      }

      continue;
    }

    if (*nick == '$' || strchr(nick, '@'))
      handle_special(p_or_n, command, source_p, nick, text);
    else
    {
      if (p_or_n != NOTICE)
      {
        if (!IsDigit(*nick) || MyClient(source_p))
          sendto_one_numeric(source_p, &me, ERR_NOSUCHNICK, nick);
      }
    }
  }

  return 1;
}
コード例 #27
0
ファイル: parse.c プロジェクト: Cloudxtreme/ircd-ratbox
/*
 *
 *      parc    number of arguments ('sender' counted as one!)
 *      parv[0] pointer to 'sender' (may point to empty string) (not used)
 *      parv[1]..parv[parc-1]
 *              pointers to additional parameters, this is a NULL
 *              terminated list (parv[parc] == NULL).
 *
 * *WARNING*
 *      Numerics are mostly error reports. If there is something
 *      wrong with the message, just *DROP* it! Don't even think of
 *      sending back a neat error message -- big danger of creating
 *      a ping pong error message...
 */
static void
do_numeric(char numeric[], struct Client *client_p, struct Client *source_p, int parc, char *parv[])
{
	struct Client *target_p;
	struct Channel *chptr;

	if(parc < 2 || !IsServer(source_p))
		return;

	/* Remap low number numerics. */
	if(numeric[0] == '0')
		numeric[0] = '1';

	/*
	 * Prepare the parameter portion of the message into 'buffer'.
	 * (Because the buffer is twice as large as the message buffer
	 * for the socket, no overflow can occur here... ...on current
	 * assumptions--bets are off, if these are changed --msa)
	 * Note: if buffer is non-empty, it will begin with SPACE.
	 */
	if(parc > 1)
	{
		char *t = buffer;	/* Current position within the buffer */
		int i;
		int tl;		/* current length of presently being built string in t */
		for (i = 2; i < (parc - 1); i++)
		{
			tl = ircsprintf(t, " %s", parv[i]);
			t += tl;
		}
		ircsprintf(t, " :%s", parv[parc - 1]);
	}

	if((target_p = find_client(parv[1])) != NULL)
	{
		if(IsMe(target_p))
		{
			/*
			 * We shouldn't get numerics sent to us,
			 * any numerics we do get indicate a bug somewhere..
			 */
			/* ugh.  this is here because of nick collisions.  when two servers
			 * relink, they burst each other their nicks, then perform collides.
			 * if there is a nick collision, BOTH servers will kill their own
			 * nicks, and BOTH will kill the other servers nick, which wont exist,
			 * because it will have been already killed by the local server.
			 *
			 * unfortunately, as we cant guarantee other servers will do the
			 * "right thing" on a nick collision, we have to keep both kills.  
			 * ergo we need to ignore ERR_NOSUCHNICK. --fl_
			 */
			/* quick comment. This _was_ tried. i.e. assume the other servers
			 * will do the "right thing" and kill a nick that is colliding.
			 * unfortunately, it did not work. --Dianora
			 */
			if(atoi(numeric) != ERR_NOSUCHNICK)
				sendto_realops_flags(UMODE_ALL, L_ADMIN,
						     "*** %s(via %s) sent a %s numeric to me: %s",
						     source_p->name, client_p->name, numeric,
						     buffer);
			return;
		}
		else if(target_p->from == client_p)
		{
			/* This message changed direction (nick collision?)
			 * ignore it.
			 */
			return;
		}

		/* csircd will send out unknown umode flag for +a (admin), drop it here. */
		if((atoi(numeric) == ERR_UMODEUNKNOWNFLAG) && MyClient(target_p))
			return;

		/* Fake it for server hiding, if its our client */
		if(ConfigServerHide.hide_servers && MyClient(target_p) && !IsOper(target_p))
			sendto_one(target_p, ":%s %s %s%s", me.name, numeric, parv[1], buffer);
		else
			sendto_one(target_p, ":%s %s %s%s", source_p->name, numeric, parv[1],
				   buffer);
		return;
	}
	else if((chptr = hash_find_channel(parv[1])) != NULL)
		sendto_channel_local(ALL_MEMBERS, chptr,
				     ":%s %s %s %s",
				     source_p->name, numeric, chptr->chname, buffer);
}
コード例 #28
0
ファイル: m_topic.c プロジェクト: KSoute/oftc-hybrid
/* m_topic()
 *  parv[0] = sender prefix
 *  parv[1] = channel name
 *  parv[2] = new topic, if setting topic
 */
static void
m_topic(struct Client *client_p, struct Client *source_p,
        int parc, char *parv[])
{
  struct Channel *chptr = NULL;
  char *p;
  struct Membership *ms;
  const char *from, *to;

  if (!MyClient(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p))
  {
    from = me.id;
    to = source_p->id;
  }
  else
  {
    from = me.name;
    to = source_p->name;
  }

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

  if (EmptyString(parv[1]))
  {
    sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
               from, to, "TOPIC");
    return;
  }

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

  if (IsChanPrefix(*parv[1]))
  {
    if ((chptr = hash_find_channel(parv[1])) == NULL)
    {
      sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
                 from, to, parv[1]);
      return;
    }

    /* setting topic */
    if (parc > 2)
    {
      if ((ms = find_channel_link(source_p, chptr)) == NULL && !IsService(source_p))
      {
        sendto_one(source_p, form_str(ERR_NOTONCHANNEL), me.name,
                   source_p->name, parv[1]);
        return;
      }

      if ((chptr->mode.mode & MODE_TOPICLIMIT) == 0 ||
          has_member_flags(ms, CHFL_CHANOP|CHFL_HALFOP) || IsGod(source_p) ||
          IsService(source_p))
      {
        char topic_info[USERHOST_REPLYLEN]; 
        if(!has_member_flags(ms, CHFL_CHANOP|CHFL_HALFOP) && 
                IsGod(source_p) && MyClient(source_p) &&
                (chptr->mode.mode & MODE_TOPICLIMIT) != 0)
        {              
          char tmp[IRCD_BUFSIZE];           
          ircsprintf(tmp, "%s is using God mode: TOPIC %s %s", source_p->name, 
                  chptr->chname, parv[2]);              
          sendto_gnotice_flags(UMODE_SERVNOTICE, L_ALL, me.name, &me, NULL, 
                  tmp);
          oftc_log(tmp);
        }
        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",
                      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, NO,
                             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),
                   from, to, chptr->chname);
    }
    else /* only asking for topic */
    {
      if (!SecretChannel(chptr) || IsMember(source_p, chptr))
      {
        if (chptr->topic == NULL)
          sendto_one(source_p, form_str(RPL_NOTOPIC),
                     from, to, chptr->chname);
        else
        {
          sendto_one(source_p, form_str(RPL_TOPIC),
                     from, to,
                     chptr->chname, chptr->topic);

          sendto_one(source_p, form_str(RPL_TOPICWHOTIME),
                     from, to, chptr->chname,
                     chptr->topic_info,
                     chptr->topic_time);
        }
      }
      else
      {
        sendto_one(source_p, form_str(ERR_NOTONCHANNEL),
                   from, to, chptr->chname);
        return;
      }
    }
  }
  else
  {
    sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
               from, to, parv[1]);
  }
}
コード例 #29
0
ファイル: m_invite.c プロジェクト: mdharris/ircd
/*
** m_invite
**      parv[0] - sender prefix
**      parv[1] - user to invite
**      parv[2] - channel name
**      parv[3] - invite timestamp
*/
static void
m_invite(struct Client *client_p, struct Client *source_p,
         int parc, char *parv[])
{
  struct Client *target_p = NULL;
  struct Channel *chptr = NULL;
  struct Membership *ms = NULL;

  if (IsServer(source_p))
    return;

  if (EmptyString(parv[2]))
  {
    sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
               me.name, source_p->name, "INVITE");
    return;
  }

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

  if ((target_p = find_person(client_p, parv[1])) == NULL)
  {
    sendto_one(source_p, form_str(ERR_NOSUCHNICK),
               me.name, source_p->name, parv[1]);
    return;
  }

  /* Do not send local channel invites to users if they are not on the
   * same server as the person sending the INVITE message. 
   */
  /* Possibly should be an error sent to source_p */
  /* done .. there should be no problem because MyConnect(source_p) should
   * always be true if parse() and such is working correctly --is
   */
  if (!MyConnect(target_p) && (*parv[2] == '&'))
  {
    if (ConfigServerHide.hide_servers == 0)
      sendto_one(source_p, form_str(ERR_USERNOTONSERV),
                 me.name, source_p->name, target_p->name);
    return;
  }

  if ((chptr = hash_find_channel(parv[2])) == NULL)
  {
    sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
               me.name, source_p->name, parv[2]);
    return;
  }

  if (MyConnect(source_p) && (ms = find_channel_link(source_p, chptr)) == NULL)
  {
    sendto_one(source_p, form_str(ERR_NOTONCHANNEL),
               me.name, source_p->name, chptr->chname);
    return;
  }

  if (MyConnect(source_p) && !has_member_flags(ms, CHFL_CHANOP|CHFL_HALFOP))
  {
    sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
               me.name, source_p->name, chptr->chname);
    return;
  }

  if ((chptr->mode.mode & MODE_OPERONLY))
  {
    if (MyConnect(source_p) && !IsOper(source_p))
    {
      sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
                 me.name, source_p->name, chptr->chname);
      return;
    }
  }

  if (IsMember(target_p, chptr))
  {
    sendto_one(source_p, form_str(ERR_USERONCHANNEL),
               me.name, source_p->name, target_p->name, chptr->chname);
    return;
  }

  if (MyConnect(source_p))
  {
    sendto_one(source_p, form_str(RPL_INVITING), me.name,
               source_p->name, target_p->name, chptr->chname);

    if (target_p->away)
      sendto_one(source_p, form_str(RPL_AWAY),
                 me.name, source_p->name, target_p->name,
                 target_p->away);
  }
  else if (parc > 3 && IsDigit(*parv[3]))
    if (atoi(parv[3]) > chptr->channelts)
      return;

  if (MyConnect(target_p))
  {
    sendto_one(target_p, ":%s!%s@%s INVITE %s :%s",
               source_p->name, source_p->username,
               source_p->host,
               target_p->name, chptr->chname);

    if (chptr->mode.mode & MODE_INVITEONLY)
    {
      sendto_channel_local(CHFL_CHANOP|CHFL_HALFOP, 0, chptr,
                             ":%s NOTICE %s :%s is inviting %s to %s.",
                             me.name, chptr->chname, source_p->name,
                             target_p->name, chptr->chname);
      sendto_channel_remote(source_p, client_p, CHFL_CHANOP|CHFL_HALFOP,
                              NOCAPS, NOCAPS, chptr,
                              ":%s NOTICE %s :%s is inviting %s to %s.",
                              source_p->name, chptr->chname, source_p->name,
                              target_p->name, chptr->chname);

      /* Add the invite if channel is +i */
      add_invite(chptr, target_p);
    }
  }
  else if (target_p->from != client_p)
    sendto_one(target_p, ":%s INVITE %s %s %lu",
               ID_or_name(source_p, target_p->from),
               ID_or_name(target_p, target_p->from),
               chptr->chname, (unsigned long)chptr->channelts);
}
コード例 #30
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;
}