809 lines
15 KiB
C
809 lines
15 KiB
C
|
/*
|
||
|
dumpgdbm.c
|
||
|
==========
|
||
|
|
||
|
Very old Homepage = http://tboudet.free.fr/dumpgdbm/
|
||
|
|
||
|
|
||
|
(g) 2003 Thierry Boudet - aka TontonTh
|
||
|
|
||
|
*/
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <unistd.h>
|
||
|
#include <string.h>
|
||
|
#include <ctype.h>
|
||
|
#include <gdbm.h>
|
||
|
|
||
|
#include <readline/readline.h>
|
||
|
#include <readline/history.h>
|
||
|
|
||
|
#include <regex.h>
|
||
|
|
||
|
#define MAIN 1
|
||
|
|
||
|
#include "dumpgdbm.h"
|
||
|
|
||
|
/* --------------------------------------------------------------------- */
|
||
|
/* global variables */
|
||
|
|
||
|
int warn_if_key_empty = 0;
|
||
|
int found_an_empty_key = 0;
|
||
|
int interactive = 0;
|
||
|
int leading_zero = 1;
|
||
|
|
||
|
#define MAX_FILENAME_LENGTH 4242 /* 63 bytes for a filename is enough
|
||
|
for all. -imaginary BG- */
|
||
|
|
||
|
char filename[MAX_FILENAME_LENGTH+2];
|
||
|
|
||
|
/* --------------------------------------------------------------------- */
|
||
|
static void
|
||
|
dump_entry(datum key, datum data, int maxsize)
|
||
|
{
|
||
|
|
||
|
#if TRACE
|
||
|
printf("@,L: %p,%d %p,%d\n", key.dptr, key.dsize, data.dptr, data.dsize);
|
||
|
#endif
|
||
|
|
||
|
printf("K: ");
|
||
|
if (hexadecimal) hexadump(key.dptr, key.dsize);
|
||
|
else if (octal) octaldump(key.dptr, key.dsize);
|
||
|
else asciidump(key.dptr, key.dsize);
|
||
|
|
||
|
printf("D: ");
|
||
|
if (hexadecimal) hexadump(data.dptr, data.dsize);
|
||
|
else if (octal) octaldump(data.dptr, data.dsize);
|
||
|
else asciidump(data.dptr, data.dsize);
|
||
|
|
||
|
free(data.dptr); /* XXX XXX */
|
||
|
|
||
|
printf("\n");
|
||
|
}
|
||
|
/* --------------------------------------------------------------------- */
|
||
|
/*
|
||
|
* here we have the main loop for batches dumps.
|
||
|
*/
|
||
|
static int
|
||
|
dump_gdbm_file(char *name)
|
||
|
{
|
||
|
GDBM_FILE file;
|
||
|
datum entry, datas;
|
||
|
|
||
|
file = gdbm_open(name, 512, GDBM_READER, 0444, NULL);
|
||
|
#if TRACE
|
||
|
fprintf(stderr, "retour gdbm_open = %08lx\n", (unsigned long)file);
|
||
|
#endif
|
||
|
|
||
|
if (file == NULL)
|
||
|
{
|
||
|
fprintf(stderr, "can't open %s\n", name);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
entry = gdbm_firstkey(file);
|
||
|
if (entry.dptr == NULL)
|
||
|
{
|
||
|
fprintf(stderr, "database %s is empty\n", name);
|
||
|
exit(2);
|
||
|
}
|
||
|
|
||
|
do
|
||
|
{
|
||
|
datas = gdbm_fetch(file, entry);
|
||
|
if (entry.dsize == 0)
|
||
|
{
|
||
|
found_an_empty_key = 1;
|
||
|
}
|
||
|
dump_entry(entry, datas, maxoctets);
|
||
|
/*
|
||
|
* XXX may be we must free the data memory here ?
|
||
|
*/
|
||
|
entry = gdbm_nextkey(file, entry);
|
||
|
} while ( entry.dptr != NULL);
|
||
|
|
||
|
gdbm_close(file);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
/* --------------------------------------------------------------------- */
|
||
|
/*
|
||
|
* Oct 17 2002: use of regular expressions.
|
||
|
*/
|
||
|
int search_key(GDBM_FILE gf, char * pattern)
|
||
|
{
|
||
|
datum entry, datas;
|
||
|
char *bufptr, *cptr;
|
||
|
int foo;
|
||
|
regex_t reg;
|
||
|
regmatch_t match[1];
|
||
|
|
||
|
if (pattern == NULL)
|
||
|
{
|
||
|
fprintf(stderr, "no pattern ??\n");
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
foo = strlen(pattern);
|
||
|
if (pattern[foo-1] == '\n')
|
||
|
pattern[foo-1] = '\0';
|
||
|
#if TRACE
|
||
|
fprintf(stderr, "Search Key: cleaned pattern [%s]\n", pattern);
|
||
|
#endif
|
||
|
|
||
|
foo = regcomp(®, pattern, REG_EXTENDED);
|
||
|
#if TRACE
|
||
|
printf("regcomp ---> %d\n", foo);
|
||
|
#endif
|
||
|
|
||
|
entry = gdbm_firstkey(gf);
|
||
|
if (entry.dptr == NULL)
|
||
|
{
|
||
|
fprintf(stderr, "database is empty or bugged\n");
|
||
|
exit(2);
|
||
|
}
|
||
|
|
||
|
do
|
||
|
{
|
||
|
bufptr = (char *)malloc(entry.dsize+2);
|
||
|
if (bufptr == NULL)
|
||
|
{
|
||
|
fprintf(stderr, "in Search Key: no memory, sorry\n");
|
||
|
exit(5);
|
||
|
}
|
||
|
|
||
|
strncpy(bufptr, entry.dptr, entry.dsize);
|
||
|
bufptr[entry.dsize] = '\0';
|
||
|
#if TRACE
|
||
|
fprintf(stderr, "Search Key: bufptr is [%s]\n", bufptr);
|
||
|
#endif
|
||
|
|
||
|
foo = regexec(®, bufptr, 1, match, 0);
|
||
|
if (foo==0)
|
||
|
{
|
||
|
datas = gdbm_fetch(gf, entry);
|
||
|
dump_entry(entry, datas, maxoctets);
|
||
|
}
|
||
|
|
||
|
free(bufptr); /* 26 Jul 2002 */
|
||
|
|
||
|
entry = gdbm_nextkey(gf, entry);
|
||
|
|
||
|
} while ( entry.dptr != NULL);
|
||
|
|
||
|
regfree(®);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
/* --------------------------------------------------------------------- */
|
||
|
/*
|
||
|
* Oct 16 2002: use of regular expressions.
|
||
|
*/
|
||
|
int search_data(GDBM_FILE gf, char * pattern)
|
||
|
{
|
||
|
datum entry, datas;
|
||
|
char *bufptr;
|
||
|
int foo;
|
||
|
regex_t reg;
|
||
|
regmatch_t match[1];
|
||
|
|
||
|
if (pattern == NULL)
|
||
|
{
|
||
|
fprintf(stderr, "no pattern ??\n");
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
foo = strlen(pattern);
|
||
|
if (pattern[foo-1] == '\n')
|
||
|
pattern[foo-1] = '\0';
|
||
|
#if TRACE
|
||
|
fprintf(stderr, "\nSearch Data: cleaned pattern [%s]\n", pattern);
|
||
|
#endif
|
||
|
|
||
|
foo = regcomp(®, pattern, REG_EXTENDED);
|
||
|
#if TRACE
|
||
|
printf("regcomp ---> %d\n", foo);
|
||
|
#endif
|
||
|
|
||
|
entry = gdbm_firstkey(gf);
|
||
|
if (entry.dptr == NULL)
|
||
|
{
|
||
|
fprintf(stderr, "database is empty or bugged\n");
|
||
|
exit(2);
|
||
|
}
|
||
|
|
||
|
do
|
||
|
{
|
||
|
datas = gdbm_fetch(gf, entry);
|
||
|
|
||
|
if (datas.dsize > 0)
|
||
|
{
|
||
|
bufptr = (char *)malloc(datas.dsize+2);
|
||
|
if (bufptr == NULL)
|
||
|
{
|
||
|
fprintf(stderr, "in Search Data: no memory, sorry\n");
|
||
|
exit(5);
|
||
|
}
|
||
|
|
||
|
strncpy(bufptr, datas.dptr, datas.dsize);
|
||
|
bufptr[datas.dsize] = '\0';
|
||
|
#if TRACE
|
||
|
// fprintf(stderr, "Search Data: bufptr [%s]\n", bufptr);
|
||
|
#endif
|
||
|
|
||
|
foo = regexec(®, bufptr, 1, match, 0);
|
||
|
if (foo==0)
|
||
|
{
|
||
|
dump_entry(entry, datas, maxoctets);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
fprintf(stderr, "data size is 0 ?\n");
|
||
|
}
|
||
|
entry = gdbm_nextkey(gf, entry);
|
||
|
} while ( entry.dptr != NULL);
|
||
|
|
||
|
regfree(®);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/* --------------------------------------------------------------------- */
|
||
|
|
||
|
#define CMDLINE_LENGTH 80
|
||
|
|
||
|
#define CMD_QUIT 1
|
||
|
#define CMD_HEX 2
|
||
|
#define CMD_ASCII 3
|
||
|
#define CMD_OCTAL 4
|
||
|
#define CMD_FIRST 5
|
||
|
#define CMD_NEXT 6
|
||
|
#define CMD_SEVEN 7
|
||
|
#define CMD_HEIGHT 8
|
||
|
|
||
|
#define CMD_PRINT 10
|
||
|
#define CMD_KEYSEARCH 12
|
||
|
#define CMD_DATASEARCH 13
|
||
|
#define CMD_MAXOCT 14
|
||
|
#define CMD_FMBL 15
|
||
|
#define CMD_EMPTY 16
|
||
|
|
||
|
#define CMD_HELP 42
|
||
|
#define CMD_LISTCOM 43
|
||
|
#define CMD_VERSION 51
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
char *keyw;
|
||
|
int code;
|
||
|
} Commande;
|
||
|
|
||
|
Commande commandes[] =
|
||
|
{
|
||
|
{ "q", CMD_QUIT },
|
||
|
{ "ZZ", CMD_QUIT },
|
||
|
{ ":q", CMD_QUIT },
|
||
|
{ ":q!", CMD_QUIT },
|
||
|
{ "exit", CMD_QUIT },
|
||
|
{ "quit", CMD_QUIT },
|
||
|
{ "bye", CMD_QUIT },
|
||
|
|
||
|
{ "x", CMD_HEX },
|
||
|
{ "hex", CMD_HEX },
|
||
|
{ "hexa", CMD_HEX },
|
||
|
|
||
|
{ "a", CMD_ASCII },
|
||
|
{ "ascii", CMD_ASCII },
|
||
|
|
||
|
{ "o", CMD_OCTAL },
|
||
|
{ "octal", CMD_OCTAL },
|
||
|
|
||
|
{ "h", CMD_HELP },
|
||
|
{ "help", CMD_HELP },
|
||
|
{ "?", CMD_HELP },
|
||
|
|
||
|
{ "f", CMD_FIRST },
|
||
|
{ "first", CMD_FIRST },
|
||
|
|
||
|
{ "m", CMD_MAXOCT },
|
||
|
{ "maxoctets", CMD_MAXOCT },
|
||
|
{ "maxbytes", CMD_MAXOCT },
|
||
|
|
||
|
{ "n", CMD_NEXT },
|
||
|
{ "next", CMD_NEXT },
|
||
|
|
||
|
{ "p", CMD_PRINT },
|
||
|
{ "print", CMD_PRINT },
|
||
|
|
||
|
{ "ks", CMD_KEYSEARCH },
|
||
|
{ "keysearch", CMD_KEYSEARCH },
|
||
|
|
||
|
{ "ds", CMD_DATASEARCH },
|
||
|
{ "datasearch", CMD_DATASEARCH },
|
||
|
|
||
|
{ "empty", CMD_EMPTY },
|
||
|
|
||
|
{ "7", CMD_SEVEN },
|
||
|
{ "8", CMD_HEIGHT },
|
||
|
|
||
|
{ "V", CMD_VERSION },
|
||
|
{ "version", CMD_VERSION },
|
||
|
|
||
|
{ "commands", CMD_LISTCOM },
|
||
|
{ "listcom", CMD_LISTCOM },
|
||
|
|
||
|
{ "sux", 0 }
|
||
|
};
|
||
|
|
||
|
#define NBRE_CMD (sizeof(commandes)/sizeof(Commande))
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
int number;
|
||
|
char *text;
|
||
|
} Help;
|
||
|
|
||
|
|
||
|
char Help_version[] =
|
||
|
"If you send me a bug report at <oulala@chez.com>, you must give me\n"
|
||
|
" this information, with the output of 'uname -a' command.";
|
||
|
char Help_maxoctet[] =
|
||
|
"change the number of bytes displayed for key & data field.\n"
|
||
|
" can be modified with the -m NN command line option.";
|
||
|
char Help_print[] =
|
||
|
"re-print the current record, so you can see it with different 'base':\n"
|
||
|
" ascii, hexadecimal or octal. use '? [a|x|o]' for more info.";
|
||
|
char Help_first[] =
|
||
|
"JUMPTO the first record. you have to understand this. man gdbm.";
|
||
|
char Help_next[] =
|
||
|
"GOTO the next record. you have to understand this. 'man gdbm' is a must.";
|
||
|
char Help_seven[] =
|
||
|
"only true ASCII chars are printed. others are displayed as '.'";
|
||
|
char Help_height[] =
|
||
|
"display all chars. beware of differences in charset between Os !";
|
||
|
char Help_KS[] = "Search a posix regex pattern in all the key fields.";
|
||
|
char Help_DS[] = "POSIX extended regex search in all the data fields.";
|
||
|
char No_Help_Text[] = "this help text need to be written...";
|
||
|
|
||
|
Help help[] =
|
||
|
{
|
||
|
{ 0, "just a joke for my friend tnemeth :)" },
|
||
|
{ CMD_QUIT, "good bye, cruel world." },
|
||
|
{ CMD_VERSION, Help_version },
|
||
|
{ CMD_HEX, "switch to hexadecimal display." },
|
||
|
{ CMD_OCTAL, "switch to octal display, you own a pdp11 ???" },
|
||
|
{ CMD_ASCII, "switch to ascii display, see 7 & 8 commands." },
|
||
|
{ CMD_MAXOCT, Help_maxoctet },
|
||
|
{ CMD_PRINT, Help_print },
|
||
|
{ CMD_FIRST, Help_first },
|
||
|
{ CMD_NEXT, Help_next },
|
||
|
{ CMD_SEVEN, Help_seven },
|
||
|
{ CMD_HEIGHT, Help_height },
|
||
|
|
||
|
{ CMD_KEYSEARCH, Help_KS },
|
||
|
{ CMD_DATASEARCH, Help_DS },
|
||
|
|
||
|
{ CMD_HELP, "sure, 42 is the ultimate answer !" }
|
||
|
};
|
||
|
|
||
|
#define NBRE_HELP (sizeof(help)/sizeof(Help))
|
||
|
|
||
|
// -------------------------
|
||
|
|
||
|
static int
|
||
|
lookup_cmd(char *cmd)
|
||
|
{
|
||
|
int foo;
|
||
|
|
||
|
/*
|
||
|
* bon, la, c'est un hack un peu crade... mais je pense
|
||
|
* que c'est qu'on rec,oit un parametre foireux...
|
||
|
*/
|
||
|
if ( cmd[strlen(cmd)-1] == '\n') cmd[strlen(cmd)-1] = '\0';
|
||
|
|
||
|
#if TRACE
|
||
|
printf("lookup cmd [%s]\n", cmd);
|
||
|
#endif
|
||
|
|
||
|
for (foo=0; foo<NBRE_CMD; foo++)
|
||
|
{
|
||
|
|
||
|
#if TRACE
|
||
|
// printf("try cmd #%d %s\n", foo, commandes[foo].keyw);
|
||
|
#endif
|
||
|
|
||
|
if ( ! strcmp(commandes[foo].keyw, cmd) )
|
||
|
return commandes[foo].code;
|
||
|
}
|
||
|
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
// -------------------------
|
||
|
|
||
|
static void
|
||
|
help_cli(void)
|
||
|
{
|
||
|
int foo, bar;
|
||
|
|
||
|
printf("----------------( Help me Obi Wan ! )---------------\n");
|
||
|
for (foo=bar=0; foo<NBRE_CMD; foo++)
|
||
|
{
|
||
|
bar += printf("%s ", commandes[foo].keyw);
|
||
|
if (bar > 69) /* sex number ? */
|
||
|
{
|
||
|
bar = 0; puts("");
|
||
|
}
|
||
|
}
|
||
|
printf("\n-----------( use '? command' for details )----------\n");
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
full_help(char *keyword)
|
||
|
{
|
||
|
int num_keyword, foo;
|
||
|
|
||
|
num_keyword = lookup_cmd(keyword);
|
||
|
|
||
|
#if TRACE
|
||
|
fprintf(stderr, "%s -> %d\n", keyword, num_keyword);
|
||
|
#endif
|
||
|
|
||
|
if (num_keyword == -1)
|
||
|
{
|
||
|
printf("%s: no such command\n", keyword);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for (foo=0; foo<NBRE_HELP; foo++)
|
||
|
{
|
||
|
#if TRACE
|
||
|
fprintf(stderr, "%4d %4d %s\n", foo, help[foo].number, help[foo].text);
|
||
|
#endif
|
||
|
if (help[foo].number == num_keyword)
|
||
|
{
|
||
|
printf("\ncommand [%s]\n %s\n\n", keyword, help[foo].text);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static int list_commands(int foo)
|
||
|
{
|
||
|
|
||
|
puts("q ZZ exit : quit Dumpgdbm.");
|
||
|
puts("x hex : hexadecimal display");
|
||
|
puts("a ascii : ascii display");
|
||
|
puts("o octal : octal display");
|
||
|
// puts("h help | help");
|
||
|
puts("f first : jump to first record");
|
||
|
puts("n next : next record");
|
||
|
puts("m maxbytes : set number of displayed bytes");
|
||
|
puts("p print : redisplay the current record");
|
||
|
puts("ks : key search");
|
||
|
puts("ds | data search");
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// -------------------------
|
||
|
// Interpreteur de commandes
|
||
|
// -------------------------
|
||
|
static void
|
||
|
shell(void)
|
||
|
{
|
||
|
char *cptr, *pline;
|
||
|
int code_cmd, flag_exit, value;
|
||
|
GDBM_FILE gdbm_file;
|
||
|
datum entry, datas;
|
||
|
int first_ok = 0;
|
||
|
|
||
|
flag_exit = 0; // on va pas s'arreter maintenant ?
|
||
|
|
||
|
printf("working on [%s]\n", filename);
|
||
|
|
||
|
gdbm_file = gdbm_open(filename, 512, GDBM_READER, 0444, NULL);
|
||
|
if (gdbm_file == NULL)
|
||
|
{
|
||
|
fprintf(stderr, "can't open %s\n", filename);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* init of readline behaviour
|
||
|
*/
|
||
|
rl_bind_key('\t', rl_insert); /* no filename completion, silly here :) */
|
||
|
|
||
|
do
|
||
|
{
|
||
|
pline = readline("dumpgdbm > ");
|
||
|
if (pline == NULL)
|
||
|
{
|
||
|
printf("\nEOF ?\n");
|
||
|
break;
|
||
|
}
|
||
|
/*
|
||
|
* if the line is not empty, add it to the history
|
||
|
*/
|
||
|
if ( pline && *pline )
|
||
|
add_history(pline);
|
||
|
|
||
|
#if TRACE
|
||
|
printf("[%s]\n", pligne);
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
* search the first token on the line
|
||
|
*/
|
||
|
cptr = strtok(pline, " \t");
|
||
|
#if TRACE
|
||
|
fprintf(stderr, "pline %p cptr %p\n", pline, cptr);
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
* is there a text on this command-line ?
|
||
|
*/
|
||
|
if ( cptr==NULL || !strcmp("\n", cptr) ) continue;
|
||
|
|
||
|
#if TRACE
|
||
|
printf("token = %s\n", cptr);
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
* Ok, la commande est pointee par cptr, on va tenter
|
||
|
* de la comprendre...
|
||
|
*/
|
||
|
code_cmd = lookup_cmd(cptr);
|
||
|
|
||
|
switch (code_cmd)
|
||
|
{
|
||
|
case CMD_QUIT: flag_exit = 1; break;
|
||
|
|
||
|
case CMD_HEX:
|
||
|
hexadecimal = 1;
|
||
|
octal = 0;
|
||
|
break;
|
||
|
|
||
|
case CMD_OCTAL:
|
||
|
octal = 1;
|
||
|
hexadecimal = 0;
|
||
|
break;
|
||
|
|
||
|
case CMD_ASCII:
|
||
|
octal = hexadecimal = 0;
|
||
|
break;
|
||
|
|
||
|
case CMD_HELP:
|
||
|
cptr = strtok(NULL, " \t");
|
||
|
if (cptr == NULL || *cptr == '\0')
|
||
|
help_cli();
|
||
|
else
|
||
|
full_help(cptr);
|
||
|
break;
|
||
|
|
||
|
case CMD_VERSION: print_version(1); break;
|
||
|
|
||
|
case CMD_FIRST:
|
||
|
entry = gdbm_firstkey(gdbm_file);
|
||
|
if (entry.dptr == NULL)
|
||
|
{
|
||
|
fprintf(stderr, "database is empty\n");
|
||
|
break;
|
||
|
}
|
||
|
datas = gdbm_fetch(gdbm_file, entry);
|
||
|
dump_entry(entry, datas, maxoctets);
|
||
|
first_ok = 1;
|
||
|
break;
|
||
|
|
||
|
case CMD_NEXT:
|
||
|
if (first_ok)
|
||
|
entry = gdbm_nextkey(gdbm_file, entry);
|
||
|
else
|
||
|
entry = gdbm_firstkey(gdbm_file);
|
||
|
first_ok = 1;
|
||
|
if (entry.dptr == NULL)
|
||
|
{
|
||
|
fprintf(stderr, "end of database\n");
|
||
|
break;
|
||
|
}
|
||
|
datas = gdbm_fetch(gdbm_file, entry);
|
||
|
dump_entry(entry, datas, maxoctets);
|
||
|
break;
|
||
|
|
||
|
case CMD_PRINT:
|
||
|
if ( ! first_ok )
|
||
|
entry = gdbm_firstkey(gdbm_file);
|
||
|
first_ok = 42;
|
||
|
if (entry.dptr == NULL)
|
||
|
{
|
||
|
fprintf(stderr, "Print: no entry\n");
|
||
|
break;
|
||
|
}
|
||
|
datas = gdbm_fetch(gdbm_file, entry);
|
||
|
dump_entry(entry, datas, maxoctets);
|
||
|
break;
|
||
|
|
||
|
case CMD_KEYSEARCH:
|
||
|
cptr = strtok(NULL, " \t");
|
||
|
if (cptr != NULL)
|
||
|
{
|
||
|
search_key(gdbm_file, cptr);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
fprintf(stderr, "keysearch need an argument\n");
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CMD_DATASEARCH:
|
||
|
#if TRACE
|
||
|
fprintf(stderr, "==== DATA SEARCH ====\n");
|
||
|
#endif
|
||
|
search_data(gdbm_file, strtok(NULL, " \t"));
|
||
|
break;
|
||
|
|
||
|
case CMD_MAXOCT:
|
||
|
|
||
|
cptr = strtok(NULL, " \t");
|
||
|
if (cptr != NULL)
|
||
|
{
|
||
|
#if TRACE
|
||
|
fprintf(stderr, "MAXOCT: cptr %s\n", cptr);
|
||
|
#endif
|
||
|
if ( sscanf(cptr, "%d", &value) == 1 )
|
||
|
{
|
||
|
printf("maxoctets = %d\n", value);
|
||
|
maxoctets = value;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
fprintf(stderr, "need a numeric argument\n");
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
case CMD_SEVEN:
|
||
|
ok_for_8_bits = 0;
|
||
|
break;
|
||
|
|
||
|
case CMD_HEIGHT:
|
||
|
ok_for_8_bits = 1;
|
||
|
break;
|
||
|
|
||
|
case CMD_LISTCOM:
|
||
|
list_commands(0);
|
||
|
break;
|
||
|
|
||
|
case 0:
|
||
|
fprintf(stderr, "\t\tChimera roulaize grave a donf\n");
|
||
|
fprintf(stderr, "\t\tAthena widgets are so nice !!\n");
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
fprintf(stderr, "command %s : huho ?\n", cptr);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
#if TRACE
|
||
|
fprintf(stderr, "freeing command line %p\n", pline);
|
||
|
#endif
|
||
|
free(pline);
|
||
|
|
||
|
} while ( ! flag_exit );
|
||
|
|
||
|
}
|
||
|
|
||
|
/* --------------------------------------------------------------------- */
|
||
|
|
||
|
static char *optstring = "VvxohwW8m:ia";
|
||
|
|
||
|
int main(int argc, char *argv[])
|
||
|
{
|
||
|
int option_retour;
|
||
|
int foo;
|
||
|
|
||
|
init_global_vars();
|
||
|
|
||
|
while ( (option_retour = getopt(argc, argv, optstring)) >= 0)
|
||
|
{
|
||
|
#if TRACE
|
||
|
fprintf(stderr, "getopt = %d, argc = %d, optind = %d\n",
|
||
|
option_retour, argc, optind);
|
||
|
#endif
|
||
|
switch (option_retour)
|
||
|
{
|
||
|
case 'V':
|
||
|
print_version(1);
|
||
|
exit(1);
|
||
|
break;
|
||
|
case 'v':
|
||
|
verbosity++;
|
||
|
if (verbosity > 5)
|
||
|
{
|
||
|
fprintf(stderr, "Higher verbosity !\n");
|
||
|
fprintf(stderr, "now dumping kernel...\n");
|
||
|
sleep(5);
|
||
|
exit(1);
|
||
|
}
|
||
|
break;
|
||
|
case 'a':
|
||
|
hexadecimal = octal = 0;
|
||
|
break;
|
||
|
case 'x':
|
||
|
hexadecimal = 1;
|
||
|
octal = 0;
|
||
|
break;
|
||
|
case 'o':
|
||
|
octal = 1;
|
||
|
hexadecimal = 0;
|
||
|
break;
|
||
|
case 'h':
|
||
|
print_version(0);
|
||
|
print_options();
|
||
|
exit(2);
|
||
|
break;
|
||
|
case 'w':
|
||
|
warn_if_key_empty = 1;
|
||
|
break;
|
||
|
case '8':
|
||
|
ok_for_8_bits = 1;
|
||
|
break;
|
||
|
case 'i':
|
||
|
interactive = 1;
|
||
|
break;
|
||
|
case 'm':
|
||
|
if (sscanf(optarg, "%d", &foo) == 1)
|
||
|
{
|
||
|
maxoctets = foo;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
fprintf(stderr,"opt 'm' need a numeric arg\n");
|
||
|
exit(5);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#if TRACE
|
||
|
fprintf(stderr, "fin traitement options argc=%d, optind=%d\n",
|
||
|
argc, optind);
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
* a cet endroit il est probable qu'on puisse memoriser
|
||
|
* le nom du fichier GDBM dans une variable globale.
|
||
|
*/
|
||
|
if (optind != argc)
|
||
|
{
|
||
|
strncpy(filename, argv[optind], MAX_FILENAME_LENGTH);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
fprintf(stderr, "WARNING: dumpgdbm: missing filename\n");
|
||
|
print_options();
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
if (interactive)
|
||
|
{
|
||
|
shell();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
dump_gdbm_file(argv[optind]);
|
||
|
}
|
||
|
|
||
|
if (found_an_empty_key && warn_if_key_empty)
|
||
|
{
|
||
|
fprintf(stderr, "YO! A KEY IS EMPTY\n");
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/* ------------------------------------------------------- the end ----- */
|