summaryrefslogtreecommitdiff
path: root/imapd
diff options
context:
space:
mode:
authorMartin Konold <martin.konold@erfrakon.de>2006-07-15 21:21:07 (GMT)
committerMartin Konold <martin.konold@erfrakon.de>2006-07-15 21:21:07 (GMT)
commita894c1feee8e9c50b7565f07596569619d7c53f7 (patch)
tree137a73957d9605a3759c7f4ed102aeec91ce70e7 /imapd
parentb5ee4f9d80f4326d3a83afc1d036c47d6fb10b65 (diff)
downloadserver-a894c1feee8e9c50b7565f07596569619d7c53f7.tar.gz
Martin Konold: Fix hierarchical folder structure if foldersnames contain blank and other non alphanumerical characters like '-'
when using skiplist as the database backend for mailboxes.db
Diffstat (limited to 'imapd')
-rw-r--r--imapd/imapd.folderchar.patch140
-rw-r--r--imapd/imapd.spec4
2 files changed, 144 insertions, 0 deletions
diff --git a/imapd/imapd.folderchar.patch b/imapd/imapd.folderchar.patch
new file mode 100644
index 0000000..8195748
--- /dev/null
+++ b/imapd/imapd.folderchar.patch
@@ -0,0 +1,140 @@
+diff -Naurp ../cyrus-imapd-2.2.12.orig/lib/bsearch.c ./lib/bsearch.c
+--- ../cyrus-imapd-2.2.12.orig/lib/bsearch.c 2003-02-13 21:15:39.000000000 +0100
++++ ./lib/bsearch.c 2006-07-15 22:49:05.000000000 +0200
+@@ -213,3 +213,22 @@ int bsearch_compare(const char *s1, cons
+ s2++;
+ }
+ }
++
++int bsearch_ncompare(const char *s1, int l1, const char *s2, int l2)
++{
++ int min = l1 < l2 ? l1 : l2;
++ int cmp = 0;
++
++ while (min-- > 0 && (cmp = TOCOMPARE(*s1) - TOCOMPARE(*s2)) == 0) {
++ s1++;
++ s2++;
++ }
++ if (min >= 0) {
++ return cmp;
++ } else {
++ if (l2 > l1) return -1;
++ else if (l1 > l2) return 1;
++ else return 0;
++ }
++}
++
+diff -Naurp ../cyrus-imapd-2.2.12.orig/lib/bsearch.h ./lib/bsearch.h
+--- ../cyrus-imapd-2.2.12.orig/lib/bsearch.h 2003-02-13 21:15:39.000000000 +0100
++++ ./lib/bsearch.h 2006-07-14 15:06:24.000000000 +0200
+@@ -51,4 +51,6 @@ extern int bsearch_mem(const char *word,
+
+ extern int bsearch_compare(const char *s1, const char *s2);
+
++extern int bsearch_ncompare(const char *s1, int l1, const char *s2, int l2);
++
+ #endif /* INCLUDED_BSEARCH_H */
+diff -Naurp ../cyrus-imapd-2.2.12.orig/lib/cyrusdb_skiplist.c ./lib/cyrusdb_skiplist.c
+--- ../cyrus-imapd-2.2.12.orig/lib/cyrusdb_skiplist.c 2004-06-08 21:55:17.000000000 +0200
++++ ./lib/cyrusdb_skiplist.c 2006-07-15 22:51:08.000000000 +0200
+@@ -68,6 +68,7 @@
+ #include "retry.h"
+ #include "util.h"
+ #include "xmalloc.h"
++#include "bsearch.h"
+
+ #define PROB (0.5)
+
+@@ -787,24 +788,6 @@ int myclose(struct db *db)
+ return dispose_db(db);
+ }
+
+-static int compare(const char *s1, int l1, const char *s2, int l2)
+-{
+- int min = l1 < l2 ? l1 : l2;
+- int cmp = 0;
+-
+- while (min-- > 0 && (cmp = *s1 - *s2) == 0) {
+- s1++;
+- s2++;
+- }
+- if (min >= 0) {
+- return cmp;
+- } else {
+- if (l1 > l2) return 1;
+- else if (l2 > l1) return -1;
+- else return 0;
+- }
+-}
+-
+ /* returns the offset to the node asked for, or the node after it
+ if it doesn't exist.
+ if previous is set, finds the last node < key */
+@@ -824,7 +807,7 @@ static const char *find_node(struct db *
+
+ for (i = db->curlevel - 1; i >= 0; i--) {
+ while ((offset = FORWARD(ptr, i)) &&
+- compare(KEY(db->map_base + offset), KEYLEN(db->map_base + offset),
++ bsearch_ncompare(KEY(db->map_base + offset), KEYLEN(db->map_base + offset),
+ key, keylen) < 0) {
+ /* move forward at level 'i' */
+ ptr = db->map_base + offset;
+@@ -875,7 +858,7 @@ int myfetch(struct db *db,
+
+ ptr = find_node(db, key, keylen, 0);
+
+- if (ptr == db->map_base || compare(KEY(ptr), KEYLEN(ptr), key, keylen)) {
++ if (ptr == db->map_base || bsearch_ncompare(KEY(ptr), KEYLEN(ptr), key, keylen)) {
+ /* failed to find key/keylen */
+ r = CYRUSDB_NOTFOUND;
+ } else {
+@@ -963,7 +946,7 @@ int myforeach(struct db *db,
+ while (ptr != db->map_base) {
+ /* does it match prefix? */
+ if (KEYLEN(ptr) < (bit32) prefixlen) break;
+- if (prefixlen && compare(KEY(ptr), prefixlen, prefix, prefixlen)) break;
++ if (prefixlen && bsearch_ncompare(KEY(ptr), prefixlen, prefix, prefixlen)) break;
+
+ if (!goodp ||
+ goodp(rock, KEY(ptr), KEYLEN(ptr), DATA(ptr), DATALEN(ptr))) {
+@@ -1116,7 +1099,7 @@ int mystore(struct db *db,
+ newoffset = tp->logend;
+ ptr = find_node(db, key, keylen, updateoffsets);
+ if (ptr != db->map_base &&
+- !compare(KEY(ptr), KEYLEN(ptr), key, keylen)) {
++ !bsearch_ncompare(KEY(ptr), KEYLEN(ptr), key, keylen)) {
+
+ if (!overwrite) {
+ myabort(db, tp); /* releases lock */
+@@ -1282,7 +1265,7 @@ int mydelete(struct db *db,
+
+ ptr = find_node(db, key, keylen, updateoffsets);
+ if (ptr == db->map_base ||
+- !compare(KEY(ptr), KEYLEN(ptr), key, keylen)) {
++ !bsearch_ncompare(KEY(ptr), KEYLEN(ptr), key, keylen)) {
+ /* gotcha */
+ offset = ptr - db->map_base;
+
+@@ -1825,11 +1808,11 @@ static int myconsistent(struct db *db, s
+ const char *q = db->map_base + offset;
+ int cmp;
+
+- cmp = compare(KEY(ptr), KEYLEN(ptr), KEY(q), KEYLEN(q));
++ cmp = bsearch_ncompare(KEY(ptr), KEYLEN(ptr), KEY(q), KEYLEN(q));
+ if (cmp >= 0) {
+ fprintf(stdout,
+ "skiplist inconsistent: %04X: ptr %d is %04X; "
+- "compare() = %d\n",
++ "bsearch_ncompare() = %d\n",
+ ptr - db->map_base,
+ i,
+ offset, cmp);
+@@ -2058,7 +2041,7 @@ static int recovery(struct db *db, int f
+ if (TYPE(ptr) == ADD) {
+ keyptr = find_node(db, KEY(ptr), KEYLEN(ptr), updateoffsets);
+ if (keyptr == db->map_base ||
+- compare(KEY(ptr), KEYLEN(ptr), KEY(keyptr), KEYLEN(keyptr))) {
++ bsearch_ncompare(KEY(ptr), KEYLEN(ptr), KEY(keyptr), KEYLEN(keyptr))) {
+ /* didn't find exactly this node */
+ keyptr = NULL;
+ }
diff --git a/imapd/imapd.spec b/imapd/imapd.spec
index 4998ea6..a213cd7 100644
--- a/imapd/imapd.spec
+++ b/imapd/imapd.spec
@@ -57,6 +57,7 @@ Patch0: imapd.patch
Patch1: imapd.patch.group
Patch2: imapd.annotate.patch
Patch3: kolab-ldap.patch
+Patch4: imapd.folderchar.patch
# build information
Prefix: %{l_prefix}
@@ -112,6 +113,9 @@ AutoReqProv: no
%if "%{with_ldap}" == "yes"
%patch -p0 -P 3
%endif
+%if "%{with_folderchar}" == "yes"
+ %patch -p0 -P 4
+%endif
%{l_shtool} subst \
-e 's;-L/usr/local/lib;;g' \