[PATCH] vmailmgr 0.97 vmailmgrd "stat" command feature
Dale Woolridge <[email protected]> Sun, 11 Sep 2005 22:43:31 -0400
| Newsgroups | gmane.mail.vmailmgr |
|---|---|
| Message-ID | <[email protected]> |
--p7qwJlK53pWzbayA
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
The attached patch modifies vmailmgrd's "stat" command to support
an extra parameter, the literal string "recurse", which forces
vmailmgrd to calculate the new/seen/unseen stats for all directories
and subdirectories (excluding "tmp" dirs) of the initial basedir
(virtual users homedir) instead of just the contents of new/cur
(as without the "recurse" parameter).
--
-dale
--p7qwJlK53pWzbayA
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="vmailmgr-0.97-stat.recurse.dw.patch"
Index: daemon/dispatch.cc
===================================================================
--- daemon/dispatch.cc (revision 332)
+++ daemon/dispatch.cc (working copy)
@@ -74,7 +74,7 @@
ENTRY(adduser3, 5, -1, true),
ENTRY(autoresponse, 4, 5, true),
ENTRY(deluser, 3, 3, true),
- ENTRY(stat, 3, 3, true),
+ ENTRY(stat, 3, 4, true),
ENTRY(listdomain, 2, 2, false),
#ifdef TEST_DAEMON
ENTRY(echo, 0, -1, false), // For testing purposes only
Index: daemon/stat.cc
===================================================================
--- daemon/stat.cc (revision 332)
+++ daemon/stat.cc (working copy)
@@ -35,7 +35,9 @@
count_size unseen_new;
count_size unseen;
count_size seen;
-
+ bool recurse;
+ unsigned long depth;
+
mystring rep() const;
};
@@ -55,6 +57,7 @@
DIR* dir;
struct dirent* curr;
struct stat statbuf;
+ bool m_isdir, m_ismaildir, m_isnew, m_unseen;
public:
statdir(const mystring& dirname);
~statdir() { close(); }
@@ -65,6 +68,10 @@
const char* currname() const { return curr->d_name; }
void operator++() { advance(); }
void advance();
+ bool isdir() const { return m_isdir; }
+ bool ismaildir() const { return m_ismaildir; }
+ bool isnew() const { return m_isnew; }
+ bool unseen() const { return m_unseen; }
};
statdir::statdir(const mystring& dirname)
@@ -83,12 +90,10 @@
void statdir::advance()
{
+ bool ignore = false;
+
if(dir) {
- while((curr = readdir(dir)) != 0) {
- if(curr->d_name[0] == '.')
- continue;
- break;
- }
+ curr = readdir(dir);
}
if(!curr)
close();
@@ -96,57 +101,75 @@
mystring fullpath = path + "/" + curr->d_name;
if(stat(fullpath.c_str(), &statbuf) == -1)
close();
- }
-}
-
-bool stat_new_dir(const mystring& basename, stats& stats)
-{
- statdir dir(basename + "/new");
- if(!dir)
- return false;
- while(dir) {
- if(S_ISREG(dir->st_mode)) {
- ++stats.unseen_new.count;
- stats.unseen_new.size += dir->st_blocks * 512;
+
+ m_isdir = m_isnew = false;
+ if(S_ISDIR(statbuf.st_mode)) {
+ m_isdir = true;
+ m_isnew = !strcmp(curr->d_name, "new");
+ if(!m_isnew)
+ ignore = !strcmp(curr->d_name, ".") ||
+ !strcmp(curr->d_name, "..") ||
+ !strcmp(curr->d_name, "tmp");
+ m_ismaildir = m_isnew ||
+ (!ignore && !strcmp(curr->d_name, "cur"));
+ }
+ else if(!S_ISREG(statbuf.st_mode))
+ ignore = true;
+
+ m_unseen = true;
+ const char* colon = strchr(curr->d_name, ':');
+ if(colon) {
+ ++colon;
+ if(*colon++ == '2' && *colon++ == ',' && !strchr(colon, 'S'))
+ m_unseen = false;
}
- ++dir;
}
- return true;
+ if (ignore)
+ advance();
}
-bool stat_cur_dir(const mystring& basename, stats& stats)
+bool stat_dir(const mystring& basename, stats& stats, bool isnew = false)
{
- statdir dir(basename + "/cur");
+ statdir dir(basename);
+
if(!dir)
- return false;
+ return true;
+
while(dir) {
- if(S_ISREG(dir->st_mode)) {
- count_size* stat = &stats.unseen;
- const char* colon = strchr(dir.currname(), ':');
- if(colon) {
- ++colon;
- if(*colon++ == '2' && *colon++ == ',' && !strchr(colon, 'S'))
+ if(!dir.isdir()) {
+ count_size* stat = &stats.unseen_new;
+ if(!isnew) {
+ if (dir.unseen())
+ stat = &stats.unseen;
+ else
stat = &stats.seen;
}
++stat->count;
stat->size += dir->st_blocks * 512;
}
+ else if(stats.recurse || (stats.depth < 1 && dir.ismaildir())) {
+ stats.depth++;
+ if (!stat_dir(basename + "/" + dir.currname(), stats, dir.isnew()))
+ return false;
+ stats.depth--;
+ }
++dir;
}
return true;
}
-bool stat_dir(const mystring& basename, stats& stats)
-{
- return stat_new_dir(basename, stats) &&
- stat_cur_dir(basename, stats);
-}
CMD(stat)
- // Usage: stat baseuser-virtuser pass
+ // Usage: stat baseuser-virtuser pass [recurse]
{
mystring user = args[0];
mystring pass = args[1];
+ args[1] = LOG_PASSWORD;
+ bool recurse = 0;
+ if(args.count() == 3) {
+ recurse = (args[2] == "recurse");
+ }
+ logcommand(args);
pwentry* pw;
vpwentry* vpw;
@@ -158,6 +181,8 @@
mystring dirname = pw->home + "/" + vpw->directory;
stats stats;
+ stats.depth = 0;
+ stats.recurse = recurse;
if(!stat_dir(dirname, stats))
RETURN(err, "Failed to stat maildir");
--p7qwJlK53pWzbayA
Content-Type: text/plain; charset=us-ascii
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
--p7qwJlK53pWzbayA--