home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / lib / libnet / mkinit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  20.7 KB  |  780 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.  * register all neccessary
  20.  * stream converters
  21.  */
  22.  
  23. /* Please leave outside of ifdef for window's precompiled headers. */
  24. #include "mkutils.h"
  25.  
  26. #ifdef MOZILLA_CLIENT
  27. #ifdef XP_UNIX  /* this whole module is ifdef'd UNIX */
  28.  
  29. #include "mkstream.h"
  30. #include "mkformat.h"
  31. #include "net.h"
  32.  
  33. #include "cvview.h"
  34. #include "cvdisk.h"
  35. #include "cvproxy.h"
  36. #include "cvextcon.h"
  37. #include "txview.h"
  38.  
  39. #include "xlate.h"
  40.  
  41. #include "libi18n.h"        /* For character code set conversion stream    */
  42.  
  43. #include "cvactive.h"
  44.  
  45. #include "pa_parse.h"
  46.  
  47. #include "np.h"
  48.  
  49. #include "il_strm.h"            /* Image Library stream converters. */
  50.  
  51. /* The master database of mail cap info (link list) */
  52.  
  53. PRIVATE XP_List *NET_mcMasterList = 0; /* May want to save out this info */
  54.  
  55. PUBLIC void
  56. NET_mdataFree(NET_mdataStruct *md)
  57. {
  58.     FREEIF(md->contenttype);
  59.     FREEIF(md->command);
  60.     FREEIF(md->testcommand);
  61.     FREEIF(md->label);
  62.     FREEIF(md->printcommand);
  63.     FREEIF(md->src_string);
  64.     FREEIF(md->xmode);
  65.     FREE(md);
  66.     md = NULL;
  67. }
  68.  
  69. /* File is a directory ?*/
  70. PRIVATE Bool
  71. net_isDir(char *name)
  72. {
  73.     XP_StatStruct st;
  74.     if (!name || !*name) return (FALSE);
  75.     if (!stat (name, &st) && S_ISDIR(st.st_mode))
  76.         return (TRUE);
  77.     else
  78.         return (FALSE);
  79. }
  80.  
  81. PUBLIC void
  82. NET_CleanupMailCapList(char* filename)
  83. {
  84.     NET_mdataStruct *mdata;
  85.     FILE *fp = NULL;
  86.     XP_List *modifiedList = NULL;
  87.  
  88.     if ( !NET_mcMasterList ) return;
  89.  
  90.     if ( filename && *filename )
  91.     {
  92.       /* Invalid filename, then don't write */
  93.       if ( net_isDir(filename) )
  94.         return;
  95.       fp = fopen(filename, "w");
  96.       if ( !fp ) return;
  97.       modifiedList = XP_ListNew();
  98.  
  99.       while ((mdata=(NET_mdataStruct *)XP_ListRemoveEndObject(NET_mcMasterList)))
  100.       {
  101.         if (mdata->is_local )
  102.         {
  103.         if ( mdata->src_string && *mdata->src_string)
  104.         {
  105.         fputs(mdata->src_string, fp);
  106.         if ( mdata->src_string[strlen(mdata->src_string)-1] != '\n' )
  107.            fputs("\n", fp);
  108.         }
  109.         else mdata->src_string = 0;
  110.  
  111.         NET_mdataFree(mdata);
  112.         }
  113.         else if (mdata->is_modified)
  114.             XP_ListAddObject(modifiedList, mdata);
  115.         else 
  116.         {
  117.             NET_mdataFree(mdata);
  118.         }
  119.       }
  120.      while ((mdata=(NET_mdataStruct *)XP_ListRemoveEndObject(modifiedList)))
  121.           {
  122.         if ( mdata->src_string && *mdata->src_string)
  123.         {
  124.         fputs(mdata->src_string, fp);
  125.         if ( mdata->src_string[strlen(mdata->src_string)-1] != '\n' )
  126.           fputs("\n", fp);
  127.         }
  128.         else mdata->src_string = 0;
  129.                 NET_mdataFree(mdata);
  130.           }
  131.  
  132.       fclose(fp);
  133.     }
  134.     else
  135.     {
  136.       while ((mdata = (NET_mdataStruct *)XP_ListRemoveEndObject(NET_mcMasterList)))
  137.           {
  138.         NET_mdataFree(mdata);
  139.       }
  140.     }
  141.     XP_ListDestroy(NET_mcMasterList);
  142.     NET_mcMasterList = 0;
  143. }
  144.  
  145. /* register all your converters
  146.  *
  147.  * YOU MUST register a "*" converter for
  148.  * EVERY format out type, this acts as a default
  149.  * and prevents a "Could not convert error"
  150.  */
  151. PUBLIC void
  152. NET_RegisterConverters (char * personal_file, char * global_file)
  153. {
  154.  
  155.  
  156.   NET_CleanupMailCapList(NULL);
  157.   NET_mcMasterList = XP_ListNew();
  158.  
  159.   NET_RegisterMIMEDecoders ();
  160.  
  161.   NET_RegisterExternalViewerCommand (IMAGE_WILDCARD, "xv %s", 0);
  162.  
  163.   NET_RegisterExternalViewerCommand ("audio/ulaw", "playulaw", 2000);
  164.  
  165. #ifdef NOT  /* NO default audio */
  166. #ifdef __sun
  167.   NET_RegisterExternalViewerCommand (AUDIO_BASIC, "cat > /dev/audio", 2000);
  168. #else
  169.   NET_RegisterExternalViewerCommand (AUDIO_BASIC, "playulaw", 2000);
  170. #endif /* __sgi */
  171. #endif /* NOT */
  172.  
  173.   NET_RegisterExternalViewerCommand (VIDEO_MPEG,
  174.                                      /* throw away stderr and stdout, since
  175.                                         mpeg_play is so darn noisy. */
  176.                                      "mpeg_play %s >/dev/null 2>&1", 0);
  177.  
  178.   NET_RegisterExternalViewerCommand ("image/x-xwd", "xwud", 2000);
  179.  
  180.   /* global file must come first!!!!!!!!!!!!!!
  181.    */
  182.   if (global_file)
  183.     NET_ProcessMailcapFile (global_file, FALSE);
  184.  
  185.   if (personal_file)
  186.     NET_ProcessMailcapFile (personal_file, TRUE);
  187. }
  188.  
  189. /*
  190.  * before you modify this,
  191.  * make darn sure you want to deviuate from the standard bellcore mailcap
  192.  * handling!!  *this means you Garrett!!*"
  193.  *
  194.  * Code borrowed from:
  195.  *
  196.  *  Copyright (c) 1991 Bell Communications Research, Inc. (Bellcore)
  197.  *
  198.  *  Permission to use, copy, modify, and distribute this material
  199.  *  for any purpose and without fee is hereby granted, provided
  200.  *  that the above copyright notice and this permission notice
  201.  *  appear in all copies, and that the name of Bellcore not be
  202.  *  used in advertising or publicity pertaining to this
  203.  *  material without the specific, prior written permission
  204.  *  of an authorized representative of Bellcore.  BELLCORE
  205.  *  MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY
  206.  *  OF THIS MATERIAL FOR ANY PURPOSE.  IT IS PROVIDED "AS IS",
  207.  *  WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
  208.  */
  209.  
  210. /*
  211.  *  Metamail -- A tool to help diverse mail readers
  212.  *              cope with diverse multimedia mail formats.
  213.  *
  214.  *  Author:  Nathaniel S. Borenstein, Bellcore
  215.  *
  216.  */
  217.  
  218. struct MailcapEntry {
  219.     char *contenttype;
  220.     char *command;
  221.     char *testcommand;
  222.     int needsterminal;
  223.     int copiousoutput;
  224.     int needtofree;
  225.     char *label;
  226.     char *printcommand;
  227.     int32 stream_buffer_size;
  228.     char *xmode;
  229. };
  230.  
  231. #define LINE_BUF_SIZE      2048
  232. #define TMPFILE_NAME_SIZE  127
  233.  
  234. PRIVATE char *GetCommand (char *s, char **t)
  235. {
  236.     char *s2;
  237.     int quoted = 0;
  238.  
  239.     s2 = (char *) XP_ALLOC(XP_STRLEN(s)*2 + 3); /* absolute max, if all % signs */
  240.     if(!s2)
  241.         return(NULL);
  242.     *s2 = 0;
  243.     *t = s2;
  244.  
  245.  
  246.     while (s && *s)
  247.       {
  248.         if (quoted)
  249.           {
  250.             if (*s == '%')
  251.                 *s2++ = '%';
  252.  
  253.             *s2++ = *s++;
  254.             quoted = 0;
  255.           }
  256.         else
  257.           {
  258.             if (*s == ';')
  259.               {
  260.                 break;  /* finish the string below */
  261.               }
  262.             if (*s == '\\')
  263.               {
  264.                 quoted = 1;
  265.                 ++s;
  266.               }
  267.             else
  268.               {
  269.                 *s2++ = *s++;
  270.               }
  271.           }
  272.       }
  273.  
  274.     /* look at the last character of the command and make sure it doesn't have
  275.      * a '&'
  276.      */
  277.     if( s2 > *t && *(s2-1) == '&')
  278.         s2--;  /* kill the ampersand */
  279.  
  280.     *s2 = 0;  /* terminate string */
  281.  
  282.     if(*s)
  283.         return(s+1);
  284.     else
  285.         return(s);
  286. }
  287.  
  288. /* Trims leading and trailing space in the input string while converting
  289.  * it to all lower case.
  290.  *
  291.  * WARNING: Modified input string.
  292.  */
  293. PRIVATE char *Cleanse (char *s)
  294. {
  295.     char *tmp, *news, *tmpnews;
  296.  
  297.     news = s;
  298.     /* strip leading white space */
  299.     while (*s && XP_IS_SPACE(*s)) ++s;
  300.     /* put in lower case */
  301.     for (tmpnews=news, tmp=s; *tmp; tmpnews++, ++tmp) {
  302.       *tmpnews = tolower ((unsigned char)*tmp);
  303.     }
  304.     *tmpnews = '\0';
  305.     /* strip trailing white space */
  306.     while (*--tmpnews && XP_IS_SPACE(*tmpnews)) *tmpnews = 0;
  307.     return(news);
  308. }
  309.  
  310. PRIVATE void BuildCommand (char *Buf, char *controlstring, char *TmpFileName)
  311. {
  312.     char *from, *to;
  313.     int prefixed = 0;
  314.  
  315.     for (from=controlstring, to=Buf; *from != '\0'; from++)
  316.       {
  317.         if (prefixed)
  318.           {
  319.             prefixed = 0;
  320.             switch(*from)
  321.               {
  322.                 case '%':
  323.                     *to++ = '%';
  324.                     break;
  325.                 case 'n':
  326.                 case 'F':
  327.                      fprintf(stderr, "metamail: Bad mailcap \"test\" clause: %s\n", controlstring);
  328.                 case 's':
  329.                     if (TmpFileName)
  330.                       {
  331.                         XP_STRCPY(to, TmpFileName);
  332.                         to += XP_STRLEN(TmpFileName);
  333.                       }
  334.                     break;
  335.                 default:
  336.                     fprintf(stderr,
  337.                 "%s: Ignoring unsupported format code in mailcap file: %%%c\n",
  338.                               XP_AppName, *from);
  339.                     break;
  340.               }
  341.           }
  342.         else if (*from == '%')
  343.           {
  344.             prefixed = 1;
  345.           }
  346.         else
  347.           {
  348.             *to++ = *from;
  349.           }
  350.       }
  351.     *to = 0;
  352. }
  353.  
  354. static void
  355. net_register_new_converter(char *contenttype, char *command, char *xmode,
  356.                            int buffer_size)
  357. {
  358.         /* xmode takes priority over command */
  359.         if (xmode && !XP_STRCASECMP(xmode, NET_COMMAND_NETSCAPE))
  360.         {
  361.                 if ( !XP_STRCASECMP(contenttype, TEXT_HTML) )
  362.                         NET_RegisterContentTypeConverter (TEXT_HTML, FO_PRESENT,
  363.                                                 NULL, INTL_ConvCharCode);
  364.                 else if (!XP_STRCASECMP(contenttype, TEXT_MDL))
  365.                         NET_RegisterContentTypeConverter (TEXT_MDL, FO_PRESENT,
  366.                                                 NULL, INTL_ConvCharCode);
  367.  
  368.                 else if (!XP_STRCASECMP(contenttype, TEXT_PLAIN))
  369.                         NET_RegisterContentTypeConverter (TEXT_PLAIN, FO_PRESENT,
  370.                                                 NULL, NET_PlainTextConverter);
  371.                 else if (!XP_STRCASECMP(contenttype, IMAGE_GIF))
  372.                         NET_RegisterContentTypeConverter (IMAGE_GIF,
  373.                                  FO_PRESENT,NULL, IL_ViewStream);
  374.                 else if (!XP_STRCASECMP(contenttype, IMAGE_XBM) ||
  375.                          !XP_STRCASECMP(contenttype, IMAGE_XBM2) ||
  376.                          !XP_STRCASECMP(contenttype, IMAGE_XBM3))
  377.                         NET_RegisterContentTypeConverter (IMAGE_XBM,
  378.                                  FO_PRESENT,NULL, IL_ViewStream);
  379.                 else if (!XP_STRCASECMP(contenttype, IMAGE_JPG) ||
  380.                          !XP_STRCASECMP(contenttype, IMAGE_PJPG))
  381.                         NET_RegisterContentTypeConverter (IMAGE_JPG,
  382.                                  FO_PRESENT,NULL, IL_ViewStream);
  383.  
  384.                 else if (!XP_STRCASECMP(contenttype, IMAGE_PNG)) 
  385.                         NET_RegisterContentTypeConverter (IMAGE_PNG,
  386.                                  FO_PRESENT,NULL, IL_ViewStream);
  387.                 else if (!XP_STRCASECMP(contenttype,
  388.                                      APPLICATION_NS_PROXY_AUTOCONFIG))
  389.                         NET_RegisterContentTypeConverter(
  390.                                 APPLICATION_NS_PROXY_AUTOCONFIG,
  391.                                 FO_PRESENT,
  392.                                 (void *)0, NET_ProxyAutoConfig);
  393.                 else if (!XP_STRCASECMP(contenttype,
  394.                                      APPLICATION_NS_JAVASCRIPT_AUTOCONFIG))
  395.                         NET_RegisterContentTypeConverter(
  396.                                 APPLICATION_NS_JAVASCRIPT_AUTOCONFIG,
  397.                                 FO_PRESENT,
  398.                                 (void *)0, NET_ProxyAutoConfig);
  399.                 else
  400.                 {
  401.                     fprintf(stderr,
  402.             "%s: Ignoring unsupported netscape contenttype in user mailcap file.\n", XP_AppName);
  403.                 }
  404.         }
  405.         else if (xmode && !strncasecmp(xmode, NET_COMMAND_PLUGIN,
  406.                                        strlen(NET_COMMAND_PLUGIN)))
  407.           {
  408.             char *pluginName = xmode + strlen(NET_COMMAND_PLUGIN);
  409.             /* For plugins enable the plugin for this mimetype */
  410.             NPL_EnablePlugin(contenttype, pluginName, TRUE);
  411.           }
  412.         else if (xmode &&
  413.                  (!XP_STRCASECMP(xmode, NET_COMMAND_SAVE_TO_DISK) || 
  414.                   !XP_STRCASECMP(xmode, NET_COMMAND_SAVE_BY_NETSCAPE)))
  415.                 NET_RegisterContentTypeConverter(contenttype,
  416.                                 FO_PRESENT,
  417.                                 NULL, fe_MakeSaveAsStream );
  418.  
  419.         else if (xmode && !XP_STRCASECMP(xmode, NET_COMMAND_UNKNOWN))
  420.                 NET_RegisterContentTypeConverter(contenttype,
  421.                                 FO_PRESENT,
  422.                                 NULL, fe_MakeSaveAsStream );
  423.  
  424.         else if (xmode && !XP_STRCASECMP(xmode,NET_COMMAND_DELETED))
  425.           {
  426.             /* Do nothing */
  427.           }
  428.         else if (command && *command )/* It's an external application then */
  429.     {
  430.  
  431.         /* register the command
  432.          *
  433.          * but only if it isn't text/html
  434.          */
  435.         if(strcasecomp(contenttype, TEXT_HTML) &&
  436.            strcasecomp(contenttype, MESSAGE_RFC822) &&
  437.            strcasecomp(contenttype, MESSAGE_NEWS))
  438.           NET_RegisterExternalViewerCommand(contenttype, command, buffer_size);
  439.     }
  440. }
  441.  
  442.  
  443. PRIVATE int PassesTest (struct MailcapEntry *mc)
  444. {
  445.     int result;
  446.     char *cmd, TmpFileName[TMPFILE_NAME_SIZE];
  447.  
  448.     if (!mc->testcommand) return(1);
  449.     tmpnam(TmpFileName);
  450.     cmd = (char *)XP_ALLOC(1024);
  451.     if (!cmd)
  452.         return(0);
  453.     BuildCommand(cmd, mc->testcommand, TmpFileName);
  454.     TRACEMSG(("Executing test command: %s\n", cmd));
  455.     result = system(cmd);
  456.     free(cmd);
  457.  
  458.     remove(TmpFileName);
  459.  
  460.     if(result)
  461.         TRACEMSG(("[HTInit] Test failed!\n"));
  462.     else
  463.         TRACEMSG(("[HTInit] Test passed!\n"));
  464.  
  465.     return(result==0);
  466. }
  467.  
  468. PRIVATE int ProcessMailcapEntry (FILE *fp, struct MailcapEntry *mc,
  469.             char** src_string, Bool is_local)
  470. {
  471.     NET_cdataStruct *tmp_cd = NULL;
  472.     NET_cdataStruct *cd = NULL;
  473.     NET_mdataStruct *md = NULL;
  474.     int unprocessed_entryalloc = 1023, len;
  475.     char *unprocessed_entry, *s, *t, *buffer;
  476.     char *arg, *eq;
  477.     char *command=0;
  478.     
  479.     buffer = (char *) XP_ALLOC(LINE_BUF_SIZE);
  480.     if (!buffer)
  481.         return 0;
  482.     unprocessed_entry = (char *) XP_ALLOC(1 + unprocessed_entryalloc);
  483.     if (!unprocessed_entry)
  484.       {
  485.         free(buffer);
  486.         return 0;
  487.       }
  488.     *unprocessed_entry = '\0';
  489.     while (fgets(buffer, LINE_BUF_SIZE, fp))
  490.       {
  491.         if ( !*src_string )
  492.             StrAllocCopy(*src_string, buffer );
  493.         else
  494.             *src_string = XP_AppendStr(*src_string, buffer);
  495.         
  496.         if (buffer[0] == '#')
  497.             continue;
  498.         len = XP_STRLEN(buffer);
  499.         if (len == 0)
  500.             continue;
  501.         if (buffer[len-1] == '\n')
  502.             buffer[--len] = 0;
  503.         if ((len + XP_STRLEN(unprocessed_entry)) > unprocessed_entryalloc)
  504.           {
  505.             unprocessed_entryalloc += 1024;
  506.             unprocessed_entry = (char *) XP_REALLOC(unprocessed_entry, unprocessed_entryalloc+1);
  507.             TRACEMSG(("Growing input line in mkinit"));
  508.             if (!unprocessed_entry)
  509.               {
  510.                 TRACEMSG(("ERROR! Growing input line in mkinit"));
  511.                 return 0;
  512.               }
  513.           }
  514.         if (len > 0 && buffer[len-1] == '\\')
  515.           {
  516.             buffer[len-1] = 0;
  517.             XP_STRCAT(unprocessed_entry, buffer);
  518.           }
  519.         else
  520.           {
  521.             XP_STRCAT(unprocessed_entry, buffer);
  522.             break;
  523.           }
  524.       }
  525.     
  526.     for (s=unprocessed_entry; *s && XP_IS_SPACE(*s); ++s)
  527.         ; /* NULL BODY */
  528.     if (!*s)
  529.       {
  530.         /* totally blank entry -- quietly ignore */
  531.         free(unprocessed_entry);
  532.         free(buffer);
  533.         return(0);
  534.       }
  535.     s = XP_STRCHR(unprocessed_entry, ';');
  536.     if (s == NULL)
  537.       {
  538.         fprintf(stderr, "%s: Ignoring invalid mailcap entry: %s\n",
  539.                 XP_AppName, unprocessed_entry);
  540.         free(unprocessed_entry);
  541.         free(buffer);
  542.         XP_FREE(*src_string);
  543.         *src_string = 0;
  544.         return(0);
  545.       }
  546.     *s++ = 0;
  547.     mc->needsterminal = 0;
  548.     mc->copiousoutput = 0;
  549.     mc->needtofree = 1;
  550.     mc->testcommand = 0;
  551.     mc->label = NULL;
  552.     mc->printcommand = NULL;
  553.     mc->contenttype = 0; /* init */
  554.     mc->xmode = 0;
  555.     mc->stream_buffer_size = 0;
  556.     StrAllocCopy(mc->contenttype, unprocessed_entry); /* copy */
  557.     if (!mc->contenttype)
  558.       {
  559.         free(buffer);
  560.         TRACEMSG(("mailcap: no content-type"));
  561.         return 0;
  562.       }
  563.     s = GetCommand(s, &mc->command);
  564.     
  565.     while (s && *s != '\0')
  566.       {
  567.         arg = s;
  568.         eq = XP_STRCHR(arg, '=');
  569.         if (eq)
  570.             *eq++ = 0;
  571.         else
  572.             eq = arg;
  573.         
  574.         t = GetCommand(eq, &command);
  575.         
  576.         if (arg && *arg)
  577.           {
  578.             arg = Cleanse(arg);
  579.             if ( eq && !XP_STRCMP(arg, NET_MOZILLA_FLAGS))
  580.               {
  581.                 /* xmode is case sensitive. That is why we dont Cleanse it. */
  582.                 mc->xmode = command;
  583.                 command = 0;
  584.               }
  585.             else {
  586.               command = Cleanse(command);
  587.               if (eq && !XP_STRCMP(arg, "test"))
  588.                 {
  589.                   mc->testcommand = command;
  590.                   command = 0;
  591.                   TRACEMSG(("mailcap: found testcommand:%s\n",mc->testcommand));
  592.                 }
  593.               else if (eq && !XP_STRCMP(arg, "description"))
  594.                 {
  595.                   mc->label = command;
  596.                   command = 0;
  597.                 }
  598.               else if (eq && !XP_STRCMP(arg, "label"))
  599.                 {
  600.                   mc->label = command; /* bogus old name for description */
  601.                   command = 0;
  602.                 }
  603.               else if (eq && !XP_STRCMP(arg, "stream-buffer-size"))
  604.                 {
  605.                   mc->stream_buffer_size = atol(command);
  606.                   TRACEMSG(("mailcap: found stream-buffer-size:%d\n",mc->stream_buffer_size));
  607.                   FREEIF(command);
  608.                   command = 0;
  609.                 }
  610.               else
  611.                   FREEIF(command);
  612.             }
  613.           }
  614.         else if (command && *command) FREEIF(command);
  615.         s = t;
  616.       }
  617.     
  618.     free(unprocessed_entry);
  619.     
  620.     /* Copy over the mail cap entry so that it can saved into data base */
  621.     
  622.     if (mc)
  623.       {
  624.         md = NET_mdataCreate();
  625.         
  626.         if ( !md ) return (-1);
  627.         StrAllocCopy(md->contenttype, mc->contenttype);
  628.         StrAllocCopy(md->command, mc->command);
  629.         StrAllocCopy(md->testcommand, mc->testcommand);
  630.         StrAllocCopy(md->label, mc->label);
  631.         StrAllocCopy(md->printcommand, mc->printcommand);
  632.         md->stream_buffer_size = mc->stream_buffer_size;
  633.         if (is_local && *src_string && **src_string)
  634.             StrAllocCopy(md->src_string, *src_string); /* copy buffer */
  635.         StrAllocCopy(md->xmode, mc->xmode);
  636.         md->is_local = is_local;
  637.         XP_FREE(*src_string);
  638.         *src_string = 0;
  639.       }
  640.  
  641.  
  642.     if (PassesTest(mc))
  643.       {
  644.         TRACEMSG(("mailcap: Setting up conversion %s : %s\n", mc->contenttype,
  645.                   mc->command));
  646.         
  647.         net_register_new_converter(XP_StripLine(mc->contenttype), 
  648.                                    mc->command, mc->xmode,
  649.                                    mc->stream_buffer_size);
  650.         if (md)
  651.             md->test_succeed = TRUE;
  652.       }
  653.     
  654.     /* Add to the database */
  655.     if (md)
  656.       {
  657.         NET_mdataStruct *old_md = NULL;
  658.         
  659.         if ( !(old_md = NET_mdataExist(md)))
  660.             NET_mdataAdd(md);
  661.         else
  662.           {
  663.             NET_mdataRemove(old_md);
  664.             NET_mdataAdd(md);
  665.           }
  666.         
  667.         cd = NET_cdataCreate();
  668.         cd->ci.type = 0;
  669.         cd->is_external = 1;
  670.         cd->is_local = 0; /* This is internal; only for user to view */
  671.         StrAllocCopy(cd->ci.type, md->contenttype );
  672.         
  673.         /* Does not exist add this contenttype to mime content list  */
  674.         if ( !(tmp_cd = NET_cdataExist(cd) ) )
  675.             NET_cdataAdd(cd);
  676.         else /* Already Exist, so we don't need to add it again. Then, free it now */
  677.             NET_cdataRemove(cd);
  678.       }
  679.     
  680.     free(buffer);
  681.     FREEIF(mc->contenttype);
  682.     FREEIF(mc->command);
  683.     FREEIF(mc->testcommand);
  684.     FREEIF(mc->label);
  685.     FREEIF(mc->xmode);
  686.     return(1);
  687. }
  688.  
  689. /* reads a mailcap file and adds entries to the
  690.  * external viewers converter list
  691.  */
  692. PUBLIC int
  693. NET_ProcessMailcapFile (char *file, Bool is_local)
  694. {
  695.     struct MailcapEntry mc;
  696.     FILE *fp;
  697.     char *src_string = 0;
  698.  
  699.     TRACEMSG(("Loading types config file '%s'\n", file));
  700.  
  701.     if ( !net_isDir(file) )
  702.     {
  703.         fp = fopen(file, "r");
  704.  
  705.         while (fp && !feof(fp))
  706.           {
  707.             ProcessMailcapEntry(fp, &mc, &src_string, is_local);
  708.           }
  709.         if (fp) fclose(fp);
  710.     }
  711.     return(-1);
  712. }
  713.  
  714.  
  715. PUBLIC XP_List *
  716. mailcap_MasterListPointer(void)
  717. {
  718.     return (NET_mcMasterList);
  719. }
  720.  
  721. PUBLIC NET_mdataStruct *
  722. NET_mdataCreate(void)
  723. {
  724.     NET_mdataStruct *md = XP_NEW(NET_mdataStruct);
  725.  
  726.         if(!md)
  727.            return(NULL);
  728.  
  729.         memset(md, 0, sizeof(NET_mdataStruct));
  730.  
  731.     return md;
  732. }
  733.  
  734. PUBLIC void
  735. NET_mdataAdd(NET_mdataStruct *md)
  736. {
  737.     XP_ListAddObject(NET_mcMasterList, md);
  738. }
  739.  
  740.  
  741. PUBLIC void
  742. NET_mdataRemove(NET_mdataStruct *md)
  743. {
  744.     XP_ListRemoveObject(NET_mcMasterList, md);
  745.  
  746.     NET_mdataFree(md);
  747.  
  748. }
  749.  
  750. PUBLIC NET_mdataStruct*
  751. NET_mdataExist(NET_mdataStruct *old_md )
  752. {
  753.         NET_mdataStruct *found_md = NULL;
  754.         NET_mdataStruct *md = NULL;
  755.         XP_List *infoList;
  756.  
  757.         infoList = mailcap_MasterListPointer();
  758.  
  759.         if ( !infoList )
  760.                 return found_md;
  761.  
  762.         while ((md= (NET_mdataStruct *)XP_ListNextObject(infoList)))
  763.         {
  764.                 if ( old_md->contenttype &&
  765.                      md->contenttype &&
  766.                      !strcasecomp(old_md->contenttype, md->contenttype))
  767.                 {
  768.                         /* found matching type */
  769.                         found_md = md;
  770.                         break;
  771.                 }
  772.         }
  773.         return found_md;
  774. }
  775.  
  776.  
  777.  
  778. #endif /* XP_UNIX */
  779. #endif /* MOZILLA_CLIENT */
  780.