home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / lib / libmime / mimefilt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  12.2 KB  |  460 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. /*   mimefilt.c --- test harness for libmime.a
  20.      Created: Jamie Zawinski <jwz@netscape.com>, 15-May-96.
  21.  
  22.    This program reads a message from stdin and writes the output of the MIME
  23.    parser on stdout.
  24.  
  25.    Parameters can be passed to the parser through the usual URL mechanism:
  26.  
  27.      mimefilt BASE-URL?headers=all&rot13 < in > out
  28.  
  29.    Some parameters can't be affected that way, so some additional switches
  30.    may be passed on the command line after the URL:
  31.  
  32.      -fancy        whether fancy headers should be generated (default)
  33.  
  34.      -no-fancy    opposite; this uses the headers used in the cases of
  35.                 FO_SAVE_AS_TEXT or FO_QUOTE_MESSAGE
  36.  
  37.      -html        whether we should convert to HTML (like FO_PRESENT);
  38.                 this is the default if no ?part= is specified.
  39.  
  40.      -raw        don't convert to HTML (FO_SAVE_AS);
  41.                 this is the default if a ?part= is specified.
  42.  
  43.      -outline    at the end, print a debugging overview of the MIME structure
  44.  
  45.    Before any output comes a blurb listing the content-type, charset, and 
  46.    various other info that would have been put in the generated URL struct.
  47.    It's printed to the beginning of the output because otherwise this out-
  48.    of-band data would have been lost.  (So the output of this program is,
  49.    in fact, a raw HTTP response.)
  50.  */
  51.  
  52. #include "mimemsg.h"
  53. #include "prglobal.h"
  54.  
  55. #include "key.h"
  56. #include "cert.h"
  57. #include "secrng.h"
  58. #include "secmod.h"
  59. #include "pk11func.h"
  60.  
  61.  
  62. #ifndef XP_UNIX
  63. ERROR!    This is a unix-only file for the "mimefilt" standalone program.
  64.         This does not go into libmime.a.
  65. #endif
  66.  
  67.  
  68. static char *
  69. test_file_type (const char *filename, void *stream_closure)
  70. {
  71.   const char *suf = XP_STRRCHR(filename, '.');
  72.   if (!suf)
  73.     return 0;
  74.   suf++;
  75.  
  76.   if (!strcasecomp(suf, "txt") ||
  77.       !strcasecomp(suf, "text"))
  78.     return XP_STRDUP("text/plain");
  79.   else if (!strcasecomp(suf, "htm") ||
  80.            !strcasecomp(suf, "html"))
  81.     return XP_STRDUP("text/html");
  82.   else if (!strcasecomp(suf, "gif"))
  83.     return XP_STRDUP("image/gif");
  84.   else if (!strcasecomp(suf, "jpg") ||
  85.            !strcasecomp(suf, "jpeg"))
  86.     return XP_STRDUP("image/jpeg");
  87.   else if (!strcasecomp(suf, "pjpg") ||
  88.            !strcasecomp(suf, "pjpeg"))
  89.     return XP_STRDUP("image/pjpeg");
  90.   else if (!strcasecomp(suf, "xbm"))
  91.     return XP_STRDUP("image/x-xbitmap");
  92.   else if (!strcasecomp(suf, "xpm"))
  93.     return XP_STRDUP("image/x-xpixmap");
  94.   else if (!strcasecomp(suf, "xwd"))
  95.     return XP_STRDUP("image/x-xwindowdump");
  96.   else if (!strcasecomp(suf, "bmp"))
  97.     return XP_STRDUP("image/x-MS-bmp");
  98.   else if (!strcasecomp(suf, "au"))
  99.     return XP_STRDUP("audio/basic");
  100.   else if (!strcasecomp(suf, "aif") ||
  101.            !strcasecomp(suf, "aiff") ||
  102.            !strcasecomp(suf, "aifc"))
  103.     return XP_STRDUP("audio/x-aiff");
  104.   else if (!strcasecomp(suf, "ps"))
  105.     return XP_STRDUP("application/postscript");
  106.   else if (!strcasecomp(suf, "p7m"))
  107.     return XP_STRDUP("application/x-pkcs7-mime");
  108.   else if (!strcasecomp(suf, "p7c"))
  109.     return XP_STRDUP("application/x-pkcs7-mime");
  110.   else if (!strcasecomp(suf, "p7s"))
  111.     return XP_STRDUP("application/x-pkcs7-signature");
  112.   else
  113.     return 0;
  114. }
  115.  
  116. static char *
  117. test_type_icon(const char *type, void *stream_closure)
  118. {
  119.   if (!strncasecomp(type, "text/", 5))
  120.     return XP_STRDUP("internal-gopher-text");
  121.   else if (!strncasecomp(type, "image/", 6))
  122.     return XP_STRDUP("internal-gopher-image");
  123.   else if (!strncasecomp(type, "audio/", 6))
  124.     return XP_STRDUP("internal-gopher-sound");
  125.   else if (!strncasecomp(type, "video/", 6))
  126.     return XP_STRDUP("internal-gopher-movie");
  127.   else if (!strncasecomp(type, "application/", 12))
  128.     return XP_STRDUP("internal-gopher-binary");
  129.   else
  130.     return XP_STRDUP("internal-gopher-unknown");
  131. }
  132.  
  133. static int
  134. test_output_fn(char *buf, int32 size, void *closure)
  135. {
  136.   FILE *out = (FILE *) closure;
  137.   if (out)
  138.     return fwrite(buf, sizeof(*buf), size, out);
  139.   else
  140.     return 0;
  141. }
  142.  
  143. static int
  144. test_output_init_fn (const char *type,
  145.                      const char *charset,
  146.                      const char *name,
  147.                      const char *x_mac_type,
  148.                      const char *x_mac_creator,
  149.                      void *stream_closure)
  150. {
  151.   FILE *out = (FILE *) stream_closure;
  152.   fprintf(out, "CONTENT-TYPE: %s", type);
  153.   if (charset)
  154.     fprintf(out, "; charset=\"%s\"", charset);
  155.   if (name)
  156.     fprintf(out, "; name=\"%s\"", name);
  157.   if (x_mac_type || x_mac_creator)
  158.     fprintf(out, "; x-mac-type=\"%s\"; x-mac-creator=\"%s\"",
  159.             x_mac_type ? x_mac_type : "",
  160.             x_mac_creator ? x_mac_type : "");
  161.   fprintf(out, CRLF CRLF);
  162.   return 0;
  163. }
  164.  
  165.  
  166. static int
  167. test_set_html_state_fn (void *stream_closure,
  168.                         XP_Bool layer_encapsulate_p,
  169.                         XP_Bool start_p,
  170.                         XP_Bool abort_p)
  171. {
  172.   char random_close_tags[] =
  173.         "</TABLE></TABLE></TABLE></TABLE></TABLE></TABLE>"
  174.         "</DL></DL></DL></DL></DL></DL></DL></DL></DL></DL>"
  175.         "</DL></DL></DL></DL></DL></DL></DL></DL></DL></DL>"
  176.         "</B></B></B></B></B></B></B></B></B></B></B></B>"
  177.         "</PRE></PRE></PRE></PRE></PRE></PRE></PRE></PRE>"
  178.         "<BASEFONT SIZE=3></SCRIPT>";
  179.   return test_output_fn(random_close_tags, XP_STRLEN(random_close_tags),
  180.                         stream_closure);
  181. }
  182.  
  183. static void *
  184. test_image_begin(const char *image_url, const char *content_type,
  185.                  void *stream_closure)
  186. {
  187.   return ((void *) XP_STRDUP(image_url));
  188. }
  189.  
  190. static void
  191. test_image_end(void *image_closure, int status)
  192. {
  193.   char *url = (char *) image_closure;
  194.   if (url) XP_FREE(url);
  195. }
  196.  
  197. static char *
  198. test_image_make_image_html(void *image_data)
  199. {
  200.   char *url = (char *) image_data;
  201. #if 0
  202.   const char *prefix = "<P><CENTER><IMG SRC=\"";
  203.   const char *suffix = "\"></CENTER><P>";
  204. #else
  205.   const char *prefix = ("<P><CENTER><TABLE BORDER=2 CELLPADDING=20"
  206.                         " BGCOLOR=WHITE>"
  207.                         "<TR><TD ALIGN=CENTER>"
  208.                         "an inlined image would have gone here for<BR>");
  209.   const char *suffix = "</TD></TR></TABLE></CENTER><P>";
  210. #endif
  211.   char *buf;
  212.   buf = (char *) XP_ALLOC (XP_STRLEN (prefix) + XP_STRLEN (suffix) +
  213.                            XP_STRLEN (url) + 20);
  214.   if (!buf) return 0;
  215.   *buf = 0;
  216.   XP_STRCAT (buf, prefix);
  217.   XP_STRCAT (buf, url);
  218.   XP_STRCAT (buf, suffix);
  219.   return buf;
  220. }
  221.  
  222. static int test_image_write_buffer(char *buf, int32 size, void *image_closure)
  223. {
  224.   return 0;
  225. }
  226.  
  227. static char *
  228. test_passwd_prompt (PK11SlotInfo *slot, void *wincx)
  229. {
  230.   char buf[2048], *s;
  231.   fprintf(stdout, "#### Password required: ");
  232.   s = fgets(buf, sizeof(buf)-1, stdin);
  233.   if (!s) return s;
  234.   if (s[strlen(s)-1] == '\r' ||
  235.       s[strlen(s)-1] == '\n')
  236.     s[strlen(s)-1] = '\0';
  237.   return s;
  238. }
  239.  
  240.  
  241. int
  242. test(FILE *in, FILE *out,
  243.      const char *url,
  244.      XP_Bool fancy_headers_p,
  245.      XP_Bool html_p,
  246.      XP_Bool outline_p,
  247.      XP_Bool decrypt_p,
  248.      XP_Bool variable_width_plaintext_p)
  249. {
  250.   int status = 0;
  251.   MimeObject *obj = 0;
  252.   MimeDisplayOptions *opt = XP_NEW(MimeDisplayOptions);
  253.   XP_MEMSET(opt, 0, sizeof(*opt));
  254.  
  255.   if (decrypt_p) html_p = FALSE;
  256.  
  257.   opt->fancy_headers_p = fancy_headers_p;
  258.   opt->headers = MimeHeadersSome;
  259.   opt->no_inline_p = FALSE;
  260.   opt->rot13_p = FALSE;
  261.  
  262.   status = mime_parse_url_options(url, opt);
  263.   if (status < 0)
  264.     {
  265.       XP_FREE(opt);
  266.       return MK_OUT_OF_MEMORY;
  267.     }
  268.  
  269.   opt->url                    = url;
  270.   opt->write_html_p            = html_p;
  271.   opt->decrypt_p            = decrypt_p;
  272.   opt->output_init_fn        = test_output_init_fn;
  273.   opt->output_fn            = test_output_fn;
  274.   opt->set_html_state_fn  = test_set_html_state_fn;
  275.   opt->charset_conversion_fn= 0;
  276.   opt->rfc1522_conversion_fn= 0;
  277.   opt->reformat_date_fn        = 0;
  278.   opt->file_type_fn            = test_file_type;
  279.   opt->type_description_fn    = 0;
  280.   opt->type_icon_name_fn    = test_type_icon;
  281.   opt->stream_closure        = out;
  282.  
  283.   opt->image_begin            = test_image_begin;
  284.   opt->image_end            = test_image_end;
  285.   opt->make_image_html        = test_image_make_image_html;
  286.   opt->image_write_buffer    = test_image_write_buffer;
  287.  
  288.   opt->variable_width_plaintext_p = variable_width_plaintext_p;
  289.  
  290.   obj = mime_new ((MimeObjectClass *)&mimeMessageClass,
  291.                   (MimeHeaders *) NULL,
  292.                   MESSAGE_RFC822);
  293.   if (!obj)
  294.     {
  295.       XP_FREE(opt);
  296.       return MK_OUT_OF_MEMORY;
  297.     }
  298.   obj->options = opt;
  299.  
  300.   status = obj->class->initialize(obj);
  301.   if (status >= 0)
  302.     status = obj->class->parse_begin(obj);
  303.   if (status < 0)
  304.     {
  305.       XP_FREE(opt);
  306.       XP_FREE(obj);
  307.       return MK_OUT_OF_MEMORY;
  308.     }
  309.  
  310.   while (1)
  311.     {
  312.       char buf[255];
  313.       int size = fread(buf, sizeof(*buf), sizeof(buf), stdin);
  314.       if (size <= 0) break;
  315.       status = obj->class->parse_buffer(buf, size, obj);
  316.       if (status < 0)
  317.         {
  318.           mime_free(obj);
  319.           XP_FREE(opt);
  320.           return status;
  321.         }
  322.     }
  323.  
  324.   status = obj->class->parse_eof(obj, FALSE);
  325.   if (status >= 0)
  326.     status = obj->class->parse_end(obj, FALSE);
  327.   if (status < 0)
  328.     {
  329.       mime_free(obj);
  330.       XP_FREE(opt);
  331.       return status;
  332.     }
  333.  
  334.   if (outline_p)
  335.     {
  336.       fprintf(out, "\n\n"
  337.           "###############################################################\n");
  338.       obj->class->debug_print(obj, stderr, 0);
  339.       fprintf(out,
  340.           "###############################################################\n");
  341.     }
  342.  
  343.   mime_free (obj);
  344.   XP_FREE(opt);
  345.   return 0;
  346. }
  347.  
  348.  
  349. static char *
  350. test_cdb_name_cb (void *arg, int vers)
  351. {
  352.   static char f[1024];
  353.   if (vers <= 4)
  354.     sprintf(f, "%s/.netscape/cert.db", getenv("HOME"));
  355.   else
  356.     sprintf(f, "%s/.netscape/cert%d.db", getenv("HOME"), vers);
  357.   return f;
  358. }
  359.  
  360. static char *
  361. test_kdb_name_cb (void *arg, int vers)
  362. {
  363.   static char f[1024];
  364.   if (vers <= 2)
  365.     sprintf(f, "%s/.netscape/key.db", getenv("HOME"));
  366.   else
  367.     sprintf(f, "%s/.netscape/key%d.db", getenv("HOME"), vers);
  368.   return f;
  369. }
  370.  
  371. extern void SEC_Init(void);
  372.  
  373. int
  374. main (int argc, char **argv)
  375. {
  376.   int32 i = 1;
  377.   char *url = "";
  378.   XP_Bool fancy_p = TRUE;
  379.   XP_Bool html_p = TRUE;
  380.   XP_Bool outline_p = FALSE;
  381.   XP_Bool decrypt_p = FALSE;
  382.   char filename[1000];
  383.   CERTCertDBHandle *cdb_handle;
  384.   SECKEYKeyDBHandle *kdb_handle;
  385.  
  386.   PR_Init("mimefilt", 24, 1, 0);
  387.  
  388.   cdb_handle = (CERTCertDBHandle *)  malloc(sizeof(*cdb_handle));
  389.   memset(cdb_handle, 0, sizeof(*cdb_handle));
  390.  
  391.   if (SECSuccess != CERT_OpenCertDB(cdb_handle, FALSE, test_cdb_name_cb, NULL))
  392.     CERT_OpenVolatileCertDB(cdb_handle);
  393.   CERT_SetDefaultCertDB(cdb_handle);
  394.  
  395.   RNG_RNGInit();
  396.  
  397.   kdb_handle = SECKEY_OpenKeyDB(PR_FALSE, test_kdb_name_cb, NULL);
  398.   SECKEY_SetDefaultKeyDB(kdb_handle);
  399.  
  400.   PK11_SetPasswordFunc(test_passwd_prompt);
  401.  
  402.   sprintf(filename, "%s/.netscape/secmodule.db", getenv("HOME"));
  403.   SECMOD_init(filename);
  404.  
  405.   SEC_Init();
  406.  
  407.  
  408.   if (i < argc)
  409.     {
  410.       if (argv[i][0] == '-')
  411.         url = XP_STRDUP("");
  412.       else
  413.         url = argv[i++];
  414.     }
  415.  
  416.   if (url &&
  417.       (XP_STRSTR(url, "?part=") ||
  418.        XP_STRSTR(url, "&part=")))
  419.     html_p = FALSE;
  420.  
  421.   while (i < argc)
  422.     {
  423.       if (!XP_STRCMP(argv[i], "-fancy"))
  424.         fancy_p = TRUE;
  425.       else if (!XP_STRCMP(argv[i], "-no-fancy"))
  426.         fancy_p = FALSE;
  427.       else if (!XP_STRCMP(argv[i], "-html"))
  428.         html_p = TRUE;
  429.       else if (!XP_STRCMP(argv[i], "-raw"))
  430.         html_p = FALSE;
  431.       else if (!XP_STRCMP(argv[i], "-outline"))
  432.         outline_p = TRUE;
  433.       else if (!XP_STRCMP(argv[i], "-decrypt"))
  434.         decrypt_p = TRUE;
  435.       else
  436.         {
  437.           fprintf(stderr,
  438.           "usage: %s [ URL [ -fancy | -no-fancy | -html | -raw | -outline | -decrypt ]]\n"
  439.                   "     < message/rfc822 > output\n",
  440.                   (XP_STRRCHR(argv[0], '/') ?
  441.                    XP_STRRCHR(argv[0], '/') + 1 :
  442.                    argv[0]));
  443.           i = 1;
  444.           goto FAIL;
  445.         }
  446.       i++;
  447.     }
  448.  
  449.   i = test(stdin, stdout, url, fancy_p, html_p, outline_p, decrypt_p, TRUE);
  450.   fprintf(stdout, "\n");
  451.   fflush(stdout);
  452.  
  453.  FAIL:
  454.  
  455.   CERT_ClosePermCertDB(cdb_handle);
  456.   SECKEY_CloseKeyDB(kdb_handle);
  457.  
  458.   exit(i);
  459. }
  460.