Back to index

lightning-sunbird  0.9+nobinonly
Functions
nsGREGlue.cpp File Reference
#include "nsXPCOMGlue.h"
#include "nsINIParser.h"
#include "nsVersionComparator.h"
#include "nsXPCOMPrivate.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>

Go to the source code of this file.

Functions

static PRBool safe_strncat (char *dest, const char *append, PRUint32 count)
 Like strncat, appends a buffer to another buffer.
static PRBool CheckVersion (const char *toCheck, const GREVersionRange *versions, PRUint32 versionsLength)
nsresult GRE_GetGREPathWithProperties (const GREVersionRange *versions, PRUint32 versionsLength, const GREProperty *properties, PRUint32 propertiesLength, char *aBuffer, PRUint32 aBufLen)
 Locate the path of the xpcom shared library from a GRE with specified properties.

Function Documentation

static PRBool CheckVersion ( const char *  toCheck,
const GREVersionRange versions,
PRUint32  versionsLength 
) [static]

Definition at line 351 of file nsGREGlue.cpp.

{
  
  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;
}

Here is the call graph for this function:

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:

static PRBool safe_strncat ( char *  dest,
const char *  append,
PRUint32  count 
) [static]

Like strncat, appends a buffer to another buffer.

This is where the similarity ends. Firstly, the "count" here is the total size of the buffer (not the number of chars to append. Secondly, the function returns PR_FALSE if the buffer is not long enough to hold the concatenated string.

Definition at line 84 of file nsGREGlue.cpp.

{
  char *end = dest + count - 1;

  // skip to the end of dest
  while (*dest)
    ++dest;

  while (*append && dest < end) {
    *dest = *append;
    ++dest, ++append;
  }

  *dest = '\0';

  return *append == '\0';
}