/*
 * m_users
 *      parv[0] = sender prefix
 *      parv[1] = servername
 */
static int
m_users(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	if(hunt_server(client_p, source_p, ":%s USERS :%s", 1, parc, parv) == HUNTED_ISME)
	{
		sendto_one_numeric(source_p, RPL_LOCALUSERS,
				   form_str(RPL_LOCALUSERS),
				   dlink_list_length(&lclient_list), 
				   Count.max_loc,
				   dlink_list_length(&lclient_list), 
				   Count.max_loc);

		sendto_one_numeric(source_p, RPL_GLOBALUSERS, 
				   form_str(RPL_GLOBALUSERS),
				   Count.total, Count.max_tot,
				   Count.total, Count.max_tot);
	}

	return 0;
}
/* SET MAX */
static void
quote_max(struct Client *source_p, int newval)
{
	if(newval > 0)
	{
		if(newval > MASTER_MAX)
		{
			sendto_one(source_p,
				   ":%s NOTICE %s :You cannot set MAXCLIENTS to > MASTER_MAX (%d)",
				   me.name, source_p->name, MASTER_MAX);
			return;
		}

		if(newval < 32)
		{
			sendto_one(source_p,
				   ":%s NOTICE %s :You cannot set MAXCLIENTS to < 32 (%d:%d)",
				   me.name, source_p->name, GlobalSetOptions.maxclients,
				   highest_fd);
			return;
		}

		GlobalSetOptions.maxclients = newval;

		sendto_realops_snomask(SNO_GENERAL, L_ALL,
				     "%s!%s@%s set new MAXCLIENTS to %d (%lu current)",
				     source_p->name, source_p->username, source_p->host,
				     GlobalSetOptions.maxclients, 
				     dlink_list_length(&lclient_list));

		return;
	}
	else
	{
		sendto_one(source_p, ":%s NOTICE %s :Current Maxclients = %d (%lu)",
			   me.name, source_p->name, GlobalSetOptions.maxclients,
			   dlink_list_length(&lclient_list));
	}
}
/*
 * m_locops - LOCOPS message handler
 * (write to *all* local opers currently online)
 *      parv[0] = sender prefix
 *      parv[1] = message text
 */
static void
m_locops(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
{
	if(EmptyString(parv[1]))
	{
		sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "LOCOPS");
		return;
	}

	sendto_wallops_flags(UMODE_LOCOPS, source_p, "LOCOPS - %s", parv[1]);

	if(dlink_list_length(&cluster_list) > 0)
		cluster_generic(source_p, "LOCOPS", CLUSTER_LOCOPS, CAP_CLUSTER,
				":%s", parv[1]);
}
Exemple #4
0
/*! \brief RELOAD subcommand handler
 *         Attempts to reload a module, throwing an error if
 *         the module could not be found or loaded
 * \param source_p Pointer to client issuing the command
 * \param arg      Additional argument which might be needed by this handler
 */
static void
module_reload(struct Client *source_p, const char *arg)
{
  const char *m_bn = NULL;
  struct module *modp = NULL;
  int check_core = 0;

  if (!strcmp(arg, "*"))
  {
    unsigned int modnum = 0;
    dlink_node *node = NULL, *node_next = NULL;

    sendto_one_notice(source_p, &me, ":Reloading all modules");

    modnum = dlink_list_length(modules_get_list());

    DLINK_FOREACH_SAFE(node, node_next, modules_get_list()->head)
    {
      modp = node->data;

      if (!(modp->flags & MODULE_FLAG_NOUNLOAD))
        unload_one_module(modp->name, 0);
    }
Exemple #5
0
/*
 * m_lljoin
 *      parv[0] = sender prefix
 *      parv[1] = channel
 *      parv[2] = nick ("!nick" == cjoin)
 *      parv[3] = key (optional)
 *
 * If a lljoin is received, from our uplink, join
 * the requested client to the given channel, or ignore it
 * if there is an error.
 *
 *   Ok, the way this works. Leaf client tries to join a channel, 
 * it doesn't exist so the join does a cburst request on behalf of the
 * client, and aborts that join. The cburst sjoin's the channel if it
 * exists on the hub, and sends back an LLJOIN to the leaf. Thats where
 * this is now..
 *
 */
static void
ms_lljoin(struct Client *client_p, struct Client *source_p,
          int parc, char *parv[])
{
  char *chname = NULL;
  char *nick = NULL;
  char *key = NULL;
  int  flags;
  int  i;
  struct Client *target_p;
  struct Channel *chptr;

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

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

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

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

  flags = 0;

  target_p = find_person(client_p, nick);

  if (!target_p)
    return;

  if (!MyClient(target_p))
    return;

  if (!check_channel_name(chname, 0))
  {
    sendto_gnotice_flags(UMODE_DEBUG, L_ALL, me.name, &me, NULL,
                         "*** Too long or invalid channel name from %s: %s",
                         target_p->name, chname);
    return;
  }

  chptr = make_channel(chname);
  flags = CHFL_CHANOP;
   
  if(!chptr)
    return;

  if (dlink_list_length(&chptr->members) == 0)
    flags = CHFL_CHANOP;
  else
    flags = 0;

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

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

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

  if ((dlink_list_length(&target_p->channel) >= ConfigChannel.max_chans_per_user) &&
      (!IsOper(target_p) || (dlink_list_length(&target_p->channel) >=
                             ConfigChannel.max_chans_per_user*3)))
  {
      sendto_one(target_p, form_str(ERR_TOOMANYCHANNELS),
		 me.name, nick, chptr->chname );
      return; 
  }
  
  if (flags == CHFL_CHANOP)
  {
      chptr->channelts = CurrentTime;

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

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

  add_user_to_channel(chptr, target_p, flags, YES);

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

  channel_member_names(target_p, chptr, 1);
}
/* m_knock
 *    parv[0] = sender prefix
 *    parv[1] = channel
 *
 *  The KNOCK command has the following syntax:
 *   :<sender> KNOCK <channel>
 *
 *  If a user is not banned from the channel they can use the KNOCK
 *  command to have the server NOTICE the channel operators notifying
 *  they would like to join.  Helpful if the channel is invite-only, the
 *  key is forgotten, or the channel is full (INVITE can bypass each one
 *  of these conditions.  Concept by Dianora <*****@*****.**> and written by
 *  <anonymous>
 */
static int
m_knock(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
    struct Channel *chptr;
    char *p, *name;

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

    name = LOCAL_COPY(parv[1]);

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

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

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

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

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

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


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

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

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

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

    chptr->last_knock = CurrentTime;

    if(ConfigChannel.use_knock)
        sendto_channel_local(ONLY_CHANOPS, chptr, form_str(RPL_KNOCK),
                             me.name, name, name, source_p->name,
                             source_p->username, source_p->host);

    sendto_server(client_p, chptr, CAP_KNOCK|CAP_TS6, NOCAPS,
                  ":%s KNOCK %s", use_id(source_p), name);
    sendto_server(client_p, chptr, CAP_KNOCK, CAP_TS6,
                  ":%s KNOCK %s", source_p->name, name);
    return 0;
}
Exemple #7
0
/*
 * m_accept - ACCEPT command handler
 *      parv[0] = sender prefix
 *      parv[1] = servername
 */
static void m_accept(struct Client *client_p, struct Client *source_p,
                    int parc, char *parv[])
{
  char *nick;
  char *p = NULL;
  static char addbuf[BUFSIZE];
  static char delbuf[BUFSIZE];
  struct Client *target_p;
  int accept_num;
  
  if(*parv[1] == '*')
  {
    list_accepts(source_p);
    return;
  }

  build_nicklist(source_p, addbuf, delbuf, parv[1]);

  /* parse the delete list */
  for(nick = strtoken(&p, delbuf, ","); nick != NULL;
      nick = strtoken(&p, NULL, ","))
  {
    /* shouldnt happen, but lets be paranoid */
    if(((target_p = find_client(nick)) == NULL) || !IsPerson(target_p))
    {
      sendto_one(source_p, form_str(ERR_NOSUCHNICK),
                 me.name, source_p->name, nick);
      continue;
    }

    /* user isnt on clients accept list */
    if(!accept_message(target_p, source_p))
    {
      sendto_one(source_p, form_str(ERR_ACCEPTNOT),
                 me.name, source_p->name, target_p->name);
      continue;
    }

    del_from_accept(target_p, source_p);
  }

  /* get the number of accepts they have */ 
  accept_num = dlink_list_length(&source_p->allow_list);
  
  /* parse the add list */
  for(nick = strtoken(&p, addbuf, ","); nick;
      nick = strtoken(&p, NULL, ","), accept_num++)
  {
    /* shouldnt happen, but lets be paranoid */
    if(((target_p = find_client(nick)) == NULL) || !IsPerson(target_p)) 
    {
      sendto_one(source_p, form_str(ERR_NOSUCHNICK),
                 me.name, source_p->name, nick);
      continue;
    }

    /* user is already on clients accept list */
    if(accept_message(target_p, source_p))
    {
      sendto_one(source_p, form_str(ERR_ACCEPTEXIST),
                 me.name, source_p->name, target_p->name);
      continue;
    }

    if(accept_num >= ConfigFileEntry.max_accept)
    {
      sendto_one(source_p, form_str(ERR_ACCEPTFULL),
                 me.name, source_p->name);
      return;
    }
      
    /* why is this here? */
    /* del_from accept(target_p, source_p); */
    add_accept(source_p, target_p);

  }


}
Exemple #8
0
    DLINK_FOREACH_SAFE(node, node_next, modules_get_list()->head)
    {
      modp = node->data;

      if (!(modp->flags & MODULE_FLAG_NOUNLOAD))
        unload_one_module(modp->name, 0);
    }

    load_all_modules(0);
    load_conf_modules();
    load_core_modules(0);

    sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
                         "Module Restart: %u modules unloaded, %u modules loaded",
                         modnum, dlink_list_length(modules_get_list()));
    ilog(LOG_TYPE_IRCD, "Module Restart: %u modules unloaded, %u modules loaded",
         modnum, dlink_list_length(modules_get_list()));
    return;
  }

  if ((modp = findmodule_byname((m_bn = libio_basename(arg)))) == NULL)
  {
    sendto_one_notice(source_p, &me, ":Module %s is not loaded", m_bn);
    return;
  }

  if (modp->flags & MODULE_FLAG_NOUNLOAD)
  {
    sendto_one_notice(source_p, &me, ":Module %s is a resident module and may not be unloaded",
                      m_bn);
Exemple #9
0
/* m_knock
 *    parv[0] = sender prefix
 *    parv[1] = channel
 *
 *  The KNOCK command has the following syntax:
 *   :<sender> KNOCK <channel>
 *
 *  If a user is not banned from the channel they can use the KNOCK
 *  command to have the server NOTICE the channel operators notifying
 *  they would like to join.  Helpful if the channel is invite-only, the
 *  key is forgotten, or the channel is full (INVITE can bypass each one
 *  of these conditions.  Concept by Dianora <*****@*****.**> and written by
 *  <anonymous>
 */
static void
m_knock(struct Client *client_p, struct Client *source_p,
        int parc, char *parv[])
{
  struct Channel *chptr = NULL;

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

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

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

  /* Normal channel, just be sure they aren't on it */
  if (IsMember(source_p, chptr))
  {
    sendto_one(source_p, form_str(ERR_KNOCKONCHAN), me.name,
               source_p->name, chptr->chname);
    return;
  }

  if (!((chptr->mode.mode & MODE_INVITEONLY) || (*chptr->mode.key) ||
        (chptr->mode.limit && dlink_list_length(&chptr->members) >=
         chptr->mode.limit)))
  {
    sendto_one(source_p, form_str(ERR_CHANOPEN), me.name,
               source_p->name, chptr->chname);
    return;
  }

  if (MyClient(source_p))
  {
    /*
     * Don't allow a knock if the user is banned, or the channel is private
     */
    if (PrivateChannel(chptr) || is_banned(chptr, source_p))
    {
      sendto_one(source_p, form_str(ERR_CANNOTSENDTOCHAN),
                 me.name, source_p->name, chptr->chname);
      return;
    }

    /*
     * flood protection:
     * allow one knock per user per knock_delay
     * allow one knock per channel per knock_delay_channel
     *
     * we only limit local requests..
     */
    if ((source_p->localClient->last_knock + ConfigChannel.knock_delay) >
        CurrentTime)
    {
      sendto_one(source_p, form_str(ERR_TOOMANYKNOCK), me.name,
                 source_p->name, chptr->chname, "user");
      return;
    }

    if ((chptr->last_knock + ConfigChannel.knock_delay_channel) > CurrentTime)
    {
      sendto_one(source_p, form_str(ERR_TOOMANYKNOCK), me.name,
                 source_p->name, chptr->chname, "channel");
      return;
    }

    source_p->localClient->last_knock = CurrentTime;

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

  chptr->last_knock = CurrentTime;

  if (ConfigChannel.use_knock)
    sendto_channel_local(CHFL_CHANOP, NO, chptr, form_str(RPL_KNOCK),
                         me.name, chptr->chname, chptr->chname,
                         source_p->name, source_p->username,
                         source_p->host);

  sendto_server(client_p, chptr, CAP_KNOCK|CAP_TS6, NOCAPS,
                ":%s KNOCK %s", ID(source_p), chptr->chname);
  sendto_server(client_p, chptr, CAP_KNOCK, CAP_TS6,
                ":%s KNOCK %s", source_p->name, chptr->chname);
}