mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-13 18:27:35 +00:00
58641ee9f5
Added glibc ifndefs to strdup declarations. Fixed problem with stderr under glibc 2.1. Patch submitted by Tom Rini <trini@kernel.crashing.org>.
1906 lines
46 KiB
C++
1906 lines
46 KiB
C++
/* $Id: qtmoz.cpp,v 1.6 1998/10/22 06:04:35 cls%seawood.org Exp $
|
|
*
|
|
* The contents of this file are subject to the Netscape Public License
|
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
* http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
* for the specific language governing rights and limitations under the
|
|
* NPL.
|
|
*
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. Portions
|
|
* created by Warwick Allison, Kalle Dalheimer, Eirik Eng, Matthias
|
|
* Ettrich, Arnt Gulbrandsen, Haavard Nord and Paul Olav Tvete are
|
|
* Copyright (C) 1998 Warwick Allison, Kalle Dalheimer, Eirik Eng,
|
|
* Matthias Ettrich, Arnt Gulbrandsen, Haavard Nord and Paul Olav
|
|
* Tvete. All Rights Reserved.
|
|
*/
|
|
|
|
// This is a kludge to get around the fact that DEBUG turns on internal QT
|
|
// debugging information that we do not want.
|
|
|
|
#ifndef DEBUG
|
|
#define debug_off
|
|
#endif
|
|
|
|
// Qt includes
|
|
#include <qapp.h>
|
|
#include <qsocknot.h>
|
|
#include <qmsgbox.h>
|
|
|
|
#ifdef debug_off
|
|
#undef DEBUG
|
|
#undef debug_off
|
|
#endif
|
|
|
|
#include "client.h"
|
|
#include "QtEventPusher.h"
|
|
#include "mainwindow.h"
|
|
#include "streaming.h"
|
|
|
|
#include "qtfe_err.h"
|
|
#include "plevent.h"
|
|
#include "xpgetstr.h"
|
|
#include "nf.h"
|
|
|
|
#include "name.h"
|
|
#include "xp.h"
|
|
#include "xp_help.h" /* for XP_NetHelp() */
|
|
//#include "xp_sec.h"
|
|
#include "ssl.h"
|
|
#include "np.h"
|
|
#include "secnav.h"
|
|
#include "secrng.h"
|
|
#include "private/prpriv.h" /* for PR_NewNamedMonitor */
|
|
|
|
#include "libimg.h" /* Image Library public API. */
|
|
|
|
#include "prefapi.h"
|
|
#include "hk_funcs.h"
|
|
|
|
#include "libmocha.h"
|
|
|
|
#include "prnetdb.h"
|
|
#include "plevent.h"
|
|
|
|
#if 0
|
|
#include "bkmks.h" /* for drag and drop in mail compose */
|
|
#endif
|
|
|
|
#include "NSReg.h"
|
|
|
|
#define XFE_RDF
|
|
#ifdef XFE_RDF
|
|
#include "rdf.h"
|
|
#endif
|
|
|
|
#if defined(XP_UNIX)
|
|
#include <signal.h>
|
|
#include <unistd.h>
|
|
#include <sys/time.h>
|
|
#include <sys/wait.h>
|
|
#include <netinet/in.h>
|
|
|
|
#include <X11/keysym.h>
|
|
|
|
#ifdef __sgi
|
|
# include <malloc.h>
|
|
#endif
|
|
|
|
#if defined(AIXV3) || defined(__osf__)
|
|
#include <sys/select.h>
|
|
#endif /* AIXV3 */
|
|
|
|
#include <arpa/inet.h> /* for inet_*() */
|
|
#include <netdb.h> /* for gethostbyname() */
|
|
#include <pwd.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/utsname.h>
|
|
#include <sys/errno.h>
|
|
#endif // XP_UNIX
|
|
|
|
#include <sys/types.h>
|
|
#include <fcntl.h>
|
|
|
|
|
|
#ifdef MOZILLA_GPROF
|
|
#include "gmon.h"
|
|
#endif
|
|
|
|
#ifndef _STDC_
|
|
#define _STDC_ 1
|
|
#define HACKED_STDC 1
|
|
#endif
|
|
|
|
#ifdef HACKED_STDC
|
|
#undef HACKED_STDC
|
|
#undef _STDC_
|
|
#endif
|
|
|
|
#if defined(_CC_MSVC_)
|
|
#include <direct.h>
|
|
#include <process.h>
|
|
#define getcwd _getcwd
|
|
#define mkdir _mkdir
|
|
#endif
|
|
|
|
#if defined(XP_WIN)
|
|
extern "C" char *NOT_NULL(const char *p)
|
|
{
|
|
ASSERT(p != 0 );
|
|
return (char*)p;
|
|
}
|
|
|
|
extern "C" void XP_AssertAtLine( char *fileName, int line )
|
|
{
|
|
#ifdef DEBUG
|
|
warning( "Assert failed in %s, line %d", fileName, line );
|
|
#endif
|
|
}
|
|
|
|
#endif
|
|
|
|
#if defined(XP_UNIX) && defined(SW_THREADS)
|
|
extern "C" int PR_XGetXtHackFD(void);
|
|
#endif
|
|
extern "C" Bool QTFE_Confirm(MWContext * context, const char * Msg);
|
|
|
|
/* This means "suppress the splash screen if there is was a URL specified
|
|
on the command line." With betas, we always want the splash screen to
|
|
be printed to make sure the user knows it's beta. */
|
|
#define NON_BETA
|
|
|
|
/* Allow a nethelp startup flag */
|
|
#define NETHELP_STARTUP_FLAG
|
|
|
|
const char *fe_progname_long;
|
|
const char *fe_progname;
|
|
const char *fe_progclass;
|
|
|
|
char *fe_pidlock = 0;
|
|
|
|
/* Polaris components */
|
|
char *fe_host_on_demand_path = 0;
|
|
|
|
#if defined(XP_WIN)
|
|
typedef int pid_t;
|
|
#endif
|
|
|
|
static int
|
|
fe_create_pidlock (const char *name, unsigned long *paddr, pid_t *ppid);
|
|
|
|
// forwards
|
|
static XP_Bool fe_ensure_config_dir_exists ();
|
|
static void registerConverters (void);
|
|
static const char * fe_locate_program_path(const char *fe_prog);
|
|
|
|
extern
|
|
MWContext *
|
|
fe_MakeWindow(QWidget* toplevel, MWContext *context_to_copy,
|
|
URL_Struct *url, char *window_name, MWContextType type,
|
|
bool skip_get_url);
|
|
|
|
XP_Bool fe_ReadLastUserHistory(char **hist_entry_ptr);
|
|
|
|
PRMonitor *fdset_lock;
|
|
extern "C" {
|
|
PRThread *mozilla_thread;
|
|
PREventQueue* mozilla_event_queue;
|
|
}
|
|
|
|
#if defined(NSPR) && defined(TOSHOK_FIXES_THE_SPLASH_SCREEN_HANGS)
|
|
#define NSPR_SPLASH
|
|
#endif
|
|
|
|
static void
|
|
usage (void)
|
|
{
|
|
fprintf (stderr, XP_GetString( QTFE_USAGE_MSG1 ), 0 + 4,
|
|
fe_progname);
|
|
|
|
#ifdef USE_NONSHARED_COLORMAPS
|
|
fprintf (stderr, XP_GetString( QTFE_USAGE_MSG2 ) );
|
|
#endif
|
|
|
|
fprintf (stderr, XP_GetString( QTFE_USAGE_MSG3 ) );
|
|
|
|
fprintf (stderr, XP_GetString( QTFE_USAGE_MSG5 ) );
|
|
}
|
|
|
|
#include <errno.h>
|
|
#if 0
|
|
#if defined(XP_UNIX)
|
|
#if !defined(__FreeBSD__) && !defined(LINUX_GLIBC_2)
|
|
#include <sys/errno.h>
|
|
extern char *sys_errlist[];
|
|
extern int sys_nerr;
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
void
|
|
fe_perror_2 (const char *message)
|
|
{
|
|
int e = errno;
|
|
char *es = 0;
|
|
char buf1 [2048];
|
|
char buf2 [512];
|
|
char *b = buf1;
|
|
if (e >= 0 && e < sys_nerr) {
|
|
es = sys_errlist [e];
|
|
} else {
|
|
PR_snprintf (buf2, sizeof (buf2), XP_GetString( QTFE_UNKNOWN_ERROR_CODE ),
|
|
errno);
|
|
es = buf2;
|
|
}
|
|
if (message)
|
|
PR_snprintf (buf1, sizeof (buf1), "%.900s\n%.900s", message, es);
|
|
else
|
|
b = buf2;
|
|
FE_Alert(0,b);
|
|
}
|
|
|
|
/*******************
|
|
* Signal handlers *
|
|
*******************/
|
|
void fe_sigchild_handler(int)
|
|
{
|
|
#if defined(XP_UNIX)
|
|
pid_t pid;
|
|
int status = 0;
|
|
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
|
|
#ifdef DEBUG_dp
|
|
fprintf(stderr, "fe_sigchild_handler: Reaped pid %d.\n", pid);
|
|
#endif
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/* Netlib re-enters itself sometimes, so this has to be a counter not a flag */
|
|
static int fe_netlib_hungry_p = 0;
|
|
|
|
void
|
|
XP_SetCallNetlibAllTheTime (MWContext * context)
|
|
{
|
|
fe_netlib_hungry_p++;
|
|
}
|
|
|
|
void
|
|
XP_ClearCallNetlibAllTheTime (MWContext * context)
|
|
{
|
|
--fe_netlib_hungry_p;
|
|
XP_ASSERT(fe_netlib_hungry_p >= 0);
|
|
}
|
|
|
|
static char *fe_accept_language = NULL;
|
|
|
|
void
|
|
fe_SetAcceptLanguage(char *new_accept_lang)
|
|
{
|
|
if (fe_accept_language)
|
|
XP_FREE(fe_accept_language);
|
|
|
|
fe_accept_language = new_accept_lang;
|
|
}
|
|
|
|
char *
|
|
FE_GetAcceptLanguage(void)
|
|
{
|
|
return fe_accept_language;
|
|
}
|
|
|
|
/* ******************************************* Windows ifdef */
|
|
|
|
#if defined(XP_WIN)
|
|
extern "C"
|
|
void FE_Trace( const char *s )
|
|
{
|
|
// QMessageBox::information( 0, "FE_Trace", s );
|
|
}
|
|
|
|
extern "C"
|
|
void FE_Print( const char *s )
|
|
{
|
|
// QMessageBox::information( 0, "FE_Print", s );
|
|
// debug("FE_Print called, no implementation");
|
|
}
|
|
|
|
extern "C"
|
|
void NPL_Init()
|
|
{
|
|
// QMessageBox::information( 0, "", "NPL_Init" );
|
|
}
|
|
|
|
extern "C"
|
|
void NPL_PreparePrint( MWContext *, SHIST_SavedData *)
|
|
{
|
|
}
|
|
|
|
|
|
extern "C" void
|
|
NPL_DeleteSessionData(MWContext*, void*)
|
|
{
|
|
}
|
|
|
|
extern "C" char*
|
|
NPL_FindPluginEnabledForType(const char*)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
extern "C" void
|
|
NPL_EmbedURLExit(URL_Struct *, int, MWContext *)
|
|
{
|
|
}
|
|
|
|
extern "C" void
|
|
NPL_SameElement(LO_EmbedStruct*)
|
|
{
|
|
}
|
|
|
|
extern "C" void
|
|
NPL_SetPluginWindow(void *)
|
|
{
|
|
}
|
|
|
|
extern "C" NPError
|
|
NPL_RefreshPluginList(XP_Bool)
|
|
{
|
|
return NPERR_NO_ERROR;
|
|
}
|
|
|
|
extern "C" NPBool
|
|
NPL_IteratePluginFiles(NPReference*, char**, char**, char**)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
extern "C" NPBool
|
|
NPL_IteratePluginTypes(NPReference*, NPReference, NPMIMEType*, char***,
|
|
char**, void**)
|
|
{
|
|
return (NPBool)FALSE;
|
|
}
|
|
|
|
void
|
|
NPL_URLExit(URL_Struct *, int, MWContext *)
|
|
{
|
|
}
|
|
|
|
extern XP_Bool
|
|
NPL_HandleURL(MWContext *, FO_Present_Types, URL_Struct *,
|
|
Net_GetUrlExitFunc *)
|
|
{
|
|
return (XP_Bool)FALSE;
|
|
}
|
|
|
|
|
|
extern "C"
|
|
void
|
|
NET_RegisterConverters (char *, char *)
|
|
{
|
|
}
|
|
|
|
extern "C"
|
|
void XL_TranslatePostscript(MWContext *, URL_Struct *, SHIST_SavedData *_data, PrintSetup *)
|
|
{
|
|
}
|
|
|
|
extern "C"
|
|
void XL_InitializePrintSetup(PrintSetup *)
|
|
{
|
|
}
|
|
|
|
extern "C" int
|
|
WFE_DoCompuserveAuthenticate(MWContext *, URL_Struct *, char * )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
extern "C" char *
|
|
WFE_BuildCompuserveAuthString(URL_Struct *)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
extern "C"
|
|
PRBool FE_IsNetscapeDefault()
|
|
{
|
|
// QMessageBox::information( 0, "", "FE_ISNETSCAPEDEFAULT" );
|
|
return PR_TRUE;
|
|
}
|
|
|
|
extern "C"
|
|
PRBool FE_MakeNetscapeDefault()
|
|
{
|
|
// QMessageBox::information( 0, "", "FE_MAKENETSCAPEDEFAULT" );
|
|
return PR_TRUE;
|
|
}
|
|
|
|
extern "C"
|
|
void FE_URLEcho(URL_Struct *, int, MWContext *)
|
|
{
|
|
// QMessageBox::information( 0, "", "FE_URLECHO" );
|
|
}
|
|
|
|
extern "C"
|
|
int32 FE_SystemRAM( void )
|
|
{
|
|
// QMessageBox::information( 0, "", "FE_SYSTEMRAM" );
|
|
return 640000;
|
|
}
|
|
|
|
extern "C"
|
|
int32 FE_SystemClockSpeed( void )
|
|
{
|
|
// QMessageBox::information( 0, "", "FE_SYSTEMCLOCKSPEED" );
|
|
return 8;
|
|
}
|
|
|
|
extern "C"
|
|
char *FE_SystemCPUInfo(void)
|
|
{
|
|
// QMessageBox::information( 0, "", "FE_SYSTEMCPUINFO" );
|
|
return "8088";
|
|
}
|
|
|
|
extern "C"
|
|
void FE_LoadUrl( char *, BOOL )
|
|
{
|
|
// QMessageBox::information( 0, "", "FE_LOADURL" );
|
|
// debug("FE_LoadUrl");
|
|
}
|
|
|
|
extern "C"
|
|
void FE_UrlChangedContext(URL_Struct *, MWContext *, MWContext *)
|
|
{
|
|
// QMessageBox::information( 0, "", "FE_URLCHANGEDCONTEXT" );
|
|
}
|
|
|
|
|
|
extern "C"
|
|
XP_Bool FE_UseExternalProtocolModule(MWContext *, FO_Present_Types,
|
|
URL_Struct *,
|
|
Net_GetUrlExitFunc *)
|
|
{
|
|
// QMessageBox::information( 0, "", "FE_USEEXTERNALPROTOCOLMODULE" );
|
|
return (XP_Bool)FALSE;
|
|
}
|
|
|
|
extern "C"
|
|
int32 FE_LPtoDPoint(MWContext *, int32 logicalPoint)
|
|
{
|
|
// QMessageBox::information( 0, "", "FE_LPTODPOINT" );
|
|
return logicalPoint;
|
|
}
|
|
|
|
extern "C"
|
|
void *FE_GetSingleByteTable(int16, int16, int)
|
|
{
|
|
// QMessageBox::information( 0, "", "FE_GETSINGLEBYTETABLE" );
|
|
return 0;
|
|
}
|
|
|
|
extern "C"
|
|
char *FE_LockTable(void **)
|
|
{
|
|
// QMessageBox::information( 0, "", "FE_LOCKTABLE" );
|
|
return 0;
|
|
}
|
|
|
|
extern "C"
|
|
void FE_FreeSingleByteTable(void **)
|
|
{
|
|
// QMessageBox::information( 0, "", "FE_FREESINGLEBYTETABLE" );
|
|
}
|
|
|
|
extern "C"
|
|
void FE_FinishedRelayout(MWContext *)
|
|
{
|
|
// QMessageBox::information( 0, "", "FE_FINISHEDRELAYOUT" );
|
|
}
|
|
|
|
extern "C"
|
|
void FE_DisplayDropTableFeedback(MWContext *, EDT_DragTableData *)
|
|
{
|
|
// QMessageBox::information( 0, "", "FE_DISPLAYDROPTABLEFEEDBACK" );
|
|
}
|
|
|
|
extern "C"
|
|
void FE_UpdateEnableStates(MWContext *)
|
|
{
|
|
// QMessageBox::information( 0, "", "FE_UPDATEENABLESTATES" );
|
|
}
|
|
|
|
static char fixFont[12] = "Courier New";
|
|
static char propFont[6] = "Arial";
|
|
|
|
extern "C" XP_Bool FE_CheckFormTextAttributes(MWContext *context,
|
|
LO_TextAttr *oldAttr, LO_TextAttr *newAttr, int32 type)
|
|
{
|
|
if (oldAttr && newAttr && !oldAttr->font_face) {
|
|
memcpy(newAttr,oldAttr, sizeof(LO_TextAttr));
|
|
// setup the text attribute here.
|
|
|
|
|
|
if (oldAttr->fontmask & LO_FONT_FIXED) {
|
|
newAttr->font_face = fixFont;
|
|
}
|
|
else {
|
|
if (newAttr->size > 1);
|
|
newAttr->size -=1;
|
|
newAttr->font_face = propFont;
|
|
}
|
|
newAttr->font_weight = 500; /* 100, 200, ... 900 */
|
|
newAttr->FE_Data = NULL; /* For the front end to store font IDs */
|
|
return TRUE;
|
|
}
|
|
else
|
|
return FALSE;
|
|
|
|
#if 0
|
|
QMessageBox::information( 0, "", "FE_CHECKFORMTEXTATTRIBUTES" );
|
|
return (XP_Bool)TRUE;
|
|
#endif
|
|
}
|
|
|
|
extern "C"
|
|
void BMFE_ChangingBookmarksFile()
|
|
{
|
|
}
|
|
|
|
extern "C"
|
|
void BMFE_ChangedBookmarksFile()
|
|
{
|
|
}
|
|
|
|
|
|
#endif // XP_WIN
|
|
/* ******************************************* Windows ifdef */
|
|
|
|
extern "C"
|
|
void FEU_StayingAlive()
|
|
{
|
|
// QMessageBox::information( 0, "", "FEU_STAYINGALIVE" );
|
|
}
|
|
|
|
extern "C" void FE_AlternateCompose(
|
|
char *, char *, char *, char *, char *,
|
|
char *, char *, char *,
|
|
char *, char *, char *,
|
|
char *, char *,
|
|
char *, char *, char *)
|
|
{
|
|
// QMessageBox::information( 0, "", "FE_ALTERNATECOMPOSE" );
|
|
}
|
|
|
|
|
|
static void
|
|
fe_fix_fds (void)
|
|
{
|
|
/* Bad Things Happen if stdin, stdout, and stderr have been closed
|
|
(as by the `sh' incantation "netscape 1>&- 2>&-"). I think what
|
|
happens is, the X connection gets allocated to one of these fds,
|
|
and then some random library writes to stderr, and the connection
|
|
gets hosed. I think this must be a general problem with X programs,
|
|
but I'm not sure. Anyway, cause them to be open to /dev/null if
|
|
they aren't closed. This must be done before any other files are
|
|
opened.
|
|
|
|
We do this by opening /dev/null three times, and then closing those
|
|
fds, *unless* any of them got allocated as #0, #1, or #2, in which
|
|
case we leave them open. Gag.
|
|
*/
|
|
#if defined(XP_UNIX)
|
|
int fd0 = open ("/dev/null", O_RDWR);
|
|
int fd1 = open ("/dev/null", O_RDWR);
|
|
int fd2 = open ("/dev/null", O_RDWR);
|
|
if (fd0 > 2U) close (fd0);
|
|
if (fd1 > 2U) close (fd1);
|
|
if (fd2 > 2U) close (fd2);
|
|
#endif
|
|
}
|
|
|
|
#if defined(XP_UNIX)
|
|
extern "C" char **environ;
|
|
#endif
|
|
|
|
static void
|
|
losePrivilege(void)
|
|
{
|
|
/* If we've been run as setuid or setgid to someone else (most likely root)
|
|
turn off the extra permissions. Nobody ought to be installing Mozilla
|
|
as setuid in the first place, but let's be extra special careful...
|
|
Someone might get stupid because of movemail or something.
|
|
*/
|
|
#if defined(XP_UNIX)
|
|
setgid (getgid ());
|
|
setuid (getuid ());
|
|
#endif
|
|
/* Is there anything special we should do if running as root?
|
|
Features we should disable...?
|
|
if (getuid () == 0) ...
|
|
*/
|
|
}
|
|
|
|
static char *fe_home_dir;
|
|
static char *fe_config_dir;
|
|
|
|
/*
|
|
* build_simple_user_agent_string
|
|
*/
|
|
static void
|
|
build_simple_user_agent_string(char *versionLocale)
|
|
{
|
|
char buf [1024];
|
|
int totlen;
|
|
|
|
if (XP_AppVersion) {
|
|
free((void *)XP_AppVersion);
|
|
XP_AppVersion = NULL;
|
|
}
|
|
|
|
/* SECNAV_Init must have a language string in XP_AppVersion.
|
|
* If missing, it is supplied here. This string is very short lived.
|
|
* After SECNAV_Init returns, build_user_agent_string() will build the
|
|
* string that is expected by existing servers.
|
|
*/
|
|
if (!versionLocale || !*versionLocale) {
|
|
versionLocale = " [en]"; /* default is english for SECNAV_Init() */
|
|
}
|
|
|
|
/* be safe about running past end of buf */
|
|
totlen = sizeof buf;
|
|
memset(buf, 0, totlen);
|
|
strncpy(buf, "fe_version", totlen - 1);
|
|
totlen -= strlen(buf);
|
|
strncat(buf, versionLocale, totlen - 1);
|
|
|
|
XP_AppVersion = strdup (buf);
|
|
/* if it fails, leave XP_AppVersion NULL */
|
|
}
|
|
|
|
extern const char fe_version[];
|
|
|
|
/*
|
|
* build_user_agent_string
|
|
*/
|
|
static void
|
|
build_user_agent_string(char *versionLocale)
|
|
{
|
|
char buf [1024];
|
|
|
|
#if defined(XP_UNIX)
|
|
struct utsname uts;
|
|
|
|
strcpy (buf, fe_version);
|
|
|
|
#ifdef GOLD
|
|
strcat(buf, "Gold");
|
|
#endif
|
|
|
|
if (versionLocale) {
|
|
strcat (buf, versionLocale);
|
|
}
|
|
|
|
strcat (buf, " (Qt; ");
|
|
#if defined(_WS_WIN_)
|
|
strcat (buf, "Windows; ");
|
|
#elif defined(_WS_X11_)
|
|
strcat (buf, "X11; ");
|
|
#endif
|
|
// strcat (buf, XP_SecurityVersion (FALSE));
|
|
strcat (buf, "; ");
|
|
|
|
if (uname (&uts) < 0) {
|
|
#if defined(__sun)
|
|
strcat (buf, "SunOS");
|
|
#elif defined(__NT__)
|
|
strcat (buf, "Windows NT");
|
|
#elif defined(_WS_WIN_)
|
|
strcat (buf, "Windows");
|
|
#elif defined(__sgi)
|
|
strcat (buf, "IRIX");
|
|
#elif defined(__FreeBSD__)
|
|
strcat (buf, "FreeBSD");
|
|
#elif defined(__386BSD__)
|
|
strcat (buf, "BSD/386");
|
|
#elif defined(__osf__)
|
|
strcat (buf, "OSF1");
|
|
#elif defined(AIXV3)
|
|
strcat (buf, "AIX");
|
|
#elif defined(_HPUX_SOURCE)
|
|
strcat (buf, "HP-UX");
|
|
#elif defined(__linux)
|
|
strcat (buf, "Linux");
|
|
#elif defined(_ATT4)
|
|
strcat (buf, "NCR/ATT");
|
|
#elif defined(__USLC__)
|
|
strcat (buf, "UNIX_SV");
|
|
#elif defined(sony)
|
|
strcat (buf, "NEWS-OS");
|
|
#elif defined(nec_ews)
|
|
strcat (buf, "NEC/EWS-UX/V");
|
|
#elif defined(SNI)
|
|
strcat (buf, "SINIX-N");
|
|
#else
|
|
ERROR!! run "uname -s" and put the result here.
|
|
#endif
|
|
strcat (buf,XP_GetString(QTFE_MOZILLA_UNAME_FAILED));
|
|
|
|
fprintf (stderr,
|
|
XP_GetString(QTFE_MOZILLA_UNAME_FAILED_CANT_DETERMINE_SYSTEM),
|
|
fe_progname);
|
|
} else {
|
|
char *s;
|
|
|
|
#if defined(_ATT4)
|
|
strcpy(uts.sysname,"NCR/ATT");
|
|
#endif /* NCR/ATT */
|
|
|
|
#if defined(nec_ews)
|
|
strcpy(uts.sysname,"NEC");
|
|
#endif /* NEC */
|
|
|
|
PR_snprintf (buf + strlen(buf), sizeof(buf) - strlen(buf),
|
|
#ifdef AIX
|
|
/* AIX uname is incompatible with the rest of the Unix world. */
|
|
"%.100s %.100s.%.100s", uts.sysname, uts.version, uts.release);
|
|
#else
|
|
"%.100s %.100s", uts.sysname, uts.release);
|
|
#endif
|
|
|
|
/* If uts.machine contains only hex digits, throw it away.
|
|
This is so that every single AIX machine in
|
|
the world doesn't generate a unique vendor ID string. */
|
|
s = uts.machine;
|
|
while (s && *s)
|
|
{
|
|
if (!isxdigit (*s))
|
|
break;
|
|
s++;
|
|
}
|
|
if (s && *s)
|
|
PR_snprintf (buf + strlen (buf), sizeof(buf)-strlen(buf),
|
|
" %.100s", uts.machine);
|
|
}
|
|
|
|
#ifndef MOZ_COMMUNICATOR_NAME
|
|
strcat (buf, "; Nav");
|
|
#endif
|
|
|
|
#elif defined(XP_WIN)
|
|
strcpy (buf, "fe_version (Windows; I; Windows/Qt; Nav" );
|
|
#endif
|
|
|
|
strcat (buf, ")");
|
|
|
|
#if defined(__sun) && !defined(__svr4__) /* compiled on SunOS 4.1.3 */
|
|
if (uts.release [0] == '5') {
|
|
fprintf (stderr,
|
|
XP_GetString(QTFE_MOZILLA_TRYING_TO_RUN_SUNOS_ON_SOLARIS),
|
|
fe_progname,
|
|
uts.release);
|
|
}
|
|
#endif /* 4.1.3 */
|
|
|
|
assert(strlen(buf) < sizeof buf);
|
|
if (strlen(buf) >= sizeof(buf)) abort(); /* stack already damaged */
|
|
|
|
if (XP_AppVersion) {
|
|
free((void *)XP_AppVersion);
|
|
XP_AppVersion = NULL;
|
|
}
|
|
XP_AppVersion = strdup (buf);
|
|
if (!XP_AppVersion) {
|
|
XP_AppVersion = "";
|
|
}
|
|
}
|
|
|
|
|
|
QtEventPusher::QtEventPusher(int fd)
|
|
{
|
|
QSocketNotifier* sn = new QSocketNotifier( fd, QSocketNotifier::Read, this );
|
|
QObject::connect( sn, SIGNAL(activated(int)), this, SLOT(push(int)));
|
|
}
|
|
void QtEventPusher::push(int fd)
|
|
{
|
|
debug( "Push %i", fd );
|
|
PR_ProcessPendingEvents(mozilla_event_queue);
|
|
NET_ProcessNet(0,NET_EVERYTIME_TYPE);
|
|
NET_PollSockets();
|
|
}
|
|
|
|
|
|
|
|
|
|
/* fe_MimimalNoUICleanup
|
|
*
|
|
* This does a cleanup of the only the absolute essential stuff.
|
|
* - saves bookmarks, addressbook
|
|
* - saves global history
|
|
* - saves cookies
|
|
* (since all these saves are protected by flags anyway, we wont endup saving
|
|
* again if all these happened before.)
|
|
* - remove lock file if existent
|
|
*
|
|
|
|
this is installed as a qt post-routine.
|
|
|
|
*/
|
|
static void
|
|
minimalNoUICleanup()
|
|
{
|
|
if (fe_pidlock) unlink (fe_pidlock);
|
|
fe_pidlock = NULL;
|
|
|
|
//fe_SaveBookmarks ();
|
|
|
|
PREF_SavePrefFile();
|
|
NR_ShutdownRegistry();
|
|
|
|
RDF_Shutdown();
|
|
GH_SaveGlobalHistory ();
|
|
NET_SaveCookies(NULL);
|
|
//AltMailExit();
|
|
}
|
|
|
|
|
|
static const int hist_buflen = 1024;
|
|
static char hist_buffer[hist_buflen];
|
|
|
|
void
|
|
mozilla_main(int argc, char** argv)
|
|
{
|
|
int i;
|
|
#if defined(XP_UNIX)
|
|
struct sigaction act;
|
|
#endif
|
|
|
|
char *s;
|
|
|
|
char versionLocale[32];
|
|
|
|
versionLocale[0] = 0;
|
|
|
|
fe_progname = argv [0];
|
|
s = XP_STRRCHR (fe_progname, '/');
|
|
if (s) fe_progname = s + 1;
|
|
|
|
losePrivilege(); /* Do this real early */
|
|
|
|
#ifdef MOZILLA_GPROF
|
|
/*
|
|
* Do this early, but after the async DNS process has spawned.
|
|
*/
|
|
gmon_init(); /* initialize, maybe start, profiling */
|
|
#endif /*MOZILLA_GPROF*/
|
|
|
|
/*
|
|
** Initialize the runtime, preparing for multi-threading. Make mozilla
|
|
** a higher priority than any java applet. Java's priority range is
|
|
** 1-10, and we're mapping that to 11-20 (in sysThreadSetPriority).
|
|
*/
|
|
#if defined(XP_UNIX) && !defined(NDEBUG)
|
|
extern PRLogModuleInfo* NETLIB;
|
|
NETLIB = PR_NewLogModule("netlib");
|
|
#endif
|
|
|
|
PR_SetThreadGCAble();
|
|
PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_LAST);
|
|
PR_BlockClockInterrupts();
|
|
|
|
#if defined(XP_UNIX)
|
|
PR_XLock();
|
|
#endif
|
|
mozilla_thread = PR_CurrentThread();
|
|
fdset_lock = PR_NewNamedMonitor("mozilla-fdset-lock");
|
|
|
|
/*
|
|
** Create a pipe used to wakeup mozilla from select. A problem we had
|
|
** to solve is the case where a non-mozilla thread uses the netlib to
|
|
** fetch a file. Because the netlib operates by updating mozilla's
|
|
** select set, and because mozilla might be in the middle of select
|
|
** when the update occurs, sometimes mozilla never wakes up (i.e. it
|
|
** looks hung). Because of this problem we create a pipe and when a
|
|
** non-mozilla thread wants to wakeup mozilla we write a byte to the
|
|
** pipe.
|
|
*/
|
|
mozilla_event_queue = PR_CreateEventQueue("mozilla-event-queue", mozilla_thread);
|
|
|
|
if (mozilla_event_queue == NULL) {
|
|
fprintf(stderr,
|
|
XP_GetString(QTFE_MOZILLA_FAILED_TO_INITIALIZE_EVENT_QUEUE),
|
|
fe_progname);
|
|
exit(-1);
|
|
}
|
|
|
|
fe_fix_fds ();
|
|
|
|
#ifdef MEMORY_DEBUG
|
|
#ifdef __sgi
|
|
mallopt (M_DEBUG, 1);
|
|
mallopt (M_CLRONFREE, 0xDEADBEEF);
|
|
#endif
|
|
#endif
|
|
|
|
#if defined(XP_UNIX) && defined(DEBUG)
|
|
XP_StatStruct stat_struct;
|
|
|
|
extern int il_debug;
|
|
if(getenv("ILD"))
|
|
il_debug=atoi(getenv("ILD"));
|
|
|
|
if(stat(".WWWtraceon", &stat_struct) != -1)
|
|
MKLib_trace_flag = 2;
|
|
#endif
|
|
|
|
/* user agent stuff used to be here */
|
|
fe_progclass = QTFE_PROGCLASS_STRING;
|
|
XP_AppName = (char *)fe_progclass;
|
|
XP_AppCodeName = "Mozilla";
|
|
|
|
#if defined(XP_WIN)
|
|
#define OSTYPE "WIN32"
|
|
#endif
|
|
/* OSTYPE is defined by the build environment (config.mk) */
|
|
XP_AppPlatform = OSTYPE;
|
|
|
|
/* Hack the -help and -version arguments before opening the display. */
|
|
for (i = 1; i < argc; i++) {
|
|
if (!XP_STRCASECMP(argv [i], "-h") ||
|
|
!XP_STRCASECMP(argv [i], "-help") ||
|
|
!XP_STRCASECMP(argv [i], "--help"))
|
|
{
|
|
usage ();
|
|
exit (0);
|
|
}
|
|
/* because of stand alone java, we need not support -java. sudu/warren */
|
|
#ifdef JAVA
|
|
#ifdef JAVA_COMMAND_LINE_SUPPORT
|
|
/*
|
|
* -java will not be supported once it has been replaced by stand alone java
|
|
* this ifdef remains in case someone needs it and should be removed once
|
|
* stand alone java is in the mainstream sudu/warren
|
|
*/
|
|
|
|
else if (!XP_STRCASECMP(argv [i], "-java") ||
|
|
!XP_STRCASECMP(argv [i], "--java"))
|
|
{
|
|
extern int start_java(int argc, char **argv);
|
|
start_java(argc-i, &argv[i]);
|
|
exit (0);
|
|
}
|
|
#endif /* JAVA_COMMAND_LINE_SUPPORT */
|
|
#endif
|
|
else if (!XP_STRCASECMP(argv [i], "-v") ||
|
|
!XP_STRCASECMP(argv [i], "-version") ||
|
|
!XP_STRCASECMP(argv [i], "--version"))
|
|
{
|
|
fprintf (stderr, "Qt scape\n");
|
|
exit (0);
|
|
}
|
|
else if (!XP_STRCASECMP(argv [i], "-netcaster") ||
|
|
!XP_STRCASECMP(argv [i], "--netcaster")
|
|
)
|
|
{
|
|
char *r = argv [i];
|
|
if (r[0] == '-' && r[1] == '-')
|
|
r++;
|
|
}
|
|
}
|
|
|
|
#if defined(__sun)
|
|
/* The nightmare which is XKeysymDB is unrelenting. */
|
|
/* It'd be nice to check the existence of the osf keysyms here
|
|
to know whether we're screwed yet, but we must set $XKEYSYMDB
|
|
before initializing the connection; and we can't query the
|
|
keysym DB until after initializing the connection. */
|
|
char *override = getenv ("XKEYSYMDB");
|
|
struct stat st;
|
|
if (override && !stat (override, &st))
|
|
{
|
|
/* They set it, and it exists. Good. */
|
|
} else {
|
|
char *try1 = "/usr/lib/X11/XKeysymDB";
|
|
char *try2 = "/usr/openwin/lib/XKeysymDB";
|
|
char *try3 = "/usr/openwin/lib/X11/XKeysymDB";
|
|
char buf [1024];
|
|
if (override) {
|
|
fprintf (stderr,
|
|
XP_GetString(QTFE_MOZILLA_XKEYSYMDB_SET_BUT_DOESNT_EXIST),
|
|
argv [0], override);
|
|
}
|
|
|
|
if (!stat (try1, &st)) {
|
|
PR_snprintf (buf, sizeof (buf), "XKEYSYMDB=%.900s", try1);
|
|
putenv (buf);
|
|
} else if (!stat (try2, &st)) {
|
|
PR_snprintf (buf, sizeof (buf), "XKEYSYMDB=%.900s", try2);
|
|
putenv (buf);
|
|
} else if (!stat (try3, &st)) {
|
|
PR_snprintf (buf, sizeof (buf), "XKEYSYMDB=%.900s", try3);
|
|
putenv (buf);
|
|
} else {
|
|
fprintf (stderr,
|
|
XP_GetString(QTFE_MOZILLA_NO_XKEYSYMDB_FILE_FOUND),
|
|
argv [0], try1, try2, try3);
|
|
}
|
|
}
|
|
#endif /* sun */
|
|
|
|
/* Must do this early now so that mail can load directories */
|
|
/* Setting fe_home_dir likewise must happen early. */
|
|
|
|
char buf [1024];
|
|
#if defined(XP_WIN)
|
|
PREF_Init("c:/qtmoz/preferences.js");
|
|
fe_home_dir = "c:/qtmoz";
|
|
#else
|
|
fe_home_dir = getenv ("HOME");
|
|
if (!fe_home_dir || !*fe_home_dir)
|
|
{
|
|
/* Default to "/" in case a root shell is running in dire straits. */
|
|
struct passwd *pw = getpwuid(getuid());
|
|
|
|
fe_home_dir = pw ? pw->pw_dir : "/";
|
|
} else {
|
|
char *slash;
|
|
|
|
/* Trim trailing slashes just to be fussy. */
|
|
while ((slash = strrchr(fe_home_dir, '/')) && slash[1] == '\0')
|
|
*slash = '\0';
|
|
}
|
|
|
|
PR_snprintf (buf, sizeof (buf), "%s/%s", fe_home_dir,
|
|
MOZ_USER_DIR "/preferences.js");
|
|
PREF_Init((char*)buf);
|
|
#endif // XP_WIN
|
|
|
|
#if defined(XP_WIN)
|
|
fe_progname_long = argv[0]; /* Qt knows where the program is */
|
|
#else
|
|
fe_progname_long = fe_locate_program_path (argv [0]);
|
|
#endif
|
|
|
|
PR_UnblockClockInterrupts();
|
|
|
|
int fd;
|
|
|
|
/*
|
|
* We would like to yield the X lock to other (Java) threads when
|
|
* the Mozilla thread calls select(), but we should only do so
|
|
* when Qt calls select from its main event loop. (There are other
|
|
* times when select is called, e.g. from within Xlib. At these
|
|
* times, it is not safe to release the X lock.) Within select,
|
|
* we detect that the caller is Qt by looking at the file
|
|
* descriptors. If one of them is this special unused FD that we
|
|
* are adding here, then we know that Qt is calling us, so it is
|
|
* safe to release the X lock. -- erik
|
|
*/
|
|
#if defined(XP_UNIX) && defined(SW_THREADS)
|
|
if ( (fd = PR_XGetXtHackFD()) >= 0 )
|
|
new QSocketNotifier( fd, QSocketNotifier::Read, qApp );
|
|
#endif
|
|
if ( (fd = PR_GetEventQueueSelectFD(mozilla_event_queue)) >= 0 )
|
|
new QtEventPusher(fd);
|
|
|
|
/* Things blow up if argv[0] has a "." in it. */
|
|
s = (char *) fe_progname;
|
|
while ((s = strchr (s, '.')))
|
|
*s = '_';
|
|
|
|
/* Hack remaining arguments - assume things beginning with "-" are
|
|
* misspelled switches, instead of file names. Magic for -help and
|
|
* -version has already happened.
|
|
*/
|
|
for (i = 1; i < argc; i++)
|
|
if (*argv [i] == '-') {
|
|
fprintf (stderr, XP_GetString( QTFE_UNRECOGNISED_OPTION ),
|
|
fe_progname, argv [i]);
|
|
usage ();
|
|
exit (-1);
|
|
}
|
|
|
|
/* See if another instance is running. If so, don't use the .db files */
|
|
if (fe_ensure_config_dir_exists ())
|
|
{
|
|
char *name;
|
|
unsigned long addr;
|
|
pid_t pid;
|
|
|
|
name = PR_smprintf ("%s/lock", fe_config_dir);
|
|
addr = 0;
|
|
pid = 0;
|
|
if (name == NULL)
|
|
/* out of memory -- what to do? */;
|
|
else if (fe_create_pidlock (name, &addr, &pid) == 0) {
|
|
/* Remember name in fe_pidlock so we can unlink it on exit. */
|
|
fe_pidlock = name;
|
|
} else {
|
|
char *fmt = NULL;
|
|
char *lock = name ? name : MOZ_USER_DIR "/lock";
|
|
|
|
fmt = PR_sprintf_append(fmt, XP_GetString(QTFE_APP_HAS_DETECTED_LOCK),
|
|
XP_AppName, lock);
|
|
fmt = PR_sprintf_append(fmt,
|
|
XP_GetString(QTFE_ANOTHER_USER_IS_RUNNING_APP),
|
|
XP_AppName,
|
|
fe_config_dir);
|
|
|
|
if (addr != 0 && pid != 0) {
|
|
struct in_addr inaddr;
|
|
PRHostEnt *hp, hpbuf;
|
|
char dbbuf[PR_NETDB_BUF_SIZE];
|
|
const char *host;
|
|
|
|
inaddr.s_addr = addr;
|
|
|
|
PRStatus sts;
|
|
PRNetAddr pr_addr;
|
|
|
|
pr_addr.inet.family = AF_INET;
|
|
pr_addr.inet.ip = addr;
|
|
sts = PR_GetHostByAddr(&pr_addr,dbbuf, sizeof(dbbuf), &hpbuf);
|
|
if (sts == PR_FAILURE)
|
|
hp = NULL;
|
|
else
|
|
hp = &hpbuf;
|
|
host = (hp == NULL) ? inet_ntoa(inaddr) : hp->h_name;
|
|
fmt = PR_sprintf_append(fmt,
|
|
XP_GetString(QTFE_APPEARS_TO_BE_RUNNING_ON_HOST_UNDER_PID),
|
|
host, (unsigned)pid);
|
|
}
|
|
|
|
fmt = PR_sprintf_append(fmt,
|
|
XP_GetString(QTFE_YOU_MAY_CONTINUE_TO_USE),
|
|
XP_AppName);
|
|
fmt = PR_sprintf_append(fmt,
|
|
XP_GetString(QTFE_OTHERWISE_CHOOSE_CANCEL),
|
|
XP_AppName, lock, XP_AppName);
|
|
|
|
if (fmt) {
|
|
if (!QTFE_Confirm(0,fmt))
|
|
exit (0);
|
|
free (fmt);
|
|
}
|
|
if (name) free (name);
|
|
|
|
/* Keep on-disk databases from being open-able. */
|
|
dbSetOrClearDBLock (LockOutDatabase);
|
|
}
|
|
}
|
|
|
|
#if defined(XP_UNIX)
|
|
/* Install the default signal handlers */
|
|
act.sa_handler = fe_sigchild_handler;
|
|
act.sa_flags = 0;
|
|
sigfillset(&act.sa_mask);
|
|
sigaction (SIGCHLD, &act, NULL);
|
|
#endif
|
|
|
|
/* New XP-prefs routine. */
|
|
SECNAV_InitConfigObject();
|
|
|
|
PR_snprintf (buf, sizeof (buf), "%s/%s", fe_home_dir, MOZ_USER_DIR "/user.js");
|
|
PREF_ReadUserJSFile(buf);
|
|
PR_snprintf (buf, sizeof (buf), "%s/%s", fe_home_dir, MOZ_USER_DIR "/hook.js");
|
|
HK_ReadHookFile(buf);
|
|
|
|
/*fe_globalPrefs.global_history_expiration*/
|
|
GH_SetGlobalHistoryTimeout (14 * 24 * 60 * 60);
|
|
|
|
NR_StartupRegistry();
|
|
|
|
/* this must be before InstallPreferences(),
|
|
and after fe_InitializeGlobalResources(). */
|
|
registerConverters ();
|
|
|
|
#ifdef SAVE_ALL
|
|
SAVE_Initialize (); /* Register some more converters. */
|
|
#endif /* SAVE_ALL */
|
|
|
|
#if defined(XP_WIN)
|
|
fe_config_dir = "c:/qtmoz";
|
|
mkdir("c:/qtmoz");
|
|
#endif
|
|
PREF_SetDefaultCharPref("profile.name", "hackers@troll.no");
|
|
PREF_SetDefaultCharPref("profile.directory", fe_config_dir);
|
|
PREF_SetDefaultIntPref("profile.numprofiles", 1);
|
|
|
|
|
|
/* SECNAV_INIT needs this defined, but build_user_agent_string cannot
|
|
* be called until after SECNAV_INIT, so call this simplified version.
|
|
*/
|
|
build_simple_user_agent_string(versionLocale);
|
|
|
|
// Init global history database
|
|
PREF_GetCharPref("browser.history_file", hist_buffer, &hist_buflen);
|
|
FE_GlobalHist = hist_buffer;
|
|
GH_InitGlobalHistory();
|
|
|
|
/*
|
|
** Initialize the security library.
|
|
**
|
|
** MAKE SURE THIS IS DONE BEFORE YOU CALL THE NET_InitNetLib, CUZ
|
|
** OTHERWISE THE FILE LOCK ON THE HISTORY DB IS LOST!
|
|
*/
|
|
SECNAV_Init();
|
|
|
|
/* Must be called after ekit, since user agent is configurable */
|
|
/* Must also be called after SECNAV_Init, since crypto is dynamic */
|
|
build_user_agent_string(versionLocale);
|
|
|
|
RNG_SystemInfoForRNG ();
|
|
SECNAV_RunInitialSecConfig();
|
|
|
|
/* Initialize the network library. */
|
|
/* The unit for tcp buffer size is changed from ktypes to btyes */
|
|
NET_InitNetLib (8192, 50);
|
|
|
|
|
|
/* Initialize the Image Library */
|
|
IL_Init();
|
|
|
|
/* Initialize libmocha after netlib and before plugins. */
|
|
LM_InitMocha ();
|
|
|
|
|
|
#ifdef XFE_RDF
|
|
/* Initialize RDF */
|
|
{
|
|
RDF_InitParamsStruct rdf_params;
|
|
char *buf = 0;
|
|
rdf_params.profileURL
|
|
= XP_PlatformFileToURL(fe_config_dir);
|
|
|
|
if (PREF_CopyCharPref( "browser.bookmark_file", &buf ) == PREF_OK )
|
|
rdf_params.bookmarksURL = XP_PlatformFileToURL(buf);
|
|
|
|
rdf_params.globalHistoryURL
|
|
= XP_PlatformFileToURL(hist_buffer);
|
|
|
|
RDF_Init(&rdf_params);
|
|
|
|
XP_FREEIF(rdf_params.profileURL);
|
|
XP_FREEIF(rdf_params.bookmarksURL);
|
|
XP_FREEIF(rdf_params.globalHistoryURL);
|
|
free(buf);
|
|
}
|
|
#endif /*XFE_RDF*/
|
|
|
|
NPL_Init();
|
|
|
|
/* At this point, everything in argv[] is a document for us to display.
|
|
Create a window for each document.
|
|
*/
|
|
if (argc > 1) {
|
|
for (i = 1; i < argc; i++) {
|
|
char buf [2048];
|
|
if (argv [i][0] == '/') {
|
|
/* It begins with a / so it's a file. */
|
|
URL_Struct *url;
|
|
|
|
PR_snprintf (buf, sizeof (buf), "file:%.900s", argv [i]);
|
|
url = NET_CreateURLStruct (buf, NET_DONT_RELOAD);
|
|
|
|
FE_MakeNewWindow (0, url, NULL, 0);
|
|
} else {
|
|
PRHostEnt hpbuf;
|
|
char dbbuf[PR_NETDB_BUF_SIZE];
|
|
char *s = argv [i];
|
|
|
|
while (*s && *s != ':' && *s != '/')
|
|
s++;
|
|
|
|
if (*s == ':' || (PR_GetHostByName (argv [i], dbbuf, sizeof(dbbuf), &hpbuf) == PR_SUCCESS)) {
|
|
/* There is a : before the first / so it's a URL.
|
|
Or it is a host name, which are also magically URLs. */
|
|
URL_Struct *url = NET_CreateURLStruct (argv [i], NET_DONT_RELOAD);
|
|
FE_MakeNewWindow (0, url, NULL, 0);
|
|
} else {
|
|
/* There is a / or end-of-string before so it's a file. */
|
|
char cwd [1024];
|
|
URL_Struct *url;
|
|
#ifdef SUNOS4
|
|
if (! getwd (cwd))
|
|
#else
|
|
if (! getcwd (cwd, sizeof cwd))
|
|
#endif
|
|
{
|
|
fprintf (stderr, "%s: getwd: %s\n", fe_progname, cwd);
|
|
break;
|
|
}
|
|
PR_snprintf (buf, sizeof (buf),
|
|
"file:%.900s/%.900s", cwd, argv [i]);
|
|
url = NET_CreateURLStruct (buf, NET_DONT_RELOAD);
|
|
FE_MakeNewWindow (0, url, NULL, 0);
|
|
}
|
|
}
|
|
} /* end for */
|
|
} else {
|
|
FE_MakeNewWindow (0, 0, NULL, 0);
|
|
}
|
|
}
|
|
|
|
#ifdef _HPUX_SOURCE
|
|
/* Words cannot express how much HPUX!
|
|
Sometimes rename("/u/jwz/.MCOM-cache", "/u/jwz/.netscape-cache")
|
|
will fail and randomly corrupt memory (but only in the case where
|
|
the first is a directory and the second doesn't exist.) To avoid
|
|
this, we fork-and-exec `mv' instead of using rename().
|
|
*/
|
|
# include <sys/wait.h>
|
|
|
|
# undef rename
|
|
# define rename hpux_www_
|
|
static int
|
|
rename (const char *source, const char *target)
|
|
{
|
|
struct sigaction newact, oldact;
|
|
pid_t forked;
|
|
int ac = 0;
|
|
char **av = (char **) malloc (10 * sizeof (char *));
|
|
av [ac++] = strdup ("/bin/mv");
|
|
av [ac++] = strdup ("-f");
|
|
av [ac++] = strdup (source);
|
|
av [ac++] = strdup (target);
|
|
av [ac++] = 0;
|
|
|
|
/* Setup signals so that SIGCHLD is ignored as we want to do waitpid */
|
|
newact.sa_handler = SIG_DFL;
|
|
newact.sa_flags = 0;
|
|
sigfillset(&newact.sa_mask);
|
|
sigaction (SIGCHLD, &newact, &oldact);
|
|
|
|
switch (forked = fork ())
|
|
{
|
|
case -1:
|
|
while (--ac >= 0)
|
|
free (av [ac]);
|
|
free (av);
|
|
/* Reset SIGCHLD signal hander before returning */
|
|
sigaction(SIGCHLD, &oldact, NULL);
|
|
return -1; /* fork() failed (errno is meaningful.) */
|
|
break;
|
|
case 0:
|
|
{
|
|
execvp (av[0], av);
|
|
exit (-1); /* execvp() failed (this exits the child fork.) */
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
/* This is the "old" process (subproc pid is in `forked'.) */
|
|
int status = 0;
|
|
|
|
/* wait for `mv' to terminate. */
|
|
pid_t waited_pid = waitpid (forked, &status, 0);
|
|
|
|
/* Reset SIGCHLD signal hander before returning */
|
|
sigaction(SIGCHLD, &oldact, NULL);
|
|
|
|
while (--ac >= 0)
|
|
free (av [ac]);
|
|
free (av);
|
|
|
|
return 0;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
#endif /* !HPUX */
|
|
|
|
#if 0
|
|
#if defined(XP_UNIX)
|
|
#if !defined(__FreeBSD__) && !defined(MACLINUX) && !defined(LINUX_GLIBC_2)
|
|
extern char *sys_errlist[];
|
|
extern int sys_nerr;
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
static XP_Bool
|
|
fe_ensure_config_dir_exists ()
|
|
{
|
|
char *dir, *fmt;
|
|
static char buf [2048];
|
|
struct stat st;
|
|
XP_Bool exists;
|
|
|
|
dir = PR_smprintf ("%s/%s", fe_home_dir, MOZ_USER_DIR);
|
|
if (!dir)
|
|
return FALSE;
|
|
|
|
exists = !stat (dir, &st);
|
|
|
|
if (exists && !(st.st_mode & S_IFDIR))
|
|
{
|
|
/* It exists but is not a directory!
|
|
Rename the old file so that we can create the directory.
|
|
*/
|
|
char *loser = (char *) XP_ALLOC (XP_STRLEN (dir) + 100);
|
|
XP_STRCPY (loser, dir);
|
|
XP_STRCAT (loser, ".BAK");
|
|
if (rename (dir, loser) == 0) {
|
|
fmt = XP_GetString( QTFE_EXISTED_BUT_WAS_NOT_A_DIRECTORY );
|
|
exists = FALSE;
|
|
} else {
|
|
fmt = XP_GetString( QTFE_EXISTS_BUT_UNABLE_TO_RENAME );
|
|
}
|
|
|
|
PR_snprintf (buf, sizeof (buf), fmt, XP_AppName, dir, loser);
|
|
XP_FREE (loser);
|
|
FE_Alert (0,buf);
|
|
if (exists) {
|
|
free (dir);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
if (!exists) {
|
|
/* ~/.netscape/ does not exist. Create the directory.
|
|
*/
|
|
#if defined(XP_WIN)
|
|
if (mkdir (dir) < 0) {
|
|
#else
|
|
if (mkdir (dir, 0700) < 0) {
|
|
#endif
|
|
fmt = XP_GetString( QTFE_UNABLE_TO_CREATE_DIRECTORY );
|
|
PR_snprintf (buf, sizeof (buf), fmt, XP_AppName, dir,
|
|
((errno >= 0 && errno < sys_nerr)
|
|
? sys_errlist [errno] : XP_GetString( QTFE_UNKNOWN_ERROR )));
|
|
FE_Alert (0,buf);
|
|
free (dir);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
fe_config_dir = dir;
|
|
return TRUE;
|
|
}
|
|
|
|
#ifndef INADDR_LOOPBACK
|
|
#define INADDR_LOOPBACK 0x7F000001
|
|
#endif
|
|
|
|
#define MAXTRIES 100
|
|
|
|
void
|
|
quitQapp(int status)
|
|
{
|
|
if (qApp) qApp->exit(status); // Will actually exit next loop
|
|
}
|
|
|
|
static int
|
|
fe_create_pidlock (const char *name, unsigned long *paddr, pid_t *ppid)
|
|
{
|
|
char hostname[64]; /* should use MAXHOSTNAMELEN */
|
|
PRHostEnt *hp, hpbuf;
|
|
char dbbuf[PR_NETDB_BUF_SIZE];
|
|
unsigned long myaddr, addr;
|
|
struct in_addr inaddr;
|
|
char *signature;
|
|
int len, tries, rval;
|
|
char buf[1024]; /* should use PATH_MAX or pathconf */
|
|
char *colon, *after;
|
|
pid_t pid;
|
|
|
|
{
|
|
PRStatus sts;
|
|
|
|
sts = PR_GetSystemInfo(PR_SI_HOSTNAME, hostname, sizeof(hostname));
|
|
if (sts == PR_FAILURE)
|
|
inaddr.s_addr = INADDR_LOOPBACK;
|
|
else {
|
|
sts = PR_GetHostByName (hostname, dbbuf, sizeof(dbbuf), &hpbuf);
|
|
if (sts == PR_FAILURE)
|
|
inaddr.s_addr = INADDR_LOOPBACK;
|
|
else {
|
|
hp = &hpbuf;
|
|
memcpy (&inaddr, hp->h_addr, sizeof inaddr);
|
|
}
|
|
}
|
|
}
|
|
|
|
myaddr = inaddr.s_addr;
|
|
signature = PR_smprintf ("%s:%u", inet_ntoa (inaddr), (unsigned)getpid ());
|
|
tries = 0;
|
|
addr = 0;
|
|
pid = 0;
|
|
#if defined(XP_WIN)
|
|
rval = 0;
|
|
#elif defined(XP_UNIX)
|
|
while ((rval = symlink (signature, name)) < 0)
|
|
{
|
|
if (errno != EEXIST)
|
|
break;
|
|
len = readlink (name, buf, sizeof buf - 1);
|
|
if (len > 0) {
|
|
buf[len] = '\0';
|
|
colon = strchr (buf, ':');
|
|
if (colon != NULL) {
|
|
*colon++ = '\0';
|
|
if ((addr = inet_addr (buf)) != (unsigned long)-1) {
|
|
pid = strtol (colon, &after, 0);
|
|
if (pid != 0 && *after == '\0') {
|
|
if (addr != myaddr) {
|
|
/* Remote pid: give up even if lock is stuck. */
|
|
break;
|
|
}
|
|
|
|
/* signator was a local process -- check liveness */
|
|
if (kill (pid, 0) == 0 || errno != ESRCH) {
|
|
/* Lock-owning process appears to be alive. */
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Try to claim a bogus or stuck lock. */
|
|
(void) unlink (name);
|
|
if (++tries > MAXTRIES)
|
|
break;
|
|
}
|
|
#endif
|
|
|
|
if (rval == 0)
|
|
{
|
|
#if defined(XP_UNIX)
|
|
struct sigaction act, oldact;
|
|
|
|
act.sa_handler = quitQapp;
|
|
act.sa_flags = 0;
|
|
sigfillset (&act.sa_mask);
|
|
|
|
/* Set SIGINT, SIGTERM and SIGHUP to our quitQapp(). If these signals
|
|
* have already been ignored, dont install our handler because we
|
|
* could have been started up in the background with a nohup.
|
|
*/
|
|
sigaction (SIGINT, NULL, &oldact);
|
|
if (oldact.sa_handler != SIG_IGN)
|
|
sigaction (SIGINT, &act, NULL);
|
|
|
|
sigaction (SIGHUP, NULL, &oldact);
|
|
if (oldact.sa_handler != SIG_IGN)
|
|
sigaction (SIGHUP, &act, NULL);
|
|
|
|
sigaction (SIGTERM, NULL, &oldact);
|
|
if (oldact.sa_handler != SIG_IGN)
|
|
sigaction (SIGTERM, &act, NULL);
|
|
|
|
#ifdef SUNOS4
|
|
/* atexit() is not available in sun4. Use qt's support. */
|
|
qAddPostRoutine( minimalNoUICleanup );
|
|
#else
|
|
/* Register a atexit() handler to remove lock file */
|
|
atexit(minimalNoUICleanup);
|
|
#endif /* SUNOS4 */
|
|
|
|
#endif // XP_UNIX
|
|
}
|
|
free (signature);
|
|
*paddr = addr;
|
|
*ppid = pid;
|
|
return rval;
|
|
}
|
|
|
|
XP_Bool
|
|
fe_is_absolute_path(char *filename)
|
|
{
|
|
return ( filename && *filename && filename[0] == '/' );
|
|
}
|
|
|
|
XP_Bool
|
|
fe_is_working_dir(char *filename, char** progname)
|
|
{
|
|
*progname = 0;
|
|
|
|
if ( filename && *filename ) {
|
|
if ( (int)strlen(filename)>1 &&
|
|
filename[0] == '.' && filename[1] == '/')
|
|
{
|
|
char *str;
|
|
char *name;
|
|
|
|
name = filename;
|
|
|
|
str = strrchr(name, '/');
|
|
if ( str ) name = str+1;
|
|
|
|
*progname = (char*)malloc((strlen(name)+1)*sizeof(char));
|
|
strcpy(*progname, name);
|
|
|
|
return TRUE;
|
|
} else if (strchr(filename, '/')) {
|
|
*progname = (char*)malloc((strlen(filename)+1)*sizeof(char));
|
|
strcpy(*progname, filename);
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
XP_Bool
|
|
fe_found_in_binpath(char* filename, char** dirfile)
|
|
{
|
|
char *binpath = 0;
|
|
char *dirpath = 0;
|
|
struct stat buf;
|
|
|
|
*dirfile = 0;
|
|
binpath = getenv("PATH");
|
|
|
|
if ( binpath ) {
|
|
binpath = XP_STRDUP(binpath);
|
|
dirpath = XP_STRTOK(binpath, ":");
|
|
while(dirpath) {
|
|
if ( dirpath[strlen(dirpath)-1] == '/' ) {
|
|
dirpath[strlen(dirpath)-1] = '\0';
|
|
}
|
|
|
|
*dirfile = PR_smprintf("%s/%s", dirpath, filename);
|
|
|
|
if ( !stat(*dirfile, &buf) ) {
|
|
XP_FREE(binpath);
|
|
return TRUE;
|
|
}
|
|
dirpath = XP_STRTOK(NULL,":");
|
|
XP_FREE(*dirfile);
|
|
*dirfile = 0;
|
|
}
|
|
XP_FREE(binpath);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
char *
|
|
fe_expand_working_dir(char *cwdfile)
|
|
{
|
|
char *dirfile = 0;
|
|
char *string;
|
|
#if defined(SUNOS4)||defined(AIX)
|
|
char path [MAXPATHLEN];
|
|
#endif
|
|
|
|
#if defined(SUNOS4)||defined(AIX)
|
|
string = getwd (path);
|
|
#else
|
|
string = getcwd(NULL, MAXPATHLEN);
|
|
#endif
|
|
|
|
dirfile = (char *)malloc((strlen(string)+strlen("/")+strlen(cwdfile)+1)
|
|
*sizeof(char));
|
|
strcpy(dirfile, string);
|
|
strcat(dirfile,"/");
|
|
strcat(dirfile, cwdfile);
|
|
#if !(defined(SUNOS4) || defined(AIX))
|
|
XP_FREE(string);
|
|
#endif
|
|
return dirfile;
|
|
}
|
|
|
|
/****************************************
|
|
* This function will return either of these
|
|
* type of the exe file path:
|
|
* 1. return FULL Absolute path if user specifies a full path
|
|
* 2. return FULL Absolute path if the program was found in user
|
|
* current working dir
|
|
* 3. return relative path (ie. the same as it is in fe_progname)
|
|
* if program was found in binpath
|
|
*
|
|
****************************************/
|
|
static const char *
|
|
fe_locate_program_path(const char *fe_prog)
|
|
{
|
|
char *ret_path = 0;
|
|
char *dirfile = 0;
|
|
char *progname = 0;
|
|
|
|
StrAllocCopy(progname, fe_prog);
|
|
|
|
if ( fe_is_absolute_path(progname) ) {
|
|
StrAllocCopy(ret_path, progname);
|
|
XP_FREE(progname);
|
|
return ret_path;
|
|
} else if ( fe_is_working_dir(progname, &dirfile) ) {
|
|
ret_path = fe_expand_working_dir(dirfile);
|
|
XP_FREE(dirfile);
|
|
XP_FREE(progname);
|
|
return ret_path;
|
|
} else if ( fe_found_in_binpath(progname, &ret_path) ) {
|
|
if ( fe_is_absolute_path(ret_path) ) {
|
|
/* Found in the bin path; then return only the exe filename */
|
|
/* Always use bin path as the search path for the file
|
|
for consecutive session*/
|
|
XP_FREE(ret_path);
|
|
ret_path = progname;
|
|
XP_FREE(dirfile);
|
|
} else if (fe_is_working_dir(ret_path, &dirfile) ) {
|
|
XP_FREE(ret_path);
|
|
XP_FREE(progname);
|
|
ret_path = fe_expand_working_dir(dirfile);
|
|
XP_FREE(dirfile);
|
|
}
|
|
return ret_path;
|
|
} else {
|
|
XP_FREE(ret_path);
|
|
XP_FREE(dirfile);
|
|
XP_FREE(progname);
|
|
|
|
fprintf(stderr,
|
|
XP_GetString(QTFE_MOZILLA_NOT_FOUND_IN_PATH),
|
|
fe_progname);
|
|
|
|
exit(-1);
|
|
}
|
|
return "";
|
|
}
|
|
|
|
|
|
/* Retrieve the first entry in the previous session's history list */
|
|
XP_Bool fe_ReadLastUserHistory(char **hist_entry_ptr)
|
|
{
|
|
char *value;
|
|
char buffer[1024];
|
|
char *hist_entry = 0;
|
|
FILE *fp = fopen("qtmozilla_history","r");
|
|
|
|
if ( !fp )
|
|
return FALSE;
|
|
|
|
if ( !fgets(buffer, 1024, fp) )
|
|
*buffer = 0;
|
|
|
|
while (fgets(buffer, 1024, fp )){
|
|
value = XP_StripLine(buffer);
|
|
if (strlen(value)==0 || *value == '#')
|
|
continue;
|
|
hist_entry = XP_STRDUP(value);
|
|
break;
|
|
}
|
|
fclose(fp);
|
|
*hist_entry_ptr = hist_entry;
|
|
|
|
if (hist_entry)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
// Called in modules/libpref/src/prefapi.c
|
|
extern "C"
|
|
void fe_GetProgramDirectory(char *path, int len)
|
|
{
|
|
char * separator;
|
|
char * prog = 0;
|
|
|
|
*path = '\0';
|
|
|
|
if ( fe_is_absolute_path( (char*)fe_progname_long ) )
|
|
strncpy (path, fe_progname_long, len);
|
|
else if ( fe_found_in_binpath((char*)fe_progname_long, &prog) ) {
|
|
strncpy (path, prog, len);
|
|
XP_FREE (prog);
|
|
}
|
|
|
|
if (( separator = XP_STRRCHR(path, '/') ))
|
|
separator[1] = 0;
|
|
}
|
|
|
|
|
|
static void myMessageOutput( QtMsgType, const char * )
|
|
{
|
|
}
|
|
|
|
|
|
class NetProcess : public QObject {
|
|
public:
|
|
NetProcess() { startTimer(50); }
|
|
void timerEvent(QTimerEvent*) {
|
|
NET_ProcessNet(0,NET_EVERYTIME_TYPE);
|
|
PR_ProcessPendingEvents(mozilla_event_queue);
|
|
NET_PollSockets();
|
|
}
|
|
};
|
|
|
|
main(int argc, char** argv)
|
|
{
|
|
#ifdef NDEBUG
|
|
qInstallMsgHandler( myMessageOutput );
|
|
#endif
|
|
QApplication::setFont(QFont("Helvetica", 12));
|
|
QApplication::setColorSpec(QApplication::ManyColor);
|
|
QApplication app(argc, argv);
|
|
QObject::connect( &app, SIGNAL( lastWindowClosed() ),
|
|
&app, SLOT( quit() ) );
|
|
mozilla_main(argc, argv);
|
|
NetProcess np;
|
|
return app.exec();
|
|
}
|
|
|
|
static
|
|
void
|
|
registerConverters (void)
|
|
{
|
|
#ifdef NEW_DECODERS
|
|
NET_ClearAllConverters ();
|
|
#endif /* NEW_DECODERS */
|
|
NF_FontBrokerInitialize();
|
|
|
|
/* Register standard decoders
|
|
This must come AFTER all calls to NET_RegisterExternalDecoderCommand(),
|
|
(at least in the `NEW_DECODERS' world.)
|
|
*/
|
|
NET_RegisterMIMEDecoders ();
|
|
|
|
/* How to save to disk. */
|
|
NET_RegisterContentTypeConverter( "*", FO_SAVE_AS, NULL,
|
|
fe_MakeSaveAsStream );
|
|
|
|
/* Saving any binary format as type `text' should save as `source' instead.
|
|
*/
|
|
NET_RegisterContentTypeConverter( "*", FO_SAVE_AS_TEXT, NULL,
|
|
fe_MakeSaveAsStreamNoPrompt );
|
|
NET_RegisterContentTypeConverter( "*", FO_QUOTE_MESSAGE, NULL,
|
|
fe_MakeSaveAsStreamNoPrompt );
|
|
|
|
/* default presentation converter - offer to save unknown types. */
|
|
NET_RegisterContentTypeConverter( "*", FO_PRESENT, NULL,
|
|
fe_MakeSaveAsStream );
|
|
|
|
#if 0
|
|
NET_RegisterContentTypeConverter( "*", FO_VIEW_SOURCE, NULL,
|
|
fe_MakeViewSourceStream );
|
|
#endif
|
|
|
|
#ifndef NO_MOCHA_CONVERTER_HACK
|
|
/* libmocha:LM_InitMocha() installs this convert. We blow away all
|
|
* converters that were installed and hence these mocha default converters
|
|
* dont get recreated. And mocha has no call to re-register them.
|
|
* So this hack. - dp/brendan
|
|
*/
|
|
NET_RegisterContentTypeConverter(APPLICATION_JAVASCRIPT, FO_PRESENT, 0,
|
|
NET_CreateMochaConverter);
|
|
#endif /* NO_MOCHA_CONVERTER_HACK */
|
|
|
|
/* Parse stuff out of the .mime.types and .mailcap files.
|
|
* We dont have to check dates of files for modified because all that
|
|
* would have been done by the caller. The only place time checking
|
|
* happens is
|
|
* (1) Helperapp page is created
|
|
* (2) Helpers are being saved (OK button pressed on the General Prefs).
|
|
*/
|
|
#define THE_SIZE 1024
|
|
int size = THE_SIZE;
|
|
char buf1[THE_SIZE];
|
|
char buf2[THE_SIZE];
|
|
PREF_GetCharPref( "helpers.private_mime_types_file", buf1, &size );
|
|
PREF_GetCharPref( "helpers.global_mime_types_file", buf2, &size );
|
|
NET_InitFileFormatTypes( buf1, buf2 );
|
|
//#warning Work with changed files here. How do you do that? Kalle.
|
|
|
|
PREF_GetCharPref( "helpers.private_mailcap_file", buf1, &size );
|
|
PREF_GetCharPref( "helpers.global_mailcap_file", buf2, &size );
|
|
NET_RegisterConverters( buf1, buf2 );
|
|
//#warning Work with changed files here. How do you do that? Kalle.
|
|
|
|
#ifndef NO_WEB_FONTS
|
|
/* Register webfont converters */
|
|
NF_RegisterConverters();
|
|
#endif /* NO_WEB_FONTS */
|
|
|
|
#if 0 // NOT YET
|
|
/* Plugins go on top of all this */
|
|
fe_RegisterPluginConverters();
|
|
#endif
|
|
}
|