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

60
CheckResolv/Makefile Normal file
View File

@ -0,0 +1,60 @@
#-------------------------------------------------------------------
#
# CheckResolv
#
# editable configuration variables:
DESTDIR = /usr/local
COPT = -g -ansi -Wall
#
# you can now compile with "make checkresolv" and install it
# with "su -c 'make install'"
#
#-------------------------------------------------------------------
VERSION=0.25
all:
@echo
@echo " may be you can read (and edit) the Makefile before"
@echo " trying to compile and run that kludge..."
@echo
@echo " for impatients: try \"make checkresolv\""
@echo
checkresolv.o: checkresolv.c Makefile fonctions.h
gcc $(COPT) -c -DVERSION=\"$(VERSION)\" -DTRACE=0 $<
fonctions.o: fonctions.c Makefile fonctions.h
gcc $(COPT) -c -DVERSION=\"$(VERSION)\" -DTRACE=0 $<
checkresolv: checkresolv.o fonctions.o
gcc $(COPT) $^ -o $@
#-------------------------------------------------------------------
#
# install procedure is _also_ quick and dirty
#
install:
install --strip checkresolv $(DESTDIR)/bin
install checkresolv.man $(DESTDIR)/man/man1/checkresolv.1
#-------------------------------------------------------------------
FILES=*.c *.h Makefile CHANGELOG README TODO checkresolv.man *.html
TARNAME=checkresolv-$(VERSION).tar.gz
tarball: $(FILES)
@echo "Tarball is" $(TARNAME)
@ls $^ > MANIFEST ; \
( cd .. ; \
tar zcvf $(TARNAME) `sed 's/^/CheckResolv\//' CheckResolv/MANIFEST` )
@date >> tarball
@wc -c ../$(TARNAME)
lines: $(FILES)
wc $(FILES) | sort -n
#-------------------------------------------------------------------

21
CheckResolv/README.md Normal file
View File

@ -0,0 +1,21 @@
```
CheckResolv
===========
This is a quick and dirty hack, built for chasing
a LPRng latency problem. Usage is very simple:
you give a hostname or an IP addr, and the soft
try a few lookup and/or reverse lookup.
Options are:
-V display version
-r do a reverse lookup
-v increase verbosity
-e print relateds env vars
-t display time op operations
Have a good life, don't release CO2 in the Ternet...
```

12
CheckResolv/TODO Normal file
View File

@ -0,0 +1,12 @@
This is the TODO file for CheckResolv
-------------------------------------
- virer les GNUismes du Makefile
- check for potentials buffers overflows
- write a really cut manpage
- add a function to analyze /etc/resolv.conf
- add a function to check /etc/hosts
- build a fonction for detect DNS used by the resolver.

238
CheckResolv/checkresolv.c Normal file
View File

@ -0,0 +1,238 @@
/*
* CheckResolv
* ===========
*
* quick and dirty debugging hack.
*
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#define __USE_BSD
#include <string.h>
/* #undef __USE_BSD */
#include <sys/time.h>
#include <getopt.h>
#define __USE_MISC
#include <netdb.h> /* herror ? */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "fonctions.h"
char * strdup(char *); /* DIRTY HACK */
/* ------------------------------------------------------------ */
/* quick and dirty global variables */
int verbose = 0;
int do_reverse = 0;
int do_environ = 0;
int do_timing = 0;
/* ------------------------------------------------------------ */
/* parameter '*txt' is not used */
int print_hostent(struct hostent *ph, char *txt)
{
char *ptr, **pptr;
printf("h_name: %s\n", ph->h_name);
pptr = ph->h_aliases;
if (verbose) {
printf("h_aliases: %p -> %p\n", pptr, *pptr);
}
while ( (ptr = *(pptr)) != NULL ) {
printf(" alias: %s\n", ptr);
pptr++;
}
if (verbose) {
printf("h_addrtype: %d\n", ph->h_addrtype);
printf("h_length: %d\n", ph->h_length);
}
print_ip((struct in_addr **)ph->h_addr_list); /* strange cast */
return 0;
}
/* ------------------------------------------------------------ */
/*
* If we have a list of IP addr, we can try a
* reverse lookup, no ?
*/
int check_reverse(struct hostent *ph)
{
struct in_addr **liste;
struct in_addr *addr;
struct in_addr l_addr; /* Jules */
struct hostent *revph;
int nbre;
double t1 , t2;
char *ptmp;
if (do_timing) t1 = chronometre();
nbre = 0;
liste = (struct in_addr **)ph->h_addr_list;
while (NULL != (addr = *liste++)) {
l_addr = *addr; /* Jules */
#if TRACE
fprintf(stderr, "---> %p %p\n", addr, l_addr);
#endif
revph = gethostbyaddr(&l_addr, ph->h_length, ph->h_addrtype);
if (NULL != revph) {
/* taking over hidden string vars */
ptmp = strdup(inet_ntoa(l_addr));
if (NULL == ptmp) {
fprintf(stderr, "no memory in %s, line %d\n",
__FILE__, __LINE__);
abort();
}
#if TRACE
fprintf(stderr, "%s:%d %p %p\n", __func__, __LINE__,
ptmp, revph->h_name);
#endif
printf("reverse %-16s -> %s\n", ptmp, revph->h_name);
free(ptmp);
}
else {
/* fprintf(stderr, "reverse ? wtf ?\n"); */
herror("reverse lookup"); /* this func is obsolete ! */
}
nbre++;
}
if (do_timing) {
t2 = chronometre();
if (nbre > 1)
printf("reverse take %.3f s (%.3f s)\n", t2-t1, (t2-t1)/nbre);
else
printf("reverse take %.3f s.\n", t2-t1);
}
return 0;
}
/* ------------------------------------------------------------ */
struct hostent *direct_lookup(char *hostname)
{
struct hostent *p_host;
double t1 , t2;
int foo;
if (do_timing) t1 = chronometre();
p_host = gethostbyname(hostname);
if (do_timing) t2 = chronometre();
if (p_host==NULL)
{
fprintf(stderr, "error %d on '%s'", h_errno, hostname);
herror(" ");
return NULL;
}
foo = print_hostent(p_host, NULL);
if (do_timing) printf("gethostbyname take %.3f s.\n", t2 - t1);
return p_host;
}
/* ------------------------------------------------------------ */
int analyse(char *nom, int flag)
{
struct hostent *p_host;
p_host = direct_lookup(nom);
/*
* new, 31 jan 2005, v 0.19
* if the requested 'hostname' seems to be an ip address, can we
* force a valid reverse lookup ?
*/
if (is_IP_addr(nom) && !do_reverse)
{
fprintf(stderr, "* if %s is a valid ip addr, try the '-r' switch.\n",
nom);
}
if (do_reverse && (p_host!=NULL))
check_reverse(p_host);
return 0;
}
/* ------------------------------------------------------------ */
/*
* Set some global flags, based on our environment
* variable.
*/
void analyze_environ(void)
{
char *ptr;
ptr = getenv("CHECKRESOLV");
if (ptr == NULL)
return;
if ( ! strcmp("tech", ptr) ) {
do_reverse = 1;
do_timing = 1;
}
if ( ! strcmp("all", ptr) ) {
do_reverse = 1;
do_timing = 1;
verbose = 1;
do_environ = 1;
}
}
/* ------------------------------------------------------------ */
int main (int argc, char *argv[])
{
int foo;
char * liste_opt = "vrhteV";
int option;
if (argc == 1) help_options();
while ((option=getopt(argc, argv, liste_opt)) != -1)
{
switch(option)
{
case 'v': verbose++; break;
case 'r': do_reverse=1; break;
case 'e': do_environ=1; break;
case 't': do_timing=1; break;
case 'h': usage(); break;
case 'V': version(); break;
}
}
#if TRACE
fprintf(stderr, "argc %d optind %d\n", argc, optind);
for (foo=optind; foo<argc; foo++)
{
fprintf(stderr, " %4d %s\n", foo, argv[foo]);
}
#endif
/*
* env vars can override command line options.
*/
analyze_environ();
for (foo=optind; foo<argc; foo++)
{
printf("------------( %s \n", argv[foo]);
analyse(argv[foo], 0);
}
if (do_environ) print_envvars(0);
return 0;
}
/* ------------------------------------------------------------ */

View File

@ -0,0 +1,44 @@
<html>
<head>
<title>CheckResolv</title>
<meta name="keywords" content="resolver, BIND, DNS, resolv.conf">
</head>
<body>
<h1>CheckResolv</h1>
<p>
This is a <i>quick'n'dirty</i> tool for checking the configuration
of your local resolver and/or DNS configuration. See the
included manpage and source code for more explanations.
</p>
<h2>options</h2>
<dl> <dt>-V <dd>display version number and exit.
<dt>-h <dd>brief help on the command-line options.
<dt>-v <dd>display various useless messages.
<dt>-r <dd>do reverse lookup on IP address discovered.
<dt>-e <dd>show content of a few environment var resolver-related.
<dt>-t <dd>compute elapsed time of operation, not really accurate.
</dl>
<hr>
<p>
This software use only basic functions like <i>gethostbyname(3)</i>
or <i>gethostbyaddr(3)</i>. Checkresolv use the more low-level
of the resolver galaxy, so it works like any &quot;lambda&quot;
application. Really nice when you have to catch a mysterious
failure in a <small>LAMBDA</small> software.
</p>
<p>
The environmemt variable <tt>CHECKRESOLV</tt> control the verbosity.
A value of <tt>tech</tt> add the display of reverse lookup and timings.
And setting to <tt>all</tt> give you all the bells'n'whistles needed
by geeks.
</p>
</body>
</html>

View File

@ -0,0 +1,80 @@
.TH CheckResolv 1 "2005 September" "various OS" "Tonton Th"
.SH NAME
checkresolv \- quick & dirty tool for checking sanity of resolver.
.SH SYNOPSIS
\fBcheckresolv\fP -V
.br
\fBcheckresolv\fP [options] host.name
.br
\fBcheckresolv\fP [options] 42.51.69.406
.SH DESCRIPTION
CheckResolv is a (not so) q'n'd tool for checking basic capacities and
potentials bugs of your resolver configuration.
I have started the dev of this thing when I was working hard on a remote
nasty printing problems.
It use only \fBgethostbyname\fP and \fBgethostbyaddr\fP functions,
like any lambda applications.
CheckResolv can also display environment variables who can modify the behaviour
of this damned resolver, or give you some problems.
.SH OPTIONS
.B -V
display version number and exit.
.br
.B -h
brief help on the command-line options.
.br
.B -v
display various useless messages.
.br
.B -r
do reverse lookup on IP address discovered.
.br
.B -e
show content of a few environment vars resolver-related.
.br
.B -t
compute elapsed time of operation, not really accurate.
.SH TIPS
If you have a strange problem between two hosts, "don't panic". Take the time
to compil CheckResolv on the two hosts, and run it with the -r option, first
with the hostname, and after that, with the IP address.
And do this two runs on the two hosts. So, you get four results.
Now, use your brain...
.SH CONFIG FILE
All your config files are belong to us. In the futur, may be you can
put a list of env vars to display in a file.
.SH ENV VARS
If the environment variable CHECKRESOLV is set to "tech", reverse lookup
and timing are activated, very nice when your pop3 server take 42 seconds
before you can get some silly answer.
And "all" give you all the bells & whistles.
This variable override command lines options.
.SH SEE ALSO
.BR resolver (5),
.BR host (1),
.BR dig (1),
.BR nslookup (1)
.SH BUGS
Some are here, some are waiting in the dark. Hidden static storage is a pain.
No IPv6 support. No Slackware package, no Debian package...
.SH COMPILATION
Currently (2005 march), this software was only tested on Slackware 10.0 and
Debian Sarge, but it can
compile 'fine' on others Linux or *BSD flavors. IRIX is also a valuable target,
because my troll-master use it...
.SH AUTHOR(S)
Thierry (aka tth) Boudet, with help from @donis, Miod, Reynerie...

167
CheckResolv/fonctions.c Normal file
View File

@ -0,0 +1,167 @@
/*
* CheckResolv
* ===========
* quick and dirty debugging hack.
*
* a bunch of various undocumented functions.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include "fonctions.h"
/* ------------------------------------------------------------ */
/*
* return !0 if str seems to be a quadnumber ip address.
*/
int is_IP_addr(char *str)
{
int nbrdots, length, foo, flag;
/* int o[4]; */
length = strlen(str);
flag = nbrdots = 0;
for (foo=0; foo<length; foo++)
{
if (str[foo]=='.') nbrdots++;
else if ( ! isdigit(str[foo]) )
return 0;
}
return nbrdots==3;
}
/*
* warning, this func is a kludge.
*/
/* ------------------------------------------------------------ */
double chronometre(void)
{
struct timeval tv;
int foo;
double ftemps;
foo = gettimeofday(&tv, NULL);
if (foo) perror("get time of day");
ftemps = (double)tv.tv_sec + ((double)tv.tv_usec/1e6);
return ftemps;
}
/* ------------------------------------------------------------ */
int print_ip(struct in_addr **liste)
{
struct in_addr *addr;
if (liste==NULL)
{
fprintf(stderr, "print addrip (%s:%d): liste is NULL\n",
__FILE__, __LINE__);
exit(5);
}
while ((addr = *liste++)!=NULL)
{
printf("ip: %s", inet_ntoa(*addr));
/*
* mmmm, must resolve globals vars...
if (verbose)
printf(" %8x", *addr);
*/
printf("\n");
}
return 0;
}
/* ------------------------------------------------------------ */
static void print_onevar(char *name)
{
char *ptr;
if ((ptr=getenv(name)) == NULL)
printf("%-29s is not defined\n", name);
else
printf("%-27s = '%s'\n", name, ptr);
}
struct envvars
{
char *name;
char *comment;
} envvars[] =
{
{ "HOSTNAME", NULL },
{ "HOSTALIASES", NULL },
{ "http_proxy", NULL },
{ "ftp_proxy", NULL },
{ "PRINTER", NULL },
{ "RESOLV_HOST_CONF", NULL },
{ "RESOLV_SERV_ORDER", NULL },
{ "RESOLV_SPOOF_CHECK", NULL },
{ "RESOLV_MULTI", NULL },
{ "RESOLV_REORDER", NULL },
{ "CHECKRESOLV", NULL },
{ "TONTON_TH", NULL },
{ NULL, NULL }
};
/*
* by the way, if you know another interesting env vars in
* the resolver context...
*/
int print_envvars(int flags)
{
struct envvars *pev;
puts("");
pev = envvars;
while (pev->name != NULL)
{
print_onevar(pev->name);
pev++;
}
return 0;
}
/* ------------------------------------------------------------ */
void help_options(void)
{
fputs("checkresolv [-v] [-r] [-e] [-t] hostname|ipaddr\n", stderr);
fputs("checkresolv -h : more help\n", stderr);
fputs("checkresolv -V : print version\n", stderr);
}
/* ------------------------------------------------------------ */
void usage(void)
{
fprintf(stderr, "*** CheckResolv v %s *** by tth ***\n", VERSION);
fputs("Usage:\n", stderr);
fputs("\tcheckresolv [options] hostname | @ip\n", stderr);
fputs("\n", stderr);
fputs("options:\n", stderr);
fputs("\t-V: display version number\n", stderr);
fputs("\t-v: increase verbosity\n", stderr);
fputs("\t-r: try a reverse lookup\n", stderr);
fputs("\t-e: print some env vars\n", stderr);
fputs("\t-t: print elapsed time\n", stderr);
fputs("\n", stderr);
fputs("environmemt variable:\n", stderr);
fputs("\tname: CHECKRESOLV\n", stderr);
fputs("\tvalue: \"tech\" reverse-lookup and timing\n", stderr);
fputs("\tvalue: \"all\" all the bells & whistles\n", stderr);
fputs("\n", stderr);
exit(0);
}
/* ------------------------------------------------------------ */
void version(void)
{
printf("CheckResolv v %s by tth\n", VERSION);
}
/* ------------------------------------------------------------ */

17
CheckResolv/fonctions.h Normal file
View File

@ -0,0 +1,17 @@
/*
* CheckResolv
* ===========
* quick and dirty debugging hack.
*
*/
int is_IP_addr(char *str);
double chronometre(void);
int print_ip(struct in_addr **liste);
void help_options(void);
void usage(void);
void version(void);
int print_envvars(int flag);

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

3
Hexdiff/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
hexdiff

71
Hexdiff/Makefile Normal file
View File

@ -0,0 +1,71 @@
#
# VISUEL HEXDIFF
# --------------
#
# old site : http://tboudet.free.fr/hexdiff/
#
OU_LE_METTRE = /usr/local
VERSION=0.0.50
TARNAME="hexdiff-$(VERSION).tar.gz"
all: hexdiff
#
# if you define TRACE to a non zero value, you get a
# lot of debugging trace on _stderr_
#
COMP=gcc
COPT=-g -DVERSION=\"$(VERSION)\" -DTRACE=0 -ansi
LOPT=-lncurses
hexdiff.o: hexdiff.c Makefile hexdiff.h
$(COMP) $(COPT) -Wall -O2 -c hexdiff.c
fonctions.o: fonctions.c Makefile hexdiff.h
$(COMP) $(COPT) -Wall -O2 -c fonctions.c
parse_rc.o: parse_rc.c Makefile hexdiff.h
$(COMP) $(COPT) -Wall -O2 -c parse_rc.c
fileinfo.o: fileinfo.c Makefile hexdiff.h
$(COMP) $(COPT) -Wall -O2 -c fileinfo.c
sel_file.o: sel_file.c Makefile hexdiff.h
$(COMP) $(COPT) -Wall -O2 -c sel_file.c
asciiview.o: asciiview.c Makefile hexdiff.h
$(COMP) $(COPT) -Wall -O2 -c asciiview.c
OBJECTS=hexdiff.o fonctions.o fileinfo.o parse_rc.o sel_file.o \
asciiview.o
hexdiff: Makefile $(OBJECTS)
$(COMP) $(OBJECTS) -o $@ $(LOPT)
#
# this install procedure is very crude.
#
install:
cp hexdiff hexdiff.install
strip hexdiff.install
cp hexdiff.install $(OU_LE_METTRE)/bin/hexdiff
rm hexdiff.install
cp hexdiff.1 $(OU_LE_METTRE)/man/man1/hexdiff.1
@echo "you can copy hexdiff.rc in your HOME as .hexdiffrc"
FILES=hexdiff.c hexdiff.1 Makefile README TODO BUGS fonctions.c CHANGES \
hexdiff.h parse_rc.c hexdiff.rc fileinfo.c sel_file.c \
asciiview.c memcheck.sh
tarball: $(FILES)
@echo $(TARNAME)
ls $^ > MANIFEST ; \
( cd .. ; \
tar zcvf $(TARNAME) `sed 's/^/HexDiff\//' HexDiff/MANIFEST` )
date >> tarball
lines: $(FILES)
wc $(FILES) | sort -n

19
Hexdiff/README.md Normal file
View File

@ -0,0 +1,19 @@
# Hexdiff
Un truc en ncurses pour voir les différences entre deux fichiers binaires.
```
look at:
- the Makefile
- the man page
- the source code
old website:
http://tboudet.free.fr/hexdiff/
installation:
1) run make
2) patch
3) goto 1
```

14
Hexdiff/TODO Normal file
View File

@ -0,0 +1,14 @@
add a '/' keystroke for searching a byte sequence in
the current file.
drink a beer ? or, better, eat a Guinness ?
write a better english. write a better doc. write a
better manpage. write a better code.
make a Slackware package. Mmmeee.
move the config file from $HOME/.hexdiffrc to
$HOME/.tth/hexdiff.rc

202
Hexdiff/asciiview.c Normal file
View File

@ -0,0 +1,202 @@
/*
+----------------+
| Ascii View |
+----------------+
*/
#include <stdio.h>
#include <unistd.h>
#include "hexdiff.h"
/*----------------------------------------------------------------*/
static void av_sauve_contexte(void)
{ /* code to be defined ? */ }
/*----------------------------------------------------------------*/
static void av_restaure_contexte(void)
{ /* code to be defined ? */ }
/*----------------------------------------------------------------*/
static char * ascii_name(int code)
{
static char static_buffer[20];
/* XXX this big switch must be audited.... */
switch (code)
{
case 0: return "NUL";
case 1: return "SOH ^a";
case 2: return "STX ^b";
case 3: return "ETX ^c";
case 4: return "EOT ^d";
case 5: return "ENQ ^e";
case 6: return "ACQ ^f";
case 7: return "BEL ^g";
case 8: return "BS ^h";
case 9: return "HT ^i";
case 10: return "LF ^j";
case 11: return "VT ^k";
case 12: return "FF ^l";
case 13: return "CR ^m";
case 14: return "SO ^n";
case 15: return "SI ^o";
case 16: return "DLE ^p";
case 17: return "DC1 ^q";
case 18: return "DC2 ^r";
case 19: return "DC3 ^s";
case 20: return "DC4 ^t";
case 21: return "NAK ^u";
case 22: return "SYN ^v";
case 23: return "ETB ^w";
case 24: return "CAN ^x";
case 25: return "EM ^y";
case 26: return "SUB ^z";
case 27: return "ESC";
case 28: return "FS ";
case 29: return "GS ";
case 30: return "RS ";
case 31: return "US ";
case 32: return "SPACE";
case 127: return "DEL";
}
if (code < 128)
{
sprintf(static_buffer, "'%c'", code);
return static_buffer;
}
/* may be for code > 127, we can put the "html" code &blabla; ? */
return "";
}
/*----------------------------------------------------------------*/
#define ASCV_I2LIG(idx) ((idx)>>6)
#define ASCV_I2COL(idx) ((idx)&63)
static int av_affiche(Fichier *fic, WINDOW *pop, int clig, int ccol)
{
int foo, lig, col, car;
char chaine[100];
long depl;
unsigned char octet;
wstandout(pop);
for (foo=1; foo<65; foo++)
mvwaddch(pop, 1, foo, ' ');
mvwaddstr(pop, 1, 2, fic->nom);
depl = (clig*64)+ccol;
octet = fic->buffer[depl];
sprintf(chaine, "%7ld : %3d 0x%02x 0%03o",
fic->offset+depl, octet, octet, octet);
mvwaddstr(pop, 18, 1, chaine);
mvwaddstr(pop, 18, 33, " ");
mvwaddstr(pop, 18, 33, ascii_name(fic->buffer[depl]));
wstandend(pop);
for (foo=0; foo<16*64; foo++)
{
lig = ASCV_I2LIG(foo);
col = ASCV_I2COL(foo);
car = fic->buffer[foo];
car = is_printable(car) ? car : ' ';
if (clig==lig && ccol==col)
wstandout(pop);
mvwaddch(pop, lig+2, col+1, car);
if (clig==lig && ccol==col)
wstandend(pop);
}
/* put the cursor at the current location */
/* this was a really bad idea for Xterm users, because
* current pos char was written in "standout", and the
* text cursor of xterm re-reverse it.
* XXX wmove(pop, clig+2, ccol+1);
*/
wmove(pop,1,64);
wrefresh(pop);
return 0;
}
/*----------------------------------------------------------------*/
/* new: 2004 Nov.
* still in developement.
*/
int asciiview(void)
{
WINDOW * popup;
int foo, key, flag_exit;
int clig, ccol; /* position du curseur */
Fichier * fic;
av_sauve_contexte();
popup = newwin(21, 66, 3, 5);
bordure(popup);
wstandout(popup);
for (foo=1; foo<65; foo++)
mvwaddch(popup, 19, foo, ' ');
mvwaddstr(popup, 19, 1, " 'Q' quit, <tab> see other file");
for (foo=1; foo<65; foo++)
mvwaddch(popup, 18, foo, ' ');
wstandend(popup);
wrefresh(popup);
flag_exit = 0;
clig = ccol = 0;
do
{
if (fenetre_active==0) fic = &f1;
else fic = &f2;
av_affiche(fic, popup, clig, ccol);
key = getch();
switch (key)
{
case 'q': case 'Q':
flag_exit = 1;
break;
case '\t':
fenetre_active ^= 1;
break;
case KEY_UP:
if (clig>0) clig--; break;
case KEY_DOWN:
if (clig<15) clig++; break;
case KEY_LEFT:
if (ccol>0) ccol--;
else if (clig>0)
{
/* go to the previous line */
ccol=63; clig--;
}
break;
case KEY_RIGHT:
if (ccol<63) ccol++;
else if (clig<15)
{
/* go to the next line */
ccol=0; clig++;
}
break;
case KEY_HOME:
ccol = clig = 0; break;
case KEY_END:
ccol = 63; clig = 15; break;
default:
flash();
break;
}
} while ( ! flag_exit );
delwin(popup);
av_restaure_contexte();
return 42;
}
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/

138
Hexdiff/fileinfo.c Normal file
View File

@ -0,0 +1,138 @@
/*
fileinfo.c
----------
More infos --> http://tboudet.free.fr/hexdiff/
*/
#include <stdio.h>
#include <time.h>
#include <pwd.h>
#include <grp.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include "hexdiff.h"
/*----------------------------------------------------------------*/
/* private vars of this module */
/*----------------------------------------------------------------*/
/*
* this func need more "configurability"
*/
static void prtime(time_t t, char *pstr)
{
struct tm *ptm;
int foo;
ptm = gmtime(&t);
foo = strftime(pstr, 99, "%Y-%m-%d %H:%M:%S", ptm);
}
/*----------------------------------------------------------------*/
#define W_FILEINFO 48
WINDOW * do_fileinfo(int fd, int ligne)
{
WINDOW * popup;
int foo, lig, hpopup;
struct stat stat_buf;
char buffer[100];
struct passwd *pass;
struct group *grp;
if (config.ext_fileinfo) hpopup = 13;
else hpopup = 12;
popup = newwin(hpopup, W_FILEINFO, ligne, 15);
if ( popup==NULL ) return NULL;
bordure(popup);
#if TRACE
sprintf(buffer, " fileinfos fd %d ", fd);
mvwaddstr(popup, 0, 10, buffer);
#endif
foo = fstat(fd, &stat_buf);
if (foo==0)
{
lig = 2;
sprintf(buffer, "dev: %ld", (long)(stat_buf.st_dev));
mvwaddstr(popup, lig, 2, buffer);
sprintf(buffer, "inode: %ld", stat_buf.st_ino);
mvwaddstr(popup, lig, 22, buffer);
lig += 2;
sprintf(buffer, "uid: %d", stat_buf.st_uid);
mvwaddstr(popup, lig, 2, buffer);
sprintf(buffer, "gid: %d", stat_buf.st_gid);
mvwaddstr(popup, lig, 22, buffer);
if (config.ext_fileinfo)
{
lig++;
pass = getpwuid(stat_buf.st_uid);
if (pass==NULL) strcpy(buffer, "unknow user");
else sprintf(buffer, "user: %s", pass->pw_name);
mvwaddstr(popup, lig, 2, buffer);
grp = getgrgid(stat_buf.st_gid);
if (grp==NULL) strcpy(buffer, "unknow group");
else sprintf(buffer, "group: %s", grp->gr_name);
mvwaddstr(popup, lig, 22, buffer);
}
lig+=2;
/* Nov 2004: may be, here, we need a 'ls-like' display ,
with "-rwxr-x---" look'n'feel ? */
sprintf(buffer, "rwx: %05o", stat_buf.st_mode & 01777);
mvwaddstr(popup, lig, 2, buffer);
sprintf(buffer, "size: %ld", stat_buf.st_size);
mvwaddstr(popup, lig, 22, buffer);
lig+=2;
/* we don't display the atime, because, after all,
hexdiff _is_ reading the file :) */
prtime(stat_buf.st_mtime, buffer);
mvwaddstr(popup, lig, 4, "mtime:");
mvwaddstr(popup, lig, 14, buffer);
lig++;
prtime(stat_buf.st_ctime, buffer);
mvwaddstr(popup, lig, 4, "ctime:");
mvwaddstr(popup, lig, 14, buffer);
}
else
{
sprintf(buffer, "fstat error = %d", foo);
mvwaddstr(popup, 6, 2, buffer);
}
wrefresh(popup);
return popup;
}
/*----------------------------------------------------------------*/
int fileinfo(int fd, int ligne)
{
WINDOW * pop;
pop = do_fileinfo(fd, ligne);
getch();
delwin(pop);
return 0;
}
/*----------------------------------------------------------------*/
int double_fileinfo(int fd1, int ligne1, int fd2, int ligne2)
{
WINDOW * pop1, * pop2;
pop1 = do_fileinfo(fd1, ligne1);
pop2 = do_fileinfo(fd2, ligne2);
getch();
delwin(pop1);
delwin(pop2);
return 0;
}
/*----------------------------------------------------------------*/

331
Hexdiff/fonctions.c Normal file
View File

@ -0,0 +1,331 @@
/*
fonctions.c
-----------
Old site --> http://tboudet.free.fr/hexdiff/
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include "hexdiff.h"
/*----------------------------------------------------------------*/
int is_printable(int octet)
{
if (config.show_8bits)
return isprint(octet & 0x7f);
return isprint(octet);
}
/*----------------------------------------------------------------*/
int ouvre_fichier(char *nom)
{
int fd, foo;
struct stat statbuf;
Fichier *fichier;
long offset;
if ( (fd=open(nom, O_RDONLY)) < 0)
{
return 0;
}
if (fenetre_active==0)
{
fichier = &f1; offset = f2.offset;
}
else
{
fichier = &f2; offset = f1.offset;
}
/*
* close the old file
*/
close(fichier->fd);
/*
* store information on newly open file
*/
strncpy(fichier->nom, nom, T_NOM);
foo = fstat(fd, &statbuf);
fichier->fd = fd;
fichier->taille = statbuf.st_size;
fichier->offset = offset;
fichier->lus = 0;
return 1;
}
/*----------------------------------------------------------------*/
void barre_inverse(char c, int ligne)
{
int foo;
standout();
for (foo=0; foo<80; foo++)
mvaddch(ligne, foo, c);
standend();
/* refresh(); */
}
/*----------------------------------------------------------------*/
/* new 28 juillet 2007 */
static int calcul_pourcent(Fichier *f)
{
float foo;
if (f->taille < 16) return 0;
foo = ((float)f->offset * 100.0) / (float)f->taille;
return (int)foo;
}
/*----------------------------------------------------------------*/
int
ecrire_barres_fichiers(void)
{
char buffer[150];
int pourcent;
barre_inverse(' ', BARRE_1);
barre_inverse(' ', BARRE_2);
standout();
mvaddstr(BARRE_1, 0, fenetre_active ? " " : "**");
mvaddstr(BARRE_1, 3, f1.nom);
pourcent = calcul_pourcent(&f1);
sprintf(buffer, "%8ld %8ld %3d%%", f1.taille, f1.offset, pourcent);
/*sprintf(buffer, "%8ld %8ld %8ld", f1.taille, f1.offset, f1.lus);*/
mvaddstr(BARRE_1, 52, buffer);
mvaddstr(BARRE_2, 0, fenetre_active ? "**" : " ");
mvaddstr(BARRE_2, 3, f2.nom);
pourcent = calcul_pourcent(&f2);
sprintf(buffer, "%8ld %8ld %3d%%", f2.taille, f2.offset, pourcent);
mvaddstr(BARRE_2, 52, buffer);
if (config.show_8bits) mvaddstr(0, 72, " 8bits ");
else mvaddstr(0, 72, " 7bits ");
if (config.offsets_in_hex) mvaddstr(0, 66, " hex ");
else mvaddstr(0, 66, " dec ");
standend();
return 0;
}
/*----------------------------------------------------------------*/
int
fond_ecran(void)
{
#if TRACE
int foo;
char buffer[200];
#endif
barre_inverse(' ', 0);
standout();
mvaddstr(0, 2, " Visuel HexDiff v " VERSION " by tTh 2007 ");
#if TRACE
sprintf(buffer, " screen size %dx%d ", COLS, LINES);
foo = strlen(buffer);
mvaddstr(0, COLS-2-foo, buffer);
#endif
standend();
refresh();
#if TRACE
fprintf(stderr, "HAUT %3d\n", HAUT);
fprintf(stderr, "HAUT_1 %3d BARRE_1 %3d\n", HAUT_1, BARRE_1);
fprintf(stderr, "HAUT_2 %3d BARRE_2 %3d\n", HAUT_2, BARRE_2);
#endif
return 0;
}
/*----------------------------------------------------------------*/
void bordure(WINDOW * w)
{
if (config.nice_border)
box(w, 0, 0);
else
wborder(w, '|', '|', '-', '-', '+', '+', '+', '+');
}
/*----------------------------------------------------------------*/
typedef struct
{
int ligne;
char * texte;
} ligne_aide;
ligne_aide lignes[] =
{
{ 2, "x q : quit now, 'tfatf'" },
{ 4, "u j (U) : go up one (4) lines" },
{ 5, "d k (D) : go down one (4) lines" },
{ 6, "<spc> : go down one full page" },
{ 7, "0 : back to begin of files" },
{ 8, "$ : goto end of shortest file" },
{ 9, "<tab> : toggle the active window" },
{ 10, "g : input a new file offset" },
/* { 11, "= : synchronize the two offsets" }, */
{ 12, "H : 'toogle' hex/dec offset display" },
{ 13, "7 8 : display control of bit 7" },
{ 14, "i (I) : info about file(s)" },
{ 15, "n : jump to the next difference" },
{ 16, "^O : open new file in current win" },
{ 17, "A : Ascii View (new feature :)" }
};
#define NB_LIG (sizeof(lignes)/sizeof(ligne_aide))
#define L_POPUP 2
#define C_POPUP 11
void popup_aide(void)
{
WINDOW * popup;
int foo, bar, ligmax, largmax;
ligmax = largmax = 0;
for (foo=0; foo<NB_LIG; foo++)
{
if ((bar=lignes[foo].ligne) > ligmax) ligmax = bar;
if ((bar=strlen(lignes[foo].texte)) > largmax) largmax = bar;
}
ligmax += 3;
largmax += 7;
popup = newwin(ligmax, largmax, L_POPUP, C_POPUP);
bordure(popup);
for (foo=0; foo<NB_LIG; foo++)
{
mvwaddstr(popup, lignes[foo].ligne, 3, lignes[foo].texte);
}
wrefresh(popup);
getch();
delwin(popup);
}
/*----------------------------------------------------------------*/
static char *about_texte[] =
{
"Visuel Hexdiff - version " VERSION,
"(c) 2007 by Thierry [tth] Boudet",
"http://tboudet.free.fr/hexdiff/",
"send bugs reports: tontonth@free.fr",
"binary build: " __DATE__ "/" __TIME__,
};
void about(void)
{
WINDOW * popup;
int nblignes = sizeof(about_texte) / sizeof(char *);
int foo;
#if TRACE
fprintf(stderr, "boite about: %d lignes\n", nblignes);
#endif
popup = newwin((nblignes*2)+3, 43, L_POPUP, C_POPUP);
bordure(popup);
for (foo=0; foo<nblignes; foo++)
{
#if TRACE
fprintf(stderr, "%d '%s'\n", foo, about_texte[foo]);
#endif
mvwaddstr(popup, (foo*2)+2, 4, about_texte[foo]);
}
wrefresh(popup);
getch();
delwin(popup);
/* pourquoi, quand je fait le 'delwin', ncurses
ne rafraichit pas la zone qui etait masquee ?
*/
}
/*----------------------------------------------------------------*/
void aide_cl(int flag)
{
int foo;
if (!flag)
{
fputs("\tusage:\n", stderr);
fputs("\t\thexdiff -h\n", stderr);
fputs("\t\thexdiff -V\n", stderr);
fputs("\t\thexdiff -X\n", stderr);
fputs("\t\thexdiff file.A file.B\n", stderr);
exit(1);
}
fputs("\n", stderr);
fputs("\t+------------------------------------------------+\n", stderr);
fputs("\t| commandes clavier |\n", stderr);
fputs("\t+------------------------------------------------+\n", stderr);
for (foo=0; foo<NB_LIG; foo++)
{
fprintf(stderr, "\t| %-46s |\n", lignes[foo].texte);
}
fputs("\t+------------------------------------------------+\n", stderr);
fputs("\t| Pour le reste: 'man hexdiff', hein... |\n", stderr);
fputs("\t+------------------------------------------------+\n", stderr);
fputs("\n", stderr);
exit(1);
}
/*----------------------------------------------------------------*/
/*
* cette fonction de saisie est codee a la "GRUIK" (aka "rache method")
*/
#define W_FEN_SL 40
#define H_FEN_SL 5
long saisir_un_long(char *txt)
{
WINDOW * saisie;
int l, c, foo;
long valeur;
saisie = newwin(H_FEN_SL, W_FEN_SL, 5, 20);
wstandout(saisie);
/*
* la, je me demande pourquoi je suis oblige de 'poker' des espaces
* au lieu d'appeler une fonction de base. par exemple, wclear() ne
* semble pas prendre en compte le wstandout() ?
*/
for (l=0; l<H_FEN_SL; l++)
for (c=0; c<W_FEN_SL; c++)
mvwaddch(saisie, l, c, ' ');
bordure(saisie);
mvwaddstr(saisie, 2, 3, txt);
wstandend(saisie);
mvwaddstr(saisie, 2, 25, " ");
wrefresh(saisie);
echo();
foo = mvwscanw(saisie, 2, 25, "%ld", &valeur);
noecho();
/* wrefresh(saisie); */
delwin(saisie);
if (foo == 1)
return valeur;
return -1;
}
/*----------------------------------------------------------------*/
void version(void)
{
fprintf(stderr, "\nThis is 'hexdiff' v "VERSION", made by tontonTh in 2007\n");
fprintf(stderr, "homepage: http://tboudet.free.fr/hexdiff/\n");
#if TRACE
fprintf(stderr, "Warning ! compiled with active TRACE !\n");
#endif
fputs("\n", stderr);
exit(1);
}
/*----------------------------------------------------------------*/

129
Hexdiff/hexdiff.1 Normal file
View File

@ -0,0 +1,129 @@
.TH HexDiff 1 "November 1905" "Divers Un*ces" "TontonTh tools"
.SH NAME
hexdiff \- un 'visuel diff' pour les fichiers binaires
.SH SYNOPSIS
\fBhexdiff\fP -V
.br
\fBhexdiff\fP -h|-?
.br
\fBhexdiff\fP file1 file2
.SH DESCRIPTION
\fBhexdiff\fP a été crée pour faciliter le débuggage de routines d'écriture
de fichiers images (PCX et BMP, comme par hasard). En comparant un fichier
kimarche et un fichier que je fabrique, ça va aider :)
.br
\fBhexdiff\fP affiche, après le lancement, deux fenètres montrant un dump
hexadécimal et ascii du début des deux fichiers. Deux barres d'état
donnent le nom du fichier, sa taille et l'offset courant.
La fenêtre courante est marquée par '**' à gauche de l'écran.
A l'aide de diverses touches du clavier, vous pouvez vous déplacer
simultanément dans les deux fichiers, et le dump vous montrera alors,
en vidéo inverse, les octets qui sont différents entre les deux fichiers.
Après, hein, c'est à vous d'interpréter...
.SH OPTIONS
.B -V
Pour connaitre la version du machin-bidule.
.br
.B -h | -?
Ah, il y a un peu de l'aide. Bon à savoir.
.br
.B -X
Help for debugging your ~/.hexdiffrc, or the rc file parser.
.SH KEYBOARD COMMANDS
.B x q
Quitte le programme. Parfois...
.br
.B u j U
Remonte d'une ligne (de 16 octets), ou de quatre, dans les deux fichiers.
.br
.B d k D
Descend d'une ou quatre lignes dans les deux fichiers.
.br
.B <space>
Descend de plusieurs lignes dans les deux fichiers. Ce nombre étant calculé
selon la taille de l'écran, je ne peux le révéler ici.
.br
.B 0 <home>
Reprend au début des deux fichiers.
.br
.B $
Vous emmène aux environs de juste avant la fin du plus petit des deux fichiers.
.br
.B g
Propose de saisir un nouvel offset pour les deux fichiers. Attention, cette
fonctions a été écrite à la 'Gruik' et n'est donc pas fiable.
.br
.B H
Bascule l'affichage des offsets entre le décimal et l'hexadécimal. Le mode
initial est configurable.
.br
.B i
Affichage des informations 'fstat' sur le fichier sélectionné.
.br
.B I
Affiche les mêmes informations, mais pour les deux fichiers simultanément.
.br
.B A
Open the (currently) experimental AsciiViewer.
Maybe coredump with no request. <tab> switch as usual.
.br
.B ^O
Ouverture d'un nouveau fichier dans la fenêtre courante. Le "selecteur de
fichier" est encore rudimentaire. Utiliser 'Q' pour annuler, <Enter> pour
valider, et '?' pour l'aide.
.br
.B n
Part à la recherche de la prochaine différence entre les deux fichiers.
.br
.B <tab>
Change la fenètre active. Pour le moment, ça ne sert presque à rien.
Ah, non, il parait que ça joue sur le contexte d'autres fonctions.
Personne ne m'en a parlé, je ne suis au courant de rien, alors
je --->[]
.br
.B ?
"Popupe" une fenètre d'aide reprenant les principales commandes. Pour
les autres commandes: un seul slogan, Utsl.
.SH CONFIG FILE
Le fichier de configuration est
.B .hexdiffrc
et doit se trouver dans le
.B $HOME
de l'utilisateur.
Une ligne commençant par un
.B '#'
est un commentaire. Les lignes vides sont ignorées. Pour plus de détails,
consulter le fichier 'hexdiff.rc' qui devrait se trouver dans l'archive.
.SH SEE ALSO
.BR diff (1),
.BR cmp (1)
.SH BUGS
Si vous redimensionnez votre xterm, \fBhexdiff\fP se prend un SIGWINCH,
et s'en va probablement visiter le pays des Slashies. Dans la pratique,
il en revient très vite.
.br
L'affichage en fin de fichier, si les tailles sont différentes, est
parfois un peu déglingué. Mais je vais réparer ça.
.br
Cette page de man n'est pas synchrone avec la réalité virtuelle du code.
Car le code évolue plus vite que la réalité. Parfois.
.SH AUTHOR
Thierry Boudet aka
.B tTh
qui 'spleytise' avec vigueur ce petit programme depuis Mars 2002.
Pour en savoir un peu plus sur ce logiciel:
http://tboudet.free.fr/hexdiff/ et sur moi: http://tontonth.free.fr/plop/
.SH DEDICACE
Ce logiciel est dédié aux kamarades trolleurs de l'équipe HardStory du
CULTe, sans qui rien n'est pas faisable. <http://www.culte.org/>

394
Hexdiff/hexdiff.c Normal file
View File

@ -0,0 +1,394 @@
/*
Visuel Hexdiff
--------------
More infos --> http://tboudet.free.fr/hexdiff/
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#define MAIN
#include "hexdiff.h"
/*----------------------------------------------------------------*/
static void finish(int signal)
{
endwin(); exit(0);
}
/*----------------------------------------------------------------*/
int
affiche_les_dumps(void)
{
int foo, bar, idx, flag;
char buff[50];
char *format_offset;
memset(f1.buffer, 0, T_BUFF);
memset(f2.buffer, 0, T_BUFF);
/*
* lire les deux fichiers...
*/
lseek(f1.fd, f1.offset, SEEK_SET);
f1.lus = read(f1.fd, f1.buffer, T_BUFF);
lseek(f2.fd, f2.offset, SEEK_SET);
f2.lus = read(f2.fd, f2.buffer, T_BUFF);
ecrire_barres_fichiers();
/*
* afficher les offsets
*/
format_offset = config.offsets_in_hex ? "%08lx" : "%8ld";
for (foo=0; foo<HAUT; foo++)
{
move(HAUT_1+foo, 0); clrtoeol();
move(HAUT_2+foo, 0); clrtoeol();
sprintf(buff, format_offset, foo*16+f1.offset);
mvaddstr(HAUT_1+foo, 0, buff);
sprintf(buff, format_offset, foo*16+f2.offset);
mvaddstr(HAUT_2+foo, 0, buff);
}
/*
* afficher les octets
*/
for (foo=0; foo<HAUT; foo++)
{
for (bar=0; bar<16; bar++)
{
idx = foo*16 + bar;
/*
* il faut prendre en compte le cas ou la taille
* des fichiers n'est pas la meme, pour ne pas mettre
* en evidence les octets qui debordent.
*/
flag = f1.buffer[idx]!=f2.buffer[idx];
/*
* fenetre du haut
*/
if (flag && !fenetre_active) standout();
if (idx < f1.lus)
{
sprintf(buff, "%02x", f1.buffer[idx]);
mvaddstr(HAUT_1+foo, bar*3+11, buff);
if (is_printable(f1.buffer[idx]))
mvaddch(HAUT_1+foo, bar+62, f1.buffer[idx]);
else
mvaddch(HAUT_1+foo, bar+62, ' ');
}
if (flag && !fenetre_active) standend();
/*
* fenetre du bas
*/
if (flag && fenetre_active) standout();
if (idx < f2.lus)
{
sprintf(buff, "%02x", f2.buffer[idx]);
mvaddstr(HAUT_2+foo, bar*3+11, buff);
if (is_printable(f2.buffer[idx]))
mvaddch(HAUT_2+foo, bar+62, f2.buffer[idx]);
else
mvaddch(HAUT_2+foo, bar+62, ' ');
}
if (flag && fenetre_active) standend();
}
}
refresh();
return 0;
}
/*----------------------------------------------------------------*/
/*
* la boucle principale. tant qu'on a pas presse une touche
* kifaiquitter, on reste dedans.
*/
int
interactive(void)
{
int clef; /* la touche en question */
int flag_exit = 0; /* devient 1 si on doit quitter la boucle */
int pas_a_la_fin;
int foo;
long lfoo;
char chaine[T_NOM+1];
#if TRACE
char buff[100];
#endif
do
{
affiche_les_dumps();
pas_a_la_fin = (f1.offset<f1.taille) && (f2.offset<f2.taille);
clef = getch();
#if TRACE
sprintf(buff, "%c %04x %d ", clef, clef, pas_a_la_fin);
mvaddstr(0, 0, buff); refresh();
#endif
switch (clef)
{
case 'x': case 'q':
flag_exit = 1;
break;
case 'u': case 'j':
case KEY_UP:
if (f1.offset>15) f1.offset -= 16;
if (f2.offset>15) f2.offset -= 16;
break;
case 'U':
f1.offset -= 64;
if (f1.offset<0) f1.offset=0;
f2.offset -= 64;
if (f2.offset<0) f2.offset=0;
break;
case 'd': case 'k':
case KEY_DOWN:
if (pas_a_la_fin)
{
f1.offset += 16;
f2.offset += 16;
}
break;
case 'D':
if (pas_a_la_fin)
{
f1.offset += 64;
f2.offset += 64;
}
break;
case 'H':
config.offsets_in_hex ^= 1;
break;
case ' ':
case KEY_NPAGE:
if (pas_a_la_fin)
{
f1.offset += (HAUT-1)*16;
f2.offset += (HAUT-1)*16;
}
break;
case KEY_PPAGE:
lfoo = f1.offset - (HAUT-1)*16;
if (lfoo<0) lfoo = 0;
f1.offset = f2.offset = lfoo;
break;
case '0':
case KEY_HOME:
f1.offset = f2.offset = 0;
break;
case '7':
config.show_8bits = 0;
break;
case '8':
config.show_8bits = 1;
break;
case '$':
/* jump to the end of the smallest file */
lfoo = (f1.taille<f2.taille) ? f1.taille : f2.taille;
f1.offset = f2.offset = (lfoo-16) & 0xffffff0;
break;
case '=':
lfoo = (f1.offset<f2.offset) ? f1.offset : f2.offset;
f1.offset = f2.offset = lfoo & 0xffffff0;
break;
case 'g':
lfoo = saisir_un_long("nouvel offset");
if (lfoo != -1)
f1.offset = f2.offset = lfoo & 0xffffff0;
break;
case 'i':
if (fenetre_active == 0)
fileinfo(f1.fd, HAUT_1);
else
fileinfo(f2.fd, HAUT_2);
break;
case 'I':
double_fileinfo(f1.fd, HAUT_1, f2.fd, HAUT_2);
break;
case 'A':
/**** asciiview ****/
asciiview();
break;
/*
* a patch from Mark Glines:
* key 'n' search for the next difference
*/
case 'n': /* next */
for(lfoo = f1.offset + 16;
lfoo < f1.taille && (lfoo+f2.offset-f1.offset) < f2.taille;
lfoo += 16) {
char buf1[16], buf2[16];
int diff = f2.offset - f1.offset;
lseek(f1.fd, lfoo, SEEK_SET);
lseek(f2.fd, lfoo+diff, SEEK_SET);
if(read(f1.fd,buf1,16) == 16)
if(read(f2.fd,buf2,16) == 16)
if(memcmp(buf1,buf2,16)) {
f1.offset = lfoo;
f2.offset = lfoo + diff;
break;
}
}
break;
case '?':
popup_aide();
break;
case 'a':
about();
break;
case 0x0f: /* CTRL O */
foo = select_new_file(chaine, T_NOM, 0);
if (foo)
ouvre_fichier(chaine);
break;
case '\t': /* TAB */
fenetre_active ^= 1;
break;
case '\f': /* CTRL L */
wrefresh(curscr);
break;
case 'V': /* plugin viewers ? */
break;
default: /* this key was not used */
flash();
break;
}
} while ( ! flag_exit );
return 0;
}
/*----------------------------------------------------------------*/
/*
* HERE WE GO, FAST AND FURIOUS !
*/
int main(int argc, char *argv[])
{
int foo;
struct stat statbuf;
#if TRACE
fprintf(stderr, "\n------ trace de %s ------\n", argv[0]);
fflush(stderr);
#endif
if (argc == 1) aide_cl(0);
if (argc == 2)
{
if (!strcmp(argv[1], "-?") || !strcmp(argv[1], "-h"))
aide_cl(1);
if (!strcmp(argv[1], "-V")) version();
if (!strcmp(argv[1], "-X"))
{
foo = lire_configuration(1);
exit(0);
}
}
if (argc != 3) aide_cl(0);
/*
* initialisation des variables globales
*/
fenetre_active = 0;
/*
* on va essayer d'ouvrir les fichiers.
*/
if ( (f1.fd=open(argv[1], O_RDONLY)) < 0)
{
perror(argv[1]); exit(2);
}
else
{
strncpy(f1.nom, argv[1], T_NOM);
foo = fstat(f1.fd, &statbuf);
f1.taille = statbuf.st_size;
f1.offset = 0;
f1.lus = 0;
}
if ( (f2.fd=open(argv[2], O_RDONLY)) < 0)
{
perror(argv[2]); exit(2);
}
else
{
strncpy(f2.nom, argv[2], T_NOM);
foo = fstat(f2.fd, &statbuf);
f2.taille = statbuf.st_size;
f2.offset = 0;
f2.lus = 0;
}
/*
* si on arrive ici, c'est que les deux fichiers sont ouverts,
* donc on peut tenter de lire le fichier de configuration...
*/
foo = lire_configuration(0);
/*
* ... et ensuite, on peut passer en mode 'Vizzual'.
*/
initscr();
nonl(); cbreak(); noecho();
keypad(stdscr, TRUE); /* acces aux touches 'curseur' */
foo = fond_ecran();
interactive(); /* GOTO LOOP */
/*
* plop, on a fini, restaurer la console
*/
finish(0);
return 0;
}
/*----------------------------------------------------------------*/

99
Hexdiff/hexdiff.h Normal file
View File

@ -0,0 +1,99 @@
/*
* global .h file for hexdiff
* --------------------------
*/
#include <ncurses.h>
/* "#define VERSION" is now in the Makefile */
#define T_BUFF 4242
#define T_NOM 360
typedef struct
{
int fd;
long taille;
long offset;
long lus;
char nom[T_NOM+1]; /* buffer overflow ? */
unsigned char buffer[T_BUFF];
} Fichier;
typedef struct
{
int nice_border;
int show_8bits;
char *language;
int offsets_in_hex;
int ext_fileinfo;
int show_hidden;
int sf_flag;
int explique; /* not used */
int zoom;
int asciiview; /* not used */
} configuration;
/*
* declaration of globals vars
*/
#ifdef MAIN
#define EXTERN
#else
#define EXTERN extern
#endif
EXTERN Fichier f1, f2;
EXTERN int fenetre_active;
EXTERN configuration config;
/*
* macros de positionnement en hauteur
*/
#define HAUT ((LINES-3)/2)
#define HAUT_1 1
#define BARRE_1 (HAUT_1+HAUT)
#define HAUT_2 (HAUT_1+(HAUT)+1)
#define BARRE_2 (HAUT_2+HAUT)
/*
* prototype des fonctions
*/
void barre_inverse(char c, int ligne);
int ecrire_barres_fichiers(void);
int fond_ecran(void);
void about(void);
void aide_cl(int flag);
void bordure(WINDOW * w);
void popup_aide(void);
long saisir_un_long(char *txt);
void version(void);
int is_printable(int octet);
int ouvre_fichier(char *nom);
/*
* file parse_rc.c
*/
#define HEXDIFF_RC ".hexdiffrc"
int init_configuration(void);
int lire_configuration(int flag);
/*
* file fileinfo.c
*/
int fileinfo(int fd, int ligne);
int double_fileinfo(int, int, int, int);
/*
* file sel_file.c
*/
int select_new_file(char *, int, int);
int select_set_opt(int flg);
/*
* file asciiview.c
*/
int asciiview(void);
int octalview(void); /* not urgent */

31
Hexdiff/hexdiff.rc Normal file
View File

@ -0,0 +1,31 @@
#
# fichier de configuration pour Hexdiff
# http://tboudet.free.fr/hexdiff/
#
# enable (1) or disable (0) display of chars
# with a code > 127. charset dependant.
# you can toogle this flag with the 7 and 8 keys
show_8bits 1
# enable or disable usage of semi-graphic chars
# around the various popup windows.
nice_border 0
# select decimal or hexa display of file offset.
# the key 'H' switch interactively beetwen the two modes.
offsets_in_hex 0
# sorry, at this time, no octal offset display...
# if set to 1, display the id of user and group
# in the fileinfo popup (access by 'i' or 'I' key
ext_fileinfo 1
# those flags is not yet used...
language fr
asciiview 0
# is the file selector display hidden file ?
show_hidden 0

15
Hexdiff/memcheck.sh Normal file
View File

@ -0,0 +1,15 @@
#!/bin/sh
#
# seek for memory leaks
# ---------------------
# you need a recent version of http://www.valgrind.org/
#
make hexdiff
rm valgr-plop*
valgrind --tool=memcheck --log-file=valgr-plop \
--leak-check=yes --show-reachable=yes \
./hexdiff hexdiff.o fonctions.o

259
Hexdiff/parse_rc.c Normal file
View File

@ -0,0 +1,259 @@
/*
HEXDIFF - lecture du fichier de configuration
---------------------------------------------
Attention, programmation a la "Gruiik" !-)
Il y a plein de GOTO dans cette fonction, mais je
les daguisent habilement en fortranisme.
-- tTh --
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* pour strtok */
/* certaines mauvaises langues pratendent
* que 'strtok' est obsolete, insecure et
* pas elegant. moi, je veux bien, mais
* alors,il faut me montrer par quoi le
* remplacer...
*/
#include "hexdiff.h"
/*----------------------------------------------------------------*/
/*
* positionner a des valeurs connues toutes les options de
* configuration.
*
* 18juin2002: euh, on ne pourrait pas faire ce truc a la
* declaration de la variable ?
*/
int
init_configuration(void)
{
config.nice_border = 0;
config.show_8bits = 0;
config.language = "fr";
config.offsets_in_hex = 0;
config.ext_fileinfo = 0;
config.show_hidden = 1;
config.sf_flag = 0;
config.explique = 0;
config.zoom = 0;
config.asciiview = 0;
return 51; /* have a Pastis ? */
}
/*----------------------------------------------------------------*/
#define DO_NICE_BORDER 1
#define DO_LANGUAGE 2
#define DO_SHOW_8BITS 3
#define DO_OFFSET_HEX 4
#define DO_EXT_FILEINFO 5
#define DO_SHOW_HIDDEN 20
#define DO_FS_FLAG 21
#define DO_EXPLIQUE 24
#define DO_START_ZOOM 25
#define DO_ASCIIVIEW 26
#define FLAG 1
#define TEXTE 2
#define NOMBRE 3
#define KEY_ALIAS 4
struct conf_var
{
char *nom;
int code;
int type;
};
struct conf_var conf_vars[] =
{
{ "nice_border", DO_NICE_BORDER, FLAG },
{ "language", DO_LANGUAGE, TEXTE },
{ "show_8bits", DO_SHOW_8BITS, FLAG },
{ "offsets_in_hex", DO_OFFSET_HEX, FLAG },
{ "ext_fileinfo", DO_EXT_FILEINFO, FLAG },
{ "show_hidden", DO_SHOW_HIDDEN, FLAG },
{ "fs_flag", DO_FS_FLAG, NOMBRE },
{ "explique", DO_EXPLIQUE, FLAG },
{ "start_zoom", DO_START_ZOOM, FLAG },
{ "asciiview", DO_ASCIIVIEW, NOMBRE }
} ;
#define NB_TOKEN ( sizeof(conf_vars) / sizeof(struct conf_var) )
/*----------------------------------------------------------------*/
static int lookup_token(char *token)
{
int foo;
for (foo=0; foo<NB_TOKEN; foo++)
if ( !strcmp(token, conf_vars[foo].nom) )
return foo;
return -1;
}
/*
*/
#define LIGNE_RC 442
/*----------------------------------------------------------------*/
/*
* If 'flag' is set to a non-zero value:
* - the configfile name is set to './hexdiff.rc'
* - parsing trace is displayed
*/
int
lire_configuration(int flag)
{
FILE *fp;
char ligne[LIGNE_RC+3];
int line_number, foo;
int numtok;
char *machin, *valeur;
char *delim = " \t=";
char *home;
#if TRACE
fprintf(stderr, "*** lecture fichier de conf, flag=%d\n", flag);
#endif
if ( (home=getenv("HOME")) != NULL )
{
/*
* XXX - WARNING BUFFER OVERFLOW HERE !!!
*/
foo = strlen(home) + strlen(HEXDIFF_RC);
if (foo > LIGNE_RC)
{
fprintf(stderr, ".hexdiffrc buff overflow %d, bad $HOME ?\n",
foo);
exit(1);
}
strcpy(ligne, home); strcat(ligne, "/");
strcat(ligne, HEXDIFF_RC);
}
else
/*
* oui, bon, c'est pas trop coherent, mais je ne
* savais pas trop quoi faire en cas de 'homeless',
* alors je me suis permis de supposer un contexte
* msdos/djgpp ...
*/
{
strcpy(ligne, "c:\\hexdiff.rc");
}
#if TRACE
if (flag) /* we are in .rc debug context */
{
strcpy(ligne, "hexdiff.rc");
}
#endif
if ( (fp = fopen(ligne, "r")) == NULL )
{
perror("hexdiff config file");
return -1;
}
line_number = 1;
while ( fgets(ligne, LIGNE_RC, fp) != NULL )
{
/*
* virer le caractere de fin de ligne (Gruiikage)
*/
foo=strlen(ligne);
if (foo>0)
ligne[foo-1] = '\0';
#if TRACE
fprintf(stderr, "%4d %4d : %s\n",
line_number, foo, ligne);
#endif
line_number++;
/*
* decomposition de la ligne en machins
*/
machin = strtok(ligne, delim);
if (machin == NULL) /* ya pas de token */
{
continue;
}
if ( machin[0] == '#' ) /* c'est un commentaire */
{
continue;
}
numtok = lookup_token(machin);
if (flag)
fprintf(stderr, "TOKEN = [%s] code=%d\n", machin, numtok);
if ( numtok < 0 ) { continue; }
valeur = strtok(NULL, delim); /* is strtok() usable in 2007 ? */
if ( valeur != NULL )
{
if (flag)
fprintf(stderr, "VALUE = [%s]\n", valeur);
switch(conf_vars[numtok].code)
{
case DO_NICE_BORDER:
config.nice_border = atoi(valeur);
break;
case DO_SHOW_8BITS:
config.show_8bits = atoi(valeur);
break;
case DO_LANGUAGE:
#if TRACE
fprintf(stderr, "lang=%s\n", valeur);
#endif
break;
case DO_OFFSET_HEX:
config.offsets_in_hex = atoi(valeur);
break;
case DO_EXT_FILEINFO:
config.ext_fileinfo = atoi(valeur);
break;
case DO_SHOW_HIDDEN:
config.show_hidden = atoi(valeur);
break;
case DO_FS_FLAG:
break;
case DO_EXPLIQUE:
break;
}
}
else /* valeur == NULL */
{
#if TRACE
fprintf(stderr, "null value ?\n");
#endif
continue;
}
}
fclose(fp);
return 42; /* thx for all the fishes, Douglas */
}
/*----------------------------------------------------------------*/

352
Hexdiff/sel_file.c Normal file
View File

@ -0,0 +1,352 @@
/*
sel_file.c
----------
old site --> http://tboudet.free.fr/hexdiff/
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pwd.h>
#include <grp.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
/* nasty hack */
char *strdup(char *);
/* end of hack */
#include <ctype.h>
#include <dirent.h>
#include "hexdiff.h"
/*----------------------------------------------------------------*/
/* private vars of this module */
typedef struct {
long taille;
char *nom;
int idx;
} FICH;
static FICH *liste;
static int taille; /* taille de la liste */
static int nombre; /* nbre d'entrees dans la liste */
#define TCHONK 42
/*----------------------------------------------------------------*/
static int teste_dirent(const struct dirent *de, struct stat *pstat)
{
int foo;
foo = stat(de->d_name, pstat);
if (S_ISDIR(pstat->st_mode))
return 0;
if (config.show_hidden==0 && de->d_name[0]=='.')
return 0;
return 1;
}
/*----------------------------------------------------------------*/
static int compare_nom_asc(const void *pa, const void *pb)
{
return strcmp( ((FICH *)pa)->nom, ((FICH *)pb)->nom);
}
static int compare_nom_desc(const void *pa, const void *pb)
{
return strcmp( ((FICH *)pb)->nom, ((FICH *)pa)->nom);
}
static int compare_taille_asc(const void *pa, const void *pb)
{
return ((FICH *)pa)->taille - ((FICH *)pb)->taille;
}
static int compare_taille_desc(const void *pa, const void *pb)
{
return ((FICH *)pb)->taille - ((FICH *)pa)->taille;
}
static int compare_idx(const void *pa, const void *pb)
{
return ((FICH *)pa)->idx - ((FICH *)pb)->idx;
}
#define PAR_NOM_ASC 1
#define PAR_NOM_DESC 2
#define PAR_TAILLE_ASC 3
#define PAR_TAILLE_DESC 4
#define PAR_IDX 5
#define PAR_PLOP 6
static int trier_la_liste(int comment)
{
switch (comment)
{
case PAR_NOM_ASC:
qsort(liste, nombre, sizeof(FICH), compare_nom_asc);
break;
case PAR_NOM_DESC:
qsort(liste, nombre, sizeof(FICH), compare_nom_desc);
break;
case PAR_TAILLE_ASC:
qsort(liste, nombre, sizeof(FICH), compare_taille_asc);
break;
case PAR_TAILLE_DESC:
qsort(liste, nombre, sizeof(FICH), compare_taille_desc);
break;
case PAR_IDX:
qsort(liste, nombre, sizeof(FICH), compare_idx);
break;
}
return 0;
}
/*----------------------------------------------------------------*/
static int liste_fichiers(WINDOW *win, int flag)
{
DIR *dir;
struct dirent *de;
struct stat statbuf;
int foo;
/*
* initializing local vars, for list-of-files
*/
if ( NULL == (liste = malloc(TCHONK*sizeof(FICH))) )
{
wprintw(win, "no mem for file list");
wrefresh(win);
return 1;
}
taille = TCHONK;
dir = opendir(".");
if (dir == NULL)
{
wprintw(win, "error on 'opendir'");
wrefresh(win);
return 1;
}
nombre = 0;
while ( (de=readdir(dir)) != NULL)
{
if ( ! teste_dirent(de, &statbuf) )
{
continue;
}
/* strdup is a 'non-portable' function ? */
liste[nombre].nom = strdup(de->d_name);
liste[nombre].taille = statbuf.st_size;
liste[nombre].idx = nombre;
nombre++;
wrefresh(win);
/*
* if needed, increase the size of the list
*/
if (nombre >= taille)
{
liste = realloc(liste, sizeof(FICH)*(taille+TCHONK));
taille += TCHONK;
}
}
foo = closedir(dir);
return nombre;
}
/*----------------------------------------------------------------*/
char *txt_aide_fs[] =
{
"\n WARNING !\n\n",
" this file selector is a 'quick and dirty' hack\n",
" and code was written with a 'Spleyt' spirit :)\n\n",
"\n",
" smart keys are:\n\n",
" a -> sort by name ascending\n",
" A -> sort by name reversing\n",
" s -> sort by size\n",
" S -> sort reverse by size\n",
" n -> no sort\n",
"",
"sort by date is a work in progress..."
};
int help_on_file_selector(WINDOW *win, int flag)
{
int foo;
werase(win);
for (foo=0; foo<(sizeof(txt_aide_fs)/sizeof(char *)); foo++)
{
wprintw(win, txt_aide_fs[foo]);
wrefresh(win);
}
foo = getch();
return 0;
}
/*----------------------------------------------------------------*/
/*
* new, 2005 June: now, we get the max usable length for *nomfich.
*/
int select_new_file(char *nomfich, int t_nom, int flags)
{
int ligmax, largmax, affh, idx = -1;
WINDOW *fen_1, *fen_2;
int foo, first, curseur, flag_exit, key;
char chaine[T_NOM];
/*
* quick'n'dirty security check, need more work.
*/
if (t_nom > T_NOM)
{
fprintf(stderr, "\n%s:%d possible buffer overflow\n", __FILE__, __LINE__);
exit(1);
}
ligmax = LINES-8; /* taille verticale de la popup */
largmax = 62;
fen_1 = newwin(ligmax, largmax, 2, 12);
bordure(fen_1); wrefresh(fen_1);
/*
* first line of popup display active win number
* and current win directory. as this time, we can't
* select another directory ;-(
*/
wstandout(fen_1);
for (foo=1; foo<largmax-1; foo++)
{
mvwaddch(fen_1, 1, foo, ' ');
mvwaddch(fen_1, ligmax-2, foo, ' ');
}
/* XXX display the number of the active window
XXX in this file selector.
sprintf(chaine, "<%d>", fenetre_active);
mvwaddstr(fen_1, 1, 2, chaine);
*/
if (getcwd(chaine,99)!=NULL)
mvwaddstr(fen_1, 1, 3, chaine);
else
mvwaddstr(fen_1, 1, 9, " can't get cwd, sorry... ");
mvwaddstr(fen_1, ligmax-2, 4, "'Q' to abort, <Enter> to select, '?' for help");
wstandend(fen_1);
wrefresh(fen_1);
/*
* create a subwindow for the scrolling selector
*/
fen_2 = derwin(fen_1, ligmax-4, largmax-2, 2, 1);
scrollok(fen_2, 1);
affh = ligmax-4; /* XXX need a valid value :) */
foo = liste_fichiers(fen_2, 0);
#if TRACE
wprintw(fen_2, "ret liste fichiers = %d\n", foo);
wrefresh(fen_2);
getch();
#endif
trier_la_liste(PAR_NOM_ASC);
/*
* now, the file list is built, so display the selector.
*/
first = curseur = 0;
flag_exit = 0;
do
{
werase(fen_2);
for (foo=0; foo<affh; foo++)
{
idx = foo+first;
if (idx >= nombre)
break;
if (curseur==foo) wstandout(fen_2);
mvwprintw(fen_2, foo, 1, " %-46s %9ld ",
liste[idx].nom, liste[idx].taille);
if (curseur==foo) wstandend(fen_2);
}
wrefresh(fen_2);
#if TRACE
mvwprintw(fen_1, 1, 2, "curs %3d first %3d ", curseur, first);
wrefresh(fen_1);
#endif
/*
* user interaction
*/
key = getch();
switch (key)
{
case KEY_UP:
if (curseur) curseur--;
else if (first>0) first--;
break;
case KEY_DOWN:
if ((curseur+first) >= (nombre-1)) break;
if (curseur < affh-1) curseur++;
else if (first<(nombre-affh)) first++;
break;
/* SORT operations */
case 'a':
trier_la_liste(PAR_NOM_ASC); break;
case 'A':
trier_la_liste(PAR_NOM_DESC); break;
case 's':
trier_la_liste(PAR_TAILLE_ASC); break;
case 'S':
trier_la_liste(PAR_TAILLE_DESC); break;
case '?':
help_on_file_selector(fen_2, 0);
break;
case '\r':
idx = curseur+first;
flag_exit = 1;
break;
case 'Q': flag_exit = -1; break;
}
} while ( ! flag_exit );
delwin(fen_1);
if (flag_exit == 1)
{
strcpy(nomfich, liste[idx].nom);
}
/*
* free the memory used by our list
*/
for (foo=0; foo<nombre; foo++)
free(liste[foo].nom);
free(liste);
return flag_exit==1;
}
/*----------------------------------------------------------------*/
int select_set_opt(int flg)
{
#if TRACE
#endif
return 0;
}
/*----------------------------------------------------------------*/

View File

@ -1,3 +1,7 @@
# KlugyTools
Divers outils pour faire des choses diverses...
Divers outils pour faire des choses diverses...
Beaucoup de choses anciennes que je traine de systèmes en systèmes, et qui ont
parfois une utilité limitée.