Make history functions generic
Signed-off-by: Lon Hohberger <lhh@redhat.com>
This commit is contained in:
parent
da7d3f4c9d
commit
d505e229a7
25
include/history.h
Normal file
25
include/history.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef _HISTORY_H
|
||||
#define _HISTORY_H
|
||||
|
||||
typedef struct _history_node {
|
||||
list_head();
|
||||
void *data;
|
||||
time_t when;
|
||||
} history_node;
|
||||
|
||||
typedef int (*history_compare_fn)(void *, void *);
|
||||
|
||||
typedef struct _history_info {
|
||||
history_node *hist;
|
||||
history_compare_fn compare_func;
|
||||
time_t timeout;
|
||||
size_t element_size;
|
||||
} history_info_t;
|
||||
|
||||
history_info_t *history_init(history_compare_fn func,
|
||||
time_t expiration, size_t element_size);
|
||||
int history_check(history_info_t *hinfo, void *stuff);
|
||||
int history_record(history_info_t *hinfo, void *data);
|
||||
int history_wipe(history_info_t *hinfo);
|
||||
|
||||
#endif
|
122
server/history.c
Normal file
122
server/history.c
Normal file
@ -0,0 +1,122 @@
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <list.h>
|
||||
#include <history.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
history_info_t *
|
||||
history_init(history_compare_fn func, time_t expiration, size_t element_size)
|
||||
{
|
||||
history_info_t *hist;
|
||||
|
||||
errno = EINVAL;
|
||||
if (!func || !expiration || !element_size)
|
||||
return NULL;
|
||||
|
||||
hist = malloc(sizeof(*hist));
|
||||
if (!hist)
|
||||
return NULL;
|
||||
memset(hist, 0, sizeof(*hist));
|
||||
|
||||
hist->timeout = expiration;
|
||||
hist->element_size = element_size;
|
||||
hist->compare_func = func;
|
||||
|
||||
return hist;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Purge our history when the entries time out.
|
||||
*
|
||||
* Returns 1 if a matching history node was found, or 0
|
||||
* if not.
|
||||
*/
|
||||
int
|
||||
history_check(history_info_t *hinfo, void *stuff)
|
||||
{
|
||||
history_node *entry = NULL;
|
||||
time_t now;
|
||||
int x;
|
||||
|
||||
if (!hinfo)
|
||||
return 0; /* XXX */
|
||||
|
||||
if (!hinfo->hist)
|
||||
return 0;
|
||||
|
||||
now = time(NULL);
|
||||
|
||||
loop_again:
|
||||
list_for((&hinfo->hist), entry, x) {
|
||||
if (entry->when < (now - hinfo->timeout)) {
|
||||
list_remove((&hinfo->hist), entry);
|
||||
free(entry->data);
|
||||
free(entry);
|
||||
goto loop_again;
|
||||
}
|
||||
|
||||
if (hinfo->compare_func(entry->data, stuff)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
history_record(history_info_t *hinfo, void *data)
|
||||
{
|
||||
history_node *entry = NULL;
|
||||
|
||||
errno = EINVAL;
|
||||
if (!data || !hinfo)
|
||||
return -1;
|
||||
|
||||
if (history_check(hinfo, data) == 1) {
|
||||
errno = EEXIST;
|
||||
return -1;
|
||||
}
|
||||
|
||||
entry = malloc(sizeof(*entry));
|
||||
if (!entry) {
|
||||
return -1;
|
||||
}
|
||||
memset(entry, 0, sizeof(*entry));
|
||||
|
||||
entry->data = malloc(hinfo->element_size);
|
||||
if (!entry->data) {
|
||||
free(entry);
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(entry->data, data, hinfo->element_size);
|
||||
entry->when = time(NULL);
|
||||
list_insert((&hinfo->hist), entry);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
history_wipe(history_info_t *hinfo)
|
||||
{
|
||||
history_node *entry = NULL;
|
||||
|
||||
if (!hinfo)
|
||||
return -1;
|
||||
|
||||
while (hinfo->hist) {
|
||||
entry = hinfo->hist;
|
||||
list_remove((&hinfo->hist), entry);
|
||||
free(entry->data);
|
||||
free(entry);
|
||||
}
|
||||
|
||||
/* User must free(hinfo); */
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user