| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 
 | /*
 *  A minimalistic tar archiver for sigtool and freshclam.
 *  Copyright (C) 2015 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
 *  Copyright (C) 2007 Sourcefire, Inc.
 *  Author: Tomasz Kojm <tkojm@clamav.net>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  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., 51 Franklin Street, Fifth Floor, Boston,
 *  MA 02110-1301, USA.
 */
#if HAVE_CONFIG_H
#include "clamav-config.h"
#endif
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#ifdef  HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <zlib.h>
#include "libclamav/clamav.h"
#include "tar.h"
struct tar_header {
    char name[100];	/* File name */
    char mode[8];	/* File mode */
    char uid[8];	/* UID */
    char gid[8];	/* GID */
    char size[12];	/* File size (octal) */
    char mtime[12];	/* Last modification */
    char chksum[8];	/* Header checksum */
    char type[1];	/* File type */
    char lname[100];	/* Linked file name */
    char pad[255];
};
#define TARBLK 512
int tar_addfile(int fd, gzFile gzs, const char *file)
{
	int s, bytes;
	struct tar_header hdr;
	STATBUF sb;
	unsigned char buff[FILEBUFF], *pt;
	unsigned int i, chksum = 0;
    if((s = open(file, O_RDONLY|O_BINARY)) == -1)
	return -1;
    if(FSTAT(s, &sb) == -1) {
	close(s);
	return -1;
    }
    memset(&hdr, 0, TARBLK);
    strncpy(hdr.name, file, 100);
    hdr.name[99]='\0';
    snprintf(hdr.size, 12, "%o", (unsigned int) sb.st_size);
    pt = (unsigned char *) &hdr;
    for(i = 0; i < TARBLK; i++)
	chksum += *pt++;
    snprintf(hdr.chksum, 8, "%06o", chksum + 256);
    if(gzs) {
	if(!gzwrite(gzs, &hdr, TARBLK)) {
	    close(s);
	    return -1;
	}
    } else {
	if(write(fd, &hdr, TARBLK) != TARBLK) {
	    close(s);
	    return -1;
	}
    }
    while((bytes = read(s, buff, FILEBUFF)) > 0) {
	if(gzs) {
	    if(!gzwrite(gzs, buff, bytes)) {
		close(s);
		return -1;
	    }
	} else {
	    if(write(fd, buff, bytes) != bytes) {
		close(s);
		return -1;
	    }
	}
    }
    close(s);
    if(sb.st_size % TARBLK) {
	memset(&hdr, 0, TARBLK);
	if(gzs) {
	    if(!gzwrite(gzs, &hdr, TARBLK - (sb.st_size % TARBLK)))
		return -1;
	} else {
	    if(write(fd, &hdr, TARBLK - (sb.st_size % TARBLK)) == -1)
		return -1;
	}
    }
    return 0;
}
 |