wilde: utils/admin validate-skiplist.c,NONE,1.1
cvs at intevation.de
cvs at intevation.de
Sun Mar 26 01:24:40 CET 2006
Author: wilde
Update of /kolabrepository/utils/admin
In directory doto:/tmp/cvs-serv2207
Added Files:
validate-skiplist.c
Log Message:
New file validate-skiplist.c -- a simple cyrus skiplist validator.
--- NEW FILE: validate-skiplist.c ---
/* -------------------------------------------------------------------
validate-skiplist
Copyright (C) 2006 by Sascha Wilde <wilde at sha-bang.de>
This program is free software under the GNU GPL (>=v2)
Read the file COPYING coming with the software for details.
-------------------------------------------------------------------
This little tool does a simple syntactic evaluation on cyrus
skiplist database files.
It does no semantic checking, no log replay, and _no_ locking (so
don't use it on files used by a running system.)
WARNING:
This is only tested on little endian systems and will most likely
break on big endian machines!
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <err.h>
#define INFO(blk) if (verbose) { blk }
#define WARN(blk) if (warnings) { blk }
int verbose = 0;
int warnings = 0;
/* skiplist stuff: */
#define MAGICNUM 0xa1028b0d
#define INORDER 1
#define ADD 2
#define DELETE 4
#define COMMIT 255
#define DUMMY 257
/* statistics */
int inorder = 0;
int add = 0;
int delete = 0;
int commit = 0;
void
print_usage ()
{
puts ("Usage: validate-skiplist [OPTIONS] [FILE]");
puts ("Validate cyrus skiplist FILE.\n");
puts (" -w print out non fatal warnings");
puts (" -v be verbose");
puts (" -h print this help message and exit");
exit (0);
}
int32_t
read_word (FILE *file)
{
int i, c;
int32_t word = 0;
for (i = 0; i < 4; i++)
{
word = word << 8;
if ((c = fgetc (file)) == EOF)
errx (1, "Unexpected end of file at 0x%X", ftell (file));
word += c;
}
return word;
}
void
jump_to_position (FILE *file, long pos)
{
if (fseek (file, pos, SEEK_SET) == -1)
errx (1, "Unexpected end of file at 0x%X", ftell (file));
}
void
commit_maybe (FILE *file)
{
if (read_word (file) == COMMIT)
{
++commit;
}
else
fseek (file, -4, SEEK_CUR);
}
void
add_delete (FILE *file)
{
int32_t word;
word = read_word (file);
switch (word)
{
case ADD:
/* FIXME: we should inspect add nodes more in depth. */
while (read_word (file) != 0xffffffff) /* skip till termination */
++add;
break;
case DELETE:
read_word (file);
++delete;
break;
default:
errx (1, "Bad node: expected ADD or DELETE at 0x%X! (found %i)",
ftell (file), word);
}
commit_maybe (file);
}
void
validate_file (char* filename)
{
int i,c;
int32_t word;
long logstart;
FILE *file;
INFO (printf ("Checking file \"%s\"\n", filename););
if (!(file = fopen (filename, "r")))
err (1, "%s", filename);
WARN (word = read_word (file); /* magic number */
if (word != MAGICNUM)
printf ("Strange magic number %X expected %X\n", word, MAGICNUM);
);
INFO (jump_to_position (file, 20); /* jump to version numbers */
printf ("Skiplist file Version %i.", read_word (file));
printf ("%i\n", read_word (file));
printf ("Max level: %i\n", read_word (file));
printf ("Current level: %i\n", read_word (file));
printf ("%i active items\n", read_word (file));
);
jump_to_position (file, 40);
logstart = read_word (file);
INFO (printf ("Log start at 0x%X\n", logstart);
word = read_word (file);
printf ("Last recovery on %s\n", ctime (&word));
);
jump_to_position (file, 48);
if ((word = read_word (file)) != DUMMY)
errx (1, "First skipnode is not of type DUMMY (found %i)\n", word);
jump_to_position (file, logstart);
INFO (puts ("Checking log part..."););
while ((c = getc (file)) != EOF)
{
ungetc (c, file);
add_delete (file);
}
INFO (printf ("Found %i ADD, %i DELETE and %i COMMIT nodes in log.\n",
add, delete, commit);
);
fclose (file);
}
int
main (int argc, char** argv)
{
int c;
while ((c = getopt (argc, argv, "hvw")) != -1)
switch (c)
{
case 'h':
print_usage ();
break;
case 'v':
verbose = 1;
break;
case 'w':
warnings = 1;
break;
default:
exit (1);
}
if (optind == (argc - 1))
validate_file (argv[optind]);
else
errx (1, "Missing filename.");
exit (0);
}
More information about the commits
mailing list