Back to index

courier  0.68.2
Classes | Defines | Enumerations | Functions
maildirfilter.h File Reference
#include "config.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  maildirfilterrule
struct  maildirfilter
struct  maildir_filter_autoresp_info

Defines

#define MFR_DOESNOT   1 /* Negates pretty much every condition */
#define MFR_BODY
#define MFR_CONTINUE   4 /* Continue filtering (cc instead of to) */
#define MFR_PLAINSTRING   8 /* Pattern is a plain string, not a regex */
#define maildir_filter_freerules(r)
#define MF_ERR_BADRULENAME   1
#define MF_ERR_BADRULETYPE   2
#define MF_ERR_BADRULEHEADER   3
#define MF_ERR_BADRULEVALUE   4
#define MF_ERR_BADRULEFOLDER   5
#define MF_ERR_BADFROMHDR   6
#define MF_ERR_EXISTS   7
#define MF_ERR_INTERNAL   100
#define MF_LOADOK   0
#define MF_LOADNOTFOUND   1
#define MF_LOADFOREIGN   2
#define MF_LOADERROR   3

Enumerations

enum  maildirfiltertype {
  startswith, endswith, contains, hasrecipient,
  mimemultipart, textplain, islargerthan, anymessage
}

Functions

struct maildirfilterrulemaildir_filter_appendrule (struct maildirfilter *r, const char *name, enum maildirfiltertype type, int flags, const char *header, const char *value, const char *folder, const char *fromhdr, int *errcode)
int maildir_filter_setautoreplyfrom (struct maildirfilter *, const char *)
void maildir_filter_ruleup (struct maildirfilter *, struct maildirfilterrule *)
void maildir_filter_ruledown (struct maildirfilter *, struct maildirfilterrule *)
void maildir_filter_ruledel (struct maildirfilter *, struct maildirfilterrule *)
int maildir_filter_ruleupdate (struct maildirfilter *, struct maildirfilterrule *, const char *, enum maildirfiltertype, int, const char *, const char *, const char *, const char *, int *)
int maildir_filter_saverules (struct maildirfilter *, const char *, const char *, const char *, const char *)
int maildir_filter_loadrules (struct maildirfilter *, const char *)
int maildir_filter_importmaildirfilter (const char *)
int maildir_filter_loadmaildirfilter (struct maildirfilter *, const char *)
int maildir_filter_savemaildirfilter (struct maildirfilter *, const char *, const char *)
int maildir_filter_exportmaildirfilter (const char *)
int maildir_filter_hasmaildirfilter (const char *)
void maildir_filter_endmaildirfilter (const char *)
int maildir_filter_autoresp_info_init_str (struct maildir_filter_autoresp_info *, const char *)
int maildir_filter_autoresp_info_init (struct maildir_filter_autoresp_info *, const char *)
void maildir_filter_autoresp_info_free (struct maildir_filter_autoresp_info *)
char * maildir_filter_autoresp_info_asstr (struct maildir_filter_autoresp_info *)

Class Documentation

struct maildirfilterrule

Definition at line 27 of file maildirfilter.h.

Collaboration diagram for maildirfilterrule:
Class Members
char * fieldname
char * fieldvalue
char * fromhdr
struct maildirfilterrule * next
struct maildirfilterrule * prev
char * rulename
char * tofolder
struct maildirfilter

Definition at line 44 of file maildirfilter.h.

Collaboration diagram for maildirfilter:
Class Members
struct maildirfilterrule * first
struct maildirfilterrule * last
struct maildir_filter_autoresp_info

Definition at line 140 of file maildirfilter.h.

Class Members
unsigned days
int dsnflag
char * name
int noquote

Define Documentation

#define maildir_filter_freerules (   r)
Value:
do { \
       while ( (r)->first ) \
              maildir_filter_ruledel( (r), (r)->first );       \
       } while (0)

Definition at line 88 of file maildirfilter.h.

#define MF_ERR_BADFROMHDR   6

Definition at line 104 of file maildirfilter.h.

#define MF_ERR_BADRULEFOLDER   5

Definition at line 103 of file maildirfilter.h.

#define MF_ERR_BADRULEHEADER   3

Definition at line 101 of file maildirfilter.h.

#define MF_ERR_BADRULENAME   1

Definition at line 99 of file maildirfilter.h.

#define MF_ERR_BADRULETYPE   2

Definition at line 100 of file maildirfilter.h.

#define MF_ERR_BADRULEVALUE   4

Definition at line 102 of file maildirfilter.h.

#define MF_ERR_EXISTS   7

Definition at line 105 of file maildirfilter.h.

#define MF_ERR_INTERNAL   100

Definition at line 106 of file maildirfilter.h.

#define MF_LOADERROR   3

Definition at line 121 of file maildirfilter.h.

#define MF_LOADFOREIGN   2

Definition at line 120 of file maildirfilter.h.

#define MF_LOADNOTFOUND   1

Definition at line 119 of file maildirfilter.h.

#define MF_LOADOK   0

Definition at line 118 of file maildirfilter.h.

#define MFR_BODY
Value:
2      /* startswith/endswith/contains applied
                            ** to body.
                            */

Definition at line 34 of file maildirfilter.h.

#define MFR_CONTINUE   4 /* Continue filtering (cc instead of to) */

Definition at line 35 of file maildirfilter.h.

#define MFR_DOESNOT   1 /* Negates pretty much every condition */

Definition at line 33 of file maildirfilter.h.

#define MFR_PLAINSTRING   8 /* Pattern is a plain string, not a regex */

Definition at line 36 of file maildirfilter.h.


Enumeration Type Documentation

Enumerator:
startswith 
endswith 
contains 
hasrecipient 
mimemultipart 
textplain 
islargerthan 
anymessage 

Definition at line 16 of file maildirfilter.h.

                       {
       startswith,
       endswith,
       contains,
       hasrecipient,
       mimemultipart,
       textplain,
       islargerthan,        /* Use negation for the opposite! */
       anymessage
       } ;

Function Documentation

struct maildirfilterrule* maildir_filter_appendrule ( struct maildirfilter r,
const char *  name,
enum maildirfiltertype  type,
int  flags,
const char *  header,
const char *  value,
const char *  folder,
const char *  fromhdr,
int *  errcode 
) [read]

Definition at line 45 of file maildirfilter.c.

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

       *errcode=MF_ERR_INTERNAL;

       if (!p)       return (0);
       memset(p, 0, sizeof(*p));

       if ((p->prev=r->last) != 0)
              p->prev->next=p;
       else
              r->first=p;
       r->last=p;

       if (maildir_filter_ruleupdate(r, p, name, type, flags,
                       header, value, folder, fromhdr, errcode))
       {
              maildir_filter_ruledel(r, p);
              return (0);
       }
       return (p);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 852 of file maildirfilter.c.

{
       char days_buf[NUMBUFSIZE+10];

       const char *dsn_arg="";
       const char *days_arg="";
       const char *noquote_arg="";

       char *p;

       if (i->dsnflag)
              dsn_arg=" dsn=1";
       if (i->days > 0)
       {
              strcpy(days_buf, " days=");
              libmail_str_size_t(i->days, days_buf+6);
              days_arg=days_buf;
       }

       if (i->noquote)
              noquote_arg=" noquote";

       p=malloc(strlen(i->name)+1+strlen(dsn_arg)+strlen(days_arg)+
               strlen(noquote_arg));
       if (!p)
              return (NULL);

       strcat(strcat(strcat(strcpy(p, i->name), dsn_arg), days_arg),
              noquote_arg);
       return (p);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 843 of file maildirfilter.c.

{
       if (i->name)
       {
              free(i->name);
              i->name=0;
       }
}

Here is the caller graph for this function:

int maildir_filter_autoresp_info_init ( struct maildir_filter_autoresp_info ,
const char *   
)

Definition at line 802 of file maildirfilter.c.

{
       memset(i, 0, sizeof(*i));

       if (maildir_autoresponse_validate(NULL, c))
              return (-1);
       i->name=strdup(c);
       if (!(i->name))
              return (-1);
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 814 of file maildirfilter.c.

{
       char *p;

       memset(i, 0, sizeof(*i));
       i->name=strdup(c);
       if (!(i->name))
              return (-1);

       if (strtok(i->name, " \t\r\n") == NULL)
       {
              errno=EINVAL;
              free(i->name);
              i->name=0;
              return (-1);
       }

       while ((p=strtok(NULL, " \t\r\n")) != NULL)
       {
              if (strncmp(p, "dsn=", 4) == 0)
                     i->dsnflag=atoi(p+4) ? 1:0;
              else if (strncmp(p, "days=", 5) == 0)
                     i->days=atoi(p+5);
              else if (strcmp(p, "noquote") == 0)
                     i->noquote=1;
       }
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_filter_endmaildirfilter ( const char *  )

Definition at line 256 of file maildirfilter2.c.

{
char *maildirfilter=maildir_filter_config_maildirfilter(maildir);
char *newname;

       if (!maildirfilter)  return;

       newname=malloc(strlen(maildir)+sizeof("/maildirfilter.tmp"));
       if (!newname)
       {
              free(maildirfilter);
              return;
       }

       strcat(strcpy(newname, maildir), "/maildirfilter.tmp");
       unlink(newname);
       free(maildirfilter);
       free(newname);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_filter_exportmaildirfilter ( const char *  )

Definition at line 223 of file maildirfilter2.c.

{
char *maildirfilter=maildir_filter_config_maildirfilter(maildir);
char *newname;
int    rc;

       if (!maildirfilter)  return (-1);

       newname=malloc(strlen(maildir)+sizeof("/maildirfilter.tmp"));
       if (!newname)
       {
              free(maildirfilter);
              return (-1);
       }

       strcat(strcpy(newname, maildir), "/maildirfilter.tmp");
       rc=rename(newname, maildirfilter);
       free(maildirfilter);
       free(newname);
       return (rc);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_filter_hasmaildirfilter ( const char *  )

Definition at line 245 of file maildirfilter2.c.

{
const char *p=maildir_filter_config(maildir, "MAILDIR");

       if (!p || !*p)       return (-1);

       p=maildir_filter_config(maildir, "MAILDIRFILTER");
       if (!p || !*p)       return (-1);
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_filter_importmaildirfilter ( const char *  )

Definition at line 77 of file maildirfilter2.c.

{
       const char *p=maildir_filter_config(maildir, "MAILDIRFILTER");
       char *maildirfilter;
       FILE *i, *o;
       struct maildir_tmpcreate_info createInfo;

       if (!p)       return (-1);

       if (!*p)
       {
              errno=ENOENT;
              return (-1);
       }

       maildirfilter=maildir_filter_config_maildirfilter(maildir);
       if (!maildirfilter)  return (-1);

       maildir_tmpcreate_init(&createInfo);

       createInfo.maildir=maildir;
       createInfo.uniq="maildirfilter-tmp";
       createInfo.doordie=1;

       if ((o=maildir_tmpcreate_fp(&createInfo)) == NULL)
       {
              free(maildirfilter);
              return (-1);
       }

       strcat(strcpy(createInfo.newname, maildir),
              "/maildirfilter.tmp"); /* We enough we have enough mem: .uniq */

       if ((i=fopen(maildirfilter, "r")) == 0)
       {
       struct maildirfilter mf;

              if (errno != ENOENT)
              {
                     fclose(o);
                     unlink(createInfo.tmpname);
                     maildir_tmpcreate_free(&createInfo);
                     free(maildirfilter);
                     return (-1);
              }

              memset(&mf, 0, sizeof(mf));
              fclose(o);
              unlink(createInfo.tmpname);
              unlink(createInfo.newname);
              maildir_filter_savemaildirfilter(&mf, maildir, "");
              /* write out a blank one */
       }
       else
       {
              char   buf[BUFSIZ];
              int    n;

              while ((n=fread(buf, 1, sizeof(buf), i)) > 0)
                     if (fwrite(buf, 1, n, o) != n)
                     {
                            fclose(o);
                            fclose(i);
                            unlink(createInfo.tmpname);
                            maildir_tmpcreate_free(&createInfo);
                            free(maildirfilter);
                            return (-1);
                     }
              if (fflush(o))
              {
                     fclose(o);
                     fclose(i);
                     unlink(createInfo.tmpname);
                     maildir_tmpcreate_free(&createInfo);
                     free(maildirfilter);
                     return (-1);
              }
              fclose(o);
              fclose(i);
              if (chmod(createInfo.tmpname, 0600)
                  || rename(createInfo.tmpname, createInfo.newname))
              {
                     unlink(createInfo.tmpname);
                     maildir_tmpcreate_free(&createInfo);
                     free(maildirfilter);
                     return (-1);
              }
       }

       maildir_tmpcreate_free(&createInfo);
       free(maildirfilter);
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_filter_loadmaildirfilter ( struct maildirfilter ,
const char *   
)

Definition at line 171 of file maildirfilter2.c.

{
char *newname=malloc(strlen(maildir)+sizeof("/maildirfilter.tmp"));
int    rc;

       if (!newname) return (-1);
       strcat(strcpy(newname, maildir), "/maildirfilter.tmp");

       rc=maildir_filter_loadrules(mf, newname);
       free(newname);
       if (rc && rc != MF_LOADNOTFOUND)
              rc= -1;
       else
              rc=0;
       return (rc);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_filter_loadrules ( struct maildirfilter ,
const char *   
)

Definition at line 652 of file maildirfilter.c.

{
FILE   *f=fopen(filename, "r");
char   buf[BUFSIZ];
char   *p;

enum   maildirfiltertype new_type;
char   new_header[256];
char   new_value[256];
char   new_folder[256];
char   new_autoreplyfrom[512];

int    flags;

       if (!f)       return (MF_LOADNOTFOUND);

       if (fgets(buf, sizeof(buf), f) == 0 ||
              strncmp(buf, "#MFMAILDROP=", 12))
       {
              fclose(f);
              return (MF_LOADFOREIGN);
       }

       flags=atoi(buf+12);
       if (flags != 1 && flags != 2)
       {
              fclose(f);
              return (MF_LOADFOREIGN);
       }

       new_type=contains;
       new_header[0]=0;
       new_value[0]=0;
       new_folder[0]=0;
       new_autoreplyfrom[0]=0;
       flags=0;

#define       SET(f,b) { f[0]=0; strncat( (f), (b), sizeof(f)-1); }

       while ( fgets(buf, sizeof(buf), f))
       {
       int    i;

              p=strchr(buf, '\n');
              if (p) *p=0;
              if (strncmp(buf, "##", 2))  continue;
              p=buf+2;
              while ( *p && isspace((int)(unsigned char)*p))
                     ++p;

              if (strncasecmp(p, "From:", 5) == 0)
              {
                     p += 5;
                     SET(new_autoreplyfrom, p);
                     continue;
              }


              if (strncasecmp(p, "Op:", 3) == 0)
              {
                     p += 3;

                     for (i=0; typelist[i].name; i++)
                            if (strcasecmp(typelist[i].name, p) == 0)
                                   break;
                     if (!typelist[i].name)
                     {
                            fclose(f);
                            return (MF_LOADFOREIGN);
                     }
                     new_type=typelist[i].type;
                     continue;
              }

              if (strncasecmp(p, "Header:", 7) == 0)
              {
                     p += 7;
                     SET(new_header, p);
                     continue;
              }

              if (strncasecmp(p, "Value:", 6) == 0)
              {
                     p += 6;
                     SET(new_value, p);
                     continue;
              }

              if (strncasecmp(p, "Folder:", 7) == 0)
              {
                     p += 7;

                     if (*p == '.')
                     {
                            strcpy(new_folder, INBOX);
                     }
                     else
                            new_folder[0]=0;

                     if (strcmp(p, "."))
                            strncat(new_folder, p,
                                   sizeof(new_folder)-1-strlen(new_folder));
                     continue;
              }

              if (strcasecmp(p, "plainstring") == 0)
              {
                     flags |= MFR_PLAINSTRING;
                     continue;
              }

              if (strcasecmp(p, "doesnot") == 0)
              {
                     flags |= MFR_DOESNOT;
                     continue;
              }

              if (strcasecmp(p, "continue") == 0)
              {
                     flags |= MFR_CONTINUE;
                     continue;
              }

              if (strcasecmp(p, "body") == 0)
              {
                     flags |= MFR_BODY;
                     continue;
              }

              if (strncasecmp(p, "Name:", 5) == 0)
              {
              int dummy;

                     p += 5;
                     maildir_filter_appendrule(r, p, new_type, flags,
                                            new_header,
                                            new_value, new_folder,
                                            new_autoreplyfrom, &dummy);
                     new_type=contains;
                     new_header[0]=0;
                     new_value[0]=0;
                     new_folder[0]=0;
                     new_autoreplyfrom[0]=0;
                     flags=0;
              }
       }
       fclose(f);
       return (MF_LOADOK);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_filter_ruledel ( struct maildirfilter ,
struct maildirfilterrule  
)

Definition at line 371 of file maildirfilter.c.

{
       if (p->prev)  p->prev->next=p->next;
       else          r->first=p->next;

       if (p->next)  p->next->prev=p->prev;
       else          r->last=p->prev;

       if (p->rulename)     free(p->rulename);
       if (p->fieldname)    free(p->fieldname);
       if (p->fieldvalue)   free(p->fieldvalue);
       if (p->tofolder)     free(p->tofolder);
       if (p->fromhdr)             free(p->fromhdr);
       free(p);
}

Here is the caller graph for this function:

void maildir_filter_ruledown ( struct maildirfilter ,
struct maildirfilterrule  
)

Definition at line 404 of file maildirfilter.c.

{
struct maildirfilterrule *q;

       q=p->next;
       if (!q)       return;
       q->prev=p->prev;
       if (q->prev)  q->prev->next=q;
       else          r->first=q;

       if ((p->next=q->next) != 0) p->next->prev=p;
       else   r->last=p;

       p->prev=q;
       q->next=p;
}

Here is the caller graph for this function:

void maildir_filter_ruleup ( struct maildirfilter ,
struct maildirfilterrule  
)

Definition at line 387 of file maildirfilter.c.

{
struct maildirfilterrule *q;

       q=p->prev;
       if (!q)       return;
       q->next=p->next;
       if (p->next)  p->next->prev=q;
       else          r->last=q;

       if ((p->prev=q->prev) != 0) p->prev->next=p;
       else   r->first=p;

       p->next=q;
       q->prev=p;
}

Here is the caller graph for this function:

int maildir_filter_ruleupdate ( struct maildirfilter ,
struct maildirfilterrule ,
const char *  ,
enum  maildirfiltertype,
int  ,
const char *  ,
const char *  ,
const char *  ,
const char *  ,
int *   
)

Definition at line 77 of file maildirfilter.c.

{
       const char *c;
       struct maildirfilterrule *pom;

/*
** Before creating a new rule, validate all input.
*/

       *errcode=0;

       /* rule name: may not contain quotes or control characters. */
       *errcode=MF_ERR_BADRULENAME;
       if (!name || !*name || strlen(name) > 200)
              return (-1);

       for (c=name; *c; c++)
              if ((unsigned char)*c < ' ' || *c == '\'' || *c == '"' ||
                     *c == '`')
                     return (-1);

       /* rule name: may not already exist */
       *errcode=MF_ERR_EXISTS;
       
       for (pom=r->first; pom->next; pom=pom->next) {
           if (p!=pom && !strcmp(name, pom->rulename))
              return (-1);
       }

       /* rule type: we must know what it is */

       switch (type) {
       case startswith:
       case endswith:
       case contains:
       case hasrecipient:
       case mimemultipart:
       case textplain:
       case islargerthan:
       case anymessage:
              break;
       default:
              *errcode=MF_ERR_BADRULETYPE;
              break;
       } ;

       /* header: */

       *errcode=MF_ERR_BADRULEHEADER;

       c=header;
       if (c && strlen(c) > 200)   return (-1);
       if (c == 0 || *c == 0)
       {
              switch (type) {
              case hasrecipient:
              case islargerthan:
              case mimemultipart:
              case textplain:
              case anymessage:
                     break;
              case contains:
              case startswith:
              case endswith:
                     if (flags & MFR_BODY)
                            break;
                     /* FALLTHRU */
              default:
                     /* required */

                     return (-1);
              }
       }
       else for ( ; *c; c++)
       {
              /* no control characters */
              if (*c <= ' ' || *c == MDIRSEP[0] || *c >= 127 || *c == '\'' ||
                     *c == '\\' || *c == '"' || *c == '`' || *c == '/')
                     return (-1);
       }

       /* rule pattern */

       *errcode=MF_ERR_BADRULEVALUE;

       c=value;
       if (c && strlen(c) > 200)   return (-1);
       if (c == 0 || *c == 0)
       {
              switch (type) {
              case mimemultipart:
              case textplain:
              case anymessage:
                     break;
              default:
                     /* required */

                     return (-1);
              }
       }
       else if (!(flags & MFR_PLAINSTRING))
       {
              /*
              ** Let PCRE decide if this is a valid pattern.
              **
              ** One exception: the forward slash character, and some other
              ** special characters, must always be escaped.
              */

              while (*c)
              {
                     if (*c == '/' || *c == '$' || *c == '!'
                            || *c == '`' || (int)(unsigned char)*c < ' '
                            || *c == '\'' || *c == '"') return (-1);
                                          /* must be escaped */

                     if (type == islargerthan)
                     {
                            if (!isdigit((int)(unsigned char)*c))
                                   return (-1);
                     }

                     if (*c == '(')
                     {
                            if (type == hasrecipient)   return (-1);
                            ++c;
                            if (*c == ')')       return (-1);
                            continue;
                     }
                     if (*c == ')')
                     {
                            if (type == hasrecipient)   return (-1);
                            ++c;
                            continue;
                     }
                     if (*c == '[')       /* This is a set */
                     {
                            if (type == hasrecipient)   return (-1);
                            ++c;
                            for (;;)
                            {
                                   if (*c == '\'' || *c == '"' ||
                                          *c == '`')
                                          return (-1); /* must be quoted*/
                                   if (*c == '\\')
                                          ++c;
                                   if (!*c)      return (-1);
                                   if ((int)(unsigned char)*c < ' ')
                                          return (-1);
                                   ++c;
                                   if (*c == ']')       break;
                                   if (*c != '-')       continue;
                                   ++c;

                                   if (*c == '\'' || *c == '"' ||
                                          *c == '`')
                                          return (-1); /* must be quoted*/
                                   if (*c == '\\')
                                          ++c;
                                   if ((int)(unsigned char)*c < ' ')
                                          return (-1);
                                   if (!*c)      return (-1);
                                   ++c;
                                   if (*c == ']')       break;
                            }
                            ++c;
                            continue;
                     }

                     if (*c == '\\')
                     {
                            if (type == hasrecipient)   return (-1);
                            ++c;
                     }
                     if (!*c)      return (-1);
                     ++c;
              }

#if HAVE_PCRE_H
              switch (type) {
              case contains:
              case startswith:
              case endswith:
                     {
                            const char *errptr;
                            int errindex;

                            pcre *p=pcre_compile(value, 0,
                                               &errptr,
                                               &errindex,
                                               0);


                            if (p == NULL)
                                   return -1;
                            pcre_free(p);
                     }
                     break;
              default:
                     break;
              }
#endif
       }

       /* validate FROM header */

       *errcode=MF_ERR_BADFROMHDR;

       while (fromhdr && *fromhdr && isspace((int)(unsigned char)*fromhdr))
              ++fromhdr;

       for (c=fromhdr; *c; c++)
              if ((int)(unsigned char)*c < ' ')
                     return (-1);

       *errcode=MF_ERR_BADRULEFOLDER;

       /* validate name of destination folder */

       c=folder;
       if (!c)       return (-1);
       if (strlen(c) > 200) return (-1);

       if (*c == '*' || *c == '!')
       {
              /* Forward, or bounce with an error */

              ++c;
              for ( ; *c; c++)
              {
                     if (strchr("'\"$\\`;(){}#&<>~", *c) ||
                            (unsigned char)*c < ' ')
                            return (-1);
              }
       }
       else if (*c == '+')  /* Autorespond */
       {
              struct maildir_filter_autoresp_info ai;

              if (maildir_filter_autoresp_info_init_str(&ai, c+1))
                     return (-1);

              maildir_filter_autoresp_info_free(&ai);
       }
       else if (strcmp(c, "exit") == 0)   /* Purge */
       {
       }
       else
       {
              char *s;

              if (strcmp(c, INBOX) &&
                  strncmp(c, INBOX ".", sizeof(INBOX)))
                     return -1;

              s=maildir_name2dir(".", c);

              if (!s)
                     return -1;
              free(s);
       }

       /* OK, we're good */

       *errcode=MF_ERR_INTERNAL;

       if (p->rulename)     free(p->rulename);
       if ((p->rulename=strdup(name)) == 0)      return (-1);
       p->type=type;
       if (p->fieldname)    free(p->fieldname);
       if ((p->fieldname=strdup(header ? header:"")) == 0)     return (-1);
       if (p->fieldvalue)   free(p->fieldvalue);
       if ((p->fieldvalue=strdup(value ? value:"")) == 0)      return (-1);
       if (p->tofolder)     free(p->tofolder);
       if ((p->tofolder=malloc(strlen(folder)+1)) == 0) return (-1);
       strcpy(p->tofolder, folder);

       if (p->fromhdr)             free(p->fromhdr);
       if ((p->fromhdr=strdup(fromhdr ? fromhdr:"")) == NULL)
              return (-1);

       p->flags=flags;
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_filter_savemaildirfilter ( struct maildirfilter ,
const char *  ,
const char *   
)

Definition at line 189 of file maildirfilter2.c.

{
       const char *maildirpath=maildir_filter_config(maildir, "MAILDIR");
       struct maildir_tmpcreate_info createInfo;
       int fd, rc;

       if (!maildirpath || !*maildirpath)
       {
              errno=EINVAL;
              return (-1);
       }

       maildir_tmpcreate_init(&createInfo);
       createInfo.maildir=maildir;
       createInfo.uniq="maildirfilter-tmp";
       createInfo.doordie=1;

       if ((fd=maildir_tmpcreate_fd(&createInfo)) < 0)
              return -1;

       close(fd);
       unlink(createInfo.tmpname);

       strcat(strcpy(createInfo.newname, maildir), "/maildirfilter.tmp");

       rc=maildir_filter_saverules(mf, createInfo.tmpname,
                                maildir, maildirpath, from);
       if (rc == 0 && rename(createInfo.tmpname, createInfo.newname))
              rc= -1;
       maildir_tmpcreate_free(&createInfo);
       return (rc);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_filter_saverules ( struct maildirfilter ,
const char *  ,
const char *  ,
const char *  ,
const char *   
)

Definition at line 439 of file maildirfilter.c.

{
FILE   *f=fopen(filename, "w");
struct maildirfilterrule *p;

       if (!f)       return (-1);

       fprintf(f,    "#MFMAILDROP=2\n"
                     "#\n"
                     "# DO NOT EDIT THIS FILE.  This is an automatically"
                                          " generated filter.\n"
                     "\n");

       for (fprintf(f, "FROM='"); *fromaddr; fromaddr++)
       {
              if (*fromaddr == '\'' || *fromaddr == '\\')
                     putc('\\', f);
              putc(*fromaddr, f);
       }
       fprintf(f, "\'\n");

       for (p=r->first; p; p=p->next)
       {
       const char *fieldname=p->fieldname ? p->fieldname:"";
       const char *fieldvalue=p->fieldvalue ? p->fieldvalue:"";
       const char *tofolder=p->tofolder ? p->tofolder:"";

              fprintf(f, "##Op:%s\n",
                     typelist[p->type].name);
              fprintf(f, "##Header:%s\n", fieldname);
              fprintf(f, "##Value:%s\n", fieldvalue);
              fprintf(f, "##Folder:%s\n",
                     strcmp(tofolder, INBOX) == 0 ? ".":
                     strncmp(tofolder, INBOX ".", sizeof(INBOX)) == 0
                     ? strchr(tofolder, '.'):tofolder);
              fprintf(f, "##From:%s\n", p->fromhdr ? p->fromhdr:"");

              if (p->flags & MFR_PLAINSTRING)
                     fprintf(f, "##PlainString\n");
              if (p->flags & MFR_DOESNOT)
                     fprintf(f, "##DoesNot\n");
              if (p->flags & MFR_BODY)
                     fprintf(f, "##Body\n");
              if (p->flags & MFR_CONTINUE)
                     fprintf(f, "##Continue\n");

              fprintf(f, "##Name:%s\n\n", p->rulename ? p->rulename:"");

              fprintf(f, "\nif (");

              if (p->flags & MFR_DOESNOT)
                     fprintf(f, "!");
              fprintf(f, "(");

              switch (p->type)     {
              case startswith:
                     if (p->flags & MFR_BODY)
                     {
                            fprintf(f, "/^");
                            print_pattern(f, p->flags, fieldvalue);
                            fprintf(f, "/:b");
                     }
                     else
                     {
                            fprintf(f, "/^%s: *", fieldname);
                            print_pattern(f, p->flags, fieldvalue);
                            fprintf(f, "/");
                     }
                     break;
              case endswith:
                     if (p->flags & MFR_BODY)
                     {
                            fprintf(f, "/");
                            print_pattern(f, p->flags, fieldvalue);
                            fprintf(f, "$/:b");
                     }
                     else
                     {
                            fprintf(f, "/^%s:.*", fieldname);
                            print_pattern(f, p->flags, fieldvalue);
                            fprintf(f, "$/");
                     }
                     break;
              case contains:
                     if (p->flags & MFR_BODY)
                     {
                            fprintf(f, "/");
                            print_pattern(f, p->flags, fieldvalue);
                            fprintf(f, "/:b");
                     }
                     else
                     {
                            fprintf(f, "/^%s:.*", fieldname);
                            print_pattern(f, p->flags, fieldvalue);
                            fprintf(f, "/");
                     }
                     break;
              case hasrecipient:
                     fprintf(f, "hasaddr(\"%s\")", fieldvalue);
                     break;
              case mimemultipart:
                     fprintf(f, "/^Content-Type: *multipart\\/mixed/");
                     break;
              case textplain:
                     fprintf(f, " (! /^Content-Type:/) || "
                                   "/^Content-Type: text\\/plain$/ || "
                                   "/^Content-Type: text\\/plain;/");
                     break;
              case islargerthan:
                     fprintf(f, "$SIZE > %s", fieldvalue);
                     break;
              case anymessage:
                     fprintf(f, "1");
                     break;
              }
              fprintf(f, "))\n"
                     "{\n");

              if (*tofolder == '!')
              {
                     fprintf(f, "    %s \"| $SENDMAIL -f \" '\"\"' \" %s\"\n",
                            p->flags & MFR_CONTINUE ? "cc":"to",
                                   tofolder+1);
              }
              else if (*tofolder == '*')
              {
                     fprintf(f, "    echo \"%s\"\n"
                            "    EXITCODE=%d\n"
                            "    exit\n", tofolder+1, EX_SOFTWARE);
              }
              else if (*tofolder == '+')
              {
                     struct maildir_filter_autoresp_info ai;

                     if (maildir_filter_autoresp_info_init_str(&ai, tofolder+1) == 0)
                     {
                            if (p->fromhdr && p->fromhdr[0])
                            {
                                   const char *cp;

                                   fprintf(f, "    AUTOREPLYFROM='");


                                   for (cp=p->fromhdr; *cp; ++cp)
                                   {
                                          if (*cp == '\'' || *cp == '\\')
                                                 putc('\\', f);
                                          putc(*cp, f);
                                   }
                                   fprintf(f, "'\n");
                            }
                            else
                                   fprintf(f, "    AUTOREPLYFROM=\"$FROM\"\n"
                                          );

                            fprintf(f, "   `%s -A \"X-Sender: $FROM\""
                                   " -A \"From: $AUTOREPLYFROM\"",
                                   MAILBOT);
                            if (ai.dsnflag)
                                   fprintf(f, " -M \"$FROM\"");
                            fprintf(f, " -m \"%s/autoresponses/%s\"",
                                   maildirpath, ai.name);
                            if (ai.noquote)
                                   fprintf(f, " -N");
                            if (ai.days > 0)
                                   fprintf(f,
                                          " -d \"%s/autoresponses/"
                                          "%s.dat\" -D %u",
                                   maildirpath, ai.name, ai.days);
                            fprintf(f, " $SENDMAIL -t -f \"\"`\n");
                            maildir_filter_autoresp_info_free(&ai);
                     }
              }
              else if (strcmp(tofolder, "exit") == 0)
              {
                     fprintf(f, "    exit\n");
              }
              else
              {
                     char *s;

                     s=maildir_name2dir(maildirpath, tofolder);

                     if (!s)
                            fprintf(f, "  # INTERNAL ERROR in maildir_name2dir\n");
                     else
                     {
                            fprintf(f,
                                   "   %s \"%s/.\"\n",
                                   p->flags & MFR_CONTINUE ? "cc":"to",
                                   s);
                            free(s);
                     }
              }
              fprintf(f, "}\n\n");
       }
       fflush(f);
       if (ferror(f))
       {
              fclose(f);
              return (-1);
       }
       fprintf(f, "to \"%s/.\"\n", maildirpath);
       if (fclose(f))
              return (-1);
       if (chmod(filename, 0600))
              return (-1);

       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_filter_setautoreplyfrom ( struct maildirfilter ,
const char *   
)