Exemple #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*));
}
Exemple #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;
}
Exemple #3
0
/** Set a server's numeric nick.
 * See @ref numnicks for more details.
 * @param[in] c %Server that is being assigned a numnick.
 * @param[in] numeric Numnick value for server.
 */
void SetYXXServerName(struct Client* c, unsigned int numeric)
{
    assert(0 != c);
    assert(numeric < NN_MAX_SERVER);

    inttobase64(cli_yxx(c), numeric, 2);
    if (numeric >= lastNNServer)
        lastNNServer = numeric + 1;
    server_list[numeric] = c;
}
Exemple #4
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));
  }
}
Exemple #5
0
/** Register numeric of new (local) client.
 * See @ref numnicks for more details.
 * Assign a numnick and add it to our client_list.
 * @param[in] cptr %User being registered.
 */
int SetLocalNumNick(struct Client *cptr)
{
    static unsigned int last_nn     = 0;
    struct Client**     client_list = cli_serv(&me)->client_list;
    unsigned int        mask        = cli_serv(&me)->nn_mask;
    unsigned int        count       = 0;

    assert(cli_user(cptr)->server == &me);

    while (client_list[last_nn & mask]) {
        if (++count == NN_MAX_CLIENT) {
            assert(count < NN_MAX_CLIENT);
            return 0;
        }
        if (++last_nn == NN_MAX_CLIENT)
            last_nn = 0;
    }
    client_list[last_nn & mask] = cptr;  /* Reserve the numeric ! */

    inttobase64(cli_yxx(cptr), last_nn, 3);
    if (++last_nn == NN_MAX_CLIENT)
        last_nn = 0;
    return 1;
}
Exemple #6
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;
}
Exemple #7
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;
}
/* Rewritten by Run - 24 sept 94 */
static void exit_one_client(struct Client* bcptr, const char* comment)
{
  struct SLink *lp;
  struct Ban *bp;

  if (cli_serv(bcptr) && cli_serv(bcptr)->client_list)  /* Was SetServerYXX called ? */
    ClearServerYXX(bcptr);      /* Removes server from server_list[] */
  if (IsUser(bcptr)) {
    /*
     * clear out uping requests
     */
    if (IsUPing(bcptr))
      uping_cancel(bcptr, 0);
    /*
     * Stop a running /LIST clean
     */
    if (MyUser(bcptr) && cli_listing(bcptr)) {
      MyFree(cli_listing(bcptr));
      cli_listing(bcptr) = NULL;
    }
    /*
     * If a person is on a channel, send a QUIT notice
     * to every client (person) on the same channel (so
     * that the client can show the "**signoff" message).
     * (Note: The notice is to the local clients *only*)
     */
    sendcmdto_common_channels_butone(bcptr, CMD_QUIT, NULL, ":%s", comment);

    remove_user_from_all_channels(bcptr);

    /* Clean up invitefield */
    while ((lp = cli_user(bcptr)->invited))
      del_invite(bcptr, lp->value.chptr);

    /* Clean up silencefield */
    while ((bp = cli_user(bcptr)->silence)) {
      cli_user(bcptr)->silence = bp->next;
      free_ban(bp);
    }

    /* Clean up snotice lists */
    if (MyUser(bcptr))
      set_snomask(bcptr, ~0, SNO_DEL);

    if (IsInvisible(bcptr)) {
      assert(UserStats.inv_clients > 0);
      --UserStats.inv_clients;
    }
    if (IsOper(bcptr)) {
      assert(UserStats.opers > 0);
      --UserStats.opers;
    }
    if (MyConnect(bcptr))
      Count_clientdisconnects(bcptr, UserStats);
    else
      Count_remoteclientquits(UserStats, bcptr);
  }
  else if (IsServer(bcptr))
  {
    /* Remove downlink list node of uplink */
    remove_dlink(&(cli_serv(cli_serv(bcptr)->up))->down, cli_serv(bcptr)->updown);
    cli_serv(bcptr)->updown = 0;

    if (MyConnect(bcptr))
      Count_serverdisconnects(UserStats);
    else
      Count_remoteserverquits(UserStats);
  }
  else if (IsMe(bcptr))
  {
    sendto_opmask_butone(0, SNO_OLDSNO, "ERROR: tried to exit me! : %s",
			 comment);
    return;                     /* ...must *never* exit self! */
  }
  else if (IsUnknown(bcptr) || IsConnecting(bcptr) || IsHandshake(bcptr))
    Count_unknowndisconnects(UserStats);

  /*
   * Update IPregistry
   */
  if (IsIPChecked(bcptr))
    IPcheck_disconnect(bcptr);

  /* 
   * Remove from serv->client_list
   * NOTE: user is *always* NULL if this is a server
   */
  if (cli_user(bcptr)) {
    assert(!IsServer(bcptr));
    /* bcptr->user->server->serv->client_list[IndexYXX(bcptr)] = NULL; */
    RemoveYXXClient(cli_user(bcptr)->server, cli_yxx(bcptr));
  }

  /* Remove bcptr from the client list */
#ifdef DEBUGMODE
  if (hRemClient(bcptr) != 0)
    Debug((DEBUG_ERROR, "%p !in tab %s[%s] %p %p %p %d %d %p",
          bcptr, cli_name(bcptr), cli_from(bcptr) ? cli_sockhost(cli_from(bcptr)) : "??host",
          cli_from(bcptr), cli_next(bcptr), cli_prev(bcptr), cli_fd(bcptr),
          cli_status(bcptr), cli_user(bcptr)));
#else
  hRemClient(bcptr);
#endif
  remove_client_from_list(bcptr);
}