summaryrefslogtreecommitdiff
path: root/bin/gzip/zip.c
blob: 919be41226ecb896149bde11104980404056b682 (plain)
1
2
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
/* zip.c -- compress files to the gzip or pkzip format
 * Copyright (C) 1992-1993 Jean-loup Gailly
 * This is free software; you can redistribute it and/or modify it under the
 * terms of the GNU General Public License, see the file COPYING.
 */

#ifdef RCSID
static char rcsid[] = "$Id: zip.c,v 1.1 2002/08/18 00:59:21 hpa Exp $";
#endif

#include <ctype.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>

#include "tailor.h"
#include "gzip.h"

local ulg crc; /* crc on uncompressed file data */

/* ===========================================================================
 * Deflate in to out.
 * IN assertions: the input and output buffers are cleared.
 *   The variables time_stamp and save_orig_name are initialized.
 */
int zip(in, out)
int in, out; /* input and output file descriptors */
{
	uch flags = 0;	       /* general purpose bit flags */
	ush attr = 0;	       /* ascii/binary flag */
	ush deflate_flags = 0; /* pkzip -es, -en or -ex equivalent */

	ifd = in;
	ofd = out;
	outcnt = 0;

	/* Write the header to the gzip file. See algorithm.doc for the format
	 */

	method = DEFLATED;
	put_byte(GZIP_MAGIC[0]); /* magic header */
	put_byte(GZIP_MAGIC[1]);
	put_byte(DEFLATED); /* compression method */

	if (save_orig_name) {
		flags |= ORIG_NAME;
	}
	put_byte(flags); /* general flags */
	put_long(time_stamp);

	/* Write deflated file to zip file */
	crc = updcrc(0, 0);

	bi_init(out);
	ct_init(&attr, &method);
	lm_init(level, &deflate_flags);

	put_byte((uch)deflate_flags); /* extra flags */
	put_byte(OS_CODE);	      /* OS identifier */

	if (save_orig_name) {
		char *p = basename(ifname); /* Don't save the directory part. */
		do {
			put_char(*p);
		} while (*p++);
	}
	header_bytes = (long)outcnt;

	(void)deflate();

#if !defined(NO_SIZE_CHECK) && !defined(RECORD_IO)
	/* Check input size (but not in VMS -- variable record lengths mess it
	 * up) and not on MSDOS -- diet in TSR mode reports an incorrect file
	 * size)
	 */
	if (ifile_size != -1L && isize != (ulg)ifile_size) {
		Trace((stderr, " actual=%ld, read=%ld ", ifile_size, isize));
		fprintf(stderr, "%s: %s: file size changed while zipping\n",
			progname, ifname);
	}
#endif

	/* Write the crc and uncompressed size */
	put_long(crc);
	put_long(isize);
	header_bytes += 2 * sizeof(long);

	flush_outbuf();
	return OK;
}

/* ===========================================================================
 * Read a new buffer from the current input file, perform end-of-line
 * translation, and update the crc and input file size.
 * IN assertion: size >= 2 (for end-of-line translation)
 */
int file_read(buf, size)
char *buf;
unsigned size;
{
	unsigned len;

	Assert(insize == 0, "inbuf not empty");

	len = read(ifd, buf, size);
	if (len == (unsigned)(-1) || len == 0)
		return (int)len;

	crc = updcrc((uch *)buf, len);
	isize += (ulg)len;
	return (int)len;
}