1/* zip.c -- compress files to the gzip or pkzip format 2 * Copyright (C) 1992-1993 Jean-loup Gailly 3 * This is free software; you can redistribute it and/or modify it under the 4 * terms of the GNU General Public License, see the file COPYING. 5 */ 6 7#ifdef RCSID 8static char rcsid[] = "$Id: zip.c 3476 2003-06-11 15:56:10Z darkwyrm $"; 9#endif 10 11#include <ctype.h> 12#include <sys/types.h> 13 14#include "tailor.h" 15#include "gzip.h" 16#include "crypt.h" 17 18#ifdef HAVE_UNISTD_H 19# include <unistd.h> 20#endif 21#ifndef NO_FCNTL_H 22# include <fcntl.h> 23#endif 24 25local ulg crc; /* crc on uncompressed file data */ 26long header_bytes; /* number of bytes in gzip header */ 27 28/* =========================================================================== 29 * Deflate in to out. 30 * IN assertions: the input and output buffers are cleared. 31 * The variables time_stamp and save_orig_name are initialized. 32 */ 33int zip(in, out) 34 int in, out; /* input and output file descriptors */ 35{ 36 uch flags = 0; /* general purpose bit flags */ 37 ush attr = 0; /* ascii/binary flag */ 38 ush deflate_flags = 0; /* pkzip -es, -en or -ex equivalent */ 39 40 ifd = in; 41 ofd = out; 42 outcnt = 0; 43 44 /* Write the header to the gzip file. See algorithm.doc for the format */ 45 46 method = DEFLATED; 47 put_byte(GZIP_MAGIC[0]); /* magic header */ 48 put_byte(GZIP_MAGIC[1]); 49 put_byte(DEFLATED); /* compression method */ 50 51 if (save_orig_name) { 52 flags |= ORIG_NAME; 53 } 54 put_byte(flags); /* general flags */ 55 put_long(time_stamp); 56 57 /* Write deflated file to zip file */ 58 crc = updcrc(0, 0); 59 60 bi_init(out); 61 ct_init(&attr, &method); 62 lm_init(level, &deflate_flags); 63 64 put_byte((uch)deflate_flags); /* extra flags */ 65 put_byte(OS_CODE); /* OS identifier */ 66 67 if (save_orig_name) { 68 char *p = our_basename(ifname); /* Don't save the directory part. */ 69 do { 70 put_char(*p); 71 } while (*p++); 72 } 73 header_bytes = (long)outcnt; 74 75 (void)deflate(); 76 77#if !defined(NO_SIZE_CHECK) && !defined(RECORD_IO) 78 /* Check input size (but not in VMS -- variable record lengths mess it up) 79 * and not on MSDOS -- diet in TSR mode reports an incorrect file size) 80 */ 81 if (ifile_size != -1L && isize != (ulg)ifile_size) { 82 Trace((stderr, " actual=%ld, read=%ld ", ifile_size, isize)); 83 fprintf(stderr, "%s: %s: file size changed while zipping\n", 84 progname, ifname); 85 } 86#endif 87 88 /* Write the crc and uncompressed size */ 89 put_long(crc); 90 put_long(isize); 91 header_bytes += 2*sizeof(long); 92 93 flush_outbuf(); 94 return OK; 95} 96 97 98/* =========================================================================== 99 * Read a new buffer from the current input file, perform end-of-line 100 * translation, and update the crc and input file size. 101 * IN assertion: size >= 2 (for end-of-line translation) 102 */ 103int file_read(buf, size) 104 char *buf; 105 unsigned size; 106{ 107 unsigned len; 108 109 Assert(insize == 0, "inbuf not empty"); 110 111 len = read(ifd, buf, size); 112 if (len == (unsigned)(-1) || len == 0) return (int)len; 113 114 crc = updcrc((uch*)buf, len); 115 isize += (ulg)len; 116 return (int)len; 117} 118