very old code commited, ymmv

This commit is contained in:
tTh
2022-11-24 14:37:21 +01:00
parent 4fa31cb790
commit c653852ee2
35 changed files with 4153 additions and 1 deletions

1
DumpGDBM/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
MANIFEST

91
DumpGDBM/Makefile Normal file
View File

@@ -0,0 +1,91 @@
# ----------------------------------------------------
# this is the Makefile for the 'dumpgdbm' utility
# ----------------------------------------------------
#
# Pour plus d'information, le mieux, c'est de m'ecrire
# <oulala@chez.com> ou de me faire parvenir une caisse
# de vin australien. Ou chilien, ils font du bon vin
# au Chili: du Cabernet-Sauvignon de premiere bourre.
#
# ----------------------------------------------------
#
OU_LE_METTRE = /usr/local
#
# Positionner TRACE a 42 pour avoir un binaire
# qui raconte sa vie, son oeuvre, ses trolls...
#
# you can safely remove the -g (debug) options.
#
TRACE = 0
C_OPT = -Wall -DTRACE=$(TRACE)
# ----------------------------------------------------
all: dumpgdbm cleargdbm
dump_funcs.o: dump_funcs.c dumpgdbm.h Makefile
cc $(C_OPT) -c dump_funcs.c
dumpgdbm.o: dumpgdbm.c dumpgdbm.h Makefile
cc $(C_OPT) -c dumpgdbm.c
dumpgdbm: dumpgdbm.o dump_funcs.o Makefile
cc $(C_OPT) dumpgdbm.o dump_funcs.o -lgdbm -lreadline -ltermcap -o dumpgdbm
exemple.gdbm: exemple.pl Makefile
-rm exemple.gdbm
perl ./exemple.pl
cleargdbm: cleargdbm.c Makefile
cc $(C_OPT) cleargdbm.c -lgdbm -o cleargdbm
love:
@echo "--------- No War --------"
@echo "install -> " $(OU_LE_METTRE)/
@echo "trace -> " $(TRACE)
#
# Bon, OK, ma methode d'installation est rudimentaire,
# mais fallait lire la doc avant, si votre systeme est
# tout detruit, c'est pas de ma faute. Ymmv.
#
install:
cp dumpgdbm dumpgdbm.install
strip dumpgdbm.install
cp dumpgdbm.install $(OU_LE_METTRE)/bin/dumpgdbm
rm dumpgdbm.install
cp dumpgdbm.1 $(OU_LE_METTRE)/man/man1/dumpgdbm.1
cp cleargdbm.1 $(OU_LE_METTRE)/man/man1/cleargdbm.1
@echo
@echo "configuration modified, you have to reboot now."
@echo " [YES] [NO] [MAY BE] [DON'T KNOW]"
@echo
@sleep 1
@echo "arf, arf, trop drole, on s'y croirait..."
@echo
#
# Rah, mais qu'est ce qu'est Gruiik, ce truc !
#
tarball: dumpgdbm.c dumpgdbm.1 Makefile README TODO MANIFEST BUGS \
cleargdbm.c cleargdbm.1 INSTALL dump_funcs.c \
dumpgdbm.h exemple.pl
( cd .. ; \
tar zcvf dumpgdbm.tar.gz `sed 's/^/DumpGDBM\//' DumpGDBM/MANIFEST` )
date >> tarball
#
# merci de votre attention.
#
# http://la.buvette.org/ego/
# http://krabulator.free.fr/devel/
#
#
#-- end of Makefile --

2
DumpGDBM/README.md Normal file
View File

@@ -0,0 +1,2 @@
# DumpGDBM

BIN
DumpGDBM/cleargdbm Executable file

Binary file not shown.

59
DumpGDBM/cleargdbm.1 Normal file
View File

@@ -0,0 +1,59 @@
.TH ClearGDBM 1 "Juillet 2002" "GNU/Linux" "tontonTh tools"
.SH NAME
cleargdbm \- Videur de fichiers GDBM
.SH SYNOPSYS
\fBcleargdbm\fP -V
.br
\fBcleargdbm\fP -h|-?
.br
\fBcleargdbm\fP [-v] fichier.gdbm
.SH DESCRIPTION
Les fichiers GDBM permettent de stocker des 'tables associatives'
sur mémoire permanente. La rapidité de lecture de ces tables est
impressionante. Je les utilise parfois comme cache de bases de
données dans des applications Web.
.br
\fBcleargdbm\fP permet de 'vider' une table gdbm, en fait de l'effacer
physiquement du disque, puis de la re-créer sans rien y mettre dedans.
Accessoirement, on peut aussi mesurer la vitesse d'utilisation, de
manière totalement arbitraire (à la BogoMIPS, en fait).
.br
Le programme tente de préserver certaines caractéristiques du fichier
destroyé: les droits d'accès uniquement à l'heure actuelle.
.SH OPTIONS
.B -V
pour connaitre la version du machin-bidule.
.br
.B -v
pour avoir du bavardage (fmbl roulaize) sur ce que fait ce kludge.
.br
.B -h -?
Ah, il y a un peu de l'aide. On va en avoir besoin.
.br
.SH SEE ALSO
.BR gdbm (3)
.BR GDBM_File (3pm)
.BR dumpgdbm (1)
.SH BUGS
Il y en a probablement quelques uns qui trainent...
Au lieu de raler, il faut signaler les problêmes à l'auteur.
Toutes les idées d'amélioration sont les bienvenues.
De bonnes bouteilles aussi.
Bières anglo/saxonnes (Guinness roulaize) ou vins languedociens.
.SH AUTHOR
Thierry Boudet (oulala@chez.com) depuis Juillet 1999.
Pour en savoir plus: http://krabulator.free.fr/devel/ ou La.Buvette.Org.
.SH DEDICACE
Ce logiciel est dédié à Florence D. qui est le soleil de ma vie.

167
DumpGDBM/cleargdbm.c Normal file
View File

@@ -0,0 +1,167 @@
/*
cleargdbm.c
===========
very old homepage = http://krabulator.free.fr/devel/
=====================================================
WARNING! this program is _not_ secure! don't use it
with a setuid root setting.
=====================================================
(g) 2003 Thierry Boudet - aka TontonTh
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <gdbm.h>
#define VERSION "0.0.12"
#define MAX_FILENAME_LENGTH 4242 // 63 bytes for a filename is enough
// for all. -imaginary BG-
char filename[MAX_FILENAME_LENGTH+2];
int verbosity = 0;
int block_size = 512;
/* --------------------------------------------------------------------- */
static void
print_version(int totale)
{
printf ("\n");
printf ("*** ClearGDBM version %s (g) 2003 TontonTh Useless Soft.\n", VERSION);
printf ("\n");
if (totale)
{
printf (" file " __FILE__ " compiled " __DATE__ " at " __TIME__ "\n");
printf (" %s\n", gdbm_version);
printf ("\n");
}
#if TRACE
printf (" WARNING: compiled with TRACE option. May be _bogus_ !\n\n");
#endif
}
/* --------------------------------------------------------------------- */
static void
help(void)
{
}
/* --------------------------------------------------------------------- */
static int
clear_gdbm(char *name, int flag)
{
int foo;
GDBM_FILE file;
struct stat infos;
int mode;
#if TRACE
fprintf(stderr, "TRACE: try to clear gdbm file '%s', flag=%d\n", name, flag);
#endif
/*
* on va vérifier si c'est bien un fichier GDBM qu'on va niquer, là.
*/
file = gdbm_open(name, 512, GDBM_READER, 0444, NULL);
if (file == NULL)
{
fprintf(stderr, "Hu, Ho, '%s' is not a GDBM file, err: %s\n",
name, gdbm_strerror(gdbm_errno));
exit(1);
}
gdbm_close(file);
/*
* nous allons récuperer quelques infos sur le fichier à n*q**r.
*/
foo = stat(name, &infos);
#if TRACE
fprintf(stderr, "TRACE: retour stat = %d\n", foo);
#endif
mode = infos.st_mode & 0777;
fprintf(stderr, "protection = 0%03o\n", mode);
/*
* bon, maintenant, on y va --force
*/
foo = unlink(name);
if (foo)
{
perror ("unlink file");
exit(1);
}
file = gdbm_open(name, 512, GDBM_WRCREAT, mode, NULL);
if (file == NULL)
{
fprintf(stderr, "Ho, désolé, pas pu créer %s (%s)\n",
name, gdbm_strerror(gdbm_errno));
exit(1);
}
gdbm_close(file);
return 0;
}
/* --------------------------------------------------------------------- */
/*
* let's go for the destroy :)
*/
static char *optstring = "Vvhb:?";
int main(int argc, char *argv[])
{
int option_retour;
int foo;
char *nomfichier;
while ( (option_retour = getopt(argc, argv, optstring)) >= 0)
{
#if TRACE
fprintf(stderr, "TRACE: getopt = %d, argc = %d, optind = %d\n",
option_retour, argc, optind);
#endif
switch (option_retour)
{
case 'V':
print_version(1);
break;
case 'v':
verbosity++;
break;
case 'h': case '?':
help();
break;
}
}
#if TRACE
fprintf(stderr, "TRACE: fin traitement options argc=%d, optind=%d\n",
argc, optind);
fprintf(stderr, "TRACE: next arg %s\n", argv[argc-1]);
#endif
nomfichier = argv[argc-1];
/*
* WARNING!
*
* this programme is not secure. carefully read the sources
* before use. you have be warned.
*/
clear_gdbm(nomfichier, 0);
return 0;
}
/* --------------------------------------------------------------------- */

165
DumpGDBM/dump_funcs.c Normal file
View File

@@ -0,0 +1,165 @@
/*
various functions for dumpgdbm
==============================
--------------------------------------------------------------------
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--------------------------------------------------------------------
(g) 2003 Thierry Boudet - aka TontonTh
*/
#include <stdio.h>
#include <gdbm.h>
#include <ctype.h>
#include <regex.h>
#include "dumpgdbm.h"
/* --------------------------------------------------------------------- */
void
print_version(int totale)
{
printf ("\n");
printf ("*** DumpGDBM version %s (g) 2003 TontonTh Useless Soft.\n", VERSION);
printf ("\n");
if (totale)
{
printf (" more info -> http://krabulator.free.fr/devel/\n");
printf (" this software is released under the 'Gnu Public License'\n");
printf (" %s\n", gdbm_version);
printf ("\n");
}
#if TRACE
printf (" WARNING: compiled with TRACE option. May be _bogus_ !\n\n");
#endif
}
/* --------------------------------------------------------------------- */
void
print_options(void)
{
printf ("command-line options:\n");
printf ("\t-V\tprint version and infos.\n");
printf ("\t-x\thexadecimal display.\n");
printf ("\t-o\toctal display.\n");
printf ("\t-a\tascii display.\n");
printf ("\t-v\tbe verbose. more tchatche.\n");
printf ("\t-w\twarn if key empty. [todo]\n");
printf ("\t-W\tsilent search empty key. [todo]\n");
printf ("\t-m 42\tset the qty of bytes displayed.\n");
printf ("\t-8\tdisplay chars with ascii>127\n");
printf ("\t-i\tstart in interactive mode\n");
printf ("\n");
}
/* --------------------------------------------------------------------- */
void init_global_vars(void)
{
verbosity = 0;
maxoctets = 75;
hexadecimal = 0;
octal = 0;
ok_for_8_bits = 0;
}
/* --------------------------------------------------------------------- */
int
hexadump(void *ptr, int count)
{
int i, j;
unsigned char *cptr;
cptr = (unsigned char *)ptr;
if (count > maxoctets) count = maxoctets;
j = 0;
for (i=0; i<count; i++)
{
printf(" %02x", cptr[i]);
if (j++ > 22 && i!=(count-1))
{
printf("\n ");
j = 0;
}
}
printf("\n");
return 0;
}
/* --------------------------------------------------------------------- */
int
octaldump(void *ptr, int count)
{
int i, j;
unsigned char *cptr;
cptr = (unsigned char *)ptr;
if (count > maxoctets) count = maxoctets;
j = 0;
for (i=0; i<count; i++)
{
printf(" %03o", cptr[i]);
if (j++ > 16 && i!=(count-1))
{
printf("\n ");
j = 0;
}
}
printf("\n");
return 0;
}
/* --------------------------------------------------------------------- */
int
asciidump(void *ptr, int count)
{
int i, j;
unsigned char *cptr;
cptr = (unsigned char *)ptr;
if (count > maxoctets) count = maxoctets;
#if TRACE
fprintf(stderr, "ok_for_8_bits %d\n", ok_for_8_bits);
#endif
j = 0;
for (i=0; i<count; i++)
{
if ( ok_for_8_bits )
{
if (isprint(cptr[i]) || cptr[i]>127)
printf("%c", cptr[i]);
else
printf(".");
}
else
{
if (isprint(cptr[i]))
printf("%c", cptr[i]);
else
printf(".");
}
if (j++ > 70 && i!=(count-1))
{
printf("\n ");
j = 0;
}
}
printf("\n");
return 0;
}
/* --------------------------------------------------------------------- */

BIN
DumpGDBM/dumpgdbm Executable file

Binary file not shown.

110
DumpGDBM/dumpgdbm.1 Normal file
View File

@@ -0,0 +1,110 @@
.TH DumpGDBM 1 "Fevrier 2003" "GNU/Linux" "Oulala tools"
.SH NAME
dumpgdbm \- Dumpeur de fichiers GDBM
.SH SYNOPSYS
\fBdumpgdbm\fP -V
.br
\fBdumpgdbm\fP -h
.br
\fBdumpgdbm\fP [-vxoa8] [-m 42] [-i] fichier.gdbm
.SH DESCRIPTION
Les fichiers GDBM permettent de stocker des 'tables associatives'
sur mémoire permanente. La rapidité de lecture de ces tables est
impressionante. Mais leur utilisation est parfois surprenante.
Par exemple, la présence ou non d'un '\\0' en fin de chaine...
.br
\fBdumpgdbm\fP affiche en ascii, en octal, ou en hexadécimal les
couples (clef/valeur) contenus dans un fichier GDBM.
Il devrait contenir bientôt (ymmv) un mécanisme de détection des clefs nulles,
réputées pour créer des problèmes dans des langages à typage faible,
comme Perl ou PHP. Suggestions attendues...
.SH OPTIONS
.B -V
pour connaitre la version du machin-bidule.
.br
.B -x
affichage des octets en hexadecimal.
.br
.B -o
affichage en octal (pdp11 roulaize).
.br
.B -a
affichage en ascii (voir aussi -8)
.br
.B -v
pour avoir du bavardage (fmbl roulaize)
.br
.B -h
ah, il y a un peu de l'aide.
.br
.B -8
C'est OK pour afficher les caractères dont le code ascii > 128.
.br
.B -m 42
détermine le nombre maximum d'octets affichés.
.br
.B -i
démarrage en mode interactif.
Les options -x, -a et -o sont exclusives et c'est la dernière rencontrée
sur la ligne de commande qui a la priorité.
L'option -8 n'a de sens qu'en mode ascii.
.SH INTERACTIF
Pour le mettre en oeuvre, c'est l'option
.B -i
au lancement, et ensuite, au prompt, un
.B ?
pour une liste abrégée des commandes. Puis taper:
.B help command
ou
.B listcom
pour en savoir un peu plus. Désolé, mais mon interpréteur de commandes n'est
pas (encore) parfait. Il utilise readline, mais ne sauvegarde pas (encore)
l'historique des commandes.
Les commandes de recherche,
.B ds
et
.B ks
, utilisent les expressions régulières POSIX.
.SH SEE ALSO
.BR gdbm (3)
.BR GDBM_File (3pm)
.BR cleargdbm (1)
.BR regex(3)
.SH BUGS
Il y en a probablement quelques uns qui trainent...
Par exemple, rien n'est encore prévu pour l'EBCDIC (Flo?).
Mais bon, au lieu de raler, il faut signaler les problêmes à l'auteur.
Toutes les idées d'amélioration sont les bienvenues.
De bonnes bouteilles aussi.
Bières anglo/saxonnes (Guinness roulaize) ou vins languedociens.
.SH SORRY
I have to rewrite this man page in english, but my english is very poor.
.SH LICENSE
Ce logiciel est distribué sous la bienveillante protection de la
GNU GENERAL PUBLIC LICENSE, version 2. J'en profite pour remercier
.B RMS
sans qui rien de tout ça ne serait arrivé.
.SH AUTHOR
Thierry Boudet (oulala@chez.com) depuis Juillet 1999.
Pour en savoir plus: http://krabulator.free.fr/devel/ ou
http://tboudet.free.fr/
.SH DEDICACE
Euh, donc ce logiciel est dédié à Jennifer Mack, dont je suis un fervent
admirateur depuis très longtemps. Merci également à Joshua, qui m'a fait
découvrir que tout cela n'est qu'un jeu.

808
DumpGDBM/dumpgdbm.c Normal file
View File

@@ -0,0 +1,808 @@
/*
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(&reg, 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(&reg, 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(&reg);
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(&reg, 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(&reg, 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(&reg);
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 ----- */

26
DumpGDBM/dumpgdbm.h Normal file
View File

@@ -0,0 +1,26 @@
#ifdef MAIN
#define EXTERN
#else
#define EXTERN extern
#endif
#define VERSION "0.2.27"
/* --------------------------------------------------------------------- */
/* global variables */
EXTERN int verbosity;
EXTERN int maxoctets;
EXTERN int hexadecimal;
EXTERN int octal;
EXTERN int ok_for_8_bits;
/* --------------------------------------------------------------------- */
void print_version(int);
void print_options(void);
void init_global_vars(void);
int hexadump(void *ptr, int count);
int octaldump(void *ptr, int count);
int asciidump(void *ptr, int count);

23
DumpGDBM/exemple.pl Executable file
View File

@@ -0,0 +1,23 @@
#!/usr/bin/perl -w
use strict;
use GDBM_File;
my $nomdb = "exemple.gdbm";
my (%DB, @champs);
my ($user, $gecos);
open(SOURCE, "< /etc/passwd") or die "source $!";
tie(%DB, "GDBM_File", $nomdb, GDBM_WRCREAT, 0666) or die "gdbm $!";
while (<SOURCE>)
{
@champs = split ":", $_;
$user = $champs[0]."\0";
$gecos = $champs[4]."\0";
$DB{$user} = $gecos;
}
untie %DB;
close SOURCE;
0;