コード例 #1
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;
}
コード例 #2
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;
}
コード例 #3
0
ファイル: m_check.c プロジェクト: NX-Andro/nefarious
void checkChannel(struct Client *sptr, struct Channel *chptr)
{
   char outbuf[TOPICLEN + MODEBUFLEN + 64], modebuf[MODEBUFLEN], parabuf[MODEBUFLEN];

   /* Header */
   send_reply(sptr, RPL_DATASTR, " ");
   send_reply(sptr, RPL_CHKHEAD, "channel", chptr->chname);
   send_reply(sptr, RPL_DATASTR, " ");

   /* Creation Time */
   ircd_snprintf(sptr, outbuf, sizeof(outbuf), "  Creation time:: %s", myctime(chptr->creationtime));
   send_reply(sptr, RPL_DATASTR, outbuf);

   /* Topic */
   if (strlen(chptr->topic) <= 0)
      send_reply(sptr, RPL_DATASTR, "          Topic:: <none>");
   else {
      ircd_snprintf(sptr, outbuf, sizeof(outbuf), "          Topic:: %s", chptr->topic);
      send_reply(sptr, RPL_DATASTR, outbuf);

      /* ..set by */
      ircd_snprintf(sptr, outbuf, sizeof(outbuf), "         Set by:: %s", chptr->topic_nick);
      send_reply(sptr, RPL_DATASTR, outbuf);
   }

   /* Channel Modes */

   strcpy(outbuf, "Channel mode(s):: ");

   modebuf[0] = '\0';
   parabuf[0] = '\0';

   channel_modes(sptr, modebuf, parabuf, sizeof(modebuf), chptr);

   if(modebuf[1] == '\0')
      strcat(outbuf, "<none>");
   else if(*parabuf) {
      strcat(outbuf, modebuf);
      strcat(outbuf, " ");
      strcat(outbuf, parabuf);
   } else
      strcat(outbuf, modebuf);

   send_reply(sptr, RPL_DATASTR, outbuf);

   /* Don't send 'END OF CHECK' message, it's sent in checkUsers, which is called after this. */
}
コード例 #4
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);
    }
  }
}
コード例 #5
0
ファイル: m_mode.c プロジェクト: NX-Andro/nefarious
int
m_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
{
  struct Channel *chptr = 0;
  unsigned int hoflags  = 0;
  struct ModeBuf mbuf;
  struct Membership *member = 0;

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

  clean_channelname(parv[1]);

  if (!(chptr = FindChannel(parv[1])))
    return set_user_mode(cptr, sptr, parc, parv);

  ClrFlag(sptr, FLAG_TS8);

  member = find_member_link(chptr, sptr);

  if (parc < 3) {
    char modebuf[MODEBUFLEN];
    char parabuf[MODEBUFLEN];

    *modebuf = *parabuf = '\0';
    modebuf[1] = '\0';
    channel_modes(sptr, modebuf, parabuf, sizeof(parabuf), chptr);
    send_reply(sptr, RPL_CHANNELMODEIS, chptr->chname, modebuf, parabuf);
    send_reply(sptr, RPL_CREATIONTIME, chptr->chname, chptr->creationtime);
    return 0;
  }

  if ((!member && !IsChannelService(sptr)) ||
      (member && !IsChanOp(member) && !IsHalfOp(member))) {
    if (IsLocalChannel(chptr->chname) && HasPriv(sptr, PRIV_MODE_LCHAN)) {
      modebuf_init(&mbuf, sptr, cptr, chptr,
		   (MODEBUF_DEST_CHANNEL | /* Send mode to channel */
		    MODEBUF_DEST_HACK4));  /* Send HACK(4) notice */
      mode_parse(&mbuf, cptr, sptr, chptr, parc - 2, parv + 2,
		 (MODE_PARSE_SET |    /* Set the mode */
		  MODE_PARSE_FORCE), NULL); /* Force it to take */
      return modebuf_flush(&mbuf);
    } else
      mode_parse(0, cptr, sptr, chptr, parc - 2, parv + 2,
		 (member ? MODE_PARSE_NOTOPER : MODE_PARSE_NOTMEMBER), NULL);
    return 0;
  }

  modebuf_init(&mbuf, sptr, cptr, chptr,
	       (MODEBUF_DEST_CHANNEL | /* Send mode to channel */
		MODEBUF_DEST_SERVER)); /* Send mode to servers */

  if (member && IsChanOp(member))
    hoflags = MODE_PARSE_SET; /* set unconditionally */
  else if (member && IsHalfOp(member))
    hoflags = MODE_PARSE_ISHALFOP|MODE_PARSE_SET|MODE_PARSE_NOTOPER; /* allowed to +v */
  else
    hoflags = MODE_PARSE_NOTOPER;
  mode_parse(&mbuf, cptr, sptr, chptr, parc - 2, parv + 2, hoflags, member);
  return modebuf_flush(&mbuf);
}
コード例 #6
0
int
m_scan_cmodes(struct Client *cptr, struct Client *sptr, int parc, char *parv[], char *varparv[])
{
  char *cmode_string = parv[2], *c;
  unsigned int include_modes, exclude_modes;
  int require_autodline = 0, require_forward = 0;
  int what = MODE_ADD;
  int list_channels = 1;
  int list_max = 0;
  int listed_so_far = 0, count = 0;
  char *mask = NULL;
  struct Channel *achptr;
  int i;

  if (!HasUmode(sptr,UMODE_USER_AUSPEX))
    {
      if (SeesOperMessages(sptr))
	sendto_one(sptr,":%s NOTICE %s :You have no a umode", me.name, parv[0]);
      else
	sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
      return 0;
    }

  if (parc < 3)
    {
      if (!IsServer(sptr))
	sendto_one(sptr, form_str(ERR_NEEDMOREPARAMS),
		   me.name, parv[0], "SCAN CMODES");
      return 0;
    }

  include_modes = exclude_modes = 0;

  for (c = cmode_string; *c; c++)
    switch(*c)
      {
      case '+':
	what = MODE_ADD;
	break;
      case '-':
	what = MODE_DEL;
	break;
      default:
        {
          int this_mode = 0;
          switch(*c)
            {
            case 'c':
              this_mode = MODE_NOCOLOR;
              break;
            case 'D':
	      require_autodline = what == MODE_ADD ? 1 : -1;
              break;
#ifdef INVITE_CHANNEL_FORWARDING
            case 'f':
	      require_forward = what == MODE_ADD ? 1 : -1;
              break;
#endif
            case 'g':
              this_mode = MODE_FREEINVITE;
              break;
            case 'i':
              this_mode = MODE_INVITEONLY;
              break;
#ifdef JUPE_CHANNEL
            case 'j':
              this_mode = MODE_JUPED;
              break;
#endif
            case 'L':
              this_mode = MODE_LARGEBANLIST;
              break;
            case 'm':
              this_mode = MODE_MODERATED;
              break;
            case 'n':
              this_mode = MODE_NOPRIVMSGS;
              break;
            case 'P':
              this_mode = MODE_PERM;
              break;
            case 'Q':
              this_mode = MODE_NOFORWARD;
              break;
            case 'r':
              this_mode = MODE_NOUNIDENT;
              break;
            case 'R':
              this_mode = MODE_QUIETUNIDENT;
              break;
            case 's':
              this_mode = MODE_SECRET;
              break;
            case 't':
              this_mode = MODE_TOPICLIMIT;
              break;
            case 'z':
              this_mode = MODE_OPMODERATE;
              break;
            default:
	      sendto_one(sptr, form_str(ERR_UNKNOWNMODE), me.name, sptr->name, *c);
	      return 0;
            }

          if (what == MODE_ADD)
            include_modes |= this_mode;
          else
            exclude_modes |= this_mode;
        }
      }

  for (i = 3; i < parc; i++)
    {
      if (!irccmp(parv[i], "no-list"))
	list_channels = 0;
      else if (!irccmp(parv[i], "list"))
	list_channels = 1;
      else if (i < (parc - 1))
	{
	  if (!irccmp(parv[i], "list-max"))
	    {
	      list_max = strtoul(parv[++i], NULL, 0);
	    }
	  else if (!irccmp(parv[i], "mask"))
	    {
	      mask = parv[++i];
	    }
	}
    }

  for (achptr = channel; achptr; achptr = achptr->nextch)
    {
      if ((achptr->mode.mode & include_modes) != include_modes)
        continue;

      if ((achptr->mode.mode & exclude_modes))
        continue;

#ifdef INVITE_CHANNEL_FORWARDING
      if (achptr->mode.invite_forward_channel_name[0] && require_forward == -1)
	continue;
      if (!achptr->mode.invite_forward_channel_name[0] && require_forward == 1)
	continue;
#endif

      if (achptr->mode.autodline_frequency && require_autodline == -1)
	continue;
      if (!achptr->mode.autodline_frequency && require_autodline == 1)
	continue;

      if (list_channels && (!list_max || (listed_so_far < list_max)))
	{
          static char     modebuf[MODEBUFLEN];
          static char     parabuf[MODEBUFLEN];
	  listed_so_far++;
          *modebuf = *parabuf = '\0';
          modebuf[1] = '\0';
          channel_modes(sptr, modebuf, parabuf, achptr);
	  sendto_one(sptr, form_str(RPL_CHANNELMODEIS),
                       me.name, sptr->name,
                       achptr->chname, modebuf, parabuf);
	}
      count++;
    }

  send_markup(sptr, &me, "CMODE-END", "End of channel mode list");
/*   send_markup(sptr, &me, "SCAN-SUMMARY", "!begin<1>%d!end<1> matched", count); */
  send_markup(sptr, &me, "SCAN-SUMMARY", "%d matched", count);

  return 0;
}
コード例 #7
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;
}
コード例 #8
0
ファイル: m_mode.c プロジェクト: fgt-transit/aFailIRCd
/*
 * m_mode - MODE command handler
 * parv[1] - channel
 */
static int
m_mode(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct Channel *chptr = NULL;
	struct membership *msptr;
	int n = 2;
	const char *dest;
	int operspy = 0;

	dest = parv[1];

	if(IsOperSpy(source_p) && *dest == '!')
	{
		dest++;
		operspy = 1;

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

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

	if(!check_channel_name(dest))
	{
		sendto_one_numeric(source_p, ERR_BADCHANNAME, form_str(ERR_BADCHANNAME), parv[1]);
		return 0;
	}

	chptr = find_channel(dest);

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

	/* Now know the channel exists */
	if(parc < n + 1)
	{
		if(operspy)
			report_operspy(source_p, "MODE", chptr->chname);

		sendto_one(source_p, form_str(RPL_CHANNELMODEIS),
			   me.name, source_p->name, parv[1],
			   operspy ? channel_modes(chptr, &me) : channel_modes(chptr, source_p));

		sendto_one(source_p, form_str(RPL_CREATIONTIME),
			   me.name, source_p->name, parv[1], chptr->channelts);
	}
	else
	{
		msptr = find_channel_membership(chptr, source_p);

		/* 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, msptr, parc - n, parv + n);
	}

	return 0;
}
コード例 #9
0
ファイル: m_list.c プロジェクト: Northfire/rabbitircd
/*
 * * m_list *      parv[0] = sender prefix *      parv[1] = channel
 */
DLLFUNC CMD_FUNC(m_list)
{
	aChannel *chptr;
	TS   currenttime = TStime();
	char *name, *p = NULL;
	LOpts *lopt = NULL;
	Link *lp;
	int  usermax, usermin, error = 0, doall = 0;
	TS   chantimemin, chantimemax;
	TS   topictimemin, topictimemax;
	Link *yeslist = NULL, *nolist = NULL;

	static char *usage[] = {
		"   Usage: /LIST <options>",
		"",
		"If you don't include any options, the default is to send you the",
		"entire unfiltered list of channels. Below are the options you can",
		"use, and what channels LIST will return when you use them.",
		">number  List channels with more than <number> people.",
		"<number  List channels with less than <number> people.",
		"C>number List channels created between now and <number> minutes ago.",
		"C<number List channels created earlier than <number> minutes ago.",
		"T>number List channels whose topics are older than <number> minutes",
		"         (Ie, they have not changed in the last <number> minutes.",
		"T<number List channels whose topics are not older than <number> minutes.",
		"*mask*   List channels that match *mask*",
		"!*mask*  List channels that do not match *mask*",
		NULL
	};

	/* Some starting san checks -- No interserver lists allowed. */
	if (cptr != sptr || !sptr->user)
		return 0;

	/* If a /list is in progress, then another one will cancel it */
	if ((lopt = sptr->user->lopt) != NULL)
	{
		sendto_one(sptr, rpl_str(RPL_LISTEND), me.name, parv[0]);
		free_str_list(sptr->user->lopt->yeslist);
		free_str_list(sptr->user->lopt->nolist);
		MyFree(sptr->user->lopt);
		sptr->user->lopt = NULL;
		return 0;
	}

	if (parc < 2 || BadPtr(parv[1]))
	{

		sendto_one(sptr, rpl_str(RPL_LISTSTART), me.name, parv[0]);
		lopt = sptr->user->lopt = (LOpts *) MyMalloc(sizeof(LOpts));
		memset(lopt, '\0', sizeof(LOpts));

		lopt->showall = 1;

		if (DBufLength(&cptr->sendQ) < 2048)
			send_list(cptr, 64);

		return 0;
	}

	if ((parc == 2) && (parv[1][0] == '?') && (parv[1][1] == '\0'))
	{
		char **ptr = usage;
		for (; *ptr; ptr++)
			sendto_one(sptr, rpl_str(RPL_LISTSYNTAX),
			    me.name, cptr->name, *ptr);
		return 0;
	}

	sendto_one(sptr, rpl_str(RPL_LISTSTART), me.name, parv[0]);

	chantimemax = topictimemax = currenttime + 86400;
	chantimemin = topictimemin = 0;
	usermin = 1;		/* Minimum of 1 */
	usermax = -1;		/* No maximum */

	for (name = strtok_r(parv[1], ",", &p); name && !error;
	    name = strtok_r(NULL, ",", &p))
	{

		switch (*name)
		{
		  case '<':
			  usermax = atoi(name + 1) - 1;
			  doall = 1;
			  break;
		  case '>':
			  usermin = atoi(name + 1) + 1;
			  doall = 1;
			  break;
		  case 'C':
		  case 'c':	/* Channel TS time -- creation time? */
			  ++name;
			  switch (*name++)
			  {
			    case '<':
				    chantimemax = currenttime - 60 * atoi(name);
				    doall = 1;
				    break;
			    case '>':
				    chantimemin = currenttime - 60 * atoi(name);
				    doall = 1;
				    break;
			    default:
				    sendto_one(sptr, err_str(ERR_LISTSYNTAX), me.name, cptr->name);
				    error = 1;
			  }
			  break;
#ifdef LIST_USE_T
		  case 'T':
		  case 't':
			  ++name;
			  switch (*name++)
			  {
			    case '<':
				    topictimemax =
					currenttime - 60 * atoi(name);
				    doall = 1;
				    break;
			    case '>':
				    topictimemin =
					currenttime - 60 * atoi(name);
				    doall = 1;
				    break;
			    default:
				    sendto_one(sptr,
					err_str(ERR_LISTSYNTAX),
					me.name, cptr->name,
					"Bad list syntax, type /list ?");
				    error = 1;
			  }
			  break;
#endif
		  default:	/* A channel, possibly with wildcards.
				 * Thought for the future: Consider turning wildcard
				 * processing on the fly.
				 * new syntax: !channelmask will tell ircd to ignore
				 * any channels matching that mask, and then
				 * channelmask will tell ircd to send us a list of
				 * channels only masking channelmask. Note: Specifying
				 * a channel without wildcards will return that
				 * channel even if any of the !channelmask masks
				 * matches it.
				 */
			  if (*name == '!')
			  {
				  doall = 1;
				  lp = make_link();
				  lp->next = nolist;
				  nolist = lp;
				  DupString(lp->value.cp, name + 1);
			  }
			  else if (strchr(name, '*') || strchr(name, '?'))
			  {
				  doall = 1;
				  lp = make_link();
				  lp->next = yeslist;
				  yeslist = lp;
				  DupString(lp->value.cp, name);
			  }
			  else	/* Just a normal channel */
			  {
				  chptr = find_channel(name, NullChn);
				  if (chptr && (ShowChannel(sptr, chptr) || OPCanSeeSecret(sptr))) {
#ifdef LIST_SHOW_MODES
					modebuf[0] = '[';
					channel_modes(sptr, modebuf+1, parabuf, sizeof(modebuf)-1, sizeof(parabuf), chptr);
					if (modebuf[2] == '\0')
						modebuf[0] = '\0';
					else
						strlcat(modebuf, "]", sizeof modebuf);
#endif
					  sendto_one(sptr,
					      rpl_str(RPL_LIST),
					      me.name, parv[0],
					      name, chptr->users,
#ifdef LIST_SHOW_MODES
					      modebuf,
#endif
					      (chptr->topic ? chptr->topic :
					      ""));
}
			  }
		}		/* switch */
	}			/* while */

	if (doall)
	{
		lopt = sptr->user->lopt = (LOpts *) MyMalloc(sizeof(LOpts));
		memset(lopt, '\0', sizeof(LOpts));
		lopt->usermin = usermin;
		lopt->usermax = usermax;
		lopt->topictimemax = topictimemax;
		lopt->topictimemin = topictimemin;
		lopt->chantimemax = chantimemax;
		lopt->chantimemin = chantimemin;
		lopt->nolist = nolist;
		lopt->yeslist = yeslist;

		if (DBufLength(&cptr->sendQ) < 2048)
			send_list(cptr, 64);
		return 0;
	}

	sendto_one(sptr, rpl_str(RPL_LISTEND), me.name, parv[0]);

	return 0;
}
コード例 #10
0
ファイル: m_mode.c プロジェクト: KSoute/oftc-hybrid
/*
 * 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 (EmptyString(parv[1]))
  {
    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]))
  {
    /* if here, it has to be a non-channel name */
    set_user_mode(client_p, source_p, parc, parv);
    return;
  }

  if ((chptr = hash_find_channel(parv[1])) == NULL)
  {
    sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
	       ID_or_name(&me, source_p->from),
	       ID_or_name(source_p, source_p->from),
	       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, source_p->name, chptr->chname, modebuf, parabuf);
    sendto_one(source_p, form_str(RPL_CREATIONTIME),
               me.name, source_p->name, chptr->chname, 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);
    }
  }
}
コード例 #11
0
ファイル: m_svshost.c プロジェクト: Cloudxtreme/ircd-3
/*
 * ms_svshost - SVSHOST command handler
 *      parv[0] = sender prefix
 *      parv[1] = remote server
 *      parv[2] = client nick
 *      parv[3] = vhost to spoof
 */
static void ms_svshost(struct Client* client_p, struct Client* source_p,
                      int parc, char* parv[])
{
  char *flag;
  struct Client *victim;
  struct Channel *chptr, *top_chptr, *banchans[100];
  static char comment[] = "Spoofing with vhost...";
  static char urbanned[] = "You are banned";
  char modebuf[MODEBUFLEN], parabuf[MODEBUFLEN];
  int hide_or_not;
  dlink_node *ptr;
  int i, num = 0;
  
  if (ServerInfo.gateway && get_bridge_token(client_p))
  	return;

  if (hunt_server(client_p, source_p, ":%s SVSHOST %s %s :%s", 
		  1, parc, parv) != HUNTED_ISME)
    return;

  if (!find_z_conf(parv[0]))
    return;
    
  victim = find_client(parv[2]);
  if (victim && !IsServer(victim) && MyConnect(victim))
  {
  	extern int introduce_client(struct Client *, struct Client *,
  		struct User *, char *);
  
  	sendto_server(NULL, victim, NULL, NOCAPS, NOCAPS,
		NOFLAGS, ":%s QUIT :%s", victim->name, comment);

/*	sendto_common_channels_local(victim, ":%s!%s@%s QUIT :%s",
		victim->name, victim->username, victim->host, comment);*/
		
/*	++current_serial;	not needed i suppose */

	if (victim->user->channel.head)
	for (ptr = victim->user->channel.head; ptr; ptr = ptr->next) {
		chptr = (struct Channel *)ptr->data;
		
		sendto_channel_local_butone(victim, ALL_MEMBERS, 
			chptr, ":%s!%s@%s QUIT :%s",
			victim->name, victim->username,
			victim->host, comment);
	}
	
	strncpy(victim->host, parv[3], HOSTLEN)[HOSTLEN] = 0;
	
	sendto_one(victim, ":%s NOTICE %s :*** Notice -- Spoofing your host as %s",
		me.name, victim->name, victim->host);
	
	if (victim->user->channel.head)
	for (ptr = victim->user->channel.head; ptr; ptr = ptr->next) {
		chptr = (struct Channel *)ptr->data;
		
#ifdef VCHANS
		top_chptr = RootChan(chptr);
#else
		top_chptr = chptr;
#endif		
		if (is_banned(chptr, victim) & (CHFL_BAN|CHFL_DENY)) {
			sendto_one(victim, ":%s KICK %s %s :%s",
				me.name, top_chptr->chname, victim->name,
				urbanned);
			
			/*remove_user_from_channel(chptr, victim);*/
			banchans[num++] = chptr;
			continue;
		}
		
		if (is_chan_op(chptr, victim)) 
			flag = "+o";
#ifdef HALFOPS			
		else if (is_half_op(chptr, victim)) 
			flag = "+h";
#endif			
		else if (is_voiced(chptr, victim))
			flag = "+v";
		else flag = "";
#ifdef REQUIRE_OANDV
		if (find_user_link(&chptr->chanops_voiced, victim))
			flag = "+ov";
#endif
		sendto_channel_local_butone(victim, ALL_MEMBERS, 
			chptr, ":%s!%s@%s JOIN :%s",
			victim->name, victim->username,
			victim->host, top_chptr->chname);
			
#ifdef ANONOPS
		if (chptr->mode.mode & MODE_HIDEOPS)
			hide_or_not = ONLY_CHANOPS_HALFOPS;
		else
#endif
			hide_or_not = ALL_MEMBERS;
			
		if (flag[0])
		sendto_channel_local_butone(victim, hide_or_not,
			chptr, ":%s MODE %s %s %s %s",
			me.name, top_chptr->chname, flag,
			victim->name, flag[2]? victim->name : "");		
	}
	
	for (i=0; i < num; i++)
		remove_user_from_channel(banchans[i], victim);
	
	introduce_client(NULL, victim, victim->user, victim->name);
	
	victim->lazyLinkClientExists = 0;	/* force introducing to LL servers below... */
	
	if (victim->user->channel.head)
	for (ptr = victim->user->channel.head; ptr; ptr = ptr->next) {
		chptr = (struct Channel *)ptr->data;
		
		if (is_chan_op(chptr, victim)) 
			flag = "@";
#ifdef HALFOPS			
		else if (is_half_op(chptr, victim)) 
			flag = "%";
#endif			
		else if (is_voiced(chptr, victim))
			flag = "+";
		else flag = "";
#ifdef REQUIRE_OANDV
		if (find_user_link(&chptr->chanops_voiced, victim))
			flag = "@+";
#endif
		channel_modes(chptr, victim, modebuf, parabuf);
		sendto_server(NULL, victim, chptr, NOCAPS, NOCAPS,
			LL_ICLIENT|LL_ICHAN, ":%s SJOIN %lu %s %s %s :%s%s",
			me.name, (unsigned long)chptr->channelts,
			chptr->chname, modebuf, parabuf, 
			flag, victim->name);
	}
  }
}
コード例 #12
0
ファイル: m_mode.c プロジェクト: aboutnet/ircu-abnet
int
m_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
{
  struct Channel *chptr = 0;
  struct ModeBuf mbuf;
  struct Membership *member;

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

  if (!IsChannelName(parv[1]) || !(chptr = FindChannel(parv[1])))
  {
    struct Client *acptr;

    acptr = FindUser(parv[1]);
    if (!acptr)
    {
      send_reply(sptr, ERR_NOSUCHCHANNEL, parv[1]);
      return 0;
    }
    else if (sptr != acptr)
    {
      send_reply(sptr, ERR_USERSDONTMATCH);
      return 0;
    }
    return set_user_mode(cptr, sptr, parc, parv, ALLOWMODES_ANY);
  }

  ClrFlag(sptr, FLAG_TS8);

  member = find_member_link(chptr, sptr);

  if (parc < 3) {
    char modebuf[MODEBUFLEN];
    char parabuf[MODEBUFLEN];

    *modebuf = *parabuf = '\0';
    modebuf[1] = '\0';
    channel_modes(sptr, modebuf, parabuf, sizeof(parabuf), chptr, member);
    send_reply(sptr, RPL_CHANNELMODEIS, chptr->chname, modebuf, parabuf);
    send_reply(sptr, RPL_CREATIONTIME, chptr->chname, chptr->creationtime);
    return 0;
  }

  if (!member || !IsChanOp(member)) {
    if (IsLocalChannel(chptr->chname) && HasPriv(sptr, PRIV_MODE_LCHAN)) {
      modebuf_init(&mbuf, sptr, cptr, chptr,
		   (MODEBUF_DEST_CHANNEL | /* Send mode to channel */
		    MODEBUF_DEST_HACK4));  /* Send HACK(4) notice */
      mode_parse(&mbuf, cptr, sptr, chptr, parc - 2, parv + 2,
		 (MODE_PARSE_SET |    /* Set the mode */
		  MODE_PARSE_FORCE),  /* Force it to take */
		  member);
      return modebuf_flush(&mbuf);
    } else
      mode_parse(0, cptr, sptr, chptr, parc - 2, parv + 2,
		 (member ? MODE_PARSE_NOTOPER : MODE_PARSE_NOTMEMBER), member);
    return 0;
  }

  modebuf_init(&mbuf, sptr, cptr, chptr,
	       (MODEBUF_DEST_CHANNEL | /* Send mode to channel */
		MODEBUF_DEST_SERVER)); /* Send mode to servers */
  mode_parse(&mbuf, cptr, sptr, chptr, parc - 2, parv + 2, MODE_PARSE_SET, member);
  return modebuf_flush(&mbuf);
}
コード例 #13
0
ファイル: m_join.c プロジェクト: Cloudxtreme/ircd-ratbox
/*
 * m_join
 *      parv[0] = sender prefix
 *      parv[1] = channel
 *      parv[2] = channel password (key)
 */
static void
m_join(struct Client *client_p,
       struct Client *source_p,
       int parc,
       char *parv[])
{
  struct Channel *chptr = NULL;
  char  *name, *key = NULL;
  int   i, flags = 0;
  char  *p = NULL, *p2 = NULL;
  int   successful_join_count = 0; /* Number of channels successfully joined */
  
  if (*parv[1] == '\0')
    {
      sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
                 me.name, parv[0], "JOIN");
      return;
    }

  if (parc > 2)
    {
      key = strtoken(&p2, parv[2], ",");
    }

  for (name = strtoken(&p, parv[1], ","); name;
         key = (key) ? strtoken(&p2, NULL, ",") : NULL,
         name = strtoken(&p, NULL, ","))
    {

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

      /*
      ** JOIN 0 sends out a part for all channels a user
      ** has joined.
      **
      ** this should be either disabled or selectable in
      ** config file .. it's abused a lot more than it's
      ** used these days :/ --is
      */
      if (*name == '0' && !atoi(name))
      {
        if (source_p->user->channel.head == NULL)
          continue;
	  
        do_join_0(&me,source_p);
	continue;
      }
      
      /* check it begins with # or & */
      else if(!IsChannelName(name))
      {
        sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
	           me.name, source_p->name, name);
	continue;
      }

      if(ConfigServerHide.disable_local_channels &&
        (*name == '&'))
      {
        sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
	           me.name, source_p->name, name);
        continue;
      }

      /* check the length */
      if (strlen(name) > CHANNELLEN)
      {
        sendto_one(source_p, form_str(ERR_BADCHANNAME),
	           me.name, source_p->name, name);
	continue;
      }
      
      /* see if its resv'd */
      if(find_channel_resv(name) && 
         (!IsOper(source_p) || !ConfigChannel.no_oper_resvs))
	{
	  sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
		     me.name, source_p->name, name);
          sendto_realops_flags(UMODE_SPY, L_ALL,
                   "User %s (%s@%s) is attempting to join locally juped channel %s",
                   source_p->name, source_p->username, source_p->host, name);
	  continue;
	}

      /* look for the channel */
      if((chptr = hash_find_channel(name)) != NULL)
	{
	  if(IsMember(source_p, chptr))
            return;

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

	  if (chptr->users == 0)
	    flags = CHFL_CHANOP;
	  else
	    flags = 0;
	}
      else
	{
	  if(splitmode && !IsOper(source_p) && (*name != '&') && 
            (ConfigChannel.no_create_on_split || ConfigChannel.no_join_on_split))
	  {
	    sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
	               me.name, source_p->name, name);
	    continue;
	  }
	  
	  flags = CHFL_CHANOP;
	}

      if ((source_p->user->joined >= ConfigChannel.max_chans_per_user) &&
         (!IsOper(source_p) || (source_p->user->joined >=
	                        ConfigChannel.max_chans_per_user*3)))
	{
	  sendto_one(source_p, form_str(ERR_TOOMANYCHANNELS),
		     me.name, parv[0], name);
	  if(successful_join_count)
	    source_p->localClient->last_join_time = CurrentTime;
	  return;
	}

      if(flags == 0)        /* if channel doesn't exist, don't penalize */
	successful_join_count++;

      if(chptr == NULL)     /* If I already have a chptr, no point doing this */
	{
	  chptr = get_or_create_channel(source_p, name, NULL);
	}
      
      if(chptr == NULL)
	{
	  sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
		     me.name, parv[0], name);
	  if(successful_join_count > 0)
	    successful_join_count--;
	  continue;
	}

    if (!IsOper(source_p))
     check_spambot_warning(source_p, name);
      
      /* can_join checks for +i key, bans etc */
      if ( (i = can_join(source_p, chptr, key)) )
	{
	  sendto_one(source_p,
		     form_str(i), me.name, parv[0], name);
	  if(successful_join_count > 0)
	    successful_join_count--;
	  continue;
	}

      /* add the user to the channel */
      add_user_to_channel(chptr, source_p, flags);

      /* we send the user their join here, because we could have to
       * send a mode out next.
       */
      sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN :%s",
			   source_p->name,
			   source_p->username,
			   source_p->host,
			   chptr->chname);

      /* if theyre joining opped (ie, new chan or joining one thats
       * persisting) then set timestamp to current, set +nt and
       * broadcast the sjoin with its old modes, or +nt.
       */
      if (flags & CHFL_CHANOP)
	{
          char mbuf[MODEBUFLEN];
          char pbuf[MODEBUFLEN];

	  chptr->channelts = CurrentTime;
          chptr->mode.mode |= MODE_TOPICLIMIT;
          chptr->mode.mode |= MODE_NOPRIVMSGS;

	  sendto_channel_local(ONLY_CHANOPS, chptr, ":%s MODE %s +nt",
			       me.name, chptr->chname);

          if(*chptr->chname == '#')
          {
            channel_modes(chptr, source_p, mbuf, pbuf);

            strlcat(mbuf, " ", sizeof(mbuf));

            if(pbuf[0] != '\0')
              strlcat(mbuf, pbuf, sizeof(mbuf));

            /* note: mbuf here will have a trailing space.  we add one above,
             * and channel_modes() will leave a trailing space on pbuf if
             * its used --fl
             */
	    sendto_server(client_p, chptr, NOCAPS, NOCAPS,
                          ":%s SJOIN %lu %s %s:@%s",
                          me.name, (unsigned long) chptr->channelts, 
                          chptr->chname, mbuf, parv[0]);
          }

          /* drop our +beI modes */
          free_channel_list(&chptr->banlist);
          free_channel_list(&chptr->exceptlist);
          free_channel_list(&chptr->invexlist);
	}
      else 
	{
	  sendto_server(client_p, chptr, NOCAPS, NOCAPS,
                        ":%s SJOIN %lu %s + :%s",
                        me.name, (unsigned long) chptr->channelts,
                        chptr->chname, parv[0]);
        }

      del_invite(chptr, source_p);
      
      if (chptr->topic != NULL)
	{
	  sendto_one(source_p, form_str(RPL_TOPIC), me.name,
		     parv[0], chptr->chname, chptr->topic);

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

      channel_member_names(source_p, chptr, chptr->chname, 1);

      if(successful_join_count)
	source_p->localClient->last_join_time = CurrentTime;
    }
}
コード例 #14
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);
	}
}
コード例 #15
0
ファイル: m_list.c プロジェクト: Northfire/rabbitircd
void _send_list(aClient *cptr, int numsend)
{
	aChannel *chptr;
	LOpts *lopt = cptr->user->lopt;
	unsigned int  hashnum;

	/* Begin of /list? then send official channels. */
	if ((lopt->starthash == 0) && conf_offchans)
	{
		ConfigItem_offchans *x;
		for (x = conf_offchans; x; x = (ConfigItem_offchans *)x->next)
		{
			if (find_channel(x->chname, (aChannel *)NULL))
				continue; /* exists, >0 users.. will be sent later */
			sendto_one(cptr,
			    rpl_str(RPL_LIST), me.name,
			    cptr->name, x->chname,
			    0,
#ifdef LIST_SHOW_MODES
			    "",
#endif					    
			    x->topic ? x->topic : "");
		}
	}

	for (hashnum = lopt->starthash; hashnum < CH_MAX; hashnum++)
	{
		if (numsend > 0)
			for (chptr =
			    (aChannel *)hash_get_chan_bucket(hashnum);
			    chptr; chptr = chptr->hnextch)
			{
				if (SecretChannel(chptr)
				    && !IsMember(cptr, chptr)
				    && !OPCanSeeSecret(cptr))
					continue;

				/* Much more readable like this -- codemastr */
				if ((!lopt->showall))
				{
					/* User count must be in range */
					if ((chptr->users < lopt->usermin) || 
					    ((lopt->usermax >= 0) && (chptr->users > 
					    lopt->usermax)))
						continue;

					/* Creation time must be in range */
					if ((chptr->creationtime && (chptr->creationtime <
					    lopt->chantimemin)) || (chptr->creationtime >
					    lopt->chantimemax))
						continue;

					/* Topic time must be in range */
					if ((chptr->topic_time < lopt->topictimemin) ||
					    (chptr->topic_time > lopt->topictimemax))
						continue;

					/* Must not be on nolist (if it exists) */
					if (lopt->nolist && find_str_match_link(lopt->nolist,
					    chptr->chname))
						continue;

					/* Must be on yeslist (if it exists) */
					if (lopt->yeslist && !find_str_match_link(lopt->yeslist,
					    chptr->chname))
						continue;
				}
#ifdef LIST_SHOW_MODES
				modebuf[0] = '[';
				channel_modes(cptr, modebuf+1, parabuf, sizeof(modebuf)-1, sizeof(parabuf), chptr);
				if (modebuf[2] == '\0')
					modebuf[0] = '\0';
				else
					strlcat(modebuf, "]", sizeof modebuf);
#endif
				if (!OPCanSeeSecret(cptr))
					sendto_one(cptr,
					    rpl_str(RPL_LIST), me.name,
					    cptr->name,
					    ShowChannel(cptr,
					    chptr) ? chptr->chname :
					    "*", chptr->users,
#ifdef LIST_SHOW_MODES
					    ShowChannel(cptr, chptr) ?
					    modebuf : "",
#endif
					    ShowChannel(cptr,
					    chptr) ? (chptr->topic ?
					    chptr->topic : "") : "");
				else
					sendto_one(cptr,
					    rpl_str(RPL_LIST), me.name,
					    cptr->name, chptr->chname,
					    chptr->users,
#ifdef LIST_SHOW_MODES
					    modebuf,
#endif					    
					    (chptr->topic ? chptr->topic : ""));
				numsend--;
			}
		else
			break;
	}

	/* All done */
	if (hashnum == CH_MAX)
	{
		sendto_one(cptr, rpl_str(RPL_LISTEND), me.name, cptr->name);
		free_str_list(cptr->user->lopt->yeslist);
		free_str_list(cptr->user->lopt->nolist);
		MyFree(cptr->user->lopt);
		cptr->user->lopt = NULL;
		return;
	}

	/* 
	 * We've exceeded the limit on the number of channels to send back
	 * at once.
	 */
	lopt->starthash = hashnum;
	return;
}
コード例 #16
0
ファイル: m_join.c プロジェクト: blank4/unrealircd
/* Routine that actually makes a user join the channel
 * this does no actual checking (banned, etc.) it just adds the user
 */
DLLFUNC void _join_channel(aChannel *chptr, aClient *cptr, aClient *sptr, int flags)
{
    char *parv[] = { 0, 0 };
    /*
       **  Complete user entry to the new channel (if any)
     */
    add_user_to_channel(chptr, sptr, flags);
    /*
       ** notify all other users on the new channel
     */
    if (chptr->mode.mode & MODE_AUDITORIUM)
    {
        if (MyClient(sptr))
            sendto_one(sptr, ":%s!%s@%s JOIN :%s",
                       sptr->name, sptr->user->username,
                       GetHost(sptr), chptr->chname);
        sendto_chanops_butone(NULL, chptr, ":%s!%s@%s JOIN :%s",
                              sptr->name, sptr->user->username,
                              GetHost(sptr), chptr->chname);
    }
    else
        sendto_channel_butserv(chptr, sptr,
                               ":%s JOIN :%s", sptr->name, chptr->chname);

    sendto_serv_butone_token_opt(cptr, OPT_NOT_SJ3, sptr->name, MSG_JOIN,
                                 TOK_JOIN, "%s", chptr->chname);

#ifdef JOIN_INSTEAD_OF_SJOIN_ON_REMOTEJOIN
    if ((MyClient(sptr) && !(flags & CHFL_CHANOP)) || !MyClient(sptr))
        sendto_serv_butone_token_opt(cptr, OPT_SJ3, sptr->name, MSG_JOIN,
                                     TOK_JOIN, "%s", chptr->chname);
    if (flags && !(flags & CHFL_DEOPPED))
    {
#endif
        /* I _know_ that the "@%s " look a bit wierd
           with the space and all .. but its to get around
           a SJOIN bug --stskeeps */
        sendto_serv_butone_token_opt(cptr, OPT_SJ3|OPT_SJB64,
                                     me.name, MSG_SJOIN, TOK_SJOIN,
                                     "%B %s :%s%s ", (long)chptr->creationtime,
                                     chptr->chname, chfl_to_sjoin_symbol(flags), sptr->name);
        sendto_serv_butone_token_opt(cptr, OPT_SJ3|OPT_NOT_SJB64,
                                     me.name, MSG_SJOIN, TOK_SJOIN,
                                     "%li %s :%s%s ", chptr->creationtime,
                                     chptr->chname, chfl_to_sjoin_symbol(flags), sptr->name);
#ifdef JOIN_INSTEAD_OF_SJOIN_ON_REMOTEJOIN
    }
#endif

    if (MyClient(sptr))
    {
        /*
           ** Make a (temporal) creationtime, if someone joins
           ** during a net.reconnect : between remote join and
           ** the mode with TS. --Run
         */
        if (chptr->creationtime == 0)
        {
            chptr->creationtime = TStime();
            sendto_serv_butone_token(cptr, me.name,
                                     MSG_MODE, TOK_MODE, "%s + %lu",
                                     chptr->chname, chptr->creationtime);
        }
        del_invite(sptr, chptr);
        if (flags && !(flags & CHFL_DEOPPED))
        {
#ifndef PREFIX_AQ
            if ((flags & CHFL_CHANOWNER) || (flags & CHFL_CHANPROT))
            {
                /* +ao / +qo for when PREFIX_AQ is off */
                sendto_serv_butone_token_opt(cptr, OPT_NOT_SJ3,
                                             me.name,
                                             MSG_MODE, TOK_MODE, "%s +o%c %s %s %lu",
                                             chptr->chname, chfl_to_chanmode(flags), sptr->name, sptr->name,
                                             chptr->creationtime);
            } else {
#endif
                /* +v/+h/+o (and +a/+q if PREFIX_AQ is on) */
                sendto_serv_butone_token_opt(cptr, OPT_NOT_SJ3,
                                             me.name,
                                             MSG_MODE, TOK_MODE, "%s +%c %s %lu",
                                             chptr->chname, chfl_to_chanmode(flags), sptr->name,
                                             chptr->creationtime);
#ifndef PREFIX_AQ
            }
#endif
        }
        if (chptr->topic)
        {
            sendto_one(sptr, rpl_str(RPL_TOPIC),
                       me.name, sptr->name, chptr->chname, chptr->topic);
            sendto_one(sptr,
                       rpl_str(RPL_TOPICWHOTIME), me.name,
                       sptr->name, chptr->chname, chptr->topic_nick,
                       chptr->topic_time);
        }
        if (chptr->users == 1 && (MODES_ON_JOIN
#ifdef EXTCMODE
                                  || iConf.modes_on_join.extmodes)
#endif
           )
        {
#ifdef EXTCMODE
            int i;
            chptr->mode.extmode =  iConf.modes_on_join.extmodes;
            /* Param fun */
            for (i = 0; i <= Channelmode_highest; i++)
            {
                if (!Channelmode_Table[i].flag || !Channelmode_Table[i].paracount)
                    continue;
                if (chptr->mode.extmode & Channelmode_Table[i].mode)
                {
                    CmodeParam *p;
                    p = Channelmode_Table[i].put_param(NULL, iConf.modes_on_join.extparams[i]);
                    AddListItem(p, chptr->mode.extmodeparam);
                }
            }
#endif
            chptr->mode.mode = MODES_ON_JOIN;
#ifdef NEWCHFLOODPROT
            if (iConf.modes_on_join.floodprot.per)
            {
                chptr->mode.floodprot = MyMalloc(sizeof(ChanFloodProt));
                memcpy(chptr->mode.floodprot, &iConf.modes_on_join.floodprot, sizeof(ChanFloodProt));
            }
#else
            chptr->mode.kmode = iConf.modes_on_join.kmode;
            chptr->mode.per = iConf.modes_on_join.per;
            chptr->mode.msgs = iConf.modes_on_join.msgs;
#endif
            *modebuf = *parabuf = 0;
            channel_modes(sptr, modebuf, parabuf, chptr);
            /* This should probably be in the SJOIN stuff */
            sendto_serv_butone_token(&me, me.name, MSG_MODE, TOK_MODE,
                                     "%s %s %s %lu", chptr->chname, modebuf, parabuf,
                                     chptr->creationtime);
            sendto_one(sptr, ":%s MODE %s %s %s", me.name, chptr->chname, modebuf, parabuf);
        }
        parv[0] = sptr->name;
        parv[1] = chptr->chname;
        do_cmd(cptr, sptr, "NAMES", 2, parv);
        RunHook4(HOOKTYPE_LOCAL_JOIN, cptr, sptr,chptr,parv);
    } else {
        RunHook4(HOOKTYPE_REMOTE_JOIN, cptr, sptr, chptr, parv); /* (rarely used) */
    }

#ifdef NEWCHFLOODPROT
    /* I'll explain this only once:
     * 1. if channel is +f
     * 2. local client OR synced server
     * 3. then, increase floodcounter
     * 4. if we reached the limit AND only if source was a local client.. do the action (+i).
     * Nr 4 is done because otherwise you would have a noticeflood with 'joinflood detected'
     * from all servers.
     */
    if (chptr->mode.floodprot && (MyClient(sptr) || sptr->srvptr->serv->flags.synced) &&
            !IsULine(sptr) && do_chanflood(chptr->mode.floodprot, FLD_JOIN) && MyClient(sptr))
    {
        do_chanflood_action(chptr, FLD_JOIN, "join");
    }
#endif
}
コード例 #17
0
ファイル: m_forcejoin.c プロジェクト: fgt-transit/aFailIRCd
/* 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 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.
	 * this code has a side effect of losing keys, but..
	 */
	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 &, and local chans are disabled */
		else if(!IsChannelName(name) ||
		       (!ConfigChannel.use_local_channels && name[0] == '&'))
		{
			sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
					   form_str(ERR_NOSUCHCHANNEL), 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
		{
			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;
			
			if(ConfigChannel.founder_on_channel_create && ConfigChannel.use_founder)
				flags |= CHFL_FOUNDER;

			if(ConfigChannel.admin_on_channel_create && ConfigChannel.use_admin)
				flags |= CHFL_ADMIN;

			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);
		
			/* autochanmodes stuff */
			if(ConfigChannel.autochanmodes)
			{
				char * ch;
				for(ch = ConfigChannel.autochanmodes; *ch != '\0'; ch++)
				{
					chptr->mode.mode |= chmode_table[(unsigned int)*ch].mode_type;
				}
			}
			else
			{
				chptr->mode.mode |= MODE_TOPICLIMIT;
				chptr->mode.mode |= MODE_NOPRIVMSGS;
			}

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

			sendto_server(target_p, chptr, CAP_TS6, NOCAPS,
				       ":%s SJOIN %ld %s %s :%s%s",
				       me.id, (long) chptr->channelts,
				       chptr->chname, modes,
				       flags & CHFL_FOUNDER ? "~@" : "@",
				       get_id(target_p, client_p));

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

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