/*
 * loader.c - load platform dependent DSO containing freebl implementation.
 *
 * 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/. */

#define _GNU_SOURCE 1
#include "loader.h"
#include "prmem.h"
#include "prerror.h"
#include "prinit.h"
#include "prenv.h"
#include "blname.c"

#include "prio.h"
#include "prprf.h"
#include <stdio.h>
#include "prsystem.h"
#include "nsslowhash.h"
#include <dlfcn.h>
#include "pratom.h"

static PRLibrary *blLib;

#define LSB(x) ((x)&0xff)
#define MSB(x) ((x) >> 8)

static const NSSLOWVector *vector;
static const char *libraryName = NULL;

/* pretty much only glibc uses this, make sure we don't have any depenencies
 * on nspr.. */
#undef PORT_Alloc
#undef PORT_Free
#define PORT_Alloc malloc
#define PR_Malloc malloc
#define PORT_Free free
#define PR_Free free
#define PR_GetDirectorySeparator() '/'
#define PR_LoadLibraryWithFlags(libspec, flags) \
    (PRLibrary *)dlopen(libSpec.value.pathname, RTLD_NOW | RTLD_LOCAL)
#define PR_GetLibraryFilePathname(name, addr) \
    freebl_lowhash_getLibraryFilePath(addr)

static char *
freebl_lowhash_getLibraryFilePath(void *addr)
{
    Dl_info dli;
    if (dladdr(addr, &dli) == 0) {
        return NULL;
    }
    return strdup(dli.dli_fname);
}

/*
 * The PR_LoadLibraryWithFlags call above defines this variable away, so we
 * don't need it..
 */
#ifdef nodef
static const char *NameOfThisSharedLib =
    SHLIB_PREFIX "freebl" SHLIB_VERSION "." SHLIB_SUFFIX;
#endif

#include "genload.c"

/* This function must be run only once. */
/*  determine if hybrid platform, then actually load the DSO. */
static PRStatus
freebl_LoadDSO(void)
{
    PRLibrary *handle;
    const char *name = getLibName();

    if (!name) {
        /*PR_SetError(PR_LOAD_LIBRARY_ERROR,0); */
        return PR_FAILURE;
    }
    handle = loader_LoadLibrary(name);
    if (handle) {
        void *address = dlsym(handle, "NSSLOW_GetVector");
        if (address) {
            NSSLOWGetVectorFn *getVector = (NSSLOWGetVectorFn *)address;
            const NSSLOWVector *dsoVector = getVector();
            if (dsoVector) {
                unsigned short dsoVersion = dsoVector->version;
                unsigned short myVersion = NSSLOW_VERSION;
                if (MSB(dsoVersion) == MSB(myVersion) &&
                    LSB(dsoVersion) >= LSB(myVersion) &&
                    dsoVector->length >= sizeof(NSSLOWVector)) {
                    vector = dsoVector;
                    libraryName = name;
                    blLib = handle;
                    return PR_SUCCESS;
                }
            }
        }
        (void)dlclose(handle);
    }
    return PR_FAILURE;
}

static PRCallOnceType loadFreeBLOnce;

static void
freebl_RunLoaderOnce(void)
{
    /* Don't have NSPR, so can use the real PR_CallOnce, implement a stripped
     * down version. */
    if (loadFreeBLOnce.initialized) {
        return;
    }
    if (__sync_lock_test_and_set(&loadFreeBLOnce.inProgress, 1) == 0) {
        loadFreeBLOnce.status = freebl_LoadDSO();
        loadFreeBLOnce.initialized = 1;
    } else {
        /* shouldn't have a lot of takers on the else clause, which is good
         * since we don't have condition variables yet.
         * 'initialized' only ever gets set (not cleared) so we don't
         * need the traditional locks. */
        while (!loadFreeBLOnce.initialized) {
            sleep(1); /* don't have condition variables, just give up the CPU */
        }
    }
}

static const NSSLOWVector *
freebl_InitVector(void)
{
    if (!vector) {
        freebl_RunLoaderOnce();
    }
    return vector;
}

const FREEBLVector *
FREEBL_GetVector(void)
{
    if (freebl_InitVector()) {
        return (vector->p_FREEBL_GetVector)();
    }
    return NULL;
}

NSSLOWInitContext *
NSSLOW_Init(void)
{
    if (freebl_InitVector()) {
        return (vector->p_NSSLOW_Init)();
    }
    return NULL;
}

void
NSSLOW_Shutdown(NSSLOWInitContext *context)
{
    if (freebl_InitVector()) {
        (vector->p_NSSLOW_Shutdown)(context);
    }
}

void
NSSLOW_Reset(NSSLOWInitContext *context)
{
    if (freebl_InitVector()) {
        (vector->p_NSSLOW_Reset)(context);
    }
}

NSSLOWHASHContext *
NSSLOWHASH_NewContext(
    NSSLOWInitContext *initContext,
    HASH_HashType hashType)
{
    if (freebl_InitVector()) {
        return (vector->p_NSSLOWHASH_NewContext)(initContext, hashType);
    }
    return NULL;
}

void
NSSLOWHASH_Begin(NSSLOWHASHContext *context)
{
    if (freebl_InitVector()) {
        (vector->p_NSSLOWHASH_Begin)(context);
    }
}

void
NSSLOWHASH_Update(NSSLOWHASHContext *context,
                  const unsigned char *buf,
                  unsigned int len)
{
    if (freebl_InitVector()) {
        (vector->p_NSSLOWHASH_Update)(context, buf, len);
    }
}

void
NSSLOWHASH_End(NSSLOWHASHContext *context,
               unsigned char *buf,
               unsigned int *ret, unsigned int len)
{
    if (freebl_InitVector()) {
        (vector->p_NSSLOWHASH_End)(context, buf, ret, len);
    }
}

void
NSSLOWHASH_Destroy(NSSLOWHASHContext *context)
{
    if (freebl_InitVector()) {
        (vector->p_NSSLOWHASH_Destroy)(context);
    }
}

unsigned int
NSSLOWHASH_Length(NSSLOWHASHContext *context)
{
    if (freebl_InitVector()) {
        return (vector->p_NSSLOWHASH_Length)(context);
    }
    return -1;
}
