Bug 299992 (final patch!) - Allow glue-finding code to specify additional features such as toolkit=gtk r=darin

This commit is contained in:
bsmedberg%covad.net 2005-09-01 12:33:47 +00:00
Родитель 5f6c672312
Коммит 008f048933
6 изменённых файлов: 332 добавлений и 103 удалений

Просмотреть файл

@ -37,9 +37,12 @@
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#include "nsXPCOMPrivate.h"
#include "nsXPCOMGlue.h" #include "nsXPCOMGlue.h"
#include "nsINIParser.h"
#include "nsVersionComparator.h"
#include "nsXPCOMPrivate.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -56,6 +59,7 @@
#elif defined(XP_MACOSX) #elif defined(XP_MACOSX)
# include <CFBundle.h> # include <CFBundle.h>
# include <unistd.h> # include <unistd.h>
# include <dirent.h>
#elif defined(XP_UNIX) #elif defined(XP_UNIX)
# include <unistd.h> # include <unistd.h>
# include <sys/param.h> # include <sys/param.h>
@ -71,32 +75,56 @@
#include <sys/stat.h> #include <sys/stat.h>
static PRBool
CheckVersion(const char* toCheck,
const GREVersionRange *versions,
PRUint32 versionsLength);
#if defined(XP_MACOSX) #if defined(XP_MACOSX)
static PRBool static PRBool
GRE_FindGREFramework(const char* version, const char* rootPath, GRE_FindGREFramework(const char* rootPath,
const GREVersionRange *versions,
PRUint32 versionsLength,
const GREProperty *properties,
PRUint32 propertiesLength,
char* buffer, PRUint32 buflen); char* buffer, PRUint32 buflen);
#elif defined(XP_UNIX) #elif defined(XP_UNIX)
static PRBool static PRBool
GRE_GetPathFromConfigDir(const char* version, const char* dirname, GRE_GetPathFromConfigDir(const char* dirname,
const GREVersionRange *versions,
PRUint32 versionsLength,
const GREProperty *properties,
PRUint32 propertiesLength,
char* buffer, PRUint32 buflen); char* buffer, PRUint32 buflen);
static PRBool static PRBool
GRE_GetPathFromConfigFile(const char* version, const char* dirname, GRE_GetPathFromConfigFile(const char* filename,
const GREVersionRange *versions,
PRUint32 versionsLength,
const GREProperty *properties,
PRUint32 propertiesLength,
char* buffer, PRUint32 buflen); char* buffer, PRUint32 buflen);
#elif defined(XP_WIN) #elif defined(XP_WIN)
static PRBool static PRBool
GRE_GetPathFromRegKey(const char* version, HKEY aRegKey, GRE_GetPathFromRegKey(HKEY aRegKey,
const GREVersionRange *versions,
PRUint32 versionsLength,
const GREProperty *properties,
PRUint32 propertiesLength,
char* buffer, PRUint32 buflen); char* buffer, PRUint32 buflen);
#endif #endif
nsresult nsresult
GRE_GetGREPathForVersion(const char *aVersion, GRE_GetGREPathWithProperties(const GREVersionRange *versions,
PRUint32 versionsLength,
const GREProperty *properties,
PRUint32 propertiesLength,
char *aBuffer, PRUint32 aBufLen) char *aBuffer, PRUint32 aBufLen)
{ {
// if GRE_HOME is in the environment, use that GRE // if GRE_HOME is in the environment, use that GRE
@ -180,18 +208,27 @@ GRE_GetGREPathForVersion(const char *aVersion,
// Check ~/Library/Frameworks/XUL/Versions/<version>/libxpcom.dylib // Check ~/Library/Frameworks/XUL/Versions/<version>/libxpcom.dylib
const char *home = getenv("HOME"); const char *home = getenv("HOME");
if (home && *home && GRE_FindGREFramework(aVersion, home, aBuffer, aBufLen)) { if (home && *home && GRE_FindGREFramework(home,
versions, versionsLength,
properties, propertiesLength,
aBuffer, aBufLen)) {
return NS_OK; return NS_OK;
} }
// Check /Library/Frameworks/XUL/Versions/<version>/libxpcom.dylib // Check /Library/Frameworks/XUL/Versions/<version>/libxpcom.dylib
if (GRE_FindGREFramework(aVersion, "", aBuffer, aBufLen)) { if (GRE_FindGREFramework("",
versions, versionsLength,
properties, propertiesLength,
aBuffer, aBufLen)) {
return NS_OK; return NS_OK;
} }
#elif defined(XP_UNIX) #elif defined(XP_UNIX)
env = getenv("MOZ_GRE_CONF"); env = getenv("MOZ_GRE_CONF");
if (env && GRE_GetPathFromConfigFile(aVersion, env, aBuffer, aBufLen)) { if (env && GRE_GetPathFromConfigFile(env,
versions, versionsLength,
properties, propertiesLength,
aBuffer, aBufLen)) {
return NS_OK; return NS_OK;
} }
@ -204,7 +241,10 @@ GRE_GetGREPathForVersion(const char *aVersion,
snprintf(buffer, sizeof(buffer), snprintf(buffer, sizeof(buffer),
"%s" XPCOM_FILE_PATH_SEPARATOR GRE_CONF_NAME, env); "%s" XPCOM_FILE_PATH_SEPARATOR GRE_CONF_NAME, env);
if (GRE_GetPathFromConfigFile(aVersion, buffer, aBuffer, aBufLen)) { if (GRE_GetPathFromConfigFile(buffer,
versions, versionsLength,
properties, propertiesLength,
aBuffer, aBufLen)) {
return NS_OK; return NS_OK;
} }
@ -213,18 +253,27 @@ GRE_GetGREPathForVersion(const char *aVersion,
snprintf(buffer, sizeof(buffer), snprintf(buffer, sizeof(buffer),
"%s" XPCOM_FILE_PATH_SEPARATOR GRE_USER_CONF_DIR, env); "%s" XPCOM_FILE_PATH_SEPARATOR GRE_USER_CONF_DIR, env);
if (GRE_GetPathFromConfigDir(aVersion, buffer, aBuffer, aBufLen)) { if (GRE_GetPathFromConfigDir(buffer,
versions, versionsLength,
properties, propertiesLength,
aBuffer, aBufLen)) {
return NS_OK; return NS_OK;
} }
} }
// Look for a global /etc/gre.conf file // Look for a global /etc/gre.conf file
if (GRE_GetPathFromConfigFile(aVersion, GRE_CONF_PATH, aBuffer, aBufLen)) { if (GRE_GetPathFromConfigFile(GRE_CONF_PATH,
versions, versionsLength,
properties, propertiesLength,
aBuffer, aBufLen)) {
return NS_OK; return NS_OK;
} }
// Look for a group of config files in /etc/gre.d/ // Look for a group of config files in /etc/gre.d/
if (GRE_GetPathFromConfigDir(aVersion, GRE_CONF_DIR, aBuffer, aBufLen)) { if (GRE_GetPathFromConfigDir(GRE_CONF_DIR,
versions, versionsLength,
properties, propertiesLength,
aBuffer, aBufLen)) {
return NS_OK; return NS_OK;
} }
@ -244,7 +293,10 @@ GRE_GetGREPathForVersion(const char *aVersion,
// //
if (::RegOpenKeyEx(HKEY_CURRENT_USER, GRE_WIN_REG_LOC, 0, if (::RegOpenKeyEx(HKEY_CURRENT_USER, GRE_WIN_REG_LOC, 0,
KEY_READ, &hRegKey) == ERROR_SUCCESS) { KEY_READ, &hRegKey) == ERROR_SUCCESS) {
PRBool ok = GRE_GetPathFromRegKey(aVersion, hRegKey, aBuffer, aBufLen); PRBool ok = GRE_GetPathFromRegKey(hRegKey,
versions, versionsLength,
properties, propertiesLength,
aBuffer, aBufLen);
::RegCloseKey(hRegKey); ::RegCloseKey(hRegKey);
if (ok) if (ok)
@ -253,7 +305,10 @@ GRE_GetGREPathForVersion(const char *aVersion,
if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, GRE_WIN_REG_LOC, 0, if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, GRE_WIN_REG_LOC, 0,
KEY_ENUMERATE_SUB_KEYS, &hRegKey) == ERROR_SUCCESS) { KEY_ENUMERATE_SUB_KEYS, &hRegKey) == ERROR_SUCCESS) {
PRBool ok = GRE_GetPathFromRegKey(aVersion, hRegKey, aBuffer, aBufLen); PRBool ok = GRE_GetPathFromRegKey(hRegKey,
versions, versionsLength,
properties, propertiesLength,
aBuffer, aBufLen);
::RegCloseKey(hRegKey); ::RegCloseKey(hRegKey);
if (ok) if (ok)
@ -264,16 +319,65 @@ GRE_GetGREPathForVersion(const char *aVersion,
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
static PRBool
CheckVersion(const char* toCheck,
const GREVersionRange *versions,
PRUint32 versionsLength)
{
for (const GREVersionRange *versionsEnd = versions + versionsLength;
versions < versionsEnd;
++versions) {
PRInt32 c = NS_CompareVersions(toCheck, versions->lower);
if (c < 0)
continue;
if (!c && !versions->lowerInclusive)
continue;
c = NS_CompareVersions(toCheck, versions->upper);
if (c > 0)
continue;
if (!c && !versions->upperInclusive)
continue;
return PR_TRUE;
}
return PR_FALSE;
}
#ifdef XP_MACOSX #ifdef XP_MACOSX
PRBool PRBool
GRE_FindGREFramework(const char* version, const char* rootPath, GRE_FindGREFramework(const char* rootPath,
const GREVersionRange *versions,
PRUint32 versionsLength,
const GREProperty *properties,
PRUint32 propertiesLength,
char* buffer, PRUint32 buflen) char* buffer, PRUint32 buflen)
{ {
snprintf(buffer, buflen, PRBool found = PR_FALSE;
"%s/Library/Frameworks/" GRE_FRAMEWORK_NAME "/Versions/%s/" XPCOM_DLL,
rootPath, version);
snprintf(buffer, buflen,
"%s/Library/Frameworks/" GRE_FRAMEWORK_NAME "/Versions", rootPath);
DIR *dir = opendir(buffer);
if (dir) {
struct dirent *entry;
while (!found && (entry = readdir(dir))) {
if (CheckVersion(entry->d_name, versions, versionsLength)) {
snprintf(buffer, buflen,
"%s/Library/Frameworks/" GRE_FRAMEWORK_NAME
"/Versions/%s/" XPCOM_DLL, rootPath, entry->d_name);
if (access(buffer, R_OK | X_OK) == 0) if (access(buffer, R_OK | X_OK) == 0)
found = PR_TRUE;
}
}
closedir(dir);
}
if (found)
return PR_TRUE; return PR_TRUE;
buffer[0] = '\0'; buffer[0] = '\0';
@ -290,7 +394,11 @@ static PRBool IsConfFile(const char *filename)
} }
PRBool PRBool
GRE_GetPathFromConfigDir(const char* version, const char* dirname, GRE_GetPathFromConfigDir(const char* dirname,
const GREVersionRange *versions,
PRUint32 versionsLength,
const GREProperty *properties,
PRUint32 propertiesLength,
char* buffer, PRUint32 buflen) char* buffer, PRUint32 buflen)
{ {
// Open the directory provided and try to read any files in that // Open the directory provided and try to read any files in that
@ -314,7 +422,10 @@ GRE_GetPathFromConfigDir(const char* version, const char* dirname,
snprintf(fullPath, sizeof(fullPath), "%s" XPCOM_FILE_PATH_SEPARATOR "%s", snprintf(fullPath, sizeof(fullPath), "%s" XPCOM_FILE_PATH_SEPARATOR "%s",
dirname, entry->d_name); dirname, entry->d_name);
found = GRE_GetPathFromConfigFile(version, fullPath, buffer, buflen); found = GRE_GetPathFromConfigFile(fullPath,
versions, versionsLength,
properties, propertiesLength,
buffer, buflen);
} }
closedir(dir); closedir(dir);
@ -324,50 +435,73 @@ GRE_GetPathFromConfigDir(const char* version, const char* dirname,
#define READ_BUFFER_SIZE 1024 #define READ_BUFFER_SIZE 1024
struct INIClosure
{
nsINIParser &parser;
const GREVersionRange *versions;
PRUint32 versionsLength;
const GREProperty *properties;
PRUint32 propertiesLength;
char *pathBuffer;
PRUint32 buflen;
PRBool found;
};
static PRBool
CheckINIHeader(const char *aHeader, void *aClosure)
{
nsresult rv;
INIClosure *c = NS_REINTERPRET_CAST(INIClosure *, aClosure);
if (!CheckVersion(aHeader, c->versions, c->versionsLength))
return PR_TRUE;
const GREProperty *properties = c->properties;
const GREProperty *endProperties = properties + c->propertiesLength;
for (; properties < endProperties; ++properties) {
char buffer[MAXPATHLEN];
rv = c->parser.GetString(aHeader, properties->property,
buffer, sizeof(buffer));
if (NS_FAILED(rv))
return PR_TRUE;
if (strcmp(buffer, properties->value))
return PR_TRUE;
}
rv = c->parser.GetString(aHeader, "GRE_PATH", c->pathBuffer, c->buflen);
if (NS_FAILED(rv))
return PR_TRUE;
// We found a good GRE! Stop looking.
c->found = PR_TRUE;
return PR_FALSE;
}
PRBool PRBool
GRE_GetPathFromConfigFile(const char* version, const char* filename, GRE_GetPathFromConfigFile(const char* filename,
const GREVersionRange *versions,
PRUint32 versionsLength,
const GREProperty *properties,
PRUint32 propertiesLength,
char* pathBuffer, PRUint32 buflen) char* pathBuffer, PRUint32 buflen)
{ {
int versionlen = strlen(version); nsINIParser parser;
nsresult rv = parser.Init(filename);
if (NS_FAILED(rv))
return PR_FALSE;
*pathBuffer = '\0'; INIClosure c = {
char buffer[READ_BUFFER_SIZE]; parser,
FILE *cfg; versions, versionsLength,
PRBool foundHeader = PR_FALSE; properties, propertiesLength,
pathBuffer, buflen,
PR_FALSE
};
if ((cfg = fopen(filename,"r")) == nsnull) { parser.GetSections(CheckINIHeader, &c);
return nsnull; return c.found;
}
while (fgets(buffer, READ_BUFFER_SIZE, cfg) != nsnull) {
// skip over comment lines and blank lines
if (buffer[0] == '#' || buffer[0] == '\n') {
continue;
}
// we found a section heading, check to see if it is the one we
// are interested in.
if (buffer[0] == '[') {
foundHeader = (buffer[versionlen + 1] == ']' &&
strncmp(buffer + 1, version, versionlen) == 0);
continue;
}
static const char kGreHome[] = "GRE_PATH=";
if (foundHeader && !strncmp(buffer, kGreHome, sizeof(kGreHome) - 1)) {
strncpy(pathBuffer, buffer + 9, buflen);
// kill the line feed if any
PRInt32 len = strlen(pathBuffer);
len--;
if (pathBuffer[len] == '\n')
pathBuffer[len] = '\0';
break;
}
}
fclose(cfg);
return (*pathBuffer != '\0');
} }
#elif defined(XP_WIN) #elif defined(XP_WIN)
@ -397,7 +531,11 @@ CopyWithEnvExpansion(char* aDest, const char* aSource, PRUint32 aBufLen,
} }
PRBool PRBool
GRE_GetPathFromRegKey(const char* aVersion, HKEY aRegKey, GRE_GetPathFromRegKey(HKEY aRegKey,
const GREVersionRange *versions,
PRUint32 versionsLength,
const GREProperty *properties,
PRUint32 propertiesLength,
char* aBuffer, PRUint32 aBufLen) char* aBuffer, PRUint32 aBufLen)
{ {
// Formerly, GREs were registered at the key HKLM/Software/Mozilla/GRE/<version> // Formerly, GREs were registered at the key HKLM/Software/Mozilla/GRE/<version>
@ -405,6 +543,7 @@ GRE_GetPathFromRegKey(const char* aVersion, HKEY aRegKey,
// Software/Mozilla/GRE, with the following valuepairs: // Software/Mozilla/GRE, with the following valuepairs:
// Version=<version> (REG_SZ) // Version=<version> (REG_SZ)
// GreHome=<path> (REG_SZ or REG_EXPAND_SZ) // GreHome=<path> (REG_SZ or REG_EXPAND_SZ)
// <Property>=<value> (REG_SZ)
// //
// Additional meta-info may be available in the future, including // Additional meta-info may be available in the future, including
// localization info, ABI, and other information which might be pertinent // localization info, ABI, and other information which might be pertinent
@ -436,24 +575,42 @@ GRE_GetPathFromRegKey(const char* aVersion, HKEY aRegKey,
char version[40]; char version[40];
DWORD versionlen = 40; DWORD versionlen = 40;
char pathbuf[MAXPATHLEN]; char pathbuf[MAXPATHLEN];
DWORD pathlen = sizeof(pathbuf); DWORD pathlen;
DWORD pathtype; DWORD pathtype;
PRBool ok = PR_FALSE;
if (::RegQueryValueEx(subKey, "Version", NULL, NULL, if (::RegQueryValueEx(subKey, "Version", NULL, NULL,
(BYTE*) version, &versionlen) == ERROR_SUCCESS && (BYTE*) version, &versionlen) == ERROR_SUCCESS &&
strncmp(aVersion, version, versionlen) == 0) { CheckVersion(version, versions, versionsLength)) {
if (::RegQueryValueEx(subKey, "GreHome", NULL, &pathtype,
(BYTE*) pathbuf, &pathlen) == ERROR_SUCCESS && ok = PR_TRUE;
*pathbuf && const GREProperty *props = properties;
CopyWithEnvExpansion(aBuffer, pathbuf, aBufLen, pathtype) && const GREProperty *propsEnd = properties + propertiesLength;
access(aBuffer, R_OK) == 0) { for (; ok && props < propsEnd; ++props) {
RegCloseKey(subKey); pathlen = sizeof(pathbuf);
return PR_TRUE; if (!::RegQueryValueEx(subKey, props->property, NULL, &pathtype,
(BYTE*) pathbuf, &pathlen) ||
strcmp(pathbuf, props->value))
ok = PR_FALSE;
}
pathlen = sizeof(pathbuf);
if (ok &&
(!::RegQueryValueEx(subKey, "GreHome", NULL, &pathtype,
(BYTE*) pathbuf, &pathlen) == ERROR_SUCCESS ||
!*pathbuf ||
!CopyWithEnvExpansion(aBuffer, pathbuf, aBufLen, pathtype) ||
access(aBuffer, R_OK))) {
ok = PR_FALSE;
} }
} }
RegCloseKey(subKey); RegCloseKey(subKey);
if (ok)
return PR_TRUE;
++i; ++i;
} }

Просмотреть файл

@ -46,6 +46,7 @@
#include "nsIDirectoryService.h" #include "nsIDirectoryService.h"
#include "nsDirectoryServiceDefs.h" #include "nsDirectoryServiceDefs.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsMemory.h"
#include "nspr.h" #include "nspr.h"
#include "plstr.h" #include "plstr.h"
@ -293,7 +294,14 @@ GRE_GetGREPath()
} }
} }
GRE_GetGREPathForVersion(GRE_BUILD_ID, sGRELocation, MAXPATHLEN); static const GREVersionRange version = {
GRE_BUILD_ID, PR_TRUE,
GRE_BUILD_ID, PR_TRUE
};
GRE_GetGREPathWithProperties(&version, 1,
nsnull, 0,
sGRELocation, MAXPATHLEN);
if (*sGRELocation) if (*sGRELocation)
return sGRELocation; return sGRELocation;

Просмотреть файл

@ -48,23 +48,46 @@ class nsILocalFile;
* dynamically linked versions of the glue. * dynamically linked versions of the glue.
*/ */
struct GREVersionRange {
const char *lower;
PRBool lowerInclusive;
const char *upper;
PRBool upperInclusive;
};
struct GREProperty {
const char *property;
const char *value;
};
/** /**
* Locate the path of a particular version of the GRE. * Locate the path of a GRE with certain properties.
* *
* @param version The GRE version to search for. * @param versions An array of version ranges: if any version range
* @param buffer A buffer to be filled with the appropriate path. If the * matches, the GRE is considered acceptable.
* "local" GRE is specified (via the USE_LOCAL_GRE environment * @param versionsLength The length of the versions array.
* variable, for example), this buffer will be set to the empty * @param properties A null-terminated list of GRE property/value pairs
* string. * which must all be satisfied.
* @param propertiesLength Length of the properties array.
* @param buffer A buffer to be filled with the appropriate path. If
* the "local" GRE is specified (via the USE_LOCAL_GRE
* environment variable, for example), this buffer
* will be set to the empty string.
* @param buflen The length of buffer. This must be at least * @param buflen The length of buffer. This must be at least
* PATH_MAX/MAXPATHLEN. * PATH_MAX/MAXPATHLEN.
* @throws NS_ERROR_FAILURE if an appropriate GRE could not be found. * @throws NS_ERROR_FAILURE if an appropriate GRE could not be found.
* @note The properties parameter is ignored on macintosh, because of the
* manner in which the XUL frameworks are installed by version.
* @note Currently this uses a "first-fit" algorithm, it does not select
* the newest available GRE.
*/ */
extern "C" NS_COM_GLUE nsresult extern "C" NS_COM_GLUE nsresult
GRE_GetGREPathForVersion(const char *version, GRE_GetGREPathWithProperties(const GREVersionRange *versions,
PRUint32 versionsLength,
const GREProperty *properties,
PRUint32 propertiesLength,
char *buffer, PRUint32 buflen); char *buffer, PRUint32 buflen);
#ifdef XPCOM_GLUE #ifdef XPCOM_GLUE
/** /**

Просмотреть файл

@ -353,12 +353,17 @@ int main(int argc, char* argv[])
return 1; return 1;
} }
char version[MAXPATHLEN]; char path[MAXPATHLEN];
nsresult rv = GRE_GetGREPathForVersion(argv[2], version, MAXPATHLEN); const GREVersionRange vr = {
argv[2], PR_TRUE,
argv[2], PR_TRUE
};
nsresult rv = GRE_GetGREPathWithProperties(&vr, 1, nsnull, 0,
path, sizeof(path));
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return 1; return 1;
printf("%s\n", version); printf("%s\n", path);
return 0; return 0;
} }

Просмотреть файл

@ -49,6 +49,8 @@ PROGRAM = xulrunner$(BIN_SUFFIX)
CPPSRCS = nsXULStubOSX.cpp CPPSRCS = nsXULStubOSX.cpp
REQUIRES = xpcom
endif # OS_ARCH endif # OS_ARCH
DEFINES += -DXPCOM_GLUE DEFINES += -DXPCOM_GLUE

Просмотреть файл

@ -36,29 +36,21 @@
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#include <unistd.h> #include <unistd.h>
#include <stdlib.h>
#include <CFBundle.h> #include <CFBundle.h>
#include <Processes.h> #include <Processes.h>
#include "nsBuildID.h" #include "nsBuildID.h"
#include "nsXPCOMGlue.h" #include "nsXPCOMGlue.h"
#include "nsINIParser.h"
#define VERSION_MAXLEN 128
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
char greDir[PATH_MAX]; nsresult rv;
// XXXbsmedberg: read application.ini version information instead of
// using compiled-in GRE_BUILD_ID
nsresult rv = GRE_GetGREPathForVersion(GRE_BUILD_ID, greDir, sizeof(greDir));
if (NS_FAILED(rv)) {
// XXXbsmedberg: Do something much smarter here: notify the
// user/offer to download/?
fprintf(stderr,
"Could not find compatible GRE, version <" GRE_BUILD_ID ">\n");
return 1;
}
CFBundleRef appBundle = CFBundleGetMainBundle(); CFBundleRef appBundle = CFBundleGetMainBundle();
if (!appBundle) if (!appBundle)
@ -95,9 +87,51 @@ main(int argc, char **argv)
kCFStringEncodingUTF8); kCFStringEncodingUTF8);
CFRelease(iniPathStr); CFRelease(iniPathStr);
char **argv2 = (char**) malloc(sizeof(char*) * (argc + 2)); nsINIParser parser;
if (!argv2) rv = parser.Init(iniPath);
if (NS_FAILED(rv)) {
fprintf(stderr, "Could not read application.ini\n");
return 1; return 1;
}
char greDir[PATH_MAX];
char minVersion[VERSION_MAXLEN];
// If a gecko maxVersion is not specified, we assume that the app uses only
// frozen APIs, and is therefore compatible with any xulrunner 1.x.
char maxVersion[VERSION_MAXLEN] = "2";
GREVersionRange range = {
minVersion,
PR_TRUE,
maxVersion,
PR_FALSE
};
rv = parser.GetString("Gecko", "MinVersion", minVersion, sizeof(minVersion));
if (NS_FAILED(rv)) {
fprintf(stderr,
"The application.ini does not specify a [Gecko] MinVersion\n");
return 1;
}
rv = parser.GetString("Gecko", "MaxVersion", maxVersion, sizeof(maxVersion));
if (NS_SUCCEEDED(rv))
range.upperInclusive = PR_TRUE;
rv = GRE_GetGREPathWithProperties(&range, 1, nsnull, 0,
greDir, sizeof(greDir));
if (NS_FAILED(rv)) {
// XXXbsmedberg: Do something much smarter here: notify the
// user/offer to download/?
fprintf(stderr,
"Could not find compatible GRE between version %s and %s.\n",
range.lower, range.upper);
return 1;
}
char **argv2 = (char**) alloca(sizeof(char*) * (argc + 2));
char xulBin[PATH_MAX]; char xulBin[PATH_MAX];
snprintf(xulBin, sizeof(xulBin), "%s/xulrunner-bin", greDir); snprintf(xulBin, sizeof(xulBin), "%s/xulrunner-bin", greDir);