Alex,
I was in a similar situation a year ago, and my solution was to alter
the behaviour of courier-imap as a workaround. I know how to write,
debug and modify code, and since Sam's code is clear and well written it
wasn't that difficult. A patch is attached to this mail which would
apply cleanly to courier-imap 1.4.0. I have been running this since
1.3.7 was released (more than half a year). I still regard outlook to be
broken in this regard, but since smooth migration (from an uw-imap
installation) was a high priority, I didn't really have much of a
choice. Never the less, I highly respect Sam's decision to not address
this need in his code base. But since it's open source (thank god for
that, it have saved me a lot of headache!) nothing stops you from
applying inofficial patches like this one.
Things to be aware of with this patch in particular:
1) I had to change the namespace prefix for shared folders from "shared"
to "#shared" (a la uw-imap) in order to avoid a potential folder name
conflict.
2) The top level personal folder behaviour is not active by default. You
need to put a line with "IMAP_PERSONAL_NAMESPACE_AT_TOP_LEVEL=1" in your
imapd configuration file.
3) This alternate behaviour has not been tested together with the use of
shared folders.
Hope it helps.
Regards, Tomas
Alex Zhukov wrote:
> hi all!
>
> an extract from imap/FAQ
>
>>I can't create any top-level folders, only subfolders of INBOX
>>
> ...
> and then it says i have to tune my IMAP client
>
> is there a way (patch may be or some server config file) not to tune clients ?
>
> i'm trying to migrate our 90k+ user mailing system to qmail + ldap + courier
> imap and it's a pain-in-the-ass to tell all them to tune their Outlook's to
> get their folders not "inside" INBOX folder
>
> courier imap: 1.4.1
> qmailldap: qmail-ldap-1.03-20011001a
> openldap: 2.0.18
>
> PS: dont flame me. i've read the RFC2342 :)
>
> thanks in advance
>
> _______________________________________________
> courier-users mailing list
> [EMAIL PROTECTED]
> Unsubscribe: https://lists.sourceforge.net/lists/listinfo/courier-users
>
--- ./imap/imapd.c- Wed Nov 14 05:14:51 2001
+++ ./imap/imapd.c Mon Jan 7 19:57:30 2002
@@ -73,7 +73,7 @@
#include "unicode/unicode.h"
-#define SHARED "shared"
+#define SHARED "#shared"
static const char rcsid[]="$Id: imapd.c,v 1.70 2001/11/14 04:14:24 mrsam Exp $";
@@ -351,25 +351,33 @@
}
else
{
+ const char * envp = getenv("IMAP_PERSONAL_NAMESPACE_AT_TOP_LEVEL");
+ const int isTopLevelEnabled = envp && atoi(envp);
+
#if HAVE_STRNCASECMP
if (strncasecmp(arg, INBOX, sizeof(INBOX)-1))
#else
if (strnicmp(arg, INBOX, sizeof(INBOX)-1))
#endif
{
- free(p);
- return (0);
+ if (!isTopLevelEnabled)
+ {
+ free(p);
+ return (0);
+ }
}
-
- arg += sizeof(INBOX)-1;
+ else if (!isTopLevelEnabled)
+ arg += sizeof(INBOX)-1;
if (*arg == 0)
arg=maildir_folderdir(0, 0);
- else if (*arg++ != '.')
+ else if (!isTopLevelEnabled && *arg++ != '.')
{
free(p);
return (0);
}
+ else if (isTopLevelEnabled)
+ arg=maildir_folderdir(0, (*arg == '.') ? arg + 1 : arg);
else
arg=maildir_folderdir(0, arg);
}
@@ -1196,6 +1205,8 @@
while (fgets(buf, sizeof(buf), oldfp) != 0)
{
char *p=strchr(buf, '\n');
+ const char * envp = getenv("IMAP_PERSONAL_NAMESPACE_AT_TOP_LEVEL");
+ char *arg;
if (p) *p=0;
if (sub_strcmp(buf, f) == 0)
@@ -1206,7 +1217,21 @@
free(newf);
return; /* Already subscribed */
}
- fprintf(newfp, "%s\n", buf);
+ p = buf;
+#if HAVE_STRNCASECMP
+ if (!strncasecmp(buf, INBOX, sizeof(INBOX)-1))
+#else
+ if (!strnicmp(buf, INBOX, sizeof(INBOX)-1))
+#endif
+ {
+ if (envp && atoi(envp) && buf[sizeof(INBOX)] != 0)
+ {
+ p = buf + sizeof(INBOX);
+ }
+ }
+ arg = valid_mailbox_name(p,0);
+ if (arg && !access(arg, 0))
+ fprintf(newfp, "%s\n", p);
}
fclose(oldfp);
}
@@ -1234,11 +1259,27 @@
while (fgets(buf, sizeof(buf), oldfp) != 0)
{
char *p=strchr(buf, '\n');
+ const char * envp = getenv("IMAP_PERSONAL_NAMESPACE_AT_TOP_LEVEL");
+ char *arg;
if (p) *p=0;
- if (sub_strcmp(buf, f) == 0)
+ p = buf;
+#if HAVE_STRNCASECMP
+ if (!strncasecmp(buf, INBOX, sizeof(INBOX)-1))
+#else
+ if (!strnicmp(buf, INBOX, sizeof(INBOX)-1))
+#endif
+ {
+ if (envp && atoi(envp) && buf[sizeof(INBOX)] != 0)
+ {
+ p = buf + sizeof(INBOX);
+ }
+ }
+ if (sub_strcmp(p, f) == 0)
continue;
- fprintf(newfp, "%s\n", buf);
+ arg = valid_mailbox_name(p,0);
+ if (!access(arg, 0))
+ fprintf(newfp, "%s\n", p);
}
fclose(oldfp);
}
@@ -2224,10 +2272,16 @@
if (strcmp(curtoken->tokenbuf, "NAMESPACE") == 0)
{
+ const char * envp = getenv("IMAP_PERSONAL_NAMESPACE_AT_TOP_LEVEL");
+
if (nexttoken()->tokentype != IT_EOL)
return (-1);
- writes("* NAMESPACE ((\"INBOX.\" \".\")) NIL ((\""
- SHARED ".\" \".\"))\r\n");
+ if (envp && atoi(envp))
+ writes("* NAMESPACE ((\"\" \".\")) NIL ((\""
+ SHARED ".\" \".\"))\r\n");
+ else
+ writes("* NAMESPACE ((\"INBOX.\" \".\")) NIL ((\""
+ SHARED ".\" \".\"))\r\n");
writes(tag);
writes(" OK NAMESPACE completed.\r\n");
return (0);
--- ./imap/mailboxlist.c- Wed Dec 5 14:17:20 2001
+++ ./imap/mailboxlist.c Mon Dec 31 21:38:30 2001
@@ -310,10 +310,34 @@
while (fgets(buf, sizeof(buf), fp) != 0)
{
char *q=strchr(buf, '\n');
+ const char * envp = getenv("IMAP_PERSONAL_NAMESPACE_AT_TOP_LEVEL");
+ char *arg;
if (q) *q=0;
- folder_entry(buf, hier, found_hier,
- folders, hierarchies);
+ if (envp && atoi(envp))
+ {
+ q = buf;
+#if HAVE_STRNCASECMP
+ if (!strncasecmp(buf, INBOX, sizeof(INBOX)-1)
+#else
+ if (!strnicmp(buf, INBOX, sizeof(INBOX)-1)
+#endif
+ && buf[sizeof(INBOX)] != 0)
+ {
+ q = buf + sizeof(INBOX);
+ }
+ arg = valid_mailbox_name(q,0);
+ if (arg && !access(arg, 0))
+ folder_entry(q, hier, found_hier,
+ folders, hierarchies);
+ }
+ else
+ {
+ arg = valid_mailbox_name(buf,0);
+ if (arg && !access(arg, 0))
+ folder_entry(buf, hier, found_hier,
+ folders, hierarchies);
+ }
}
fclose(fp);
}
@@ -375,6 +399,7 @@
while (dirp && (de=readdir(dirp)) != 0)
{
char *p;
+ const char * envp = getenv("IMAP_PERSONAL_NAMESPACE_AT_TOP_LEVEL");
if (de->d_name[0] != '.' ||
strcmp(de->d_name, "..") == 0)
@@ -395,6 +420,9 @@
}
strcpy(p, "INBOX");
+ if (envp && atoi(envp) && strcmp(de->d_name, "."))
+ strcpy(p, de->d_name + 1);
+ else
if (strcmp(de->d_name, "."))
strcat(p, de->d_name);
@@ -572,6 +600,10 @@
static int match_mailbox(char *name, char *pattern)
{
size_t i;
+const char * envp = getenv("IMAP_PERSONAL_NAMESPACE_AT_TOP_LEVEL");
+
+ if (envp && atoi(envp))
+ return (match_recursive(name, pattern, HIERCH));
/* First component, INBOX, is case insensitive */