Ejemplo n.º 1
0
/*
 * hAddClient
 * Adds a client's name in the proper hash linked list, can't fail,
 * cptr must have a non-null name or expect a coredump, the name is
 * infact taken from cptr->name
 */
int hAddClient(struct Client *cptr)
{
    HASHREGS hashv = strhash(cli_name(cptr));

    cli_hnext(cptr) = clientTable[hashv];
    clientTable[hashv] = cptr;

    return 0;
}
Ejemplo n.º 2
0
/*
 * hSeekClient
 * New semantics: finds a client whose name is 'name' and whose
 * status is one of those marked in TMask, if can't find one
 * returns NULL. If it finds one moves it to the top of the list
 * and returns it.
 */
struct Client* hSeekClient(const char *name, int TMask)
{
    HASHREGS hashv      = strhash(name);
    struct Client *cptr = clientTable[hashv];

    if (cptr) {
        if (0 == (cli_status(cptr) & TMask) || 0 != ircd_strcmp(name, cli_name(cptr))) {
            struct Client* prev;
            while (prev = cptr, cptr = cli_hnext(cptr)) {
                if ((cli_status(cptr) & TMask) && (0 == ircd_strcmp(name, cli_name(cptr)))) {
                    cli_hnext(prev) = cli_hnext(cptr);
                    cli_hnext(cptr) = clientTable[hashv];
                    clientTable[hashv] = cptr;
                    break;
                }
            }
        }
    }
    return cptr;
}
Ejemplo n.º 3
0
/*
 * hChangeClient
 * Removes the old name of a client from a linked list and adds
 * the new one to another linked list, there is a slight chanche
 * that this is useless if the two hashes are the same but it still
 * would need to move the name to the top of the list.
 * As always it's responsibility of the caller to check that
 * both newname and cptr->name are valid names (not "" or NULL).
 * Typically, to change the nick of an already hashed client:
 * if (!BadPtr(newname) && ClearTheNameSomeHow(newname)) {
 *   hChangeClient(cptr, newname);
 *   strcpy(cptr->name, newname);
 *   };
 * There isn't an equivalent function for channels since they
 * don't change name.
 */
int hChangeClient(struct Client *cptr, const char *newname)
{
    HASHREGS newhash = strhash(newname);

    assert(0 != cptr);
    hRemClient(cptr);

    cli_hnext(cptr) = clientTable[newhash];
    clientTable[newhash] = cptr;
    return 0;
}
Ejemplo n.º 4
0
int m_hash(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
{
    int max_chain = 0;
    int buckets   = 0;
    int count     = 0;
    struct Client*  cl;
    struct Channel* ch;
    int i;

    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Hash Table Statistics", sptr);

    for (i = 0; i < HASHSIZE; ++i) {
        if ((cl = clientTable[i])) {
            int len = 0;
            ++buckets;
            for ( ; cl; cl = cli_hnext(cl))
                ++len;
            if (len > max_chain)
                max_chain = len;
            count += len;
        }
    }

    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Client: entries: %d buckets: %d "
                  "max chain: %d", sptr, count, buckets, max_chain);

    buckets = 0;
    count   = 0;
    max_chain = 0;

    for (i = 0; i < HASHSIZE; ++i) {
        if ((ch = channelTable[i])) {
            int len = 0;
            ++buckets;
            for ( ; ch; ch = ch->hnext)
                ++len;
            if (len > max_chain)
                max_chain = len;
            count += len;
        }
    }

    sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Channel: entries: %d buckets: %d "
                  "max chain: %d", sptr, count, buckets, max_chain);
    return 0;
}
Ejemplo n.º 5
0
/*
 * Create a new struct Client structure and set it to initial state.
 *
 *   from == NULL,   create local client (a client connected to a socket).
 *
 *   from != NULL,   create remote client (behind a socket associated with
 *                   the client defined by 'from').
 *                   ('from' is a local client!!).
 */
struct Client* make_client(struct Client *from, int status)
{
  struct Client* cptr = 0;
  struct Connection* con = 0;

  assert(!from || cli_verify(from));

  cptr = alloc_client();

  assert(0 != cptr);
  assert(!cli_magic(cptr));
  assert(0 == from || 0 != cli_connect(from));

  if (!from) { /* local client, allocate a struct Connection */
    con = alloc_connection();

    assert(0 != con);
    assert(!con_magic(con));

    con_magic(con) = CONNECTION_MAGIC;
    con_fd(con) = -1; /* initialize struct Connection */
    con_freeflag(con) = 0;
    con_nextnick(con) = CurrentTime - NICK_DELAY;
    con_nexttarget(con) = CurrentTime - (TARGET_DELAY * (STARTTARGETS - 1));
    con_handler(con) = UNREGISTERED_HANDLER;
    con_client(con) = cptr;

    cli_local(cptr) = 1; /* Set certain fields of the struct Client */
    cli_since(cptr) = cli_lasttime(cptr) = cli_firsttime(cptr) = CurrentTime;
    cli_lastnick(cptr) = TStime();
  } else
    con = cli_connect(from); /* use 'from's connection */

  assert(0 != con);
  assert(con_verify(con));

  cli_magic(cptr) = CLIENT_MAGIC;
  cli_connect(cptr) = con; /* set the connection and other fields */
  cli_status(cptr) = status;
  cli_hnext(cptr) = cptr;
  strcpy(cli_username(cptr), "unknown");

  return cptr;
}
Ejemplo n.º 6
0
/*
 * hRemClient
 * Removes a Client's name from the hash linked list
 */
int hRemClient(struct Client *cptr)
{
    HASHREGS hashv = strhash(cli_name(cptr));
    struct Client *tmp = clientTable[hashv];

    if (tmp == cptr) {
        clientTable[hashv] = cli_hnext(cptr);
        cli_hnext(cptr) = cptr;
        return 0;
    }

    while (tmp) {
        if (cli_hnext(tmp) == cptr) {
            cli_hnext(tmp) = cli_hnext(cli_hnext(tmp));
            cli_hnext(cptr) = cptr;
            return 0;
        }
        tmp = cli_hnext(tmp);
    }
    return -1;
}
Ejemplo n.º 7
0
/** Release a Client.
 * In addition to the cleanup done by dealloc_client(), this will free
 * any pending auth request, free the connection for local clients,
 * and delete the processing timer for the client.
 * @param[in] cptr Client to free.
 */
void free_client(struct Client* cptr)
{
  if (!cptr)
    return;
  /*
   * forget to remove the client from the hash table?
   */
  assert(cli_verify(cptr));
  assert(cli_hnext(cptr) == cptr);
  /* or from linked list? */
  assert(cli_next(cptr) == 0);
  assert(cli_prev(cptr) == 0);

  Debug((DEBUG_LIST, "Freeing client %s [%p], connection %p", cli_name(cptr),
	 cptr, cli_connect(cptr)));

  if (cli_auth(cptr))
    destroy_auth_request(cli_auth(cptr), 0);

  /* Make sure we didn't magically get re-added to the list */
  assert(cli_next(cptr) == 0);
  assert(cli_prev(cptr) == 0);

  if (cli_from(cptr) == cptr) { /* in other words, we're local */
    cli_from(cptr) = 0;
    /* timer must be marked as not active */
    if (!cli_freeflag(cptr) && !t_active(&(cli_proc(cptr))))
      dealloc_connection(cli_connect(cptr)); /* connection not open anymore */
    else {
      if (-1 < cli_fd(cptr) && cli_freeflag(cptr) & FREEFLAG_SOCKET)
	socket_del(&(cli_socket(cptr))); /* queue a socket delete */
      if (cli_freeflag(cptr) & FREEFLAG_TIMER)
	timer_del(&(cli_proc(cptr))); /* queue a timer delete */
    }
  }

  cli_connect(cptr) = 0;

  dealloc_client(cptr); /* actually destroy the client */
}