1e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li/* 2e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * Copyright (c) 2006 Stefan Traby <stefan@hello-penguin.com> 3e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * 4e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * Redistribution and use in source and binary forms, with or without modifica- 5e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * tion, are permitted provided that the following conditions are met: 6e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * 7e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * 1. Redistributions of source code must retain the above copyright notice, 8e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * this list of conditions and the following disclaimer. 9e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * 10e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * 2. Redistributions in binary form must reproduce the above copyright 11e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * notice, this list of conditions and the following disclaimer in the 12e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * documentation and/or other materials provided with the distribution. 13e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * 14e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 15e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- 16e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 17e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- 18e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 20e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 21e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- 22e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 23e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * OF THE POSSIBILITY OF SUCH DAMAGE. 24e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * 25e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * Alternatively, the contents of this file may be used under the terms of 26e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * the GNU General Public License ("GPL") version 2 or any later version, 27e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * in which case the provisions of the GPL are applicable instead of 28e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * the above. If you wish to allow the use of your version of this file 29e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * only under the terms of the GPL and not to allow others to use your 30e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * version of this file under the BSD license, indicate your decision 31e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * by deleting the provisions above and replace them with the notice 32e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * and other provisions required by the GPL. If you do not delete the 33e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * provisions above, a recipient may use your version of this file under 34e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * either the BSD or the GPL. 35e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li */ 36e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 37e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#include "config.h" 38e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#include <stdio.h> 39e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#include <string.h> 40e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#include <stdlib.h> 41e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#include <unistd.h> 42e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#include <sys/types.h> 43e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#include <sys/stat.h> 44e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#include <fcntl.h> 45e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#include <errno.h> 46e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#include <limits.h> 47e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#include "lzf.h" 48e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 49e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#ifdef HAVE_GETOPT_H 50e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li# include <getopt.h> 51e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#endif 52e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 53e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#define BLOCKSIZE (1024 * 64 - 1) 54e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#define MAX_BLOCKSIZE BLOCKSIZE 55e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 56e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Litypedef unsigned char u8; 57e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 58e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Listatic off_t nr_read, nr_written; 59e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 60e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Listatic const char *imagename; 61e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Listatic enum { compress, uncompress, lzcat } mode = compress; 62e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Listatic int verbose = 0; 63e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Listatic int force = 0; 64e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Listatic long blocksize = BLOCKSIZE; 65e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 66e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#ifdef HAVE_GETOPT_LONG 67e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 68e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li struct option longopts[] = { 69e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li {"compress", 0, 0, 'c'}, 70e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li {"decompress", 0, 0, 'd'}, 71e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li {"uncompress", 0, 0, 'd'}, 72e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li {"force", 0, 0, 'f'}, 73e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li {"help", 0, 0, 'h'}, 74e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li {"verbose", 0, 0, 'v'}, 75e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li {"blocksize", 1, 0, 'b'}, 76e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li {0, 0, 0, 0} 77e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li }; 78e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 79e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li static const char *opt = 80e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li "-c --compress compress\n" 81e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li "-d --decompress decompress\n" 82e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li "-f --force force overwrite of output file\n" 83e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li "-h --help give this help\n" "-v --verbose verbose mode\n" "-b # --blocksize # set blocksize\n" "\n"; 84e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 85e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#else 86e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 87e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li static const char *opt = 88e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li "-c compress\n" 89e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li "-d decompress\n" 90e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li "-f force overwrite of output file\n" 91e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li "-h give this help\n" 92e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li "-v verbose mode\n" 93e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li "-b # set blocksize\n" 94e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li "\n"; 95e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 96e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#endif 97e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 98e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Listatic void 99e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Liusage (int rc) 100e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li{ 101e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li fprintf (stderr, "\n" 102e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li "lzf, a very lightweight compression/decompression utility written by Stefan Traby.\n" 103e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li "uses liblzf written by Marc Lehmann <schmorp@schmorp.de> You can find more info at\n" 104e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li "http://liblzf.plan9.de/\n" 105e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li "\n" 106e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li "usage: lzf [-dufhvb] [file ...]\n" 107e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li " unlzf [file ...]\n" 108e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li " lzcat [file ...]\n" 109e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li "\n%s", 110e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li opt); 111e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 112e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li exit (rc); 113e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li} 114e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 115e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Listatic inline ssize_t 116e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Lirread (int fd, void *buf, size_t len) 117e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li{ 118e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li ssize_t rc = 0, offset = 0; 119e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li char *p = buf; 120e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 121e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li while (len && (rc = read (fd, &p[offset], len)) > 0) 122e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 123e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li offset += rc; 124e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li len -= rc; 125e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 126e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 127e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li nr_read += offset; 128e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 129e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (rc < 0) 130e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li return rc; 131e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 132e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li return offset; 133e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li} 134e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 135e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li/* returns 0 if all written else -1 */ 136e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Listatic inline ssize_t 137e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Liwwrite (int fd, void *buf, size_t len) 138e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li{ 139e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li ssize_t rc; 140e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li char *b = buf; 141e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li size_t l = len; 142e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 143e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li while (l) 144e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 145e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li rc = write (fd, b, l); 146e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (rc < 0) 147e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 148e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li fprintf (stderr, "%s: write error: ", imagename); 149e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li perror (""); 150e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li return -1; 151e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 152e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 153e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li l -= rc; 154e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li b += rc; 155e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 156e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 157e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li nr_written += len; 158e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li return 0; 159e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li} 160e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 161e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li/* 162e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * Anatomy: an lzf file consists of any number of blocks in the following format: 163e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * 164e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * \x00 EOF (optional) 165e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * "ZV\0" 2-byte-usize <uncompressed data> 166e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * "ZV\1" 2-byte-csize 2-byte-usize <compressed data> 167e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * "ZV\2" 4-byte-crc32-0xdebb20e3 (NYI) 168e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li */ 169e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 170e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 171e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#define TYPE0_HDR_SIZE 5 172e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#define TYPE1_HDR_SIZE 7 173e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#define MAX_HDR_SIZE 7 174e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#define MIN_HDR_SIZE 5 175e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 176e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Listatic int 177e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Licompress_fd (int from, int to) 178e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li{ 179e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li ssize_t us, cs, len; 180e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li u8 buf1[MAX_BLOCKSIZE + MAX_HDR_SIZE + 16]; 181e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li u8 buf2[MAX_BLOCKSIZE + MAX_HDR_SIZE + 16]; 182e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li u8 *header; 183e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 184e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li nr_read = nr_written = 0; 185e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li while ((us = rread (from, &buf1[MAX_HDR_SIZE], blocksize)) > 0) 186e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 187e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li cs = lzf_compress (&buf1[MAX_HDR_SIZE], us, &buf2[MAX_HDR_SIZE], us > 4 ? us - 4 : us); 188e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (cs) 189e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 190e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li header = &buf2[MAX_HDR_SIZE - TYPE1_HDR_SIZE]; 191e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li header[0] = 'Z'; 192e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li header[1] = 'V'; 193e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li header[2] = 1; 194e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li header[3] = cs >> 8; 195e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li header[4] = cs & 0xff; 196e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li header[5] = us >> 8; 197e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li header[6] = us & 0xff; 198e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li len = cs + TYPE1_HDR_SIZE; 199e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 200e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li else 201e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { // write uncompressed 202e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li header = &buf1[MAX_HDR_SIZE - TYPE0_HDR_SIZE]; 203e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li header[0] = 'Z'; 204e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li header[1] = 'V'; 205e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li header[2] = 0; 206e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li header[3] = us >> 8; 207e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li header[4] = us & 0xff; 208e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li len = us + TYPE0_HDR_SIZE; 209e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 210e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 211e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (wwrite (to, header, len) == -1) 212e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li return -1; 213e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 214e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 215e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li return 0; 216e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li} 217e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 218e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Listatic int 219e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Liuncompress_fd (int from, int to) 220e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li{ 221e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li u8 header[MAX_HDR_SIZE]; 222e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li u8 buf1[MAX_BLOCKSIZE + MAX_HDR_SIZE + 16]; 223e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li u8 buf2[MAX_BLOCKSIZE + MAX_HDR_SIZE + 16]; 224e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li u8 *p; 225e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li int l, rd; 226e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li ssize_t rc, cs, us, bytes, over = 0; 227e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 228e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li nr_read = nr_written = 0; 229e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li while (1) 230e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 231e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li rc = rread (from, header + over, MAX_HDR_SIZE - over); 232e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (rc < 0) 233e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 234e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li fprintf (stderr, "%s: read error: ", imagename); 235e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li perror (""); 236e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li return -1; 237e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 238e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 239e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li rc += over; 240e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li over = 0; 241e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (!rc || header[0] == 0) 242e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li return 0; 243e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 244e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (rc < MIN_HDR_SIZE || header[0] != 'Z' || header[1] != 'V') 245e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 246e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li fprintf (stderr, "%s: invalid data stream - magic not found or short header\n", imagename); 247e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li return -1; 248e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 249e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 250e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li switch (header[2]) 251e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 252e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li case 0: 253e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li cs = -1; 254e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li us = (header[3] << 8) | header[4]; 255e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li p = &header[TYPE0_HDR_SIZE]; 256e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li break; 257e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li case 1: 258e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (rc < TYPE1_HDR_SIZE) 259e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 260e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li goto short_read; 261e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 262e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li cs = (header[3] << 8) | header[4]; 263e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li us = (header[5] << 8) | header[6]; 264e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li p = &header[TYPE1_HDR_SIZE]; 265e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li break; 266e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li default: 267e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li fprintf (stderr, "%s: unknown blocktype\n", imagename); 268e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li return -1; 269e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 270e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 271e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li bytes = cs == -1 ? us : cs; 272e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li l = &header[rc] - p; 273e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 274e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (l > 0) 275e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li memcpy (buf1, p, l); 276e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 277e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (l > bytes) 278e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 279e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li over = l - bytes; 280e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li memmove (header, &p[bytes], over); 281e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 282e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 283e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li p = &buf1[l]; 284e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li rd = bytes - l; 285e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (rd > 0) 286e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if ((rc = rread (from, p, rd)) != rd) 287e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li goto short_read; 288e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 289e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (cs == -1) 290e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 291e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (wwrite (to, buf1, us)) 292e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li return -1; 293e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 294e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li else 295e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 296e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (lzf_decompress (buf1, cs, buf2, us) != us) 297e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 298e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li fprintf (stderr, "%s: decompress: invalid stream - data corrupted\n", imagename); 299e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li return -1; 300e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 301e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 302e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (wwrite (to, buf2, us)) 303e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li return -1; 304e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 305e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 306e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 307e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li return 0; 308e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 309e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Lishort_read: 310e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li fprintf (stderr, "%s: short data\n", imagename); 311e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li return -1; 312e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li} 313e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 314e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Listatic int 315e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Liopen_out (const char *name) 316e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li{ 317e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li int fd; 318e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li int m = O_EXCL; 319e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 320e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (force) 321e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li m = 0; 322e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 323e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li fd = open (name, O_CREAT | O_WRONLY | O_TRUNC | m, 600); 324e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#if defined(__MINGW32__) 325e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li _setmode(fd, _O_BINARY); 326e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#endif 327e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li return fd; 328e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li} 329e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 330e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Listatic int 331e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Licompose_name (const char *fname, char *oname) 332e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li{ 333e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li char *p; 334e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 335e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (mode == compress) 336e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 337e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (strlen (fname) > PATH_MAX - 4) 338e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 339e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li fprintf (stderr, "%s: %s.lzf: name too long", imagename, fname); 340e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li return -1; 341e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 342e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 343e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li strcpy (oname, fname); 344e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li strcat (oname, ".lzf"); 345e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 346e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li else 347e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 348e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (strlen (fname) > PATH_MAX) 349e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 350e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li fprintf (stderr, "%s: %s: name too long\n", imagename, fname); 351e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li return -1; 352e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 353e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 354e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li strcpy (oname, fname); 355e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li p = &oname[strlen (oname)] - 4; 356e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (p < oname || strcmp (p, ".lzf")) 357e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 358e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li fprintf (stderr, "%s: %s: unknown suffix\n", imagename, fname); 359e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li return -1; 360e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 361e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 362e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li *p = 0; 363e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 364e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 365e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li return 0; 366e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li} 367e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 368e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Listatic int 369e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Lirun_file (const char *fname) 370e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li{ 371e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li int fd, fd2; 372e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li int rc; 373e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li struct stat mystat; 374e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li char oname[PATH_MAX + 1]; 375e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 376e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (mode != lzcat) 377e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (compose_name (fname, oname)) 378e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li return -1; 379e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 380e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#if !defined(__MINGW32__) 381e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li rc = lstat (fname, &mystat); 382e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#else 383e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li rc = stat (fname, &mystat); 384e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#endif 385e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li fd = open (fname, O_RDONLY); 386e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#if defined(__MINGW32__) 387e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li _setmode(fd, _O_BINARY); 388e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#endif 389e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (rc || fd == -1) 390e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 391e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li fprintf (stderr, "%s: %s: ", imagename, fname); 392e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li perror (""); 393e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li return -1; 394e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 395e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 396e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (!S_ISREG (mystat.st_mode)) 397e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 398e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li fprintf (stderr, "%s: %s: not a regular file.\n", imagename, fname); 399e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li close (fd); 400e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li return -1; 401e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 402e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 403e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (mode == lzcat) 404e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 405e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li rc = uncompress_fd (fd, 1); 406e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li close (fd); 407e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li return rc; 408e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 409e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 410e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li fd2 = open_out (oname); 411e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (fd2 == -1) 412e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 413e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li fprintf (stderr, "%s: %s: ", imagename, oname); 414e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li perror (""); 415e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li close (fd); 416e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li return -1; 417e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 418e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 419e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (mode == compress) 420e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 421e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li rc = compress_fd (fd, fd2); 422e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (!rc && verbose) 423e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li fprintf (stderr, "%s: %5.1f%% -- replaced with %s\n", 424e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li fname, nr_read == 0 ? 0 : 100.0 - nr_written / ((double) nr_read / 100.0), oname); 425e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 426e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li else 427e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 428e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li rc = uncompress_fd (fd, fd2); 429e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (!rc && verbose) 430e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li fprintf (stderr, "%s: %5.1f%% -- replaced with %s\n", 431e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li fname, nr_written == 0 ? 0 : 100.0 - nr_read / ((double) nr_written / 100.0), oname); 432e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 433e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 434e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#if !defined(__MINGW32__) 435e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li fchmod (fd2, mystat.st_mode); 436e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#else 437e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li chmod (oname, mystat.st_mode); 438e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#endif 439e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li close (fd); 440e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li close (fd2); 441e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 442e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (!rc) 443e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li unlink (fname); 444e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 445e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li return rc; 446e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li} 447e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 448e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Liint 449e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Limain (int argc, char *argv[]) 450e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li{ 451e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li char *p = argv[0]; 452e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li int optc; 453e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li int rc = 0; 454e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 455e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li errno = 0; 456e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li p = getenv ("LZF_BLOCKSIZE"); 457e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (p) 458e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 459e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li blocksize = strtoul (p, 0, 0); 460e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (errno || !blocksize || blocksize > MAX_BLOCKSIZE) 461e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li blocksize = BLOCKSIZE; 462e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 463e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 464e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li p = strrchr (argv[0], '/'); 465e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li imagename = p ? ++p : argv[0]; 466e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 467e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (!strncmp (imagename, "un", 2) || !strncmp (imagename, "de", 2)) 468e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li mode = uncompress; 469e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 470e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (strstr (imagename, "cat")) 471e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li mode = lzcat; 472e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 473e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#ifdef HAVE_GETOPT_LONG 474e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li while ((optc = getopt_long (argc, argv, "cdfhvb:", longopts, 0)) != -1) 475e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#else 476e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li while ((optc = getopt (argc, argv, "cdfhvb:")) != -1) 477e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li#endif 478e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 479e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li switch (optc) 480e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 481e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li case 'c': 482e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li mode = compress; 483e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li break; 484e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li case 'd': 485e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li mode = uncompress; 486e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li break; 487e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li case 'f': 488e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li force = 1; 489e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li break; 490e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li case 'h': 491e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li usage (0); 492e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li break; 493e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li case 'v': 494e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li verbose = 1; 495e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li break; 496e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li case 'b': 497e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li errno = 0; 498e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li blocksize = strtoul (optarg, 0, 0); 499e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (errno || !blocksize || blocksize > MAX_BLOCKSIZE) 500e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li blocksize = BLOCKSIZE; 501e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li break; 502e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li default: 503e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li usage (1); 504e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li break; 505e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 506e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 507e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 508e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (optind == argc) 509e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { // stdin stdout 510e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (!force) 511e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 512e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if ((mode == uncompress || mode == lzcat) && isatty (0)) 513e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 514e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li fprintf (stderr, "%s: compressed data not read from a terminal. Use -f to force decompression.\n", imagename); 515e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li exit (1); 516e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 517e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (mode == compress && isatty (1)) 518e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li { 519e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li fprintf (stderr, "%s: compressed data not written to a terminal. Use -f to force compression.\n", imagename); 520e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li exit (1); 521e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 522e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 523e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 524e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li if (mode == compress) 525e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li rc = compress_fd (0, 1); 526e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li else 527e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li rc = uncompress_fd (0, 1); 528e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 529e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li exit (rc ? 1 : 0); 530e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li } 531e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 532e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li while (optind < argc) 533e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li rc |= run_file (argv[optind++]); 534e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 535e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li exit (rc ? 1 : 0); 536e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li} 537e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li 538