]> git.cworth.org Git - gzip/blob - zip.c
Avoid creating an undersized buffer for the hufts table.
[gzip] / zip.c
1 /* zip.c -- compress files to the gzip or pkzip format
2
3    Copyright (C) 1997, 1998, 1999, 2006, 2007 Free Software Foundation, Inc.
4    Copyright (C) 1992-1993 Jean-loup Gailly
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2, or (at your option)
9    any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software Foundation,
18    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
19
20 #ifdef RCSID
21 static char rcsid[] = "$Id: zip.c,v 1.7 2007/03/20 05:09:51 eggert Exp $";
22 #endif
23
24 #include <config.h>
25 #include <ctype.h>
26
27 #include "tailor.h"
28 #include "gzip.h"
29 #include "crypt.h"
30
31 #ifdef HAVE_UNISTD_H
32 #  include <unistd.h>
33 #endif
34 #ifdef HAVE_FCNTL_H
35 #  include <fcntl.h>
36 #endif
37
38 local ulg crc;       /* crc on uncompressed file data */
39 off_t header_bytes;   /* number of bytes in gzip header */
40
41 /* ===========================================================================
42  * Deflate in to out.
43  * IN assertions: the input and output buffers are cleared.
44  *   The variables time_stamp and save_orig_name are initialized.
45  */
46 int zip(in, out)
47     int in, out;            /* input and output file descriptors */
48 {
49     uch  flags = 0;         /* general purpose bit flags */
50     ush  attr = 0;          /* ascii/binary flag */
51     ush  deflate_flags = 0; /* pkzip -es, -en or -ex equivalent */
52     ulg  stamp;
53
54     ifd = in;
55     ofd = out;
56     outcnt = 0;
57
58     /* Write the header to the gzip file. See algorithm.doc for the format */
59
60     method = DEFLATED;
61     put_byte(GZIP_MAGIC[0]); /* magic header */
62     put_byte(GZIP_MAGIC[1]);
63     put_byte(DEFLATED);      /* compression method */
64
65     if (save_orig_name) {
66         flags |= ORIG_NAME;
67     }
68     put_byte(flags);         /* general flags */
69     stamp = (0 <= time_stamp.tv_sec && time_stamp.tv_sec <= 0xffffffff
70              ? (ulg) time_stamp.tv_sec
71              : (ulg) 0);
72     put_long (stamp);
73
74     /* Write deflated file to zip file */
75     crc = updcrc(0, 0);
76
77     bi_init(out);
78     ct_init(&attr, &method);
79     lm_init(level, &deflate_flags);
80
81     put_byte((uch)deflate_flags); /* extra flags */
82     put_byte(OS_CODE);            /* OS identifier */
83
84     if (save_orig_name) {
85         char *p = gzip_base_name (ifname); /* Don't save the directory part. */
86         do {
87             put_char(*p);
88         } while (*p++);
89     }
90     header_bytes = (off_t)outcnt;
91
92     (void)deflate();
93
94 #if !defined(NO_SIZE_CHECK) && !defined(RECORD_IO)
95   /* Check input size (but not in VMS -- variable record lengths mess it up)
96    * and not on MSDOS -- diet in TSR mode reports an incorrect file size)
97    */
98     if (ifile_size != -1L && bytes_in != ifile_size) {
99         fprintf(stderr, "%s: %s: file size changed while zipping\n",
100                 program_name, ifname);
101     }
102 #endif
103
104     /* Write the crc and uncompressed size */
105     put_long(crc);
106     put_long((ulg)bytes_in);
107     header_bytes += 2*sizeof(long);
108
109     flush_outbuf();
110     return OK;
111 }
112
113
114 /* ===========================================================================
115  * Read a new buffer from the current input file, perform end-of-line
116  * translation, and update the crc and input file size.
117  * IN assertion: size >= 2 (for end-of-line translation)
118  */
119 int file_read(buf, size)
120     char *buf;
121     unsigned size;
122 {
123     unsigned len;
124
125     Assert(insize == 0, "inbuf not empty");
126
127     len = read_buffer (ifd, buf, size);
128     if (len == 0) return (int)len;
129     if (len == (unsigned)-1) {
130         read_error();
131         return EOF;
132     }
133
134     crc = updcrc((uch*)buf, len);
135     bytes_in += (off_t)len;
136     return (int)len;
137 }