/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
 * This file is meant to be included by other .c files.
 * This file takes a "parameter", the scope which includes this
 * code shall declare this variable:
 *   const char *NameOfThisSharedLib;
 *
 * NameOfThisSharedLib:
 *   The file name of the shared library that shall be used as the
 *   "reference library". The loader will attempt to load the requested
 *   library from the same directory as the reference library.
 */

#ifdef XP_UNIX
#include <unistd.h>
#define BL_MAXSYMLINKS 20

/*
 * If 'link' is a symbolic link, this function follows the symbolic links
 * and returns the pathname of the ultimate source of the symbolic links.
 * If 'link' is not a symbolic link, this function returns NULL.
 * The caller should call PR_Free to free the string returned by this
 * function.
 */
static char*
loader_GetOriginalPathname(const char* link)
{
#ifdef __GLIBC__
    char* tmp = realpath(link, NULL);
    char* resolved;
    if (!tmp)
        return NULL;
    resolved = PR_Malloc(strlen(tmp) + 1);
    strcpy(resolved, tmp); /* This is necessary because PR_Free might not be using free() */
    free(tmp);
    return resolved;
#else
    char* resolved = NULL;
    char* input = NULL;
    PRUint32 iterations = 0;
    PRInt32 len = 0, retlen = 0;
    if (!link) {
        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
        return NULL;
    }
    len = PR_MAX(1024, strlen(link) + 1);
    resolved = PR_Malloc(len);
    input = PR_Malloc(len);
    if (!resolved || !input) {
        if (resolved) {
            PR_Free(resolved);
        }
        if (input) {
            PR_Free(input);
        }
        return NULL;
    }
    strcpy(input, link);
    while ((iterations++ < BL_MAXSYMLINKS) &&
           ((retlen = readlink(input, resolved, len - 1)) > 0)) {
        char* tmp = input;
        resolved[retlen] = '\0'; /* NULL termination */
        input = resolved;
        resolved = tmp;
    }
    PR_Free(resolved);
    if (iterations == 1 && retlen < 0) {
        PR_Free(input);
        input = NULL;
    }
    return input;
#endif
}
#endif /* XP_UNIX */

/*
 * Load the library with the file name 'name' residing in the same
 * directory as the reference library, whose pathname is 'referencePath'.
 */
static PRLibrary*
loader_LoadLibInReferenceDir(const char* referencePath, const char* name)
{
    PRLibrary* dlh = NULL;
    char* fullName = NULL;
    char* c;
    PRLibSpec libSpec;

    /* Remove the trailing filename from referencePath and add the new one */
    c = strrchr(referencePath, PR_GetDirectorySeparator());
    if (c) {
        size_t referencePathSize = 1 + c - referencePath;
        fullName = (char*)PORT_Alloc(strlen(name) + referencePathSize + 1);
        if (fullName) {
            memcpy(fullName, referencePath, referencePathSize);
            strcpy(fullName + referencePathSize, name);
#ifdef DEBUG_LOADER
            PR_fprintf(PR_STDOUT, "\nAttempting to load fully-qualified %s\n",
                       fullName);
#endif
            libSpec.type = PR_LibSpec_Pathname;
            libSpec.value.pathname = fullName;
            dlh = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL);
            PORT_Free(fullName);
        }
    }
    return dlh;
}

/*
 * We use PR_GetLibraryFilePathname to get the pathname of the loaded
 * shared lib that contains this function, and then do a PR_LoadLibrary
 * with an absolute pathname for the softoken shared library.
 */

static PRLibrary*
loader_LoadLibrary(const char* nameToLoad)
{
    PRLibrary* lib = NULL;
    char* fullPath = NULL;
    PRLibSpec libSpec;

    /* Get the pathname for nameOfAlreadyLoadedLib, i.e. /usr/lib/libnss3.so
     * PR_GetLibraryFilePathname works with either the base library name or a
     * function pointer, depending on the platform. We can't query an exported
     * symbol such as NSC_GetFunctionList, because on some platforms we can't
     * find symbols in loaded implicit dependencies.
     * But we can just get the address of this function !
     */
    fullPath = PR_GetLibraryFilePathname(NameOfThisSharedLib,
                                         (PRFuncPtr)&loader_LoadLibrary);

    if (fullPath) {
        lib = loader_LoadLibInReferenceDir(fullPath, nameToLoad);
#ifdef XP_UNIX
        if (!lib) {
            /*
             * If fullPath is a symbolic link, resolve the symbolic
             * link and try again.
             */
            char* originalfullPath = loader_GetOriginalPathname(fullPath);
            if (originalfullPath) {
                PR_Free(fullPath);
                fullPath = originalfullPath;
                lib = loader_LoadLibInReferenceDir(fullPath, nameToLoad);
            }
        }
#endif
        PR_Free(fullPath);
    }
    if (!lib) {
#ifdef DEBUG_LOADER
        PR_fprintf(PR_STDOUT, "\nAttempting to load %s\n", nameToLoad);
#endif
        libSpec.type = PR_LibSpec_Pathname;
        libSpec.value.pathname = nameToLoad;
        lib = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL);
    }
    if (NULL == lib) {
#ifdef DEBUG_LOADER
        PR_fprintf(PR_STDOUT, "\nLoading failed : %s.\n", nameToLoad);
#endif
    }
    return lib;
}
