Ejemplo n.º 1
0
/** Set a server's numeric nick.
 * @param[in] cptr %Client that announced the server (ignored).
 * @param[in,out] server %Server that is being assigned a numnick.
 * @param[in] yxx %Numeric nickname for server.
 */
void SetServerYXX(struct Client* cptr, struct Client* server, const char* yxx)
{
    unsigned int index;
    if (5 == strlen(yxx)) {
        ircd_strncpy(cli_yxx(server), yxx, 2);
        ircd_strncpy(cli_serv(server)->nn_capacity, yxx + 2, 3);
    }
    else {
        (cli_yxx(server))[0]               = yxx[0];
        cli_serv(server)->nn_capacity[0] = yxx[1];
        cli_serv(server)->nn_capacity[1] = yxx[2];
    }
    cli_serv(server)->nn_mask = base64toint(cli_serv(server)->nn_capacity);

    index = base64toint(cli_yxx(server));
    if (index >= lastNNServer)
        lastNNServer = index + 1;
    server_list[index] = server;

    /* Note, exit_one_client uses the fact that `client_list' != NULL to
     * determine that SetServerYXX has been called - and then calls
     * ClearServerYXX. However, freeing the allocation happens in free_client() */
    cli_serv(server)->client_list =
        (struct Client**) MyCalloc(cli_serv(server)->nn_mask + 1, sizeof(struct Client*));
}
Ejemplo n.º 2
0
/** Register numeric of new (remote) client.
 * See @ref numnicks for more details.
 * Add it to the appropriate client_list.
 * @param[in] acptr %User being registered.
 * @param[in] yxx User's numnick.
 */
void SetRemoteNumNick(struct Client* acptr, const char *yxx)
{
    struct Client** acptrp;
    struct Client*  server = cli_user(acptr)->server;

    if (5 == strlen(yxx)) {
        strcpy(cli_yxx(acptr), yxx + 2);
    }
    else {
        (cli_yxx(acptr))[0] = *++yxx;
        (cli_yxx(acptr))[1] = *++yxx;
        (cli_yxx(acptr))[2] = 0;
    }
    Debug((DEBUG_DEBUG, "SetRemoteNumNick: %s(%d)", cli_yxx(acptr),
           base64toint(cli_yxx(acptr)) & cli_serv(server)->nn_mask));

    acptrp = &(cli_serv(server))->client_list[base64toint(cli_yxx(acptr)) & cli_serv(server)->nn_mask];
    if (*acptrp) {
        /*
         * this exits the old client in the array, not the client
         * that is being set
         */
        exit_client(cli_from(acptr), *acptrp, server, "Numeric nick collision (Ghost)");
    }
    *acptrp = acptr;
}
Ejemplo n.º 3
0
/** Look up a server by numnick string.
 * See @ref numnicks for more details.
 * @param[in] numeric %Numeric nickname of server (may contain trailing junk).
 * @return %Server with that numnick (or NULL).
 */
static struct Client* FindXNServer(const char* numeric)
{
    char buf[3];
    buf[0] = *numeric++;
    buf[1] = *numeric;
    buf[2] = '\0';
    Debug((DEBUG_DEBUG, "FindXNServer: %s(%d)", buf, base64toint(buf)));
    return server_list[base64toint(buf)];
}
Ejemplo n.º 4
0
/** Remove a client from a server's user array.
 * @param[in] server %Server that owns the user to remove.
 * @param[in] yxx Numnick of client to remove.
 */
void RemoveYXXClient(struct Client* server, const char* yxx)
{
    assert(0 != server);
    assert(0 != yxx);
    if (*yxx) {
        Debug((DEBUG_DEBUG, "RemoveYXXClient: %s(%d)", yxx,
               base64toint(yxx) & cli_serv(server)->nn_mask));
        cli_serv(server)->client_list[base64toint(yxx) & cli_serv(server)->nn_mask] = 0;
    }
}
Ejemplo n.º 5
0
/** Look up a server by numnick string.
 * See @ref numnicks for more details.
 * @param[in] numeric %Numeric nickname of server.
 * @return %Server with that numnick (or NULL).
 */
struct Client* FindNServer(const char* numeric)
{
    unsigned int len = strlen(numeric);

    if (len < 3) {
        Debug((DEBUG_DEBUG, "FindNServer: %s(%d)", numeric, base64toint(numeric)));
        return server_list[base64toint(numeric)];
    }
    else if (len == 3) {
        Debug((DEBUG_DEBUG, "FindNServer: %c(%d)", *numeric,
               convert2n[(unsigned char) *numeric]));
        return server_list[convert2n[(unsigned char) *numeric]];
    }
    return FindXNServer(numeric);
}
Ejemplo n.º 6
0
void checkServer(struct Client *sptr, struct Client *acptr)
{
   char outbuf[BUFSIZE];

   /* Header */
   send_reply(sptr, RPL_DATASTR, " ");
   send_reply(sptr, RPL_CHKHEAD, "server", acptr->cli_name);
   send_reply(sptr, RPL_DATASTR, " ");

   ircd_snprintf(0, outbuf, sizeof(outbuf),  "   Connected at:: %s (%Tu)", myctime(acptr->cli_serv->timestamp), acptr->cli_serv->timestamp);
   send_reply(sptr, RPL_DATASTR, outbuf);

   ircd_snprintf(0, outbuf, sizeof(outbuf), "    Server name:: %s", acptr->cli_name);
   send_reply(sptr, RPL_DATASTR,  outbuf);

   if (cli_sslclifp(acptr) && (strlen(cli_sslclifp(acptr)) > 0)) {
     ircd_snprintf(0, outbuf, sizeof(outbuf), "SSL Fingerprint:: %s", cli_sslclifp(acptr));
     send_reply(sptr, RPL_DATASTR, outbuf);
   }

   ircd_snprintf(0, outbuf, sizeof(outbuf), "        Numeric:: %s --> %d", NumServ(acptr), base64toint(acptr->cli_yxx));
   send_reply(sptr, RPL_DATASTR, outbuf);

   ircd_snprintf(0, outbuf, sizeof(outbuf), "          Users:: %d / %d", (acptr == &me) ? UserStats.local_clients : cli_serv(acptr)->clients, 
                 base64toint(cli_serv(acptr)->nn_capacity));
   send_reply(sptr, RPL_DATASTR, outbuf);

   if (IsBurst(acptr))
     send_reply(sptr, RPL_DATASTR, "         Status:: Bursting");
   else if (IsBurstAck(acptr))
     send_reply(sptr, RPL_DATASTR, "         Status:: Awaiting EOB Ack");
   else if (IsService(acptr))
     send_reply(sptr, RPL_DATASTR, "         Status:: Network Service");
   else if (IsHub(acptr))
     send_reply(sptr, RPL_DATASTR, "         Status:: Network Hub");

   ircd_snprintf(0, outbuf, sizeof(outbuf), "          Class:: %s", get_client_class(acptr));
   send_reply(sptr, RPL_DATASTR, outbuf);

   if (feature_bool(FEAT_CHECK_EXTENDED)) {
     int dlinkc = 0;
     struct DLink* slink = NULL;
    
     send_reply(sptr, RPL_DATASTR, " ");
     send_reply(sptr, RPL_DATASTR, "Downlinks::");
     for (slink = cli_serv(acptr)->down; slink; slink = slink->next) {
       ircd_snprintf(0, outbuf, sizeof(outbuf), "[%d] - %s%s", ++dlinkc, 
             IsBurst(slink->value.cptr) ? "*" : IsBurstAck(slink->value.cptr) ? "!" : IsService(slink->value.cptr) ? "=" : IsHub(slink->value.cptr) ? "+" : " ", 
             cli_name(slink->value.cptr));
       send_reply(sptr, RPL_DATASTR, outbuf);
     }

     if (!dlinkc)
       send_reply(sptr, RPL_DATASTR, "<none>");
   }

   /* Send 'END OF CHECK' message */
   send_reply(sptr, RPL_ENDOFCHECK, " ");
}
Ejemplo n.º 7
0
/** Look up a user by numnick string.
 * See @ref numnicks for more details.
 * @param[in] yxx %Numeric nickname of user.
 * @return %User with that numnick (or NULL).
 */
struct Client* findNUser(const char* yxx)
{
    struct Client* server = 0;
    if (5 == strlen(yxx)) {
        if (0 != (server = FindXNServer(yxx))) {
            Debug((DEBUG_DEBUG, "findNUser: %s(%d)", yxx,
                   base64toint(yxx + 2) & cli_serv(server)->nn_mask));
            return cli_serv(server)->client_list[base64toint(yxx + 2) & cli_serv(server)->nn_mask];
        }
    }
    else if (0 != (server = FindNServer(yxx))) {
        Debug((DEBUG_DEBUG, "findNUser: %s(%d)",
               yxx, base64toint(yxx + 1) & cli_serv(server)->nn_mask));
        return cli_serv(server)->client_list[base64toint(yxx + 1) & cli_serv(server)->nn_mask];
    }
    return 0;
}
Ejemplo n.º 8
0
char *asuka_nickip(char *host)
{
    struct in_addr addr;
    int decoded;

    decoded = base64toint(host);
    addr.s_addr = ntohl(decoded);
    return sstrdup(inet_ntoa(addr));
}
Ejemplo n.º 9
0
bool CProtocol::Process ( const CString& szLine )
{
    bool bGotText = false;
    std::vector < CString > vec;

    // Separamos los tokens del comando
    size_t iPos = szLine.find ( ':' );
    if ( iPos != CString::npos )
    {
        bGotText = true;
        szLine.Split ( vec, ' ', 0, iPos - 1 );
        vec [ vec.size () - 1 ] = std::string ( szLine, iPos + 1 );
    }
    else
        szLine.Split ( vec, ' ' );


    if ( !m_bGotServer )
    {
        // El primer mensaje esperado es el de la información del servidor al que nos conectamos
        if ( bGotText && szLine.compare ( 0, 6, "SERVER" ) == 0 )
        {
            // Procesamos el mensaje
            CMessageSERVER message;
            message.SetSource ( NULL );
            if ( ! message.ProcessMessage ( szLine, vec ) )
                return false;

            // Generamos el numérico

            m_bGotServer = true;
            new CServer ( &m_me, message.GetYXX (), message.GetHost (), message.GetDesc (), message.GetFlags () );
            return true;
        }

        return false;
    }

    // Buscamos el orígen del mensaje
    CClient* pSource = 0;
    unsigned long ulNumeric = base64toint ( vec [ 0 ] );
    if ( ulNumeric > 4095 )
    {
        // Es un usuario
        CServer* pServer;

        if ( ulNumeric > 262143 )
        {
            // Servidor con numérico de dos dígitos
            pServer = m_me.GetServer ( ulNumeric >> 18 );
            if ( pServer )
                pSource = pServer->GetUser ( ulNumeric & 262143 );
        }
Ejemplo n.º 10
0
/** Decode an IP address from base64.
 * @param[in] input Input buffer to decode.
 * @param[out] addr IP address structure to populate.
 */
void base64toip(const char* input, struct irc_in_addr* addr)
{
    memset(addr, 0, sizeof(*addr));
    if (strlen(input) == 6) {
        unsigned int in = base64toint(input);
        /* An all-zero address should stay that way. */
        if (in) {
            addr->in6_16[5] = htons(65535);
            addr->in6_16[6] = htons(in >> 16);
            addr->in6_16[7] = htons(in & 65535);
        }
    } else {
Ejemplo n.º 11
0
static void
stats_servers_verbose(struct Client* sptr, struct StatDesc* sd, int stat,
		      char* param)
{
  struct Client *acptr;

  /* lowercase 'v' is for human-readable,
   * uppercase 'V' is for machine-readable */
  if (stat == 'v')
    send_reply(sptr, SND_EXPLICIT | RPL_STATSVERBOSE,
	       "%-20s %-20s Flags Hops Numeric   Lag  RTT   Up Down "
	       "Clients/Max Proto %-10s :Info", "Servername", "Uplink",
	       "LinkTS");

  for (acptr = GlobalClientList; acptr; acptr = cli_next(acptr)) {
    if (!IsServer(acptr) && !IsMe(acptr))
      continue;
    if (param && match(param, cli_name(acptr))) /* narrow search */
      continue;
    send_reply(sptr, SND_EXPLICIT | RPL_STATSVERBOSE, stat == 'v' ?
	       "%-20s %-20s %c%c%c%c  %4i %s %-4i %5i %4i %4i %4i %5i %5i "
	       "P%-2i   %Tu :%s" :
	       "%s %s %c%c%c%c %i %s %i %i %i %i %i %i %i P%i %Tu :%s",
	       cli_name(acptr),
	       cli_name(cli_serv(acptr)->up),
	       IsBurst(acptr) ? 'B' : '-',
	       IsBurstAck(acptr) ? 'A' : '-',
	       IsHub(acptr) ? 'H' : '-',
	       IsService(acptr) ? 'S' : '-',
	       cli_hopcount(acptr),
	       NumServ(acptr),
	       base64toint(cli_yxx(acptr)),
	       cli_serv(acptr)->lag,
	       cli_serv(acptr)->asll_rtt,
	       cli_serv(acptr)->asll_to,
	       cli_serv(acptr)->asll_from,
	       cli_serv(acptr)->clients,
	       cli_serv(acptr)->nn_mask,
	       cli_serv(acptr)->prot,
	       cli_serv(acptr)->timestamp,
	       cli_info(acptr));
  }
}
Ejemplo n.º 12
0
/** Set a server's capacity.
 * @param[in] c %Server whose capacity is being set.
 * @param[in] capacity Maximum number of clients the server supports.
 */
void SetYXXCapacity(struct Client* c, unsigned int capacity)
{
    unsigned int max_clients = 16;
    /*
     * Calculate mask to be used for the maximum number of clients
     */
    while (max_clients < capacity)
        max_clients <<= 1;
    /*
     * Sanity checks
     */
    if (max_clients > NN_MAX_CLIENT) {
        fprintf(stderr, "MAXCLIENTS (or MAXCONNECTIONS) is (at least) %d "
                "too large ! Please decrease this value.\n",
                max_clients - NN_MAX_CLIENT);
        exit(-1);
    }
    --max_clients;
    inttobase64(cli_serv(c)->nn_capacity, max_clients, 3);
    cli_serv(c)->nn_mask = max_clients;       /* Our Numeric Nick mask */
    cli_serv(c)->client_list = (struct Client**) MyCalloc(max_clients + 1,
                               sizeof(struct Client*));
    server_list[base64toint(cli_yxx(c))] = c;
}
Ejemplo n.º 13
0
/*
 * ms_nick - server message handler for nicks
 * parv[0] = sender prefix
 * parv[1] = nickname
 *
 * If from server, source is client:
 *   parv[2] = timestamp
 *
 * Source is server:
 *   parv[2] = hopcount
 *   parv[3] = timestamp
 *   parv[4] = username
 *   parv[5] = hostname
 *   parv[6] = umode (optional)
 *   parv[parc-3] = IP#                 <- Only Protocol >= 10
 *   parv[parc-2] = YXX, numeric nick   <- Only Protocol >= 10
 *   parv[parc-1] = info
 *   parv[0] = server
 */
int ms_nick(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  struct Client* acptr;
  char           nick[NICKLEN + 2];
  time_t         lastnick = 0;
  int            differ = 1;
  int            samelastnick = 0;
  
  assert(0 != cptr);
  assert(0 != sptr);
  assert(IsServer(cptr));

  if ((IsServer(sptr) && parc < 8) || parc < 3) {
    sendto_opmask_butone(0, SNO_OLDSNO, "bad NICK param count for %s from %C",
			 parv[1], cptr);
    return need_more_params(sptr, "NICK");
  }

  ircd_strncpy(nick, parv[1], NICKLEN);
  nick[NICKLEN] = '\0';

  if (IsServer(sptr)) {
    lastnick = atoi(parv[3]);
    if (lastnick > OLDEST_TS && !IsBurstOrBurstAck(sptr)) 
      cli_serv(sptr)->lag = TStime() - lastnick;
  }
  else {
    lastnick = atoi(parv[2]); 
    if (lastnick > OLDEST_TS && !IsBurstOrBurstAck(sptr))
      cli_serv(cli_user(sptr)->server)->lag = TStime() - lastnick;
  }
  /*
   * If do_nick_name() returns a null name OR if the server sent a nick
   * name and do_nick_name() changed it in some way (due to rules of nick
   * creation) then reject it. If from a server and we reject it,
   * and KILL it. -avalon 4/4/92
   */
  if (0 == do_nick_name(nick) || 0 != strcmp(nick, parv[1])) {
    send_reply(sptr, ERR_ERRONEUSNICKNAME, parv[1]);

    ++ServerStats->is_kill;
    sendto_opmask_butone(0, SNO_OLDSNO, "Bad Nick: %s From: %s %C", parv[1],
			 parv[0], cptr);
    sendcmdto_one(&me, CMD_KILL, cptr, "%s :%s (%s <- %s[%s])",
		  IsServer(sptr) ? parv[parc - 2] : parv[0], 
		  cli_name(&me), parv[1], nick, cli_name(cptr));
    if (!IsServer(sptr)) {
      /*
       * bad nick _change_
       */
      sendcmdto_serv_butone(&me, CMD_KILL, 0, "%s :%s (%s <- %s!%s@%s)",
			    parv[0], cli_name(&me), cli_name(cptr), parv[0],
			    cli_user(sptr) ? cli_username(sptr) : "",
			    cli_user(sptr) ? cli_name(cli_user(sptr)->server) :
			    cli_name(cptr));
    }
    return 0;
  }
  /*
   * Check against nick name collisions.
   *
   * Put this 'if' here so that the nesting goes nicely on the screen :)
   * We check against server name list before determining if the nickname
   * is present in the nicklist (due to the way the below for loop is
   * constructed). -avalon
   */
   
  assert(NULL == strchr(nick,'.'));

  acptr = FindClient(nick);
  if (!acptr) {
    /*
     * No collisions, all clear...
     */
    return set_nick_name(cptr, sptr, nick, parc, parv);
  }
  assert(0 != acptr);

  /*
   * If acptr == sptr, then we have a client doing a nick
   * change between *equivalent* nicknames as far as server
   * is concerned (user is changing the case of his/her
   * nickname or somesuch)
   */
  if (acptr == sptr) {
    if (strcmp(cli_name(acptr), nick) == 0)
      /*
       * This is just ':old NICK old' type thing.
       * Just forget the whole thing here. There is
       * no point forwarding it to anywhere,
       * especially since servers prior to this
       * version would treat it as nick collision.
       */
      return 0;                        /* NICK Message ignored */
    else
      /*
       * Allows change of case in his/her nick
       */
      return set_nick_name(cptr, sptr, nick, parc, parv);
  }

  /*
   * Note: From this point forward it can be assumed that
   * acptr != sptr (point to different client structures).
   */
  assert(acptr != sptr);
  /*
   * If the older one is "non-person", the new entry is just
   * allowed to overwrite it. Just silently drop non-person,
   * and proceed with the nick. This should take care of the
   * "dormant nick" way of generating collisions...
   */
  if (IsUnknown(acptr) && MyConnect(acptr)) {
    ++ServerStats->is_ref;
    IPcheck_connect_fail(cli_ip(acptr));
    exit_client(cptr, acptr, &me, "Overridden by other sign on");
    return set_nick_name(cptr, sptr, nick, parc, parv);
  }
  /*
   * Decide, we really have a nick collision and deal with it
   */
  /*
   * NICK was coming from a server connection.
   * This means we have a race condition (two users signing on
   * at the same time), or two net fragments reconnecting with the same nick.
   * The latter can happen because two different users connected
   * or because one and the same user switched server during a net break.
   * If the TimeStamps are equal, we kill both (or only 'new'
   * if it was a ":server NICK new ...").
   * Otherwise we kill the youngest when user@host differ,
   * or the oldest when they are the same.
   * We treat user and ~user as different, because if it wasn't
   * a faked ~user the AUTH wouldn't have added the '~'.
   * --Run
   *
   */


  if (IsServer(sptr)) {
    /*
     * A new NICK being introduced by a neighbouring
     * server (e.g. message type ":server NICK new ..." received)
     *
     * compare IP address and username
     */
    differ =  (cli_ip(acptr).s_addr != htonl(base64toint(parv[parc - 3]))) ||
              (0 != ircd_strcmp(cli_user(acptr)->username, parv[4]));
    sendto_opmask_butone(0, SNO_OLDSNO, "Nick collision on %C (%C %Tu <- "
			 "%C %Tu (%s user@host))", acptr, cli_from(acptr),
			 cli_lastnick(acptr), cptr, lastnick,
			 differ ? "Different" : "Same");
  }
  else {
    /*
     * A NICK change has collided (e.g. message type ":old NICK new").
     *
     * compare IP address and username
     */
    differ =  (cli_ip(acptr).s_addr != cli_ip(sptr).s_addr) ||
              (0 != ircd_strcmp(cli_user(acptr)->username, cli_user(sptr)->username));              
    sendto_opmask_butone(0, SNO_OLDSNO, "Nick change collision from %C to "
			 "%C (%C %Tu <- %C %Tu)", sptr, acptr, cli_from(acptr),
			 cli_lastnick(acptr), cptr, lastnick);
  }
  /*
   * Now remove (kill) the nick on our side if it is the youngest.
   * If no timestamp was received, we ignore the incoming nick
   * (and expect a KILL for our legit nick soon ):
   * When the timestamps are equal we kill both nicks. --Run
   * acptr->from != cptr should *always* be true (?).
   *
   * This exits the client sending the NICK message
   */
  if (cli_from(acptr) != cptr) {
    if ((differ && lastnick >= cli_lastnick(acptr)) ||
	(!differ && lastnick <= cli_lastnick(acptr))) {
      if (!IsServer(sptr)) {
        ++ServerStats->is_kill;
	sendcmdto_serv_butone(&me, CMD_KILL, NULL, "%C :%s (Nick collision)",
			      sptr, cli_name(&me));
        assert(!MyConnect(sptr));

        SetFlag(sptr, FLAG_KILLED);

	exit_client_msg(cptr, sptr, &me,
			       "Killed (%s (Nick collision))",
			       feature_str(FEAT_HIS_SERVERNAME));

	sptr = 0; /* Make sure we don't use the dead client */

      } else {
        /* We need to kill this incoming client, which hasn't been properly registered yet.
         * Send a KILL message upstream to the server it came from  */
        sendcmdto_one(&me, CMD_KILL, sptr, "%s :%s (Nick collision)", parv[parc-2], cli_name(&me));
      } 
      /* If the two have the same TS then we want to kill both sides, so
       * don't leave yet!
       */
      if (lastnick != cli_lastnick(acptr))
        return 0;                /* Ignore the NICK */
    }
    send_reply(acptr, ERR_NICKCOLLISION, nick);
  }

  ++ServerStats->is_kill;
  SetFlag(acptr, FLAG_KILLED);
  
  if (lastnick == cli_lastnick(acptr))
    samelastnick = 1;
    
  /*
   * This exits the client we had before getting the NICK message
   */
  if (differ) {
    sendcmdto_serv_butone(&me, CMD_KILL, NULL, "%C :%s (older nick "
			  "overruled)", acptr, cli_name(&me));
    if (MyConnect(acptr)) {
      sendcmdto_one(acptr, CMD_QUIT, cptr, ":Killed (%s (older "
		    "nick overruled))",  feature_str(FEAT_HIS_SERVERNAME));
      sendcmdto_one(&me, CMD_KILL, acptr, "%C :%s (older nick "
		    "overruled)", acptr, feature_str(FEAT_HIS_SERVERNAME));
    }

    exit_client_msg(cptr, acptr, &me, "Killed (%s (older nick "
		    "overruled))", feature_str(FEAT_HIS_SERVERNAME));
  }
  else {
    sendcmdto_serv_butone(&me, CMD_KILL, NULL, "%C :%s (nick collision from "
			  "same user@host)", acptr, cli_name(&me));
    if (MyConnect(acptr)) {
      sendcmdto_one(acptr, CMD_QUIT, cptr, ":Killed (%s (nick "
		    "collision from same user@host))",
		    feature_str(FEAT_HIS_SERVERNAME));
      sendcmdto_one(&me, CMD_KILL, acptr, "%C :%s (older nick "
		    "overruled)", acptr, feature_str(FEAT_HIS_SERVERNAME));
    }
    exit_client_msg(cptr, acptr, &me, "Killed (%s (nick collision from "
		    "same user@host))", feature_str(FEAT_HIS_SERVERNAME));
  }
  if (samelastnick)
    return 0;

  assert(0 != sptr);
  return set_nick_name(cptr, sptr, nick, parc, parv);
}
Ejemplo n.º 14
0
/** Unassign a server's numnick.
 * @param[in] server %Server that should be removed from the numnick table.
 */
void ClearServerYXX(const struct Client *server)
{
    unsigned int index = base64toint(cli_yxx(server));
    if (server_list[index] == server)     /* Sanity check */
        server_list[index] = 0;
}
Ejemplo n.º 15
0
void CChannel::SetModes ( const CString& szModes, const std::vector < CString >& vecModeParams )
{
    unsigned int uiParamIndex = 0;
    enum { ADD, DEL } eDirection = ADD;
    CServer& me = CProtocol::GetSingleton ().GetMe ();

    const char* p = szModes.c_str ();
    while ( *p != '\0' )
    {
        switch ( *p )
        {
        case '+':
        {
            eDirection = ADD;
            break;
        }
        case '-':
        {
            eDirection = DEL;
            break;
        }
        default:
        {
            unsigned long ulMode = ms_ulChannelModes [ (unsigned char)*p ];
            if ( ulMode != 0 )
            {
                if ( ulMode < CMODE_PARAMSMAX )
                {
                    if ( eDirection == ADD )
                        m_ulModes |= ulMode;
                    else
                        m_ulModes &= ~ulMode;

                    if ( ulMode >= CMODE_MAX )
                    {
                        // El modo lleva parámetros
                        switch ( ulMode )
                        {
                        case CMODE_KEY:
                            if ( eDirection == ADD )
                                SetKey ( vecModeParams [ uiParamIndex ] );
                            else
                                SetKey ( "" );
                            ++uiParamIndex;
                            break;
                        case CMODE_LIMIT:
                            if ( eDirection == ADD )
                            {
                                SetLimit ( atoi ( vecModeParams [ uiParamIndex ] ) );
                                ++uiParamIndex;
                            }
                            else
                                SetLimit ( 0 );
                            break;
                        }
                    }
                }
                else
                {
                    // Cambiamos flags de usuarios o bans
                    if ( ulMode == CFLAG_BAN )
                    {
                        if ( eDirection == ADD )
                            AddBan ( vecModeParams [ uiParamIndex ] );
                        else
                            RemoveBan ( vecModeParams [ uiParamIndex ] );
                        ++uiParamIndex;
                    }
                    else
                    {
                        CUser* pUser = me.GetUserAnywhere ( base64toint ( vecModeParams [ uiParamIndex ] ) );
                        ++uiParamIndex;

                        if ( pUser )
                        {
                            CMembership* pMembership = GetMembership ( pUser );
                            if ( pMembership )
                            {
                                unsigned long ulCurFlags = pMembership->GetFlags ();
                                if ( eDirection == ADD )
                                    pMembership->SetFlags ( ulCurFlags | ulMode );
                                else
                                    pMembership->SetFlags ( ulCurFlags & ~ulMode );
                            }
                        }
                    }
                }
            }
        }
        }
        ++p;
    }
}
Ejemplo n.º 16
0
Archivo: m_map.c Proyecto: ryden/ircuRH
static void dump_map(struct Client *cptr, struct Client *server, char *mask, int prompt_length)
{
    static char prompt[64];
    struct DLink *lp;
    char *p = &prompt[prompt_length];
    int cnt = 0;

    *p = '\0';
    if (prompt_length > 60)
        send_reply(cptr, RPL_MAPMORE, prompt, cli_name(server));
    else {
        char lag[512];
        int showserv = 1;
        unsigned int totalusers = UserStats.clients;
        unsigned int percentage;
        unsigned int serv_clients;

        if (totalusers == 0)
            totalusers = 1; /* ¿? NO deberia ocurrir nunca... */

        percentage = (10000 * (IsMe(server) ? UserStats.local_clients : cli_serv(server)->clients)) / totalusers;
        if (IsMe(server))
            strcpy(lag,"(0s)");
        else if (cli_serv(server)->lag>10000)
            lag[0]=0;
        else if (cli_serv(server)->lag<0)
            strcpy(lag,"(0s)");
        else
            sprintf(lag,"(%is)",cli_serv(server)->lag);
        if (IsHiddenserv(server) && !feature_bool(FEAT_SHOWSERVON_MAP))
            if (!IsAnOper(cptr) && !es_representante(cptr))
                showserv = 0;

        serv_clients = (server == &me) ? UserStats.local_clients : cli_serv(server)->clients;

        send_reply(cptr, RPL_MAP, prompt, (
                       (IsBurst(server)) ? "*" : (IsBurstAck(server) ? "!" : "")),
                   showserv ? cli_name(server) : feature_str(FEAT_HIS_SERVERNAME),
                   lag, NumServ(server), base64toint(NumServ(server)), serv_clients,
                   (serv_clients == 1) ? "" : "s",
                   (percentage / 100), (percentage % 100));
    }
    if (prompt_length > 0)
    {
        p[-1] = ' ';
        if (p[-2] == '`')
            p[-2] = ' ';
    }
    if (prompt_length > 60)
        return;
    strcpy(p, "|-");
    for (lp = cli_serv(server)->down; lp; lp = lp->next)
        if (match(mask, cli_name(lp->value.cptr)))
            cli_flags(lp->value.cptr) &= ~FLAGS_MAP;
        else
        {
            cli_flags(lp->value.cptr) |= FLAGS_MAP;
            cnt++;
        }
    for (lp = cli_serv(server)->down; lp; lp = lp->next)
    {
        if ((cli_flags(lp->value.cptr) & FLAGS_MAP) == 0)
            continue;
        if (--cnt == 0)
            *p = '`';
        dump_map(cptr, lp->value.cptr, mask, prompt_length + 2);
    }
    if (prompt_length > 0)
        p[-1] = '-';
}