예제 #1
0
/*
** m_part
**      parv[0] = sender prefix
**      parv[1] = channel
**      parv[2] = reason
*/
static void
m_part(struct Client *client_p, struct Client *source_p,
       int parc, char *parv[])
{
  char *p = NULL, *name = NULL;
  char reason[KICKLEN + 1] = { '\0' };

  if (IsServer(source_p))
    return;

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

  if (parc > 2 && !EmptyString(parv[2]))
    strlcpy(reason, parv[2], sizeof(reason));

  /* Finish the flood grace period... */
  if (MyClient(source_p) && !IsFloodDone(source_p))
    flood_endgrace(source_p);

  for (name = strtoken(&p, parv[1], ","); name;
       name = strtoken(&p,    NULL, ","))
    part_one_client(source_p, name, reason);
}
예제 #2
0
/*
 * inputs	- flag privmsg or notice
 * 		- pointer to command "PRIVMSG" or "NOTICE"
 *		- pointer to client_p
 *		- pointer to source_p
 *		- pointer to channel
 */
static void
m_message(int p_or_n,
          char *command,
          struct Client *client_p,
          struct Client *source_p, int parc, char *parv[])
{
  int i;

  if (parc < 2 || *parv[1] == '\0')
  {
    if (p_or_n != NOTICE)
      sendto_one(source_p, form_str(source_p,ERR_NORECIPIENT), me.name,
                 source_p->name, command);
    return;
  }

  if (parc < 3 || *parv[2] == '\0')
  {
    if (p_or_n != NOTICE)
      sendto_one(source_p, form_str(source_p,ERR_NOTEXTTOSEND), me.name,
                 source_p->name);
    return;
  }

  /* Finish the flood grace period... */
  if(MyClient(source_p) && !IsFloodDone(source_p))
    flood_endgrace(source_p);

  if (build_target_list(p_or_n, command, client_p, source_p, parv[1],
                        parv[2]) < 0)
  {
    /* Sigh.  We need to relay this command to the hub */
    if (!ServerInfo.hub && (uplink != NULL))
      sendto_one(uplink, ":%s %s %s :%s",
		 source_p->name, command, parv[1], parv[2]);
    return;
  }

  for (i = 0; i < ntargets; i++)
  {
    switch (targets[i].type)
    {
      case ENTITY_CHANNEL:
        msg_channel(p_or_n, command, client_p, source_p,
                    (struct Channel *)targets[i].ptr, parv[2]);
        break;

      case ENTITY_CHANOPS_ON_CHANNEL:
        msg_channel_flags(p_or_n, command, client_p, source_p,
                          (struct Channel *)targets[i].ptr,
                          targets[i].flags, parv[2]);
        break;

      case ENTITY_CLIENT:
        msg_client(p_or_n, command, source_p,
                   (struct Client *)targets[i].ptr, parv[2]);
        break;
    }
  }
}
예제 #3
0
/*
** m_part
**      parv[0] = sender prefix
**      parv[1] = channel
**      parv[2] = reason
*/
static int
m_part(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	char *p, *name;
	char reason[REASONLEN + 1];
	char *s = LOCAL_COPY(parv[1]);

	reason[0] = '\0';

	if(parc > 2)
		strlcpy(reason, parv[2], sizeof(reason));

	name = strtoken(&p, s, ",");

	/* Finish the flood grace period... */
	if(MyClient(source_p) && !IsFloodDone(source_p))
		flood_endgrace(source_p);

	while (name)
	{
		part_one_client(client_p, source_p, name, reason);
		name = strtoken(&p, NULL, ",");
	}
	return 0;
}
예제 #4
0
/*
** m_away
**      parv[1] = away message
*/
static int
m_away(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
    if(MyClient(source_p) && source_p->localClient->next_away &&
       !IsFloodDone(source_p))
        flood_endgrace(source_p);

    if(!IsClient(source_p))
        return 0;

    if(parc < 2 || EmptyString(parv[1])) {
        /* Marking as not away */
        if(source_p->user->away != NULL) {
            /* we now send this only if they were away before --is */
            sendto_server(client_p, NULL, CAP_TS6, NOCAPS,
                          ":%s AWAY", use_id(source_p));
            free_away(source_p);

            sendto_common_channels_local_butone(source_p, CLICAP_AWAY_NOTIFY, NOCAPS, ":%s!%s@%s AWAY",
                                                source_p->name, source_p->username, source_p->host);
        }
        if(MyConnect(source_p))
            sendto_one_numeric(source_p, RPL_UNAWAY, form_str(RPL_UNAWAY));
        return 0;
    }

    /* Rate limit this because it is sent to common channels. */
    if (MyClient(source_p)) {
        if(!IsOper(source_p) &&
           source_p->localClient->next_away > rb_current_time()) {
            sendto_one(source_p, form_str(RPL_LOAD2HI),
                       me.name, source_p->name, "AWAY");
            return 0;
        }
        if(source_p->localClient->next_away < rb_current_time() -
           ConfigFileEntry.away_interval)
            source_p->localClient->next_away = rb_current_time();
        else
            source_p->localClient->next_away = rb_current_time() +
                                               ConfigFileEntry.away_interval;
    }


    if(source_p->user->away == NULL)
        allocate_away(source_p);
    if(strncmp(source_p->user->away, parv[1], AWAYLEN - 1)) {
        rb_strlcpy(source_p->user->away, parv[1], AWAYLEN);
        sendto_server(client_p, NULL, CAP_TS6, NOCAPS,
                      ":%s AWAY :%s", use_id(source_p), source_p->user->away);
    }

    if(MyConnect(source_p))
        sendto_one_numeric(source_p, RPL_NOWAWAY, form_str(RPL_NOWAWAY));

    sendto_common_channels_local_butone(source_p, CLICAP_AWAY_NOTIFY, NOCAPS, ":%s!%s@%s AWAY :%s",
                                        source_p->name, source_p->username, source_p->host,
                                        source_p->user->away);

    return 0;
}
예제 #5
0
static void do_join_0(struct Client *client_p, struct Client *source_p)
{
  struct Channel *chptr=NULL;
  dlink_node   *lp;

  /* Finish the flood grace period... */
  if(MyClient(source_p) && !IsFloodDone(source_p))
      flood_endgrace(source_p);
          
          
  sendto_server(client_p, NULL, NOCAPS, NOCAPS, 
                ":%s JOIN 0", source_p->name);

  if (source_p->user->channel.head &&
      MyConnect(source_p) && !IsOper(source_p))
   check_spambot_warning(source_p, NULL);

  while ((lp = source_p->user->channel.head))
    {
      chptr = lp->data;
      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(chptr, source_p);
    }
}
예제 #6
0
/*
** m_part
**      parv[0] = sender prefix
**      parv[1] = channel
**      parv[2] = reason
*/
static void
m_part(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
{
	char *p, *name;
	char reason[TOPICLEN + 1];

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

	reason[0] = '\0';

	if(parc > 2)
		strlcpy(reason, parv[2], sizeof(reason));

	name = strtoken(&p, parv[1], ",");

	/* Finish the flood grace period... */
	if(MyClient(source_p) && !IsFloodDone(source_p))
		flood_endgrace(source_p);

	while (name)
	{
		part_one_client(client_p, source_p, name, reason);
		name = strtoken(&p, (char *) NULL, ",");
	}
	return;
}
예제 #7
0
static void
mo_away(struct Client *client_p, struct Client *source_p,
        int parc, char *parv[])
{
  char *cur_away_msg = source_p->user->away;
  char *new_away_msg;
  size_t nbytes = 0;

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

  if (parc < 2 || EmptyString(parv[1]))
  {
    /* Marking as not away */
    if (cur_away_msg)
    {
      /* we now send this only if they were away before --is */
      sendto_server(client_p, source_p, NULL, CAP_TS6, NOCAPS,
                    NOFLAGS, ":%s AWAY", ID(source_p));
      sendto_server(client_p, source_p, NULL, NOCAPS, CAP_TS6,
                    NOFLAGS, ":%s AWAY", source_p->name);

      MyFree(cur_away_msg);
      source_p->user->away = NULL;
    }

    sendto_one(source_p, form_str(RPL_UNAWAY),
               me.name, parv[0]);
    return;
  }

  source_p->user->last_away = CurrentTime;
  new_away_msg              = parv[1];

  nbytes = strlen(new_away_msg);
  if (nbytes > (size_t)TOPICLEN) {
    new_away_msg[TOPICLEN] = '\0';
    nbytes = TOPICLEN;
  }

  /* we now send this only if they
   * weren't away already --is */
  if (!cur_away_msg)
  {
    sendto_server(client_p, source_p, NULL, CAP_TS6, NOCAPS,
                  NOFLAGS, ":%s AWAY :%s", ID(source_p), new_away_msg);
    sendto_server(client_p, source_p, NULL, NOCAPS, CAP_TS6,
                  NOFLAGS, ":%s AWAY :%s", source_p->name, new_away_msg);
  }
  else
    MyFree(cur_away_msg);

  cur_away_msg = MyMalloc(nbytes + 1);
  strcpy(cur_away_msg, new_away_msg);
  source_p->user->away = cur_away_msg;

  sendto_one(source_p, form_str(RPL_NOWAWAY), me.name, parv[0]);
}
예제 #8
0
static int
m_cycle(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
    char *p, *name;
    char *s = LOCAL_COPY(parv[1]);
    struct Channel *chptr;
    struct membership *msptr;

    name = rb_strtok_r(s, ",", &p);

    /* Finish the flood grace period... */
    if(MyClient(source_p) && !IsFloodDone(source_p))
        flood_endgrace(source_p);

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

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

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

        if((is_any_op(msptr) || !MyConnect(source_p) ||
            ((can_send(chptr, source_p, msptr) > 0 &&
              (source_p->localClient->firsttime +
               ConfigFileEntry.anti_spam_exit_message_time) < rb_current_time())))) {
            sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
                          ":%s PART %s :Cycling", use_id(source_p), chptr->chname);
            sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s :Cycling",
                                 source_p->name, source_p->username,
                                 source_p->host, chptr->chname);
        } else {
            sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
                          ":%s PART %s", use_id(source_p), 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);

        chptr = NULL;
        msptr = NULL;

        name = rb_strtok_r(NULL, ",", &p);
    }

    user_join(client_p, source_p, parv[1], parc > 2 ? parv[2] : NULL);

    return 0;
}
예제 #9
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;
}
예제 #10
0
/*
** m_oper
**      parv[0] = sender prefix
**      parv[1] = oper name
**      parv[2] = oper password
*/
static void
m_oper(struct Client *client_p, struct Client *source_p,
       int parc, char *parv[])
{
  struct ConfItem *conf;
  struct AccessItem *aconf=NULL;
  const char *name = parv[1];
  const char *password = parv[2];

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

  /* end the grace period */
  if (!IsFloodDone(source_p))
    flood_endgrace(source_p);

  if ((conf = find_password_conf(name,source_p)) == NULL)
  {
    sendto_one(source_p, form_str(ERR_NOOPERHOST), me.name, source_p->name);
    conf = find_exact_name_conf(OPER_TYPE, name, NULL, NULL);
    failed_oper_notice(source_p, name, (conf != NULL) ?
                       "host mismatch" : "no oper {} block");
    log_failed_oper(source_p, name);
    return;
  }

  aconf = (struct AccessItem *)map_to_conf(conf);

  if (match_oper_password(password, aconf))
  {
    if (attach_conf(source_p, conf) != 0)
    {
      sendto_one(source_p, ":%s NOTICE %s :Can't attach conf!",
                 me.name, source_p->name);
      failed_oper_notice(source_p, name, "can't attach conf!");
      log_failed_oper(source_p, name);
      return;
    }

    oper_up(source_p);

    ilog(L_TRACE, "OPER %s by %s!%s@%s",
         name, source_p->name, source_p->username, source_p->host);
    log_oper(source_p, name);
  }
  else
  {
    sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), me.name, parv[0]);
    failed_oper_notice(source_p, name, "password mismatch");
    log_failed_oper(source_p, name);
  }
}
예제 #11
0
파일: m_time.c 프로젝트: awilfox/charybdis
/*
 * m_time
 *      parv[1] = servername
 */
static void
m_time(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	/* this is not rate limited, so end the grace period */
	if(MyClient(source_p) && !IsFloodDone(source_p))
		flood_endgrace(source_p);

	if(hunt_server(client_p, source_p, ":%s TIME :%s", 1, parc, parv) == HUNTED_ISME)
		sendto_one_numeric(source_p, RPL_TIME, form_str(RPL_TIME),
				   me.name, date());
}
예제 #12
0
/*
 * m_away
 *  parv[0] = sender prefix
 *  parv[1] = away message
 */
static void
m_away(struct Client *client_p, struct Client *source_p,
       int parc, char *parv[])
{
  if (!IsFloodDone(source_p))
    flood_endgrace(source_p);

  if (parc < 2 || EmptyString(parv[1]))
  {
    /* Marking as not away */
    if (source_p->away[0])
    {
      source_p->away[0] = '\0';
      /* we now send this only if they were away before --is */
      sendto_server(client_p, CAP_TS6, NOCAPS,
                    ":%s AWAY", ID(source_p));
      sendto_server(client_p, NOCAPS, CAP_TS6,
                    ":%s AWAY", source_p->name);
      sendto_common_channels_local(source_p, 1, CAP_AWAY_NOTIFY,
                                   ":%s!%s@%s AWAY",
                                   source_p->name, source_p->username,
                                   source_p->host);
    }

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

  if ((CurrentTime - source_p->localClient->last_away) < ConfigFileEntry.pace_wait)
  {
    sendto_one(source_p, form_str(RPL_LOAD2HI),
               me.name, source_p->name);
    return;
  }

  source_p->localClient->last_away = CurrentTime;
  sendto_one(source_p, form_str(RPL_NOWAWAY), me.name, source_p->name);

  if (!strncmp(source_p->away, parv[1], sizeof(source_p->away) - 1))
    return;

  strlcpy(source_p->away, parv[1], sizeof(source_p->away));

  sendto_common_channels_local(source_p, 1, CAP_AWAY_NOTIFY,
                               ":%s!%s@%s AWAY :%s",
                               source_p->name, source_p->username,
                               source_p->host, source_p->away);
  sendto_server(client_p, CAP_TS6, NOCAPS,
                ":%s AWAY :%s", ID(source_p), source_p->away);
  sendto_server(client_p, NOCAPS, CAP_TS6,
                ":%s AWAY :%s", source_p->name, source_p->away);
}
예제 #13
0
/*
** m_oper
**      parv[0] = sender prefix
**      parv[1] = oper name
**      parv[2] = oper password
*/
static void
m_oper(struct Client *client_p, struct Client *source_p,
       int parc, char *parv[])
{
  struct MaskItem *conf = NULL;
  const char *name = parv[1];
  const char *password = parv[2];

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

  /* end the grace period */
  if (!IsFloodDone(source_p))
    flood_endgrace(source_p);

  if ((conf = find_exact_name_conf(CONF_OPER, source_p, name, NULL, NULL)) == NULL)
  {
    sendto_one(source_p, form_str(ERR_NOOPERHOST), me.name, source_p->name);
    conf = find_exact_name_conf(CONF_OPER, NULL, name, NULL, NULL);
    failed_oper_notice(source_p, name, (conf != NULL) ?
                       "host mismatch" : "no oper {} block");
    return;
  }

  if (match_conf_password(password, conf))
  {
    if (attach_conf(source_p, conf) != 0)
    {
      sendto_one(source_p, ":%s NOTICE %s :Can't attach conf!",
                 me.name, source_p->name);
      failed_oper_notice(source_p, name, "can't attach conf!");
      return;
    }

    ++conf->count;
    oper_up(source_p);

    ilog(LOG_TYPE_OPER, "OPER %s by %s!%s@%s",
         name, source_p->name, source_p->username, source_p->host);
  }
  else
  {
    sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), me.name, source_p->name);
    failed_oper_notice(source_p, name, "password mismatch");
  }
}
예제 #14
0
/*! \brief TIME command handler
 *
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = command
 *      - parv[1] = nickname/servername
 */
static int
m_time(struct Client *source_p, int parc, char *parv[])
{
  /* This is not rate limited, so end the grace period */
  if (!IsFloodDone(source_p))
    flood_endgrace(source_p);

  /* This is safe enough to use during non hidden server mode */
  if (!ConfigServerHide.disable_remote_commands)
    if (hunt_server(source_p, ":%s TIME :%s", 1, parc, parv) != HUNTED_ISME)
      return 0;

  sendto_one_numeric(source_p, &me, RPL_TIME, me.name, date(0));
  return 0;
}
예제 #15
0
파일: m_time.c 프로젝트: azzurra/bluebox
/*
 * m_time
 *      parv[0] = sender prefix
 *      parv[1] = servername
 */
static int
m_time(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
    /* this is not rate limited, so end the grace period */
    char buf[80];
    if (MyClient(source_p) && !IsFloodDone(source_p))
        flood_endgrace(source_p);


    if (hunt_server(client_p, source_p, ":%s TIME :%s", 1, parc, parv) == HUNTED_ISME)
    {
        sendto_one_numeric(source_p, RPL_TIME, form_str(RPL_TIME),
                           me.name, rb_date(rb_current_time(), buf, sizeof(buf)));
    }
    return 0;
}
예제 #16
0
파일: m_part.c 프로젝트: nask0/ircd-hybrid
/*! \brief PART 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] = part message
 */
static int
m_part(struct Client *source_p, int parc, char *parv[])
{
  if (EmptyString(parv[1]))
  {
    sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "PART");
    return 0;
  }

  /* Finish the flood grace period... */
  if (MyClient(source_p) && !IsFloodDone(source_p))
    flood_endgrace(source_p);

  channel_do_part(source_p, parv[1], parv[2]);
  return 0;
}
예제 #17
0
/*
 * m_time
 *      parv[0] = sender prefix
 *      parv[1] = servername
 */
static void m_time(struct Client *client_p, struct Client *source_p,
                  int parc, char *parv[])
{
  /* this is not rate limited, so end the grace period */
  if(MyClient(source_p) && !IsFloodDone(source_p))
    flood_endgrace(source_p);

  /* This is safe enough to use during non hidden server mode */
  if(!ConfigServerHide.disable_remote)
    {
      if (hunt_server(client_p,source_p,":%s TIME :%s",1,parc,parv) != HUNTED_ISME)
        return;
    }

  sendto_one(source_p, form_str(RPL_TIME), me.name,
             parv[0], me.name, date(0));
}
예제 #18
0
/*
** m_away
**      parv[0] = sender prefix
**      parv[1] = away message
*/
static int
m_away(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	if(MyClient(source_p) && !IsFloodDone(source_p))
		flood_endgrace(source_p);

	if(!IsClient(source_p))
		return 0;

	if(parc < 2 || EmptyString(parv[1]))
	{
		/* Marking as not away */
		if(source_p->user->away != NULL)
		{
			/* we now send this only if they were away before --is */
			sendto_server(client_p, NULL, CAP_TS6, NOCAPS,
				      ":%s AWAY", use_id(source_p));
			sendto_server(client_p, NULL, NOCAPS, CAP_TS6, ":%s AWAY", source_p->name);
			free_away(source_p);
		}
		if(MyConnect(source_p))
			sendto_one(source_p, form_str(RPL_UNAWAY), me.name, source_p->name);
		return 0;
	}


	if(source_p->user->away == NULL)
	{
		allocate_away(source_p);
		rb_strlcpy(source_p->user->away, parv[1], AWAYLEN);
		sendto_server(client_p, NULL, CAP_TS6, NOCAPS,
			      ":%s AWAY :%s", use_id(source_p), source_p->user->away);
		sendto_server(client_p, NULL, NOCAPS, CAP_TS6,
			      ":%s AWAY :%s", source_p->name, source_p->user->away);

	}
	else
	{
		rb_strlcpy(source_p->user->away, parv[1], AWAYLEN);
	}

	if(MyConnect(source_p))
		sendto_one(source_p, form_str(RPL_NOWAWAY), me.name, source_p->name);

	return 0;
}
예제 #19
0
/*
** m_away
**      parv[1] = away message
*/
static int
m_away(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	if(MyClient(source_p) && !IsFloodDone(source_p))
		flood_endgrace(source_p);

	if(!IsClient(source_p))
		return 0;

	if(parc < 2 || EmptyString(parv[1]))
	{
		/* Marking as not away */
		if(source_p->user->away != NULL)
		{
			/* we now send this only if they were away before --is */
			sendto_server(client_p, NULL, CAP_TS6, NOCAPS,
				      ":%s AWAY", use_id(source_p));
			free_away(source_p);

			sendto_common_channels_local_butone(source_p, CLICAP_AWAY_NOTIFY, NOCAPS, ":%s!%s@%s AWAY",
							    source_p->name, source_p->username, source_p->host);
		}
		if(MyConnect(source_p))
			sendto_one_numeric(source_p, RPL_UNAWAY, form_str(RPL_UNAWAY));
		return 0;
	}

	if(source_p->user->away == NULL)
		allocate_away(source_p);
	if(strncmp(source_p->user->away, parv[1], AWAYLEN - 1))
	{
		rb_strlcpy(source_p->user->away, parv[1], AWAYLEN);
		sendto_server(client_p, NULL, CAP_TS6, NOCAPS, 
			      ":%s AWAY :%s", use_id(source_p), source_p->user->away);
	}
	
	if(MyConnect(source_p))
		sendto_one_numeric(source_p, RPL_NOWAWAY, form_str(RPL_NOWAWAY));

	sendto_common_channels_local_butone(source_p, CLICAP_AWAY_NOTIFY, NOCAPS, ":%s!%s@%s AWAY :%s",
					    source_p->name, source_p->username, source_p->host,
					    source_p->user->away);

	return 0;
}
예제 #20
0
/*
 * inputs       - flag privmsg or notice
 *              - pointer to command "PRIVMSG" or "NOTICE"
 *              - pointer to source_p
 *              - pointer to channel
 */
static void
m_message(int p_or_n, const char *command, struct Client *source_p, int parc, char *parv[])
{
  if (parc < 2 || EmptyString(parv[1]))
  {
    if (p_or_n != NOTICE)
      sendto_one_numeric(source_p, &me, ERR_NORECIPIENT, command);
    return;
  }

  if (parc < 3 || EmptyString(parv[2]))
  {
    if (p_or_n != NOTICE)
      sendto_one_numeric(source_p, &me, ERR_NOTEXTTOSEND);
    return;
  }

  /* Finish the flood grace period... */
  if (MyClient(source_p) && !IsFloodDone(source_p))
    flood_endgrace(source_p);

  if (build_target_list(p_or_n, command, source_p, parv[1], parv[2]) < 0)
    return;

  for (unsigned int i = 0; i < ntargets; ++i)
  {
    switch (targets[i].type)
    {
      case ENTITY_CLIENT:
        msg_client(p_or_n, command, source_p, targets[i].ptr, parv[2]);
        break;

      case ENTITY_CHANNEL:
        msg_channel(p_or_n, command, source_p, targets[i].ptr, parv[2]);
        break;

      case ENTITY_CHANOPS_ON_CHANNEL:
        msg_channel_flags(p_or_n, command, source_p, targets[i].ptr,
                          targets[i].flags, parv[2]);
        break;
    }
  }
}
예제 #21
0
/*
** m_part
**      parv[0] = sender prefix
**      parv[1] = channel
**      parv[2] = reason
*/
static int
m_part(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	char *p, *name;
	char *reason = NULL;
	char *s = LOCAL_COPY(parv[1]);

	if(parc > 2)
		reason = LOCAL_COPY_N(parv[2], REASONLEN);

	name = rb_strtok_r(s, ",", &p);

	/* Finish the flood grace period... */
	if(MyClient(source_p) && !IsFloodDone(source_p))
		flood_endgrace(source_p);

	while(name)
	{
		part_one_client(client_p, source_p, name, reason);
		name = rb_strtok_r(NULL, ",", &p);
	}
	return 0;
}
예제 #22
0
파일: m_kick.c 프로젝트: azzurra/bluebox
/*
** m_kick
**      parv[0] = sender prefix
**      parv[1] = channel
**      parv[2] = client to kick
**      parv[3] = kick comment
*/
static int
m_kick(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
    struct membership *msptr;
    struct Client *who;
    struct Channel *chptr;
    int chasing = 0;
    int halfop = 0;
    char *comment;
    const char *name;
    char *p = NULL;
    const char *user;
    static char buf[BUFSIZE];

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

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

    name = parv[1];

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

    if (!IsServer(source_p))
    {
        msptr = find_channel_membership(chptr, source_p);

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

        if (!is_chanop(msptr) && !is_halfop(msptr))
        {
            if (MyConnect(source_p))
            {
                sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
                           me.name, source_p->name, name);
                return 0;
            }

            /* If its a TS 0 channel, do it the old way */
            if (chptr->channelts == 0)
            {
                sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
                           get_id(&me, source_p), get_id(source_p, source_p), name);
                return 0;
            }
        }
        halfop = !is_chanop(msptr) && is_halfop(msptr);

        /* Its a user doing a kick, but is not showing as chanop locally
         * its also not a user ON -my- server, and the channel has a TS.
         * There are two cases we can get to this point then...
         *
         *     1) connect burst is happening, and for some reason a legit
         *        op has sent a KICK, but the SJOIN hasn't happened yet or
         *        been seen. (who knows.. due to lag...)
         *
         *     2) The channel is desynced. That can STILL happen with TS
         *
         *     Now, the old code roger wrote, would allow the KICK to
         *     go through. Thats quite legit, but lets weird things like
         *     KICKS by users who appear not to be chanopped happen,
         *     or even neater, they appear not to be on the channel.
         *     This fits every definition of a desync, doesn't it? ;-)
         *     So I will allow the KICK, otherwise, things are MUCH worse.
         *     But I will warn it as a possible desync.
         *
         *     -Dianora
         */
    }

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

    user = parv[2];

    if (!(who = find_chasing(source_p, user, &chasing)))
    {
        return 0;
    }

    msptr = find_channel_membership(chptr, who);

    if (msptr != NULL)
    {
        if (MyClient(source_p) && IsService(who))
        {
            sendto_one(source_p, form_str(ERR_ISCHANSERVICE),
                       me.name, source_p->name, who->name, chptr->chname);
            return 0;
        }

        if (halfop && (is_chanop(msptr) || is_halfop(msptr)))
        {
            if (MyConnect(source_p))
            {
                sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
                           me.name, source_p->name, name);
                return 0;
            }

            /* If its a TS 0 channel, do it the old way */
            if (chptr->channelts == 0)
            {
                sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
                           get_id(&me, source_p), get_id(source_p, source_p), name);
                return 0;
            }
        }

        comment = LOCAL_COPY_N((EmptyString(parv[3])) ? who->name : parv[3], REASONLEN);

        /* jdc
         * - In the case of a server kicking a user (i.e. CLEARCHAN),
         *   the kick should show up as coming from the server which did
         *   the kick.
         * - Personally, flame and I believe that server kicks shouldn't
         *   be sent anyways.  Just waiting for some oper to abuse it...
         */
        if (IsServer(source_p))
            sendto_channel_local(ALL_MEMBERS, chptr, ":%s KICK %s %s :%s",
                                 source_p->name, name, who->name, comment);
        else
            sendto_channel_local(ALL_MEMBERS, chptr,
                                 ":%s!%s@%s KICK %s %s :%s",
                                 source_p->name, source_p->username,
                                 IsCloaked(source_p) ? source_p->virthost : source_p->host,
                                 name, who->name, comment);

        sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
                      ":%s KICK %s %s :%s",
                      use_id(source_p), chptr->chname, use_id(who), comment);
        sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
                      ":%s KICK %s %s :%s",
                      source_p->name, chptr->chname, who->name, comment);
        remove_user_from_channel(msptr);
    }
    else if (MyClient(source_p))
        sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL,
                           form_str(ERR_USERNOTINCHANNEL), user, name);

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

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

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

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

	chptr = find_channel(parv[1]);

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

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

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

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

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

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

	return 0;
}
예제 #24
0
/*! \brief NICK command handler (called by already registered,
 *         locally connected clients)
 *
 * \param client_p Pointer to allocated Client struct with physical connection
 *                 to this server, i.e. with an open socket connected.
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = sender prefix
 *      - parv[1] = nickname
 */
static void
m_nick(struct Client *client_p, struct Client *source_p,
       int parc, char *parv[])
{
  char nick[NICKLEN + 1] = { '\0' };
  struct Client *target_p = NULL;
  struct MaskItem *conf = NULL;

  assert(source_p == client_p);

  if (parc < 2 || EmptyString(parv[1]))
  {
    sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN),
               me.name, source_p->name);
    return;
  }

  /* mark end of grace period, to prevent nickflooding */
  if (!IsFloodDone(source_p))
    flood_endgrace(source_p);

  /* terminate nick to NICKLEN */
  strlcpy(nick, parv[1], IRCD_MIN(sizeof(nick), ServerInfo.max_nick_length + 1));

  /* check the nickname is ok */
  if (!valid_nickname(nick, 1))
  {
    sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME), me.name,
               source_p->name, nick, "Erroneous Nickname");
    return;
  }

  if (!IsExemptResv(source_p) &&
      !(HasUMode(source_p, UMODE_OPER) && ConfigFileEntry.oper_pass_resv) &&
      (conf = find_matching_name_conf(CONF_NRESV, nick, NULL, NULL, 0)))
  {
    ++conf->count;
    sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME),
               me.name, source_p->name, nick, conf->reason);
    sendto_realops_flags(UMODE_REJ, L_ALL, SEND_NOTICE,
                         "Forbidding reserved nick [%s] from user %s",
                         nick, get_client_name(client_p, HIDE_IP));
    return;
  }

  if ((target_p = hash_find_client(nick)) == NULL)
    change_local_nick(source_p, nick);
  else if (target_p == source_p)
  {
    /*
     * If (target_p == source_p) the client is changing nicks between
     * equivalent nicknames ie: [nick] -> {nick}
     */

    /* Check the nick isn't exactly the same */
    if (strcmp(target_p->name, nick))
      change_local_nick(source_p, nick);
  }
  else if (IsUnknown(target_p))
  {
    /*
     * If the client that has the nick isn't registered yet (nick but no
     * user) then drop the unregged client
     */
    exit_client(target_p, &me, "Overridden");
    change_local_nick(source_p, nick);
  }
  else
    sendto_one(source_p, form_str(ERR_NICKNAMEINUSE), me.name,
               source_p->name, nick);
}
예제 #25
0
static int
m_remove(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct membership *msptr;
	struct Client *who;
	struct Channel *chptr;
	int chasing = 0;
	char *comment;
	const char *name;
	char *p = NULL;
	const char *user;
	static char buf[BUFSIZE];

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

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

	name = parv[1];

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

	if(!IsServer(source_p))
	{
		msptr = find_channel_membership(chptr, source_p);

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

		if(get_channel_access(source_p, msptr, MODE_ADD) < CHFL_CHANOP)
		{
			if(MyConnect(source_p))
			{
				sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
					   me.name, source_p->name, name);
				return 0;
			}

			/* If its a TS 0 channel, do it the old way */
			if(chptr->channelts == 0)
			{
				sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
					   get_id(&me, source_p), get_id(source_p, source_p), name);
				return 0;
			}
		}

		/* Its a user doing a kick, but is not showing as chanop locally
		 * its also not a user ON -my- server, and the channel has a TS.
		 * There are two cases we can get to this point then...
		 *
		 *     1) connect burst is happening, and for some reason a legit
		 *        op has sent a KICK, but the SJOIN hasn't happened yet or
		 *        been seen. (who knows.. due to lag...)
		 *
		 *     2) The channel is desynced. That can STILL happen with TS
		 *
		 *     Now, the old code roger wrote, would allow the KICK to
		 *     go through. Thats quite legit, but lets weird things like
		 *     KICKS by users who appear not to be chanopped happen,
		 *     or even neater, they appear not to be on the channel.
		 *     This fits every definition of a desync, doesn't it? ;-)
		 *     So I will allow the KICK, otherwise, things are MUCH worse.
		 *     But I will warn it as a possible desync.
		 *
		 *     -Dianora
		 */
	}

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

	user = parv[2];		/* strtoken(&p2, parv[2], ","); */

	if(!(who = find_chasing(source_p, user, &chasing)))
	{
		return 0;
	}

	msptr = find_channel_membership(chptr, who);

	if(msptr != NULL)
	{
		if(MyClient(source_p) && IsService(who))
		{
			sendto_one(source_p, form_str(ERR_ISCHANSERVICE),
				   me.name, source_p->name, who->name, chptr->chname);
			return 0;
		}

		if(MyClient(source_p))
		{
			hook_data_channel_approval hookdata;

			hookdata.client = source_p;
			hookdata.chptr = chptr;
			hookdata.msptr = msptr;
			hookdata.target = who;
			hookdata.approved = 1;
			hookdata.dir = MODE_ADD;	/* ensure modules like override speak up */

			call_hook(h_can_kick, &hookdata);

			if (!hookdata.approved)
				return 0;
		}

		comment = LOCAL_COPY((EmptyString(parv[3])) ? who->name : parv[3]);
		if(strlen(comment) > (size_t) REASONLEN)
			comment[REASONLEN] = '\0';

		/* jdc
		 * - In the case of a server kicking a user (i.e. CLEARCHAN),
		 *   the kick should show up as coming from the server which did
		 *   the kick.
		 * - Personally, flame and I believe that server kicks shouldn't
		 *   be sent anyways.  Just waiting for some oper to abuse it...
		 */
		sendto_channel_local(ALL_MEMBERS, chptr,
				     ":%s!%s@%s PART %s :requested by %s (%s)",
				     who->name, who->username,
				     who->host, name, source_p->name, comment);

		sendto_server(client_p, chptr, CAP_REMOVE, NOCAPS,
			      ":%s REMOVE %s %s :%s",
			      use_id(source_p), chptr->chname, use_id(who), comment);
		sendto_server(client_p, chptr, NOCAPS, CAP_REMOVE,
			      ":%s KICK %s %s :%s",
			      use_id(source_p), chptr->chname, use_id(who), comment);

		remove_user_from_channel(msptr);
	}
	else if (MyClient(source_p))
		sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL,
				   form_str(ERR_USERNOTINCHANNEL), user, name);

	return 0;
}
예제 #26
0
/*
 * m_topic
 *      parv[1] = channel name
 *	parv[2] = new topic, if setting topic
 */
static int
m_topic(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct Channel *chptr = NULL;
	struct membership *msptr;
	char *p = NULL;
	const char *name;
	int operspy = 0;

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

	name = parv[1];

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

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

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

	chptr = find_channel(name);

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

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

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

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

		if(((chptr->mode.mode & MODE_TOPICLIMIT) == 0 ||
					get_channel_access(source_p, chptr, msptr, MODE_ADD, NULL) >= CHFL_CHANOP) &&
				(!MyClient(source_p) ||
				 can_send(chptr, source_p, msptr)))
		{
			char topic[TOPICLEN + 1];
			char topic_info[USERHOST_REPLYLEN];
			rb_strlcpy(topic, parv[2], sizeof(topic));
			rb_sprintf(topic_info, "%s!%s@%s",
					source_p->name, source_p->username, source_p->host);

			if (ConfigChannel.strip_topic_colors)
				strip_colour(topic);

			set_channel_topic(chptr, topic, topic_info, rb_current_time());

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

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

	return 0;
}
예제 #27
0
/*
** m_oper
**      parv[0] = sender prefix
**      parv[1] = oper name
**      parv[2] = oper password
*/
static void
m_oper(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
{
	struct ConfItem *aconf;
	struct ConfItem *oconf = NULL;
	char *name;
	char *password;
	dlink_node *ptr;

	name = parv[1];
	password = parv[2];

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

	/* end the grace period */
	if(!IsFloodDone(source_p))
		flood_endgrace(source_p);

	if((aconf = find_password_aconf(name, source_p)) == NULL)
	{
		sendto_one(source_p, form_str(ERR_NOOPERHOST), me.name, source_p->name);
		log_foper(source_p, name);

		if(ConfigFileEntry.failed_oper_notice)
		{
			sendto_realops_flags(UMODE_ALL, L_ALL,
					     "Failed OPER attempt - host mismatch by %s (%s@%s)",
					     source_p->name, source_p->username, source_p->host);
		}
		return;
	}

	if(match_oper_password(password, aconf))
	{
		/*
		   20001216:
		   detach old iline
		   -einride
		 */
		ptr = source_p->localClient->confs.head;
		if(ptr)
		{

			oconf = ptr->data;
			detach_conf(source_p, oconf);
		}

		if(attach_conf(source_p, aconf) != 0)
		{
			sendto_one(source_p, ":%s NOTICE %s :Can't attach conf!",
				   me.name, source_p->name);
			sendto_realops_flags(UMODE_ALL, L_ALL,
					     "Failed OPER attempt by %s (%s@%s) can't attach conf!",
					     source_p->name, source_p->username, source_p->host);
			log_foper(source_p, name);
			/* 
			   20001216:
			   Reattach old iline
			   -einride
			 */
			attach_conf(source_p, oconf);
			return;
		}

		oper_up(source_p, aconf);

		ilog(L_TRACE, "OPER %s by %s!%s@%s",
		     name, source_p->name, source_p->username, source_p->host);
		log_oper(source_p, name);
		return;
	}
	else
	{
		sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), me.name, parv[0]);
		log_foper(source_p, name);

		if(ConfigFileEntry.failed_oper_notice)
		{
			sendto_realops_flags(UMODE_ALL, L_ALL,
					     "Failed OPER attempt by %s (%s@%s)",
					     source_p->name, source_p->username, source_p->host);
		}
	}
}
예제 #28
0
/*
** m_away
**      parv[0] = sender prefix
**      parv[1] = away message
*/
static void
m_away(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
{
	char *away, *awy2 = parv[1];

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

	if(!IsClient(source_p))
		return;

	away = source_p->user->away;

	if(parc < 2 || !*awy2)
	{
		/* Marking as not away */

		if(away)
		{
			/* we now send this only if they were away before --is */
			sendto_server(client_p, NULL, NOCAPS, NOCAPS, ":%s AWAY", source_p->name);
			MyFree(away);
			source_p->user->away = NULL;
		}
		if(MyConnect(source_p))
			sendto_one(source_p, form_str(RPL_UNAWAY), me.name, parv[0]);
		return;
	}

	/* Marking as away */

	if(MyConnect(source_p) && !IsOper(source_p) &&
	   (CurrentTime - source_p->user->last_away) < ConfigFileEntry.pace_wait)
	{
		sendto_one(source_p, form_str(RPL_LOAD2HI),
			   me.name, parv[0], "AWAY");
		return;
	}

	source_p->user->last_away = CurrentTime;

	if(strlen(awy2) > (size_t) TOPICLEN)
		awy2[TOPICLEN] = '\0';

	/* we now send this only if they weren't away already --is */
	if(!away)
	{
		sendto_server(client_p, NULL, NOCAPS, NOCAPS,
			      ":%s AWAY :%s", source_p->name, awy2);
	}
	else
		MyFree(away);

	away = (char *) MyMalloc(strlen(awy2) + 1);
	strcpy(away, awy2);

	source_p->user->away = away;

	if(MyConnect(source_p))
		sendto_one(source_p, form_str(RPL_NOWAWAY), me.name, parv[0]);
}
예제 #29
0
/*
 * 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);
    }
  }
}
예제 #30
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);
}