Example #1
0
static void
ms_ping(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
{
	struct Client *target_p;
	const char *origin, *destination;

	if(parc < 2 || *parv[1] == '\0')
	{
		sendto_one(source_p, form_str(ERR_NOORIGIN), me.name, parv[0]);
		return;
	}

	origin = source_p->name;
	destination = parv[2];	/* Will get NULL or pointer (parc >= 2!!) */

	if(!EmptyString(destination) && irccmp(destination, me.name) != 0
	   && irccmp(destination, me.id) != 0)
	{
		if((target_p = find_server(destination)))
			sendto_one(target_p, ":%s PING %s :%s", parv[0], origin, destination);
		else
		{
			sendto_one(source_p, form_str(ERR_NOSUCHSERVER),
				   ID_or_name(&me, client_p), parv[0], destination);
			return;
		}
	}
	else
		sendto_one(source_p, ":%s PONG %s :%s",
			   ID_or_name(&me, client_p), (destination) ? destination : me.name,
			   origin);
}
Example #2
0
/* apply_tdline()
 *
 * inputs	-
 * output	- NONE
 * side effects	- tkline as given is placed
 */
static void
apply_dline(struct Client *source_p, struct MaskItem *conf,
            time_t tkline_time)
{
  if (tkline_time)
  {
    conf->until = CurrentTime + tkline_time;
    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
                         "%s added temporary %d min. D-Line for [%s] [%s]",
                         get_oper_name(source_p), tkline_time/60,
                         conf->host, conf->reason);
    sendto_one(source_p, ":%s NOTICE %s :Added temporary %d min. D-Line [%s]",
               MyConnect(source_p) ? me.name : ID_or_name(&me, source_p->from),
               source_p->name, tkline_time/60, conf->host);
    ilog(LOG_TYPE_DLINE, "%s added temporary %d min. D-Line for [%s] [%s]",
         get_oper_name(source_p), tkline_time/60, conf->host, conf->reason);
  }
  else
  {
    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
                         "%s added D-Line for [%s] [%s]",
                         get_oper_name(source_p), conf->host, conf->reason);
    sendto_one(source_p, ":%s NOTICE %s :Added D-Line [%s]",
               MyConnect(source_p) ? me.name : ID_or_name(&me, source_p->from),
               source_p->name, conf->host);
    ilog(LOG_TYPE_DLINE, "%s added D-Line for [%s] [%s]",
         get_oper_name(source_p), conf->host, conf->reason);

  }

  SetConfDatabase(conf);
  conf->setat = CurrentTime;
  add_conf_by_address(CONF_DLINE, conf);
  rehashed_klines = 1;
}
Example #3
0
/*
 * ms_tmode()
 *
 * inputs	- parv[0] = UID
 *		  parv[1] = TS
 *		  parv[2] = channel name
 *		  parv[3] = modestring
 */
static void
ms_tmode(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
{
  struct Channel *chptr = NULL;
  struct Membership *member = NULL;

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

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

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

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

    set_channel_mode(client_p, source_p, chptr, member, parc - 3, parv + 3, chptr->chname);
  }
}
Example #4
0
/*! \brief PONG 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] = origin
 *      - parv[2] = destination
 */
static int
ms_pong(struct Client *source_p, int parc, char *parv[])
{
    struct Client *target_p = NULL;
    const char *destination = NULL;

    if (parc < 2 || EmptyString(parv[1]))
    {
        sendto_one_numeric(source_p, &me, ERR_NOORIGIN);
        return 0;
    }

    destination = parv[2];

    /* Now attempt to route the PONG, comstud pointed out routable PING
     * is used for SPING.  routable PING should also probably be left in
     *        -Dianora
     * That being the case, we will route, but only for registered clients (a
     * case can be made to allow them only from servers). -Shadowfax
     */
    if (!EmptyString(destination) && match(destination, me.name) &&
            irccmp(destination, me.id))
    {
        if ((target_p = hash_find_client(destination)) ||
                (target_p = hash_find_id(destination)))
            sendto_one(target_p, ":%s PONG %s %s",
                       ID_or_name(source_p, target_p), parv[1],
                       ID_or_name(target_p, target_p));
        else if (!IsDigit(*destination))
            sendto_one_numeric(source_p, &me, ERR_NOSUCHSERVER, destination);
    }

    return 0;
}
Example #5
0
/*
 * ms_version - VERSION command handler
 *      parv[0] = sender prefix
 *      parv[1] = remote server
 */
static void
ms_version(struct Client *client_p, struct Client *source_p,
           int parc, char *parv[])
{
  if (hunt_server(client_p, source_p, ":%s VERSION :%s", 
                  1, parc, parv) == HUNTED_ISME)
  {
    sendto_one(source_p, form_str(RPL_VERSION),
               ID_or_name(&me, client_p),
               ID_or_name(source_p, client_p),
               ircd_version, serno,
               me.name, confopts(source_p), serveropts);
    show_isupport(source_p);
  }
}
Example #6
0
/*
** ms_info()
**  parv[0] = sender prefix
**  parv[1] = servername
*/
static void
ms_info(struct Client *client_p, struct Client *source_p,
        int parc, char *parv[])
{
  if (!IsClient(source_p))
      return;
  
  if (hunt_server(client_p, source_p, ":%s INFO :%s", 1, parc, parv) == HUNTED_ISME)
  {
    info_spy(source_p);
    send_info_text(source_p); 

    if (IsOper(source_p))
      send_conf_options(source_p);
      
    send_birthdate_online_time(source_p);
    sendto_one(source_p, form_str(RPL_ENDOFINFO),
               ID_or_name(&me, client_p), ID_or_name(source_p, client_p));

  }
}
Example #7
0
/* msg_channel()
 *
 * inputs	- flag privmsg or notice
 * 		- pointer to command "PRIVMSG" or "NOTICE"
 *		- pointer to client_p
 *		- pointer to source_p
 *		- pointer to channel
 * output	- NONE
 * side effects	- message given channel
 */
static void
msg_channel(int p_or_n, const char *command, struct Client *client_p,
	    struct Client *source_p, struct Channel *chptr, char *text)
{
	int result;

	if(MyClient(source_p))
	{
		/* idle time shouldnt be reset by notices --fl */
		if(p_or_n != NOTICE)
			source_p->localClient->last = CurrentTime;
	}

#ifndef STATIC_MODULES
	execute_callback(channel_message, source_p, chptr, text);
#endif

	/* chanops and voiced can flood their own channel with impunity */
	if((result = can_send(chptr, source_p, NULL, text, p_or_n)) > 0)
	{
		if(result == CAN_SEND_OPV ||
		   !flood_attack_channel(p_or_n, source_p, chptr, chptr->chname))
		{
			sendto_channel_butone(client_p, source_p, chptr, command, ":%s", text);
		}
	}
	else
	{
		if(p_or_n != NOTICE)
		{
			if(result == CAN_SEND_NOREGNICK)
				sendto_one(source_p, form_str(ERR_NEEDREGGEDNICK),
					   ID_or_name(&me, client_p),
					   ID_or_name(source_p, client_p),
					   chptr->chname, "speak in");
			else if(result == CAN_SEND_NOCTRLS)
				sendto_one(source_p, form_str(ERR_NOCTRLSONCHAN),
					   ID_or_name(&me, client_p),
					   ID_or_name(source_p, client_p), chptr->chname, text);
			else if(result == CAN_SEND_NOCTCP)
				sendto_one(source_p, form_str(ERR_NOCTCP),
					ID_or_name(&me, client_p),
					ID_or_name(source_p, client_p), chptr->chname, "channel", text);
			else
				sendto_one(source_p, form_str(ERR_CANNOTSENDTOCHAN),
					   ID_or_name(&me, client_p),
					   ID_or_name(source_p, client_p), chptr->chname);
		}
	}
}
Example #8
0
/* do_admin()
 *
 * inputs	- pointer to client to report to
 * output	- none
 * side effects	- admin info is sent to client given
 */
static void
do_admin(struct Client *source_p)
{
  const char *nick;

  if (IsPerson(source_p))
    admin_spy(source_p);

  nick = ID_or_name(source_p, source_p->from);

  sendto_one(source_p, form_str(RPL_ADMINME),
	     ID_or_name(&me, source_p->from), nick, me.name);
  if (AdminInfo.name != NULL)
    sendto_one(source_p, form_str(RPL_ADMINLOC1),
	       ID_or_name(&me, source_p->from), nick, AdminInfo.name);
  if (AdminInfo.description != NULL)
    sendto_one(source_p, form_str(RPL_ADMINLOC2),
	       ID_or_name(&me, source_p->from), nick, AdminInfo.description);
  if (AdminInfo.email != NULL)
    sendto_one(source_p, form_str(RPL_ADMINEMAIL),
	       ID_or_name(&me, source_p->from), nick, AdminInfo.email);
}
/*! \brief Sends administrative information about this server.
 *
 * \param source_p Pointer to client to report to
 */
static void
do_admin(struct Client *source_p)
{
  const char *me_name = ID_or_name(&me, source_p->from);
  const char *nick = ID_or_name(source_p, source_p->from);

  sendto_realops_flags(UMODE_SPY, L_ALL, SEND_NOTICE,
                       "ADMIN requested by %s (%s@%s) [%s]",
                       source_p->name, source_p->username,
                       source_p->host, source_p->servptr->name);

  sendto_one(source_p, form_str(RPL_ADMINME),
             me_name, nick, me.name);

  if (AdminInfo.name != NULL)
    sendto_one(source_p, form_str(RPL_ADMINLOC1),
               me_name, nick, AdminInfo.name);
  if (AdminInfo.description != NULL)
    sendto_one(source_p, form_str(RPL_ADMINLOC2),
               me_name, nick, AdminInfo.description);
  if (AdminInfo.email != NULL)
    sendto_one(source_p, form_str(RPL_ADMINEMAIL),
               me_name, nick, AdminInfo.email);
}
Example #10
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);
    }
  }
}
Example #11
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 (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);
    }
  }
}
Example #12
0
/*
** 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);
}
Example #13
0
static void
do_ison(struct Client *client_p, struct Client *up, struct Client *source_p,
        int parc, char *parv[])
{
  struct Client *target_p = NULL;
  char *nick;
  char *p;
  char *current_insert_point, *current_insert_point2;
  char buf[IRCD_BUFSIZE];
  char buf2[IRCD_BUFSIZE];
  int len;
  int i;
  int done = 0;
  int relay_to_hub = 0;

  current_insert_point2 = buf2;
  *buf2 = '\0';

  len = ircsprintf(buf, form_str(RPL_ISON), me.name, parv[0]);
  current_insert_point = buf + len;

  /* rfc1459 is ambigious about how to handle ISON
   * this should handle both interpretations.
   */
  for (i = 1; i < parc; i++)
  {
    for (nick = strtoken(&p, parv[i], " "); nick;
         nick = strtoken(&p, NULL, " "))
    {
      if ((target_p = find_person(client_p, nick)))
      {
        len = strlen(target_p->name);

        if ((current_insert_point + (len + 5)) < (buf + sizeof(buf)))
        {
          memcpy(current_insert_point, target_p->name, len);
          current_insert_point += len;
          *current_insert_point++ = ' ';
        }
        else
        {
          done = 1;
          break;
        }
      }

      if (up)
      {
        /* Build up a single list, for use if we relay.. */
        len = strlen(nick);

        if ((current_insert_point2 + len + 5) < (buf2 + sizeof(buf2)))
        {
          memcpy(current_insert_point2, nick, len);
          current_insert_point2 += len;
          *current_insert_point2++ = ' ';
        }

        if (target_p == NULL)
        {
          /*
           * XXX Ick. we need to ask our hub if nick is online.
           * it's probably safest to relay the whole command,
           * unless we can answer it fully ourselves.
           * -davidt
           */
          relay_to_hub = 1;

          /* Also cache info about nick */
          sendto_one(up, ":%s NBURST %s", ID_or_name(&me, up), nick);
        }
      }
    }

    if (done)
      break;
  }

  /*  current_insert_point--;
   *  Do NOT take out the trailing space, it breaks ircII
   *  --Rodder */

  *current_insert_point  = '\0';
  *current_insert_point2 = '\0'; 
  
  if (relay_to_hub)
    sendto_one(up, ":%s ISON :%s", ID_or_name(source_p, up), buf2);
  else
    sendto_one(source_p, "%s", buf);
}
Example #14
0
/*
 *
 *      parc    number of arguments ('sender' counted as one!)
 *      parv[0] pointer to 'sender' (may point to empty string) (not used)
 *      parv[1]..parv[parc-1]
 *              pointers to additional parameters, this is a NULL
 *              terminated list (parv[parc] == NULL).
 *
 * *WARNING*
 *      Numerics are mostly error reports. If there is something
 *      wrong with the message, just *DROP* it! Don't even think of
 *      sending back a neat error message -- big danger of creating
 *      a ping pong error message...
 */
static void
do_numeric(char numeric[], struct Client *client_p, struct Client *source_p,
           int parc, char *parv[])
{
  struct Client *target_p;
  struct Channel *chptr;
  char *t;    /* current position within the buffer */
  int i, tl;  /* current length of presently being built string in t */

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

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

  /* Prepare the parameter portion of the message into 'buffer'.
   * (Because the buffer is twice as large as the message buffer
   * for the socket, no overflow can occur here... ...on current
   * assumptions--bets are off, if these are changed --msa)
   */
  t = buffer;
  for (i = 2; i < (parc - 1); i++)
  {
    tl = ircsprintf(t, " %s", parv[i]);
    t += tl;
  }

  ircsprintf(t," :%s", parv[parc-1]);

  if (((target_p = find_person(client_p, parv[1])) != NULL) ||
      ((target_p = find_server(parv[1])) != NULL))
  {
    if (IsMe(target_p)) 
    {
      int num;

      /*
       * We shouldn't get numerics sent to us,
       * any numerics we do get indicate a bug somewhere..
       */
      /* ugh.  this is here because of nick collisions.  when two servers
       * relink, they burst each other their nicks, then perform collides.
       * if there is a nick collision, BOTH servers will kill their own
       * nicks, and BOTH will kill the other servers nick, which wont exist,
       * because it will have been already killed by the local server.
       *
       * unfortunately, as we cant guarantee other servers will do the
       * "right thing" on a nick collision, we have to keep both kills.  
       * ergo we need to ignore ERR_NOSUCHNICK. --fl_
       */
      /* quick comment. This _was_ tried. i.e. assume the other servers
       * will do the "right thing" and kill a nick that is colliding.
       * unfortunately, it did not work. --Dianora
       */

      /* Yes, a good compiler would have optimised this, but
       * this is probably easier to read. -db
       */
      num = atoi(numeric);

      if ((num != ERR_NOSUCHNICK))
        sendto_gnotice_flags(UMODE_ALL, L_ALL, me.name, &me, NULL,
			     "*** %s(via %s) sent a %s numeric to me: %s",
			     source_p->name, client_p->name, numeric, buffer);
      return;
    }
    else if (target_p->from == client_p) 
    {
      /* This message changed direction (nick collision?)
       * ignore it.
       */
      return;
    }

    /* csircd will send out unknown umode flag for +a (admin), drop it here. */
    if ((atoi(numeric) == ERR_UMODEUNKNOWNFLAG) && MyClient(target_p))
      return;
    
    /* Fake it for server hiding, if its our client */
    if (ConfigServerHide.hide_servers &&
        MyClient(target_p) && !IsOper(target_p))
      sendto_one(target_p, ":%s %s %s%s", me.name, numeric, target_p->name, buffer);
    else
      sendto_one(target_p, ":%s %s %s%s", ID_or_name(source_p, target_p->from),
                 numeric, ID_or_name(target_p, target_p->from), buffer);
    return;
  }
  else if ((chptr = hash_find_channel(parv[1])) != NULL)
    sendto_channel_local(ALL_MEMBERS, NO, chptr,
			 ":%s %s %s %s",
			 source_p->name,
			 numeric, chptr->chname, buffer);
}
Example #15
0
/* write_conf_line()
 *
 * inputs       - pointer to struct AccessItem
 *		- string current_date (small date)
 *              - time_t cur_time
 * output       - NONE
 * side effects - This function takes care of
 *                finding right conf file, writing
 *                the right lines to this file, 
 *                notifying the oper that their kline/dline etc. is in place
 *                notifying the opers on the server about the k/d etc. line
 *                
 * - Dianora
 */
void 
write_conf_line(struct Client *source_p, struct ConfItem *conf,
		const char *current_date, time_t cur_time, time_t duration)
{
  FBFILE *out;
  const char *filename, *from, *to;
  struct AccessItem *aconf;
  struct MatchItem *xconf;
  struct ResvChannel *cresv_p=NULL;
  struct MatchItem *nresv_p=NULL;
  ConfType type;

  type = conf->type;
  filename = get_conf_name(type);

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

  if ((out = fbopen(filename, "a")) == NULL)
  {
    sendto_realops_flags(UMODE_ALL, L_ALL,
                         "*** Problem opening %s ", filename);
    return;
  }

  switch(type)
  {
  case KLINE_TYPE:
    aconf = (struct AccessItem *)map_to_conf(conf);
    if(duration == 0)
    {
      sendto_realops_flags(UMODE_ALL, L_ALL,
          "%s added K-Line for [%s@%s] [%s]",
          get_oper_name(source_p), aconf->user, aconf->host, aconf->reason);
      sendto_one(source_p, ":%s NOTICE %s :Added K-Line [%s@%s]",
          from, to, aconf->user, aconf->host);
      ilog(L_TRACE, "%s added K-Line for [%s@%s] [%s]",
          source_p->name, aconf->user, aconf->host, aconf->reason);
      log_oper_action(LOG_KLINE_TYPE, source_p, "[%s@%s] [%s]\n",
          aconf->user, aconf->host, aconf->reason);
      write_csv_line(out, "%s%s%s%s%s%s%d",
          aconf->user, aconf->host, aconf->reason, aconf->oper_reason, 
          current_date, get_oper_name(source_p), cur_time);
    }
    else
    {
      sendto_realops_flags(UMODE_ALL, L_ALL,
          "%s added temporary %d min. K-Line for [%s@%s] [%s]",
          get_oper_name(source_p), duration/60, aconf->user, aconf->host, 
          aconf->reason);
      sendto_one(source_p,
          ":%s NOTICE %s :Added temporary %d min. K-Line [%s@%s]", from, to, 
          duration/60, aconf->user, aconf->host);
      ilog(L_TRACE, "%s added temporary %ld min. K-Line for [%s@%s] [%s]",
          source_p->name, duration/60, aconf->user, aconf->host, aconf->reason);
      log_oper_action(LOG_TEMP_KLINE_TYPE, source_p, "[%s@%s] [%s]\n",
          aconf->user, aconf->host, aconf->reason);
      write_csv_line(out, "%s%s%s%s%s%s%d%d", aconf->user, aconf->host,
          aconf->reason, aconf->oper_reason, current_date,
          get_oper_name(source_p), cur_time, aconf->hold);
    }
    break;

  case RKLINE_TYPE:
    aconf = map_to_conf(conf);
    if(duration == 0)
    {
      sendto_realops_flags(UMODE_ALL, L_ALL,
          "%s added RK-Line for [%s@%s] [%s]",
          get_oper_name(source_p),
          aconf->user, aconf->host, aconf->reason);
      sendto_one(source_p, ":%s NOTICE %s :Added RK-Line [%s@%s]",
          from, to, aconf->user, aconf->host);
      ilog(L_TRACE, "%s added K-Line for [%s@%s] [%s]",
          source_p->name, aconf->user, aconf->host, aconf->reason);
      log_oper_action(LOG_RKLINE_TYPE, source_p, "[%s@%s] [%s]\n",
          aconf->user, aconf->host, aconf->reason);
      write_csv_line(out, "%s%s%s%s%s%s%d",
          aconf->user, aconf->host,
          aconf->reason, aconf->oper_reason, current_date,
          get_oper_name(source_p), cur_time);
    }
    else
    {
      sendto_realops_flags(UMODE_ALL, L_ALL,
          "%s added temporary %d min. RK-Line for [%s@%s] [%s]",
          get_oper_name(source_p), duration/60, aconf->user, aconf->host,
          aconf->reason);
      sendto_one(source_p, 
          ":%s NOTICE %s :Added temporary %d min. RK-Line [%s@%s]", from, to, 
          duration/60, aconf->user, aconf->host);
      ilog(L_TRACE, "%s added temporary %ld min. RK-Line for [%s@%s] [%s]",
          source_p->name, duration/60,
          aconf->user, aconf->host, aconf->reason);
      log_oper_action(LOG_TEMP_RKLINE_TYPE, source_p, "[%s@%s] [%s]\n",
          aconf->user, aconf->host, aconf->reason);
      write_csv_line(out, "%s%s%s%s%s%s%d%d",
          aconf->user, aconf->host,
          aconf->reason, aconf->oper_reason, current_date,
          get_oper_name(source_p), cur_time, aconf->hold);
    }
    break;

  case DLINE_TYPE:
    aconf = (struct AccessItem *)map_to_conf(conf);
    if(duration == 0)
    {
      sendto_realops_flags(UMODE_ALL, L_ALL,
          "%s added D-Line for [%s] [%s]",
          get_oper_name(source_p), aconf->host, aconf->reason);
      sendto_one(source_p, ":%s NOTICE %s :Added D-Line [%s] to %s",
          from, to, aconf->host, filename);
      ilog(L_TRACE, "%s added D-Line for [%s] [%s]",
          get_oper_name(source_p), aconf->host, aconf->reason);
      log_oper_action(LOG_DLINE_TYPE, source_p, "[%s] [%s]\n",
          aconf->host, aconf->reason);
      write_csv_line(out, "%s%s%s%s%s%d",
          aconf->host, aconf->reason, aconf->oper_reason, 
          current_date,
          get_oper_name(source_p), cur_time);
    }
    else
    {
      sendto_realops_flags(UMODE_ALL, L_ALL,
          "%s added temporary %d min. D-Line for [%s] [%s]",
          get_oper_name(source_p), duration/60, aconf->host, aconf->reason);

      sendto_one(source_p, ":%s NOTICE %s :Added temporary %d min. D-Line [%s]",
          from, to, duration/60, aconf->host);
      ilog(L_TRACE, "%s added temporary %d min. D-Line for [%s] [%s]",
          source_p->name, (int)duration/60, aconf->host, aconf->reason);
      log_oper_action(LOG_TEMP_DLINE_TYPE, source_p, "[%s@%s] [%s]\n",
          aconf->user, aconf->host, aconf->reason);
      write_csv_line(out, "%s%s%s%s%s%d%d",
          aconf->host, aconf->reason, aconf->oper_reason, 
          current_date, get_oper_name(source_p), cur_time, aconf->hold);
    }
    break;

  case XLINE_TYPE:
    xconf = (struct MatchItem *)map_to_conf(conf);
    if(duration == 0)
    {
      sendto_realops_flags(UMODE_ALL, L_ALL,
          "%s added X-Line for [%s] [%s]",
          get_oper_name(source_p), conf->name,
          xconf->reason);
      sendto_one(source_p,
          ":%s NOTICE %s :Added X-Line [%s] [%d] [%s] to %s",
          from, to, conf->name, 
          xconf->action, xconf->reason, filename);
      ilog(L_TRACE, "%s added X-Line for [%s] [%s]",
          get_oper_name(source_p), conf->name, xconf->reason);
      write_csv_line(out, "%s%s%s%s%s%d",
          conf->name, xconf->reason, xconf->oper_reason,
          current_date, get_oper_name(source_p), cur_time);
    }
    else
    {
      sendto_realops_flags(UMODE_ALL, L_ALL,
          "%s added temporary %d min. X-Line for [%s] [%s]",
          get_oper_name(source_p), (int)duration/60,
          conf->name, xconf->reason);
      sendto_one(source_p, ":%s NOTICE %s :Added temporary %d min. X-Line [%s]",
          MyConnect(source_p) ? me.name : ID_or_name(&me, source_p->from),
          source_p->name, (int)duration/60, conf->name);
      ilog(L_TRACE, "%s added temporary %d min. X-Line for [%s] [%s]",
          source_p->name, (int)duration/60,
          conf->name, xconf->reason);
      write_csv_line(out, "%s%s%s%s%s%d%d",
          conf->name, xconf->reason, xconf->oper_reason,
          current_date, get_oper_name(source_p), cur_time, xconf->hold);
 
    }
    break;

  case RXLINE_TYPE:
    xconf = (struct MatchItem *)map_to_conf(conf);
    if(duration == 0)
    {
      sendto_realops_flags(UMODE_ALL, L_ALL,
          "%s added RX-Line for [%s] [%s]",
          get_oper_name(source_p), conf->name,
          xconf->reason);
      sendto_one(source_p,
          ":%s NOTICE %s :Added RX-Line [%s] [%s] to %s",
          from, to, conf->name,
          xconf->reason, filename);
      ilog(L_TRACE, "%s added X-Line for [%s] [%s]",
          get_oper_name(source_p), conf->name, xconf->reason);
      write_csv_line(out, "%s%s%s%s%s%d",
          conf->name, xconf->reason, xconf->oper_reason,
          current_date, get_oper_name(source_p), cur_time);
    }
    else
    {
      sendto_realops_flags(UMODE_ALL, L_ALL,
          "%s added temporary %d min. RX-Line for [%s] [%s]",
          get_oper_name(source_p), (int)duration/60, conf->name, xconf->reason);
      sendto_one(source_p, 
          ":%s NOTICE %s :Added temporary %d min. RX-Line [%s]",
          from, to, (int)duration/60, conf->name);
      ilog(L_TRACE, "%s added temporary %d min. RX-Line for [%s] [%s]",
          source_p->name, (int)duration/60,
          conf->name, xconf->reason);
      write_csv_line(out, "%s%s%s%s%s%d%d",
          conf->name, xconf->reason, xconf->oper_reason,
          current_date, get_oper_name(source_p), cur_time, xconf->hold);
    }
    break;

  case CRESV_TYPE:
    cresv_p = (struct ResvChannel *)map_to_conf(conf);
    if(duration == 0)
      write_csv_line(out, "%s%s", cresv_p->name, cresv_p->reason);
    else
      write_csv_line(out, "%s%s%d", cresv_p->name, cresv_p->reason, cresv_p->hold);
    break;

  case NRESV_TYPE:
    nresv_p = (struct MatchItem *)map_to_conf(conf);
    if(duration == 0)
      write_csv_line(out, "%s%s", conf->name, nresv_p->reason);
    else
      write_csv_line(out, "%s%s%d", conf->name, nresv_p->reason, nresv_p->hold);
    break;

  default:
    fbclose(out);
    return;
  }

  fbclose(out);
}
Example #16
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, const char *command, struct Client *client_p,
	  struct Client *source_p, int parc, char *parv[])
{
	int i;

	if(parc < 2 || EmptyString(parv[1]))
	{
		if(p_or_n != NOTICE)
			sendto_one(source_p, form_str(ERR_NORECIPIENT),
				   ID_or_name(&me, client_p),
				   ID_or_name(source_p, client_p), command);
		return;
	}

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

	/* Finish the flood grace period... */
	if(MyClient(source_p) && !IsFloodDone(source_p))
#if 0
		&&irccmp(source_p->name, parv[1]) != 0)	/* some dumb clients msg/notice themself
							   to determine lag to the server BEFORE
							   sending JOIN commands, and then flood
							   off because they left gracemode. -wiz */
			/*
			 * Not our problem if they do this.    -Michael
			 */
#endif
			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;
		}
	}
}
Example #17
0
/* build_target_list()
 *
 * inputs	- pointer to given client_p (server)
 *		- pointer to given source (oper/client etc.)
 *		- pointer to list of nicks/channels
 *		- pointer to table to place results
 *		- pointer to text (only used if source_p is an oper)
 * output	- number of valid entities
 * side effects	- target_table is modified to contain a list of
 *		  pointers to channels or clients
 *		  if source client is an oper
 *		  all the classic old bizzare oper privmsg tricks
 *		  are parsed and sent as is, if prefixed with $
 *		  to disambiguate.
 *
 */
static int
build_target_list(int p_or_n, const char *command, struct Client *client_p,
		  struct Client *source_p, char *nicks_channels, char *text)
{
	int type;
	char *p = NULL, *nick, *target_list, ncbuf[IRCD_BUFSIZE];
	struct Channel *chptr = NULL;
	struct Client *target_p = NULL;

	/* Sigh, we can't mutilate parv[1] incase we need it to send to a hub */
	if(!ServerInfo.hub && (uplink != NULL) && IsCapable(uplink, CAP_LL))
	{
		strlcpy(ncbuf, nicks_channels, sizeof(ncbuf));
		target_list = ncbuf;
	}
	else
		  target_list = nicks_channels;	/* skip strcpy for non-lazyleafs */

	ntargets = 0;

	for(nick = strtoken(&p, target_list, ","); nick; nick = strtoken(&p, NULL, ","))
	{
		char *with_prefix;
		/*
		 * channels are privmsg'd a lot more than other clients, moved up
		 * here plain old channel msg?
		 */

		if(IsChanPrefix(*nick))
		{
			/* ignore send of local channel to a server (should not happen) */
			if(*nick == '&' && IsServer(client_p))
				continue;

			if((chptr = hash_find_channel(nick)) != NULL)
			{
				if(!duplicate_ptr(chptr))
				{
					if(ntargets >= ConfigFileEntry.max_targets)
					{
						sendto_one(source_p, form_str(ERR_TOOMANYTARGETS),
							   ID_or_name(&me, client_p),
							   ID_or_name(source_p, client_p), nick,
							   ConfigFileEntry.max_targets);
						return (1);
					}
					targets[ntargets].ptr = (void *) chptr;
					targets[ntargets++].type = ENTITY_CHANNEL;
				}
			}
			else
			{
				if(!ServerInfo.hub && (uplink != NULL) && IsCapable(uplink, CAP_LL))
					return -1;
				else if(p_or_n != NOTICE)
					sendto_one(source_p, form_str(ERR_NOSUCHNICK),
						   ID_or_name(&me, client_p),
						   ID_or_name(source_p, client_p), nick);
			}
			continue;
		}

		/* look for a privmsg to another client */
		if((target_p = find_person(client_p, nick)) != NULL)
		{
			if(!duplicate_ptr(target_p))
			{
				if(ntargets >= ConfigFileEntry.max_targets)
				{
					sendto_one(source_p, form_str(ERR_TOOMANYTARGETS),
						   ID_or_name(&me, client_p),
						   ID_or_name(source_p, client_p), nick,
						   ConfigFileEntry.max_targets);
					return (1);
				}
				targets[ntargets].ptr = (void *) target_p;
				targets[ntargets].type = ENTITY_CLIENT;
				targets[ntargets++].flags = 0;
			}
			continue;
		}

		/* @#channel or +#channel message ? */

		type = 0;
		with_prefix = nick;
		/*  allow ~&%+@ if someone wants to do that */
		for(;;)
		{
#ifdef CHANAQ
			if(*nick == '~')
				type |= CHFL_OWNER;
			else if(*nick == '&')
				type |= CHFL_OWNER | CHFL_PROTECTED;
			else
#endif
			if(*nick == '@')
				type |= CHFL_OWNER | CHFL_PROTECTED | CHFL_CHANOP;
#ifdef HALFOPS
			else if(*nick == '%')
				type |= CHFL_OWNER | CHFL_PROTECTED | CHFL_CHANOP | CHFL_HALFOP;
#endif
			else if(*nick == '+')
				type |= CHFL_OWNER | CHFL_PROTECTED | CHFL_CHANOP | CHFL_HALFOP |
					CHFL_VOICE;
			else
				break;
			nick++;
		}

		if(type != 0)
		{
			/* suggested by Mortiis */
			if(*nick == '\0')	/* if its a '\0' dump it, there is no recipient */
			{
				sendto_one(source_p, form_str(ERR_NORECIPIENT),
					   ID_or_name(&me, client_p),
					   ID_or_name(source_p, client_p), command);
				continue;
			}

			/* At this point, nick+1 should be a channel name i.e. #foo or &foo
			 * if the channel is found, fine, if not report an error
			 */

			if((chptr = hash_find_channel(nick)) != NULL)
			{
				if(!has_member_flags(find_channel_link(source_p, chptr),
						     CHFL_OWNER | CHFL_PROTECTED | CHFL_CHANOP |
						     CHFL_HALFOP | CHFL_VOICE))
				{
					sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
						   ID_or_name(&me, client_p),
						   ID_or_name(source_p, client_p), with_prefix);
					return (-1);
				}

				if(!duplicate_ptr(chptr))
				{
					if(ntargets >= ConfigFileEntry.max_targets)
					{
						sendto_one(source_p, form_str(ERR_TOOMANYTARGETS),
							   ID_or_name(&me, client_p),
							   ID_or_name(source_p, client_p), nick,
							   ConfigFileEntry.max_targets);
						return (1);
					}
					targets[ntargets].ptr = (void *) chptr;
					targets[ntargets].type = ENTITY_CHANOPS_ON_CHANNEL;
					targets[ntargets++].flags = type;
				}
			}
			else
			{
				if(!ServerInfo.hub && (uplink != NULL) && IsCapable(uplink, CAP_LL))
					return -1;
				else if(p_or_n != NOTICE)
					sendto_one(source_p, form_str(ERR_NOSUCHNICK),
						   ID_or_name(&me, client_p),
						   ID_or_name(source_p, client_p), nick);
			}
			continue;
		}

		if((*nick == '$') || strchr(nick, '@') != NULL)
		{
			handle_special(p_or_n, command, client_p, source_p, nick, text);
		}
		else
		{
			if(!ServerInfo.hub && (uplink != NULL) && IsCapable(uplink, CAP_LL))
				return -1;
			else if(p_or_n != NOTICE)
			{
				if(!IsDigit(*nick) || MyClient(source_p))
					sendto_one(source_p, form_str(ERR_NOSUCHNICK),
						   ID_or_name(&me, client_p),
						   ID_or_name(source_p, client_p), nick);
			}
		}
		/* continue; */
	}

	return (1);
}