home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / mozilla.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  151.1 KB  |  5,205 lines

  1. /* -*- Mode: C; tab-width: 8; 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. /*
  20.    mozilla.c --- initialization for the X front end.
  21.    Created: Jamie Zawinski <jwz@netscape.com>, 22-Jun-94.
  22.  */
  23.  
  24. #include "mozilla.h"
  25. #include "altmail.h"
  26. #include "name.h"
  27. #include "xfe.h"
  28. #include "prefs.h"
  29. #include "net.h"
  30. #include "xp.h"
  31. #include "xp_help.h" /* for XP_NetHelp() */
  32. #include "xp_sec.h"
  33. #include "ssl.h"
  34. #include "np.h"
  35. #include "outline.h"
  36. #include "mailnews.h"
  37. #include "fonts.h"
  38. #include "secnav.h"
  39. #include "secrng.h"
  40. #include "mozjava.h"
  41. #ifdef NSPR20
  42. #include "private/prpriv.h"    /* for PR_NewNamedMonitor */
  43. #endif /* NSPR20 */
  44.  
  45. #include "libimg.h"             /* Image Library public API. */
  46.  
  47. #include "prefapi.h"
  48. #include "hk_funcs.h"
  49.  
  50. #include "libmocha.h"
  51.  
  52. #ifdef EDITOR
  53. #include "xeditor.h"
  54. #endif
  55. #include "prnetdb.h"
  56. #ifndef NSPR20
  57. #include "prevent.h"
  58. #else
  59. #include "plevent.h"
  60. #endif
  61. #include "e_kit.h"
  62.  
  63. #include "bkmks.h"        /* for drag and drop in mail compose */
  64. #include "icons.h"
  65. #include "icondata.h"
  66.  
  67. #include "felocale.h"
  68.  
  69. #include "motifdnd.h"
  70.  
  71. #include "NSReg.h"
  72.  
  73. #define XFE_RDF
  74. #ifdef XFE_RDF
  75. #include "rdf.h"
  76. #endif
  77.  
  78. #include <signal.h>
  79. #include <unistd.h>
  80. #include <sys/time.h>
  81. #include <sys/wait.h>
  82. #include <netinet/in.h>
  83.  
  84. #include <X11/keysym.h>
  85.  
  86. #ifdef __sgi
  87. # include <malloc.h>
  88. #endif
  89.  
  90. #if defined(AIXV3) || defined(__osf__)
  91. #include <sys/select.h>
  92. #endif /* AIXV3 */
  93.  
  94. #include <arpa/inet.h>    /* for inet_*() */
  95. #include <netdb.h>    /* for gethostbyname() */
  96. #include <pwd.h>
  97. #include <sys/stat.h>
  98. #include <sys/param.h>
  99.  
  100. #include <sys/utsname.h>
  101.  
  102. #include <sys/types.h>
  103. #include <fcntl.h>
  104.  
  105. #include <sys/errno.h>
  106.  
  107. #ifdef UNIX_ASYNC_DNS
  108. #include "xfe-dns.h"
  109. #endif
  110.  
  111. #ifdef MOZILLA_GPROF
  112. #include "gmon.h"
  113. #endif
  114.  
  115. #ifndef _STDC_
  116. #define _STDC_ 1
  117. #define HACKED_STDC 1
  118. #endif
  119.  
  120. #include "src/Netcaster.h"
  121.  
  122. #include <XmL/Folder.h>
  123.  
  124. #include <Xfe/Xfe.h>            /* for xfe widgets and utilities */
  125. #include <Xfe/Button.h>
  126.  
  127. #ifdef HACKED_STDC
  128. #undef HACKED_STDC
  129. #undef _STDC_
  130. #endif
  131.  
  132. extern int awt_MToolkit_dispatchToWidget(XEvent *xev);
  133. extern XP_Bool fe_IsCalendarInstalled(void);
  134.  
  135.  
  136. /* for XP_GetString() */
  137. #include <xpgetstr.h>
  138. extern int XFE_RESOURCES_NOT_INSTALLED_CORRECTLY;
  139. extern int XFE_USAGE_MSG1;
  140. extern int XFE_USAGE_MSG2;
  141. extern int XFE_USAGE_MSG3;
  142. #if defined(MOZ_MAIL_NEWS) && defined(EDITOR) && defined(TASKBAR)
  143. extern int XFE_USAGE_MSG4;
  144. #endif
  145. extern int XFE_USAGE_MSG5;
  146. extern int XFE_VERSION_COMPLAINT_FORMAT;
  147. extern int XFE_INAPPROPRIATE_APPDEFAULT_FILE;
  148. extern int XFE_INVALID_GEOMETRY_SPEC;
  149. extern int XFE_UNRECOGNISED_OPTION;
  150. extern int XFE_APP_HAS_DETECTED_LOCK;
  151. extern int XFE_ANOTHER_USER_IS_RUNNING_APP;
  152. extern int XFE_APPEARS_TO_BE_RUNNING_ON_HOST_UNDER_PID;
  153. extern int XFE_APPEARS_TO_BE_RUNNING_ON_ANOTHER_HOST_UNDER_PID;
  154. extern int XFE_YOU_MAY_CONTINUE_TO_USE;
  155. extern int XFE_OTHERWISE_CHOOSE_CANCEL;
  156. extern int XFE_EXISTED_BUT_WAS_NOT_A_DIRECTORY;
  157. extern int XFE_EXISTS_BUT_UNABLE_TO_RENAME;
  158. extern int XFE_UNABLE_TO_CREATE_DIRECTORY;
  159. extern int XFE_UNKNOWN_ERROR;
  160. extern int XFE_ERROR_CREATING;
  161. extern int XFE_ERROR_WRITING;
  162. extern int XFE_ERROR_SAVING_OPTIONS;
  163. extern int XFE_CREATE_CONFIG_FILES;
  164. extern int XFE_OLD_FILES_AND_CACHE;
  165. extern int XFE_OLD_FILES;
  166. extern int XFE_THE_MOTIF_KEYSYMS_NOT_DEFINED;
  167. extern int XFE_SOME_MOTIF_KEYSYMS_NOT_DEFINED;
  168.  
  169. extern int XFE_SPLASH_REGISTERING_CONVERTERS;
  170. extern int XFE_SPLASH_INITIALIZING_SECURITY_LIBRARY;
  171. extern int XFE_SPLASH_INITIALIZING_NETWORK_LIBRARY;
  172. extern int XFE_SPLASH_INITIALIZING_MESSAGE_LIBRARY;
  173. extern int XFE_SPLASH_INITIALIZING_IMAGE_LIBRARY;
  174. extern int XFE_SPLASH_INITIALIZING_MOCHA;
  175. extern int XFE_SPLASH_INITIALIZING_PLUGINS;
  176.  
  177. extern int XFE_PREFS_DOWNGRADE;
  178.  
  179. extern int XFE_MOZILLA_WRONG_RESOURCE_FILE_VERSION;
  180. extern int XFE_MOZILLA_CANNOT_FOND_RESOURCE_FILE;
  181. extern int XFE_MOZILLA_LOCALE_NOT_SUPPORTED_BY_XLIB;
  182. extern int XFE_MOZILLA_LOCALE_C_NOT_SUPPORTED;
  183. extern int XFE_MOZILLA_LOCALE_C_NOT_SUPPORTED_EITHER;
  184. extern int XFE_MOZILLA_NLS_LOSAGE;
  185. extern int XFE_MOZILLA_NLS_PATH_NOT_SET_CORRECTLY;
  186. extern int XFE_MOZILLA_UNAME_FAILED;
  187. extern int XFE_MOZILLA_UNAME_FAILED_CANT_DETERMINE_SYSTEM;
  188. extern int XFE_MOZILLA_TRYING_TO_RUN_SUNOS_ON_SOLARIS;
  189. extern int XFE_MOZILLA_FAILED_TO_INITIALIZE_EVENT_QUEUE;
  190. extern int XFE_MOZILLA_INVALID_REMOTE_OPTION;
  191. extern int XFE_MOZILLA_ID_OPTION_MUST_PRECEED_REMOTE_OPTIONS;
  192. extern int XFE_MOZILLA_ONLY_ONE_ID_OPTION_CAN_BE_USED;
  193. extern int XFE_MOZILLA_INVALID_OD_OPTION;
  194. extern int XFE_MOZILLA_ID_OPTION_CAN_ONLY_BE_USED_WITH_REMOTE;
  195. extern int XFE_MOZILLA_NOT_FOUND_IN_PATH;
  196. extern int XFE_MOZILLA_RENAMING_SOMETHING_TO_SOMETHING;
  197. extern int XFE_MOZILLA_ERROR_SAVING_OPTIONS;
  198.  
  199. extern int XFE_MOZILLA_XKEYSYMDB_SET_BUT_DOESNT_EXIST;
  200. extern int XFE_MOZILLA_NO_XKEYSYMDB_FILE_FOUND;
  201.  
  202. extern void fe_showCalendar(Widget toplevel);
  203.  
  204. extern void fe_createBookmarks(Widget toplevel, void */*XXX XFE_Frame*/, Chrome *chromespec);
  205. extern MWContext* fe_showBookmarks(Widget toplevel, void *parent_frame, Chrome *chromespec);
  206. extern MWContext* fe_showHistory(Widget toplevel, void *parent_frame, Chrome *chromespec);
  207.  
  208. #ifdef MOZ_MAIL_NEWS
  209. extern MWContext* fe_showInbox(Widget toplevel, void *parent_frame, Chrome *chromespec, XP_Bool with_reuse, XP_Bool getNewMail);
  210. extern MWContext* fe_showNewsgroups(Widget toplevel, void *parent_frame, Chrome *chromespec);
  211. extern Widget fe_MailComposeWin_Create(MWContext* context, Widget parent);
  212. extern void fe_showConference(Widget w, char *email, short use, char *coolAddr);
  213. extern void FE_InitAddrBook();
  214. #endif
  215.  
  216. extern int XFE_COLORMAP_WARNING_TO_IGNORE;
  217.  
  218. #if defined(__sun) && !defined(__svr4__) && (XtSpecificationRelease != 5)
  219. ERROR!!  Must use X11R5 with Motif 1.2 on SunOS 4.1.3!
  220. #endif
  221.  
  222. /* This means "suppress the splash screen if there is was a URL specified
  223.    on the command line."  With betas, we always want the splash screen to
  224.    be printed to make sure the user knows it's beta. */
  225. #define NON_BETA
  226.  
  227. /* Allow a nethelp startup flag */
  228. #define NETHELP_STARTUP_FLAG
  229.  
  230. const char *fe_progname_long;
  231. const char *fe_progname;
  232. const char *fe_progclass;
  233. XtAppContext fe_XtAppContext;
  234. void (*old_xt_warning_handler) (String nameStr, String typeStr, String classStr,
  235.     String defaultStr, String* params, Cardinal* num_params);
  236. XtErrorHandler old_xt_warningOnly_handler;
  237. Display *fe_display = NULL;
  238. Atom WM_SAVE_YOURSELF; /* For Session Manager */
  239.  
  240. char *fe_pidlock;
  241.  
  242. /* Polaris components */
  243. static void fe_InitPolarisComponents(char *);
  244. char *fe_calendar_path = 0;
  245. char *fe_host_on_demand_path = 0;
  246.  
  247. /* Conference */
  248. static void fe_InitConference(char *);
  249. char *fe_conference_path = 0;
  250.  
  251. static int
  252. fe_create_pidlock (const char *name, unsigned long *paddr, pid_t *ppid);
  253.  
  254. static void fe_check_use_async_dns(void);
  255.  
  256. XP_Bool fe_ReadLastUserHistory(char **hist_entry_ptr);
  257.  
  258. #ifdef DEBUG
  259. int Debug;
  260. #endif
  261.  
  262. PRMonitor *fdset_lock;
  263. PRThread *mozilla_thread;
  264. PREventQueue* mozilla_event_queue;
  265.  
  266. /* Begin - Session Manager stuff */
  267.  
  268. int  save_argc = 0;
  269. char **save_argv = NULL;
  270.  
  271. void fe_wm_save_self_cb(Widget, XtPointer, XtPointer);
  272. static const char* fe_locate_program_path(const char* progname);
  273. static char* fe_locate_component_path(const char* fe_prog, char*comp_name);
  274.  
  275. /* End - Session Manager stuff */
  276.  
  277.  
  278. void fe_sec_logo_cb (Widget, XtPointer, XtPointer);
  279.  
  280. #ifndef OLD_UNIX_FILES
  281. static XP_Bool fe_ensure_config_dir_exists (Widget toplevel);
  282. static void fe_copy_init_files (Widget toplevel);
  283. static void fe_clean_old_init_files (Widget toplevel);
  284. #else  /* OLD_UNIX_FILES */
  285. static void fe_rename_init_files (Widget toplevel);
  286. static char *fe_renamed_cache_dir = 0;
  287. #endif /* OLD_UNIX_FILES */
  288.  
  289. static void fe_read_screen_for_rng (Display *dpy, Screen *screen);
  290. static int x_fatal_error_handler(Display *dpy);
  291. static int x_error_handler (Display *dpy, XErrorEvent *event);
  292. static void xt_warning_handler(String nameStr, String typeStr, String classStr,
  293.     String defaultStr, String* params, Cardinal* num_params);
  294. static void xt_warningOnly_handler(String msg);
  295. void fe_GetProgramDirectory(char *path, int len);
  296.  
  297. #if defined(NSPR) && defined(TOSHOK_FIXES_THE_SPLASH_SCREEN_HANGS)
  298. #define NSPR_SPLASH
  299. #endif
  300.  
  301. #ifdef NSPR_SPLASH
  302. extern void fe_splashStart(Widget);
  303. extern void fe_splashUpdateText(char *text);
  304. extern void fe_splashStop(void);
  305. #endif
  306.  
  307. extern void fe_startDisplayFactory(Widget toplevel);
  308.  
  309. static XrmOptionDescRec options [] = {
  310.   { "-geometry",    ".geometry",           XrmoptionSepArg, 0 },
  311.   { "-visual",        ".TopLevelShell.visualID", XrmoptionSepArg, 0 },
  312.   { "-ncols",        ".maxImageColors",        XrmoptionSepArg, 0 },
  313.   { "-iconic",        ".iconic",           XrmoptionNoArg, "True" },
  314.   { "-install",        ".installColormap",       XrmoptionNoArg, "True" },
  315.   { "-noinstall",    ".installColormap",       XrmoptionNoArg, "False" },
  316.   { "-no-install",    ".installColormap",       XrmoptionNoArg, "False" },
  317.   { "-netcaster",    ".startNetcaster",       XrmoptionNoArg, "True" },
  318. #ifdef USE_NONSHARED_COLORMAPS
  319.   { "-share",        ".shareColormap",       XrmoptionNoArg, "True" },
  320.   { "-noshare",        ".shareColormap",       XrmoptionNoArg, "False" },
  321.   { "-no-share",    ".shareColormap",       XrmoptionNoArg, "False" },
  322. #endif
  323.   { "-mono",        ".forceMono",           XrmoptionNoArg, "True" },
  324.   { "-gravity-works",    ".windowGravityWorks",       XrmoptionNoArg, "True" },
  325.   { "-broken-gravity",    ".windowGravityWorks",       XrmoptionNoArg, "False" },
  326.  
  327.   { "-xrm",        0,               XrmoptionResArg, 0 },
  328. #ifdef NSPR_SPLASH
  329.   { "-splash",        ".showSplash",           XrmoptionNoArg, "True" },
  330.   { "-nosplash",    ".showSplash",           XrmoptionNoArg, "False" },
  331. #endif
  332.  
  333. #ifdef MOZ_TASKBAR
  334.   /* Startup component flags */
  335.   { "-component-bar",        ".componentBar",    XrmoptionNoArg, "True" },
  336. #endif
  337. #ifdef MOZ_MAIL_NEWS
  338.  
  339.   { "-composer",            ".composer",        XrmoptionNoArg, "True" },
  340.   { "-edit",                ".composer",        XrmoptionNoArg, "True" },
  341.  
  342.   { "-messenger",            ".mail",            XrmoptionNoArg, "True" },
  343.   { "-mail",                ".mail",            XrmoptionNoArg, "True" },
  344.  
  345. #endif
  346.  
  347.   { "-bookmarks",            ".bookmarks",        XrmoptionNoArg, "True" },
  348.   { "-history",                ".history",            XrmoptionNoArg, "True" },
  349.  
  350. #ifdef NETHELP_STARTUP_FLAG
  351.   { "-nethelp",                ".nethelp",            XrmoptionNoArg, "True" },
  352. #endif
  353.  
  354.   { "-discussions",            ".news",            XrmoptionNoArg, "True" },
  355.   { "-news",                ".news",            XrmoptionNoArg, "True" },
  356.  
  357.   { "-dont-save-geometry-prefs",    ".dontSaveGeometryPrefs",    XrmoptionNoArg, "True"  },
  358.   { "-ignore-geometry-prefs",        ".ignoreGeometryPrefs",        XrmoptionNoArg, "True"  },
  359.  
  360.   { "-no-about-splash",                ".noAboutSplash",            XrmoptionNoArg, "True"  },
  361.  
  362.   /* Turn session management on/off */
  363.   { "-session-management",            ".sessionManagement",        XrmoptionNoArg, "True"  },
  364.   { "-no-session-management",        ".sessionManagement",        XrmoptionNoArg, "False" },
  365.  
  366.   /* Turn IRIX session management on/off */
  367.   { "-irix-session-management",        ".irixSessionManagement",    XrmoptionNoArg, "True"  },
  368.   { "-no-irix-session-management",    ".irixSessionManagement",    XrmoptionNoArg, "False" },
  369.  
  370.   { "-dont-force-window-stacking",    ".dontForceWindowStacking",    XrmoptionNoArg, "True" },
  371. };
  372.  
  373. extern char *fe_fallbackResources[];
  374.  
  375. XtResource fe_Resources [] =
  376. {
  377.   { "linkForeground", XtCForeground, XtRPixel, sizeof (String),
  378.     XtOffset (fe_ContextData *, link_pixel), XtRString, XtDefaultForeground },
  379.   { "vlinkForeground", XtCForeground, XtRPixel, sizeof (String),
  380.     XtOffset (fe_ContextData *, vlink_pixel), XtRString, XtDefaultForeground },
  381.   { "alinkForeground", XtCForeground, XtRPixel, sizeof (String),
  382.     XtOffset (fe_ContextData *, alink_pixel), XtRString, XtDefaultForeground },
  383.  
  384.   { "selectForeground", XtCForeground, XtRPixel, sizeof (String),
  385.     XtOffset (fe_ContextData *, select_fg_pixel), XtRString,
  386.     XtDefaultForeground },
  387.   { "selectBackground", XtCBackground, XtRPixel, sizeof (String),
  388.     XtOffset (fe_ContextData *, select_bg_pixel), XtRString,
  389.     XtDefaultBackground },
  390.  
  391.   { "textBackground", XtCBackground, XtRPixel, sizeof (String),
  392.     XtOffset (fe_ContextData *, text_bg_pixel), XtRString,
  393.     XtDefaultBackground },
  394.  
  395.   { "defaultForeground", XtCForeground, XtRPixel, sizeof (String),
  396.     XtOffset (fe_ContextData *, default_fg_pixel), XtRString,
  397.     XtDefaultForeground },
  398.   { "defaultBackground", XtCBackground, XtRPixel, sizeof (String),
  399.     XtOffset (fe_ContextData *, default_bg_pixel), XtRString,
  400.     XtDefaultBackground },
  401.  
  402.   { "defaultBackgroundImage", XtCString, XtRString, sizeof (String),
  403.     XtOffset (fe_ContextData *, default_background_image),
  404.     XtRImmediate, "" },
  405.  
  406. #ifndef NO_SECURITY
  407.   { "secureDocumentColor", XtCForeground, XtRPixel, sizeof (String),
  408.     XtOffset (fe_ContextData *, secure_document_pixel), XtRString, "green" },
  409.   { "insecureDocumentColor", XtCForeground, XtRPixel, sizeof (String),
  410.     XtOffset (fe_ContextData *, insecure_document_pixel), XtRString, "red" },
  411. #endif /* ! NO_SECURITY */
  412.  
  413.   { "linkCursor", XtCCursor, XtRCursor, sizeof (Cursor),
  414.     XtOffset (fe_ContextData *, link_cursor), XtRString, "hand2" },
  415.   { "busyCursor", XtCCursor, XtRCursor, sizeof (Cursor),
  416.     XtOffset (fe_ContextData *, busy_cursor), XtRString, "watch" },
  417.  
  418.   { "saveNextLinkCursor", XtCCursor, XtRCursor, sizeof (Cursor),
  419.     XtOffset (fe_ContextData *, save_next_link_cursor), XtRString, "hand2" },
  420.   { "saveNextNonlinkCursor", XtCCursor, XtRCursor, sizeof (Cursor),
  421.     XtOffset (fe_ContextData *, save_next_nonlink_cursor),
  422.     XtRString, "crosshair" },
  423. #ifdef EDITOR
  424.   { "editableTextCursor", XtCCursor, XtRCursor, sizeof (Cursor),
  425.     XtOffset (fe_ContextData *, editable_text_cursor),
  426.     XtRString, "xterm" },
  427.   { "tableSelectionCursor", XtCCursor, XtRCursor, sizeof (Cursor),
  428.     XtOffset (fe_ContextData *, tab_sel_cursor),
  429.     XtRString, "top_left_corner" },
  430.   { "rowSelectionCursor", XtCCursor, XtRCursor, sizeof (Cursor),
  431.     XtOffset (fe_ContextData *, row_sel_cursor),
  432.     XtRString, "right_side" },
  433.   { "columnSelectionCursor", XtCCursor, XtRCursor, sizeof (Cursor),
  434.     XtOffset (fe_ContextData *, col_sel_cursor),
  435.     XtRString, "bottom_side" },
  436.   { "cellSelectionCursor", XtCCursor, XtRCursor, sizeof (Cursor),
  437.     XtOffset (fe_ContextData *, cel_sel_cursor),
  438.     XtRString, "top_left_corner" },
  439.   { "resizeColumnCursor", XtCCursor, XtRCursor, sizeof (Cursor),
  440.     XtOffset (fe_ContextData *, resize_col_cursor),
  441.     XtRString, "left_side" },
  442.   { "resizeTableCursor", XtCCursor, XtRCursor, sizeof (Cursor),
  443.     XtOffset (fe_ContextData *, resize_tab_cursor),
  444.     XtRString, "left_side" },
  445.   { "addColumnCursor", XtCCursor, XtRCursor, sizeof (Cursor),
  446.     XtOffset (fe_ContextData *, add_col_cursor),
  447.     XtRString, "right_side" },
  448.   { "addRowCursor", XtCCursor, XtRCursor, sizeof (Cursor),
  449.     XtOffset (fe_ContextData *, add_row_cursor),
  450.     XtRString, "right_side" },
  451. #endif
  452.  
  453.   { "confirmExit", XtCBoolean, XtRBoolean, sizeof (Boolean),
  454.     XtOffset (fe_ContextData *, confirm_exit_p), XtRImmediate,
  455.     (XtPointer) True },
  456.  
  457.   { "progressInterval", "Seconds", XtRCardinal, sizeof (int),
  458.     XtOffset (fe_ContextData *, progress_interval),
  459.     XtRImmediate, (XtPointer) 1 },
  460.   { "busyBlinkRate", "Microseconds", XtRCardinal, sizeof (int),
  461.     XtOffset (fe_ContextData *, busy_blink_rate),
  462.     XtRImmediate, (XtPointer) 500 },
  463.   { "hysteresis", "Pixels", XtRCardinal, sizeof (int),
  464.     XtOffset (fe_ContextData *, hysteresis), XtRImmediate, (XtPointer) 5 },
  465.   { "blinkingEnabled", "BlinkingEnabled", XtRBoolean, sizeof (Boolean),
  466.     XtOffset (fe_ContextData *, blinking_enabled_p), XtRImmediate,
  467.     (XtPointer) True }
  468. };
  469. Cardinal fe_ResourcesSize = XtNumber (fe_Resources);
  470.  
  471. XtResource fe_GlobalResources [] =
  472. {
  473.   { "encodingFilters", XtCString, XtRString, sizeof (String),
  474.     XtOffset (fe_GlobalData *, encoding_filters), XtRImmediate, "" },
  475.  
  476.   { "saveHistoryInterval", "Seconds", XtRCardinal, sizeof (int),
  477.     XtOffset (fe_GlobalData *, save_history_interval), XtRImmediate,
  478.     (XtPointer) 600 },
  479.  
  480.   { "terminalTextTranslations", XtCTranslations,
  481.     XtRTranslationTable, sizeof (XtTranslations),
  482.     XtOffset (fe_GlobalData *, terminal_text_translations),
  483.     XtRImmediate, 0 },
  484.   { "nonterminalTextTranslations", XtCTranslations,
  485.     XtRTranslationTable, sizeof (XtTranslations),
  486.     XtOffset (fe_GlobalData *, nonterminal_text_translations),
  487.     XtRImmediate, 0 },
  488.  
  489.   { "globalTranslations", XtCTranslations,
  490.     XtRTranslationTable, sizeof (XtTranslations),
  491.     XtOffset (fe_GlobalData *, global_translations),
  492.     XtRImmediate, 0 },
  493.   { "globalTextFieldTranslations", XtCTranslations,
  494.     XtRTranslationTable, sizeof (XtTranslations),
  495.     XtOffset (fe_GlobalData *, global_text_field_translations),
  496.     XtRImmediate, 0 },
  497.   { "globalNonTextTranslations", XtCTranslations,
  498.     XtRTranslationTable, sizeof (XtTranslations),
  499.     XtOffset (fe_GlobalData *, global_nontext_translations),
  500.     XtRImmediate, 0 },
  501.  
  502.   { "editingTranslations", XtCTranslations,
  503.     XtRTranslationTable, sizeof (XtTranslations),
  504.     XtOffset (fe_GlobalData *, editing_translations),
  505.     XtRImmediate, 0 },
  506.   { "singleLineEditingTranslations", XtCTranslations,
  507.     XtRTranslationTable, sizeof (XtTranslations),
  508.     XtOffset (fe_GlobalData *, single_line_editing_translations),
  509.     XtRImmediate, 0 },
  510.   { "multiLineEditingTranslations", XtCTranslations,
  511.     XtRTranslationTable, sizeof (XtTranslations),
  512.     XtOffset (fe_GlobalData *, multi_line_editing_translations),
  513.     XtRImmediate, 0 },
  514.   { "formElemEditingTranslations", XtCTranslations, /* form text field elem only */
  515.     XtRTranslationTable, sizeof (XtTranslations),
  516.     XtOffset (fe_GlobalData *, form_elem_editing_translations),
  517.     XtRImmediate, 0 },
  518.  
  519.   { "browserGlobalTranslations", XtCTranslations,
  520.     XtRTranslationTable, sizeof (XtTranslations),
  521.     XtOffset (fe_GlobalData *, browser_global_translations),
  522.     XtRImmediate, 0 },
  523.   { "abGlobalTranslations", XtCTranslations,
  524.     XtRTranslationTable, sizeof (XtTranslations),
  525.     XtOffset (fe_GlobalData *, ab_global_translations),
  526.     XtRImmediate, 0 },
  527.   { "bmGlobalTranslations", XtCTranslations,
  528.     XtRTranslationTable, sizeof (XtTranslations),
  529.     XtOffset (fe_GlobalData *, bm_global_translations),
  530.     XtRImmediate, 0 },
  531.   { "mnsearchGlobalTranslations", XtCTranslations,
  532.     XtRTranslationTable, sizeof (XtTranslations),
  533.     XtOffset (fe_GlobalData *, mnsearch_global_translations),
  534.     XtRImmediate, 0 },
  535.   { "ghGlobalTranslations", XtCTranslations,
  536.     XtRTranslationTable, sizeof (XtTranslations),
  537.     XtOffset (fe_GlobalData *, gh_global_translations),
  538.     XtRImmediate, 0 },
  539.   { "mailnewsGlobalTranslations", XtCTranslations,
  540.     XtRTranslationTable, sizeof (XtTranslations),
  541.     XtOffset (fe_GlobalData *, mailnews_global_translations),
  542.     XtRImmediate, 0 },
  543.   { "messagewinGlobalTranslations", XtCTranslations,
  544.     XtRTranslationTable, sizeof (XtTranslations),
  545.     XtOffset (fe_GlobalData *, messagewin_global_translations),
  546.     XtRImmediate, 0 },
  547.   { "mailcomposeGlobalTranslations", XtCTranslations,
  548.     XtRTranslationTable, sizeof (XtTranslations),
  549.     XtOffset (fe_GlobalData *, mailcompose_global_translations),
  550.     XtRImmediate, 0 },
  551.   { "addressOutlinerTraverseTranslations", XtCTranslations,
  552.     XtRTranslationTable, sizeof (XtTranslations),
  553.     XtOffset (fe_GlobalData *, address_outliner_traverse_translations),
  554.     XtRImmediate, 0 },
  555.   { "addressOutlinerKeyTranslations", XtCTranslations,
  556.     XtRTranslationTable, sizeof (XtTranslations),
  557.     XtOffset (fe_GlobalData *, address_outliner_key_translations),
  558.     XtRImmediate, 0 },
  559.   { "dialogGlobalTranslations", XtCTranslations,
  560.     XtRTranslationTable, sizeof (XtTranslations),
  561.     XtOffset (fe_GlobalData *, dialog_global_translations),
  562.     XtRImmediate, 0 },
  563.   { "editorTranslations", XtCTranslations,
  564.     XtRTranslationTable, sizeof (XtTranslations),
  565.     XtOffset (fe_GlobalData *, editor_global_translations),
  566.     XtRImmediate, 0 },
  567.  
  568.   { "forceMono", XtCBoolean, XtRBoolean, sizeof (Boolean),
  569.     XtOffset (fe_GlobalData *, force_mono_p), XtRImmediate,
  570.     (XtPointer) False },
  571.   { "wmIconPolicy", XtCString, XtRString, sizeof (String),
  572.     XtOffset (fe_GlobalData *, wm_icon_policy), XtRImmediate,
  573.     (XtPointer) NULL },
  574. #ifdef USE_NONSHARED_COLORMAPS
  575.   { "shareColormap", XtCBoolean, XtRBoolean, sizeof (Boolean),
  576.     XtOffset (fe_GlobalData *, windows_share_cmap), XtRImmediate,
  577.     (XtPointer) False },
  578. #endif
  579.   { "maxImageColors", "Integer", XtRCardinal, sizeof (int),
  580.     XtOffset (fe_GlobalData *, max_image_colors), XtRImmediate,
  581.     (XtPointer) 0 },
  582.  
  583. #ifdef __sgi
  584.   { "sgiMode", XtCBoolean, XtRBoolean, sizeof (Boolean),
  585.     XtOffset (fe_GlobalData *, sgi_mode_p), XtRImmediate,
  586.     (XtPointer) False },
  587. #endif /* __sgi */
  588.  
  589.   { "useStderrDialog", XtCBoolean, XtRBoolean, sizeof (Boolean),
  590.     XtOffset (fe_GlobalData *, stderr_dialog_p), XtRImmediate,
  591.     (XtPointer) True },
  592.   { "useStdoutDialog", XtCBoolean, XtRBoolean, sizeof (Boolean),
  593.     XtOffset (fe_GlobalData *, stdout_dialog_p), XtRImmediate,
  594.     (XtPointer) True },
  595.  
  596.   /* #### move to prefs */
  597.   { "documentColorsHavePriority", XtCBoolean, XtRBoolean, sizeof (Boolean),
  598.     XtOffset (fe_GlobalData *, document_beats_user_p), XtRImmediate,
  599.     (XtPointer) True },
  600.  
  601.   /* #### move to prefs */
  602.   { "languageRegionList", XtCString, XtRString, sizeof (String),
  603.     XtOffset (fe_GlobalData *, language_region_list), XtRImmediate, "" },
  604.   { "invalidLangTagFormatMsg", XtCString, XtRString, sizeof (String),
  605.     XtOffset (fe_GlobalData *, invalid_lang_tag_format_msg), XtRImmediate, "" },
  606.   { "invalidLangTagFormatDialogTitle", XtCString, XtRString, sizeof (String),
  607.     XtOffset (fe_GlobalData *, invalid_lang_tag_format_dialog_title), 
  608.     XtRImmediate, "" },
  609.  
  610. # define RES_ERROR "ERROR: Resources not installed correctly!"
  611.   { "noDocumentLoadedMessage", XtCString, XtRString, sizeof (String),
  612.     XtOffset (fe_GlobalData *, no_url_loaded_message),
  613.     XtRImmediate, RES_ERROR },
  614.   { "optionsSavedMessage", XtCString, XtRString, sizeof (String),
  615.     XtOffset (fe_GlobalData *, options_saved_message),
  616.     XtRImmediate, RES_ERROR },
  617.   { "clickToSaveMessage", XtCString, XtRString, sizeof (String),
  618.     XtOffset (fe_GlobalData *, click_to_save_message),
  619.     XtRImmediate, RES_ERROR },
  620.   { "clickToSaveCancelledMessage", XtCString, XtRString, sizeof (String),
  621.     XtOffset (fe_GlobalData *, click_to_save_cancelled_message),
  622.     XtRImmediate, RES_ERROR },
  623.   { "noNextURLMessage", XtCString, XtRString, sizeof (String),
  624.     XtOffset (fe_GlobalData *, no_next_url_message),
  625.     XtRImmediate, RES_ERROR },
  626.   { "noPreviousURLMessage", XtCString, XtRString, sizeof (String),
  627.     XtOffset (fe_GlobalData *, no_previous_url_message),
  628.     XtRImmediate, RES_ERROR },
  629.   { "noHomeURLMessage", XtCString, XtRString, sizeof (String),
  630.     XtOffset (fe_GlobalData *, no_home_url_message),
  631.     XtRImmediate, RES_ERROR },
  632.   { "notOverImageMessage", XtCString, XtRString, sizeof (String),
  633.     XtOffset (fe_GlobalData *, not_over_image_message),
  634.     XtRImmediate, RES_ERROR },
  635.   { "notOverLinkMessage", XtCString, XtRString, sizeof (String),
  636.     XtOffset (fe_GlobalData *, not_over_link_message),
  637.     XtRImmediate, RES_ERROR },
  638.   { "noSearchStringMessage", XtCString, XtRString, sizeof (String),
  639.     XtOffset (fe_GlobalData *, no_search_string_message),
  640.     XtRImmediate, RES_ERROR },
  641.   { "wrapSearchMessage", XtCString, XtRString, sizeof (String),
  642.     XtOffset (fe_GlobalData *, wrap_search_message),
  643.     XtRImmediate, RES_ERROR },
  644.   { "wrapSearchBackwardMessage", XtCString, XtRString, sizeof (String),
  645.     XtOffset (fe_GlobalData *, wrap_search_backward_message),
  646.     XtRImmediate, RES_ERROR },
  647.   { "wrapSearchNotFoundMessage", XtCString, XtRString, sizeof (String),
  648.     XtOffset (fe_GlobalData *, wrap_search_not_found_message),
  649.     XtRImmediate, RES_ERROR },
  650.   { "noAddressesMessage", XtCString, XtRString, sizeof (String),
  651.     XtOffset (fe_GlobalData *, no_addresses_message),
  652.     XtRImmediate, RES_ERROR },
  653.   { "noFileMessage", XtCString, XtRString, sizeof (String),
  654.     XtOffset (fe_GlobalData *, no_file_message),
  655.     XtRImmediate, RES_ERROR },
  656.   { "noPrintCommandMessage", XtCString, XtRString, sizeof (String),
  657.     XtOffset (fe_GlobalData *, no_print_command_message),
  658.     XtRImmediate, RES_ERROR },
  659.   { "bookmarksChangedMessage", XtCString, XtRString, sizeof (String),
  660.     XtOffset (fe_GlobalData *, bookmarks_changed_message),
  661.     XtRImmediate, RES_ERROR },
  662.   { "bookmarkConflictMessage", XtCString, XtRString, sizeof (String),
  663.     XtOffset (fe_GlobalData *, bookmark_conflict_message),
  664.     XtRImmediate, RES_ERROR },
  665.   { "bookmarksNoFormsMessage", XtCString, XtRString, sizeof (String),
  666.     XtOffset (fe_GlobalData *, bookmarks_no_forms_message),
  667.     XtRImmediate, RES_ERROR },
  668.   { "reallyQuitMessage", XtCString, XtRString, sizeof (String),
  669.     XtOffset (fe_GlobalData *, really_quit_message),
  670.     XtRImmediate, RES_ERROR },
  671.   { "doubleInclusionMessage", XtCString, XtRString, sizeof (String),
  672.     XtOffset (fe_GlobalData *, double_inclusion_message),
  673.     XtRImmediate, RES_ERROR },
  674.   { "expireNowMessage", XtCString, XtRString, sizeof (String),
  675.     XtOffset (fe_GlobalData *, expire_now_message),
  676.     XtRImmediate, RES_ERROR },
  677.   { "clearMemCacheMessage", XtCString, XtRString, sizeof (String),
  678.     XtOffset (fe_GlobalData *, clear_mem_cache_message),
  679.     XtRImmediate, RES_ERROR },
  680.   { "clearDiskCacheMessage", XtCString, XtRString, sizeof (String),
  681.     XtOffset (fe_GlobalData *, clear_disk_cache_message),
  682.     XtRImmediate, RES_ERROR },
  683.   { "createCacheDirErrorMessage", XtCString, XtRString, sizeof (String),
  684.     XtOffset (fe_GlobalData *, create_cache_dir_message),
  685.     XtRImmediate, RES_ERROR },
  686.   { "createdCacheDirMessage", XtCString, XtRString, sizeof (String),
  687.     XtOffset (fe_GlobalData *, created_cache_dir_message),
  688.     XtRImmediate, RES_ERROR },
  689.   { "cacheNotDirMessage", XtCString, XtRString, sizeof (String),
  690.     XtOffset (fe_GlobalData *, cache_not_dir_message),
  691.     XtRImmediate, RES_ERROR },
  692.   { "cacheSuffixMessage", XtCString, XtRString, sizeof (String),
  693.     XtOffset (fe_GlobalData *, cache_suffix_message),
  694.     XtRImmediate, RES_ERROR },
  695.   { "cubeTooSmallMessage", XtCString, XtRString, sizeof (String),
  696.     XtOffset (fe_GlobalData *, cube_too_small_message),
  697.     XtRImmediate, RES_ERROR },
  698.   { "renameInitFilesMessage", XtCString, XtRString, sizeof (String),
  699.     XtOffset (fe_GlobalData *, rename_files_message),
  700.     XtRImmediate, RES_ERROR },
  701.   { "overwriteFileMessage", XtCString, XtRString, sizeof (String),
  702.     XtOffset (fe_GlobalData *, overwrite_file_message),
  703.     XtRImmediate, RES_ERROR },
  704.   { "unsentMailMessage", XtCString, XtRString, sizeof (String),
  705.     XtOffset (fe_GlobalData *, unsent_mail_message),
  706.     XtRImmediate, RES_ERROR },
  707.   { "binaryDocumentMessage", XtCString, XtRString, sizeof (String),
  708.     XtOffset (fe_GlobalData *, binary_document_message),
  709.     XtRImmediate, RES_ERROR },
  710.   { "defaultCharset", XtCString, XtRString, sizeof (String),
  711.     XtOffset (fe_GlobalData *, default_url_charset),
  712.     XtRImmediate, "" },
  713.   { "emptyMessageQuestion", XtCString, XtRString, sizeof (String),
  714.     XtOffset (fe_GlobalData *, empty_message_message),
  715.     XtRImmediate, RES_ERROR },
  716.   { "defaultMailtoText", XtCString, XtRString, sizeof (String),
  717.     XtOffset (fe_GlobalData *, default_mailto_text),
  718.     XtRImmediate, "" },
  719.   { "helperAppDeleteMessage", XtCString, XtRString, sizeof (String),
  720.     XtOffset (fe_GlobalData *, helper_app_delete_message),
  721.     XtRImmediate, "" },
  722.  
  723. #ifdef MOZ_TASKBAR
  724.   /* Startup component flags */
  725.   { "componentBar", XtCBoolean, XtRBoolean, sizeof(Boolean),
  726.     XtOffset (fe_GlobalData *, startup_component_bar), XtRImmediate,
  727.     (XtPointer) False },
  728. #endif
  729. #ifdef MOZ_MAIL_NEWS
  730.   { "composer", XtCBoolean, XtRBoolean, sizeof(Boolean),
  731.     XtOffset (fe_GlobalData *, startup_composer), XtRImmediate,
  732.     (XtPointer) False },
  733.  
  734.   { "mail", XtCBoolean, XtRBoolean, sizeof(Boolean),
  735.     XtOffset (fe_GlobalData *, startup_mail), XtRImmediate,
  736.     (XtPointer) False },
  737.  
  738.   { "news", XtCBoolean, XtRBoolean, sizeof(Boolean),
  739.     XtOffset (fe_GlobalData *, startup_news), XtRImmediate,
  740.     (XtPointer) False },
  741.  
  742. #endif
  743.  
  744. #ifdef NETHELP_STARTUP_FLAG
  745.   { "nethelp", XtCBoolean, XtRBoolean, sizeof(Boolean),
  746.     XtOffset (fe_GlobalData *, startup_nethelp), XtRImmediate,
  747.     (XtPointer) False },
  748. #endif
  749.  
  750.   { "history", XtCBoolean, XtRBoolean, sizeof(Boolean),
  751.     XtOffset (fe_GlobalData *, startup_history), XtRImmediate,
  752.     (XtPointer) False },
  753.  
  754.   { "bookmarks", XtCBoolean, XtRBoolean, sizeof(Boolean),
  755.     XtOffset (fe_GlobalData *, startup_bookmarks), XtRImmediate,
  756.     (XtPointer) False },
  757.  
  758.   { "iconic", XtCBoolean, XtRBoolean, sizeof (Boolean),
  759.     XtOffset (fe_GlobalData *, startup_iconic), XtRImmediate,
  760.     (XtPointer) False },
  761.  
  762.   { "geometry", XtCString, XtRString, sizeof (String),
  763.     XtOffset (fe_GlobalData *, startup_geometry), XtRString,
  764.     "" },
  765.  
  766.   { "dontSaveGeometryPrefs", XtCBoolean, XtRBoolean, sizeof (Boolean),
  767.     XtOffset (fe_GlobalData *, dont_save_geom_prefs), XtRImmediate,
  768.     (XtPointer) False },
  769.  
  770.   { "ignoreGeometryPrefs", XtCBoolean, XtRBoolean, sizeof (Boolean),
  771.     XtOffset (fe_GlobalData *, ignore_geom_prefs), XtRImmediate,
  772.     (XtPointer) False },
  773.  
  774.   { "noAboutSplash", XtCBoolean, XtRBoolean, sizeof (Boolean),
  775.     XtOffset (fe_GlobalData *, startup_no_about_splash), XtRImmediate,
  776.     (XtPointer) False },
  777.  
  778.  
  779.   /* Session management is on by default */
  780.   { "sessionManagement", XtCBoolean, XtRBoolean, sizeof (Boolean),
  781.     XtOffset (fe_GlobalData *, session_management), XtRImmediate,
  782.     (XtPointer) True },
  783.  
  784.   /* IRIX Session management should only be on by default on irix platforms */
  785.   { "irixSessionManagement", XtCBoolean, XtRBoolean, sizeof (Boolean),
  786.     XtOffset (fe_GlobalData *, irix_session_management), XtRImmediate,
  787. #if (defined(IRIX))
  788.     (XtPointer) True },
  789. #else
  790.     (XtPointer) False },
  791. #endif
  792.   { "dontForceWindowStacking", XtCBoolean, XtRBoolean, sizeof (Boolean),
  793.     XtOffset (fe_GlobalData *, dont_force_window_stacking), XtRImmediate,
  794.     (XtPointer) False },
  795.  
  796. #ifdef NSPR_SPLASH
  797.   { "showSplash", XtCBoolean, XtRBoolean, sizeof (Boolean),
  798.     XtOffset (fe_GlobalData *, show_splash), XtRImmediate,
  799.     (XtPointer) True },
  800. #endif
  801.   { "editorUpdateDelay", "ms", XtRCardinal, sizeof (Cardinal),
  802.     XtOffset (fe_GlobalData *, editor_update_delay), XtRImmediate, 
  803.     (XtPointer) 20
  804.   },
  805.   { "editorImInputEnabled", XtCBoolean, XtRBoolean, sizeof (Boolean),
  806.     XtOffset (fe_GlobalData *, editor_im_input_enabled), XtRImmediate,
  807. #if (defined(IRIX) && !defined(IRIX6_2) && !defined(IRIX6_3))
  808.     (XtPointer) False },
  809. #else
  810.     (XtPointer) True }
  811. #endif
  812.  
  813. # undef RES_ERROR
  814. };
  815. Cardinal fe_GlobalResourcesSize = XtNumber (fe_GlobalResources);
  816.  
  817. fe_GlobalData   fe_globalData   = { 0, };
  818. XFE_GlobalPrefs fe_globalPrefs  = { 0, };
  819. XFE_GlobalPrefs fe_defaultPrefs = { 0, };
  820.  
  821. static void
  822. usage (void)
  823. {
  824.   fprintf (stderr, XP_GetString( XFE_USAGE_MSG1 ), fe_long_version + 4,
  825.                   fe_progname);
  826.  
  827. #ifdef USE_NONSHARED_COLORMAPS
  828.   fprintf (stderr,  XP_GetString( XFE_USAGE_MSG2 ) );
  829. #endif
  830.  
  831.   fprintf (stderr, XP_GetString( XFE_USAGE_MSG3 ) );
  832.  
  833. #if defined(MOZ_MAIL_NEWS) && defined(MOZ_TASKBAR) && defined(EDITOR)
  834.   fprintf (stderr, XP_GetString( XFE_USAGE_MSG4 ) );
  835. #endif
  836.  
  837.   fprintf (stderr, XP_GetString( XFE_USAGE_MSG5 ) );
  838. }
  839.  
  840. /*******************
  841.  * Signal handlers *
  842.  *******************/
  843. void fe_sigchild_handler(int signo)
  844. {
  845.   pid_t pid;
  846.   int status = 0;
  847.   while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
  848. #ifdef DEBUG_dp
  849.     fprintf(stderr, "fe_sigchild_handler: Reaped pid %d.\n", pid);
  850. #endif
  851.   }
  852. }
  853.  
  854. /* Netlib re-enters itself sometimes, so this has to be a counter not a flag */
  855. static int fe_netlib_hungry_p = 0;
  856.  
  857. void
  858. XFE_SetCallNetlibAllTheTime (MWContext * context)
  859. {
  860.   fe_netlib_hungry_p++;
  861. }
  862.  
  863. void
  864. XFE_ClearCallNetlibAllTheTime (MWContext * context)
  865. {
  866.   --fe_netlib_hungry_p;
  867.   XP_ASSERT(fe_netlib_hungry_p >= 0);
  868. }
  869.  
  870. void
  871. XP_SetCallNetlibAllTheTime (MWContext * context)
  872. {
  873.   fe_netlib_hungry_p++;
  874. }
  875.  
  876. void
  877. XP_ClearCallNetlibAllTheTime (MWContext * context)
  878. {
  879.   --fe_netlib_hungry_p;
  880.   XP_ASSERT(fe_netlib_hungry_p >= 0);
  881. }
  882.  
  883. static void  fe_EventForRNG (XEvent *event);
  884. /* Use a static so that the difference between the running X clock
  885.    and the time that we are about to block is a function of the
  886.    amount of time the last processing took.
  887.  */
  888. static XEvent fe_last_event;
  889.  
  890.  
  891. /* Hack to determine whether a Motif drag operation is in progress.
  892.  * This also catches menu system activity, but that should be cool.
  893.  */
  894. #include <Xm/DisplayP.h>
  895. #define IsMotifDragActive(dpy) ( \
  896.                                     ((XmDisplayRec*)XmGetXmDisplay(dpy))->display.userGrabbed \
  897.                                     ? TRUE : FALSE )
  898.  
  899. /* Process events. The idea here is to give X events priority over
  900.    file descriptor input so that the user gets better interactive
  901.    response under heavy i/o load.
  902.  
  903.    While we are it, we try to gather up a bunch of events to shovel
  904.    into the security library to "improve" randomness.
  905.  
  906.    Finally, we try to block when there is really nothing to do,
  907.    but we block in such a way as to allow java applets to get the
  908.    cpu while we are blocked.
  909.  
  910.    Simple, eh? If you don't understand it, don't touch it. Instead
  911.    find kipp.
  912.    */
  913. void
  914. fe_EventLoop ()
  915. {
  916.   XtInputMask pending;
  917.   static unsigned long device_event_count = 0;
  918.   XP_Bool haveEvent;        /* Used only in debugging sessions. */
  919. #ifdef DEBUG
  920.   int first_time = 1;
  921.   static int entry_depth = 0;
  922.   static int spinning_wildly = 0;
  923.  
  924.   entry_depth++;
  925. #endif
  926.  
  927.   /* Feed the security library the last event we handled. We do this here
  928.      before peeking for another event so that the elapsed time between calls
  929.      can have some impact on the outcome.
  930.      */
  931.   fe_EventForRNG (&fe_last_event);
  932.  
  933.   /* Release X lock and wait for an event to show up. This might not return
  934.      an X event, and it will not block until there is an X event. However,
  935.      it will block (i.e. call select) if there is no X events, timer events
  936.      or i/o events immediately pending. Which is what we want it to do.
  937.  
  938.      XtAppPeekEvent promises to return after something is ready:
  939.      i/o, x event or xt timer. It returns a value that indicates
  940.      if the event structure passed to it gets filled in (we don't care
  941.      so we ignore the value). The locking is now done inside select - Radha
  942.      */
  943.   /*   PR_XUnlock(); */
  944.   haveEvent = XtAppPeekEvent(fe_XtAppContext, &fe_last_event);
  945.   /*   PR_XLock();  */
  946.  
  947.   /* Consume all the X events and timer events right now. As long as
  948.      there are X events or Xt timer events, we will sit and spin here.
  949.      As soon as those are exhausted we fall out of the loop.
  950.      */
  951.   for (;;) {
  952.       /* fe_EventLoop()'s stratified processing of events/timers/input
  953.        * can confuse Motif Drag+Drop, and result in permanent window
  954.        * droppings: Motif fires off its own drag event loop from
  955.        * a timer proc, but there is a few-milliseconds window between
  956.        * XmDragStart() and the timer firing. If a user ButtonRelease
  957.        * event arrives and is processed by fe_EventLoop() during that window,
  958.        * then the cursor window dropping is left behind until the entire
  959.        * application quits..
  960.        *
  961.        * So, detect the start of a drag, and revert to a spick+span Xt event
  962.        * loop until the timer for the Motif drag event loop kicks in.
  963.        */
  964.       if (fe_display && IsMotifDragActive(fe_display)) {
  965.           XEvent event;
  966.           while (IsMotifDragActive(fe_display)) {
  967.               XtAppNextEvent(fe_XtAppContext,&event);
  968.               XtDispatchEvent(&event);
  969.           }
  970.           /* all done, let the funkiness continue. */
  971.       }
  972.  
  973.       
  974.       /* Get a mask of the pending events, timers and i/o streams that
  975.      are ready for processing. This event will not block, but instead
  976.      will return 0 when there is nothing pending remaining.
  977.      */
  978.       pending = XtAppPending(fe_XtAppContext);
  979.       if (pending == 0) {
  980. #ifdef DEBUG
  981.       /* Nothing to do anymore. Time to leave. We ought to be able to
  982.          assert that first_time is 0; that is, that we have
  983.          processed at least one event before breaking out of the loop.
  984.          Such an assert would help us detect busted Xt libraries.  However,
  985.          in reality, we have already determined that we do have such busted
  986.          libraries.  So, we'll assert that this doesn't happen more than
  987.          once in a row, so that we know we don't really spin wildly.
  988.          */
  989.       if (first_time) {
  990. #ifndef I_KNOW_MY_Xt_IS_BAD
  991. #ifdef NSPR20
  992.         /*
  993.          * XXX - TO BE FIXED
  994.          * with NSPR20 this count seems to go as high as 7 or 8; needs to
  995.          * be investigated further
  996.          */
  997.           XP_ASSERT(spinning_wildly < 12);
  998. #else
  999.           XP_ASSERT(spinning_wildly < 3);
  1000. #endif
  1001. #endif /* I_KNOW_MY_Xt_IS_BAD */
  1002.           spinning_wildly++;
  1003.       }
  1004. #endif
  1005.       break;
  1006.       }
  1007. #ifdef DEBUG
  1008.       /* Now we have one event. It's no longer our first time */
  1009.       first_time = 0;
  1010.       spinning_wildly = 0;
  1011. #endif
  1012.       if (pending & XtIMXEvent) {
  1013. #ifdef JAVA
  1014.       extern int awt_MToolkit_dispatchToWidget(XEvent *);
  1015. #endif
  1016.       /* We have an X event to process. We check them first because
  1017.          we want to be as responsive to the user as possible.
  1018.          */
  1019.       if (device_event_count < 300) {
  1020.           /* While the security library is still hungry for events
  1021.          we feed it all the events we get. We use XtAppPeekEvent
  1022.          to grab a copy of the event that XtAppPending said was
  1023.          available.
  1024.          */
  1025.           XtAppPeekEvent(fe_XtAppContext, &fe_last_event);
  1026.           fe_EventForRNG (&fe_last_event);
  1027.  
  1028.           /* If it's an interesting event, count it towards our
  1029.          goal of 300 events. After 300 events, we don't need
  1030.          to feed the security library as often (which makes
  1031.          us more efficient at event processing)
  1032.          */
  1033.           if (fe_last_event.xany.type == ButtonPress ||
  1034.           fe_last_event.xany.type == ButtonRelease ||
  1035.           fe_last_event.xany.type == KeyPress ||
  1036.           fe_last_event.xany.type == MotionNotify)
  1037.           {
  1038.           device_event_count++;
  1039.           }
  1040.       }
  1041. #ifdef JAVA
  1042.        else {
  1043.            XtAppPeekEvent(fe_XtAppContext, &fe_last_event);
  1044.        }
  1045.        /* Allow Java to filter this event. If java doesn't
  1046.       ** consume the event, give it to mozilla
  1047.       */
  1048.        if (awt_MToolkit_dispatchToWidget(&fe_last_event) == 0) {
  1049. #endif    /* JAVA */
  1050.       /* Feed the X event to Xt, being careful to not allow it to
  1051.          process timers or i/o. */
  1052.       XtAppProcessEvent(fe_XtAppContext, XtIMXEvent);
  1053.  
  1054. #ifdef JAVA
  1055.        } else {
  1056.            /* Discard event since Java has processed it.
  1057.           Don't use XtAppNextEvent here, otherwise Xt will
  1058.           spin wildly (at least on IRIX). -- erik
  1059.           */
  1060.                 XNextEvent(fe_display, &fe_last_event); 
  1061.       }
  1062. #endif   /* JAVA */
  1063.       } else if (pending & XtIMTimer) {
  1064.       /* Let Xt dispatch the Xt timer event. For this case we fall out
  1065.          of the loop in case a very fast timer was set.
  1066.          */
  1067.       XtAppProcessEvent(fe_XtAppContext, XtIMTimer);
  1068.       break;
  1069.       } else {
  1070.       /* Go ahead and process the i/o event XtAppPending has
  1071.          reported. However, as soon as it is done fall out of
  1072.          the loop. This way we return to the caller after
  1073.          doing something.
  1074.          */
  1075.       XtAppProcessEvent(fe_XtAppContext, pending);
  1076.  
  1077. #ifdef __sgi
  1078.       /*
  1079.        * The SGI version of Xt has a bug where XtAppPending will mark
  1080.        * an internal data structure again when it sees input pending on
  1081.        * the Asian input method socket, even though XtAppProcessEvent
  1082.        * has already put a dummy X event with zero keycode on the X
  1083.        * event queue, which is supposed to tell Xlib to read the IM
  1084.        * socket (when XFilterEvent is called by Xt).
  1085.        *
  1086.        * So we process the dummy event immediately after it has been
  1087.        * put on the queue, so that XtAppPending doesn't mark its data
  1088.        * structure again.
  1089.        */
  1090.       while (XPending(fe_display)) {
  1091.           XtAppProcessEvent(fe_XtAppContext, XtIMXEvent);
  1092.       }
  1093. #endif /* __sgi */
  1094.  
  1095.       break;
  1096.       }
  1097.   }
  1098.  
  1099. #ifdef JAVA
  1100. {
  1101.    extern void awt_MToolkit_finishModals(void);
  1102.    awt_MToolkit_finishModals();
  1103. }
  1104. #endif /* JAVA */
  1105.  
  1106.   /* If netlib is anxious, service it after every event, and service it
  1107.      continuously while there are no events. */
  1108.   if (fe_netlib_hungry_p)
  1109.     do
  1110.     {
  1111. #ifdef QUANTIFY
  1112. quantify_start_recording_data();
  1113. #endif /* QUANTIFY */
  1114.       NET_ProcessNet (-1, NET_EVERYTIME_TYPE);
  1115. #ifdef QUANTIFY
  1116. quantify_stop_recording_data();
  1117. #endif /* QUANTIFY */
  1118. #ifdef MOZ_NEO
  1119.       /* Currently just to give NeoAccess some cycles - whether it does
  1120.          anything, and what it does needs investigation. Also, this really
  1121.          needs to be a NeoOnIdle when other neoaccess components come on line
  1122.        */
  1123.       MSG_OnIdle();  
  1124. #endif
  1125.     }
  1126.     while (fe_netlib_hungry_p && !XtAppPending (fe_XtAppContext));
  1127. #ifdef DEBUG
  1128.   entry_depth--;
  1129. #endif
  1130. }
  1131.  
  1132. static void
  1133. fe_EventForRNG (XEvent *event)
  1134. {
  1135.   struct
  1136.   {
  1137.     XEvent event;
  1138.     unsigned char noise[16];
  1139.   } data;
  1140.  
  1141.   data.event = *event;
  1142.  
  1143.   /* At this point, we are idle.  Get a high-res clock value. */
  1144.   (void) RNG_GetNoise(data.noise, sizeof(data.noise));
  1145.  
  1146.   /* Kick security library random number generator to make it very
  1147.      hard for a bad guy to predict where the random number generator
  1148.      is at.  Initialize it with the current time, and the *previous*
  1149.      X event we read (which happens to have a server timestamp in it.)
  1150.      The X event came from before this current idle period began, and
  1151.      will be uninitialized stack data the first time through.
  1152.    */
  1153.   RNG_RandomUpdate(&data, sizeof(data));
  1154. }
  1155.  
  1156.  
  1157. static void
  1158. fe_splash_timer (XtPointer closure, XtIntervalId *id)
  1159. {
  1160.   Boolean *flag = (Boolean *) closure;
  1161.   *flag = True;
  1162. }
  1163.  
  1164. char *sploosh = 0;
  1165. static Boolean plonkp = False;
  1166. static Boolean plonkp_cancel = False;
  1167.  
  1168. /* provide an entry point to cancel plonk's load of initial window */
  1169.  
  1170. void
  1171. plonk_cancel()
  1172. {
  1173.     plonkp_cancel = True;
  1174. }
  1175.  
  1176. /* provide query of whether plonk was cancelled by a user action */
  1177.  
  1178. Boolean
  1179. plonk_cancelled(void)
  1180. {
  1181.     return plonkp_cancel;
  1182. }
  1183.  
  1184. Boolean
  1185. plonk (MWContext *context)
  1186. {
  1187.   int flags = 0;
  1188.   int win = False;
  1189.   Boolean timed_out = False;
  1190.   XtIntervalId id;
  1191.   Display *dpy = XtDisplay (CONTEXT_WIDGET (context));
  1192.   char *ab = "\246\247\264\272\271\177\270\265\261\246\270\255";
  1193.   char *au ="\246\247\264\272\271\177\246\272\271\255\264\267\270";
  1194.   char *blank = "\246\247\264\272\271\177\247\261\246\263\260";
  1195.   char *tmp;
  1196.  
  1197.   plonkp_cancel=False;
  1198.  
  1199.   /* Do not plonk if this flag is set */
  1200.   if (fe_globalData.startup_no_about_splash)
  1201.   {
  1202.       return False;
  1203.   }
  1204.   
  1205.   if ((context->type != MWContextBrowser &&
  1206.     context->type != MWContextMail &&
  1207.     context->type != MWContextNews)
  1208.       || (context->restricted_target)
  1209.       )
  1210.     return False;
  1211.  
  1212.   if (plonkp)
  1213.     return False;
  1214.   plonkp = True;
  1215.   if (sploosh) free (sploosh);
  1216.   sploosh = strdup (ab);
  1217.   for (tmp = sploosh; *tmp; tmp++) *tmp -= 69;
  1218.   fe_GetURL (context, NET_CreateURLStruct (sploosh, NET_DONT_RELOAD), FALSE);
  1219.  
  1220.   id = XtAppAddTimeOut (fe_XtAppContext, 60 * 1000, fe_splash_timer,
  1221.             &timed_out);
  1222.  
  1223.   /* #### Danger, this is weird and duplicates much of the work done
  1224.      in fe_EventLoop ().
  1225.    */
  1226.   while (! timed_out)
  1227.     {
  1228.       XtInputMask pending = XtAppPending (fe_XtAppContext);
  1229.  
  1230.       /* AAAAAUUUUGGHHH!!!  Sleep for a second, or until an X event arrives,
  1231.      and then loop until some input of any type has arrived.   The Xt event
  1232.      model completely **** and I'm tired of trying to figure out how to
  1233.      implement this without polling.
  1234.        */
  1235.       while (! pending)
  1236.     {
  1237.       fd_set fds;
  1238.       int fd = ConnectionNumber (dpy);
  1239.       int usecs = 1000000L;
  1240.       struct timeval tv;
  1241.       tv.tv_sec  = usecs / 1000000L;
  1242.       tv.tv_usec = usecs % 1000000L;
  1243.       memset(&fds, 0, sizeof(fds));
  1244.       FD_SET (fd, &fds);
  1245.       (void) select (fd + 1, &fds, 0, 0, &tv);
  1246.       pending = XtAppPending (fe_XtAppContext);
  1247.     }
  1248.  
  1249.       if (pending & XtIMXEvent)
  1250.     do
  1251.       {
  1252.         int nf = 0;
  1253.         XEvent event;
  1254.         XtAppNextEvent (fe_XtAppContext, &event);
  1255.  
  1256.         if (event.xany.type == KeyPress /* ||
  1257.         event.xany.type == KeyRelease */)
  1258.           {
  1259.         KeySym s = XKeycodeToKeysym (dpy, event.xkey.keycode, 0);
  1260.         switch (s)
  1261.           {
  1262.           case XK_Alt_L:     nf = 1<<0; break;
  1263.           case XK_Meta_L:    nf = 1<<0; break;
  1264.           case XK_Alt_R:     nf = 1<<1; break;
  1265.           case XK_Meta_R:    nf = 1<<1; break;
  1266.           case XK_Control_L: nf = 1<<2; break;
  1267.           case XK_Control_R: nf = 1<<3; break;
  1268.           }
  1269.  
  1270.         if (event.xany.type == KeyPress)
  1271.           flags |= nf;
  1272.         else
  1273.           flags &= ~nf;
  1274.         win = (flags == 15 || flags == 7 || flags == 11);
  1275.         if (nf && !win)
  1276.           event.xany.type = 0;
  1277.           }
  1278.  
  1279.         if (!timed_out &&
  1280.         (plonkp_cancel ||
  1281.                  event.xany.type == KeyPress ||
  1282.          event.xany.type == ButtonPress))
  1283.           {
  1284.         XtRemoveTimeOut (id);
  1285.         timed_out = True;
  1286.         id = 0;
  1287.           }
  1288.         if (event.xany.type)
  1289.           XtDispatchEvent (&event);
  1290.         pending = XtAppPending (fe_XtAppContext);
  1291.       }
  1292.     while ((pending & XtIMXEvent) && !timed_out);
  1293.  
  1294.       if ((pending & (~XtIMXEvent)) && !timed_out)
  1295.     do
  1296.       {
  1297.         XtAppProcessEvent (fe_XtAppContext, (~XtIMXEvent));
  1298.         pending = XtAppPending (fe_XtAppContext);
  1299.       }
  1300.     while ((pending & (~XtIMXEvent)) && !timed_out);
  1301.  
  1302.       /* If netlib is anxious, service it after every event, and service it
  1303.      continuously while there are no events. */
  1304.       if (fe_netlib_hungry_p && !timed_out)
  1305.     do
  1306.       {
  1307. #ifdef QUANTIFY
  1308. quantify_start_recording_data();
  1309. #endif /* QUANTIFY */
  1310.         NET_ProcessNet (-1, NET_EVERYTIME_TYPE);
  1311. #ifdef QUANTIFY
  1312. quantify_stop_recording_data();
  1313. #endif /* QUANTIFY */
  1314.       }
  1315.     while (fe_netlib_hungry_p && !XtAppPending (fe_XtAppContext)
  1316.            && !timed_out);
  1317.     }
  1318.  
  1319.   if (sploosh) {
  1320.     free (sploosh);
  1321.     sploosh = 0;
  1322.   }
  1323.  
  1324.   /* We timed out. But the context might have been destroyed by now
  1325.      if the user killed it with the window manager WM_DELETE. So we
  1326.      validate the context. */
  1327.   if (!fe_contextIsValid(context)) return True;
  1328.  
  1329.   if (SHIST_GetCurrent (&context->hist))
  1330.     /* If there's a current URL, then the remote control code must have
  1331.        kicked in already.  Don't clear it all. */
  1332.     return 1;
  1333.   
  1334.   if (plonkp_cancel)
  1335.       /* if the application forced a cancellation, don't load sploosh */
  1336.       return 1;
  1337.   
  1338.   sploosh = strdup (win ? au : blank);
  1339.   for (tmp = sploosh; *tmp; tmp++) *tmp -= 69;
  1340.   fe_GetURL (context, NET_CreateURLStruct (sploosh, NET_DONT_RELOAD), FALSE);
  1341.   return win;
  1342. }
  1343.  
  1344.  
  1345. /* #define NEW_VERSION_CHECKING */
  1346.  
  1347.  
  1348. #ifdef NEW_VERSION_CHECKING
  1349. static Bool fe_version_checker (XrmDatabase *db,
  1350.                 XrmBindingList bindings,
  1351.                 XrmQuarkList quarks,
  1352.                 XrmRepresentation *type,
  1353.                 XrmValue *value,
  1354.                 XPointer closure);
  1355. #endif /* NEW_VERSION_CHECKING */
  1356.  
  1357. static void
  1358. fe_sanity_check_resources (Widget toplevel)
  1359. {
  1360.   XrmDatabase db = XtDatabase (XtDisplay (toplevel));
  1361.   XrmValue value;
  1362.   char *type;
  1363.   char full_name [2048], full_class [2048];
  1364.   int count;
  1365.   PR_snprintf (full_name, sizeof (full_name), "%s.version", fe_progname);
  1366.   PR_snprintf (full_class, sizeof (full_class), "%s.version", fe_progclass);
  1367.  
  1368. #ifdef NEW_VERSION_CHECKING
  1369.  
  1370.   if (XrmGetResource (db, full_name, full_class, &type, &value) == True)
  1371.     {
  1372.       /* We have found the resource "Netscape.version: N.N".
  1373.      Versions past 1.1b3 does not use that, so that must
  1374.      mean an older resource db is being picked up.
  1375.      Complain, and refuse to run until this is fixed.
  1376.        */
  1377.       char str [1024];
  1378.       strncpy (str, (char *) value.addr, value.size);
  1379.       str [value.size] = 0;
  1380.  
  1381. #define VERSION_COMPLAINT_FORMAT XP_GetString( XFE_VERSION_COMPLAINT_FORMAT )
  1382.  
  1383.       fprintf (stderr, VERSION_COMPLAINT_FORMAT,
  1384.            fe_progname, fe_version, str, fe_progclass);
  1385.       exit (-1);
  1386.     }
  1387.  
  1388.   {
  1389.     const char *s1;
  1390.     char *s2;
  1391.     XrmName name_list [100];
  1392.     XrmClass class_list [100];
  1393.     char clean_version [255];
  1394.  
  1395.     /* Set clean_version to be a quark-safe version of fe_version,
  1396.        ie, "1.1b3N" ==> "v11b3N". */
  1397.     s2 = clean_version;
  1398.     *s2++ = 'v';
  1399.     for (s1 = fe_version; *s1; s1++)
  1400.       if (*s1 != ' ' && *s1 != '\t' && *s1 != '.' && *s1 != '*' && !s1 != '?')
  1401.     *s2++ = *s1;
  1402.     *s2 = 0;
  1403.  
  1404.     XrmStringToNameList (full_name, name_list);
  1405.     XrmStringToClassList (full_class, class_list);
  1406.  
  1407.     XrmEnumerateDatabase (db, name_list, class_list, XrmEnumOneLevel,
  1408.               fe_version_checker, (XtPointer) clean_version);
  1409.  
  1410.     /* If we've made it to here, then our iteration over the database
  1411.        has not turned up any suspicious "version" resources.  So now
  1412.        look for the version tag to see if we have any resources at all.
  1413.      */
  1414.     PR_snprintf (full_name, sizeof (full_name), 
  1415.             "%s.version.%s", fe_progname, clean_version);
  1416.     PR_snprintf (full_class, sizeof (full_class),
  1417.             "%s.version.%s", fe_progclass, clean_version);
  1418.     XrmStringToNameList (full_name, name_list);
  1419.     XrmStringToClassList (full_class, class_list);
  1420.     if (XrmGetResource (db, full_name, full_class, &type, &value) != True)
  1421.       {
  1422.     /* We have not found "Netscape.version.WRONG: WRONG", but neither
  1423.        have we found "Netscape.version.RIGHT: RIGHT".  Die.
  1424.      */
  1425.     fprintf (stderr, XP_GetString( XFE_INAPPROPRIATE_APPDEFAULT_FILE ),
  1426.            fe_progname, fe_progclass);
  1427.     exit (-1);
  1428.       }
  1429.   }
  1430.  
  1431. #else /* !NEW_VERSION_CHECKING */
  1432.  
  1433.   if (XrmGetResource (db, full_name, full_class, &type, &value) == True)
  1434.     {
  1435.       char str [1024];
  1436.       strncpy (str, (char *) value.addr, value.size);
  1437.       str [value.size] = 0;
  1438.       if (strcmp (str, fe_version))
  1439.     {
  1440.       fprintf (stderr,
  1441.                XP_GetString(XFE_MOZILLA_WRONG_RESOURCE_FILE_VERSION),
  1442.                fe_progname, fe_version, str, fe_progclass);
  1443.       exit (-1);
  1444.     }
  1445.     }
  1446.   else
  1447.     {
  1448.       fprintf (stderr,
  1449.                XP_GetString(XFE_MOZILLA_CANNOT_FOND_RESOURCE_FILE),
  1450.                fe_progname, fe_progclass);
  1451.  
  1452.       exit (-1);
  1453.     }
  1454. #endif /* !NEW_VERSION_CHECKING */
  1455.  
  1456.   /* Now sanity-check the XKeysymDB. */
  1457.   count = 0;
  1458.   if (XStringToKeysym ("osfActivate")  == 0) count++;    /* 1 */
  1459.   if (XStringToKeysym ("osfCancel")    == 0) count++;    /* 2 */
  1460.   if (XStringToKeysym ("osfPageLeft")  == 0) count++;    /* 3 */
  1461.   if (XStringToKeysym ("osfLeft")      == 0) count++;    /* 4 */
  1462.   if (XStringToKeysym ("osfPageUp")    == 0) count++;    /* 5 */
  1463.   if (XStringToKeysym ("osfUp")        == 0) count++;    /* 6 */
  1464.   if (XStringToKeysym ("osfBackSpace") == 0) count++;    /* 7 */
  1465.   if (count > 0)
  1466.     {
  1467.         char *str;
  1468.  
  1469.         if ( count == 7 )
  1470.             str = XP_GetString( XFE_THE_MOTIF_KEYSYMS_NOT_DEFINED );
  1471.         else
  1472.             str = XP_GetString( XFE_SOME_MOTIF_KEYSYMS_NOT_DEFINED );
  1473.  
  1474.       fprintf (stderr, str, fe_progname, XP_AppName );
  1475.       /* Don't exit for this one, just limp along. */
  1476.     }
  1477. }
  1478.  
  1479.  
  1480. #ifdef NEW_VERSION_CHECKING
  1481. static Bool
  1482. fe_version_checker (XrmDatabase *db,
  1483.             XrmBindingList bindings,
  1484.             XrmQuarkList quarks,
  1485.             XrmRepresentation *type,
  1486.             XrmValue *value,
  1487.             XPointer closure)
  1488. {
  1489.   char *name [100];
  1490.   int i = 0;
  1491.   char *desired_tail = (char *) closure;
  1492.   assert (quarks);
  1493.   assert (desired_tail);
  1494.   if (!quarks || !desired_tail)
  1495.     return False;
  1496.   while (quarks[i])
  1497.     name [i++] = XrmQuarkToString (quarks[i]);
  1498.  
  1499.   if (i != 3 ||
  1500.       !!strcmp (name[0], fe_progclass) ||
  1501.       !!strcmp (name[1], "version") ||
  1502.       name[2][0] != 'v')
  1503.     /* this is junk... */
  1504.     return False;
  1505.  
  1506.   if (value->addr &&
  1507.       !strncmp (fe_version, (char *) value->addr, value->size) &&
  1508.       i > 0 && !strcmp (desired_tail, name [i-1]))
  1509.     {
  1510.       /* The resource we have found is the one we want/expect.  That's ok. */
  1511.     }
  1512.   else
  1513.     {
  1514.       /* complain. */
  1515.       char str [1024];
  1516.       strncpy (str, (char *) value->addr, value->size);
  1517.       str [value->size] = 0;
  1518.       fprintf (stderr, VERSION_COMPLAINT_FORMAT,
  1519.            fe_progname, fe_version, str, fe_progclass);
  1520.       exit (-1);
  1521.     }
  1522.  
  1523.   /* Always return false, to continue iterating. */
  1524.   return False;
  1525. }
  1526. #endif /* NEW_VERSION_CHECKING */
  1527.  
  1528.  
  1529.  
  1530.  
  1531. #ifdef __linux
  1532.  /* On Linux, Xt seems to prints 
  1533.        "Warning: locale not supported by C library, locale unchanged"
  1534.     no matter what $LANG is set to, even if it's "C" or undefined.
  1535.  
  1536.     This is because `setlocale(LC_ALL, "")' always returns 0, while
  1537.     `setlocale(LC_ALL, NULL)' returns "C".  I think the former is
  1538.     incorrect behavior, even if the intent is to only support one
  1539.     locale, but that's how it is.
  1540.  
  1541.     The Linux 1.1.59 man page for setlocale(3) says
  1542.  
  1543.        At the moment, the only supported locales are the portable
  1544.        "C" and "POSIX" locales, which makes  calling  setlocale()
  1545.        almost  useless.    Support for other locales will be there
  1546.        Real Soon Now.
  1547.  
  1548.     Yeah, whatever.  So until there is real locale support, we might
  1549.     as well not try and initialize Xlib to use it.
  1550.  
  1551.     The reason that defining `BROKEN_I18N' does not stub out all of
  1552.     `lose_internationally()' is that we still need to cope with
  1553.     `BROKEN_I18N'.  By calling `setlocale (LC_CTYPE, NULL)' we can
  1554.     tell whether the "C" locale is defined, and therefore whether
  1555.     the `nls' dir exists, and therefore whether Xlib will dump core
  1556.     the first time the user tries to paste.
  1557.  */
  1558. # define BROKEN_I18N
  1559. # define NLS_LOSSAGE
  1560. #endif /* __linux */
  1561.  
  1562. #if defined(__sun) && !defined(__svr4__)    /* SunOS 4.1.3 */
  1563.  /* All R5-based systems have the problem that if the `nls' directory
  1564.     doesn't exist, trying to cut or paste causes a core dump in Xlib.
  1565.     This controls whether we try to generate a warning about this.
  1566.   */
  1567. # define NLS_LOSSAGE
  1568. #endif /* SunOS 4.1.3 */
  1569.  
  1570. #ifdef __386BSD__                /* BSDI is also R5 */
  1571. # define NLS_LOSSAGE
  1572. #endif /* BSDI */
  1573.  
  1574. static void
  1575. lose_internationally (void)
  1576. {
  1577.   char *locale;
  1578.   Boolean losing, was_default;
  1579.  
  1580. /*
  1581.  * For whatever reason, Japanese titles don't work unless you call
  1582.  * XtSetLanguageProc on DEC. We call XtAppInitialize later, which
  1583.  * calls setlocale. (See the XtAppInitialize call for more
  1584.  * comments.) -- erik
  1585.  */
  1586. #ifdef __osf__
  1587.   XtSetLanguageProc(NULL, NULL, NULL);
  1588. #else /* __osf__ */
  1589.   setlocale (LC_CTYPE, "");
  1590.   setlocale (LC_TIME,  "");
  1591.   setlocale (LC_COLLATE, "");
  1592.   fe_InitCollation();
  1593. #endif /* __osf__ */
  1594.  
  1595.   losing = !XSupportsLocale();
  1596.   locale = setlocale (LC_CTYPE, NULL);
  1597.   if (! locale) locale = "C";
  1598.  
  1599.   was_default = !strcmp ("C", locale);
  1600.  
  1601.   if (losing && !was_default)
  1602.     {
  1603.       fprintf (stderr,
  1604.                XP_GetString(XFE_MOZILLA_LOCALE_NOT_SUPPORTED_BY_XLIB),
  1605.                fe_progname, locale);
  1606.  
  1607.       setlocale (LC_CTYPE, "C");
  1608.       putenv ("LC_CTYPE=C");
  1609.       losing = !XSupportsLocale();
  1610.     }
  1611.  
  1612.   if (losing)
  1613.   {
  1614.       fprintf (stderr, 
  1615.                (was_default ?
  1616.                 XP_GetString(XFE_MOZILLA_LOCALE_C_NOT_SUPPORTED) :
  1617.                 XP_GetString(XFE_MOZILLA_LOCALE_C_NOT_SUPPORTED_EITHER)),
  1618.                fe_progname);
  1619.  
  1620.  
  1621. #ifdef NLS_LOSSAGE
  1622.       {
  1623.           char buf[64];
  1624.  
  1625. # if defined (__linux)
  1626. # if defined (MACLINUX)
  1627.           XP_SPRINTF(buf,"/usr/X11/lib/X11/locale/");
  1628. # else
  1629.           XP_SPRINTF(buf,"/usr/X386/lib/X11/nls/");
  1630. # endif
  1631. # elif defined (__386BSD__)
  1632.           XP_SPRINTF(buf,"/usr/X11/lib/X11/nls/");
  1633. # else /* SunOS 4.1.3, and a guess at anything else... */
  1634.           XP_SPRINTF(buf,"/usr/lib/X11/nls/");
  1635. # endif
  1636.  
  1637.           fprintf(stderr,
  1638.                   XP_GetString(XFE_MOZILLA_NLS_LOSAGE),
  1639.                   XP_AppName, 
  1640.                   XP_AppName,
  1641.                   buf);
  1642.       }
  1643. #else /* !NLS_LOSSAGE */
  1644.  
  1645.           fprintf(stderr,XP_GetString(XFE_MOZILLA_NLS_PATH_NOT_SET_CORRECTLY));
  1646.  
  1647. #endif /* !NLS_LOSSAGE */
  1648.   }
  1649.  
  1650. #ifdef BROKEN_I18N
  1651.   losing = True;
  1652. #endif /* BROKEN_I18N */
  1653.  
  1654.   /* If we're in a losing state, calling these will cause Xlib to exit.
  1655.      It's arguably better to try and limp along. */
  1656.   if (! losing)
  1657.     {
  1658.       /*
  1659.       XSetLocaleModifiers (NULL);
  1660.       */
  1661.       XSetLocaleModifiers ("");
  1662.       /*
  1663.       XtSetLanguageProc (NULL, NULL, NULL);
  1664.       */
  1665.     }
  1666. }
  1667.  
  1668.  
  1669. static char *fe_accept_language = NULL;
  1670.  
  1671. void
  1672. fe_SetAcceptLanguage(char *new_accept_lang)
  1673. {
  1674.   if (fe_accept_language)
  1675.     XP_FREE(fe_accept_language);
  1676.  
  1677.   fe_accept_language = new_accept_lang;
  1678. }
  1679.  
  1680.  
  1681. char *
  1682. FE_GetAcceptLanguage(void)
  1683. {
  1684.     return fe_accept_language;
  1685. }
  1686.  
  1687.  
  1688. static void
  1689. fe_fix_fds (void)
  1690. {
  1691.   /* Bad Things Happen if stdin, stdout, and stderr have been closed
  1692.      (as by the `sh' incantation "netscape 1>&- 2>&-").  I think what
  1693.      happens is, the X connection gets allocated to one of these fds,
  1694.      and then some random library writes to stderr, and the connection
  1695.      gets hosed.  I think this must be a general problem with X programs,
  1696.      but I'm not sure.  Anyway, cause them to be open to /dev/null if
  1697.      they aren't closed.  This must be done before any other files are
  1698.      opened.
  1699.  
  1700.      We do this by opening /dev/null three times, and then closing those
  1701.      fds, *unless* any of them got allocated as #0, #1, or #2, in which
  1702.      case we leave them open.  Gag.
  1703.    */
  1704.   int fd0 = open ("/dev/null", O_RDWR);
  1705.   int fd1 = open ("/dev/null", O_RDWR);
  1706.   int fd2 = open ("/dev/null", O_RDWR);
  1707.   if (fd0 > 2U) close (fd0);
  1708.   if (fd1 > 2U) close (fd1);
  1709.   if (fd2 > 2U) close (fd2);
  1710. }
  1711.  
  1712.  
  1713. extern char **environ;
  1714.  
  1715. static void
  1716. fe_fix_environment (Display *dpy)
  1717. {
  1718.   char buf [1024];
  1719.   static Boolean env_hacked_p = False;
  1720.  
  1721.   if (env_hacked_p)
  1722.     return;
  1723.   env_hacked_p = True;
  1724.  
  1725.   /* Store $DISPLAY into the environment, so that the $DISPLAY variable that
  1726.      the spawned processes inherit is the same as the value of -display passed
  1727.      in on our command line (which is not necessarily the same as what our
  1728.      $DISPLAY variable is.)
  1729.    */
  1730.   PR_snprintf (buf, sizeof (buf), "DISPLAY=%.900s", DisplayString (dpy));
  1731.   if (putenv (strdup (buf)))
  1732.     abort ();
  1733. }
  1734.  
  1735. static void
  1736. fe_hack_uid(void)
  1737. {
  1738.   /* If we've been run as setuid or setgid to someone else (most likely root)
  1739.      turn off the extra permissions.  Nobody ought to be installing Mozilla
  1740.      as setuid in the first place, but let's be extra special careful...
  1741.      Someone might get stupid because of movemail or something.
  1742.   */
  1743.   setgid (getgid ());
  1744.   setuid (getuid ());
  1745.  
  1746.   /* Is there anything special we should do if running as root?
  1747.      Features we should disable...?
  1748.      if (getuid () == 0) ...
  1749.    */
  1750. }
  1751.  
  1752.  
  1753. static void fe_event_processor_callback (XtPointer closure, int *fd, XtIntervalId *id)
  1754. {
  1755.     XP_ASSERT(*fd == PR_GetEventQueueSelectFD(mozilla_event_queue));
  1756.     PR_ProcessPendingEvents(mozilla_event_queue);
  1757. }
  1758.  
  1759. #ifdef JAVA
  1760. void FE_TrackJavaConsole(int on, void *notused)
  1761. {
  1762.     struct fe_MWContext_cons *cl = fe_all_MWContexts;
  1763.     Widget widget;
  1764.     while (cl) {
  1765.     MWContext *cx = cl->context;
  1766.     CONTEXT_DATA(cx)->show_java_console_p = on;
  1767.     if ((widget = CONTEXT_DATA(cx)->show_java) != NULL) {
  1768.         XtVaSetValues(widget, XmNset, on, 0);
  1769.     }
  1770.     cl = cl->next;
  1771.     }
  1772. }
  1773. #endif /* JAVA */
  1774.  
  1775. /* Dummy input precedures and timer callbacks to track Xt's select fd
  1776. ** in nspr
  1777. */
  1778. static void dummyInputProc(XtPointer closure, int *fd, XtInputId *id)
  1779. {
  1780. }
  1781.  
  1782. #ifdef XFE_XLOCK_FD_TIMER_HACK
  1783. /* see comments below */
  1784. static void dummyTimerProc(XtPointer closure, XtIntervalId *id)
  1785. {
  1786.     (void) XtAppAddTimeOut(fe_XtAppContext, 500L, dummyTimerProc, NULL);
  1787. }
  1788. #endif /*XFE_XLOCK_FD_TIMER_HACK*/
  1789.  
  1790. static void fe_late_init(void)
  1791. {
  1792.   LOCK_FDSET();
  1793.   XtAppAddInput (fe_XtAppContext, PR_GetEventQueueSelectFD(mozilla_event_queue),
  1794.          (XtPointer) (XtInputReadMask),
  1795.          fe_event_processor_callback, 0);
  1796.   UNLOCK_FDSET();
  1797. }
  1798.  
  1799. static int
  1800. fe_xt_hack_okayToReleaseXLock()
  1801. {
  1802.   return(XEventsQueued(fe_display, QueuedAlready) == 0);
  1803. }
  1804.  
  1805. static Boolean fe_command_line_done = False;
  1806.  
  1807. Display *fe_dpy_kludge;
  1808. Screen *fe_screen_kludge;
  1809.  
  1810. static char *fe_home_dir;
  1811. static char *fe_config_dir;
  1812.  
  1813. /*
  1814.  * build_simple_user_agent_string
  1815.  */
  1816. static void
  1817. build_simple_user_agent_string(char *versionLocale)
  1818. {
  1819.     char buf [1024];
  1820.     int totlen;
  1821.  
  1822.     if (XP_AppVersion) {
  1823.     free((void *)XP_AppVersion);
  1824.     XP_AppVersion = NULL;
  1825.     }
  1826.  
  1827.     /* SECNAV_Init must have a language string in XP_AppVersion.
  1828.      * If missing, it is supplied here.  This string is very short lived.
  1829.      * After SECNAV_Init returns, build_user_agent_string() will build the 
  1830.      * string that is expected by existing servers.  
  1831.      */
  1832.     if (!versionLocale || !*versionLocale) {    
  1833.     versionLocale = " [en]";   /* default is english for SECNAV_Init() */
  1834.     }
  1835.  
  1836.     /* be safe about running past end of buf */
  1837.     totlen = sizeof buf;
  1838.     memset(buf, 0, totlen);
  1839.     strncpy(buf, fe_version, totlen - 1);
  1840.     totlen -= strlen(buf);
  1841.     strncat(buf, versionLocale, totlen - 1);
  1842.  
  1843.     XP_AppVersion = strdup (buf);
  1844.     /* if it fails, leave XP_AppVersion NULL */
  1845. }
  1846.  
  1847. /*
  1848.  * build_user_agent_string
  1849.  */
  1850. static void
  1851. build_user_agent_string(char *versionLocale)
  1852. {
  1853.     char buf [1024];
  1854.     struct utsname uts;
  1855.  
  1856. #ifndef __sgi
  1857.     if (fe_VendorAnim) abort (); /* only SGI has one of these now. */
  1858. #endif /* __sgi */
  1859.  
  1860.     strcpy (buf, fe_version);
  1861.  
  1862. #ifdef GOLD
  1863.     strcat(buf, "Gold");
  1864. #endif
  1865.  
  1866.     if ( ekit_Enabled() && ekit_UserAgent() ) { 
  1867.         strcat(buf, "C-");
  1868.         strcat(buf, ekit_UserAgent());
  1869.     }
  1870.  
  1871.     if (versionLocale) {
  1872.     strcat (buf, versionLocale);
  1873.     }
  1874.  
  1875.     strcat (buf, " (X11; ");
  1876.     strcat (buf, XP_SecurityVersion (FALSE));
  1877.     strcat (buf, "; ");
  1878.  
  1879.     if (uname (&uts) < 0)
  1880.       {
  1881. #if defined(__sun)
  1882.     strcat (buf, "SunOS");
  1883. #elif defined(__sgi)
  1884.     strcat (buf, "IRIX");
  1885. #elif defined(__FreeBSD__)
  1886.     strcat (buf, "FreeBSD");
  1887. #elif defined(__386BSD__)
  1888.     strcat (buf, "BSD/386");
  1889. #elif defined(__osf__)
  1890.     strcat (buf, "OSF1");
  1891. #elif defined(AIXV3)
  1892.     strcat (buf, "AIX");
  1893. #elif defined(_HPUX_SOURCE)
  1894.     strcat (buf, "HP-UX");
  1895. #elif defined(__linux)
  1896. #if defined(MACLINUX)
  1897.     strcat (buf, "MkLinux");
  1898. #else
  1899.     strcat (buf, "Linux");
  1900. #endif
  1901. #elif defined(_ATT4)
  1902.     strcat (buf, "NCR/ATT");
  1903. #elif defined(__USLC__)
  1904.     strcat (buf, "UNIX_SV");
  1905. #elif defined(sony)
  1906.     strcat (buf, "NEWS-OS");
  1907. #elif defined(nec_ews)
  1908.     strcat (buf, "NEC/EWS-UX/V");
  1909. #elif defined(SNI)
  1910.     strcat (buf, "SINIX-N");
  1911. #else
  1912.     ERROR!! run "uname -s" and put the result here.
  1913. #endif
  1914.         strcat (buf,XP_GetString(XFE_MOZILLA_UNAME_FAILED));
  1915.  
  1916.     fprintf (real_stderr,
  1917.              XP_GetString(XFE_MOZILLA_UNAME_FAILED_CANT_DETERMINE_SYSTEM),
  1918.              fe_progname);
  1919.       }
  1920.     else
  1921.       {
  1922.     char *s;
  1923.  
  1924. #if defined(_ATT4)
  1925.     strcpy(uts.sysname,"NCR/ATT");
  1926. #endif   /* NCR/ATT */
  1927.  
  1928. #if defined(nec_ews)
  1929.         strcpy(uts.sysname,"NEC");
  1930. #endif   /* NEC */
  1931.  
  1932.  
  1933.     PR_snprintf (buf + strlen(buf), sizeof(buf) - strlen(buf),
  1934. #ifdef AIX
  1935.             /* AIX uname is incompatible with the rest of the Unix world. */
  1936.             "%.100s %.100s.%.100s", uts.sysname, uts.version, uts.release);
  1937. #else
  1938.             "%.100s %.100s", uts.sysname, uts.release);
  1939. #endif
  1940.  
  1941.     /* If uts.machine contains only hex digits, throw it away.
  1942.        This is so that every single AIX machine in
  1943.        the world doesn't generate a unique vendor ID string. */
  1944.     s = uts.machine;
  1945.     while (s && *s)
  1946.       {
  1947.         if (!isxdigit (*s))
  1948.           break;
  1949.         s++;
  1950.       }
  1951.     if (s && *s)
  1952.       PR_snprintf (buf + strlen (buf), sizeof(buf)-strlen(buf),
  1953.             " %.100s", uts.machine);
  1954.       }
  1955.  
  1956. #ifndef MOZ_COMMUNICATOR_NAME
  1957.     strcat (buf, "; Nav");
  1958. #endif
  1959.  
  1960.     strcat (buf, ")");
  1961.  
  1962.  
  1963. #if defined(__sun) && !defined(__svr4__)    /* compiled on SunOS 4.1.3 */
  1964.     if (uts.release [0] == '5')
  1965.       {
  1966.  
  1967.     fprintf (stderr,
  1968.              XP_GetString(XFE_MOZILLA_TRYING_TO_RUN_SUNOS_ON_SOLARIS),
  1969.              fe_progname, 
  1970.              uts.release);
  1971.       }
  1972. #endif /* 4.1.3 */
  1973.  
  1974.     assert(strlen(buf) < sizeof buf);
  1975.     if (strlen(buf) >= sizeof(buf)) abort(); /* stack already damaged */
  1976.  
  1977.     if (XP_AppVersion) {
  1978.     free((void *)XP_AppVersion);
  1979.     XP_AppVersion = NULL;
  1980.     }
  1981.     XP_AppVersion = strdup (buf);
  1982.     if (!XP_AppVersion) {
  1983.     XP_AppVersion = "";
  1984.     }
  1985. }
  1986.  
  1987. /*
  1988.  *    Sorry folks, C++ has come to town. *Some* C++ compilers/linkers require
  1989.  *    the program's main() to be in a C++ file. I've added a losing C++ main()
  1990.  *    in cplusplusmain.cc. This guy will call mozilla_main(). Look, I'm really
  1991.  *    sorry about this. I don't know what to say. C++ loses, Cfront loses,
  1992.  *    we are now steeped in all of their lossage. We will descend into the
  1993.  *    burning pit of punctuation used for obscure language features, our
  1994.  *    links will go asunder, when we seek out our proper inheritance, from
  1995.  *    the mother *and* father from which we were begat, we shall be awash,
  1996.  *    for we will be without identity. We shall try to be pure, but shall find
  1997.  *    ourselves unable to instanciate. ... shall be statically bound unto
  1998.  *    him. Oh, woe unto us... djw
  1999.  */
  2000. int
  2001. #ifdef CPLUSPLUS_LINKAGE
  2002. mozilla_main
  2003. #else
  2004. main
  2005. #endif
  2006. (int argc, char** argv)
  2007. {
  2008.   Widget toplevel;
  2009.   Display *dpy;
  2010.   int i;
  2011.   Widget disp_obj;
  2012.   struct sigaction act;
  2013.  
  2014.   char *s;
  2015.   char **remote_commands = 0;
  2016.   int remote_command_count = 0;
  2017.   int remote_command_size = 0;
  2018.   unsigned long remote_window = 0;
  2019.  
  2020.   XP_StatStruct stat_struct;
  2021.  
  2022. #ifdef MOZ_MAIL_NEWS
  2023.   MWContext* biffcontext;
  2024. #endif
  2025.  
  2026.   XP_Bool netcasterShown=FALSE;
  2027.  
  2028.   char versionLocale[32];
  2029.  
  2030.   versionLocale[0] = 0;
  2031.  
  2032.   fe_progname = argv [0];
  2033.   s = XP_STRRCHR (fe_progname, '/');
  2034.   if (s) fe_progname = s + 1;
  2035.  
  2036.   real_stderr = stderr;
  2037.   real_stdout = stdout;
  2038.  
  2039.   fe_hack_uid();    /* Do this real early */
  2040.  
  2041.   /* 
  2042.    * Check the environment for MOZILLA_NO_ASYNC_DNS.  It would be nice to
  2043.    * make this either a pref or a resource/option.  But, at this point in
  2044.    * the game neither prefs nor xt resources have been initialized and read.
  2045.    */
  2046.   fe_check_use_async_dns();
  2047.  
  2048. #ifdef UNIX_ASYNC_DNS
  2049.   if (fe_UseAsyncDNS())
  2050.   {
  2051.       XFE_InitDNS_Early(argc,argv);   /* Do this early (before Java, NSPR.) */
  2052.   }
  2053. #endif
  2054.  
  2055. #ifdef MOZILLA_GPROF
  2056.    /*
  2057.     *    Do this early, but after the async DNS process has spawned.
  2058.     */
  2059.    gmon_init(); /* initialize, maybe start, profiling */
  2060. #endif /*MOZILLA_GPROF*/
  2061.  
  2062.   /*
  2063.   ** Initialize the runtime, preparing for multi-threading. Make mozilla
  2064.   ** a higher priority than any java applet. Java's priority range is
  2065.   ** 1-10, and we're mapping that to 11-20 (in sysThreadSetPriority).
  2066.   */
  2067. #ifdef NSPR20
  2068. /* No explicit initialization needed for NSPR 2.0 */
  2069.   {
  2070. #ifdef DEBUG
  2071.       extern PRLogModuleInfo* NETLIB;
  2072. #endif
  2073.  
  2074. #ifdef MOZ_MAIL_NEWS
  2075.       extern PRLogModuleInfo* NNTP;
  2076. #endif
  2077.  
  2078. #ifdef DEBUG
  2079.       NETLIB = PR_NewLogModule("netlib");
  2080. #endif
  2081.  
  2082. #ifdef MOZ_MAIL_NEWS
  2083.       NNTP = PR_NewLogModule("nntp");
  2084. #endif
  2085.  
  2086.       PR_SetThreadGCAble();
  2087.       PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_LAST);
  2088.       PR_BlockClockInterrupts();
  2089.   }
  2090.  
  2091. #elif defined(NSPR_SPLASH) /* !NSPR20 && NSPR_SPLASH */
  2092.   /*
  2093.   ** if we're using the splash screen, we need the mozilla thread to
  2094.   ** be at a lower priority (so the label gets updated and we handle X
  2095.   ** events quickly.  It may make the startup time longer, but the user
  2096.   ** will be happier.  We'll set it back after fe_splashStop().
  2097.   */
  2098.   PR_Init("mozilla", 20, 1, 0);
  2099. #else                      /* !NSPR20 && !NSPR_SPLASH */
  2100.   PR_Init("mozilla", 24, 1, 0);
  2101. #endif                     /* NSRP20 */
  2102.  
  2103.   LJ_SetProgramName(argv[0]);
  2104.   PR_XLock();
  2105.   mozilla_thread = PR_CurrentThread();
  2106.   fdset_lock = PR_NewNamedMonitor("mozilla-fdset-lock");
  2107.  
  2108.   /*
  2109.   ** Create a pipe used to wakeup mozilla from select. A problem we had
  2110.   ** to solve is the case where a non-mozilla thread uses the netlib to
  2111.   ** fetch a file. Because the netlib operates by updating mozilla's
  2112.   ** select set, and because mozilla might be in the middle of select
  2113.   ** when the update occurs, sometimes mozilla never wakes up (i.e. it
  2114.   ** looks hung). Because of this problem we create a pipe and when a
  2115.   ** non-mozilla thread wants to wakeup mozilla we write a byte to the
  2116.   ** pipe.
  2117.   */
  2118.   mozilla_event_queue = PR_CreateEventQueue("mozilla-event-queue", mozilla_thread);
  2119.  
  2120.   if (mozilla_event_queue == NULL) 
  2121.   {
  2122.       fprintf(stderr,
  2123.               XP_GetString(XFE_MOZILLA_FAILED_TO_INITIALIZE_EVENT_QUEUE), 
  2124.               fe_progname);
  2125.       
  2126.       exit(-1);
  2127.   }
  2128.  
  2129.   fe_fix_fds ();
  2130.  
  2131. #ifdef MEMORY_DEBUG
  2132. #ifdef __sgi
  2133.   mallopt (M_DEBUG, 1);
  2134.   mallopt (M_CLRONFREE, 0xDEADBEEF);
  2135. #endif
  2136. #endif
  2137.  
  2138. #ifdef DEBUG
  2139.       {
  2140.       extern int il_debug;
  2141.       if(getenv("ILD"))
  2142.           il_debug=atoi(getenv("ILD"));
  2143.       }
  2144.  
  2145.   if(stat(".WWWtraceon", &stat_struct) != -1)
  2146.       MKLib_trace_flag = 2;
  2147. #endif
  2148.  
  2149.   /* user agent stuff used to be here */
  2150.   fe_progclass = XFE_PROGCLASS_STRING;
  2151.   XP_AppName = fe_progclass;
  2152.   XP_AppCodeName = "Mozilla";
  2153.  
  2154.   /* OSTYPE is defined by the build environment (config.mk) */
  2155.   XP_AppPlatform = OSTYPE;
  2156.  
  2157.  
  2158.   save_argv = (char **)calloc(argc, sizeof(char*));
  2159.  
  2160.   save_argc = 1;
  2161.   /* Hack the -help and -version arguments before opening the display. */
  2162.   for (i = 1; i < argc; i++)
  2163.     {
  2164.       if (!XP_STRCASECMP(argv [i], "-h") ||
  2165.       !XP_STRCASECMP(argv [i], "-help") ||
  2166.       !XP_STRCASECMP(argv [i], "--help"))
  2167.     {
  2168.       usage ();
  2169.       exit (0);
  2170.     }
  2171. /* because of stand alone java, we need not support -java. sudu/warren */
  2172. #ifdef JAVA
  2173. #ifdef JAVA_COMMAND_LINE_SUPPORT
  2174. /*
  2175.  * -java will not be supported once it has been replaced by stand alone java
  2176.  * this ifdef remains in case someone needs it and should be removed once
  2177.  * stand alone java is in the mainstream sudu/warren
  2178.  */
  2179.  
  2180.       else if (!XP_STRCASECMP(argv [i], "-java") ||
  2181.            !XP_STRCASECMP(argv [i], "--java"))
  2182.     {
  2183.       extern int start_java(int argc, char **argv);
  2184.       start_java(argc-i, &argv[i]);
  2185.       exit (0);
  2186.     }
  2187. #endif /* JAVA_COMMAND_LINE_SUPPORT */
  2188. #endif
  2189.       else if (!XP_STRCASECMP(argv [i], "-v") ||
  2190.            !XP_STRCASECMP(argv [i], "-version") ||
  2191.            !XP_STRCASECMP(argv [i], "--version"))
  2192.     {
  2193.       fprintf (stderr, "%s\n", fe_long_version + 4);
  2194.       exit (0);
  2195.     }
  2196.       else if (!XP_STRCASECMP(argv [i], "-remote") ||
  2197.            !XP_STRCASECMP(argv [i], "--remote"))
  2198.     {
  2199.       if (remote_command_count == remote_command_size)
  2200.         {
  2201.           remote_command_size += 20;
  2202.           remote_commands =
  2203.         (remote_commands
  2204.          ? realloc (remote_commands,
  2205.                 remote_command_size * sizeof (char *))
  2206.          : calloc (remote_command_size, sizeof (char *)));
  2207.         }
  2208.       i++;
  2209.       if (!argv[i] || *argv[i] == '-' || *argv[i] == 0)
  2210.         {
  2211.           fprintf (stderr,
  2212.                    XP_GetString(XFE_MOZILLA_INVALID_REMOTE_OPTION),
  2213.                    fe_progname, 
  2214.                    argv[i] ? argv[i] : "");
  2215.           usage ();
  2216.           exit (-1);
  2217.         }
  2218.       remote_commands [remote_command_count++] = argv[i];
  2219.     }
  2220.       else if (!XP_STRCASECMP(argv [i], "-raise") ||
  2221.            !XP_STRCASECMP(argv [i], "--raise") ||
  2222.            !XP_STRCASECMP(argv [i], "-noraise") ||
  2223.            !XP_STRCASECMP(argv [i], "--noraise"))
  2224.     {
  2225.       char *r = argv [i];
  2226.       if (r[0] == '-' && r[1] == '-')
  2227.         r++;
  2228.       if (remote_command_count == remote_command_size)
  2229.         {
  2230.           remote_command_size += 20;
  2231.           remote_commands =
  2232.         (remote_commands
  2233.          ? realloc (remote_commands,
  2234.                 remote_command_size * sizeof (char *))
  2235.          : calloc (remote_command_size, sizeof (char *)));
  2236.         }
  2237.       remote_commands [remote_command_count++] = r;
  2238.     }
  2239.       else if (!XP_STRCASECMP(argv [i], "-netcaster") ||
  2240.            !XP_STRCASECMP(argv [i], "--netcaster")
  2241.            )
  2242.     {
  2243.       char *r = argv [i];
  2244.       if (r[0] == '-' && r[1] == '-')
  2245.         r++;
  2246.       fe_globalData.startup_netcaster=True;
  2247.     }
  2248.       else if (!XP_STRCASECMP(argv [i], "-id") ||
  2249.            !XP_STRCASECMP(argv [i], "--id"))
  2250.     {
  2251.       char c;
  2252.       if (remote_command_count > 0)
  2253.         {
  2254.             fprintf (stderr,
  2255.                      XP_GetString(XFE_MOZILLA_ID_OPTION_MUST_PRECEED_REMOTE_OPTIONS),
  2256.                fe_progname);
  2257.           usage ();
  2258.           exit (-1);
  2259.         }
  2260.       else if (remote_window != 0)
  2261.         {
  2262.           fprintf (stderr,
  2263.                    XP_GetString(XFE_MOZILLA_ONLY_ONE_ID_OPTION_CAN_BE_USED),
  2264.                    fe_progname);
  2265.           usage ();
  2266.           exit (-1);
  2267.         }
  2268.       i++;
  2269.       if (argv[i] &&
  2270.           1 == sscanf (argv[i], " %ld %c", &remote_window, &c))
  2271.         ;
  2272.       else if (argv[i] &&
  2273.            1 == sscanf (argv[i], " 0x%lx %c", &remote_window, &c))
  2274.         ;
  2275.       else
  2276.         {
  2277.           fprintf (stderr,
  2278.                    XP_GetString(XFE_MOZILLA_INVALID_OD_OPTION),
  2279.                    fe_progname, argv[i] ? argv[i] : "");
  2280.           usage ();
  2281.           exit (-1);
  2282.         }
  2283.      }
  2284.        else  /* Save these args  for session manager */
  2285.          {
  2286.          save_argv[save_argc] = 0;
  2287.          save_argv[save_argc] = (char*)malloc((strlen(argv[i])+1)*
  2288.                 sizeof(char*)); 
  2289.              strcpy(save_argv[save_argc], argv[i]);
  2290.          save_argc++;
  2291.          }
  2292.      }
  2293.  
  2294.   lose_internationally ();
  2295.  
  2296. #if defined(__sun)
  2297.   {
  2298.     /* The nightmare which is XKeysymDB is unrelenting. */
  2299.     /* It'd be nice to check the existence of the osf keysyms here
  2300.        to know whether we're screwed yet, but we must set $XKEYSYMDB
  2301.        before initializing the connection; and we can't query the
  2302.        keysym DB until after initializing the connection. */
  2303.     char *override = getenv ("XKEYSYMDB");
  2304.     struct stat st;
  2305.     if (override && !stat (override, &st))
  2306.       {
  2307.     /* They set it, and it exists.  Good. */
  2308.       }
  2309.     else
  2310.       {
  2311.     char *try1 = "/usr/lib/X11/XKeysymDB";
  2312.     char *try2 = "/usr/openwin/lib/XKeysymDB";
  2313.     char *try3 = "/usr/openwin/lib/X11/XKeysymDB";
  2314.     char buf [1024];
  2315.     if (override)
  2316.       {
  2317.         fprintf (stderr,
  2318.                  XP_GetString(XFE_MOZILLA_XKEYSYMDB_SET_BUT_DOESNT_EXIST),
  2319.                  argv [0], override);
  2320.       }
  2321.  
  2322.     if (!stat (try1, &st))
  2323.       {
  2324.         PR_snprintf (buf, sizeof (buf), "XKEYSYMDB=%.900s", try1);
  2325.         putenv (buf);
  2326.       }
  2327.     else if (!stat (try2, &st))
  2328.       {
  2329.         PR_snprintf (buf, sizeof (buf), "XKEYSYMDB=%.900s", try2);
  2330.         putenv (buf);
  2331.       }
  2332.     else if (!stat (try3, &st))
  2333.       {
  2334.         PR_snprintf (buf, sizeof (buf), "XKEYSYMDB=%.900s", try3);
  2335.         putenv (buf);
  2336.       }
  2337.     else
  2338.       {
  2339.         fprintf (stderr,
  2340.                  XP_GetString(XFE_MOZILLA_NO_XKEYSYMDB_FILE_FOUND),
  2341.                  argv [0], try1, try2, try3);
  2342.       }
  2343.       }
  2344.   }
  2345. #endif /* sun */
  2346.  
  2347.   /* Must do this early now so that mail can load directories */
  2348.   /* Setting fe_home_dir likewise must happen early. */
  2349.   fe_home_dir = getenv ("HOME");
  2350.   if (!fe_home_dir || !*fe_home_dir)
  2351.     {
  2352.       /* Default to "/" in case a root shell is running in dire straits. */
  2353.       struct passwd *pw = getpwuid(getuid());
  2354.  
  2355.       fe_home_dir = pw ? pw->pw_dir : "/";
  2356.     }
  2357.   else
  2358.     {
  2359.       char *slash;
  2360.  
  2361.       /* Trim trailing slashes just to be fussy. */
  2362.       while ((slash = strrchr(fe_home_dir, '/')) && slash[1] == '\0')
  2363.     *slash = '\0';
  2364.     }
  2365. {
  2366.     char buf [1024];
  2367.     PR_snprintf (buf, sizeof (buf), "%s/%s", fe_home_dir,
  2368. #ifdef OLD_UNIX_FILES
  2369.         ".netscape-preferences"
  2370. #else
  2371.         ".netscape/preferences.js"
  2372. #endif
  2373.         );
  2374.  
  2375.     fe_globalData.user_prefs_file = strdup (buf);
  2376.  
  2377.     PREF_Init((char*) fe_globalData.user_prefs_file);
  2378. }
  2379.  
  2380. #ifdef MOZ_MAIL_NEWS
  2381.   fe_mailNewsPrefs = MSG_CreatePrefs();
  2382. #endif
  2383.  
  2384.   toplevel = XtAppInitialize (&fe_XtAppContext, (char *) fe_progclass, options,
  2385.                   sizeof (options) / sizeof (options [0]),
  2386.                   &argc, argv, fe_fallbackResources, 0, 0);
  2387.  
  2388.  
  2389.  
  2390.   FE_SetToplevelWidget(toplevel);
  2391.  
  2392.   /* we need to set the drag/drop protocol style to dynamic
  2393.      or the drag-into-menus stuff for the 4.0 quickfile
  2394.      stuff won't work. */
  2395.   disp_obj = XmGetXmDisplay(XtDisplay(toplevel));
  2396.  
  2397.   XtVaSetValues(disp_obj,
  2398.         XmNdragInitiatorProtocolStyle, XmDRAG_PREFER_DYNAMIC,
  2399.         XmNdragReceiverProtocolStyle, XmDRAG_PREFER_DYNAMIC,
  2400.         NULL);
  2401.  
  2402.   fe_progname_long = fe_locate_program_path (argv [0]);
  2403.  
  2404. /*
  2405.  * We set all locale categories except for LC_CTYPE back to "C" since
  2406.  * we want to be careful, and since we already know that libnet depends
  2407.  * on the C locale for strftime for HTTP, NNTP and RFC822. We call
  2408.  * XtSetLanguageProc before calling XtAppInitialize, which makes the latter
  2409.  * call setlocale for all categories. Hence the setting back to "C"
  2410.  * stuff here. See other comments near the XtSetLanguageProc call. -- erik
  2411.  */
  2412. #ifdef __osf__
  2413.   /*
  2414.    * For some strange reason, we cannot set LC_COLLATE to "C" on DEC,
  2415.    * otherwise the text widget misbehaves, e.g. deleting one byte instead
  2416.    * of two when backspacing over a Japanese character. Grrr. -- erik
  2417.    */
  2418.   /* setlocale(LC_COLLATE, "C"); */
  2419.   fe_InitCollation();
  2420.  
  2421.   setlocale(LC_MONETARY, "C");
  2422.   setlocale(LC_NUMERIC, "C");
  2423.   /*setlocale(LC_TIME, "C");*/
  2424.   setlocale(LC_MESSAGES, "C");
  2425. #endif /* __osf__ */
  2426.  
  2427.   fe_display = dpy = XtDisplay (toplevel);
  2428.  
  2429. #if defined(NSPR20)
  2430.   PR_UnblockClockInterrupts();
  2431. #else
  2432.   /* Now we can turn the nspr clock on */
  2433.   PR_StartEvents(0);
  2434. #endif    /* NSPR20 */
  2435.  
  2436.   {
  2437.     extern void AwtRegisterXtAppVars(Display *dpy,
  2438.                      XtAppContext ac, char *class);
  2439.     AwtRegisterXtAppVars(fe_display, fe_XtAppContext, (char *)fe_progclass);
  2440.   }
  2441.  
  2442.  {
  2443.      extern int PR_XGetXtHackFD(void);
  2444.      int fd;
  2445.  
  2446.      /*
  2447.       * We would like to yield the X lock to other (Java) threads when
  2448.       * the Mozilla thread calls select(), but we should only do so
  2449.       * when Xt calls select from its main event loop. (There are other
  2450.       * times when select is called, e.g. from within Xlib. At these
  2451.       * times, it is not safe to release the X lock.) Within select,
  2452.       * we detect that the caller is Xt by looking at the file
  2453.       * descriptors. If one of them is this special unused FD that we
  2454.       * are adding here, then we know that Xt is calling us, so it is
  2455.       * safe to release the X lock. -- erik
  2456.       */
  2457.      fd = PR_XGetXtHackFD();
  2458.      if (fd >= 0) {
  2459.          (void) XtAppAddInput(fe_XtAppContext, fd,
  2460.              (XtPointer) XtInputReadMask, dummyInputProc, NULL);
  2461.      }
  2462.  
  2463. #ifdef XFE_XLOCK_FD_TIMER_HACK
  2464.     /*
  2465.      * don't think we need this anymore, and we'd like to be able to go
  2466.      * completely idle....djw & radha
  2467.      */
  2468.      /*
  2469.       * For some reason, Xt sometimes calls select() only with the FD for
  2470.       * the X connection, without a timeout. Since we only release the
  2471.       * X lock when the special FD (added above) is selected, we need to
  2472.       * have some way of breaking out of this situation. The following
  2473.       * hack sets a 500 millisecond timer for this purpose. When the timer
  2474.       * fires, the next time Xt calls select, it will be with the right
  2475.       * FDs. Ugh. -- erik
  2476.       */
  2477.       (void) XtAppAddTimeOut(fe_XtAppContext, 500L, dummyTimerProc, NULL); 
  2478. #endif /*XFE_XLOCK_FD_TIMER_HACK*/
  2479.    }
  2480.  
  2481.   /* For security stuff... */
  2482.   fe_dpy_kludge = dpy;
  2483.   fe_screen_kludge = XtScreen (toplevel);
  2484.  
  2485.  
  2486.   /* Initialize the security library. This must be done prior
  2487.      to any calls that will cause X event activity, since the
  2488.      event loop calls security functions.
  2489.    */
  2490.  
  2491.   XtGetApplicationNameAndClass (dpy,
  2492.                 (char **) &fe_progname,
  2493.                 (char **) &fe_progclass);
  2494.  
  2495.   /* Things blow up if argv[0] has a "." in it. */
  2496.   {
  2497.     char *s = (char *) fe_progname;
  2498.     while ((s = strchr (s, '.')))
  2499.       *s = '_';
  2500.   }
  2501.  
  2502.  
  2503.   /* If there were any -command options, then we are being invoked in our
  2504.      role as a controller of another Mozilla window; find that other window,
  2505.      send it the commands, and exit. */
  2506.   if (remote_command_count > 0)
  2507.     {
  2508.       int status = fe_RemoteCommands (dpy, (Window) remote_window,
  2509.                       remote_commands);
  2510.       exit (status);
  2511.     }
  2512.   else if (remote_window)
  2513.     {
  2514.       fprintf (stderr,
  2515.                XP_GetString(XFE_MOZILLA_ID_OPTION_CAN_ONLY_BE_USED_WITH_REMOTE),
  2516.            fe_progname);
  2517.       usage ();
  2518.       exit (-1);
  2519.     }
  2520.  
  2521.   fe_sanity_check_resources (toplevel);
  2522.  
  2523.   {
  2524.     char    clas[128];
  2525.     XrmDatabase    db;
  2526.     char    *locale;
  2527.     char    name[128];
  2528.     char    *type;
  2529.     XrmValue    value;
  2530.  
  2531.     db = XtDatabase(dpy);
  2532.     PR_snprintf(name, sizeof(name), "%s.versionLocale", fe_progname);
  2533.     PR_snprintf(clas, sizeof(clas), "%s.VersionLocale", fe_progclass);
  2534.     if (XrmGetResource(db, name, clas, &type, &value) && *((char *) value.addr))
  2535.       {
  2536.         PR_snprintf(versionLocale, sizeof(versionLocale), " [%s]",
  2537.         (char *) value.addr);
  2538.  
  2539.         XP_AppLanguage = strdup((char*)value.addr);
  2540.  
  2541.         fe_version_and_locale = PR_smprintf("%s%s", fe_version, versionLocale);
  2542.         if (!fe_version_and_locale)
  2543.       {
  2544.         fe_version_and_locale = (char *) fe_version;
  2545.       }
  2546.       }
  2547.     if (!XP_AppLanguage) {
  2548.     XP_AppLanguage = strdup("en");
  2549.     }
  2550.  
  2551.     PR_snprintf(name, sizeof(name), "%s.httpAcceptLanguage", fe_progname);
  2552.     PR_snprintf(clas, sizeof(clas), "%s.HttpAcceptLanguage", fe_progclass);
  2553.     if (XrmGetResource(db, name, clas, &type, &value) && *((char *) value.addr))
  2554.       {
  2555.     fe_accept_language = (char *) value.addr;
  2556.       }
  2557.  
  2558.     locale = fe_GetNormalizedLocaleName();
  2559.     if (locale)
  2560.       {
  2561.         PR_snprintf(name, sizeof(name), "%s.localeCharset.%s", fe_progname,
  2562.         locale);
  2563.     free((void *) locale);
  2564.       }
  2565.     else
  2566.       {
  2567.         PR_snprintf(name, sizeof(name), "%s.localeCharset.C", fe_progname);
  2568.       }
  2569.     PR_snprintf(clas, sizeof(clas), "%s.LocaleCharset.Locale", fe_progclass);
  2570.     if (XrmGetResource(db, name, clas, &type, &value) && *((char *) value.addr))
  2571.       {
  2572.     fe_LocaleCharSetID = INTL_CharSetNameToID((char *) value.addr);
  2573.     if (fe_LocaleCharSetID == CS_UNKNOWN)
  2574.       {
  2575.         fe_LocaleCharSetID = CS_LATIN1;
  2576.       }
  2577.       }
  2578.     else
  2579.       {
  2580.     fe_LocaleCharSetID = CS_LATIN1;
  2581.       }
  2582.     INTL_CharSetIDToName(fe_LocaleCharSetID, fe_LocaleCharSetName);
  2583.   }
  2584.  
  2585.   /* Now that we've got a display and know we're going to behave as a
  2586.      client rather than a remote controller, fix the $DISPLAY setting. */
  2587.   fe_fix_environment (dpy);
  2588.  
  2589.   /* Hack remaining arguments - assume things beginning with "-" are
  2590.      misspelled switches, instead of file names.  Magic for -help and
  2591.      -version has already happened.
  2592.    */
  2593.   for (i = 1; i < argc; i++)
  2594.     if (*argv [i] == '-')
  2595.       {
  2596.     fprintf (stderr, XP_GetString( XFE_UNRECOGNISED_OPTION ),
  2597.          fe_progname, argv [i]);
  2598.     usage ();
  2599.     exit (-1);
  2600.       }
  2601.  
  2602.  
  2603.   /* Must be called before XFE_ReadPrefs(). */
  2604.   fe_InitFonts(dpy);
  2605.  
  2606.   /* See if another instance is running.  If so, don't use the .db files */
  2607.   if (fe_ensure_config_dir_exists (toplevel))
  2608.     {
  2609.       char *name;
  2610.       unsigned long addr;
  2611.       pid_t pid;
  2612.  
  2613.       name = PR_smprintf ("%s/lock", fe_config_dir);
  2614.       addr = 0;
  2615.       pid = 0;
  2616.       if (name == NULL)
  2617.     /* out of memory -- what to do? */;
  2618.       else if (fe_create_pidlock (name, &addr, &pid) == 0)
  2619.     {
  2620.       /* Remember name in fe_pidlock so we can unlink it on exit. */
  2621.       fe_pidlock = name;
  2622.  
  2623.       /* Remember that we have access to the databases.
  2624.        * This lets us know when we can enable the history window. */
  2625.       fe_globalData.all_databases_locked = FALSE;
  2626.     }
  2627.       else 
  2628.     {
  2629.       char *fmt = NULL;
  2630.       char *lock = name ? name : ".netscape/lock";
  2631.  
  2632.       fmt = PR_sprintf_append(fmt, XP_GetString(XFE_APP_HAS_DETECTED_LOCK),
  2633.                   XP_AppName, lock);
  2634.       fmt = PR_sprintf_append(fmt,
  2635.                   XP_GetString(XFE_ANOTHER_USER_IS_RUNNING_APP),
  2636.                   XP_AppName,
  2637.                   fe_config_dir);
  2638.  
  2639.       if (addr != 0 && pid != 0)
  2640.         {
  2641.           struct in_addr inaddr;
  2642.           PRHostEnt *hp, hpbuf;
  2643.           char dbbuf[PR_NETDB_BUF_SIZE];
  2644.           const char *host;
  2645.  
  2646.           inaddr.s_addr = addr;
  2647. #ifndef NSPR20
  2648.           hp = PR_gethostbyaddr((char *)&inaddr, sizeof inaddr, AF_INET,
  2649.                     &hpbuf, dbbuf, sizeof(dbbuf), 0);
  2650. #else
  2651.               {
  2652.           PRStatus sts;
  2653.           PRNetAddr pr_addr;
  2654.  
  2655.           pr_addr.inet.family = AF_INET;
  2656.           pr_addr.inet.ip = addr;
  2657.           sts = PR_GetHostByAddr(&pr_addr,dbbuf, sizeof(dbbuf), &hpbuf);
  2658.           if (sts == PR_FAILURE)
  2659.           hp = NULL;
  2660.           else
  2661.           hp = &hpbuf;
  2662.           }
  2663. #endif
  2664.           host = (hp == NULL) ? inet_ntoa(inaddr) : hp->h_name;
  2665.           fmt = PR_sprintf_append(fmt,
  2666.               XP_GetString(XFE_APPEARS_TO_BE_RUNNING_ON_HOST_UNDER_PID),
  2667.               host, (unsigned)pid);
  2668.         }
  2669.  
  2670.       fmt = PR_sprintf_append(fmt,
  2671.                   XP_GetString(XFE_YOU_MAY_CONTINUE_TO_USE),
  2672.                   XP_AppName);
  2673.       fmt = PR_sprintf_append(fmt,
  2674.                   XP_GetString(XFE_OTHERWISE_CHOOSE_CANCEL),
  2675.                   XP_AppName, lock, XP_AppName);
  2676.  
  2677.       if (fmt)
  2678.         {
  2679.           if (!fe_Confirm_2 (toplevel, fmt))
  2680.         exit (0);
  2681.           free (fmt);
  2682.         }
  2683.       if (name) free (name);
  2684.  
  2685.       /* Keep on-disk databases from being open-able. */
  2686.       dbSetOrClearDBLock (LockOutDatabase);
  2687.       fe_globalData.all_databases_locked = TRUE;
  2688.     }
  2689.     }
  2690.  
  2691.   {
  2692.     /* Install the default signal handlers */
  2693.     act.sa_handler = fe_sigchild_handler;
  2694.     act.sa_flags = 0;
  2695.     sigfillset(&act.sa_mask);
  2696.     sigaction (SIGCHLD, &act, NULL);
  2697.  
  2698.     fe_InitializeGlobalResources (toplevel);
  2699.  
  2700. #ifndef OLD_UNIX_FILES
  2701.  
  2702.     /* Maybe we want to copy an old set of files before reading them
  2703.        with their historically-current names. */
  2704.     fe_copy_init_files (toplevel);
  2705.  
  2706. #else  /* OLD_UNIX_FILES */
  2707.  
  2708.     /* Maybe we want to rename an old set of files before reading them
  2709.        with their historically-current names. */
  2710.     fe_rename_init_files (toplevel);
  2711.  
  2712. #endif /* OLD_UNIX_FILES */
  2713.  
  2714.     /* New XP-prefs routine. */
  2715.     SECNAV_InitConfigObject();
  2716.     
  2717.     /* Must be called before XFE_DefaultPrefs */
  2718.     ekit_Initialize(toplevel);
  2719.     AltMailInit();
  2720.  
  2721.     FE_register_pref_callbacks();
  2722.  
  2723.     /* Load up the preferences. */
  2724.     XFE_DefaultPrefs (&fe_defaultPrefs);
  2725.  
  2726.     /* must be called after fe_InitFonts() */
  2727.     XFE_ReadPrefs ((char *) fe_globalData.user_prefs_file, &fe_globalPrefs);
  2728.  
  2729.     fe_check_prefs_version(&fe_globalPrefs);
  2730.     if (fe_globalPrefs.prefs_need_upgrade > 0) {
  2731.         if (! fe_CheckVersionAndSavePrefs((char *) fe_globalData.user_prefs_file,
  2732.                                           &fe_globalPrefs))
  2733.             fe_perror_2 (toplevel, XP_GetString( XFE_ERROR_SAVING_OPTIONS ) );
  2734.     }    
  2735.     else if (fe_globalPrefs.prefs_need_upgrade < 0) {
  2736.         char *msg = PR_smprintf(XP_GetString(XFE_PREFS_DOWNGRADE),
  2737.                                 fe_globalPrefs.version_number,
  2738.                                 PREFS_CURRENT_VERSION);
  2739.         fe_Alert_2 (toplevel, msg);
  2740.         XP_FREE(msg);
  2741.     }
  2742.  
  2743. {
  2744.     char buf [1024];
  2745.     PR_snprintf (buf, sizeof (buf), "%s/%s", fe_home_dir, ".netscape/user.js");
  2746.     PREF_ReadUserJSFile(buf);
  2747.     PR_snprintf (buf, sizeof (buf), "%s/%s", fe_home_dir, ".netscape/hook.js");
  2748.     HK_ReadHookFile(buf);
  2749. }
  2750.  
  2751.     fe_startDisplayFactory(toplevel);
  2752.  
  2753. #ifndef OLD_UNIX_FILES
  2754.     fe_clean_old_init_files (toplevel); /* finish what we started... */
  2755.         /* spider begin */
  2756.         /* TODO: need to rename lid cache dir too! */
  2757.         /* spider end */
  2758. #else  /* OLD_UNIX_FILES */
  2759.     /* kludge kludge - the old name is *stored* in the prefs, so if we've
  2760.        renamed the cache directory, rename it in the preferences too. */
  2761.     if (fe_renamed_cache_dir)
  2762.       {
  2763.     if (fe_globalPrefs.cache_dir)
  2764.       free (fe_globalPrefs.cache_dir);
  2765.     fe_globalPrefs.cache_dir = fe_renamed_cache_dir;
  2766.     fe_renamed_cache_dir = 0;
  2767.     if (!XFE_SavePrefs ((char *) fe_globalData.user_prefs_file,
  2768.                 &fe_globalPrefs))
  2769.       fe_perror_2 (toplevel, XP_GetString( XFE_ERROR_SAVING_OPTIONS ) );
  2770.       }
  2771. #endif /* OLD_UNIX_FILES */
  2772.  
  2773.     GH_SetGlobalHistoryTimeout (fe_globalPrefs.global_history_expiration
  2774.                 * 24 * 60 * 60);
  2775.   }
  2776. #ifdef NSPR_SPLASH
  2777.     if (fe_globalData.show_splash)
  2778.       {
  2779.     PR_XUnlock();
  2780.     fe_splashStart(toplevel);
  2781.       }
  2782. #endif
  2783.  
  2784. #ifdef NSPR_SPLASH
  2785.   if (fe_globalData.show_splash)
  2786.     fe_splashUpdateText(XP_GetString(XFE_SPLASH_REGISTERING_CONVERTERS));
  2787. #endif
  2788.  
  2789.   NR_StartupRegistry();
  2790.   fe_RegisterConverters ();  /* this must be before InstallPreferences(),
  2791.                 and after fe_InitializeGlobalResources(). */
  2792.  
  2793. #ifdef SAVE_ALL
  2794.   SAVE_Initialize ();         /* Register some more converters. */
  2795. #endif /* SAVE_ALL */
  2796.  
  2797.   PREF_SetDefaultCharPref("profile.name", fe_globalPrefs.email_address);
  2798.   PREF_SetDefaultCharPref("profile.directory", fe_config_dir);
  2799.   PREF_SetDefaultIntPref("profile.numprofiles", 1);
  2800.  
  2801.   GH_InitGlobalHistory();
  2802.  
  2803.   /* SECNAV_INIT needs this defined, but build_user_agent_string cannot 
  2804.    * be called until after SECNAV_INIT, so call this simplified version.
  2805.    */
  2806.   build_simple_user_agent_string(versionLocale);
  2807.  
  2808.   fe_InstallPreferences (0);
  2809.  
  2810.   /*
  2811.   ** Initialize the security library.
  2812.   **
  2813.   ** MAKE SURE THIS IS DONE BEFORE YOU CALL THE NET_InitNetLib, CUZ
  2814.   ** OTHERWISE THE FILE LOCK ON THE HISTORY DB IS LOST!
  2815.   */
  2816. #ifdef NSPR_SPLASH
  2817.   if (fe_globalData.show_splash)
  2818.     fe_splashUpdateText(XP_GetString(XFE_SPLASH_INITIALIZING_SECURITY_LIBRARY));
  2819. #endif
  2820.   SECNAV_Init();
  2821.  
  2822.   /* Must be called after ekit, since user agent is configurable */
  2823.   /* Must also be called after SECNAV_Init, since crypto is dynamic */
  2824.   build_user_agent_string(versionLocale);
  2825.  
  2826.   RNG_SystemInfoForRNG ();
  2827.   RNG_FileForRNG (fe_globalPrefs.history_file);
  2828.   fe_read_screen_for_rng (dpy, XtScreen (toplevel));
  2829.   SECNAV_RunInitialSecConfig();
  2830.   
  2831.   /* Initialize the network library. */
  2832. #ifdef NSPR_SPLASH
  2833.   if (fe_globalData.show_splash)
  2834.     fe_splashUpdateText(XP_GetString(XFE_SPLASH_INITIALIZING_NETWORK_LIBRARY));
  2835. #endif
  2836.   /* The unit for tcp buffer size is changed from ktypes to btyes */
  2837.   NET_InitNetLib (fe_globalPrefs.network_buffer_size, 50);
  2838.  
  2839. #ifdef UNIX_ASYNC_DNS
  2840.   if (fe_UseAsyncDNS())
  2841.   {
  2842.       /* Finish initializing the nonblocking DNS code. */
  2843.       XFE_InitDNS_Late(fe_XtAppContext);
  2844.   }
  2845. #endif
  2846.  
  2847.   /* Initialize the message library. */
  2848. #ifdef NSPR_SPLASH
  2849.   if (fe_globalData.show_splash)
  2850.     fe_splashUpdateText(XP_GetString(XFE_SPLASH_INITIALIZING_MESSAGE_LIBRARY));
  2851. #endif
  2852. #ifdef MOZ_MAIL_NEWS
  2853.   MSG_InitMsgLib(); 
  2854. #endif
  2855.  
  2856.   /* Initialize the Image Library */
  2857. #ifdef NSPR_SPLASH
  2858.   if (fe_globalData.show_splash)
  2859.     fe_splashUpdateText(XP_GetString(XFE_SPLASH_INITIALIZING_IMAGE_LIBRARY));
  2860. #endif
  2861.   IL_Init();
  2862.  
  2863.   /* Initialize libmocha after netlib and before plugins. */
  2864. #ifdef NSPR_SPLASH
  2865.   if (fe_globalData.show_splash)
  2866.     fe_splashUpdateText(XP_GetString(XFE_SPLASH_INITIALIZING_MOCHA));
  2867. #endif
  2868.   LM_InitMocha ();
  2869.  
  2870. #ifdef NSPR_SPLASH
  2871.   if (fe_globalData.show_splash)
  2872.     {
  2873.       fe_splashUpdateText(XP_GetString(XFE_SPLASH_INITIALIZING_PLUGINS));
  2874.       PR_XLock();
  2875.     }
  2876. #endif
  2877.  
  2878.   NPL_Init();
  2879.  
  2880. #ifdef NSPR_SPLASH
  2881.   if (fe_globalData.show_splash)
  2882.     {
  2883.       PR_XUnlock();
  2884.  
  2885.       fe_splashStop();
  2886.  
  2887.       PR_SetThreadPriority(mozilla_thread, 24);
  2888.  
  2889.       PR_XLock();
  2890.     }
  2891. #endif
  2892.  
  2893. #ifdef XFE_RDF
  2894.   /* Initialize RDF */
  2895.   {
  2896.     RDF_InitParamsStruct rdf_params;
  2897.  
  2898.     /* we need some initial context, so create bookmarks */
  2899.     fe_createBookmarks(toplevel, NULL, NULL);
  2900.  
  2901.     rdf_params.profileURL 
  2902.       = XP_PlatformFileToURL(fe_config_dir);
  2903.     rdf_params.bookmarksURL
  2904.       = XP_PlatformFileToURL(fe_globalPrefs.bookmark_file);
  2905.     rdf_params.globalHistoryURL
  2906.       = XP_PlatformFileToURL(fe_globalPrefs.history_file);
  2907.  
  2908.     RDF_Init(&rdf_params);
  2909.  
  2910.     XP_FREEIF(rdf_params.profileURL);
  2911.     XP_FREEIF(rdf_params.bookmarksURL);
  2912.     XP_FREEIF(rdf_params.globalHistoryURL);
  2913.   }
  2914. #endif /*XFE_RDF*/
  2915.  
  2916.   /* Do some late initialization */
  2917.   fe_late_init();
  2918. #ifdef JAVA
  2919.   LJ_SetConsoleShowCallback(FE_TrackJavaConsole, 0);
  2920. #endif
  2921.   
  2922.   fe_InitCommandActions ();
  2923.   fe_InitMouseActions ();
  2924.   fe_InitKeyActions ();
  2925. #ifdef EDITOR
  2926.   fe_EditorInitActions();
  2927. #endif
  2928.  
  2929. #ifdef EDITOR
  2930.   fe_EditorStaticInit();
  2931. #endif
  2932. #ifdef MOZ_MAIL_NEWS
  2933.   FE_InitAddrBook();
  2934. #endif
  2935.  
  2936.   fe_InitPolarisComponents(argv[0]);
  2937.   fe_InitConference(argv[0]);
  2938.  
  2939.   XSetErrorHandler (x_error_handler);
  2940.   XSetIOErrorHandler (x_fatal_error_handler);
  2941.  
  2942.   old_xt_warning_handler = XtAppSetWarningMsgHandler(fe_XtAppContext,
  2943.                              xt_warning_handler);
  2944.   old_xt_warningOnly_handler =  XtAppSetWarningHandler(fe_XtAppContext,
  2945.                                xt_warningOnly_handler);
  2946.  
  2947.   /* At this point, everything in argv[] is a document for us to display.
  2948.      Create a window for each document.
  2949.    */
  2950.   if (argc > 1)
  2951.   {
  2952.       for (i = 1; i < argc; i++)
  2953.       {
  2954.           char buf [2048];
  2955.           if (argv [i][0] == '/')
  2956.           {
  2957.               /* It begins with a / so it's a file. */
  2958.               URL_Struct *url;
  2959.               MWContextType type;
  2960.               
  2961.               PR_snprintf (buf, sizeof (buf), "file:%.900s", argv [i]);
  2962.               url = NET_CreateURLStruct (buf, NET_DONT_RELOAD);
  2963.  
  2964. #ifdef NON_BETA
  2965.               plonkp = True;
  2966. #endif
  2967.               
  2968. #ifdef MOZ_MAIL_NEWS
  2969.               if (fe_globalData.startup_composer)
  2970.               {
  2971.                   type = MWContextEditor;
  2972.               }
  2973.               else
  2974. #endif
  2975.               {
  2976.                   type = MWContextBrowser;
  2977.               }
  2978.               
  2979.               fe_MakeWindow (toplevel, 0, url, NULL, type, FALSE);
  2980.           }
  2981.           else if (argv [i][0] == 0)
  2982.           {
  2983.               /* -nethelp takes precedence over -composer */
  2984.               if (fe_globalData.startup_nethelp)
  2985.               {
  2986. #ifdef NETHELP_STARTUP_FLAG
  2987.                   /* we need some initial context, so create bookmarks */
  2988.                   fe_createBookmarks(toplevel, NULL, NULL);
  2989.                   /* the bookmarks context gets used in FE_GetNetHelpContext */
  2990.                   XP_NetHelp(NULL, HELP_COMMUNICATOR);
  2991. #endif
  2992.               }
  2993.               else
  2994.               {
  2995.                   MWContextType type;
  2996.                   
  2997. #ifdef MOZ_MAIL_NEWS
  2998.                   if (fe_globalData.startup_composer)
  2999.                   {
  3000.                       type = MWContextEditor;
  3001.                   }
  3002.                   else
  3003. #endif
  3004.                   {
  3005.                       type = MWContextBrowser;
  3006.                   }
  3007.                   
  3008.                   fe_MakeWindow (toplevel, 0, 0, NULL, type, FALSE);
  3009.               }
  3010.           }
  3011.           else
  3012.           {
  3013.               PRHostEnt hpbuf;
  3014.               char dbbuf[PR_NETDB_BUF_SIZE];
  3015.               char *s = argv [i];
  3016.               
  3017.               MWContextType type;
  3018.  
  3019. #ifdef NETHELP_STARTUP_FLAG
  3020.               /* Has an argument */
  3021.               if (fe_globalData.startup_nethelp)
  3022.               {
  3023.                 fe_globalData.startup_iconic = TRUE;
  3024.               }
  3025. #endif
  3026. #ifdef MOZ_MAIL_NEWS
  3027.                   if (fe_globalData.startup_composer)
  3028.                     {
  3029.                       type = MWContextEditor;
  3030.                     }
  3031.                   else
  3032. #endif
  3033.                     {
  3034.                       type = MWContextBrowser;
  3035.                     }
  3036.               
  3037.                   while (*s && *s != ':' && *s != '/')
  3038.                     s++;
  3039.                   
  3040. #ifndef NSPR20
  3041.                   if (*s == ':' || PR_gethostbyname (argv [i], &hpbuf, dbbuf, sizeof(dbbuf), 0))
  3042. #else
  3043.                   if (*s == ':' || (PR_GetHostByName (argv [i], dbbuf, sizeof(dbbuf), &hpbuf) == PR_SUCCESS))
  3044. #endif
  3045.                     {
  3046.                       /* There is a : before the first / so it's a URL.
  3047.                          Or it is a host name, which are also magically URLs.
  3048.                          */
  3049.                       URL_Struct *url = NET_CreateURLStruct (argv [i], NET_DONT_RELOAD);
  3050.                   
  3051. #ifdef MOZ_MAIL_NEWS
  3052.                       if (!XP_STRNCASECMP (argv[i], "mailto:", 7))
  3053.                         type = MWContextMessageComposition;
  3054.                       else if (!XP_STRNCASECMP (argv[i], "addrbk:", 7))
  3055.                         type = MWContextAddressBook;
  3056. #endif
  3057.                   
  3058. #ifdef NON_BETA
  3059.                       plonkp = True;
  3060. #endif
  3061.                       fe_MakeWindow (toplevel, 0, url, NULL, type, FALSE);
  3062.                     }
  3063.                   else
  3064.                     {
  3065.                       /* There is a / or end-of-string before
  3066.                          so it's a file. */
  3067.                       char cwd [1024];
  3068.                       URL_Struct *url;
  3069. #ifdef SUNOS4
  3070.                       if (! getwd (cwd))
  3071. #else
  3072.                         if (! getcwd (cwd, sizeof cwd))
  3073. #endif
  3074.                           {
  3075.                             fprintf (stderr, "%s: getwd: %s\n", 
  3076.                                      fe_progname, cwd);
  3077.                             break;
  3078.                           }
  3079.                       PR_snprintf (buf, sizeof (buf),
  3080.                                    "file:%.900s/%.900s", cwd, argv [i]);
  3081.                       url = NET_CreateURLStruct (buf, NET_DONT_RELOAD);
  3082. #ifdef NON_BETA
  3083.                       plonkp = True;
  3084. #endif
  3085.                       fe_MakeWindow (toplevel, 0, url, NULL, MWContextBrowser,
  3086.                                      FALSE);
  3087.                     }
  3088. #ifdef NETHELP_STARTUP_FLAG
  3089.                   if (fe_globalData.startup_nethelp)
  3090.                     {
  3091.                       XP_NetHelp(NULL, HELP_COMMUNICATOR);
  3092.                       type = MWContextBrowser;
  3093.                     }
  3094. #endif
  3095.           }
  3096.       } /* end for */
  3097.  
  3098. #ifdef MOZ_MAIL_NEWS
  3099.       /* -mail: show inbox */
  3100.       if (fe_globalData.startup_mail)
  3101.       {
  3102.           fe_showInbox(toplevel, NULL, NULL,
  3103.                        fe_globalPrefs.reuse_thread_window, False);
  3104.       }
  3105.       
  3106.       /* -news: show news */
  3107.       if (fe_globalData.startup_news)
  3108.       {
  3109.           fe_showNewsgroups(toplevel, NULL, NULL);
  3110.       }
  3111. #endif  /* MOZ_MAIL_NEWS */
  3112.       
  3113.       /* -bookmarks: show bookmarks */
  3114.       if (fe_globalData.startup_bookmarks)
  3115.       {
  3116.           fe_showBookmarks(toplevel,NULL,NULL);
  3117.       }
  3118.       
  3119.       /* -history: show history */
  3120.       if (fe_globalData.startup_history)
  3121.       {
  3122.           fe_showHistory(toplevel,NULL,NULL);
  3123.       }
  3124.   }
  3125.   else
  3126.   {
  3127.       /* These command line options override the pres */
  3128.       if (
  3129. #ifdef MOZ_TASKBAR
  3130.               fe_globalData.startup_component_bar || 
  3131. #endif
  3132. #ifdef MOZ_MAIL_NEWS
  3133.           fe_globalData.startup_composer ||
  3134.           fe_globalData.startup_mail ||
  3135.           fe_globalData.startup_news ||
  3136. #endif
  3137.           fe_globalData.startup_nethelp)
  3138.       {
  3139. #ifdef MOZ_TASKBAR
  3140.           /* -component-bar: show the task bar only */
  3141.           if (fe_globalData.startup_component_bar)
  3142.           {
  3143.               extern void fe_showTaskBar(Widget toplevel);
  3144.               extern fe_colormap * fe_GetSharedColormap(void);
  3145.  
  3146.               fe_colormap *cmap = fe_GetSharedColormap();
  3147.               
  3148.               MWContext * task_bar_context;
  3149.  
  3150.               /* Make sure the bookmark frame is alive, since the floating
  3151.                  task bar uses it as its parent frame */
  3152.               fe_createBookmarks(toplevel, NULL, NULL);
  3153.               
  3154.               task_bar_context = XP_NewContext();
  3155.               
  3156.               task_bar_context->fe.data = XP_NEW_ZAP(fe_ContextData);
  3157.               
  3158.               CONTEXT_DATA(task_bar_context)->colormap = cmap;
  3159.               
  3160.               fe_InitIconColors(task_bar_context);
  3161.               
  3162.               fe_showTaskBar(toplevel);
  3163.  
  3164.               XP_FREE(CONTEXT_DATA(task_bar_context));
  3165.               XP_FREE(task_bar_context);
  3166.           }
  3167.           else
  3168. #endif
  3169.           {
  3170. #ifdef MOZ_MAIL_NEWS
  3171.               /* -composer: show the composer */
  3172.               if (fe_globalData.startup_composer)
  3173.               {
  3174.                   fe_MakeWindow(toplevel, 0, NULL, NULL,MWContextEditor,FALSE);
  3175.               }
  3176.  
  3177.               /* -mail: show inbox */
  3178.               if (fe_globalData.startup_mail)
  3179.               {
  3180.                   fe_showInbox(toplevel, NULL, NULL,
  3181.                                fe_globalPrefs.reuse_thread_window, False);
  3182.               }
  3183.  
  3184.               /* -news: show news */
  3185.               if (fe_globalData.startup_news)
  3186.               {
  3187.                   fe_showNewsgroups(toplevel, NULL, NULL);
  3188.               }
  3189. #endif  /* MOZ_MAIL_NEWS */
  3190.  
  3191.               /* -nethelp: show nethelp only (no args)*/
  3192.               if (fe_globalData.startup_nethelp)
  3193.               {
  3194. #ifdef NETHELP_STARTUP_FLAG
  3195.                   /* we need some initial context, so create bookmarks */
  3196.                   fe_createBookmarks(toplevel, NULL, NULL);
  3197.                   /* the bookmarks context gets used in FE_GetNetHelpContext */
  3198.                   XP_NetHelp(NULL, HELP_COMMUNICATOR);
  3199.  
  3200.                   fe_globalData.startup_iconic = TRUE;
  3201.                   fe_MakeWindow (toplevel, 0, 0, NULL, MWContextBrowser, FALSE);
  3202. #endif
  3203.               }
  3204.  
  3205.               /*
  3206.                * These two only get shown if one of the above was shown.
  3207.                * They can only exist if another frame is shown.
  3208.                */
  3209.  
  3210.               /* -bookmarks: show bookmarks */
  3211.               if (fe_globalData.startup_bookmarks)
  3212.               {
  3213.                   fe_showBookmarks(toplevel,NULL,NULL);
  3214.               }
  3215.       
  3216.               /* -history: show history */
  3217.               if (fe_globalData.startup_history)
  3218.               {
  3219.                   fe_showHistory(toplevel,NULL,NULL);
  3220.               }
  3221.           }
  3222.       }
  3223.       else
  3224.       {
  3225.           URL_Struct *url = 0;
  3226.           XP_Bool     launch_appl = FALSE;
  3227.  
  3228.           /*
  3229.            * startup_mode in Navigator 4.0 is obsolete as we allow the user
  3230.            * to launch more than one application during startup. 
  3231.            *
  3232.            * if (fe_globalPrefs.startup_mode == 1)
  3233.            *     bufp = XP_STRDUP ("mailbox:");
  3234.            * else if (fe_globalPrefs.startup_mode == 2)
  3235.            *     bufp = XP_STRDUP ("news:");
  3236.            * else {
  3237.            * if (fe_globalPrefs.home_document && *fe_globalPrefs.home_document)
  3238.            *         bufp = XP_STRDUP (fe_globalPrefs.home_document);
  3239.            * }
  3240.            *
  3241.            * url = NET_CreateURLStruct (bufp, FALSE);
  3242.            * fe_MakeWindow (toplevel, 0, url, NULL, MWContextBrowser, FALSE);
  3243.            * if (bufp) XP_FREE (bufp);
  3244.            */
  3245.  
  3246.           /* Make sure we pop up the browser if no application is specified */
  3247.           launch_appl = fe_globalPrefs.startup_browser_p ||
  3248. #ifdef MOZ_MAIL_NEWS
  3249.               fe_globalPrefs.startup_mail_p ||
  3250.               fe_globalPrefs.startup_news_p ||
  3251. #endif
  3252. #ifdef EDITOR
  3253.               fe_globalPrefs.startup_editor_p ||
  3254. #endif
  3255.               fe_globalPrefs.startup_conference_p ||
  3256.               fe_globalPrefs.startup_netcaster_p ||
  3257.               fe_globalData.startup_netcaster ||
  3258.               fe_globalPrefs.startup_calendar_p;
  3259.           
  3260.           if ((fe_globalPrefs.startup_browser_p == True) ||
  3261.               (! launch_appl)) {
  3262.               url = fe_GetBrowserStartupUrlStruct();
  3263.               fe_MakeWindow(toplevel, 0, url, NULL, MWContextBrowser, FALSE);
  3264.           }
  3265.           
  3266. #ifdef MOZ_MAIL_NEWS
  3267.           if (fe_globalPrefs.startup_mail_p == True) {
  3268.               fe_showInbox(toplevel, NULL, NULL, fe_globalPrefs.reuse_thread_window, False);
  3269.           }
  3270.           
  3271.           if (fe_globalPrefs.startup_news_p == True) 
  3272.           {
  3273.               fe_showNewsgroups(toplevel, NULL, NULL);
  3274.           }
  3275. #endif
  3276. #ifdef EDITOR
  3277.           if (fe_globalPrefs.startup_editor_p == True) {
  3278.               fe_showEditor(toplevel, NULL, NULL, NULL);
  3279.           }
  3280. #endif
  3281. #ifdef MOZ_MAIL_NEWS
  3282.  
  3283.           if (fe_globalPrefs.startup_conference_p == True) {
  3284.               if (fe_IsConferenceInstalled())
  3285.                   fe_showConference(toplevel, 0 /* email */,
  3286.                                     0 /* use */, 0 /* coolAddr */);
  3287.           }
  3288. #endif  /* MOZ_MAIL_NEWS */
  3289.           
  3290.           if (fe_globalPrefs.startup_netcaster_p == True) {
  3291.             fe_globalData.startup_netcaster=False;
  3292.             fe_showNetcaster(toplevel);
  3293.           }
  3294.           
  3295.           if (fe_globalPrefs.startup_calendar_p == True) {
  3296.             if (fe_IsCalendarInstalled())
  3297.               fe_showCalendar(toplevel);
  3298.           }
  3299.         }
  3300.     }
  3301.  
  3302.   if (fe_globalData.startup_netcaster)
  3303.     fe_showNetcaster(toplevel);
  3304.  
  3305. #ifdef MOZ_MAIL_NEWS
  3306.   /* Create the biffcontext, to keep the new-mail notifiers up-to-date. */
  3307.   biffcontext = XP_NewContext();
  3308.   biffcontext->type = MWContextBiff;
  3309.   biffcontext->funcs = fe_BuildDisplayFunctionTable();
  3310.   CONTEXT_DATA(biffcontext) = XP_NEW_ZAP(fe_ContextData);
  3311.   XP_AddContextToList(biffcontext);
  3312.   MSG_BiffInit(biffcontext, fe_mailNewsPrefs);
  3313. #endif
  3314.  
  3315.   fe_command_line_done = True;
  3316.  
  3317.   {
  3318.     extern void PR_SetXtHackOkayToReleaseXLockFn(int (*fn)(void));
  3319.     PR_SetXtHackOkayToReleaseXLockFn(fe_xt_hack_okayToReleaseXLock);
  3320.   }
  3321.  
  3322.   while (1)
  3323.     fe_EventLoop ();
  3324.  
  3325.   return (0);
  3326. }
  3327.  
  3328. #ifdef _HPUX_SOURCE
  3329. /* Words cannot express how much HPUX!
  3330.    Sometimes rename("/u/jwz/.MCOM-cache", "/u/jwz/.netscape-cache")
  3331.    will fail and randomly corrupt memory (but only in the case where
  3332.    the first is a directory and the second doesn't exist.)  To avoid
  3333.    this, we fork-and-exec `mv' instead of using rename().
  3334.  */
  3335. # include <sys/wait.h>
  3336.  
  3337. # undef rename
  3338. # define rename hpux_www_
  3339. static int
  3340. rename (const char *source, const char *target)
  3341. {
  3342.   struct sigaction newact, oldact;
  3343.   pid_t forked;
  3344.   int ac = 0;
  3345.   char **av = (char **) malloc (10 * sizeof (char *));
  3346.   av [ac++] = strdup ("/bin/mv");
  3347.   av [ac++] = strdup ("-f");
  3348.   av [ac++] = strdup (source);
  3349.   av [ac++] = strdup (target);
  3350.   av [ac++] = 0;
  3351.     
  3352.   /* Setup signals so that SIGCHLD is ignored as we want to do waitpid */
  3353.   newact.sa_handler = SIG_DFL;
  3354.   newact.sa_flags = 0;
  3355.   sigfillset(&newact.sa_mask);
  3356.   sigaction (SIGCHLD, &newact, &oldact);
  3357.  
  3358.   switch (forked = fork ())
  3359.     {
  3360.     case -1:
  3361.       while (--ac >= 0)
  3362.     free (av [ac]);
  3363.       free (av);
  3364.       /* Reset SIGCHLD signal hander before returning */
  3365.       sigaction(SIGCHLD, &oldact, NULL);
  3366.       return -1;    /* fork() failed (errno is meaningful.) */
  3367.       break;
  3368.     case 0:
  3369.       {
  3370.     execvp (av[0], av);
  3371.     exit (-1);    /* execvp() failed (this exits the child fork.) */
  3372.     break;
  3373.       }
  3374.     default:
  3375.       {
  3376.     /* This is the "old" process (subproc pid is in `forked'.) */
  3377.     int status = 0;
  3378.  
  3379.     /* wait for `mv' to terminate. */
  3380.     pid_t waited_pid = waitpid (forked, &status, 0);
  3381.  
  3382.     /* Reset SIGCHLD signal hander before returning */
  3383.     sigaction(SIGCHLD, &oldact, NULL);
  3384.  
  3385.     while (--ac >= 0)
  3386.       free (av [ac]);
  3387.     free (av);
  3388.  
  3389.     return 0;
  3390.     break;
  3391.       }
  3392.     }
  3393. }
  3394. #endif /* !HPUX */
  3395.  
  3396.  
  3397.  
  3398. /* With every release, we change the names or locations of the init files.
  3399.    Is this a feature?
  3400.  
  3401.               1.0                       1.1                      2.0
  3402.   ========================== ======================== ========================
  3403.   .MCOM-bookmarks.html       .netscape-bookmarks.html .netscape/bookmarks.html
  3404.   .MCOM-HTTP-cookie-file     .netscape-cookies        .netscape/cookies
  3405.   .MCOM-preferences          .netscape-preferences    .netscape/preferences
  3406.   .MCOM-global-history       .netscape-history        .netscape/history
  3407.   .MCOM-cache/               .netscape-cache/         .netscape/cache/
  3408.   .MCOM-cache/MCOM-cache-fat .netscape-cache/index    .netscape/cache/index.db
  3409.   .MCOM-newsgroups-*         .netscape-newsgroups-*   .netscape/newsgroups-*
  3410.    <none>                     <none>                  .netscape/cert.db
  3411.    <none>                     <none>                  .netscape/cert-nameidx.db
  3412.    <none>                     <none>                  .netscape/key.db
  3413.    <none>                     <none>                  .netscape/popstate
  3414.    <none>                     <none>                  .netscape/cachelist
  3415.    <none>                     <none>                  nsmail/
  3416.    <none>                     <none>                  .netscape/mailsort
  3417.  
  3418.   Files that never changed:
  3419.  
  3420.   .newsrc-*                  .newsrc-*                .newsrc-*
  3421.   .snewsrc-*                 .snewsrc-*               .snewsrc-*
  3422.  */
  3423.  
  3424. #ifdef OLD_UNIX_FILES
  3425.  
  3426.  
  3427. static void
  3428. fe_rename_init_files (Widget toplevel)
  3429. {
  3430.   struct stat st;
  3431.   char file1 [1024];
  3432.   char file2 [1024];
  3433.   char buf [1024];
  3434.   char *s1, *s2;
  3435.   Boolean asked = False;
  3436.  
  3437.   PR_snprintf (file1, sizeof (file1), "%s/", fe_home_dir);
  3438.   strcpy (file2, file1);
  3439.   s1 = file1 + strlen (file1);
  3440.   s2 = file2 + strlen (file2);
  3441.  
  3442. #define FROB(NAME1,NAME2,GAG)                        \
  3443.   strcpy (s1, NAME1);                            \
  3444.   strcpy (s2, NAME2);                            \
  3445.   if (stat (file2, &st))                        \
  3446.     if (!stat (file1, &st))                        \
  3447.       {                                    \
  3448.     if (! asked)                            \
  3449.       {                                \
  3450.         if (fe_Confirm_2 (toplevel,                    \
  3451.                   fe_globalData.rename_files_message))    \
  3452.           asked = True;                        \
  3453.         else                            \
  3454.           return;                            \
  3455.       }                                \
  3456.     if (rename (file1, file2))                    \
  3457.       {                                \
  3458.         PR_snprintf (buf, sizeof (buf),
  3459.                      XP_GetString(XFE_MOZILLA_RENAMING_SOMETHING_TO_SOMETHING),
  3460.                      s1, s2); \
  3461.         fe_perror_2 (toplevel, buf);                \
  3462.       }                                \
  3463.         else if (GAG)                            \
  3464.       fe_renamed_cache_dir = strdup (file2);            \
  3465.       }
  3466.  
  3467.   FROB (".MCOM-bookmarks.html",          ".netscape-bookmarks.html", False);
  3468.   FROB (".MCOM-HTTP-cookie-file",      ".netscape-cookies", False);
  3469.   FROB (".MCOM-preferences",          ".netscape-preferences", False);
  3470.   FROB (".MCOM-global-history",          ".netscape-history", False);
  3471.   FROB (".MCOM-cache",              ".netscape-cache", True);
  3472.   FROB (".netscape-cache/MCOM-cache-fat", ".netscape-cache/index", False);
  3473. #undef FROB
  3474. }
  3475.  
  3476. #else  /* !OLD_UNIX_FILES */
  3477.  
  3478. #if !defined(__FreeBSD__) && !defined(MACLINUX) && !defined(LINUX_GLIBC_2)
  3479. extern char *sys_errlist[];
  3480. extern int sys_nerr;
  3481. #endif
  3482.  
  3483. static XP_Bool
  3484. fe_ensure_config_dir_exists (Widget toplevel)
  3485. {
  3486.   char *dir, *fmt;
  3487.   static char buf [2048];
  3488.   struct stat st;
  3489.   XP_Bool exists;
  3490.  
  3491.   dir = PR_smprintf ("%s/.netscape", fe_home_dir);
  3492.   if (!dir)
  3493.     return FALSE;
  3494.  
  3495.   exists = !stat (dir, &st);
  3496.  
  3497.   if (exists && !(st.st_mode & S_IFDIR))
  3498.     {
  3499.       /* It exists but is not a directory!
  3500.      Rename the old file so that we can create the directory.
  3501.      */
  3502.       char *loser = (char *) XP_ALLOC (XP_STRLEN (dir) + 100);
  3503.       XP_STRCPY (loser, dir);
  3504.       XP_STRCAT (loser, ".BAK");
  3505.       if (rename (dir, loser) == 0)
  3506.     {
  3507.       fmt = XP_GetString( XFE_EXISTED_BUT_WAS_NOT_A_DIRECTORY );
  3508.       exists = FALSE;
  3509.     }
  3510.       else
  3511.     {
  3512.       fmt = XP_GetString( XFE_EXISTS_BUT_UNABLE_TO_RENAME );
  3513.     }
  3514.  
  3515.       PR_snprintf (buf, sizeof (buf), fmt, XP_AppName, dir, loser);
  3516.       XP_FREE (loser);
  3517.       fe_Alert_2 (toplevel, buf);
  3518.       if (exists)
  3519.     {
  3520.       free (dir);
  3521.       return FALSE;
  3522.     }
  3523.     }
  3524.  
  3525.   if (!exists)
  3526.     {
  3527.       /* ~/.netscape/ does not exist.  Create the directory.
  3528.        */
  3529.       if (mkdir (dir, 0700) < 0)
  3530.     {
  3531.       fmt = XP_GetString( XFE_UNABLE_TO_CREATE_DIRECTORY );
  3532.       PR_snprintf (buf, sizeof (buf), fmt, XP_AppName, dir,
  3533.            ((errno >= 0 && errno < sys_nerr)
  3534.             ? sys_errlist [errno] : XP_GetString( XFE_UNKNOWN_ERROR )));
  3535.       fe_Alert_2 (toplevel, buf);
  3536.       free (dir);
  3537.       return FALSE;
  3538.     }
  3539.     }
  3540.  
  3541.   fe_config_dir = dir;
  3542.   return TRUE;
  3543. }
  3544.  
  3545. #ifndef SUNOS4
  3546. void
  3547. fe_atexit_handler(void)
  3548. {
  3549.   fe_MinimalNoUICleanup();
  3550.   if (fe_pidlock) unlink (fe_pidlock);
  3551.   fe_pidlock = NULL;
  3552. }
  3553. #endif /* SUNOS4 */
  3554.  
  3555. #ifndef INADDR_LOOPBACK
  3556. #define    INADDR_LOOPBACK        0x7F000001
  3557. #endif
  3558.  
  3559. #define MAXTRIES    100
  3560.  
  3561. static int
  3562. fe_create_pidlock (const char *name, unsigned long *paddr, pid_t *ppid)
  3563. {
  3564.   char hostname[64];        /* should use MAXHOSTNAMELEN */
  3565.   PRHostEnt *hp, hpbuf;
  3566.   char dbbuf[PR_NETDB_BUF_SIZE];
  3567.   unsigned long myaddr, addr;
  3568.   struct in_addr inaddr;
  3569.   char *signature;
  3570.   int len, tries, rval;
  3571.   char buf[1024];        /* should use PATH_MAX or pathconf */
  3572.   char *colon, *after;
  3573.   pid_t pid;
  3574.  
  3575. #ifndef NSPR20
  3576.   if (gethostname (hostname, sizeof hostname) < 0 ||
  3577.       (hp = PR_gethostbyname (hostname, &hpbuf, dbbuf, sizeof(dbbuf), 0)) == NULL)
  3578.     inaddr.s_addr = INADDR_LOOPBACK;
  3579.   else
  3580.     memcpy (&inaddr, hp->h_addr, sizeof inaddr);
  3581. #else
  3582.   {
  3583.   PRStatus sts;
  3584.  
  3585.   sts = PR_GetSystemInfo(PR_SI_HOSTNAME, hostname, sizeof(hostname));
  3586.   if (sts == PR_FAILURE)
  3587.     inaddr.s_addr = INADDR_LOOPBACK;
  3588.   else {
  3589.     sts = PR_GetHostByName (hostname, dbbuf, sizeof(dbbuf), &hpbuf);
  3590.     if (sts == PR_FAILURE)
  3591.       inaddr.s_addr = INADDR_LOOPBACK;
  3592.     else {
  3593.       hp = &hpbuf;
  3594.       memcpy (&inaddr, hp->h_addr, sizeof inaddr);
  3595.     }
  3596.   }
  3597.   }
  3598. #endif
  3599.  
  3600.   myaddr = inaddr.s_addr;
  3601.   signature = PR_smprintf ("%s:%u", inet_ntoa (inaddr), (unsigned)getpid ());
  3602.   tries = 0;
  3603.   addr = 0;
  3604.   pid = 0;
  3605.   while ((rval = symlink (signature, name)) < 0)
  3606.     {
  3607.       if (errno != EEXIST)
  3608.     break;
  3609.       len = readlink (name, buf, sizeof buf - 1);
  3610.       if (len > 0)
  3611.     {
  3612.       buf[len] = '\0';
  3613.       colon = strchr (buf, ':');
  3614.       if (colon != NULL)
  3615.         {
  3616.           *colon++ = '\0';
  3617.           if ((addr = inet_addr (buf)) != (unsigned long)-1)
  3618.         {
  3619.           pid = strtol (colon, &after, 0);
  3620.           if (pid != 0 && *after == '\0')
  3621.             {
  3622.               if (addr != myaddr)
  3623.             {
  3624.               /* Remote pid: give up even if lock is stuck. */
  3625.               break;
  3626.             }
  3627.  
  3628.               /* signator was a local process -- check liveness */
  3629.               if (kill (pid, 0) == 0 || errno != ESRCH)
  3630.             {
  3631.               /* Lock-owning process appears to be alive. */
  3632.               break;
  3633.             }
  3634.             }
  3635.         }
  3636.         }
  3637.     }
  3638.  
  3639.       /* Try to claim a bogus or stuck lock. */
  3640.       (void) unlink (name);
  3641.       if (++tries > MAXTRIES)
  3642.     break;
  3643.     }
  3644.  
  3645.   if (rval == 0)
  3646.     {
  3647.       struct sigaction act, oldact;
  3648.  
  3649.       act.sa_handler = fe_Exit;
  3650.       act.sa_flags = 0;
  3651.       sigfillset (&act.sa_mask);
  3652.  
  3653.       /* Set SIGINT, SIGTERM and SIGHUP to our fe_Exit(). If these signals
  3654.        * have already been ignored, dont install our handler because we
  3655.        * could have been started up in the background with a nohup.
  3656.        */
  3657.       sigaction (SIGINT, NULL, &oldact);
  3658.       if (oldact.sa_handler != SIG_IGN)
  3659.     sigaction (SIGINT, &act, NULL);
  3660.  
  3661.       sigaction (SIGHUP, NULL, &oldact);
  3662.       if (oldact.sa_handler != SIG_IGN)
  3663.     sigaction (SIGHUP, &act, NULL);
  3664.  
  3665.       sigaction (SIGTERM, NULL, &oldact);
  3666.       if (oldact.sa_handler != SIG_IGN)
  3667.     sigaction (SIGTERM, &act, NULL);
  3668.  
  3669. #ifndef SUNOS4
  3670.       /* atexit() is not available in sun4. We need to find someother
  3671.        * mechanism to do this in sun4. Maybe we will get a signal or
  3672.        * something.
  3673.        */
  3674.  
  3675.       /* Register a atexit() handler to remove lock file */
  3676.       atexit(fe_atexit_handler);
  3677. #endif /* SUNOS4 */
  3678.     }
  3679.   free (signature);
  3680.   *paddr = addr;
  3681.   *ppid = pid;
  3682.   return rval;
  3683. }
  3684.  
  3685.  
  3686. /* This copies one file to another, optionally setting the permissions.
  3687.  */
  3688. static void
  3689. fe_copy_file (Widget toplevel, const char *in, const char *out, int perms)
  3690. {
  3691.   char buf [1024];
  3692.   FILE *ifp, *ofp;
  3693.   int n;
  3694.   ifp = fopen (in, "r");
  3695.   if (!ifp) return;
  3696.   ofp = fopen (out, "w");
  3697.   if (!ofp)
  3698.     {
  3699.       PR_snprintf (buf, sizeof (buf), XP_GetString( XFE_ERROR_CREATING ), out);
  3700.       fe_perror_2 (toplevel, buf);
  3701.       return;
  3702.     }
  3703.  
  3704.   if (perms)
  3705.     fchmod (fileno (ofp), perms);
  3706.  
  3707.   while ((n = fread (buf, 1, sizeof(buf), ifp)) > 0)
  3708.     while (n > 0)
  3709.       {
  3710.     int w = fwrite (buf, 1, n, ofp);
  3711.     if (w < 0)
  3712.       {
  3713.         PR_snprintf (buf, sizeof (buf), XP_GetString( XFE_ERROR_WRITING ), out);
  3714.         fe_perror_2 (toplevel, buf);
  3715.         return;
  3716.       }
  3717.     n -= w;
  3718.       }
  3719.   fclose (ofp);
  3720.   fclose (ifp);
  3721. }
  3722.  
  3723.  
  3724. /* This does several things that need to be done before the preferences
  3725.    file is loaded:
  3726.  
  3727.    - cause the directory ~/.netscape/ to exist,
  3728.      and warn if it couldn't be created
  3729.  
  3730.    - cause these files to be *copied* from their older
  3731.      equivalents, if there are older versions around
  3732.  
  3733.      ~/.netscape/preferences
  3734.      ~/.netscape/bookmarks.html
  3735.      ~/.netscape/cookies
  3736.  */
  3737. static XP_Bool fe_copied_init_files = FALSE;
  3738.  
  3739. static void
  3740. fe_copy_init_files (Widget toplevel)
  3741. {
  3742.   struct stat st1;
  3743.   struct stat st2;
  3744.   char file1 [512];
  3745.   char file2 [512];
  3746.   char *s1, *s2;
  3747.  
  3748.   if (!fe_config_dir)
  3749.     /* If we were unable to cause ~/.netscape/ to exist, give up now. */
  3750.     return;
  3751.  
  3752.   PR_snprintf (file1, sizeof (file1), "%s/", fe_home_dir);
  3753.   strcpy (file2, file1);
  3754.   s1 = file1 + strlen (file1);
  3755.   s2 = file2 + strlen (file2);
  3756.  
  3757. #define FROB(OLD1, OLD2, NEW, PERMS)            \
  3758.   strcpy (s1, OLD1);                    \
  3759.   strcpy (s2, NEW);                    \
  3760.   if (!stat (file2, &st2))                \
  3761.     ;    /* new exists - leave it alone */        \
  3762.   else if (!stat (file1, &st1))                \
  3763.     {                            \
  3764.       fe_copied_init_files = TRUE;            \
  3765.       fe_copy_file (toplevel, file1, file2, 0);        \
  3766.     }                            \
  3767.   else                            \
  3768.     {                            \
  3769.       strcpy (s1, OLD2);                \
  3770.       if (!stat (file1, &st1))                \
  3771.     {                        \
  3772.           fe_copied_init_files = TRUE;            \
  3773.       fe_copy_file (toplevel, file1, file2, 0);    \
  3774.         }                        \
  3775.     }
  3776.  
  3777.   FROB(".netscape-preferences",
  3778.        ".MCOM-preferences",
  3779.        ".netscape/preferences",
  3780.        0)
  3781.   FROB(".netscape-bookmarks.html",
  3782.        ".MCOM-bookmarks.html",
  3783.        ".netscape/bookmarks.html",
  3784.        0)
  3785.  
  3786.   FROB(".netscape-cookies",
  3787.        ".MCOM-HTTP-cookie-file",
  3788.        ".netscape/cookies",
  3789.        (S_IRUSR | S_IWUSR))        /* rw only by owner */
  3790.  
  3791. #undef FROB
  3792. }
  3793.  
  3794.  
  3795. /* This does several things that need to be done after the preferences
  3796.    file is loaded:
  3797.  
  3798.    - if files were renamed, change the historical values in the preferences
  3799.      file to the new values, and save it out again
  3800.  
  3801.    - offer to delete any obsolete ~/.MCOM or ~/.netscape- that are still
  3802.      sitting around taking up space
  3803.  */
  3804. static void
  3805. fe_clean_old_init_files (Widget toplevel)
  3806. {
  3807.   char buf[1024];
  3808.  
  3809.   char nbm[512],    mbm[512];
  3810.   char ncook[512],  mcook[512];
  3811.   char npref[512],  mpref[512];
  3812.   char nhist[512],  mhist[512];
  3813.   char ncache[512], mcache[512];
  3814.  
  3815.  
  3816.   XP_Bool old_stuff = FALSE;
  3817.   XP_Bool old_cache = FALSE;
  3818.  
  3819.   char *slash;
  3820.   struct stat st;
  3821.  
  3822.   /* spider begin */
  3823.   /* TODO: where does this string get free'd? */
  3824.   if (fe_globalPrefs.sar_cache_dir) free (fe_globalPrefs.sar_cache_dir);
  3825.   PR_snprintf (buf, sizeof (buf), "%s/.netscape/archive/", fe_home_dir);
  3826.   fe_globalPrefs.sar_cache_dir = strdup (buf);
  3827.   /* spider end */
  3828.  
  3829.   if (!fe_copied_init_files)
  3830.     return;
  3831.  
  3832.   /* History and cache always go in the new place by default,
  3833.      no matter what they were set to before. */
  3834.   if (fe_globalPrefs.history_file) free (fe_globalPrefs.history_file);
  3835.   PR_snprintf (buf, sizeof (buf), "%s/.netscape/history.db", fe_home_dir);
  3836.   fe_globalPrefs.history_file = strdup (buf);
  3837.  
  3838.   if (fe_globalPrefs.cache_dir) free (fe_globalPrefs.cache_dir);
  3839.   PR_snprintf (buf, sizeof (buf), "%s/.netscape/cache/", fe_home_dir);
  3840.   fe_globalPrefs.cache_dir = strdup (buf);
  3841.  
  3842.   /* If they were already keeping their bookmarks file in a different
  3843.      place, don't change that preferences setting. */
  3844.   PR_snprintf (buf, sizeof (buf), "%s/.netscape-bookmarks.html", fe_home_dir);
  3845.   if (!fe_globalPrefs.bookmark_file ||
  3846.       !XP_STRCMP (fe_globalPrefs.bookmark_file, buf))
  3847.     {
  3848.       if (fe_globalPrefs.bookmark_file) free (fe_globalPrefs.bookmark_file);
  3849.       PR_snprintf (buf, sizeof (buf), "%s/.netscape/bookmarks.html",
  3850.            fe_home_dir);
  3851.       fe_globalPrefs.bookmark_file = strdup (buf);
  3852.     }
  3853.  
  3854.   /* If their home page was set to their bookmarks file (and that was
  3855.      the default location) then move it to the new place too. */
  3856.   PR_snprintf (buf, sizeof (buf), "file:%s/.netscape-bookmarks.html",
  3857.            fe_home_dir);
  3858.   if (!fe_globalPrefs.home_document ||
  3859.       !XP_STRCMP (fe_globalPrefs.home_document, buf))
  3860.     {
  3861.       if (fe_globalPrefs.home_document) free (fe_globalPrefs.home_document);
  3862.       PR_snprintf (buf, sizeof (buf), "file:%s/.netscape/bookmarks.html",
  3863.            fe_home_dir);
  3864.       fe_globalPrefs.home_document = strdup (buf);
  3865.     }
  3866.  
  3867.   fe_copied_init_files = FALSE;
  3868.  
  3869.   if (!XFE_SavePrefs ((char *) fe_globalData.user_prefs_file, &fe_globalPrefs))
  3870.     fe_perror_2 (toplevel,XP_GetString(XFE_MOZILLA_ERROR_SAVING_OPTIONS));
  3871.  
  3872.  
  3873.   PR_snprintf (nbm, sizeof (nbm), "%s/", fe_home_dir);
  3874.  
  3875.   strcpy (mbm, nbm);    strcat (mbm,   ".MCOM-bookmarks.html");
  3876.   strcpy (ncook, nbm);  strcat (ncook, ".netscape-cookies");
  3877.   strcpy (mcook, nbm);  strcat (mcook, ".MCOM-HTTP-cookie-file");
  3878.   strcpy (npref, nbm);  strcat (npref, ".netscape-preferences");
  3879.   strcpy (mpref, nbm);  strcat (mpref, ".MCOM-preferences");
  3880.   strcpy (nhist, nbm);  strcat (nhist, ".netscape-history");
  3881.   strcpy (mhist, nbm);  strcat (mhist, ".MCOM-global-history");
  3882.   strcpy (ncache, nbm); strcat (ncache,".netscape-cache");
  3883.   strcpy (mcache, nbm); strcat (mcache,".MCOM-cache");
  3884.                         strcat (nbm,   ".netscape-bookmarks.html");
  3885.  
  3886.   if (stat (nbm, &st) == 0   || stat (mbm, &st) == 0 ||
  3887.       stat (ncook, &st) == 0 || stat (mcook, &st) == 0 ||
  3888.       stat (npref, &st) == 0 || stat (mpref, &st) == 0 ||
  3889.       stat (nhist, &st) == 0 || stat (mhist, &st) == 0)
  3890.     old_stuff = TRUE;
  3891.  
  3892.   if (stat (ncache, &st) == 0 || stat (mcache, &st) == 0)
  3893.     old_stuff = old_cache = TRUE;
  3894.  
  3895.   if (old_stuff)
  3896.     {
  3897.       Boolean doit;
  3898.       char *fmt = XP_GetString( XFE_CREATE_CONFIG_FILES );
  3899.  
  3900.       char *foo =
  3901.     (old_cache
  3902.      ? XP_GetString( XFE_OLD_FILES_AND_CACHE )
  3903.      : XP_GetString( XFE_OLD_FILES ) );
  3904.  
  3905.       PR_snprintf (buf, sizeof (buf), fmt, XP_AppName, foo);
  3906.  
  3907.       doit = (Bool) ((int) fe_dialog (toplevel, "convertQuestion", buf,
  3908.                   TRUE, 0, TRUE, FALSE, 0));
  3909.       if (doit)
  3910.     {
  3911.       DIR *dir;
  3912.  
  3913.       /* Nuke the simple files */
  3914.       unlink (nbm);   unlink (mbm);
  3915.       unlink (ncook); unlink (mcook);
  3916.       unlink (npref); unlink (mpref);
  3917.       unlink (nhist); unlink (mhist);
  3918.  
  3919.       /* Nuke the 1.1 cache directory and files in it */
  3920.       dir = opendir (ncache);
  3921.       if (dir)
  3922.         {
  3923.           struct dirent *dp;
  3924.           strcpy (buf, ncache);
  3925.           slash = buf + strlen (buf);
  3926.           *slash++ = '/';
  3927.           while ((dp = readdir (dir)))
  3928.         {
  3929.           strcpy (slash, dp->d_name);
  3930.           unlink (buf);
  3931.         }
  3932.           closedir (dir);
  3933.           rmdir (ncache);
  3934.         }
  3935.  
  3936.       /* Nuke the 1.0 cache directory and files in it */
  3937.       dir = opendir (mcache);
  3938.       if (dir)
  3939.         {
  3940.           struct dirent *dp;
  3941.           strcpy (buf, mcache);
  3942.           slash = buf + strlen (buf);
  3943.           *slash++ = '/';
  3944.           while ((dp = readdir (dir)))
  3945.         {
  3946.           if (strncmp (dp->d_name, "cache", 5) &&
  3947.               strcmp (dp->d_name, "index") &&
  3948.               strcmp (dp->d_name, "MCOM-cache-fat"))
  3949.             continue;
  3950.           strcpy (slash, dp->d_name);
  3951.           unlink (buf);
  3952.         }
  3953.           closedir (dir);
  3954.           rmdir (mcache);
  3955.         }
  3956.  
  3957.       /* Now look for the saved-newsgroup-listings in ~/. and nuke those.
  3958.          (We could rename them, but I just don't care.)
  3959.        */
  3960.       slash = strrchr (nbm, '/');
  3961.       slash[1] = '.';
  3962.       slash[2] = 0;
  3963.       dir = opendir (nbm);
  3964.       if (dir)
  3965.         {
  3966.           struct dirent *dp;
  3967.           while ((dp = readdir (dir)))
  3968.         {
  3969.           if (dp->d_name[0] != '.')
  3970.             continue;
  3971.           if (!strncmp (dp->d_name, ".MCOM-newsgroups-", 17) ||
  3972.               !strncmp (dp->d_name, ".netscape-newsgroups-", 21))
  3973.             {
  3974.               strcpy (slash+1, dp->d_name);
  3975.               unlink (nbm);
  3976.             }
  3977.         }
  3978.           closedir (dir);
  3979.         }
  3980.     }
  3981.     }
  3982. }
  3983.  
  3984. #endif /* !OLD_UNIX_FILES */
  3985.  
  3986. #ifdef MOZ_MAIL_NEWS
  3987.  
  3988. /*
  3989.  * Message Composition
  3990.  */
  3991.  
  3992. extern void
  3993. fe_mc_field_changed(Widget widget, XtPointer closure, XtPointer call_data)
  3994. {
  3995.   MWContext* context = fe_WidgetToMWContext(widget);
  3996.   MSG_HEADER_SET msgtype = (MSG_HEADER_SET) closure;
  3997.   char* value = 0;
  3998.   XP_ASSERT (context);
  3999.   if (!context) return;
  4000.   value = fe_GetTextField(widget);
  4001.   MSG_SetCompHeader (CONTEXT_DATA(context)->comppane, msgtype, value);
  4002. }
  4003.  
  4004.  
  4005. extern void
  4006. fe_mc_field_lostfocus(Widget widget, XtPointer closure, XtPointer call_data)
  4007. {
  4008.   MWContext* context = fe_WidgetToMWContext(widget);
  4009.   MSG_HEADER_SET msgtype = (MSG_HEADER_SET) closure;
  4010.   char* value = 0;
  4011.   char* newvalue;
  4012.   XP_ASSERT (context);
  4013.   if (!context) return;
  4014.   value = fe_GetTextField(widget);
  4015.   newvalue = MSG_UpdateHeaderContents(CONTEXT_DATA(context)->comppane,
  4016.                       msgtype, value);
  4017.   if (newvalue) {
  4018.     fe_SetTextField(widget, newvalue);
  4019.     MSG_SetCompHeader(CONTEXT_DATA(context)->comppane, msgtype, newvalue);
  4020.     XP_FREE(newvalue);
  4021.   }
  4022. }
  4023.  
  4024. extern void
  4025. fe_browse_file_of_text (MWContext *context, Widget text_field, Boolean dirp);
  4026.  
  4027. static void
  4028. fe_mailto_browse_cb(Widget widget, XtPointer closure, XtPointer call_data)
  4029. {
  4030.   MWContext* context = (MWContext*) closure;
  4031.   fe_browse_file_of_text(context, CONTEXT_DATA(context)->mcFcc, FALSE); 
  4032. }
  4033.  
  4034. #define Off(field) XtOffset(fe_ContextData*, field)
  4035. #define ISLABEL        0x0001
  4036. #define ADDBROWSE    0x0002
  4037. #define ISDROPSITE    0x0008
  4038. static struct {
  4039.   char* name;
  4040.   int offset;
  4041.   MSG_HEADER_SET msgtype;
  4042.   int flags;
  4043. } description[] = {
  4044.   {"from",    Off(mcFrom),        MSG_FROM_HEADER_MASK, ISLABEL},
  4045.   {"replyTo",     Off(mcReplyTo),        MSG_REPLY_TO_HEADER_MASK, ISDROPSITE},
  4046.   {"to",    Off(mcTo),        MSG_TO_HEADER_MASK, ISDROPSITE},
  4047.   {"cc",    Off(mcCc),        MSG_CC_HEADER_MASK, ISDROPSITE},
  4048.   {"bcc",    Off(mcBcc),        MSG_BCC_HEADER_MASK, ISDROPSITE},
  4049.   {"fcc",    Off(mcFcc),        MSG_FCC_HEADER_MASK,ADDBROWSE},
  4050.   {"newsgroups",Off(mcNewsgroups),    MSG_NEWSGROUPS_HEADER_MASK, 0},
  4051.   {"followupTo",Off(mcFollowupTo),    MSG_FOLLOWUP_TO_HEADER_MASK,0},
  4052.   {"attachments",Off(mcAttachments),    MSG_ATTACHMENTS_HEADER_MASK, ISDROPSITE},
  4053. };
  4054. #define NUM (sizeof(description) / sizeof(description[0]))
  4055. /*
  4056.   {"subject",     Off(mcSubject),        MSG_SUBJECT_HEADER_MASK, 0},
  4057. */
  4058.  
  4059. #endif  /* MOZ_MAIL_NEWS */
  4060.  
  4061. void resize(Widget w, XtPointer clientData, XtPointer callData)
  4062. {
  4063.     Widget form = (Widget)clientData;
  4064.  
  4065.     XtVaSetValues(form, XmNwidth, XfeWidth(w), 0 );
  4066.     XmUpdateDisplay(XtParent(XtParent(form)));
  4067.  
  4068.  
  4069. }
  4070.  
  4071. void expose(Widget w, XtPointer clientData, XtPointer callData)
  4072. {
  4073.     Widget form = (Widget)clientData;
  4074.  
  4075.     XtVaSetValues(form, XmNwidth, XfeWidth(w), 0 );
  4076.  
  4077. }
  4078.  
  4079. #ifdef MOZ_MAIL_NEWS
  4080.  
  4081. WidgetList
  4082. fe_create_composition_widgets(MWContext* context, Widget pane, int *numkids)
  4083. {
  4084.  
  4085.   Widget* form;
  4086.   Widget label[NUM];
  4087.   Widget widget[NUM];
  4088.   Widget other[NUM];
  4089.   Widget kids[10]; 
  4090.   /*XmFontList fontList;*/
  4091.   Arg av [20];
  4092.   int ac = 0;
  4093.   int i;
  4094.   char buf[100];
  4095.   int maxwidth = 0;
  4096.  
  4097.   
  4098.   fe_ContextData* data = CONTEXT_DATA(context);
  4099.   Widget formParent;
  4100.   Widget scroller;
  4101.   Widget drawingArea;
  4102.   Widget hsb, vsb;
  4103.  
  4104.   XtVaSetValues(pane, XmNseparatorOn, True, 0);
  4105.   ac = 0;
  4106.   XtSetArg(av[ac], XmNscrollingPolicy, XmAUTOMATIC); ac++;
  4107.   scroller = XmCreateScrolledWindow(pane,  "scrollerX", av, ac);
  4108.   XtManageChild(scroller);
  4109.  
  4110.   XtVaGetValues(scroller, XmNclipWindow, &drawingArea,
  4111.                 XmNhorizontalScrollBar, &hsb,
  4112.                 XmNverticalScrollBar, &vsb, 0 );
  4113.  
  4114.   XtVaSetValues(hsb, 
  4115.         XmNhighlightThickness, 0,
  4116.          0);
  4117.   XtVaSetValues(vsb, 
  4118.         XmNhighlightThickness, 0,
  4119.          0);
  4120.  
  4121.  
  4122.   ac = 0;
  4123.   XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  4124.   XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  4125.   XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  4126.   XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  4127.   formParent = XmCreateForm(scroller, "mailto_parent", av, ac);
  4128.   XtManageChild(formParent);
  4129.   XtAddCallback(drawingArea, XmNresizeCallback, resize, formParent);
  4130.   XtAddCallback(drawingArea, XmNexposeCallback, expose, formParent);
  4131.  
  4132.   *numkids = 0;
  4133.   form = (WidgetList)XtMalloc(sizeof(Widget)*(NUM+1));
  4134.  
  4135.   XtVaSetValues(pane, XmNseparatorOn, False, 0);
  4136.  
  4137.   for (i=0 ; i<NUM ; i++) {
  4138.     int flags = description[i].flags;
  4139.     ac = 0;
  4140.     form[i] = XmCreateForm(formParent, "mailto_field", av, ac);
  4141.     other[i] = NULL;
  4142.     if (flags & (ADDBROWSE)) {
  4143.       ac = 0;
  4144.  
  4145.       XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  4146.       XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  4147.       XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  4148.       other[i] = XmCreatePushButtonGadget(form[i], "browseButton", av, ac);
  4149.       XtAddCallback(other[i], XmNactivateCallback, fe_mailto_browse_cb,
  4150.             context);
  4151.     }
  4152.     ac = 0;
  4153.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  4154.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  4155.     XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  4156.     if (other[i]) {
  4157.       XtSetArg(av[ac], XmNrightAttachment, XmATTACH_WIDGET); ac++;
  4158.       XtSetArg(av[ac], XmNrightWidget, other[i]); ac++;
  4159.     } else {
  4160.       XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  4161.     }
  4162.     if (flags & ISLABEL) {
  4163.       XtSetArg(av[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++;
  4164.       widget[i] = XmCreateLabelGadget(form[i], description[i].name, av, ac);
  4165.     } else {
  4166.       XtSetArg(av[ac], XmNeditMode, XmMULTI_LINE_EDIT); ac++;
  4167.       XtSetArg(av[ac], XmNwordWrap, True); ac++;
  4168.       XtSetArg(av[ac], XmNcolumns, 30); ac++;
  4169.       XtSetArg(av[ac], XmNrows, 3); ac++;
  4170.       XtSetArg(av[ac], XmNresizeHeight, True); ac++;
  4171.       XtSetArg(av[ac], XmNresizeWidth, True); ac++;
  4172.       widget[i] = fe_CreateText(form[i], description[i].name, av, ac);
  4173.       XtAddCallback(widget[i], XmNvalueChangedCallback, fe_mc_field_changed,
  4174.             (XtPointer) description[i].msgtype);
  4175.       XtAddCallback(widget[i], XmNlosingFocusCallback, fe_mc_field_lostfocus,
  4176.             (XtPointer) description[i].msgtype);
  4177.     }
  4178.  
  4179.     *((Widget*) ((char*) data + description[i].offset)) = widget[i];
  4180.  
  4181.     ac = 0;
  4182.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  4183.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  4184.     XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  4185.     XtSetArg(av[ac], XmNrightAttachment, XmATTACH_WIDGET); ac++;
  4186.     XtSetArg(av[ac], XmNrightWidget, widget[i]); ac++;
  4187.     PR_snprintf(buf, sizeof (buf), "%sLabel", description[i].name);
  4188.     label[i] = XmCreateLabelGadget(form[i], buf, av, ac);
  4189.     if (maxwidth < XfeWidth(label[i])) {
  4190.       maxwidth = XfeWidth(label[i]);
  4191.     }
  4192.  
  4193.  
  4194.   }
  4195.   for (i=0 ; i<NUM ; i++) {
  4196.     XtVaSetValues(widget[i], XmNleftOffset, maxwidth, 0);
  4197.     kids[0] = label[i];
  4198.     kids[1] = widget[i];
  4199.     kids[2] = other[i];
  4200.     XtManageChildren(kids, other[i] ? 3 : 2);
  4201.    }
  4202.     XtVaSetValues(form[0],
  4203.                 XmNtopAttachment, XmATTACH_FORM,
  4204.                 XmNbottomAttachment, XmATTACH_NONE,
  4205.                 XmNleftAttachment, XmATTACH_FORM,
  4206.                 XmNrightAttachment, XmATTACH_FORM, 0);
  4207.   for (i=1 ; i<NUM ; i++) {
  4208.     XtVaSetValues(form[i],
  4209.                 XmNtopAttachment, XmATTACH_WIDGET,
  4210.                 XmNtopWidget, form[i-1],
  4211.                 XmNbottomAttachment, XmATTACH_NONE,
  4212.                 XmNleftAttachment, XmATTACH_FORM,
  4213.                 XmNrightAttachment, XmATTACH_FORM, 0);
  4214.   }
  4215. /*
  4216.     XtVaSetValues(form[i],
  4217.                   XmNpaneMinimum, XfeHeight(widget[i]),
  4218.                   XmNpaneMaximum, XfeHeight(widget[i]),
  4219.                   0);
  4220. */
  4221.  
  4222.   *numkids = NUM;
  4223.  
  4224.   return form;
  4225.   /* XtManageChild(form[NUM]); Unfortunately, this makes the window be too
  4226.      small. */
  4227.  
  4228. }
  4229.  
  4230.  
  4231. void
  4232. FE_MsgShowHeaders (MSG_Pane* comppane, MSG_HEADER_SET headers)
  4233. {
  4234.   MWContext* context = MSG_GetContext(comppane);
  4235.   fe_ContextData* data = CONTEXT_DATA(context);
  4236.   int i;
  4237.   int oncount = 0;
  4238.   int offcount = 0;
  4239.   Widget on[20];
  4240.   Widget off[20];
  4241.   XP_ASSERT(context->type == MWContextMessageComposition);
  4242.   for (i=0 ; i<NUM ; i++) {
  4243.     Widget widget = *((Widget*) ((char*) data + description[i].offset));
  4244.     Widget parent = XtParent(widget);
  4245.     if (headers & description[i].msgtype) {
  4246.       on[oncount++] = parent;
  4247.     } else {
  4248.       off[offcount++] = parent;
  4249.     }
  4250.   }
  4251.   if (offcount) XtUnmanageChildren(off, offcount);
  4252.   if (oncount) XtManageChildren(on, oncount);
  4253. }
  4254.  
  4255. #undef NUM
  4256. #undef ADDBROWSE
  4257. #undef ISLABEL
  4258. #undef Off
  4259.  
  4260. #endif  /* MOZ_MAIL_NEWS */
  4261.  
  4262. #ifdef JAVA
  4263.  
  4264. #include <Xm/Label.h>
  4265.  
  4266. /*
  4267. ** MOTIF. What else can you say?
  4268. */
  4269. Widget
  4270. FE_MakeAppletSecurityChrome(Widget parent, char* warning)
  4271. {
  4272.     Widget warningWindow, label, form, sep, skinnyDrawingArea;
  4273.     XmString cwarning;
  4274.     Arg av[20];
  4275.     Widget sec_logo = 0;
  4276.     int ac = 0;
  4277.     MWContext* someRandomContext = NULL;
  4278.     Colormap cmap;
  4279.     Pixel fg;
  4280.     Pixel bg;
  4281.  
  4282.     someRandomContext = XP_FindContextOfType(NULL, MWContextBrowser);
  4283.     if (!someRandomContext)
  4284.     someRandomContext = XP_FindContextOfType(NULL, MWContextMail);
  4285.     if (!someRandomContext)
  4286.     someRandomContext = XP_FindContextOfType(NULL, MWContextNews);
  4287.     if (!someRandomContext)
  4288.     someRandomContext = fe_all_MWContexts->context;
  4289.  
  4290.     cmap = fe_cmap(someRandomContext);
  4291.     fg = CONTEXT_DATA(someRandomContext)->fg_pixel;
  4292.     bg = CONTEXT_DATA(someRandomContext)->default_bg_pixel;
  4293.  
  4294.     ac = 0;
  4295.     XtSetArg(av[ac], XmNspacing, 0); ac++;
  4296.     XtSetArg(av[ac], XmNheight, 20); ac++;
  4297.     XtSetArg(av[ac], XmNmarginHeight, 0); ac++;
  4298.     XtSetArg(av[ac], XmNmarginWidth, 0); ac++;
  4299.     XtSetArg(av[ac], XmNcolormap, cmap); ac++;
  4300.     XtSetArg(av[ac], XmNforeground, fg); ac++;
  4301.     XtSetArg(av[ac], XmNbackground, bg); ac++;
  4302.     XtSetArg(av[ac], XmNresizable, False); ac++;
  4303.     warningWindow = XmCreateForm(parent, "javaWarning", av, ac);
  4304.  
  4305.     /* We make this widget to give the seperator something to seperate. */
  4306.     ac = 0;
  4307.     XtSetArg(av[ac], XmNheight, 1); ac++;
  4308.     XtSetArg(av[ac], XmNcolormap, cmap); ac++;
  4309.     XtSetArg(av[ac], XmNbackground, bg); ac++;
  4310.     XtSetArg(av[ac], XmNresizePolicy, XmRESIZE_NONE); ac++;
  4311.     skinnyDrawingArea = XmCreateDrawingArea(warningWindow, "javaDA", av, ac);
  4312.  
  4313.     ac = 0;
  4314.     sep = XmCreateSeparatorGadget(warningWindow, "javaSep", av, ac);
  4315.  
  4316.     ac = 0;
  4317.     XtSetArg(av[ac], XmNspacing, 0); ac++;
  4318.     XtSetArg(av[ac], XmNmarginHeight, 0); ac++;
  4319.     XtSetArg(av[ac], XmNmarginWidth, 0); ac++;
  4320.     XtSetArg(av[ac], XmNcolormap, cmap); ac++;
  4321.     XtSetArg(av[ac], XmNforeground, fg); ac++;
  4322.     XtSetArg(av[ac], XmNbackground, bg); ac++;
  4323.     XtSetArg(av[ac], XmNresizable, False); ac++;
  4324.     form = XmCreateForm(warningWindow, "javaForm", av, ac);
  4325.  
  4326.     cwarning = XmStringCreate (warning, XmFONTLIST_DEFAULT_TAG);
  4327.     ac = 0;
  4328.     XtSetArg(av[ac], XmNhighlightThickness, 0); ac++;
  4329.     XtSetArg(av[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++;
  4330.     XtSetArg(av[ac], XmNrecomputeSize, False); ac++;
  4331.     XtSetArg(av[ac], XmNcolormap, cmap); ac++;
  4332.     XtSetArg(av[ac], XmNforeground, fg); ac++;
  4333.     XtSetArg(av[ac], XmNbackground, bg); ac++;
  4334.     XtSetArg(av[ac], XmNlabelString, cwarning); ac++;
  4335.     label = XmCreateLabelGadget (form, "mouseDocumentation", av, ac);
  4336.     XmStringFree(cwarning);
  4337.  
  4338.     {
  4339.     Dimension w, h;
  4340.     Pixmap p = fe_SecurityPixmap(NULL, &w, &h, 0);
  4341.     ac = 0;
  4342.     XtSetArg(av[ac], XmNresizable, False); ac++;
  4343.     XtSetArg(av[ac], XmNlabelType, XmPIXMAP); ac++;
  4344.     XtSetArg(av[ac], XmNalignment, XmALIGNMENT_CENTER); ac++;
  4345.     XtSetArg(av[ac], XmNlabelPixmap, p); ac++;
  4346.     XtSetArg(av[ac], XmNwidth, w); ac++;
  4347.     XtSetArg(av[ac], XmNheight, h); ac++;
  4348.     XtSetArg(av[ac], XmNcolormap, cmap); ac++;
  4349.     XtSetArg (av [ac], XmNshadowThickness, 2); ac++;
  4350.     sec_logo = XmCreatePushButtonGadget (form, "javaSecLogo", av, ac);
  4351.     }
  4352.  
  4353.     /* Now that widgets have been created, do the form attachments */
  4354.     XtVaSetValues(skinnyDrawingArea,
  4355.           XmNtopAttachment, XmATTACH_FORM,
  4356.           XmNbottomAttachment, XmATTACH_NONE,
  4357.           XmNleftAttachment, XmATTACH_FORM,
  4358.           XmNrightAttachment, XmATTACH_FORM,
  4359.           0);
  4360.  
  4361.     XtVaSetValues(sep,
  4362.           XmNtopAttachment, XmATTACH_WIDGET,
  4363.           XmNtopWidget, skinnyDrawingArea,
  4364.           XmNbottomAttachment, XmATTACH_NONE,
  4365.           XmNleftAttachment, XmATTACH_FORM,
  4366.           XmNrightAttachment, XmATTACH_FORM,
  4367.           0);
  4368.  
  4369.     XtVaSetValues(form,
  4370.           XmNtopAttachment, XmATTACH_WIDGET,
  4371.           XmNtopWidget, sep,
  4372.           XmNbottomAttachment, XmATTACH_FORM,
  4373.           XmNleftAttachment, XmATTACH_FORM,
  4374.           XmNrightAttachment, XmATTACH_FORM,
  4375.           0);
  4376.  
  4377.     if (sec_logo) {
  4378.     XtVaSetValues(sec_logo,
  4379.               XmNtopAttachment, XmATTACH_FORM,
  4380.               XmNbottomAttachment, XmATTACH_FORM,
  4381.               XmNleftAttachment, XmATTACH_FORM,
  4382.               XmNleftOffset, 4,
  4383.               XmNrightAttachment, XmATTACH_NONE,
  4384.               0);
  4385.     }
  4386.  
  4387.     XtVaSetValues(label,
  4388.           XmNtopAttachment, XmATTACH_FORM,
  4389.           XmNbottomAttachment, XmATTACH_FORM,
  4390.           XmNleftAttachment, XmATTACH_WIDGET,
  4391.           XmNleftWidget, sec_logo,
  4392.           XmNrightAttachment, XmATTACH_FORM,
  4393.           0);
  4394.  
  4395.     XtManageChild(label);
  4396.     if (sec_logo)
  4397.     XtManageChild(sec_logo);
  4398.     XtManageChild(form);
  4399.     XtManageChild(sep);
  4400.     XtManageChild(skinnyDrawingArea);
  4401.     XtManageChild(warningWindow);
  4402.     return warningWindow;
  4403. }
  4404. #endif
  4405.  
  4406. /*
  4407.  * Sash Geometry is saved as
  4408.  *     <pane-config>: w x h [;<pane-config>:wxh]
  4409.  *           %d       %dx%d
  4410.  *    or
  4411.  *    w x h
  4412.  *    %dx%d
  4413.  * for each type of pane configuration we store the widths and heights
  4414.  */
  4415.  
  4416. static char *
  4417. fe_ParseSashGeometry(char *old_geom_str, int pane_config,
  4418.             unsigned int *w, unsigned int *h, Boolean find_mode_p)
  4419. {
  4420.     char *geom_str = old_geom_str;
  4421.     char buf[100], *s, *t;
  4422.     int n;
  4423.     int tmppane, tmpw, tmph;
  4424.  
  4425.     char new_geom_str[512];
  4426.     int len = 0;
  4427.  
  4428.     new_geom_str[0] = '\0';
  4429.  
  4430.     while (geom_str && *geom_str) {
  4431.  
  4432.     for (s=buf, t=geom_str; *t && *t != ';'; ) *s++=*t++;
  4433.     *s = '\0';
  4434.     if (*t == ';') t++;
  4435.     geom_str = t;
  4436.     /* At end of this:
  4437.      * geom_str - points to next section
  4438.      * buf - has copy of this section
  4439.      * t, s - tmp
  4440.      */
  4441.  
  4442.     for (s = buf; *s && *s != ':'; s++);
  4443.     if (*s == ':') {     /* New format */
  4444.         n = sscanf(buf,"%d:%dx%d", &tmppane, &tmpw, &tmph);
  4445.         if (n < 3) n = 0;
  4446.     }
  4447.     else {            /* Old format */
  4448.         n = sscanf(buf,"%dx%d", &tmpw, &tmph);
  4449.         if (n < 2) n = 0;
  4450.         tmppane = FE_PANES_NORMAL;
  4451.     }
  4452.     /* At the end of this:
  4453.      * n - '0' indicates badly formed section
  4454.      * tmppane, tmpw, tmph - if n > 0 indicate %d:%dx%d
  4455.      */
  4456.  
  4457.     if (find_mode_p && (n > 0) && tmppane == pane_config) {
  4458.         *w = tmpw;
  4459.         *h = tmph;
  4460.         return(old_geom_str);
  4461.     }
  4462.     if (n != 0 && tmppane != pane_config) {
  4463.         if (len != 0) {
  4464.         PR_snprintf(&new_geom_str[len], sizeof(new_geom_str)-len, ";");
  4465.         len++;
  4466.         }
  4467.         PR_snprintf(&new_geom_str[len], sizeof(new_geom_str)-len, 
  4468.                 "%d:%dx%d", tmppane, tmpw, tmph);
  4469.         len = strlen(new_geom_str);
  4470.     }
  4471.     }
  4472.     if (find_mode_p)
  4473.     return(NULL);
  4474.     else {
  4475.     if (*new_geom_str)
  4476.         s = PR_smprintf("%d:%dx%d;%s", pane_config, *w, *h, new_geom_str);
  4477.     else
  4478.         s = PR_smprintf("%d:%dx%d", pane_config, *w, *h);
  4479.     return(s);
  4480.     }
  4481. }
  4482.  
  4483. char *
  4484. fe_MakeSashGeometry(char *old_geom_str, int pane_config,
  4485.             unsigned int w, unsigned int h)
  4486. {
  4487.     char *new_geom_str =
  4488.     fe_ParseSashGeometry(old_geom_str, pane_config, &w, &h, False);
  4489.     return(new_geom_str);
  4490. }
  4491.  
  4492.  
  4493. void
  4494. fe_GetSashGeometry(char *geom_str, int pane_config,
  4495.             unsigned int *w, unsigned int *h)
  4496. {
  4497.     (void) fe_ParseSashGeometry(geom_str, pane_config, w, h, True);
  4498.     return;
  4499. }
  4500.  
  4501. extern XtPointer
  4502. fe_tooltip_mappee(Widget widget, XtPointer data)
  4503. {
  4504.     if (XtIsSubclass(widget, xmManagerWidgetClass)) 
  4505.     {
  4506.         if (XfeMenuIsOptionMenu(widget)
  4507.             ||
  4508.             XtIsSubclass(widget, xmDrawingAreaWidgetClass)
  4509.             ) 
  4510.         {
  4511.             fe_WidgetAddToolTips(widget);
  4512.         } 
  4513.         else if (fe_ManagerCheckGadgetToolTips(widget, NULL)) 
  4514.         {
  4515.             fe_ManagerAddGadgetToolTips(widget, NULL);
  4516.         }
  4517.     } 
  4518.     else if (XtIsSubclass(widget, xmPushButtonWidgetClass)
  4519.              ||
  4520.              XtIsSubclass(widget, xmToggleButtonWidgetClass)
  4521.              ||
  4522.              XtIsSubclass(widget, xmCascadeButtonWidgetClass)
  4523.              ||
  4524.              XtIsSubclass(widget, xfeButtonWidgetClass)
  4525.         ) 
  4526.     {
  4527.         fe_WidgetAddToolTips(widget);
  4528.     }
  4529.     
  4530.     return NULL;
  4531. }
  4532.  
  4533. #ifdef LEDGES
  4534. static void
  4535. fe_configure_ledges (MWContext *context, int top_p, int bot_p)
  4536. {
  4537.   Widget top_ledge = CONTEXT_DATA (context)->top_ledge;
  4538.   Widget bot_ledge = CONTEXT_DATA (context)->bottom_ledge;
  4539.   Widget k1[2], k2[2];
  4540.   int c1 = 0, c2 = 0;
  4541.  
  4542.   if (top_p)
  4543.     k1[c1++] = top_ledge;
  4544.   else
  4545.     k2[c2++] = top_ledge;
  4546.  
  4547.   if (bot_p)
  4548.     k1[c1++] = bot_ledge;
  4549.   else
  4550.     k2[c2++] = bot_ledge;
  4551.  
  4552.   if (c1) XtManageChildren (k1, c1);
  4553.   if (c2) XtUnmanageChildren (k2, c2);
  4554. }
  4555. #endif /* LEDGES */
  4556.  
  4557.  
  4558. void
  4559. fe_sec_logo_cb (Widget widget, XtPointer closure, XtPointer call_data)
  4560. {
  4561.   MWContext *context = (MWContext *) closure;
  4562.   SECNAV_SecurityAdvisor (context, SHIST_CreateURLStructFromHistoryEntry (context,
  4563.                    SHIST_GetCurrent (&context->hist)));
  4564. }
  4565.  
  4566. void
  4567. fe_AbortCallback (Widget widget, XtPointer closure, XtPointer call_data)
  4568. {
  4569.   MWContext *context = (MWContext *) closure;
  4570.   XP_InterruptContext (context);
  4571.  
  4572.   /* If we were downloading, cleanup the file we downloaded to. */
  4573.   if (context->type == MWContextSaveToDisk) {
  4574.     char *filename = fe_GetTextField (CONTEXT_DATA(context)->url_label);
  4575.     XP_FileRemove(filename, xpTemporary);
  4576.   }
  4577. }
  4578.  
  4579.  
  4580. #include <X11/Xmu/Error.h>
  4581. #include <X11/Xproto.h>
  4582.  
  4583. static int
  4584. x_fatal_error_handler(Display *dpy)
  4585. {
  4586.   fe_MinimalNoUICleanup();
  4587.   if (fe_pidlock) unlink (fe_pidlock);
  4588.   fe_pidlock = NULL;
  4589.  
  4590.   /* This function is not expected to return */
  4591.   exit(-1);
  4592. }
  4593.  
  4594. static int
  4595. x_error_handler (Display *dpy, XErrorEvent *event)
  4596. {
  4597.   /* For a couple of not-very-good reasons, we sometimes try to free color
  4598.      cells that we haven't allocated, so ignore BadAccess errors from
  4599.      XFreeColors().  (This only happens in low color situations when
  4600.      substitutions have been performed and something has gone wrong...)
  4601.    */
  4602.   if (event->error_code == BadAccess &&
  4603.       event->request_code == X_FreeColors)
  4604.     return 0;
  4605.  
  4606.   /* fvwm (a version of twm) tends to issue passive grabs
  4607.      on the right mouse button.  This will cause any Motif program to get a
  4608.      BadAccess when calling XmCreatePopupMenu(), and will cause it to be
  4609.      possible to have popup menus that are still up while no mouse button
  4610.      is depressed.  No doubt there's some arcane way to configure fvwm to
  4611.      not do this, but it's much easier to just punt on this particular error
  4612.      message.
  4613.    */
  4614.   if (event->error_code == BadAccess &&
  4615.       event->request_code == X_GrabButton)
  4616.     return 0;
  4617.  
  4618.   fprintf (real_stderr, "\n%s:\n", fe_progname);
  4619.   XmuPrintDefaultErrorMessage (dpy, event, real_stderr);
  4620.  
  4621. #ifndef DONT_PRINT_WIDGETS_IN_ERROR_HANDLER
  4622.   {
  4623.       Window window = event ? event->resourceid : None;
  4624.  
  4625.       if (window != None)
  4626.       {
  4627.           Widget guilty = XtWindowToWidget(dpy,window);
  4628.  
  4629.           fprintf(real_stderr,"  Widget hierarchy of resource: ");
  4630.  
  4631.           if (guilty)
  4632.           {
  4633.               while(guilty)
  4634.               {
  4635.                   fprintf(real_stderr,"%s",XtName(guilty));
  4636.  
  4637.                   guilty = XtParent(guilty);
  4638.  
  4639.                   if (guilty)
  4640.                   {
  4641.                       fprintf(real_stderr,".");
  4642.                   }
  4643.               }
  4644.           }
  4645.           else
  4646.           {
  4647.               fprintf(real_stderr,"unknown\n");
  4648.           }
  4649.  
  4650.           fprintf(real_stderr,"\n");
  4651.       }
  4652.   }
  4653. #endif
  4654.   return 0;
  4655. }
  4656.  
  4657. static void xt_warning_handler(String nameStr, String typeStr,
  4658.     String classStr, String defaultStr,
  4659.     String* params, Cardinal* num_params)
  4660. {
  4661.   /* Xt error handler to ignore colormap warnings */
  4662.   if (nameStr && *nameStr) {
  4663.     /* Ignore all colormap warnings */
  4664.     if (!strcmp(nameStr, "noColormap"))
  4665.       return;
  4666.   }
  4667.  
  4668.   (*old_xt_warning_handler)(nameStr, typeStr, classStr, defaultStr,
  4669.                params, num_params);
  4670. }
  4671.  
  4672. static void xt_warningOnly_handler(String msg)
  4673. {
  4674.   static char *ignore_me = NULL;
  4675.   int len = 0;
  4676.  
  4677.   if (!ignore_me) {
  4678.       ignore_me = XP_GetString(XFE_COLORMAP_WARNING_TO_IGNORE);
  4679.       if (ignore_me && *ignore_me)
  4680.       len = strlen(ignore_me);
  4681.   }
  4682.  
  4683.   /* Xt error handler to ignore colormap warnings */
  4684.   if (msg && *msg && len && strlen(msg) >= len &&
  4685.       !XP_STRNCASECMP(msg, ignore_me, len)) {
  4686.       /* Ignore all colormap warning messages */
  4687. #ifdef DEBUG_dp
  4688.       fprintf(stderr, "dp, I am ignoring \"%s\"\n", msg);
  4689. #endif /* DEBUG_dp */
  4690.     return;
  4691.   }
  4692.  
  4693.   if (old_xt_warningOnly_handler && *old_xt_warningOnly_handler)
  4694.       (*old_xt_warningOnly_handler)(msg);
  4695. }
  4696.  
  4697. static void
  4698. fe_read_screen_for_rng (Display *dpy, Screen *screen)
  4699. {
  4700.     XImage *image;
  4701.     size_t image_size;
  4702.     int32 coords[4];
  4703.     int x, y, w, h;
  4704.  
  4705.     assert (dpy && screen);
  4706.     if (!dpy || !screen) return;
  4707.  
  4708.     RNG_GenerateGlobalRandomBytes(coords,  sizeof(coords));
  4709.  
  4710.     x = coords[0] & 0xFFF;
  4711.     y = coords[1] & 0xFFF;
  4712.     w = (coords[2] & 0x7f) | 0x40; /* make sure w is in range [64..128) */
  4713.     h = (coords[3] & 0x7f) | 0x40; /* same for h */
  4714.  
  4715. #ifdef NSPR_SPLASH
  4716.     if (fe_globalData.show_splash)
  4717.       PR_XLock();
  4718. #endif
  4719.  
  4720.     x = (screen->width - w + x) % (screen->width - w);
  4721.     y = (screen->height - h + y) % (screen->height - h);
  4722.     image = XGetImage(dpy, screen->root, x, y, w, h, ~0, ZPixmap);
  4723.     if (!image) return;
  4724.     image_size = (image->width * image->height * image->bits_per_pixel) / 8;
  4725.     if (image->data)
  4726.     RNG_RandomUpdate(image->data, image_size);
  4727.     XDestroyImage(image);
  4728.  
  4729. #ifdef NSPR_SPLASH
  4730.     if (fe_globalData.show_splash)
  4731.       PR_XUnlock();
  4732. #endif
  4733. }
  4734.  
  4735. /*****************************
  4736.  * Context List manipulation *
  4737.  *****************************/
  4738.  
  4739. /* XFE maintains a list of all contexts that it created. This is different
  4740.    from that maintained by xp as that wouldnt have bookmark, addressbook etc.
  4741.    contexts. */
  4742.  
  4743. Boolean fe_contextIsValid( MWContext *context )
  4744. {
  4745.   struct fe_MWContext_cons *cons = fe_all_MWContexts;
  4746.   for (; cons && cons->context != context; cons = cons->next);
  4747.   return (cons != NULL);
  4748. }
  4749.  
  4750. void
  4751. fe_getVisualOfContext(MWContext *context, Visual **v_ptr, Colormap *cmap_ptr,
  4752.                 Cardinal *depth_ptr)
  4753. {
  4754.     Widget mainw = CONTEXT_WIDGET(context);
  4755.  
  4756.     while(!XtIsWMShell(mainw) && (XtParent(mainw)!=0))
  4757.     mainw = XtParent(mainw);
  4758.  
  4759.     XtVaGetValues (mainw,
  4760.             XtNvisual, v_ptr,
  4761.             XtNcolormap, cmap_ptr,
  4762.             XtNdepth, depth_ptr, 0);
  4763.  
  4764.     return;
  4765. }
  4766. /*******************************
  4767.  * Session Manager stuff  
  4768.  *******************************/
  4769. Boolean 
  4770. fe_add_session_manager(MWContext *context)
  4771. {
  4772.     Widget shell;
  4773.  
  4774.       if (context->type != MWContextBrowser &&
  4775.             context->type != MWContextMail &&
  4776.             context->type != MWContextNews) return False;
  4777.  
  4778.  
  4779.     someGlobalContext = context;
  4780.     shell  = CONTEXT_WIDGET(context);
  4781.  
  4782.       WM_SAVE_YOURSELF = XmInternAtom(XtDisplay(shell),
  4783.                 "WM_SAVE_YOURSELF", False);
  4784.         XmAddWMProtocols(shell,
  4785.                                 &WM_SAVE_YOURSELF,1);
  4786.         XmAddWMProtocolCallback(shell,
  4787.                 WM_SAVE_YOURSELF,
  4788.                 fe_wm_save_self_cb, someGlobalContext);
  4789.     return True;
  4790. }
  4791.  
  4792. void fe_wm_save_self_cb(Widget w, XtPointer clientData, XtPointer callData)
  4793. {
  4794.     Widget shell = w;
  4795.  
  4796.     if (save_argv[0])
  4797.       XP_FREE(save_argv[0]);
  4798.     save_argv[0]= 0;
  4799.  
  4800.     /*always use long name*/
  4801.     StrAllocCopy(save_argv[0], fe_progname_long);
  4802.  
  4803.     /* Has to register with a valid toplevel shell */
  4804.     XSetCommand(XtDisplay(shell),
  4805.                 XtWindow(shell), save_argv, save_argc);
  4806.  
  4807.     /* On sgi: we will get this every 15 mins. So dont ever exit here.
  4808.     ** The atexit handler fe_atexit_hander() will take care of removing
  4809.     ** the pid_lock file.
  4810.     */
  4811.     fe_MinimalNoUICleanup();
  4812. }
  4813.  
  4814. Boolean
  4815. fe_is_absolute_path(char *filename)
  4816. {
  4817.     if ( filename && *filename && filename[0] == '/')
  4818.         return True;
  4819.     return False;
  4820. }
  4821.  
  4822. Boolean
  4823. fe_is_working_dir(char *filename, char** progname)
  4824. {
  4825.    *progname = 0;
  4826.  
  4827.    if ( filename && *filename )
  4828.    {
  4829.     if ( (int)strlen(filename)>1 && 
  4830.            filename[0] == '.' && filename[1] == '/')
  4831.     {
  4832.           char *str;
  4833.           char *name;
  4834.  
  4835.       name = filename;
  4836.  
  4837.       str = strrchr(name, '/');
  4838.       if ( str ) name = str+1;
  4839.  
  4840.       *progname = (char*)malloc((strlen(name)+1)*sizeof(char));
  4841.       strcpy(*progname, name);
  4842.  
  4843.       return True;
  4844.     }
  4845.     else if (strchr(filename, '/'))
  4846.     {
  4847.       *progname = (char*)malloc((strlen(filename)+1)*sizeof(char));
  4848.       strcpy(*progname, filename);
  4849.       return True;
  4850.     }
  4851.     }
  4852.     return False;
  4853. }
  4854.  
  4855. Boolean 
  4856. fe_found_in_binpath(char* filename, char** dirfile)
  4857. {
  4858.     char *binpath = 0;
  4859.     char *dirpath = 0;
  4860.     struct stat buf;
  4861.  
  4862.     *dirfile = 0;
  4863.     binpath = getenv("PATH");
  4864.  
  4865.     if ( binpath )
  4866.     {
  4867.         binpath = XP_STRDUP(binpath);
  4868.     dirpath = XP_STRTOK(binpath, ":");
  4869.         while(dirpath)
  4870.         {
  4871.        if ( dirpath[strlen(dirpath)-1] == '/' )
  4872.            {
  4873.             dirpath[strlen(dirpath)-1] = '\0';
  4874.            }
  4875.  
  4876.        *dirfile = PR_smprintf("%s/%s", dirpath, filename);
  4877.  
  4878.         if ( !stat(*dirfile, &buf) )
  4879.            {
  4880.            XP_FREE(binpath);
  4881.         return True;
  4882.            }
  4883.        dirpath = XP_STRTOK(NULL,":");
  4884.        XP_FREE(*dirfile);
  4885.        *dirfile = 0;
  4886.         }
  4887.     XP_FREE(binpath);
  4888.     }
  4889.     return False;
  4890. }
  4891.  
  4892. char *
  4893. fe_expand_working_dir(char *cwdfile)
  4894. {
  4895.    char *dirfile = 0;
  4896.    char *string;
  4897. #if defined(SUNOS4)||defined(AIX)
  4898.    char path [MAXPATHLEN];
  4899. #endif
  4900.  
  4901. #if defined(SUNOS4)||defined(AIX)
  4902.    string = getwd (path);
  4903. #else
  4904.    string = getcwd(NULL, MAXPATHLEN);
  4905. #endif
  4906.  
  4907.    dirfile = (char *)malloc((strlen(string)+strlen("/")+strlen(cwdfile)+1) 
  4908.             *sizeof(char));
  4909.    strcpy(dirfile, string);
  4910.    strcat(dirfile,"/");
  4911.    strcat(dirfile, cwdfile);
  4912. #if !(defined(SUNOS4) || defined(AIX))
  4913.    XP_FREE(string);
  4914. #endif
  4915.    return dirfile;
  4916. }
  4917.  
  4918. /****************************************
  4919.  * This function will return either of these
  4920.  * type of the exe file path:
  4921.  * 1. return FULL Absolute path if user specifies a full path
  4922.  * 2. return FULL Absolute path if the program was found in user 
  4923.  *    current working dir 
  4924.  * 3. return relative path (ie. the same as it is in fe_progname)
  4925.  *    if program was found in binpath
  4926.  *
  4927.  ****************************************/
  4928. const char *
  4929. fe_locate_program_path(const char *fe_prog)
  4930. {
  4931.   char *ret_path = 0;
  4932.   char *dirfile = 0;
  4933.   char *progname = 0;
  4934.  
  4935.   StrAllocCopy(progname, fe_prog);
  4936.  
  4937.   if ( fe_is_absolute_path(progname) )
  4938.   {
  4939.     StrAllocCopy(ret_path, progname);
  4940.         XP_FREE(progname);
  4941.     return ret_path;
  4942.   }
  4943.   else if ( fe_is_working_dir(progname, &dirfile) )
  4944.   {
  4945.     ret_path = fe_expand_working_dir(dirfile);
  4946.         XP_FREE(dirfile);
  4947.         XP_FREE(progname);
  4948.         return ret_path;
  4949.   }
  4950.   else if ( fe_found_in_binpath(progname, &ret_path) )
  4951.   {
  4952.         if ( fe_is_absolute_path(ret_path) )
  4953.         {
  4954.        /* Found in the bin path; then return only the exe filename */
  4955.        /* Always use bin path as the search path for the file 
  4956.           for consecutive session*/
  4957.        XP_FREE(ret_path);
  4958.        ret_path = progname;
  4959.               XP_FREE(dirfile);
  4960.     }
  4961.     else if (fe_is_working_dir(ret_path, &dirfile) )
  4962.     {
  4963.         XP_FREE(ret_path);
  4964.         XP_FREE(progname);
  4965.         ret_path = fe_expand_working_dir(dirfile);
  4966.             XP_FREE(dirfile);
  4967.     }
  4968.     return ret_path;
  4969.   }
  4970.   else
  4971.   {
  4972.       XP_FREE(ret_path);
  4973.       XP_FREE(dirfile);
  4974.       XP_FREE(progname);
  4975.  
  4976.       fprintf(stderr,
  4977.               XP_GetString(XFE_MOZILLA_NOT_FOUND_IN_PATH),
  4978.               fe_progname);
  4979.     
  4980.       exit(-1);
  4981.   }
  4982. }
  4983.  
  4984. /****************************************
  4985.  * This function will return either of these
  4986.  * type of the file path:
  4987.  * 1. return FULL Absolute path if user specifies a full path
  4988.  * 2. return FULL Absolute path if the program was found in user 
  4989.  *    current working dir 
  4990.  * 3. return relative path (ie. the same as it is in fe_progname)
  4991.  *    if program was found in binpath
  4992.  * 4. return NULL if we cannot locate it
  4993.  ****************************************/
  4994. static char *
  4995. fe_locate_component_path(const char *fe_prog, char *comp_file)
  4996. {
  4997.   char *ret_path = 0;
  4998.   char *dirfile = 0;
  4999.   char *progname = 0;
  5000.   char  compname[1024];
  5001.   char *separator;
  5002.   char *moz_home = 0;
  5003.   struct stat buf;
  5004.  
  5005.   /* replace the program name with component name first */
  5006.   XP_STRCPY(compname, fe_prog);
  5007.   separator = XP_STRRCHR(compname, '/');
  5008.   if (separator) {
  5009.       XP_STRCPY(separator+1, comp_file);
  5010.   }
  5011.   else {
  5012.       XP_STRCPY(compname, comp_file);
  5013.   }
  5014.  
  5015.   StrAllocCopy(progname, compname);
  5016.  
  5017.   if ( fe_is_absolute_path(progname) ) {
  5018.       if (! stat(progname, &buf)) {
  5019.           StrAllocCopy(ret_path, progname);
  5020.           XP_FREE(progname);
  5021.           return ret_path;
  5022.       }
  5023.   }
  5024.   
  5025.   if ( fe_is_working_dir(progname, &dirfile) ) {
  5026.       ret_path = fe_expand_working_dir(dirfile);
  5027.       if (! stat(ret_path, &buf)) {
  5028.           XP_FREE(dirfile);
  5029.           XP_FREE(progname);
  5030.           return ret_path;
  5031.       }
  5032.   }
  5033.  
  5034.   /* Now see if we can find it in the bin path */
  5035.   if ( fe_found_in_binpath(comp_file, &ret_path) ) {
  5036.       if ( fe_is_absolute_path(ret_path) ) {
  5037.           /* Found in the bin path; then return only the exe filename */
  5038.           /* Always use bin path as the search path for the file 
  5039.              for consecutive session*/
  5040.           XP_FREE(progname);
  5041.           XP_FREE(dirfile);
  5042.           return ret_path;
  5043.       }
  5044.       else if (ret_path[0] == '.' && ret_path[1] == '/') { /* . relative */
  5045.           char* foo = fe_expand_working_dir(&ret_path[2]);
  5046.           XP_FREE(ret_path);
  5047.           ret_path = foo;
  5048.           XP_FREE(progname);
  5049.           XP_FREE(dirfile);
  5050.           return ret_path;
  5051.       }
  5052.   }
  5053.  
  5054.   /* Check $MOZILLA_HOME */
  5055.  
  5056.   moz_home  = getenv("MOZILLA_HOME");
  5057.  
  5058.   if (moz_home) {
  5059.       XP_SPRINTF(compname, "%s/%s", moz_home, comp_file);
  5060.       if (! stat(compname, &buf)) {
  5061.           StrAllocCopy(ret_path, compname);
  5062.           if (dirfile) XP_FREE(dirfile);
  5063.           if (progname) XP_FREE(progname);
  5064.           return ret_path;
  5065.       }
  5066.   }
  5067.  
  5068.   /* cannot find it */
  5069.  
  5070.   if (ret_path) XP_FREE(ret_path);
  5071.   if (dirfile) XP_FREE(dirfile);
  5072.   if (progname) XP_FREE(progname);
  5073.   return NULL;
  5074. }
  5075.  
  5076. /* Retrieve the first entry in the previous session's history list */
  5077. XP_Bool fe_ReadLastUserHistory(char **hist_entry_ptr)
  5078. {
  5079.     char *value;
  5080.     char  buffer[1024];
  5081.     char *hist_entry = 0;
  5082.     FILE *fp = fopen(fe_globalPrefs.user_history_file,"r");
  5083.  
  5084.     if ( !fp )
  5085.         return FALSE;
  5086.  
  5087.     if ( !fgets(buffer, 1024, fp) )
  5088.         *buffer = 0;
  5089.  
  5090.     while (fgets(buffer, 1024, fp )){
  5091.         value = XP_StripLine(buffer);
  5092.         if (strlen(value)==0 || *value == '#')
  5093.             continue;
  5094.         hist_entry = XP_STRDUP(value);
  5095.         break;
  5096.     }
  5097.     fclose(fp);
  5098.     *hist_entry_ptr = hist_entry;
  5099.  
  5100.     if (hist_entry)
  5101.         return TRUE;
  5102.     else
  5103.         return FALSE;
  5104. }
  5105.  
  5106. void fe_GetProgramDirectory(char *path, int len)
  5107. {
  5108.     char * separator;
  5109.     char * prog = 0;
  5110.  
  5111.     *path = '\0';
  5112.  
  5113.     if ( fe_is_absolute_path( (char*)fe_progname_long ) )
  5114.         strncpy (path, fe_progname_long, len);
  5115.     else
  5116.     {
  5117.         if ( fe_found_in_binpath((char*)fe_progname_long, &prog) )
  5118.         {
  5119.             strncpy (path, prog, len);
  5120.                XP_FREE (prog);
  5121.         }
  5122.     }
  5123.  
  5124.     if (( separator = XP_STRRCHR(path, '/') ))
  5125.         separator[1] = 0;
  5126.     return;
  5127. }
  5128.  
  5129. static void fe_InitPolarisComponents(char *prog_name)
  5130. {
  5131.     /* For now, just check if we can find the key file associated with
  5132.      * each Polaris component.
  5133.      */
  5134.  
  5135.     fe_calendar_path = fe_locate_component_path(prog_name, "nscal");
  5136.     fe_host_on_demand_path = fe_locate_component_path(prog_name, "3270/he3270en.htm");
  5137. }
  5138.  
  5139. static void fe_InitConference(char *prog_name)
  5140. {
  5141.     /* For now, just check if we can find the key file associated with
  5142.      * conference
  5143.      */
  5144.  
  5145.     fe_conference_path = fe_locate_component_path(prog_name, "nsconference");
  5146. }
  5147.  
  5148. XP_Bool fe_GetCommandLineDone(void)
  5149. {
  5150.     return fe_command_line_done;
  5151. }
  5152.  
  5153. int fe_GetSavedArgc(void)
  5154. {
  5155.     return save_argc;
  5156. }
  5157.  
  5158. char ** fe_GetSavedArgv(void)
  5159. {
  5160.     static int need_to_change_argv_0 = True;
  5161.  
  5162.     if (need_to_change_argv_0)
  5163.     {
  5164.         need_to_change_argv_0 = False;
  5165.         
  5166.         if (save_argv[0])
  5167.         {
  5168.             XP_FREE(save_argv[0]);
  5169.         }
  5170.         
  5171.         save_argv[0]= 0;
  5172.         
  5173.         /*always use long name*/
  5174.         StrAllocCopy(save_argv[0], fe_progname_long);
  5175.     }
  5176.  
  5177.     return save_argv;
  5178. }
  5179.  
  5180. /*
  5181.  * Make Async DNS optional at runtime.
  5182.  */
  5183. static XP_Bool _use_async_dns = True;
  5184.  
  5185. XP_Bool fe_UseAsyncDNS(void)
  5186. {
  5187.     return _use_async_dns;
  5188. }
  5189.  
  5190. static void fe_check_use_async_dns(void)
  5191. {
  5192.     char * c = getenv ("MOZILLA_NO_ASYNC_DNS");
  5193.     
  5194.     _use_async_dns = True;
  5195.  
  5196.     if (c && *c)
  5197.     {
  5198.         /* Just in case make sure the var is not [fF0] (for funky logic) */
  5199.         if (*c != 'f' && *c != 'F' && *c != '0')
  5200.         {
  5201.             _use_async_dns = False;
  5202.         }
  5203.     }
  5204. }
  5205.