Back to index

courier  0.68.2
Classes | Functions
mail.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  ll_mail

Functions

struct ll_mailll_mail_alloc (const char *filename)
int ll_mail_lock (struct ll_mail *)
int ll_mail_open (struct ll_mail *)
int ll_mail_open_ro (struct ll_mail *)
void ll_mail_free (struct ll_mail *)
int ll_dotlock (const char *dotlock, const char *tmpfile, int timeout)

Class Documentation

struct ll_mail

Definition at line 18 of file mail.h.

Class Members
int cclientfd
char * cclientfile
char * dotlock
char * file

Function Documentation

int ll_dotlock ( const char *  dotlock,
const char *  tmpfile,
int  timeout 
)

Definition at line 487 of file mail.c.

{
       char myidbuf[IDBUFSIZE];

       getid(myidbuf);

       if (try_dotlock(tmpfile, dotlock, myidbuf))
       {
              if (errno == EEXIST)
                     dotlock_exists(dotlock, myidbuf, timeout);
              return -1;
       }
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct ll_mail* ll_mail_alloc ( const char *  filename) [read]

Definition at line 23 of file mail.c.

{
       struct ll_mail *p=(struct ll_mail *)malloc(sizeof(struct ll_mail));

       if (!p)
              return NULL;

       if ((p->file=strdup(filename)) == NULL)
       {
              free(p);
              return NULL;
       }

       p->cclientfd= -1;
       p->cclientfile=NULL;

       p->dotlock=NULL;

       return p;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void ll_mail_free ( struct ll_mail )

Definition at line 442 of file mail.c.

{
       char myid[IDBUFSIZE];
       char idbuf[IDBUFSIZE];

       getid(myid);

       if (p->cclientfd >= 0)
       {
              if (lseek(p->cclientfd, 0L, SEEK_SET) == 0 &&
                  readid(idbuf, p->cclientfd) == 0 &&
                  strcmp(myid, idbuf) == 0)
              {
                     if (ftruncate(p->cclientfd, 0) >= 0)
                            unlink(p->cclientfile);
              }
              close(p->cclientfd);
              free(p->cclientfile);
       }

       if (p->dotlock)
       {
              int fd=open(p->dotlock, O_RDONLY);

              if (fd >= 0)
              {
                     if (readid(idbuf, fd) == 0 &&
                         strcmp(myid, idbuf) == 0)
                     {
                            close(fd);
                            unlink(p->dotlock);
                            free(p->dotlock);
                            free(p->file);
                            free(p);
                            return;
                     }
                     close(fd);
              }

              free(p->dotlock);
       }
       free(p->file);
       free(p);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ll_mail_lock ( struct ll_mail )

Definition at line 115 of file mail.c.

{
       struct stat stat_buf;
       char idbuf[IDBUFSIZE];
       char idbuf2[IDBUFSIZE];

       char fn[NUMBUFSIZE*2 + 20];
       char *f;
       int fd;

       getid(idbuf);

       if (p->cclientfd >= 0)
              return 0;

       if (stat(p->file, &stat_buf) < 0)
              return -1;

       if (snprintf(fn, sizeof(fn), "/tmp/.%lx.%lx",
                   (unsigned long)stat_buf.st_dev,
                   (unsigned long)stat_buf.st_ino) < 0)
       {
              errno=ENOSPC;
              return (-1);
       }

       if ((f=strdup(fn)) == NULL)
              return (-1);

       /* We do things a bit differently.  First, try O_EXCL */

       if ((fd=open(f, O_RDWR|O_CREAT|O_EXCL, 0644)) >= 0)
       {
              struct stat stat_buf2;

              if (ll_lockfd(fd, ll_writelock, ll_whence_start, 0) < 0 ||
                  fcntl(fd, F_SETFD, FD_CLOEXEC) < 0 ||
                  writeid(idbuf, fd) < 0)
              {
                     /* This shouldn't happen */

                     close(fd);
                     free(f);
                     return (-1);
              }

              /* Rare race condition: */

              if (fstat(fd, &stat_buf) < 0 ||
                  lstat(f, &stat_buf2) < 0 ||
                  stat_buf.st_dev != stat_buf2.st_dev ||
                  stat_buf.st_ino != stat_buf2.st_ino)
              {
                     errno=EAGAIN;
                     close(fd);
                     free(f);
                     return (-1);
              }

              p->cclientfd=fd;
              p->cclientfile=f;
              return 0;
       }

       /*
       ** An existing lockfile.  See if it's tagged with another
       ** pid on this server, which no longer exists.
       */

       if ((fd=open(f, O_RDONLY)) >= 0)
       {
              pid_t p=-1;

              if (readid(idbuf2, fd) == 0 &&
                  (p=getpidid(idbuf2, idbuf)) != 0 &&
                  kill(p, 0) < 0 && errno == ESRCH)
              {
                     errno=EAGAIN;
                     close(fd);
                     unlink(f); /* Don't try again right away */
                     free(f);
                     return (-1);
              }

              /* If we can't lock, someone must have it open, game over. */

              if (p == getpid() /* It's us! */

                  || ll_lockfd(fd, ll_readlock, ll_whence_start, 0) < 0)
              {
                     errno=EEXIST;
                     close(fd);
                     free(f);
                     return (-1);
              }

              close(fd);
       }

       /* Stale 0-length lockfiles are blown away after 5 mins */

       if (lstat(f, &stat_buf) == 0 && stat_buf.st_size == 0 &&
           stat_buf.st_mtime + 300 < time(NULL))
       {
              errno=EAGAIN;
              unlink(f);
              free(f);
              return (-1);
       }

       errno=EAGAIN;
       free(f);
       return (-1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ll_mail_open ( struct ll_mail )

Definition at line 437 of file mail.c.

{
       return ll_mail_open_do(p, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ll_mail_open_ro ( struct ll_mail )

Definition at line 432 of file mail.c.

{
       return ll_mail_open_do(p, 1);
}

Here is the call graph for this function:

Here is the caller graph for this function: