Back to index

courier  0.68.2
lcrewrite.c
Go to the documentation of this file.
00001 /*
00002 ** Copyright 1998 - 2002 Double Precision, Inc.
00003 ** See COPYING for distribution information.
00004 */
00005 
00006 #include      "courier.h"
00007 #include      "rw.h"
00008 #include      "rfc822.h"
00009 #include      <stdlib.h>
00010 #include      <string.h>
00011 #include      <ctype.h>
00012 
00013 
00014 /*
00015 **    Address rewriting rules.
00016 */
00017 
00018        /* Tokenize text for RFC822 parsing */
00019 
00020 struct rfc822t *rw_rewrite_tokenize(const char *address)
00021 {
00022 struct rfc822t *tokens=rfc822t_alloc_new(address, NULL, NULL);
00023 int    i;
00024 
00025        if (!tokens)  clog_msg_errno();
00026        for (i=1; i<tokens->ntokens; i++)
00027               tokens->tokens[i-1].next=tokens->tokens+i;
00028        return (tokens);
00029 }
00030 
00031        /* Call a transport module's rewrite function */
00032 
00033 void rw_rewrite_module(struct rw_transport *module,
00034        struct rw_info *rwi, void (*func)(struct rw_info *))
00035 {
00036        if (!module || !module->rw_ptr)
00037               (*rwi->err_func)(450, "Internal failure.", rwi);
00038        else if (module->rw_ptr->rewrite_del)
00039               (*module->rw_ptr->rewrite)(rwi, func);
00040        else
00041               (*rwi->err_func)(550, "Invalid address.", rwi);
00042 }
00043 
00044 int rw_syntaxchk(struct rfc822token *t)
00045 {
00046 int    cnt;
00047 
00048        /*
00049        ** The following tokens:  ! @ % : . may NOT:
00050        **
00051        ** a) appear next to each other, and b) appear at the beginning or
00052        ** the end of the address.
00053        **
00054        */
00055        if (!t)       return (0);   /* <> envelope sender ok */
00056 
00057        cnt=1;
00058 
00059        while (t)
00060        {
00061               switch (t->token)    {
00062               case '<':
00063               case '>':
00064               case ';':
00065               case '(':
00066               case ')':
00067                      return (-1);  /* These cannot appear anywhere */
00068               case '!':
00069               case '@':
00070               case '%':
00071               case ':':
00072               case '.':
00073                      if (++cnt > 1)       return (-1);
00074                      break;
00075               case 0:
00076               case '"':
00077                      {
00078                             int i;
00079 
00080                             for (i=0; i<t->len; i++)
00081                             {
00082                                    unsigned char c=t->ptr[i];
00083 
00084                                    if (isspace((int)c) || c < ' ')
00085                                           return (-1);
00086                             }
00087                      }
00088               default:
00089                      cnt=0;
00090                      break;
00091               }
00092               t=t->next;
00093        }
00094        if (cnt)      return (-1);
00095        return (0);
00096 }
00097 
00098        /* Common rewrite tail function to convert RFC822 tokens back into
00099        ** a text string.
00100        */
00101 void rw_rewrite_print(struct rw_info *info)
00102 {
00103 char   *p=rfc822_gettok(info->ptr);
00104 
00105        if (!p)              clog_msg_errno();
00106 
00107        ( (struct rw_info_rewrite *)info->udata)->buf=p;
00108 }
00109 
00110 static void do_rw_rewrite_chksyn_print(struct rw_info *info,
00111                                    struct rfc822token *t)
00112 {
00113        if (rw_syntaxchk(t))
00114        {
00115        static const char errmsg[]="Syntax error: ";
00116        char   *addr=rfc822_gettok(info->ptr);
00117        char   *buf;
00118 
00119               if (!addr)    clog_msg_errno();
00120               buf=courier_malloc(strlen(addr)+sizeof(errmsg));
00121               strcat(strcpy(buf, errmsg), addr);
00122               free(addr);
00123               (*info->err_func)(553, buf, info);
00124               free(buf);
00125        }
00126        else
00127               rw_rewrite_print(info);
00128 }
00129 
00130 void rw_rewrite_chksyn_print(struct rw_info *info)
00131 {
00132        do_rw_rewrite_chksyn_print(info, info->ptr);
00133 }
00134 
00135 void rw_rewrite_chksyn_at_ok_print(struct rw_info *info)
00136 {
00137        struct rfc822token *t=info->ptr;
00138 
00139        if (t && t->token == '@')
00140               t=t->next;
00141 
00142        do_rw_rewrite_chksyn_print(info, t);
00143 }
00144