From 93bfbb18e77f33d6551a4725b1802c6340aa2c60 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Wilfried=20G=C3=B6esgens?= Date: Sat, 23 Feb 2008 18:37:23 +0000 Subject: [PATCH] * fixed several crash / invalid data cases in the hash implementation * add mimetype to icon facility * fix some warnings in the deb-build * bumped version no --- libcitadel/configure.in | 2 +- libcitadel/debian/changelog | 14 +++- libcitadel/debian/files | 6 +- libcitadel/debian/rules | 20 +++--- libcitadel/lib/hash.c | 34 +++++---- libcitadel/lib/libcitadel.h | 25 ++++--- libcitadel/lib/mime_parser.c | 131 +++++++++++++++++++++++++++++++++++ 7 files changed, 196 insertions(+), 36 deletions(-) diff --git a/libcitadel/configure.in b/libcitadel/configure.in index 4071fbad4..dad2a9998 100755 --- a/libcitadel/configure.in +++ b/libcitadel/configure.in @@ -5,7 +5,7 @@ dnl dnl Ensure that libcitadel is configured with autoconf 2.52 or newer AC_PREREQ(2.52) -AC_INIT(libcitadel, 1.05, https://uncensored.citadel.org) +AC_INIT(libcitadel, 1.06, https://uncensored.citadel.org) AC_CONFIG_SRCDIR(Makefile.in) AC_CONFIG_AUX_DIR(conftools) diff --git a/libcitadel/debian/changelog b/libcitadel/debian/changelog index 8bd4c5eb0..4c7317943 100644 --- a/libcitadel/debian/changelog +++ b/libcitadel/debian/changelog @@ -1,6 +1,16 @@ -libcitadel (7.24-1) unstable; urgency=low +libcitadel (1.06-7) stable; urgency=high + + * mime to icon guessing + * fixed hash lookups + + -- Wilfried Goesgens Sat, 23 Feb 2008 0:00:00 +0001 +libcitadel (1.05-4) stable; urgency=high + + * include xdgmime + + -- Wilfried Goesgens Tue, 12 Feb 2008 0:00:00 +0001 +libcitadel (1.03-3) unstable; urgency=low * initial debian release -- Wilfried Goesgens Sun, 18 Nov 2007 23:55:21 +0100 - \ No newline at end of file diff --git a/libcitadel/debian/files b/libcitadel/debian/files index efb3739e3..525ce5997 100644 --- a/libcitadel/debian/files +++ b/libcitadel/debian/files @@ -1,3 +1,3 @@ -libcitadel1_7.24-1_i386.deb libs optional -libcitadel1-dbg_7.24-1_i386.deb libdevel optional -libcitadel-dev_7.24-1_i386.deb libdevel optional +libcitadel1_1.05-4_i386.deb libs optional +libcitadel1-dbg_1.05-4_i386.deb libdevel optional +libcitadel-dev_1.05-4_i386.deb libdevel optional diff --git a/libcitadel/debian/rules b/libcitadel/debian/rules index 2219e78da..4ce1be12f 100755 --- a/libcitadel/debian/rules +++ b/libcitadel/debian/rules @@ -56,16 +56,16 @@ binary-indep: build install dh_testroot -i dh_installdocs -i -A README dh_installchangelogs -i debian/no-upstream-changelog - dh_install -i --sourcedir=debian/tmp - dh_link -i - dh_strip -i - dh_compress -i - dh_fixperms -i - dh_installdeb -i - dh_shlibdeps -i - dh_gencontrol -i - dh_md5sums -i - dh_builddeb -i +# dh_install -i --sourcedir=debian/tmp +# dh_link -i +# dh_strip -i +# dh_compress -i +# dh_fixperms -i +# dh_installdeb -i +# dh_shlibdeps -i +# dh_gencontrol -i +# dh_md5sums -i +# dh_builddeb -i # Build architecture-dependent files here. binary-arch: build install diff --git a/libcitadel/lib/hash.c b/libcitadel/lib/hash.c index 1c624e8f4..a3e33f1a2 100644 --- a/libcitadel/lib/hash.c +++ b/libcitadel/lib/hash.c @@ -31,11 +31,12 @@ struct HashList { struct HashPos { long Position; }; - -int PrintHash(HashList *Hash) +#define DEBUG +int PrintHash(HashList *Hash, PrintHashContent First, PrintHashContent Second) { - char *foo; - char *bar; + const char *foo; + const char *bar; + const char *bla = ""; long key; long i; if (Hash->MyKeys != NULL) @@ -57,10 +58,13 @@ int PrintHash(HashList *Hash) { key = Hash->LookupTable[i]->Key; foo = Hash->LookupTable[i]->HashKey; - bar = (char*) Hash->Members[Hash->LookupTable[i]->Position]->Data; + if (First != NULL) + bar = First(Hash->Members[Hash->LookupTable[i]->Position]->Data); + if (Second != NULL) + bla = Second(Hash->Members[Hash->LookupTable[i]->Position]->Data); } #ifdef DEBUG - printf (" ---- Hashkey[%ld][%ld]: '%s' Value: '%s' \n", i, key, foo, bar); + printf (" ---- Hashkey[%ld][%ld]: '%s' Value: '%s' ; %s\n", i, key, foo, bar, bla); #endif } #ifdef DEBUG @@ -147,10 +151,14 @@ static void InsertHashItem(HashList *Hash, NewPayloadArea = (Payload**) malloc(sizeof(Payload*) * Hash->MemberSize * 2); memset(&NewPayloadArea[Hash->MemberSize], 0, sizeof(Payload*) * Hash->MemberSize); memcpy(NewPayloadArea, Hash->Members, sizeof(Payload*) * Hash->MemberSize); + free(Hash->Members); + Hash->Members = NewPayloadArea; NewTable = malloc(sizeof(HashKey*) * Hash->MemberSize * 2); memset(&NewTable[Hash->MemberSize], 0, sizeof(HashKey*) * Hash->MemberSize); - memcpy(NewTable, &Hash->LookupTable, sizeof(HashKey*) * Hash->MemberSize); + memcpy(NewTable, Hash->LookupTable, sizeof(HashKey*) * Hash->MemberSize); + free(Hash->LookupTable); + Hash->LookupTable = NewTable; Hash->MemberSize *= 2; } @@ -264,14 +272,16 @@ void Put(HashList *Hash, char *HKey, long HKLen, void *Data, DeleteHashDataFunc } } -int GetHash(HashList *Hash, char *HKey, long HKLen, void **Data) +int GetHash(HashList *Hash, const char *HKey, long HKLen, void **Data) { long HashBinKey; long HashAt; - HashBinKey = CalcHashKey(HKey, HKLen); + HashBinKey = CalcHashKey((char*)HKey, HKLen); HashAt = FindInHash(Hash, HashBinKey); - if ((HashAt < 0) || (HashAt >= Hash->nMembersUsed)) { + if ((HashAt < 0) || + (HashAt >= Hash->nMembersUsed) || + (Hash->LookupTable[HashAt]->Key != HashBinKey)) { *Data = NULL; return 0; } @@ -289,7 +299,7 @@ int GetKey(HashList *Hash, char *HKey, long HKLen, void **Payload) return 0; } -int GetHashKeys(HashList *Hash, const char ***List) +int GetHashKeys(HashList *Hash, char ***List) { long i; if (Hash->MyKeys != NULL) @@ -300,7 +310,7 @@ int GetHashKeys(HashList *Hash, const char ***List) Hash->MyKeys[i] = Hash->LookupTable[i]->HashKey; } - *List = Hash->MyKeys; + *List = (char**)Hash->MyKeys; return Hash->nMembersUsed; } diff --git a/libcitadel/lib/libcitadel.h b/libcitadel/lib/libcitadel.h index ce76ac61b..7dac9e971 100644 --- a/libcitadel/lib/libcitadel.h +++ b/libcitadel/lib/libcitadel.h @@ -9,8 +9,8 @@ * since we reference time_t... */ #include - -#define LIBCITADEL_VERSION_NUMBER 105 +#include +#define LIBCITADEL_VERSION_NUMBER 106 /* * Here's a bunch of stupid magic to make the MIME parser portable. @@ -177,6 +177,11 @@ void the_mime_parser(char *partnum, const char *GuessMimeType(char *data, size_t dlen); const char* GuessMimeByFilename(const char *what, size_t len); +/** Run once at Programstart */ +int LoadIconDir(const char *DirName); +/** guess an icon to the mimetype */ +const char *GetIconFilename(char *MimeType, size_t len); +void ShutDownLibCitadel(void); /* tools */ @@ -245,6 +250,10 @@ char *vcard_serialize(struct vCard *); void vcard_fn_to_n(char *vname, char *n, size_t vname_size); void remove_charset_attribute(char *strbuf); +/** + * Citadels Hashlist Implementation + */ + typedef struct HashList HashList; typedef struct HashKey HashKey; @@ -252,24 +261,24 @@ typedef struct HashKey HashKey; typedef struct HashPos HashPos; typedef void (*DeleteHashDataFunc)(void * Data); - - +typedef const char *(*PrintHashContent)(void * Data); HashList *NewHash(void); -void DeleteHash(HashList **Hash); +void DeleteHash(HashList **Hash); -int GetHash(HashList *Hash, char *HKey, long HKLen, void **Data); +int GetHash(HashList *Hash, const char *HKey, long HKLen, void **Data); void Put(HashList *Hash, char *HKey, long HKLen, void *Data, DeleteHashDataFunc DeleteIt); int GetKey(HashList *Hash, char *HKey, long HKLen, void **Data); -int GetHashKeys(HashList *Hash, const char ***List); +int GetHashKeys(HashList *Hash, char ***List); -int PrintHash(HashList *Hash); +int PrintHash(HashList *Hash, PrintHashContent first, PrintHashContent Second); HashPos *GetNewHashPos(void); + void DeleteHashPos(HashPos **DelMe); int GetNextHashPos(HashList *Hash, HashPos *At, long *HKLen, char **HashKey, void **Data); diff --git a/libcitadel/lib/mime_parser.c b/libcitadel/lib/mime_parser.c index 56cd0b0d6..14f292a6d 100644 --- a/libcitadel/lib/mime_parser.c +++ b/libcitadel/lib/mime_parser.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include #include "xdgmime/xdgmime.h" @@ -738,3 +740,132 @@ const char* GuessMimeByFilename(const char *what, size_t len) /* and let xdgmime do the fallback. */ return xdg_mime_get_mime_type_from_file_name(what); } + +static HashList *IconHash = NULL; + +typedef struct IconName IconName; + +struct IconName { + char *FlatName; + char *FileName; +}; + +static void DeleteIcon(void *IconNamePtr) +{ + IconName *Icon = (IconName*) IconNamePtr; + free(Icon->FlatName); + free(Icon->FileName); +} + +static const char *PrintFlat(void *IconNamePtr) +{ + IconName *Icon = (IconName*) IconNamePtr; + return Icon->FlatName; +} +static const char *PrintFile(void *IconNamePtr) +{ + IconName *Icon = (IconName*) IconNamePtr; + return Icon->FileName; +} +#define GENSTR "x-generic" +#define IGNORE_PREFIX_1 "gnome-mime" +int LoadIconDir(const char *DirName) +{ + DIR *filedir = NULL; + struct dirent *filedir_entry; + int d_namelen; + int d_without_ext; + IconName *Icon; + + filedir = opendir (DirName); + IconHash = NewHash(); + if (filedir == NULL) { + return 0; + } + + while ((filedir_entry = readdir(filedir))) + { + char *MinorPtr; + char *PStart; +#ifdef _DIRENT_HAVE_D_NAMELEN + d_namelen = filedir_entry->d_namelen; +#else + d_namelen = strlen(filedir_entry->d_name); +#endif + d_without_ext = d_namelen; + while ((d_without_ext > 0) && (filedir_entry->d_name[d_without_ext] != '.')) + d_without_ext --; + if ((d_without_ext == 0) || (d_namelen < 3)) + continue; + + if ((sizeof(IGNORE_PREFIX_1) < d_namelen) && + (strncmp(IGNORE_PREFIX_1, + filedir_entry->d_name, + sizeof(IGNORE_PREFIX_1) - 1) == 0)) { + PStart = filedir_entry->d_name + sizeof(IGNORE_PREFIX_1); + d_without_ext -= sizeof(IGNORE_PREFIX_1); + } + else { + PStart = filedir_entry->d_name; + } + Icon = malloc(sizeof(IconName)); + + Icon->FileName = malloc(d_namelen + 1); + memcpy(Icon->FileName, filedir_entry->d_name, d_namelen + 1); + + Icon->FlatName = malloc(d_without_ext + 1); + memcpy(Icon->FlatName, PStart, d_without_ext); + Icon->FlatName[d_without_ext] = '\0'; + /* Try to find Minor type in image-jpeg */ + MinorPtr = strchr(Icon->FlatName, '-'); + if (MinorPtr != NULL) { + size_t MinorLen; + MinorLen = 1 + d_without_ext - (MinorPtr - Icon->FlatName + 1); + if ((MinorLen == sizeof(GENSTR)) && + (strncmp(MinorPtr + 1, GENSTR, sizeof(GENSTR)) == 0)) { + /* ok, we found a generic filename. cut the generic. */ + *MinorPtr = '\0'; + d_without_ext = d_without_ext - (MinorPtr - Icon->FlatName); + } + else { /* Map the major / minor separator to / */ + *MinorPtr = '/'; + } + } + +// PrintHash(IconHash, PrintFlat, PrintFile); +// printf("%s - %s\n", Icon->FlatName, Icon->FileName); + Put(IconHash, Icon->FlatName, d_without_ext, Icon, DeleteIcon); +// PrintHash(IconHash, PrintFlat, PrintFile); + } + return 1; +} + +const char *GetIconFilename(char *MimeType, size_t len) +{ + IconName *Icon; + + if(IconHash == NULL) + return NULL; + + GetHash(IconHash, MimeType, len, (void**)&Icon); + /* didn't find the exact mimetype? try major only. */ + if (Icon == NULL) { + char * pMinor; + pMinor = strchr(MimeType, '/'); + if (pMinor != NULL) { + *pMinor = '\0'; + GetHash(IconHash, MimeType, pMinor - MimeType, (void**)&Icon); + } + } + if (Icon == NULL) { + return NULL; + } + + /*printf("Getting: [%s] == [%s] -> [%s]\n", MimeType, Icon->FlatName, Icon->FileName);*/ + return Icon->FileName; +} + +void ShutDownLibCitadel(void) +{ + DeleteHash(&IconHash); +} -- 2.30.2