X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libatalk%2Facl%2Fcache.c;h=bc9806d9d323f1e58af3c44e0c94c79b62ad1037;hb=68d459c6f7d8ca87c0422f3b58d79951e9f47a2e;hp=3b3a888f8682629393038d799b0782e9abe19cb4;hpb=dfd4a2594c2123549b2fd1e6d5dc43d15aafc850;p=netatalk.git diff --git a/libatalk/acl/cache.c b/libatalk/acl/cache.c index 3b3a888f..bc9806d9 100644 --- a/libatalk/acl/cache.c +++ b/libatalk/acl/cache.c @@ -1,5 +1,4 @@ /* - $Id: cache.c,v 1.6 2010-04-23 11:37:05 franklahm Exp $ Copyright (c) 2008,2009 Frank Lahm This program is free software; you can redistribute it and/or modify @@ -31,40 +30,43 @@ typedef struct cacheduser { unsigned long uid; /* for future use */ uuidtype_t type; - uuidp_t uuid; + unsigned char *uuid; char *name; time_t creationtime; struct cacheduser *prev; struct cacheduser *next; } cacheduser_t; -cacheduser_t *namecache[256]; /* indexed by hash of name */ -cacheduser_t *uuidcache[256]; /* indexed by hash of uuid */ +static cacheduser_t *namecache[256]; /* indexed by hash of name */ +static 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, type: %s, cached: %s", - i, entry->name, uuidstring, uuidtype[entry->type], timestr); - free(uuidstring); + 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); } } @@ -72,20 +74,23 @@ static int dumpcache() { 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: %s, cached: %s", - i, uuidstring, entry->name, uuidtype[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 */ @@ -103,7 +108,7 @@ static unsigned char hashstring(unsigned char *str) { 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; @@ -122,15 +127,10 @@ static unsigned char hashuuid(uuidp_t uuid) { 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; + unsigned char *uuid = NULL; cacheduser_t *cacheduser = NULL; - cacheduser_t *entry; unsigned char hash; -#ifdef DEBUG - dumpcache(); -#endif - /* allocate mem and copy values */ name = malloc(strlen(inname)+1); if (!name) { @@ -167,15 +167,14 @@ int add_cachebyname( const char *inname, const uuidp_t inuuid, const uuidtype_t /* get hash */ hash = hashstring((unsigned char *)name); - /* insert cache entry into cache array */ - if (namecache[hash] == NULL) { /* this queue is empty */ + /* 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; - } 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; } cleanup: @@ -188,76 +187,75 @@ cleanup: free(cacheduser); } -#ifdef DEBUG - dumpcache(); -#endif - 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, unsigned char *uuid) { int ret; unsigned char hash; cacheduser_t *entry; time_t tim; -#ifdef DEBUG - dumpcache(); -#endif - hash = hashstring((unsigned char *)name); - if (! namecache[hash]) + if (namecache[hash] == NULL) return -1; entry = namecache[hash]; while (entry) { ret = strcmp(entry->name, name); - if (ret == 0 && type == entry->type) { + 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\' in queue {%d}", entry->name, hash); + LOG(log_debug, logtype_default, "search_cachebyname: expired: name:\"%s\"", entry->name); /* remove item */ - if (entry->prev) /* 2nd to last in queue */ + if (entry->prev) { + /* 2nd to last in queue */ entry->prev->next = entry->next; - else { /* queue head */ + 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); -#ifdef DEBUG - dumpcache(); -#endif return -1; } else { memcpy(uuid, entry->uuid, UUID_BINSIZE); -#ifdef DEBUG - dumpcache(); -#endif + *type = entry->type; return 0; } } entry = entry->next; } -#ifdef DEBUG - dumpcache(); -#endif + return -1; } +/* + * Caller must free allocated name + */ int search_cachebyuuid( uuidp_t uuidp, char **name, uuidtype_t *type) { int ret; unsigned char hash; cacheduser_t *entry; time_t tim; -#ifdef DEBUG - dumpcache(); -#endif - hash = hashuuid(uuidp); if (! uuidcache[hash]) @@ -270,51 +268,42 @@ int search_cachebyuuid( uuidp_t uuidp, char **name, uuidtype_t *type) { tim = time(NULL); if ((tim - entry->creationtime) > CACHESECONDS) { LOG(log_debug, logtype_default, "search_cachebyuuid: expired: name:\'%s\' in queue {%d}", entry->name, hash); - if (entry->prev) /* 2nd to last in queue */ + if (entry->prev) { + /* 2nd to last in queue */ entry->prev->next = entry->next; - else { /* queue head */ + 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); -#ifdef DEBUG - dumpcache(); -#endif return -1; } else { *name = malloc(strlen(entry->name)+1); strcpy(*name, entry->name); *type = entry->type; -#ifdef DEBUG - dumpcache(); -#endif return 0; } } entry = entry->next; } -#ifdef DEBUG - dumpcache(); -#endif - return -1; } 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; + unsigned char *uuid = NULL; cacheduser_t *cacheduser = NULL; cacheduser_t *entry; unsigned char hash; -#ifdef DEBUG - dumpcache(); -#endif - /* allocate mem and copy values */ name = malloc(strlen(inname)+1); if (!name) { @@ -351,15 +340,14 @@ int add_cachebyuuid( uuidp_t inuuid, const char *inname, uuidtype_t type, const /* get hash */ hash = hashuuid(uuid); - /* insert cache entry into cache array */ - if (uuidcache[hash] == NULL) { /* this queue is empty */ + /* 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; - } 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; } cleanup: @@ -372,9 +360,5 @@ cleanup: free(cacheduser); } -#ifdef DEBUG - dumpcache(); -#endif - return ret; }