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

/*
** dbck.c
**
** utility for fixing corrupt cert databases
**
*/
#include <stdio.h>
#include <string.h>

#include "secutil.h"
#include "cdbhdl.h"
#include "certdb.h"
#include "cert.h"
#include "nspr.h"
#include "prtypes.h"
#include "prtime.h"
#include "prlong.h"
#include "pcert.h"
#include "nss.h"

static char *progName;

/* placeholders for pointer error types */
static void *WrongEntry;
static void *NoNickname;
static void *NoSMime;

typedef enum {
    /* 0*/ NoSubjectForCert = 0,
    /* 1*/ SubjectHasNoKeyForCert,
    /* 2*/ NoNicknameOrSMimeForSubject,
    /* 3*/ WrongNicknameForSubject,
    /* 4*/ NoNicknameEntry,
    /* 5*/ WrongSMimeForSubject,
    /* 6*/ NoSMimeEntry,
    /* 7*/ NoSubjectForNickname,
    /* 8*/ NoSubjectForSMime,
    /* 9*/ NicknameAndSMimeEntries,
    NUM_ERROR_TYPES
} dbErrorType;

static char *dbErrorString[NUM_ERROR_TYPES] = {
    /* 0*/ "<CERT ENTRY>\nDid not find a subject entry for this certificate.",
    /* 1*/ "<SUBJECT ENTRY>\nSubject has certKey which is not in db.",
    /* 2*/ "<SUBJECT ENTRY>\nSubject does not have a nickname or email address.",
    /* 3*/ "<SUBJECT ENTRY>\nUsing this subject's nickname, found a nickname entry for a different subject.",
    /* 4*/ "<SUBJECT ENTRY>\nDid not find a nickname entry for this subject.",
    /* 5*/ "<SUBJECT ENTRY>\nUsing this subject's email, found an S/MIME entry for a different subject.",
    /* 6*/ "<SUBJECT ENTRY>\nDid not find an S/MIME entry for this subject.",
    /* 7*/ "<NICKNAME ENTRY>\nDid not find a subject entry for this nickname.",
    /* 8*/ "<S/MIME ENTRY>\nDid not find a subject entry for this S/MIME profile.",
};

static char *errResult[NUM_ERROR_TYPES] = {
    "Certificate entries that had no subject entry.",
    "Subject entries with no corresponding Certificate entries.",
    "Subject entries that had no nickname or S/MIME entries.",
    "Redundant nicknames (subjects with the same nickname).",
    "Subject entries that had no nickname entry.",
    "Redundant email addresses (subjects with the same email address).",
    "Subject entries that had no S/MIME entry.",
    "Nickname entries that had no subject entry.",
    "S/MIME entries that had no subject entry.",
    "Subject entries with BOTH nickname and S/MIME entries."
};

enum {
    GOBOTH = 0,
    GORIGHT,
    GOLEFT
};

typedef struct
{
    PRBool verbose;
    PRBool dograph;
    PRFileDesc *out;
    PRFileDesc *graphfile;
    int dbErrors[NUM_ERROR_TYPES];
} dbDebugInfo;

struct certDBEntryListNodeStr {
    PRCList link;
    certDBEntry entry;
    void *appData;
};
typedef struct certDBEntryListNodeStr certDBEntryListNode;

/*
 * A list node for a cert db entry.  The index is a unique identifier
 * to use for creating generic maps of a db.  This struct handles
 * the cert, nickname, and smime db entry types, as all three have a
 * single handle to a subject entry.
 * This structure is pointed to by certDBEntryListNode->appData.
 */
typedef struct
{
    PLArenaPool *arena;
    int index;
    certDBEntryListNode *pSubject;
} certDBEntryMap;

/*
 * Subject entry is special case, it has bidirectional handles.  One
 * subject entry can point to several certs (using the same DN), and
 * a nickname and/or smime entry.
 * This structure is pointed to by certDBEntryListNode->appData.
 */
typedef struct
{
    PLArenaPool *arena;
    int index;
    int numCerts;
    certDBEntryListNode **pCerts;
    certDBEntryListNode *pNickname;
    certDBEntryListNode *pSMime;
} certDBSubjectEntryMap;

/*
 * A map of a certdb.
 */
typedef struct
{
    int numCerts;
    int numSubjects;
    int numNicknames;
    int numSMime;
    int numRevocation;
    certDBEntryListNode certs;      /* pointer to head of cert list */
    certDBEntryListNode subjects;   /* pointer to head of subject list */
    certDBEntryListNode nicknames;  /* pointer to head of nickname list */
    certDBEntryListNode smime;      /* pointer to head of smime list */
    certDBEntryListNode revocation; /* pointer to head of revocation list */
} certDBArray;

/* Cast list to the base element, a certDBEntryListNode. */
#define LISTNODE_CAST(node) \
    ((certDBEntryListNode *)(node))

static void
Usage(char *progName)
{
#define FPS fprintf(stderr,
    FPS "Type %s -H for more detailed descriptions\n", progName);
    FPS "Usage:  %s -D [-d certdir] [-m] [-v [-f dumpfile]]\n",
    progName);
#ifdef DORECOVER
    FPS "        %s -R -o newdbname [-d certdir] [-aprsx] [-v [-f dumpfile]]\n",
    progName);
#endif
    exit(-1);
}

static void
LongUsage(char *progName)
{
    FPS "%-15s Display this help message.\n",
    "-H");
    FPS "%-15s Dump analysis.  No changes will be made to the database.\n",
    "-D");
    FPS "%-15s Cert database directory (default is ~/.netscape)\n",
    "   -d certdir");
    FPS "%-15s Put database graph in ./mailfile (default is stdout).\n",
    "   -m");
    FPS "%-15s Verbose mode.  Dumps the entire contents of your cert8.db.\n",
    "   -v");
    FPS "%-15s File to dump verbose output into. (default is stdout)\n",
    "   -f dumpfile");
#ifdef DORECOVER
    FPS "%-15s Repair the database.  The program will look for broken\n",
    "-R");
    FPS "%-15s dependencies between subject entries and certificates,\n",
        "");
    FPS "%-15s between nickname entries and subjects, and between SMIME\n",
        "");
    FPS "%-15s profiles and subjects.  Any duplicate entries will be\n",
        "");
    FPS "%-15s removed, any missing entries will be created.\n",
        "");
    FPS "%-15s File to store new database in (default is new_cert8.db)\n",
    "   -o newdbname");
    FPS "%-15s Cert database directory (default is ~/.netscape)\n",
    "   -d certdir");
    FPS "%-15s Prompt before removing any certificates.\n",
        "   -p");
    FPS "%-15s Keep all possible certificates.  Only remove certificates\n",
    "   -a");
    FPS "%-15s which prevent creation of a consistent database.  Thus any\n",
    "");
    FPS "%-15s expired or redundant entries will be kept.\n",
    "");
    FPS "%-15s Keep redundant nickname/email entries.  It is possible\n",
    "   -r");
    FPS "%-15s only one such entry will be usable.\n",
    "");
    FPS "%-15s Don't require an S/MIME profile in order to keep an S/MIME\n",
    "   -s");
    FPS "%-15s cert.  An empty profile will be created.\n",
    "");
    FPS "%-15s Keep expired certificates.\n",
    "   -x");
    FPS "%-15s Verbose mode - report all activity while recovering db.\n",
    "   -v");
    FPS "%-15s File to dump verbose output into.\n",
    "   -f dumpfile");
    FPS "\n");
#endif
    exit(-1);
#undef FPS
}

/*******************************************************************
 *
 *  Functions for dbck.
 *
 ******************************************************************/

void
printHexString(PRFileDesc *out, SECItem *hexval)
{
    unsigned int i;
    for (i = 0; i < hexval->len; i++) {
        if (i != hexval->len - 1) {
            PR_fprintf(out, "%02x:", hexval->data[i]);
        } else {
            PR_fprintf(out, "%02x", hexval->data[i]);
        }
    }
    PR_fprintf(out, "\n");
}

SECStatus
dumpCertificate(CERTCertificate *cert, int num, PRFileDesc *outfile)
{
    int userCert = 0;
    CERTCertTrust *trust = cert->trust;
    userCert = (SEC_GET_TRUST_FLAGS(trust, trustSSL) & CERTDB_USER) ||
               (SEC_GET_TRUST_FLAGS(trust, trustEmail) & CERTDB_USER) ||
               (SEC_GET_TRUST_FLAGS(trust, trustObjectSigning) & CERTDB_USER);
    if (num >= 0) {
        PR_fprintf(outfile, "Certificate: %3d\n", num);
    } else {
        PR_fprintf(outfile, "Certificate:\n");
    }
    PR_fprintf(outfile, "----------------\n");
    if (userCert)
        PR_fprintf(outfile, "(User Cert)\n");
    PR_fprintf(outfile, "## SUBJECT:  %s\n", cert->subjectName);
    PR_fprintf(outfile, "## ISSUER:  %s\n", cert->issuerName);
    PR_fprintf(outfile, "## SERIAL NUMBER:  ");
    printHexString(outfile, &cert->serialNumber);
    { /*  XXX should be separate function.  */
        PRTime timeBefore, timeAfter;
        PRExplodedTime beforePrintable, afterPrintable;
        char *beforestr, *afterstr;
        DER_DecodeTimeChoice(&timeBefore, &cert->validity.notBefore);
        DER_DecodeTimeChoice(&timeAfter, &cert->validity.notAfter);
        PR_ExplodeTime(timeBefore, PR_GMTParameters, &beforePrintable);
        PR_ExplodeTime(timeAfter, PR_GMTParameters, &afterPrintable);
        beforestr = PORT_Alloc(100);
        afterstr = PORT_Alloc(100);
        PR_FormatTime(beforestr, 100, "%a %b %d %H:%M:%S %Y", &beforePrintable);
        PR_FormatTime(afterstr, 100, "%a %b %d %H:%M:%S %Y", &afterPrintable);
        PR_fprintf(outfile, "## VALIDITY:  %s to %s\n", beforestr, afterstr);
    }
    PR_fprintf(outfile, "\n");
    return SECSuccess;
}

SECStatus
dumpCertEntry(certDBEntryCert *entry, int num, PRFileDesc *outfile)
{
#if 0
    NSSLOWCERTCertificate *cert;
    /* should we check for existing duplicates? */
    cert = nsslowcert_DecodeDERCertificate(&entry->cert.derCert,
                        entry->cert.nickname);
#else
    CERTCertificate *cert;
    cert = CERT_DecodeDERCertificate(&entry->derCert, PR_FALSE, NULL);
#endif
    if (!cert) {
        fprintf(stderr, "Failed to decode certificate.\n");
        return SECFailure;
    }
    cert->trust = (CERTCertTrust *)&entry->trust;
    dumpCertificate(cert, num, outfile);
    CERT_DestroyCertificate(cert);
    return SECSuccess;
}

SECStatus
dumpSubjectEntry(certDBEntrySubject *entry, int num, PRFileDesc *outfile)
{
    char *subjectName = CERT_DerNameToAscii(&entry->derSubject);

    PR_fprintf(outfile, "Subject: %3d\n", num);
    PR_fprintf(outfile, "------------\n");
    PR_fprintf(outfile, "## %s\n", subjectName);
    if (entry->nickname)
        PR_fprintf(outfile, "## Subject nickname:  %s\n", entry->nickname);
    if (entry->emailAddrs) {
        unsigned int n;
        for (n = 0; n < entry->nemailAddrs && entry->emailAddrs[n]; ++n) {
            char *emailAddr = entry->emailAddrs[n];
            if (emailAddr[0]) {
                PR_fprintf(outfile, "## Subject email address:  %s\n",
                           emailAddr);
            }
        }
    }
    PR_fprintf(outfile, "## This subject has %d cert(s).\n", entry->ncerts);
    PR_fprintf(outfile, "\n");
    PORT_Free(subjectName);
    return SECSuccess;
}

SECStatus
dumpNicknameEntry(certDBEntryNickname *entry, int num, PRFileDesc *outfile)
{
    PR_fprintf(outfile, "Nickname: %3d\n", num);
    PR_fprintf(outfile, "-------------\n");
    PR_fprintf(outfile, "##  \"%s\"\n\n", entry->nickname);
    return SECSuccess;
}

SECStatus
dumpSMimeEntry(certDBEntrySMime *entry, int num, PRFileDesc *outfile)
{
    PR_fprintf(outfile, "S/MIME Profile: %3d\n", num);
    PR_fprintf(outfile, "-------------------\n");
    PR_fprintf(outfile, "##  \"%s\"\n", entry->emailAddr);
#ifdef OLDWAY
    PR_fprintf(outfile, "##  OPTIONS:  ");
    printHexString(outfile, &entry->smimeOptions);
    PR_fprintf(outfile, "##  TIMESTAMP:  ");
    printHexString(outfile, &entry->optionsDate);
#else
    SECU_PrintAny(stdout, &entry->smimeOptions, "##  OPTIONS  ", 0);
    fflush(stdout);
    if (entry->optionsDate.len && entry->optionsDate.data)
        PR_fprintf(outfile, "##  TIMESTAMP: %.*s\n",
                   entry->optionsDate.len, entry->optionsDate.data);
#endif
    PR_fprintf(outfile, "\n");
    return SECSuccess;
}

SECStatus
mapCertEntries(certDBArray *dbArray)
{
    certDBEntryCert *certEntry;
    certDBEntrySubject *subjectEntry;
    certDBEntryListNode *certNode, *subjNode;
    certDBSubjectEntryMap *smap;
    certDBEntryMap *map;
    PLArenaPool *tmparena;
    SECItem derSubject;
    SECItem certKey;
    PRCList *cElem, *sElem;

    /* Arena for decoded entries */
    tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (tmparena == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return SECFailure;
    }

    /* Iterate over cert entries and map them to subject entries.
     * NOTE: mapSubjectEntries must be called first to alloc memory
     * for array of subject->cert map.
     */
    for (cElem = PR_LIST_HEAD(&dbArray->certs.link);
         cElem != &dbArray->certs.link; cElem = PR_NEXT_LINK(cElem)) {
        certNode = LISTNODE_CAST(cElem);
        certEntry = (certDBEntryCert *)&certNode->entry;
        map = (certDBEntryMap *)certNode->appData;
        CERT_NameFromDERCert(&certEntry->derCert, &derSubject);
        CERT_KeyFromDERCert(tmparena, &certEntry->derCert, &certKey);
        /*  Loop over found subjects for cert's DN.  */
        for (sElem = PR_LIST_HEAD(&dbArray->subjects.link);
             sElem != &dbArray->subjects.link; sElem = PR_NEXT_LINK(sElem)) {
            subjNode = LISTNODE_CAST(sElem);
            subjectEntry = (certDBEntrySubject *)&subjNode->entry;
            if (SECITEM_ItemsAreEqual(&derSubject, &subjectEntry->derSubject)) {
                unsigned int i;
                /*  Found matching subject name, create link.  */
                map->pSubject = subjNode;
                /*  Make sure subject entry has cert's key.  */
                for (i = 0; i < subjectEntry->ncerts; i++) {
                    if (SECITEM_ItemsAreEqual(&certKey,
                                              &subjectEntry->certKeys[i])) {
                        /*  Found matching cert key.  */
                        smap = (certDBSubjectEntryMap *)subjNode->appData;
                        smap->pCerts[i] = certNode;
                        break;
                    }
                }
            }
        }
    }
    PORT_FreeArena(tmparena, PR_FALSE);
    return SECSuccess;
}

SECStatus
mapSubjectEntries(certDBArray *dbArray)
{
    certDBEntrySubject *subjectEntry;
    certDBEntryListNode *subjNode;
    certDBSubjectEntryMap *subjMap;
    PRCList *sElem;

    for (sElem = PR_LIST_HEAD(&dbArray->subjects.link);
         sElem != &dbArray->subjects.link; sElem = PR_NEXT_LINK(sElem)) {
        /* Iterate over subject entries and map subjects to nickname
         * and smime entries.  The cert<->subject map will be handled
         * by a subsequent call to mapCertEntries.
         */
        subjNode = LISTNODE_CAST(sElem);
        subjectEntry = (certDBEntrySubject *)&subjNode->entry;
        subjMap = (certDBSubjectEntryMap *)subjNode->appData;
        /* need to alloc memory here for array of matching certs. */
        subjMap->pCerts = PORT_ArenaAlloc(subjMap->arena,
                                          subjectEntry->ncerts * sizeof(int));
        subjMap->numCerts = subjectEntry->ncerts;
        subjMap->pNickname = NoNickname;
        subjMap->pSMime = NoSMime;

        if (subjectEntry->nickname) {
            /* Subject should have a nickname entry, so create a link. */
            PRCList *nElem;
            for (nElem = PR_LIST_HEAD(&dbArray->nicknames.link);
                 nElem != &dbArray->nicknames.link;
                 nElem = PR_NEXT_LINK(nElem)) {
                certDBEntryListNode *nickNode;
                certDBEntryNickname *nicknameEntry;
                /*  Look for subject's nickname in nickname entries.  */
                nickNode = LISTNODE_CAST(nElem);
                nicknameEntry = (certDBEntryNickname *)&nickNode->entry;
                if (PL_strcmp(subjectEntry->nickname,
                              nicknameEntry->nickname) == 0) {
                    /*  Found a nickname entry for subject's nickname.  */
                    if (SECITEM_ItemsAreEqual(&subjectEntry->derSubject,
                                              &nicknameEntry->subjectName)) {
                        certDBEntryMap *nickMap;
                        nickMap = (certDBEntryMap *)nickNode->appData;
                        /*  Nickname and subject match.  */
                        subjMap->pNickname = nickNode;
                        nickMap->pSubject = subjNode;
                    } else if (subjMap->pNickname == NoNickname) {
                        /*  Nickname entry found is for diff. subject.  */
                        subjMap->pNickname = WrongEntry;
                    }
                }
            }
        }
        if (subjectEntry->emailAddrs) {
            unsigned int n;
            for (n = 0; n < subjectEntry->nemailAddrs &&
                        subjectEntry->emailAddrs[n];
                 ++n) {
                char *emailAddr = subjectEntry->emailAddrs[n];
                if (emailAddr[0]) {
                    PRCList *mElem;
                    /* Subject should have an smime entry, so create a link. */
                    for (mElem = PR_LIST_HEAD(&dbArray->smime.link);
                         mElem != &dbArray->smime.link;
                         mElem = PR_NEXT_LINK(mElem)) {
                        certDBEntryListNode *smimeNode;
                        certDBEntrySMime *smimeEntry;
                        /*  Look for subject's email in S/MIME entries.  */
                        smimeNode = LISTNODE_CAST(mElem);
                        smimeEntry = (certDBEntrySMime *)&smimeNode->entry;
                        if (PL_strcmp(emailAddr,
                                      smimeEntry->emailAddr) == 0) {
                            /*  Found a S/MIME entry for subject's email.  */
                            if (SECITEM_ItemsAreEqual(
                                    &subjectEntry->derSubject,
                                    &smimeEntry->subjectName)) {
                                certDBEntryMap *smimeMap;
                                /*  S/MIME entry and subject match.  */
                                subjMap->pSMime = smimeNode;
                                smimeMap = (certDBEntryMap *)smimeNode->appData;
                                smimeMap->pSubject = subjNode;
                            } else if (subjMap->pSMime == NoSMime) {
                                /*  S/MIME entry found is for diff. subject.  */
                                subjMap->pSMime = WrongEntry;
                            }
                        }
                    } /* end for */
                }     /* endif (emailAddr[0]) */
            }         /* end for */
        }             /* endif (subjectEntry->emailAddrs) */
    }
    return SECSuccess;
}

void
printnode(dbDebugInfo *info, const char *str, int num)
{
    if (!info->dograph)
        return;
    if (num < 0) {
        PR_fprintf(info->graphfile, str);
    } else {
        PR_fprintf(info->graphfile, str, num);
    }
}

PRBool
map_handle_is_ok(dbDebugInfo *info, void *mapPtr, int indent)
{
    if (mapPtr == NULL) {
        if (indent > 0)
            printnode(info, "                ", -1);
        if (indent >= 0)
            printnode(info, "******************* ", -1);
        return PR_FALSE;
    } else if (mapPtr == WrongEntry) {
        if (indent > 0)
            printnode(info, "                  ", -1);
        if (indent >= 0)
            printnode(info, "??????????????????? ", -1);
        return PR_FALSE;
    } else {
        return PR_TRUE;
    }
}

/* these call each other */
void print_smime_graph(dbDebugInfo *info, certDBEntryMap *smimeMap,
                       int direction);
void print_nickname_graph(dbDebugInfo *info, certDBEntryMap *nickMap,
                          int direction);
void print_subject_graph(dbDebugInfo *info, certDBSubjectEntryMap *subjMap,
                         int direction, int optindex, int opttype);
void print_cert_graph(dbDebugInfo *info, certDBEntryMap *certMap,
                      int direction);

/* Given an smime entry, print its unique identifier.  If GOLEFT is
 * specified, print the cert<-subject<-smime map, else just print
 * the smime entry.
 */
void
print_smime_graph(dbDebugInfo *info, certDBEntryMap *smimeMap, int direction)
{
    certDBSubjectEntryMap *subjMap;
    certDBEntryListNode *subjNode;
    if (direction == GOLEFT) {
        /* Need to output subject and cert first, see print_subject_graph */
        subjNode = smimeMap->pSubject;
        if (map_handle_is_ok(info, (void *)subjNode, 1)) {
            subjMap = (certDBSubjectEntryMap *)subjNode->appData;
            print_subject_graph(info, subjMap, GOLEFT,
                                smimeMap->index, certDBEntryTypeSMimeProfile);
        } else {
            printnode(info, "<---- S/MIME   %5d   ", smimeMap->index);
            info->dbErrors[NoSubjectForSMime]++;
        }
    } else {
        printnode(info, "S/MIME   %5d   ", smimeMap->index);
    }
}

/* Given a nickname entry, print its unique identifier.  If GOLEFT is
 * specified, print the cert<-subject<-nickname map, else just print
 * the nickname entry.
 */
void
print_nickname_graph(dbDebugInfo *info, certDBEntryMap *nickMap, int direction)
{
    certDBSubjectEntryMap *subjMap;
    certDBEntryListNode *subjNode;
    if (direction == GOLEFT) {
        /* Need to output subject and cert first, see print_subject_graph */
        subjNode = nickMap->pSubject;
        if (map_handle_is_ok(info, (void *)subjNode, 1)) {
            subjMap = (certDBSubjectEntryMap *)subjNode->appData;
            print_subject_graph(info, subjMap, GOLEFT,
                                nickMap->index, certDBEntryTypeNickname);
        } else {
            printnode(info, "<---- Nickname %5d   ", nickMap->index);
            info->dbErrors[NoSubjectForNickname]++;
        }
    } else {
        printnode(info, "Nickname %5d   ", nickMap->index);
    }
}

/* Given a subject entry, if going right print the graph of the nickname|smime
 * that it maps to (by its unique identifier); and if going left
 * print the list of certs that it points to.
 */
void
print_subject_graph(dbDebugInfo *info, certDBSubjectEntryMap *subjMap,
                    int direction, int optindex, int opttype)
{
    certDBEntryMap *map;
    certDBEntryListNode *node;
    int i;
    /* The first line of output always contains the cert id, subject id,
     * and nickname|smime id.  Subsequent lines may contain additional
     * cert id's for the subject if going left or both directions.
     * Ex. of printing the graph for a subject entry:
     * Cert 3 <- Subject 5 -> Nickname 32
     * Cert 8 /
     * Cert 9 /
     * means subject 5 has 3 certs, 3, 8, and 9, and corresponds
     * to nickname entry 32.
     * To accomplish the above, it is required to dump the entire first
     * line left-to-right, regardless of the input direction, and then
     * finish up any remaining cert entries.  Hence the code is uglier
     * than one may expect.
     */
    if (direction == GOLEFT || direction == GOBOTH) {
        /* In this case, nothing should be output until the first cert is
         * located and output (cert 3 in the above example).
         */
        if (subjMap->numCerts == 0 || subjMap->pCerts == NULL)
            /* XXX uh-oh */
            return;
        /* get the first cert and dump it. */
        node = subjMap->pCerts[0];
        if (map_handle_is_ok(info, (void *)node, 0)) {
            map = (certDBEntryMap *)node->appData;
            /* going left here stops. */
            print_cert_graph(info, map, GOLEFT);
        } else {
            info->dbErrors[SubjectHasNoKeyForCert]++;
        }
        /* Now it is safe to output the subject id. */
        if (direction == GOLEFT)
            printnode(info, "Subject  %5d <---- ", subjMap->index);
        else /* direction == GOBOTH */
            printnode(info, "Subject  %5d ----> ", subjMap->index);
    }
    if (direction == GORIGHT || direction == GOBOTH) {
        /* Okay, now output the nickname|smime for this subject. */
        if (direction != GOBOTH) /* handled above */
            printnode(info, "Subject  %5d ----> ", subjMap->index);
        if (subjMap->pNickname) {
            node = subjMap->pNickname;
            if (map_handle_is_ok(info, (void *)node, 0)) {
                map = (certDBEntryMap *)node->appData;
                /* going right here stops. */
                print_nickname_graph(info, map, GORIGHT);
            }
        }
        if (subjMap->pSMime) {
            node = subjMap->pSMime;
            if (map_handle_is_ok(info, (void *)node, 0)) {
                map = (certDBEntryMap *)node->appData;
                /* going right here stops. */
                print_smime_graph(info, map, GORIGHT);
            }
        }
        if (!subjMap->pNickname && !subjMap->pSMime) {
            printnode(info, "******************* ", -1);
            info->dbErrors[NoNicknameOrSMimeForSubject]++;
        }
        if (subjMap->pNickname && subjMap->pSMime) {
            info->dbErrors[NicknameAndSMimeEntries]++;
        }
    }
    if (direction != GORIGHT) { /* going right has only one cert */
        if (opttype == certDBEntryTypeNickname)
            printnode(info, "Nickname %5d   ", optindex);
        else if (opttype == certDBEntryTypeSMimeProfile)
            printnode(info, "S/MIME   %5d   ", optindex);
        for (i = 1 /* 1st one already done */; i < subjMap->numCerts; i++) {
            printnode(info, "\n", -1); /* start a new line */
            node = subjMap->pCerts[i];
            if (map_handle_is_ok(info, (void *)node, 0)) {
                map = (certDBEntryMap *)node->appData;
                /* going left here stops. */
                print_cert_graph(info, map, GOLEFT);
                printnode(info, "/", -1);
            }
        }
    }
}

/* Given a cert entry, print its unique identifer.  If GORIGHT is specified,
 * print the cert->subject->nickname|smime map, else just print
 * the cert entry.
 */
void
print_cert_graph(dbDebugInfo *info, certDBEntryMap *certMap, int direction)
{
    certDBSubjectEntryMap *subjMap;
    certDBEntryListNode *subjNode;
    if (direction == GOLEFT) {
        printnode(info, "Cert     %5d <---- ", certMap->index);
        /* only want cert entry, terminate here. */
        return;
    }
    /* Keep going right then. */
    printnode(info, "Cert     %5d ----> ", certMap->index);
    subjNode = certMap->pSubject;
    if (map_handle_is_ok(info, (void *)subjNode, 0)) {
        subjMap = (certDBSubjectEntryMap *)subjNode->appData;
        print_subject_graph(info, subjMap, GORIGHT, -1, -1);
    } else {
        info->dbErrors[NoSubjectForCert]++;
    }
}

SECStatus
computeDBGraph(certDBArray *dbArray, dbDebugInfo *info)
{
    PRCList *cElem, *sElem, *nElem, *mElem;
    certDBEntryListNode *node;
    certDBEntryMap *map;
    certDBSubjectEntryMap *subjMap;

    /* Graph is of this form:
     *
     * certs:
     * cert ---> subject ---> (nickname|smime)
     *
     * subjects:
     * cert <--- subject ---> (nickname|smime)
     *
     * nicknames and smime:
     * cert <--- subject <--- (nickname|smime)
     */

    /* Print cert graph. */
    for (cElem = PR_LIST_HEAD(&dbArray->certs.link);
         cElem != &dbArray->certs.link; cElem = PR_NEXT_LINK(cElem)) {
        /* Print graph of everything to right of cert entry. */
        node = LISTNODE_CAST(cElem);
        map = (certDBEntryMap *)node->appData;
        print_cert_graph(info, map, GORIGHT);
        printnode(info, "\n", -1);
    }
    printnode(info, "\n", -1);

    /* Print subject graph. */
    for (sElem = PR_LIST_HEAD(&dbArray->subjects.link);
         sElem != &dbArray->subjects.link; sElem = PR_NEXT_LINK(sElem)) {
        /* Print graph of everything to both sides of subject entry. */
        node = LISTNODE_CAST(sElem);
        subjMap = (certDBSubjectEntryMap *)node->appData;
        print_subject_graph(info, subjMap, GOBOTH, -1, -1);
        printnode(info, "\n", -1);
    }
    printnode(info, "\n", -1);

    /* Print nickname graph. */
    for (nElem = PR_LIST_HEAD(&dbArray->nicknames.link);
         nElem != &dbArray->nicknames.link; nElem = PR_NEXT_LINK(nElem)) {
        /* Print graph of everything to left of nickname entry. */
        node = LISTNODE_CAST(nElem);
        map = (certDBEntryMap *)node->appData;
        print_nickname_graph(info, map, GOLEFT);
        printnode(info, "\n", -1);
    }
    printnode(info, "\n", -1);

    /* Print smime graph. */
    for (mElem = PR_LIST_HEAD(&dbArray->smime.link);
         mElem != &dbArray->smime.link; mElem = PR_NEXT_LINK(mElem)) {
        /* Print graph of everything to left of smime entry. */
        node = LISTNODE_CAST(mElem);
        if (node == NULL)
            break;
        map = (certDBEntryMap *)node->appData;
        print_smime_graph(info, map, GOLEFT);
        printnode(info, "\n", -1);
    }
    printnode(info, "\n", -1);

    return SECSuccess;
}

/*
 * List the entries in the db, showing handles between entry types.
 */
void
verboseOutput(certDBArray *dbArray, dbDebugInfo *info)
{
    int i, ref;
    PRCList *elem;
    certDBEntryListNode *node;
    certDBEntryMap *map;
    certDBSubjectEntryMap *smap;
    certDBEntrySubject *subjectEntry;

    /* List certs */
    for (elem = PR_LIST_HEAD(&dbArray->certs.link);
         elem != &dbArray->certs.link; elem = PR_NEXT_LINK(elem)) {
        node = LISTNODE_CAST(elem);
        map = (certDBEntryMap *)node->appData;
        dumpCertEntry((certDBEntryCert *)&node->entry, map->index, info->out);
        /* walk the cert handle to it's subject entry */
        if (map_handle_is_ok(info, map->pSubject, -1)) {
            smap = (certDBSubjectEntryMap *)map->pSubject->appData;
            ref = smap->index;
            PR_fprintf(info->out, "-->(subject %d)\n\n\n", ref);
        } else {
            PR_fprintf(info->out, "-->(MISSING SUBJECT ENTRY)\n\n\n");
        }
    }
    /* List subjects */
    for (elem = PR_LIST_HEAD(&dbArray->subjects.link);
         elem != &dbArray->subjects.link; elem = PR_NEXT_LINK(elem)) {
        int refs = 0;
        node = LISTNODE_CAST(elem);
        subjectEntry = (certDBEntrySubject *)&node->entry;
        smap = (certDBSubjectEntryMap *)node->appData;
        dumpSubjectEntry(subjectEntry, smap->index, info->out);
        /* iterate over subject's certs */
        for (i = 0; i < smap->numCerts; i++) {
            /* walk each subject handle to it's cert entries */
            if (map_handle_is_ok(info, smap->pCerts[i], -1)) {
                ref = ((certDBEntryMap *)smap->pCerts[i]->appData)->index;
                PR_fprintf(info->out, "-->(%d. certificate %d)\n", i, ref);
            } else {
                PR_fprintf(info->out, "-->(%d. MISSING CERT ENTRY)\n", i);
            }
        }
        if (subjectEntry->nickname) {
            ++refs;
            /* walk each subject handle to it's nickname entry */
            if (map_handle_is_ok(info, smap->pNickname, -1)) {
                ref = ((certDBEntryMap *)smap->pNickname->appData)->index;
                PR_fprintf(info->out, "-->(nickname %d)\n", ref);
            } else {
                PR_fprintf(info->out, "-->(MISSING NICKNAME ENTRY)\n");
            }
        }
        if (subjectEntry->nemailAddrs &&
            subjectEntry->emailAddrs &&
            subjectEntry->emailAddrs[0] &&
            subjectEntry->emailAddrs[0][0]) {
            ++refs;
            /* walk each subject handle to it's smime entry */
            if (map_handle_is_ok(info, smap->pSMime, -1)) {
                ref = ((certDBEntryMap *)smap->pSMime->appData)->index;
                PR_fprintf(info->out, "-->(s/mime %d)\n", ref);
            } else {
                PR_fprintf(info->out, "-->(MISSING S/MIME ENTRY)\n");
            }
        }
        if (!refs) {
            PR_fprintf(info->out, "-->(NO NICKNAME+S/MIME ENTRY)\n");
        }
        PR_fprintf(info->out, "\n\n");
    }
    for (elem = PR_LIST_HEAD(&dbArray->nicknames.link);
         elem != &dbArray->nicknames.link; elem = PR_NEXT_LINK(elem)) {
        node = LISTNODE_CAST(elem);
        map = (certDBEntryMap *)node->appData;
        dumpNicknameEntry((certDBEntryNickname *)&node->entry, map->index,
                          info->out);
        if (map_handle_is_ok(info, map->pSubject, -1)) {
            ref = ((certDBEntryMap *)map->pSubject->appData)->index;
            PR_fprintf(info->out, "-->(subject %d)\n\n\n", ref);
        } else {
            PR_fprintf(info->out, "-->(MISSING SUBJECT ENTRY)\n\n\n");
        }
    }
    for (elem = PR_LIST_HEAD(&dbArray->smime.link);
         elem != &dbArray->smime.link; elem = PR_NEXT_LINK(elem)) {
        node = LISTNODE_CAST(elem);
        map = (certDBEntryMap *)node->appData;
        dumpSMimeEntry((certDBEntrySMime *)&node->entry, map->index, info->out);
        if (map_handle_is_ok(info, map->pSubject, -1)) {
            ref = ((certDBEntryMap *)map->pSubject->appData)->index;
            PR_fprintf(info->out, "-->(subject %d)\n\n\n", ref);
        } else {
            PR_fprintf(info->out, "-->(MISSING SUBJECT ENTRY)\n\n\n");
        }
    }
    PR_fprintf(info->out, "\n\n");
}

/* A callback function, intended to be called from nsslowcert_TraverseDBEntries
 * Builds a PRCList of DB entries of the specified type.
 */
SECStatus
SEC_GetCertDBEntryList(SECItem *dbdata, SECItem *dbkey,
                       certDBEntryType entryType, void *pdata)
{
    certDBEntry *entry;
    certDBEntryListNode *node;
    PRCList *list = (PRCList *)pdata;

    if (!dbdata || !dbkey || !pdata || !dbdata->data || !dbkey->data) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    entry = nsslowcert_DecodeAnyDBEntry(dbdata, dbkey, entryType, NULL);
    if (!entry) {
        return SECSuccess; /* skip it */
    }
    node = PORT_ArenaZNew(entry->common.arena, certDBEntryListNode);
    if (!node) {
        /* DestroyDBEntry(entry); */
        PLArenaPool *arena = entry->common.arena;
        PORT_Memset(&entry->common, 0, sizeof entry->common);
        PORT_FreeArena(arena, PR_FALSE);
        return SECFailure;
    }
    node->entry = *entry; /* crude but effective. */
    PR_INIT_CLIST(&node->link);
    PR_INSERT_BEFORE(&node->link, list);
    return SECSuccess;
}

int
fillDBEntryArray(NSSLOWCERTCertDBHandle *handle, certDBEntryType type,
                 certDBEntryListNode *list)
{
    PRCList *elem;
    certDBEntryListNode *node;
    certDBEntryMap *mnode;
    certDBSubjectEntryMap *smnode;
    PLArenaPool *arena;
    int count = 0;

    /* Initialize a dummy entry in the list.  The list head will be the
     * next element, so this element is skipped by for loops.
     */
    PR_INIT_CLIST((PRCList *)list);
    /* Collect all of the cert db entries for this type into a list. */
    nsslowcert_TraverseDBEntries(handle, type, SEC_GetCertDBEntryList, list);

    for (elem = PR_LIST_HEAD(&list->link);
         elem != &list->link; elem = PR_NEXT_LINK(elem)) {
        /* Iterate over the entries and ... */
        node = (certDBEntryListNode *)elem;
        if (type != certDBEntryTypeSubject) {
            arena = PORT_NewArena(sizeof(*mnode));
            mnode = PORT_ArenaZNew(arena, certDBEntryMap);
            mnode->arena = arena;
            /* ... assign a unique index number to each node, and ... */
            mnode->index = count;
            /* ... set the map pointer for the node. */
            node->appData = (void *)mnode;
        } else {
            /* allocate some room for the cert pointers also */
            arena = PORT_NewArena(sizeof(*smnode) + 20 * sizeof(void *));
            smnode = PORT_ArenaZNew(arena, certDBSubjectEntryMap);
            smnode->arena = arena;
            smnode->index = count;
            node->appData = (void *)smnode;
        }
        count++;
    }
    return count;
}

void
freeDBEntryList(PRCList *list)
{
    PRCList *next, *elem;
    certDBEntryListNode *node;
    certDBEntryMap *map;

    for (elem = PR_LIST_HEAD(list); elem != list;) {
        next = PR_NEXT_LINK(elem);
        node = (certDBEntryListNode *)elem;
        map = (certDBEntryMap *)node->appData;
        PR_REMOVE_LINK(&node->link);
        PORT_FreeArena(map->arena, PR_TRUE);
        PORT_FreeArena(node->entry.common.arena, PR_TRUE);
        elem = next;
    }
}

void
DBCK_DebugDB(NSSLOWCERTCertDBHandle *handle, PRFileDesc *out,
             PRFileDesc *mailfile)
{
    int i, nCertsFound, nSubjFound, nErr;
    int nCerts, nSubjects, nSubjCerts, nNicknames, nSMime, nRevocation;
    PRCList *elem;
    char c;
    dbDebugInfo info;
    certDBArray dbArray;

    PORT_Memset(&dbArray, 0, sizeof(dbArray));
    PORT_Memset(&info, 0, sizeof(info));
    info.verbose = (PRBool)(out != NULL);
    info.dograph = info.verbose;
    info.out = (out) ? out : PR_STDOUT;
    info.graphfile = mailfile ? mailfile : PR_STDOUT;

    /*  Fill the array structure with cert/subject/nickname/smime entries.  */
    dbArray.numCerts = fillDBEntryArray(handle, certDBEntryTypeCert,
                                        &dbArray.certs);
    dbArray.numSubjects = fillDBEntryArray(handle, certDBEntryTypeSubject,
                                           &dbArray.subjects);
    dbArray.numNicknames = fillDBEntryArray(handle, certDBEntryTypeNickname,
                                            &dbArray.nicknames);
    dbArray.numSMime = fillDBEntryArray(handle, certDBEntryTypeSMimeProfile,
                                        &dbArray.smime);
    dbArray.numRevocation = fillDBEntryArray(handle, certDBEntryTypeRevocation,
                                             &dbArray.revocation);

    /*  Compute the map between the database entries.  */
    mapSubjectEntries(&dbArray);
    mapCertEntries(&dbArray);
    computeDBGraph(&dbArray, &info);

    /*  Store the totals for later reference.  */
    nCerts = dbArray.numCerts;
    nSubjects = dbArray.numSubjects;
    nNicknames = dbArray.numNicknames;
    nSMime = dbArray.numSMime;
    nRevocation = dbArray.numRevocation;
    nSubjCerts = 0;
    for (elem = PR_LIST_HEAD(&dbArray.subjects.link);
         elem != &dbArray.subjects.link; elem = PR_NEXT_LINK(elem)) {
        certDBSubjectEntryMap *smap;
        smap = (certDBSubjectEntryMap *)LISTNODE_CAST(elem)->appData;
        nSubjCerts += smap->numCerts;
    }

    if (info.verbose) {
        /*  Dump the database contents.  */
        verboseOutput(&dbArray, &info);
    }

    freeDBEntryList(&dbArray.certs.link);
    freeDBEntryList(&dbArray.subjects.link);
    freeDBEntryList(&dbArray.nicknames.link);
    freeDBEntryList(&dbArray.smime.link);
    freeDBEntryList(&dbArray.revocation.link);

    PR_fprintf(info.out, "\n");
    PR_fprintf(info.out, "Database statistics:\n");
    PR_fprintf(info.out, "N0: Found %4d Certificate entries.\n",
               nCerts);
    PR_fprintf(info.out, "N1: Found %4d Subject entries (unique DN's).\n",
               nSubjects);
    PR_fprintf(info.out, "N2: Found %4d Cert keys within Subject entries.\n",
               nSubjCerts);
    PR_fprintf(info.out, "N3: Found %4d Nickname entries.\n",
               nNicknames);
    PR_fprintf(info.out, "N4: Found %4d S/MIME entries.\n",
               nSMime);
    PR_fprintf(info.out, "N5: Found %4d CRL entries.\n",
               nRevocation);
    PR_fprintf(info.out, "\n");

    nErr = 0;
    for (i = 0; i < NUM_ERROR_TYPES; i++) {
        PR_fprintf(info.out, "E%d: Found %4d %s\n",
                   i, info.dbErrors[i], errResult[i]);
        nErr += info.dbErrors[i];
    }
    PR_fprintf(info.out, "--------------\n    Found %4d errors in database.\n",
               nErr);

    PR_fprintf(info.out, "\nCertificates:\n");
    PR_fprintf(info.out, "N0 == N2 + E%d + E%d\n", NoSubjectForCert,
               SubjectHasNoKeyForCert);
    nCertsFound = nSubjCerts +
                  info.dbErrors[NoSubjectForCert] +
                  info.dbErrors[SubjectHasNoKeyForCert];
    c = (nCertsFound == nCerts) ? '=' : '!';
    PR_fprintf(info.out, "%d %c= %d + %d + %d\n", nCerts, c, nSubjCerts,
               info.dbErrors[NoSubjectForCert],
               info.dbErrors[SubjectHasNoKeyForCert]);
    PR_fprintf(info.out, "\nSubjects:\n");
    PR_fprintf(info.out,
               "N1 == N3 + N4 + E%d + E%d + E%d + E%d + E%d - E%d - E%d - E%d\n",
               NoNicknameOrSMimeForSubject,
               WrongNicknameForSubject,
               NoNicknameEntry,
               WrongSMimeForSubject,
               NoSMimeEntry,
               NoSubjectForNickname,
               NoSubjectForSMime,
               NicknameAndSMimeEntries);
    nSubjFound = nNicknames + nSMime +
                 info.dbErrors[NoNicknameOrSMimeForSubject] +
                 info.dbErrors[WrongNicknameForSubject] +
                 info.dbErrors[NoNicknameEntry] +
                 info.dbErrors[WrongSMimeForSubject] +
                 info.dbErrors[NoSMimeEntry] -
                 info.dbErrors[NoSubjectForNickname] -
                 info.dbErrors[NoSubjectForSMime] -
                 info.dbErrors[NicknameAndSMimeEntries];
    c = (nSubjFound == nSubjects) ? '=' : '!';
    PR_fprintf(info.out,
               "%2d %c= %2d + %2d + %2d + %2d + %2d + %2d + %2d - %2d - %2d - %2d\n",
               nSubjects, c, nNicknames, nSMime,
               info.dbErrors[NoNicknameOrSMimeForSubject],
               info.dbErrors[WrongNicknameForSubject],
               info.dbErrors[NoNicknameEntry],
               info.dbErrors[WrongSMimeForSubject],
               info.dbErrors[NoSMimeEntry],
               info.dbErrors[NoSubjectForNickname],
               info.dbErrors[NoSubjectForSMime],
               info.dbErrors[NicknameAndSMimeEntries]);
    PR_fprintf(info.out, "\n");
}

#ifdef DORECOVER
#include "dbrecover.c"
#endif /* DORECOVER */

enum {
    cmd_Debug = 0,
    cmd_LongUsage,
    cmd_Recover
};

enum {
    opt_KeepAll = 0,
    opt_CertDir,
    opt_Dumpfile,
    opt_InputDB,
    opt_OutputDB,
    opt_Mailfile,
    opt_Prompt,
    opt_KeepRedundant,
    opt_KeepNoSMimeProfile,
    opt_Verbose,
    opt_KeepExpired
};

static secuCommandFlag dbck_commands[] =
    {
      { /* cmd_Debug,    */ 'D', PR_FALSE, 0, PR_FALSE },
      { /* cmd_LongUsage,*/ 'H', PR_FALSE, 0, PR_FALSE },
      { /* cmd_Recover,  */ 'R', PR_FALSE, 0, PR_FALSE }
    };

static secuCommandFlag dbck_options[] =
    {
      { /* opt_KeepAll,           */ 'a', PR_FALSE, 0, PR_FALSE },
      { /* opt_CertDir,           */ 'd', PR_TRUE, 0, PR_FALSE },
      { /* opt_Dumpfile,          */ 'f', PR_TRUE, 0, PR_FALSE },
      { /* opt_InputDB,           */ 'i', PR_TRUE, 0, PR_FALSE },
      { /* opt_OutputDB,          */ 'o', PR_TRUE, 0, PR_FALSE },
      { /* opt_Mailfile,          */ 'm', PR_FALSE, 0, PR_FALSE },
      { /* opt_Prompt,            */ 'p', PR_FALSE, 0, PR_FALSE },
      { /* opt_KeepRedundant,     */ 'r', PR_FALSE, 0, PR_FALSE },
      { /* opt_KeepNoSMimeProfile,*/ 's', PR_FALSE, 0, PR_FALSE },
      { /* opt_Verbose,           */ 'v', PR_FALSE, 0, PR_FALSE },
      { /* opt_KeepExpired,       */ 'x', PR_FALSE, 0, PR_FALSE }
    };

#define CERT_DB_FMT "%s/cert%s.db"

static char *
dbck_certdb_name_cb(void *arg, int dbVersion)
{
    const char *configdir = (const char *)arg;
    const char *dbver;
    char *smpname = NULL;
    char *dbname = NULL;

    switch (dbVersion) {
        case 8:
            dbver = "8";
            break;
        case 7:
            dbver = "7";
            break;
        case 6:
            dbver = "6";
            break;
        case 5:
            dbver = "5";
            break;
        case 4:
        default:
            dbver = "";
            break;
    }

    /* make sure we return something allocated with PORT_ so we have properly
     * matched frees at the end */
    smpname = PR_smprintf(CERT_DB_FMT, configdir, dbver);
    if (smpname) {
        dbname = PORT_Strdup(smpname);
        PR_smprintf_free(smpname);
    }
    return dbname;
}

int
main(int argc, char **argv)
{
    NSSLOWCERTCertDBHandle *certHandle;

    PRFileDesc *mailfile = NULL;
    PRFileDesc *dumpfile = NULL;

    char *pathname = 0;
    char *fullname = 0;
    char *newdbname = 0;

    PRBool removeExpired, requireProfile, singleEntry;
    SECStatus rv;
    secuCommand dbck;

    dbck.numCommands = sizeof(dbck_commands) / sizeof(secuCommandFlag);
    dbck.numOptions = sizeof(dbck_options) / sizeof(secuCommandFlag);
    dbck.commands = dbck_commands;
    dbck.options = dbck_options;

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

    rv = SECU_ParseCommandLine(argc, argv, progName, &dbck);

    if (rv != SECSuccess)
        Usage(progName);

    if (dbck.commands[cmd_LongUsage].activated)
        LongUsage(progName);

    if (!dbck.commands[cmd_Debug].activated &&
        !dbck.commands[cmd_Recover].activated) {
        PR_fprintf(PR_STDERR, "Please specify -H, -D or -R.\n");
        Usage(progName);
    }

    removeExpired = !(dbck.options[opt_KeepAll].activated ||
                      dbck.options[opt_KeepExpired].activated);

    requireProfile = !(dbck.options[opt_KeepAll].activated ||
                       dbck.options[opt_KeepNoSMimeProfile].activated);

    singleEntry = !(dbck.options[opt_KeepAll].activated ||
                    dbck.options[opt_KeepRedundant].activated);

    if (dbck.options[opt_OutputDB].activated) {
        newdbname = PL_strdup(dbck.options[opt_OutputDB].arg);
    } else {
        newdbname = PL_strdup("new_cert8.db");
    }

    /*  Create a generic graph of the database.  */
    if (dbck.options[opt_Mailfile].activated) {
        mailfile = PR_Open("./mailfile", PR_RDWR | PR_CREATE_FILE, 00660);
        if (!mailfile) {
            fprintf(stderr, "Unable to create mailfile.\n");
            return -1;
        }
    }

    /*  Dump all debugging info while running.  */
    if (dbck.options[opt_Verbose].activated) {
        if (dbck.options[opt_Dumpfile].activated) {
            dumpfile = PR_Open(dbck.options[opt_Dumpfile].arg,
                               PR_RDWR | PR_CREATE_FILE, 00660);
            if (!dumpfile) {
                fprintf(stderr, "Unable to create dumpfile.\n");
                return -1;
            }
        } else {
            dumpfile = PR_STDOUT;
        }
    }

    /*  Set the cert database directory.  */
    if (dbck.options[opt_CertDir].activated) {
        SECU_ConfigDirectory(dbck.options[opt_CertDir].arg);
    }

    pathname = SECU_ConfigDirectory(NULL);

    PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
    rv = NSS_NoDB_Init(pathname);
    if (rv != SECSuccess) {
        fprintf(stderr, "NSS_NoDB_Init failed\n");
        return -1;
    }

    certHandle = PORT_ZNew(NSSLOWCERTCertDBHandle);
    if (!certHandle) {
        SECU_PrintError(progName, "unable to get database handle");
        return -1;
    }
    certHandle->ref = 1;

#ifdef NOTYET
    /*  Open the possibly corrupt database.  */
    if (dbck.options[opt_InputDB].activated) {
        PRFileInfo fileInfo;
        fullname = PR_smprintf("%s/%s", pathname,
                               dbck.options[opt_InputDB].arg);
        if (PR_GetFileInfo(fullname, &fileInfo) != PR_SUCCESS) {
            fprintf(stderr, "Unable to read file \"%s\".\n", fullname);
            return -1;
        }
        rv = CERT_OpenCertDBFilename(certHandle, fullname, PR_TRUE);
    } else
#endif
    {
/*  Use the default.  */
#ifdef NOTYET
        fullname = SECU_CertDBNameCallback(NULL, CERT_DB_FILE_VERSION);
        if (PR_GetFileInfo(fullname, &fileInfo) != PR_SUCCESS) {
            fprintf(stderr, "Unable to read file \"%s\".\n", fullname);
            return -1;
        }
#endif
        rv = nsslowcert_OpenCertDB(certHandle,
                                   PR_TRUE,             /* readOnly */
                                   NULL,                /* rdb appName */
                                   "",                  /* rdb prefix */
                                   dbck_certdb_name_cb, /* namecb */
                                   pathname,            /* configDir */
                                   PR_FALSE);           /* volatile */
    }

    if (rv) {
        SECU_PrintError(progName, "unable to open cert database");
        return -1;
    }

    if (dbck.commands[cmd_Debug].activated) {
        DBCK_DebugDB(certHandle, dumpfile, mailfile);
        return 0;
    }

#ifdef DORECOVER
    if (dbck.commands[cmd_Recover].activated) {
        DBCK_ReconstructDBFromCerts(certHandle, newdbname,
                                    dumpfile, removeExpired,
                                    requireProfile, singleEntry,
                                    dbck.options[opt_Prompt].activated);
        return 0;
    }
#endif

    if (mailfile)
        PR_Close(mailfile);
    if (dumpfile)
        PR_Close(dumpfile);
    if (certHandle) {
        nsslowcert_ClosePermCertDB(certHandle);
        PORT_Free(certHandle);
    }
    return -1;
}
