Back to index

courier  0.68.2
mimegpgheader.c
Go to the documentation of this file.
00001 /*
00002 ** Copyright 2001 Double Precision, Inc.  See COPYING for
00003 ** distribution information.
00004 */
00005 
00006 
00007 #include "config.h"
00008 #include <stdio.h>
00009 #include <stdlib.h>
00010 #include <string.h>
00011 #include <ctype.h>
00012 #include <errno.h>
00013 #include "mimegpgheader.h"
00014 
00015 void libmail_readheader_init(struct read_header_context *cts)
00016 {
00017        cts->continue_header=0;
00018        cts->header_len=0;
00019        cts->first=0;
00020        cts->last=0;
00021 }
00022 
00023 int libmail_readheader(struct read_header_context *cts, const char *buf)
00024 {
00025        int l;
00026        char *s;
00027        struct header *p;
00028 
00029        l=strlen(buf);
00030        p=0;
00031 
00032        if (cts->continue_header)
00033               p=cts->last;
00034        else if (isspace((int)(unsigned char)buf[0]))
00035               p=cts->last;
00036 
00037        if (!p)
00038        {
00039               p=(struct header *)malloc(sizeof(*p));
00040               if (!p)
00041                      return -1;
00042 
00043               p->next=0;
00044               p->header=0;
00045               cts->header_len=0;
00046               if (cts->last)
00047                      cts->last->next=p;
00048               else
00049                      cts->first=p;
00050               cts->last=p;
00051        }
00052 
00053        s=p->header ? realloc(p->header, cts->header_len + l + 1)
00054               :malloc(l+1);
00055 
00056        if (!s)
00057               return (-1);
00058 
00059        strcpy(s+cts->header_len, buf);
00060        cts->header_len += l;
00061        p->header=s;
00062 
00063        cts->continue_header=!l || buf[l-1] != '\n';
00064 
00065        return 0;
00066 }
00067 
00068 struct header *libmail_readheader_finish(struct read_header_context *cts)
00069 {
00070        struct header *last;
00071 
00072        for (last=cts->first; last; last=last->next)
00073        {
00074               char *q, *r;
00075 
00076               if (!last->header)
00077                      continue;
00078 
00079               for (q=r=last->header; *r; r++)
00080               {
00081                      if (*r == '\r')
00082                             continue;
00083                      *q++ = *r;
00084               }
00085               *q=0;
00086        }
00087        return (cts->first);
00088 }
00089 
00090 void libmail_header_free(struct header *p)
00091 {
00092        struct header *q;
00093 
00094        while (p)
00095        {
00096               q=p->next;
00097               if (p->header)
00098                      free(p->header);
00099               free(p);
00100               p=q;
00101        }
00102 }
00103 
00104 struct header *libmail_header_find(struct header *p, const char *n)
00105 {
00106        int l=strlen(n);
00107 
00108        while (p)
00109        {
00110               if (p->header && strncasecmp(p->header, n, l) == 0)
00111                      return (p);
00112               p=p->next;
00113        }
00114        return (p);
00115 }
00116 
00117 const char *libmail_header_find_txt(struct header *p, const char *n)
00118 {
00119        p=libmail_header_find(p, n);
00120        if (p)
00121               return (p->header+strlen(n));
00122        return (NULL);
00123 }
00124 
00125 void libmail_mimeheader_free(struct mime_header *m)
00126 {
00127        struct mime_attribute *a;
00128 
00129        while ((a=m->attr_list) != 0)
00130        {
00131               m->attr_list=a->next;
00132               if (a->name)
00133                      free(a->name);
00134               if (a->value)
00135                      free(a->value);
00136               free(a);
00137        }
00138        free(m->header_name);
00139        free(m);
00140 }
00141 
00142 static void striptrlspc(char *p)
00143 {
00144        char *q;
00145 
00146        for (q=p; *p; p++)
00147               if (!isspace((int)(unsigned char)*p))
00148                      q=p+1;
00149        *q=0;
00150 }
00151 
00152 struct mime_header *libmail_mimeheader_parse(const char *field)
00153 {
00154        struct mime_header *header=0;
00155        struct mime_attribute *last_attr=0;
00156 
00157        while (*field || header == 0)
00158        {
00159               const char *p;
00160 
00161               if (*field && isspace((int)(unsigned char)*field))
00162               {
00163                      ++field;
00164                      continue;
00165               }
00166               for (p=field; *p; p++)
00167               {
00168                      if (*p == ';')
00169                             break;
00170                      if (*p == '=' && header)
00171                             break;
00172               }
00173 
00174               if (!header)
00175               {
00176                      if ((header=(struct mime_header *)
00177                           malloc(sizeof(*header))) == 0)
00178                             return NULL;
00179 
00180                      if ((header->header_name=malloc(p-field+1)) == 0)
00181                      {
00182                             free(header);
00183                             return (NULL);
00184                      }
00185                      memcpy(header->header_name, field, p-field);
00186                      header->header_name[p-field]=0;
00187                      header->attr_list=NULL;
00188                      striptrlspc(header->header_name);
00189                      field=p;
00190               }
00191               else
00192               {
00193                      struct mime_attribute *a=(struct mime_attribute *)
00194                             malloc(sizeof(struct mime_attribute));
00195                      int pass, len;
00196                      char *s=0;
00197 
00198                      if (!a)
00199                      {
00200                             libmail_mimeheader_free(header);
00201                             return NULL;
00202                      }
00203                      if ((a->name=malloc(p-field+1)) == NULL)
00204                      {
00205                             free(a);
00206                             libmail_mimeheader_free(header);
00207                             return NULL;
00208                      }
00209                      memcpy(a->name, field, p-field);
00210                      a->name[p-field]=0;
00211                      striptrlspc(a->name);
00212                      a->value=0;
00213                      a->next=0;
00214                      if (last_attr)
00215                      {
00216                             last_attr->next=a;
00217                      }
00218                      else
00219                      {
00220                             header->attr_list=a;
00221                      }
00222                      last_attr=a;
00223 
00224                      if (*p == '=')
00225                             ++p;
00226 
00227                      while (*p && isspace((int)(unsigned char)*p))
00228                      {
00229                             ++p;
00230                      }
00231 
00232                      field=p;
00233 
00234                      len=0;
00235                      for (pass=0; pass<2; pass++)
00236                      {
00237                             int quote=0;
00238 
00239                             if (pass)
00240                             {
00241                                    s=a->value=malloc(len);
00242                                    if (!s)
00243                                    {
00244                                           libmail_mimeheader_free(header);
00245                                           return NULL;
00246                                    }
00247                             }
00248                             len=0;
00249 
00250                             for (p=field; *p; )
00251                             {
00252                                    if (*p == ';' && !quote)
00253                                    {
00254                                           break;
00255                                    }
00256 
00257                                    if (*p == '"')
00258                                    {
00259                                           quote= !quote;
00260                                           ++p;
00261                                           continue;
00262                                    }
00263 
00264                                    if (*p == '\\' && p[1])
00265                                           ++p;
00266 
00267                                    if (pass)
00268                                           s[len]= *p;
00269                                    ++len;
00270                                    ++p;
00271                             }
00272                             if (pass)
00273                                    s[len]=0;
00274                             ++len;
00275                      }
00276 
00277                      striptrlspc(a->value);
00278                      field=p;
00279                      if (a->value[0] == 0)
00280                      {
00281                             free(a->value);
00282                             a->value=0;
00283                      }
00284               }
00285               if (*field == ';')
00286                      ++field;
00287        }
00288 
00289        return (header);
00290 }
00291 
00292 const char *libmail_mimeheader_getattr(struct mime_header *m, const char *name)
00293 {
00294        struct mime_attribute *a;
00295 
00296        for (a=m->attr_list; a; a=a->next)
00297        {
00298               if (strcasecmp(a->name, name) == 0)
00299                      return (a->value);
00300        }
00301        return (0);
00302 }
00303 
00304 #if 0
00305 void libmail_mimeheader_setattr(struct mime_header *m,
00306                             const char *name, const char *value)
00307 {
00308        struct mime_attribute *a, *lasta=0;
00309 
00310        for (a=m->attr_list; a; a=a->next)
00311        {
00312               if (strcasecmp(a->name, name) == 0)
00313               {
00314                      if (a->value)
00315                             free(a->value);
00316                      a->value=0;
00317                      if (value)
00318                      {
00319                             a->value=strdup(value);
00320                             if (!a->value)
00321                             {
00322                                    perror("strdup");
00323                                    exit(1);
00324                             }
00325                      }
00326                      return;
00327               }
00328               lasta=a;
00329        }
00330 
00331        a=(struct mime_attribute *)malloc(sizeof(struct mime_attribute));
00332        if (!a)
00333        {
00334               perror("malloc");
00335               exit(1);
00336        }
00337        if (!(a->name=strdup(name)))
00338        {
00339               free(a);
00340               perror("malloc");
00341               exit(1);
00342        }
00343 
00344        a->value=0;
00345        a->next=0;
00346        if (value && !(a->value=strdup(value)))
00347        {
00348               free(a->name);
00349               free(a);
00350               perror("malloc");
00351               exit(1);
00352        }
00353 
00354        if (lasta)
00355               lasta->next=a;
00356        else
00357               m->attr_list=a;
00358 }
00359 
00360 void print_mime_header(FILE *f, struct mime_header *m)
00361 {
00362        struct mime_attribute *a;
00363 
00364        fprintf(f, "%s", m->header_name);
00365 
00366        for (a=m->attr_list; a; a=a->next)
00367        {
00368               const char *p;
00369 
00370               fprintf(f, "; %s%s", a->name, a->value ? "=":"");
00371               if (!a->value)
00372                      continue;
00373 
00374               for (p=a->value; *p; p++)
00375                      if (strchr("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_", *p) == NULL)
00376                             break;
00377 
00378               if (!*p)
00379               {
00380                      fprintf(f, "%s", a->value);
00381                      continue;
00382               }
00383               putc('"', f);
00384               for (p=a->value; *p; p++)
00385               {
00386                      if (*p == '"' || *p == '\\')
00387                             putc('\\', f);
00388                      putc(*p, f);
00389               }
00390               putc('"', f);
00391        }
00392 }
00393 #endif