New code added.

git-svn: trunk@64
remotes/push_mirror/metadata
Tomasz Kojm 22 years ago
parent 9e7b0c12db
commit 8139fd99cb
  1. 5
      clamav-devel/AUTHORS
  2. 16
      clamav-devel/ChangeLog
  3. 4
      clamav-devel/clamd/cfgfile.c
  4. 3
      clamav-devel/clamd/scanner.c
  5. 7
      clamav-devel/clamd/server.c
  6. 18
      clamav-devel/clamd/tcpserver.c
  7. 6
      clamav-devel/clamscan/manager.c
  8. 26
      clamav-devel/clamscan/others.c
  9. 1
      clamav-devel/clamscan/others.h
  10. 14
      clamav-devel/etc/clamav.conf
  11. 4
      clamav-devel/freshclam/manager.c
  12. 22
      clamav-devel/libclamav/clamav.h
  13. 314
      clamav-devel/libclamav/cvd.c
  14. 20
      clamav-devel/libclamav/others.c
  15. 2
      clamav-devel/libclamav/others.h
  16. 22
      clamav-devel/libclamav/readdb.c
  17. 14
      clamav-devel/libclamav/scanners.c
  18. 43
      clamav-devel/libclamav/zziplib/zzip-conf.h
  19. 37
      clamav-devel/libclamav/zziplib/zzip-dir.c
  20. 1
      clamav-devel/libclamav/zziplib/zzip-err.c
  21. 64
      clamav-devel/libclamav/zziplib/zzip-file.c
  22. 8
      clamav-devel/libclamav/zziplib/zzip-file.h
  23. 291
      clamav-devel/libclamav/zziplib/zzip-zip.c
  24. 3
      clamav-devel/libclamav/zziplib/zzip.h
  25. 107
      clamav-devel/libclamav/zziplib/zziplib.h
  26. 4
      clamav-devel/sigtool/options.c
  27. 233
      clamav-devel/sigtool/sigtool.c

@ -7,6 +7,9 @@ Nigel Horne <njh@bandsman.co.uk>
home page : http://bandsman.co.uk
Author of clamav-milter and the whole mbox code.
System administrator (www, mailing lists, mirror issues, virus
submission mechanisms): Luca 'NERvOus' Gibelli <nervous@nervous.it>
Database developers:
aCaB <acab@digitalfuture.it>
@ -15,6 +18,7 @@ Jason Englander <jason@englanders.cc>
Tomasz Kojm <zolw@konarski.edu.pl>
Tomasz Papszun <tomek@lodz.tpsa.pl>
TrashScan was written by Trashware <trashware@gmx.net>.
ClamAV patches were submitted by (in alphabetical order):
@ -28,6 +32,7 @@ Jason Englander <jason@englanders.cc>
David Ford <david+cert@blue-labs.org>
Nigel Horne <njh@smsltd.demon.co.uk>
Hrvoje Habjanic <hrvoje.habjanic@zg.hinet.hr>
Nicholas M. Kirsch <nick@kirsch.org>
Robbert Kouprie <robbert@exx.nl>
Thomas Lamy <Thomas.Lamy@in-online.net>
Peter N Lewis <peter@stairways.com.au>

@ -1,3 +1,19 @@
Mon Sep 29 13:42:51 CEST 2003 (tk)
----------------------------------
* libclamav: initial support for cvd file format (a database container file
with support for digital signatures)
* libclamav: fixed zip recursion problem introduced in -20030907 (bug
reported by Tomasz Papszun)
* libclamav: support for gzip and Maildir files was enabled if ScanMail _or_
ScanArchive was defined. Fixed.
* libclamav: zziplib updated to 0.12.83 (probably not the newest one but
seems to be very stable)
* sigtool: --build (builds a cvd file, not finished yet)
* clamd: new directive TCPAddr by Bernard Quatermass
* libclamav: new scan option CL_DISABLERAR (disables built-in rar unpacker)
* clamd: rar scanning is now disabled by default and may be enabled with
ScanRAR in clamav.conf.
Mon Sep 29 07:15:30 BST 2003 (njh)
----------------------------------
* clamav-milter: ensure remoteIP is initialised

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 Tomasz Kojm <zolw@konarski.edu.pl>
* Copyright (C) 2002, 2003 Tomasz Kojm <zolw@konarski.edu.pl>
*
* 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
@ -46,11 +46,13 @@ struct cfgstruct *parsecfg(const char *cfgfile)
{"MaxFileSize", OPT_COMPSIZE},
{"ScanMail", OPT_NOARG},
{"ScanArchive", OPT_NOARG},
{"ScanRAR", OPT_NOARG},
{"ArchiveMaxFileSize", OPT_COMPSIZE},
{"ArchiveMaxRecursion", OPT_NUM},
{"ArchiveMaxFiles", OPT_NUM},
{"ArchiveLimitMemoryUsage", OPT_NOARG},
{"DataDirectory", OPT_STR},
{"TCPAddr", OPT_STR},
{"TCPSocket", OPT_NUM},
{"LocalSocket", OPT_STR},
{"MaxConnectionQueueLength", OPT_NUM},

@ -215,6 +215,9 @@ int scanstream(int odesc, unsigned long int *scanned, const struct cl_node *root
return -1;
}
logg("*Accepted connection on port %d\n", port);
if(cfgopt(copt, "StreamSaveToDisk")) {
if((tmp = tmpfile()) == NULL) {
shutdown(sockfd, 2);

@ -447,6 +447,13 @@ int acceptloop(int socketd, struct cl_node *root, const struct cfgstruct *copt)
if(cfgopt(copt, "ScanArchive")) {
logg("Archive support enabled.\n");
options |= CL_ARCHIVE;
if(cfgopt(copt, "ScanRAR")) {
logg("RAR support enabled.\n");
} else {
logg("RAR support disabled.\n");
options |= CL_DISABLERAR;
}
} else {
logg("Archive support disabled.\n");
}

@ -36,11 +36,19 @@ int tcpserver(const struct optstruct *opt, const struct cfgstruct *copt, struct
int sockfd, backlog;
struct cfgstruct *cpt;
char *estr;
const char *taddr;
memset((char *) &server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(cfgopt(copt, "TCPSocket")->numarg);
server.sin_addr.s_addr = INADDR_ANY;
taddr = cfgopt(copt, "TCPAddr")->strarg;
if ( taddr != NULL && *taddr )
{
server.sin_addr.s_addr = inet_addr( taddr );
}else
{
server.sin_addr.s_addr = INADDR_ANY;
}
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
@ -55,8 +63,12 @@ int tcpserver(const struct optstruct *opt, const struct cfgstruct *copt, struct
//fprintf(stderr, "ERROR: can't bind(): %s\n", estr);
logg("!bind() error: %s\n", estr);
exit(1);
} else
logg("Binded to port %d\n", cfgopt(copt, "TCPSocket")->numarg);
} else {
if ( taddr != NULL && *taddr )
logg("Bound to address %s on port %d\n", taddr, cfgopt(copt, "TCPSocket")->numarg);
else
logg("Bound to port %d\n", cfgopt(copt, "TCPSocket")->numarg);
}
if((cpt = cfgopt(copt, "MaxConnectionQueueLength")))
backlog = cpt->numarg;

@ -182,7 +182,7 @@ int scanmanager(const struct optstruct *opt)
}
/* generate the temporary directory */
dir = gentemp(tmpdir);
dir = cl_gentemp(tmpdir);
if(mkdir(dir, 0700)) {
mprintf("@Can't create the temporary directory %s\n", dir);
exit(63); /* critical */
@ -473,7 +473,7 @@ int scancompressed(const char *filename, struct cl_node *root, const struct pass
/* generate the temporary directory */
gendir = gentemp(tmpdir);
gendir = cl_gentemp(tmpdir);
if(mkdir(gendir, 0700)) {
mprintf("@Can't create the temporary directory %s\n", gendir);
exit(63); /* critical */
@ -670,7 +670,7 @@ int scandenied(const char *filename, struct cl_node *root, const struct passwd *
}
/* generate the temporary directory */
gendir = gentemp(tmpdir);
gendir = cl_gentemp(tmpdir);
if(mkdir(gendir, 0700)) {
mprintf("@Can't create the temporary directory %s\n", gendir);
exit(63); /* critical */

@ -420,32 +420,6 @@ int filecopy(const char *src, const char *dest)
return close(d);
}
char *gentemp(const char *dir)
{
char *name, *mdir, *tmp;
unsigned char salt[32];
int cnt=0, i;
if(!dir)
mdir = "/tmp";
else
mdir = (char *) dir;
name = (char*) calloc(strlen(mdir) + 1 + 16 + 1, sizeof(char));
cnt += sprintf(name, "%s/", mdir);
do {
for(i = 0; i < 32; i++)
salt[i] = cl_rndnum(255);
tmp = cl_md5buff(salt, 32);
strncat(name, tmp, 16);
free(tmp);
} while(fileinfo(name, 1) != -1);
return(name);
}
int strbcasestr(const char *haystack, const char *needle)
{
char *pt = (char *) haystack;

@ -35,7 +35,6 @@ int strbcasestr(const char *haystack, const char *needle);
int readaccess(const char *path, const char *username);
int writeaccess(const char *path, const char *username);
int filecopy(const char *src, const char *dest);
char *gentemp(const char *dir);
/* njh@bandsman.co.uk: for BeOS */
/* TODO: configure should see if sete[ug]id is set on the target */

@ -53,7 +53,13 @@ Example
LocalSocket /tmp/clamd
# Remove stale socket after unclean shutdown.
#FixStaleSocket
#RemoveStaleSocket
# TCP address.
# By default we bind to INADDR_ANY, probably not wise.
# Enable the following to provide some degree of protection
# from the outside world.
#TCPAddr 127.0.0.1
# TCP port address.
#TCPSocket 3310
@ -132,6 +138,12 @@ MaxDirectoryRecursion 15
# Comment this line to disable scanning of the archives.
ScanArchive
# By default the built-in RAR unpacker is disabled because the code
# terribly leaks, however it's probably a good idea to enable it.
#ScanRAR
# Options below protect your system against Denial of Service attacks
# with archive bombs.

@ -174,7 +174,7 @@ int downloadmanager(const struct optstruct *opt, const char *hostname)
/* temporary file is created in clamav's directory thus we don't need
* to create it immediately, because race conditions are impossible
*/
tempname = gentemp(".");
tempname = cl_gentemp(".");
/* download the database */
/* FIXME: We need to reconnect, because we won't be able to donwload
@ -232,7 +232,7 @@ int downloadmanager(const struct optstruct *opt, const char *hostname)
}
if(updatedb2) {
tempname = gentemp(".");
tempname = cl_gentemp(".");
/* download viruses.db2 */

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 Tomasz Kojm <zolw@konarski.edu.pl>
* Copyright (C) 2002, 2003 Tomasz Kojm <zolw@konarski.edu.pl>
*
* 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
@ -56,11 +56,13 @@ extern "C"
#define CL_EMALFDB -5 /* malformed database */
#define CL_EPATSHORT -6 /* pattern too short */
#define CL_ETMPDIR -7 /* mkdir() failed */
#define CL_ECVDEXTR -8 /* CVD extraction failure */
/* options */
#define CL_RAW 00
#define CL_ARCHIVE 01
#define CL_MAIL 0100
#define CL_DISABLERAR 01000
struct patt {
short int *pattern;
@ -94,6 +96,16 @@ struct cl_stat {
struct stat *stattab;
};
struct cl_cvd {
char *time; /* 2 */
int version; /* 3 */
int sigs; /* 4 */
short int fl; /* 5 */
char *md5; /* 6 */
char *dsig; /* 7 */
char *builder; /* 8 */
};
/* file scanning */
extern int cl_scanbuff(const char *buffer, unsigned int length, char **virname, const struct cl_node *root);
@ -106,6 +118,9 @@ extern int cl_loaddb(const char *filename, struct cl_node **root, int *virnum);
extern int cl_loaddbdir(const char *dirname, struct cl_node **root, int *virnum);
extern char *cl_retdbdir(void);
extern struct cl_cvd *cl_cvdhead(const char *file);
extern void cl_cvdfree(struct cl_cvd *cvd);
/* data dir stat functions */
extern int cl_statinidir(const char *dirname, struct cl_stat *dbstat);
extern int cl_statchkdir(const struct cl_stat *dbstat);
@ -126,7 +141,7 @@ extern char *cl_md5buff(const char *buffer, unsigned int length);
extern int cl_mbox(const char *dir, int desc);
/* compute MD5 message digest from filename (compatible with md5sum(1)) */
/* compute MD5 message digest from file (compatible with md5sum(1)) */
extern char *cl_md5file(const char *filename);
/* decode hexadecimal string */
@ -138,6 +153,9 @@ extern char *cl_str2hex(const char *string, unsigned int len);
/* generate a pseudo-random number */
extern unsigned int cl_rndnum(unsigned int max);
/* generate unique file name in temporary directory */
char *cl_gentemp(const char *dir);
#ifdef __cplusplus
};
#endif

@ -0,0 +1,314 @@
/*
* Copyright (C) 2003 Tomasz Kojm <zolw@konarski.edu.pl>
*
* untgz() is based on public domain minitar utility by Charles G. Waldman
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <zlib.h>
#include "clamav.h"
#define TAR_BLOCKSIZE 512
int cli_untgz(int fd, const char *destdir)
{
char *fullname, osize[13], name[101], type;
char block[TAR_BLOCKSIZE];
int nbytes, nread, nwritten, in_block = 0;
unsigned int size;
FILE *outfile = NULL;
gzFile *infile;
cli_dbgmsg("in cli_untgz()\n");
if((infile = gzdopen(fd, "rb")) == NULL) {
cli_errmsg("Can't gzdopen() descriptor %d\n", fd);
return -1;
}
fullname = (char *) calloc(sizeof(char), strlen(destdir) + 100 + 5);
while(1) {
nread = gzread(infile, block, TAR_BLOCKSIZE);
if(!in_block && nread == 0)
break;
if(nread != TAR_BLOCKSIZE) {
cli_errmsg("Incomplete block read.\n");
free(fullname);
return -1;
}
if(!in_block) {
if (block[0] == '\0') /* We're done */
break;
strncpy(name, block, 100);
name[100] = '\0';
strcpy(fullname, destdir);
strcat(fullname, "/");
strcat(fullname, name);
cli_dbgmsg("Unpacking %s\n",fullname);
type = block[156];
switch(type) {
case '0':
case '\0':
break;
case '5':
cli_errmsg("Directories in CVD are not supported.\n");
free(fullname);
return -1;
default:
cli_errmsg("Unknown type flag %c.\n",type);
free(fullname);
return -1;
}
in_block = 1;
if(outfile) {
if(fclose(outfile)) {
cli_errmsg("Cannot close file %s.\n", fullname);
free(fullname);
return -1;
}
outfile = NULL;
}
if(!(outfile = fopen(fullname, "wb"))) {
cli_errmsg("Cannot create file %s.\n", fullname);
free(fullname);
return -1;
}
strncpy(osize, block + 124, 12);
osize[12] = '\0';
size = -1;
sscanf(osize, "%o", &size);
if(size < 0) {
cli_errmsg("Invalid size in header.\n");
free(fullname);
return -1;
}
} else { /* write or continue writing file contents */
nbytes = size > TAR_BLOCKSIZE ? TAR_BLOCKSIZE : size;
nwritten = fwrite(block, 1, nbytes, outfile);
if(nwritten != nbytes) {
cli_errmsg("Wrote %d instead of %d (%s).\n", nwritten, nbytes, fullname);
free(fullname);
return -1;
}
size -= nbytes;
if(size == 0)
in_block = 0;
}
}
return 0;
}
char *cli_cut(const char *line, int field)
{
int length, counter = 0, i, j = 0, k;
char *buffer;
length = strlen(line);
buffer = (char *) cli_calloc(length, sizeof(char));
for(i = 0; i < length; i++) {
if(line[i] == ':') {
counter++;
if(counter == field) {
break;
} else {
memset(buffer, 0, length);
j = 0;
}
} else {
buffer[j++] = line[i];
}
}
return (char *) cli_realloc(buffer, strlen(buffer) + 1);
}
struct cl_cvd *cli_cvdhead(const char *head)
{
char *pt;
struct cl_cvd *cvd;
cvd = (struct cl_cvd *) cli_calloc(1, sizeof(struct cl_cvd));
cvd->time = cli_cut(head, 2);
pt = cli_cut(head, 3);
cvd->version = atoi(pt);
free(pt);
pt = cli_cut(head, 4);
cvd->sigs = atoi(pt);
free(pt);
pt = cli_cut(head, 5);
cvd->fl = (short int) atoi(pt);
free(pt);
cvd->md5 = cli_cut(head, 6);
cvd->dsig = cli_cut(head, 7);
cvd->builder = cli_cut(head, 8);
return cvd;
}
struct cl_cvd *cl_cvdhead(const char *file)
{
char head[257];
FILE *fd;
int i;
if((fd = fopen(file, "rb")) == NULL) {
cli_errmsg("Can't open CVD file %s\n", file);
return NULL;
}
if(fread(head, 1, 256, fd) != 256) {
cli_errmsg("Can't read CVD head from %s\n", file);
return NULL;
}
head[256] = 0;
for(i = 255; i > 0 && !isalnum(head[i]); head[i] = 0, i--);
if(strncmp(head, "ClamAV-VDB:", 11)) {
cli_errmsg("%s is not a CVD file.\n");
return NULL;
}
return cli_cvdhead(head);
}
void cl_cvdfree(struct cl_cvd *cvd)
{
free(cvd->time);
free(cvd->md5);
free(cvd->dsig);
free(cvd->builder);
free(cvd);
}
int cli_cvdload(FILE *fd, struct cl_node **root, int *virnum)
{
char head[257], *dir, *tmp, buffer[BUFFSIZE];
int bytes;
struct cl_cvd *cvd;
const char *tmpdir;
FILE *tmpd;
cli_dbgmsg("in cli_cvdload()\n");
if(fread(head, 1, 256, fd) != 256) {
cli_errmsg("Can't read CVD head.\n");
return -1;
}
head[256] = 0;
cvd = cli_cvdhead(head);
/* verify md5/dsig */
/* unpack */
tmpdir = getenv("TMPDIR");
if(tmpdir == NULL)
#ifdef P_tmpdir
tmpdir = P_tmpdir;
#else
tmpdir = "/tmp";
#endif
dir = cl_gentemp(tmpdir);
if(mkdir(dir, 0700)) {
cli_errmsg("cli_cvdload(): Can't create temporary directory %s\n", dir);
return CL_ETMPDIR;
}
/*
if(cli_untgz(fileno(fd), dir)) {
cli_errmsg("cli_cvdload(): Can't unpack CVD file.\n");
return CL_ECVDEXTR;
}
*/
/* FIXME: it seems there is some problem with current position after
* gzdopen() in cli_untgz(). Temporarily we need this wrapper:
*/
/* start */
tmp = cl_gentemp(tmpdir);
if((tmpd = fopen(tmp, "wb+")) == NULL) {
cli_errmsg("Can't create temporary file %s\n", tmp);
free(dir);
free(tmp);
return -1;
}
while((bytes = fread(buffer, 1, BUFFSIZE, fd)) > 0)
fwrite(buffer, 1, bytes, tmpd);
fflush(tmpd);
fseek(tmpd, 0L, SEEK_SET);
if(cli_untgz(fileno(tmpd), dir)) {
cli_errmsg("cli_cvdload(): Can't unpack CVD file.\n");
cli_rmdirs(dir);
free(dir);
unlink(tmp);
free(tmp);
return CL_ECVDEXTR;
}
fclose(tmpd);
unlink(tmp);
free(tmp);
/* end */
/* load extracted directory */
cl_loaddbdir(dir, root, virnum);
cli_rmdirs(dir);
free(dir);
return 0;
}

@ -119,8 +119,10 @@ char *cl_strerror(int clerror)
return "Malformed database.";
case CL_EPATSHORT:
return "Too short pattern detected.";
case CL_ECVDEXTR:
return "CVD extraction failure.";
case CL_ENULLARG:
return "Null argument passed when initialized is required.";
return "Null argument passed while initialized is required.";
default:
return "Unknown error code.";
}
@ -200,6 +202,19 @@ void *cli_calloc(size_t nmemb, size_t size)
} else return alloc;
}
void *cli_realloc(void *ptr, size_t size)
{
void *alloc;
alloc = realloc(ptr, size);
if(!alloc) {
cli_errmsg("cli_realloc(): Can't re-allocate memory to %d byte.\n", size);
perror("realloc_problem");
return NULL;
} else return alloc;
}
#ifndef C_URANDOM
/* it's very weak */
#include <sys/time.h>
@ -253,7 +268,8 @@ unsigned int cl_rndnum(unsigned int max)
}
#endif
char *cli_gentemp(const char *dir)
/* it uses MD5 to avoid potential races in tmp */
char *cl_gentemp(const char *dir)
{
char *name, *mdir, *tmp;
unsigned char salt[32];

@ -26,7 +26,7 @@ void cli_errmsg(const char *str, ...);
void cli_dbgmsg(const char *str, ...);
void *cli_malloc(size_t nmemb);
void *cli_calloc(size_t nmemb, size_t size);
char *cli_gentemp(const char *dir);
void *cli_realloc(void *ptr, size_t size);
int cli_rmdirs(const char *dirname);
#endif

@ -1,6 +1,5 @@
/*
* Copyright (C) 2002 Tomasz Kojm <zolw@konarski.edu.pl>
* Copyright (C) 2002, 2003 Tomasz Kojm <zolw@konarski.edu.pl>
*
* 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
@ -90,6 +89,17 @@ int cl_loaddb(const char *filename, struct cl_node **root, int *virnum)
cli_dbgmsg("Loading %s\n", filename);
/* check for CVD file */
fgets(buffer, 12, fd);
fseek(fd, 0L, SEEK_SET);
if(!strncmp(buffer, "ClamAV-VDB:", 11)) {
cli_dbgmsg("%s: CVD file detected\n", filename);
ret = cli_cvdload(fd, root, virnum);
fclose(fd);
return ret;
}
while(fgets(buffer, BUFFSIZE, fd)) {
/* for forward compatibility */
@ -181,11 +191,15 @@ int cl_loaddbdir(const char *dirname, struct cl_node **root, int *virnum)
while((dent = readdir(dd))) {
if(dent->d_ino) {
if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..") && (cli_strbcasestr(dent->d_name, ".db") || cli_strbcasestr(dent->d_name, ".db2"))) {
if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..") &&
(cli_strbcasestr(dent->d_name, ".db") ||
cli_strbcasestr(dent->d_name, ".db2") ||
cli_strbcasestr(dent->d_name, ".cvd"))) {
dbfile = (char *) cli_calloc(strlen(dent->d_name) + strlen(dirname) + 2, sizeof(char));
if(!dbfile) {
cli_dbgmsg("cl_loaddbdir() -> dbfile == NULL\n");
cli_dbgmsg("cl_loaddbdir(): dbfile == NULL\n");
closedir(dd);
return CL_EMEM;
}

@ -49,6 +49,7 @@ int cli_scanrar_inuse = 0;
#define SCAN_ARCHIVE (options & CL_ARCHIVE)
#define SCAN_MAIL (options & CL_MAIL)
#define DISABLE_RAR (options & CL_DISABLERAR)
#define MAGIC_BUFFER_SIZE 14
#define RAR_MAGIC_STR "Rar!"
@ -555,7 +556,7 @@ int cli_scanmail(int desc, char **virname, long int *scanned, const struct cl_no
#endif
/* generate the temporary directory */
dir = cli_gentemp(tmpdir);
dir = cl_gentemp(tmpdir);
if(mkdir(dir, 0700)) {
cli_errmsg("ScanMail -> Can't create temporary directory %s\n", dir);
/*
@ -619,22 +620,23 @@ int cli_magic_scandesc(int desc, char **virname, long int *scanned, const struct
if (bread != MAGIC_BUFFER_SIZE) {
/* short read: No need to do magic */
(*reclev)--;
return ret;
}
#ifdef CL_THREAD_SAFE
/* this check protects against recursive deadlock */
if(SCAN_ARCHIVE && !cli_scanrar_inuse && !strncmp(magic, RAR_MAGIC_STR, strlen(RAR_MAGIC_STR))) {
if(!DISABLE_RAR && SCAN_ARCHIVE && !cli_scanrar_inuse && !strncmp(magic, RAR_MAGIC_STR, strlen(RAR_MAGIC_STR))) {
ret = cli_scanrar(desc, virname, scanned, root, limits, options, reclev);
}
#else
if(SCAN_ARCHIVE && !strncmp(magic, RAR_MAGIC_STR, strlen(RAR_MAGIC_STR))) {
if(!DISABLE_RAR && SCAN_ARCHIVE && !strncmp(magic, RAR_MAGIC_STR, strlen(RAR_MAGIC_STR))) {
ret = cli_scanrar(desc, virname, scanned, root, limits, options, reclev);
}
#endif
#ifdef HAVE_ZLIB_H
else if(SCAN_ARCHIVE && !strncmp(magic, ZIP_MAGIC_STR, strlen(ZIP_MAGIC_STR))) {
ret = cli_scanzip(desc, virname, scanned, root, limits, options, reclev);
} else if(!strncmp(magic, GZIP_MAGIC_STR, strlen(GZIP_MAGIC_STR))) {
} else if(SCAN_ARCHIVE && !strncmp(magic, GZIP_MAGIC_STR, strlen(GZIP_MAGIC_STR))) {
ret = cli_scangzip(desc, virname, scanned, root, limits, options, reclev);
}
#endif
@ -648,10 +650,10 @@ int cli_magic_scandesc(int desc, char **virname, long int *scanned, const struct
}
else if(SCAN_MAIL && !strncmp(magic, RAWMAIL_MAGIC_STR, strlen(RAWMAIL_MAGIC_STR))) {
ret = cli_scanmail(desc, virname, scanned, root, limits, options, reclev);
} else if(!strncmp(magic, MAILDIR_MAGIC_STR, strlen(MAILDIR_MAGIC_STR))) {
} else if(SCAN_MAIL && !strncmp(magic, MAILDIR_MAGIC_STR, strlen(MAILDIR_MAGIC_STR))) {
cli_dbgmsg("Recognized Maildir mail file.\n");
ret = cli_scanmail(desc, virname, scanned, root, limits, options, reclev);
} else if(!strncmp(magic, DELIVERED_MAGIC_STR, strlen(DELIVERED_MAGIC_STR))) {
} else if(SCAN_MAIL && !strncmp(magic, DELIVERED_MAGIC_STR, strlen(DELIVERED_MAGIC_STR))) {
cli_dbgmsg("Recognized (Delivered-To) mail file.\n");
ret = cli_scanmail(desc, virname, scanned, root, limits, options, reclev);
}

@ -2,7 +2,7 @@
* Author:
* Guido Draheim <guidod@gmx.de>
*
* Copyright (c) 2001 Guido Draheim
* Copyright (c) 2001,2002,2003 Guido Draheim
* All rights reserved,
* use under the restrictions of the
* Lesser GNU General Public License
@ -53,15 +53,34 @@
#define _zzip_inline inline
#endif
#endif
#ifndef _zzip_size_t
#ifdef ZZIP_size_t
#define _zzip_size_t ZZIP_size_t
#else
#define _zzip_size_t size_t
#endif
#endif
#ifndef _zzip_ssize_t
#ifdef ZZIP_ssize_t
#define _zzip_ssize_t ZZIP_ssize_t
#else
#define _zzip_ssize_t ssize_t
#endif
#endif
/* whether this library shall use a 64bit off_t largefile variant in 64on32: */
/* (some exported names must be renamed to avoid bad calls after linking) */
#if defined ZZIP_LARGEFILE_SENSITIVE && _FILE_OFFSET_BITS+0 == 64
#define ZZIP_LARGEFILE_RENAME
#elif defined _LARGE_FILES /* on AIX */
#define ZZIP_LARGEFILE_RENAME
#if defined ZZIP_LARGEFILE_SENSITIVE
# if _FILE_OFFSET_BITS+0 == 64
# define ZZIP_LARGEFILE_RENAME
# elif defined _LARGE_FILES /* used on older AIX to get at 64bit off_t */
# define ZZIP_LARGEFILE_RENAME
# elif defined _ZZIP_LARGEFILE /* or simply use this one for zzip64 runs */
# define ZZIP_LARGEFILE_RENAME
# endif
#endif
/* if some were forgotten but required to have 64bit off_t largefile.. */
/* if the environment did not setup these for 64bit off_t largefile... */
#ifdef ZZIP_LARGEFILE_RENAME
# ifndef _FILE_OFFSET_BITS
# ifdef ZZIP__FILE_OFFSET_BITS /* == 64 */
@ -70,7 +89,12 @@
# endif
# ifndef _LARGE_FILES
# ifdef ZZIP__LARGE_FILES /* == 1 */
# define _LARGE_FILES 1
# define _LARGE_FILES ZZIP__LARGE_FILES
# endif
# endif
# ifndef _LARGEFILE_SOURCE
# ifdef ZZIP__LARGEFILE_SOURCE /* == 1 */
# define _LARGEFILE_SOURCE ZZIP__LARGEFILE_SOURCE
# endif
# endif
#endif
@ -141,6 +165,11 @@
#define __attribute__(X)
#endif
#if defined ZZIP_EXPORTS || defined ZZIPLIB_EXPORTS
# undef ZZIP_DLL
#define ZZIP_DLL 1
#endif
/* based on zconf.h : */
/* compile with -DZZIP_DLL for Windows DLL support */
#if defined ZZIP_DLL

@ -1,4 +1,3 @@
#define USE_DIRENT 0
/*
* Author:
* Guido Draheim <guidod@gmx.de>
@ -24,6 +23,8 @@
#include <stdio.h>
#endif
//#include "__dirent.h"
#ifndef offsetof
#pragma warning had to DEFINE offsetof as it was not in stddef.h
#define offsetof(T,M) ((unsigned)(& ((T*)0)->M))
@ -50,11 +51,13 @@ zzip_rewinddir(ZZIP_DIR * dir)
{
if (! dir) return;
/*
if (USE_DIRENT && dir->realdir)
{
_zzip_rewinddir(dir->realdir);
return;
}
*/
if (dir->hdr0)
dir->hdr = dir->hdr0;
@ -118,11 +121,12 @@ zzip_readdir(ZZIP_DIR * dir)
{
if (! dir) { errno=EBADF; return 0; }
/*
if (USE_DIRENT && dir->realdir)
{
if (! real_readdir(dir))
return 0;
}else
}else */
{
if (! dir->hdr) return 0;
@ -147,10 +151,10 @@ zzip_telldir(ZZIP_DIR* dir)
{
if (! dir) { errno=EBADF; return -1; }
if (USE_DIRENT && dir->realdir)
/* if (USE_DIRENT && dir->realdir)
{
return _zzip_telldir(dir->realdir);
}else
}else*/
{
return ((zzip_off_t) ((char*) dir->hdr - (char*) dir->hdr0));
}
@ -164,10 +168,10 @@ zzip_seekdir(ZZIP_DIR* dir, zzip_off_t offset)
{
if (! dir) return;
if (USE_DIRENT && dir->realdir)
/*if (USE_DIRENT && dir->realdir)
{
_zzip_seekdir(dir->realdir, offset);
}else
}else*/
{
dir->hdr = (struct zzip_dir_hdr*)
(dir->hdr0 ? (char*) dir->hdr0 + (size_t) offset : 0);
@ -229,6 +233,23 @@ zzip_opendir_ext_io(zzip_char_t* filename, int o_modes,
# ifdef ZZIP_HAVE_SYS_STAT_H
if (stat(filename, &st) >= 0 && S_ISDIR(st.st_mode)
){
/* if (USE_DIRENT)
{
_zzip_DIR* realdir = _zzip_opendir(filename);
if (realdir)
{
if (! (dir = (ZZIP_DIR *)calloc(1, sizeof (*dir))))
{
_zzip_closedir(realdir);
return 0;
}else
{
dir->realdir = realdir;
dir->realname = strdup(filename);
return dir;
}
}
} */
return 0;
}
# endif /* HAVE_SYS_STAT_H */
@ -253,13 +274,13 @@ zzip_closedir(ZZIP_DIR* dir)
{
if (! dir) { errno = EBADF; return -1; }
if (USE_DIRENT && dir->realdir)
/*if (USE_DIRENT && dir->realdir)
{
_zzip_closedir(dir->realdir);
free(dir->realname);
free(dir);
return 0;
}else
}else*/
{
zzip_dir_close(dir);
return 0;

@ -81,6 +81,7 @@ zzip_strerror(int errcode)
zzip_char_t*
zzip_strerror_of(ZZIP_DIR* dir)
{
if (! dir) return strerror (errno);
return zzip_strerror(dir->errcode);
}

@ -16,14 +16,15 @@
#include "strc.h"
#include <string.h>
#include <sys/types.h> /* njh@bandsman.co.uk: for icc7.0 */
#include <string.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdlib.h>
#include <ctype.h>
#include <zzipformat.h>
//#include "__debug.h"
#if 0
# if defined ZZIP_HAVE_IO_H
@ -88,17 +89,14 @@ zzip_file_saveoffset(ZZIP_FILE * fp)
return 0;
}
# ifndef ZZIP_CHECK_BACKSLASH_DIRSEPARATOR
# define ZZIP_CHECK_BACKSLASH_DIRSEPARATOR 0
# ifndef ZZIP_CHECK_BACKSLASH_DIRSEPARATOR /* NOTE: also default */
# define ZZIP_CHECK_BACKSLASH_DIRSEPARATOR 0 /* to "NO" on win32 ! */
# endif
# if !defined strcasecmp && !defined ZZIP_HAVE_STRCASECMP
# define ZZIP_CHECK_BACKSLASH_DIRSEPARATOR 1
# endif
#if ! ZZIP_CHECK_BACKSLASH_DIRSEPARATOR+0
#define dirsep_strrchr(N,C) strrchr(N,C)
#define dirsep_casecmp strcasecmp
@ -172,6 +170,9 @@ zzip_file_open(ZZIP_DIR * dir, zzip_char_t* name, int o_mode)
if (n) hdr_name = n + 1;
}
//HINT4("name='%s', compr=%d, size=%d\n",
// hdr->d_name, hdr->d_compr, hdr->d_usize);
if (!cmp(hdr_name, name))
{
switch (hdr->d_compr)
@ -222,11 +223,11 @@ zzip_file_open(ZZIP_DIR * dir, zzip_char_t* name, int o_mode)
{ /* skip local header - should test tons of other info,
* but trust that those are correct */
int dataoff;
zzip_ssize_t dataoff;
struct zzip_file_header * p = (void*) fp->buf32k;
dataoff = dir->io->read(dir->fd, (void*)p, sizeof(*p));
if (dataoff < (int) sizeof(*p))
if (dataoff < (zzip_ssize_t)sizeof(*p))
{ err = ZZIP_DIR_READ; goto error; }
if (! ZZIP_FILE_HEADER_CHECKMAGIC(p)) /* PK\3\4 */
{ err = ZZIP_CORRUPTED; goto error; }
@ -323,12 +324,12 @@ zzip_close(ZZIP_FILE* fp)
* required just that but the latest zlib would work just fine with
* a smaller buffer.
*/
int
zzip_file_read(ZZIP_FILE * fp, char * buf, int len)
zzip_ssize_t
zzip_file_read(ZZIP_FILE * fp, char * buf, zzip_size_t len)
{
ZZIP_DIR * dir;
int l;
int rv;
zzip_size_t l;
zzip_ssize_t rv;
if (! fp || ! fp->dir) return 0;
@ -358,14 +359,15 @@ zzip_file_read(ZZIP_FILE * fp, char * buf, int len)
do {
int err;
int startlen;
zzip_size_t startlen;
if (fp->crestlen > 0 && fp->d_stream.avail_in == 0)
{
int cl = fp->crestlen > ZZIP_32K ? ZZIP_32K : fp->crestlen;
/* int cl = fp->crestlen > 128? 128: fp->crestlen; */
zzip_size_t cl = ( fp->crestlen < ZZIP_32K ?
fp->crestlen : ZZIP_32K );
/* zzip_size_t cl = fp->crestlen > 128 ? 128 : fp->crestlen; */
int i = fp->io->read(dir->fd, fp->buf32k, cl);
zzip_ssize_t i = fp->io->read(dir->fd, fp->buf32k, cl);
if (i <= 0)
{
dir->errcode = ZZIP_DIR_READ; /* or ZZIP_DIR_READ_EOF ? */
@ -412,14 +414,14 @@ zzip_file_read(ZZIP_FILE * fp, char * buf, int len)
* perform a normal => read(2)-call, otherwise => zzip_file_read is called
* to decompress the data stream and any error is mapped to => errno(3).
*/
int
zzip_read(ZZIP_FILE * fp, char * buf, int len)
zzip_ssize_t
zzip_read(ZZIP_FILE * fp, char * buf, zzip_size_t len)
{
if (! fp) return 0;
if (! fp->dir)
{ return fp->io->read(fp->fd, buf, len); } /* stat fd */
else
{ register int v;
{ register zzip_ssize_t v;
v = zzip_file_read(fp, buf, len);
if (v == -1) { errno = zzip_errno(fp->dir->errcode); }
return v;
@ -428,8 +430,8 @@ zzip_read(ZZIP_FILE * fp, char * buf, int len)
/** => zzip_read
*/
int
zzip_fread(void *ptr, int size, int nmemb, ZZIP_FILE *file)
zzip_size_t
zzip_fread(void *ptr, zzip_size_t size, zzip_size_t nmemb, ZZIP_FILE *file)
{
if (! size) size=1;
return zzip_read (file, ptr, size*nmemb)/size;
@ -714,7 +716,7 @@ zzip_open_shared_io (ZZIP_FILE* stream,
/* see if we can share the same zip directory */
if (stream && stream->dir && stream->dir->realname)
{
int len = strlen (stream->dir->realname);
zzip_size_t len = strlen (stream->dir->realname);
if (! memcmp (filename, stream->dir->realname, len) &&
filename[len] == '/' && filename[len+1])
{
@ -864,10 +866,10 @@ zzip_rewind(ZZIP_FILE *fp)
* how gzio implements it, so I'm not sure there is a better way
* without using the internals of the algorithm.
*/
int
zzip_seek(ZZIP_FILE * fp, int offset, int whence)
zzip_off_t
zzip_seek(ZZIP_FILE * fp, zzip_off_t offset, int whence)
{
int cur_pos, rel_ofs, read_size, ofs;
zzip_off_t cur_pos, rel_ofs, read_size, ofs;
ZZIP_DIR *dir;
if (! fp)
@ -875,7 +877,7 @@ zzip_seek(ZZIP_FILE * fp, int offset, int whence)
if (! fp->dir)
{ /* stat fd */
return fp->io->seeks(fp->fd,offset,whence);
return fp->io->seeks(fp->fd, offset, whence);
}
cur_pos = zzip_tell(fp);
@ -914,7 +916,7 @@ zzip_seek(ZZIP_FILE * fp, int offset, int whence)
if (read_size < 0) /* bad offset, before beginning of file */
return -1;
if (read_size + cur_pos > fp->usize) /* bad offset, past EOF */
if (read_size + cur_pos > (zzip_off_t)fp->usize) /* bad offset, past EOF */
return -1;
if (read_size == 0) /* nothing to read */
@ -953,10 +955,10 @@ zzip_seek(ZZIP_FILE * fp, int offset, int whence)
while (read_size > 0)
{
int size = ZZIP_32K;
if (read_size < ZZIP_32K) size = (int)read_size;
zzip_off_t size = ZZIP_32K;
if (read_size < size/*32K*/) size = read_size;
size = zzip_file_read(fp, buf, size);
size = zzip_file_read(fp, buf, (zzip_size_t)size);
if (size <= 0) { free(buf); return -1; }
read_size -= size;
@ -979,7 +981,7 @@ zzip_seek(ZZIP_FILE * fp, int offset, int whence)
* calculated from the amount of data left and the total uncompressed
* size;
*/
int
zzip_off_t
zzip_tell(ZZIP_FILE * fp)
{
if (! fp)

@ -65,10 +65,10 @@ struct zzip_file
struct zzip_dir* dir;
int fd;
int method;
int restlen;
int crestlen;
int usize;
int csize;
zzip_size_t restlen;
zzip_size_t crestlen;
zzip_size_t usize;
zzip_size_t csize;
/* added dataoffset member - data offset from start of zipfile*/
zzip_off_t dataoffset;
char* buf32k;

@ -27,6 +27,11 @@
//#include "__mmap.h"
//#include "__debug.h"
#define __sizeof(X) ((zzip_ssize_t)(sizeof(X)))
/* per default, we use a little hack to correct bad z_rootseek parts */
#define ZZIP_CORRECT_ROOTSEEK 1
/* ------------------------- fetch helpers --------------------------------- */
/**
@ -39,7 +44,7 @@ uint32_t __zzip_get32(unsigned char * s)
| ((uint32_t)s[1] << 8) | (uint32_t)s[0];
}
/** => __zzip_get16
/** => __zzip_get32
* This function does the same for a 16 bit value.
*/
uint16_t __zzip_get16(unsigned char * s)
@ -47,6 +52,88 @@ uint16_t __zzip_get16(unsigned char * s)
return ((uint16_t)s[1] << 8) | (uint16_t)s[0];
}
/* --------------------------- internals -------------------------------- */
/* internal functions of zziplib, avoid at all cost, changes w/o warning.
* we do export them for debugging purpose and special external tools
* which know what they do and which can adapt from version to version
*/
int __zzip_find_disk_trailer( int fd, zzip_off_t filesize,
struct zzip_disk_trailer * trailer,
zzip_plugin_io_t io);
int __zzip_parse_root_directory( int fd,
struct zzip_disk_trailer * trailer,
struct zzip_dir_hdr ** hdr_return,
zzip_plugin_io_t io);
_zzip_inline char* __zzip_aligned4(char* p);
/* ------------------------ harden routines ------------------------------ */
#ifdef ZZIP_HARDEN
/*
* check for inconsistent values in trailer and prefer lower seek value
* - we fix values assuming the root directory was written at the end
* and it is just before the zip trailer. Therefore, ...
*/
_zzip_inline static void __fixup_rootseek(
zzip_off_t offset_of_trailer,
struct zzip_disk_trailer* trailer)
{
if ( (zzip_off_t) ZZIP_GET32(trailer->z_rootseek) >
offset_of_trailer - (zzip_off_t) ZZIP_GET32(trailer->z_rootsize) &&
offset_of_trailer > (zzip_off_t) ZZIP_GET32(trailer->z_rootsize))
{
register zzip_off_t offset;
offset = offset_of_trailer - ZZIP_GET32(trailer->z_rootsize);
trailer->z_rootseek[0] = offset & 0xff;
trailer->z_rootseek[1] = offset >> 8 & 0xff;
trailer->z_rootseek[2] = offset >> 16 & 0xff;
trailer->z_rootseek[3] = offset >> 24 & 0xff;
//HINT2("new rootseek=%li",
// (long) ZZIP_GET32(trailer->z_rootseek));
}
}
#define __correct_rootseek(A,B,C)
#elif defined ZZIP_CORRECT_ROOTSEEK
/* store the seekvalue of the trailer into the "z_magic" field and with
* a 64bit off_t we overwrite z_disk/z_finaldisk as well. If you change
* anything in zziplib or dump the trailer structure then watch out that
* these are still unused, so that this code may still (ab)use those. */
#define __fixup_rootseek(_offset_of_trailer, _trailer) \
*(zzip_off_t*)_trailer = _offset_of_trailer;
#define __correct_rootseek( _u_rootseek, _u_rootsize, _trailer) \
if (_u_rootseek > *(zzip_off_t*)_trailer - _u_rootsize) \
_u_rootseek = *(zzip_off_t*)_trailer - _u_rootsize;
#else
#define __fixup_rootseek(A,B)
#define __correct_rootseek(A,B,C)
#endif
#ifdef DEBUG
_zzip_inline static void __debug_dir_hdr (struct zzip_dir_hdr* hdr)
{
if (sizeof(struct zzip_dir_hdr) > sizeof(struct zzip_root_dirent))
{ WARN1("internal sizeof-mismatch may break wreakage"); }
/* the internal directory structure is never bigger than the
* external zip central directory space had been beforehand
* (as long as the following assertion holds...)
*/
//if (((unsigned)hdr)&3)
//{ NOTE1("this machine's malloc(3) returns sth. not u32-aligned"); }
/* we assume that if this machine's malloc has returned a non-aligned
* memory block, then it is actually safe to access misaligned data, and
* since it does only affect the first hdr it should not even bring about
* too much of that cpu's speed penalty
*/
}
#else
#define __debug_dir_hdr(X)
#endif
/* -------------------------- low-level interface -------------------------- */
#if defined BUFSIZ
@ -70,11 +157,13 @@ __zzip_find_disk_trailer(int fd, zzip_off_t filesize,
struct zzip_disk_trailer * trailer,
zzip_plugin_io_t io)
{
/*
#ifdef DEBUG
#define return(val) { e=val; goto cleanup; }
#define return(val) { e=val; HINT2("%s", zzip_strerror(e)); goto cleanup; }
#else
*/
#define return(val) { e=val; goto cleanup; }
#endif
//#endif
register int e;
#ifndef _LOWSTK
@ -84,13 +173,13 @@ __zzip_find_disk_trailer(int fd, zzip_off_t filesize,
char* buf = malloc(2*ZZIP_BUFSIZ);
#endif
zzip_off_t offset = 0;
size_t maplen = 0;
zzip_off_t maplen = 0; /* mmap(),read(),getpagesize() use size_t !! */
char* fd_map = 0;
if (!trailer)
{ return(EINVAL); }
if (filesize < sizeof(struct zzip_disk_trailer))
if (filesize < __sizeof(struct zzip_disk_trailer))
{ return(ZZIP_DIR_TOO_SHORT); }
if (!buf)
@ -99,8 +188,7 @@ __zzip_find_disk_trailer(int fd, zzip_off_t filesize,
offset = filesize; /* a.k.a. old offset */
while(1) /* outer loop */
{
register unsigned char* p;
register unsigned char* s;
register unsigned char* mapped;
if (offset <= 0) { return(ZZIP_DIR_EDH_MISSING); }
@ -108,6 +196,34 @@ __zzip_find_disk_trailer(int fd, zzip_off_t filesize,
if (filesize-offset > 64*1024)
{ return(ZZIP_DIR_EDH_MISSING); }
/* the new offset shall overlap with the area after the old offset! */
/*if (USE_MMAP && io->use_mmap)
{
zzip_off_t mapoff = offset;
{
zzip_off_t pagesize = _zzip_getpagesize (io->use_mmap);
if (pagesize < ZZIP_BUFSIZ) goto non_mmap;
if (mapoff == filesize && filesize > pagesize)
mapoff -= pagesize;
if (mapoff < pagesize) {
maplen = mapoff + pagesize; mapoff = 0;
} else {
mapoff -= pagesize; maplen = 2*pagesize;
if (mapoff & (pagesize-1)) {
pagesize -= mapoff & (pagesize-1);
mapoff += pagesize;
maplen -= pagesize;
}
}
if (mapoff + maplen > filesize) maplen = filesize - mapoff;
}
fd_map = _zzip_mmap(io->use_mmap, fd, mapoff, (zzip_size_t)maplen);
if (fd_map == MAP_FAILED) goto non_mmap;
mapped = fd_map; offset = mapoff;
HINT3("mapped *%p len=%li", fd_map, (long) maplen);
} else */ {
non_mmap:
fd_map = 0; /* have no mmap */
{
zzip_off_t pagesize = ZZIP_BUFSIZ;
@ -128,35 +244,52 @@ __zzip_find_disk_trailer(int fd, zzip_off_t filesize,
if (io->seeks(fd, offset, SEEK_SET) < 0)
{ return(ZZIP_DIR_SEEK); }
if (io->read(fd, buf, maplen) < (long)maplen)
if (io->read(fd, buf, (zzip_size_t)maplen) < (zzip_ssize_t)maplen)
{ return(ZZIP_DIR_READ); }
p = buf; /* success */
mapped = buf; /* success */
//HINT5("offs=$%lx len=%li filesize=%li pagesize=%i",
//(long)offset, (long)maplen, (long)filesize, ZZIP_BUFSIZ);
}
/* now, check for the trailer-magic, hopefully near the end of file */
for (s = p + maplen-1; (s >= p); s--)
{
if (*s == 'P'
&& p+maplen-1-s > sizeof(*trailer)-2
&& ZZIP_DISK_TRAILER_CHECKMAGIC(s))
{
/* if the file-comment is not present, it happens
that the z_comment field often isn't either */
if (p+maplen-1-s > sizeof(*trailer))
{ memcpy (trailer, s, sizeof(*trailer)); }
else
{
memcpy (trailer, s, sizeof(*trailer)-2);
trailer->z_comment[0] = 0; trailer->z_comment[1] = 0;
}
{ return(0); }
}
{/* now, check for the trailer-magic, hopefully near the end of file */
register unsigned char* end = mapped + maplen;
register unsigned char* tail;
for (tail = end-1; (tail >= mapped); tail--)
{
if ((*tail == 'P') && /* quick pre-check for trailer magic */
end-tail >= __sizeof(*trailer)-2 &&
ZZIP_DISK_TRAILER_CHECKMAGIC(tail))
{
/* if the file-comment is not present, it happens
that the z_comment field often isn't either */
if (end-tail >= __sizeof(*trailer))
{
memcpy (trailer, tail, sizeof(*trailer));
}else{
memcpy (trailer, tail, sizeof(*trailer)-2);
trailer->z_comment[0] = 0;
trailer->z_comment[1] = 0;
}
__fixup_rootseek (offset + tail-mapped, trailer);
{ return(0); }
}
}
}
/*if (USE_MMAP && fd_map)
{
HINT3("unmap *%p len=%li", fd_map, (long) maplen);
_zzip_munmap(io->use_mmap, fd_map, (zzip_size_t)maplen); fd_map = 0;
}*/
} /*outer loop*/
cleanup:
/*if (USE_MMAP && fd_map)
{
HINT3("unmap *%p len=%li", fd_map, (long) maplen);
_zzip_munmap(io->use_mmap, fd_map, (zzip_size_t)maplen);
}*/
# ifdef _LOWSTK
free(buf);
# endif
@ -174,8 +307,8 @@ __zzip_find_disk_trailer(int fd, zzip_off_t filesize,
_zzip_inline char* __zzip_aligned4(char* p)
{
#define aligned4 __zzip_aligned4
p += ((long)p)&1;
p += ((long)p)&2;
p += ((long)p)&1; /* warnings about truncation of a "pointer" */
p += ((long)p)&2; /* to a "long int" may be safely ignored :) */
return p;
}
@ -196,34 +329,33 @@ __zzip_parse_root_directory(int fd,
struct zzip_dir_hdr * hdr0;
uint16_t * p_reclen = 0;
short entries;
long offset;
char* fd_map = 0;
long offset; /* offset from start of root directory */
char* fd_map = 0;
int32_t fd_gap = 0;
uint16_t u_entries = ZZIP_GET16(trailer->z_entries);
uint32_t u_rootsize = ZZIP_GET32(trailer->z_rootsize);
uint32_t u_rootseek = ZZIP_GET32(trailer->z_rootseek);
__correct_rootseek (u_rootseek, u_rootsize, trailer);
hdr0 = (struct zzip_dir_hdr*) malloc(u_rootsize);
if (!hdr0)
return ZZIP_DIRSIZE;
hdr = hdr0;
hdr = hdr0; __debug_dir_hdr (hdr);
# ifdef DEBUG
if (sizeof(struct zzip_dir_hdr) > sizeof(struct zzip_root_dirent))
{ WARN1("internal sizeof-mismatch may break wreakage"); }
/* the internal directory structure is never bigger than the
* external zip central directory space had been beforehand
* (as long as the following assertion holds...)
*/
if (((unsigned)hdr0)&3)
{ NOTE1("this machine's malloc(3) returns sth. not u32-aligned"); }
/* we assume that if this machine's malloc has returned a non-aligned
* memory block, then it is actually safe to access misaligned data, and
* since it does only affect the first hdr it should not even bring about
* too much of that cpu's speed penalty
*/
# endif
/*if (USE_MMAP && io->use_mmap)
{
fd_gap = u_rootseek & (_zzip_getpagesize(io->use_mmap)-1) ;
HINT4(" mapseek=0x%x, maplen=%d, fd_gap=%d",
u_rootseek-fd_gap, u_rootsize+fd_gap, fd_gap);
fd_map = _zzip_mmap(io->use_mmap,
fd, u_rootseek-fd_gap, u_rootsize+fd_gap);
if (fd_map == MAP_FAILED) {
NOTE2("map failed: %s",strerror(errno));
fd_map=0;
}else{
HINT3("mapped *%p len=%i", fd_map, u_rootsize+fd_gap);
}
}*/
for (entries=u_entries, offset=0; entries > 0; entries--)
{
@ -236,11 +368,14 @@ __zzip_parse_root_directory(int fd,
{
if (io->seeks(fd, u_rootseek+offset, SEEK_SET) < 0)
return ZZIP_DIR_SEEK;
if (io->read(fd, &dirent, sizeof(dirent)) < sizeof(dirent))
if (io->read(fd, &dirent, sizeof(dirent)) < __sizeof(dirent))
return ZZIP_DIR_READ;
d = &dirent;
}
if (offset+sizeof(*d) > u_rootsize)
{ /*FAIL2("%i's entry stretches beyond root directory", entries);*/ break;}
# if 0 && defined DEBUG
zzip_debug_xbuf ((unsigned char*) d, sizeof(*d) + 8);
# endif
@ -248,8 +383,9 @@ __zzip_parse_root_directory(int fd,
u_extras = ZZIP_GET16(d->z_extras);
u_comment = ZZIP_GET16(d->z_comment);
u_namlen = ZZIP_GET16(d->z_namlen);
//HINT5("offset=0x%lx, size %ld, dirent *%p, hdr %p\n",
// offset+u_rootseek, (long)u_rootsize, d, hdr);
/* writes over the read buffer, Since the structure where data is
copied is smaller than the data in buffer this can be done.
It is important that the order of setting the fields is considered
@ -264,10 +400,12 @@ __zzip_parse_root_directory(int fd,
hdr->d_compr = (uint8_t)ZZIP_GET16(d->z_compr);
if (hdr->d_compr > 255) hdr->d_compr = 255;
if (fd_map)
{ memcpy(hdr->d_name, fd_map+fd_gap+offset+sizeof(*d), u_namlen); }
else
{ io->read(fd, hdr->d_name, u_namlen); }
if (offset+sizeof(*d) + u_namlen > u_rootsize)
{ /*FAIL2("%i's name stretches beyond root directory", entries);*/ break;}
if (fd_map)
{ memcpy(hdr->d_name, fd_map+fd_gap+offset+sizeof(*d), u_namlen); }
else { io->read(fd, hdr->d_name, u_namlen); }
hdr->d_name[u_namlen] = '\0';
hdr->d_namlen = u_namlen;
@ -275,26 +413,38 @@ __zzip_parse_root_directory(int fd,
offset += sizeof(*d) + u_namlen + u_extras + u_comment;
if (offset > (long)u_rootsize)
break;
{ /*FAIL2("%i's end beyond root directory", entries);*/ entries--; break;}
//HINT5("file %d { compr=%d crc32=$%x offset=%d",
// entries, hdr->d_compr, hdr->d_crc32, hdr->d_off);
//HINT5("csize=%d usize=%d namlen=%d extras=%d",
// hdr->d_csize, hdr->d_usize, u_namlen, u_extras);
//HINT5("comment=%d name='%s' %s <sizeof %d> } ",
// u_comment, hdr->d_name, "",(int) sizeof(*d));
p_reclen = &hdr->d_reclen;
{ register char* p = (char*) hdr;
register char* q = aligned4 (p + sizeof(*hdr) + u_namlen + 1);
*p_reclen = q - p;
*p_reclen = (uint16_t)(q - p);
hdr = (struct zzip_dir_hdr*) q;
}
}/*for*/
if (!p_reclen)
return 0; /* 0 (sane) entries in zip directory... */
*p_reclen = 0; /* mark end of list */
/*if (USE_MMAP && fd_map)
{
HINT3("unmap *%p len=%i", fd_map, u_rootsize+fd_gap);
_zzip_munmap(io->use_mmap, fd_map, u_rootsize+fd_gap);
}*/
if (hdr_return)
*hdr_return = hdr0;
if (p_reclen)
{
*p_reclen = 0; /* mark end of list */
return 0;
if (hdr_return)
*hdr_return = hdr0;
} /* else zero (sane) entries */
return (entries ? ZZIP_CORRUPTED : 0);
}
/* ------------------------- high-level interface ------------------------- */
@ -444,13 +594,18 @@ __zzip_dir_parse (ZZIP_DIR* dir)
* { rv = EINVAL; goto error; }
*/
//HINT2("------------------ fd=%i", (int) dir->fd);
if ((filesize = dir->io->filesize(dir->fd)) < 0)
{ rv = ZZIP_DIR_STAT; goto error; }
//HINT2("------------------ filesize=%ld", (long) filesize);
if ((rv = __zzip_find_disk_trailer(dir->fd, filesize, &trailer,
dir->io)) != 0)
{ goto error; }
//HINT5("directory = { entries= %d/%d, size= %d, seek= %d } ",
// ZZIP_GET16(trailer.z_entries), ZZIP_GET16(trailer.z_finalentries),
// ZZIP_GET32(trailer.z_rootsize), ZZIP_GET32(trailer.z_rootseek));
if ( (rv = __zzip_parse_root_directory(dir->fd, &trailer, &dir->hdr0,
dir->io)) != 0)
@ -470,7 +625,7 @@ __zzip_try_open(zzip_char_t* filename, int filemode,
{
auto char file[PATH_MAX];
int fd;
int len = strlen (filename);
zzip_size_t len = strlen (filename);
if (len+4 >= PATH_MAX) return -1;
memcpy(file, filename, len+1);

@ -75,6 +75,9 @@ ZZIP_DIR*
zzip_dir_fdopen_ext_io(int fd, zzip_error_t * errorcode_p,
zzip_strings_t* ext, const zzip_plugin_io_t io);
ZZIP_DIR* /*depracated*/
zzip_dir_alloc_ext_io (zzip_strings_t* ext, const zzip_plugin_io_t io);
/* get 16/32 bits from little-endian zip-file to host byteorder */
uint32_t __zzip_get32(unsigned char * s);
uint16_t __zzip_get16(unsigned char * s);

@ -3,12 +3,17 @@
* Guido Draheim <guidod@gmx.de>
* Tomi Ollila <Tomi.Ollila@iki.fi>
*
* Copyright (c) 1999,2000,2001,2002 Guido Draheim
* Copyright (c) 1999,2000,2001,2002,2003 Guido Draheim
* All rights reserved,
* usage allowed under the restrictions of the
* Lesser GNU General Public License
* note the additional license information
* that can be found in COPYING.ZZIP
*
* if you see "unknown symbol" errors, check first that `-I ..` is part of
* your compiler options - a special hint to VC/IDE users who tend to make up
* their own workspace files. All includes look like #include <zzip|*.h>, so
* you need to add an include path to the dir containing (!!) the ./zzip/ dir
*/
#ifndef _ZZIP_ZZIP_H /* zziplib.h */
@ -17,6 +22,8 @@
#include <zzip-conf.h>
#include <fcntl.h>
#include <stddef.h> /* size_t and friends */
/* msvc6 has neither ssize_t (we assume "int") nor off_t (assume "long") */
#ifdef __cplusplus
extern "C" {
@ -72,6 +79,8 @@ typedef enum
typedef char _zzip_const * _zzip_const zzip_strings_t;
typedef char _zzip_const zzip_char_t;
typedef _zzip_off_t zzip_off_t;
typedef _zzip_size_t zzip_size_t;
typedef _zzip_ssize_t zzip_ssize_t;
typedef struct zzip_dir ZZIP_DIR;
typedef struct zzip_file ZZIP_FILE;
typedef struct zzip_dirent ZZIP_DIRENT;
@ -87,7 +96,7 @@ struct zzip_dirent
/*
* Getting error strings
* zzip-err.c
* zzip/err.c
*/
_zzip_export /* error in _opendir : */
zzip_char_t* zzip_strerror(int errcode);
@ -100,7 +109,7 @@ int zzip_errno(int errcode);
/*
* Functions to grab information from ZZIP_DIR/ZZIP_FILE structure
* (if ever needed)
* zzip-info.c
* zzip/info.c
*/
_zzip_export
int zzip_error(ZZIP_DIR * dir);
@ -124,7 +133,7 @@ int zzip_realfd(ZZIP_FILE * fp);
/*
* zip handle management
* zzip-zip.c
* zzip/zip.c
*/
_zzip_export
ZZIP_DIR * zzip_dir_alloc(zzip_strings_t* fileext);
@ -147,8 +156,8 @@ int zzip_dir_read(ZZIP_DIR * dir, ZZIP_DIRENT * dirent);
/*
* Scanning files in zip archive
* zzip-dir.c
* zzip-zip.c
* zzip/dir.c
* zzip/zip.c
*/
_zzip_export
ZZIP_DIR * zzip_opendir(zzip_char_t* filename);
@ -165,30 +174,33 @@ void zzip_seekdir(ZZIP_DIR * dir, zzip_off_t offset);
/*
* 'opening', 'closing' and reading invidual files in zip archive.
* zzip-file.c
* zzip/file.c
*/
_zzip_export
ZZIP_FILE * zzip_file_open(ZZIP_DIR * dir, zzip_char_t* name, int modes);
_zzip_export
int zzip_file_close(ZZIP_FILE * fp);
_zzip_export
int zzip_file_read(ZZIP_FILE * fp, char* buf, int len);
zzip_ssize_t zzip_file_read(ZZIP_FILE * fp, char* buf, zzip_size_t len);
_zzip_export
ZZIP_FILE * zzip_open(zzip_char_t* name, int flags);
_zzip_export
int zzip_close(ZZIP_FILE * fp);
_zzip_export
int zzip_read(ZZIP_FILE * fp, char * buf, int len);
zzip_ssize_t zzip_read(ZZIP_FILE * fp, char * buf, zzip_size_t len);
/*
* the stdc variant to open/read/close files. - Take note of the freopen()
* call as it may reuse an existing preparsed copy of a zip central directory
*/
_zzip_export
ZZIP_FILE* zzip_freopen(zzip_char_t* name, zzip_char_t* mode, ZZIP_FILE*);
_zzip_export
ZZIP_FILE* zzip_fopen(zzip_char_t* name, zzip_char_t* mode);
_zzip_export
int zzip_fread(void *ptr, int size, int nmemb, ZZIP_FILE *file);
zzip_size_t zzip_fread(void *ptr, zzip_size_t size, zzip_size_t nmemb,
ZZIP_FILE * file);
_zzip_export
int zzip_fclose(ZZIP_FILE * fp);
@ -198,21 +210,18 @@ int zzip_fclose(ZZIP_FILE * fp);
_zzip_export
int zzip_rewind(ZZIP_FILE *fp);
_zzip_export
int zzip_seek(ZZIP_FILE * fp, int offset, int
whence);
zzip_off_t zzip_seek(ZZIP_FILE * fp, zzip_off_t offset, int whence);
_zzip_export
int zzip_tell(ZZIP_FILE * fp);
zzip_off_t zzip_tell(ZZIP_FILE * fp);
/*
* reading info of a single file
* zzip-stat.c
* zzip/stat.c
*/
_zzip_export
int zzip_dir_stat(ZZIP_DIR * dir, zzip_char_t* name,
ZZIP_STAT * zs, int flags);
#ifdef ZZIP_LARGEFILE_RENAME
#define zzip_open_shared_io zzip_open_shared_io64
#define zzip_open_ext_io zzip_open_ext_io64
@ -246,13 +255,73 @@ ZZIP_FILE * zzip_file_open_ext_io(ZZIP_DIR * dir,
zzip_strings_t* ext, zzip_plugin_io_t io);
_zzip_export
ZZIP_DIR * zzip_dir_open_ext_io(zzip_char_t* filename,
ZZIP_DIR * zzip_dir_open_ext_io(zzip_char_t* filename,
zzip_error_t* errcode_p,
zzip_strings_t* ext, zzip_plugin_io_t io);
#if defined _ZZIP_WRITE_SOURCE
/* ........................................................................
* write support is not yet implemented
* zzip/write.c
*/
#define ZZIP_NO_CREAT 1
ZZIP_DIR* zzip_dir_creat_ext_io(zzip_char_t* name, int o_mode,
zzip_strings_t* ext, zzip_plugin_io_t io);
ZZIP_DIR* zzip_dir_creat(zzip_char_t* name, int o_mode);
int zzip_file_mkdir(ZZIP_DIR* dir, zzip_char_t* name, int o_mode);
ZZIP_FILE* zzip_file_creat(ZZIP_DIR* dir, zzip_char_t* name, int o_mode);
zzip_ssize_t zzip_file_write(ZZIP_FILE* file,
const void* ptr, zzip_size_t len);
ZZIP_DIR* zzip_createdir(zzip_char_t* name, int o_mode);
zzip_ssize_t zzip_write(ZZIP_FILE* file, const void* ptr, zzip_size_t len);
zzip_size_t zzip_fwrite(const void* ptr, zzip_size_t len,
zzip_size_t multiply, ZZIP_FILE* file);
#ifndef zzip_savefile
#define zzip_savefile 0
#define zzip_savefile_is_null
#endif
#ifdef _ZZIP_NO_INLINE
#define zzip_mkdir(_name_,_mode_) \
zzip_file_mkdir((zzip_savefile),(_name_),(_mode_))
#define zzip_creat(_name_,_mode_) \
zzip_file_creat((zzip_savefile),(_name_),(_mode_))
#define zzip_sync() \
{ zzip_closedir((zzip_savefile)); (zzip_savefile) = 0; }
#define zzip_start(_name_,_mode_,_ext_) \
{ if ((zzip_savefile)) zzip_closedir((zzip_savefile));
zzip_savefile = zzip_dir_creat(_name_, _mode_,_ext_); }
#else
_zzip_inline static int zzip_mkdir(zzip_char_t* name, int o_mode)
{ return zzip_file_mkdir(zzip_savefile, name, o_mode); }
_zzip_inline static ZZIP_FILE* zzip_creat(zzip_char_t* name, int o_mode)
{ return zzip_file_creat(zzip_savefile, name, o_mode); }
#ifndef zzip_savefile_is_null
_zzip_inline static void zzip_sync(void)
{ zzip_closedir(zzip_savefile); zzip_savefile = 0; }
_zzip_inline static void zzip_mkfifo(zzip_char_t* name, int o_mode)
{ if ((zzip_savefile)) zzip_closedir (zzip_savefile);
zzip_savefile = zzip_createdir(_name_,_mode_); }
#else
_zzip_inline static void zzip_sync(void) {}
_zzip_inline static void zzip_mkfifo(zzip_char_t* name, int o_mode) {}
#endif
#endif /* _ZZIP_NO_INLINE */
#endif /* _ZZIP_WRITE_SOURCE */
#ifdef __cplusplus
};
#endif
#endif /* _ZZIPLIB_H */
/*
* Local variables:
* c-file-style: "stroustrup"
* End:
*/

@ -34,7 +34,7 @@ int main(int argc, char **argv)
int ret, opt_index, i, len;
struct optstruct *opt;
const char *getopt_parameters = "hvVc:s:f:";
const char *getopt_parameters = "hvVc:s:f:b:i:";
static struct option long_options[] = {
{"help", 0, 0, 'h'},
@ -47,6 +47,8 @@ int main(int argc, char **argv)
{"command", 1, 0, 'c'},
{"string", 1, 0, 's'},
{"file", 1, 0, 'f'},
{"build", 1, 0, 'b'},
{"info", 1, 0, 'i'},
{0, 0, 0, 0}
};

@ -24,6 +24,9 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <zlib.h>
#include <time.h>
#include <locale.h>
#include <clamav.h>
#include "options.h"
@ -73,7 +76,7 @@ char *cut(const char *file, long int start, long int end)
exit(13);
}
fname = gentemp(".");
fname = cl_gentemp(".");
if((wd = fopen(fname, "wb")) == NULL) {
mprintf("!Can't create temporary file %s\n", fname);
exit(14);
@ -102,7 +105,7 @@ char *cut(const char *file, long int start, long int end)
char *change(const char *file, long int x)
{
char *fname, buffer[BUFFSIZE];
char *fname, buffer[FBUFFSIZE];
int bytes, size, sum, ch;
FILE *rd, *wd;
@ -112,13 +115,13 @@ char *change(const char *file, long int x)
exit(13);
}
fname = gentemp(".");
fname = cl_gentemp(".");
if((wd = fopen(fname, "wb+")) == NULL) {
mprintf("!Can't create temporary file %s\n", fname);
exit(14);
}
while((bytes = fread(buffer, 1, BUFFSIZE, rd)) > 0)
while((bytes = fread(buffer, 1, FBUFFSIZE, rd)) > 0)
fwrite(buffer, 1, bytes, wd);
fclose(rd);
@ -134,7 +137,7 @@ char *change(const char *file, long int x)
void sigtool(struct optstruct *opt)
{
char buffer[BUFFSIZE];
char buffer[FBUFFSIZE];
int bytes;
char *pt;
@ -158,12 +161,20 @@ void sigtool(struct optstruct *opt)
if(optl(opt, "hex-dump")) {
while((bytes = read(0, buffer, BUFFSIZE)) > 0) {
while((bytes = read(0, buffer, FBUFFSIZE)) > 0) {
pt = cl_str2hex(buffer, bytes);
write(1, pt, 2 * bytes);
free(pt);
}
} else if(optc(opt, 'b')) {
build(opt);
} else if(optc(opt, 'i')) {
cvdinfo(opt);
} else {
int jmp, lastjmp, start, end, found = 0, exec = 0, pos, filesize;
char *c, *s, *f, *tmp, *signame, *bsigname, *f2;
@ -330,7 +341,7 @@ void sigtool(struct optstruct *opt)
if(fileinfo(signame, 1) != -1) {
mprintf("File %s exists.\n", signame);
free(signame);
signame = gentemp(".");
signame = cl_gentemp(".");
}
bsigname = (char *) mcalloc(strlen(f) + 10, sizeof(char));
@ -338,7 +349,7 @@ void sigtool(struct optstruct *opt)
if(fileinfo(bsigname, 1) != -1) {
mprintf("File %s exists.\n", bsigname);
free(bsigname);
bsigname = gentemp(".");
bsigname = cl_gentemp(".");
}
if((wd = fopen(signame, "wb")) == NULL) {
@ -350,7 +361,7 @@ void sigtool(struct optstruct *opt)
mprintf("Saving signature in %s file.\n", signame);
while((bytes = fread(buffer, 1, BUFFSIZE, fd)) > 0) {
while((bytes = fread(buffer, 1, FBUFFSIZE, fd)) > 0) {
pt = cl_str2hex(buffer, bytes);
fwrite(pt, 1, 2 * bytes, wd);
free(pt);
@ -369,6 +380,204 @@ void sigtool(struct optstruct *opt)
//free_opt(opt);
}
int build(struct optstruct *opt)
{
int ret, no = 0, bytes, itmp;
struct stat foo;
char buffer[BUFFSIZE], *tarfile = NULL, *gzfile = NULL, header[257],
smbuff[25], *pt;
struct cl_node *root = NULL;
FILE *tar, *cvd;
gzFile *gz;
time_t timet;
struct tm *brokent;
/* build a tar.gz archive
* we need: COPYING, viruses.db / viruses.db2
* in current working directory
*/
if(stat("COPYING", &foo) == -1) {
mprintf("COPYING file not found in current working directory.\n");
exit(1);
}
if(stat("viruses.db", &foo) == -1 || stat("viruses.db2", &foo) == -1) {
mprintf("Virus database not found in current working directory.\n");
exit(1);
}
cl_debug(); /* enable debug messages */
if((ret = cl_loaddbdir(cl_retdbdir(), &root, &no))) {
mprintf("!Can't load database: %s\n", cl_strerror(ret));
exit(1);
}
cl_freetrie(root);
mprintf("Database properly parsed.\n");
if(!no)
mprintf("WARNING: There are no signatures in the database(s).\n");
else
mprintf("Signatures: %d\n", no);
tarfile = cl_gentemp(".");
switch(fork()) {
case -1:
mprintf("!Can't fork.\n");
exit(1);
case 0:
{
char *args[] = { "tar", "-cvf", tarfile, "COPYING", "viruses.db", "viruses.db2", NULL };
execv("/bin/tar", args);
mprintf("!Can't execute tar\n");
perror("tar");
exit(1);
}
default:
wait(NULL);
}
if(stat(tarfile, &foo) == -1) {
mprintf("!Can't generate tar file.\n");
exit(1);
}
if((tar = fopen(tarfile, "rb")) == NULL) {
mprintf("!Can't open file %s\n", tarfile);
exit(1);
}
gzfile = cl_gentemp(".");
if((gz = gzopen(gzfile, "wb")) == NULL) {
mprintf("!Can't open file %s to write.\n", gzfile);
exit(1);
}
while((bytes = fread(buffer, 1, BUFFSIZE, tar)) > 0)
gzwrite(gz, buffer, bytes);
fclose(tar);
unlink(tarfile);
free(tarfile);
gzclose(gz);
/* generate header */
/* magic string */
strcpy(header, "ClamAV-VDB:");
/* time */
time(&timet);
brokent = localtime(&timet);
setlocale(LC_TIME, "C");
strftime(smbuff, 24, "%b-%d %H-%M %Z:", brokent);
strcat(header, smbuff);
/* version number */
// tutaj ma przeczytac naglowek z obecnej bazy o tej samej nazwie
// i uzyc o jeden wiekszy
mprintf("!Can't read database version number from current local database\n");
fflush(stdin);
mprintf("Please enter a version number for the new database: ");
scanf("%d", &itmp);
sprintf(smbuff, "%d:", itmp);
strcat(header, smbuff);
/* number of signatures */
sprintf(smbuff, "%d:", no);
strcat(header, smbuff);
/* functionality level */
// pobierac z cl_funclevel()
sprintf(smbuff, "%d:", 1);
strcat(header, smbuff);
/* MD5 */
pt = cl_md5file(gzfile);
strcat(header, pt);
strcat(header, ":");
/* digital signature */
strcat(header, ":");
/* builder */
fflush(stdin);
mprintf("Builder name: ");
//fgets(smbuff, 24, stdin);
fscanf(stdin, "%s:", &smbuff);
strcat(header, smbuff);
//strcat(header, ":");
/* fill up with spaces */
if(strlen(header) > 256) {
mprintf("!Generated signature is too long.\n");
exit(1);
}
while(strlen(header) < 256)
strcat(header, " ");
/* build the final database */
pt = getargc(opt, 'b');
if((cvd = fopen(pt, "wb")) == NULL) {
mprintf("!Can't write the final database %s\n", pt);
exit(1);
}
fwrite(header, 1, 256, cvd);
if((tar = fopen(gzfile, "rb")) == NULL) {
mprintf("!Can't open file %s for reading.\n", gzfile);
exit(1);
}
while((bytes = fread(buffer, 1, BUFFSIZE, tar)) > 0)
fwrite(buffer, 1, bytes, cvd);
fclose(tar);
fclose(cvd);
unlink(gzfile);
free(gzfile);
mprintf("Database %s created.\n", pt);
// teraz zaladuj baze
}
void cvdinfo(struct optstruct *opt)
{
struct cl_cvd *cvd;
char *pt;
if((cvd = cl_cvdhead(getargc(opt, 'i'))) == NULL) {
mprintf("!Can't read CVD header from %s\n", getargc(opt, 'i'));
exit(1);
}
mprintf("Creation time: %s\n", cvd->time);
mprintf("Version: %d\n", cvd->version);
mprintf("# of signatures: %d\n", cvd->sigs);
mprintf("Functionality level: %d\n", cvd->fl);
mprintf("Builder: %s\n", cvd->builder);
mprintf("MD5: %s\n", cvd->md5);
// pt = cl_md5file( DODAC WERYFIKACJE
mprintf("Digital signature: %s\n", cvd->dsig);
// wyczysc cvd
}
void help(void)
{
mprintf("\n");
@ -384,7 +593,9 @@ void help(void)
mprintf(" string and send it to stdout\n");
mprintf(" --command -c scanner command string, with options\n");
mprintf(" --string -s 'virus found' string in scan. output\n");
mprintf(" --file -f infected file\n\n");
mprintf(" --file -f infected file\n");
mprintf("\n DATABASE DEVELOPING:\n\n");
mprintf(" --build NAME -b NAME Build database\n");
exit(0);
}

Loading…
Cancel
Save