dbcheck.c

来自「db.* (pronounced dee-be star) is an adva」· C语言 代码 · 共 2,087 行 · 第 1/5 页

C
2,087
字号
/*************************************************************************** *                                                                         * * db.*                                                                    * * open source database, dbcheck utility                                   * *                                                                         * * Copyright (c) 2000 Centura Software Corporation. All rights reserved.   * *                                                                         * * Use of this software, whether in source code format, or in executable,  * * binary object code form, is governed by the CENTURA OPEN SOURCE LICENSE * * which is fully described in the LICENSE.TXT file, included within this  * * distribution of source code files.                                      *  *                                                                         * **************************************************************************//*-----------------------------------------------------------------------    dbcheck - db.* Database Consistency Check Utility    To execute:        dbcheck [-options] dbname [dbfile(s)]    Options:        [-s] [-k] [-dk] [-kd] [-ts] [-a] [-r#] [p#] [-f#] [-t] [-c]        [-sg [<mode>,]<password>]    Where:         -s        = Perform complete set consistency check         -k        = Perform key file structure consistency check         -dk       = Perform key access consistency check from data files         -kd       = Perform key data consisteny check from key files         -ts       = Perform time stamp checks for records and sets         -a        = Does -s -dk -kd -ts         -nk       = Disables -k, -dk, -kd, and causes key files to be ignored         -r#       = Report every # percent to stderr         -p#       = Number of pages for db.* to allocate to its page cache         -f#       = Number of open files db.* is allowed to have         -t        = Print a traceback of the b-tree at the first sign of disorder         -c        = Print counts of objects scanned in the check         -sg       = Specifies the SafeGarde encryption information         dbname    = Name of database to be checked         dbfile(s) = If specified check only these files    If no "-" options are specified, dbcheck merely checks the delete    chains and verifies that the ids and addresses in each slot are sane.    The "-" options perform better integrity checks, but can add significant    run time.    The -r option is useful when you have a huge database, and you want    to keep tabs in how far dbcheck has progressed.  The -f and -p options    can improve speed, at the cost of extra memory.  The -t option is used    to quickly inspect the tree to find out why it is disordered.  The -c    option can be useful to determine if the database has application level    integrity.-----------------------------------------------------------------------*//*********************** INCLUDE FILES ******************************/#define MOD dbcheck#include "db.star.h"#include "dbcache.h"#include "version.h"#define DBCHECK#include "cnvfld.h"#define ERR_DEFINE#include "dbcheck.h"#define MAXTEXT 1600/* ********************** EXTERNAL VARIABLE DECLARATIONS ************* */extern char    etext,                    edata,                    end;/* ********************** LOCAL FUNCTION DECLARATIONS **************** */static void flush(void);void EXTERNAL_FCN dbcheck_dberr(int errnum, DB_TCHAR *errmsg){    vtprintf(DB_TEXT("\n%s (errnum = %d)\n"), errmsg, errnum);}/***************************************************************************//***************************************************************************//*                             Main Processing                             *//***************************************************************************//***************************************************************************/int MAIN(int argc, DB_TCHAR *argv[]){    int status = S_OKAY;    long tot_err_cnt = 0;    char *pgbuf = NULL;    CHKOPTS *opts = NULL;    DBINFO *dbi = NULL;    DB_TASK *task = NULL;  /* dberr and other macros reference                              a pointer called 'task' */    setvbuf( stdout, NULL, _IONBF, 0 );    setvbuf( stderr, NULL, _IONBF, 0 );    vtprintf(DBSTAR_UTIL_DESC(DB_TEXT("Database Consistency Check")));    psp_init();    if ((status = parse_args(argc, argv, &opts)) != S_OKAY) {        psp_term();        return 1;    }    fflush(stdout);    psp_handleInterrupt(flush);    if ((status = d_opentask(&task)) == S_OKAY)    {        if ((status = d_set_dberr(dbcheck_dberr, task)) == S_OKAY)        {            if ((status = setup(&pgbuf, opts, &dbi, task)) == S_OKAY)                status = scan(pgbuf, dbi, task);            fflush(stdout);            pr_stat(status, dbi);            if (status == S_OKAY)                pr_counts(dbi, task);            if (dbi)                   /* allocated in setup_db */            {                if (dbi->errinfo)                    tot_err_cnt += dbi->errinfo->tot_err_cnt;                free_dbinfo(dbi);            }            if (pgbuf)                 /* allocated in setup_db */                psp_freeMemory(pgbuf, 0);            d_close(task);            /* database opened in setup() */        }        d_closetask(task);    }    psp_handleInterrupt(NULL);    if (status != S_OKAY)        tot_err_cnt++;    if (opts)                        /* allocated in parse_args */    {        if (opts->fnames)            psp_freeMemory(opts->fnames, 0);        psp_freeMemory(opts, 0);    }    psp_term();    return(tot_err_cnt != 0);}/*************************************************************************    Parse the argument vector*/   static int parse_args(int argc, DB_TCHAR **argv, CHKOPTS **ppopts){    register int i;    CHKOPTS *opts;#if defined(SAFEGARDE)    DB_TCHAR *cp;    DB_TCHAR *password;    int       mode;#endif    if (argc < 2)    {        usage();        return(S_UNAVAIL);    }    opts = (CHKOPTS *) psp_cGetMemory(sizeof(CHKOPTS), 0);    if (!opts)        return(S_NOMEMORY);    opts->report = -1;    opts->numpages = 64;    opts->fnames = (DB_TCHAR **) psp_cGetMemory(argc * sizeof(DB_TCHAR *), 0);    if (opts->fnames == NULL)    {        psp_freeMemory(opts, 0);        return(S_NOMEMORY);    }    /* process the options */    for (i = 1; i < argc; i++)    {        if (vtstricmp(argv[i], DB_TEXT("-s")) == 0)            opts->setscan = TRUE;        else if (vtstricmp(argv[i], DB_TEXT("-k")) == 0)            opts->keyscan = TRUE;        else if (vtstricmp(argv[i], DB_TEXT("-dk")) == 0)            opts->datkey = TRUE;        else if (vtstricmp(argv[i], DB_TEXT("-kd")) == 0)            opts->keydat = TRUE;        else if (vtstricmp(argv[i], DB_TEXT("-ts")) == 0)            opts->timestmp = TRUE;        else if (vtstricmp(argv[i], DB_TEXT("-nk")) == 0)            opts->ignorekey = TRUE;        else if (vtstrnicmp(argv[i], DB_TEXT("-r"), 2) == 0)            opts->report = (short) vttoi(argv[i] + 2);        else if (vtstrnicmp(argv[i], DB_TEXT("-p"), 2) == 0)            opts->numpages = (short) vttoi(argv[i] + 2);        else if (vtstrnicmp(argv[i], DB_TEXT("-f"), 2) == 0)            opts->numfiles = (short) vttoi(argv[i] + 2);        else if (vtstricmp(argv[i], DB_TEXT("-t")) == 0)            opts->treetrace = TRUE;        else if (vtstricmp(argv[i], DB_TEXT("-c")) == 0)            opts->counts = TRUE;        else if (vtstricmp(argv[i], DB_TEXT("-a")) == 0)        {            opts->keyscan = opts->setscan = opts->datkey =            opts->keydat = opts->timestmp = TRUE;        }        else if (vtstricmp(argv[i], DB_TEXT("-sg")) == 0)        {            if (i == argc - 1)            {                vftprintf(stderr, DB_TEXT("dbcheck: no password specified\n"));                usage();                return S_UNAVAIL;            }#if defined(SAFEGARDE)            if ((cp = vtstrchr(argv[++i], DB_TEXT(','))) != NULL)                *cp++ = DB_TEXT('\0');            if (cp)            {                if (vtstricmp(argv[i], "low") == 0)                    mode = LOW_ENC;                else if (vtstricmp(argv[i], "med") == 0)                    mode = MED_ENC;                else if (vtstricmp(argv[i], "high") == 0)                    mode = HIGH_ENC;                else                {                    vftprintf(stderr, DB_TEXT("dbcheck: invalid encryption mode\n"));                    usage();                    return S_UNAVAIL;                }                password = cp;            }            else            {                mode = MED_ENC;                password = argv[i];            }            if ((opts->sg = sg_create(mode, password)) == NULL)            {                vftprintf(stderr, DB_TEXT("dbcheck: Could not create SafeGarde context\n"));                return S_UNAVAIL;            }#else            vftprintf(stderr, DB_TEXT("dbcheck: SafeGarde is not available in this version\n"));            return S_UNAVAIL;#endif        }        else if (argv[i][0] == DB_TEXT('-'))        {            vftprintf(stderr, DB_TEXT("dbcheck: invalid option: %s\n"), argv[i]);            usage();            return(S_UNAVAIL);        }        else if (opts->dbname == NULL)            opts->dbname = argv[i];    /* first non-option string is db name */        else            opts->fnames[opts->nfnames++] = argv[i];    }    if (opts->dbname == NULL)    {        usage();        return(S_UNAVAIL);    }    if (opts->ignorekey == TRUE)    {        opts->keyscan = opts->datkey = opts->keydat = FALSE;    }    *ppopts = opts;    return(S_OKAY);}/***************************************************************************    Print a usage message*/static void usage(){    vtprintf(DB_TEXT("usage:  dbcheck [-options] dbname [dbfile(s)]\n"));    vtprintf(DB_TEXT("options: [-s] [-k] [-dk] [-kd] [-a] [-nk] [-ts] [-r#] [-p#] [-f#] [-t] [-c]\n"));    vtprintf(DB_TEXT("         [-sg [<mode>,]password]\n\n"));    vtprintf(DB_TEXT("  -s  = Perform complete set consistency check\n"));    vtprintf(DB_TEXT("  -k  = Perform key file structure consistency check\n"));    vtprintf(DB_TEXT("  -dk = Perform key access consistency check from data to key files\n"));    vtprintf(DB_TEXT("  -kd = Perform key data consistency check from key to data files\n"));    vtprintf(DB_TEXT("  -a  = Does -s -dk -kd -ts\n"));    vtprintf(DB_TEXT("  -nk = Disables -k, -dk, -kd, and causes key files to be ignored\n"));    vtprintf(DB_TEXT("  -ts = Perform time stamp checks for records and sets\n"));    vtprintf(DB_TEXT("  -r# = Report every # percent to stderr\n"));    vtprintf(DB_TEXT("  -p# = Max number of pages for its page cache\n"));    vtprintf(DB_TEXT("  -f# = Max number of open files allowed to have open at once\n"));    vtprintf(DB_TEXT("  -t  = Print a traceback of the b-tree at the first sign of disorder\n"));    vtprintf(DB_TEXT("  -c  = Print counts of objects scanned in the check\n"));    vtprintf(DB_TEXT("  -sg = Specifies SafeGarde encryption information\n"));    vtprintf(DB_TEXT("         <mode> can be 'low', 'med' (default), or 'high'\n"));    vtprintf(DB_TEXT("\n"));}/***************************************************************************    Flush the stdout buffer in case only a few errors were found.*/static void flush(void){    DB_TCHAR ch;    fflush(stdout);    vtprintf(DB_TEXT("[INTERRUPT] Terminate? (y/n) "));    do {        ch = vgettchar();        if (ch == DB_TEXT('y') || ch == DB_TEXT('Y'))            exit(1);    } while (ch != DB_TEXT('\n') && ch != DB_TEOF);    vtprintf(DB_TEXT("Continuing execution\n"));}/**************************************************************************    returns dbd_ver of DBD*/static int get_dbd_ver(DB_TCHAR *dbname, char *dbd_ver, DB_TASK *task){    DB_TCHAR dbfile[FILENMLEN] = DB_TEXT("");    PSP_FH   dbf;    int      stat = S_OKAY;    /* form database dictionary name */    if (vtstrlen(dbname) + vtstrlen(DB_REF(db_name)) >= FILENMLEN + 4)        return (dberr(S_NAMELEN));    vtstrcpy(dbfile, dbname);    vtstrcat(dbfile, DB_TEXT(".dbd"));    if ((dbf = psp_fileOpen(dbfile, O_RDONLY, PSP_FLAG_DENYNO)) == NULL)        return (dberr(S_INVDB));    if (psp_fileRead(dbf, (void *) dbd_ver, DBD_COMPAT_LEN) != DBD_COMPAT_LEN)        stat = S_OKAY;    psp_fileClose(dbf);     if (stat != S_OKAY)        dberr(stat);    return(stat);}/**************************************************************************    Setup structures used later*/static int setup(    char **ppbuf,    CHKOPTS *opts,    DBINFO **ppdb,    DB_TASK *task){    int status = S_OKAY;    if ((status = setup_db(ppbuf, opts, ppdb, task)) == S_OKAY)    {        if ((status = setup_keys(*ppdb, task)) == S_OKAY)        {            if ((status = setup_sets(*ppdb, task)) == S_OKAY)            {                if ((status = setup_tots(*ppdb, task)) == S_OKAY)                {                    if ((status = setup_cnts(*ppdb, task)) == S_OKAY)                        status = setup_temp_files(*ppdb, task);                }            }        }    }    return status;}/***************************************************************************    Open the database and read the data dictionary*/static int setup_db(    char **ppbuf,    CHKOPTS *opts,    DBINFO **ppdb,    DB_TASK *task){    int      i, j, status = S_OKAY;    DB_TCHAR dbfile[FILENMLEN];    PSP_FH   dbf;    DB_TCHAR filnam[FILENMLEN];    DBINFO  *dbi;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?