setquota problem

Paul Bossi paulbossi at hotmail.com
Sat Mar 8 13:10:01 EST 2003


Here's the problem, any attempt to SETQUOTA on a mailbox
in a domain with first character of a digit, e.g.
"4demo.com", fails:

    Mar  8 00:41:14 linux imap[20406]: IOERROR: creating quota
    file /var/imap/domain/q/4demo.com/quota/s/user.someuser.NEW:
    No such file or directory

dir_hash_c is the cyrus imapd function that computes the
"q" location in that path named above:

    /var/imap/domain/q/4demo.com/quota/s/user.someuser.NEW

This path *always* FAILS when using mkimap tools to
create the directories as is recommended:

    mkimap -d 4demo.com

The mkimap utility in tools directory does a simple
"substr($domain, 0, 1) instead of this hash algorithm
involving special treatment of q.

One of these is clearly wrong.

Here's the perl function from the mkimap utility that
decides (incorrectly as far as I can tell) to use "4"
instead of "q" in this situation:

   sub mkdomain {
       my $domain = shift;
       my $hash = shift;

       mkdir "domain", 0755;
       chdir "domain";
       if ($hash) {
       mkdir substr($domain, 0, 1), 0755;
       chdir substr($domain, 0, 1);
       }
       mkdir "$domain", 0755;
       chdir $domain;
   }

The tools/rehash perl script already has a perl equivalent
dir_hash_c, whose relevant portion here is:

    # plb: i added next two lines, this needs to be fleshed
    # out more in mkimap, i don't know what functionality
    # the basic/full is referring to, but it seems to be in
    # the C version as well (via ifdefs), so should be here
    # too, I'd guess.
    $tofull = 0;      # HACK
    $tobasic = 1;     # HACK, force use of rehash's tobasic code.
    sub dir_hash_c {
        my $name = shift;
        my ($h, $n);

        if ($tofull) {
        $n = 0;
        foreach my $b (split(/ */, $name)) {
            $n = (($n << 3) ^ ($n >> 5)) ^ ord($b);
        }
        $h = chr(ord('A') + ($n % 23));
        return $h;
        }
        elsif ($tobasic) {
        $h = lc(substr($name, 0, 1));
        if (!($h =~ /[a-z]/)) { $h = 'q'; }
        return $h;
        }
    }

So the mkdomain function could be changed as follows to
fix the problem, simply using the above function instead
of the first char via substr:

   sub mkdomain {
       my $domain = shift;
       my $hash = shift;

       mkdir "domain", 0755;
       chdir "domain";
       if ($hash) {
       mkdir dir_hash_c($domain), 0755;
       chdir dir_hash_c($domain);
       }
       mkdir "$domain", 0755;
       chdir $domain;
   }

But as I said above, the only thing missing in this fix is
handling of the basic/full stuff.

Comments?  Should I post this to the devel list?


_________________________________________________________________
STOP MORE SPAM with the new MSN 8 and get 2 months FREE*  
http://join.msn.com/?page=features/junkmail





More information about the Info-cyrus mailing list