Good job on this patch David!

I noticed the same behavior, but didn't put 2 and 2 together quite as well
as you did...


On a different note, in regard to bugs, have you noticed that the
".current_size" code in vdelivermail is broken?  .current_size never reduces
as you delete mail.  It just keeps getting bigger and bigger....

I was working on a "user over quota" message when I discovered it.  Made my
code a real pain in the ass to figure out.  I kept blaming my code for some
of the things I was seeing happen.  I finally realized that even the "stock"
code was broken.

I'm working on it, but I'm not much of a C programmer..  I'm struggling
pretty hard with this stuff.  Maybe you'd be interested in taking a look at
it?  (Now that I've pointed it out, you'd probably look into it anyway.  :)

Chris Bunnell

----- Original Message -----
From: "David Wartell" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Monday, July 02, 2001 12:05 PM
Subject: patch to vpopmail.c to fix Solaris unlink() bug


> Here is a patch to fix a bug that was found in int vdelfiles( char *) in
vpopmail.c.  The problem is that vdelfiles assumes that
> calling unlink() on a directory will return an error.  This is true on
Linux but is NOT true on Solaris.  What the vdelfiles() code
> does on Solaris without this patch on Solaris is unlink the given
directory from its parent which leaves the file system corrupted
> and the disk space and inodes used even though the entry looks like it is
deleted.  The patch should make the code more portable (at
> least across Linux AND Solaris).
>
> Here is a sequence of commands which repoduce the error on a Solaris host.
The commands were run on a fresh install of vpopmail
> 4.10.24, although 4.10.26 and earlier produce the same error on Solaris.
The patch is known to patch cleanly against 4.10.24 and
> 4.10.26
>
> --------------------------testing reproducing the
error---------------------------
> Notice the link count for the domains directory.
> apollo:/var/vpopmail # ls -l -d domains
> drwx------   2 vpopmail vchkpw        512 Jun 29 14:51 domains/
>
> I add a domain and of course the link count goes up as expected because a
directory was added to domains
> apollo:/var/vpopmail # bin/vadddomain foo.com 2782y2
> apollo:/var/vpopmail # ls -l -d domains
> drwx------   3 vpopmail vchkpw        512 Jun 29 14:52 domains/
>
> I add a second domain and the link count of domain goes up again as
expected
> apollo:/var/vpopmail # bin/vadddomain foo2.com 2782y2
> apollo:/var/vpopmail # ls -l -d domains
> drwx------   4 vpopmail vchkpw        512 Jun 29 14:52 domains/
>
> Now I remove a domain and the link count of domains does NOT go down!
This means the disk space and inodes are still being used.
> apollo:/var/vpopmail # bin/vdeldomain foo2.com
> apollo:/var/vpopmail # ls -l -d domains
> drwx------   4 vpopmail vchkpw        512 Jun 29 14:52 domains/
> apollo:/var/vpopmail # ls -l domains
> total 1
> drwx------   3 vpopmail vchkpw        512 Jun 29 14:52 foo.com/
> apollo:/var/vpopmail #
>
>
> ----------------the
patch------------------------------------------------------
> diff vpopmail.c ../vpopmail-4.10.24.dist/vpopmail.c
>
> 425,434c425,448
> <       /* try to unlink the file, this will fail on directories
> <        * but it will succeed on symbolic links, because it a
> <        * file ;) this is how we erase an aliased domain from
> <        * the file system.
> <        * On success, return success
> <        */
> <     if ( unlink(dir) == 0 ) {
> <               /* return success */
> <               return(0);
> <       }
> ---
> > /* Modified By David Wartell [EMAIL PROTECTED] to work with
Solaris.
> >  * Unlike Linux, Solaris will NOT return error when unlink() is called
on a
> >  * directory.   A correct implementation to support Linux & Solaris is
to test
> >  * to see if the file is a directory.  If it is not a directory unlink()
it.
> >  * If unlink() returns an error return error.
> >  */
> >
> >     if (lstat(dir, &statbuf) == 0) {
> >         // if dir is not a directory unlink it
> >       if ( !( S_ISDIR(statbuf.st_mode) ) ) {
> >           if ( unlink(dir) == 0 ) {
> >               /* return success we deleted the file */
> >               return(0);
> >             }
> >           else {
> >                 /* error, return error to calling function, we couldn't
unlink the file */
> >                 return(-1);
> >             }
> >         }
> >
> >     } else {
> >         /* error, return error to calling function, we couldn't lstat
the file */
> >       return(-1);
> >     }
>
> -David Wartell
> ActionWeb Services
> [EMAIL PROTECTED]
>
>

Reply via email to