user-directory.c revision 430d256a6244b2a780c298febc66e74d6b6e8cc2
/* Copyright (c) 2010-2013 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "ioloop.h"
#include "array.h"
#include "hash.h"
#include "llist.h"
#include "mail-user-hash.h"
#include "mail-host.h"
#include "user-directory.h"
/* n% of timeout_secs */
#define USER_NEAR_EXPIRING_PERCENTAGE 10
#define USER_NEAR_EXPIRING_MIN 3
#define USER_NEAR_EXPIRING_MAX 30
struct user_directory_iter {
struct user_directory *dir;
};
struct user_directory {
/* unsigned int username_hash => user */
/* sorted by time */
struct user *prev_insert_pos;
char *username_hash_fmt;
unsigned int timeout_secs;
/* If user's expire time is less than this many seconds away,
don't assume that other directors haven't yet expired it */
unsigned int user_near_expiring_secs;
};
{
struct user_directory_iter *const *iterp;
}
}
{
}
{
if (expire_timestamp > ioloop_time)
return TRUE;
/* don't free this user until the kill is finished */
return TRUE;
}
return TRUE;
i_warning("User %u weakness appears to be stuck, removing it",
}
return FALSE;
}
{
}
unsigned int username_hash)
{
}
return user;
}
static void
{
break;
}
else {
else
}
}
static void
{
break;
}
else {
else
}
}
struct user *
{
/* make sure we don't add timestamps higher than ioloop time */
if (timestamp > ioloop_time)
else {
/* need to insert to correct position. we should get here
only when handshaking. the handshaking USER requests should
come sorted by timestamp. so keep track of the previous
insert position, the next USER should be inserted after
it. */
/* find the position starting from tail */
user);
} else {
user);
}
}
return user;
}
{
}
{
}
}
{
return -1;
return 1;
return 0;
}
{
if (users_count == 0) {
return;
}
/* place all users into array and sort it */
/* recreate the linked list */
array_free(&users);
}
const char *username)
{
}
{
}
{
return expire_timestamp < ioloop_time;
}
struct user_directory *
{
struct user_directory *dir;
return dir;
}
{
}
struct user_directory_iter *
{
struct user_directory_iter *iter;
return iter;
}
{
return FALSE;
return user;
}
{
struct user_directory_iter *const *iters;
unsigned int i, count;
for (i = 0; i < count; i++) {
break;
}
}
}