Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions | Variables
VerReg.c File Reference
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include "reg.h"
#include "NSReg.h"
#include "VerReg.h"

Go to the source code of this file.

Defines

#define MAXREGVERLEN   32 /* Version=12345.12345.12345.12345 */
#define VERSTR   "Version"
#define CHKSTR   "Check"
#define PATHSTR   "Path"
#define DIRSTR   "Directory"
#define NAVHOME   "InstallDir"
#define REFCSTR   "RefCount"
#define SHAREDSTR   "Shared"
#define PACKAGENAMESTR   "PackageName"
#define SHAREDFILESSTR   "/Shared Files"
#define VERSION_NAME   "Mozilla"
#define NAVIGATOR_NODE   "/mozilla.org"
#define CURRENT_VER   "CurrentVersion"
#define PATH_ROOT(p)   ( ((p) && *(p)==PATHDEL) ? ROOTKEY_VERSIONS : curver )
#define UNIX_ROOT(p)   ( ((p) && *(p)==PATHDEL) ? ROOTKEY_VERSIONS : unixver )

Functions

static REGERR vr_Init (void)
static XP_Bool vr_CompareDirs (char *dir1, char *dir2)
static REGERR vr_SetCurrentNav (char *product, char *programPath, char *versionStr)
static REGERR vr_ParseVersion (char *verstr, VERSION *result)
static REGERR vr_SetPathname (HREG reg, RKEY key, char *entry, char *dir)
static REGERR vr_GetPathname (HREG reg, RKEY key, char *entry, char *buf, uint32 sizebuf)
static REGERR vr_FindKey (char *name, HREG *hreg, RKEY *key)
static REGERR vr_GetUninstallItemPath (char *regPackageName, char *regbuf, uint32 regbuflen)
static REGERR vr_convertPackageName (char *regPackageName, char *convertedPackageName, uint32 convertedDataLength)
 Replaces all '/' with '_',in the given string.If an '_' already exists in the given string, it is escaped by adding another '_' to it.
static REGERR vr_unmanglePackageName (char *mangledPackageName, char *regPackageName, uint32 regPackageLength)
 VR_INTERFACE (REGERR)

Variables

static int isInited = 0
static RKEY curver = 0
static char gCurstr [MAXREGNAMELEN]
static HREG vreg = 0
static char * app_dir = NULL
char * verRegName = NULL
PRLockvr_lock = NULL

Define Documentation

#define CHKSTR   "Check"

Definition at line 88 of file VerReg.c.

#define CURRENT_VER   "CurrentVersion"

Definition at line 99 of file VerReg.c.

#define DIRSTR   "Directory"

Definition at line 90 of file VerReg.c.

#define MAXREGVERLEN   32 /* Version=12345.12345.12345.12345 */

Definition at line 85 of file VerReg.c.

#define NAVHOME   "InstallDir"

Definition at line 91 of file VerReg.c.

#define NAVIGATOR_NODE   "/mozilla.org"

Definition at line 98 of file VerReg.c.

#define PACKAGENAMESTR   "PackageName"

Definition at line 94 of file VerReg.c.

#define PATH_ROOT (   p)    ( ((p) && *(p)==PATHDEL) ? ROOTKEY_VERSIONS : curver )

Definition at line 101 of file VerReg.c.

#define PATHSTR   "Path"

Definition at line 89 of file VerReg.c.

#define REFCSTR   "RefCount"

Definition at line 92 of file VerReg.c.

#define SHAREDFILESSTR   "/Shared Files"

Definition at line 95 of file VerReg.c.

#define SHAREDSTR   "Shared"

Definition at line 93 of file VerReg.c.

#define UNIX_ROOT (   p)    ( ((p) && *(p)==PATHDEL) ? ROOTKEY_VERSIONS : unixver )

Definition at line 102 of file VerReg.c.

#define VERSION_NAME   "Mozilla"

Definition at line 97 of file VerReg.c.

#define VERSTR   "Version"

Definition at line 87 of file VerReg.c.


Function Documentation

static XP_Bool vr_CompareDirs ( char *  dir1,
char *  dir2 
) [static]

Definition at line 303 of file VerReg.c.

{
    int len1,len2;
   
    XP_ASSERT( dir1 && dir2 );
    if (!dir1 || !dir2) return FALSE;

    len1 = XP_STRLEN( dir1 );
    len2 = XP_STRLEN( dir2 );

    if ( dir1[len1-1] == VR_FILE_SEP )
        len1--;
    if ( dir2[len2-1] == VR_FILE_SEP )
        len2--;

    if ( len1 != len2 )
        return FALSE;

#if defined(XP_UNIX) && !defined(XP_MACOSX)
    return ( XP_STRNCMP(dir1, dir2, len1) == 0 );
#else
    return ( XP_STRNCASECMP(dir1, dir2, len1) == 0 );
#endif
}

Here is the caller graph for this function:

static REGERR vr_convertPackageName ( char *  regPackageName,
char *  convertedPackageName,
uint32  convertedDataLength 
) [static]

Replaces all '/' with '_',in the given string.If an '_' already exists in the given string, it is escaped by adding another '_' to it.

Definition at line 1239 of file VerReg.c.

{
    uint32 length = 0;
    uint32 i;
    uint32 j = 0;

    length = XP_STRLEN(regPackageName);
    
    if (convertedDataLength <= length)
        return REGERR_BUFTOOSMALL;

    for (i=0, j=0; i<length; i++, j++)
    {
        if (j < (convertedDataLength-1))
        {
            convertedPackageName[j] = regPackageName[i];
        }
        else
        {
            return REGERR_BUFTOOSMALL;
        }
        if (regPackageName[i] == '_')
        {
            if ((j+1) < (convertedDataLength-1))
            {
                convertedPackageName[j+1] = '_';
            }
            else
            {
                return REGERR_BUFTOOSMALL;
            }
            j = j + 1;
        }
    }

    if (convertedPackageName[j-1] == '/')
        convertedPackageName[j-1] = '\0';
    else
    {
        if (j < convertedDataLength)
        {
            convertedPackageName[j] = '\0';
        }
        else
        {
            return REGERR_BUFTOOSMALL;
        }
    }

    length = 0;
    length = XP_STRLEN(convertedPackageName);
    for (i=1; i<length; i++)
    {
        if (convertedPackageName[i] == '/')
            convertedPackageName[i] = '_';
    }

    return REGERR_OK;
}
static REGERR vr_FindKey ( char *  name,
HREG hreg,
RKEY key 
) [static]

Definition at line 654 of file VerReg.c.

{
    REGERR err = REGERR_NOFIND;
    RKEY rootkey;

#if !defined(STANDALONE_REGISTRY) && defined(XP_UNIX) && !defined(XP_MACOSX)
    if (unixreg != NULL) {
        *hreg = unixreg;
        rootkey = UNIX_ROOT(component_path);
        if (rootkey)
            err = NR_RegGetKey( *hreg, rootkey, component_path, key );
        else
            err = REGERR_NOFIND;
    }
    if (unixreg == NULL || err == REGERR_NOFIND ) 
#endif
    {
        *hreg = vreg;
        rootkey = PATH_ROOT(component_path);
        if (rootkey)
            err = NR_RegGetKey( *hreg, rootkey, component_path, key );
        else
            err = REGERR_NOFIND;
    }

    return err;
}
static REGERR vr_GetPathname ( HREG  reg,
RKEY  key,
char *  entry,
char *  buf,
uint32  sizebuf 
) [static]

Definition at line 448 of file VerReg.c.

{
    REGERR  err;
    REGINFO info;
    
    info.size = sizeof(REGINFO);
        
#if !defined(XP_MAC) && !defined(XP_MACOSX)
        err = NR_RegGetEntry( reg, key, entry, (void*)buf, &sizebuf );
        return err;
#else
    
    err = NR_RegGetEntryInfo( reg, key, entry, &info );
    
    if (err != REGERR_OK)
        return err;
    
    if (info.entryType == REGTYPE_ENTRY_FILE ||
        info.entryType == REGTYPE_ENTRY_STRING_UTF )
    {
        err = NR_RegGetEntry( reg, key, entry, (void*)buf, &sizebuf );  
    }
    else if (info.entryType == REGTYPE_ENTRY_BYTES)
    {

        extern char * nr_PathFromMacAlias(const void * alias, uint32 aliasLength);

        #define MAC_ALIAS_BUFFER_SIZE 4000
        char stackBuf[MAC_ALIAS_BUFFER_SIZE];
        uint32 stackBufSize = MAC_ALIAS_BUFFER_SIZE;
        char * tempBuf;

        err = NR_RegGetEntry( reg, key, entry, (void*)stackBuf, &stackBufSize );

        if (err != REGERR_OK)
            return err;

        tempBuf = nr_PathFromMacAlias(stackBuf, stackBufSize);

        if (tempBuf == NULL) 
        {
            /* don't change error w/out changing vr_SetCurrentNav to match */
            buf[0] = '\0';
            err = REGERR_NOFILE;
         }
        else 
        {
            if (XP_STRLEN(tempBuf) > sizebuf)
                err = REGERR_BUFTOOSMALL;
            else
                XP_STRCPY(buf, tempBuf);

            XP_FREE(tempBuf);
        }
    }
    else
    {
        /* what did we put here?? */
        err = REGERR_BADTYPE;
    }
    
    return err;

#endif 
    
}

Here is the caller graph for this function:

static REGERR vr_GetUninstallItemPath ( char *  regPackageName,
char *  regbuf,
uint32  regbuflen 
) [static]

Definition at line 1166 of file VerReg.c.

{
    XP_Bool bSharedUninstall = FALSE;
    XP_Bool bNavPackage = FALSE;
    uint32 len = 0;
    uint32 sharedstrlen = 0;
    uint32 curstrlen = 0;
    uint32 curregbuflen = 0;

    /* determine install type */
    if (*regPackageName == '\0') {
        bNavPackage = TRUE;
    }
    else if ( *regPackageName == PATHDEL) {
        bSharedUninstall = TRUE;
    }

    /* create uninstall path prefix */
    len = XP_STRLEN(REG_UNINSTALL_DIR);
    if (len < regbuflen)
    {
        XP_STRCPY( regbuf, REG_UNINSTALL_DIR );
    }
    else
    {
        return REGERR_BUFTOOSMALL;
    }
    if (bSharedUninstall)
    {
        sharedstrlen = XP_STRLEN(SHAREDSTR);
        if (sharedstrlen < (regbuflen - len))
            XP_STRCAT( regbuf, SHAREDSTR );
        else 
            return REGERR_BUFTOOSMALL;
    }
    else
    {
        curstrlen = XP_STRLEN(gCurstr);
        if (curstrlen < (regbuflen - len))
            XP_STRCAT( regbuf, gCurstr );
        else 
            return REGERR_BUFTOOSMALL;
        if (1 < (regbuflen - len - curstrlen))
            XP_STRCAT( regbuf, "/" );
        else 
            return REGERR_BUFTOOSMALL;
    }  

    /* add final uninstall node name */
    len = 0;
    curregbuflen = XP_STRLEN(regbuf);
    if ( bNavPackage ) {
        len = XP_STRLEN(UNINSTALL_NAV_STR);
        if (len < (regbuflen - curregbuflen))
            XP_STRCAT( regbuf, UNINSTALL_NAV_STR );
        else 
            return REGERR_BUFTOOSMALL;
    }
    else {
        len = XP_STRLEN(regPackageName);
        if (len < (regbuflen - curregbuflen))
            XP_STRCAT( regbuf, regPackageName );
        else 
            return REGERR_BUFTOOSMALL;
    }
    return REGERR_OK;
}
static REGERR vr_Init ( void  ) [static]

Definition at line 168 of file VerReg.c.

{

    REGERR  err = REGERR_OK;
    char    *regname = vr_findVerRegName();
#if defined(XP_UNIX) && !defined(XP_MACOSX) || defined(STANDALONE_REGISTRY)
    char    curstr[MAXREGNAMELEN];
    RKEY    navKey;
#endif
#if defined(XP_UNIX) && !defined(XP_MACOSX)
    char    *regbuf = NULL;
#endif

#ifndef STANDALONE_REGISTRY
    if (vr_lock == NULL)
        return REGERR_FAIL;
#endif
    PR_Lock(vr_lock);

    if (!isInited)
    {
#if defined(XP_UNIX) && !defined(XP_MACOSX)
        /* need browser directory to find the correct registry */
        if (app_dir != NULL) {
            regbuf = (char*)XP_ALLOC( 10 + XP_STRLEN(app_dir) );
            if (regbuf != NULL ) {
                XP_STRCPY( regbuf, app_dir );
                XP_STRCAT( regbuf, "/registry" );
            } 
            else {
                err = REGERR_MEMORY;
            }
        } 
        if ( err != REGERR_OK )
            goto done;

        if (bGlobalRegistry) 
            regname = regbuf;
#endif

        /* Open version registry */
        err = NR_RegOpen( regname, &vreg );

#ifndef STANDALONE_REGISTRY
        if (err == REGERR_OK) 
        {
            /* find/set the current nav node */
            err = vr_SetCurrentNav( VERSION_NAME, app_dir, NULL );
            if ( REGERR_OK != err ) {
                /* couldn't find or set current nav -- big problems! */
                NR_RegClose( vreg );
                goto done;
            }
        }

#if defined(XP_UNIX) && !defined(XP_MACOSX)
        /* try to open shared Unix registry, but not an error if you can't */
        unixreg = NULL;
        if (!bGlobalRegistry && err == REGERR_OK ) {
            unixver = 0;
            if (NR_RegOpen( regbuf, &unixreg ) == REGERR_OK) {
                if (NR_RegGetKey( unixreg, ROOTKEY_VERSIONS, NAVIGATOR_NODE, 
                    &navKey) == REGERR_OK) 
                {
                    if (NR_RegGetEntryString( unixreg, navKey, CURRENT_VER,
                        curstr, sizeof(curstr)) == REGERR_OK ) 
                    {
                        NR_RegGetKey( unixreg, navKey, curstr, &unixver );
                    }
                }
            }
        }
#endif

        if (err == REGERR_OK) {
            /* successfully opened! */
            isInited = 1;
        }
        goto done;
#else
        if (err != REGERR_OK)
            goto done;

        /* Determine 'curver' key and ensure correct structure by adding */

        /* ...find top-level "Navigator" node (add if missing) */
        err = NR_RegAddKey( vreg, ROOTKEY_VERSIONS, NAVIGATOR_NODE, &navKey );
        if (err != REGERR_OK)
            goto done;

        /* ...look for "Current Version" entry */
        err = NR_RegGetEntryString( vreg, navKey, CURRENT_VER, curstr,
                                    sizeof(curstr) );
        if ( err == REGERR_NOFIND ) {
            /* If not found create one with the built-in version */
            err = NR_RegSetEntryString( vreg, navKey, CURRENT_VER, VERSION_NAME );
            XP_STRCPY( curstr, VERSION_NAME );
        }
        if ( err != REGERR_OK )
            goto done;

        /* ...look for "curstr" child key of the navigator node */
        err = NR_RegAddKey( vreg, navKey, curstr, &curver );

        if (err == REGERR_OK) {
            /* successfully opened! */
            isInited = 1;
        }
#endif
    }

done:
    PR_Unlock(vr_lock);
#if defined(XP_UNIX) && !defined(XP_MACOSX) && !defined(STANDALONE_REGISTRY)
    XP_FREEIF(regbuf);
#endif
    return err;

}   /* Init */

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 694 of file VerReg.c.

{
    REGERR err;

    /* make sure vreg (src) is open */
    err = vr_Init();
    if (err != REGERR_OK)
        return err;

    err = NR_RegPack( vreg, userData, fn );

    return err;

}   /* PackRegistry */

Here is the call graph for this function:

REGERR vr_ParseVersion ( char *  verstr,
VERSION result 
) [static]

Definition at line 329 of file VerReg.c.

{

    result->major = result->minor = result->release = result->build = 0;
    result->major = atoi(verstr);
    while (*verstr && *verstr != '.')
        verstr++;
    if (*verstr)
    {
        verstr++;
        result->minor = atoi(verstr);
        while (*verstr && *verstr != '.')
            verstr++;
        if (*verstr)
        {
            verstr++;
            result->release = atoi(verstr);
            while (*verstr && *verstr != '.')
                verstr++;
            if (*verstr)
            {
                verstr++;
                result->build = atoi(verstr);
                while (*verstr && *verstr != '.')
                    verstr++;
            }
        }
    }

    return REGERR_OK;

}   /* ParseVersion */
static REGERR vr_SetCurrentNav ( char *  product,
char *  programPath,
char *  versionStr 
) [static]

Definition at line 519 of file VerReg.c.

{
    REGERR      err;
    REGENUM     state;
    RKEY        navKey;
    int         bFound;
    int         nCopy;
    char        regname[MAXREGNAMELEN];
    char        dirbuf[MAXREGNAMELEN];

    XP_ASSERT( installation ); /* required */
    XP_ASSERT( programPath );  /* required */
    if ( !installation || !programPath )
        return REGERR_PARAM;

    err = NR_RegAddKey( vreg, ROOTKEY_VERSIONS, NAVIGATOR_NODE, &navKey );
    if (err != REGERR_OK)
        goto done;

    /* ...look for "Current Version" entry */
    err = NR_RegGetEntryString( vreg, navKey, CURRENT_VER, gCurstr, sizeof(gCurstr));
    if ( err == REGERR_NOFIND )
    {
        /* No current installation, we can simply add a new one  */
        err = NR_RegAddKey( vreg, navKey, installation, &curver );

        /* ... add Path and Version properties */
        if ( err == REGERR_OK ) 
        {
            err = vr_SetPathname( vreg, curver, NAVHOME, programPath );
            if ( REGERR_OK == err && versionStr != NULL && *versionStr != '\0')
            {
                err = NR_RegSetEntryString( vreg, curver, VERSTR, versionStr );
            }
        }

        if ( REGERR_OK == err ) {
            /* successfully added, make it the current version */
            err = NR_RegSetEntryString(vreg, navKey, CURRENT_VER, installation);
        }

        if (err != REGERR_OK)
            goto done;
    }
    else if ( REGERR_OK == err )
    {
        /* found one: if we're lucky we got the right one */
        bFound = FALSE;
        err = NR_RegGetKey( vreg, navKey, gCurstr, &curver );
        if ( REGERR_OK == err ) {
            err = vr_GetPathname( vreg, curver, NAVHOME, dirbuf, sizeof(dirbuf) );
            if ( REGERR_OK == err ) {
                bFound = vr_CompareDirs(dirbuf, programPath);
            }
            else if ( REGERR_NOFIND == err ) {
                /* assume this is the right one since it's 'Current' */
                err = vr_SetPathname( vreg, curver, NAVHOME, programPath );
                bFound = TRUE;
            }
        }
        
        /* Look for an existing installation if not found */
        state = 0;
        while (!bFound && ((err == REGERR_OK) || (err == REGERR_NOFILE)) ) {
            err = NR_RegEnumSubkeys( vreg, navKey, &state, gCurstr,
                    sizeof(gCurstr), REGENUM_NORMAL );

            if (REGERR_OK == err ) {
                err = vr_GetPathname( vreg, state, NAVHOME, dirbuf, sizeof(dirbuf) );
                if (REGERR_OK == err ) {
                    if (vr_CompareDirs( dirbuf, programPath )) {
                        bFound = TRUE;
                        curver = (RKEY)state;
                    }
                }
                else if ( err == REGERR_NOFIND ) {
                    /* wasn't a navigator node */
                    err = REGERR_OK;
                }
            }
        }

        /* found the right one, make it current */
        if (bFound) {
            err = NR_RegSetEntryString( vreg, navKey, CURRENT_VER, gCurstr );
            /* update version (curver already set) */
            if ( REGERR_OK == err && versionStr != NULL && *versionStr != '\0' ) {
                err = NR_RegSetEntryString( vreg, curver, VERSTR, versionStr );
            }
        }
        /* otherwise if no current installation matches */
        else if ( err == REGERR_NOMORE )
        {
            /* look for an empty slot to put new installation */
            nCopy = 1;
            XP_STRCPY( regname, installation );
            do {
                err = NR_RegGetKey( vreg, navKey, regname, &curver );
                if (err == REGERR_OK) {
                    nCopy++;
                    sprintf( regname, "%s #%d", installation, nCopy );
                }
            } while (err==REGERR_OK);

            if (err != REGERR_NOFIND)
                goto done;  /* real error, bail */

            /* found an unused name -- add it */
            err = NR_RegAddKey( vreg, navKey, regname, &curver );
            if ( err != REGERR_OK )
                goto done;

            /* add path and version properties */
            err = vr_SetPathname( vreg, curver, NAVHOME, programPath );
            if ( REGERR_OK == err && versionStr != NULL && *versionStr != '\0' ) {
                err = NR_RegSetEntryString( vreg, curver, VERSTR, versionStr );
            }

            if ( REGERR_OK == err ) {
                /* everything's OK, make it current */
                err = NR_RegSetEntryString(vreg,navKey,CURRENT_VER,regname);
            }
        }
    }
done:
    return err;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static REGERR vr_SetPathname ( HREG  reg,
RKEY  key,
char *  entry,
char *  dir 
) [static]

Definition at line 436 of file VerReg.c.

{
    REGERR err;
    int32  datalen = XP_STRLEN(dir)+1; /* include '\0' */

    err = NR_RegSetEntry( reg, key, entry, REGTYPE_ENTRY_FILE, dir, datalen);

    return err;
}

Here is the caller graph for this function:

static REGERR vr_unmanglePackageName ( char *  mangledPackageName,
char *  regPackageName,
uint32  regPackageLength 
) [static]

Definition at line 1299 of file VerReg.c.

{
    uint32 length = 0;
    uint32 i = 0;
    uint32 j = 0;

    length = XP_STRLEN(mangledPackageName);
    
    if (regPackageLength <= length)
        return REGERR_BUFTOOSMALL;

    while (i < length)
    {
        if ((mangledPackageName[i] != '_') || (i == length-1)){
            if (j < (regPackageLength - 1))
                regPackageName[j] = mangledPackageName[i];
            else
                return REGERR_BUFTOOSMALL;
            j = j + 1;  
            i = i + 1;
        } else if (mangledPackageName[i + 1] != '_') { 
            if (j < (regPackageLength - 1))
                regPackageName[j] = '/';
            else
                return REGERR_BUFTOOSMALL;
            j = j + 1;
            i = i + 1;
        } else {
            if (j < (regPackageLength - 1))
                regPackageName[j] = '_';
            else
                return REGERR_BUFTOOSMALL;
            j = j + 1;
            i = i + 2;
        }
    }
    if (j < regPackageLength)
        regPackageName[j] = '\0';
    else
        return REGERR_BUFTOOSMALL;
    return REGERR_OK;
}

Variable Documentation

char* app_dir = NULL [static]

Definition at line 115 of file VerReg.c.

RKEY curver = 0 [static]

Definition at line 110 of file VerReg.c.

char gCurstr[MAXREGNAMELEN] [static]

Definition at line 111 of file VerReg.c.

int isInited = 0 [static]

Definition at line 109 of file VerReg.c.

char* verRegName = NULL

Definition at line 117 of file VerReg.c.

Definition at line 135 of file VerReg.c.

HREG vreg = 0 [static]

Definition at line 113 of file VerReg.c.