/* 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/. */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "nss.h"
#include "secutil.h"
#include "pk11pub.h"
#include "cert.h"

typedef struct commandDescriptStr {
    int required;
    char *arg;
    char *des;
} commandDescript;

enum optionNames {
    opt_liborder = 0,
    opt_mainDB,
    opt_lib1DB,
    opt_lib2DB,
    opt_mainRO,
    opt_lib1RO,
    opt_lib2RO,
    opt_mainCMD,
    opt_lib1CMD,
    opt_lib2CMD,
    opt_mainTokNam,
    opt_lib1TokNam,
    opt_lib2TokNam,
    opt_oldStyle,
    opt_verbose,
    opt_summary,
    opt_help,
    opt_last
};

static const secuCommandFlag options_init[] =
    {
      { /* opt_liborder */ 'o', PR_TRUE, "1M2zmi", PR_TRUE, "order" },
      { /* opt_mainDB */ 'd', PR_TRUE, 0, PR_FALSE, "main_db" },
      { /* opt_lib1DB */ '1', PR_TRUE, 0, PR_FALSE, "lib1_db" },
      { /* opt_lib2DB */ '2', PR_TRUE, 0, PR_FALSE, "lib2_db" },
      { /* opt_mainRO */ 'r', PR_FALSE, 0, PR_FALSE, "main_readonly" },
      { /* opt_lib1RO */ 0, PR_FALSE, 0, PR_FALSE, "lib1_readonly" },
      { /* opt_lib2RO */ 0, PR_FALSE, 0, PR_FALSE, "lib2_readonly" },
      { /* opt_mainCMD */ 'c', PR_TRUE, 0, PR_FALSE, "main_command" },
      { /* opt_lib1CMD */ 0, PR_TRUE, 0, PR_FALSE, "lib1_command" },
      { /* opt_lib2CMD */ 0, PR_TRUE, 0, PR_FALSE, "lib2_command" },
      { /* opt_mainTokNam */ 't', PR_TRUE, 0, PR_FALSE, "main_token_name" },
      { /* opt_lib1TokNam */ 0, PR_TRUE, 0, PR_FALSE, "lib1_token_name" },
      { /* opt_lib2TokNam */ 0, PR_TRUE, 0, PR_FALSE, "lib2_token_name" },
      { /* opt_oldStype */ 's', PR_FALSE, 0, PR_FALSE, "oldStype" },
      { /* opt_verbose */ 'v', PR_FALSE, 0, PR_FALSE, "verbose" },
      { /* opt_summary */ 'z', PR_FALSE, 0, PR_FALSE, "summary" },
      { /* opt_help */ 'h', PR_FALSE, 0, PR_FALSE, "help" }
    };

static const commandDescript options_des[] =
    {
      { /* opt_liborder */ PR_FALSE, "initOrder",
        " Specifies the order of NSS initialization and shutdown. Order is\n"
        " given as a string where each character represents either an init or\n"
        " a shutdown of the main program or one of the 2 test libraries\n"
        " (library 1 and library 2). The valid characters are as follows:\n"
        "   M Init the main program\n   1 Init library 1\n"
        "   2 Init library 2\n"
        "   m Shutdown the main program\n   i Shutdown library 1\n"
        "   z Shutdown library 2\n" },
      { /* opt_mainDB */ PR_TRUE, "nss_db",
        " Specified the directory to open the nss database for the main\n"
        " program. Must be specified if \"M\" is given in the order string\n" },
      { /* opt_lib1DB */ PR_FALSE, "nss_db",
        " Specified the directory to open the nss database for library 1.\n"
        " Must be specified if \"1\" is given in the order string\n" },
      { /* opt_lib2DB */ PR_FALSE, "nss_db",
        " Specified the directory to open the nss database for library 2.\n"
        " Must be specified if \"2\" is given in the order string\n" },
      { /* opt_mainRO */ PR_FALSE, NULL,
        " Open the main program's database read only.\n" },
      { /* opt_lib1RO */ PR_FALSE, NULL,
        " Open library 1's database read only.\n" },
      { /* opt_lib2RO */ PR_FALSE, NULL,
        " Open library 2's database read only.\n" },
      { /* opt_mainCMD */ PR_FALSE, "nss_command",
        " Specifies the NSS command to execute in the main program.\n"
        " Valid commands are: \n"
        "   key_slot, list_slots, list_certs, add_cert, none.\n"
        " Default is \"none\".\n" },
      { /* opt_lib1CMD */ PR_FALSE, "nss_command",
        " Specifies the NSS command to execute in library 1.\n" },
      { /* opt_lib2CMD */ PR_FALSE, "nss_command",
        " Specifies the NSS command to execute in library 2.\n" },
      { /* opt_mainTokNam */ PR_FALSE, "token_name",
        " Specifies the name of PKCS11 token for the main program's "
        "database.\n" },
      { /* opt_lib1TokNam */ PR_FALSE, "token_name",
        " Specifies the name of PKCS11 token for library 1's database.\n" },
      { /* opt_lib2TokNam */ PR_FALSE, "token_name",
        " Specifies the name of PKCS11 token for library 2's database.\n" },
      { /* opt_oldStype */ PR_FALSE, NULL,
        " Use NSS_Shutdown rather than NSS_ShutdownContext in the main\n"
        " program.\n" },
      { /* opt_verbose */ PR_FALSE, NULL,
        " Noisily output status to standard error\n" },
      { /* opt_summarize */ PR_FALSE, NULL,
        "report a summary of the test results\n" },
      { /* opt_help */ PR_FALSE, NULL, " give this message\n" }
    };

/*
 * output our short help (table driven). (does not exit).
 */
static void
short_help(const char *prog)
{
    int count = opt_last;
    int i, words_found;

    /* make sure all the tables are up to date before we allow compiles to
     * succeed */
    PR_STATIC_ASSERT(sizeof(options_init) / sizeof(secuCommandFlag) == opt_last);
    PR_STATIC_ASSERT(sizeof(options_init) / sizeof(secuCommandFlag) ==
                     sizeof(options_des) / sizeof(commandDescript));

    /* print the base usage */
    fprintf(stderr, "usage: %s ", prog);
    for (i = 0, words_found = 0; i < count; i++) {
        if (!options_des[i].required) {
            fprintf(stderr, "[");
        }
        if (options_init[i].longform) {
            fprintf(stderr, "--%s", options_init[i].longform);
            words_found++;
        } else {
            fprintf(stderr, "-%c", options_init[i].flag);
        }
        if (options_init[i].needsArg) {
            if (options_des[i].arg) {
                fprintf(stderr, " %s", options_des[i].arg);
            } else {
                fprintf(stderr, " arg");
            }
            words_found++;
        }
        if (!options_des[i].required) {
            fprintf(stderr, "]");
        }
        if (i < count - 1) {
            if (words_found >= 5) {
                fprintf(stderr, "\n      ");
                words_found = 0;
            } else {
                fprintf(stderr, " ");
            }
        }
    }
    fprintf(stderr, "\n");
}

/*
 * print out long help. like short_help, this does not exit
 */
static void
long_help(const char *prog)
{
    int i;
    int count = opt_last;

    short_help(prog);
    /* print the option descriptions */
    fprintf(stderr, "\n");
    for (i = 0; i < count; i++) {
        fprintf(stderr, "        ");
        if (options_init[i].flag) {
            fprintf(stderr, "-%c", options_init[i].flag);
            if (options_init[i].longform) {
                fprintf(stderr, ",");
            }
        }
        if (options_init[i].longform) {
            fprintf(stderr, "--%s", options_init[i].longform);
        }
        if (options_init[i].needsArg) {
            if (options_des[i].arg) {
                fprintf(stderr, " %s", options_des[i].arg);
            } else {
                fprintf(stderr, " arg");
            }
            if (options_init[i].arg) {
                fprintf(stderr, " (default = \"%s\")", options_init[i].arg);
            }
        }
        fprintf(stderr, "\n%s", options_des[i].des);
    }
}

/*
 * record summary data
 */
struct bufferData {
    char *data; /* lowest address of the buffer */
    char *next; /* pointer to the next element on the buffer */
    int len;    /* length of the buffer */
};

/* our actual buffer. If data is NULL, then all append ops
 * except are noops */
static struct bufferData buffer = { NULL, NULL, 0 };

#define CHUNK_SIZE 1000

/*
 * get our initial data. and set the buffer variables up. on failure,
 * just don't initialize the buffer.
 */
static void
initBuffer(void)
{
    buffer.data = PORT_Alloc(CHUNK_SIZE);
    if (!buffer.data) {
        return;
    }
    buffer.next = buffer.data;
    buffer.len = CHUNK_SIZE;
}

/*
 * grow the buffer. If we can't get more data, record a 'D' in the second
 * to last record and allow the rest of the data to overwrite the last
 * element.
 */
static void
growBuffer(void)
{
    char *new = PORT_Realloc(buffer.data, buffer.len + CHUNK_SIZE);
    if (!new) {
        buffer.data[buffer.len - 2] = 'D'; /* signal malloc failure in summary */
        /* buffer must always point to good memory if it exists */
        buffer.next = buffer.data + (buffer.len - 1);
        return;
    }
    buffer.next = new + (buffer.next - buffer.data);
    buffer.data = new;
    buffer.len += CHUNK_SIZE;
}

/*
 * append a label, doubles as appending a single character.
 */
static void
appendLabel(char label)
{
    if (!buffer.data) {
        return;
    }

    *buffer.next++ = label;
    if (buffer.data + buffer.len >= buffer.next) {
        growBuffer();
    }
}

/*
 * append a string onto the buffer. The result will be <string>
 */
static void
appendString(char *string)
{
    if (!buffer.data) {
        return;
    }

    appendLabel('<');
    while (*string) {
        appendLabel(*string++);
    }
    appendLabel('>');
}

/*
 * append a bool, T= true, F=false
 */
static void
appendBool(PRBool bool)
{
    if (!buffer.data) {
        return;
    }

    if (bool) {
        appendLabel('t');
    } else {
        appendLabel('f');
    }
}

/*
 * append a single hex nibble.
 */
static void
appendHex(unsigned char nibble)
{
    if (nibble <= 9) {
        appendLabel('0' + nibble);
    } else {
        appendLabel('a' + nibble - 10);
    }
}

/*
 * append a 32 bit integer (even on a 64 bit platform).
 * for simplicity append it as a hex value, full extension with 0x prefix.
 */
static void
appendInt(unsigned int value)
{
    int i;

    if (!buffer.data) {
        return;
    }

    appendLabel('0');
    appendLabel('x');
    value = value & 0xffffffff; /* only look at the buttom 8 bytes */
    for (i = 0; i < 8; i++) {
        appendHex(value >> 28);
        value = value << 4;
    }
}

/* append a trust flag */
static void
appendFlags(unsigned int flag)
{
    char trust[10];
    char *cp = trust;

    trust[0] = 0;
    printflags(trust, flag);
    while (*cp) {
        appendLabel(*cp++);
    }
}

/*
 * dump our buffer out with a result= flag so we can find it easily.
 * free the buffer as a side effect.
 */
static void
dumpBuffer(void)
{
    if (!buffer.data) {
        return;
    }

    appendLabel(0); /* terminate */
    printf("\nresult=%s\n", buffer.data);
    PORT_Free(buffer.data);
    buffer.data = buffer.next = NULL;
    buffer.len = 0;
}

/*
 * usage, like traditional usage, automatically exit
 */
static void
usage(const char *prog)
{
    short_help(prog);
    dumpBuffer();
    exit(1);
}

/*
 * like usage, except prints the long version of help
 */
static void
usage_long(const char *prog)
{
    long_help(prog);
    dumpBuffer();
    exit(1);
}

static const char *
bool2String(PRBool bool)
{
    return bool ? "true" : "false";
}

/*
 * print out interesting info about the given slot
 */
void
print_slot(PK11SlotInfo *slot, int log)
{
    if (log) {
        fprintf(stderr, "* Name=%s Token_Name=%s present=%s, ro=%s *\n",
                PK11_GetSlotName(slot), PK11_GetTokenName(slot),
                bool2String(PK11_IsPresent(slot)),
                bool2String(PK11_IsReadOnly(slot)));
    }
    appendLabel('S');
    appendString(PK11_GetTokenName(slot));
    appendBool(PK11_IsPresent(slot));
    appendBool(PK11_IsReadOnly(slot));
}

/*
 * list all our slots
 */
void
do_list_slots(const char *progName, int log)
{
    PK11SlotList *list;
    PK11SlotListElement *le;

    list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE, NULL);
    if (list == NULL) {
        fprintf(stderr, "ERROR: no tokens found %s\n",
                SECU_Strerror(PORT_GetError()));
        appendLabel('S');
        appendString("none");
        return;
    }

    for (le = PK11_GetFirstSafe(list); le;
         le = PK11_GetNextSafe(list, le, PR_TRUE)) {
        print_slot(le->slot, log);
    }
    PK11_FreeSlotList(list);
}

static PRBool
sort_CN(CERTCertificate *certa, CERTCertificate *certb, void *arg)
{
    char *commonNameA, *commonNameB;
    int ret;

    commonNameA = CERT_GetCommonName(&certa->subject);
    commonNameB = CERT_GetCommonName(&certb->subject);

    if (commonNameA == NULL) {
        PORT_Free(commonNameB);
        return PR_TRUE;
    }
    if (commonNameB == NULL) {
        PORT_Free(commonNameA);
        return PR_FALSE;
    }
    ret = PORT_Strcmp(commonNameA, commonNameB);
    PORT_Free(commonNameA);
    PORT_Free(commonNameB);
    return (ret < 0) ? PR_TRUE : PR_FALSE;
}

/*
 * list all the certs
 */
void
do_list_certs(const char *progName, int log)
{
    CERTCertList *list;
    CERTCertList *sorted;
    CERTCertListNode *node;
    CERTCertTrust trust;
    unsigned int i;

    list = PK11_ListCerts(PK11CertListUnique, NULL);
    if (list == NULL) {
        fprintf(stderr, "ERROR: no certs found %s\n",
                SECU_Strerror(PORT_GetError()));
        appendLabel('C');
        appendString("none");
        return;
    }

    sorted = CERT_NewCertList();
    if (sorted == NULL) {
        fprintf(stderr, "ERROR: no certs found %s\n",
                SECU_Strerror(PORT_GetError()));
        appendLabel('C');
        appendLabel('E');
        appendInt(PORT_GetError());
        return;
    }

    /* sort the list */
    for (node = CERT_LIST_HEAD(list); !CERT_LIST_END(node, list);
         node = CERT_LIST_NEXT(node)) {
        CERT_AddCertToListSorted(sorted, node->cert, sort_CN, NULL);
    }

    for (node = CERT_LIST_HEAD(sorted); !CERT_LIST_END(node, sorted);
         node = CERT_LIST_NEXT(node)) {
        CERTCertificate *cert = node->cert;
        char *commonName;

        SECU_PrintCertNickname(node, stderr);
        if (log) {
            fprintf(stderr, "*	Slot=%s*\n", cert->slot ? PK11_GetTokenName(cert->slot) : "none");
            fprintf(stderr, "*	Nickname=%s*\n", cert->nickname);
            fprintf(stderr, "*	Subject=<%s>*\n", cert->subjectName);
            fprintf(stderr, "*	Issuer=<%s>*\n", cert->issuerName);
            fprintf(stderr, "*	SN=");
            for (i = 0; i < cert->serialNumber.len; i++) {
                if (i != 0)
                    fprintf(stderr, ":");
                fprintf(stderr, "%02x", cert->serialNumber.data[0]);
            }
            fprintf(stderr, " *\n");
        }
        appendLabel('C');
        commonName = CERT_GetCommonName(&cert->subject);
        appendString(commonName ? commonName : "*NoName*");
        PORT_Free(commonName);
        if (CERT_GetCertTrust(cert, &trust) == SECSuccess) {
            appendFlags(trust.sslFlags);
            appendFlags(trust.emailFlags);
            appendFlags(trust.objectSigningFlags);
        }
    }
    CERT_DestroyCertList(list);
}

/*
 * need to implement yet... try to add a new certificate
 */
void
do_add_cert(const char *progName, int log)
{
    PORT_Assert(/* do_add_cert not implemented */ 0);
}

/*
 * display the current key slot
 */
void
do_key_slot(const char *progName, int log)
{
    PK11SlotInfo *slot = PK11_GetInternalKeySlot();
    if (!slot) {
        fprintf(stderr, "ERROR: no internal key slot found %s\n",
                SECU_Strerror(PORT_GetError()));
        appendLabel('K');
        appendLabel('S');
        appendString("none");
    }
    print_slot(slot, log);
    PK11_FreeSlot(slot);
}

/*
 * execute some NSS command.
 */
void
do_command(const char *label, int initialized, secuCommandFlag *command,
           const char *progName, int log)
{
    char *command_string;
    if (!initialized) {
        return;
    }

    if (command->activated) {
        command_string = command->arg;
    } else {
        command_string = "none";
    }

    if (log) {
        fprintf(stderr, "*Executing nss command \"%s\" for %s*\n",
                command_string, label);
    }

    /* do something */
    if (PORT_Strcasecmp(command_string, "list_slots") == 0) {
        do_list_slots(progName, log);
    } else if (PORT_Strcasecmp(command_string, "list_certs") == 0) {
        do_list_certs(progName, log);
    } else if (PORT_Strcasecmp(command_string, "add_cert") == 0) {
        do_add_cert(progName, log);
    } else if (PORT_Strcasecmp(command_string, "key_slot") == 0) {
        do_key_slot(progName, log);
    } else if (PORT_Strcasecmp(command_string, "none") != 0) {
        fprintf(stderr, ">> Unknown command (%s)\n", command_string);
        appendLabel('E');
        appendString("bc");
        usage_long(progName);
    }
}

/*
 * functions do handle
 * different library initializations.
 */
static int main_initialized;
static int lib1_initialized;
static int lib2_initialized;

void
main_Init(secuCommandFlag *db, secuCommandFlag *tokNam,
          int readOnly, const char *progName, int log)
{
    SECStatus rv;
    if (log) {
        fprintf(stderr, "*NSS_Init for the main program*\n");
    }
    appendLabel('M');
    if (!db->activated) {
        fprintf(stderr, ">> No main_db has been specified\n");
        usage(progName);
    }
    if (main_initialized) {
        fprintf(stderr, "Warning: Second initialization of Main\n");
        appendLabel('E');
        appendString("2M");
    }
    if (tokNam->activated) {
        PK11_ConfigurePKCS11(NULL, NULL, NULL, tokNam->arg,
                             NULL, NULL, NULL, NULL, 0, 0);
    }
    rv = NSS_Initialize(db->arg, "", "", "",
                        NSS_INIT_NOROOTINIT |
                            (readOnly ? NSS_INIT_READONLY : 0));
    if (rv != SECSuccess) {
        appendLabel('E');
        appendInt(PORT_GetError());
        fprintf(stderr, ">> %s\n", SECU_Strerror(PORT_GetError()));
        dumpBuffer();
        exit(1);
    }
    main_initialized = 1;
}

void
main_Do(secuCommandFlag *command, const char *progName, int log)
{
    do_command("main", main_initialized, command, progName, log);
}

void
main_Shutdown(int old_style, const char *progName, int log)
{
    SECStatus rv;
    appendLabel('N');
    if (log) {
        fprintf(stderr, "*NSS_Shutdown for the main program*\n");
    }
    if (!main_initialized) {
        fprintf(stderr, "Warning: Main shutdown without corresponding init\n");
    }
    if (old_style) {
        rv = NSS_Shutdown();
    } else {
        rv = NSS_ShutdownContext(NULL);
    }
    fprintf(stderr, "Shutdown main state = %d\n", rv);
    if (rv != SECSuccess) {
        appendLabel('E');
        appendInt(PORT_GetError());
        fprintf(stderr, "ERROR: %s\n", SECU_Strerror(PORT_GetError()));
    }
    main_initialized = 0;
}

/* common library init */
NSSInitContext *
lib_Init(const char *lableString, char label, int initialized,
         secuCommandFlag *db, secuCommandFlag *tokNam, int readonly,
         const char *progName, int log)
{
    NSSInitContext *ctxt;
    NSSInitParameters initStrings;
    NSSInitParameters *initStringPtr = NULL;

    appendLabel(label);
    if (log) {
        fprintf(stderr, "*NSS_Init for %s*\n", lableString);
    }

    if (!db->activated) {
        fprintf(stderr, ">> No %s_db has been specified\n", lableString);
        usage(progName);
    }
    if (initialized) {
        fprintf(stderr, "Warning: Second initialization of %s\n", lableString);
    }
    if (tokNam->activated) {
        PORT_Memset(&initStrings, 0, sizeof(initStrings));
        initStrings.length = sizeof(initStrings);
        initStrings.dbTokenDescription = tokNam->arg;
        initStringPtr = &initStrings;
    }
    ctxt = NSS_InitContext(db->arg, "", "", "", initStringPtr,
                           NSS_INIT_NOROOTINIT |
                               (readonly ? NSS_INIT_READONLY : 0));
    if (ctxt == NULL) {
        appendLabel('E');
        appendInt(PORT_GetError());
        fprintf(stderr, ">> %s\n", SECU_Strerror(PORT_GetError()));
        dumpBuffer();
        exit(1);
    }
    return ctxt;
}

/* common library shutdown */
void
lib_Shutdown(const char *labelString, char label, NSSInitContext *ctx,
             int initialize, const char *progName, int log)
{
    SECStatus rv;
    appendLabel(label);
    if (log) {
        fprintf(stderr, "*NSS_Shutdown for %s\n*", labelString);
    }
    if (!initialize) {
        fprintf(stderr, "Warning: %s shutdown without corresponding init\n",
                labelString);
    }
    rv = NSS_ShutdownContext(ctx);
    fprintf(stderr, "Shutdown %s state = %d\n", labelString, rv);
    if (rv != SECSuccess) {
        appendLabel('E');
        appendInt(PORT_GetError());
        fprintf(stderr, "ERROR: %s\n", SECU_Strerror(PORT_GetError()));
    }
}

static NSSInitContext *lib1_context;
static NSSInitContext *lib2_context;
void
lib1_Init(secuCommandFlag *db, secuCommandFlag *tokNam,
          int readOnly, const char *progName, int log)
{
    lib1_context = lib_Init("lib1", '1', lib1_initialized, db, tokNam,
                            readOnly, progName, log);
    lib1_initialized = 1;
}

void
lib2_Init(secuCommandFlag *db, secuCommandFlag *tokNam,
          int readOnly, const char *progName, int log)
{
    lib2_context = lib_Init("lib2", '2', lib2_initialized,
                            db, tokNam, readOnly, progName, log);
    lib2_initialized = 1;
}

void
lib1_Do(secuCommandFlag *command, const char *progName, int log)
{
    do_command("lib1", lib1_initialized, command, progName, log);
}

void
lib2_Do(secuCommandFlag *command, const char *progName, int log)
{
    do_command("lib2", lib2_initialized, command, progName, log);
}

void
lib1_Shutdown(const char *progName, int log)
{
    lib_Shutdown("lib1", 'I', lib1_context, lib1_initialized, progName, log);
    lib1_initialized = 0;
    /* don't clear lib1_Context, so we can test multiple attempts to close
      * the same context produces correct errors*/
}

void
lib2_Shutdown(const char *progName, int log)
{
    lib_Shutdown("lib2", 'Z', lib2_context, lib2_initialized, progName, log);
    lib2_initialized = 0;
    /* don't clear lib2_Context, so we can test multiple attempts to close
     * the same context produces correct errors*/
}

int
main(int argc, char **argv)
{
    SECStatus rv;
    secuCommand libinit;
    char *progName;
    char *order;
    secuCommandFlag *options;
    int log = 0;

    progName = strrchr(argv[0], '/');
    progName = progName ? progName + 1 : argv[0];

    libinit.numCommands = 0;
    libinit.commands = 0;
    libinit.numOptions = opt_last;
    options = (secuCommandFlag *)PORT_Alloc(sizeof(options_init));
    if (options == NULL) {
        fprintf(stderr, ">> %s:Not enough free memory to run command\n",
                progName);
        exit(1);
    }
    PORT_Memcpy(options, options_init, sizeof(options_init));
    libinit.options = options;

    rv = SECU_ParseCommandLine(argc, argv, progName, &libinit);
    if (rv != SECSuccess) {
        usage(progName);
    }

    if (libinit.options[opt_help].activated) {
        long_help(progName);
        exit(0);
    }

    log = libinit.options[opt_verbose].activated;
    if (libinit.options[opt_summary].activated) {
        initBuffer();
    }

    order = libinit.options[opt_liborder].arg;
    if (!order) {
        usage(progName);
    }

    if (log) {
        fprintf(stderr, "* initializing with order \"%s\"*\n", order);
    }

    for (; *order; order++) {
        switch (*order) {
            case 'M':
                main_Init(&libinit.options[opt_mainDB],
                          &libinit.options[opt_mainTokNam],
                          libinit.options[opt_mainRO].activated,
                          progName, log);
                break;
            case '1':
                lib1_Init(&libinit.options[opt_lib1DB],
                          &libinit.options[opt_lib1TokNam],
                          libinit.options[opt_lib1RO].activated,
                          progName, log);
                break;
            case '2':
                lib2_Init(&libinit.options[opt_lib2DB],
                          &libinit.options[opt_lib2TokNam],
                          libinit.options[opt_lib2RO].activated,
                          progName, log);
                break;
            case 'm':
                main_Shutdown(libinit.options[opt_oldStyle].activated,
                              progName, log);
                break;
            case 'i':
                lib1_Shutdown(progName, log);
                break;
            case 'z':
                lib2_Shutdown(progName, log);
                break;
            default:
                fprintf(stderr, ">> Unknown init/shutdown command \"%c\"", *order);
                usage_long(progName);
        }
        main_Do(&libinit.options[opt_mainCMD], progName, log);
        lib1_Do(&libinit.options[opt_lib1CMD], progName, log);
        lib2_Do(&libinit.options[opt_lib2CMD], progName, log);
    }

    if (NSS_IsInitialized()) {
        appendLabel('X');
        fprintf(stderr, "Warning: NSS is initialized\n");
    }
    dumpBuffer();

    exit(0);
}
