Back to index

courier  0.68.2
comrwmsg.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      "courier.h"
00007 #include      "rw.h"
00008 #include      "rwint.h"
00009 #include      <stdio.h>
00010 #include      <ctype.h>
00011 #include      <string.h>
00012 #include      <stdlib.h>
00013 
00014 void rw_rewrite_msg_init(struct rwmsginfo *rwinfo,
00015        int (*writefunc)(const char *p, unsigned l, void *),
00016        void (*rewritefunc)(struct rw_info *,
00017               void (*)(struct rw_info *), void *),
00018        void *arg)
00019 {
00020        memset(rwinfo, 0, sizeof(*rwinfo));
00021 
00022        rwinfo->inheaders=1;
00023        rwinfo->writefunc=writefunc;
00024        rwinfo->rewritefunc=rewritefunc;
00025        rwinfo->arg=arg;
00026 }
00027 
00028 int rw_rewrite_msg_finish(struct rwmsginfo *rwinfo)
00029 {
00030 int    j=0;
00031 
00032        while (rwinfo->inheaders)
00033        {
00034               if (rw_rewrite_msgheaders("\n", 1, rwinfo))
00035               {
00036                      j= -1;
00037                      break;
00038               }
00039        }
00040 
00041        if (rwinfo->headerbuf)
00042               free(rwinfo->headerbuf);
00043        return (j);
00044 }
00045 
00046 static void add2header(const char *, unsigned, struct rwmsginfo *);
00047 static int dorewriteheader(struct rwmsginfo *);
00048 
00049 int rw_rewrite_msgheaders(const char *p, unsigned l,
00050        struct rwmsginfo *msginfo)
00051 {
00052        while (msginfo->inheaders)
00053        {
00054               if (l == 0)   return (0);
00055 
00056               while (l)
00057               {
00058               unsigned i;
00059 
00060                      if (*p == '\n')
00061                      {
00062                             if (msginfo->lastnl)
00063                             {
00064                                    if (dorewriteheader(msginfo))
00065                                           return (-1);
00066                                    msginfo->inheaders=0;
00067                                    break;
00068                             }
00069                             add2header(p, 1, msginfo);
00070                             msginfo->lastnl=1;
00071                             ++p;
00072                             --l;
00073                             continue;
00074                      }
00075 
00076                      if (msginfo->lastnl)
00077                      {
00078                             if (!isspace((int)(unsigned char)*p))
00079                                    if (dorewriteheader(msginfo))
00080                                           return (-1);
00081                             msginfo->lastnl=0;
00082                      }
00083 
00084                      for (i=0; i < l; i++)
00085                             if (p[i] == '\n')
00086                                    break;
00087                      add2header(p, i, msginfo);
00088                      p += i;
00089                      l -= i;
00090               }
00091        }
00092 
00093        return ((*msginfo->writefunc)(p, l, msginfo->arg));
00094 }
00095 
00096 static void add2header(const char *p, unsigned l, struct rwmsginfo *msginfo)
00097 {
00098        if (l + msginfo->headerbuflen > msginfo->headerbufsize)
00099        {
00100        unsigned ll=(msginfo->headerbufsize + l + 1023) & ~1023;
00101        char   *buf=courier_malloc(ll);
00102 
00103               if (msginfo->headerbufsize)
00104                      memcpy(buf, msginfo->headerbuf, msginfo->headerbufsize);
00105               if (msginfo->headerbuf)     free(msginfo->headerbuf);
00106               msginfo->headerbuf=buf;
00107               msginfo->headerbufsize=ll;
00108        }
00109        memcpy(msginfo->headerbuf+msginfo->headerbuflen, p, l);
00110        msginfo->headerbuflen += l;
00111 }
00112 
00113 static int dorewriteheader(struct rwmsginfo *msginfo)
00114 {
00115        add2header("", 1, msginfo);
00116 
00117        if ( DO_REWRITE_HEADER(msginfo->headerbuf))
00118        {
00119        char *s, *t;
00120        char   *errmsgbuf=0;
00121 
00122               s=rw_rewrite_header_func( msginfo->rewritefunc,
00123                         msginfo->headerbuf,
00124                         RW_OUTPUT|RW_HEADER,
00125                         0,
00126                         &errmsgbuf,
00127                      msginfo->arg);
00128 
00129               if (errmsgbuf)  free(errmsgbuf);
00130               if (s)
00131               {
00132                      if ((*msginfo->writefunc)(s, strlen(s),
00133                             msginfo->arg)) return (-1);
00134                      t=strrchr(s, '\n');
00135                      if (!t || t[1])
00136                             if ((*msginfo->writefunc)("\n", 1,
00137                                    msginfo->arg)) return (-1);
00138                      free(s);
00139                      msginfo->headerbuflen=0;
00140                      return (0);
00141               }
00142        }
00143        if ((*msginfo->writefunc)(msginfo->headerbuf, msginfo->headerbuflen-1,
00144                             msginfo->arg))
00145               return (-1);
00146        msginfo->headerbuflen=0;
00147        return (0);
00148 }