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 0;
|
||||||
return users_fetch(users, user) != NULL;
|
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
|
* Date Who Description
|
||||||
* 23/06/13 Mark Riddoch Initial implementation
|
* 23/06/13 Mark Riddoch Initial implementation
|
||||||
|
* 23/07/13 Mark Riddoch Addition of hashtable iterator
|
||||||
*
|
*
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
@ -437,3 +438,68 @@ hashtable_write_unlock(HASHTABLE *table)
|
|||||||
{
|
{
|
||||||
atomic_add(&table->writelock, -1);
|
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
|
void
|
||||||
dcb_usersPrint(DCB *dcb, USERS *users)
|
dcb_usersPrint(DCB *dcb, USERS *users)
|
||||||
{
|
{
|
||||||
|
HASHITERATOR *iter;
|
||||||
|
char *sep, *user;
|
||||||
|
|
||||||
dcb_printf(dcb, "Users table data\n");
|
dcb_printf(dcb, "Users table data\n");
|
||||||
dcb_hashtable_stats(dcb, users->data);
|
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 int admin_verify(char *, char *);
|
||||||
extern char *admin_add_user(char *, char *);
|
extern char *admin_add_user(char *, char *);
|
||||||
extern int admin_test_user(char *);
|
extern int admin_test_user(char *);
|
||||||
|
extern void dcb_PrintAdminUsers(DCB *dcb);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
*
|
*
|
||||||
* Date Who Description
|
* Date Who Description
|
||||||
* 23/06/13 Mark Riddoch Initial implementation
|
* 23/06/13 Mark Riddoch Initial implementation
|
||||||
|
* 23/07/13 Mark Riddoch Addition of iterator mechanism
|
||||||
*
|
*
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
@ -46,6 +47,17 @@ typedef struct hashentry {
|
|||||||
struct hashentry *next; /**< The overflow chain */
|
struct hashentry *next; /**< The overflow chain */
|
||||||
} HASHENTRIES;
|
} 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
|
* 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 */
|
/**< Fetch the data for a given key */
|
||||||
extern void hashtable_stats(HASHTABLE *); /**< Print statisitics */
|
extern void hashtable_stats(HASHTABLE *); /**< Print statisitics */
|
||||||
extern void dcb_hashtable_stats(DCB *, 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
|
#endif
|
||||||
|
@ -75,6 +75,7 @@ struct subcommand {
|
|||||||
int arg_types[3];
|
int arg_types[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void telnetdShowUsers(DCB *);
|
||||||
/**
|
/**
|
||||||
* The subcommands of the show command
|
* The subcommands of the show command
|
||||||
*/
|
*/
|
||||||
@ -97,7 +98,9 @@ struct subcommand showoptions[] = {
|
|||||||
{ARG_TYPE_ADDRESS, 0, 0} },
|
{ARG_TYPE_ADDRESS, 0, 0} },
|
||||||
{ "epoll", 0, dprintPollStats, "Show the poll statistics",
|
{ "epoll", 0, dprintPollStats, "Show the poll statistics",
|
||||||
{0, 0, 0} },
|
{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} },
|
{ARG_TYPE_ADDRESS, 0, 0} },
|
||||||
{ NULL, 0, NULL, NULL,
|
{ NULL, 0, NULL, NULL,
|
||||||
{0, 0, 0} }
|
{0, 0, 0} }
|
||||||
@ -503,3 +506,15 @@ char *err;
|
|||||||
else
|
else
|
||||||
dcb_printf(dcb, "Failed to add new user. %s\n", err);
|
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