home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / src / PrefsDialogAppl.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  36.9 KB  |  1,537 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.    pref_helpers.c --- Preference->Helper dialogs.
  20.    Created: Dora Hsu <dora@netscape.com>, 25-Mar-96.
  21. */
  22.  
  23. #define TRUE   1
  24. #define FALSE  0
  25.  
  26. extern "C" {
  27. #include "net.h"
  28. }
  29. #include "xp_list.h"
  30. #include "xfe.h"
  31. #include "PrefsDialogAppl.h"
  32. #include "prefs.h"
  33.  
  34. #include <XmL/Grid.h>
  35. #include <XmL/Folder.h>
  36. #include "felocale.h"
  37.  
  38. #define TYPE            "type"
  39. #define DESC            "desc"
  40. #define ENC                "enc"
  41. #define ICON            "icon"
  42. #define LANG            "lang"
  43. #define EXTS            "exts"
  44. #define ALT                "alt"
  45. #define SPACE            " "
  46.  
  47. extern int XFE_NO_PLUGINS;
  48. extern int XFE_HELPERS_NETSCAPE;
  49. extern int XFE_HELPERS_UNKNOWN;
  50. extern int XFE_HELPERS_SAVE;
  51. extern int XFE_HELPERS_PLUGIN;
  52. extern int XFE_HELPERS_EMPTY_MIMETYPE;
  53. extern int XFE_HELPERS_LIST_HEADER;
  54. extern int XFE_HELPERS_PLUGIN_DESC_CHANGE;
  55. extern int XFE_HELPERS_APP_TELNET;
  56. extern int XFE_HELPERS_APP_TN3270;
  57. extern int XFE_HELPERS_APP_RLOGIN;
  58. extern int XFE_HELPERS_APP_RLOGIN_USER;
  59.  
  60. #define FE_MOZILLA_MIME_COMMENT             "#mime types added by Netscape Helper"
  61. #define FE_MOZILLA_MAILCAP_COMMENT       "#mailcap entry added by Netscape Helper"
  62.  
  63. #define FIELD_OFFSET(field) offsetof(struct _XFE_GlobalPrefs, field)
  64. #define GET_FIELD(map, prefs) ( ((char*) prefs) + map.offset )
  65.  
  66. // Static applications
  67.  
  68. typedef struct _static_app_entry {
  69.     int      *desc_label;
  70.     size_t    prefs_offset;
  71. } static_app_entry;
  72.  
  73. static static_app_entry static_apps[] = {
  74.     {
  75.         &XFE_HELPERS_APP_TELNET,
  76.         FIELD_OFFSET(telnet_command)
  77.     },
  78.     {
  79.         &XFE_HELPERS_APP_TN3270,
  80.         FIELD_OFFSET(tn3270_command)
  81.     },
  82.     {
  83.         &XFE_HELPERS_APP_RLOGIN,
  84.         FIELD_OFFSET(rlogin_command)
  85.     },
  86.     {
  87.         &XFE_HELPERS_APP_RLOGIN_USER,
  88.         FIELD_OFFSET(rlogin_user_command)
  89.     },
  90. };
  91.  
  92. static int num_static_apps = sizeof(static_apps) / sizeof(static_app_entry);
  93.  
  94. extern "C" {
  95.     char                   *XP_GetString(int i);
  96.     XP_Bool                 fe_IsMailcapEntryPlugin(NET_mdataStruct *md_item);
  97.     char                   *fe_GetPluginNameFromMailcapEntry(NET_mdataStruct *md_item);
  98.     int                     fe_GetMimetypeInfoFromPlugin(char *pluginName, char *mimetype,
  99.                                                          char **r_desc, char **r_ext);
  100.  
  101.     static char            *PrefsDialogAppl_appendKey (char *buf, char *key, char *val, Boolean hasSep);
  102.     static void             PrefsDialogAppl_append_list_row(PrefsDataGeneralAppl *fep,
  103.                                                             int row, 
  104.                                                             char *data);
  105.     static void             PrefsDialogAppl_add_list_row(PrefsDataGeneralAppl *fep,
  106.                                                          char *data);
  107.     static char            *PrefsDialogAppl_deleteKey (char *buf, char *key, Boolean hasSep);
  108.     static int              PrefsDialogAppl_getToken(char *mess, char *token, int *n);
  109.     static NET_cdataStruct *PrefsDialogAppl_get_exist_data(NET_cdataStruct *old_cd, int *old_pos);
  110.     static char            *PrefsDialogAppl_new_string(char *old_str, char* type,  
  111.                                                        char *value, char *del);
  112.     static Boolean          PrefsDialogAppl_start_new_line( char *old_string, char *de, int n );
  113.     static char*            PrefsDialogAppl_cleanString(char *newbuf );
  114.     static void             PrefsDialogAppl_update_mailcap_entry (char *mimeType, NET_mdataStruct *md,
  115.                                                                   char *flag );
  116. }
  117.  
  118. // ==================== Public Functions ====================
  119.  
  120. void xfe_prefsDialogAppl_build_mime_list(PrefsDataGeneralAppl *fep)
  121. {
  122.     int item_count = fep->static_apps_count; // static applications are listed first
  123.     NET_mdataStruct *md;
  124.     NET_cdataStruct *cd_item;
  125.  
  126.     /* Get beginning of the list */
  127.  
  128.     XP_List *infolist = cinfo_MasterListPointer();
  129.     XtVaSetValues( fep->helpers_list, XmNlayoutFrozen, True, NULL);
  130.  
  131.     /* Get the file format from the object in order to
  132.        build the Helpers  */
  133.  
  134.     while ((cd_item = (NET_cdataStruct *)XP_ListNextObject(infolist))) {
  135.         if ( cd_item->ci.type  && strlen(cd_item->ci.type) >0 ) {
  136.             /* Add this item to the list table */
  137.             if ( !xfe_prefsDialogAppl_is_deleted_type(cd_item) ) {
  138.                 md = xfe_prefsDialogAppl_get_mailcap_from_type(cd_item->ci.type);
  139.                 xfe_prefsDialogAppl_append_type_to_list(fep, cd_item,md, item_count);
  140.                 item_count++;
  141.             }
  142.         }
  143.     }
  144.  
  145.     XtVaSetValues( fep->helpers_list, XmNlayoutFrozen, False, NULL);
  146. }
  147.  
  148. NET_cdataStruct *xfe_prefsDialogAppl_get_mime_data_at_pos(int pos) /* Starting from 0 */
  149. {
  150.     int              count = 0;
  151.     NET_cdataStruct *cd = NULL;
  152.     XP_List         *infoList = cinfo_MasterListPointer();
  153.  
  154.     while((cd = (NET_cdataStruct *)XP_ListNextObject(infoList))) {
  155.         if ( cd->ci.type  && *cd->ci.type 
  156.              && ! xfe_prefsDialogAppl_is_deleted_type(cd)) {
  157.             if ( pos == count ) {
  158.                 break;
  159.             }
  160.             else
  161.                 count++;
  162.         }
  163.     }
  164.  
  165.     return cd;
  166. }
  167.  
  168. Bool xfe_prefsDialogAppl_handle_by_netscape(char *type)
  169. {
  170.     Bool rightType = False;
  171.     if (!strcmp(type, TEXT_HTML) ||
  172.         !strcmp(type, TEXT_MDL)||
  173.         !strcmp(type, TEXT_PLAIN)||
  174.         !strcmp(type, IMAGE_GIF) ||
  175.         !strcmp(type, IMAGE_JPG) ||
  176.         !strcmp(type, IMAGE_PJPG) ||
  177.         !strcmp(type, IMAGE_XBM) ||
  178.         !strcmp(type, IMAGE_XBM2) ||
  179.         !strcmp(type, IMAGE_XBM3) ||
  180.         !strcmp(type, APPLICATION_NS_PROXY_AUTOCONFIG)
  181.         ) {
  182.         rightType = True;
  183.     }
  184.     return rightType;
  185. }
  186.  
  187. Bool xfe_prefsDialogAppl_handle_by_saveToDisk(char *type)
  188. {
  189.     Bool rightType = False;
  190.     if ( !strcmp(type, APPLICATION_OCTET_STREAM) )
  191.         rightType = True;
  192.  
  193.     return rightType;
  194. }
  195.  
  196. NET_mdataStruct *xfe_prefsDialogAppl_get_mailcap_from_type(char *type)
  197. {
  198.     NET_mdataStruct *md_item= NULL, *new_item = NULL;
  199.     /* Get beginning of the list
  200.      */
  201.     XP_List *infolist = mailcap_MasterListPointer();
  202.  
  203.     while ((md_item = (NET_mdataStruct *)XP_ListNextObject(infolist)))
  204.       {
  205.         if ( type && md_item->contenttype &&
  206.              !XP_STRCASECMP(type, md_item->contenttype))
  207.           {
  208.             new_item = md_item;
  209.             break;
  210.           }
  211.       }
  212.     return new_item;
  213. }
  214.  
  215. char *xfe_prefsDialogAppl_construct_new_mailcap_string(NET_mdataStruct *md, 
  216.                                                        char* contenttype,
  217.                                                        char *command, 
  218.                                                        char *flag)
  219. {
  220.     char *str = NULL;
  221.     char *buf0 = 0;
  222.     char buf1[1024];
  223.     char buf2[1024];
  224.     int  len;
  225.  
  226.     memset(buf1, '\0', 1024);
  227.     memset(buf2, '\0', 1024);
  228.  
  229.     if ( !md && !contenttype ) 
  230.         return str;
  231.     else if ( command && *command && flag && *flag ) {
  232.         sprintf(buf1, "%s\n%s;%s", FE_MOZILLA_MAILCAP_COMMENT,
  233.                 md? md->contenttype: contenttype ,command );
  234.    
  235.         sprintf(buf2, ";\\\n\t%s=%s", NET_MOZILLA_FLAGS, flag);
  236.  
  237.         len = strlen(buf1)+strlen(buf2)+1;
  238.  
  239.         buf0 = (char*)malloc(len*sizeof(char));
  240.         memset(buf0, '\0', len);
  241.         strcpy(buf0, buf1);
  242.         strcat(buf0, buf2);
  243.     }
  244.     else if ( command && *command ){
  245.         /* APPLICATION MODE */
  246.         sprintf(buf1, "%s\n%s;%s", FE_MOZILLA_MAILCAP_COMMENT,
  247.                 md ? md->contenttype: contenttype , command);
  248.  
  249.         len = strlen(buf1)+1;
  250.         buf0 = (char*)malloc(len*sizeof(char));
  251.         memset(buf0, '\0', len);
  252.  
  253.         strcpy(buf0, buf1);
  254.     }
  255.     else if ( flag && *flag ) {
  256.         sprintf(buf1, "%s\n%s;", FE_MOZILLA_MAILCAP_COMMENT,
  257.                 md? md->contenttype: contenttype );
  258.         sprintf(buf2, ";\\\n\t%s=%s", NET_MOZILLA_FLAGS, flag);
  259.  
  260.         len = strlen(buf1)+strlen(buf2)+1;
  261.  
  262.         buf0 = (char*)malloc(len*sizeof(char));
  263.         memset(buf0, '\0', len);
  264.         strcpy(buf0, buf1);
  265.         strcat(buf0, buf2);
  266.     }
  267.     else {
  268.         sprintf(buf1, "%s\n%s;", FE_MOZILLA_MAILCAP_COMMENT,
  269.                 md? md->contenttype: contenttype );
  270.         sprintf(buf2, ";\\\n\t%s=%s", NET_MOZILLA_FLAGS, NET_COMMAND_UNKNOWN);
  271.  
  272.         len = strlen(buf1)+strlen(buf2)+1;
  273.  
  274.         buf0 = (char*)malloc(len*sizeof(char));
  275.         memset(buf0, '\0', len);
  276.         strcpy(buf0, buf1);
  277.         strcat(buf0, buf2);
  278.     }
  279.  
  280.     memset(buf1, '\0', strlen(buf1));
  281.     memset(buf2, '\0', strlen(buf2));
  282.     if (md &&  md->label && *md->label)
  283.         sprintf(buf1, ";\\\n\t%s=%s", "description", md->label );
  284.     if ( md && md->testcommand && *md->testcommand)
  285.         sprintf(buf2, ";\\\n\t%s=%s", "test", md->testcommand );
  286.     len = strlen(buf0)+strlen(buf1)+strlen(buf2)+strlen("\n")+1;
  287.     str = (char*)malloc(len*sizeof(char));
  288.     memset(str, '\0', len);
  289.     strcpy(str, buf0);
  290.     strcat(str, buf1);
  291.     strcat(str, buf2);
  292.     free(buf0);
  293.     buf0 = 0;
  294.     return str;
  295. }
  296.  
  297. char*
  298. xfe_prefsDialogAppl_addCommand(char *buf, char *command)
  299. {
  300.     char         *newbuf=0;
  301.     int           len, i, n;
  302.     unsigned int  j;
  303.  
  304.     /* validate inputs here */
  305.     if (!buf || !command ||
  306.         !strlen(buf) || !strlen(command))
  307.         return 0;
  308.  
  309.     len = strlen(buf) + strlen(command) +
  310.       strlen(";") * 2 + strlen("\n") + 1;
  311.  
  312.     j = strlen(buf);
  313.     newbuf = (char *)malloc (len);
  314.     memset(newbuf, '\0', len);
  315.  
  316.     /* buf is the src string. Hence skip any comments that are preceding
  317.      * the actual specification. Then find the place of the ';'.
  318.      */
  319.     n = 0;
  320.     n += strspn(&buf[n], " \t\n");
  321.     while (buf[n] && buf[n] == '#') 
  322.       {
  323.         n++;
  324.         /* Skip until and including the newline */
  325.         while (buf[n] && buf[n] != '\n') n++;
  326.         n += strspn(&buf[n], " \t\n");
  327.       }
  328.     if (buf[n] == '\0')
  329.         /* No entry. The entire entry was a comment. Punt. */
  330.         return(0);
  331.     n += strcspn (&buf[n], ";");        /* find the ';' */
  332.  
  333.     if ( buf[n] == ';' )
  334.       {
  335.         j = n+1;
  336.  
  337.         if ( j < strlen(buf) )
  338.           {
  339.             i = strcspn (buf+j, ";"); /* find the second ";" */
  340.  
  341.             /* If the second semicolon is missing, it is right for us
  342.              * to assume its presence at the end.
  343.              */
  344.             j = j+i+1;
  345.           }
  346.       }
  347.  
  348.     strncpy(newbuf, buf, n);
  349.     newbuf[n] = '\0';
  350.     strcat (newbuf, ";");
  351.     strcat (newbuf, command);
  352.     if (j < strlen(buf))  /* more entries after command */
  353.       {
  354.         strcat (newbuf, ";");
  355.         strcat (newbuf, buf + j);
  356.       }
  357.     /*
  358.       strcat (newbuf, "\n");
  359.       */
  360.  
  361.     return(newbuf);
  362. }
  363.  
  364. char *xfe_prefsDialogAppl_deleteCommand(char *buf)
  365. {
  366.     char        *newbuf=0;
  367.     int          len, i, n;
  368.     unsigned int j;
  369.  
  370.     /* validate inputs here */
  371.     if (!buf || !strlen(buf))
  372.         return 0;
  373.  
  374.     len = strlen(buf) + 1;
  375.     j = strlen(buf);
  376.  
  377.     newbuf = (char *)malloc (len);
  378.     memset(newbuf, '\0', len);
  379.  
  380.     /* buf is the src string. Hence skip any comments that are preceding
  381.      * the actual specification. Then find the place of the ';'.
  382.      */
  383.     n = 0;
  384.     n += strspn(&buf[n], " \t\n");
  385.     while (buf[n] && buf[n] == '#') {
  386.         n++;
  387.         /* Skip until and including the newline */
  388.         while (buf[n] && buf[n] != '\n') n++;
  389.         n += strspn(&buf[n], " \t\n");
  390.     }
  391.     if (buf[n] == '\0')
  392.         /* No entry. The entire entry was a comment. Punt. */
  393.         return(0);
  394.     n += strcspn (&buf[n], ";");        /* find the ';' */
  395.  
  396.     if ( buf[n] == ';' ) {
  397.         j = n+1;
  398.  
  399.         if ( j < strlen(buf) ) {
  400.             i = strcspn (buf+j, ";"); /* find the second ";" */
  401.             j = j +i;
  402.  
  403.             if ( j < strlen(buf) && buf[j] == ';' )
  404.                 j = j + 1;
  405.         }
  406.     }
  407.  
  408.     strncpy(newbuf, buf, n);
  409.     newbuf[n] = '\0';
  410.     if (j < strlen(buf))  /* more entries after command */ {
  411.         strcat (newbuf, ";");
  412.         strcat (newbuf, ";");
  413.         strcat (newbuf, buf + j);
  414.     }
  415.     /*
  416.       strcat (newbuf, "\n");
  417.       */
  418.  
  419.     return newbuf;
  420. }
  421.  
  422. char *xfe_prefsDialogAppl_updateKey(char *buf, char *key, char *newVal, Boolean hasSep)
  423. {
  424.     char *newbuf=NULL;
  425.     char  tok[80];
  426.     int   len, i, k=0, n;
  427.     int   found = 0;
  428.     int   quote = 0;
  429.  
  430.     /* validate inputs here */
  431.     if (!buf || !key || !newVal ||
  432.         !strlen(buf) || !strlen(key) || !strlen(newVal))
  433.         return NULL;
  434.  
  435.     len = strlen(buf);
  436.     i = 0;
  437.  
  438.     while (!found && i < len) {
  439.         n = PrefsDialogAppl_getToken(buf, tok, &i);
  440.         if (strcmp(tok, key) == 0) {
  441.             n = strspn(buf+i, " \t\n");
  442.             i += n;
  443.             if (buf[i] == '=') {
  444.                 n = strspn(buf+i, " =\"\t\n");
  445.                 if ( buf[i+n-1]== '\"')
  446.                     quote = 1;
  447.                 k = i + n;
  448.  
  449.                 if (hasSep)
  450.                     len = strcspn (buf+k, ";");
  451.                 else {
  452.                     if ( quote ) {
  453.                         len = strcspn(buf+k, "\""); /* end quote*/
  454.                         quote = 0;
  455.                     }
  456.                     else
  457.                         len = strcspn (buf+k, " \t\\");
  458.                 }
  459.  
  460.                 strncpy(tok, buf+k, len);
  461.                 tok[len] = '\0';
  462.                 i = k + len;
  463.                 found = 1;
  464.             }
  465.         }
  466.     }
  467.   
  468.     if (found) {
  469.         len = strlen(buf) - strlen(tok) + strlen(newVal) + 3;
  470.         newbuf = (char *)malloc (len);
  471.         memset (newbuf, 0, len);
  472.         strncpy(newbuf, buf, k);
  473.         newbuf[k] = 0;
  474.         if (tok[0] == '"')
  475.             strcat (newbuf, "\"");
  476.         strcat (newbuf, newVal);
  477.         if (tok[0] == '"')
  478.             strcat (newbuf, "\"");
  479.         strcat (newbuf, buf+i);
  480.     }
  481.     return(newbuf);
  482. }
  483.  
  484. void xfe_prefsDialogAppl_add_new_mailcap_data(char *contenttype, 
  485.                                               char* src_str,
  486.                                               char *command,
  487.                                               char *xmode,
  488.                                               Boolean isLocal)
  489. {
  490.     NET_mdataStruct *md = 0;
  491.  
  492.     md = NET_mdataCreate();
  493.     if ( md ) {
  494.         md->contenttype = 0;
  495.         md->command = 0;
  496.         md->label = 0;
  497.         md->testcommand = 0;
  498.         md->printcommand = 0;
  499.         md->stream_buffer_size = 0;
  500.         md->xmode = 0;
  501.         md->src_string = 0;
  502.         md->is_modified = 1;
  503.         md->is_local = isLocal;
  504.         if ( contenttype  && *contenttype )
  505.             StrAllocCopy(md->contenttype, contenttype );
  506.         if ( command && *command )
  507.             StrAllocCopy(md->command, command);
  508.         if ( xmode && *xmode )
  509.             StrAllocCopy(md->xmode, xmode);
  510.         if ( src_str && *src_str )
  511.             StrAllocCopy(md->src_string, src_str);
  512.         NET_mdataAdd(md);
  513.     }
  514. }
  515.  
  516. Boolean xfe_prefsDialogAppl_is_deleted_type (NET_cdataStruct *cd_item)
  517. {
  518.     NET_mdataStruct *md_item = 0;
  519.  
  520.     /* Check if this mime is deleted from the list */
  521.  
  522.     md_item = xfe_prefsDialogAppl_get_mailcap_from_type(cd_item->ci.type);
  523.  
  524.     if ( md_item && md_item->xmode && *md_item->xmode )
  525.         if ( !XP_STRCASECMP(md_item->xmode, NET_COMMAND_DELETED))
  526.             return True;
  527.         else return False;
  528.     else if (md_item && (!md_item->command|| !*md_item->command))
  529.         return True;
  530.  
  531.     return False;
  532. }
  533.  
  534. char *xfe_prefsDialogAppl_get_string_from_type(NET_cdataStruct *cd_item, 
  535.                                                NET_mdataStruct *md)
  536. {
  537.     char *desc = 0, *action = 0, *line = 0;
  538.  
  539.     if ( cd_item->ci.desc && strlen(cd_item->ci.desc) ) {
  540.         cd_item->ci.desc = fe_StringTrim(cd_item->ci.desc);
  541.         StrAllocCopy( desc, cd_item->ci.desc);
  542.     }
  543.     if ( cd_item->ci.type && strlen(cd_item->ci.type) ) {
  544.         cd_item->ci.type = fe_StringTrim(cd_item->ci.type);
  545.         if (desc == 0)
  546.             StrAllocCopy( desc, cd_item->ci.type);
  547.     }
  548.  
  549.     if ( md && md->xmode && *md->xmode ) {
  550.         if ( !XP_STRCASECMP(md->xmode, NET_COMMAND_NETSCAPE ))
  551.             StrAllocCopy(action, XP_GetString(XFE_HELPERS_NETSCAPE));
  552.         else if (!strcmp(md->xmode, NET_COMMAND_SAVE_TO_DISK) ||
  553.                  (!strcmp(md->xmode, NET_COMMAND_SAVE_BY_NETSCAPE)))
  554.             StrAllocCopy(action, XP_GetString(XFE_HELPERS_SAVE));
  555.         else if ( !XP_STRCASECMP(md->xmode, NET_COMMAND_UNKNOWN ))
  556.             StrAllocCopy(action, XP_GetString(XFE_HELPERS_UNKNOWN));
  557.         else if (fe_IsMailcapEntryPlugin(md)) {
  558.             char *pluginName = fe_GetPluginNameFromMailcapEntry(md);
  559.             action = PR_smprintf(XP_GetString(XFE_HELPERS_PLUGIN),
  560.                                  pluginName);
  561.         }
  562.     }
  563.     else if (md && md->command && *md->command) {
  564.         md->command = fe_StringTrim(md->command);
  565.         StrAllocCopy( action, md->command);
  566.     }
  567.     else if (xfe_prefsDialogAppl_handle_by_netscape(cd_item->ci.type) )
  568.         StrAllocCopy(action, XP_GetString(XFE_HELPERS_NETSCAPE));
  569.     else if (xfe_prefsDialogAppl_handle_by_saveToDisk(cd_item->ci.type))
  570.         StrAllocCopy(action, XP_GetString(XFE_HELPERS_SAVE));
  571.     else
  572.         StrAllocCopy(action, XP_GetString(XFE_HELPERS_UNKNOWN));
  573.  
  574.     if ( desc && action ) {
  575.         line = PR_smprintf("%s|%s", desc, action); 
  576.     }
  577.  
  578.     XP_FREEIF(desc);
  579.     XP_FREEIF(action);
  580.     return line;
  581. }
  582.  
  583. void xfe_prefsDialogAppl_append_type_to_list(PrefsDataGeneralAppl *fep, 
  584.                                              NET_cdataStruct *cd_item, 
  585.                                              NET_mdataStruct *md,
  586.                                              int pos)
  587. {
  588.     char *line = xfe_prefsDialogAppl_get_string_from_type(cd_item, md);
  589.  
  590.     if (line) {
  591.         if (pos <= 0)
  592.             PrefsDialogAppl_add_list_row(fep, line);
  593.         else 
  594.             PrefsDialogAppl_append_list_row(fep, pos, line);
  595.     }
  596.  
  597.     XP_FREEIF(line);
  598. }
  599.  
  600. void xfe_prefsDialogAppl_insert_type_at_pos(PrefsDataGeneralAppl *fep, 
  601.                                             NET_cdataStruct *cd_item, 
  602.                                             NET_mdataStruct *md,
  603.                                             int pos)
  604. {
  605.     char *line = xfe_prefsDialogAppl_get_string_from_type(cd_item, md);
  606.     if (! line) return;
  607.  
  608.     int total ;
  609.     XtVaGetValues( fep->helpers_list, XmNrows, &total, 0 );
  610.  
  611.     if ( pos < total ) {
  612.         XmLGridAddRows(fep->helpers_list, XmCONTENT, pos, 1);
  613.         XmLGridSetStringsPos(fep->helpers_list, XmCONTENT, pos, 
  614.                              XmCONTENT, 0, line);
  615.     }
  616.     else {
  617.         /* append to the end */
  618.         PrefsDialogAppl_append_list_row(fep, pos, line);
  619.     }
  620.  
  621.     XP_FREEIF(line);
  622. }
  623.  
  624. void xfe_prefsDialogAppl_build_exts(char *ext, NET_cdataStruct *cd)
  625. {
  626.     int n = cd->num_exts;
  627.  
  628.     cd->exts = (char **) (n ? XP_REALLOC(cd->exts, (n+1)*sizeof(char *))
  629.                           : XP_ALLOC(sizeof(char *)));
  630.  
  631.     if(!cd->exts)
  632.         return;
  633.  
  634.     cd->exts[n] = 0;
  635.     StrAllocCopy(cd->exts[n], ext);
  636.     cd->num_exts = ++n;
  637. }
  638.  
  639. NET_cdataStruct *xfe_prefsDialogAppl_can_combine ( NET_cdataStruct *new_cd, 
  640.                                                    int             *old_pos)
  641. {
  642.     NET_cdataStruct *old_cd = NULL;
  643.  
  644.     old_cd = PrefsDialogAppl_get_exist_data(new_cd, old_pos);
  645.  
  646.     return old_cd;
  647. }
  648.  
  649. Boolean
  650. xfe_prefsDialogAppl_get_mime_data_real_pos(NET_cdataStruct *old_cd, int *real_pos)
  651. {
  652.     Boolean found = False; 
  653.     XP_List *infoList = cinfo_MasterListPointer();
  654.     NET_cdataStruct *cd;
  655.  
  656.     if (!infoList) return found;
  657.     *real_pos = 0;
  658.  
  659.     while ((cd=(NET_cdataStruct*)XP_ListNextObject(infoList)))
  660.       {
  661.         if ( !xfe_prefsDialogAppl_is_deleted_type(cd) )
  662.           {
  663.             if ( cd->ci.type ) /* should skip the encoding ones which type = null */
  664.               {
  665.                 if ( old_cd == cd )
  666.                   {
  667.                     found = True;
  668.                     break;
  669.                   }
  670.                 else (*real_pos)++;
  671.               }
  672.           }
  673.       }
  674.     return found;
  675. }
  676.  
  677. char *
  678. xfe_prefsDialogAppl_replace_new_mime_string(NET_cdataStruct *old_cd, NET_cdataStruct *new_cd)
  679. {
  680.     int n;
  681.     char old_exts[200];
  682.     char new_exts[200];
  683.     char *str = NULL;
  684.     char *old_str = NULL;
  685.  
  686.  
  687.  
  688.     if ( !old_cd->src_string ) return NULL;
  689.     str = strdup(old_cd->src_string);
  690.     memset(old_exts, '\0', 200);
  691.     memset(new_exts, '\0', 200);
  692.  
  693.     if (old_cd->ci.type && *old_cd->ci.type )
  694.       {
  695.         if (new_cd->ci.type && *new_cd->ci.type ) 
  696.           {
  697.             old_str = str;
  698.             str = xfe_prefsDialogAppl_updateKey(old_str, TYPE, new_cd->ci.type, 0 );
  699.  
  700.             if ( !str )
  701.               {
  702.                 str = PrefsDialogAppl_new_string(old_str, TYPE,
  703.                                                  new_cd->ci.type, SPACE);
  704.               }
  705.             XP_FREE(old_str);
  706.           }
  707.         else 
  708.           {
  709.             old_str = str;
  710.             str = PrefsDialogAppl_deleteKey(str, TYPE, 0 );
  711.             XP_FREE(old_str);
  712.           }
  713.     
  714.       }
  715.     else
  716.       {
  717.         old_str = str;
  718.         str = PrefsDialogAppl_new_string(str, TYPE,
  719.                                     new_cd->ci.type, SPACE);
  720.         XP_FREE(old_str);
  721.       }
  722.  
  723.  
  724.  
  725.     if (old_cd->ci.desc && *old_cd->ci.desc )
  726.       {
  727.         if (new_cd->ci.desc && *new_cd->ci.desc ) 
  728.           {
  729.             old_str = str;
  730.             str = xfe_prefsDialogAppl_updateKey(str, DESC, new_cd->ci.desc, 0 );
  731.             
  732.             if ( !str )
  733.               {
  734.                 str = PrefsDialogAppl_new_string(old_str, DESC,
  735.                                             new_cd->ci.desc, SPACE);
  736.               }
  737.             XP_FREE(old_str);
  738.           }
  739.         else 
  740.           {
  741.             old_str = str;
  742.             str = PrefsDialogAppl_deleteKey(str, DESC,0 );
  743.             XP_FREE(old_str);
  744.           }
  745.       }
  746.     else
  747.       {
  748.         old_str = str;
  749.         str = PrefsDialogAppl_new_string(str, DESC,
  750.                                     new_cd->ci.desc, SPACE);
  751.         XP_FREE(old_str);
  752.       }
  753.  
  754.     if ( old_cd->exts && *old_cd->exts )
  755.       {
  756.         for (n= 0; n < old_cd->num_exts; n++ )
  757.           {
  758.             if ( n > 0 )
  759.                 strcat( old_exts, ",");
  760.             if ( n == 0 )
  761.                 strcpy(old_exts, old_cd->exts[n]);
  762.             else
  763.                 strcat(old_exts, old_cd->exts[n]);
  764.           }
  765.  
  766.         if ( new_cd->num_exts > 0 )
  767.           { 
  768.  
  769.             for (n= 0; n < new_cd->num_exts; n++ )
  770.               {
  771.                 if ( n > 0 )
  772.                     strcat( new_exts, ",");
  773.                 if ( n == 0 )
  774.                     strcpy(new_exts, new_cd->exts[n]);
  775.                 else
  776.                     strcat(new_exts, new_cd->exts[n]);
  777.               }
  778.             old_str = str;
  779.             str = xfe_prefsDialogAppl_updateKey(str, EXTS, new_exts, 0 );
  780.             if ( !str )
  781.               {
  782.                 str = PrefsDialogAppl_new_string(old_str, EXTS,
  783.                                             new_exts, SPACE);
  784.               }
  785.             XP_FREE(old_str);
  786.           }
  787.         else
  788.           {
  789.             old_str = str;
  790.             str = PrefsDialogAppl_deleteKey(str, EXTS, 0);
  791.             XP_FREE(old_str);
  792.           }
  793.       }
  794.     else
  795.       {
  796.         if ( new_cd->num_exts > 0 )
  797.           { 
  798.  
  799.             for (n= 0; n < new_cd->num_exts; n++ )
  800.               {
  801.                 if ( n > 0 )
  802.                     strcat( new_exts, ",");
  803.                 strcat(new_exts, new_cd->exts[n]);
  804.               }
  805.             old_str = str;
  806.             str = PrefsDialogAppl_new_string(str, EXTS,
  807.                                         new_exts, SPACE);
  808.             XP_FREE(old_str);
  809.           }
  810.       }
  811.  
  812.     return str;
  813. }
  814.  
  815. char *
  816. xfe_prefsDialogAppl_construct_new_mime_string(NET_cdataStruct *new_cd)
  817. {
  818.     int n;
  819.     int len;
  820.     char buffer1[1024];
  821.     char buffer2[1024];
  822.     char *string = 0;
  823.     char *str = 0;
  824.     char *old_str = NULL;
  825.     XP_List *masterList = cinfo_MasterListPointer();
  826.  
  827.     strcpy(buffer1, FE_MOZILLA_MIME_COMMENT);
  828.     if ( NET_IsOldMimeTypes(masterList) )
  829.       {
  830.         sprintf(buffer2, "%s", new_cd->ci.type); 
  831.         if ( new_cd->num_exts > 0 ) 
  832.             for ( n = 0; n < new_cd->num_exts; n++ )
  833.               {
  834.                 if (n == 0 ) 
  835.                     strcat(buffer2, SPACE);
  836.                 else 
  837.                     strcat(buffer2, SPACE);
  838.                 strcat(buffer2, new_cd->exts[n]);
  839.               }
  840.         len = strlen(buffer1)+strlen(buffer2)+ 2*strlen("\n")+1;
  841.         string = (char*)malloc(len *sizeof(char));
  842.         strcpy(string, buffer1);
  843.         strcat(string, "\n");
  844.         strcat(string, buffer2);
  845.       }
  846.     else
  847.       {
  848.         n = 0;
  849.         if ( new_cd->ci.type &&  *new_cd->ci.type )
  850.           {
  851.             str = PrefsDialogAppl_new_string(old_str, TYPE, new_cd->ci.type, SPACE);
  852.             XP_FREE(old_str);
  853.           }
  854.         if ( new_cd->ci.encoding && *new_cd->ci.encoding )
  855.           {
  856.             old_str = str;
  857.             str = PrefsDialogAppl_new_string(old_str, ENC, new_cd->ci.encoding, SPACE);
  858.             XP_FREE(old_str);
  859.           }
  860.  
  861.         if ( new_cd->ci.language && *new_cd->ci.language)
  862.           {
  863.             old_str = str;
  864.             str = PrefsDialogAppl_new_string(old_str, LANG, new_cd->ci.language, SPACE);
  865.             XP_FREE(old_str);
  866.           }
  867.  
  868.         if ( new_cd->ci.desc && *new_cd->ci.desc)
  869.           {
  870.             old_str = str;
  871.             str = PrefsDialogAppl_new_string(old_str, DESC, 
  872.                                         new_cd->ci.desc, SPACE);
  873.             XP_FREE(old_str);
  874.           }
  875.  
  876.         if ( new_cd->ci.alt_text && *new_cd->ci.alt_text)
  877.           {
  878.             old_str = str;
  879.             str = PrefsDialogAppl_new_string(old_str, ALT, new_cd->ci.alt_text, SPACE);
  880.             XP_FREE(old_str);
  881.           }
  882.  
  883.         if ( new_cd->ci.icon && *new_cd->ci.icon)
  884.           {
  885.             old_str = str;
  886.             str = PrefsDialogAppl_new_string(old_str, ICON, new_cd->ci.icon, SPACE);
  887.             XP_FREE(old_str);
  888.           }
  889.  
  890.         if ( new_cd->exts && *new_cd->exts)
  891.           {
  892.             char exts[1024];
  893.  
  894.             memset(exts, '\0', 1024);
  895.             for (n= 0; n < new_cd->num_exts; n++ )
  896.               {
  897.                 if ( n > 0 )
  898.                     strcat( exts, ",");
  899.                 strcat(exts, new_cd->exts[n]);
  900.               }
  901.             
  902.             old_str = str;
  903.             str = PrefsDialogAppl_new_string(old_str, EXTS, exts, SPACE);
  904.             XP_FREE(old_str);
  905.           }
  906.         len = strlen(buffer1)+strlen(str)+ 2 *strlen("\n") + 1;
  907.         string = (char*)malloc(len *sizeof(char));
  908.         memset(string, '\0', len);
  909.         strcpy(string, buffer1);
  910.         strcat(string, "\n");
  911.         strcat(string, str);
  912.       }
  913.  
  914.     return string;
  915. }
  916.  
  917. void
  918. xfe_prefsDialogAppl_build_handle(PrefsDataApplEdit    *fep)
  919. {
  920.     NET_mdataStruct *old_md = NULL;
  921.     char *src_str;
  922.     char *oldStr = NULL;
  923.  
  924.     old_md = xfe_prefsDialogAppl_get_mailcap_from_type(fep->cd->ci.type);
  925.  
  926.     /* old_md might be marked "Deleted", but that's okay */
  927.     /* because we will replace it with the new md data value */
  928.  
  929.     if ( XmToggleButtonGetState(fep->navigator_toggle) )
  930.       {
  931.         PrefsDialogAppl_update_mailcap_entry(fep->cd->ci.type, old_md,
  932.                                              NET_COMMAND_NETSCAPE);
  933.             
  934.       }
  935.     else if (XmToggleButtonGetState(fep->plugin_toggle))
  936.       {
  937.         char *value;
  938.         int n = 0;
  939.         XtVaGetValues(fep->plugin_combo, XmNuserData, &n, 0);
  940.         value = PR_smprintf("%s%s", NET_COMMAND_PLUGIN, fep->plugins[n]);
  941.         PrefsDialogAppl_update_mailcap_entry(fep->cd->ci.type, old_md, value);
  942.         XP_FREE(value);
  943.       }
  944.     else if (XmToggleButtonGetState(fep->app_toggle))
  945.       {
  946.         char * text = fe_GetTextField(fep->app_text);
  947.         if ( text && *text)
  948.           {
  949.             text = fe_StringTrim(text);
  950.  
  951.             if( old_md )
  952.               {
  953.                 oldStr = old_md->src_string;
  954.                 old_md->src_string = 0;
  955.               }
  956.  
  957.             if ( !oldStr || !strlen(oldStr) ) 
  958.                 src_str = xfe_prefsDialogAppl_construct_new_mailcap_string
  959.                     (old_md, fep->cd->ci.type, text, NULL);
  960.             else 
  961.               {
  962.                 src_str = xfe_prefsDialogAppl_addCommand (oldStr, text);
  963.                 XP_FREE(oldStr);
  964.  
  965.                 oldStr = src_str;
  966.                 src_str = PrefsDialogAppl_deleteKey(oldStr, NET_MOZILLA_FLAGS, 1);
  967.                 if ( src_str )
  968.                     XP_FREE(oldStr);
  969.                 else src_str = oldStr;
  970.  
  971.               }
  972.  
  973.             if ( old_md )
  974.               {
  975.                 StrAllocCopy(old_md->command, text);
  976.                 if ( old_md->src_string )
  977.                     XP_FREE(old_md->src_string);
  978.                 old_md->src_string = 0;
  979.                 if ( src_str && *src_str )
  980.                     old_md->src_string = src_str;
  981.                 if (old_md->xmode) XP_FREE(old_md->xmode);
  982.                 old_md->xmode = 0;
  983.                 old_md->is_modified = 1;
  984.               }
  985.             else
  986.               {
  987.                 xfe_prefsDialogAppl_add_new_mailcap_data(fep->cd->ci.type,
  988.                                                          src_str,text, NULL, 1);
  989.                 XP_FREE(src_str);
  990.               }
  991.           }
  992.         else
  993.           {
  994.             if ( old_md )
  995.               {
  996.                 oldStr = old_md->src_string;
  997.                 old_md->src_string = 0;
  998.               }
  999.             if ( !oldStr || !strlen(oldStr) ) 
  1000.               {
  1001.                 src_str = xfe_prefsDialogAppl_construct_new_mailcap_string
  1002.                     (old_md, fep->cd->ci.type, NULL, NET_COMMAND_UNKNOWN);
  1003.               }
  1004.             else 
  1005.               {
  1006.                 src_str = xfe_prefsDialogAppl_deleteCommand(oldStr); 
  1007.                 XP_FREE(oldStr);
  1008.  
  1009.                 oldStr = src_str;
  1010.                 src_str = xfe_prefsDialogAppl_updateKey(oldStr, NET_MOZILLA_FLAGS,
  1011.                                                         NET_COMMAND_UNKNOWN, True);
  1012.                 if ( !src_str )
  1013.                     src_str = PrefsDialogAppl_appendKey ( oldStr, NET_MOZILLA_FLAGS,
  1014.                                                           NET_COMMAND_UNKNOWN, 1);
  1015.  
  1016.                 XP_FREE(oldStr);
  1017.               }
  1018.             if ( old_md )
  1019.               {
  1020.                 StrAllocCopy(old_md->command, text);
  1021.                 if ( old_md->src_string ) 
  1022.                     XP_FREE(old_md->src_string);
  1023.                 old_md->src_string = 0;
  1024.                 if ( src_str && *src_str )
  1025.                     old_md->src_string = src_str;
  1026.                 if (old_md->xmode) XP_FREE(old_md->xmode);
  1027.                 old_md->xmode = strdup(NET_COMMAND_UNKNOWN);
  1028.                 old_md->is_modified = 1;
  1029.               }
  1030.             else
  1031.               {
  1032.                 xfe_prefsDialogAppl_add_new_mailcap_data(fep->cd->ci.type,
  1033.                                                          src_str,NULL,
  1034.                                                          NET_COMMAND_UNKNOWN, 1);
  1035.                 XP_FREE(src_str);
  1036.               }
  1037.           }
  1038.         if (text) XtFree(text);
  1039.       }
  1040.     else if (XmToggleButtonGetState(fep->save_toggle))
  1041.       {
  1042.           PrefsDialogAppl_update_mailcap_entry(fep->cd->ci.type, old_md,
  1043.                                               NET_COMMAND_SAVE_TO_DISK);
  1044.       }
  1045.     else /* Everything else, we set it to be unknown */
  1046.       {
  1047.         PrefsDialogAppl_update_mailcap_entry(fep->cd->ci.type, old_md,
  1048.                                              NET_COMMAND_UNKNOWN);
  1049.       }
  1050.         
  1051. }
  1052.  
  1053. int xfe_prefsAppl_get_static_app_count()
  1054. {
  1055.     return num_static_apps;
  1056. }
  1057.  
  1058. void xfe_prefsAppl_set_static_app_command(int index, char *command)
  1059. {
  1060.     char *field;
  1061.  
  1062.     if (index >= num_static_apps) {
  1063.         /* shouldn't happen */
  1064.         return;
  1065.     }
  1066.  
  1067.     field = (char *)&fe_globalPrefs + static_apps[index].prefs_offset;
  1068.     XP_FREEIF(*(char **)field);
  1069.     *(char **)field = XP_STRDUP(command);
  1070. }
  1071.  
  1072. char *xfe_prefsAppl_get_static_app_command(int index)
  1073. {
  1074.     /* Caller shouldn't free up the string returned from this function */
  1075.     char *field;
  1076.     if (index >= num_static_apps) {
  1077.         /* shouldn't happen */
  1078.         return "";
  1079.     }
  1080.     else {
  1081.         field = (char *)&fe_globalPrefs + static_apps[index].prefs_offset;
  1082.         return *(char **)field;
  1083.     }
  1084. }
  1085.  
  1086. char *xfe_prefsAppl_get_static_app_desc(int index)
  1087. {
  1088.     /* Caller shouldn't free up the string returned from this function */
  1089.     if (index >= num_static_apps) {
  1090.         /* shouldn't happen */
  1091.         return "";
  1092.     }
  1093.     else {
  1094.         return XP_GetString(*static_apps[index].desc_label);
  1095.     }
  1096. }
  1097.  
  1098. void xfe_prefsDialogAppl_build_static_list(PrefsDataGeneralAppl *fep)
  1099. {
  1100.     // Build the static apps first. Instead of using static mime 
  1101.     // libprefs API which I cannot find, use the regular prefs
  1102.     // for now. This is not ideal, but at least we can get this
  1103.     // functionality in.
  1104.  
  1105.     XtVaSetValues(fep->helpers_list, XmNlayoutFrozen, True, NULL);
  1106.  
  1107.     char *desc = 0;
  1108.     char *action = 0;
  1109.     char *line = 0;
  1110.  
  1111.     for (int i = 0; i < num_static_apps; i++) {
  1112.         StrAllocCopy(desc, xfe_prefsAppl_get_static_app_desc(i));
  1113.         StrAllocCopy(action, xfe_prefsAppl_get_static_app_command(i));
  1114.  
  1115.         if ( desc && action ) {
  1116.             line = PR_smprintf("%s|%s", desc, action); 
  1117.             if (i == 0)
  1118.                 PrefsDialogAppl_add_list_row(fep, line);
  1119.             else 
  1120.                 PrefsDialogAppl_append_list_row(fep, i, line);
  1121.         }
  1122.         XP_FREEIF(desc);
  1123.         XP_FREEIF(action);
  1124.         XP_FREEIF(line);
  1125.     }
  1126.  
  1127.     XtVaSetValues(fep->helpers_list, XmNlayoutFrozen, False, NULL);
  1128.     
  1129.     fep->static_apps_count = num_static_apps; 
  1130. }
  1131.  
  1132. // ==================== Static Functions ====================
  1133.  
  1134. static void PrefsDialogAppl_add_list_row(PrefsDataGeneralAppl *fep, char *data)
  1135. {
  1136.     int total ;
  1137.     XtVaGetValues( fep->helpers_list, XmNrows, &total, 0 );
  1138.     XmLGridAddRows(fep->helpers_list, XmCONTENT, -1, 1);
  1139.     if ( total > 0 )
  1140.         XmLGridMoveRows(fep->helpers_list, 1, 0, total);
  1141.     XmLGridSetStringsPos(fep->helpers_list, XmCONTENT, 0, 
  1142.                          XmCONTENT, 0, data);
  1143.  
  1144. static void PrefsDialogAppl_append_list_row(PrefsDataGeneralAppl *fep, int row, char *data)
  1145. {
  1146.     int total ;
  1147.     XtVaGetValues( fep->helpers_list, XmNrows, &total, 0 );
  1148.     if ( row >= total )
  1149.         XmLGridAddRows(fep->helpers_list, XmCONTENT, -1, 1);
  1150.  
  1151.     XmLGridSetStringsPos(fep->helpers_list, XmCONTENT, row, 
  1152.                          XmCONTENT, 0, data);
  1153.  
  1154. static int /* returns len of token */
  1155. PrefsDialogAppl_getToken (char *mess, char *token, int *n) /* n: next position to search*/
  1156. {
  1157.     int len, i, j;
  1158.  
  1159.     if (mess == NULL)
  1160.         return(0);
  1161.  
  1162.     if ((unsigned int)*n > strlen(mess))
  1163.         return(0);
  1164.  
  1165.     i = *n;
  1166.     len = strspn(mess+i, " =;\\\t\n\0");
  1167.     i += len;
  1168.  
  1169.     j = i;
  1170.     if (mess[i] == '"')
  1171.       {
  1172.         i++; j++;
  1173.         for (len = 0; mess[j] != '\n' && mess[j++] != '"'; len++);
  1174.       }
  1175.     else
  1176.         len = strcspn(mess+i, " =;\\\t\n\0");
  1177.     strncpy(token, mess+i, len);
  1178.     token[len] = '\0';
  1179.  
  1180.     if (j > 0 && mess[j-1] == '"') i++;
  1181.  
  1182.     *n = i + len;
  1183.  
  1184.     return(len);
  1185. }
  1186.  
  1187. static NET_cdataStruct *
  1188. PrefsDialogAppl_get_exist_data(NET_cdataStruct *old_cd, int *old_pos)
  1189. {
  1190.     NET_cdataStruct *found_cd = NULL;
  1191.     NET_cdataStruct *cd = NULL;
  1192.     XP_List *infoList = cinfo_MasterListPointer();
  1193.  
  1194.     *old_pos = 0;
  1195.  
  1196.     if ( !infoList )
  1197.         return found_cd;
  1198.  
  1199.     while ((cd= (NET_cdataStruct *)XP_ListNextObject(infoList)))
  1200.       {
  1201.         if ( old_cd->ci.type && cd->ci.type )
  1202.           {
  1203.             if( !XP_STRCASECMP(old_cd->ci.type, cd->ci.type))
  1204.               {
  1205.                 /* found matching type regardless whether it is deleted
  1206.                  * one or not. caller needs to decide what they want to
  1207.                  *  with this old_cd 
  1208.                  */
  1209.                 found_cd = cd;
  1210.                 break;
  1211.               }
  1212.             else (*old_pos)++;
  1213.           }
  1214.       }
  1215.     return found_cd;
  1216. }
  1217.  
  1218.  
  1219. static char *
  1220. PrefsDialogAppl_new_string(char *old_str, char* type,  char *value, char *del)
  1221. {
  1222.     char *str = 0 ;
  1223.     int len = 0;
  1224.     Boolean newline = False;
  1225.     Boolean quoted = False;
  1226.  
  1227.  
  1228.     if ( !value || !*value)
  1229.       {
  1230.         if ( old_str )
  1231.           {
  1232.             str = (char*)malloc((strlen(old_str)+1)*sizeof(char));
  1233.             strcpy(str, old_str);
  1234.             return str;
  1235.           }
  1236.         else return NULL;
  1237.       }
  1238.  
  1239.     if (!old_str)
  1240.       {
  1241.         if ( !strcmp(type, DESC) || !strcmp(type, EXTS) ) 
  1242.           {
  1243.             len = strlen(type) + strlen("=") + strlen(value) + 2 * strlen("\"") 
  1244.               + strlen(del) + 1;
  1245.  
  1246.             str = (char*)malloc(len *sizeof(char));
  1247.             memset(str, '\0', len);
  1248.             strcpy(str, type);
  1249.             strcat(str, "=");
  1250.             strcat(str, "\"");
  1251.             strcat(str, value);
  1252.             strcat(str, "\"");
  1253.             strcat(str, del);
  1254.           }
  1255.         else 
  1256.           {
  1257.             len = strlen(type) +strlen("=") + strlen(value) + 
  1258.               strlen(del) +1;
  1259.  
  1260.             str = (char*)malloc(len *sizeof(char));
  1261.             memset(str, '\0', len);
  1262.             strcpy(str, type);
  1263.             strcat(str, "=");
  1264.             strcat(str, value);
  1265.             strcat(str, del);
  1266.           }
  1267.       }
  1268.     else 
  1269.       {
  1270.         if ( old_str[strlen(old_str)-1] == '\n')
  1271.             old_str[strlen(old_str)-1] = '\0';
  1272.  
  1273.  
  1274.         if (PrefsDialogAppl_start_new_line(old_str, del, 2) )
  1275.           {
  1276.             newline = True;
  1277.             len = strlen(" \\\n");
  1278.           }
  1279.  
  1280.         if ( !strcmp(type, DESC) || !strcmp(type, EXTS) ) 
  1281.           {
  1282.             quoted = True;
  1283.             len = len + 2 * strlen("\"") ;
  1284.           }
  1285.  
  1286.  
  1287.         len = len + strlen(old_str)+ strlen("\t\t")+ 
  1288.           strlen(type) + strlen("=") + strlen(value)+ 
  1289.           strlen(del) +   1;
  1290.  
  1291.         str = (char*)malloc(len*sizeof(char));
  1292.         memset(str, '\0', len);
  1293.         strcpy(str, old_str);
  1294.  
  1295.         if ( newline )
  1296.             strcat(str, " \\\n");
  1297.         else
  1298.             strcat(str, "\t\t");
  1299.         strcat(str, type);
  1300.         strcat(str, "=");
  1301.         if (quoted)
  1302.             strcat(str, "\"");
  1303.         strcat(str, value);
  1304.         if (quoted)
  1305.             strcat(str, "\"");
  1306.         strcat(str, del);
  1307.  
  1308.       }
  1309.  
  1310.     return str;
  1311. }
  1312.  
  1313. static Boolean 
  1314. PrefsDialogAppl_start_new_line( char *old_string, char *de, int n )
  1315. {
  1316.     Boolean yes = False;
  1317.     int i = 1;
  1318.     char *str = 0;
  1319.     char *string = strdup(old_string);
  1320.  
  1321.     while (1) {
  1322.  
  1323.       while ((*string) && XP_IS_SPACE(*string)) ++string;
  1324.  
  1325.       if ( *string && (*string != '#') ) 
  1326.         {
  1327.           if ( string && de && n > 0)
  1328.             {
  1329.               str =  XP_STRTOK( string, de);
  1330.  
  1331.               while (  i < n || str )
  1332.                 {
  1333.                   str = XP_STRTOK(NULL, de);
  1334.                   i++;
  1335.                 }   
  1336.  
  1337.               if ( i >= n ) /* String ended */
  1338.                 {
  1339.                   yes = True;
  1340.                   break;
  1341.                 }
  1342.             }
  1343.         }
  1344.       else
  1345.         {
  1346.           while ((*string) && (*string != '\n')) ++string;
  1347.           if (*string && *string == '\n') string++;
  1348.           else break;
  1349.         }
  1350.     }
  1351.  
  1352.     return yes;
  1353.  
  1354. static char*
  1355. PrefsDialogAppl_deleteKey (char *buf, char *key, Boolean hasSep)
  1356. {
  1357.     char *newbuf=NULL;
  1358.     char  tok[80];
  1359.     int   len, i, j = 0, k = 0, n;
  1360.     int   found = 0;
  1361.     int   quote = 0;
  1362.  
  1363.     /* validate inputs here */
  1364.     if (!buf || !key ||
  1365.         !strlen(buf) || !strlen(key))
  1366.         return NULL;
  1367.  
  1368.     len = strlen(buf);
  1369.     i = 0;
  1370.     while (!found && i < len)
  1371.       {
  1372.         j = i;
  1373.         n = PrefsDialogAppl_getToken(buf, tok, &i);
  1374.         if (strcmp(tok, key) == 0)
  1375.           {
  1376.             n = strspn(buf+i, " \t\n");
  1377.             i += n;
  1378.             if (buf[i] == '=')
  1379.               {
  1380.                 n = strspn(buf+i, " =\"\t\n");
  1381.                 if ( buf[i+n-1] == '\"')
  1382.                     quote = 1;
  1383.                 k = i + n;
  1384.                 if (hasSep)
  1385.                     len = strcspn (buf+k, ";");
  1386.                 else
  1387.                   {
  1388.                     if ( quote )
  1389.                       {
  1390.                         n = strcspn(buf+k, "\""); /* end quote*/
  1391.                         if ( buf[k+n] == '\"')
  1392.                             k = k + n;
  1393.                         quote = 0;
  1394.                       }
  1395.                     len = strcspn (buf+k, " \t\\");
  1396.                   }
  1397.                 i = k + len;
  1398.                 found = 1;
  1399.               }
  1400.           }
  1401.         else
  1402.           {
  1403.             n = strspn(buf+i, " ;\\\t\n");
  1404.             i += n;
  1405.           }
  1406.       }
  1407.     if (found)
  1408.       {
  1409.         newbuf = strdup (buf);
  1410.         newbuf[j] = '\0';
  1411.         found = 0;
  1412.         newbuf = PrefsDialogAppl_cleanString(newbuf);
  1413.         strcat (newbuf, buf+i);
  1414.         newbuf = PrefsDialogAppl_cleanString(newbuf);
  1415.  
  1416.         /*
  1417.           if( newbuf[strlen(newbuf)-1] != '\n' ) strcat(newbuf, "\n");
  1418.           */
  1419.       }
  1420.     return(newbuf);
  1421. }
  1422.  
  1423. static char* PrefsDialogAppl_cleanString(char *newbuf )
  1424. {
  1425.     int i = 0;
  1426.     int found =  0;
  1427.  
  1428.     while (!found && strlen(newbuf) > 0)
  1429.       {
  1430.         if ( newbuf[strlen(newbuf)-1] == ' ' ||
  1431.              newbuf[strlen(newbuf)-1] == '\\' ||
  1432.              newbuf[strlen(newbuf)-1] == ';' ||
  1433.              newbuf[strlen(newbuf)-1] == '\n' ||
  1434.              newbuf[strlen(newbuf)-1] == '\t' )
  1435.           {
  1436.             newbuf[strlen(newbuf)-1] = '\0';
  1437.           }
  1438.         else found = 1;
  1439.       }
  1440.  
  1441.     found = 0;
  1442.     i = 0;
  1443.     while (!found && strlen(newbuf) > 0 && ((unsigned int)i) < strlen(newbuf))
  1444.       {
  1445.         if ( newbuf[i] == '\\' ||
  1446.              newbuf[i] == ';' )
  1447.           {
  1448.             strncpy( newbuf, newbuf+i+1, strlen(newbuf)-i);
  1449.           }
  1450.         else found = 1;
  1451.         i++;
  1452.       }
  1453.  
  1454.     return newbuf;
  1455. }
  1456.  
  1457. static void
  1458. PrefsDialogAppl_update_mailcap_entry (char *mimeType, NET_mdataStruct *md,
  1459.                                       char *flag )
  1460. {
  1461.     char *oldStr = NULL;
  1462.     char *src_str = 0;
  1463.  
  1464.     if (md)
  1465.       {
  1466.         oldStr = md->src_string;
  1467.         md->src_string = 0;
  1468.       }
  1469.  
  1470.     if ( !oldStr || !strlen(oldStr) ) 
  1471.         src_str = xfe_prefsDialogAppl_construct_new_mailcap_string (md, mimeType,     
  1472.                                                                     md? md->command: (char *)NULL,
  1473.                                                                     flag);
  1474.     else 
  1475.       {
  1476.         src_str = xfe_prefsDialogAppl_updateKey(oldStr, NET_MOZILLA_FLAGS, flag, True);
  1477.  
  1478.         if ( !src_str )
  1479.             src_str = PrefsDialogAppl_appendKey(oldStr, NET_MOZILLA_FLAGS, flag, 1);
  1480.         
  1481.         XP_FREE(oldStr);
  1482.       }
  1483.  
  1484.     if ( md )
  1485.       {
  1486.         if ( md->src_string ) XP_FREE(md->src_string);
  1487.         if ( src_str && *src_str)
  1488.             md->src_string = src_str;
  1489.         if ( md->xmode ) XP_FREE(md->xmode);
  1490.         md->xmode = strdup(flag);
  1491.         md->is_modified = 1;
  1492.       }
  1493.     else {
  1494.       xfe_prefsDialogAppl_add_new_mailcap_data(mimeType, src_str, NULL, flag, 1);
  1495.       XP_FREE(src_str);
  1496.     }
  1497.  
  1498. static char*
  1499. PrefsDialogAppl_appendKey (char *buf, char *key, char *val, Boolean hasSep)
  1500. {
  1501.     char *newbuf=NULL;
  1502.     char  str[80];
  1503.     int   len, i;
  1504.     
  1505.     /* validate inputs here */
  1506.     if (!buf || !key || !val ||
  1507.         !strlen(buf) || !strlen(key) || !strlen(val))
  1508.         return NULL;
  1509.     
  1510.     if (hasSep)
  1511.         sprintf(str, "; \\\n%s=%s", key, val);
  1512.     else
  1513.         sprintf(str, " \\\n%s=%s", key, val);
  1514.     len = strlen(buf);
  1515.     for (i = len-1;
  1516.          buf[i] == '\n' || buf[i] == '\\' || buf[i] == ' ' || buf[i] == '\t';
  1517.          i--);
  1518.     i++;
  1519.  
  1520.     len = strlen(buf) + strlen(str) + 1 + 1;
  1521.     newbuf = (char *)malloc(len);
  1522.     memset (newbuf, 0, len);
  1523.     strncpy (newbuf, buf, i);  /* i-1 */
  1524.     newbuf[i] = 0;
  1525.     if (newbuf[i-1] == ';') newbuf[i-1] = 0;
  1526.     strcat (newbuf, str);
  1527.  
  1528.     return(newbuf);
  1529. }
  1530.  
  1531.  
  1532.  
  1533.