Subject: Namespace & Cclient

From: Ričardas Čepas <[email-masked]>
Date: Mon, 6 Mar 2000 13:17:29 +0200

Hi,

I have a perl script using Mail::Cclient and c-client lib from 4.7a wu-imapd.
I would like to be able to access different imap servers from it. Problem
is that cyrus requires user.$username. prefix for private mailboxes; wu-imapd
don't. Is there some clean way to get that parameter from server?

		Thank you,
-- 
                                      Ričardas Čepas
~~
~

---

From: Mark Crispin <[email-masked]>
Date: Mon, 6 Mar 2000 09:29:27 -0800 (PST)

> I have a perl script using Mail::Cclient and c-client lib from 4.7a
  ^^  UW, not "WU"

We are the University of Washington, not Washington University.  Since there
are several US universities with "Washington" in the name, it's important to
use the right name.

> is that cyrus requires user.$username. prefix for private mailboxes;
  ^^ UW
> don't. Is there some clean way to get that parameter from server?

Did you try getting the namespace list?  I don't know how the Perl software
would do it, but there is a c-client option to get the namespace.

---

From: Ričardas Čepas <[email-masked]>
Date: Mon, 6 Mar 2000 21:08:30 +0200

> are several US universities with "Washington" in the name, it's important to

	Sorry, I was unaware of that.
> would do it, but there is a c-client option to get the namespace.

I can get it manually:
S: * OK richard.eu.org Cyrus IMAP4 v1.6.22 server ready
S: * CAPABILITY IMAP4 IMAP4rev1 ACL QUOTA LITERAL+ NAMESPACE UIDPLUS X-NON-HIERARCHICAL-RENAME NO_ATOMIC_RENAME UNSELECT
<.........>
. namespace
* NAMESPACE (("INBOX." ".")) NIL (("" "."))
.
	But  it seems there isn't perl interface to GET_NAMESPACE (?).
Probably I'll need to hack it myself :(

		Thank you for the response.
-- 
                                      Ričardas Čepas
~~
~

---

From: Ričardas Čepas <[email-masked]>
Date: Mon, 20 Mar 2000 12:14:36 +0200

Hi !
 
 Is it possible to run GETQUOTAROOT with c-client somehow?
 
 	Thank you,
 	Richard.
-- 
                                      Ričardas Čepas
~~
~

---

From: Ričardas Čepas <[email-masked]>
Date: Mon, 3 Apr 2000 13:21:45 +0200

On Mon Mar 27 20:25:44 2000 -0800 Mark Crispin wrote:

> On Mon, 20 Mar 2000 12:14:36 +0200, =?UTF-8?B?UmnEjWFyZGFzIMSMZXBhcw==?=
> wrote:
> RFC 2087 is not implemented in c-client.
> 
> It's pretty meaningless in the UNIX environment, as it describes a quota
> system that has little in common with UNIX quotas.

	Hmm, sometimes it works on Unix. Anyway here are patches attached
in case somebody else will need that.
-- 
                                      Ričardas Čepas
~~
~
*** imap-4.7b/src/c-client/imap4r1.c.orig	Fri Oct 29 06:22:05 1999
--- imap-4.7b/src/c-client/imap4r1.c	Mon Apr  3 12:44:45 2000
***************
*** 142,147 ****
--- 142,165 ----
        imap_send (((MAILSTREAM *) value),"NAMESPACE",NIL);
      value = (void *) &((IMAPLOCAL *) ((MAILSTREAM *) value)->local)->namespace;
      break;
+   case GET_QUOTAROOT_SET_INBOX:
+     if (((IMAPLOCAL *) ((MAILSTREAM *) value)->local)->use_quota ) {
+       if (!((IMAPLOCAL *) ((MAILSTREAM *) value)->local)->quota_inbox_set) {
+         imap_send (((MAILSTREAM *) value),"GETQUOTAROOT INBOX",NIL);
+       }
+       value = (void *) ((IMAPLOCAL *) ((MAILSTREAM *) value)->local)->quota_inbox_set;
+     } else {
+       value = NIL;
+     }
+     break;
+   case GET_QUOTAROOT_USED_INBOX:
+     if (((IMAPLOCAL *) ((MAILSTREAM *) value)->local)->use_quota ) {
+       imap_send (((MAILSTREAM *) value),"GETQUOTAROOT INBOX",NIL);
+       value = (void *) ((IMAPLOCAL *) ((MAILSTREAM *) value)->local)->quota_inbox_used;
+     } else {
+       value = NIL;
+     }
+     break;
    case GET_THREADERS:
      value = (void *) ((IMAPLOCAL *) ((MAILSTREAM *) value)->local)->threader;
      break;
***************
*** 2740,2745 ****
--- 2758,2776 ----
      }
      else mm_log ("Missing namespace list",WARN);
    }
+   else if (!strcmp (reply->key,"QUOTAROOT")) {
+     /* ignore for now */
+   }
+   else if (!strcmp (reply->key,"QUOTA")) {
+     if (s = reply->text) {	/* parse GETQUOTAROOT INBOX results */
+       imap_parse_quota (stream,&s);
+       if (s && *s) {
+ 	sprintf (LOCAL->tmp,"Junk after quota data: %.80s",s);
+ 	mm_log (LOCAL->tmp,WARN);
+       }
+     }
+     else mm_log ("Missing quota data",WARN);
+   }
    else if (!strcmp (reply->key,"SORT")) {
      sortresults_t sr = (sortresults_t)
        mail_parameters (NIL,GET_SORTRESULTS,NIL);
***************
*** 2897,2902 ****
--- 2928,2934 ----
        else if (!strcmp (t,"NAMESPACE")) LOCAL->use_namespace = T;
        else if (!strcmp (t,"MAILBOX-REFERRALS")) LOCAL->use_mbx_ref = T;
        else if (!strcmp (t,"LOGIN-REFERRALS")) LOCAL->use_log_ref = T;
+       else if (!strcmp (t,"QUOTA")) LOCAL->use_quota = T;
        else if (!strcmp (t,"SCAN")) LOCAL->use_scan = T;
        else if (!strncmp (t,"SORT",4)) LOCAL->use_sort = T;
        else if (!strncmp (t,"THREAD=",7)) {
***************
*** 3071,3076 ****
--- 3103,3139 ----
      }
    }
    return ret;
+ }
+ 
+ /* Parse a quota response
+  * Accepts: current text pointer
+  * Returns: storage quota list, text pointer updated
+  */
+ 
+ void *imap_parse_quota (MAILSTREAM *stream,char **txtptr)
+ {
+   /* * QUOTA user.rchrch (STORAGE 217 250) */
+   char *t;
+   unsigned long quota_inbox_set,quota_inbox_used;
+   if (!(
+ 	(strtok(*txtptr, " ")) && 
+ 	(t=strtok(NULL, "( ")) && !strcmp(t, "STORAGE")
+ 	&& (t=strtok(NULL, "() ")) && ((quota_inbox_used=strtoul(t,&t,10)) || *t == '\0')
+ 	&& (t=strtok(NULL, "() ")) && ((quota_inbox_set =strtoul(t,&t,10)) || *t == '\0')
+ 	)) {
+     sprintf (LOCAL->tmp,"Not a quota: %.80s",*txtptr);
+     mm_log (LOCAL->tmp,WARN);
+     *txtptr = NIL;		/* stop parse now */
+   } else {
+     LOCAL->quota_inbox_used = quota_inbox_used;
+     LOCAL->quota_inbox_set = quota_inbox_set;
+     /*if (stream->debug) {
+       sprintf (LOCAL->tmp,"Parsed quota: used is %lu, set is %lu",quota_inbox_used,quota_inbox_set);
+       mm_dlog (LOCAL->tmp);
+     }*/
+     while (**txtptr) ++*txtptr;
+   }
+ 
  }
  
  /* Parse a thread node list
*** imap-4.7b/src/c-client/imap4r1.h.orig	Tue Jul 27 22:09:32 1999
--- imap-4.7b/src/c-client/imap4r1.h	Tue Mar 28 21:10:49 2000
***************
*** 76,87 ****
--- 76,90 ----
    unsigned int use_namespace :1;/* server has NAMESPACE */
    unsigned int use_mbx_ref : 1;	/* server has mailbox referrals */
    unsigned int use_log_ref : 1;	/* server has login referrals */
+   unsigned int use_quota :1;	/* server has QUOTA */
    unsigned int use_scan : 1;	/* server has SCAN */
    unsigned int use_sort : 1;	/* server has SORT */
    unsigned int use_authanon : 1;/* server has anonymous authentication */
    unsigned int uidsearch : 1;	/* UID searching */
    unsigned int byeseen : 1;	/* saw a BYE response */
    unsigned int use_auth : MAXAUTHENTICATORS;
+   unsigned long quota_inbox_used;	/* quota for INBOX */
+   unsigned long quota_inbox_set;	/* quota for INBOX */
    unsigned long sortsize;	/* sort return data size */
    unsigned long *sortdata;	/* sort return data */
    NAMESPACE **namespace;	/* namespace return data */
***************
*** 237,242 ****
--- 240,246 ----
  void imap_parse_response (MAILSTREAM *stream,char *text,long errflg,long ntfy);
  NAMESPACE *imap_parse_namespace (MAILSTREAM *stream,char **txtptr,
  				 IMAPPARSEDREPLY *reply);
+ void *imap_parse_quota (MAILSTREAM *stream,char **txtptr);
  THREADNODE *imap_parse_thread (char **txtptr);
  void imap_parse_header (MAILSTREAM *stream,ENVELOPE **env,SIZEDTEXT *hdr,
  			STRINGLIST *stl);
*** imap-4.7b/src/c-client/mail.c.orig	Tue Nov  2 01:17:26 1999
--- imap-4.7b/src/c-client/mail.c	Thu Mar 30 11:39:54 2000
***************
*** 271,276 ****
--- 271,281 ----
        (*stream->dtb->parameters) (function,stream) :
  	env_parameters (function,stream);
      break;
+   case GET_QUOTAROOT_USED_INBOX:
+   case GET_QUOTAROOT_SET_INBOX:
+     ret = (stream && stream->dtb) ?
+       (*stream->dtb->parameters) (function,stream) : 0;
+     break;
    case SET_DRIVERS:
      fatal ("SET_DRIVERS not permitted");
    case GET_DRIVERS:
*** imap-4.7b/src/c-client/mail.h.orig	Tue Nov  2 01:14:42 1999
--- imap-4.7b/src/c-client/mail.h	Tue Mar 28 19:55:18 2000
***************
*** 104,109 ****
--- 104,111 ----
  #define SET_THREADERS (long) 114
  #define GET_NAMESPACE (long) 115
  #define SET_NAMESPACE (long) 116
+ #define GET_QUOTAROOT_SET_INBOX (long) 1115
+ #define GET_QUOTAROOT_USED_INBOX (long) 1116
  #define GET_MAILPROXYCOPY (long) 117
  #define SET_MAILPROXYCOPY (long) 118
  #define GET_SERVICENAME (long) 119
*** Mail-Cclient-0.5/Cclient.xs.orig	Mon Jun  7 15:50:30 1999
--- Mail-Cclient-0.5/Cclient.xs	Thu Mar 30 15:52:02 2000
***************
*** 1183,1188 ****
--- 1183,1198 ----
  		mail_parameters(stream, SET_ANONYMOUSHOME, SvPV(sv, na));
  	    else
  		res_str = mail_parameters(stream, GET_ANONYMOUSHOME, 0);
+ 	} else if (strEQ(param, "QUOTAROOT_SET_INBOX")) {
+ 	    if (sv)
+ 		croak("can't set this parameter: %s", param);
+ 	    else
+ 		res_int = (int) mail_parameters(stream, GET_QUOTAROOT_SET_INBOX, 0);
+ 	} else if (strEQ(param, "QUOTAROOT_USED_INBOX")) {
+ 	    if (sv)
+ 		croak("can't set this parameter: %s", param);
+ 	    else
+ 		res_int = (int) mail_parameters(stream, GET_QUOTAROOT_USED_INBOX, 0);
  	} else if (strEQ(param, "OPENTIMEOUT")) {
  	    if (sv)
  		mail_parameters(stream, SET_OPENTIMEOUT, (void*)SvIV(sv));

---

From: Mark Crispin <[email-masked]>
Date: Mon, 3 Apr 2000 23:53:38 -0700 (PDT)

Hello -

Thank you for your suggestion for implementing QUOTA support in the IMAP
client code of c-client.  Unfortunately, the IMAP client code is the easy
part; as you discovered it's just a matter of babbling the right command and
getting a response.

However, what most people are concerned about is the support in the IMAP
server, which means quota support in the various local file drivers.  That's
much harder, since that involves interacting with UNIX quotas.

I do not want to implement QUOTA support that is only in the IMAP client code
and is an incomplete implementation of the QUOTA specification.

-- Mark --