[patch] centesimal dirhash: alternative hashing scheme for usernames
with trailing numeric
Michael Rourke
m.rourke at unsw.edu.au
Mon May 19 19:20:25 EDT 2003
Please find attached a patch to Cyrus Imapd 2.1.12 that we use for our site.
Our usernames look like [sz]NNNNNNNN (N=[0..9]), so we want to use the
last two digits as the directory hash (99 directories "00" to "99"). The
central hashing routine has been modified to return a string (into a
caller supplied buffer) rather than a char, so future hashing extensions
will be easier.
The configure option for this is "--enable-centdirhash"
"tools/rehash centesimal" will convert basic to centesimal hashing
--
Michael Rourke, Network Services Developer, +61 2 9385 1137
Enterprise IT Infrastructure Unit, University of New South Wales
-------------- next part --------------
*** cyrus-imapd-2.1.12/config.h.in Mon Feb 3 21:31:12 2003
--- cyrus-imapd-2.1.12.patch/config.h.in Mon May 19 22:12:49 2003
***************
*** 136,141 ****
--- 136,144 ----
/* use full directory hashing? */
#undef USE_DIR_FULL
+ /* use centesimal directory hashing? */
+ #undef USE_DIR_CENTESIMAL
+
/* do we have the UCD SNMP libraries? */
#undef HAVE_UCDSNMP
*** cyrus-imapd-2.1.12/configure Mon Feb 3 21:31:13 2003
--- cyrus-imapd-2.1.12.patch/configure Mon May 19 22:12:49 2003
***************
*** 5512,5517 ****
--- 5512,5529 ----
fi
+ # Check whether --enable-centdirhash or --disable-centdirhash was given.
+ if test "${enable_centdirhash+set}" = set; then
+ enableval="$enable_centdirhash"
+ if test "$enableval" = yes; then
+ cat >> confdefs.h <<\EOF
+ #define USE_DIR_CENTESIMAL 1
+ EOF
+
+ fi
+ fi
+
+
echo $ac_n "checking to use old sieve service name""... $ac_c" 1>&6
echo "configure:5517: checking to use old sieve service name" >&5
# Check whether --enable-oldsievename or --disable-oldsievename was given.
*** cyrus-imapd-2.1.12/configure.in Tue Jan 28 20:49:42 2003
--- cyrus-imapd-2.1.12.patch/configure.in Mon May 19 22:12:49 2003
***************
*** 825,830 ****
--- 825,837 ----
AC_DEFINE(USE_DIR_FULL)
fi)
+ AC_ARG_ENABLE(centdirhash,
+ [ --enable-centdirhash enable centesimal directory hashing -- last two
+ digits of numeric username],
+ if test "$enableval" = yes; then
+ AC_DEFINE(USE_DIR_CENTESIMAL)
+ fi)
+
AC_MSG_CHECKING(to use old sieve service name)
AC_ARG_ENABLE(oldsievename,
[ --enable-oldsievename enable the use of 'imap' as the sieve service name],
*** cyrus-imapd-2.1.12/imap/lmtpd.c Thu Nov 28 17:47:15 2002
--- cyrus-imapd-2.1.12.patch/imap/lmtpd.c Mon May 19 22:12:49 2003
***************
*** 1078,1088 ****
/* check ~USERNAME/.sieve */
snprintf(buf, sizeof(buf), "%s/%s", pent->pw_dir, ".sieve");
} else { /* look in sieve_dir */
! char hash;
! hash = (char) dir_hash_c(user);
! snprintf(buf, sizeof(buf), "%s/%c/%s/default", sieve_dir, hash, user);
}
return (fopen(buf, "r"));
--- 1078,1088 ----
/* check ~USERNAME/.sieve */
snprintf(buf, sizeof(buf), "%s/%s", pent->pw_dir, ".sieve");
} else { /* look in sieve_dir */
! char * hash, hb[DIR_HASHBUF_SIZE];
! hash = dir_hash_s(hb, user);
! snprintf(buf, sizeof(buf), "%s/%s/%s/default", sieve_dir, hash, user);
}
return (fopen(buf, "r"));
*** cyrus-imapd-2.1.12/imap/mailbox.c Wed Jan 8 17:40:17 2003
--- cyrus-imapd-2.1.12.patch/imap/mailbox.c Mon May 19 22:12:49 2003
***************
*** 2628,2634 ****
const char *name)
{
const char *idx;
! char c, *p;
if (config_hashimapspool) {
idx = strchr(name, '.');
--- 2628,2634 ----
const char *name)
{
const char *idx;
! char *s, *p, hb[DIR_HASHBUF_SIZE];
if (config_hashimapspool) {
idx = strchr(name, '.');
***************
*** 2637,2645 ****
} else {
idx++;
}
! c = (char) dir_hash_c(idx);
! sprintf(buf, "%s/%c/%s", root, c, name);
} else {
/* standard mailbox placement */
sprintf(buf, "%s/%s", root, name);
--- 2637,2645 ----
} else {
idx++;
}
! s = dir_hash_s(hb, idx);
! sprintf(buf, "%s/%s/%s", root, s, name);
} else {
/* standard mailbox placement */
sprintf(buf, "%s/%s", root, name);
***************
*** 2655,2661 ****
our human time is worth more than efficiency */
void mailbox_hash_quota(char *buf, unsigned size, const char *qr) {
const char *idx;
! char c;
idx = strchr(qr, '.'); /* skip past user. */
if (idx == NULL) {
--- 2655,2661 ----
our human time is worth more than efficiency */
void mailbox_hash_quota(char *buf, unsigned size, const char *qr) {
const char *idx;
! char *s, hb[DIR_HASHBUF_SIZE];
idx = strchr(qr, '.'); /* skip past user. */
if (idx == NULL) {
***************
*** 2663,2671 ****
} else {
idx++;
}
! c = (char) dir_hash_c(idx);
! if(snprintf(buf, size, "%s%s%c/%s", config_dir, FNAME_QUOTADIR, c, qr)
>= size) {
fatal("insufficient buffer size in mailbox_hash_quota",EC_TEMPFAIL);
}
--- 2663,2671 ----
} else {
idx++;
}
! s = dir_hash_s(hb, idx);
! if(snprintf(buf, size, "%s%s%s/%s", config_dir, FNAME_QUOTADIR, s, qr)
>= size) {
fatal("insufficient buffer size in mailbox_hash_quota",EC_TEMPFAIL);
}
*** cyrus-imapd-2.1.12/imap/mbdump.c Wed Jan 8 17:40:17 2003
--- cyrus-imapd-2.1.12.patch/imap/mbdump.c Mon May 19 22:12:49 2003
***************
*** 374,387 ****
* (it makes almost no sense in the conext of a murder) */
/* xxx will need to be update for bytecode */
if(!sieve_usehomedir) {
! char ext_fname[2048];
if(mbdir) closedir(mbdir);
mbdir = NULL;
! snprintf(sieve_path, sizeof(sieve_path), "%s/%c/%s",
config_getstring("sievedir", "/usr/sieve"),
! (char) dir_hash_c(userid), userid);
mbdir=opendir(sieve_path);
if(mbdir) {
--- 374,387 ----
* (it makes almost no sense in the conext of a murder) */
/* xxx will need to be update for bytecode */
if(!sieve_usehomedir) {
! char ext_fname[2048], hb[DIR_HASHBUF_SIZE];
if(mbdir) closedir(mbdir);
mbdir = NULL;
! snprintf(sieve_path, sizeof(sieve_path), "%s/%s/%s",
config_getstring("sievedir", "/usr/sieve"),
! dir_hash_s(hb, userid), userid);
mbdir=opendir(sieve_path);
if(mbdir) {
***************
*** 464,470 ****
int curfile = -1;
const char *userid = NULL;
struct mailbox mb;
! char sieve_path[2048];
int sieve_usehomedir = config_getswitch("sieveusehomedir", 0);
memset(&file, 0, sizeof(struct buf));
--- 464,470 ----
int curfile = -1;
const char *userid = NULL;
struct mailbox mb;
! char sieve_path[2048], hb[DIR_HASHBUF_SIZE];
int sieve_usehomedir = config_getswitch("sieveusehomedir", 0);
memset(&file, 0, sizeof(struct buf));
***************
*** 476,484 ****
userid = mbname+5;
if(!sieve_usehomedir)
! snprintf(sieve_path, sizeof(sieve_path), "%s/%c/%s",
config_getstring("sievedir", "/usr/sieve"),
! (char) dir_hash_c(userid), userid);
}
/* we better be in a list now */
--- 476,484 ----
userid = mbname+5;
if(!sieve_usehomedir)
! snprintf(sieve_path, sizeof(sieve_path), "%s/%s/%s",
config_getstring("sievedir", "/usr/sieve"),
! dir_hash_s(hb, userid), userid);
}
/* we better be in a list now */
*** cyrus-imapd-2.1.12/imap/mboxlist.c Wed Jan 8 17:40:17 2003
--- cyrus-imapd-2.1.12.patch/imap/mboxlist.c Mon May 19 22:12:49 2003
***************
*** 2318,2328 ****
char *mboxlist_hash_usersubs(const char *userid)
{
char *fname = xmalloc(strlen(config_dir) + sizeof(FNAME_USERDIR) +
! strlen(userid) + sizeof(FNAME_SUBSSUFFIX) + 10);
! char c;
! c = (char) dir_hash_c(userid);
! sprintf(fname, "%s%s%c/%s%s", config_dir, FNAME_USERDIR, c, userid,
FNAME_SUBSSUFFIX);
return fname;
--- 2318,2328 ----
char *mboxlist_hash_usersubs(const char *userid)
{
char *fname = xmalloc(strlen(config_dir) + sizeof(FNAME_USERDIR) +
! strlen(userid) + sizeof(FNAME_SUBSSUFFIX) + 11);
! char *s, hb[DIR_HASHBUF_SIZE];
! s = dir_hash_s(hb, userid);
! sprintf(fname, "%s%s%s/%s%s", config_dir, FNAME_USERDIR, s, userid,
FNAME_SUBSSUFFIX);
return fname;
*** cyrus-imapd-2.1.12/imap/seen_db.c Tue Aug 13 16:46:33 2002
--- cyrus-imapd-2.1.12.patch/imap/seen_db.c Mon May 19 22:14:10 2003
***************
*** 105,115 ****
char *seen_getpath(const char *userid)
{
char *fname = xmalloc(strlen(config_dir) + sizeof(FNAME_USERDIR) +
! strlen(userid) + sizeof(FNAME_SEENSUFFIX) + 10);
! char c;
! c = (char) dir_hash_c(userid);
! sprintf(fname, "%s%s%c/%s%s", config_dir, FNAME_USERDIR, c, userid,
FNAME_SEENSUFFIX);
return fname;
--- 105,115 ----
char *seen_getpath(const char *userid)
{
char *fname = xmalloc(strlen(config_dir) + sizeof(FNAME_USERDIR) +
! strlen(userid) + sizeof(FNAME_SEENSUFFIX) + 11);
! char *s, hb[DIR_HASHBUF_SIZE];
! s = dir_hash_s(hb, userid);
! sprintf(fname, "%s%s%s/%s%s", config_dir, FNAME_USERDIR, s, userid,
FNAME_SEENSUFFIX);
return fname;
*** cyrus-imapd-2.1.12/imap/user.c Fri Dec 20 15:58:34 2002
--- cyrus-imapd-2.1.12.patch/imap/user.c Mon May 19 22:14:10 2003
***************
*** 115,121 ****
int user_deletesieve(char *user)
{
! char sieve_path[2048];
char filename[2048];
DIR *mbdir;
struct dirent *next = NULL;
--- 115,121 ----
int user_deletesieve(char *user)
{
! char sieve_path[2048], hb[DIR_HASHBUF_SIZE];
char filename[2048];
DIR *mbdir;
struct dirent *next = NULL;
***************
*** 123,131 ****
/* oh well */
if(config_getswitch("sieveusehomedir", 0)) return 0;
! snprintf(sieve_path, sizeof(sieve_path), "%s/%c/%s",
config_getstring("sievedir", "/usr/sieve"),
! dir_hash_c(user), user);
mbdir=opendir(sieve_path);
if(mbdir) {
--- 123,131 ----
/* oh well */
if(config_getswitch("sieveusehomedir", 0)) return 0;
! snprintf(sieve_path, sizeof(sieve_path), "%s/%s/%s",
config_getstring("sievedir", "/usr/sieve"),
! dir_hash_s(hb, user), user);
mbdir=opendir(sieve_path);
if(mbdir) {
***************
*** 276,288 ****
#endif
int user_deletequotas(const char *user)
{
! char c, qpath[MAX_MAILBOX_NAME], *tail;
DIR *dirp;
struct dirent *f;
/* this violates the quota abstraction layer; oh well */
! c = dir_hash_c(user);
! snprintf(qpath, sizeof(qpath), "%s%s%c/", config_dir, FNAME_QUOTADIR, c);
tail = qpath + strlen(qpath);
dirp = opendir(qpath);
--- 276,288 ----
#endif
int user_deletequotas(const char *user)
{
! char *s, qpath[MAX_MAILBOX_NAME], *tail, hb[DIR_HASHBUF_SIZE];
DIR *dirp;
struct dirent *f;
/* this violates the quota abstraction layer; oh well */
! s = dir_hash_s(hb, user);
! snprintf(qpath, sizeof(qpath), "%s%s%s/", config_dir, FNAME_QUOTADIR, s);
tail = qpath + strlen(qpath);
dirp = opendir(qpath);
*** cyrus-imapd-2.1.12/lib/util.c Tue Sep 25 19:35:27 2001
--- cyrus-imapd-2.1.12.patch/lib/util.c Mon May 19 22:14:10 2003
***************
*** 230,243 ****
return (cmp ? NULL : kv + mid);
}
! /* Examine the name of a file, and return a single character
! * (as an int) that can be used as the name of a hash
* directory. Stop before the first dot. Caller is responsible
! * for skipping any prefix of the name.
*/
! int dir_hash_c(const char *name)
{
! int c;
#ifdef USE_DIR_FULL
unsigned char *pt;
unsigned int n;
--- 230,267 ----
return (cmp ? NULL : kv + mid);
}
! /* Examine the name of a file, and return a string
! * that can be used as the name of a hash
* directory. Stop before the first dot. Caller is responsible
! * for skipping any prefix of the name, and providing buffer
! * DIR_HASHBUF_SIZE.
*/
! char * dir_hash_s(char *buf, const char *name)
{
! char *cp = buf;
! #ifdef USE_DIR_CENTESIMAL
! unsigned char *pt;
! unsigned int n;
!
! n = 0;
! pt = (unsigned char *)name;
! while (*pt && *pt != '.') {
! ++pt;
! ++n;
! }
! /*
! * if the username ends in two decimal digits
! * return those digits - otherwise "00"
! */
! if (n < 3 || !isdigit(pt[-1]) || !isdigit(pt[-2])) {
! *cp++ = '0';
! *cp++ = '0';
! }
! else {
! *cp++ = pt[-2];
! *cp++ = pt[-1];
! }
! #else
#ifdef USE_DIR_FULL
unsigned char *pt;
unsigned int n;
***************
*** 248,257 ****
n = ((n << DIR_X) ^ (n >> DIR_Y)) ^ *pt;
++pt;
}
! c = DIR_A + (n % DIR_P);
#else
! c = tolower(*name);
! if (!isascii(c) || !islower(c)) c = 'q';
#endif
! return c;
}
--- 272,284 ----
n = ((n << DIR_X) ^ (n >> DIR_Y)) ^ *pt;
++pt;
}
! *cp++ = DIR_A + (n % DIR_P);
#else
! *cp = tolower(*name);
! if (!isascii(*cp) || !islower(*cp)) *cp = 'q';
! cp++;
#endif
! #endif
! *cp++ = '\0';
! return buf;
}
*** cyrus-imapd-2.1.12/lib/util.h Mon Aug 13 16:36:56 2001
--- cyrus-imapd-2.1.12.patch/lib/util.h Mon May 19 22:14:10 2003
***************
*** 93,103 ****
};
#endif
! /* Examine the name of a file, and return a single character
! * (as an int) that can be used as the name of a hash
* directory. Caller is responsible for skipping any prefix
! * of the name.
*/
! extern int dir_hash_c(const char *name);
#endif /* INCLUDED_UTIL_H */
--- 93,105 ----
};
#endif
! #define DIR_HASHBUF_SIZE 3
!
! /* Examine the name of a file, and return a string
! * that can be used as the name of a hash
* directory. Caller is responsible for skipping any prefix
! * of the name, and providing buffer DIR_HASHBUF_SIZE.
*/
! extern char * dir_hash_s(char *buf, const char *name);
#endif /* INCLUDED_UTIL_H */
*** cyrus-imapd-2.1.12/timsieved/actions.c Fri Oct 18 20:18:01 2002
--- cyrus-imapd-2.1.12.patch/timsieved/actions.c Mon May 19 22:14:10 2003
***************
*** 97,111 ****
int actions_setuser(const char *userid)
{
! char hash;
char *foo=sieve_dir;
int result;
sieve_dir=(char *) xmalloc(1024);
! hash = (char) dir_hash_c(userid);
! snprintf(sieve_dir, 1023, "%s/%c/%s", foo, hash,userid);
result = chdir(sieve_dir);
if (result != 0) {
--- 97,111 ----
int actions_setuser(const char *userid)
{
! char *hash, hb[DIR_HASHBUF_SIZE];
char *foo=sieve_dir;
int result;
sieve_dir=(char *) xmalloc(1024);
! hash = dir_hash_s(hb, userid);
! snprintf(sieve_dir, 1023, "%s/%s/%s", foo, hash,userid);
result = chdir(sieve_dir);
if (result != 0) {
*** cyrus-imapd-2.1.12/tools/rehash Fri Aug 23 21:10:43 2002
--- cyrus-imapd-2.1.12.patch/tools/rehash Mon May 19 22:14:10 2003
***************
*** 77,83 ****
shift @ARGV;
}
if ("-h" eq $ARGV[0] || @ARGV < 1) {
! print "usage: rehash [-i] [-f] none|basic|full [imapd.conf]\n";
print " -i interactive\n";
print " -f keep going on errors\n";
exit;
--- 77,83 ----
shift @ARGV;
}
if ("-h" eq $ARGV[0] || @ARGV < 1) {
! print "usage: rehash [-i] [-f] none|basic|full|centesimal [imapd.conf]\n";
print " -i interactive\n";
print " -f keep going on errors\n";
exit;
***************
*** 85,92 ****
$tonone = 1 if ("none" eq $ARGV[0]);
$tobasic = 1 if ("basic" eq $ARGV[0]);
$tofull = 1 if ("full" eq $ARGV[0]);
! unless ($tonone || $tobasic || $tofull) {
! print "rehash: one of none/basic/full required\n";
exit;
}
shift @ARGV;
--- 85,93 ----
$tonone = 1 if ("none" eq $ARGV[0]);
$tobasic = 1 if ("basic" eq $ARGV[0]);
$tofull = 1 if ("full" eq $ARGV[0]);
! $tocentesimal = 1 if ("centesimal" eq $ARGV[0]);
! unless ($tonone || $tobasic || $tofull || $tocentesimal) {
! print "rehash: one of none/basic/full/centesimal required\n";
exit;
}
shift @ARGV;
***************
*** 93,107 ****
@bdirs = ("a".."z");
@fdirs = ("A".."W");
! $dirs = [@bdirs, at fdirs] if $tonone;
! if ($tobasic) {
$dirs = \@bdirs;
$old = \@fdirs;
}
! if ($tofull) {
$dirs = \@fdirs;
$old = \@bdirs;
}
sub ouch {
my $msg = shift;
--- 94,115 ----
@bdirs = ("a".."z");
@fdirs = ("A".."W");
! for ($i = 0; $i < 100; $i++) {
! push @cdirs, sprintf("%02d", $i)
! }
! $dirs = [@bdirs, at fdirs, at cdirs] if $tonone;
! if ($tobasic) { # full => basic
$dirs = \@bdirs;
$old = \@fdirs;
}
! if ($tofull) { # basic => full
$dirs = \@fdirs;
$old = \@bdirs;
}
+ if ($tocentesimal) { # basic => centesimal
+ $dirs = \@cdirs;
+ $old = \@bdirs;
+ }
sub ouch {
my $msg = shift;
***************
*** 113,123 ****
}
}
! 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);
--- 121,135 ----
}
}
! sub dir_hash_s {
my $name = shift;
my ($h, $n);
! if ($tocentesimal) {
! return $1 if $name =~ /([0-9][0-9])$/;
! return "00";
! }
! elsif ($tofull) {
$n = 0;
foreach my $b (split(/ */, $name)) {
$n = (($n << 3) ^ ($n >> 5)) ^ ord($b);
***************
*** 212,218 ****
if ($s =~ /^\./s) { next; }
# hash on name before '.sub' suffix
if ($s =~ /^(.+)\./) {
! $h = dir_hash_c($1);
rename("$i/$s", "$h/$s") or ouch "couldn't move $s back!";
}
}
--- 224,230 ----
if ($s =~ /^\./s) { next; }
# hash on name before '.sub' suffix
if ($s =~ /^(.+)\./) {
! $h = dir_hash_s($1);
rename("$i/$s", "$h/$s") or ouch "couldn't move $s back!";
}
}
***************
*** 226,232 ****
# hash on name before '.sub' suffix
if ($f =~ /^(.+)\./) {
print "$f\n";
! $h = dir_hash_c($1);
rename ($f, "$h/$f") or ouch "couldn't move $f into $h";
}
}
--- 238,244 ----
# hash on name before '.sub' suffix
if ($f =~ /^(.+)\./) {
print "$f\n";
! $h = dir_hash_s($1);
rename ($f, "$h/$f") or ouch "couldn't move $f into $h";
}
}
***************
*** 269,275 ****
while ($s = readdir SUB) {
# hash on name after 'user.'
if ($s =~ /^.+\.(.+)$/) {
! $h = dir_hash_c($1);
rename("$i/$s", ".$h/$s")
or ouch "couldn't move $s back!";
}
--- 281,287 ----
while ($s = readdir SUB) {
# hash on name after 'user.'
if ($s =~ /^.+\.(.+)$/) {
! $h = dir_hash_s($1);
rename("$i/$s", ".$h/$s")
or ouch "couldn't move $s back!";
}
***************
*** 284,290 ****
# hash on name after 'user.'
if ($mbox =~ /^.*\.(.*)$/) {
! $h = dir_hash_c($1);
rename($mbox, ".$h/$mbox")
or ouch "couldn't move $mbox into $h";
next;
--- 296,302 ----
# hash on name after 'user.'
if ($mbox =~ /^.*\.(.*)$/) {
! $h = dir_hash_s($1);
rename($mbox, ".$h/$mbox")
or ouch "couldn't move $mbox into $h";
next;
***************
*** 291,297 ****
}
# we should try to hash the entire file
! $h = dir_hash_c($mbox);
rename($mbox, ".$h/$mbox")
or ouch "couldn't move $mbox into $h";
next;
--- 303,309 ----
}
# we should try to hash the entire file
! $h = dir_hash_s($mbox);
rename($mbox, ".$h/$mbox")
or ouch "couldn't move $mbox into $h";
next;
***************
*** 332,338 ****
if (opendir SUB, $i) {
while ($s = readdir SUB) {
unless ($s =~ /^\./) {
! $h = dir_hash_c($s);
rename("$i/$s", ".$h/$s")
or ouch "couldn't move $s back!";
}
--- 344,350 ----
if (opendir SUB, $i) {
while ($s = readdir SUB) {
unless ($s =~ /^\./) {
! $h = dir_hash_s($s);
rename("$i/$s", ".$h/$s")
or ouch "couldn't move $s back!";
}
***************
*** 409,415 ****
if ($sub =~ /(.*)\.(.*)/) { $ismbox = 1; next; }
print "/$sub ";
! $h = dir_hash_c($sub);
mkdir (".$h/$dir", 0755); # might already be there
rename("$i/$dir/$sub", ".$h/$dir/$sub") or
ouch "couldn't move $dir/$sub into $h";
--- 421,427 ----
if ($sub =~ /(.*)\.(.*)/) { $ismbox = 1; next; }
print "/$sub ";
! $h = dir_hash_s($sub);
mkdir (".$h/$dir", 0755); # might already be there
rename("$i/$dir/$sub", ".$h/$dir/$sub") or
ouch "couldn't move $dir/$sub into $h";
***************
*** 417,423 ****
closedir DIR;
# if $ismbox is set, then $dir is a mailbox of it's own right
if ($ismbox) {
! $h = dir_hash_c($dir);
mkdir (".$h/$dir", 0755); # might already be there
opendir DIR, "$i/$dir";
while ($sub = readdir DIR) {
--- 429,435 ----
closedir DIR;
# if $ismbox is set, then $dir is a mailbox of it's own right
if ($ismbox) {
! $h = dir_hash_s($dir);
mkdir (".$h/$dir", 0755); # might already be there
opendir DIR, "$i/$dir";
while ($sub = readdir DIR) {
***************
*** 450,456 ****
# this isn't a child
if ($sub =~ /(.*)\.(.*)/) { $ismbox = 1; next; }
! $h = dir_hash_c($sub);
mkdir (".$h/$dir", 0755); # might already be there
rename("$dir/$sub", ".$h/$dir/$sub") or
ouch "couldn't move $dir/$sub into $h";
--- 462,468 ----
# this isn't a child
if ($sub =~ /(.*)\.(.*)/) { $ismbox = 1; next; }
! $h = dir_hash_s($sub);
mkdir (".$h/$dir", 0755); # might already be there
rename("$dir/$sub", ".$h/$dir/$sub") or
ouch "couldn't move $dir/$sub into $h";
***************
*** 458,464 ****
closedir DIR;
# if $ismbox is set, then $dir is a mailbox of it's own right
if ($ismbox) {
! $h = dir_hash_c($dir);
mkdir (".$h/$dir", 0755); # might already be there
opendir DIR, $dir;
while ($sub = readdir DIR) {
--- 470,476 ----
closedir DIR;
# if $ismbox is set, then $dir is a mailbox of it's own right
if ($ismbox) {
! $h = dir_hash_s($dir);
mkdir (".$h/$dir", 0755); # might already be there
opendir DIR, $dir;
while ($sub = readdir DIR) {
More information about the Info-cyrus
mailing list