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. 283
      clamav-devel/libclamav/zziplib/zzip-zip.c
  24. 3
      clamav-devel/libclamav/zziplib/zzip.h
  25. 105
      clamav-devel/libclamav/zziplib/zziplib.h
  26. 4
      clamav-devel/sigtool/options.c
  27. 231
      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 */
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;
}
/* 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); }
}
__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;
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;
# 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...)
*/
hdr = hdr0; __debug_dir_hdr (hdr);
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,7 +383,8 @@ __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.
@ -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
@ -250,9 +259,69 @@ 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