Back to index

courier  0.68.2
msgbodystructure.c
Go to the documentation of this file.
00001 /*
00002 ** Copyright 1998 - 2001 Double Precision, Inc.
00003 ** See COPYING for distribution information.
00004 */
00005 
00006 #if    HAVE_CONFIG_H
00007 #include      "config.h"
00008 #endif
00009 #include      "imaptoken.h"
00010 #include      "imapwrite.h"
00011 #include      "rfc822/rfc822.h"
00012 #include      "rfc2045/rfc2045.h"
00013 #include      <stdio.h>
00014 #include      <ctype.h>
00015 #include      <stdlib.h>
00016 #include      <string.h>
00017 
00018 
00019 extern void msgenvelope(void (*)(const char *, size_t),
00020               FILE *, struct rfc2045 *);
00021 
00022 extern void msgappends(void (*)(const char *, size_t), const char *, size_t);
00023 
00024 static void do_param_list(void (*writefunc)(const char *, size_t),
00025        struct rfc2045attr *a)
00026 {
00027 int    flag;
00028 char   *p;
00029 
00030        flag=0;
00031        p="(";
00032        for (; a; a=a->next)
00033        {
00034               (*writefunc)(p, strlen(p));
00035               (*writefunc)("\"", 1);
00036               if (a->name)
00037                      msgappends(writefunc, a->name, strlen(a->name));
00038               (*writefunc)("\" \"", 3);
00039               if (a->value)
00040               {
00041 #if    IMAP_CLIENT_BUGS
00042 
00043               /* NETSCAPE */
00044 
00045               char *u, *v, *w;
00046 
00047                      u=strdup(a->value);
00048                      if (!u)       write_error_exit(0);
00049                      strcpy(u, a->value);
00050                      for (v=w=u; *v; v++)
00051                             if (*v != '\\')      *w++ = *v;
00052                      *w=0;
00053                      msgappends(writefunc, u, strlen(u));
00054                      free(u);
00055 
00056 #else
00057                      msgappends(writefunc, a->value, strlen(a->value));
00058 #endif
00059               }
00060               (*writefunc)("\"", 1);
00061               flag=1;
00062               p=" ";
00063        }
00064        if (flag)
00065               (*writefunc)(")", 1);
00066        else
00067               (*writefunc)("NIL", 3);
00068 }
00069 
00070 static void contentstr( void (*writefunc)(const char *, size_t), const char *s)
00071 {
00072        if (!s || !*s)
00073        {
00074               (*writefunc)("NIL", 3);
00075               return;
00076        }
00077 
00078        (*writefunc)("\"", 1);
00079        msgappends(writefunc, s, strlen(s));
00080        (*writefunc)("\"", 1);
00081 }
00082 
00083 
00084 static void do_disposition(
00085        void (*writefunc)(const char *, size_t), const char *disposition_s,
00086        struct rfc2045attr *disposition_a)
00087 {
00088        if ( (disposition_s == 0 || *disposition_s == 0) &&
00089               disposition_a == 0)
00090        {
00091               (*writefunc)("NIL", 3);
00092               return;
00093        }
00094        (*writefunc)("(", 1);
00095 
00096        if (disposition_s && *disposition_s)
00097        {
00098               (*writefunc)("\"", 1);
00099               msgappends(writefunc, disposition_s,
00100                      strlen(disposition_s));
00101               (*writefunc)("\"", 1);
00102        }
00103        else
00104               (*writefunc)("\"\"", 2);
00105 
00106        (*writefunc)(" ", 1);
00107        do_param_list(writefunc, disposition_a);
00108        (*writefunc)(")", 1);
00109 }
00110 
00111 void msgbodystructure( void (*writefunc)(const char *, size_t), int dox,
00112        FILE *fp, struct rfc2045 *mimep)
00113 {
00114 const char *content_type_s;
00115 const char *content_transfer_encoding_s;
00116 const char *charset_s;
00117 off_t start_pos, end_pos, start_body;
00118 off_t nlines, nbodylines;
00119 const char *disposition_s;
00120 
00121 char   *p, *q;
00122 
00123        rfc2045_mimeinfo(mimep, &content_type_s, &content_transfer_encoding_s,
00124               &charset_s);
00125        rfc2045_mimepos(mimep, &start_pos, &end_pos, &start_body,
00126               &nlines, &nbodylines);
00127 
00128        disposition_s=mimep->content_disposition;
00129 
00130        (*writefunc)("(", 1);
00131 
00132        if (mimep->firstpart && mimep->firstpart->isdummy &&
00133               mimep->firstpart->next)
00134               /* MULTIPART */
00135        {
00136        struct rfc2045       *childp;
00137 
00138               for (childp=mimep->firstpart; (childp=childp->next) != 0; )
00139                      msgbodystructure(writefunc, dox, fp, childp);
00140 
00141               (*writefunc)(" \"", 2);
00142               p=strchr(content_type_s, '/');
00143               if (p)
00144                      msgappends(writefunc, p+1, strlen(p+1));
00145               (*writefunc)("\"", 1);
00146 
00147               if (dox)
00148               {
00149                      (*writefunc)(" ", 1);
00150                      do_param_list(writefunc, mimep->content_type_attr);
00151 
00152                      (*writefunc)(" ", 1);
00153                      do_disposition(writefunc, disposition_s,
00154                             mimep->content_disposition_attr);
00155 
00156                      (*writefunc)(" ", 1);
00157                      contentstr(writefunc, rfc2045_content_language(mimep));
00158               }
00159        }
00160        else
00161        {
00162        char   *mybuf;
00163        char   buf[40];
00164        const  char *cp;
00165 
00166               mybuf=my_strdup(content_type_s);
00167               q=strtok(mybuf, " /");
00168               (*writefunc)("\"", 1);
00169               if (q)
00170                      msgappends(writefunc, q, strlen(q));
00171               (*writefunc)("\" \"", 3);
00172               if (q) q=strtok(0, " /");
00173               if (q)
00174                      msgappends(writefunc, q, strlen(q));
00175               free(mybuf);
00176               (*writefunc)("\" ", 2);
00177 
00178               do_param_list(writefunc, mimep->content_type_attr);
00179 
00180               (*writefunc)(" ", 1);
00181               cp=rfc2045_content_id(mimep);
00182               if (!cp || !*cp)
00183                      contentstr(writefunc, cp);
00184               else
00185               {
00186                      (*writefunc)("\"<", 2);
00187                      msgappends(writefunc, cp, strlen(cp));
00188                      (*writefunc)(">\"", 2);
00189               }
00190               (*writefunc)(" ", 1);
00191               contentstr(writefunc, rfc2045_content_description(mimep));
00192 
00193               (*writefunc)(" \"", 2);
00194               msgappends(writefunc, content_transfer_encoding_s,
00195                      strlen(content_transfer_encoding_s));
00196               (*writefunc)("\" ", 2);
00197 
00198               sprintf(buf, "%lu", (unsigned long)
00199                      (end_pos-start_body+nbodylines));
00200                      /* nbodylines added for CRs */
00201               (*writefunc)(buf, strlen(buf));
00202 
00203               if (
00204               (content_type_s[0] == 't' || content_type_s[0] == 'T') &&
00205               (content_type_s[1] == 'e' || content_type_s[1] == 'E') &&
00206               (content_type_s[2] == 'x' || content_type_s[2] == 'X') &&
00207               (content_type_s[3] == 't' || content_type_s[3] == 'T') &&
00208                      (content_type_s[4] == '/' ||
00209                       content_type_s[4] == 0))
00210               {
00211                      (*writefunc)(" ", 1);
00212                      sprintf(buf, "%lu", (unsigned long)nbodylines);
00213                      (*writefunc)(buf, strlen(buf));
00214               }
00215 
00216               if (mimep->firstpart && !mimep->firstpart->isdummy)
00217                      /* message/rfc822 */
00218               {
00219                      (*writefunc)(" ", 1);
00220                      msgenvelope(writefunc, fp, mimep->firstpart);
00221                      (*writefunc)(" ", 1);
00222                      msgbodystructure(writefunc, dox, fp, mimep->firstpart);
00223                      (*writefunc)(" ", 1);
00224                      sprintf(buf, "%lu", (unsigned long)nbodylines);
00225                      (*writefunc)(buf, strlen(buf));
00226               }
00227 
00228               if (dox)
00229               {
00230                      (*writefunc)(" ", 1);
00231                      contentstr(writefunc, rfc2045_content_md5(mimep));
00232 
00233                      (*writefunc)(" ", 1);
00234                      do_disposition(writefunc, disposition_s,
00235                             mimep->content_disposition_attr);
00236 
00237                      (*writefunc)(" NIL", 4);
00238                             /* TODO Content-Language: */
00239               }
00240        }
00241        (*writefunc)(")", 1);
00242 }