/*
- $Id: cache.c,v 1.1 2009-02-02 11:55:01 franklahm Exp $
- Copyright (c) 2008,2009 Frank Lahm <franklahm@gmail.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- */
+ Copyright (c) 2008,2009 Frank Lahm <franklahm@gmail.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "cache.h"
typedef struct cacheduser {
- unsigned long uid; /* for future use */
+ unsigned long uid; /* for future use */
uuidtype_t type;
uuidp_t uuid;
char *name;
struct cacheduser *next;
} cacheduser_t;
-cacheduser_t *namecache[256]; /* indexed by hash of name */
-cacheduser_t *uuidcache[256]; /* indexed by hash of uuid */
+cacheduser_t *namecache[256]; /* indexed by hash of name */
+cacheduser_t *uuidcache[256]; /* indexed by hash of uuid */
/********************************************************
* helper function
********************************************************/
-static int dumpcache() {
+void uuidcache_dump(void) {
int i;
int ret = 0;
cacheduser_t *entry;
- char *uuidstring = NULL;
char timestr[200];
struct tm *tmp = NULL;
for ( i=0 ; i<256; i++) {
- if ((entry = namecache[i]) != NULL) {
- do {
- uuid_bin2string(entry->uuid, &uuidstring);
- tmp = localtime(&entry->creationtime);
- if (tmp == NULL)
- continue;
- if (strftime(timestr, 200, "%c", tmp) == 0)
- continue;
- LOG(log_debug9, logtype_default, "namecache{%d}]: name:%s, uuid:%s, cached: %s", i, entry->name, uuidstring, timestr);
- free(uuidstring);
- } while ((entry = entry->next) != NULL);
- }
+ if ((entry = namecache[i]) != NULL) {
+ do {
+ tmp = localtime(&entry->creationtime);
+ if (tmp == NULL)
+ continue;
+ if (strftime(timestr, 200, "%c", tmp) == 0)
+ continue;
+ LOG(log_debug, logtype_default,
+ "namecache{%d}: name:%s, uuid:%s, type%s: %s, cached: %s",
+ i,
+ entry->name,
+ uuid_bin2string(entry->uuid),
+ (entry->type & UUID_ENOENT) == UUID_ENOENT ? "[negative]" : "",
+ uuidtype[entry->type & UUIDTYPESTR_MASK],
+ timestr);
+ } while ((entry = entry->next) != NULL);
+ }
}
for ( i=0; i<256; i++) {
if ((entry = uuidcache[i]) != NULL) {
do {
- uuid_bin2string(entry->uuid, &uuidstring);
+
tmp = localtime(&entry->creationtime);
if (tmp == NULL)
continue;
if (strftime(timestr, 200, "%c", tmp) == 0)
continue;
- LOG(log_debug9, logtype_default, "uuidcache{%d}: uuid:%s, name:%s, type:%d, cached: %s", i, uuidstring, entry->name, entry->type,timestr);
- free(uuidstring);
+ LOG(log_debug, logtype_default,
+ "uuidcache{%d}: uuid:%s, name:%s, type%s: %s, cached: %s",
+ i,
+ uuid_bin2string(entry->uuid),
+ entry->name,
+ (entry->type & UUID_ENOENT) == UUID_ENOENT ? "[negative]" : "",
+ uuidtype[entry->type & UUIDTYPESTR_MASK],
+ timestr);
} while ((entry = entry->next) != NULL);
}
}
-
- return ret;
}
/* hash string it into unsigned char */
unsigned char index;
int c;
while ((c = *str++) != 0)
- hash = ((hash << 5) + hash) ^ c; /* (hash * 33) ^ c */
+ hash = ((hash << 5) + hash) ^ c; /* (hash * 33) ^ c */
index = 85 ^ (hash & 0xff);
while ((hash = hash >> 8) != 0)
- index ^= (hash & 0xff);
-
+ index ^= (hash & 0xff);
+
return index;
}
-/* hash uuid_t into unsigned char */
+/* hash atalk_uuid_t into unsigned char */
static unsigned char hashuuid(uuidp_t uuid) {
unsigned char index = 83;
int i;
for (i=0; i<16; i++) {
- index ^= uuid[i];
- index += uuid[i];
+ index ^= uuid[i];
+ index += uuid[i];
}
return index;
}
-/********************************************************
+/********************************************************
* Interface
********************************************************/
int add_cachebyname( const char *inname, const uuidp_t inuuid, const uuidtype_t type, const unsigned long uid _U_) {
int ret = 0;
char *name = NULL;
- uuidp_t uuid;
+ uuidp_t uuid = NULL;
cacheduser_t *cacheduser = NULL;
- cacheduser_t *entry;
unsigned char hash;
/* allocate mem and copy values */
name = malloc(strlen(inname)+1);
if (!name) {
- LOG(log_error, logtype_default, "add_cachebyname: mallor error");
- ret = -1;
- goto cleanup;
+ LOG(log_error, logtype_default, "add_cachebyname: mallor error");
+ ret = -1;
+ goto cleanup;
}
-
+
uuid = malloc(UUID_BINSIZE);
if (!uuid) {
- LOG(log_error, logtype_default, "add_cachebyname: mallor error");
- ret = -1;
- goto cleanup;
+ LOG(log_error, logtype_default, "add_cachebyname: mallor error");
+ ret = -1;
+ goto cleanup;
}
cacheduser = malloc(sizeof(cacheduser_t));
if (!cacheduser) {
- LOG(log_error, logtype_default, "add_cachebyname: mallor error");
- ret = -1;
- goto cleanup;
+ LOG(log_error, logtype_default, "add_cachebyname: mallor error");
+ ret = -1;
+ goto cleanup;
}
strcpy(name, inname);
/* get hash */
hash = hashstring((unsigned char *)name);
- /* insert cache entry into cache array */
- if (namecache[hash] == NULL) { /* this queue is empty */
- namecache[hash] = cacheduser;
- } else { /* queue is not empty, search end of queue*/
- entry = namecache[hash];
- while( entry->next != NULL)
- entry = entry->next;
- cacheduser->prev = entry;
- entry->next = cacheduser;
+ /* insert cache entry into cache array at head of queue */
+ if (namecache[hash] == NULL) {
+ /* this queue is empty */
+ namecache[hash] = cacheduser;
+ } else {
+ cacheduser->next = namecache[hash];
+ namecache[hash]->prev = cacheduser;
+ namecache[hash] = cacheduser;
}
cleanup:
if (ret != 0) {
- if (name)
- free(name);
- if (uuid)
- free(uuid);
- if (cacheduser)
- free(cacheduser);
+ if (name)
+ free(name);
+ if (uuid)
+ free(uuid);
+ if (cacheduser)
+ free(cacheduser);
}
+
return ret;
}
-int search_cachebyname( const char *name, uuidtype_t type, uuidp_t uuid) {
+/*!
+ * Search cache by name and uuid type
+ *
+ * @args name (r) name to search
+ * @args type (rw) type (user or group) of name, returns found type here which might
+ * mark it as a negative entry
+ * @args uuid (w) found uuid is returned here
+ * @returns 0 on sucess, entry found
+ * -1 no entry found
+ */
+int search_cachebyname(const char *name, uuidtype_t *type, uuidp_t uuid) {
int ret;
unsigned char hash;
cacheduser_t *entry;
hash = hashstring((unsigned char *)name);
- if (! namecache[hash])
- return -1;
+ if (namecache[hash] == NULL)
+ return -1;
entry = namecache[hash];
while (entry) {
- ret = strcmp(entry->name, name);
- if (ret == 0 && type == entry->type) {
- /* found, now check if expired */
- tim = time(NULL);
- if ((tim - entry->creationtime) > CACHESECONDS) {
- /* remove item */
- if (entry->prev) /* 2nd to last in queue */
- entry->prev->next = entry->next;
- else /* queue head */
- namecache[hash] = entry->next;
- free(entry->name);
- free(entry->uuid);
- free(entry);
- return -1;
- } else {
- memcpy(uuid, entry->uuid, UUID_BINSIZE);
- return 0;
- }
- }
- entry = entry->next;
+ ret = strcmp(entry->name, name);
+ if (ret == 0 && *type == (entry->type & UUIDTYPESTR_MASK)) {
+ /* found, now check if expired */
+ tim = time(NULL);
+ if ((tim - entry->creationtime) > CACHESECONDS) {
+ LOG(log_debug, logtype_default, "search_cachebyname: expired: name:\"%s\"", entry->name);
+ /* remove item */
+ if (entry->prev) {
+ /* 2nd to last in queue */
+ entry->prev->next = entry->next;
+ if (entry->next)
+ /* not the last element */
+ entry->next->prev = entry->prev;
+ } else {
+ /* queue head */
+ if ((namecache[hash] = entry->next) != NULL)
+ namecache[hash]->prev = NULL;
+ }
+ free(entry->name);
+ free(entry->uuid);
+ free(entry);
+ return -1;
+ } else {
+ memcpy(uuid, entry->uuid, UUID_BINSIZE);
+ *type = entry->type;
+ return 0;
+ }
+ }
+ entry = entry->next;
}
+
return -1;
}
+/*
+ * Caller must free allocated name
+ */
int search_cachebyuuid( uuidp_t uuidp, char **name, uuidtype_t *type) {
int ret;
unsigned char hash;
if (ret == 0) {
tim = time(NULL);
if ((tim - entry->creationtime) > CACHESECONDS) {
- LOG(log_info, logtype_default, "search_cachebyuuid: expired: name:\'%s\' in queue {%d}", entry->name, hash);
- if (entry->prev)
+ LOG(log_debug, logtype_default, "search_cachebyuuid: expired: name:\'%s\' in queue {%d}", entry->name, hash);
+ if (entry->prev) {
+ /* 2nd to last in queue */
entry->prev->next = entry->next;
- else
- uuidcache[hash] = entry->next;
+ if (entry->next)
+ /* not the last element */
+ entry->next->prev = entry->prev;
+ } else {
+ /* queue head */
+ if ((uuidcache[hash] = entry->next) != NULL)
+ uuidcache[hash]->prev = NULL;
+ }
free(entry->name);
free(entry->uuid);
free(entry);
return -1;
} else {
- *name = malloc(strlen(entry->name)+1);
- strcpy(*name, entry->name);
- *type = entry->type;
+ *name = malloc(strlen(entry->name)+1);
+ strcpy(*name, entry->name);
+ *type = entry->type;
return 0;
}
}
int add_cachebyuuid( uuidp_t inuuid, const char *inname, uuidtype_t type, const unsigned long uid _U_) {
int ret = 0;
char *name = NULL;
- uuidp_t uuid;
+ uuidp_t uuid = NULL;
cacheduser_t *cacheduser = NULL;
cacheduser_t *entry;
unsigned char hash;
/* allocate mem and copy values */
name = malloc(strlen(inname)+1);
if (!name) {
- LOG(log_error, logtype_default, "add_cachebyuuid: mallor error");
- ret = -1;
- goto cleanup;
+ LOG(log_error, logtype_default, "add_cachebyuuid: mallor error");
+ ret = -1;
+ goto cleanup;
}
-
+
uuid = malloc(UUID_BINSIZE);
if (!uuid) {
- LOG(log_error, logtype_default, "add_cachebyuuid: mallor error");
- ret = -1;
- goto cleanup;
+ LOG(log_error, logtype_default, "add_cachebyuuid: mallor error");
+ ret = -1;
+ goto cleanup;
}
cacheduser = malloc(sizeof(cacheduser_t));
if (!cacheduser) {
- LOG(log_error, logtype_default, "add_cachebyuuid: mallor error");
- ret = -1;
- goto cleanup;
+ LOG(log_error, logtype_default, "add_cachebyuuid: mallor error");
+ ret = -1;
+ goto cleanup;
}
strcpy(name, inname);
/* get hash */
hash = hashuuid(uuid);
- /* insert cache entry into cache array */
- if (uuidcache[hash] == NULL) { /* this queue is empty */
- uuidcache[hash] = cacheduser;
- } else { /* queue is not empty, search end of queue*/
- entry = uuidcache[hash];
- while( entry->next != NULL)
- entry = entry->next;
- cacheduser->prev = entry;
- entry->next = cacheduser;
+ /* insert cache entry into cache array at head of queue */
+ if (uuidcache[hash] == NULL) {
+ /* this queue is empty */
+ uuidcache[hash] = cacheduser;
+ } else {
+ cacheduser->next = uuidcache[hash];
+ uuidcache[hash]->prev = cacheduser;
+ uuidcache[hash] = cacheduser;
}
cleanup:
if (ret != 0) {
- if (name)
- free(name);
- if (uuid)
- free(uuid);
- if (cacheduser)
- free(cacheduser);
+ if (name)
+ free(name);
+ if (uuid)
+ free(uuid);
+ if (cacheduser)
+ free(cacheduser);
}
+
return ret;
}