Back to index

lightning-sunbird  0.9+nobinonly
Classes | Functions
nsXPCOMGlue.h File Reference
#include "nscore.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  GREVersionRange
 The following function is available in both the standalone and dynamically linked versions of the glue. More...
struct  GREProperty

Functions

NS_COM_GLUE nsresult GRE_GetGREPathWithProperties (const GREVersionRange *versions, PRUint32 versionsLength, const GREProperty *properties, PRUint32 propertiesLength, char *buffer, PRUint32 buflen)
 Locate the path of the xpcom shared library from a GRE with specified properties.

Class Documentation

struct GREVersionRange

The following function is available in both the standalone and dynamically linked versions of the glue.

Definition at line 51 of file nsXPCOMGlue.h.

Class Members
const char * lower
PRBool lowerInclusive
const char * upper
PRBool upperInclusive
struct GREProperty

Definition at line 58 of file nsXPCOMGlue.h.

Class Members
const char * property
const char * value

Function Documentation

NS_COM_GLUE nsresult GRE_GetGREPathWithProperties ( const GREVersionRange versions,
PRUint32  versionsLength,
const GREProperty properties,
PRUint32  propertiesLength,
char *  buffer,
PRUint32  buflen 
)

Locate the path of the xpcom shared library from a GRE with specified properties.

Parameters:
versionsAn array of version ranges: if any version range matches, the GRE is considered acceptable.
versionsLengthThe length of the versions array.
propertiesA null-terminated list of GRE property/value pairs which must all be satisfied.
propertiesLengthLength of the properties array.
bufferA 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.
buflenThe length of buffer. This must be at least PATH_MAX/MAXPATHLEN.
Exceptions:
NS_ERROR_FAILUREif 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.
Currently this uses a "first-fit" algorithm, it does not select the newest available GRE.

Definition at line 148 of file nsGREGlue.cpp.

{
  // if GRE_HOME is in the environment, use that GRE
  const char* env = getenv("GRE_HOME");
  if (env && *env) {
    char p[MAXPATHLEN];
    snprintf(p, sizeof(p), "%s" XPCOM_FILE_PATH_SEPARATOR XPCOM_DLL, env);
    p[sizeof(p) - 1] = '\0';

#if XP_UNIX
    if (realpath(p, aBuffer))
      return NS_OK;
#elif XP_WIN
    if (_fullpath(aBuffer, p, aBufLen))
      return NS_OK;
#else
    // hope for the best
    // xxxbsmedberg: other platforms should have a "make absolute" function
#endif

    if (strlen(p) >= aBufLen)
      return NS_ERROR_FILE_NAME_TOO_LONG;

    strcpy(aBuffer, p);

    return NS_OK;
  }

  // the Gecko bits that sit next to the application or in the LD_LIBRARY_PATH
  env = getenv("USE_LOCAL_GRE");
  if (env && *env) {
    *aBuffer = nsnull;
    return NS_OK;
  }

#ifdef XP_MACOSX
  aBuffer[0] = '\0';

  // Check the bundle first, for <bundle>/Contents/Frameworks/XUL.framework/libxpcom.dylib
  CFBundleRef appBundle = CFBundleGetMainBundle();
  if (appBundle) {
    CFURLRef fwurl = CFBundleCopyPrivateFrameworksURL(appBundle);
    CFURLRef absfwurl = nsnull;
    if (fwurl) {
      absfwurl = CFURLCopyAbsoluteURL(fwurl);
      CFRelease(fwurl);
    }

    if (absfwurl) {
      CFURLRef xulurl =
        CFURLCreateCopyAppendingPathComponent(NULL, absfwurl,
                                              CFSTR(GRE_FRAMEWORK_NAME),
                                              PR_TRUE);

      if (xulurl) {
        CFURLRef xpcomurl =
          CFURLCreateCopyAppendingPathComponent(NULL, xulurl,
                                                CFSTR("libxpcom.dylib"),
                                                PR_FALSE);

        if (xpcomurl) {
          char tbuffer[MAXPATHLEN];

          if (CFURLGetFileSystemRepresentation(xpcomurl, PR_TRUE,
                                               (UInt8*) tbuffer,
                                               sizeof(tbuffer)) &&
              access(tbuffer, R_OK | X_OK) == 0) {
            if (!realpath(tbuffer, aBuffer)) {
              aBuffer[0] = '\0';
            }
          }

          CFRelease(xpcomurl);
        }

        CFRelease(xulurl);
      }

      CFRelease(absfwurl);
    }
  }

  if (aBuffer[0])
    return NS_OK;

  // Check ~/Library/Frameworks/XUL.framework/Versions/<version>/libxpcom.dylib
  const char *home = getenv("HOME");
  if (home && *home && GRE_FindGREFramework(home,
                                            versions, versionsLength,
                                            properties, propertiesLength,
                                            aBuffer, aBufLen)) {
    return NS_OK;
  }

  // Check /Library/Frameworks/XUL.framework/Versions/<version>/libxpcom.dylib
  if (GRE_FindGREFramework("",
                           versions, versionsLength,
                           properties, propertiesLength,
                           aBuffer, aBufLen)) {
    return NS_OK;
  }

#elif defined(XP_UNIX) 
  env = getenv("MOZ_GRE_CONF");
  if (env && GRE_GetPathFromConfigFile(env,
                                       versions, versionsLength,
                                       properties, propertiesLength,
                                       aBuffer, aBufLen)) {
    return NS_OK;
  }

  env = getenv("HOME");
  if (env && *env) {
    char buffer[MAXPATHLEN];

    // Look in ~/.gre.config

    snprintf(buffer, sizeof(buffer),
             "%s" XPCOM_FILE_PATH_SEPARATOR GRE_CONF_NAME, env);
    
    if (GRE_GetPathFromConfigFile(buffer,
                                  versions, versionsLength,
                                  properties, propertiesLength,
                                  aBuffer, aBufLen)) {
      return NS_OK;
    }

    // Look in ~/.gre.d/*.conf

    snprintf(buffer, sizeof(buffer),
             "%s" XPCOM_FILE_PATH_SEPARATOR GRE_USER_CONF_DIR, env);

    if (GRE_GetPathFromConfigDir(buffer,
                                 versions, versionsLength,
                                 properties, propertiesLength,
                                 aBuffer, aBufLen)) {
      return NS_OK;
    }
  }

  // Look for a global /etc/gre.conf file
  if (GRE_GetPathFromConfigFile(GRE_CONF_PATH,
                                versions, versionsLength,
                                properties, propertiesLength,
                                aBuffer, aBufLen)) {
    return NS_OK;
  }

  // Look for a group of config files in /etc/gre.d/
  if (GRE_GetPathFromConfigDir(GRE_CONF_DIR,
                               versions, versionsLength,
                               properties, propertiesLength,
                               aBuffer, aBufLen)) {
    return NS_OK;
  }

#elif defined(XP_WIN)
  HKEY hRegKey = NULL;
    
  // A couple of key points here:
  // 1. Note the usage of the "Software\\Mozilla\\GRE" subkey - this allows
  //    us to have multiple versions of GREs on the same machine by having
  //    subkeys such as 1.0, 1.1, 2.0 etc. under it.
  // 2. In this sample below we're looking for the location of GRE version 1.2
  //    i.e. we're compatible with GRE 1.2 and we're trying to find it's install
  //    location.
  //
  // Please see http://www.mozilla.org/projects/embedding/GRE.html for
  // more info.
  //
  if (::RegOpenKeyEx(HKEY_CURRENT_USER, GRE_WIN_REG_LOC, 0,
                     KEY_READ, &hRegKey) == ERROR_SUCCESS) {
    PRBool ok = GRE_GetPathFromRegKey(hRegKey,
                                      versions, versionsLength,
                                      properties, propertiesLength,
                                      aBuffer, aBufLen);
    ::RegCloseKey(hRegKey);

    if (ok)
      return NS_OK;
  }

  if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, GRE_WIN_REG_LOC, 0,
                     KEY_ENUMERATE_SUB_KEYS, &hRegKey) == ERROR_SUCCESS) {
    PRBool ok = GRE_GetPathFromRegKey(hRegKey,
                                      versions, versionsLength,
                                      properties, propertiesLength,
                                      aBuffer, aBufLen);
    ::RegCloseKey(hRegKey);

    if (ok)
      return NS_OK;
  }
#endif

  return NS_ERROR_FAILURE;
}

Here is the call graph for this function:

Here is the caller graph for this function: