Back to index

courier  0.68.2
dotforward.c
Go to the documentation of this file.
00001 /*
00002 ** Copyright 1998 - 2000 Double Precision, Inc.
00003 ** See COPYING for distribution information.
00004 */
00005 
00006 #include      "config.h"
00007 #include      "courier.h"
00008 #include      "rfc822/rfc822.h"
00009 #include      <stdio.h>
00010 #include      <stdlib.h>
00011 #include      <string.h>
00012 #include      <ctype.h>
00013 #include      <sysexits.h>
00014 #if    HAVE_UNISTD_H
00015 #include      <unistd.h>
00016 #endif
00017 
00018 
00019 struct delivered_to {
00020        struct delivered_to *next;
00021        char *addr;
00022        } *delivtolist=0;
00023 char *myaddr;
00024 static int exit_code;
00025 
00026 /*
00027 ** Extract and save all addresses in the Delivered-To: header.
00028 */
00029 
00030 static void initdelivto()
00031 {
00032 char   buf[BUFSIZ];
00033 char   *p, *r;
00034 struct delivered_to *q;
00035 
00036        p=getenv("DTLINE");
00037        if (!p || !(p=strchr(p, ':')))     exit(0);
00038        ++p;
00039        while (*p && isspace((int)(unsigned char)*p))    ++p;
00040        myaddr=strdup(p);
00041        if (!myaddr)
00042        {
00043               perror("malloc");
00044               exit(EX_TEMPFAIL);
00045        }
00046        domainlower(myaddr);
00047        locallower(myaddr);
00048        if (strchr(myaddr, '@') == 0)
00049        {
00050               fprintf(stderr, "Invalid DTLINE environment variable.\n");
00051               exit(EX_TEMPFAIL);
00052        }
00053 
00054        while (fgets(buf, sizeof(buf), stdin))
00055        {
00056               p=strchr(buf, '\n');
00057               if (p) *p=0;
00058               if (strncasecmp(buf, "Delivered-To:", 13))       continue;
00059               p=buf+13;
00060               while (*p && isspace((int)(unsigned char)*p))    ++p;
00061               q=malloc(sizeof(*q)+1+strlen(p));
00062               if (!q)
00063               {
00064                      perror("malloc");
00065                      exit(EX_TEMPFAIL);
00066               }
00067               strcpy(q->addr=(char *)(q+1), p);
00068               q->next=delivtolist;
00069               delivtolist=q;
00070               domainlower(q->addr);
00071               r=strchr(q->addr, '@');
00072               if (!r || config_islocal(r+1, 0))
00073                      locallower(q->addr);
00074        }
00075 }
00076 
00077 static void readforward(FILE *f, int n)
00078 {
00079 char   buf[BUFSIZ];
00080 char   *p;
00081 struct rfc822t *t;
00082 struct rfc822a *a;
00083 int    i;
00084 char   *sep;
00085 
00086        while (fgets(buf, sizeof(buf), f))
00087        {
00088               p=strchr(buf, '\n');
00089               if (p) *p=0;
00090               p=buf;
00091               while (*p && isspace((int)(unsigned char)*p))    ++p;
00092               if (strncmp(p, ":include:",  9) == 0)
00093               {
00094               FILE   *g;
00095 
00096                      if (n > 10)
00097                      {
00098                             fprintf(stderr, "dotforward: too many :include files.\n");
00099                             exit(EX_NOUSER);
00100                      }
00101 
00102                      p += 9;
00103                      while (*p && isspace((int)(unsigned char)*p))    ++p;
00104                      if (!*p)      continue;
00105                      g=fopen(p, "r");
00106                      if (!g)
00107                      {
00108                             perror(p);
00109                             exit(EX_NOUSER);
00110                      }
00111                      readforward(g, n+1);
00112                      fclose(g);
00113                      continue;
00114               }
00115               if (*p == '|' || *p == '/' || *p == '.')
00116               {
00117                      printf("%s\n", p);
00118                      continue;
00119               }
00120               t=rfc822t_alloc_new(p, NULL, NULL);
00121               if (!t || !(a=rfc822a_alloc(t)))
00122               {
00123                      perror("malloc");
00124                      exit(EX_NOUSER);
00125               }
00126 
00127               for (i=0; i<a->naddrs; i++)
00128               {
00129                      if (a->addrs[i].tokens &&
00130                          a->addrs[i].tokens->token == '"' &&
00131                          a->addrs[i].tokens->next == NULL)
00132                             a->addrs[i].tokens->token=0;
00133 
00134                      p=rfc822_getaddr(a, i);
00135                      if (!p)
00136                      {
00137                             perror("malloc");
00138                             exit(EX_NOUSER);
00139                      }
00140                      if (*p == '|' || *p == '/')
00141                      {
00142                             printf("%s\n", p);
00143                      }
00144                      free(p);
00145               }
00146               sep=0;
00147               for (i=0; i<a->naddrs; i++)
00148               {
00149               char   *q, *r;
00150               struct delivered_to *s;
00151               char   *t;
00152               char   *orig;
00153 
00154                      p=rfc822_getaddr(a, i);
00155                      if (!p)
00156                      {
00157                             perror("malloc");
00158                             exit(EX_NOUSER);
00159                      }
00160                      if (*p == '|' || *p == '/' || *p == '.')
00161                      {
00162                             free(p);
00163                             continue;
00164                      }
00165                      q=p;
00166                      if (*q == '\\')
00167                             ++q;
00168 
00169                      r=strchr(q, '@');
00170                      if (!r || config_islocal(r+1, 0))
00171                             locallower(q);
00172                      domainlower(q);
00173                      t=0;
00174                      orig=q;
00175 
00176                      if (strchr(q, '@') == 0)
00177                      {
00178                             t=malloc(strlen(q)+1+strlen(myaddr));
00179                                    /* overkill, yeah */
00180                             if (!t)
00181                             {
00182                                    perror("malloc");
00183                                    exit(EX_NOUSER);
00184                             }
00185                             strcat(strcpy(t, q), strchr(myaddr, '@'));
00186                             q=t;
00187                      }
00188 
00189                      if (strcmp(myaddr, q) == 0)
00190                      {
00191                             exit_code=0;
00192                             free(p);
00193                             if (t) free(t);
00194                             continue;
00195                      }
00196 
00197                      for (s=delivtolist; s; s=s->next)
00198                      {
00199                             if (strcmp(s->addr, q) == 0)
00200                                    break;
00201                      }
00202                      if (!s)
00203                      {
00204                             if (sep)      printf("%s", sep);
00205                             else   printf("!");
00206                             sep=", ";
00207                             printf("%s", orig);
00208                      }
00209                      free(p);
00210                      if (t) free(t);
00211               }
00212               if (sep)      printf("\n");
00213               rfc822a_free(a);
00214               rfc822t_free(t);
00215        }
00216 }
00217 
00218 int main(int argc, char **argv)
00219 {
00220 char   *homedir;
00221 FILE   *f;
00222 
00223        homedir=getenv("HOME");
00224        if (!homedir) exit(0);
00225        if (chdir(homedir))
00226        {
00227               perror(homedir);
00228               exit(EX_TEMPFAIL);
00229        }
00230        if ((f=fopen(".forward", "r")) == 0)
00231               exit (0);
00232        initdelivto();
00233        exit_code=99;
00234        readforward(f, 0);
00235        exit(exit_code);
00236 }