<GUILT TRIP> I should probably mention the whole fact about ECamp
(www.ecamp.net/www.myecamp.com) paying my time and all that stuff <shrug>
ok </GUILT TRIP>

Take it easy fellahs,

Eric

On Fri, 18 Aug 2000, Eric Peters wrote:

> I havn't tested this much any feedback would be good but after adding
> 100,000 uers and corrupting god knows how many .dir_control files it had
> to be done : )
> 
> Eric
> 
> 
> diff -rcN vpopmail-4.8.9.orig/bigdir.c vpopmail-4.8.9/bigdir.c
> *** vpopmail-4.8.9.orig/bigdir.c      Wed Jun  7 21:00:59 2000
> --- vpopmail-4.8.9/bigdir.c   Fri Aug 18 07:32:33 2000
> ***************
> *** 25,31 ****
> --- 25,34 ----
>   #include <fcntl.h>
>   #include <unistd.h>
>   #include <string.h>
> + #include <errno.h>
> + 
>   #include "bigdir.h"
> + #include "file_lock.h"
>   #include "config.h"
>   
>   #define MAX_DIR_LIST 62
> ***************
> *** 66,71 ****
> --- 69,75 ----
>   int read_dir_control(vdir_type *vdir)
>   { 
>    FILE *fs;
> +  int try=0;
>   
>       if ( (fs = fopen(".dir-control", "r")) == NULL ) {
>               int i;
> ***************
> *** 83,88 ****
> --- 87,112 ----
>               vdir->the_dir[0] = 0;
>               return(-1);
>       } 
> + 
> +     while(read_lock(fileno(fs), 0, SEEK_SET, 0) < 0)
> +     {
> +             if (errno == EAGAIN || errno == EACCES) 
> +             {
> +                     /* there might be other errors cases in which
> +                     * you might try again. 
> +                     */
> +                     if (++try < MAX_TRY_RLOCK) {
> +                             (void) sleep(2);
> +                             continue;
> +                     }
> +                     (void) fprintf(stderr,"File busy try again later!\n");
> +                     return(-1);
> +             }
> + 
> +             perror("fcntl");
> +             exit(2);
> +     }
> + 
>       fscanf(fs, "%lu\n", &vdir->cur_users);
>       fscanf(fs, "%d\n", &vdir->level_cur);
>       fscanf(fs, "%d\n", &vdir->level_max);
> ***************
> *** 104,109 ****
> --- 128,135 ----
>               &vdir->level_index[2]);
>       fscanf(fs, "%s\n", vdir->the_dir); 
>   
> +     unlock_lock(fileno(fs), 0, SEEK_SET, 0);
> + 
>       fclose(fs);
>   
>       return(0);
> ***************
> *** 112,121 ****
> --- 138,168 ----
>   int write_dir_control(vdir_type *vdir)
>   { 
>    FILE *fs;
> +  int try=0;
>   
>       if ( (fs = fopen(".dir-control", "w+")) == NULL ) {
>               return(-1);
>       } 
> + 
> +     while(read_lock(fileno(fs), 0, SEEK_SET, 0) < 0)
> +     {
> +             if (errno == EAGAIN || errno == EACCES) 
> +             {
> +                     /* there might be other errors cases in which
> +                     * you might try again. 
> +                     */
> +                     if (++try < MAX_TRY_RLOCK) {
> +                             (void) sleep(2);
> +                             continue;
> +                     }
> +                     (void) fprintf(stderr,"File busy try again later!\n");
> +                     return(-1);
> +             }
> + 
> +             perror("fcntl");
> +             exit(2);
> +     }
> + 
>       fprintf(fs, "%lu\n", vdir->cur_users);
>       fprintf(fs, "%d\n", vdir->level_cur);
>       fprintf(fs, "%d\n", vdir->level_max);
> ***************
> *** 136,141 ****
> --- 183,191 ----
>               vdir->level_index[1],
>               vdir->level_index[2]);
>       fprintf(fs, "%s\n", vdir->the_dir); 
> + 
> +     unlock_lock(fileno(fs), 0, SEEK_SET, 0);
> + 
>       fclose(fs);
>       chown(".dir-control",VPOPMAILUID, VPOPMAILGID);
>       return(0);
> diff -rcN vpopmail-4.8.9.orig/bigdir.h vpopmail-4.8.9/bigdir.h
> *** vpopmail-4.8.9.orig/bigdir.h      Wed Jun  7 21:00:59 2000
> --- vpopmail-4.8.9/bigdir.h   Fri Aug 18 07:32:33 2000
> ***************
> *** 22,27 ****
> --- 22,30 ----
>   #define MAX_DIR_LEVELS        3
>   #define MAX_USERS_PER_LEVEL 100
>   
> + #define MAX_TRY_RLOCK       10
> + #define MAX_TRY_WLOCK       15
> + 
>   #define MAX_DIR_NAME  300
>   typedef struct {
>       int level_cur;
> diff -rcN vpopmail-4.8.9.orig/file_lock.c vpopmail-4.8.9/file_lock.c
> *** vpopmail-4.8.9.orig/file_lock.c   Wed Dec 31 19:00:00 1969
> --- vpopmail-4.8.9/file_lock.c        Fri Aug 18 07:32:33 2000
> ***************
> *** 0 ****
> --- 1,50 ----
> + /*
> + file_lock.c
> + 
> + functions straight out of Richard Steven's 
> + "Advanced Programming in the UNIX Environment"
> + 
> + Translated into bytes by Eric Peters ([EMAIL PROTECTED])
> +     August 19, 2000
> + 
> + */
> + 
> + #include <sys/types.h>
> + #include <stdio.h>  /* for perror() */
> + #include <errno.h>  /* for perror() */
> + #include <fcntl.h>
> + 
> + int
> + lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len)
> + {
> +     struct flock    lock;
> + 
> +     lock.l_type     = type;         /* F_RDLCK, F_WRLCK, F_UNLCK */
> +     lock.l_start    = offset;       /* byte offset, relative to l_whence */
> +     lock.l_whence   = whence;       /* SEEK_SET, SEEK_CUR, SEEK_END */
> +     lock.l_len      = len;          /* #bytes (0 means to EOF) */
> + 
> +     return( fcntl(fd, cmd, &lock) );
> + }
> + 
> + 
> + pid_t
> + lock_test(int fd, int type, off_t offset, int whence, off_t len)
> + {
> +     struct flock    lock;
> + 
> +     lock.l_type     = type;         /* F_RDLCK, F_WRLCK, F_UNLCK */
> +     lock.l_start    = offset;       /* byte offset, relative to l_whence */
> +     lock.l_whence   = whence;       /* SEEK_SET, SEEK_CUR, SEEK_END */
> +     lock.l_len      = len;          /* #bytes (0 means to EOF) */
> + 
> +     if (fcntl(fd, F_GETLK, &lock) < 0)
> +     {
> +             perror("fcntl error");
> +             return(0);
> +     }
> + 
> +     if (lock.l_type == F_UNLCK)
> +             return(0);      /* false, region is not locked yb another proc */
> +     return(lock.l_pid);     /* true, return pid of lock owner */
> + }
> diff -rcN vpopmail-4.8.9.orig/file_lock.h vpopmail-4.8.9/file_lock.h
> *** vpopmail-4.8.9.orig/file_lock.h   Wed Dec 31 19:00:00 1969
> --- vpopmail-4.8.9/file_lock.h        Fri Aug 18 07:32:33 2000
> ***************
> *** 0 ****
> --- 1,38 ----
> + /*
> + file_lock.h
> + 
> + functions straight out of Richard Steven's 
> + "Advanced Programming in the UNIX Environment"
> + 
> + Translated into bytes by Eric Peters ([EMAIL PROTECTED])
> +     August 19, 2000
> + 
> + */
> + 
> + int
> + lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len);
> + 
> + #define read_lock(fd, offset, whence, len) \
> +             lock_reg(fd, F_SETLK, F_RDLCK, offset, whence, len)
> + 
> + #define readw_lock(fd, offset, whence, len) \
> +             lock_reg(fd, F_SETLKW, F_RDLCK, offset, whence, len)
> + 
> + #define write_lock(fd, offset, whence, len) \
> +             lock_reg(fd, F_SETLK, F_WRLCK, offset, whence, len)
> + 
> + #define writew_lock(fd, offset, whence, len) \
> +             lock_reg(fd, F_SETLKW, F_WRLCK, offset, whence, len)
> + 
> + #define unlock_lock(fd, offset, whence, len) \
> +             lock_reg(fd, F_SETLK, F_UNLCK, offset, whence, len)
> + 
> + 
> + pid_t
> + lock_test(int fd, int type, off_t offset, int whence, off_t len);
> + 
> + #define is_readlock(fd, offset, whence, len) \
> +             lock_test(fd, F_RDLCK, offset, whence, len)
> + 
> + #define is_writelock(fd, offset, whence, len) \
> +             lock_test(fd, F_WRLCK, offset, whence, len)
> 
> 

Reply via email to