Add a C version of Veriexec's fingerprint generator, written by Matt
Fleming. This one has some nice options -- for example, an admin can run right after installing a system: fpgen -D and it will fingerprint a set of "common" system directories to the default loaction. See the man-page for more stuff. Performance-wise, here are results for both fpgen.sh (old) and this new tool: 474.599u 574.335s 13:53.05 125.9% 0+0k 0+307io 0pf+0w 0.424u 0.131s 0:00.56 98.2% 0+0k 0+2io 0pf+0w ...guess which is which? (that's ~1500 times *faster*)
This commit is contained in:
parent
177426845d
commit
ade08c91dc
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: mi,v 1.651 2006/09/16 08:38:20 tnozaki Exp $
|
||||
# $NetBSD: mi,v 1.652 2006/09/16 20:54:43 elad Exp $
|
||||
. base-sys-root
|
||||
./altroot base-sys-root
|
||||
./bin base-sys-root
|
||||
|
@ -1029,6 +1029,7 @@
|
|||
./usr/sbin/faithd base-router-bin inet6
|
||||
./usr/sbin/fixmount base-nfsclient-bin
|
||||
./usr/sbin/flush base-obsolete obsolete
|
||||
./usr/sbin/veriexecgen base-sysutil-bin
|
||||
./usr/sbin/fsinfo base-sysutil-bin
|
||||
./usr/sbin/fssconfig base-sysutil-bin
|
||||
./usr/sbin/fwctl base-sysutil-bin
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: mi,v 1.930 2006/09/10 15:45:55 plunky Exp $
|
||||
# $NetBSD: mi,v 1.931 2006/09/16 20:54:43 elad Exp $
|
||||
./etc/mtree/set.man man-sys-root
|
||||
./usr/share/info/am-utils.info man-amd-info info
|
||||
./usr/share/info/as.info man-computil-info bfd,info
|
||||
|
@ -1854,6 +1854,7 @@
|
|||
./usr/share/man/cat8/fingerd.0 man-sysutil-catman .cat
|
||||
./usr/share/man/cat8/fixmount.0 man-sysutil-catman .cat
|
||||
./usr/share/man/cat8/flush.0 man-postfix-catman postfix,.cat
|
||||
./usr/share/man/cat8/veriexecgen.0 man-sysutil-catman .cat
|
||||
./usr/share/man/cat8/fsck.0 man-sysutil-catman .cat
|
||||
./usr/share/man/cat8/fsck_ext2fs.0 man-ext2fs-catman .cat
|
||||
./usr/share/man/cat8/fsck_ffs.0 man-sysutil-catman .cat
|
||||
|
@ -4226,6 +4227,7 @@
|
|||
./usr/share/man/man8/fingerd.8 man-sysutil-man .man
|
||||
./usr/share/man/man8/fixmount.8 man-sysutil-man .man
|
||||
./usr/share/man/man8/flush.8 man-postfix-man postfix,.man
|
||||
./usr/share/man/man8/veriexecgen.8 man-sysutil-man .man
|
||||
./usr/share/man/man8/fsck.8 man-sysutil-man .man
|
||||
./usr/share/man/man8/fsck_ext2fs.8 man-ext2fs-man .man
|
||||
./usr/share/man/man8/fsck_ffs.8 man-sysutil-man .man
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile,v 1.219 2006/09/07 00:50:45 ad Exp $
|
||||
# $NetBSD: Makefile,v 1.220 2006/09/16 20:54:43 elad Exp $
|
||||
# from: @(#)Makefile 5.20 (Berkeley) 6/12/93
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
@ -21,7 +21,7 @@ SUBDIR= ac accton altq amd apm apmd arp bad144 bind bootp \
|
|||
sliplogin sntp \
|
||||
spray sti sunlabel sup syslogd tadpolectl tcpdchk \
|
||||
tcpdmatch tcpdump timed tpctl traceroute trpt unlink \
|
||||
usbdevs user videomode vipw vnconfig wiconfig wlanctl wpa \
|
||||
usbdevs user videomode vipw veriexecgen vnconfig wiconfig wlanctl wpa \
|
||||
wsconscfg wsfontload wsmoused wsmuxctl zdump zic
|
||||
|
||||
.if (${MKISCSI} != "no")
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
# $NetBSD: Makefile,v 1.1 2006/09/16 20:54:42 elad Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
PROG= veriexecgen
|
||||
MAN= veriexecgen.8
|
||||
|
||||
LDADD+=-lutil
|
||||
DPADD+=${LIBUTIL}
|
||||
CFLAGS+=-g
|
||||
.include <bsd.prog.mk>
|
|
@ -0,0 +1,117 @@
|
|||
.\" $NetBSD: veriexecgen.8,v 1.1 2006/09/16 20:54:42 elad Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This code is derived from software contributed to The NetBSD Foundation
|
||||
.\" by Matt Fleming.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the NetBSD
|
||||
.\" Foundation, Inc. and its contributors.
|
||||
.\" 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
.\" contributors may be used to endorse or promote products derived
|
||||
.\" from this software without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd September 16, 2006
|
||||
.Dt VERIEXECGEN 8
|
||||
.Sh NAME
|
||||
.Nm veriexecgen
|
||||
.Nd generate fingerprints for Veriexec
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl Aarv
|
||||
.Op Fl d Pa dir
|
||||
.Op Fl o Pa fingerprintdb
|
||||
.Op Fl t Ar algorithm
|
||||
.Nm
|
||||
.Op Fl h
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
can be used to create a fingerprint database for use with Veriexec.
|
||||
.Pp
|
||||
By default,
|
||||
.Nm
|
||||
will scan the current working directory for executable file, fingerprint them
|
||||
using
|
||||
.Dq sha256 ,
|
||||
then write the data to
|
||||
.Pa /etc/signatures .
|
||||
.Pp
|
||||
If the output file already exists,
|
||||
.Nm
|
||||
will save a backup copy in the same file only with a
|
||||
.Dq .old
|
||||
suffix.
|
||||
.Pp
|
||||
The following options are available:
|
||||
.Bl -tag
|
||||
.It Fl A
|
||||
Append to the output file, don't overwrite it.
|
||||
.It Fl a
|
||||
Add fingerprints for non-executable files as well.
|
||||
.It Fl D
|
||||
Search system directories,
|
||||
.Pa /bin ,
|
||||
.Pa /sbin ,
|
||||
.Pa /usr/bin ,
|
||||
.Pa /usr/sbin ,
|
||||
and
|
||||
.Pa /usr/lib .
|
||||
.Fl d
|
||||
flag.
|
||||
.It Fl d Ar dir
|
||||
Scan for files in
|
||||
.Ar dir .
|
||||
Multiple uses of this flag can specify more than one directory.
|
||||
.\" .It Fl F
|
||||
.\" Try to guess the correct flags for every file.
|
||||
.It Fl h
|
||||
Display the help screen.
|
||||
.It Fl o Ar fingerprintdb
|
||||
Save the generated fingerprint database to
|
||||
.Ar fingerprintdb .
|
||||
.It Fl r
|
||||
Scan recursively.
|
||||
.It Fl t Ar algorithm
|
||||
Use
|
||||
.Ar algorithm
|
||||
for the fingerprints.
|
||||
Must be one of
|
||||
.Dq md5 ,
|
||||
.Dq sha1 ,
|
||||
.Dq sha256 ,
|
||||
.Dq sha384 ,
|
||||
.Dq sha512 ,
|
||||
or
|
||||
.Dq rmd160 .
|
||||
.It Fl v
|
||||
Verbose mode.
|
||||
Print messages describing what operations are being done.
|
||||
.El
|
||||
.\" .Sh EXAMPLES
|
||||
.\" Foo.
|
||||
.Sh SEE ALSO
|
||||
.Xr veriexec 4 ,
|
||||
.Xr veriexectl 8
|
|
@ -0,0 +1,375 @@
|
|||
/* $NetBSD: veriexecgen.c,v 1.1 2006/09/16 20:54:42 elad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Matt Fleming.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/dirent.h>
|
||||
#include <sys/verified_exec.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fts.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <util.h>
|
||||
|
||||
#include <md5.h>
|
||||
#include <crypto/sha1.h>
|
||||
#include <crypto/sha2.h>
|
||||
#include <crypto/rmd160.h>
|
||||
|
||||
#define IS_EXEC(mode) ((mode) & (S_IXUSR | S_IXGRP | S_IXOTH))
|
||||
|
||||
#define DEFAULT_DBFILE "/etc/signatures"
|
||||
#define DEFAULT_HASH "sha256"
|
||||
#define DEFAULT_SYSPATHS { "/bin", "/sbin", "/usr/bin", "/usr/sbin", \
|
||||
"/usr/lib", NULL }
|
||||
|
||||
struct fentry {
|
||||
char filename[MAXPATHLEN];
|
||||
char *hash_val;
|
||||
int flags;
|
||||
TAILQ_ENTRY(fentry) f;
|
||||
};
|
||||
TAILQ_HEAD(, fentry) fehead;
|
||||
|
||||
struct hash {
|
||||
const char *hashname;
|
||||
char *(*filefunc) (const char *, char *);
|
||||
} hashes[] = {
|
||||
{ "MD5", MD5File },
|
||||
{ "SHA1", SHA1File },
|
||||
{ "SHA256", SHA256_File },
|
||||
{ "SHA384", SHA384_File },
|
||||
{ "SHA512", SHA512_File },
|
||||
{ "RMD160", RMD160File },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
int Aflag, aflag, Dflag, Fflag, rflag, vflag;
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"usage: %s [-Aarv] [-D] [-d dir] [-o fingerprintdb]"
|
||||
" [-t algorithm]\n", getprogname());
|
||||
}
|
||||
|
||||
static void
|
||||
banner(struct hash *hash_type, char **search_path)
|
||||
{
|
||||
int j;
|
||||
|
||||
(void)printf("Fingerprinting ");
|
||||
|
||||
for (j = 0; search_path[j] != NULL; j++)
|
||||
(void)printf("%s ", search_path[j]);
|
||||
|
||||
(void)printf("(%s) (%s) using %s\n",
|
||||
aflag ? "all files" : "executables only",
|
||||
rflag ? "recursive" : "non-recursive",
|
||||
hash_type->hashname);
|
||||
}
|
||||
|
||||
static struct hash *
|
||||
find_hash(char *hash_type)
|
||||
{
|
||||
struct hash *hash;
|
||||
|
||||
for (hash = hashes; hash->hashname != NULL; hash++)
|
||||
if (strcasecmp(hash_type, hash->hashname) == 0)
|
||||
return hash;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *
|
||||
do_hash(char *filename, struct hash * h)
|
||||
{
|
||||
return h->filefunc(filename, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
figure_flags(char *path, mode_t mode)
|
||||
{
|
||||
#ifdef notyet
|
||||
if (Fflag) {
|
||||
/* Try to figure out right flag(s). */
|
||||
return VERIEXEC_DIRECT;
|
||||
}
|
||||
#endif /* notyet */
|
||||
|
||||
if (!IS_EXEC(mode))
|
||||
return VERIEXEC_FILE;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
check_dup(char *filename)
|
||||
{
|
||||
struct fentry *lwalk;
|
||||
|
||||
TAILQ_FOREACH(lwalk, &fehead, f) {
|
||||
if (strncmp(lwalk->filename, filename,
|
||||
(unsigned long) MAXPATHLEN) == 0)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
add_new_entry(FTSENT *file, struct hash *hash)
|
||||
{
|
||||
struct fentry *e;
|
||||
struct stat sb;
|
||||
|
||||
if (file->fts_info == FTS_SL) {
|
||||
if (stat(file->fts_path, &sb) == -1)
|
||||
err(1, "Cannot stat symlink");
|
||||
} else
|
||||
sb = *file->fts_statp;
|
||||
|
||||
if (!aflag && !Dflag && IS_EXEC(sb.st_mode))
|
||||
return;
|
||||
|
||||
e = ecalloc(1UL, sizeof(*e));
|
||||
|
||||
if (realpath(file->fts_accpath, e->filename) == NULL)
|
||||
err(1, "Cannot find absolute path");
|
||||
if (check_dup(e->filename)) {
|
||||
free(e);
|
||||
return;
|
||||
}
|
||||
if ((e->hash_val = do_hash(e->filename, hash)) == NULL)
|
||||
errx(1, "Cannot calculate hash");
|
||||
e->flags = figure_flags(e->filename, sb.st_mode);
|
||||
|
||||
TAILQ_INSERT_TAIL(&fehead, e, f);
|
||||
}
|
||||
|
||||
static void
|
||||
walk_dir(char **search_path, struct hash *hash)
|
||||
{
|
||||
FTS *fh;
|
||||
FTSENT *file;
|
||||
|
||||
if ((fh = fts_open(search_path, FTS_PHYSICAL, NULL)) == NULL)
|
||||
err(1, "fts_open");
|
||||
|
||||
while ((file = fts_read(fh)) != NULL) {
|
||||
if (!rflag && file->fts_level > 1) {
|
||||
fts_set(fh, file, FTS_SKIP);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (file->fts_info) {
|
||||
case FTS_D:
|
||||
case FTS_DC:
|
||||
case FTS_DP:
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (file->fts_errno) {
|
||||
errx(1, "%s: %s", file->fts_path,
|
||||
strerror(file->fts_errno));
|
||||
}
|
||||
|
||||
add_new_entry(file, hash);
|
||||
}
|
||||
|
||||
fts_close(fh);
|
||||
}
|
||||
|
||||
static char *
|
||||
flags2str(int flags)
|
||||
{
|
||||
if (flags != 0)
|
||||
return "FILE";
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
static void
|
||||
store_entries(char *dbfile, struct hash *hash)
|
||||
{
|
||||
FILE *fp;
|
||||
int move = 1;
|
||||
char old_dbfile[MAXPATHLEN];
|
||||
time_t ct;
|
||||
struct stat sb;
|
||||
struct fentry *e;
|
||||
|
||||
if (stat(dbfile, &sb) != 0) {
|
||||
if (errno == ENOENT)
|
||||
move = 0;
|
||||
else
|
||||
err(1, "could not stat %s", dbfile);
|
||||
}
|
||||
if (move && !Aflag) {
|
||||
if (vflag)
|
||||
(void)printf("\nBacking up existing fingerprint file "
|
||||
"to \"%s.old\"\n\n", dbfile);
|
||||
|
||||
if (snprintf(old_dbfile, MAXPATHLEN, "%s.old", dbfile) <
|
||||
strlen(dbfile) + 4) {
|
||||
err(1, "%s", old_dbfile);
|
||||
}
|
||||
if (rename(dbfile, old_dbfile) == -1)
|
||||
err(1, "could not rename file");
|
||||
}
|
||||
|
||||
fp = efopen(dbfile, Aflag ? "a" : "w+");
|
||||
|
||||
time(&ct);
|
||||
(void)fprintf(fp, "# Generated by %s, %.24s\n",
|
||||
getlogin(), ctime(&ct));
|
||||
|
||||
TAILQ_FOREACH(e, &fehead, f) {
|
||||
if (vflag)
|
||||
(void)printf("Adding %s.\n", e->filename);
|
||||
|
||||
(void)fprintf(fp, "%s %s %s %s\n", e->filename,
|
||||
hash->hashname, e->hash_val, flags2str(e->flags));
|
||||
}
|
||||
|
||||
(void)fclose(fp);
|
||||
|
||||
if (!vflag)
|
||||
return;
|
||||
|
||||
(void)printf("\n\n"
|
||||
"#############################################################\n"
|
||||
" PLEASE VERIFY CONTENTS OF %s AND FINE-TUNE THE\n"
|
||||
" FLAGS WHERE APPROPRIATE AFTER READING veriexecctl(8)\n"
|
||||
"#############################################################\n",
|
||||
dbfile);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int ch, total = 0;
|
||||
char *dbfile = NULL;
|
||||
char **search_path = NULL;
|
||||
struct hash *hash = NULL;
|
||||
|
||||
Aflag = aflag = Dflag = Fflag = rflag = vflag = 0;
|
||||
|
||||
while ((ch = getopt(argc, argv, "AaDd:ho:rt:v")) != -1) {
|
||||
switch (ch) {
|
||||
case 'A':
|
||||
Aflag = 1;
|
||||
break;
|
||||
case 'a':
|
||||
aflag = 1;
|
||||
break;
|
||||
case 'D':
|
||||
Dflag = 1;
|
||||
break;
|
||||
case 'd':
|
||||
search_path = erealloc(search_path, sizeof(char *) *
|
||||
(total + 1));
|
||||
search_path[total] = optarg;
|
||||
search_path[++total] = NULL;
|
||||
break;
|
||||
#ifdef notyet
|
||||
case 'F':
|
||||
Fflag = 1;
|
||||
break;
|
||||
#endif /* notyet */
|
||||
case 'h':
|
||||
usage();
|
||||
return 0;
|
||||
case 'o':
|
||||
dbfile = optarg;
|
||||
break;
|
||||
case 'r':
|
||||
rflag = 1;
|
||||
break;
|
||||
case 't':
|
||||
hash = find_hash(optarg);
|
||||
break;
|
||||
case 'v':
|
||||
vflag = 1;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (dbfile == NULL)
|
||||
dbfile = DEFAULT_DBFILE;
|
||||
|
||||
if (hash == NULL) {
|
||||
if ((hash = find_hash(DEFAULT_HASH)) == NULL)
|
||||
errx(1, "No hash algorithm");
|
||||
}
|
||||
|
||||
TAILQ_INIT(&fehead);
|
||||
|
||||
if (search_path == NULL)
|
||||
Dflag = 1;
|
||||
|
||||
if (Dflag) {
|
||||
char *sys_paths[] = DEFAULT_SYSPATHS;
|
||||
|
||||
if (vflag)
|
||||
banner(hash, sys_paths);
|
||||
walk_dir(sys_paths, hash);
|
||||
}
|
||||
|
||||
if (search_path != NULL) {
|
||||
if (vflag)
|
||||
banner(hash, search_path);
|
||||
walk_dir(search_path, hash);
|
||||
}
|
||||
|
||||
store_entries(dbfile, hash);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue