Back to index

courier  0.68.2
Functions
maildircache.h File Reference
#include <sys/types.h>
#include <time.h>
#include <pwd.h>
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

int maildir_cache_init (time_t, const char *, const char *, const char *const *)
void maildir_cache_start (void)
void maildir_cache_save (const char *, time_t, const char *, uid_t, gid_t)
void maildir_cache_cancel (void)
int maildir_cache_search (const char *, time_t, int(*)(uid_t, gid_t, const char *, void *), void *)
void maildir_cache_purge ()

Function Documentation

void maildir_cache_cancel ( void  )

Definition at line 317 of file maildircache.c.

{
       if (childproc > 0)
       {
              if (write(childpipe, "CANCELLED\n", 10) < 0)
                     perror("write");

              close(childpipe);
       }
}

Here is the caller graph for this function:

int maildir_cache_init ( time_t  ,
const char *  ,
const char *  ,
const char *const *   
)

Definition at line 56 of file maildircache.c.

{
       unsigned x;

       expinterval=n;
       cachedir=d;
       cacheowner=o;
       authvars=a;

       for (x=0; a[x]; x++)
              ;

       if ((authvals=malloc(sizeof(char *)*(x+1))) == NULL)
              return (-1);

       for (x=0; a[x]; x++)
              authvals[x]=0;
       return (0);
}

Here is the caller graph for this function:

Definition at line 461 of file maildircache.c.

{
       time_t now;
       pid_t p;
       int waitstat;
       struct passwd *pw;
       struct purge_list *pl;
       DIR *dirp;
       struct dirent *de;
       struct sigaction sa, oldsa;

       time(&now);

       if (lastclean && lastclean >= now - expinterval)
              return;

       lastclean=now;

       memset(&sa, 0, sizeof(sa));

       sa.sa_handler=SIG_DFL;
       if (sigaction(SIGCHLD, &sa, &oldsa) < 0)
       {
              perror("sigaction");
              return;
       }

       p=fork();

       if (p < 0)
              return;

       if (p)
       {
              pid_t p2;

              while ((p2=wait(&waitstat)) >= 0 && p2 != p)
                     ;

              sigaction(SIGCHLD, &oldsa, NULL);
              return;
       }

       p=fork();

       if (p)
              exit(0);

       pw=getpwnam(cacheowner);

       if (!pw)
       {
              fprintf(stderr, "CRIT: maildircache: no such user %s - cannot purge login cache dir\n",
                     cacheowner);
              exit(0);
       }

       if (setgid(pw->pw_gid) < 0 || setuid(pw->pw_uid) < 0)
       {
              fprintf(stderr, "CRIT: maildircache: cannot change to uid/gid for %s - cannot purge login cache dir\n",
                     cacheowner);
              exit(0);
       }

       if (chdir(cachedir))
       {
              fprintf(stderr, "CRIT: maildircache: cannot change dir to %s\n", cachedir);
              exit(0);
       }

       pl=NULL;

       dirp=opendir(".");

       now /= expinterval;
       --now;

       while (dirp && (de=readdir(dirp)) != NULL)
       {
              if (!isdigit((int)(unsigned char)de->d_name[0]))
                     continue;

              if (atol(de->d_name) >= now)
                     continue;

              add_purge_list(&pl, de->d_name);
       }
       if (dirp)
              closedir(dirp);

       while (pl)
       {
              struct purge_list *p=pl;

              pl=pl->next;

              rmrf(p->n);
              free(p->n);
              free(p);
       }
       exit(0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_cache_save ( const char *  ,
time_t  ,
const char *  ,
uid_t  ,
gid_t   
)

Definition at line 279 of file maildircache.c.

{
char   buf[2048];
char   buf2[NUMBUFSIZE];
pid_t  p;
int    waitstat;

       strcat(strcpy(buf, a), " ");
       strcat(strcat(buf, libmail_str_time_t(b, buf2)), " ");
       strcat(strcat(buf, libmail_str_uid_t(u, buf2)), " ");
       strcat(strcat(buf, libmail_str_gid_t(g, buf2)), " ");
       strncat(buf, homedir, sizeof(buf)-2-strlen(homedir));
       strcat(buf, "\n");

       if (savebuf(buf, strlen(buf)) == 0)
       {
       int    i;

              for (i=0; authvars[i]; i++)
              {
              const char *p;

                     strcat(strcpy(buf, authvars[i]), "=");
                     p=getenv(authvars[i]);
                     if (!p || strlen(p)+strlen(buf) >= sizeof(buf)-2 ||
                            strchr(p, '\n'))
                            continue;
                     strcat(strcat(buf, p), "\n");
                     if (savebuf(buf, strlen(buf)))     break;
              }
       }
       close(childpipe);
       while ((p=wait(&waitstat)) != -1 && p != childproc)
              ;
       childproc= -1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_cache_search ( const char *  ,
time_t  ,
int(*)(uid_t, gid_t, const char *, void *)  ,
void *   
)

Definition at line 328 of file maildircache.c.

{
       char *f=create_cache_name(a, b);
       FILE *fp;
       uid_t  u;
       gid_t  g;
       char dir[1024];
       int    n;
       int    c;

       if (!f)
              return (-1);
       fp=fopen(f, "r");
       free(f);
       if (!fp)
              return (-1);

       u=0;
       while ((c=getc(fp)) != ' ')
       {
              if (c < '0' || c > '9')
              {
                     fclose(fp);
                     return (-1);
              }
              u=u*10 + (c-'0');
       }

       g=0;
       while ((c=getc(fp)) != ' ')
       {
              if (c < '0' || c > '9')
              {
                     fclose(fp);
                     return (-1);
              }
              g=g*10 + (c-'0');
       }

       for (n=0; (c=getc(fp)) != EOF; n++)
       {
              if (c == '\n')       break;
              if (n >= sizeof(dir)-1)
              {
                     fclose(fp);
                     fprintf(stderr, "CRIT: maildircache: Cache record overflow.\n");
                     return (-1);
              }
              dir[n]=(char)c;
       }
       dir[n]=0;

       if ((n=(*callback_func)(u, g, dir, callback_arg)) != 0)
       {
              fclose(fp);
              return (n);
       }

       if (c != EOF)
       {
              while (fgets(dir, sizeof(dir), fp))
              {
              char   *q;

                     if ( (q=strchr(dir, '\n')) == 0)
                     {
                            fclose(fp);
                            fprintf(stderr, "CRIT: maildircache: Cache record overflow.\n");
                            return (-1);
                     }
                     *q=0;

                     for (n=0; authvars[n]; n++)
                     {
                            int l=strlen(authvars[n]);

                            if (strncmp(dir, authvars[n], l) == 0 &&
                                dir[l] == '=')
                            {
                                   char *s=strdup(dir);

                                   if (!s)
                                   {
                                          fclose(fp);
                                          perror("CRIT: maildircache: malloc failed");
                                          return (-1);
                                   }

                                   putenv(s);

                                   if (authvals[n])
                                          free(authvals[n]);
                                   authvals[n]=s;
                                   break;
                            }
                     }
              }
              fclose(fp);
       }
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_cache_start ( void  )

Definition at line 144 of file maildircache.c.

{
int    pipefd[2];
char   buf[2048];
int    i, j;
char   *userid, *login_time, *data;
time_t login_time_n;
char   *f;
FILE   *fp;

       if (pipe(pipefd) < 0)
       {
              perror("CRIT: maildircache: pipe() failed");
              return;
       }
       while ((childproc=fork()) < 0)
       {
              sleep(5);
       }

       if (childproc)
       {
              close(pipefd[0]);
              childpipe=pipefd[1];
              return;
       }
       close(pipefd[1]);
       i=0;

       for (;;)
       {
              if (i >= sizeof(buf)-1)
              {
                     close(pipefd[0]);

                     /* Problems */

                     fprintf(stderr, "CRIT: maildircache: Max cache buffer overflow.\n");
                     exit(1);
              }

              j=read(pipefd[0], buf+i, sizeof(buf)-1-i);
              if (j < 0)
              {
                     perror("CRIT: maildircache: Cache create failure");
                     exit(1);
              }
              if (j == 0)   break;
              i += j;
       }
       close(pipefd[0]);
       buf[i]=0;

       {
       struct passwd *pwd=getpwnam(cacheowner);

              if (!pwd || setgid(pwd->pw_gid) || setuid(pwd->pw_uid))
              {
                     fprintf(stderr, "CRIT: maildircache: Cache create failure - cannot change to user %s\n",
                            cacheowner);
                     exit(1);
              }
       }

       if (strncmp(buf, "CANCELLED\n", 10) == 0)
              exit (0);

       userid=buf;
       if ((login_time=strchr(userid, ' ')) == 0)
       {
              fprintf(stderr, "CRIT: maildircache: Cache create failure - authentication process crashed.\n");
              exit(1);
       }
       *login_time++=0;
       if ((data=strchr(login_time, ' ')) == 0)
       {
              fprintf(stderr, "CRIT: maildircache: Cache create failure - authentication process crashed.\n");
              exit(1);
       }
       *data++=0;

       login_time_n=0;
       while (*login_time >= '0' && *login_time <= '9')
              login_time_n = login_time_n * 10 + (*login_time++ -'0');

       f=create_cache_name(userid, login_time_n);

       if (!f)
              exit(0);

       if ((fp=fopen(f, "w")) == 0)       /* Try creating subdirs */
       {
              char   *p=f+strlen(cachedir);

              while (p && *p == '/')
              {
                     *p=0;
                     mkdir(f, 0700);
                     *p='/';
                     p=strchr(p+1, '/');
              }

              if ((fp=fopen(f, "w")) == 0)
              {
                     fprintf(stderr, "CRIT: maildircache: Cache create failure - unable to create file %s.\n", f);
                     exit(1);
              }
       }
       free(f);

       if ( fwrite(data, strlen(data), 1, fp) != 1 || fflush(fp)
            || ferror(fp))
       {
              fclose(fp);
              unlink(f);    /* Problems */
              fprintf(stderr, "CRIT: maildircache: Cache create failure - write error.\n");
              exit(1);
       }
       else   fclose(fp);
       exit(0);
}

Here is the call graph for this function:

Here is the caller graph for this function: