Addition of hashtable iterator
User print routine rejig of show users to show dbusers and a new show users command in the debugcli
This commit is contained in:
@ -185,3 +185,14 @@ admin_test_user(char *user)
|
||||
return 0;
|
||||
return users_fetch(users, user) != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the statistics and user names of the administration users
|
||||
*
|
||||
* @param dcb A DCB to send the output to
|
||||
*/
|
||||
void
|
||||
dcb_PrintAdminUsers(DCB *dcb)
|
||||
{
|
||||
dcb_usersPrint(dcb, users);
|
||||
}
|
||||
|
@ -51,6 +51,7 @@
|
||||
*
|
||||
* Date Who Description
|
||||
* 23/06/13 Mark Riddoch Initial implementation
|
||||
* 23/07/13 Mark Riddoch Addition of hashtable iterator
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
@ -437,3 +438,68 @@ hashtable_write_unlock(HASHTABLE *table)
|
||||
{
|
||||
atomic_add(&table->writelock, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an iterator on a hash table
|
||||
*
|
||||
* @param table The table to ceate an iterator on
|
||||
* @return An iterator to use in future calls
|
||||
*/
|
||||
HASHITERATOR *
|
||||
hashtable_iterator(HASHTABLE *table)
|
||||
{
|
||||
HASHITERATOR *rval;
|
||||
|
||||
if ((rval = (HASHITERATOR *)malloc(sizeof(HASHITERATOR))) != NULL)
|
||||
{
|
||||
rval->table = table;
|
||||
rval->chain = 0;
|
||||
rval->depth = -1;
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the next key for a hashtable iterator
|
||||
*
|
||||
* @param iter The hashtable iterator
|
||||
* @return The next key value or NULL
|
||||
*/
|
||||
void *
|
||||
hashtable_next(HASHITERATOR *iter)
|
||||
{
|
||||
int i;
|
||||
HASHENTRIES *entries;
|
||||
|
||||
iter->depth++;
|
||||
while (iter->chain < iter->table->hashsize)
|
||||
{
|
||||
if ((entries = iter->table->entries[iter->chain]) != NULL)
|
||||
{
|
||||
i = 0;
|
||||
hashtable_read_lock(iter->table);
|
||||
while (entries && i < iter->depth)
|
||||
{
|
||||
entries = entries->next;
|
||||
i++;
|
||||
}
|
||||
hashtable_read_unlock(iter->table);
|
||||
if (entries)
|
||||
return entries->key;
|
||||
}
|
||||
iter->depth = 0;
|
||||
iter->chain++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free a hashtable iterator
|
||||
*
|
||||
* @param iter The iterator to free
|
||||
*/
|
||||
void
|
||||
hashtable_iterator_free(HASHITERATOR *iter)
|
||||
{
|
||||
free(iter);
|
||||
}
|
||||
|
14
core/users.c
14
core/users.c
@ -170,6 +170,20 @@ usersPrint(USERS *users)
|
||||
void
|
||||
dcb_usersPrint(DCB *dcb, USERS *users)
|
||||
{
|
||||
HASHITERATOR *iter;
|
||||
char *sep, *user;
|
||||
|
||||
dcb_printf(dcb, "Users table data\n");
|
||||
dcb_hashtable_stats(dcb, users->data);
|
||||
if ((iter = hashtable_iterator(users->data)) != NULL)
|
||||
{
|
||||
dcb_printf(dcb, "User names: ");
|
||||
sep = "";
|
||||
while ((user = hashtable_next(iter)) != NULL)
|
||||
{
|
||||
dcb_printf(dcb, "%s%s", sep, user);
|
||||
sep = ", ";
|
||||
}
|
||||
dcb_printf(dcb, "\n");
|
||||
}
|
||||
}
|
||||
|
@ -34,5 +34,7 @@
|
||||
extern int admin_verify(char *, char *);
|
||||
extern char *admin_add_user(char *, char *);
|
||||
extern int admin_test_user(char *);
|
||||
extern void dcb_PrintAdminUsers(DCB *dcb);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -27,6 +27,7 @@
|
||||
*
|
||||
* Date Who Description
|
||||
* 23/06/13 Mark Riddoch Initial implementation
|
||||
* 23/07/13 Mark Riddoch Addition of iterator mechanism
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
@ -46,6 +47,17 @@ typedef struct hashentry {
|
||||
struct hashentry *next; /**< The overflow chain */
|
||||
} HASHENTRIES;
|
||||
|
||||
/**
|
||||
* HASHTABLE iterator - used to walk the hashtable in a thread safe
|
||||
* way
|
||||
*/
|
||||
typedef struct hashiterator {
|
||||
struct hashtable
|
||||
*table; /**< The hashtable the iterator refers to */
|
||||
int chain; /**< The current chain we are walking */
|
||||
int depth; /**< The current depth down the chain */
|
||||
} HASHITERATOR;
|
||||
|
||||
/**
|
||||
* The type definition for the memory allocation functions
|
||||
*/
|
||||
@ -80,4 +92,9 @@ extern void *hashtable_fetch(HASHTABLE *, void *);
|
||||
/**< Fetch the data for a given key */
|
||||
extern void hashtable_stats(HASHTABLE *); /**< Print statisitics */
|
||||
extern void dcb_hashtable_stats(DCB *, HASHTABLE *); /**< Print statisitics */
|
||||
extern HASHITERATOR *hashtable_iterator(HASHTABLE *);
|
||||
/**< Allocate an iterator on the hashtable */
|
||||
extern void *hashtable_next(HASHITERATOR *);
|
||||
/**< Return the key of the hash table iterator */
|
||||
extern void hashtable_iterator_free(HASHITERATOR *);
|
||||
#endif
|
||||
|
@ -75,6 +75,7 @@ struct subcommand {
|
||||
int arg_types[3];
|
||||
};
|
||||
|
||||
static void telnetdShowUsers(DCB *);
|
||||
/**
|
||||
* The subcommands of the show command
|
||||
*/
|
||||
@ -97,7 +98,9 @@ struct subcommand showoptions[] = {
|
||||
{ARG_TYPE_ADDRESS, 0, 0} },
|
||||
{ "epoll", 0, dprintPollStats, "Show the poll statistics",
|
||||
{0, 0, 0} },
|
||||
{ "users", 1, dcb_usersPrint, "Show statistics for a users table",
|
||||
{ "dbusers", 1, dcb_usersPrint, "Show statistics and user names for a service's user table",
|
||||
{ARG_TYPE_ADDRESS, 0, 0} },
|
||||
{ "users", 0, telnetdShowUsers, "Show statistics and user names for the debug interface",
|
||||
{ARG_TYPE_ADDRESS, 0, 0} },
|
||||
{ NULL, 0, NULL, NULL,
|
||||
{0, 0, 0} }
|
||||
@ -503,3 +506,15 @@ char *err;
|
||||
else
|
||||
dcb_printf(dcb, "Failed to add new user. %s\n", err);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the adminsitration users
|
||||
*
|
||||
* @param dcb The DCB to print the user data to
|
||||
*/
|
||||
static void
|
||||
telnetdShowUsers(DCB *dcb)
|
||||
{
|
||||
dcb_printf(dcb, "Administration interface users:\n");
|
||||
dcb_PrintAdminUsers(dcb);
|
||||
}
|
||||
|
Reference in New Issue
Block a user