X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libatalk%2Facl%2Fcache.c;h=86bc34dcfd59bf4bbb81c9785a072b502fda4e4c;hb=b0bcb8f6b0571592a50ce039882c9319e012a270;hp=538ff33d8ddd85d09acd1864e82182b96ba2bd55;hpb=d9cb7e3267c7ff5bb1d2c2ad16194606f280b949;p=netatalk.git diff --git a/libatalk/acl/cache.c b/libatalk/acl/cache.c index 538ff33d..86bc34dc 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,7 +30,7 @@ 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; @@ -45,26 +44,29 @@ 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 */ @@ -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; }