Note to readers: After you apply this patch, your queue will no longer
be readable in its current state. So, either install this into
/var/qmail2 and run both qmails until the queue is emptied on the old
one, or else accept that your current queue will have to be destroyed
and ``rm -rf /var/qmail/queue; make setup''.
From: Bruce Guenter
To: Russell Nelson
Subject: Missing piece of your big-todo patch
Date: Tue, 3 Aug 1999 08:12:11 -0600
Greetings.
While testing the performance of a big todo directory, I observed that
qmail-qstat miscounted the number of messages in the todo directory.
I've appended the necessary patch to yours.
--
Bruce Guenter http://em.ca/~bruceg/
diff -u orig/qmail-clean.c ./qmail-clean.c
--- orig/qmail-clean.c Tue Apr 15 01:05:23 1997
+++ ./qmail-clean.c Thu Jul 10 16:20:33 1997
@@ -73,22 +73,26 @@
if (line.len < 7) { respond("x"); continue; }
if (line.len > 100) { respond("x"); continue; }
if (line.s[line.len - 1]) { respond("x"); continue; } /* impossible */
- for (i = 5;i < line.len - 1;++i)
+ for (i = line.len - 2;i > 4;--i)
+ {
+ if (line.s[i] == '/') break;
if ((unsigned char) (line.s[i] - '0') > 9)
{ respond("x"); continue; }
- if (!scan_ulong(line.s + 5,&id)) { respond("x"); continue; }
+ }
+ if (line.s[i] == '/')
+ if (!scan_ulong(line.s + i + 1,&id)) { respond("x"); continue; }
if (byte_equal(line.s,5,"foop/"))
{
#define U(prefix,flag) fmtqfn(fnbuf,prefix,id,flag); \
if (unlink(fnbuf) == -1) if (errno != error_noent) { respond("!"); continue; }
- U("intd/",0)
+ U("intd/",1)
U("mess/",1)
respond("+");
}
else if (byte_equal(line.s,4,"todo/"))
{
- U("intd/",0)
- U("todo/",0)
+ U("intd/",1)
+ U("todo/",1)
respond("+");
}
else
diff -u orig/hier.c ./hier.c
--- orig/hier.c Tue Apr 15 01:05:23 1997
+++ ./hier.c Tue Jul 8 13:40:50 1997
@@ -100,6 +100,8 @@
substdio_puts(subfdout,"622:/queue/lock/:trigger:\n");
dsplit("queue/mess",auto_uidq,0750);
+ dsplit("queue/todo",auto_uidq,0750);
+ dsplit("queue/intd",auto_uidq,0700);
dsplit("queue/info",auto_uids,0700);
dsplit("queue/local",auto_uids,0700);
dsplit("queue/remote",auto_uids,0700);
diff -u orig/qmail-queue.c ./qmail-queue.c
--- orig/qmail-queue.c Tue Apr 15 01:05:23 1997
+++ ./qmail-queue.c Tue Jul 8 13:33:17 1997
@@ -180,8 +180,8 @@
messnum = pidst.st_ino;
messfn = fnnum("mess/",1);
- todofn = fnnum("todo/",0);
- intdfn = fnnum("intd/",0);
+ todofn = fnnum("todo/",1);
+ intdfn = fnnum("intd/",1);
if (link(pidfn,messfn) == -1) die(105);
if (unlink(pidfn) == -1) die(105);
diff -u orig/qmail-send.c ./qmail-send.c
--- orig/qmail-send.c Tue Apr 15 01:05:23 1997
+++ ./qmail-send.c Wed Jul 9 02:04:09 1997
@@ -101,7 +101,7 @@
}
void fnmake_info(id) unsigned long id; { fn.len = fmtqfn(fn.s,"info/",id,1); }
-void fnmake_todo(id) unsigned long id; { fn.len = fmtqfn(fn.s,"todo/",id,0); }
+void fnmake_todo(id) unsigned long id; { fn.len = fmtqfn(fn.s,"todo/",id,1); }
void fnmake_mess(id) unsigned long id; { fn.len = fmtqfn(fn.s,"mess/",id,1); }
void fnmake_foop(id) unsigned long id; { fn.len = fmtqfn(fn.s,"foop/",id,0); }
void fnmake_split(id) unsigned long id; { fn.len = fmtqfn(fn.s,"",id,1); }
@@ -1242,7 +1242,8 @@
/* this file is too long ---------------------------------------------- TODO */
datetime_sec nexttodorun;
-DIR *tododir; /* if 0, have to opendir again */
+int flagtododir = 0; /* if 0, have to readsubdir_init again */
+readsubdir todosubdir;
stralloc todoline = {0};
char todobuf[SUBSTDIO_INSIZE];
char todobufinfo[512];
@@ -1250,7 +1251,7 @@
void todo_init()
{
- tododir = 0;
+ flagtododir = 0;
nexttodorun = now();
trigger_set();
}
@@ -1262,7 +1263,7 @@
{
if (flagexitasap) return;
trigger_selprep(nfds,rfds);
- if (tododir) *wakeup = 0;
+ if (flagtododir) *wakeup = 0;
if (*wakeup > nexttodorun) *wakeup = nexttodorun;
}
@@ -1279,8 +1280,7 @@
char ch;
int match;
unsigned long id;
- unsigned int len;
- direntry *d;
+ int z;
int c;
unsigned long uid;
unsigned long pid;
@@ -1291,32 +1291,26 @@
if (flagexitasap) return;
- if (!tododir)
+ if (!flagtododir)
{
if (!trigger_pulled(rfds))
if (recent < nexttodorun)
return;
trigger_set();
- tododir = opendir("todo");
- if (!tododir)
- {
- pausedir("todo");
- return;
- }
+ readsubdir_init(&todosubdir, "todo", pausedir);
+ flagtododir = 1;
nexttodorun = recent + SLEEP_TODO;
}
- d = readdir(tododir);
- if (!d)
+ switch(readsubdir_next(&todosubdir, &id))
{
- closedir(tododir);
- tododir = 0;
- return;
+ case 1:
+ break;
+ case 0:
+ flagtododir = 0;
+ default:
+ return;
}
- if (str_equal(d->d_name,".")) return;
- if (str_equal(d->d_name,"..")) return;
- len = scan_ulong(d->d_name,&id);
- if (!len || d->d_name[len]) return;
fnmake_todo(id);
--- qmail-1.03/qmail-qstat.sh.orig Tue Aug 3 08:06:47 1999
+++ qmail-1.03/qmail-qstat.sh Tue Aug 3 08:06:38 1999
@@ -3,7 +3,7 @@
cd /var/qmail
messdirs=`echo queue/mess/* | wc -w`
messfiles=`find queue/mess/* -print | wc -w`
-tododirs=`echo queue/todo | wc -w`
-todofiles=`find queue/todo -print | wc -w`
+tododirs=`echo queue/todo/* | wc -w`
+todofiles=`find queue/todo/* -print | wc -w`
echo messages in queue: `expr $messfiles - $messdirs`
echo messages in queue but not yet preprocessed: `expr $todofiles - $tododirs`