Back to index

lightning-sunbird  0.9+nobinonly
mimefilt.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 /*   mimefilt.c --- test harness for libmime.a
00039 
00040    This program reads a message from stdin and writes the output of the MIME
00041    parser on stdout.
00042 
00043    Parameters can be passed to the parser through the usual URL mechanism:
00044 
00045      mimefilt BASE-URL?headers=all&rot13 < in > out
00046 
00047    Some parameters can't be affected that way, so some additional switches
00048    may be passed on the command line after the URL:
00049 
00050      -fancy          whether fancy headers should be generated (default)
00051 
00052      -no-fancy       opposite; this uses the headers used in the cases of
00053                             FO_SAVE_AS_TEXT or FO_QUOTE_MESSAGE
00054 
00055      -html           whether we should convert to HTML (like FO_PRESENT);
00056                             this is the default if no ?part= is specified.
00057 
00058      -raw            don't convert to HTML (FO_SAVE_AS);
00059                             this is the default if a ?part= is specified.
00060 
00061      -outline at the end, print a debugging overview of the MIME structure
00062 
00063    Before any output comes a blurb listing the content-type, charset, and 
00064    various other info that would have been put in the generated URL struct.
00065    It's printed to the beginning of the output because otherwise this out-
00066    of-band data would have been lost.  (So the output of this program is,
00067    in fact, a raw HTTP response.)
00068  */
00069 
00070 #include "mimemsg.h"
00071 #include "prglobal.h"
00072 
00073 #include "key.h"
00074 #include "cert.h"
00075 #include "secrng.h"
00076 #include "secmod.h"
00077 #include "pk11func.h"
00078 #include "nsMimeStringResources.h"
00079 
00080 #ifndef XP_UNIX
00081 ERROR! This is a unix-only file for the "mimefilt" standalone program.
00082               This does not go into libmime.a.
00083 #endif
00084 
00085 
00086 static char *
00087 test_file_type (const char *filename, void *stream_closure)
00088 {
00089   const char *suf = PL_strrchr(filename, '.');
00090   if (!suf)
00091        return 0;
00092   suf++;
00093 
00094   if (!nsCRT::strcasecmp(suf, "txt") ||
00095          !nsCRT::strcasecmp(suf, "text"))
00096        return nsCRT::strdup("text/plain");
00097   else if (!nsCRT::strcasecmp(suf, "htm") ||
00098                  !nsCRT::strcasecmp(suf, "html"))
00099        return nsCRT::strdup("text/html");
00100   else if (!nsCRT::strcasecmp(suf, "gif"))
00101        return nsCRT::strdup("image/gif");
00102   else if (!nsCRT::strcasecmp(suf, "jpg") ||
00103                  !nsCRT::strcasecmp(suf, "jpeg"))
00104        return nsCRT::strdup("image/jpeg");
00105   else if (!nsCRT::strcasecmp(suf, "pjpg") ||
00106                  !nsCRT::strcasecmp(suf, "pjpeg"))
00107        return nsCRT::strdup("image/pjpeg");
00108   else if (!nsCRT::strcasecmp(suf, "xbm"))
00109        return nsCRT::strdup("image/x-xbitmap");
00110   else if (!nsCRT::strcasecmp(suf, "xpm"))
00111        return nsCRT::strdup("image/x-xpixmap");
00112   else if (!nsCRT::strcasecmp(suf, "xwd"))
00113        return nsCRT::strdup("image/x-xwindowdump");
00114   else if (!nsCRT::strcasecmp(suf, "bmp"))
00115        return nsCRT::strdup("image/x-MS-bmp");
00116   else if (!nsCRT::strcasecmp(suf, "au"))
00117        return nsCRT::strdup("audio/basic");
00118   else if (!nsCRT::strcasecmp(suf, "aif") ||
00119                  !nsCRT::strcasecmp(suf, "aiff") ||
00120                  !nsCRT::strcasecmp(suf, "aifc"))
00121        return nsCRT::strdup("audio/x-aiff");
00122   else if (!nsCRT::strcasecmp(suf, "ps"))
00123        return nsCRT::strdup("application/postscript");
00124   else
00125        return 0;
00126 }
00127 
00128 static char *
00129 test_type_icon(const char *type, void *stream_closure)
00130 {
00131   if (!nsCRT::strncasecmp(type, "text/", 5))
00132        return nsCRT::strdup("resource://gre/res/html/gopher-text.gif");
00133   if (!nsCRT::strncasecmp(type, "image/", 6))
00134        return nsCRT::strdup("resource://gre/res/html/gopher-image.gif");
00135   if (!nsCRT::strncasecmp(type, "audio/", 6))
00136        return nsCRT::strdup("resource://gre/res/html/gopher-sound.gif");
00137   if (!nsCRT::strncasecmp(type, "video/", 6))
00138        return nsCRT::strdup("resource://gre/res/html/gopher-movie.gif");
00139   if (!nsCRT::strncasecmp(type, "application/", 12))
00140        return nsCRT::strdup("resource://gre/res/html/gopher-binary.gif");
00141 
00142   return nsCRT::strdup("resource://gre/res/html/gopher-unknown.gif");
00143 }
00144 
00145 static int
00146 test_output_fn(char *buf, PRInt32 size, void *closure)
00147 {
00148   FILE *out = (FILE *) closure;
00149   if (out)
00150        return fwrite(buf, sizeof(*buf), size, out);
00151   else
00152        return 0;
00153 }
00154 
00155 static int
00156 test_output_init_fn (const char *type,
00157                                     const char *charset,
00158                                     const char *name,
00159                                     const char *x_mac_type,
00160                                     const char *x_mac_creator,
00161                                     void *stream_closure)
00162 {
00163   FILE *out = (FILE *) stream_closure;
00164   fprintf(out, "CONTENT-TYPE: %s", type);
00165   if (charset)
00166        fprintf(out, "; charset=\"%s\"", charset);
00167   if (name)
00168        fprintf(out, "; name=\"%s\"", name);
00169   if (x_mac_type || x_mac_creator)
00170        fprintf(out, "; x-mac-type=\"%s\"; x-mac-creator=\"%s\"",
00171                      x_mac_type ? x_mac_type : "",
00172                      x_mac_creator ? x_mac_type : "");
00173   fprintf(out, CRLF CRLF);
00174   return 0;
00175 }
00176 
00177 static void *
00178 test_image_begin(const char *image_url, const char *content_type,
00179                              void *stream_closure)
00180 {
00181   return ((void *) nsCRT::strdup(image_url));
00182 }
00183 
00184 static void
00185 test_image_end(void *image_closure, int status)
00186 {
00187   char *url = (char *) image_closure;
00188   if (url) PR_Free(url);
00189 }
00190 
00191 static char *
00192 test_image_make_image_html(void *image_data)
00193 {
00194   char *url = (char *) image_data;
00195 #if 0
00196   const char *prefix = "<P><CENTER><IMG SRC=\"";
00197   const char *suffix = "\"></CENTER><P>";
00198 #else
00199   const char *prefix = ("<P><CENTER><TABLE BORDER=2 CELLPADDING=20"
00200                                           " BGCOLOR=WHITE>"
00201                                           "<TR><TD ALIGN=CENTER>"
00202                                           "an inlined image would have gone here for<BR>");
00203   const char *suffix = "</TD></TR></TABLE></CENTER><P>";
00204 #endif
00205   PRUint32 buflen = strlen (prefix) + strlen (suffix) + strlen (url) + 20;
00206   char *buf = (char *) PR_MALLOC (buflen);
00207   if (!buf) return 0;
00208   *buf = 0;
00209   PL_strcatn (buf, buflen, prefix);
00210   PL_strcatn (buf, buflen, url);
00211   PL_strcatn (buf, buflen, suffix);
00212   return buf;
00213 }
00214 
00215 static int test_image_write_buffer(const char *buf, PRInt32 size, void *image_closure)
00216 {
00217   return 0;
00218 }
00219 
00220 static char *
00221 test_passwd_prompt (PK11SlotInfo *slot, void *wincx)
00222 {
00223   char buf[2048], *s;
00224   fprintf(stdout, "#### Password required: ");
00225   s = fgets(buf, sizeof(buf)-1, stdin);
00226   if (!s) return s;
00227   if (s[nsCRT::strlen(s)-1] == '\r' ||
00228          s[nsCRT::strlen(s)-1] == '\n')
00229        s[nsCRT::strlen(s)-1] = '\0';
00230   return s;
00231 }
00232 
00233 
00234 int
00235 test(FILE *in, FILE *out,
00236         const char *url,
00237         PRBool fancy_headers_p,
00238         PRBool html_p,
00239         PRBool outline_p,
00240         PRBool dexlate_p,
00241         PRBool variable_width_plaintext_p)
00242 {
00243   int status = 0;
00244   MimeObject *obj = 0;
00245   MimeDisplayOptions *opt = new MimeDisplayOptions;
00246 //  memset(opt, 0, sizeof(*opt));
00247 
00248   if (dexlate_p) html_p = PR_FALSE;
00249 
00250   opt->fancy_headers_p = fancy_headers_p;
00251   opt->headers = MimeHeadersSome;
00252   opt->rot13_p = PR_FALSE;
00253 
00254   status = mime_parse_url_options(url, opt);
00255   if (status < 0)
00256        {
00257          PR_Free(opt);
00258          return MIME_OUT_OF_MEMORY;
00259        }
00260 
00261   opt->url                                = url;
00262   opt->write_html_p                = html_p;
00263   opt->dexlate_p                   = dexlate_p;
00264   opt->output_init_fn              = test_output_init_fn;
00265   opt->output_fn                   = test_output_fn;
00266   opt->charset_conversion_fn= 0;
00267   opt->rfc1522_conversion_p = PR_FALSE;
00268   opt->file_type_fn                = test_file_type;
00269   opt->stream_closure              = out;
00270 
00271   opt->image_begin                 = test_image_begin;
00272   opt->image_end                   = test_image_end;
00273   opt->make_image_html             = test_image_make_image_html;
00274   opt->image_write_buffer   = test_image_write_buffer;
00275 
00276   opt->variable_width_plaintext_p = variable_width_plaintext_p;
00277 
00278   obj = mime_new ((MimeObjectClass *)&mimeMessageClass,
00279                               (MimeHeaders *) NULL,
00280                               MESSAGE_RFC822);
00281   if (!obj)
00282        {
00283          PR_Free(opt);
00284          return MIME_OUT_OF_MEMORY;
00285        }
00286   obj->options = opt;
00287 
00288   status = obj->class->initialize(obj);
00289   if (status >= 0)
00290        status = obj->class->parse_begin(obj);
00291   if (status < 0)
00292        {
00293          PR_Free(opt);
00294          PR_Free(obj);
00295          return MIME_OUT_OF_MEMORY;
00296        }
00297 
00298   while (1)
00299        {
00300          char buf[255];
00301          int size = fread(buf, sizeof(*buf), sizeof(buf), stdin);
00302          if (size <= 0) break;
00303          status = obj->class->parse_buffer(buf, size, obj);
00304          if (status < 0)
00305               {
00306                 mime_free(obj);
00307                 PR_Free(opt);
00308                 return status;
00309               }
00310        }
00311 
00312   status = obj->class->parse_eof(obj, PR_FALSE);
00313   if (status >= 0)
00314        status = obj->class->parse_end(obj, PR_FALSE);
00315   if (status < 0)
00316        {
00317          mime_free(obj);
00318          PR_Free(opt);
00319          return status;
00320        }
00321 
00322   if (outline_p)
00323        {
00324          fprintf(out, "\n\n"
00325                 "###############################################################\n");
00326          obj->class->debug_print(obj, stderr, 0);
00327          fprintf(out,
00328                 "###############################################################\n");
00329        }
00330 
00331   mime_free (obj);
00332   PR_Free(opt);
00333   return 0;
00334 }
00335 
00336 
00337 static char *
00338 test_cdb_name_cb (void *arg, int vers)
00339 {
00340   static char f[1024];
00341   if (vers <= 4)
00342        sprintf(f, "%s/.netscape/cert.db", getenv("HOME"));
00343   else
00344        sprintf(f, "%s/.netscape/cert%d.db", getenv("HOME"), vers);
00345   return f;
00346 }
00347 
00348 static char *
00349 test_kdb_name_cb (void *arg, int vers)
00350 {
00351   static char f[1024];
00352   if (vers <= 2)
00353        sprintf(f, "%s/.netscape/key.db", getenv("HOME"));
00354   else
00355        sprintf(f, "%s/.netscape/key%d.db", getenv("HOME"), vers);
00356   return f;
00357 }
00358 
00359 extern void SEC_Init(void);
00360 
00361 int
00362 main (int argc, char **argv)
00363 {
00364   PRInt32 i = 1;
00365   char *url = "";
00366   PRBool fancy_p = PR_TRUE;
00367   PRBool html_p = PR_TRUE;
00368   PRBool outline_p = PR_FALSE;
00369   PRBool dexlate_p = PR_FALSE;
00370   char filename[1000];
00371   CERTCertDBHandle *cdb_handle;
00372   SECKEYKeyDBHandle *kdb_handle;
00373 
00374   PR_Init("mimefilt", 24, 1, 0);
00375 
00376   cdb_handle = (CERTCertDBHandle *)  calloc(1, sizeof(*cdb_handle));
00377 
00378   if (SECSuccess != CERT_OpenCertDB(cdb_handle, PR_FALSE, test_cdb_name_cb, NULL))
00379        CERT_OpenVolatileCertDB(cdb_handle);
00380   CERT_SetDefaultCertDB(cdb_handle);
00381 
00382   RNG_RNGInit();
00383 
00384   kdb_handle = SECKEY_OpenKeyDB(PR_FALSE, test_kdb_name_cb, NULL);
00385   SECKEY_SetDefaultKeyDB(kdb_handle);
00386 
00387   PK11_SetPasswordFunc(test_passwd_prompt);
00388 
00389   sprintf(filename, "%s/.netscape/secmodule.db", getenv("HOME"));
00390   SECMOD_init(filename);
00391 
00392   SEC_Init();
00393 
00394 
00395   if (i < argc)
00396        {
00397          if (argv[i][0] == '-')
00398               url = nsCRT::strdup("");
00399          else
00400               url = argv[i++];
00401        }
00402 
00403   if (url &&
00404          (PL_strstr(url, "?part=") ||
00405           PL_strstr(url, "&part=")))
00406        html_p = PR_FALSE;
00407 
00408   while (i < argc)
00409        {
00410          if (!nsCRT::strcmp(argv[i], "-fancy"))
00411               fancy_p = PR_TRUE;
00412          else if (!nsCRT::strcmp(argv[i], "-no-fancy"))
00413               fancy_p = PR_FALSE;
00414          else if (!nsCRT::strcmp(argv[i], "-html"))
00415               html_p = PR_TRUE;
00416          else if (!nsCRT::strcmp(argv[i], "-raw"))
00417               html_p = PR_FALSE;
00418          else if (!nsCRT::strcmp(argv[i], "-outline"))
00419               outline_p = PR_TRUE;
00420          else if (!nsCRT::strcmp(argv[i], "-dexlate"))
00421               dexlate_p = PR_TRUE;
00422          else
00423               {
00424                 fprintf(stderr,
00425                 "usage: %s [ URL [ -fancy | -no-fancy | -html | -raw | -outline | -dexlate ]]\n"
00426                               "     < message/rfc822 > output\n",
00427                               (PL_strrchr(argv[0], '/') ?
00428                                PL_strrchr(argv[0], '/') + 1 :
00429                                argv[0]));
00430                 i = 1;
00431                 goto FAIL;
00432               }
00433          i++;
00434        }
00435 
00436   i = test(stdin, stdout, url, fancy_p, html_p, outline_p, dexlate_p, PR_TRUE);
00437   fprintf(stdout, "\n");
00438   fflush(stdout);
00439 
00440  FAIL:
00441 
00442   CERT_ClosePermCertDB(cdb_handle);
00443   SECKEY_CloseKeyDB(kdb_handle);
00444 
00445   exit(i);
00446 }