diff options
author | Waldemar Brodkorb <wbx@openadk.org> | 2014-03-30 15:55:20 +0200 |
---|---|---|
committer | Waldemar Brodkorb <wbx@openadk.org> | 2014-03-30 15:55:20 +0200 |
commit | 8aed1fcd443b550c15a21ddbf1b1d3899803120a (patch) | |
tree | ce7c0a22c1d5ed7d437198b4447a3aa2fd578665 /tools/cpio/src | |
parent | 12c9d74bb923174117e28186e4a7698e623803a2 (diff) |
rework hosttools building, add tools into package stuff
Diffstat (limited to 'tools/cpio/src')
65 files changed, 0 insertions, 18246 deletions
diff --git a/tools/cpio/src/_alloca.h b/tools/cpio/src/_alloca.h deleted file mode 100644 index dc2afe5b4..000000000 --- a/tools/cpio/src/_alloca.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)_alloca.h 1.5 (gritter) 1/22/06 */ - -#if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || \ - defined (__DragonFly__) || defined (__APPLE__) -#include <stdlib.h> -#endif /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ diff --git a/tools/cpio/src/_malloc.h b/tools/cpio/src/_malloc.h deleted file mode 100644 index 1693e3673..000000000 --- a/tools/cpio/src/_malloc.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)_malloc.h 1.2 (gritter) 5/1/04 */ - -#include <stdlib.h> - -extern void *memalign(size_t, size_t); diff --git a/tools/cpio/src/_utmpx.h b/tools/cpio/src/_utmpx.h deleted file mode 100644 index c32bd9527..000000000 --- a/tools/cpio/src/_utmpx.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2004 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)_utmpx.h 1.9 (gritter) 1/22/06 */ - -#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \ - defined (__UCLIBC__) || defined (__OpenBSD__) || \ - defined (__DragonFly__) || defined (__APPLE__) -#include <sys/types.h> -#include <sys/time.h> -#include <utmp.h> - -#ifndef __dietlibc__ -struct utmpx { - char ut_user[UT_NAMESIZE]; - char ut_id[UT_LINESIZE]; - char ut_line[UT_LINESIZE]; - char ut_host[UT_HOSTSIZE]; - pid_t ut_pid; - short ut_type; - struct timeval ut_tv; - struct { - int e_termination; - int e_exit; - } ut_exit; -}; - -#ifndef EMPTY -#define EMPTY 0 -#endif -#ifndef BOOT_TIME -#define BOOT_TIME 1 -#endif -#ifndef OLD_TIME -#define OLD_TIME 2 -#endif -#ifndef NEW_TIME -#define NEW_TIME 3 -#endif -#ifndef USER_PROCESS -#define USER_PROCESS 4 -#endif -#ifndef INIT_PROCESS -#define INIT_PROCESS 5 -#endif -#ifndef LOGIN_PROCESS -#define LOGIN_PROCESS 6 -#endif -#ifndef DEAD_PROCESS -#define DEAD_PROCESS 7 -#endif -#ifndef RUN_LVL -#define RUN_LVL 8 -#endif -#ifndef ACCOUNTING -#define ACCOUNTING 9 -#endif -#else /* __dietlibc__ */ -#define utmpx utmp -#endif /* __dietlibc__ */ - -extern void endutxent(void); -extern struct utmpx *getutxent(void); -extern struct utmpx *getutxid(const struct utmpx *); -extern struct utmpx *getutxline(const struct utmpx *); -extern struct utmpx *pututxline(const struct utmpx *); -extern void setutxent(void); -extern int utmpxname(const char *); -extern void updwtmpx(const char *, const struct utmpx *); -#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __UCLIBC__ || - __OpenBSD__ || __DragonFly__ || __APPLE__ */ diff --git a/tools/cpio/src/asciitype.c b/tools/cpio/src/asciitype.c deleted file mode 100644 index f7f322173..000000000 --- a/tools/cpio/src/asciitype.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)asciitype.c 1.4 (gritter) 4/17/03 */ - -#include "asciitype.h" - -const unsigned char class_char[] = { -/* 000 nul 001 soh 002 stx 003 etx 004 eot 005 enq 006 ack 007 bel */ - C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL, -/* 010 bs 011 ht 012 nl 013 vt 014 np 015 cr 016 so 017 si */ - C_CNTRL,C_BLANK,C_WHITE,C_SPACE,C_SPACE,C_SPACE,C_CNTRL,C_CNTRL, -/* 020 dle 021 dc1 022 dc2 023 dc3 024 dc4 025 nak 026 syn 027 etb */ - C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL, -/* 030 can 031 em 032 sub 033 esc 034 fs 035 gs 036 rs 037 us */ - C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL,C_CNTRL, -/* 040 sp 041 ! 042 " 043 # 044 $ 045 % 046 & 047 ' */ - C_BLANK,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT, -/* 050 ( 051 ) 052 * 053 + 054 , 055 - 056 . 057 / */ - C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT, -/* 060 0 061 1 062 2 063 3 064 4 065 5 066 6 067 7 */ - C_OCTAL,C_OCTAL,C_OCTAL,C_OCTAL,C_OCTAL,C_OCTAL,C_OCTAL,C_OCTAL, -/* 070 8 071 9 072 : 073 ; 074 < 075 = 076 > 077 ? */ - C_DIGIT,C_DIGIT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT, -/* 100 @ 101 A 102 B 103 C 104 D 105 E 106 F 107 G */ - C_PUNCT,C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER, -/* 110 H 111 I 112 J 113 K 114 L 115 M 116 N 117 O */ - C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER, -/* 120 P 121 Q 122 R 123 S 124 T 125 U 126 V 127 W */ - C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER,C_UPPER, -/* 130 X 131 Y 132 Z 133 [ 134 \ 135 ] 136 ^ 137 _ */ - C_UPPER,C_UPPER,C_UPPER,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT, -/* 140 ` 141 a 142 b 143 c 144 d 145 e 146 f 147 g */ - C_PUNCT,C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER, -/* 150 h 151 i 152 j 153 k 154 l 155 m 156 n 157 o */ - C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER, -/* 160 p 161 q 162 r 163 s 164 t 165 u 166 v 167 w */ - C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER,C_LOWER, -/* 170 x 171 y 172 z 173 { 174 | 175 } 176 ~ 177 del */ - C_LOWER,C_LOWER,C_LOWER,C_PUNCT,C_PUNCT,C_PUNCT,C_PUNCT,C_CNTRL -}; diff --git a/tools/cpio/src/asciitype.h b/tools/cpio/src/asciitype.h deleted file mode 100644 index 6ac1961a1..000000000 --- a/tools/cpio/src/asciitype.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)asciitype.h 1.6 (gritter) 9/9/05 */ - -/* - * Locale-independent character classes. - */ -enum { - C_CNTRL = 0000, - C_BLANK = 0001, - C_WHITE = 0002, - C_SPACE = 0004, - C_PUNCT = 0010, - C_OCTAL = 0020, - C_DIGIT = 0040, - C_UPPER = 0100, - C_LOWER = 0200 -}; - -extern const unsigned char class_char[]; - -#define asciichar(c) ((unsigned)(c) <= 0177) -#define alnumchar(c) (asciichar(c)&&(class_char[c]&\ - (C_DIGIT|C_OCTAL|C_UPPER|C_LOWER))) -#define alphachar(c) (asciichar(c)&&(class_char[c]&(C_UPPER|C_LOWER))) -#define blankchar(c) (asciichar(c)&&(class_char[c]&(C_BLANK))) -#define cntrlchar(c) (asciichar(c)&&(class_char[c]==C_CNTRL) -#define digitchar(c) (asciichar(c)&&(class_char[c]&(C_DIGIT|C_OCTAL))) -#define lowerchar(c) (asciichar(c)&&(class_char[c]&(C_LOWER))) -#define punctchar(c) (asciichar(c)&&(class_char[c]&(C_PUNCT))) -#define spacechar(c) (asciichar(c)&&(class_char[c]&(C_BLANK|C_SPACE|C_WHITE))) -#define upperchar(c) (asciichar(c)&&(class_char[c]&(C_UPPER))) -#define whitechar(c) (asciichar(c)&&(class_char[c]&(C_BLANK|C_WHITE))) -#define octalchar(c) (asciichar(c)&&(class_char[c]&(C_OCTAL))) -#define graphchar(c) (asciichar(c)&&(class_char[c]&\ - (C_UPPER|C_LOWER|C_DIGIT|C_OCTAL|C_PUNCT))) -#define printchar(c) ((c)==' ' || asciichar(c)&&(class_char[c]&\ - (C_UPPER|C_LOWER|C_DIGIT|C_OCTAL|C_PUNCT))) - -#define upperconv(c) (lowerchar(c) ? (c)-'a'+'A' : (c)) -#define lowerconv(c) (upperchar(c) ? (c)-'A'+'a' : (c)) diff --git a/tools/cpio/src/atoll.h b/tools/cpio/src/atoll.h deleted file mode 100644 index 8283aff64..000000000 --- a/tools/cpio/src/atoll.h +++ /dev/null @@ -1,8 +0,0 @@ -/* Sccsid @(#)atoll.h 1.4 (gritter) 7/18/04 */ - -#if defined (__hpux) || defined (_AIX) || \ - defined (__FreeBSD__) && (__FreeBSD__) < 5 -extern long long strtoll(const char *nptr, char **endptr, int base); -extern unsigned long long strtoull(const char *nptr, char **endptr, int base); -extern long long atoll(const char *nptr); -#endif /* __hpux || _AIX || __FreeBSD__ < 5 */ diff --git a/tools/cpio/src/blank.h b/tools/cpio/src/blank.h deleted file mode 100644 index 1ab3d57b8..000000000 --- a/tools/cpio/src/blank.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * isblank() and iswblank() are not available with many pre-XSH6 - * systems. Check whether isblank was defined, and assume it is - * not available if not. - */ -/* Sccsid @(#)blank.h 1.3 (gritter) 5/1/04 */ - -#ifndef __dietlibc__ -#ifndef LIBCOMMON_BLANK_H -#define LIBCOMMON_BLANK_H 1 - -#include <ctype.h> -#include <wctype.h> - -#ifndef isblank - -static -#ifdef __GNUC__ -__inline__ -#endif /* __GNUC__ */ -int -my_isblank(int c) -{ - return c == ' ' || c == '\t'; -} -#define isblank(c) my_isblank(c) - -static int -my_iswblank(wint_t c) -{ - return c == L' ' || c == L'\t'; -} -#undef iswblank -#define iswblank(c) my_iswblank(c) - -#endif /* !isblank */ -#endif /* !LIBCOMMON_BLANK_H */ -#endif /* !__dietlibc__ */ diff --git a/tools/cpio/src/blast.c b/tools/cpio/src/blast.c deleted file mode 100644 index b62efd585..000000000 --- a/tools/cpio/src/blast.c +++ /dev/null @@ -1,449 +0,0 @@ -/* - * Changes by Gunnar Ritter, Freiburg i. Br., Germany, February 2004. - * - * Sccsid @(#)blast.c 1.2 (gritter) 2/17/04 - */ -/* blast.c - * Copyright (C) 2003 Mark Adler - * For conditions of distribution and use, see copyright notice in blast.h - * version 1.1, 16 Feb 2003 - * - * blast.c decompresses data compressed by the PKWare Compression Library. - * This function provides functionality similar to the explode() function of - * the PKWare library, hence the name "blast". - * - * This decompressor is based on the excellent format description provided by - * Ben Rudiak-Gould in comp.compression on August 13, 2001. Interestingly, the - * example Ben provided in the post is incorrect. The distance 110001 should - * instead be 111000. When corrected, the example byte stream becomes: - * - * 00 04 82 24 25 8f 80 7f - * - * which decompresses to "AIAIAIAIAIAIA" (without the quotes). - */ - -/* - * Change history: - * - * 1.0 12 Feb 2003 - First version - * 1.1 16 Feb 2003 - Fixed distance check for > 4 GB uncompressed data - */ - -#include <setjmp.h> /* for setjmp(), longjmp(), and jmp_buf */ -#include "blast.h" /* prototype for blast() */ - -#define local static /* for local function definitions */ -#define MAXBITS 13 /* maximum code length */ -#define MAXWIN 4096 /* maximum window size */ - -/* input and output state */ -struct state { - /* input state */ - blast_in infun; /* input function provided by user */ - void *inhow; /* opaque information passed to infun() */ - unsigned char *in; /* next input location */ - unsigned left; /* available input at in */ - int bitbuf; /* bit buffer */ - int bitcnt; /* number of bits in bit buffer */ - - /* input limit error return state for bits() and decode() */ - jmp_buf env; - - /* output state */ - blast_out outfun; /* output function provided by user */ - void *outhow; /* opaque information passed to outfun() */ - unsigned next; /* index of next write location in out[] */ - int first; /* true to check distances (for first 4K) */ - unsigned char out[MAXWIN]; /* output buffer and sliding window */ -}; - -/* - * Return need bits from the input stream. This always leaves less than - * eight bits in the buffer. bits() works properly for need == 0. - * - * Format notes: - * - * - Bits are stored in bytes from the least significant bit to the most - * significant bit. Therefore bits are dropped from the bottom of the bit - * buffer, using shift right, and new bytes are appended to the top of the - * bit buffer, using shift left. - */ -local int bits(struct state *s, int need) -{ - int val; /* bit accumulator */ - - /* load at least need bits into val */ - val = s->bitbuf; - while (s->bitcnt < need) { - if (s->left == 0) { - s->left = s->infun(s->inhow, &(s->in)); - if (s->left == 0) longjmp(s->env, 1); /* out of input */ - } - val |= (int)(*(s->in)++) << s->bitcnt; /* load eight bits */ - s->left--; - s->bitcnt += 8; - } - - /* drop need bits and update buffer, always zero to seven bits left */ - s->bitbuf = val >> need; - s->bitcnt -= need; - - /* return need bits, zeroing the bits above that */ - return val & ((1 << need) - 1); -} - -/* - * Huffman code decoding tables. count[1..MAXBITS] is the number of symbols of - * each length, which for a canonical code are stepped through in order. - * symbol[] are the symbol values in canonical order, where the number of - * entries is the sum of the counts in count[]. The decoding process can be - * seen in the function decode() below. - */ -struct huffman { - short *count; /* number of symbols of each length */ - short *symbol; /* canonically ordered symbols */ -}; - -/* - * Decode a code from the stream s using huffman table h. Return the symbol or - * a negative value if there is an error. If all of the lengths are zero, i.e. - * an empty code, or if the code is incomplete and an invalid code is received, - * then -9 is returned after reading MAXBITS bits. - * - * Format notes: - * - * - The codes as stored in the compressed data are bit-reversed relative to - * a simple integer ordering of codes of the same lengths. Hence below the - * bits are pulled from the compressed data one at a time and used to - * build the code value reversed from what is in the stream in order to - * permit simple integer comparisons for decoding. - * - * - The first code for the shortest length is all ones. Subsequent codes of - * the same length are simply integer decrements of the previous code. When - * moving up a length, a one bit is appended to the code. For a complete - * code, the last code of the longest length will be all zeros. To support - * this ordering, the bits pulled during decoding are inverted to apply the - * more "natural" ordering starting with all zeros and incrementing. - */ -local int decode(struct state *s, struct huffman *h) -{ - int len; /* current number of bits in code */ - int code; /* len bits being decoded */ - int first; /* first code of length len */ - int count; /* number of codes of length len */ - int index; /* index of first code of length len in symbol table */ - int bitbuf; /* bits from stream */ - int left; /* bits left in next or left to process */ - short *next; /* next number of codes */ - - bitbuf = s->bitbuf; - left = s->bitcnt; - code = first = index = 0; - len = 1; - next = h->count + 1; - while (1) { - while (left--) { - code |= (bitbuf & 1) ^ 1; /* invert code */ - bitbuf >>= 1; - count = *next++; - if (code < first + count) { /* if length len, return symbol */ - s->bitbuf = bitbuf; - s->bitcnt = (s->bitcnt - len) & 7; - return h->symbol[index + (code - first)]; - } - index += count; /* else update for next length */ - first += count; - first <<= 1; - code <<= 1; - len++; - } - left = (MAXBITS+1) - len; - if (left == 0) break; - if (s->left == 0) { - s->left = s->infun(s->inhow, &(s->in)); - if (s->left == 0) longjmp(s->env, 1); /* out of input */ - } - bitbuf = *(s->in)++; - s->left--; - if (left > 8) left = 8; - } - return -9; /* ran out of codes */ -} - -/* - * Given a list of repeated code lengths rep[0..n-1], where each byte is a - * count (high four bits + 1) and a code length (low four bits), generate the - * list of code lengths. This compaction reduces the size of the object code. - * Then given the list of code lengths length[0..n-1] representing a canonical - * Huffman code for n symbols, construct the tables required to decode those - * codes. Those tables are the number of codes of each length, and the symbols - * sorted by length, retaining their original order within each length. The - * return value is zero for a complete code set, negative for an over- - * subscribed code set, and positive for an incomplete code set. The tables - * can be used if the return value is zero or positive, but they cannot be used - * if the return value is negative. If the return value is zero, it is not - * possible for decode() using that table to return an error--any stream of - * enough bits will resolve to a symbol. If the return value is positive, then - * it is possible for decode() using that table to return an error for received - * codes past the end of the incomplete lengths. - */ -local int construct(struct huffman *h, const unsigned char *rep, int n) -{ - int symbol; /* current symbol when stepping through length[] */ - int len; /* current length when stepping through h->count[] */ - int left; /* number of possible codes left of current length */ - short offs[MAXBITS+1]; /* offsets in symbol table for each length */ - short length[256]; /* code lengths */ - - /* convert compact repeat counts into symbol bit length list */ - symbol = 0; - do { - len = *rep++; - left = (len >> 4) + 1; - len &= 15; - do { - length[symbol++] = len; - } while (--left); - } while (--n); - n = symbol; - - /* count number of codes of each length */ - for (len = 0; len <= MAXBITS; len++) - h->count[len] = 0; - for (symbol = 0; symbol < n; symbol++) - (h->count[length[symbol]])++; /* assumes lengths are within bounds */ - if (h->count[0] == n) /* no codes! */ - return 0; /* complete, but decode() will fail */ - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; /* one possible code of zero length */ - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; /* one more bit, double codes left */ - left -= h->count[len]; /* deduct count from possible codes */ - if (left < 0) return left; /* over-subscribed--return negative */ - } /* left > 0 means incomplete */ - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) - offs[len + 1] = offs[len] + h->count[len]; - - /* - * put symbols in table sorted by length, by symbol order within each - * length - */ - for (symbol = 0; symbol < n; symbol++) - if (length[symbol] != 0) - h->symbol[offs[length[symbol]]++] = symbol; - - /* return zero for complete set, positive for incomplete set */ - return left; -} - -/* - * Decode PKWare Compression Library stream. - * - * Format notes: - * - * - First byte is 0 if literals are uncoded or 1 if they are coded. Second - * byte is 4, 5, or 6 for the number of extra bits in the distance code. - * This is the base-2 logarithm of the dictionary size minus six. - * - * - Compressed data is a combination of literals and length/distance pairs - * terminated by an end code. Literals are either Huffman coded or - * uncoded bytes. A length/distance pair is a coded length followed by a - * coded distance to represent a string that occurs earlier in the - * uncompressed data that occurs again at the current location. - * - * - A bit preceding a literal or length/distance pair indicates which comes - * next, 0 for literals, 1 for length/distance. - * - * - If literals are uncoded, then the next eight bits are the literal, in the - * normal bit order in th stream, i.e. no bit-reversal is needed. Similarly, - * no bit reversal is needed for either the length extra bits or the distance - * extra bits. - * - * - Literal bytes are simply written to the output. A length/distance pair is - * an instruction to copy previously uncompressed bytes to the output. The - * copy is from distance bytes back in the output stream, copying for length - * bytes. - * - * - Distances pointing before the beginning of the output data are not - * permitted. - * - * - Overlapped copies, where the length is greater than the distance, are - * allowed and common. For example, a distance of one and a length of 518 - * simply copies the last byte 518 times. A distance of four and a length of - * twelve copies the last four bytes three times. A simple forward copy - * ignoring whether the length is greater than the distance or not implements - * this correctly. - */ -local int decomp(struct state *s) -{ - int lit; /* true if literals are coded */ - int dict; /* log2(dictionary size) - 6 */ - int symbol; /* decoded symbol, extra bits for distance */ - int len; /* length for copy */ - int dist; /* distance for copy */ - int copy; /* copy counter */ - unsigned char *from, *to; /* copy pointers */ - static int virgin = 1; /* build tables once */ - static short litcnt[MAXBITS+1], litsym[256]; /* litcode memory */ - static short lencnt[MAXBITS+1], lensym[16]; /* lencode memory */ - static short distcnt[MAXBITS+1], distsym[64]; /* distcode memory */ - static struct huffman litcode = {litcnt, litsym}; /* length code */ - static struct huffman lencode = {lencnt, lensym}; /* length code */ - static struct huffman distcode = {distcnt, distsym};/* distance code */ - /* bit lengths of literal codes */ - static const unsigned char litlen[] = { - 11, 124, 8, 7, 28, 7, 188, 13, 76, 4, 10, 8, 12, 10, 12, 10, 8, 23, 8, - 9, 7, 6, 7, 8, 7, 6, 55, 8, 23, 24, 12, 11, 7, 9, 11, 12, 6, 7, 22, 5, - 7, 24, 6, 11, 9, 6, 7, 22, 7, 11, 38, 7, 9, 8, 25, 11, 8, 11, 9, 12, - 8, 12, 5, 38, 5, 38, 5, 11, 7, 5, 6, 21, 6, 10, 53, 8, 7, 24, 10, 27, - 44, 253, 253, 253, 252, 252, 252, 13, 12, 45, 12, 45, 12, 61, 12, 45, - 44, 173}; - /* bit lengths of length codes 0..15 */ - static const unsigned char lenlen[] = {2, 35, 36, 53, 38, 23}; - /* bit lengths of distance codes 0..63 */ - static const unsigned char distlen[] = {2, 20, 53, 230, 247, 151, 248}; - static const short base[16] = { /* base for length codes */ - 3, 2, 4, 5, 6, 7, 8, 9, 10, 12, 16, 24, 40, 72, 136, 264}; - static const char extra[16] = { /* extra bits for length codes */ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8}; - - /* set up decoding tables (once--might not be thread-safe) */ - if (virgin) { - construct(&litcode, litlen, sizeof(litlen)); - construct(&lencode, lenlen, sizeof(lenlen)); - construct(&distcode, distlen, sizeof(distlen)); - virgin = 0; - } - - /* read header */ - lit = bits(s, 8); - if (lit > 1) return -1; - dict = bits(s, 8); - if (dict < 4 || dict > 6) return -2; - - /* decode literals and length/distance pairs */ - do { - if (bits(s, 1)) { - /* get length */ - symbol = decode(s, &lencode); - len = base[symbol] + bits(s, extra[symbol]); - if (len == 519) break; /* end code */ - - /* get distance */ - symbol = len == 2 ? 2 : dict; - dist = decode(s, &distcode) << symbol; - dist += bits(s, symbol); - dist++; - if (s->first && dist > s->next) - return -3; /* distance too far back */ - - /* copy length bytes from distance bytes back */ - do { - to = s->out + s->next; - from = to - dist; - copy = MAXWIN; - if (s->next < dist) { - from += copy; - copy = dist; - } - copy -= s->next; - if (copy > len) copy = len; - len -= copy; - s->next += copy; - do { - *to++ = *from++; - } while (--copy); - if (s->next == MAXWIN) { - if (s->outfun(s->outhow, s->out, s->next)) return 1; - s->next = 0; - s->first = 0; - } - } while (len != 0); - } - else { - /* get literal and write it */ - symbol = lit ? decode(s, &litcode) : bits(s, 8); - s->out[s->next++] = symbol; - if (s->next == MAXWIN) { - if (s->outfun(s->outhow, s->out, s->next)) return 1; - s->next = 0; - s->first = 0; - } - } - } while (1); - return 0; -} - -/* See comments in blast.h */ -int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow) -{ - struct state s; /* input/output state */ - int err; /* return value */ - - /* initialize input state */ - s.infun = infun; - s.inhow = inhow; - s.left = 0; - s.bitbuf = 0; - s.bitcnt = 0; - - /* initialize output state */ - s.outfun = outfun; - s.outhow = outhow; - s.next = 0; - s.first = 1; - - /* return if bits() or decode() tries to read past available input */ - if (setjmp(s.env) != 0) /* if came back here via longjmp(), */ - err = 2; /* then skip decomp(), return error */ - else - err = decomp(&s); /* decompress */ - - /* write any leftover output and update the error code if needed */ - if (err != 1 && s.next && s.outfun(s.outhow, s.out, s.next) && err == 0) - err = 1; - return err; -} - -#ifdef TEST -/* Example of how to use blast() */ -#include <stdio.h> -#include <stdlib.h> - -#define CHUNK 16384 - -local unsigned inf(void *how, unsigned char **buf) -{ - static unsigned char hold[CHUNK]; - - *buf = hold; - return fread(hold, 1, CHUNK, (FILE *)how); -} - -local int outf(void *how, unsigned char *buf, unsigned len) -{ - return fwrite(buf, 1, len, (FILE *)how) != len; -} - -/* Decompress a PKWare Compression Library stream from stdin to stdout */ -int main(void) -{ - int ret, n; - - /* decompress to stdout */ - ret = blast(inf, stdin, outf, stdout); - if (ret != 0) fprintf(stderr, "blast error: %d\n", ret); - - /* see if there are any leftover bytes */ - n = 0; - while (getchar() != EOF) n++; - if (n) fprintf(stderr, "blast warning: %d unused bytes of input\n", n); - - /* return blast() error code */ - return ret; -} -#endif diff --git a/tools/cpio/src/blast.h b/tools/cpio/src/blast.h deleted file mode 100644 index 0c16d1391..000000000 --- a/tools/cpio/src/blast.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Changes by Gunnar Ritter, Freiburg i. Br., Germany, February 2004. - * - * Sccsid @(#)blast.h 1.2 (gritter) 2/17/04 - */ -/* blast.h -- interface for blast.c - Copyright (C) 2003 Mark Adler - version 1.1, 16 Feb 2003 - - This software is provided 'as-is', without any express or implied - warranty. In no event will the author be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Mark Adler madler@alumni.caltech.edu - */ - - -/* - * blast() decompresses the PKWare Data Compression Library (DCL) compressed - * format. It provides the same functionality as the explode() function in - * that library. (Note: PKWare overused the "implode" verb, and the format - * used by their library implode() function is completely different and - * incompatible with the implode compression method supported by PKZIP.) - */ - - -typedef unsigned (*blast_in)(void *how, unsigned char **buf); -typedef int (*blast_out)(void *how, unsigned char *buf, unsigned len); -/* Definitions for input/output functions passed to blast(). See below for - * what the provided functions need to do. - */ - - -int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow); -/* Decompress input to output using the provided infun() and outfun() calls. - * On success, the return value of blast() is zero. If there is an error in - * the source data, i.e. it is not in the proper format, then a negative value - * is returned. If there is not enough input available or there is not enough - * output space, then a positive error is returned. - * - * The input function is invoked: len = infun(how, &buf), where buf is set by - * infun() to point to the input buffer, and infun() returns the number of - * available bytes there. If infun() returns zero, then blast() returns with - * an input error. (blast() only asks for input if it needs it.) inhow is for - * use by the application to pass an input descriptor to infun(), if desired. - * - * The output function is invoked: err = outfun(how, buf, len), where the bytes - * to be written are buf[0..len-1]. If err is not zero, then blast() returns - * with an output error. outfun() is always called with len <= 4096. outhow - * is for use by the application to pass an output descriptor to outfun(), if - * desired. - * - * The return codes are: - * - * 2: ran out of input before completing decompression - * 1: output error before completing decompression - * 0: successful decompression - * -1: literal flag not zero or one - * -2: dictionary size not in 4..6 - * -3: distance is too far back - * - * At the bottom of blast.c is an example program that uses blast() that can be - * compiled to produce a command-line decompression filter by defining TEST. - */ diff --git a/tools/cpio/src/cpio.1 b/tools/cpio/src/cpio.1 deleted file mode 100644 index 9c8b1f98c..000000000 --- a/tools/cpio/src/cpio.1 +++ /dev/null @@ -1,943 +0,0 @@ -'\" t -.\" Copyright (c) 2003 Gunnar Ritter -.\" -.\" This software is provided 'as-is', without any express or implied -.\" warranty. In no event will the authors be held liable for any damages -.\" arising from the use of this software. -.\" -.\" Permission is granted to anyone to use this software for any purpose, -.\" including commercial applications, and to alter it and redistribute -.\" it freely, subject to the following restrictions: -.\" -.\" 1. The origin of this software must not be misrepresented; you must not -.\" claim that you wrote the original software. If you use this software -.\" in a product, an acknowledgment in the product documentation would be -.\" appreciated but is not required. -.\" -.\" 2. Altered source versions must be plainly marked as such, and must not be -.\" misrepresented as being the original software. -.\" -.\" 3. This notice may not be removed or altered from any source distribution. -.\" Sccsid @(#)cpio.1 1.92 (gritter) 3/26/07 -.TH CPIO 1 "3/26/07" "Heirloom Toolchest" "User Commands" -.SH NAME -cpio \- copy file archives in and out -.SH SYNOPSIS -.PD 0 -.HP -.nh -.ad l -\fBcpio\fR \fB\-i\fR[\fBbcdfkmrstuvBSV6\fR] [\fB\-C\fI\ size\fR] -[\fB\-E\fI\ file\fR] [\fB\-H\fI\ hdr\fR] [[\fB\-I\fI\ file\fR] -[\fB\-M\fI\ msg\fR]] [\fB\-R\fI\ id\fR] [\fIpatterns\fR] -.HP -.ad l -\fBcpio\fR \fB\-o\fR[\fBacvABLPV\fR] [\fB\-C\fI\ size\fR] -[\fB\-H\fI\ hdr\fR] [[\fB\-M\fI\ msg\fR] [\fB\-O\fI\ file\fR]] -.HP -.ad l -\fBcpio\fR \fB\-p\fR[\fBadlmPuvLV\fR] [\fB\-R\fI\ id\fR] \fIdirectory\fR -.br -.PD -.ad b -.hy 1 -.SH DESCRIPTION -.I Cpio -creates and extracts file archives and copies files. -.PP -With the -.B \-i -option, -.I cpio -works in -.RI ` copy-in ' -mode and extracts files from a file archive. -By default, -the archive is read from standard input. -Optional arguments are interpreted as -.I patterns -and restrict the set of extracted files -to those matching any of the -.IR patterns . -A -.RB ` !\& ' -at the beginning of the -.I pattern -selects all files that do not match this -.IR pattern . -The syntax is otherwise identical to that described in -.IR glob (7), -except that the slash character -.RB ` / ' -is matched by -meta-character constructs with -.RB ` * ', -.RB ` ? ' -and -.RB ` [ '. -Care must be taken to quote meta-characters appropriately from the shell. -File permissions are set to those in the archive; -if the caller is the super-user, -ownerships are restored as well. -.I Cpio -will not create directories, -preserve modification times -or overwrite more recently modified target files -unless the appropriate -.IR \-d , -.I \-m -or -.I \-u -options are specified. -Archives compressed with -.IR bzip2 (1), -.IR compress (1), -.IR gzip (1), -or -.IR rpm (1) -are transparently de\%compressed on input. -.PP -With -.BR \-o , -.I cpio -works in -.RI ` copy-out ' -mode, -creates archives -and writes them to standard output per default. -A list of filenames to be included in the archive is -read from standard input; -if the name of a directory appears, -it is included in the archive, -but -.I cpio -will not include any of its members -unless they are explicitly given in addition. -The -.IR find (1) -utility is useful to generate a list of files -(see also its -.I \-cpio -and -.I \-ncpio -operators). -When producing a filename list for -.IR cpio , -find should always be invoked with -.I \-depth -since this makes it possible to extract write-protected directories -for users other than the super-user. -.PP -The -.B \-p -option selects -.RI ` pass ' -mode; -a list of files is read from standard input as described for -.IR \-o ; -files are copied to the specified -.IR directory , -preserving attributes as described for -.IR \-i . -Special files are re-created in the target hierarchy, -and hard links between copied files are preserved. -.PP -When a premature end-of-file is detected with -.I \-i -and -.I \-o -and the archive is a block or character special file, -the user is prompted for new media. -.PP -The following options alter the behavior of -.IR cpio : -.TP -.B \-a -Resets the access times of files -that were included in the archive with -.I \-o -or copied with -.IR \-p . -.TP -.B \-A -Append files to the archive. -The archive must be seekable, -such as a regular file or a block device, -or a tape device capable of writing between filemarks. -.TP -.B \-b -Swap bytes within each half word -and half words within each word -of input file data. -.TP -.B \-B -Blocks input and output archives at 5120 byte records. -The default blocking size is device dependent. -.TP -.B \-c -Specifies that archive headers are in SVR4 ASCII cpio format. -This option is ignored with -.I \-i -unless the -.I \-k -option is also present. -.TP -\fB\-C\fI size\fR -Blocks input and output archives at -.I size -byte records. -.TP -.B \-d -Creates missing parent directories -for each file extracted from the archive -and allows the extraction of directories. -.TP -\fB\-E\fI file\fR -Each line read from -.I file -is taken as a pattern in addition -to those specified on the command line. -.TP -.B \-f -Reverses the sense of patterns -such that a file that does not match any of the patterns -is selected. -.TP -\fB\-H\fI header\fR -Specifies the archive header format to be one of: -.sp -.in +6 -.TS -lfB l. -\fBcrc\fR SVR4 ASCII cpio format with checksum;\ -\fBsco\fR T{ -SCO UnixWare 7.1 ASCII cpio format; -T} -\fBscocrc\fR T{ -SCO UnixWare 7.1 ASCII cpio format with checksum; -T} -\fBodc\fR T{ -traditional ASCII cpio format, as standardized in IEEE Std. 1003.1, 1996; -T} -\fBbbs\fR byte-swapped binary cpio format; -\fBsgi\fR T{ -SGI IRIX extended binary cpio format; -T} -\fBcray\fR T{ -Cray UNICOS 9 cpio format; -T} -\fBcray5\fR T{ -Cray UNICOS 5 cpio format; -T} -\fBdec\fR T{ -Digital UNIX extended cpio format; -T} -\fBtar\fR tar format; -\fBotar\fR old tar format; -\fBustar\fR T{ -IEEE Std. 1003.1, 1996 tar format; -T} -.T& -l s. -\fBpax\fR[\fB:\fIoption\fB,\fR[\fIoption\fB,\fR\|...]] -.T& -l l. -\& T{ -IEEE Std. 1003.1, 2001 pax format. -Format-specific \fIoptions\fR are: -.in +2n -.ti 0 -.br -\fBlinkdata\fR -.br -For a regular file which has multiple hard links, -the file data is stored once for each link in the archive, -instead of being stored for the first entry only. -This option must be used with care -since many implementations are unable -to read the resulting archive. -.ti 0 -.br -\fBtimes\fR -.br -Causes the times of last access and last modification -of each archived file -to be stored in an extended \fIpax\fR header. -This in particular allows the time of last access -to be restored when the archive is read. -.br -.in -2n -T} -\fBsun\fR T{ -Sun Solaris 7 extended tar format; -T} -\fBgnu\fR T{ -GNU tar format; -T} -\fBbar\fR T{ -SunOS 4 bar format; -T} -\fBzip\fR[\fB:\fIcc\fR] T{ -zip format with optional compression method. -If \fIcc\fR is one of -\fBen\fR (normal, default), -\fBex\fR (extra), -\fBef\fR (fast), -or -\fBes\fR (super fast), -the standard \fIdeflate\fR compression is used. -\fBe0\fR selects no compression, -and -\fBbz2\fR selects \fIbzip2\fR compression. -T} -.TE -.in -6 -.sp -This option is ignored with -.I \-i -unless the -.I \-k -option is also present. -The default for -.I \-o -is binary cpio format. -.TP -\fB\-I\fI\ file\fR -Selects a -.I file -that is read with the -.I \-i -option instead of standard input. -.TP -.B \-k -Try to continue operation on read errors and invalid headers. -If an archive contains another archive, -files from either archive may be chosen. -.TP -.B \-l -Link files instead of copying them with -.I \-p -if possible. -.TP -.B \-L -Follow symbolic links when reading files with -.I \-o -or -.IR \-p . -.TP -.B \-m -Restore modification times of extracted files -to those given in the archive. -.TP -\fB\-M\fI message\fR -The given -.I message -is printed instead of the standard one -with -.I \-I -or -.I \-O -when changing media. -.TP -\fB\-O\fI file\fR -Selects an archive -.I file -that is written instead of standard output -with the -.I \-o -option. -.TP -.B \-P -In copy-out or pass mode, -interpret the data read from standard input -as prototype lines -of colon-separated fields -of the form -.in +3m -.sp -\fItype\fB:\fIuser\fB:\fIgroup\fB:\fImode\fB:\fIatime\fB:\fImtime\fB:\fImajor\fB:\fIminor\fB:\fIpath\fR -.sp -.in -3m -For each non-empty field, -the corresponding attribute of the input file is overridden. -With this option, -an unprivileged user can create -an archive that contains files -with arbitrary attributes. -The meanings of the individual fields are: -.RS -.TP 6 -.PD 0 -.I type -File type, one of: -\fBb\fR (block device), -\fBc\fR (character device), -\fBd\fR (directory), -\fBf\fR (plain file), -\fBp\fR (named pipe), -or -\fBs\fR (symbolic link). -.TP -.I user -The owner of the file, -which can be a numeric user ID or a user name. -.TP -.I group -The group owner of the file, -which can be a numeric group ID or a group name. -.TP -.I mode -The octal mode of the file. -.TP -.I atime -The time the file was last accessed. -Note that most archive formats cannot store this attribute, -in which case it is ignored. -The format is the same as that of the -.I mtime -field. -.TP -.I mtime -The time the file was last modified. -This is either a decimal integer -specifying the seconds past the epoch, -or an ISO\ 8601 date and time field -of the format \fIYYYYMMDD\fBT\fIHHMMSS\fR, -e.g. 20070326T190511, -the latter being relative to the current time zone -and with all digits past the \fBT\fR being optional. -.TP -.I major minor -Major and minor device numbers as with -.IR mknod (1M). -These fields are only allowed for block and character devices. -.TP -.I path -The name of the file to be archived. -If the file is not a symbolic link, -and the specification is otherwise sufficient, -the file needs not exist -at the time the archive is created. -A non-existent regular file will be empty in the archive. -.PD -.RE -.IP -This option is an extension. -.TP -.B \-r -Rename files interactively. -Before a file is extracted from the archive, -its file name is printed on standard error -and the user is prompted to specify a substitute file name. -If the line read from the terminal is empty, -the file is skipped; -if the line consists of a single dot, -the name is retained; -otherwise, -the line forms the new file name. -.TP -\fB\-R\fI user\fR -Set the ownership of extracted files -to the user and group ids of -.I user -instead of those specified in the archive. -Valid only for the super-user. -.TP -.B \-s -Swap bytes within each half word -of input file data. -.TP -.B \-S -Swap half words within each word -of input file data. -.TP -.B \-t -When combined with the -.I \-o -option, -a list of files in the archive is written to standard output; -no files are extracted. -.TP -.B \-u -.I Cpio -will overwrite existing target files -that were modified more recently than the file in the archive -when this option is given. -.TP -.B \-v -Prints the file names of archived or extracted files with -.I \-i -and -.I \-o -and a verbose output format with -.IR \-t . -If given twice -.RB ( \-vv ) -in combination with -.I \-t -when reading a -.I zip -archive, -information about compression level and method is printed. -.TP -.B \-V -Prints a dot for each archived or extracted file. -.TP -.B \-6 -Selects Unix 6th Edition archive format -(only in copy-in mode). -.PP -.ne 37 -Characteristics of archive formats are as follows: -.sp -.TS -allbox; -l r r r l -l1fB r2 n2 r2 c. - T{ -.ad l -maximum user/\%group id -T} T{ -.ad l -maximum file size -T} T{ -.ad l -maximum pathname length -T} T{ -.ad l -bits in dev_t (major/minor) -T} -binary 65535 2 GB\ 256 \ 16 -\-H\ sgi 65535 9 EB\ 256 \ 14/18 -\-H\ odc 262143 8 GB\ 256 \ 18 -\-H\ dec 262143 8 GB\ 256 \ 24/24 -T{ -\-c, \-H\ crc -T} 4.3e9 4 GB\ 1024 \ 32/32 -T{ -\-H\ sco, \-H\ scocrc -T} 4.3e9 9 EB\ 1024 \ 32/32 -T{ -\-H\ cray, \-H\ cray5 -T} 1.8e19 9 EB\ 65535 \ 64 -\-H\ otar 2097151 8 GB\ 99 \ n/a -T{ -\-H\ tar, -\-H\ ustar -T} 2097151 8 GB\ 256 (99) \ 21/21 -\-H\ pax 1.8e19 9 EB\ 65535 \ 21/21 -\-H\ sun 1.8e19 9 EB\ 65535 \ 63/63 -\-H\ gnu 1.8e19 9 EB\ 65535 \ 63/63 -\-H\ bar 2097151 8 GB\ 427 \ 21 -\-H\ zip 4.3e9 9 EB\ 60000 \ 32 -.TE -.sp -.PP -By default, -.B binary -cpio archives are written. -The byte order of such archives -depends on the machine -on which the archive is created. -Unlike some other implementations, -.I cpio -fully supports -archives of either byte order. -.I \-H\ bbs -can be used to create an archive -with the byte order opposed to that of the current machine. -.PP -The -.B sgi -format extends the binary format -to handle larger files and more device bits. -If an archive does not contain any entries -that actually need the extensions, -it is identical to a binary archive. -.I \-H\ sgi -archives are always created in MSB order. -.PP -The -.B odc -format was introduced with System\ III -and standardized with IEEE Std. 1003.1. -All known -.I cpio -implementations since around 1980 can read this format. -.PP -The -.B dec -format extends the -.I odc -format -to support more device bits. -Archives in this format are generally incompatible with -.I odc -archives -and need special implementation support to be read. -.PP -The -.B \-c -format was introduced with System\ V Release\ 4. -Except for the file size, -it imposes no practical limitations -on files archived. -The original SVR4 implementation -stores the contents of hard linked files -only once and with the last archived link. -This -.I cpio -ensures compatibility with SVR4. -With archives created by implementations that employ other methods -for storing hard linked files, -each file is extracted as a single link, -and some of these files may be empty. -Implementations that expect methods other than the original SVR4 one -may extract no data for hard linked files at all. -.PP -The -.B crc -format is essentially the same as the -.I \-c -format -but adds a simple checksum (not a CRC, despite its name) -for the data of regular files. -The checksum requires the implementation to read each file twice, -which can considerably increase running time and system overhead. -As not all implementations claiming to support this format -handle the checksum correctly, -it is of limited use. -.PP -The -.B sco -and -.B scocrc -formats are variants of the -.I \-c -and -.I \-H\ crc -formats, respectively, -with extensions to support larger files. -The extensions result in a different archive format -only if files larger than slightly below 2\ GB occur. -.PP -The -.B cray -format extends all header fields to 64 bits. -It thus imposes no practical limitations of any kind -on archived files, -but requires special implementation support -to be read. -Although it is originally a binary format, -the byte order is always MSB as on Cray machines. -The -.B cray5 -format is an older variant -that was used with UNICOS 5 and earlier. -.PP -The -.B otar -format was introduced with the Unix 7th Edition -.I tar -utility. -Archives in this format -can be read on all Unix systems since about 1980. -It can only hold regular files -(and, on more recent systems, symbolic links). -For file names that contain characters with the most significant bit set -(non-ASCII characters), -implementations differ in the interpretation of the header checksum. -.PP -The -.B ustar -format was introduced with IEEE Std. 1003.1. -It extends the old -.I tar -format -with support for directories, device files, -and longer file names. -Pathnames of single-linked files can consist of up to 256 characters, -dependent on the position of slashes. -Files with multiple links can only be archived -if the first link encountered is no longer than 100 characters. -Due to implementation errors, -file names longer than 99 characters -can not considered to be generally portable. -Another addition of the -.I ustar -format -are fields for the symbolic user and group IDs. -These fields are created by -.IR cpio , -but ignored when reading such archives. -.PP -With -.BR "\-H tar" , -a variant of the -.I ustar -format is selected -which stores file type bits in the mode field -to work around common implementation problems. -These bits are ignored by -.I cpio -when reading archives. -.PP -The -.B pax -format is an extension to the -.I ustar -format. -If attributes cannot be archived with -.IR ustar , -an extended header is written. -Unless the size of an entry is greater than 8\ GB, -a -.I pax -archive should be readable by any implementation -capable of reading -.I ustar -archives, -although files may be extracted under wrong names -and extended headers may be extracted as separate files. -If a file name contains non-UTF-8 characters, -it may not be archived or extracted correctly -because of a problem of the -.I pax -format specification. -.PP -The -.B sun -format extends the -.I ustar -format similar as the -.I pax -format does. -The extended headers in -.I sun -format archives are not understood -by implementations that support only the -.I pax -format and vice-versa. -The -.I sun -format has also problems with non-UTF-8 characters in file names. -.PP -The -.B GNU -.I tar -format is mostly compatible with the other -.I tar -formats, -unless an archive entry actually uses its extended features. -There are no practical limitations on files archived with this format. -The implementation of -.I cpio -is limited to expanded numerical fields -and long file names; -in particular, -there is no support for sparse files or incremental backups. -If -.I cpio -creates a multi-volume -.I GNU -archive, -it just splits a single-volume archive in multiple parts, -as with the other formats; -.I GNU -multi-volume archives are not supported. -.PP -The -.B bar -format is similar to the -.I tar -format, but can store longer file names. -It requires special implementation support to be read. -.PP -The -.B zip -format can be read in many non-Unix environments. -There are several restrictions on archives -intended for data exchange: -only regular files should be stored; -file times, permissions and ownerships -might be ignored by other implementations; -there should be no more than 65536 files in the archive; -the total archive size should not exceed 2 GB; -only -.I deflate -compression should be used. -Otherwise, -.I cpio -stores all information available with other archive formats -in extended -.I zip -file headers, -so if archive portability is of no concern, -the -.I zip -implementation in -.I cpio -can archive complete Unix file hierarchies. -.I Cpio -supports the -.I zip64 -format extension for large files; -it automatically writes -.I zip64 -entries if necessary. -.I Cpio -can extract all known -.I zip -format compression codes. -It does not support -.I zip -encryption. -Multi-volume -.I zip -archives are created as splitted single-volume archives, -as with the other formats written by -.IR cpio ; -generic multi-volume -.I zip -archives are not supported. -.SH EXAMPLES -Extract all files named -.I Makefile -or -.I makefile -from the archive stored on -.IR /dev/rmt/c0s0 , -overwriting recent files: -.RS 2 -.sp -cpio \-idmu \-I /dev/rmt/c0s0 \'[Mm]akefile\' \'*/[Mm]akefile\' -.RE -.PP -List the files contained in a software distribution archive: -.RS 2 -.sp -cpio \-itv \-I distribution.tar.gz -.RE -.PP -Write a -.IR gzip (1) -compressed -.I ustar -archive containing all files below the directory -.I \%project -to the file -.IR \%project.tar.gz , -excluding all directories named -.I CVS -or -.I SCCS -and their contents: -.RS 2 -.sp -find project \-depth \-print | egrep \-v \'/(CVS|SCCS)(/|$)\' | -.br - cpio \-o \-H ustar | gzip \-c > project.tar.gz -.RE -.PP -Copy the directory -.I work -and its contents -to the directory -.IR \%savedfiles : -.RS 2 -.sp -find work \-depth \-print | cpio \-pdm savedfiles -.RE -.PP -Self-extracting zip archives are not automatically recognized, -but can normally be read using the -.I \-k -option, as with -.RS 2 -.sp -cpio \-itvk \-H zip \-I archive.exe -.sp -.RE -.SH "ENVIRONMENT VARIABLES" -.TP -.BR LANG ", " LC_ALL -See -.IR locale (7). -.TP -.B LC_CTYPE -Selects the mapping of bytes to characters -used for matching patterns. -.TP -.B LC_TIME -Sets the month names printed with -.IR \-tv . -.TP -.B SYSV3 -If this variable is set, -the -.I \-c -option has the same effect as \fI\-H odc\fR; -\fB\-H newc\fR can be used -to select SVR4 ASCII format. -The output format of -.I \-tv -is changed, as well as the text of diagnostic messages. -.SH "SEE ALSO" -find(1), -pax(1), -tar(1) -.SH DIAGNOSTICS -.I Cpio -exits with -.sp -.TS -l8fB l. -0 after successful operation; -1 on usage errors; -2 when operation was continued after minor errors; -3 on fatal error conditions. -.TE -.SH NOTES -Device and inode numbers -are used for hard link recognition -with the various cpio formats. -Since the header space cannot hold -large numbers present in current file systems, -devices and inode numbers are set on a per-archive basis. -This enables hard link recognition with all cpio formats, -but the link connection to files appended with -.I \-A -is not preserved. -.PP -If a numeric user or group id does not fit -within the size of the header field in the selected format, -files are stored with the user id (or group id, respectively) -set to 60001. -.PP -Use of the -.I \-A -option with a -.I zip -format archive may cause data loss -if the archive was not previously created by -.I cpio -itself. -.PP -.I Cpio -cannot store file names that contain newline characters; -see the -.I NOTES -section of -.IR find (1) -for more information. -.PP -If the file names passed to -.I "cpio \-o" -begin with a slash character, -absolute path names are stored in the archive -and will be extracted to these path names later -regardless of the current working directory. -This is normally not advisable, -and relative path names should be passed to -.I cpio -only. diff --git a/tools/cpio/src/cpio.c b/tools/cpio/src/cpio.c deleted file mode 100644 index e5090e4c9..000000000 --- a/tools/cpio/src/cpio.c +++ /dev/null @@ -1,7172 +0,0 @@ -/* - * cpio - copy file archives in and out - * - * Gunnar Ritter, Freiburg i. Br., Germany, April 2003. - */ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ - -/* - * Sccsid @(#)cpio.c 1.304 (gritter) 2/14/09 - */ - -#include <sys/types.h> -#include <sys/stat.h> -#ifdef __linux__ -#if !defined (__UCLIBC__) && !defined (__dietlibc__) -#include <linux/fs.h> -#endif /* !__UCLIBC__, !__dietlibc__ */ -#include <linux/fd.h> -#undef WNOHANG -#undef WUNTRACED -#undef P_ALL -#undef P_PID -#undef P_PGID -#ifdef __dietlibc__ -#undef NR_OPEN -#undef PATH_MAX -#endif /* __dietlibc__ */ -#endif /* __linux__ */ -#include <sys/wait.h> -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <signal.h> -#include "sigset.h" -#include <time.h> -#include <utime.h> -#include <pwd.h> -#include <grp.h> -#include <limits.h> -#include <stdio.h> -#include <libgen.h> -#include <errno.h> -#include <inttypes.h> -#include <stdarg.h> -#include <locale.h> -#include <ctype.h> -#include "memalign.h" - -int sysv3; - -#if USE_ZLIB -#include <zlib.h> -#endif /* USE_ZLIB */ - -#if USE_BZLIB -#include <bzlib.h> -#endif /* USE_BZLIB */ - -#include <sys/ioctl.h> - -#if defined (__linux__) || defined (__sun) || defined (__FreeBSD__) || \ - defined (__hpux) || defined (_AIX) || defined (__NetBSD__) || \ - defined (__OpenBSD__) || defined (__DragonFly__) || \ - defined (__CYGWIN__) -#include <sys/mtio.h> -#endif - -#include <iblok.h> -#include <sfile.h> -#include <atoll.h> - -#ifdef _AIX -#include <sys/sysmacros.h> -#endif /* _AIX */ - -#ifndef major -#include <sys/mkdev.h> -#endif /* !major */ - -#include "cpio.h" -#include "blast.h" - -#ifdef __GLIBC__ -#ifdef _IO_putc_unlocked -#undef putc -#define putc(c, f) _IO_putc_unlocked(c, f) -#undef putchar -#define putchar(c) _IO_putc_unlocked(c, stdout) -#endif /* _IO_putc_unlocked */ -#endif /* __GLIBC__ */ - -/* - * The cpio code assumes that all following S_IFMT bits are the same as - * those of the mode fields in cpio headers. The only real Unix system - * known to deviate from this de facto standard is UNICOS which uses - * 0130000 for S_IFLNK. But this software does not run on UNICOS for - * a variety of other reasons anyway, so this should not be of much - * concern. - */ -#if S_IFIFO != 0010000 || \ - S_IFCHR != 0020000 || \ - S_IFDIR != 0040000 || \ - S_IFBLK != 0060000 || \ - S_IFREG != 0100000 || \ - S_IFLNK != 0120000 || \ - S_IFSOCK!= 0140000 || \ - S_IFMT != 0170000 -#error non-standard S_IFMT bits -#endif - -/* - * File types that are not present on all systems but that we want to - * recognize nevertheless. - */ -#ifndef S_IFDOOR -#define S_IFDOOR 0150000 /* Solaris door */ -#endif -#ifndef S_IFNAM -#define S_IFNAM 0050000 /* XENIX special named file */ -#endif -#ifndef S_INSEM -#define S_INSEM 0x1 /* XENIX semaphore subtype of IFNAM */ -#endif -#ifndef S_INSHD -#define S_INSHD 0x2 /* XENIX shared data subtype of IFNAM */ -#endif -#ifndef S_IFNWK -#define S_IFNWK 0110000 /* HP-UX network special file */ -#endif - -#if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || \ - defined (__DragonFly__) || defined (__APPLE__) -/* - * For whatever reason, FreeBSD casts the return values of major() and - * minor() to signed values so that normal limit comparisons will fail. - */ -static unsigned long -mymajor(long dev) -{ - return major(dev) & 0xFFFFFFFFUL; -} -#undef major -#define major(a) mymajor(a) -static unsigned long -myminor(long dev) -{ - return minor(dev) & 0xFFFFFFFFUL; -} -#undef minor -#define minor(a) myminor(a) -#endif /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ - -/* - * Device and inode counts in cpio formats are too small to store the - * information used to detect hard links on today's systems. Keep track - * of all devices and inodes and store fake counts in the archive. - */ -struct ilink { - struct ilink *l_nxt; /* next link to same i-node */ - char *l_nam; /* link name */ - size_t l_siz; /* link name size */ -}; - -struct islot { - struct islot *i_lln; /* left link */ - struct islot *i_rln; /* right link */ - struct ilink *i_lnk; /* links list */ - struct stat *i_st; /* stat information */ - char *i_name;/* name of first link encountered */ - ino_t i_ino; /* real inode number */ - uint32_t i_fino; /* fake inode number */ - nlink_t i_nlk; /* number of remaining links */ -}; - -struct dslot { - struct dslot *d_nxt; /* next device */ - struct islot *d_isl; /* inode slots */ - uint32_t d_cnt; /* used inode number count */ - uint32_t d_fake; /* faked device id */ - dev_t d_dev; /* real device id */ -}; - -union types2 { - uint8_t byte[2]; - uint16_t sword; -}; - -union types4 { - uint8_t byte[4]; - uint16_t sword[2]; - uint32_t lword; -}; - -/* - * Store and retrieve integers in a defined endian order. - */ -static uint16_t -ple16(const char *cp) -{ - return (uint16_t)(cp[0]&0377) + - ((uint16_t)(cp[1]&0377) << 8); -} - -static uint16_t -pbe16(const char *cp) -{ - return (uint16_t)(cp[1]&0377) + - ((uint16_t)(cp[0]&0377) << 8); -} - -static uint32_t -ple32(const char *cp) -{ - return (uint32_t)(cp[0]&0377) + - ((uint32_t)(cp[1]&0377) << 8) + - ((uint32_t)(cp[2]&0377) << 16) + - ((uint32_t)(cp[3]&0377) << 24); -} - -static uint32_t -pbe32(const char *cp) -{ - return (uint32_t)(cp[3]&0377) + - ((uint32_t)(cp[2]&0377) << 8) + - ((uint32_t)(cp[1]&0377) << 16) + - ((uint32_t)(cp[0]&0377) << 24); -} - -static uint32_t -pme32(const char *cp) -{ - return (uint32_t)(cp[2]&0377) + - ((uint32_t)(cp[3]&0377) << 8) + - ((uint32_t)(cp[0]&0377) << 16) + - ((uint32_t)(cp[1]&0377) << 24); -} - -static uint64_t -ple64(const char *cp) -{ - return (uint64_t)(cp[0]&0377) + - ((uint64_t)(cp[1]&0377) << 8) + - ((uint64_t)(cp[2]&0377) << 16) + - ((uint64_t)(cp[3]&0377) << 24) + - ((uint64_t)(cp[4]&0377) << 32) + - ((uint64_t)(cp[5]&0377) << 40) + - ((uint64_t)(cp[6]&0377) << 48) + - ((uint64_t)(cp[7]&0377) << 56); -} - -static uint64_t -pbe64(const char *cp) -{ - return (uint64_t)(cp[7]&0377) + - ((uint64_t)(cp[6]&0377) << 8) + - ((uint64_t)(cp[5]&0377) << 16) + - ((uint64_t)(cp[4]&0377) << 24) + - ((uint64_t)(cp[3]&0377) << 32) + - ((uint64_t)(cp[2]&0377) << 40) + - ((uint64_t)(cp[1]&0377) << 48) + - ((uint64_t)(cp[0]&0377) << 56); -} - -static void -le16p(uint16_t n, char *cp) -{ - cp[0] = (n&0x00ff); - cp[1] = (n&0xff00) >> 8; -} - -static void -be16p(uint16_t n, char *cp) -{ - cp[1] = (n&0x00ff); - cp[0] = (n&0xff00) >> 8; -} - -static void -le32p(uint32_t n, char *cp) -{ - cp[0] = (n&0x000000ff); - cp[1] = (n&0x0000ff00) >> 8; - cp[2] = (n&0x00ff0000) >> 16; - cp[3] = (n&0xff000000) >> 24; -} - -static void -be32p(uint32_t n, char *cp) -{ - cp[3] = (n&0x000000ff); - cp[2] = (n&0x0000ff00) >> 8; - cp[1] = (n&0x00ff0000) >> 16; - cp[0] = (n&0xff000000) >> 24; -} - -static void -me32p(uint32_t n, char *cp) -{ - cp[2] = (n&0x000000ff); - cp[3] = (n&0x0000ff00) >> 8; - cp[0] = (n&0x00ff0000) >> 16; - cp[1] = (n&0xff000000) >> 24; -} - -static void -le64p(uint64_t n, char *cp) -{ - cp[0] = (n&0x00000000000000ffLL); - cp[1] = (n&0x000000000000ff00LL) >> 8; - cp[2] = (n&0x0000000000ff0000LL) >> 16; - cp[3] = (n&0x00000000ff000000LL) >> 24; - cp[4] = (n&0x000000ff00000000LL) >> 32; - cp[5] = (n&0x0000ff0000000000LL) >> 40; - cp[6] = (n&0x00ff000000000000LL) >> 48; - cp[7] = (n&0xff00000000000000LL) >> 56; -} - -static void -be64p(uint64_t n, char *cp) -{ - cp[7] = (n&0x00000000000000ffLL); - cp[6] = (n&0x000000000000ff00LL) >> 8; - cp[5] = (n&0x0000000000ff0000LL) >> 16; - cp[4] = (n&0x00000000ff000000LL) >> 24; - cp[3] = (n&0x000000ff00000000LL) >> 32; - cp[2] = (n&0x0000ff0000000000LL) >> 40; - cp[1] = (n&0x00ff000000000000LL) >> 48; - cp[0] = (n&0xff00000000000000LL) >> 56; -} - -#define TNAMSIZ 100 -#define TPFXSIZ 155 -#define TMAGSIZ 6 -#define TTIMSIZ 12 - -/* - * Structure of an archive header. - */ -union bincpio { - char data[4096]; -#define SIZEOF_hdr_cpio 26 - struct hdr_cpio { - char c_magic[2]; - char c_dev[2]; - char c_ino[2]; - char c_mode[2]; - char c_uid[2]; - char c_gid[2]; - char c_nlink[2]; - char c_rdev[2]; - char c_mtime[4]; - char c_namesize[2]; - char c_filesize[4]; - } Hdr; -#define SIZEOF_cray_hdr 152 - struct cray_hdr { /* with thanks to Cray-Cyber.org */ - char C_magic[8]; - char C_dev[8]; - char C_ino[8]; - char C_mode[8]; - char C_uid[8]; - char C_gid[8]; - char C_nlink[8]; - char C_rdev[8]; - /* - * The C_param field was introduced with - * UNICOS 6 and is simply not present in - * the earlier format. Following fields - * are the same for both revisions again. - */ -#define CRAY_PARAMSZ (8*8) - char C_param[CRAY_PARAMSZ]; - char C_mtime[8]; - char C_namesize[8]; - char C_filesize[8]; - } Crayhdr; -#define SIZEOF_c_hdr 76 - struct c_hdr { - char c_magic[6]; - char c_dev[6]; - char c_ino[6]; - char c_mode[6]; - char c_uid[6]; - char c_gid[6]; - char c_nlink[6]; - char c_rdev[6]; - char c_mtime[11]; - char c_namesz[6]; - char c_filesz[11]; - } Cdr; -#define SIZEOF_d_hdr 86 - struct d_hdr { - char d_magic[6]; - char d_dev[6]; - char d_ino[6]; - char d_mode[6]; - char d_uid[6]; - char d_gid[6]; - char d_nlink[6]; - char d_rmaj[8]; - char d_rmin[8]; - char d_mtime[11]; - char d_namesz[6]; - char d_filesz[11]; - } Ddr; -#define SIZEOF_Exp_cpio_hdr 110 - struct Exp_cpio_hdr { - char E_magic[6]; - char E_ino[8]; - char E_mode[8]; - char E_uid[8]; - char E_gid[8]; - char E_nlink[8]; - char E_mtime[8]; - char E_filesize[8]; - char E_maj[8]; - char E_min[8]; - char E_rmaj[8]; - char E_rmin[8]; - char E_namesize[8]; - char E_chksum[8]; - } Edr; - struct tar_header { - char t_name[TNAMSIZ]; - char t_mode[8]; - char t_uid[8]; - char t_gid[8]; - char t_size[12]; - char t_mtime[TTIMSIZ]; - char t_chksum[8]; - char t_linkflag; - char t_linkname[TNAMSIZ]; - char t_magic[TMAGSIZ]; - char t_version[2]; - char t_uname[32]; - char t_gname[32]; - char t_devmajor[8]; - char t_devminor[8]; - char t_prefix[TPFXSIZ]; - } Tdr; -#define SIZEOF_bar_header 84 - struct bar_header { - char b_mode[8]; - char b_uid[8]; - char b_gid[8]; - char b_size[12]; - char b_mtime[12]; - char b_chksum[8]; - char b_rdev[8]; - char b_linkflag; - char b_bar_magic[2]; - char b_volume_num[4]; - char b_compressed; - char b_date[12]; - } Bdr; -#define SIZEOF_zip_header 30 - struct zip_header { - char z_signature[4]; - char z_version[2]; - char z_gflag[2]; - char z_cmethod[2]; - char z_modtime[2]; - char z_moddate[2]; - char z_crc32[4]; - char z_csize[4]; - char z_nsize[4]; - char z_namelen[2]; - char z_extralen[2]; - } Zdr; -}; - -#define BCUT 0177777 -#define OCUT 0777777 -#define ECUT 0xFFFFFFFFUL - -static const char trailer[] = "TRAILER!!!"; - -/* - * Structure of per-file extra data for zip format. - */ -union zextra { - char data[1]; -#define SIZEOF_zextra_gn 4 - struct zextra_gn { - char ze_gn_tag[2]; - char ze_gn_tsize[2]; - } Ze_gn; -#define SIZEOF_zextra_64 32 /* regular size */ -#define SIZEOF_zextra_64_a 28 /* size without startn field */ -#define SIZEOF_zextra_64_b 20 /* size without reloff field */ - struct zextra_64 { - char ze_64_tag[2]; - char ze_64_tsize[2]; - char ze_64_nsize[8]; - char ze_64_csize[8]; - char ze_64_reloff[8]; - char ze_64_startn[4]; - } Ze_64; -#define SIZEOF_zextra_pk 16 - struct zextra_pk { - char ze_pk_tag[2]; - char ze_pk_tsize[2]; - char ze_pk_atime[4]; - char ze_pk_mtime[4]; - char ze_pk_uid[2]; - char ze_pk_gid[2]; - } Ze_pk; -#define SIZEOF_zextra_ek 17 - struct zextra_et { - char ze_et_tag[2]; - char ze_et_tsize[2]; - char ze_et_flags[1]; - char ze_et_mtime[4]; - char ze_et_atime[4]; - char ze_et_ctime[4]; - } Ze_et; -#define SIZEOF_zextra_i1 16 - struct zextra_i1 { - char ze_i1_tag[2]; - char ze_i1_tsize[2]; - char ze_i1_atime[4]; - char ze_i1_mtime[4]; - char ze_i1_uid[2]; - char ze_i1_gid[2]; - } Ze_i1; -#define SIZEOF_zextra_i2 8 - struct zextra_i2 { - char ze_i2_tag[2]; - char ze_i2_tsize[2]; - char ze_i2_uid[2]; - char ze_i2_gid[2]; - } Ze_i2; -#define SIZEOF_zextra_as 16 - struct zextra_as { - char ze_as_tag[2]; - char ze_as_tsize[2]; - char ze_as_crc[4]; - char ze_as_mode[2]; - char ze_as_sizdev[4]; - char ze_as_uid[2]; - char ze_as_gid[2]; - } Ze_as; -#define SIZEOF_zextra_cp 40 - struct zextra_cp { - char ze_cp_tag[2]; - char ze_cp_tsize[2]; - char ze_cp_dev[4]; - char ze_cp_ino[4]; - char ze_cp_mode[4]; - char ze_cp_uid[4]; - char ze_cp_gid[4]; - char ze_cp_nlink[4]; - char ze_cp_rdev[4]; - char ze_cp_mtime[4]; - char ze_cp_atime[4]; - } Ze_cp; -}; - -static struct zipstuff { /* stuff for central directory at EOF */ - struct zipstuff *zs_next; - char *zs_name; /* file name */ - long long zs_size; /* file size */ - long long zs_relative; /* offset of local header */ - long long zs_csize; /* compressed size */ - uint32_t zs_crc32; /* CRC */ - time_t zs_mtime; /* modification time */ - enum cmethod zs_cmethod; /* compression method */ - int zs_gflag; /* general flag */ - mode_t zs_mode; /* file mode */ -} *zipbulk; - -/* - * Structure of the central zip directory at the end of the file. This - * (obligatory) part of a zip file is written by this implementation, - * but is completely ignored on copy-in. This means that we miss the - * mode_t stored in zc_extralen if zc_versionmade[1] is 3 (Unix). We - * have to do this since it contains the S_IFMT bits, thus telling us - * whether something is a symbolic link and resulting in different - * behavior - but as the input had to be seekable in order to do this, - * we had to store entire archives in temporary files if input came - * from a pipe to be consistent. - */ -#define SIZEOF_zipcentral 46 -struct zipcentral { - char zc_signature[4]; - char zc_versionmade[2]; - char zc_versionextr[2]; - char zc_gflag[2]; - char zc_cmethod[2]; - char zc_modtime[2]; - char zc_moddate[2]; - char zc_crc32[4]; - char zc_csize[4]; - char zc_nsize[4]; - char zc_namelen[2]; - char zc_extralen[2]; - char zc_commentlen[2]; - char zc_disknstart[2]; - char zc_internal[2]; - char zc_external[4]; - char zc_relative[4]; -}; - -#define SIZEOF_zip64end 56 -struct zip64end { - char z6_signature[4]; - char z6_recsize[8]; - char z6_versionmade[2]; - char z6_versionextr[2]; - char z6_thisdiskn[4]; - char z6_alldiskn[4]; - char z6_thisentries[8]; - char z6_allentries[8]; - char z6_dirsize[8]; - char z6_startsize[8]; -}; - -#define SIZEOF_zip64loc 20 -struct zip64loc { - char z4_signature[4]; - char z4_startno[4]; - char z4_reloff[8]; - char z4_alldiskn[4]; -}; - -#define SIZEOF_zipend 22 -struct zipend { - char ze_signature[4]; - char ze_thisdiskn[2]; - char ze_alldiskn[2]; - char ze_thisentries[2]; - char ze_allentries[2]; - char ze_dirsize[4]; - char ze_startsize[4]; - char ze_commentlen[2]; -}; - -#define SIZEOF_zipddesc 16 -struct zipddesc { - char zd_signature[4]; - char zd_crc32[4]; - char zd_csize[4]; - char zd_nsize[4]; -}; - -#define SIZEOF_zipddesc64 24 -struct zipddesc64 { - char zd_signature[4]; - char zd_crc32[4]; - char zd_csize[8]; - char zd_nsize[8]; -}; - -/* - * Magic numbers and strings. - */ -static const uint16_t mag_bin = 070707; -/*static const uint16_t mag_bbs = 0143561;*/ -static const char mag_asc[6] = "070701"; -static const char mag_crc[6] = "070702"; -static const char mag_odc[6] = "070707"; -static const long mag_sco = 0x7ffffe00; - -static const char mag_ustar[6] = "ustar\0"; -static const char mag_gnutar[8] = "ustar \0"; -static const char mag_bar[2] = "V\0"; - -static const char mag_zipctr[4] = "PK\1\2"; -static const char mag_zipsig[4] = "PK\3\4"; -static const char mag_zipend[4] = "PK\5\6"; -static const char mag_zip64e[4] = "PK\6\6"; -static const char mag_zip64l[4] = "PK\6\7"; -static const char mag_zipdds[4] = "PK\7\10"; -#define mag_zip64f 0x0001 -#define mag_zipcpio 0x0707 - -/* - * Fields for the extended pax header. - */ -static enum paxrec { - PR_NONE = 0000, - PR_ATIME = 0001, - PR_GID = 0002, - PR_LINKPATH = 0004, - PR_MTIME = 0010, - PR_PATH = 0020, - PR_SIZE = 0040, - PR_UID = 0100, - PR_SUN_DEVMAJOR = 0200, - PR_SUN_DEVMINOR = 0400 -} paxrec, globrec; - -/* - * Prototype structure, collecting user-defined information - * about a file. - */ -struct prototype { - mode_t pt_mode; /* type and permission bits */ - uid_t pt_uid; /* owner */ - gid_t pt_gid; /* group owner */ - time_t pt_atime; /* time of last access */ - time_t pt_mtime; /* time of last modification */ - dev_t pt_rdev; /* device major/minor */ - enum { - PT_NONE = 0000, - PT_TYPE = 0001, - PT_OWNER = 0002, - PT_GROUP = 0004, - PT_MODE = 0010, - PT_ATIME = 0020, - PT_MTIME = 0040, - PT_RDEV = 0100 - } pt_spec; /* specified information */ -}; - -static struct stat globst; - -/* - * This sets a sanity check limit on path names. If a longer path name - * occurs in an archive, it is treated as corrupt. This is because no - * known Unix system can handle path names of arbitrary length; limits - * are typically between 1024 and 4096. Trying to extract longer path - * names would fail anyway and will cpio eventually fail to allocate - * memory. - */ -#define SANELIMIT 0177777 - -char *progname; /* argv[0] to main() */ -static struct dslot *devices; /* devices table */ -static struct dslot *markeddevs; /* unusable device numbers */ -static char *blkbuf; /* block buffer */ -int blksiz; /* block buffer size */ -static int blktop; /* top of filled part of buffer */ -static int curpos; /* position in blkbuf */ -static uint32_t fakedev; /* fake device for single link inodes */ -static uint32_t fakeino; /* fake inode for single link inodes */ -static uint32_t harddev; /* fake device used for hard links */ -static unsigned long long maxsize;/* maximum size for format */ -static unsigned long long maxrdev;/* maximum st_rdev for format */ -static unsigned long long maxmajor;/* maximum major(st_rdev) for format */ -static unsigned long long maxminor;/* maximum minor(st_rdev) for format */ -static unsigned long long maxuid; /* maximum user id for format */ -static unsigned long long maxgid; /* maximum group id for format */ -static unsigned long long maxnlink;/* maximum link count for format */ -static int mt; /* magtape file descriptor */ -static int mfl; /* magtape flags */ -static struct stat mtst; /* fstat() on mt */ -int aflag; /* reset access times */ -int Aflag; /* append to archive */ -int bflag; /* swap bytes */ -int Bflag; /* 5120 blocking */ -int cflag; /* ascii format */ -int Cflag; /* user-defined blocking */ -int dflag; /* create directories */ -int Dflag; /* do not ask for next device */ -int eflag; /* DEC format */ -int cray_eflag; /* do not archive if values too large */ -const char *Eflag; /* filename for files to be extracted */ -int fflag; /* pattern excludes */ -int Hflag; /* header format */ -const char *Iflag; /* input archive name */ -int kflag; /* skipt corrupted parts */ -int Kflag; /* IRIX-style large file support */ -int lflag; /* link of possible */ -int Lflag; /* follow symbolic links */ -int mflag; /* retain modification times */ -const char *Mflag; /* message when switching media */ -const char *Oflag; /* output archive name */ -int Pflag; /* prototype file list */ -int rflag; /* rename files */ -const char *Rflag; /* reassign ownerships */ -static uid_t Ruid; /* uid to assign */ -static gid_t Rgid; /* gid to assign */ -int sflag; /* swap half word bytes */ -int Sflag; /* swap word bytes */ -int tflag; /* print toc */ -int uflag; /* overwrite files unconditionally */ -int hp_Uflag; /* use umask when creating files */ -int vflag; /* verbose */ -int Vflag; /* special verbose */ -int sixflag; /* 6th Edition archives */ -int action; /* -i -o -p */ -long long errcnt; /* error status */ -static unsigned long long maxpath;/* maximum path length with -i */ -static uint32_t maxino; /* maximum inode number with -i */ -static uid_t myuid; /* user id of caller */ -static gid_t mygid; /* group id of caller */ -static long long blocks; /* copying statistics: full blocks */ -static long long bytes; /* copying statistics: partial blocks */ -static long long nwritten; /* bytes written to archive */ -static off_t aoffs; /* offset in archive */ -static off_t poffs; /* physical offset in archive */ -static int tapeblock = -1; /* physical tape block size */ -struct glist *patterns; /* patterns for -i */ -static int tty; /* terminal file descriptor */ -static const char *cur_ofile; /* current original file */ -static const char *cur_tfile; /* current temporary file */ -static mode_t umsk; /* user's umask */ -static int zipclevel; /* zip compression level */ -static struct islot *inull; /* splay tree null element */ -int printsev; /* print message severity strings */ -static int compressed_bar; /* this is a compressed bar archive */ -static int formatforced; /* -k -i -Hfmt forces a format */ -static long long lineno; /* input line number */ - -int pax_dflag; /* directory matches only itself */ -int pax_kflag; /* do not overwrite files */ -int pax_nflag; /* select first archive member only */ -int pax_sflag; /* substitute file names */ -int pax_uflag; /* add only recent files to archive */ -int pax_Xflag; /* do not cross device boundaries */ -static enum { - PO_NONE = 0, - PO_LINKDATA = 01, /* include link data in type 2 */ - PO_TIMES = 02, /* create atime and mtime fields */ -} pax_oflag; /* recognized -o options */ - -static void copyout(int (*)(const char *, struct stat *)); -static size_t ofiles_cpio(char **, size_t *); -static void dooutp(void); -static int outfile(const char *, struct stat *); -static int addfile(const char *, struct stat *, uint32_t, uint32_t, int, - const char *); -static void iflush(struct islot *, uint32_t); -static void lflush(void); -static int bigendian(void); -static void getbuf(char **, size_t *, size_t); -static void prdot(int); -static void newmedia(int); -static void mclose(void); -static ssize_t mwrite(int); -static void bwrite(const char *, size_t); -static void bflush(void); -static int sum(int, const char *, struct stat *, char *); -static int rstime(const char *, struct stat *, const char *); -static struct islot *isplay(ino_t, struct islot *); -static struct islot *ifind(ino_t, struct islot **); -static void iput(struct islot *, struct islot **); -static struct dslot *dfind(struct dslot **, dev_t); -static void done(int); -static void dopass(const char *); -static int passdata(struct file *, const char *, int); -static int passfile(const char *, struct stat *); -static int filein(struct file *, int (*)(struct file *, const char *, int), - char *); -static int linkunlink(const char *, const char *); -static void tunlink(char **); -static int filet(struct file *, int (*)(struct file *, const char *, int)); -static void filev(struct file *); -static int typec(struct stat *); -static void permbits(mode_t); -static void prtime_cpio(time_t); -static void getpath(const char *, char **, char **, size_t *, size_t *); -static void setpath(const char *, char **, char **, - size_t, size_t *, size_t *); -static int imdir(char *); -static int setattr(const char *, struct stat *); -static int setowner(const char *, struct stat *); -static int canlink(const char *, struct stat *, int); -static void doinp(void); -static void storelink(struct file *); -static void flushlinks(struct file *); -static void flushnode(struct islot *, struct file *); -static void flushrest(int); -static void flushtree(struct islot *, int); -static int inpone(struct file *, int); -static int readhdr(struct file *, union bincpio *); -static void whathdr(void); -static int infile(struct file *); -static int skipfile(struct file *); -static int skipdata(struct file *f, - int (*)(struct file *, const char *, int)); -static int indata(struct file *, const char *, int); -static int totrailer(void); -static long long rdoct(const char *, int); -static long long rdhex(const char *, int); -static ssize_t mread(void); -static void mstat(void); -static int skippad(unsigned long long, int); -static int allzero(const char *, int); -static const char *getuser(uid_t); -static const char *getgroup(gid_t); -static struct glist *want(struct file *, struct glist **); -static void patfile(void); -static int ckodd(long long, int, const char *, const char *); -static int rname(char **, size_t *); -static int redirect(const char *, const char *); -static char *tnameof(struct tar_header *, char *); -static int tmkname(struct tar_header *, const char *); -static void tlinkof(struct tar_header *, struct file *); -static int tmklink(struct tar_header *, const char *); -static int tlflag(struct stat *); -static void tchksum(union bincpio *); -static int tcssum(union bincpio *, int); -static int trdsum(union bincpio *); -static mode_t tifmt(int); -static void bchksum(union bincpio *); -static int bcssum(union bincpio *); -static void blinkof(const char *, struct file *, int); -static void dump_barhdr(void); -static int zcreat(const char *, mode_t); -static int zclose(int); -static void markdev(dev_t); -static int marked(dev_t); -static void cantsup(int, const char *); -static void onint(int); -static int zipread(struct file *, const char *, int, int); -static void zipreaddesc(struct file *); -static int cantunzip(struct file *, const char *); -static time_t gdostime(const char *, const char *); -static void mkdostime(time_t, char *, char *); -static ssize_t ziprxtra(struct file *, struct zip_header *); -static void ziptrailer(void); -static void zipdefer(const char *, struct stat *, long long, - uint32_t, long long, const struct zip_header *); -static int zipwrite(int, const char *, struct stat *, - union bincpio *, size_t, uint32_t, uint32_t, - uint32_t *, long long *); -static int zipwtemp(int, const char *, struct stat *, - union bincpio *, size_t, uint32_t, uint32_t, - uint32_t *, long long *); -#if USE_ZLIB -static int zipwdesc(int, const char *, struct stat *, - union bincpio *, size_t, uint32_t, uint32_t, - uint32_t *, long long *); -#endif /* USE_ZLIB */ -static int zipwxtra(const char *, struct stat *, uint32_t, uint32_t); -static void zipinfo(struct file *); -static void readK2hdr(struct file *); -static int readgnuname(char **, size_t *, long); -static void writegnuname(const char *, long, int); -static void tgetpax(struct tar_header *, struct file *); -static enum paxrec tgetrec(char **, char **, char **); -static void wrpax(const char *, const char *, struct stat *); -static void addrec(char **, long *, long *, - const char *, const char *, long long); -static void paxnam(struct tar_header *, const char *); -static char *sequence(void); -static char *joinpath(const char *, char *); -static int utf8(const char *); -static char *getproto(char *, struct prototype *); - -size_t (*ofiles)(char **, size_t *) = ofiles_cpio; -void (*prtime)(time_t) = prtime_cpio; - -int -main(int argc, char **argv) -{ - myuid = getuid(); - mygid = getgid(); - umask(umsk = umask(0)); - progname = basename(argv[0]); - setlocale(LC_CTYPE, ""); - setlocale(LC_TIME, ""); - inull = scalloc(1, sizeof *inull); - inull->i_lln = inull->i_rln = inull; - flags(argc, argv); - switch (action) { - case 'i': - if (sigset(SIGINT, SIG_IGN) != SIG_IGN) - sigset(SIGINT, onint); - doinp(); - break; - case 'o': - dooutp(); - break; - case 'p': - if (sigset(SIGINT, SIG_IGN) != SIG_IGN) - sigset(SIGINT, onint); - dopass(argv[optind]); - break; - } - if (tflag) - fflush(stdout); - else if (Vflag) - prdot(1); - if (pax != PAX_TYPE_CPIO) - pax_onexit(); - //fprintf(stderr, "%llu blocks\n", blocks + ((bytes + 0777) >> 9)); - mclose(); - if (errcnt && sysv3 == 0) - fprintf(stderr, "%llu error(s)\n", errcnt); - return errcnt ? sysv3 ? 1 : 2 : 0; -} - -static size_t -ofiles_cpio(char **name, size_t *namsiz) -{ - static struct iblok *ip; - - if (ip == NULL) - ip = ib_alloc(0, 0); - return ib_getlin(ip, name, namsiz, srealloc); -} - -/* - * Read the file name list for -o and -p and do initial processing - * for each name. - */ -static void -copyout(int (*copyfn)(const char *, struct stat *)) -{ - char *name = NULL, *np; - size_t namsiz = 0, namlen; - struct stat st; - struct prototype pt; - - while ((namlen = ofiles(&name, &namsiz)) != 0) { - lineno++; - if (name[namlen-1] == '\n') - name[--namlen] = '\0'; - if (Pflag) - np = getproto(name, &pt); - else - np = name; - while (np[0] == '.' && np[1] == '/') { - np += 2; - while (*np == '/') - np++; - if (*np == '\0') { - np = name; - break; - } - } - if (lstat(np, &st) < 0) { - if (Pflag && *np && ((pt.pt_spec & - (PT_TYPE|PT_OWNER|PT_GROUP|PT_MODE|PT_RDEV) && - ((pt.pt_mode&S_IFMT) == S_IFBLK || - (pt.pt_mode&S_IFMT) == S_IFCHR)) || - (pt.pt_spec & - (PT_TYPE|PT_OWNER|PT_GROUP|PT_MODE) && - ((pt.pt_mode&S_IFMT) == S_IFDIR || - (pt.pt_mode&S_IFMT) == S_IFIFO || - (pt.pt_mode&S_IFMT) == S_IFREG)))) { - memset(&st, 0, sizeof st); - st.st_mode = pt.pt_mode; - st.st_blksize = 4096; - st.st_nlink = 1; - goto missingok; - } - else if (sysv3 < 0) - msg(2, 0, "< %s > ?\n", np); - else if (sysv3 > 0) - msg(2, 0, "Cannot obtain information " - "about file: \"%s\".\n", - np); - else - emsg(2, "Error with lstat of \"%s\"", np); - errcnt++; - continue; - } - missingok: - if (Lflag && (st.st_mode&S_IFMT) == S_IFLNK) { - if (stat(np, &st) < 0) { - emsg(2, "Cannot follow \"%s\"", np); - errcnt++; - continue; - } - } - /* - * These file types are essentially useless in an archive - * since they are recreated by any process that needs them. - * We thus ignore them and do not even issue a warning, - * because that would only displace more important messages - * on a terminal and confuse people who just want to copy - * directory hierarchies.--But for pax, POSIX.1-2001 requires - * us to fail! - */ - if ((st.st_mode&S_IFMT) == S_IFSOCK || - (st.st_mode&S_IFMT) == S_IFDOOR) { - if (pax >= PAX_TYPE_PAX2001) { - msg(2, 0, "Cannot handle %s \"%s\".\n", - (st.st_mode&S_IFMT) == S_IFSOCK ? - "socket" : "door", np); - errcnt++; - } - continue; - } - if (Pflag) { - if (pt.pt_spec & PT_TYPE) - if ((st.st_mode&S_IFMT) != (pt.pt_mode&S_IFMT)) - msg(4, 0, "line %lld: types " - "do not match\n", lineno); - if (pt.pt_spec & PT_OWNER) - st.st_uid = pt.pt_uid; - if (pt.pt_spec & PT_GROUP) - st.st_gid = pt.pt_gid; - if (pt.pt_spec & PT_MODE) { - st.st_mode &= ~(mode_t)07777; - st.st_mode |= pt.pt_mode; - } - if (pt.pt_spec & PT_ATIME) - st.st_atime = pt.pt_atime; - if (pt.pt_spec & PT_MTIME) - st.st_mtime = pt.pt_mtime; - if (pt.pt_spec & PT_RDEV) { - if ((st.st_mode&S_IFMT) != S_IFBLK && - (st.st_mode&S_IFMT) != S_IFCHR) - msg(4, 0, "line %lld: device type " - "specified for non-device " - "file\n", lineno); - st.st_rdev = pt.pt_rdev; - } - } - if (pax_track(np, st.st_mtime) == 0) - continue; - if ((fmttype == FMT_ZIP || - fmttype & TYP_BAR || - fmttype == FMT_GNUTAR) - && (st.st_mode&S_IFMT) == S_IFDIR && - name[namlen-1] != '/') { - if (namlen+2 >= namsiz) { - size_t diff = np - name; - name = srealloc(name, namsiz = namlen+2); - np = &name[diff]; - } - name[namlen++] = '/'; - name[namlen] = '\0'; - } - errcnt += copyfn(np, &st); - } -} - -/* - * Execution for -o. - */ -static void -dooutp(void) -{ - if (Oflag) { - if ((mt = Aflag ? open(Oflag, O_RDWR, 0666) : - creat(Oflag, 0666)) < 0) { - if (sysv3) { - emsg(013, "Cannot open <%s> for %s.", Oflag, - Aflag ? "append" : "output"); - done(1); - } else - msg(3, -2, "Cannot open \"%s\" for %s\n", Oflag, - Aflag ? "append" : "output"); - } - } else - mt = dup(1); - mstat(); - blkbuf = svalloc(blksiz, 1); - if (Aflag) { - if (totrailer() != 0) - return; - } else if (fmttype == FMT_NONE) - fmttype = bigendian() ? FMT_BINBE : FMT_BINLE; - if (fmttype & TYP_BINARY) { - maxino = 0177777; - fakeino = 0177777; - maxpath = 256; - if (fmttype & TYP_SGI) { - maxsize = 0x7FFFFFFFFFFFFFFFLL; - maxmajor = 037777; - maxminor = 0777777; - } else { - maxsize = 0x7FFFFFFFLL; - maxrdev = 0177777; - } - maxuid = 0177777; - maxgid = 0177777; - maxnlink = 0177777; - } else if (fmttype == FMT_ODC) { - maxino = 0777777; - fakeino = 0777777; - maxpath = 256; - maxsize = 077777777777LL; - maxrdev = 0777777; - maxuid = 0777777; - maxgid = 0777777; - maxnlink = 0777777; - } else if (fmttype == FMT_DEC) { - maxino = 0777777; - fakeino = 0777777; - maxpath = 256; - maxsize = 077777777777LL; - maxmajor = 077777777; - maxminor = 077777777; - maxuid = 0777777; - maxgid = 0777777; - maxnlink = 0777777; - } else if (fmttype & TYP_NCPIO) { - maxino = 0xFFFFFFFFUL; - fakeino = 0xFFFFFFFFUL; - maxpath = 1024; - maxsize = fmttype&TYP_SCO ? 0x7FFFFFFFFFFFFFFFLL : 0xFFFFFFFFUL; - maxmajor = 0xFFFFFFFFUL; - maxminor = 0xFFFFFFFFUL; - maxuid = 0xFFFFFFFFUL; - maxgid = 0xFFFFFFFFUL; - maxnlink = 0xFFFFFFFFUL; - } else if (fmttype & TYP_CRAY) { - maxino = 0xFFFFFFFFUL; - fakeino = 0xFFFFFFFFUL; - maxpath = SANELIMIT; - maxsize = 0x7FFFFFFFFFFFFFFFLL; - maxrdev = 0x7FFFFFFFFFFFFFFFLL; - maxuid = 0x7FFFFFFFFFFFFFFFLL; - maxgid = 0x7FFFFFFFFFFFFFFFLL; - maxnlink = 0x7FFFFFFFFFFFFFFFLL; - } else if (fmttype == FMT_GNUTAR) { - maxino = 0xFFFFFFFFUL; - fakeino = 0xFFFFFFFFUL; - maxpath = SANELIMIT; - maxsize = 0x7FFFFFFFFFFFFFFFLL; - maxmajor = 0x7FFFFFFFFFFFFFFFLL; - maxminor = 0x7FFFFFFFFFFFFFFFLL; - maxuid = 0x7FFFFFFFFFFFFFFFLL; - maxgid = 0x7FFFFFFFFFFFFFFFLL; - maxnlink = 0x7FFFFFFFFFFFFFFFLL; - } else if (fmttype & TYP_PAX) { - maxino = 0xFFFFFFFFUL; - fakeino = 0xFFFFFFFFUL; - maxpath = SANELIMIT; - maxsize = 0x7FFFFFFFFFFFFFFFLL; - maxmajor = fmttype==FMT_SUN ? 0x7FFFFFFFFFFFFFFFLL : 07777777; - maxminor = fmttype==FMT_SUN ? 0x7FFFFFFFFFFFFFFFLL : 07777777; - maxuid = 0x7FFFFFFFFFFFFFFFLL; - maxgid = 0x7FFFFFFFFFFFFFFFLL; - maxnlink = 0x7FFFFFFFFFFFFFFFLL; - if (pax_oflag & PO_TIMES) - globrec |= PR_ATIME|PR_MTIME; - } else if (fmttype & TYP_BAR) { - maxino = 0xFFFFFFFFUL; - fakeino = 0xFFFFFFFFUL; - maxpath = 512 - SIZEOF_bar_header - 1; - maxsize = 077777777777LL; - maxrdev = 07777777; - maxuid = 07777777; - maxgid = 07777777; - maxnlink = 0x7FFFFFFFFFFFFFFFLL; - if (nwritten == 0) - dump_barhdr(); - } else if (fmttype & TYP_USTAR) { - maxino = 0xFFFFFFFFUL; - fakeino = 0xFFFFFFFFUL; - maxpath = 256; - maxsize = 077777777777LL; - maxmajor = 07777777; - maxminor = 07777777; - maxuid = 07777777; - maxgid = 07777777; - maxnlink = 0x7FFFFFFFFFFFFFFFLL; - } else if (fmttype & TYP_OTAR) { - maxino = 0xFFFFFFFFUL; - fakeino = 0xFFFFFFFFUL; - maxpath = 99; - maxsize = 077777777777LL; - maxuid = 07777777; - maxgid = 07777777; - maxnlink = 0x7FFFFFFFFFFFFFFFLL; - } else if (fmttype == FMT_ZIP) { - maxino = 0xFFFFFFFFUL; - fakeino = 0xFFFFFFFFUL; - maxpath = 60000; - maxsize = 0x7FFFFFFFFFFFFFFFLL; - maxrdev = 0xFFFFFFFFUL; - maxuid = 0xFFFFFFFFUL; - maxgid = 0xFFFFFFFFUL; - maxnlink = 0xFFFFFFFFUL; - } else - abort(); - fakedev = 0177777; - harddev = 1; - copyout(outfile); - if (fmttype & TYP_NCPIO) - lflush(); - if (fmttype & TYP_CPIO) { - struct stat st; - - memset(&st, 0, sizeof st); - st.st_nlink = 1; - outfile(trailer, &st); - } - if (fmttype & TYP_TAR) { - char b[512]; - - memset(b, 0, sizeof b); - bwrite(b, sizeof b); - bwrite(b, sizeof b); - } - if (fmttype == FMT_ZIP) - ziptrailer(); - bflush(); -} - -/* - * Handle a single file for -o, do sanity checks and detect hard links. - */ -static int -outfile(const char *file, struct stat *st) -{ - uint32_t dev, ino; - size_t pathsz; - - if ((st->st_mode&S_IFMT) == S_IFREG) - if (mtst.st_dev == st->st_dev && mtst.st_ino == st->st_ino) - return 0; - if (st->st_size > maxsize) { - msg(2, 0, "Size of %c%s%c >%lluGB. Not dumped\n", - sysv3 ? '<' : '"', - file, - sysv3 ? '>' : '"', - (maxsize+1) / (1024*1024*1024)); - return 1; - } - if (((st->st_mode&S_IFMT)==S_IFBLK||(st->st_mode&S_IFMT)==S_IFCHR) && - (maxrdev && - (unsigned long long)st->st_rdev > maxrdev || - maxmajor && - (unsigned long long)major(st->st_rdev) > maxmajor || - maxminor && - (unsigned long long)minor(st->st_rdev) > maxminor)) { - cantsup(1, file); - return 1; - } - if ((unsigned long long)st->st_uid > maxuid) { - if (cray_eflag) { - cantsup(1, file); - return 1; - } - cantsup(0, file); - st->st_uid = 60001; - if ((st->st_mode&S_IFMT) == S_IFREG && st->st_mode & 0111) - st->st_mode &= ~(mode_t)S_ISUID; - if ((unsigned long long)st->st_gid > maxgid) { - st->st_gid = 60001; - if ((st->st_mode&S_IFMT)==S_IFREG && st->st_mode&0010) - st->st_mode &= ~(mode_t)S_ISGID; - } - } else if ((unsigned long long)st->st_gid > maxgid) { - if (cray_eflag) { - cantsup(1, file); - return 1; - } - cantsup(0, file); - st->st_gid = 60001; - if ((st->st_mode&S_IFMT) == S_IFREG && st->st_mode & 0010) - st->st_mode &= ~(mode_t)S_ISGID; - } - if ((pathsz = strlen(file)) > maxpath) { - msg(2, 0, "%s: file name too long\n", file); - return 1; - } - /* - * Detect hard links and compute fake inode counts. The mechanism - * is as follows: If a file has more than one link, a fake device - * number starting at one is used for its device, and a fake inode - * number is used starting at one too. - * - * The information on links of directories is useless, so it is - * dropped and handled like a file with a single link only: Fake - * devices are allocated just below the format's limit, fake - * i-nodes the same. - * - * This way even the binary cpio format can have up to ~4G files. - */ - if (maxino && st->st_nlink > 1 && (st->st_mode&S_IFMT) != S_IFDIR) { - struct dslot *ds, *dp; - struct islot *ip; - - dev = 1; - ds = devices; - dp = NULL; -nextdev: - for (; ds; dp = ds, ds = ds->d_nxt, dev++ /* see below! */) - if (ds->d_dev == st->st_dev) - break; - if (markeddevs && marked(dev)) { - dev++; - goto nextdev; - } - if (dev >= fakedev) - msg(4, 1, "Too many devices in archive, exiting\n"); - if (ds == NULL) { - ds = scalloc(1, sizeof *ds); - ds->d_dev = st->st_dev; - ds->d_fake = dev; - if (devices == NULL) - devices = ds; - else - dp->d_nxt = ds; - } - harddev = dev; - if ((ip = ifind(st->st_ino, &ds->d_isl)) == NULL) { - if (ds->d_cnt >= maxino) { - /* corresponds to for loop above */ - dev++, dp = ds, ds = ds->d_nxt; - goto nextdev; - } - ip = scalloc(1, sizeof *ip); - ip->i_ino = st->st_ino; - ip->i_fino = ++ds->d_cnt; - ip->i_nlk = st->st_nlink; - if (fmttype & TYP_TAR) - ip->i_name = sstrdup(file); - if (fmttype & TYP_NCPIO) { - ip->i_st = smalloc(sizeof *ip->i_st); - *ip->i_st = *st; - } - iput(ip, &ds->d_isl); - } - ino = ip->i_fino; - if (fmttype & TYP_NCPIO) { - /* - * In SVR4 ascii cpio format, files with multiple - * links are stored with a zero size except for the - * last link, which contains the actual file content. - * As one cannot know which is the last link in - * advance since some links may be outside the - * archive content, all links have to be collected - * and written out at once. - */ - struct ilink *il, *ik; - - switch (ip->i_nlk) { - case 1: - /* - * This was the last link to a file. Write - * all previous links and break to write - * the actual file content. Free the pointers - * in islot; islot remains within the tree - * with a remaining link count of zero. - */ - ip->i_nlk--; - free(ip->i_st); - ip->i_st = NULL; - for (il = ip->i_lnk, ik = NULL; il; - ik = il, il = il->l_nxt, - ik ? free(ik), 0 : 0) { - errcnt += addfile(il->l_nam, st, - dev, ino, 1, 0); - free(il->l_nam); - } - break; - case 0: - /* - * This file got a link during operation, or - * -L was specified and we encountered a link - * more than once. Start with a fresh link - * count again. - */ - ip->i_nlk = st->st_nlink; - ip->i_lnk = NULL; - ip->i_st = smalloc(sizeof *ip->i_st); - *ip->i_st = *st; - /*FALLTHRU*/ - default: - /* - * There are more links to this file. Store - * only the name and return. - */ - ip->i_nlk--; - if (ip->i_lnk) { - for (il = ip->i_lnk; il->l_nxt; - il = il->l_nxt); - il->l_nxt = scalloc(1,sizeof*il->l_nxt); - il = il->l_nxt; - } else { - ip->i_lnk = scalloc(1,sizeof*ip->i_lnk); - il = ip->i_lnk; - } - il->l_nam = smalloc(pathsz + 1); - strcpy(il->l_nam, file); - return 0; - } - } else if (fmttype & TYP_TAR) { - if (strcmp(ip->i_name, file)) - return addfile(file, st, dev, ino, 1, - ip->i_name); - } - } else { /* single-linked or directory */ - dev = fakedev; - while (markeddevs && marked(dev)) - dev--; - if ((ino = fakeino--) == 0) { - if (--dev <= harddev) - msg(4, 1, "Too many devices in archive, " - "exiting\n"); - fakedev = dev; - ino = maxino; - fakeino = ino - 1; - } - } - return addfile(file, st, dev, ino, 0, 0); -} - -/* - * Add a single file to the archive with -o. - */ -static int -addfile(const char *realfile, struct stat *st, - uint32_t dev, uint32_t ino, int zerolink, const char *linkname) -{ - union bincpio bc; - int fd = -1; - long long size; - int pad, i; - ssize_t rsz = 0, wsz = 0, hsz, fsz, psz; - long long remsz, relative, nlink; - long long Kbase = 0, Krest = 0, Ksize = 0; - struct hdr_cpio K2hdr; - uint32_t crc = 0; - long long csize = 0; - char *file; - char *symblink = NULL; - int failure = 1; - - file = sstrdup(realfile); - if (pax != PAX_TYPE_CPIO && strcmp(file, trailer)) { - size_t junk = 0; - if (pax_sflag && pax_sname(&file, &junk) == 0) - goto cleanup; - if (rflag && rname(&file, &junk) == 0) - goto cleanup; - } - fsz = strlen(file); - relative = nwritten; - memset(bc.data, 0, sizeof bc.data); - if (fmttype == FMT_PAX && pax_oflag & PO_LINKDATA && - (st->st_mode&S_IFMT) == S_IFREG) - size = st->st_size; - else if (zerolink) - size = 0; - else if ((st->st_mode&S_IFMT) == S_IFREG) - size = st->st_size; - else if ((st->st_mode&S_IFMT) == S_IFLNK) { - i = st->st_size ? st->st_size : PATH_MAX; - symblink = smalloc(i+1); - if ((size = readlink(realfile, symblink, i)) < 0) { - emsg(3, "Cannot read symbolic link \"%s\"", realfile); - goto cleanup; - } - symblink[size] = '\0'; - } else - size = 0; - nlink = ((unsigned long long)st->st_nlink>maxnlink ? - maxnlink : st->st_nlink); - if (fmttype & TYP_NCPIO) { - long size1; - if (fmttype & TYP_SCO && size >= mag_sco) { - char *ofile = file; - size1 = mag_sco; - fsz += 22; - file = smalloc(fsz + 1); - snprintf(file, fsz + 1, "%s%csize=%016llx", - ofile, 0, size); - free(ofile); - } else - size1 = size; - pad = 4; - sprintf(bc.data, "%*.*s%08lx%08lx%08lx%08lx%08lx%08lx" - "%08lx%08lx%08lx%08lx%08lx%08lx%08lx", - (int)(fmttype&TYP_CRC? sizeof mag_crc:sizeof mag_asc), - (int)(fmttype&TYP_CRC? sizeof mag_crc:sizeof mag_asc), - fmttype & TYP_CRC ? mag_crc : mag_asc, - (long)ino & ECUT, - (long)st->st_mode & ECUT, - (long)st->st_uid & ECUT, - (long)st->st_gid & ECUT, - (long)nlink & ECUT, - (long)st->st_mtime & ECUT, - (long)size1 & ECUT, - (long)major(dev) & ECUT, - (long)minor(dev) & ECUT, - (long)major(st->st_rdev) & ECUT, - (long)minor(st->st_rdev) & ECUT, - (long)++fsz, - 0L); - hsz = SIZEOF_Exp_cpio_hdr; - if ((psz = (hsz + fsz) % pad) != 0) - psz = pad - psz; - } else if (fmttype == FMT_ODC) { - pad = 1; - sprintf(bc.data, "%*.*s%06lo%06lo%06lo%06lo%06lo%06lo%06lo" - "%011lo%06lo%011lo", - (int)sizeof mag_odc, (int)sizeof mag_odc, mag_odc, - (long)dev & OCUT, - (long)ino & OCUT, - (long)st->st_mode & OCUT, - (long)st->st_uid & OCUT, - (long)st->st_gid & OCUT, - (long)nlink & OCUT, - (long)st->st_rdev & OCUT, - (long)st->st_mtime, - (long)++fsz, - (long)size); - hsz = SIZEOF_c_hdr; - if ((psz = (hsz + fsz) % pad) != 0) - psz = pad - psz; - } else if (fmttype == FMT_DEC) { - pad = 1; - sprintf(bc.data, "%*.*s%06lo%06lo%06lo%06lo%06lo%06lo" - "%08lo%08lo%011lo%06lo%011lo", - (int)sizeof mag_odc, (int)sizeof mag_odc, mag_odc, - (long)dev & OCUT, - (long)ino & OCUT, - (long)st->st_mode & OCUT, - (long)st->st_uid & OCUT, - (long)st->st_gid & OCUT, - (long)nlink & OCUT, - (long)major(st->st_rdev) & 077777777, - (long)minor(st->st_rdev) & 077777777, - (long)st->st_mtime, - (long)++fsz, - (long)size); - hsz = SIZEOF_d_hdr; - if ((psz = (hsz + fsz) % pad) != 0) - psz = pad - psz; - } else if (fmttype & TYP_BINARY) { - /* - * To avoid gcc's stupid 'comparison is always false due to - * limited range of data type' warning. - */ - unsigned long long gcccrap; - pad = 2; - if (fmttype & TYP_BE) { - be16p(mag_bin, bc.Hdr.c_magic); - be16p(dev, bc.Hdr.c_dev); - be16p(ino, bc.Hdr.c_ino); - be16p(st->st_mode, bc.Hdr.c_mode); - be16p(st->st_uid, bc.Hdr.c_uid); - be16p(st->st_gid, bc.Hdr.c_gid); - be16p(nlink, bc.Hdr.c_nlink); - be16p(st->st_rdev, bc.Hdr.c_rdev); - be32p(st->st_mtime, bc.Hdr.c_mtime); - be16p(++fsz, bc.Hdr.c_namesize); - } else { - le16p(mag_bin, bc.Hdr.c_magic); - le16p(dev, bc.Hdr.c_dev); - le16p(ino, bc.Hdr.c_ino); - le16p(st->st_mode, bc.Hdr.c_mode); - le16p(st->st_uid, bc.Hdr.c_uid); - le16p(st->st_gid, bc.Hdr.c_gid); - le16p(nlink, bc.Hdr.c_nlink); - le16p(st->st_rdev, bc.Hdr.c_rdev); - me32p(st->st_mtime, bc.Hdr.c_mtime); - le16p(++fsz, bc.Hdr.c_namesize); - } - if (fmttype & TYP_SGI && size > 0x7FFFFFFFLL) { - Krest = size & 0x7FFFFFFFLL; - Kbase = size - Krest; - Ksize = 0x100000000LL - (Kbase >> 31); - if (fmttype & TYP_BE) - be32p(Ksize, bc.Hdr.c_filesize); - else - me32p(Ksize, bc.Hdr.c_filesize); - K2hdr = bc.Hdr; - if (fmttype & TYP_BE) - be32p(Krest, K2hdr.c_filesize); - else - me32p(Krest, K2hdr.c_filesize); - } else { - if (fmttype & TYP_BE) - be32p(size, bc.Hdr.c_filesize); - else - me32p(size, bc.Hdr.c_filesize); - } - if (fmttype & TYP_SGI && - (((st->st_mode&S_IFMT) == S_IFBLK || - (st->st_mode&S_IFMT) == S_IFCHR) && - ((unsigned long long)major(st->st_rdev)>0xFF || - (unsigned long long)minor(st->st_rdev)>0xFF) || - (gcccrap = st->st_rdev) > 0177777)) { - uint32_t rdev; - rdev = (minor(st->st_rdev) & 0x0003FFFF) + - ((major(st->st_rdev)<<18) & 0xFFFC0000); - if (fmttype & TYP_BE) { - be16p(0xFFFF, bc.Hdr.c_rdev); - be32p(rdev, bc.Hdr.c_filesize); - } else { - le16p(0xFFFF, bc.Hdr.c_rdev); - me32p(rdev, bc.Hdr.c_filesize); - } - } - hsz = SIZEOF_hdr_cpio; - psz = (hsz + fsz) % 2; - } else if (fmttype & TYP_CRAY) { - int diff5 = fmttype==FMT_CRAY5 ? CRAY_PARAMSZ : 0; - mode_t mo; - pad = 1; - be64p(mag_bin, bc.Crayhdr.C_magic); - be64p(dev, bc.Crayhdr.C_dev); - be64p(ino, bc.Crayhdr.C_ino); - if ((st->st_mode&S_IFMT) == S_IFLNK) /* non-standard */ - mo = st->st_mode&07777|0130000; /* S_IFLNK on Cray */ - else - mo = st->st_mode; - be64p(mo, bc.Crayhdr.C_mode); - be64p(st->st_uid, bc.Crayhdr.C_uid); - be64p(st->st_gid, bc.Crayhdr.C_gid); - be64p(nlink, bc.Crayhdr.C_nlink); - be64p(st->st_rdev, bc.Crayhdr.C_rdev); - be64p(st->st_mtime, bc.Crayhdr.C_mtime - diff5); - be64p(++fsz, bc.Crayhdr.C_namesize - diff5); - be64p(size, bc.Crayhdr.C_filesize - diff5); - hsz = SIZEOF_cray_hdr - diff5; - psz = 0; - } else if (fmttype & TYP_BAR) { - int c, n = 0; - pad = 512; - sprintf(bc.Bdr.b_mode, "%7.7o",(int)st->st_mode&(07777|S_IFMT)); - sprintf(bc.Bdr.b_uid, "%7.7lo", (long)st->st_uid); - sprintf(bc.Bdr.b_gid, "%7.7lo", (long)st->st_gid); - sprintf(bc.Bdr.b_size, "%11.11llo", - (st->st_mode&S_IFMT) == S_IFREG && !zerolink ? - (long long)st->st_size&077777777777LL : 0LL); - sprintf(bc.Bdr.b_mtime, "%11.11lo", (long)st->st_mtime); - sprintf(bc.Bdr.b_rdev, "%7.7lo", (long)st->st_rdev); - strcpy(&bc.data[SIZEOF_bar_header], file); - c = tlflag(st); - if (zerolink == 0) { - bc.Bdr.b_linkflag = c; - if (c == '2') { - strncpy(&bc.data[SIZEOF_bar_header+fsz+1], - symblink, - 512-SIZEOF_bar_header-fsz); - n = size; - } - } else { - bc.Bdr.b_linkflag = '1'; - strncpy(&bc.data[SIZEOF_bar_header+fsz+1], linkname, - 512-SIZEOF_bar_header-fsz-1); - n = strlen(linkname); - } - if (n > 512-SIZEOF_bar_header-fsz-1) { - msg(3, 0, "%s: linked name too long\n", realfile); - goto cleanup; - } - bchksum(&bc); - hsz = 512; - psz = 0; - fsz = 0; - } else if (fmttype & TYP_TAR) { - const char *cp; - int c; - /* - * Many SVR4 cpio derivatives expect the mode field - * to contain S_IFMT bits. The meaning of these bits - * in the mode field of the ustar header is left - * unspecified by IEEE Std 1003.1, 1996, 10.1.1. - */ - int mmask = fmttype == FMT_USTAR || fmttype == FMT_PAX ? - 07777 : 07777|S_IFMT; - - paxrec = globrec; - pad = 512; - if (tmkname(&bc.Tdr, file) != 0) - goto cleanup; - sprintf(bc.Tdr.t_mode, "%7.7o", (int)st->st_mode & mmask); - if (fmttype == FMT_GNUTAR && st->st_uid > 07777777) { - be64p(st->st_uid, bc.Tdr.t_uid); - bc.Tdr.t_uid[0] |= 0200; - } else { - sprintf(bc.Tdr.t_uid, "%7.7lo", - (long)st->st_uid&07777777); - if (fmttype & TYP_PAX && st->st_uid > 07777777) - paxrec |= PR_UID; - } - if (fmttype == FMT_GNUTAR && st->st_gid > 07777777) { - be64p(st->st_gid, bc.Tdr.t_gid); - bc.Tdr.t_gid[0] |= 0200; - } else { - sprintf(bc.Tdr.t_gid, "%7.7lo", - (long)st->st_gid&07777777); - if (fmttype & TYP_PAX && st->st_gid > 07777777) - paxrec |= PR_GID; - } - if (fmttype == FMT_GNUTAR && (st->st_mode&S_IFMT) == S_IFREG && - st->st_size > 077777777777LL && !zerolink) { - bc.Tdr.t_size[0] = '\200'; - be64p(st->st_size, &bc.Tdr.t_size[4]); - } else { - sprintf(bc.Tdr.t_size, "%11.11llo", - (st->st_mode&S_IFMT) == S_IFREG && - (!zerolink || fmttype == FMT_PAX && - pax_oflag & PO_LINKDATA) ? - (long long)st->st_size&077777777777LL : 0LL); - if (fmttype & TYP_PAX && - (st->st_mode&S_IFMT) == S_IFREG && - st->st_size > 077777777777LL && - (!zerolink || fmttype == FMT_PAX && - pax_oflag & PO_LINKDATA)) - paxrec |= PR_SIZE; - } - sprintf(bc.Tdr.t_mtime, "%11.11lo", (long)st->st_mtime); - if ((c = tlflag(st)) < 0) { - if ((st->st_mode&S_IFMT) != S_IFDIR) { - msg(2, 0, "%s is not a file. Not dumped\n", - realfile); - errcnt++; - } else - failure = 0; - goto cleanup; - } - if (zerolink == 0) { - bc.Tdr.t_linkflag = c; - if (c == '2') { - if (tmklink(&bc.Tdr, symblink) != 0) - goto cleanup; - } - } else { - bc.Tdr.t_linkflag = '1'; - if (tmklink(&bc.Tdr, linkname) != 0) - goto cleanup; - } - if (fmttype & TYP_USTAR) { - if (fmttype == FMT_GNUTAR) - strcpy(bc.Tdr.t_magic, mag_gnutar); - else { - strcpy(bc.Tdr.t_magic, mag_ustar); - bc.Tdr.t_version[0] = bc.Tdr.t_version[1] = '0'; - } - if ((cp = getuser(st->st_uid)) != NULL) - sprintf(bc.Tdr.t_uname, "%.31s", cp); - if ((cp = getgroup(st->st_gid)) != NULL) - sprintf(bc.Tdr.t_gname, "%.31s", cp); - else - msg(1, 0, "could not get group information " - "for %s\n", realfile); - if (fmttype == FMT_GNUTAR && - (unsigned long long)major(st->st_rdev) - > 077777777) { - be64p(major(st->st_rdev), bc.Tdr.t_devmajor); - bc.Tdr.t_devmajor[0] |= 0200; - } else { - if (fmttype == FMT_SUN && - (unsigned long long)major(st->st_rdev) - > 077777777 && - ((st->st_mode&S_IFMT)==S_IFBLK|| - (st->st_mode&S_IFMT)==S_IFCHR)) - paxrec |= PR_SUN_DEVMAJOR; - sprintf(bc.Tdr.t_devmajor, "%7.7o", - (int)major(st->st_rdev)&07777777); - } - if (fmttype == FMT_GNUTAR && - (unsigned long long)minor(st->st_rdev) - > 077777777) { - be64p(minor(st->st_rdev), bc.Tdr.t_devminor); - bc.Tdr.t_devminor[0] |= 0200; - } else { - if (fmttype == FMT_SUN && - (unsigned long long)minor(st->st_rdev) - > 077777777 && - ((st->st_mode&S_IFMT)==S_IFBLK|| - (st->st_mode&S_IFMT)==S_IFCHR)) - paxrec |= PR_SUN_DEVMINOR; - sprintf(bc.Tdr.t_devminor, "%7.7o", - (int)minor(st->st_rdev)&07777777); - } - } - tchksum(&bc); - hsz = 512; - psz = 0; - fsz = 0; - } else if (fmttype == FMT_ZIP) { - pad = 1; - memcpy(bc.Zdr.z_signature, mag_zipsig, sizeof mag_zipsig); - bc.Zdr.z_version[0] = 10; - mkdostime(st->st_mtime, bc.Zdr.z_modtime, bc.Zdr.z_moddate); - if ((st->st_mode&S_IFMT) == S_IFREG || - (st->st_mode&S_IFMT) == S_IFLNK) { - le32p(size, bc.Zdr.z_csize); - le32p(size, bc.Zdr.z_nsize); - csize = size; - } - le16p(fsz, bc.Zdr.z_namelen); - le16p(SIZEOF_zextra_cp, bc.Zdr.z_extralen); - hsz = SIZEOF_zip_header; - psz = 0; - } else - abort(); - /* - * Start writing the file to the archive. - */ - if ((st->st_mode&S_IFMT) == S_IFREG && st->st_size != 0 && - (zerolink == 0 || fmttype == FMT_PAX && - pax_oflag & PO_LINKDATA)) { - char *buf; - size_t bufsize; - int readerr = 0; - - if ((fd = open(realfile, O_RDONLY)) < 0) { - if (sysv3 < 0) - msg(0, 0, "< %s > ?\n", realfile); - else if (sysv3 > 0) - fprintf(stderr, "<%s> ?\n", realfile); - else - msg(0, 0, "\"%s\" ?\n", realfile); - goto cleanup; - } - if (fmttype == FMT_ZIP) { - if (zipwrite(fd, file, st, &bc, fsz, dev, ino, - &crc, &csize) < 0) - goto cleanup2; - goto done; - } - if (fmttype & TYP_CRC) - if (sum(fd, realfile, st, bc.Edr.E_chksum) < 0) - goto cleanup2; - if (fmttype & TYP_PAX && paxrec != PR_NONE) - wrpax(file, symblink?symblink:linkname, st); - bwrite(bc.data, hsz); - if (fsz) - bwrite(file, fsz); - if (psz) - bwrite(&bc.data[hsz], psz); - if (Kbase) - remsz = Kbase; - else - remsz = st->st_size; - getbuf(&buf, &bufsize, st->st_blksize); - again: while (remsz > 0) { - if (fd < 0 || (rsz = read(fd, &buf[wsz], - bufsize - wsz)) < 0) { - if (readerr == 0) { - emsg(3, "Cannot read \"%s\"", realfile); - if (fd >= 0) - errcnt++; - readerr = 1; - } - if (fd >= 0 && lseek(fd, bufsize - wsz, - SEEK_CUR) < 0) { - close(fd); - fd = -1; - } - rsz = bufsize - wsz; - if (rsz > remsz) - rsz = remsz; - memset(&buf[wsz], 0, rsz); - } - if (rsz > remsz) - rsz = remsz; - wsz += rsz; - remsz -= rsz; - bwrite(buf, wsz); - memset(buf, 0, wsz); - size = wsz; - wsz = 0; - } - wsz = size; - if (Kbase) { - if ((i = Ksize % pad) != 0) - bwrite(&bc.data[hsz], i); - bwrite((char *)&K2hdr, hsz); - if (fsz) - bwrite(file, fsz); - if (psz) - bwrite(&bc.data[hsz], psz); - remsz = Krest; - Kbase = 0; - wsz = 0; - goto again; - } else if (Ksize) - wsz = Krest; - } else if ((fmttype == FMT_ZIP || fmttype & TYP_CPIO) && - (st->st_mode&S_IFMT) == S_IFLNK) { - wsz = size; - if (fmttype == FMT_ZIP) { - crc = zipcrc(0, (unsigned char *)symblink, wsz); - le32p(crc, bc.Zdr.z_crc32); - bwrite(bc.data, SIZEOF_zip_header); - bwrite(file, fsz); - zipwxtra(file, st, dev, ino); - bwrite(symblink, wsz); - } else { - bwrite(bc.data, hsz); - if (fsz) - bwrite(file, fsz); - if (psz) - bwrite(&bc.data[hsz], psz); - bwrite(symblink, wsz); - } - } else { - if (fmttype & TYP_PAX && paxrec != PR_NONE) - wrpax(file, symblink?symblink:linkname, st); - bwrite(bc.data, hsz); - if (fsz) - bwrite(file, fsz); - if (psz) - bwrite(&bc.data[hsz], psz); - if (fmttype == FMT_ZIP) - zipwxtra(file, st, dev, ino); - } -done: if (fmttype == FMT_ZIP) { - zipdefer(file, st, relative, crc, csize, &bc.Zdr); - } - if ((i = wsz % pad) != 0) - bwrite(&bc.data[hsz], pad - i); - if (vflag && strcmp(file, trailer)) - fprintf(stderr, "%s\n", file); - else if (Vflag) - prdot(0); - failure = 0; -cleanup2: - if ((st->st_mode&S_IFMT) == S_IFREG) { - if (fd >= 0) - close(fd); - if (aflag) - errcnt += rstime(realfile, st, "access"); - } -cleanup: - free(file); - free(symblink); - return failure; -} - -/* - * Flush a SVR4 cpio format inode tree for -o. - */ -static void -iflush(struct islot *ip, uint32_t dev) -{ - if (ip == inull) - return; - iflush(ip->i_lln, dev); - iflush(ip->i_rln, dev); - if (ip->i_nlk > 0 && ip->i_st) { - struct ilink *il; - - for (il = ip->i_lnk; il->l_nxt; il = il->l_nxt) - errcnt += addfile(il->l_nam, ip->i_st, - dev, ip->i_fino, 1, 0); - errcnt += addfile(il->l_nam, ip->i_st, dev, ip->i_fino, 0, 0); - } -} - -/* - * Flush the SVR4 cpio link forest for -o. - */ -static void -lflush(void) -{ - struct dslot *ds; - - for (ds = devices; ds; ds = ds->d_nxt) - iflush(ds->d_isl, ds->d_fake); -} - -int -setfmt(char *s) -{ - int i, j; - - struct { - const char *ucs; - const char *lcs; - int type; - int bits; - } fs[] = { - { "NEWC", "newc", FMT_ASC, 00 }, - { "SCO", "sco", FMT_SCOASC, 00 }, - { "CRC", "crc", FMT_CRC, 00 }, - { "SCOCRC", "scocrc", FMT_SCOCRC, 00 }, - { "ODC", "odc", FMT_ODC, 00 }, - { "DEC", "dec", FMT_DEC, 00 }, - { "BIN", "bin", FMT_NONE, 00 }, - { "BBS", "bbs", TYP_BE, 00 }, - { "SGI", "sgi", FMT_SGIBE, 00 }, - { "CRAY", "cray", FMT_CRAY, 00 }, - { "CRAY5", "cray5", FMT_CRAY5, 00 }, - { "TAR", "tar", FMT_TAR, 00 }, - { "USTAR", "ustar", FMT_USTAR, 00 }, - { "PAX:", "pax:", FMT_PAX, 00 }, - { "SUN", "sun", FMT_SUN, 00 }, - { "GNU", "gnu", FMT_GNUTAR, 00 }, - { "OTAR", "otar", FMT_OTAR, 00 }, - { "BAR", "bar", FMT_BAR, 00 }, - { "ZIP:", "zip:", FMT_ZIP, 00 }, - { NULL, NULL, 0, 00 } - }; - for (i = 0; fs[i].ucs; i++) { - for (j = 0; s[j] && - (s[j] == fs[i].ucs[j] || s[j] == fs[i].lcs[j]); - j++) - if (fs[i].ucs[j] == ':') - break; - if (s[j] == '\0' && - (fs[i].ucs[j] == '\0' || fs[i].ucs[j] == ':') || - s[j] == ':' && fs[i].ucs[j] == ':') { - fmttype = fs[i].type; - if (fmttype == FMT_ZIP && s[j] == ':') { -#if USE_ZLIB - if (strcmp(&s[j+1], "en") == 0) - zipclevel = 00; - else if (strcmp(&s[j+1], "ex") == 0) - zipclevel = 01; - else if (strcmp(&s[j+1], "ef") == 0) - zipclevel = 02; - else if (strcmp(&s[j+1], "es") == 0) - zipclevel = 03; - else -#endif /* USE_ZLIB */ - if (strcmp(&s[j+1], "e0") == 0) - zipclevel = 04; - else -#if USE_BZLIB - if (strcmp(&s[j+1], "bz2") == 0) - zipclevel = 07; - else -#endif /* USE_BZLIB */ - continue; - } else if (fmttype == FMT_NONE) - fmttype = bigendian() ? FMT_BINBE : FMT_BINLE; - else if (fmttype == TYP_BE) - fmttype = bigendian() ? FMT_BINLE : FMT_BINBE; - else if (fmttype == FMT_PAX && s[j] == ':') { - if (pax_options(&s[j+1], 0) < 0) - continue; - } - return 0; - } - } - msg(3, 0, "Invalid header \"%s\" specified.\n", s); - return -1; -} - -static int -bigendian(void) -{ - union { - char u_c[2]; - int16_t u_i; - } u; - u.u_i = 1; - return u.u_c[1] == 1; -} - -int -setreassign(const char *s) -{ - struct passwd *pwd; - int val = 0; - - if (myuid != 0) { - msg(3, 0, "R option only valid for super-user.\n"); - val = -1; - } - if ((pwd = getpwnam(s)) == NULL) { - msg(3, 0, "\"%s\" is not a valid user id\n", s); - val = -1; - } else { - Ruid = pwd->pw_uid; - Rgid = pwd->pw_gid; - } - return val; -} - -void * -srealloc(void *m, size_t n) -{ - if ((m = realloc(m, n)) == NULL) { - write(2, "Out of memory.\n", 15); - _exit(sysv3 ? 2 : 3); - } - return m; -} - -void * -smalloc(size_t n) -{ - return srealloc(NULL, n); -} - -void * -scalloc(size_t nmemb, size_t size) -{ - void *vp; - - if ((vp = calloc(nmemb, size)) == NULL) { - write(2, "Out of memory.\n", 15); - _exit(sysv3 ? 2 : 3); - } - return vp; -} - -void * -svalloc(size_t n, int force) -{ - static long pagesize; - void *vp; - - if (pagesize == 0) - if ((pagesize = sysconf(_SC_PAGESIZE)) < 0) - pagesize = 4096; - if ((vp = memalign(pagesize, n)) == NULL && force) { - write(2, "Out of memory.\n", 15); - _exit(sysv3 ? 2 : 3); - } - return vp; -} - -/* - * A single static buffer is used for intermediate copying from file - * data to the tape buffer and vice versa, for creating checksums, and - * for data transfer with -p. - */ -static void -getbuf(char **bufp, size_t *sizep, size_t best) -{ - static char *buf; - static size_t size; - - if (size != best) { - if (buf) - free(buf); - size = best; - if (size == 0 || (buf = svalloc(size, 0)) == NULL) - buf = svalloc(size = 512, 1); - } - *bufp = buf; - *sizep = size; -} - -static void -sevprnt(int sev) -{ - if (printsev) switch (sev) { - case 1: - fprintf(stderr, "INFORM: "); - break; - case 2: - fprintf(stderr, "WARNING: "); - break; - case 3: - fprintf(stderr, "ERROR: "); - break; - case 4: - fprintf(stderr, "HALT: "); - break; - } -} - -void -msg(int sev, int err, const char *fmt, ...) -{ - va_list ap; - - /* - * The error message should appear near the file it refers to. - */ - if (tflag) - fflush(stdout); - else if (Vflag) - prdot(1); - if (sysv3 >= 0 && sev >= (printsev ? 0 : -1)) - fprintf(stderr, "%s: ", progname); - sevprnt(sev); - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - if (err > 0) - done(err); - else if (err == -2) { - if (sysv3) - done(1); - usage(); - } -} - -void -emsg(int sev, const char *fmt, ...) -{ - char _fmt[60]; - int i, fl = sev & 030, n; - va_list ap; - - sev &= ~030; - i = errno; - if (tflag) - fflush(stdout); - else if (Vflag) - prdot(1); - fprintf(stderr, "%s: ", progname); - sevprnt(sev); - va_start(ap, fmt); - if (sysv3) { - if (fmt[(n=strlen(fmt))-1] == '"' && fmt[n-2] == 's' && - fmt[n-3] == '%' && fmt[n-4] == '"' && - n < sizeof _fmt) { - strcpy(_fmt, fmt); - _fmt[n-1] = '>'; - _fmt[n-4] = '<'; - fmt = _fmt; - } - } - vfprintf(stderr, fmt, ap); - va_end(ap); - if (sysv3 > 0 && sev >= 0 && fl & 010) - fprintf(stderr, "\n\t%s\n", strerror(i)); - else if (sysv3 < 0) { - if (fl & 020) - putc('\n', stderr); - else - fprintf(stderr, " (errno:%d)\n", i); - } else - fprintf(stderr, ", errno %d, %s\n", i, strerror(i)); -} - -static void -prdot(int flush) -{ - static int column; - - if (flush && column != 0 || column >= 50) { - write(action == 'o' && !Oflag ? 2 : 1, "\n", 1); - column = 0; - } - if (!flush) { - write(action == 'o' && !Oflag ? 2 : 1, ".", 1); - column++; - } -} - -/* - * Ask the user for new media if applicable, or exit. - */ -static void -newmedia(int err) -{ - static int mediacnt = 1; - static char answer[PATH_MAX+1]; - const char *mesf = action == 'i' ? - (Iflag && !sysv3 ? Iflag : "input") : - (Oflag && !sysv3 ? Oflag : "output"); - char c; - int i, j; - - if (mfl == 0 && close(mt) < 0) { - emsg(3, "Close error on \"%s\"", mesf); - errcnt++; - } - mfl = -1; - if ((mtst.st_mode&S_IFMT)!=S_IFCHR && (mtst.st_mode&S_IFMT)!=S_IFBLK || - Dflag) { - if (action == 'o') { - switch (err) { - case 0: - break; - case EFBIG: - msg(3, 0, "ulimit reached for output file.\n"); - break; - case ENOSPC: - msg(3, 0, "No space left for output file.\n"); - break; - default: - msg(3, 0, "I/O error - cannot continue, " - "errno %d, %s\n", - err, strerror(err)); - } - } - return; - } - if (err == ENOSPC || err == ENXIO || err == 0) - msg(-2, 0, sysv3 ? "Reached end of medium on %s.\a\n" : - "End of medium on \"%s\".\a\n", mesf); - else - msg(3, 0, "I/O error on \"%s\", errno %d, %s\a\n", mesf, - err, strerror(err)); - mediacnt++; - while (mfl < 0) { - if (Iflag || Oflag) - msg(-2, 0, Mflag ? Mflag : - "Change to part %d and press " - "RETURN key. [q] ", mediacnt); - else - msg(-2, 0, sysv3 ? "If you want to go on, " - "type device/file name when ready.\n" : - "To continue, type device/file name " - "when ready.\n"); - if (tty == 0) - if ((tty = open("/dev/tty", O_RDWR)) < 0 || - fcntl(tty, F_SETFD, FD_CLOEXEC) < 0) { - cantrt: errcnt++; - msg(4, 1, "Cannot read tty.\n"); - } - i = 0; - while ((j = read(tty, &c, 1)) == 1 && c != '\n') - if (i < sizeof answer - 1) - answer[i++] = c; - if (j != 1) - goto cantrt; - answer[i] = 0; - if (Iflag || Oflag) { - if (answer[0] == '\0') - snprintf(answer, sizeof answer, Iflag ? Iflag : - Oflag); - else if (answer[0] == 'q') - exit(errcnt != 0 ? sysv3 ? 1 : 2 : 0); - else if (Iflag) - Iflag = sstrdup(answer); - else if (Oflag) - Oflag = sstrdup(answer); - } else if (answer[0] == '\0') - return; - if ((mt = action == 'i' ? open(answer, O_RDONLY) : - creat(answer, 0666)) < 0) { - if (sysv3) - msg(-2, 0, "That didn't work, " - "cannot open \"%s\"\n%s\n", - answer, strerror(errno)); - else - emsg(3, "Cannot open \"%s\"", answer); - } - else - mfl = 0; - } - mstat(); -} - -static void -mclose(void) -{ - if (action == 'o' && mt >= 0 && close(mt) < 0) { - emsg(3, "Close error on \"%s\"", - Oflag && !sysv3 ? Oflag : "output"); - errcnt++; - } -} - -/* - * Write the archive buffer to tape. - */ -static ssize_t -mwrite(int max) -{ - ssize_t wo, wt = 0; - - do { - if ((wo = write(mt, blkbuf + wt, (max?max:blksiz) - wt)) < 0) { - if (errno == EINTR) { - continue; - } else { - newmedia(errno); - if (mfl == 0) { - if (fmttype & TYP_BAR) - dump_barhdr(); - continue; - } - else - done(1); - } - } - poffs += wo; - wt += wo; - } while (wt < (max?max:blksiz)); - blocks += wt >> 9; - bytes += wt & 0777; - return wt; -} - -/* - * Buffered writes to tape. - */ -static void -bwrite(const char *data, size_t sz) -{ - size_t di; - - nwritten += sz; - while (curpos + sz > blksiz) { - di = blksiz - curpos; - sz -= di; - memcpy(&blkbuf[curpos], data, di); - mwrite(0); - data += di; - curpos = 0; - } - memcpy(&blkbuf[curpos], data, sz); - curpos += sz; -} - -/* - * Flush the tape write buffer. - */ -static void -bflush(void) -{ - if (curpos) { - memset(&blkbuf[curpos], 0, blksiz - curpos); - mwrite(fmttype==FMT_ZIP && (mtst.st_mode&S_IFMT) == S_IFREG ? - curpos : 0); - } - curpos = 0; -} - -/* - * CRC format checksum calculation with -i. - */ -static int -sum(int fd, const char *fn, struct stat *sp, char *tg) -{ - char *buf; - size_t bufsize; - uint32_t size = sp->st_size, sum = 0; - ssize_t rd; - char c; - - getbuf(&buf, &bufsize, sp->st_blksize); - /* - * Unfortunately, SVR4 cpio derivatives (as on Solaris 8 and - * UnixWare 2.1) compute the checksum of signed char values, - * whereas GNU cpio and the pax implementations of AT&T and - * BSD use unsigned chars. Since there is no 'open' standard - * for the SVR4 CRC format, the SVR4 implementation should be - * taken as a de facto reference and we thus create SVR4 type - * checksums. - */ - while ((rd = read(fd, buf, size>bufsize ? bufsize : size )) > 0) { - size -= rd; - do - sum += ((signed char *)buf)[--rd]; - while (rd); - } - if (rd < 0) { - msg(3, 0, "Error computing checksum\n"); - return 1; - } - if (lseek(fd, 0, SEEK_SET) == (off_t)-1) { - emsg(3, "Cannot reset file after checksum"); - return 1; - } - c = tg[8]; - sprintf(tg, "%08lx", (long)sum); - tg[8] = c; - return 0; -} - -static int -rstime(const char *fn, struct stat *st, const char *which) -{ - struct utimbuf utb; - - utb.actime = st->st_atime; - utb.modtime = st->st_mtime; - if (pax != PAX_TYPE_CPIO && - (pax_preserve&(PAX_P_ATIME|PAX_P_MTIME)) != 0 && - (pax_preserve&PAX_P_EVERY) == 0) { - struct stat xst; - if (stat(fn, &xst) < 0) - goto fail; - if (pax_preserve&PAX_P_ATIME) - utb.actime = xst.st_atime; - if (pax_preserve&PAX_P_MTIME) - utb.modtime = xst.st_mtime; - } - if (utime(fn, &utb) < 0) { - fail: emsg(2, "Unable to reset %s time for \"%s\"", which, fn); - return 1; - } - return 0; -} - -/* - * Top-down splay function for inode tree. - */ -static struct islot * -isplay(ino_t ino, struct islot *x) -{ - struct islot hdr; - struct islot *leftmax, *rightmin; - struct islot *y; - - hdr.i_lln = hdr.i_rln = inull; - leftmax = rightmin = &hdr; - inull->i_ino = ino; - while (ino != x->i_ino) { - if (ino < x->i_ino) { - if (ino < x->i_lln->i_ino) { - y = x->i_lln; - x->i_lln = y->i_rln; - y->i_rln = x; - x = y; - } - if (x->i_lln == inull) - break; - rightmin->i_lln = x; - rightmin = x; - x = x->i_lln; - } else { - if (ino > x->i_rln->i_ino) { - y = x->i_rln; - x->i_rln = y->i_lln; - y->i_lln = x; - x = y; - } - if (x->i_rln == inull) - break; - leftmax->i_rln = x; - leftmax = x; - x = x->i_rln; - } - } - leftmax->i_rln = x->i_lln; - rightmin->i_lln = x->i_rln; - x->i_lln = hdr.i_rln; - x->i_rln = hdr.i_lln; - inull->i_ino = !ino; - return x; -} - -/* - * Find the inode number ino. - */ -static struct islot * -ifind(ino_t ino, struct islot **it) -{ - if (*it == NULL) - return NULL; - *it = isplay(ino, *it); - return (*it)->i_ino == ino ? *it : NULL; -} - -/* - * Put ik into the tree. - */ -static void -iput(struct islot *ik, struct islot **it) -{ - if ((*it) == NULL) { - ik->i_lln = ik->i_rln = inull; - (*it) = ik; - } else { - /* ifind() is always called before */ - /*(*it) = isplay(ik->i_ino, (*it));*/ - if (ik->i_ino < (*it)->i_ino) { - ik->i_lln = (*it)->i_lln; - ik->i_rln = (*it); - (*it)->i_lln = inull; - (*it) = ik; - } else if ((*it)->i_ino < ik->i_ino) { - ik->i_rln = (*it)->i_rln; - ik->i_lln = (*it); - (*it)->i_rln = inull; - (*it) = ik; - } - } -} - -/* - * Find the device dev or add it to the device/inode forest if not - * already present. - */ -static struct dslot * -dfind(struct dslot **root, dev_t dev) -{ - struct dslot *ds, *dp; - - for (ds = *root, dp = NULL; ds; dp = ds, ds = ds->d_nxt) - if (ds->d_dev == dev) - break; - if (ds == NULL) { - ds = scalloc(1, sizeof *ds); - ds->d_dev = dev; - if (*root == NULL) - *root = ds; - else - dp->d_nxt = ds; - } - return ds; -} - -/* - * Exit on fatal error conditions. - */ -static void -done(int i) -{ - if (tflag) - fflush(stdout); - errcnt += i; - mclose(); - if (errcnt && !sysv3) - fprintf(stderr, "%llu errors\n", errcnt); - exit(sysv3 ? 2 : 3); -} - -static char *pcopy, *pcend; -static size_t psz, pslen, pss; - -/* - * Execution for -p. - */ -static void -dopass(const char *target) -{ - struct stat st; - - if (access(target, W_OK) < 0) { - emsg(033, sysv3 ? "cannot write in <%s>" : - "Error during access() of \"%s\"", target); - if (sysv3) - done(1); - usage(); - } - if (stat(target, &st) < 0) { - emsg(023, "Error during stat() of \"%s\"", target); - done(1); - } - if ((st.st_mode&S_IFMT) != S_IFDIR) - msg(3, 1, sysv3 ? "<%s> not a directory.\n" : - "\"%s\" is not a directory\n", target); - getpath(target, &pcopy, &pcend, &psz, &pslen); - copyout(passfile); -} - -/* - * Callback for sfile(). - */ -/*ARGSUSED*/ -void -writerr(void *vp, int count, int written) -{ -} - -/* - * Copy file data of regular files with -p. - */ -static int -passdata(struct file *f, const char *tgt, int tfd) -{ - char *buf; - size_t bufsize; - ssize_t rd = 0; - - if (f->f_fd < 0) /* is a zero-sized unreadable file */ - return 0; -#ifdef __linux__ - if (f->f_st.st_size > 0) { - long long sent; - - sent = sfile(tfd, f->f_fd, f->f_st.st_mode, f->f_st.st_size); - blocks += (sent + 0777) >> 9; - if (sent == f->f_st.st_size) - return 0; - if (sent < 0) - goto rerr; - } -#endif /* __linux__ */ - getbuf(&buf, &bufsize, f->f_st.st_blksize); - while ((rd = read(f->f_fd, buf, bufsize)) > 0) { - blocks += (rd + 0777) >> 9; - if (write(tfd, buf, rd) != rd) { - emsg(3, "Cannot write \"%s\"", tgt); - return -1; - } - } - if (rd < 0) { -#ifdef __linux__ - rerr: -#endif /* __linux__ */ - emsg(3, "Cannot read \"%s\"", f->f_name); - return -1; - } - return 0; -} - -/* - * Handle a single file for -p. - */ -static int -passfile(const char *fn, struct stat *st) -{ - struct file f; - ssize_t sz; - int val; - char *newfn; - size_t newsz = 0; - - newfn = sstrdup(fn); - if (pax != PAX_TYPE_CPIO) { - if (pax_sflag && pax_sname(&newfn, &newsz) == 0) - return 0; - if (rflag && rname(&newfn, &newsz) == 0) - return 0; - } - setpath(newfn, &pcopy, &pcend, pslen, &psz, &pss); - free(newfn); - memset(&f, 0, sizeof f); - f.f_name = sstrdup(fn); - f.f_nsiz = strlen(fn) + 1; - f.f_st = *st; - f.f_fd = -1; - if ((st->st_mode&S_IFMT) == S_IFLNK) { - sz = st->st_size ? st->st_size : PATH_MAX; - f.f_lnam = smalloc(sz+1); - if ((sz = readlink(fn, f.f_lnam, sz+1)) < 0) { - emsg(3, "Cannot read symbolic link \"%s\"", fn); - free(f.f_lnam); - return 1; - } - f.f_lnam[sz] = '\0'; - } else if ((st->st_mode&S_IFMT) == S_IFREG) { - if ((f.f_fd = open(fn, O_RDONLY)) < 0) { - if (sysv3) - msg(2, 0, "Cannot open file \"%s\".\n", fn); - else - emsg(2, "Cannot open \"%s\", skipped", fn); - if (st->st_size != 0) - return 1; - } - } - val = filein(&f, passdata, pcopy); - if (f.f_lnam) - free(f.f_lnam); - free(f.f_name); - if (f.f_fd >= 0) - close(f.f_fd); - if (val <= 1 && aflag && (st->st_mode&S_IFMT) == S_IFREG) - errcnt += rstime(fn, st, "access"); - return val != 0; -} - -/* - * Processing of a single file common to -i and -p. Return value: 0 if - * successful, 1 at failure if data was read, 2 at failure if no data - * was read. - */ -static int -filein(struct file *f, int (*copydata)(struct file *, const char *, int), - char *tgt) -{ - struct stat nst; - char *temp = NULL; - size_t len; - int fd, i, j, new; - int failure = 2; - - if (fmttype == FMT_ZIP && (f->f_st.st_mode&S_IFMT) != S_IFREG && - (f->f_st.st_mode&S_IFMT) != S_IFLNK && - (f->f_csize > 0 || f->f_gflag & FG_DESC)) - skipfile(f); - if ((new = lstat(tgt, &nst)) == 0) { - if (action == 'p' && f->f_st.st_dev == nst.st_dev && - f->f_st.st_ino == nst.st_ino) { - msg(3, 0, sysv3 ? - "Attempt to pass file to self!\n" : - "Attempt to pass a file to itself.\n"); - return 1; - } - if ((f->f_st.st_mode&S_IFMT) == S_IFDIR) { - if ((nst.st_mode&S_IFMT) == S_IFDIR) - return setattr(tgt, &f->f_st); - rmdir(tgt); - } else { - if (pax_kflag) { - failure = 0; - goto skip; - } - if (uflag == 0 && f->f_st.st_mtime <= nst.st_mtime) { - if (pax == PAX_TYPE_CPIO) - msg(-1, 0, sysv3 ? - "current <%s> newer or same age\n" : - "Existing \"%s\" same age or newer\n", - tgt); - else - failure = 0; - goto skip; - } - } - } else { - if (imdir(tgt) < 0) - goto skip; - } - if (Vflag && !vflag) - prdot(0); - if ((f->f_st.st_mode&S_IFMT) != S_IFDIR && lflag) { - if (Lflag) { - char *symblink, *name; - struct stat xst; - name = f->f_name; - for (;;) { - if (lstat(name, &xst) < 0) { - emsg(3, "Cannot lstat \"%s\"", name); - if (name != f->f_name) - free(name); - goto cantlink; - } - if ((xst.st_mode&S_IFMT) != S_IFLNK) - break; - i = xst.st_size ? xst.st_size : PATH_MAX; - symblink = smalloc(i+1); - if ((j = readlink(name, symblink, i)) < 0) { - emsg(3, "Cannot read symbolic link " - "\"%s\"", name); - free(symblink); - if (name != f->f_name) - free(name); - goto cantlink; - } - symblink[j] = '\0'; - symblink = joinpath(name, symblink); - if (name != f->f_name) - free(name); - name = symblink; - } - if (linkunlink(name, tgt) == 0) { - if (vflag) - fprintf(stderr, "%s\n", tgt); - if (name != f->f_name) - free(name); - return 0; - } - if (name != f->f_name) - free(name); - } else if (linkunlink(f->f_name, tgt) == 0) { - if (vflag) - fprintf(stderr, "%s\n", tgt); - return 0; - } -cantlink: errcnt += 1; - } - if ((f->f_st.st_mode&S_IFMT) != S_IFDIR && f->f_st.st_nlink > 1 && - (fmttype & TYP_CPIO || fmttype == FMT_ZIP - || action == 'p') && - (i = canlink(tgt, &f->f_st, 1)) != 0) { - if (i < 0) - goto skip; - /* - * At this point, hard links in SVR4 cpio format have - * been reordered and data is associated with the first - * link; remaining links have st_size == 0 so don't - * overwrite the data here. - */ - if (fmttype & TYP_NCPIO && f->f_st.st_size == 0 || - (f->f_st.st_mode&S_IFMT) != S_IFREG) { - if (vflag) - fprintf(stderr, "%s\n", f->f_name); - return 0; - } - /* - * Make sure we can creat() this file later. - */ - chmod(tgt, 0600); - } else if (fmttype & TYP_TAR && f->f_st.st_nlink > 1) { - if (linkunlink(f->f_lnam, f->f_name) == 0) { - if (fmttype & TYP_USTAR && f->f_st.st_size > 0) - chmod(tgt, 0600); - else { - if (vflag) - fprintf(stderr, "%s\n", f->f_name); - return 0; - } - } else { - goto restore; - } - } else if (new == 0 && (f->f_st.st_mode&S_IFMT) != S_IFDIR) { - len = strlen(tgt); - temp = smalloc(len + 7); - strcpy(temp, tgt); - strcpy(&temp[len], "XXXXXX"); - if ((fd = mkstemp(temp)) < 0 || close(fd) < 0) { - emsg(3, "Cannot create temporary file"); - if (fd < 0) { - free(temp); - temp = NULL; - } - goto skip; - } - cur_ofile = tgt; - cur_tfile = temp; - if (rename(tgt, temp) < 0) { - emsg(3, "Cannot rename current \"%s\"", tgt); - tunlink(&temp); - goto skip; - } - } - switch (f->f_st.st_mode & S_IFMT) { - case S_IFDIR: - if (!dflag) { - if (action == 'p') - msg(-1, 0, "Use -d option to copy \"%s\"\n", - f->f_name); - goto restore; - } - if (mkdir(tgt, 0777) < 0 && errno != EEXIST) { - emsg(-1, "Cannot create directory \"%s\"", tgt); - goto restore; - } - break; - case S_IFLNK: - if (symlink(f->f_lnam, tgt) < 0) { - emsg(3, "Cannot create \"%s\"", tgt); - goto restore; - } - break; - case S_IFREG: - if (temp && f->f_fd < 0) - goto restore; - cur_ofile = tgt; - if ((fd = (compressed_bar ? zcreat : creat)(tgt, - f->f_st.st_mode & 0777)) < 0) { - emsg(3, "Cannot create \"%s\"", tgt); - goto skip; - } - failure = 1; - if (copydata(f, tgt, fd) != 0) { - close(fd); - goto restore; - } - if ((compressed_bar ? zclose : close)(fd) < 0) { - emsg(3, "Close error on \"%s\"", tgt); - goto restore; - } - break; - case S_IFBLK: - case S_IFCHR: - case S_IFIFO: - case S_IFNAM: - case S_IFNWK: - if (mknod(tgt, f->f_st.st_mode&(S_IFMT|0777), - f->f_st.st_rdev) < 0) { - emsg(3, "Cannot mknod() \"%s\"", tgt); - goto restore; - } - break; - default: - msg(-1, 0, "Impossible file type\n"); - goto skip; - } - if (vflag) - fprintf(stderr, "%s\n", f->f_name); - tunlink(&temp); - return setattr(tgt, &f->f_st); -skip: if (copydata == indata) - skipdata(f, copydata); -restore: - if (temp) { - if (rename(temp, tgt) < 0) { - emsg(3, "Cannot recover original version of \"%s\"", - tgt); - tunlink(&temp); - } else - fprintf(stderr, "Restoring existing \"%s\"\n", tgt); - cur_tfile = cur_ofile = NULL; - } - return failure; -} - -static int -linkunlink(const char *path1, const char *path2) -{ - int twice = 0; - - do { - if (link(path1, path2) == 0) { - if (vflag && pax == PAX_TYPE_CPIO) - printf("%s linked to %s\n", path1, path2); - return 0; - } - if (errno == EEXIST && unlink(path2) < 0) - emsg(3, sysv3 ? "cannot unlink <%s>" : - "Error cannot unlink \"%s\"", path2); - } while (twice++ == 0); - emsg(023, sysv3 ? "Cannot link <%s> & <%s>" : - "Cannot link \"%s\" and \"%s\"", path1, path2); - return -1; -} - -static void -tunlink(char **fn) -{ - cur_tfile = cur_ofile = NULL; - if (*fn) { - if (unlink(*fn) < 0) - emsg(3, "Cannot unlink() temp file \"%s\"", *fn); - free(*fn); - *fn = NULL; - } -} - -/* - * For -it[v] option. - */ -static int -filet(struct file *f, int (*copydata)(struct file *, const char *, int)) -{ - if (vflag && ( - (fmttype == FMT_ZIP && f->f_gflag & FG_DESC && - (f->f_cmethod == C_DEFLATED || f->f_cmethod == C_ENHDEFLD) && - (f->f_gflag & FG_CRYPT) == 0) || - f->f_Kbase)) { - /* - * Need to read zip data descriptor located after the - * file contents in order to know the file size. Or - * need to read second header of -K archive. - */ - int i; - i = skipdata(f, copydata); - filev(f); - return i; - } - if (vflag) - filev(f); - else - puts(f->f_name); - return skipdata(f, copydata); -} - -static void -filev(struct file *f) -{ - const char *cp; - long c; - - if (pax == PAX_TYPE_CPIO && fmttype & TYP_TAR && f->f_st.st_nlink > 1) - printf("%s linked to %s\n", f->f_lnam, f->f_name); - if (sysv3) - printf("%-6o", (int)f->f_st.st_mode&(07777|S_IFMT)); - else { - c = typec(&f->f_st); - putchar(c); - permbits(f->f_st.st_mode); - } - if (fmttype == FMT_ZIP && vflag > 1) - zipinfo(f); - else { - if (sysv3 == 0) - printf(" %3d", fmttype&TYP_TAR && - (f->f_st.st_mode&S_IFMT) == S_IFLNK ? - 2 : (int)f->f_st.st_nlink); - if ((cp = getuser(f->f_st.st_uid)) != NULL) - printf(sysv3 ? " %-6s" : " %-8s", cp); - else - printf(sysv3 ? " %-6lu" : " %-8lu", - (long)f->f_st.st_uid); - if (sysv3 == 0) { - if ((cp = getgroup(f->f_st.st_gid)) != NULL) - printf(" %-8s", cp); - else - printf(" %-8lu", (long)f->f_st.st_gid); - } - } - if (sysv3 || (f->f_st.st_mode&S_IFMT)!=S_IFCHR && - (f->f_st.st_mode&S_IFMT)!=S_IFBLK && - (f->f_st.st_mode&S_IFMT)!=S_IFNAM && - (f->f_st.st_mode&S_IFMT)!=S_IFNWK) - printf(pax != PAX_TYPE_CPIO ? "%8llu" : - sysv3 ? "%7llu" : " %-7llu", f->f_dsize); - else - printf(" %3lu,%3lu", (long)f->f_rmajor, (long)f->f_rminor); - prtime(f->f_st.st_mtime); - printf("%s", f->f_name); - if ((f->f_st.st_mode&S_IFMT) == S_IFLNK) - printf(" -> %s", f->f_lnam); - if (pax != PAX_TYPE_CPIO && (f->f_st.st_mode&S_IFMT) != S_IFDIR && - f->f_st.st_nlink>1) { - if (fmttype & TYP_TAR) - printf(" == %s", f->f_lnam); - else - canlink(f->f_name, &f->f_st, 0); - } - putchar('\n'); -} - -static int -typec(struct stat *st) -{ - switch (st->st_mode&S_IFMT) { - case S_IFREG: - return '-'; - case S_IFDIR: - return 'd'; - case S_IFLNK: - return 'l'; - case S_IFCHR: - return 'c'; - case S_IFBLK: - return 'b'; - case S_IFIFO: - return 'p'; - case S_IFNWK: - return 'n'; - case S_IFNAM: - switch (st->st_rdev) { - case S_INSEM: - return 's'; - case S_INSHD: - return 'm'; - } - /*FALLTHRU*/ - default: - msg(-1, 0, "Impossible file type\n"); - errcnt++; - return '-'; - } -} - -static void -permbits(mode_t mode) -{ - mode_t mask = 0700, shft = 6; - - while (mask) { - if (((mode & mask) >> shft) & 04) - putchar('r'); - else - putchar('-'); - if (((mode & mask) >> shft) & 02) - putchar('w'); - else - putchar('-'); - if (mask == 0700 && mode & 04000) - putchar('s'); - else if (mask == 0070 && (mode & 02010) == 02010) - putchar('s'); - else if (mask == 0070 && mode & 02000) - putchar('l'); - else if (mask == 0007 && mode & 01000) - putchar('t'); - else if (((mode & mask) >> shft) & 01) - putchar('x'); - else - putchar('-'); - mask >>= 3; - shft -= 3; - } -} - -static void -prtime_cpio(time_t t) -{ - char b[30]; - - strftime(b, sizeof b, sysv3 ? "%b %e %H:%M:%S %Y" : "%b %e %H:%M %Y", - localtime(&t)); - printf(sysv3 ? " %s " : " %s, ", b); -} - -/* - * Prepare path to add names of files below it later. - */ -static void -getpath(const char *path, char **file, char **filend, size_t *sz, size_t *slen) -{ - *sz = 14 + strlen(path) + 2; - *file = smalloc(*sz); - *filend = *file; - if (path[0] == '/' && path[1] == '\0') - *(*filend)++ = '/'; - else { - const char *cp = path; - while ((*(*filend)++ = *cp++) != '\0'); - (*filend)[-1] = '/'; - } - *slen = *filend - *file; -} - -/* - * Concatenate base (prepared with getpath()) and file. - */ -static void -setpath(const char *base, char **file, char **filend, - size_t slen, size_t *sz, size_t *ss) -{ - if (slen + (*ss = strlen(base)) >= *sz) { - *sz += slen + *ss + 15; - *file = srealloc(*file, *sz); - *filend = &(*file)[slen]; - } - strcpy(*filend, base); -} - -/* - * Create intermediate directories with -m. - */ -static int -imdir(char *fn) -{ - struct stat st; - char *cp; - int dfl = dflag != 0; - - for (cp = fn; *cp == '/'; cp++); - do { - while (*cp && *cp != '/') - cp++; - if (*cp == '/') { - *cp = '\0'; - if (stat(fn, &st) < 0) { - if (dfl) { - if (mkdir(fn, 0777) < 0) { - *cp = '/'; - emsg(-1, "Cannot create " - "directory for \"%s\"", - fn); - return -1; - } - } else { - msg(-1, 0, sysv3 ? - "missing 'd' option\n" : - "Missing -d option\n"); - dfl = 2; - } - } - *cp = '/'; - while (*cp == '/') - cp++; - } - } while (*cp); - return 0; -} - -/* - * Set file attributes and make sure that suid/sgid bits are only restored - * if the owner is the same as on the tape. - */ -static int -setattr(const char *fn, struct stat *st) -{ - mode_t mode = st->st_mode & 07777; - uid_t uid = Rflag ? Ruid : myuid; - gid_t gid = Rflag ? Rgid : mygid; - - if ((pax != PAX_TYPE_CPIO || myuid == 0) && - (pax == PAX_TYPE_CPIO || - pax_preserve&(PAX_P_OWNER|PAX_P_EVERY))) { - if (setowner(fn, st) != 0) - return 1; - } - if (pax != PAX_TYPE_CPIO && - (pax_preserve&(PAX_P_OWNER|PAX_P_EVERY)) == 0) - mode &= ~(mode_t)(S_ISUID|S_ISGID); - if (myuid != 0 || Rflag) { - if (st->st_uid != uid || st->st_gid != gid) { - mode &= ~(mode_t)S_ISUID; - if ((st->st_mode&S_IFMT) != S_IFDIR && mode & 0010) - mode &= ~(mode_t)S_ISGID; - if ((st->st_mode&S_IFMT) == S_IFDIR && st->st_gid!=gid) - mode &= ~(mode_t)S_ISGID; - } - } - if ((st->st_mode&S_IFMT) == S_IFLNK) - return 0; - if (hp_Uflag) - mode &= ~umsk|S_IFMT; - if (pax != PAX_TYPE_CPIO && - (pax_preserve&(PAX_P_MODE|PAX_P_OWNER|PAX_P_EVERY))==0) - mode &= 01777|S_IFMT; - if ((pax == PAX_TYPE_CPIO || pax_preserve&(PAX_P_MODE|PAX_P_EVERY)) && - chmod(fn, mode) < 0) { - emsg(2, "Cannot chmod() \"%s\"", fn); - return 1; - } - if (pax != PAX_TYPE_CPIO ? - (pax_preserve&(PAX_P_ATIME|PAX_P_MTIME|PAX_P_EVERY)) != - (PAX_P_ATIME|PAX_P_MTIME) : mflag) - return rstime(fn, st, "modification"); - else - return 0; -} - -static int -setowner(const char *fn, struct stat *st) -{ - uid_t uid = Rflag ? Ruid : myuid ? myuid : st->st_uid; - gid_t gid = Rflag ? Rgid : st->st_gid; - - if (((st->st_mode&S_IFMT)==S_IFLNK?lchown:chown)(fn, uid, gid) < 0) { - emsg(2, "Cannot chown() \"%s\"", fn); - return 1; - } - if (pax >= PAX_TYPE_PAX2001 && myuid && myuid != st->st_uid && - pax_preserve & (PAX_P_OWNER|PAX_P_EVERY)) { - /* - * Do not even try to preserve user ownership in this case. - * It would either fail, or, without _POSIX_CHOWN_RESTRICTED, - * leave us with a file we do not own and which we thus could - * not chmod() later. - */ - errno = EPERM; - emsg(2, "Cannot chown() \"%s\"", fn); - return 1; - } - return 0; -} - -/* - * For -i and -p: Check if device/inode have been created already and - * if so, link path (or print the link name). - */ -static int -canlink(const char *path, struct stat *st, int really) -{ - struct dslot *ds; - struct islot *ip; - - ds = dfind(&devices, st->st_dev); - if ((ip = ifind(st->st_ino, &ds->d_isl)) == NULL || - ip->i_name == NULL) { - if (ip == NULL) { - ip = scalloc(1, sizeof *ip); - ip->i_ino = st->st_ino; - if ((fmttype&(TYP_NCPIO|TYP_TAR)) == 0) - ip->i_nlk = st->st_nlink; - iput(ip, &ds->d_isl); - } - ip->i_name = sstrdup(path); - } else { - if ((fmttype&(TYP_NCPIO|TYP_TAR)) == 0) { - /* - * If an archive inode has more links than given in - * st_nlink, write a new disk inode. See the comments - * to storelink() for the rationale. - */ - if (--ip->i_nlk == 0) { - free(ip->i_name); - ip->i_name = sstrdup(path); - ip->i_nlk = st->st_nlink; - return 0; - } - } - if (really) { - /* - * If there was file data before the last link with - * SVR4 cpio formats, do not create a hard link. - */ - if (fmttype & TYP_NCPIO && ip->i_nlk == 0) - return 0; - if (linkunlink(ip->i_name, path) == 0) - return 1; - else - return -1; - } else { - printf(" == %s", ip->i_name); - return 1; - } - } - return 0; -} - -/* - * Execution for -i. - */ -static void -doinp(void) -{ - union bincpio bc; - struct file f; - int n; - - memset(&f, 0, sizeof f); - if (Eflag) - patfile(); - if (Iflag) { - if ((mt = open(Iflag, O_RDONLY)) < 0) { - if (sysv3) { - emsg(3, "Cannot open <%s> for input.", Iflag); - done(1); - } - else - msg(3, -2, "Cannot open \"%s\" for input\n", - Iflag); - } - } else - mt = dup(0); - mstat(); - blkbuf = svalloc(blksiz, 1); - if ((n = mread()) == 0) - unexeoa(); - else if (n < 0) { - emsg(3, "Read error on \"%s\"", - Iflag && !sysv3 ? Iflag : "input"); - done(1); - } - if (kflag == 0 && sixflag == 0) - fmttype = FMT_NONE; - if (fmttype == FMT_NONE) - whathdr(); - else - formatforced = 1; - while (readhdr(&f, &bc) == 0) { - if (fmttype & TYP_NCPIO && f.f_st.st_nlink > 1 && - (f.f_st.st_mode&S_IFMT) != S_IFDIR) { - if (f.f_st.st_size != 0) - flushlinks(&f); - else - storelink(&f); - } else - inpone(&f, 1); - f.f_Kbase = f.f_Krest = f.f_Ksize = 0; - f.f_oflag = 0; - } - if (fmttype & TYP_NCPIO) - flushrest(f.f_pad); -} - -/* - * SVR4 cpio link handling with -i; called if we assume that more links - * to this file will follow. - */ -static void -storelink(struct file *f) -{ - struct dslot *ds; - struct islot *ip; - struct ilink *il, *iz; - - ds = dfind(&devices, f->f_st.st_dev); - if ((ip = ifind(f->f_st.st_ino, &ds->d_isl)) == NULL) { - ip = scalloc(1, sizeof *ip); - ip->i_ino = f->f_st.st_ino; - ip->i_nlk = f->f_st.st_nlink; - ip->i_st = smalloc(sizeof *ip->i_st); - *ip->i_st = f->f_st; - iput(ip, &ds->d_isl); - } else { - if (ip->i_nlk == 0) { - /* - * More links to an inode than given in the first - * st_nlink occurence are found within this archive. - * This happens if -L was specified and soft links - * point to a file with multiple hard links. We do - * the same as SVR4 cpio implementations here and - * associate these links with a new inode, since it - * is related to the way a file with a single hard - * link but referenced by soft links is unpacked. - */ - ip->i_nlk = f->f_st.st_nlink; - if (ip->i_name) - free(ip->i_name); - ip->i_name = NULL; - ip->i_st = smalloc(sizeof *ip->i_st); - *ip->i_st = f->f_st; - } else if (ip->i_nlk <= 2) { - /* - * We get here if - * - a file with multiple links is empty; - * - a broken implementation has stored file data - * before the last link; - * - a linked file has been added to the archive later - * again (does not happen with our implementation). - */ - flushnode(ip, f); - return; - } else - ip->i_nlk--; - } - for (il = ip->i_lnk, iz = NULL; il; il = il->l_nxt) - iz = il; - il = scalloc(1, sizeof *il); - il->l_siz = strlen(f->f_name) + 1; - il->l_nam = smalloc(il->l_siz); - strcpy(il->l_nam, f->f_name); - if (iz) - iz->l_nxt = il; - else - ip->i_lnk = il; -} - -/* - * Flush all links of a file with SVR4 cpio format and -i. - */ -static void -flushlinks(struct file *f) -{ - struct dslot *ds; - struct islot *ip; - - ds = dfind(&devices, f->f_st.st_dev); - ip = ifind(f->f_st.st_ino, &ds->d_isl); - flushnode(ip, f); -} - -/* - * Data of a multi-linked file shall be transferred now for SVR4 cpio - * format and -i. - */ -static void -flushnode(struct islot *ip, struct file *f) -{ - struct file nf; - struct ilink *il, *iz; - - f->f_dsize = f->f_st.st_size; - if (ip && ip->i_nlk > 0) { - /* - * Write out the file data with the first link the user - * wants to be extracted, but show the same display size - * for all links. - */ - for (il = ip->i_lnk, iz = NULL; il; - iz = il, il = il->l_nxt, iz ? free(iz), 0 : 0) { - memset(&nf, 0, sizeof nf); - nf.f_name = il->l_nam; - nf.f_nsiz = il->l_siz; - nf.f_st = f->f_st; - nf.f_chksum = f->f_chksum; - nf.f_pad = f->f_pad; - nf.f_dsize = f->f_dsize; - if (inpone(&nf, 0) == 0) { - f->f_chksum = 0; - f->f_st.st_size = 0; - } - free(il->l_nam); - } - ip->i_lnk = NULL; - if (ip->i_st) - free(ip->i_st); - ip->i_st = NULL; - } - if (f->f_name) - inpone(f, 1); - if (ip) { - if (ip->i_nlk <= 2 && ip->i_name) { - free(ip->i_name); - ip->i_name = NULL; - } - ip->i_nlk = 0; - } -} - -/* - * This writes all remaining multiply linked files, i. e. those with - * st_size == 0 and st_nlink > number of links within the archive. - */ -static void -flushrest(int pad) -{ - struct dslot *ds; - - for (ds = devices; ds; ds = ds->d_nxt) - if (ds->d_isl != NULL) - flushtree(ds->d_isl, pad); -} - -static void -flushtree(struct islot *ip, int pad) -{ - struct file f; - - if (ip == inull) - return; - flushtree(ip->i_lln, pad); - flushtree(ip->i_rln, pad); - if (ip->i_nlk > 0 && ip->i_st) { - memset(&f, 0, sizeof f); - f.f_st = *ip->i_st; - f.f_pad = pad; - flushnode(ip, &f); - } -} - -/* - * See if the user wants to have this file with -i, and extract it or - * skip its data on the tape. - */ -static int -inpone(struct file *f, int shallskip) -{ - struct glist *gp = NULL, *gb = NULL; - int val = -1, selected = 0; - - if ((patterns == NULL || (gp = want(f, &gb)) != NULL ^ fflag) && - pax_track(f->f_name, f->f_st.st_mtime)) { - selected = 1; - if ((pax_sflag == 0 || pax_sname(&f->f_name, &f->f_nsiz)) && - (rflag == 0 || rname(&f->f_name, &f->f_nsiz))) { - errcnt += infile(f); - val = 0; - } - } else if (shallskip) - errcnt += skipfile(f); - if (gp != NULL && selected) { - gp->g_gotcha = 1; - if (gp->g_nxt && gp->g_nxt->g_art) - gp->g_nxt->g_gotcha = 1; - else if (gp->g_art && gb) - gb->g_gotcha = 1; - } - return val; -} - -/* - * Read the header for a file with -i. Return values: 0 okay, 1 end of - * archive, -1 failure. - */ -static int -readhdr(struct file *f, union bincpio *bp) -{ - long namlen, l1, l2, rd, hsz; - static long attempts; - long long skipped = 0; - - if (fmttype & TYP_TAR) { - if (f->f_name) - f->f_name[0] = '\0'; - if (f->f_lnam) - f->f_lnam[0] = '\0'; - } - paxrec = globrec; -retry: f->f_st = globst; -retry2: if (fmttype & TYP_BINARY) { - hsz = SIZEOF_hdr_cpio; - if (attempts == 0 && bread(bp->data, hsz) != hsz) - unexeoa(); - if ((fmttype&TYP_BE ? pbe16(bp->Hdr.c_magic) : - ple16(bp->Hdr.c_magic)) != mag_bin) - goto badhdr; - if (fmttype & TYP_BE) { - f->f_st.st_dev = pbe16(bp->Hdr.c_dev)&0177777; - f->f_st.st_ino = pbe16(bp->Hdr.c_ino)&0177777; - f->f_st.st_mode = pbe16(bp->Hdr.c_mode); - } else { - f->f_st.st_dev = ple16(bp->Hdr.c_dev)&0177777; - f->f_st.st_ino = ple16(bp->Hdr.c_ino)&0177777; - f->f_st.st_mode = ple16(bp->Hdr.c_mode); - } - if (sixflag) { - /* - * relevant Unix 6th Edition style mode bits - * (according to /usr/sys/inode.h, untested:) - * - * 060000 IFMT type of file - * 040000 IFDIR directory - * 020000 IFCHR character special - * 060000 IFBLK block special, 0 is regular - * 007777 permission bits as today - */ - f->f_st.st_mode &= 067777; - if ((f->f_st.st_mode & 060000) == 0) - f->f_st.st_mode |= S_IFREG; - } - if (fmttype & TYP_BE) { - f->f_st.st_uid = pbe16(bp->Hdr.c_uid)&0177777; - f->f_st.st_gid = pbe16(bp->Hdr.c_gid)&0177777; - f->f_st.st_nlink = pbe16(bp->Hdr.c_nlink)&0177777; - f->f_st.st_mtime = pbe32(bp->Hdr.c_mtime); - f->f_st.st_rdev = pbe16(bp->Hdr.c_rdev); - namlen = pbe16(bp->Hdr.c_namesize); - f->f_st.st_size = pbe32(bp->Hdr.c_filesize)&0xFFFFFFFF; - } else { - f->f_st.st_uid = ple16(bp->Hdr.c_uid)&0177777; - f->f_st.st_gid = ple16(bp->Hdr.c_gid)&0177777; - f->f_st.st_nlink = ple16(bp->Hdr.c_nlink)&0177777; - f->f_st.st_mtime = pme32(bp->Hdr.c_mtime); - f->f_st.st_rdev = ple16(bp->Hdr.c_rdev); - namlen = ple16(bp->Hdr.c_namesize); - f->f_st.st_size = pme32(bp->Hdr.c_filesize)&0xFFFFFFFF; - } - f->f_rmajor = major(f->f_st.st_rdev); - f->f_rminor = minor(f->f_st.st_rdev); - if ((f->f_st.st_rdev&0xFFFF) == 0xFFFF && - f->f_st.st_size > 0 && - ((f->f_st.st_mode&S_IFMT) == S_IFBLK || - (f->f_st.st_mode&S_IFMT) == S_IFCHR && - (!formatforced || fmttype & TYP_SGI))) { - fmttype |= TYP_SGI; - f->f_rmajor = (f->f_st.st_size&0xFFFC0000)>>18; - f->f_rminor = f->f_st.st_size&0x0003FFFF; - f->f_st.st_rdev = makedev(f->f_rmajor, f->f_rminor); - f->f_st.st_size = 0; - } - if ((f->f_st.st_mode&S_IFMT) == S_IFREG && - f->f_st.st_size&0x80000000 && - (!formatforced || fmttype & TYP_SGI)) { - fmttype |= TYP_SGI; - f->f_Ksize = f->f_st.st_size&0xFFFFFFFF; - f->f_Kbase = (0x100000000LL-f->f_st.st_size) * - 0x80000000; - f->f_st.st_size = 0; - } - f->f_pad = 2; - rd = SIZEOF_hdr_cpio; - } else if (fmttype == FMT_ODC) { - hsz = SIZEOF_c_hdr; - if (attempts == 0 && bread(bp->data, hsz) != hsz) - unexeoa(); - if(memcmp(bp->Cdr.c_magic, mag_odc, sizeof mag_odc)) - goto badhdr; - f->f_st.st_dev = rdoct(bp->Cdr.c_dev, 6); - f->f_st.st_ino = rdoct(bp->Cdr.c_ino, 6); - f->f_st.st_mode = rdoct(bp->Cdr.c_mode, 6); - f->f_st.st_uid = rdoct(bp->Cdr.c_uid, 6); - f->f_st.st_gid = rdoct(bp->Cdr.c_gid, 6); - f->f_st.st_nlink = rdoct(bp->Cdr.c_nlink, 6); - f->f_st.st_rdev = rdoct(bp->Cdr.c_rdev, 6); - f->f_rmajor = major(f->f_st.st_rdev); - f->f_rminor = minor(f->f_st.st_rdev); - f->f_st.st_mtime = rdoct(bp->Cdr.c_mtime, 11); - namlen = rdoct(bp->Cdr.c_namesz, 6); - f->f_st.st_size = rdoct(bp->Cdr.c_filesz, 11); - f->f_pad = 1; - rd = SIZEOF_c_hdr; - } else if (fmttype == FMT_DEC) { - hsz = SIZEOF_d_hdr; - if (attempts == 0 && bread(bp->data, hsz) != hsz) - unexeoa(); - if(memcmp(bp->Ddr.d_magic, mag_odc, sizeof mag_odc)) - goto badhdr; - f->f_st.st_dev = rdoct(bp->Ddr.d_dev, 6); - f->f_st.st_ino = rdoct(bp->Ddr.d_ino, 6); - f->f_st.st_mode = rdoct(bp->Ddr.d_mode, 6); - f->f_st.st_uid = rdoct(bp->Ddr.d_uid, 6); - f->f_st.st_gid = rdoct(bp->Ddr.d_gid, 6); - f->f_st.st_nlink = rdoct(bp->Ddr.d_nlink, 6); - f->f_rmajor = rdoct(bp->Ddr.d_rmaj, 8); - f->f_rminor = rdoct(bp->Ddr.d_rmin, 8); - f->f_st.st_rdev = makedev(f->f_rmajor, f->f_rminor); - f->f_st.st_mtime = rdoct(bp->Ddr.d_mtime, 11); - namlen = rdoct(bp->Ddr.d_namesz, 6); - f->f_st.st_size = rdoct(bp->Ddr.d_filesz, 11); - f->f_pad = 1; - rd = SIZEOF_d_hdr; - } else if (fmttype & TYP_NCPIO) { - hsz = SIZEOF_Exp_cpio_hdr; - if (attempts == 0 && bread(bp->data, hsz) != hsz) - unexeoa(); - if (memcmp(bp->Edr.E_magic, mag_asc, sizeof mag_asc) && - memcmp(bp->Edr.E_magic, mag_crc, sizeof mag_crc)) - goto badhdr; - f->f_st.st_ino = rdhex(bp->Edr.E_ino, 8); - f->f_st.st_mode = rdhex(bp->Edr.E_mode, 8); - f->f_st.st_uid = rdhex(bp->Edr.E_uid, 8); - f->f_st.st_gid = rdhex(bp->Edr.E_gid, 8); - f->f_st.st_nlink = rdhex(bp->Edr.E_nlink, 8); - f->f_st.st_mtime = rdhex(bp->Edr.E_mtime, 8); - f->f_st.st_size = rdhex(bp->Edr.E_filesize, 8); - l1 = rdhex(bp->Edr.E_maj, 8); - l2 = rdhex(bp->Edr.E_min, 8); - f->f_st.st_dev = makedev(l1, l2); - f->f_rmajor = rdhex(bp->Edr.E_rmaj, 8); - f->f_rminor = rdhex(bp->Edr.E_rmin, 8); - f->f_st.st_rdev = makedev(f->f_rmajor, f->f_rminor); - namlen = rdhex(bp->Edr.E_namesize, 8); - f->f_chksum = rdhex(bp->Edr.E_chksum, 8); - f->f_pad = 4; - rd = SIZEOF_Exp_cpio_hdr; - } else if (fmttype & TYP_CRAY) { - int diff5 = fmttype==FMT_CRAY5 ? CRAY_PARAMSZ : 0; - hsz = SIZEOF_cray_hdr - diff5; - if (attempts == 0 && bread(bp->data, hsz) != hsz) - unexeoa(); - if (pbe64(bp->Crayhdr.C_magic) != mag_bin) - goto badhdr; - f->f_st.st_dev = pbe64(bp->Crayhdr.C_dev); - f->f_st.st_ino = pbe64(bp->Crayhdr.C_ino); - f->f_st.st_mode = pbe64(bp->Crayhdr.C_mode); - /* - * Some of the S_IFMT bits on Cray UNICOS 9 differ from - * the common Unix values, namely: - * - * S_IFLNK 0130000 symbolic link - * S_IFOFD 0110000 off line, with data - * S_IFOFL 0120000 off line, with no data - * - * We treat the latter ones as regular files. - */ - if ((f->f_st.st_mode&S_IFMT) == 0130000) - f->f_st.st_mode = f->f_st.st_mode&07777|S_IFLNK; - else if ((f->f_st.st_mode&S_IFMT) == 0110000 || - (f->f_st.st_mode&S_IFMT) == 0120000) - f->f_st.st_mode = f->f_st.st_mode&07777|S_IFREG; - f->f_st.st_uid = pbe64(bp->Crayhdr.C_uid); - f->f_st.st_gid = pbe64(bp->Crayhdr.C_gid); - f->f_st.st_nlink = pbe64(bp->Crayhdr.C_nlink); - f->f_st.st_mtime = pbe64(bp->Crayhdr.C_mtime - diff5); - f->f_st.st_rdev = pbe64(bp->Crayhdr.C_rdev); - f->f_rmajor = major(f->f_st.st_rdev); - f->f_rminor = minor(f->f_st.st_rdev); - f->f_st.st_size = pbe64(bp->Crayhdr.C_filesize - diff5); - namlen = pbe64(bp->Crayhdr.C_namesize - diff5); - f->f_pad = 1; - rd = SIZEOF_cray_hdr - diff5; - } else if (fmttype & TYP_BAR) { - hsz = 512; - if (attempts == 0 && bread(bp->data, hsz) != hsz) - unexeoa(); - if (bp->data[SIZEOF_bar_header] == '\0') { - if (kflag && !allzero(bp->data, hsz)) - goto badhdr; - return 1; - } - if (trdsum(bp) != 0 && kflag == 0) - goto badhdr; - bp->data[512] = bp->data[513] = '\0'; - if (f->f_name == NULL || f->f_name[0] == '\0') { - if (f->f_nsiz < 512) { - free(f->f_name); - f->f_name = smalloc(f->f_nsiz = 512); - } - strcpy(f->f_name, &bp->data[SIZEOF_bar_header]); - } - namlen = strlen(f->f_name) + 1; - f->f_st.st_mode = rdoct(bp->Bdr.b_mode, 8); - f->f_st.st_uid = rdoct(bp->Bdr.b_uid, 8); - f->f_st.st_gid = rdoct(bp->Bdr.b_gid, 8); - f->f_st.st_size = rdoct(bp->Bdr.b_size, 12); - f->f_st.st_mtime = rdoct(bp->Bdr.b_mtime, 12); - f->f_st.st_rdev = rdoct(bp->Bdr.b_rdev, 8); - f->f_rmajor = major(f->f_st.st_rdev); - f->f_rminor = minor(f->f_st.st_rdev); - switch (bp->Bdr.b_linkflag) { - case '0': - f->f_st.st_mode &= 07777; - if (f->f_name[namlen-2] == '/') - f->f_st.st_mode |= S_IFDIR; - else - f->f_st.st_mode |= S_IFREG; - break; - case '1': - if (f->f_lnam == NULL || f->f_lnam[0] == '\0') - blinkof(bp->data, f, namlen); - f->f_st.st_nlink = 2; - if ((f->f_st.st_mode&S_IFMT) == 0) - f->f_st.st_mode |= S_IFREG; - break; - case '2': - if (f->f_lnam == NULL || f->f_lnam[0] == '\0') - blinkof(bp->data, f, namlen); - f->f_st.st_mode &= 07777; - f->f_st.st_mode |= S_IFLNK; - } - f->f_pad = 512; - rd = 512; - } else if (fmttype & TYP_TAR) { - hsz = 512; - if (attempts == 0 && bread(bp->data, hsz) != hsz) - unexeoa(); - if (bp->Tdr.t_name[0] == '\0') { - if (kflag && !allzero(bp->data, hsz)) - goto badhdr; - return 1; - } - if (fmttype == FMT_GNUTAR) { - if (memcmp(bp->Tdr.t_magic, mag_gnutar, 8)) - goto badhdr; - } else if (fmttype & TYP_USTAR) { - if (memcmp(bp->Tdr.t_magic, mag_ustar, 6)) - goto badhdr; - } - if (trdsum(bp) != 0 && kflag == 0) - goto badhdr; - if ((fmttype & TYP_PAX) == 0 && (fmttype == FMT_GNUTAR || - strcmp(bp->Tdr.t_name, "././@LongLink") == 0)) { - switch (bp->Tdr.t_linkflag) { - case 'L': - if (readgnuname(&f->f_name, &f->f_nsiz, - rdoct(bp->Tdr.t_size, 12)) < 0) - goto badhdr; - goto retry; - case 'K': - if (readgnuname(&f->f_lnam, &f->f_lsiz, - rdoct(bp->Tdr.t_size, 12)) < 0) - goto badhdr; - goto retry; - } - } - if (fmttype & TYP_USTAR && fmttype != FMT_GNUTAR) { - switch (bp->Tdr.t_linkflag) { - case 'g': - case 'x': - if (formatforced && fmttype != FMT_PAX) - break; - fmttype = FMT_PAX; - tgetpax(&bp->Tdr, f); - goto retry2; - case 'X': - if (formatforced && fmttype != FMT_SUN) - break; - fmttype = FMT_SUN; - tgetpax(&bp->Tdr, f); - goto retry2; - } - } - if (f->f_name == NULL || f->f_name[0] == '\0') { - if (f->f_nsiz < TNAMSIZ+TPFXSIZ+2) { - free(f->f_name); - f->f_name= smalloc(f->f_nsiz=TNAMSIZ+TPFXSIZ+2); - } - tnameof(&bp->Tdr, f->f_name); - } - namlen = strlen(f->f_name) + 1; - f->f_st.st_mode = rdoct(bp->Tdr.t_mode, 8) & 07777; - if (paxrec & PR_UID) - /*EMPTY*/; - else if (fmttype == FMT_GNUTAR && bp->Tdr.t_uid[0] & 0200) - f->f_st.st_uid = pbe64(bp->Tdr.t_uid) & - 0x7FFFFFFFFFFFFFFFLL; - else - f->f_st.st_uid = rdoct(bp->Tdr.t_uid, 8); - if (paxrec & PR_GID) - /*EMPTY*/; - else if (fmttype == FMT_GNUTAR && bp->Tdr.t_gid[0] & 0200) - f->f_st.st_gid = pbe64(bp->Tdr.t_gid) & - 0x7FFFFFFFFFFFFFFFLL; - else - f->f_st.st_gid = rdoct(bp->Tdr.t_gid, 8); - if (paxrec & PR_SIZE) - /*EMPTY*/; - else if (fmttype == FMT_GNUTAR && bp->Tdr.t_size[0] == '\200') - f->f_st.st_size = pbe64(&bp->Tdr.t_size[4]); - else - f->f_st.st_size = rdoct(bp->Tdr.t_size, 12); - if ((paxrec & PR_MTIME) == 0) - f->f_st.st_mtime = rdoct(bp->Tdr.t_mtime, TTIMSIZ); - if (bp->Tdr.t_linkflag == '1') { - if (f->f_lnam == NULL || f->f_lnam[0] == '\0') - tlinkof(&bp->Tdr, f); - f->f_st.st_mode |= S_IFREG; /* for -tv */ - f->f_st.st_nlink = 2; - } else if (bp->Tdr.t_linkflag == '2') { - if (f->f_lnam == NULL || f->f_lnam[0] == '\0') - tlinkof(&bp->Tdr, f); - f->f_st.st_mode |= S_IFLNK; - } else if (tflag == 0 && (f->f_name)[namlen-2] == '/') - f->f_st.st_mode |= S_IFDIR; - else - f->f_st.st_mode |= tifmt(bp->Tdr.t_linkflag); - if (paxrec & PR_SUN_DEVMAJOR) - /*EMPTY*/; - else if (fmttype == FMT_GNUTAR && bp->Tdr.t_devmajor[0] & 0200) - f->f_rmajor = pbe64(bp->Tdr.t_devmajor) & - 0x7FFFFFFFFFFFFFFFLL; - else - f->f_rmajor = rdoct(bp->Tdr.t_devmajor, 8); - if (paxrec & PR_SUN_DEVMINOR) - /*EMPTY*/; - else if (fmttype == FMT_GNUTAR && bp->Tdr.t_devminor[0] & 0200) - f->f_rminor = pbe64(bp->Tdr.t_devminor) & - 0x7FFFFFFFFFFFFFFFLL; - else - f->f_rminor = rdoct(bp->Tdr.t_devminor, 8); - f->f_st.st_rdev = makedev(f->f_rmajor, f->f_rminor); - f->f_pad = 512; - rd = 512; - } else if (fmttype == FMT_ZIP) { - hsz = SIZEOF_zip_header; - if (attempts == 0 && bread(bp->data, hsz) != hsz) - unexeoa(); - if (memcmp(bp->Zdr.z_signature, mag_zipctr, - sizeof mag_zipctr) == 0 || - memcmp(bp->Zdr.z_signature, mag_zipend, - sizeof mag_zipend) == 0 || - memcmp(bp->Zdr.z_signature, mag_zip64e, - sizeof mag_zip64e) == 0 || - memcmp(bp->Zdr.z_signature, mag_zip64l, - sizeof mag_zip64l) == 0) - return 1; - if (memcmp(bp->Zdr.z_signature, mag_zipsig, sizeof mag_zipsig)) - goto badhdr; - f->f_st.st_uid = myuid; - f->f_st.st_gid = mygid; - f->f_st.st_nlink = 1; - f->f_st.st_mtime = - gdostime(bp->Zdr.z_modtime, bp->Zdr.z_moddate); - f->f_st.st_size = ple32(bp->Zdr.z_nsize); - f->f_csize = ple32(bp->Zdr.z_csize); - f->f_cmethod = ple16(bp->Zdr.z_cmethod); - f->f_chksum = ple32(bp->Zdr.z_crc32); - f->f_gflag = ple16(bp->Zdr.z_gflag); - rd = SIZEOF_zip_header; - namlen = ple16(bp->Zdr.z_namelen)&0177777; - if (f->f_nsiz < namlen+1) { - free(f->f_name); - f->f_name = smalloc(f->f_nsiz = namlen+1); - } - if (bread(f->f_name, namlen) != namlen) - goto corrupt; - (f->f_name)[namlen] = '\0'; - if (f->f_name[namlen-1] == '/') - f->f_st.st_mode = 0777&~(mode_t)umsk|S_IFDIR; - else - f->f_st.st_mode = 0666&~(mode_t)umsk|S_IFREG; - rd += namlen; - if ((l1 = ziprxtra(f, &bp->Zdr)) < 0) - goto corrupt; - rd += l1; - f->f_pad = 1; - } else - abort(); - if (fmttype & TYP_CPIO) { - if (f->f_st.st_nlink <= 0 || namlen <= 0 || namlen >= SANELIMIT) - goto corrupt; - if (namlen > f->f_nsiz) { - if (f->f_name) - free(f->f_name); - f->f_name = smalloc(f->f_nsiz = namlen); - } - if (bread(f->f_name, namlen) != namlen) - unexeoa(); - if (f->f_name[namlen-1] != '\0') - goto corrupt; - rd += namlen; - skippad(rd, f->f_pad); - if (fmttype & TYP_NCPIO && - (!formatforced || fmttype & TYP_SCO)) { - /* - * The UnixWare format is a hack, but not a bad - * one. It is backwards compatible as far as - * possible; old implementations can use the -k - * option and will then get only the beginning - * of a large file, but all other files in the - * archive. - */ - if (namlen >= 24 && memcmp(&f->f_name[namlen-23], - "\0size=", 6) == 0) { - fmttype |= TYP_SCO; - f->f_st.st_size = rdhex(&f->f_name[namlen-17], - 16); - } - } - } - if (attempts) { - if (tflag) - fflush(stdout); - msg(0, 0, sysv3 < 0 ? - "Re-synced after skipping %lld bytes.\n" : - "Re-synchronized on magic number/header.\n", - skipped); - } - attempts = 0; - if (f->f_st.st_atime == 0 || (pax_preserve&(PAX_P_ATIME|PAX_P_EVERY)) == - PAX_P_ATIME) - f->f_st.st_atime = f->f_st.st_mtime; - if ((f->f_dsize = f->f_st.st_size) < 0) - goto badhdr; - if (fmttype & TYP_CPIO && strcmp(f->f_name, trailer) == 0) - return 1; - return 0; -corrupt: - if (kflag) { - if (tflag) - fflush(stdout); - msg(3, 0, "Corrupt header, file(s) may be lost.\n"); - } -badhdr: - if (kflag) { - int next = fmttype & TYP_TAR ? 512 : 1; - if (attempts++ == 0) { - if (tflag) - fflush(stdout); - msg(1, 0, sysv3 < 0 ? "Out of phase; resyncing.\n" : - "Searching for magic number/header.\n"); - errcnt++; - } - for (l1 = next; l1 < hsz; l1++) - bp->data[l1-next] = bp->data[l1]; - if (bread(&bp->data[l1-next], next) != next) - unexeoa(); - skipped++; - goto retry; - } - if (tflag) - fflush(stdout); - msg(3, 1, sysv3 < 0 ? "Out of phase--get help\n" : - sysv3 > 0 ? "Out of sync, bad magic number/header.\n" : - "Bad magic number/header.\n"); - /*NOTREACHED*/ - return -1; -} - -/* - * Determine the kind of archive on tape. - */ -static void -whathdr(void) -{ -again: if (blktop >= SIZEOF_hdr_cpio && - ple16(blkbuf) == mag_bin) { - fmttype = FMT_BINLE; - } else if (blktop >= SIZEOF_hdr_cpio && - pbe16(blkbuf) == mag_bin) { - fmttype = FMT_BINBE; - } else if (blktop >= SIZEOF_c_hdr && - memcmp(blkbuf, mag_odc, sizeof mag_odc) == 0) { - /* - * The DEC format is rubbish. Instead of introducing a new - * archive magic, its engineers reused the POSIX/odc magic - * and changed the fields. But there's a workaround: For a - * real odc archive, the byte following the file name is a - * \0 byte (unless the archive is damaged, of course). If - * it is not a \0 byte, but a \0 byte appears at the - * corresponding location for the DEC format, this is - * treated as a DEC archive. It must be noted that the - * Tru64 UNIX 5.1 cpio command is too stupid even for - * doing that - it will spill out a list of complaints - * if an extended archive is read but -e is not given. - */ - int ns1, ns2; - ns1 = rdoct(((struct c_hdr *)blkbuf)->c_namesz, 6); - ns2 = rdoct(((struct d_hdr *)blkbuf)->d_namesz, 6); - if (blktop >= SIZEOF_d_hdr && - (ns1 >= blktop - SIZEOF_c_hdr || - blkbuf[SIZEOF_c_hdr+ns1-1] != '\0') && - ns2 <= blktop - SIZEOF_d_hdr && - blkbuf[SIZEOF_d_hdr+ns2-1] == '\0') - fmttype = FMT_DEC; - else - fmttype = FMT_ODC; - } else if (blktop >= SIZEOF_Exp_cpio_hdr && - memcmp(blkbuf, mag_asc, sizeof mag_asc) == 0) { - fmttype = FMT_ASC; - } else if (blktop >= SIZEOF_Exp_cpio_hdr && - memcmp(blkbuf, mag_crc, sizeof mag_crc) == 0) { - fmttype = FMT_CRC; - } else if (blktop >= SIZEOF_cray_hdr && - pbe64(blkbuf) == mag_bin) { - /* - * Old and new Cray headers are identical in the first - * 64 header bytes (including the magic). cpio(5) on - * UNICOS does not describe what the new param field - * is for. - * - * An archive is treated as old format if the mtime - * and namesize fields make sense and all characters - * of the name are non-null. - */ - struct cray_hdr *Cp = (struct cray_hdr *)blkbuf; - long long mtime, namesize; - fmttype = FMT_CRAY; - mtime = pbe64(Cp->C_mtime - CRAY_PARAMSZ); - namesize = pbe64(Cp->C_namesize - CRAY_PARAMSZ); - if (mtime > 0 && mtime < (1LL<<31) && - namesize > 0 && namesize < 2048 && - blktop > SIZEOF_cray_hdr- - CRAY_PARAMSZ+namesize+1) { - int i; - for (i = 0; i < namesize; i++) - if (blkbuf[SIZEOF_cray_hdr- - CRAY_PARAMSZ+i] == '\0') - break; - if (i == namesize-1) - fmttype = FMT_CRAY5; - } - } else if (blktop >= 512 && - memcmp(&blkbuf[257], mag_ustar, 6) == 0 && - tcssum((union bincpio *)blkbuf, 1) == 0) { - fmttype = FMT_USTAR; - } else if (blktop >= 512 && - memcmp(&blkbuf[257], mag_gnutar, 8) == 0 && - tcssum((union bincpio *)blkbuf, 1) == 0) { - fmttype = FMT_GNUTAR; - } else if (blktop >= 512 && blkbuf[0] && /* require filename - to avoid match on - /dev/zero etc. */ - memcmp(&blkbuf[257], "\0\0\0\0\0", 5) == 0 && - tcssum((union bincpio *)blkbuf, 0) == 0) { - fmttype = FMT_OTAR; - } else if (blktop >= SIZEOF_zip_header && - (memcmp(blkbuf, mag_zipctr, sizeof mag_zipctr) == 0 || - memcmp(blkbuf, mag_zipsig, sizeof mag_zipsig) == 0 || - memcmp(blkbuf, mag_zipend, sizeof mag_zipend) == 0 || - memcmp(blkbuf, mag_zip64e, sizeof mag_zip64e) == 0 || - memcmp(blkbuf, mag_zip64l, sizeof mag_zip64l) == 0)) { - fmttype = FMT_ZIP; - } else if (blktop >= 512 && memcmp(blkbuf,"\0\0\0\0\0\0\0\0",8) == 0 && - memcmp(&blkbuf[65], mag_bar, sizeof mag_bar) == 0 && - bcssum((union bincpio *)blkbuf) == 0) { - fmttype = FMT_BAR; - compressed_bar = blkbuf[71] == '1'; - curpos = 512; - } else if (!Aflag && blktop > 3 && memcmp(blkbuf, "BZh", 3) == 0 && - redirect("bzip2", "-cd") == 0) { - goto zip; - } else if (!Aflag && blktop > 2 && memcmp(blkbuf, "\37\235", 2) == 0 && - redirect("zcat", NULL) == 0) { - goto zip; - } else if (!Aflag && blktop > 2 && memcmp(blkbuf, "\37\213", 2) == 0 && - redirect("gzip", "-cd") == 0) { - goto zip; - } else if (!Aflag && blktop > 4 && - memcmp(blkbuf, "\355\253\356\333", 4) == 0 && - redirect("rpm2cpio", "-") == 0) { - goto zip; - } else { - msg(3, 0, sysv3 ? "This is not a cpio file, bad header.\n" : - "Not a cpio file, bad header.\n"); - done(1); - } - return; -zip: - blktop = curpos = 0; - blocks = 0; - bytes = 0; - mfl = 0; - mstat(); - if (mread() == 0) - unexeoa(); - goto again; -} - -/* - * Processing of a single file with -i. - */ -static int -infile(struct file *f) -{ - int val; - - if ((fmttype & TYP_CPIO || fmttype == FMT_ZIP && f->f_st.st_size) && - (f->f_st.st_mode&S_IFMT) == S_IFLNK) { - if (f->f_lsiz < f->f_st.st_size+1) - f->f_lnam = srealloc(f->f_lnam, - f->f_lsiz = f->f_st.st_size+1); - if (bread(f->f_lnam, f->f_st.st_size) != f->f_st.st_size) - unexeoa(); - f->f_lnam[f->f_st.st_size] = '\0'; - skippad(f->f_st.st_size, f->f_pad); - } - if (tflag) - val = filet(f, indata); - else - val = filein(f, indata, f->f_name); - return val != 0; -} - -/* - * Fetch the data of regular files from tape and write it to tfd or, if - * tfd < 0, discard it. - */ -static int -indata(struct file *f, const char *tgt, int tfd) -{ - char *buf; - size_t bufsize; - struct stat ts; - long long size; - ssize_t rd; - uint32_t ssum = 0, usum = 0; - int val = 0; - int doswap = 0; - - size = fmttype == FMT_ZIP ? f->f_csize : - f->f_Kbase ? f->f_Kbase : f->f_st.st_size; - doswap = ((bflag|sflag) == 0 || - ckodd(size, 2, "bytes", f->f_name) == 0) & - ((bflag|Sflag) == 0 || - ckodd(size, 4, "halfwords", f->f_name) == 0) & - (bflag|sflag|Sflag); - if (fmttype == FMT_ZIP && f->f_cmethod != C_STORED) - return zipread(f, tgt, tfd, doswap); - if (tfd < 0 || fstat(tfd, &ts) < 0) - ts.st_blksize = 4096; - getbuf(&buf, &bufsize, ts.st_blksize); -again: while (size) { - if ((rd = bread(buf, size > bufsize ? bufsize : size)) <= 0) - unexeoa(); - if (doswap) - swap(buf, rd, bflag || sflag, bflag || Sflag); - if (tfd >= 0 && write(tfd, buf, rd) != rd) { - emsg(3, "Cannot write \"%s\"", tgt); - tfd = -1; - val = -1; - } - size -= rd; - if (fmttype & TYP_CRC) - do { - rd--; - ssum += ((signed char *)buf)[rd]; - usum += ((unsigned char *)buf)[rd]; - } while (rd); - } - if (f->f_Kbase) { - skippad(f->f_Ksize, f->f_pad); - readK2hdr(f); - size = f->f_Krest; - goto again; - } - skippad(fmttype==FMT_ZIP ? f->f_csize : - f->f_Ksize ? f->f_Krest : f->f_st.st_size, f->f_pad); - if (fmttype & TYP_CRC) { - if (f->f_chksum != ssum && f->f_chksum != usum) { - msg(3, 0, "\"%s\" - checksum error\n", f->f_name); - if (kflag) - errcnt++; - else - val = -1; - } - } - return val; -} - -/* - * Skip the data for a file on tape. - */ -static int -skipfile(struct file *f) -{ - char b[4096]; - long long size; - ssize_t rd; - - if (fmttype & TYP_TAR && ((f->f_st.st_mode&S_IFMT) == S_IFLNK || - f->f_st.st_nlink > 1)) { - if (fmttype & TYP_USTAR && (!formatforced || - fmttype == FMT_PAX) && - f->f_st.st_nlink > 1 && - f->f_st.st_size > 0) - /*EMPTY*/; - else - return 0; - } - /* - * SVR4 cpio derivatives always ignore the size of these, - * even if not reading tar formats. We do the same for now, - * although POSIX (for -H odc format) says the contrary. - */ - if (fmttype != FMT_ZIP && ((f->f_st.st_mode&S_IFMT) == S_IFDIR || - (f->f_st.st_mode&S_IFMT) == S_IFCHR || - (f->f_st.st_mode&S_IFMT) == S_IFBLK || - (f->f_st.st_mode&S_IFMT) == S_IFIFO || - (f->f_st.st_mode&S_IFMT) == S_IFNAM || - (f->f_st.st_mode&S_IFMT) == S_IFNWK)) - return 0; - if (fmttype == FMT_ZIP && f->f_gflag & FG_DESC) - return zipread(f, f->f_name, -1, 0); - size = fmttype == FMT_ZIP ? f->f_csize : - f->f_Kbase ? f->f_Kbase : f->f_st.st_size; -again: while (size) { - if ((rd = bread(b, size > sizeof b ? sizeof b : size)) <= 0) - unexeoa(); - size -= rd; - } - if (f->f_Kbase) { - skippad(f->f_Ksize, f->f_pad); - readK2hdr(f); - size = f->f_Krest; - goto again; - } - skippad(fmttype==FMT_ZIP ? f->f_csize : - f->f_Ksize ? f->f_Krest : f->f_st.st_size, f->f_pad); - return 0; -} - -/* - * Skip data also, but perform checks as if copying. - */ -static int -skipdata(struct file *f, int (*copydata)(struct file *, const char *, int)) -{ - switch (f->f_st.st_mode&S_IFMT) { - case S_IFLNK: - break; - case S_IFDIR: - case S_IFBLK: - case S_IFCHR: - case S_IFIFO: - case S_IFNAM: - case S_IFNWK: - if (fmttype != FMT_ZIP) - break; - /*FALLTHRU*/ - case S_IFREG: - default: - if (fmttype & TYP_TAR && f->f_st.st_nlink > 1 && - ((fmttype & TYP_USTAR) == 0 || - formatforced && fmttype != FMT_PAX)) - break; - if (copydata(f, f->f_name, -1) != 0) - return 1; - } - return 0; -} - -/* - * Seek to a position in the archive measured from the begin of - * operation. Handle media-dependent seeks. n must be a multiple - * of the tape device's physical block size. - */ -static int -tseek(off_t n) -{ - int fault; - - if (tapeblock > 0) { - int i = (n - poffs) / tapeblock; -#if defined (__linux__) || defined (__sun) || defined (__FreeBSD__) || \ - defined (__hpux) || defined (_AIX) || defined (__NetBSD__) || \ - defined (__OpenBSD__) || defined (__DragonFly__) || \ - defined (__CYGWIN__) - struct mtop mo; - mo.mt_op = i > 0 ? MTFSR : MTBSR; - mo.mt_count = i > 0 ? i : -i; - fault = ioctl(mt, MTIOCTOP, &mo); -#endif - } else - fault = lseek(mt, n - poffs, SEEK_CUR) == (off_t)-1 ? -1 : 0; - if (fault == 0) - poffs = n; - return fault; -} - -/* - * Advance to the trailer on the tape (for -A). - */ -static int -totrailer(void) -{ - union bincpio bc; - struct file f; - off_t ooffs, noffs, diff; - int i; - - if (mread() == 0) - unexeoa(); - if (fmttype == FMT_NONE) - whathdr(); - memset(&f, 0, sizeof f); - for (;;) { - ooffs = aoffs; - if ((i = readhdr(&f, &bc)) < 0) - goto fail; - if (i > 0) - break; - markdev(f.f_st.st_dev); - if (skipfile(&f) != 0) - goto fail; - if (fmttype == FMT_ZIP) - zipdefer(f.f_name, &f.f_st, ooffs, - f.f_chksum, f.f_csize, &bc.Zdr); - pax_track(f.f_name, f.f_st.st_mtime); - } - /* - * Now seek to the position of the trailer, but retain the - * block alignment. - */ - diff = ooffs % blksiz; - noffs = ooffs - diff; - if (diff ? tseek(noffs) == 0 && mread() >= diff && tseek(noffs) == 0 - : tseek(ooffs) == 0) { - free(f.f_name); - free(f.f_lnam); - nwritten = ooffs; - curpos = diff; - return 0; - } -fail: msg(4, 1, "Unable to append to this archive\n"); - /*NOTREACHED*/ - return 1; -} - -static long long -rdoct(const char *data, int len) -{ - int i; - long long val = 0; - - for (i = 0; i < len && data[i] == ' '; i++); - for ( ; i < len && data[i] && data[i] != ' '; i++) { - val <<= 3; - val += data[i] - '0'; - } - return val; -} - -static long long -rdhex(const char *data, int len) -{ - int i; - long long val = 0; - - for (i = 0; i < len && data[i] == ' '; i++); - for ( ; i < len && data[i] && data[i] != ' '; i++) { - val <<= 4; - val += data[i] > '9' ? data[i] > 'F' ? data[i] - 'a' + 10 : - data[i] - 'A' + 10 : data[i] - '0'; - } - return val; -} - -void -unexeoa(void) -{ - if (sysv3) { - fprintf(stderr, - "Can't read input: end of file encountered " - "prior to expected end of archive.\n"); - done(1); - } - else - msg(3, 1, "Unexpected end-of-archive encountered.\n"); -} - -static char *peekdata; -static size_t peekbot, peektop, peeksize; - -void -bunread(const char *data, size_t sz) -{ - peekdata = srealloc(peekdata, peeksize += sz); - memcpy(&peekdata[peekbot], data, sz); - peektop += sz; - aoffs -= sz; -} - -/* - * Buffered read of data from tape. sz is the amount of data required - * by the archive format; if it cannot be retrieved, processing fails. - */ -ssize_t -bread(char *data, size_t sz) -{ - ssize_t rd = 0; - - if (peekdata) { - rd = sz>peektop-peekbot ? peektop-peekbot : sz; - memcpy(&data[0], &peekdata[peekbot], rd); - sz -= rd; - peekbot += rd; - if (peekbot == peektop) { - free(peekdata); - peekdata = 0; - peeksize = 0; - peekbot = peektop = 0; - } - } - while (sz) { - if (blktop - curpos >= sz) { - memcpy(&data[rd], &blkbuf[curpos], sz); - curpos += sz; - rd += sz; - aoffs += rd; - return rd; - } - if (blktop > curpos) { - memcpy(&data[rd], &blkbuf[curpos], blktop - curpos); - rd += blktop - curpos; - sz -= blktop - curpos; - curpos = blktop; - } - if (mfl < 0) { - if (mfl == -1) { - emsg(3, "I/O error on \"%s\"", - Iflag ? Iflag : "input"); - if (kflag == 0) - break; - if (tapeblock < 0 && ( - (mtst.st_mode&S_IFMT)==S_IFBLK|| - (mtst.st_mode&S_IFMT)==S_IFCHR|| - (mtst.st_mode&S_IFMT)==S_IFREG - ) && lseek(mt, blksiz, SEEK_CUR) - == (off_t)-1) { - emsg(3, "Cannot lseek()"); - done(1); - } - } - if (kflag == 0 || mfl == -2) { - if ((mtst.st_mode&S_IFMT)!=S_IFCHR && - (mtst.st_mode&S_IFMT)!=S_IFBLK) - break; - newmedia(mfl == -1 ? errno : 0); - if (mfl == -1) { - mfl = -2; - break; - } - if (fmttype & TYP_BAR) - curpos = 512; - } - } - mread(); - } - aoffs += rd; - return rd; -} - -/* - * Read a block of data from tape. - */ -static ssize_t -mread(void) -{ - ssize_t ro, rt = 0; - - do { - if ((ro = read(mt, blkbuf + rt, blksiz - rt)) <= 0) { - if (ro < 0) { - if (errno == EINTR) - continue; - mfl = -1; - } else - mfl = -2; - if (rt > 0) { - rt += ro; - break; - } - curpos = blktop = 0; - return ro; - } - rt += ro; - poffs += ro; - if (tapeblock == 0) { - tapeblock = ro; - if (!Bflag && !Cflag) - blksiz = ro; - } - } while (rt < blksiz); - curpos = 0; - blocks += rt >> 9; - bytes += rt & 0777; - blktop = rt; - return rt; -} - -/* - * Look what kind of tape or other archive media we are working on and - * set the buffer size appropriately (if not specified by the user). - */ -static void -mstat(void) -{ - if (fstat(mt, &mtst) < 0) { - emsg(3, "Error during stat() of archive"); - done(1); - } -#if defined (__linux__) - if ((mtst.st_mode&S_IFMT) == S_IFCHR) { - struct mtget mg; - if (ioctl(mt, MTIOCGET, &mg) == 0) - tapeblock = (mg.mt_dsreg&MT_ST_BLKSIZE_MASK) >> - MT_ST_BLKSIZE_SHIFT; - } else if ((mtst.st_mode&S_IFMT) == S_IFBLK) { - /* - * If using a block device, write blocks of the floppy - * disk sector with direct i/o. This enables signals - * after each block is written instead of being ~40 - * seconds in uninterruptible sleep when calling close() - * later. For block devices other than floppies, use the - * kernel defined i/o block size. For floppies, use direct - * i/o even when reading since it is faster. - */ - struct floppy_struct fs; - int floppy = -1; - int blkbsz; - - if (blksiz == 0) { - if ((floppy = ioctl(mt, FDGETPRM, &fs)) == 0) - blksiz = fs.sect * FD_SECTSIZE(&fs); -#ifdef BLKBSZGET - else if (ioctl(mt, BLKBSZGET, &blkbsz) == 0) - blksiz = blkbsz; -#endif /* BLKBSZGET */ - } -#ifdef O_DIRECT - if ((action == 'o' || floppy == 0) && blksiz != 0) { - int flags; - if ((flags = fcntl(mt, F_GETFL)) != -1) - fcntl(mt, F_SETFL, flags | O_DIRECT); - } - } -#endif /* O_DIRECT */ -#elif defined (__sun) - if ((mtst.st_mode&S_IFMT) == S_IFCHR) { - struct mtdrivetype_request mr; - static struct mtdrivetype md; - mr.size = sizeof md; - mr.mtdtp = &md; - if (ioctl(mt, MTIOCGETDRIVETYPE, &mr) == 0) - tapeblock = md.bsize; - } -#elif defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) \ - || defined (__DragonFly__) - if ((mtst.st_mode&S_IFMT) == S_IFCHR) { - struct mtget mg; - if (ioctl(mt, MTIOCGET, &mg) == 0) - tapeblock = mg.mt_blksiz; - } -#elif defined (__CYGWIN__) - if ((mtst.st_mode&S_IFMT) == S_IFCHR) { - struct mtget mg; - if (ioctl(mt, MTIOCGET, &mg) == 0) - tapeblock = (mg.mt_dsreg&MT_ST_BLKSIZE_MASK) >> - MT_ST_BLKSIZE_SHIFT; - } -#elif defined (__hpux) || defined (_AIX) -#endif /* SVR4.2MP */ - if (blksiz == 0) - switch (mtst.st_mode&S_IFMT) { - case S_IFREG: - case S_IFBLK: - blksiz = 4096; - break; - case S_IFCHR: - if (action == 'o' && !Aflag) { - if (pax != PAX_TYPE_CPIO) { - if (fmttype & TYP_PAX) - blksiz = 5120; - else if (fmttype & TYP_TAR) - blksiz = 10240; - else if (fmttype & TYP_CPIO) - blksiz = 5120; - else - blksiz = 512; - } else - blksiz = tapeblock>0 ? tapeblock : 512; - } else - blksiz = tapeblock > 0 && tapeblock % 1024 ? - tapeblock : tapeblock > 10240 ? - tapeblock : 10240; - break; - default: - blksiz = 512; - } -} - -/* - * Skip tape data such that size becomes aligned to pad. - */ -static int -skippad(unsigned long long size, int pad) -{ - char b[512]; - int to; - - if ((to = size % pad) != 0) { - if (bread(b, pad - to) != pad - to) - unexeoa(); - } - return 0; -} - -static int -allzero(const char *bp, int n) -{ - int i; - - for (i = 0; i < n; i++) - if (bp[i] != '\0') - return 0; - return 1; -} - -#define CACHESIZE 16 - -static const char * -getuser(uid_t uid) -{ - static struct { - char *name; - uid_t uid; - } cache[CACHESIZE]; - static int last; - int i; - struct passwd *pwd; - const char *name; - - for (i = 0; i < CACHESIZE && cache[i].name; i++) - if (cache[i].uid == uid) - goto found; - if ((pwd = getpwuid(uid)) != NULL) - name = pwd->pw_name; - else - name = ""; - if (i >= CACHESIZE) { - if (last >= CACHESIZE) - last = 0; - i = last++; - } - if (cache[i].name) - free(cache[i].name); - cache[i].name = sstrdup(name); - cache[i].uid = uid; -found: return cache[i].name[0] ? cache[i].name : NULL; -} - -static const char * -getgroup(gid_t gid) -{ - static struct { - char *name; - gid_t gid; - } cache[CACHESIZE]; - static int last; - int i; - struct group *grp; - const char *name; - - for (i = 0; i < CACHESIZE && cache[i].name; i++) - if (cache[i].gid == gid) - goto found; - if ((grp = getgrgid(gid)) != NULL) - name = grp->gr_name; - else - name = ""; - if (i >= CACHESIZE) { - if (last >= CACHESIZE) - last = 0; - i = last++; - } - if (cache[i].name) - free(cache[i].name); - cache[i].name = sstrdup(name); - cache[i].gid = gid; -found: return cache[i].name[0] ? cache[i].name : NULL; -} - -/* - * Return a version of the passed string that contains at most one '%d' - * and no other printf formats. - */ -char * -oneintfmt(const char *op) -{ - char *new, *np; - int no = 0; - - np = new = smalloc(2 * strlen(op) + 1); - do { - if (*op == '%') { - *np++ = *op++; - if (*op != '%') - if (*op != 'd' || no++) - *np++ = '%'; - } - *np++ = *op; - } while (*op++); - return new; -} - -char * -sstrdup(const char *op) -{ - char *np; - - np = smalloc(strlen(op) + 1); - strcpy(np, op); - return np; -} - -/* - * Add this pattern to the extraction list with -i. - */ -void -addg(const char *pattern, int art) -{ - struct glist *gp; - - gp = scalloc(1, sizeof *gp); - if (pax == PAX_TYPE_CPIO && pattern[0] == '!') { - gp->g_not = 1; - pattern++; - } - gp->g_pat = sstrdup(pattern); - gp->g_art = art; - if (pax != PAX_TYPE_CPIO) { - struct glist *gb = NULL, *gc; - for (gc = patterns; gc; gc = gc->g_nxt) - gb = gc; - if (gb) - gb->g_nxt = gp; - else - patterns = gp; - } else { - gp->g_nxt = patterns; - patterns = gp; - } -} - -/* - * Check if the file name s matches any of the given patterns. - */ -static struct glist * -want(struct file *f, struct glist **gb) -{ - extern int gmatch(const char *, const char *); - struct glist *gp; - - for (gp = patterns; gp; gp = gp->g_nxt) { - if ((gmatch(f->f_name, gp->g_pat) != 0) ^ gp->g_not && - (pax_nflag == 0 || gp->g_gotcha == 0)) { - return gp; - } - *gb = gp; - } - return NULL; -} - -static void -patfile(void) -{ - struct iblok *ip; - char *name = NULL; - size_t namsiz = 0, namlen; - - if ((ip = ib_open(Eflag, 0)) == NULL) - msg(3, -2, "Cannot open \"%s\" to read patterns\n", Eflag); - while ((namlen = ib_getlin(ip, &name, &namsiz, srealloc)) != 0) { - if (name[namlen-1] == '\n') - name[--namlen] = '\0'; - addg(name, 0); - } - ib_close(ip); -} - -void -swap(char *b, size_t sz, int s8, int s16) -{ - uint8_t u8; - uint16_t u16; - union types2 *t2; - union types4 *t4; - int i; - - if (s8) { - for (i = 0; i < (sz >> 1); i++) { - t2 = &((union types2 *)b)[i]; - u8 = t2->byte[0]; - t2->byte[0] = t2->byte[1]; - t2->byte[1] = u8; - } - } - if (s16) { - for (i = 0; i < (sz >> 2); i++) { - t4 = &((union types4 *)b)[i]; - u16 = t4->sword[0]; - t4->sword[0] = t4->sword[1]; - t4->sword[1] = u16; - } - } -} - -static int -ckodd(long long size, int mod, const char *str, const char *fn) -{ - if (size % mod) { - msg(3, 0, "Cannot swap %s of \"%s\", odd number of %s\n", - str, fn, str); - errcnt++; - return 1; - } - return 0; -} - -/* - * Interactive rename (-r option). - */ -static int -rname(char **oldp, size_t *olds) -{ - char *new = NULL; - size_t newsize = 0; - int i, r; - char c; - - fprintf(stderr, "Rename \"%s\"? ", *oldp); - if (tty == 0) - if ((tty = open("/dev/tty", O_RDWR)) < 0 || - fcntl(tty, F_SETFD, FD_CLOEXEC) < 0) - err: msg(3, 1, "Cannot read tty.\n"); - i = 0; - while ((r = read(tty, &c, 1)) == 1 && c != '\n') { - if (i+1 >= newsize) - new = srealloc(new, newsize += 32); - new[i++] = c; - } - if (r <= 0) - goto err; - if (new == NULL) - return 0; - new[i] = '\0'; - if (new[0] == '.' && new[1] == '\0') { - free(new); - } else { - free(*oldp); - *oldp = new; - *olds = newsize; - } - return 1; -} - -/* - * Filter data from tape through the commands given in arg?. - */ -static int -redirect(const char *arg0, const char *arg1) -{ - int pd[2]; - - if (pipe(pd) < 0) - return -1; - switch (fork()) { - case 0: - if (tapeblock>=0 || lseek(mt, -blktop, SEEK_CUR) == (off_t)-1) { - int xpd[2]; - if (pipe(xpd) == 0 && fork() == 0) { - ssize_t rd, wo, wt; - close(xpd[0]); - do { - wo = wt = 0; - do { - if ((wo = write(xpd[1], - blkbuf + wt, - blktop - wt)) - <= 0) { - if (errno == EINTR) - continue; - _exit(0); - } - wt += wo; - } while (wt < blktop); - } while ((rd = mread()) >= 0); - if (rd < 0) { - emsg(3, "Read error on \"%s\"", - Iflag && !sysv3 ? - Iflag : "input"); - } - _exit(0); - } else { - close(xpd[1]); - dup2(xpd[0], 0); - close(xpd[0]); - } - } else { - dup2(mt, 0); - } - close(mt); - dup2(pd[1], 1); - close(pd[0]); - close(pd[1]); - execlp(arg0, arg0, arg1, NULL); - fprintf(stderr, "%s: could not exec %s: %s\n", - progname, arg0, strerror(errno)); - _exit(0177); - /*NOTREACHED*/ - default: - dup2(pd[0], mt); - close(pd[0]); - close(pd[1]); - tapeblock = -1; - break; - case -1: - return -1; - } - return 0; -} - -/* - * Get the name stored in a tar header. buf is expected to be at least - * TPFXSIZ+TNAMSIZ+2 bytes. - */ -static char * -tnameof(struct tar_header *hp, char *buf) -{ - const char *cp; - char *bp = buf; - - if (fmttype & TYP_USTAR && fmttype != FMT_GNUTAR && - hp->t_prefix[0] != '\0') { - cp = hp->t_prefix; - while (cp < &hp->t_prefix[TPFXSIZ] && *cp) - *bp++ = *cp++; - if (bp > buf) - *bp++ = '/'; - } - cp = hp->t_name; - while (cp < &hp->t_name[TNAMSIZ] && *cp) - *bp++ = *cp++; - *bp = '\0'; - return buf; -} - -/* - * Store fn as file name in a tar header. - */ -static int -tmkname(struct tar_header *hp, const char *fn) -{ - const char *cp, *cs = NULL; - - for (cp = fn; *cp; cp++) { - if (fmttype & TYP_USTAR && *cp == '/' && cp[1] != '\0' && - cp > fn && cp-fn <= TPFXSIZ) - cs = cp; - } - if (fmttype == FMT_GNUTAR && cp - fn > 99) { - writegnuname(fn, cp - fn + 1, 'L'); - cp = &fn[99]; - } else if (cp - (cs ? &cs[1] : fn) > TNAMSIZ) { - if (fmttype & TYP_PAX && utf8(fn)) { - paxrec |= PR_PATH; - strcpy(hp->t_name, sequence()); - return 0; - } - msg(3, 0, "%s: file name too long\n", fn); - return -1; - } - if (cs && cp - fn > TNAMSIZ) { - memcpy(hp->t_prefix, fn, cs - fn); - if (cs - fn < TPFXSIZ) - hp->t_prefix[cs - fn] = '\0'; - memcpy(hp->t_name, &cs[1], cp - &cs[1]); - if (cp - &cs[1] < TNAMSIZ) - hp->t_name[cp - &cs[1]] = '\0'; - } else { - memcpy(hp->t_name, fn, cp - fn); - if (cp - fn < TNAMSIZ) - hp->t_name[cp - fn] = '\0'; - } - return 0; -} - -/* - * Get the link name of a tar header. - */ -static void -tlinkof(struct tar_header *hp, struct file *f) -{ - const char *cp; - char *bp; - - - if (f->f_lsiz < TNAMSIZ+1) - f->f_lnam = srealloc(f->f_lnam, f->f_lsiz = TNAMSIZ+1); - cp = hp->t_linkname; - bp = f->f_lnam; - while (cp < &hp->t_linkname[TNAMSIZ] && *cp) - *bp++ = *cp++; - *bp = '\0'; -} - -/* - * Create the link name in a tar header. - */ -static int -tmklink(struct tar_header *hp, const char *fn) -{ - const char *cp; - - for (cp = fn; *cp; cp++); - if (fmttype == FMT_GNUTAR && cp - fn > 99) { - writegnuname(fn, cp - fn + 1, 'K'); - cp = &fn[99]; - } else if (cp - fn > TNAMSIZ) { - if (fmttype & TYP_PAX && utf8(fn)) { - paxrec |= PR_LINKPATH; - strcpy(hp->t_linkname, sequence()); - return 0; - } - msg(3, 0, "%s: linked name too long\n", fn); - return -1; - } - memcpy(hp->t_linkname, fn, cp - fn); - if (cp - fn < TNAMSIZ) - hp->t_linkname[cp - fn] = '\0'; - return 0; -} - -static int -tlflag(struct stat *st) -{ - if (fmttype & TYP_BAR) { - switch (st->st_mode & S_IFMT) { - case S_IFREG: - case S_IFDIR: - return '0'; - case S_IFLNK: - return '2'; - default: - return '3'; - } - } else if (fmttype & TYP_USTAR) { - switch (st->st_mode & S_IFMT) { - case S_IFREG: - return '0'; - case S_IFLNK: - return '2'; - case S_IFCHR: - return '3'; - case S_IFBLK: - return '4'; - case S_IFDIR: - return '5'; - case S_IFIFO: - return '6'; - default: - return -1; - } - } else { - switch (st->st_mode & S_IFMT) { - case S_IFREG: - return '\0'; - case S_IFLNK: - return '2'; - default: - return -1; - } - } -} - -/* - * Ustar checksums are created using unsigned chars, as specified by - * POSIX. Traditional tar implementations use signed chars. Some - * implementations (notably SVR4 cpio derivatives) use signed chars - * even for ustar archives, but this is clearly an implementation bug. - */ -static void -tchksum(union bincpio *bp) -{ - uint32_t sum; - char *cp; - - memset(bp->Tdr.t_chksum, ' ', sizeof bp->Tdr.t_chksum); - sum = 0; - if (fmttype & TYP_USTAR) - for (cp = bp->data; cp < &bp->data[512]; cp++) - sum += *((unsigned char *)cp); - else - for (cp = bp->data; cp < &bp->data[512]; cp++) - sum += *((signed char *)cp); - sprintf(bp->Tdr.t_chksum, "%7.7o", sum); -} - -static int -tcssum(union bincpio *bp, int ustar) -{ - uint32_t ssum = 0, usum = 0, osum; - char ochk[sizeof bp->Tdr.t_chksum]; - char *cp; - - osum = rdoct(bp->Tdr.t_chksum, 8); - memcpy(ochk, bp->Tdr.t_chksum, sizeof ochk); - memset(bp->Tdr.t_chksum, ' ', sizeof bp->Tdr.t_chksum); - for (cp = bp->data; cp < &bp->data[512]; cp++) { - ssum += *((signed char *)cp); - usum += *((unsigned char *)cp); - } - memcpy(bp->Tdr.t_chksum, ochk, sizeof bp->Tdr.t_chksum); - return ssum != osum && usum != osum; -} - -static int -trdsum(union bincpio *bp) -{ - int i; - - if (fmttype & TYP_BAR) - i = bcssum(bp); - else - i = tcssum(bp, fmttype & TYP_USTAR); - if (i) - msg(3, 0, "Bad header - checksum error.\n"); - return i; -} - -static mode_t -tifmt(int c) -{ - switch (c) { - default: - case '\0': - case '0': - return S_IFREG; - case '2': - return S_IFLNK; - case '3': - return S_IFCHR; - case '4': - return S_IFBLK; - case '5': - return S_IFDIR; - case '6': - return S_IFIFO; - } -} - -/* - * bar format support functions. - */ -static void -bchksum(union bincpio *bp) -{ - uint32_t sum; - char *cp; - - memset(bp->Bdr.b_chksum, ' ', sizeof bp->Bdr.b_chksum); - sum = 0; - for (cp = bp->data; cp < &bp->data[512]; cp++) - sum += *((signed char *)cp); - sprintf(bp->Bdr.b_chksum, "%7.7o", sum); -} - -static int -bcssum(union bincpio *bp) -{ - uint32_t sum, osum; - char ochk[sizeof bp->Bdr.b_chksum]; - char *cp; - - osum = rdoct(bp->Bdr.b_chksum, 8); - memcpy(ochk, bp->Bdr.b_chksum, sizeof ochk); - memset(bp->Bdr.b_chksum, ' ', sizeof bp->Bdr.b_chksum); - sum = 0; - for (cp = bp->data; cp < &bp->data[512]; cp++) - sum += *((signed char *)cp); - memcpy(bp->Bdr.b_chksum, ochk, sizeof bp->Bdr.b_chksum); - return sum != osum; -} - -static void -blinkof(const char *cp, struct file *f, int namlen) -{ - if (f->f_lsiz < 512) - f->f_lnam = srealloc(f->f_lnam, f->f_lsiz = 512); - strcpy(f->f_lnam, &cp[SIZEOF_bar_header + namlen]); -} - -static void -dump_barhdr(void) -{ - union bincpio bc; - static int volno; - static time_t now = -1; - - memset(&bc, 0, 512); - sprintf(bc.Bdr.b_uid, "%d", myuid & 07777777); - sprintf(bc.Bdr.b_gid, "%d", mygid & 07777777); - bc.Bdr.b_size[0] = '0'; - memcpy(bc.Bdr.b_bar_magic, mag_bar, sizeof bc.Bdr.b_bar_magic); - sprintf(bc.Bdr.b_volume_num, "%d", ++volno & 0777); - bc.Bdr.b_compressed = '0'; - if (now == (time_t)-1) - time(&now); - sprintf(bc.Bdr.b_date, "%llo", now & 077777777777LL); - bchksum(&bc); - bwrite(bc.data, 512); -} - -/* - * Support for compressed bar format (any regular file is piped through zcat). - */ -static pid_t zpid; - -static int -zcreat(const char *name, mode_t mode) -{ - int pd[2]; - int fd; - - if (pipe(pd) < 0) - return -1; - if ((fd = creat(name, mode)) < 0) { - fd = errno; - close(pd[0]); - close(pd[1]); - errno = fd; - return -1; - } - switch (zpid = fork()) { - case -1: - return -1; - case 0: - dup2(pd[0], 0); - dup2(fd, 1); - close(pd[0]); - close(pd[1]); - close(fd); - execlp("zcat", "zcat", NULL); - _exit(0177); - /*NOTREACHED*/ - } - close(pd[0]); - close(fd); - sigset(SIGPIPE, SIG_IGN); - return pd[1]; -} - -static int -zclose(int fd) -{ - int c, s; - - c = close(fd); - while (waitpid(zpid, &s, 0) != zpid); - return c != 0 || s != 0 ? -1 : 0; -} - -/* - * If using the -A option, device numbers that appear in the archive - * are not reused for appended files. This avoids wrong hardlink - * connections on extraction. - * - * In fact, this should be done even if we did not fake device and - * inode numbers, since it is not guaranteed that the archive was - * created on the same machine, or even on the same machine, inode - * number could have changed after a file was unlinked. - */ -static void -markdev(dev_t dev) -{ - struct dslot *dp, *dq = NULL;; - - for (dp = markeddevs; dp; dp = dp->d_nxt) { - if (dp->d_dev == dev) - return; - dq = dp; - } - dp = scalloc(1, sizeof *dp); - dp->d_dev = dev; - if (markeddevs == NULL) - markeddevs = dp; - else - dq->d_nxt = dp; -} - -static int -marked(dev_t dev) -{ - struct dslot *dp; - - for (dp = markeddevs; dp; dp = dp->d_nxt) - if (dp->d_dev == dev) - return 1; - return 0; -} - -static void -cantsup(int err, const char *file) -{ - if (sysv3) - msg(err ? 3 : 2, 0, - "format can't support expanded types on %s\n", - file); - else - msg(0, 0, "%s format can't support expanded types on %s\n", - err ? "Error" : "Warning", file); - errcnt++; -} - -static void -onint(int signo) -{ - if (cur_ofile && cur_tfile && rename(cur_tfile, cur_ofile) < 0) - emsg(3, "Cannot recover original \"%s\"", cur_ofile); - if (cur_ofile && cur_tfile == NULL && unlink(cur_ofile) < 0) - emsg(3, "Cannot remove incomplete \"%s\"", cur_ofile); - exit(signo | 0200); -} - -/* - * Read the compressed zip data part for a file. - */ -static int -zipread(struct file *f, const char *tgt, int tfd, int doswap) -{ - int val = 0; - uint32_t crc = 0; - - if (f->f_gflag & FG_DESC) { - if (f->f_cmethod != C_DEFLATED && f->f_cmethod != C_ENHDEFLD || - f->f_gflag & FG_CRYPT) - msg(4, 1, "Cannot handle zip data descriptor\n"); - f->f_csize = 0x7FFFFFFFFFFFFFFFLL; - f->f_st.st_size = 0x7FFFFFFFFFFFFFFFLL; - } else if (tfd < 0) - return skipfile(f); - if (f->f_gflag & FG_CRYPT) - return cantunzip(f, "encrypted"); - switch (f->f_cmethod) { - case C_DEFLATED: - case C_ENHDEFLD: - val = zipinflate(f, tgt, tfd, doswap, &crc); - break; - case C_SHRUNK: - val = zipunshrink(f, tgt, tfd, doswap, &crc); - break; - case C_IMPLODED: - val = zipexplode(f, tgt, tfd, doswap, &crc); - break; - case C_REDUCED1: - case C_REDUCED2: - case C_REDUCED3: - case C_REDUCED4: - val = zipexpand(f, tgt, tfd, doswap, &crc); - break; - case C_TOKENIZED: - return cantunzip(f, "tokenized"); - case C_DCLIMPLODED: - val = zipblast(f, tgt, tfd, doswap, &crc); - break; - case C_BZIP2: -#if USE_BZLIB - val = zipunbz2(f, tgt, tfd, doswap, &crc); - break; -#else /* !USE_BZLIB */ - return cantunzip(f, "bzip2 compressed"); -#endif /* !USE_BZLIB */ - default: - return cantunzip(f, "compressed"); - } - if (f->f_gflag & FG_DESC) - zipreaddesc(f); - if (val == 0 && crc != f->f_chksum) { - msg(3, 0, "\"%s\" - checksum error\n", f->f_name); - return -1; - } - return val; -} - -/* - * Read a zip data descriptor (i. e. a field after the compressed data - * that contains the actual values for sizes and crc). - */ -static void -zipreaddesc(struct file *f) -{ - if (f->f_oflag & OF_ZIP64) { - struct zipddesc64 zd64; - bread((char *)&zd64, SIZEOF_zipddesc64); - if (memcmp(zd64.zd_signature, mag_zipdds, sizeof mag_zipdds)) - msg(4, 1, "Invalid zip data descriptor\n"); - f->f_chksum = ple32(zd64.zd_crc32); - f->f_dsize = f->f_st.st_size = ple64(zd64.zd_nsize) & - 0xFFFFFFFFFFFFFFFFULL; - f->f_csize = ple64(zd64.zd_csize) & - 0xFFFFFFFFFFFFFFFFULL; - } else { - struct zipddesc zd; - bread((char *)&zd, SIZEOF_zipddesc); - if (memcmp(zd.zd_signature, mag_zipdds, sizeof mag_zipdds)) - msg(4, 1, "Invalid zip data descriptor\n"); - f->f_chksum = ple32(zd.zd_crc32); - f->f_dsize = f->f_st.st_size = ple32(zd.zd_nsize)&0xFFFFFFFFUL; - f->f_csize = ple32(zd.zd_csize)&0xFFFFFFFFUL; - } -} - -static int -cantunzip(struct file *f, const char *method) -{ - msg(3, 0, "Cannot unzip %s file \"%s\"\n", method, f->f_name); - errcnt++; - return skipfile(f); -} - -/* - * PC-DOS time format: - * - * 31 24 20 15 10 4 0 - * | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - * | | | | | - * |year |months |days |hours |minutes |biseconds| - * - * refers to local time on the machine it was created on. - */ - -static time_t -gdostime(const char *tp, const char *dp) -{ - uint32_t v; - struct tm tm; - - v = (int)(tp[0]&0377) + - ((int)(tp[1]&0377) << 8) + - ((int)(dp[0]&0377) << 16) + - ((int)(dp[1]&0377) << 24); - memset(&tm, 0, sizeof tm); - tm.tm_sec = (v&0x1F) << 1; - tm.tm_min = (v&0x7E0) >> 5; - tm.tm_hour = (v&0xF800) >> 11; - tm.tm_mday = ((v&0x1F0000) >> 16); - tm.tm_mon = ((v&0x1E00000) >> 21) - 1; - tm.tm_year = ((v&0xFE000000) >> 25) + 80; - tm.tm_isdst = -1; - return mktime(&tm); -} - -static void -mkdostime(time_t t, char *tp, char *dp) -{ - uint32_t v; - struct tm *tm; - - tm = localtime(&t); - v = (tm->tm_sec >> 1) + (tm->tm_sec&1) + (tm->tm_min << 5) + - (tm->tm_hour << 11) + (tm->tm_mday << 16) + - ((tm->tm_mon+1) << 21) + ((tm->tm_year - 80) << 25); - le16p(v&0x0000ffff, tp); - le16p((v&0xffff0000) >> 16, dp); -} - -/* - * Read and interpret the zip extra field for a file. - */ -static ssize_t -ziprxtra(struct file *f, struct zip_header *z) -{ - union zextra *x, *xp; - short tag, size; - ssize_t len; - - len = ple16(z->z_extralen)&0177777; - if (len > 0) { - x = smalloc(len); - if (bread((char *)x, len) != len) - return -1; - if (len < 4) - return len; - xp = x; - while (len > 0) { - if (len < 4) - return -1; - tag = ple16(xp->Ze_gn.ze_gn_tag); - size = (ple16(xp->Ze_gn.ze_gn_tsize)&0177777) + 4; - switch (tag) { - case mag_zip64f: /* ZIP64 extended information */ - if (size != SIZEOF_zextra_64 && - size != SIZEOF_zextra_64_a && - size != SIZEOF_zextra_64_b) - break; - if (f->f_st.st_size == 0xffffffff) - f->f_st.st_size = - ple64(xp->Ze_64.ze_64_nsize); - if (f->f_csize == 0xffffffff) - f->f_csize = - ple64(xp->Ze_64.ze_64_csize); - f->f_oflag |= OF_ZIP64; - break; - case 0x000d: /* PKWARE Unix Extra Field */ - if (size != SIZEOF_zextra_pk) - break; - f->f_st.st_atime = ple32(xp->Ze_pk.ze_pk_atime); - f->f_st.st_mtime = ple32(xp->Ze_pk.ze_pk_mtime); - f->f_st.st_uid = ple16(xp->Ze_pk.ze_pk_uid) & - 0177777; - f->f_st.st_gid = ple16(xp->Ze_pk.ze_pk_gid) & - 0177777; - break; - case 0x5455: /* Extended Timestamp Extra Field */ - if (xp->Ze_et.ze_et_flags[0] & 1) - f->f_st.st_atime = - ple32(xp->Ze_et.ze_et_atime); - if (xp->Ze_et.ze_et_flags[0] & 2) - f->f_st.st_mtime = - ple32(xp->Ze_et.ze_et_mtime); - if (xp->Ze_et.ze_et_flags[0] & 3) - f->f_st.st_ctime = - ple32(xp->Ze_et.ze_et_ctime); - break; - case 0x5855: /* Info-ZIP Unix Extra Field #1 */ - if (size != SIZEOF_zextra_i1) - break; - f->f_st.st_atime = ple32(xp->Ze_i1.ze_i1_atime); - f->f_st.st_mtime = ple32(xp->Ze_i1.ze_i1_mtime); - f->f_st.st_uid = ple16(xp->Ze_i1.ze_i1_uid) & - 0177777; - f->f_st.st_gid = ple16(xp->Ze_i1.ze_i1_gid) & - 0177777; - break; - case 0x7855: /* Info-ZIP Unix Extra Field #2 */ - if (size != SIZEOF_zextra_i2) - break; - f->f_st.st_uid = ple16(xp->Ze_i2.ze_i2_uid) & - 0177777; - f->f_st.st_gid = ple16(xp->Ze_i2.ze_i2_gid) & - 0177777; - break; - case 0x756e: /* ASi Unix Extra Field */ - if (size < SIZEOF_zextra_as) - break; - f->f_st.st_mode = ple16(xp->Ze_as.ze_as_mode); - f->f_st.st_uid = ple16(xp->Ze_as.ze_as_uid) & - 0177777; - f->f_st.st_gid = ple16(xp->Ze_as.ze_as_gid) & - 0177777; - if ((f->f_st.st_mode&S_IFMT) == S_IFLNK) { - if (f->f_lsiz < size-14+1) - f->f_lnam = srealloc(f->f_lnam, - f->f_lsiz = - size-18+1); - memcpy(f->f_lnam, &((char *)xp)[18], - size-18); - f->f_lnam[size-18] = '\0'; - f->f_st.st_size = size-18; - } else { - f->f_st.st_rdev = - ple32(xp->Ze_as.ze_as_sizdev); - f->f_rmajor = major(f->f_st.st_rdev); - f->f_rminor = minor(f->f_st.st_rdev); - } - break; - case mag_zipcpio: - if (size != SIZEOF_zextra_cp) - break; - f->f_st.st_dev = ple32(xp->Ze_cp.ze_cp_dev); - f->f_st.st_ino = ple32(xp->Ze_cp.ze_cp_ino); - f->f_st.st_mode = ple32(xp->Ze_cp.ze_cp_mode); - f->f_st.st_uid = ple32(xp->Ze_cp.ze_cp_uid) & - 0xFFFFFFFFUL; - f->f_st.st_gid = ple32(xp->Ze_cp.ze_cp_gid) & - 0xFFFFFFFFUL; - f->f_st.st_nlink = ple32(xp->Ze_cp.ze_cp_nlink)& - 0xFFFFFFFFUL; - f->f_st.st_rdev = ple32(xp->Ze_cp.ze_cp_rdev); - f->f_rmajor = major(f->f_st.st_rdev); - f->f_rminor = minor(f->f_st.st_rdev); - f->f_st.st_mtime = ple32(xp->Ze_cp.ze_cp_mtime); - f->f_st.st_atime = ple32(xp->Ze_cp.ze_cp_atime); - break; - } - xp = (union zextra *)&((char *)xp)[size]; - len -= size; - } - free(x); - } - return len; -} - -/* - * Write the central directory and the end of a zip file. - */ -static void -ziptrailer(void) -{ - struct zipstuff *zs; - struct zipcentral zc; - struct zipend ze; - long long cpstart, cpend, entries = 0; - size_t sz; - - cpstart = nwritten; - for (zs = zipbulk; zs; zs = zs->zs_next) { - entries++; - memset(&zc, 0, SIZEOF_zipcentral); - memcpy(zc.zc_signature, mag_zipctr, 4); - zc.zc_versionmade[0] = 20; - zc.zc_versionextr[0] = zs->zs_cmethod == 8 ? 20 : 10; - mkdostime(zs->zs_mtime, zc.zc_modtime, zc.zc_moddate); - le32p(zs->zs_crc32, zc.zc_crc32); - le16p(zs->zs_cmethod, zc.zc_cmethod); - le16p(zs->zs_gflag, zc.zc_gflag); - /* - * We flag files as created on PC-DOS / FAT filesystem - * and thus set PC-DOS attributes here. - */ - if ((zs->zs_mode&0222) == 0) - zc.zc_external[0] |= 0x01; /* readonly attribute */ - if ((zs->zs_mode&S_IFMT) == S_IFDIR) - zc.zc_external[0] |= 0x10; /* directory attr. */ - sz = strlen(zs->zs_name); - le16p(sz, zc.zc_namelen); - if (zs->zs_size >= 0xffffffff || zs->zs_csize >= 0xffffffff || - zs->zs_relative >= 0xffffffff) { - struct zextra_64 zf; - - memset(&zf, 0, SIZEOF_zextra_64); - le16p(mag_zip64f, zf.ze_64_tag); - le16p(SIZEOF_zextra_64 - 4, zf.ze_64_tsize); - if ((zs->zs_mode&S_IFMT) == S_IFREG || - (zs->zs_mode&S_IFMT) == S_IFLNK) { - le32p(0xffffffff, zc.zc_csize); - le32p(0xffffffff, zc.zc_nsize); - le64p(zs->zs_csize, zf.ze_64_csize); - le64p(zs->zs_size, zf.ze_64_nsize); - } - le64p(zs->zs_relative, zf.ze_64_reloff); - le32p(0xffffffff, zc.zc_relative); - le16p(SIZEOF_zextra_64, zc.zc_extralen); - bwrite((char *)&zc, SIZEOF_zipcentral); - bwrite(zs->zs_name, sz); - bwrite((char *)&zf, SIZEOF_zextra_64); - } else { - if ((zs->zs_mode&S_IFMT) == S_IFREG || - (zs->zs_mode&S_IFMT) == S_IFLNK) { - le32p(zs->zs_csize, zc.zc_csize); - le32p(zs->zs_size, zc.zc_nsize); - } - le32p(zs->zs_relative, zc.zc_relative); - bwrite((char *)&zc, SIZEOF_zipcentral); - bwrite(zs->zs_name, sz); - } - } - cpend = nwritten; - memset(&ze, 0, SIZEOF_zipend); - memcpy(ze.ze_signature, mag_zipend, 4); - if (cpend >= 0xffffffff || entries >= 0xffff) { - struct zip64end z6; - struct zip64loc z4; - - memset(&z6, 0, SIZEOF_zip64end); - memcpy(z6.z6_signature, mag_zip64e, 4); - le64p(SIZEOF_zip64end - 12, z6.z6_recsize); - z6.z6_versionmade[0] = 20; - z6.z6_versionextr[0] = 20; - le64p(entries, z6.z6_thisentries); - le64p(entries, z6.z6_allentries); - le64p(cpend - cpstart, z6.z6_dirsize); - le64p(cpstart, z6.z6_startsize); - bwrite((char *)&z6, SIZEOF_zip64end); - memset(&z4, 0, SIZEOF_zip64loc); - memcpy(z4.z4_signature, mag_zip64l, 4); - le64p(cpend, z4.z4_reloff); - le32p(1, z4.z4_alldiskn); - bwrite((char *)&z4, SIZEOF_zip64loc); - le16p(0xffff, ze.ze_thisentries); - le16p(0xffff, ze.ze_allentries); - le32p(0xffffffff, ze.ze_dirsize); - le32p(0xffffffff, ze.ze_startsize); - } else { - le16p(entries, ze.ze_thisentries); - le16p(entries, ze.ze_allentries); - le32p(cpend - cpstart, ze.ze_dirsize); - le32p(cpstart, ze.ze_startsize); - } - bwrite((char *)&ze, SIZEOF_zipend); -} - -/* - * Store the data later needed for the central directory. - */ -static void -zipdefer(const char *fn, struct stat *st, long long relative, - uint32_t crc, long long csize, const struct zip_header *zh) -{ - struct zipstuff *zp; - - zp = scalloc(1, sizeof *zp); - zp->zs_name = sstrdup(fn); - zp->zs_size = st->st_size; - zp->zs_mtime = st->st_mtime; - zp->zs_mode = st->st_mode; - zp->zs_relative = relative; - zp->zs_cmethod = ple16(zh->z_cmethod); - zp->zs_gflag = ple16(zh->z_gflag); - zp->zs_csize = csize; - zp->zs_crc32 = crc; - zp->zs_next = zipbulk; - zipbulk = zp; -} - -#define ziptrlevel() ( \ - zipclevel == 01 ? 9 : /* maximum */ \ - zipclevel == 02 ? 3 : /* fast */ \ - zipclevel == 03 ? 1 : /* super fast */\ - /*zipclevel==00*/ 6 /* normal */ \ -) - -/* - * Write (and compress) data for a regular file to a zip archive. - */ -static int -zipwrite(int fd, const char *fn, struct stat *st, union bincpio *bp, size_t sz, - uint32_t dev, uint32_t ino, uint32_t *crc, long long *csize) -{ -#if USE_ZLIB - struct z_stream_s z; - int i; - size_t osize = 0; -#endif /* USE_ZLIB */ - char *ibuf, *obuf = 0; - - if (st->st_size > 196608 || (ibuf = malloc(st->st_size)) == 0) { -#if USE_ZLIB - if (zipclevel < 04) - return zipwdesc(fd, fn, st, bp, sz, dev, ino, - crc, csize); -#endif /* USE_ZLIB */ - return zipwtemp(fd, fn, st, bp, sz, dev, ino, crc, csize); - } - *csize = 0; - if (read(fd, ibuf, st->st_size) != st->st_size) { - free(ibuf); - emsg(3, "Cannot read \"%s\"", fn); - close(fd); - return -1; - } - *crc = zipcrc(0, (unsigned char *)ibuf, st->st_size); -#if USE_BZLIB - if (zipclevel == 07) { - unsigned int sb; - if ((obuf = malloc(sb = st->st_size)) == 0) - goto store; - if (BZ2_bzBuffToBuffCompress(obuf, &sb, ibuf, st->st_size, - 9, 0, 0) != BZ_OK) - goto store; - *csize = sb; - bp->Zdr.z_cmethod[0] = C_BZIP2; - bp->Zdr.z_version[0] = 0x2e; - goto out; - } -#endif /* USE_BZLIB */ - if (zipclevel > 03) - goto store; -#if USE_ZLIB - memset(&z, 0, sizeof z); - if (deflateInit2(&z, ziptrlevel(), Z_DEFLATED, -15, - 8, Z_DEFAULT_STRATEGY) < 0) - goto store; - z.next_in = (unsigned char *)ibuf; - z.avail_in = z.total_in = st->st_size; - do { - if (z.avail_out == 0) { - if ((obuf = realloc(obuf, osize += 4096)) == 0) { - deflateEnd(&z); - goto store; - } - z.next_out = (unsigned char *)&obuf[*csize]; - z.avail_out = osize - *csize; - } - if ((i = deflate(&z, z.avail_in ? Z_NO_FLUSH : Z_FINISH)) < 0) { - deflateEnd(&z); - goto store; - } - *csize = osize - z.avail_out; - } while (z.avail_in || i != Z_STREAM_END); - deflateEnd(&z); - if (*csize < st->st_size) { - bp->Zdr.z_cmethod[0] = C_DEFLATED; - bp->Zdr.z_gflag[0] |= zipclevel << 1; - bp->Zdr.z_version[0] = 20; - } else -#endif /* USE_ZLIB */ - store: *csize = st->st_size; -#if USE_BZLIB -out: -#endif /* USE_BZLIB */ - le32p(*crc, bp->Zdr.z_crc32); - le32p(*csize, bp->Zdr.z_csize); - bwrite((char *)bp, SIZEOF_zip_header); - bwrite(fn, sz); - zipwxtra(fn, st, dev, ino); - switch (bp->Zdr.z_cmethod[0]) { - case C_DEFLATED: - case C_BZIP2: - bwrite(obuf, *csize); - break; - default: - bwrite(ibuf, *csize); - } - free(ibuf); - free(obuf); - close(fd); - return 0; -} - -/* - * Write and compress data to a zip archive for a file that is to large - * too be kept in memory. If there is an error with the temporary file - * (e. g. no space left on device), the file is stored in uncompressed - * form. - */ -static int -zipwtemp(int fd, const char *fn, struct stat *st, union bincpio *bp, size_t sz, - uint32_t dev, uint32_t ino, uint32_t *crc, long long *csize) -{ - static int tf = -1; - static char tlate[] = "/var/tmp/cpioXXXXXX"; - char ibuf[32768]; -#if USE_ZLIB || USE_BZLIB - char obuf[32768]; -#endif /* USE_ZLIB || USE_BZLIB */ - struct zextra_64 zf; - struct zextra_64 *zfp = 0; - long long size = st->st_size; - const char *sname; - int cuse, sf; - ssize_t rd; - - *csize = 0; - *crc = 0; -#if USE_ZLIB || USE_BZLIB - if (tf < 0) { - if ((tf = mkstemp(tlate)) >= 0) - unlink(tlate); - } else if (lseek(tf, 0, SEEK_SET) != 0) { - close(tf); - tf = -1; - } -#endif /* USE_ZLIB || USE_BZLIB */ -#if USE_ZLIB - if (zipclevel < 04) { - struct z_stream_s z; - memset(&z, 0, sizeof z); - if ((cuse = deflateInit2(&z, ziptrlevel(), Z_DEFLATED, - -15, 8, Z_DEFAULT_STRATEGY)) < 0) - goto store; - do { - if (z.avail_in == 0 && size > 0) { - if ((rd = read(fd, ibuf, sizeof ibuf)) <= 0) { - emsg(3, "Cannot read \"%s\"", fn); - close(fd); - ftruncate(tf, 0); - return -1; - } - z.next_in = (unsigned char *)ibuf; - z.avail_in = z.total_in = rd; - size -= rd; - *crc = zipcrc(*crc, (unsigned char *)ibuf, rd); - } - if (z.next_out == NULL || (char *)z.next_out > obuf) { - if (z.next_out && tf >= 0) { - if (write(tf, obuf, - (char *)z.next_out-obuf) != - (char *)z.next_out-obuf) { - close(tf); - tf = -1; - } - *csize += (char *)z.next_out - obuf; - } - z.next_out = (unsigned char *)obuf; - z.avail_out = sizeof obuf; - } - if (cuse >= 0 && cuse != Z_STREAM_END) - cuse = deflate(&z, - z.avail_in?Z_NO_FLUSH:Z_FINISH); - else - z.avail_in = 0; - } while (size>0 || (char *)z.next_out>obuf || - cuse>=0 && cuse!=Z_STREAM_END); - deflateEnd(&z); - goto out; - } -#endif /* USE_ZLIB */ -#if USE_BZLIB - if (zipclevel == 07) { - bz_stream bs; - int ok, on; - memset(&bs, sizeof bs, 0); - if ((ok = BZ2_bzCompressInit(&bs, 9, 0, 0)) != BZ_OK) - goto store; - cuse = 1; - do { - if (bs.avail_in == 0 && size > 0) { - if ((rd = read(fd, ibuf, sizeof ibuf)) <= 0) { - emsg(3, "Cannot read \"%s\"", fn); - close(fd); - ftruncate(tf, 0); - return -1; - } - bs.next_in = ibuf; - bs.avail_in = rd; - size -= rd; - *crc = zipcrc(*crc, (unsigned char *)ibuf, rd); - } - if (bs.next_out == NULL || bs.next_out > obuf) { - if (bs.next_out && tf >= 0) { - on = bs.next_out - obuf; - if (write(tf, obuf, on) != on) { - close(tf); - tf = -1; - } - *csize += on; - } - bs.next_out = obuf; - bs.avail_out = sizeof obuf; - } - if (ok != BZ_STREAM_END) { - switch (ok = BZ2_bzCompress(&bs, - bs.avail_in?BZ_RUN:BZ_FINISH)) { - case BZ_RUN_OK: - case BZ_FINISH_OK: - case BZ_STREAM_END: - break; - default: - msg(3, 1, "Compression error %d " - "on \"%s\"\n", ok, fn); - close(fd); - return -1; - } - } - } while (size > 0 || bs.next_out > obuf || ok != BZ_STREAM_END); - BZ2_bzCompressEnd(&bs); - goto out; - } -#endif /* USE_BZLIB */ -store: cuse = -1; - while (size > 0) { - if ((rd = read(fd, ibuf, sizeof ibuf)) <= 0) { - emsg(3, "Cannot read \"%s\"", fn); - close(fd); - return -1; - } - size -= rd; - *crc = zipcrc(*crc, (unsigned char *)ibuf, rd); - } -out: if (tf >= 0 && cuse >= 0 && *csize < st->st_size) { - if (zipclevel == 07) { - bp->Zdr.z_cmethod[0] = C_BZIP2; - bp->Zdr.z_version[0] = 0x2e; - } else { - bp->Zdr.z_cmethod[0] = C_DEFLATED; - bp->Zdr.z_gflag[0] |= zipclevel << 1; - bp->Zdr.z_version[0] = 20; - } - sf = tf; - sname = tlate; - } else { - *csize = st->st_size; - sf = fd; - sname = fn; - } - if ((lseek(sf, 0, SEEK_SET)) != 0) { - emsg(3, "Cannot rewind \"%s\"", sname); - errcnt++; - close(fd); - ftruncate(tf, 0); - return -1; - } - le32p(*crc, bp->Zdr.z_crc32); - if (st->st_size >= 0xffffffff || *csize >= 0xffffffff) { - int n; - zfp = &zf; - memset(&zf, 0, SIZEOF_zextra_64); - le16p(mag_zip64f, zf.ze_64_tag); - le16p(SIZEOF_zextra_64 - 4, zf.ze_64_tsize); - le64p(st->st_size, zf.ze_64_nsize); - le64p(*csize, zf.ze_64_csize); - le32p(0xffffffff, bp->Zdr.z_csize); - le32p(0xffffffff, bp->Zdr.z_nsize); - n = (ple16(bp->Zdr.z_extralen)&0177777) + SIZEOF_zextra_64; - le16p(n, bp->Zdr.z_extralen); - } else - le32p(*csize, bp->Zdr.z_csize); - bwrite((char *)bp, SIZEOF_zip_header); - bwrite(fn, sz); - if (zfp) - bwrite((char *)zfp, SIZEOF_zextra_64); - zipwxtra(fn, st, dev, ino); - size = *csize; - while (size) { - if ((rd=read(sf, ibuf, size>sizeof ibuf?sizeof ibuf:size)) <= 0) - msg(3, 1, "Cannot read \"%s\"\n", sname); - bwrite(ibuf, rd); - size -= rd; - } - ftruncate(tf, 0); - close(fd); - return 0; -} - -#if USE_ZLIB -/* - * Write a zip archive entry using the data descriptor structure. - */ -static int -zipwdesc(int fd, const char *fn, struct stat *st, union bincpio *bp, size_t sz, - uint32_t dev, uint32_t ino, uint32_t *crc, long long *csize) -{ - struct zextra_64 zf; - struct zextra_64 *zfp = 0; - char ibuf[32768], obuf[32768]; - long long size = st->st_size; - ssize_t rd; - struct z_stream_s z; - int cuse; - - *csize = 0; - *crc = 0; - memset(&z, 0, sizeof z); - if ((cuse = deflateInit2(&z, ziptrlevel(), Z_DEFLATED, - -15, 8, Z_DEFAULT_STRATEGY)) < 0) - return zipwtemp(fd, fn, st, bp, sz, dev, ino, crc, csize); - bp->Zdr.z_cmethod[0] = C_DEFLATED; - bp->Zdr.z_gflag[0] |= zipclevel << 1 | FG_DESC; - bp->Zdr.z_version[0] = 20; - /* - * RFC 1951 states that deflate compression needs 5 bytes additional - * space per 32k block in the worst case. Thus a compressed size - * greater than 4G-1 can be reached if at least 131052 blocks are - * used. - */ - if (st->st_size >= 131052LL*32768) { - int n; - zfp = &zf; - memset(&zf, 0, SIZEOF_zextra_64); - le16p(mag_zip64f, zf.ze_64_tag); - le16p(SIZEOF_zextra_64 - 4, zf.ze_64_tsize); - le32p(0xffffffff, bp->Zdr.z_csize); - le32p(0xffffffff, bp->Zdr.z_nsize); - n = (ple16(bp->Zdr.z_extralen)&0177777) + SIZEOF_zextra_64; - le16p(n, bp->Zdr.z_extralen); - } - bwrite((char *)bp, SIZEOF_zip_header); - bwrite(fn, sz); - if (zfp) - bwrite((char *)zfp, SIZEOF_zextra_64); - zipwxtra(fn, st, dev, ino); - do { - if (z.avail_in == 0 && size > 0) { - if ((rd = read(fd, ibuf, sizeof ibuf)) <= 0) { - emsg(3, "Cannot read \"%s\"", fn); - st->st_size -= size; - size = 0; /* can't simply stop here */ - rd = 0; /* no data */ - } - z.next_in = (unsigned char *)ibuf; - z.avail_in = z.total_in = rd; - size -= rd; - *crc = zipcrc(*crc, (unsigned char *)ibuf, rd); - } - if (z.next_out == NULL || (char *)z.next_out > obuf) { - if (z.next_out) { - bwrite(obuf, (char *)z.next_out - obuf); - *csize += (char *)z.next_out - obuf; - } - z.next_out = (unsigned char *)obuf; - z.avail_out = sizeof obuf; - } - if (cuse >= 0 && cuse != Z_STREAM_END) - cuse = deflate(&z, z.avail_in?Z_NO_FLUSH:Z_FINISH); - else - z.avail_in = 0; - } while (size > 0 || (char *)z.next_out > obuf || - cuse >= 0 && cuse != Z_STREAM_END); - deflateEnd(&z); - if (zfp) { - struct zipddesc64 zd64; - memcpy(zd64.zd_signature, mag_zipdds, sizeof mag_zipdds); - le32p(*crc, zd64.zd_crc32); - le64p(st->st_size, zd64.zd_nsize); - le64p(*csize, zd64.zd_csize); - bwrite((char *)&zd64, SIZEOF_zipddesc64); - } else { - struct zipddesc zd; - memcpy(zd.zd_signature, mag_zipdds, sizeof mag_zipdds); - le32p(*crc, zd.zd_crc32); - le32p(st->st_size, zd.zd_nsize); - le32p(*csize, zd.zd_csize); - bwrite((char *)&zd, SIZEOF_zipddesc); - } - close(fd); - return 0; -} -#endif /* USE_ZLIB */ - -/* - * Write the extra fields for a file to a zip archive (currently - * our own field type). Note that the z_extralen field in the file - * header must correspond to the size of the data written here. - */ -static int -zipwxtra(const char *fn, struct stat *st, uint32_t dev, uint32_t ino) -{ - struct zextra_cp z; - - memset(&z, 0, SIZEOF_zextra_cp); - le16p(mag_zipcpio, z.ze_cp_tag); - le16p(SIZEOF_zextra_cp - 4, z.ze_cp_tsize); - le32p(dev, z.ze_cp_mode); - le32p(ino, z.ze_cp_ino); - le32p(st->st_mode&(S_IFMT|07777), z.ze_cp_mode); - le32p(st->st_uid, z.ze_cp_uid); - le32p(st->st_gid, z.ze_cp_gid); - le32p(st->st_nlink, z.ze_cp_nlink); - le32p(st->st_rdev, z.ze_cp_rdev); - le32p(st->st_mtime, z.ze_cp_mtime); - le32p(st->st_atime, z.ze_cp_atime); - bwrite((char *)&z, SIZEOF_zextra_cp); - return SIZEOF_zextra_cp; -} - -static void -zipinfo(struct file *f) -{ - const char *cp; - char b[5]; - int i; - - printf(" %7llu", f->f_csize); - if (f->f_dsize) { - i = f->f_csize*100 / f->f_dsize; - i += f->f_csize*200 / f->f_dsize & 1; - i = 100 - i; - } else - i = 0; - printf(" %3d%%", i); - switch (f->f_cmethod) { - case C_STORED: - cp = "stor"; - break; - case C_SHRUNK: - cp = "shrk"; - break; - case C_REDUCED1: - cp = "re:1"; - break; - case C_REDUCED2: - cp = "re:2"; - break; - case C_REDUCED3: - cp = "re:3"; - break; - case C_REDUCED4: - cp = "re:4"; - break; - case C_IMPLODED: - b[0] = 'i'; - b[1] = f->f_gflag & FG_BIT1 ? '8' : '4'; - b[2] = ':'; - b[3] = f->f_gflag & FG_BIT2 ? '3' : '2'; - b[4] = '\0'; - cp = b; - break; - case C_TOKENIZED: - cp = "tokn"; - break; - case C_DEFLATED: - b[0] = 'd', b[1] = 'e', b[2] = 'f', b[4] = '\0'; - if (f->f_gflag & FG_BIT2) - b[3] = f->f_gflag & FG_BIT1 ? 'S' : 'F'; - else - b[3] = f->f_gflag & FG_BIT1 ? 'X' : 'N'; - cp = b; - break; - case C_ENHDEFLD: - cp = "edef"; - break; - case C_DCLIMPLODED: - cp = "dcli"; - break; - case C_BZIP2: - cp = "bz2 "; - break; - default: - snprintf(b, sizeof b, "%4.4X", f->f_cmethod); - cp = b; - } - printf(" %s", cp); -} - -#if USE_BZLIB -int -zipunbz2(struct file *f, const char *tgt, int tfd, int doswap, uint32_t *crc) -{ - bz_stream bs; - long long isize = f->f_csize; - char ibuf[4096], obuf[8192]; - int in, on, val = 0, ok; - - memset(&bs, 0, sizeof bs); - - if ((ok = BZ2_bzDecompressInit(&bs, 0, 0)) != BZ_OK) { - msg(3, 0, "bzip2 initialization error %d on \"%s\"\n", - ok, f->f_name); - errcnt++; - return skipfile(f); - } - while (isize > 0 || ok == BZ_OK) { - if (bs.avail_in == 0 && isize > 0) { - in = sizeof ibuf < isize ? sizeof ibuf : isize; - isize -= in; - if (bread(ibuf, in) != in) - unexeoa(); - if (doswap) - swap(ibuf, in, bflag || sflag, bflag || Sflag); - bs.next_in = ibuf; - bs.avail_in = in; - } - if (ok == BZ_OK) { - bs.next_out = obuf; - bs.avail_out = sizeof obuf; - switch (ok = BZ2_bzDecompress(&bs)) { - case BZ_OK: - case BZ_STREAM_END: - on = sizeof obuf - bs.avail_out; - if (tfd >= 0 && write(tfd, obuf, on) != on) { - emsg(3, "Cannot write \"%s\"", tgt); - tfd = -1; - val = 1; - } - *crc = zipcrc(*crc, (unsigned char *)obuf, on); - break; - default: - msg(3, 0, "compression error %d on \"%s\"\n", - ok, f->f_name); - errcnt++; - val = 1; - } - } - } - BZ2_bzDecompressEnd(&bs); - return val; -} -#endif /* USE_BZLIB */ - -struct blasthow { - struct file *bh_f; - const char *bh_tgt; - long long bh_isize; - uint32_t *bh_crc; - int bh_tfd; - int bh_doswap; - int bh_val; -}; - -static unsigned -blastin(void *how, unsigned char **buf) -{ - const int chunk = 16384; - static unsigned char *hold; - struct blasthow *bp = how; - unsigned sz; - - if (bp->bh_isize <= 0) - return 0; - if (hold == NULL) - hold = smalloc(chunk); - sz = bp->bh_isize > chunk ? chunk : bp->bh_isize; - bp->bh_isize -= sz; - if (bread((char *)hold, sz) != sz) - unexeoa(); - if (bp->bh_doswap) - swap((char *)hold, sz, bflag || sflag, bflag || Sflag); - *buf = hold; - return sz; -} - -static int -blastout(void *how, unsigned char *buf, unsigned len) -{ - struct blasthow *bp = how; - - if (bp->bh_tfd >= 0 && write(bp->bh_tfd, buf, len) != len) { - emsg(3, "Cannot write \"%s\"", bp->bh_tgt); - bp->bh_tfd = -1; - bp->bh_val = 1; - } - *bp->bh_crc = zipcrc(*bp->bh_crc, buf, len); - return 0; -} - -int -zipblast(struct file *f, const char *tgt, int tfd, int doswap, uint32_t *crc) -{ - struct blasthow bh; - int n; - - bh.bh_f = f; - bh.bh_tgt = tgt; - bh.bh_isize = f->f_csize; - bh.bh_crc = crc; - bh.bh_tfd = tfd; - bh.bh_doswap = doswap; - bh.bh_val = 0; - switch (n = blast(blastin, &bh, blastout, &bh)) { - case 0: - break; - default: - msg(3, 0, "compression error %d on \"%s\"\n", n, f->f_name); - errcnt++; - bh.bh_val = 1; - } - while (bh.bh_isize) { - char buf[4096]; - unsigned n; - n = bh.bh_isize > sizeof buf ? sizeof buf : bh.bh_isize; - if (bread(buf, n) != n) - unexeoa(); - bh.bh_isize -= n; - } - return bh.bh_val; -} - -/* - * The SGI -K format was introduced with SGI's IRIX 5.X. It is essentially - * a slightly extended binary format. The known additions are: - * - * - If the major or minor st_rdev device number exceeds the limit of - * 255 imposed by the 16-bit c_rdev field, this field is set to 0xFFFF - * and st_rdev is stored in the c_filesize 32-bit field. The first 14 - * bits of this field compose the major device number, the minor is - * stored in the remaining 18 bits. This enables implementations to - * read the modified format without special support if they ignore - * the size of device files; otherwise they will try to read a lot - * of archive data and fail. - * - * - If the file is larger than 2 GB - 1 byte, two nearly identical - * archive headers are stored for it. The only difference is in - * the c_filesize field: - * - * [first header: file size X times 2 GB] - * [first data part: X times 2 GB] - * [second header: file size modulo 2 GB] - * [second data part: rest of data] - * - * The first header can be recognized by a negative c_filesize. A - * value of 0xFFFFFFFF means that 2 GB follow, 0xFFFFFFFE -> 4 GB - * 0xFFFFFFFD -> 6 GB, 0xFFFFFFFC -> 8 GB, and so forth. The second - * is a standard binary cpio header, although the following data is - * meant to be appended to the preceding file. - * - * It is important to note that padding follows the number in - * c_filesize, not the amount of data written; thus all data parts - * with odd c_filesize fields (0xFFFFFFFF = 2+ GB, 0xFFFFFFFD = 6+ GB - * etc.) cause the following archive entries to be aligned on an odd - * offset. This seems to be an implementation artifact but has to be - * followed for compatibility. - * - * This extension seems a bit weird since no known cpio implementation - * is able to read these archive entries without special support. Thus - * a more straightforward extension (such as storing the size just past - * the file name) would well have had the same effect. Nevertheless, - * the cpio -K format is useful, so it is implemented here. - * - * --Note that IRIX 6.X tar also has a -K option. This option extends - * the tar format in essentially the same way as the second extension - * to cpio described above. Unfortunately, the result is definitively - * broken. Contrasting to the binary cpio format, the standard POSIX - * tar format is well able to hold files of size 0xFFFFFFFF and below - * in a regular manner. Thus, a tar -K archive entry is _exactly_ the - * same as two regular POSIX tar entries for the same file. And this - * situation even occurs on a regular basis with tar -r! For this - * reason, we do not implement the IRIX tar -K format and will probably - * never do so unless it is changed (the tar format really has a lot - * of options to indicate extensions that might be used for this). - * - * Many thanks to Sven Mascheck who made archiving tests on the IRIX - * machine. - */ -/* - * This function reads the second header of a SGI -K format archive. - */ -static void -readK2hdr(struct file *f) -{ - struct file n; - union bincpio bc; - - n.f_name = n.f_lnam = NULL; - n.f_nsiz = n.f_lsiz = 0; - readhdr(&n, &bc); - f->f_Krest = n.f_st.st_size; - f->f_dsize = f->f_st.st_size = n.f_st.st_size + f->f_Kbase; - f->f_Kbase = 0; - free(n.f_name); - free(n.f_lnam); -} - -/* - * Read the data of a GNU filename extra header. - */ -static int -readgnuname(char **np, size_t *sp, long length) -{ - if (length > SANELIMIT) - return -1; - if (*sp == 0 || *sp <= length) - *np = srealloc(*np, *sp = length+1); - bread(*np, length); - (*np)[length] = '\0'; - skippad(length, 512); - return 0; -} - -/* - * Write a GNU filename extra header and its data. - */ -static void -writegnuname(const char *fn, long length, int flag) -{ - union bincpio bc; - - memset(bc.data, 0, 512); - strcpy(bc.Tdr.t_name, "././@LongLink"); - sprintf(bc.Tdr.t_mode, "%7.7o", 0); - sprintf(bc.Tdr.t_uid, "%7.7o", 0); - sprintf(bc.Tdr.t_gid, "%7.7o", 0); - sprintf(bc.Tdr.t_size, "%11.11lo", length); - sprintf(bc.Tdr.t_mtime, "%11.11lo", 0L); - bc.Tdr.t_linkflag = flag; - memcpy(bc.Tdr.t_magic, mag_gnutar, 8); - strcpy(bc.Tdr.t_uname, "root"); - strcpy(bc.Tdr.t_gname, "root"); - tchksum(&bc); - bwrite(bc.data, 512); - bwrite(fn, length); - length %= 512; - memset(bc.data, 0, 512 - length); - bwrite(bc.data, 512 - length); -} - -/* - * POSIX.1-2001 pax format support. - */ -static void -tgetpax(struct tar_header *tp, struct file *f) -{ - char *keyword, *value; - char *block, *bp; - long long n; - enum paxrec pr; - - n = rdoct(tp->t_size, 12); - bp = block = smalloc(n+1); - bread(block, n); - skippad(n, 512); - block[n] = '\0'; - while (bp < &block[n]) { - int c; - pr = tgetrec(&bp, &keyword, &value); - switch (pr) { - case PR_ATIME: - f->f_st.st_atime = strtoll(value, NULL, 10); - break; - case PR_GID: - f->f_st.st_gid = strtoll(value, NULL, 10); - break; - case PR_LINKPATH: - c = strlen(value); - if (f->f_lnam == NULL || f->f_lsiz < c+1) { - f->f_lsiz = c+1; - f->f_lnam = srealloc(f->f_lnam, c+1); - } - strcpy(f->f_lnam, value); - break; - case PR_MTIME: - f->f_st.st_mtime = strtoll(value, NULL, 10); - break; - case PR_PATH: - c = strlen(value); - if (f->f_name == NULL || f->f_nsiz < c+1) { - f->f_nsiz = c+1; - f->f_name = srealloc(f->f_name, c+1); - } - strcpy(f->f_name, value); - break; - case PR_SIZE: - f->f_st.st_size = strtoll(value, NULL, 10); - break; - case PR_UID: - f->f_st.st_uid = strtoll(value, NULL, 10); - break; - case PR_SUN_DEVMAJOR: - f->f_rmajor = strtoll(value, NULL, 10); - break; - case PR_SUN_DEVMINOR: - f->f_rminor = strtoll(value, NULL, 10); - break; - } - paxrec |= pr; - } - if (tp->t_linkflag == 'g') { - globrec = paxrec & ~(PR_LINKPATH|PR_PATH|PR_SIZE); - globst = f->f_st; - } - free(block); -} - -static enum paxrec -tgetrec(char **bp, char **keyword, char **value) -{ - char *x; - long n = 0; - enum paxrec pr; - - *keyword = ""; - *value = ""; - while (**bp && (n = strtol(*bp, &x, 10)) <= 0 && (*x!=' ' || *x!='\t')) - do - (*bp)++; - while (**bp && **bp != '\n'); - if (*x == '\0' || **bp == '\0') { - (*bp)++; - return PR_NONE; - } - while (x < &(*bp)[n] && (*x == ' ' || *x == '\t')) - x++; - if (x == &(*bp)[n] || *x == '=') - goto out; - *keyword = x; - while (x < &(*bp)[n] && *x != '=') - x++; - if (x == &(*bp)[n]) - goto out; - *x = '\0'; - if (&x[1] < &(*bp)[n]) - *value = &x[1]; - (*bp)[n-1] = '\0'; -out: *bp = &(*bp)[n]; - if (strcmp(*keyword, "atime") == 0) - pr = PR_ATIME; - else if (strcmp(*keyword, "gid") == 0) - pr = PR_GID; - else if (strcmp(*keyword, "linkpath") == 0) - pr = PR_LINKPATH; - else if (strcmp(*keyword, "mtime") == 0) - pr = PR_MTIME; - else if (strcmp(*keyword, "path") == 0) - pr = PR_PATH; - else if (strcmp(*keyword, "size") == 0) - pr = PR_SIZE; - else if (strcmp(*keyword, "uid") == 0) - pr = PR_UID; - else if (strcmp(*keyword, "SUN.devmajor") == 0) - pr = PR_SUN_DEVMAJOR; - else if (strcmp(*keyword, "SUN.devminor") == 0) - pr = PR_SUN_DEVMINOR; - else - pr = PR_NONE; - return pr; -} - -static void -wrpax(const char *longname, const char *linkname, struct stat *sp) -{ - union bincpio bc; - char *pdata = NULL; - long psize = 0, pcur = 0; - long long blocks; - - memset(bc.data, 0, 512); - if (paxrec & PR_ATIME) - addrec(&pdata, &psize, &pcur, "atime", NULL, sp->st_atime); - if (paxrec & PR_GID) - addrec(&pdata, &psize, &pcur, "gid", NULL, sp->st_gid); - if (paxrec & PR_LINKPATH) - addrec(&pdata, &psize, &pcur, "linkpath", linkname, 0); - if (paxrec & PR_MTIME) - addrec(&pdata, &psize, &pcur, "mtime", NULL, sp->st_mtime); - if (paxrec & PR_PATH) - addrec(&pdata, &psize, &pcur, "path", longname, 0); - if (paxrec & PR_SIZE) - addrec(&pdata, &psize, &pcur, "size", NULL, sp->st_size); - if (paxrec & PR_UID) - addrec(&pdata, &psize, &pcur, "uid", NULL, sp->st_uid); - if (paxrec & PR_SUN_DEVMAJOR) - addrec(&pdata, &psize, &pcur, "SUN.devmajor", NULL, - major(sp->st_rdev)); - if (paxrec & PR_SUN_DEVMINOR) - addrec(&pdata, &psize, &pcur, "SUN.devminor", NULL, - minor(sp->st_rdev)); - paxnam(&bc.Tdr, longname); - sprintf(bc.Tdr.t_mode, "%7.7o", fmttype==FMT_SUN ? 0444|S_IFREG : 0444); - sprintf(bc.Tdr.t_uid, "%7.7o", 0); - sprintf(bc.Tdr.t_gid, "%7.7o", 0); - sprintf(bc.Tdr.t_size, "%11.11lo", pcur); - sprintf(bc.Tdr.t_mtime, "%11.11o", 0); - strcpy(bc.Tdr.t_magic, "ustar"); - bc.Tdr.t_version[0] = bc.Tdr.t_version[1] = '0'; - strcpy(bc.Tdr.t_uname, "root"); - strcpy(bc.Tdr.t_gname, "root"); - bc.Tdr.t_linkflag = fmttype==FMT_SUN ? 'X' : 'x'; - tchksum(&bc); - bwrite(bc.data, 512); - memset(&pdata[pcur], 0, psize - pcur); - blocks = (pcur + (512-1)) / 512; - bwrite(pdata, blocks * 512); - free(pdata); -} - -static void -addrec(char **pdata, long *psize, long *pcur, - const char *keyword, const char *sval, long long lval) -{ - char dval[25], xval[25]; - long od, d, r; - - if (sval == 0) { - sprintf(xval, "%lld", lval); - sval = xval; - } - r = strlen(keyword) + strlen(sval) + 3; - d = 0; - do { - od = d; - d = sprintf(dval, "%ld", od + r); - } while (d != od); - *psize += d + r + 1 + 512; - *pdata = srealloc(*pdata, *psize); - sprintf(&(*pdata)[*pcur], "%s %s=%s\n", dval, keyword, sval); - *pcur += d + r; -} - -static void -paxnam(struct tar_header *hp, const char *name) -{ - char buf[257], *bp; - const char *cp, *np; - int bl = 0; - static int pid; - - if (pid == 0) - pid = getpid(); - for (np = name; *np; np++); - while (np > name && *np != '/') { - np--; - bl++; - } - if ((np > name || *name == '/') && np-name <= 120) - for (bp = buf, cp = name; cp < np; bp++, cp++) - *bp = *cp; - else { - *buf = '.'; - bp = &buf[1]; - } - snprintf(bp, sizeof buf - (bp - buf), "/PaxHeaders.%d/%s", - pid, bl < 100 ? np>name?&np[1]:name : sequence()); - tmkname(hp, buf); -} - -static char * -sequence(void) -{ - static char buf[25]; - static long long d; - - sprintf(buf, "%10.10lld", ++d); - return buf; -} - -static int -pax_oneopt(const char *s, int warn) -{ - if (strcmp(s, "linkdata") == 0) - pax_oflag |= PO_LINKDATA; - else if (strcmp(s, "times") == 0) - pax_oflag |= PO_TIMES; - else { - if (warn) - msg(2, 0, "Unknown flag \"-o %s\"\n", s); - return -1; - } - return 0; -} - -int -pax_options(char *s, int warn) -{ - char *o = s, c; - int val = 0, word = 0; - - do { - if (word == 0) { - if (isspace(*s&0377)) - o = &s[1]; - else - word = 1; - } - if (*s == ',' || *s == '\0') { - c = *s; - *s = '\0'; - val |= pax_oneopt(o, warn); - *s = c; - o = &s[1]; - word = 0; - } - } while (*s++); - return val; -} - -/* - * Given a symbolic link "base" and the result of readlink "name", form - * a valid path name for the link target. - */ -static char * -joinpath(const char *base, char *name) -{ - const char *bp = NULL, *cp; - char *new, *np; - - if (*name == '/') - return name; - for (cp = base; *cp; cp++) - if (*cp == '/') - bp = cp; - if (bp == NULL) - return name; - np = new = smalloc(bp - base + strlen(name) + 2); - for (cp = base; cp < bp; cp++) - *np++ = *cp; - *np++ = '/'; - for (cp = name; *cp; cp++) - *np++ = *cp; - *np = '\0'; - free(name); - return new; -} - -static int -utf8(const char *cp) -{ - int c, n; - - while (*cp) if ((c = *cp++ & 0377) & 0200) { - if (c == (c & 037 | 0300)) - n = 1; - else if (c == (c & 017 | 0340)) - n = 2; - else if (c == (c & 07 | 0360)) - n = 3; - else if (c == (c & 03 | 0370)) - n = 4; - else if (c == (c & 01 | 0374)) - n = 5; - else - return 0; - while (n--) { - c = *cp++ & 0377; - if (c != (c & 077 | 0200)) - return 0; - } - } - return 1; -} - -static time_t -fetchtime(const char *cp) -{ - struct tm tm; - time_t t; - char *xp; - int n; - - t = strtoll(cp, &xp, 10); - if (*xp == '\0') - return t; - memset(&tm, 0, sizeof tm); - n = sscanf(cp, "%4d%2d%2dT%2d%2d%2d", - &tm.tm_year, &tm.tm_mon, &tm.tm_mday, - &tm.tm_hour, &tm.tm_min, &tm.tm_sec); - tm.tm_year -= 1900; - tm.tm_mon--; - tm.tm_isdst = -1; - t = mktime(&tm); - if (n < 3 || t == (time_t)-1) - msg(4, 1, "line %lld: illegal time \"%s\"\n", - lineno, cp); - return t; -} - -static char * -nextfield(char *cp, const char *fieldname) -{ - while (*cp && *cp != ':') - cp++; - if (*cp == 0) - msg(4, 1, "line %lld: unterminated \"%s\" field\n", - lineno, fieldname); - *cp++ = 0; - return cp; -} - -static char * -getproto(char *np, struct prototype *pp) -{ - char *tp, *xp; - long long t, u; - - memset(pp, 0, sizeof *pp); - if (*np == ':') - np++; - else { - tp = nextfield(np, "type"); - if (np[1]) - goto notype; - switch (np[0]) { - case 'b': - pp->pt_mode |= S_IFBLK; - break; - case 'c': - pp->pt_mode |= S_IFCHR; - break; - case 'd': - pp->pt_mode |= S_IFDIR; - break; - case 'f': - pp->pt_mode |= S_IFREG; - break; - case 'p': - pp->pt_mode |= S_IFIFO; - break; - case 's': - pp->pt_mode |= S_IFLNK; - break; - default: - notype: - msg(4, 1, "line %lld: unknown type \"%s\"\n", - lineno, np); - } - pp->pt_spec |= PT_TYPE; - np = tp; - } - if (*np == ':') - np++; - else { - struct passwd *pwd; - tp = nextfield(np, "owner"); - t = strtoll(np, &xp, 10); - if (*xp == '\0') - pp->pt_uid = t; - else { - if ((pwd = getpwnam(np)) == NULL) - msg(4, 1, "line %lld: unknown user \"%s\"\n", - lineno, np); - pp->pt_uid = pwd->pw_uid; - } - pp->pt_spec |= PT_OWNER; - np = tp; - } - if (*np == ':') - np++; - else { - struct group *grp; - tp = nextfield(np, "group"); - t = strtoll(np, &xp, 10); - if (*xp == '\0') - pp->pt_gid = t; - else { - if ((grp = getgrnam(np)) == NULL) - msg(4, 1, "line %lld: unknown group \"%s\"\n", - lineno, np); - pp->pt_gid = grp->gr_gid; - } - pp->pt_spec |= PT_GROUP; - np = tp; - } - if (*np == ':') - np++; - else { - tp = nextfield(np, "mode"); - t = strtol(np, &xp, 8); - if (t & ~07777 || *xp) - msg(4, 1, "line %lld: illegal mode \"%s\"\n", - lineno, np); - pp->pt_mode |= t; - pp->pt_spec |= PT_MODE; - np = tp; - } - if (*np == ':') - np++; - else { - tp = nextfield(np, "access time"); - pp->pt_atime = fetchtime(np); - pp->pt_spec |= PT_ATIME; - np = tp; - } - if (*np == ':') - np++; - else { - tp = nextfield(np, "modification time"); - pp->pt_mtime = fetchtime(np); - pp->pt_spec |= PT_MTIME; - np = tp; - } - if (*np == ':') { - np++; - if (*np++ != ':') - majmin: msg(4, 1, "line %lld: need either both major and " - "minor or none\n", - lineno); - } else { - tp = nextfield(np, "major"); - t = strtoll(np, &xp, 10); - if (*xp) - msg(4, 1, "line %lld: illegal major \"%s\"\n", - lineno, np); - np = tp; - if (*np == ':') - goto majmin; - tp = nextfield(np, "minor"); - u = strtoll(np, &xp, 10); - if (*xp) - msg(4, 1, "line %lld: illegal minor \"%s\"\n", - lineno, np); - np = tp; - pp->pt_rdev = makedev(t, u); - pp->pt_spec |= PT_RDEV; - } - return np; -} diff --git a/tools/cpio/src/cpio.h b/tools/cpio/src/cpio.h deleted file mode 100644 index 131a3d388..000000000 --- a/tools/cpio/src/cpio.h +++ /dev/null @@ -1,232 +0,0 @@ -/* - * cpio - copy file archives in and out - * - * Gunnar Ritter, Freiburg i. Br., Germany, April 2003. - */ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ - -/* Sccsid @(#)cpio.h 1.29 (gritter) 3/26/07 */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <inttypes.h> - -enum { - FMT_NONE = 00000000, /* no format chosen yet */ - - TYP_PAX = 00000010, /* uses pax-like extended headers */ - TYP_BE = 00000100, /* this binary archive is big-endian */ - TYP_SGI = 00000200, /* SGI cpio -K flag binary archive */ - TYP_SCO = 00000200, /* SCO UnixWare 7.1 extended archive */ - TYP_CRC = 00000400, /* this has a SVR4 'crc' checksum */ - TYP_BINARY = 00001000, /* this is a binary cpio type */ - TYP_OCPIO = 00002000, /* this is an old cpio type */ - TYP_NCPIO = 00004000, /* this is a SVR4 cpio type */ - TYP_CRAY = 00010000, /* this is a Cray cpio archive */ - TYP_CPIO = 00077000, /* this is a cpio type */ - TYP_OTAR = 00100000, /* this is an old tar type */ - TYP_USTAR = 00200000, /* this is a ustar type */ - TYP_BAR = 00400000, /* this is a bar type */ - TYP_TAR = 00700000, /* this is a tar type */ - - FMT_ODC = 00002001, /* POSIX ASCII cpio format */ - FMT_DEC = 00002002, /* DEC extended cpio format */ - FMT_BINLE = 00003001, /* binary (default) cpio format LE */ - FMT_BINBE = 00003101, /* binary (default) cpio format BE */ - FMT_SGILE = 00003201, /* IRIX-style -K binary format LE */ - FMT_SGIBE = 00003301, /* IRIX-style -K binary format BE */ - FMT_ASC = 00004001, /* SVR4 ASCII cpio format */ - FMT_SCOASC = 00004201, /* UnixWare 7.1 ASCII cpio format */ - FMT_CRC = 00004401, /* SVR4 ASCII cpio format w/checksum */ - FMT_SCOCRC = 00004601, /* UnixWare 7.1 ASCII cpio w/checksum */ - FMT_CRAY = 00010001, /* Cray cpio, UNICOS 6 and later */ - FMT_CRAY5 = 00010002, /* Cray cpio, UNICOS 5 and earlier */ - FMT_OTAR = 00100001, /* obsolete tar format */ - FMT_TAR = 00200001, /* our tar format type */ - FMT_USTAR = 00200002, /* ustar format */ - FMT_GNUTAR = 00200003, /* GNU tar format type */ - FMT_PAX = 00200011, /* POSIX.1-2001 pax format type */ - FMT_SUN = 00200012, /* Sun extended tar format type */ - FMT_BAR = 00400001, /* bar format type */ - - FMT_ZIP = 01000000 /* zip format */ -} fmttype; - -/* - * Zip compression method. - */ -enum cmethod { - C_STORED = 0, /* no compression */ - C_SHRUNK = 1, - C_REDUCED1 = 2, - C_REDUCED2 = 3, - C_REDUCED3 = 4, - C_REDUCED4 = 5, - C_IMPLODED = 6, - C_TOKENIZED = 7, - C_DEFLATED = 8, - C_ENHDEFLD = 9, - C_DCLIMPLODED = 10, - C_PKRESERVED = 11, - C_BZIP2 = 12, -}; - -/* - * A collection of the interesting facts about a file in copy-in mode. - */ -struct file { - struct stat f_st; /* file stat */ - long long f_rmajor; /* st_rdev major */ - long long f_rminor; /* st_rdev minor */ - long long f_dsize; /* display size */ - long long f_csize; /* compressed size */ - long long f_Kbase; /* base size for -K */ - long long f_Krest; /* rest size for -K */ - long long f_Ksize; /* faked -K size field */ - char *f_name; /* file name */ - size_t f_nsiz; /* file name size */ - char *f_lnam; /* link name */ - size_t f_lsiz; /* link name size */ - uint32_t f_chksum; /* checksum */ - int f_pad; /* padding size */ - int f_fd; /* file descriptor (for pass mode) */ - enum cmethod f_cmethod; /* zip compression method */ - enum { - FG_CRYPT = 0001, /* encrypted zip file */ - FG_BIT1 = 0002, - FG_BIT2 = 0004, - FG_DESC = 0010 /* zip file with data descriptor */ - } f_gflag; /* zip general flag */ - enum { - OF_ZIP64 = 0001 /* is a zip64 archive entry */ - } f_oflag; /* other flags */ -}; - -/* - * Patterns for gmatch(). - */ -struct glist { - struct glist *g_nxt; - const char *g_pat; - unsigned g_gotcha : 1; - unsigned g_not : 1; - unsigned g_art : 1; -}; - -extern int aflag; -extern int Aflag; -extern int bflag; -extern int Bflag; -extern int cflag; -extern int Cflag; -extern int dflag; -extern int Dflag; -extern int eflag; -extern int cray_eflag; -extern const char *Eflag; -extern int fflag; -extern int Hflag; -extern const char *Iflag; -extern int kflag; -extern int Kflag; -extern int lflag; -extern int Lflag; -extern int mflag; -extern const char *Mflag; -extern const char *Oflag; -extern int Pflag; -extern int rflag; -extern const char *Rflag; -extern int sflag; -extern int Sflag; -extern int tflag; -extern int uflag; -extern int hp_Uflag; -extern int vflag; -extern int Vflag; -extern int sixflag; -extern int action; -extern long long errcnt; -extern int blksiz; -extern int sysv3; -extern int printsev; -extern char *progname; -extern struct glist *patterns; - -enum { /* type of pax command this is */ - PAX_TYPE_CPIO = 0, /* not a pax command */ - PAX_TYPE_PAX1992 = 1, /* POSIX.2 pax command */ - PAX_TYPE_PAX2001 = 2 /* POSIX.1-2001 pax command */ -} pax; -extern int pax_dflag; -extern int pax_kflag; -extern int pax_nflag; -extern int pax_sflag; -extern int pax_uflag; -extern int pax_Xflag; - -enum { - PAX_P_NONE = 0000, - PAX_P_ATIME = 0001, - PAX_P_MTIME = 0004, - PAX_P_OWNER = 0010, - PAX_P_MODE = 0020, - PAX_P_EVERY = 0400 -} pax_preserve; - -extern size_t (*ofiles)(char **, size_t *); -extern void (*prtime)(time_t); - -extern ssize_t bread(char *, size_t); -extern void bunread(const char *, size_t); -extern void swap(char *, size_t, int, int); -extern void msg(int, int, const char *, ...); -extern void emsg(int, const char *, ...); -extern void unexeoa(void); -extern int setfmt(char *); -extern char *oneintfmt(const char *); -extern int setreassign(const char *); -extern void addg(const char *, int); -extern void *srealloc(void *, size_t); -extern void *smalloc(size_t); -extern void *scalloc(size_t, size_t); -extern void *svalloc(size_t, int); -extern char *sstrdup(const char *); -extern int pax_options(char *, int); - -extern int zipunshrink(struct file *, const char *, int, int, uint32_t *); -extern int zipexplode(struct file *, const char *, int, int, uint32_t *); -extern int zipexpand(struct file *, const char *, int, int, uint32_t *); -extern int zipinflate(struct file *, const char *, int, int, uint32_t *); -extern int zipunbz2(struct file *, const char *, int, int, uint32_t *); -extern int zipblast(struct file *, const char *, int, int, uint32_t *); - -extern uint32_t zipcrc(uint32_t, const uint8_t *, size_t); - -extern void flags(int, char **); -extern void usage(void); - -extern int pax_track(const char *, time_t); -extern void pax_prlink(struct file *); -extern int pax_sname(char **, size_t *); -extern void pax_onexit(void); diff --git a/tools/cpio/src/crc32.c b/tools/cpio/src/crc32.c deleted file mode 100644 index 084cb52cf..000000000 --- a/tools/cpio/src/crc32.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Changes by Gunnar Ritter, Freiburg i. Br., Germany, May 2003. - * - * Derived from zlib 1.1.4 - * - * Sccsid @(#)crc32.c 1.2 (gritter) 5/29/03 - */ -/* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-2002 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - - Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - */ - -#include "cpio.h" - -/* - * Table of CRC-32's of all single-byte values (made by make_crc_table) - */ -static const uint32_t crc_table[256] = { - 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, - 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, - 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, - 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, - 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, - 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, - 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, - 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, - 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, - 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, - 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, - 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, - 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, - 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, - 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, - 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, - 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, - 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, - 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, - 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, - 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, - 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, - 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, - 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, - 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, - 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, - 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, - 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, - 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, - 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, - 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, - 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, - 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, - 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, - 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, - 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, - 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, - 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, - 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, - 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, - 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, - 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, - 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, - 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, - 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, - 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, - 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, - 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, - 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, - 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, - 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, - 0x2d02ef8dL -}; - -#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); -#define DO2(buf) DO1(buf); DO1(buf); -#define DO4(buf) DO2(buf); DO2(buf); -#define DO8(buf) DO4(buf); DO4(buf); - -/* ========================================================================= */ -uint32_t -zipcrc(uint32_t crc, const uint8_t *buf, size_t len) -{ - if (buf == 0) - return 0L; - crc = crc ^ 0xffffffffL; - while (len >= 8) - { - DO8(buf); - len -= 8; - } - if (len) do { - DO1(buf); - } while (--len); - return crc ^ 0xffffffffL; -} diff --git a/tools/cpio/src/expand.c b/tools/cpio/src/expand.c deleted file mode 100644 index 5a5233f3e..000000000 --- a/tools/cpio/src/expand.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * cpio - copy file archives in and out - * - * Gunnar Ritter, Freiburg i. Br., Germany, April 2003. - */ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ - -/* Sccsid @(#)expand.c 1.6 (gritter) 12/15/03 */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "cpio.h" - -#define DLE 144 - -static void -zexread(char *data, size_t size, int doswap) -{ - if (bread(data, size) != size) - unexeoa(); - if (doswap) - swap(data, size, bflag || sflag, bflag || Sflag); -} - -#define nextbyte() ( \ - ipos >= sizeof ibuf && isize > 0 ? ( \ - zexread(ibuf, isize>sizeof ibuf?sizeof ibuf:isize, doswap), \ - ipos = 0 \ - ) : 0, \ - isize--, \ - ibuf[ipos++] & 0377 \ -) - -#define nextbit() ( \ - ibit = ibit >= 7 ? (ibyte = nextbyte(), 0) : ibit + 1, \ - isize < 0 ? (ieof = 1, -1) : (ibyte & (1<<ibit)) >> ibit \ -) - -#define sixbits(n) { \ - int t; \ - (n) = 0; \ - for (t = 0; t < 6; t++) \ - (n) |= nextbit() << t; \ -} - -#define eightbits(n) { \ - int t; \ - (n) = 0; \ - for (t = 0; t < 8; t++) \ - (n) |= nextbit() << t; \ -} - -static void -zexwrite(int *tfd, char *data, size_t size, uint32_t *crc, int *val, - const char *tgt, long long *nsize) -{ - if (size) { - if (size > *nsize) - size = *nsize; - if (*tfd >= 0 && write(*tfd, data, size) != size) { - emsg(3, "Cannot write \"%s\"", tgt); - *tfd = -1; - *val = -1; - } - *crc = zipcrc(*crc, (unsigned char *)data, size); - *nsize -= size; - } -} - -#define wadd(c) ( \ - wpos >= sizeof wbuf ? ( \ - zexwrite(&tfd, wbuf, sizeof wbuf, crc, &val, tgt, &nsize), \ - wpos = 0 \ - ) : 0, \ - wsize++, \ - wbuf[wpos++] = (c) \ -) - -#define zex_L(x) ( \ - f->f_cmethod == C_REDUCED1 ? (x) & 0177 : \ - f->f_cmethod == C_REDUCED2 ? (x) & 077 : \ - f->f_cmethod == C_REDUCED3 ? (x) & 037 : \ - /* f->f_cmethod == C_REDUCED4 */ (x) & 017 \ -) - -#define zex_F(x) ( \ - f->f_cmethod == C_REDUCED1 ? (x) == 0177 ? 2 : 3 : \ - f->f_cmethod == C_REDUCED2 ? (x) == 077 ? 2 : 3 : \ - f->f_cmethod == C_REDUCED3 ? (x) == 037 ? 2 : 3 : \ - /* f->f_cmethod == C_REDUCED4 */ (x) == 017 ? 2 : 3 \ -) - -#define zex_D(x, y) ( \ - f->f_cmethod == C_REDUCED1 ? (((x)&0200)>>7) * 0400 + (y) + 1 : \ - f->f_cmethod == C_REDUCED2 ? (((x)&0300)>>6) * 0400 + (y) + 1 : \ - f->f_cmethod == C_REDUCED3 ? (((x)&0340)>>5) * 0400 + (y) + 1 : \ - /* f->f_cmethod == C_REDUCED4 */ (((x)&0360)>>4) * 0400 + (y) + 1 \ -) - -int -zipexpand(struct file *f, const char *tgt, int tfd, int doswap, uint32_t *crc) -{ - char fset[256][33]; - char ibuf[4096], ibyte = 0, wbuf[8192]; - long ipos = sizeof ibuf, wpos = 0, isize = f->f_csize, wsize = 0; - int val = 0, ieof = 0; - int c = 0, i, j, k, n, ibit = 7, lastc, state, v = 0, len = 0; - long long nsize = f->f_st.st_size; - - *crc = 0; - memset(fset, 0, sizeof fset); - for (j = 255; j >= 0; j--) { - sixbits(n); - for (i = 0; i < n; i++) { - eightbits(fset[j][i]); - } - fset[j][32] = n<1?0:n<3?1:n<5?2:n<9?3:n<17?4:n<37?5:n<65?6:7; - } - lastc = 0; - state = 0; - while (ieof == 0) { - if (fset[lastc][32] == 0) { - eightbits(c); - } else { - if (nextbit() != 0) { - eightbits(c); - } else { - i = 0; - for (k = 0; k < fset[lastc][32]; k++) - i |= nextbit() << k; - c = fset[lastc][i] & 0377; - } - } - lastc = c; - switch (state) { - case 0: - if (c != DLE) - wadd(c); - else - state = 1; - break; - case 1: - if (c != 0) { - v = c; - len = zex_L(v); - state = zex_F(len); - } else { - wadd(DLE); - state = 0; - } - break; - case 2: - len += c; - state = 3; - break; - case 3: - n = wsize - zex_D(v, c); - for (i = 0; i < len + 3; i++) { - c = n+i >= 0 ? wbuf[n+i&sizeof wbuf-1]&0377 : 0; - wadd(c); - } - state = 0; - } - } - zexwrite(&tfd, wbuf, wpos, crc, &val, tgt, &nsize); - while (isize >= 0) - nextbyte(); - return val; -} diff --git a/tools/cpio/src/explode.c b/tools/cpio/src/explode.c deleted file mode 100644 index 863dbf672..000000000 --- a/tools/cpio/src/explode.c +++ /dev/null @@ -1,1138 +0,0 @@ -/* - * Changes by Gunnar Ritter, Freiburg i. Br., Germany, May 2003. - * - * Derived from unzip 5.40. - * - * Sccsid @(#)explode.c 1.6 (gritter) 9/30/03 - */ -/* explode.c -- put in the public domain by Mark Adler - version c15, 6 July 1996 */ - - -/* You can do whatever you like with this source file, though I would - prefer that if you modify it and redistribute it that you include - comments to that effect with your name and the date. Thank you. - - History: - vers date who what - ---- --------- -------------- ------------------------------------ - c1 30 Mar 92 M. Adler explode that uses huft_build from inflate - (this gives over a 70% speed improvement - over the original unimplode.c, which - decoded a bit at a time) - c2 4 Apr 92 M. Adler fixed bug for file sizes a multiple of 32k. - c3 10 Apr 92 M. Adler added a little memory tracking if DEBUG - c4 11 Apr 92 M. Adler added NOMEMCPY do kill use of memcpy() - c5 21 Apr 92 M. Adler added the WSIZE #define to allow reducing - the 32K window size for specialized - applications. - c6 31 May 92 M. Adler added typecasts to eliminate some warnings - c7 27 Jun 92 G. Roelofs added more typecasts. - c8 17 Oct 92 G. Roelofs changed ULONG/UWORD/byte to ulg/ush/uch. - c9 19 Jul 93 J. Bush added more typecasts (to return values); - made l[256] array static for Amiga. - c10 8 Oct 93 G. Roelofs added used_csize for diagnostics; added - buf and unshrink arguments to flush(); - undef'd various macros at end for Turbo C; - removed NEXTBYTE macro (now in unzip.h) - and bytebuf variable (not used); changed - memset() to memzero(). - c11 9 Jan 94 M. Adler fixed incorrect used_csize calculation. - c12 9 Apr 94 G. Roelofs fixed split comments on preprocessor lines - to avoid bug in Encore compiler. - c13 25 Aug 94 M. Adler fixed distance-length comment (orig c9 fix) - c14 22 Nov 95 S. Maxwell removed unnecessary "static" on auto array - c15 6 Jul 96 W. Haidinger added ulg typecasts to flush() calls. - c16 8 Feb 98 C. Spieler added ZCONST modifiers to const tables - and #ifdef DEBUG around debugging code. - c16b 25 Mar 98 C. Spieler modified DLL code for slide redirection. - - 23 May 03 Gunnar Ritter use cpio structures; C99 conversion. - */ - - -/* - Explode imploded (PKZIP method 6 compressed) data. This compression - method searches for as much of the current string of bytes (up to a length - of ~320) in the previous 4K or 8K bytes. If it doesn't find any matches - (of at least length 2 or 3), it codes the next byte. Otherwise, it codes - the length of the matched string and its distance backwards from the - current position. Single bytes ("literals") are preceded by a one (a - single bit) and are either uncoded (the eight bits go directly into the - compressed stream for a total of nine bits) or Huffman coded with a - supplied literal code tree. If literals are coded, then the minimum match - length is three, otherwise it is two. - - There are therefore four kinds of imploded streams: 8K search with coded - literals (min match = 3), 4K search with coded literals (min match = 3), - 8K with uncoded literals (min match = 2), and 4K with uncoded literals - (min match = 2). The kind of stream is identified in two bits of a - general purpose bit flag that is outside of the compressed stream. - - Distance-length pairs for matched strings are preceded by a zero bit (to - distinguish them from literals) and are always coded. The distance comes - first and is either the low six (4K) or low seven (8K) bits of the - distance (uncoded), followed by the high six bits of the distance coded. - Then the length is six bits coded (0..63 + min match length), and if the - maximum such length is coded, then it's followed by another eight bits - (uncoded) to be added to the coded length. This gives a match length - range of 2..320 or 3..321 bytes. - - The literal, length, and distance codes are all represented in a slightly - compressed form themselves. What is sent are the lengths of the codes for - each value, which is sufficient to construct the codes. Each byte of the - code representation is the code length (the low four bits representing - 1..16), and the number of values sequentially with that length (the high - four bits also representing 1..16). There are 256 literal code values (if - literals are coded), 64 length code values, and 64 distance code values, - in that order at the beginning of the compressed stream. Each set of code - values is preceded (redundantly) with a byte indicating how many bytes are - in the code description that follows, in the range 1..256. - - The codes themselves are decoded using tables made by huft_build() from - the bit lengths. That routine and its comments are in the inflate.c - module. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> - -#include "cpio.h" -#include "unzip.h" /* must supply slide[] (uint8_t) array and NEXTBYTE macro */ - -/* routines here */ -static int get_tree(struct globals *, unsigned *l, unsigned n); -static int explode_lit8(struct globals *, struct huft *tb, struct huft *tl, - struct huft *td, int bb, int bl, int bd); -static int explode_lit4(struct globals *, struct huft *tb, struct huft *tl, - struct huft *td, int bb, int bl, int bd); -static int explode_nolit8(struct globals *, struct huft *tl, struct huft *td, - int bl, int bd); -static int explode_nolit4(struct globals *, struct huft *tl, struct huft *td, - int bl, int bd); - -/* The implode algorithm uses a sliding 4K or 8K byte window on the - uncompressed stream to find repeated byte strings. This is implemented - here as a circular buffer. The index is updated simply by incrementing - and then and'ing with 0x0fff (4K-1) or 0x1fff (8K-1). Here, the 32K - buffer of inflate is used, and it works just as well to always have - a 32K circular buffer, so the index is anded with 0x7fff. This is - done to allow the window to also be used as the output buffer. */ -/* This must be supplied in an external module useable like - "uint8_t slide[8192];" or "uint8_t *slide;", where the latter would - be malloc'ed. In unzip, slide[] is actually a 32K area for use by - inflate, which uses a 32K sliding window. - */ - - -/* Tables for length and distance */ -static const uint16_t cplen2[] = - {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}; -static const uint16_t cplen3[] = - {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}; -static const uint8_t extra[] = - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 8}; -static const uint16_t cpdist4[] = - {1, 65, 129, 193, 257, 321, 385, 449, 513, 577, 641, 705, - 769, 833, 897, 961, 1025, 1089, 1153, 1217, 1281, 1345, 1409, 1473, - 1537, 1601, 1665, 1729, 1793, 1857, 1921, 1985, 2049, 2113, 2177, - 2241, 2305, 2369, 2433, 2497, 2561, 2625, 2689, 2753, 2817, 2881, - 2945, 3009, 3073, 3137, 3201, 3265, 3329, 3393, 3457, 3521, 3585, - 3649, 3713, 3777, 3841, 3905, 3969, 4033}; -static const uint16_t cpdist8[] = - {1, 129, 257, 385, 513, 641, 769, 897, 1025, 1153, 1281, - 1409, 1537, 1665, 1793, 1921, 2049, 2177, 2305, 2433, 2561, 2689, - 2817, 2945, 3073, 3201, 3329, 3457, 3585, 3713, 3841, 3969, 4097, - 4225, 4353, 4481, 4609, 4737, 4865, 4993, 5121, 5249, 5377, 5505, - 5633, 5761, 5889, 6017, 6145, 6273, 6401, 6529, 6657, 6785, 6913, - 7041, 7169, 7297, 7425, 7553, 7681, 7809, 7937, 8065}; - - -/* Macros for inflate() bit peeking and grabbing. - The usage is: - - NEEDBITS(j) - x = b & mask_bits[j]; - DUMPBITS(j) - - where NEEDBITS makes sure that b has at least j bits in it, and - DUMPBITS removes the bits from b. The macros use the variable k - for the number of bits in b. Normally, b and k are register - variables for speed. - */ - -#define NEEDBITS(n) {while(k<(n)){b|=((uint32_t)NEXTBYTE)<<k;k+=8;}} -#define DUMPBITS(n) {b>>=(n);k-=(n);} - -#define Bits 16 -#define Nob 16 -#define Eob 15 - -#define G (*Gp) - -static int -get_tree(struct globals *Gp, unsigned *l, unsigned n) -/*unsigned *l;*/ /* bit lengths */ -/*unsigned n;*/ /* number expected */ -/* Get the bit lengths for a code representation from the compressed - stream. If get_tree() returns 4, then there is an error in the data. - Otherwise zero is returned. */ -{ - unsigned i; /* bytes remaining in list */ - unsigned k; /* lengths entered */ - unsigned j; /* number of codes */ - unsigned b; /* bit length for those codes */ - - - /* get bit lengths */ - i = NEXTBYTE + 1; /* length/count pairs to read */ - k = 0; /* next code */ - do { - b = ((j = NEXTBYTE) & 0xf) + 1; /* bits in code (1..16) */ - j = ((j & 0xf0) >> 4) + 1; /* codes with those bits (1..16) */ - if (k + j > n) - return 4; /* don't overflow l[] */ - do { - l[k++] = b; - } while (--j); - } while (--i); - return k != n ? 4 : 0; /* should have read n of them */ -} - - - -static int -explode_lit8(struct globals *Gp, - struct huft *tb, struct huft *tl, struct huft *td, - int bb, int bl, int bd) -/*struct huft *tb, *tl, *td;*/ /* literal, length, and distance tables */ -/*int bb, bl, bd;*/ /* number of bits decoded by those */ -/* Decompress the imploded data using coded literals and an 8K sliding - window. */ -{ - long s; /* bytes to decompress */ - register unsigned e; /* table entry flag/number of extra bits */ - unsigned n, d; /* length and index for copy */ - unsigned w; /* current window position */ - struct huft *t; /* pointer to table entry */ - unsigned mb, ml, md; /* masks for bb, bl, and bd bits */ - register uint32_t b; /* bit buffer */ - register unsigned k; /* number of bits in bit buffer */ - unsigned u; /* true if unflushed */ - - - /* explode the coded data */ - b = k = w = 0; /* initialize bit buffer, window */ - u = 1; /* buffer unflushed */ - mb = mask_bits[bb]; /* precompute masks for speed */ - ml = mask_bits[bl]; - md = mask_bits[bd]; - s = G.ucsize; - while (s > 0) /* do until ucsize bytes uncompressed */ - { - NEEDBITS(1) - if (b & 1) /* then literal--decode it */ - { - DUMPBITS(1) - s--; - NEEDBITS((unsigned)bb) /* get coded literal */ - if ((e = (t = tb + ((~(unsigned)b) & mb))->e) > 16) - do { - if (e == 99) - return 1; - DUMPBITS(t->b) - e -= 16; - NEEDBITS(e) - } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); - DUMPBITS(t->b) - redirSlide[w++] = (uint8_t)t->v.n; - if (w == WSIZE) - { - flush(&G, redirSlide, (uint32_t)w); - w = u = 0; - } - } - else /* else distance/length */ - { - DUMPBITS(1) - NEEDBITS(7) /* get distance low bits */ - d = (unsigned)b & 0x7f; - DUMPBITS(7) - NEEDBITS((unsigned)bd) /* get coded distance high bits */ - if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16) - do { - if (e == 99) - return 1; - DUMPBITS(t->b) - e -= 16; - NEEDBITS(e) - } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); - DUMPBITS(t->b) - d = w - d - t->v.n; /* construct offset */ - NEEDBITS((unsigned)bl) /* get coded length */ - if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16) - do { - if (e == 99) - return 1; - DUMPBITS(t->b) - e -= 16; - NEEDBITS(e) - } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); - DUMPBITS(t->b) - n = t->v.n; - if (e) /* get length extra bits */ - { - NEEDBITS(8) - n += (unsigned)b & 0xff; - DUMPBITS(8) - } - - /* do the copy */ - s -= n; - do { - n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e); - if (u && w <= d) - { - memset(redirSlide + w, 0, e); - w += e; - d += e; - } - else -#ifndef NOMEMCPY - if (w - d >= e) /* (this test assumes unsigned comparison) */ - { - memcpy(redirSlide + w, redirSlide + d, e); - w += e; - d += e; - } - else /* do it slow to avoid memcpy() overlap */ -#endif /* !NOMEMCPY */ - do { - redirSlide[w++] = redirSlide[d++]; - } while (--e); - if (w == WSIZE) - { - flush(&G, redirSlide, (uint32_t)w); - w = u = 0; - } - } while (n); - } - } - - /* flush out redirSlide */ - flush(&G, redirSlide, (uint32_t)w); - if (G.csize + G.incnt + (k >> 3)) /* should have read csize bytes, but */ - { /* sometimes read one too many: k>>3 compensates */ - /*G.used_csize = G.zsize - G.csize - G.incnt - (k >> 3);*/ - return 5; - } - return 0; -} - - - -static int -explode_lit4(struct globals *Gp, - struct huft *tb, struct huft *tl, struct huft *td, - int bb, int bl, int bd) -/*struct huft *tb, *tl, *td;*/ /* literal, length, and distance tables */ -/*int bb, bl, bd;*/ /* number of bits decoded by those */ -/* Decompress the imploded data using coded literals and a 4K sliding - window. */ -{ - long s; /* bytes to decompress */ - register unsigned e; /* table entry flag/number of extra bits */ - unsigned n, d; /* length and index for copy */ - unsigned w; /* current window position */ - struct huft *t; /* pointer to table entry */ - unsigned mb, ml, md; /* masks for bb, bl, and bd bits */ - register uint32_t b; /* bit buffer */ - register unsigned k; /* number of bits in bit buffer */ - unsigned u; /* true if unflushed */ - - - /* explode the coded data */ - b = k = w = 0; /* initialize bit buffer, window */ - u = 1; /* buffer unflushed */ - mb = mask_bits[bb]; /* precompute masks for speed */ - ml = mask_bits[bl]; - md = mask_bits[bd]; - s = G.ucsize; - while (s > 0) /* do until ucsize bytes uncompressed */ - { - NEEDBITS(1) - if (b & 1) /* then literal--decode it */ - { - DUMPBITS(1) - s--; - NEEDBITS((unsigned)bb) /* get coded literal */ - if ((e = (t = tb + ((~(unsigned)b) & mb))->e) > 16) - do { - if (e == 99) - return 1; - DUMPBITS(t->b) - e -= 16; - NEEDBITS(e) - } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); - DUMPBITS(t->b) - redirSlide[w++] = (uint8_t)t->v.n; - if (w == WSIZE) - { - flush(&G, redirSlide, (uint32_t)w); - w = u = 0; - } - } - else /* else distance/length */ - { - DUMPBITS(1) - NEEDBITS(6) /* get distance low bits */ - d = (unsigned)b & 0x3f; - DUMPBITS(6) - NEEDBITS((unsigned)bd) /* get coded distance high bits */ - if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16) - do { - if (e == 99) - return 1; - DUMPBITS(t->b) - e -= 16; - NEEDBITS(e) - } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); - DUMPBITS(t->b) - d = w - d - t->v.n; /* construct offset */ - NEEDBITS((unsigned)bl) /* get coded length */ - if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16) - do { - if (e == 99) - return 1; - DUMPBITS(t->b) - e -= 16; - NEEDBITS(e) - } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); - DUMPBITS(t->b) - n = t->v.n; - if (e) /* get length extra bits */ - { - NEEDBITS(8) - n += (unsigned)b & 0xff; - DUMPBITS(8) - } - - /* do the copy */ - s -= n; - do { - n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e); - if (u && w <= d) - { - memset(redirSlide + w, 0, e); - w += e; - d += e; - } - else -#ifndef NOMEMCPY - if (w - d >= e) /* (this test assumes unsigned comparison) */ - { - memcpy(redirSlide + w, redirSlide + d, e); - w += e; - d += e; - } - else /* do it slow to avoid memcpy() overlap */ -#endif /* !NOMEMCPY */ - do { - redirSlide[w++] = redirSlide[d++]; - } while (--e); - if (w == WSIZE) - { - flush(&G, redirSlide, (uint32_t)w); - w = u = 0; - } - } while (n); - } - } - - /* flush out redirSlide */ - flush(&G, redirSlide, (uint32_t)w); - if (G.csize + G.incnt + (k >> 3)) /* should have read csize bytes, but */ - { /* sometimes read one too many: k>>3 compensates */ - /*G.used_csize = G.zsize - G.csize - G.incnt - (k >> 3);*/ - return 5; - } - return 0; -} - - - -static int -explode_nolit8(struct globals *Gp, - struct huft *tl, struct huft *td, int bl, int bd) -/*struct huft *tl, *td;*/ /* length and distance decoder tables */ -/*int bl, bd;*/ /* number of bits decoded by tl[] and td[] */ -/* Decompress the imploded data using uncoded literals and an 8K sliding - window. */ -{ - long s; /* bytes to decompress */ - register unsigned e; /* table entry flag/number of extra bits */ - unsigned n, d; /* length and index for copy */ - unsigned w; /* current window position */ - struct huft *t; /* pointer to table entry */ - unsigned ml, md; /* masks for bl and bd bits */ - register uint32_t b; /* bit buffer */ - register unsigned k; /* number of bits in bit buffer */ - unsigned u; /* true if unflushed */ - - - /* explode the coded data */ - b = k = w = 0; /* initialize bit buffer, window */ - u = 1; /* buffer unflushed */ - ml = mask_bits[bl]; /* precompute masks for speed */ - md = mask_bits[bd]; - s = G.ucsize; - while (s > 0) /* do until ucsize bytes uncompressed */ - { - NEEDBITS(1) - if (b & 1) /* then literal--get eight bits */ - { - DUMPBITS(1) - s--; - NEEDBITS(8) - redirSlide[w++] = (uint8_t)b; - if (w == WSIZE) - { - flush(&G, redirSlide, (uint32_t)w); - w = u = 0; - } - DUMPBITS(8) - } - else /* else distance/length */ - { - DUMPBITS(1) - NEEDBITS(7) /* get distance low bits */ - d = (unsigned)b & 0x7f; - DUMPBITS(7) - NEEDBITS((unsigned)bd) /* get coded distance high bits */ - if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16) - do { - if (e == 99) - return 1; - DUMPBITS(t->b) - e -= 16; - NEEDBITS(e) - } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); - DUMPBITS(t->b) - d = w - d - t->v.n; /* construct offset */ - NEEDBITS((unsigned)bl) /* get coded length */ - if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16) - do { - if (e == 99) - return 1; - DUMPBITS(t->b) - e -= 16; - NEEDBITS(e) - } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); - DUMPBITS(t->b) - n = t->v.n; - if (e) /* get length extra bits */ - { - NEEDBITS(8) - n += (unsigned)b & 0xff; - DUMPBITS(8) - } - - /* do the copy */ - s -= n; - do { - n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e); - if (u && w <= d) - { - memset(redirSlide + w, 0, e); - w += e; - d += e; - } - else -#ifndef NOMEMCPY - if (w - d >= e) /* (this test assumes unsigned comparison) */ - { - memcpy(redirSlide + w, redirSlide + d, e); - w += e; - d += e; - } - else /* do it slow to avoid memcpy() overlap */ -#endif /* !NOMEMCPY */ - do { - redirSlide[w++] = redirSlide[d++]; - } while (--e); - if (w == WSIZE) - { - flush(&G, redirSlide, (uint32_t)w); - w = u = 0; - } - } while (n); - } - } - - /* flush out redirSlide */ - flush(&G, redirSlide, (uint32_t)w); - if (G.csize + G.incnt + (k >> 3)) /* should have read csize bytes, but */ - { /* sometimes read one too many: k>>3 compensates */ - /*G.used_csize = G.zsize - G.csize - G.incnt - (k >> 3);*/ - return 5; - } - return 0; -} - - - -static int -explode_nolit4(struct globals *Gp, - struct huft *tl, struct huft *td, int bl, int bd) -/*struct huft *tl, *td;*/ /* length and distance decoder tables */ -/*int bl, bd;*/ /* number of bits decoded by tl[] and td[] */ -/* Decompress the imploded data using uncoded literals and a 4K sliding - window. */ -{ - long s; /* bytes to decompress */ - register unsigned e; /* table entry flag/number of extra bits */ - unsigned n, d; /* length and index for copy */ - unsigned w; /* current window position */ - struct huft *t; /* pointer to table entry */ - unsigned ml, md; /* masks for bl and bd bits */ - register uint32_t b; /* bit buffer */ - register unsigned k; /* number of bits in bit buffer */ - unsigned u; /* true if unflushed */ - - - /* explode the coded data */ - b = k = w = 0; /* initialize bit buffer, window */ - u = 1; /* buffer unflushed */ - ml = mask_bits[bl]; /* precompute masks for speed */ - md = mask_bits[bd]; - s = G.ucsize; - while (s > 0) /* do until ucsize bytes uncompressed */ - { - NEEDBITS(1) - if (b & 1) /* then literal--get eight bits */ - { - DUMPBITS(1) - s--; - NEEDBITS(8) - redirSlide[w++] = (uint8_t)b; - if (w == WSIZE) - { - flush(&G, redirSlide, (uint32_t)w); - w = u = 0; - } - DUMPBITS(8) - } - else /* else distance/length */ - { - DUMPBITS(1) - NEEDBITS(6) /* get distance low bits */ - d = (unsigned)b & 0x3f; - DUMPBITS(6) - NEEDBITS((unsigned)bd) /* get coded distance high bits */ - if ((e = (t = td + ((~(unsigned)b) & md))->e) > 16) - do { - if (e == 99) - return 1; - DUMPBITS(t->b) - e -= 16; - NEEDBITS(e) - } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); - DUMPBITS(t->b) - d = w - d - t->v.n; /* construct offset */ - NEEDBITS((unsigned)bl) /* get coded length */ - if ((e = (t = tl + ((~(unsigned)b) & ml))->e) > 16) - do { - if (e == 99) - return 1; - DUMPBITS(t->b) - e -= 16; - NEEDBITS(e) - } while ((e = (t = t->v.t + ((~(unsigned)b) & mask_bits[e]))->e) > 16); - DUMPBITS(t->b) - n = t->v.n; - if (e) /* get length extra bits */ - { - NEEDBITS(8) - n += (unsigned)b & 0xff; - DUMPBITS(8) - } - - /* do the copy */ - s -= n; - do { - n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e); - if (u && w <= d) - { - memset(redirSlide + w, 0, e); - w += e; - d += e; - } - else -#ifndef NOMEMCPY - if (w - d >= e) /* (this test assumes unsigned comparison) */ - { - memcpy(redirSlide + w, redirSlide + d, e); - w += e; - d += e; - } - else /* do it slow to avoid memcpy() overlap */ -#endif /* !NOMEMCPY */ - do { - redirSlide[w++] = redirSlide[d++]; - } while (--e); - if (w == WSIZE) - { - flush(&G, redirSlide, (uint32_t)w); - w = u = 0; - } - } while (n); - } - } - - /* flush out redirSlide */ - flush(&G, redirSlide, (uint32_t)w); - if (G.csize + G.incnt + (k >> 3)) /* should have read csize bytes, but */ - { /* sometimes read one too many: k>>3 compensates */ - /*G.used_csize = G.zsize - G.csize - G.incnt - (k >> 3);*/ - return 5; - } - return 0; -} - -#undef G - -int -zipexplode(struct file *f, const char *tgt, int tfd, int doswap, uint32_t *crc) -/* Explode an imploded compressed stream. Based on the general purpose - bit flag, decide on coded or uncoded literals, and an 8K or 4K sliding - window. Construct the literal (if any), length, and distance codes and - the tables needed to decode them (using huft_build() from inflate.c), - and call the appropriate routine for the type of data in the remainder - of the stream. The four routines are nearly identical, differing only - in whether the literal is decoded or simply read in, and in how many - bits are read in, uncoded, for the low distance bits. */ -{ - struct globals G; - unsigned r; /* return codes */ - struct huft *tb; /* literal code table */ - struct huft *tl; /* length code table */ - struct huft *td; /* distance code table */ - int bb; /* bits for tb */ - int bl; /* bits for tl */ - int bd; /* bits for td */ - unsigned l[256]; /* bit lengths for codes */ - - memset(&G, 0, sizeof G); - G.tgt = tgt; - G.tfd = tfd; - G.doswap = doswap; - G.crc = crc; - G.zsize = G.uzsize = f->f_csize; - G.ucsize = f->f_st.st_size; - - /* Tune base table sizes. Note: I thought that to truly optimize speed, - I would have to select different bl, bd, and bb values for different - compressed file sizes. I was surprised to find out that the values of - 7, 7, and 9 worked best over a very wide range of sizes, except that - bd = 8 worked marginally better for large compressed sizes. */ - bl = 7; - bd = (G.csize + G.incnt) > 200000L ? 8 : 7; - - - /* With literal tree--minimum match length is 3 */ -#ifdef DEBUG - G.hufts = 0; /* initialize huft's malloc'ed */ -#endif - if (f->f_gflag & FG_BIT2) - { - bb = 9; /* base table size for literals */ - if ((r = get_tree(&G, l, 256)) != 0) - goto err; - if ((r = huft_build(l, 256, 256, NULL, NULL, &tb, &bb, - Bits, Nob, Eob)) != 0) - { - if (r == 1) - huft_free(tb); - goto err; - } - if ((r = get_tree(&G, l, 64)) != 0) - goto err; - if ((r = huft_build(l, 64, 0, cplen3, extra, &tl, &bl, - Bits, Nob, Eob)) != 0) - { - if (r == 1) - huft_free(tl); - huft_free(tb); - goto err; - } - if ((r = get_tree(&G, l, 64)) != 0) - goto err; - if (f->f_gflag & FG_BIT1) /* true if 8K */ - { - if ((r = huft_build(l, 64, 0, cpdist8, extra, &td, &bd, - Bits, Nob, Eob)) != 0) - { - if (r == 1) - huft_free(td); - huft_free(tl); - huft_free(tb); - goto err; - } - r = explode_lit8(&G, tb, tl, td, bb, bl, bd); - } - else /* else 4K */ - { - if ((r = huft_build(l, 64, 0, cpdist4, extra, &td, &bd, - Bits, Nob, Eob)) != 0) - { - if (r == 1) - huft_free(td); - huft_free(tl); - huft_free(tb); - goto err; - } - r = explode_lit4(&G, tb, tl, td, bb, bl, bd); - } - huft_free(td); - huft_free(tl); - huft_free(tb); - } - else - - - /* No literal tree--minimum match length is 2 */ - { - if ((r = get_tree(&G, l, 64)) != 0) - goto err; - if ((r = huft_build(l, 64, 0, cplen2, extra, &tl, &bl, - Bits, Nob, Eob)) != 0) - { - if (r == 1) - huft_free(tl); - goto err; - } - if ((r = get_tree(&G, l, 64)) != 0) - goto err; - if (f->f_gflag & FG_BIT1) /* true if 8K */ - { - if ((r = huft_build(l, 64, 0, cpdist8, extra, &td, &bd, - Bits, Nob, Eob)) != 0) - { - if (r == 1) - huft_free(td); - huft_free(tl); - goto err; - } - r = explode_nolit8(&G, tl, td, bl, bd); - } - else /* else 4K */ - { - if ((r = huft_build(l, 64, 0, cpdist4, extra, &td, &bd, - Bits, Nob, Eob)) != 0) - { - if (r == 1) - huft_free(td); - huft_free(tl); - goto err; - } - r = explode_nolit4(&G, tl, td, bl, bd); - } - huft_free(td); - huft_free(tl); - } - Trace((stderr, "<%u > ", G.hufts)); -err: - switch (r) { - case 0: - break; - case 5: - while (G.uzsize > 0) - NEXTBYTE; - /*FALLTHRU*/ - default: - msg(3, 0, "compression error on \"%s\"\n", f->f_name); - } - return r || G.status ? -1 : 0; -} - -/* The following code is derived from: */ - -/* inflate.c -- put in the public domain by Mark Adler - version c16b, 29 March 1998 */ - -/* If BMAX needs to be larger than 16, then h and x[] should be uint32_t. */ -#define BMAX 16 /* maximum bit length of any code (16 for explode) */ -#define N_MAX 288 /* maximum number of codes in any set */ - - -int -huft_build(const unsigned *b, unsigned n, unsigned s, - const uint16_t *d, const uint8_t *e, - struct huft **t, int *m, - int bits, int nob, int eob) -/*const unsigned *b;*/ /* code lengths in bits (all assumed <= BMAX) */ -/*unsigned n;*/ /* number of codes (assumed <= N_MAX) */ -/*unsigned s;*/ /* number of simple-valued codes (0..s-1) */ -/*const uint16_t *d;*/ /* list of base values for non-simple codes */ -/*const uint16_t *e;*/ /* list of extra bits for non-simple codes */ -/*struct huft **t;*/ /* result: starting table */ -/*int *m;*/ /* maximum lookup bits, returns actual */ -/* Given a list of code lengths and a maximum table size, make a set of - tables to decode that set of codes. Return zero on success, one if - the given code set is incomplete (the tables are still built in this - case), two if the input is invalid (all zero length codes or an - oversubscribed set of lengths), and three if not enough memory. - The code with value 256 is special, and the tables are constructed - so that no bits beyond that code are fetched when that code is - decoded. */ -{ - unsigned a; /* counter for codes of length k */ - unsigned c[BMAX+1]; /* bit length count table */ - unsigned el; /* length of EOB code (value 256) */ - unsigned f; /* i repeats in table every f entries */ - int g; /* maximum code length */ - int h; /* table level */ - register unsigned i; /* counter, current code */ - register unsigned j; /* counter */ - register int k; /* number of bits in current code */ - int lx[BMAX+1]; /* memory for l[-1..BMAX-1] */ - int *l = lx+1; /* stack of bits per table */ - register unsigned *p; /* pointer into c[], b[], or v[] */ - register struct huft *q; /* points to current table */ - struct huft r; /* table entry for structure assignment */ - struct huft *u[BMAX]; /* table stack */ - unsigned v[N_MAX]; /* values in order of bit length */ - register int w; /* bits before this table == (l * h) */ - unsigned x[BMAX+1]; /* bit offsets, then code stack */ - unsigned *xp; /* pointer into x */ - int y; /* number of dummy codes added */ - unsigned z; /* number of entries in current table */ - - - /* Generate counts for each bit length */ - el = n > 256 ? b[256] : BMAX; /* set length of EOB code, if any */ - memset(c, 0, sizeof c); - p = (unsigned *)b; i = n; - do { - c[*p]++; p++; /* assume all entries <= BMAX */ - } while (--i); - if (c[0] == n) /* null input--all zero length codes */ - { - *t = NULL; - *m = 0; - return 0; - } - - - /* Find minimum and maximum length, bound *m by those */ - for (j = 1; j <= BMAX; j++) - if (c[j]) - break; - k = j; /* minimum code length */ - if ((unsigned)*m < j) - *m = j; - for (i = BMAX; i; i--) - if (c[i]) - break; - g = i; /* maximum code length */ - if ((unsigned)*m > i) - *m = i; - - - /* Adjust last length count to fill out codes, if needed */ - for (y = 1 << j; j < i; j++, y <<= 1) - if ((y -= c[j]) < 0) - return 2; /* bad input: more codes than bits */ - if ((y -= c[i]) < 0) - return 2; - c[i] += y; - - - /* Generate starting offsets into the value table for each length */ - x[1] = j = 0; - p = c + 1; xp = x + 2; - while (--i) { /* note that i == g from above */ - *xp++ = (j += *p++); - } - - - /* Make a table of values in order of bit lengths */ - memset(v, 0, sizeof v); - p = (unsigned *)b; i = 0; - do { - if ((j = *p++) != 0) - v[x[j]++] = i; - } while (++i < n); - n = x[g]; /* set n to length of v */ - - - /* Generate the Huffman codes and for each, make the table entries */ - x[0] = i = 0; /* first Huffman code is zero */ - p = v; /* grab values in bit order */ - h = -1; /* no tables yet--level -1 */ - w = l[-1] = 0; /* no bits decoded yet */ - u[0] = NULL; /* just to keep compilers happy */ - q = NULL; /* ditto */ - z = 0; /* ditto */ - - /* go through the bit lengths (k already is bits in shortest code) */ - for (; k <= g; k++) - { - a = c[k]; - while (a--) - { - /* here i is the Huffman code of length k bits for value *p */ - /* make tables up to required level */ - while (k > w + l[h]) - { - w += l[h++]; /* add bits already decoded */ - - /* compute minimum size table less than or equal to *m bits */ - z = (z = g - w) > (unsigned)*m ? *m : z; /* upper limit */ - if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ - { /* too few codes for k-w bit table */ - f -= a + 1; /* deduct codes from patterns left */ - xp = c + k; - while (++j < z) /* try smaller tables up to z bits */ - { - if ((f <<= 1) <= *++xp) - break; /* enough codes to use up j bits */ - f -= *xp; /* else deduct codes from patterns */ - } - } - if ((unsigned)w + j > el && (unsigned)w < el) - j = el - w; /* make EOB code end at table */ - z = 1 << j; /* table entries for j-bit table */ - l[h] = j; /* set table size in stack */ - - /* allocate and link in new table */ - if ((q = malloc((z + 1)*sizeof(struct huft))) == NULL) - { - if (h) - huft_free(u[0]); - return 3; /* not enough memory */ - } -#ifdef DEBUG - G.hufts += z + 1; /* track memory usage */ -#endif - *t = q + 1; /* link to list for huft_free() */ - *(t = &(q->v.t)) = NULL; - u[h] = ++q; /* table starts after link */ - - /* connect to last table, if there is one */ - if (h) - { - x[h] = i; /* save pattern for backing up */ - r.b = (uint8_t)l[h-1]; /* bits to dump before this table */ - r.e = (uint8_t)(bits + j); /* bits in this table */ - r.v.t = q; /* pointer to this table */ - j = (i & ((1 << w) - 1)) >> (w - l[h-1]); - u[h-1][j] = r; /* connect to last table */ - } - } - - /* set up table entry in r */ - r.b = (uint8_t)(k - w); - if (p >= v + n) - r.e = 99; /* out of values--invalid code */ - else if (*p < s) - { - r.e = (uint8_t)(*p < 256 ? nob : eob); /* 256 is end-of-block code */ - r.v.n = (uint16_t)*p++; /* simple code is just the value */ - } - else - { - r.e = (uint8_t)e[*p - s]; /* non-simple--look up in lists */ - r.v.n = d[*p++ - s]; - } - - /* fill code-like entries with r */ - f = 1 << (k - w); - for (j = i >> w; j < z; j += f) - q[j] = r; - - /* backwards increment the k-bit code i */ - for (j = 1 << (k - 1); i & j; j >>= 1) - i ^= j; - i ^= j; - - /* backup over finished tables */ - while ((i & ((1 << w) - 1)) != x[h]) - w -= l[--h]; /* don't need to update q */ - } - } - - - /* return actual size of base table */ - *m = l[0]; - - - /* Return true (1) if we were given an incomplete table */ - return y != 0 && g != 1; -} - - -void -huft_free(struct huft *t) -/*struct huft *t;*/ /* table to free */ -/* Free the malloc'ed tables built by huft_build(), which makes a linked - list of the tables it made, with the links in a dummy first entry of - each table. */ -{ - register struct huft *p, *q; - - - /* Go through linked list, freeing from the malloced (t[-1]) address. */ - p = t; - while (p != NULL) - { - q = (--p)->v.t; - free(p); - p = q; - } -} - -const uint16_t mask_bits[] = { - 0x0000, - 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, - 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff -}; - -void -flush(struct globals *Gp, const void *data, size_t size) -{ - if (Gp->tfd>=0 && write(Gp->tfd, data, size) != size) { - emsg(3, "Cannot write \"%s\"", Gp->tgt); - Gp->tfd = -1; - Gp->status = -1; - } - *Gp->crc = zipcrc(*Gp->crc, data, size); -} - -int -readbyte(struct globals *Gp) -{ - if (Gp->uzsize <= 0) - return EOF; - Gp->incnt = bread((char *)Gp->inbuf, - Gp->uzsize>sizeof Gp->inbuf?sizeof Gp->inbuf:Gp->uzsize); - if (Gp->incnt <= 0) - unexeoa(); - if (Gp->doswap) - swap((char *)Gp->inbuf, Gp->incnt, bflag||sflag,bflag||Sflag); - Gp->uzsize -= Gp->incnt; - Gp->incnt--; - Gp->inptr = Gp->inbuf; - return (int)(*Gp->inptr++); -} diff --git a/tools/cpio/src/flags.c b/tools/cpio/src/flags.c deleted file mode 100644 index e06c8e80d..000000000 --- a/tools/cpio/src/flags.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * cpio - copy file archives in and out - * - * Gunnar Ritter, Freiburg i. Br., Germany, April 2003. - */ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ - -/* Sccsid @(#)flags.c 1.6 (gritter) 3/26/07 */ - -#include <unistd.h> -#include <stdio.h> -#include <stdarg.h> -#include <stdlib.h> - -#include "cpio.h" - -void -flags(int ac, char **av) -{ - const char optstring[] = - "iopaAbBcC:dDeE:fH:I:kKlLmM:O:PrR:sStTuvV6"; - int i, illegal = 0; - - if (getenv("SYSV3") != NULL) - sysv3 = printsev = 1; - while ((i = getopt(ac, av, optstring)) != EOF) { - switch (i) { - case 'i': - case 'o': - case 'p': - if (action && action != i) - illegal = 1; - action = i; - break; - case 'a': - aflag = 1; - break; - case 'A': - Aflag = 1; - break; - case 'b': - bflag = 1; - break; - case 'B': - blksiz = 5120; - Bflag = 1; - break; - case 'c': - fmttype = sysv3 ? FMT_ODC : FMT_ASC; - cflag = 1; - break; - case 'C': - if ((blksiz = atol(optarg)) <= 0) - msg(4, -2, - "Illegal size given for -C option.\n"); - Cflag = 1; - break; - case 'd': - dflag = 1; - break; - case 'D': - Dflag = 1; - break; - case 'e': - /* - * This option is accepted for compatibility only, - * -Hdec should be used instead. - */ - fmttype = FMT_DEC; - eflag = 1; - break; - case 'E': - Eflag = optarg; - break; - case 'f': - fflag = 1; - break; - case 'H': - if (setfmt(optarg) < 0) - illegal = 1; - Hflag = 1; - break; - case 'I': - Iflag = optarg; - break; - case 'k': - kflag = 1; - break; - case 'K': - /* - * This option is accepted for compatibility only, - * -Hsgi should be used instead. - */ - fmttype = FMT_SGIBE; - Kflag = 1; - break; - case 'l': - lflag = 1; - break; - case 'L': - Lflag = 1; - break; - case 'm': - mflag = 1; - break; - case 'M': - Mflag = oneintfmt(optarg); - break; - case 'O': - Oflag = optarg; - break; - case 'P': - Pflag = 1; - break; - case 'r': - rflag = 1; - break; - case 'R': - if (setreassign(Rflag = optarg) < 0) - illegal = 1; - break; - case 's': - sflag = 1; - break; - case 'S': - Sflag = 1; - break; - case 't': - tflag = 1; - break; - case 'u': - uflag = 1; - break; - case 'v': - vflag++; - break; - case 'V': - Vflag = 1; - break; - case '6': - sixflag = 1; - fmttype = FMT_BINLE; - break; - default: - if (sysv3) - usage(); - illegal = 1; - } - } - switch (action) { - case 'i': - if (Oflag || Kflag || eflag || Lflag || lflag || aflag || - Aflag || Pflag) - illegal = 1; - for (i = optind; i < ac; i++) - addg(av[i], 0); - break; - case 'o': - if (Iflag || dflag || fflag || kflag || mflag || - rflag || tflag || uflag || - sixflag || Eflag || Rflag) - illegal = 1; - if (optind != ac) - illegal = 1; - break; - case 'p': - if (Iflag || Oflag || blksiz || Eflag || fmttype != FMT_NONE || - Mflag || bflag || fflag || kflag || sflag || - tflag || Sflag || sixflag) - illegal = 1; - if (optind + 1 != ac) - illegal = 1; - break; - default: - if (sysv3 == 0) - msg(3, 0, "One of -i, -o or -p must be specified.\n"); - else if (ac > 1) - msg(3, -2, "Options must include one: -o, -i, -p.\n"); - illegal = 1; - } - /* - * Sanity checks. No check for multiple occurences of options - * since they can make sense, behave as other programs and use - * the latter one. - */ - /*if (aflag && mflag) { - msg(3, 0, "-a and -m are mutually exclusive.\n"); - illegal = 1; - } why? */ - /*if (cflag && (Hflag || Kflag || eflag)) { - msg(3, 0, "-c and -H are mutually exclusive.\n"); - illegal = 1; - } allow overriding -c with -H and vice versa */ - if ((vflag || tflag) && Vflag) { - msg(3, 0, "-v and -V are mutually exclusive.\n"); - illegal = 1; - } - /*if (Bflag && Cflag) { - msg(3, 0, "-B and -C are mutually exclusive.\n"); - illegal = 1; - } allow overriding of block sizes */ - if ((Hflag || cflag || Kflag || eflag) && sixflag) { - msg(3, 0, "-H and -6 are mutually exclusive.\n"); - illegal = 1; - } - if (!sysv3 && Mflag && Oflag == NULL && Iflag == NULL) { - msg(3, 0, "-M not meaningful without -O or -I.\n"); - illegal = 1; - } - if (!sysv3 && Aflag && Oflag == NULL) { - msg(3, 0, "-A requires the -O option\n"); - illegal = 1; - } - if (illegal) - usage(); -} - -void -usage(void) -{ - if (sysv3) - fprintf(stderr, "\ -Usage: %s -o[acvVABL] [-Csize] [-Hhdr] [-Mmsg] <name-list >collection\n\ -\t%s -o[acvVABL] -Ocollection [-Csize] [-Hhdr] [-Mmsg] <name-list\n\ -\t%s -i[bcdkmrsStuvVfB6] [-Csize] [-Efile] [-Hhdr] [-Mmsg] [-Rid] [pattern ...] <collection\n\ -\t%s -i[bcdkmrsStuvVfB6] -Icollection [-Csize] [-Efile] [-Hhdr] [-Mmsg] [-Rid] [pattern ...]\n\ -\t%s -p[adlmruvVL] [-Rid] directory <name-list\n", - progname, progname, progname, progname, progname); - else - fprintf(stderr, "USAGE:\n\ -\t%s -i[bcdfkmrstuvBSV6] [-C size] [-E file] [-H hdr] [[-I file] [-M msg]] \ -[-R id] [patterns]\n\ -\t%s -o[acvABLV] [-C size] [-H hdr] [[-M msg] [-O file]]\n\ -\t%s -p[adlmuvLV] [-R id] directory\n", - progname, progname, progname); - exit(1); -} diff --git a/tools/cpio/src/getdir.c b/tools/cpio/src/getdir.c deleted file mode 100644 index 245b7641e..000000000 --- a/tools/cpio/src/getdir.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)getdir.c 1.20 (gritter) 5/14/06 */ - -#ifndef __linux__ -/* - * 32-bit Solaris and Open UNIX do not have 64-bit getdents(); but - * having _FILE_OFFSET_BITS=64 will make it use a dirent64 struct - * on Open UNIX -> SEGV. - */ -#undef _FILE_OFFSET_BITS -#endif /* !__linux__ */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> - -#if defined (__UCLIBC__) -#include <linux/types.h> -#include <linux/dirent.h> -#define getdents(a, b, c) __getdents64(a, b, c) -#define dirent dirent64 -extern int getdents(int, struct dirent *, size_t); -#elif defined (__GLIBC__) || defined (__FreeBSD__) || defined (_AIX) || \ - defined (__NetBSD__) || defined (__OpenBSD__) || \ - defined (__DragonFly__) || defined (__APPLE__) -#include <dirent.h> -#define getdents(a, b, c) getdirentries((a), (char *)(b), (c), &(db->g_offs)) -#if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || \ - defined (__DragonFly__) || defined (__APPLE__) -#undef d_ino -#endif /* __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __DragonFly__ - || __APPLE__ */ -#elif defined (__dietlibc__) -#include <dirent.h> -#include <unistd.h> -#else /* !__GLIBC__, !__dietlibc__ */ -#ifdef __hpux -#define _KERNEL -#endif /* __hpux */ -#include <sys/dirent.h> -#ifdef __hpux -#ifndef _INO64_T -typedef unsigned long long uint64_t; -typedef uint64_t ino64_t; -#endif /* !_INO64_T */ -#ifdef __LP64__ -#define dirent __dirent64 -#else /* !__LP64__ */ -#define dirent __dirent32 -#endif /* !__LP64__ */ -#define d_reclen __d_reclen -#define d_name __d_name -#define d_ino __d_ino -#endif /* __hpux */ -#endif /* !__GLIBC__, !__dietlibc__ */ - -#include "getdir.h" - -#define DIBSIZE 5120 - -struct getdb { -#if !defined (__FreeBSD__) && !defined (__NetBSD__) && !defined (__OpenBSD__) \ - && !defined (__DragonFly__) && !defined (__APPLE__) - off_t g_offs; -#else /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ - long g_offs; -#endif /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ - struct dirent *g_dirp; - const char *g_path; - struct direc g_dic; - union { - char g_dirbuf[DIBSIZE+1]; - struct dirent g_dummy[1]; - } g_u; - int g_num; - int g_fd; -}; - -struct getdb * -getdb_alloc(const char *path, int fd) -{ - struct getdb *db; - - if ((db = malloc(sizeof *db)) == NULL) - return NULL; - db->g_dirp = NULL; - db->g_offs = 0; - db->g_fd = fd; - db->g_path = path; - return db; -} - -void -getdb_free(struct getdb *db) -{ - free(db); -} - -struct direc * -getdir(struct getdb *db, int *err) -{ - int reclen; - - *err = 0; - while (db->g_dirp == NULL) - { - /*LINTED*/ - db->g_num = getdents(db->g_fd, - (struct dirent *)db->g_u.g_dirbuf, - DIBSIZE); - if (db->g_num <= 0) { - if (db->g_num < 0) - *err = errno; - db->g_offs = 0; - return NULL; - } - /*LINTED*/ - db->g_dirp = (struct dirent *)db->g_u.g_dirbuf; - while (db->g_dirp && -#if !defined (__FreeBSD__) && !defined (__NetBSD__) && !defined (__OpenBSD__) \ - && !defined (__DragonFly__) && !defined (__APPLE__) - db->g_dirp->d_ino == 0 -#else /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ - (db->g_dirp->d_fileno == 0 -#ifdef DT_WHT - || db->g_dirp->d_type == DT_WHT -#endif - ) -#endif /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ - ) - { - next: -#ifndef __DragonFly__ - reclen = db->g_dirp->d_reclen; -#else - reclen = _DIRENT_DIRSIZ(db->g_dirp); -#endif - if ((db->g_num -= reclen) == 0 || reclen == 0) - db->g_dirp = NULL; - else - db->g_dirp = - /*LINTED*/ - (struct dirent *)((char *)db->g_dirp - + reclen); - } - } -#if !defined (__FreeBSD__) && !defined (__NetBSD__) && !defined (__OpenBSD__) \ - && !defined (__DragonFly__) && !defined (__APPLE__) - if (db->g_dirp->d_ino == 0) - goto next; - db->g_dic.d_ino = db->g_dirp->d_ino; -#else /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ - if (db->g_dirp->d_fileno == 0 -#ifdef DT_WHT - || db->g_dirp->d_type == DT_WHT -#endif - ) - { - goto next; - } - db->g_dic.d_ino = db->g_dirp->d_fileno; -#endif /* __FreeBSD__, __NetBSD__, __OpenBSD__, __DragonFly__, __APPLE__ */ - db->g_dic.d_name = db->g_dirp->d_name; -#ifndef __DragonFly__ - reclen = db->g_dirp->d_reclen; -#else - reclen = _DIRENT_DIRSIZ(db->g_dirp); -#endif - if ((db->g_num -= reclen) == 0 || reclen == 0) - db->g_dirp = NULL; - else - /*LINTED*/ - db->g_dirp = (struct dirent *)((char *)db->g_dirp + reclen); - return &(db->g_dic); -} diff --git a/tools/cpio/src/getdir.h b/tools/cpio/src/getdir.h deleted file mode 100644 index 29d107b6f..000000000 --- a/tools/cpio/src/getdir.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)getdir.h 1.4 (gritter) 10/19/03 */ - -#include <sys/types.h> - -struct direc { - unsigned long long d_ino; - char *d_name; -}; - -extern struct getdb *getdb_alloc(const char *, int); -extern void getdb_free(struct getdb *); -extern struct direc *getdir(struct getdb *, int *); diff --git a/tools/cpio/src/getopt.c b/tools/cpio/src/getopt.c deleted file mode 100644 index 0a68ac8e9..000000000 --- a/tools/cpio/src/getopt.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * getopt() - command option parsing - * - * Gunnar Ritter, Freiburg i. Br., Germany, March 2002. - */ - -/* Sccsid @(#)getopt.c 1.6 (gritter) 12/16/07 */ - -#include <sys/types.h> -#include <alloca.h> -#include <string.h> -#include "msgselect.h" - -/* - * One should not think that re-implementing this is necessary, but - * - * - Some libcs print weird messages. - * - * - GNU libc getopt() is totally brain-damaged, as it requires special - * care _not_ to reorder parameters and can't be told to work correctly - * with ':' as first optstring character at all. - */ - -char *optarg = 0; -int optind = 1; -int opterr = 1; -int optopt = 0; -extern char *pfmt_label__; - -static void -error(const char *s, int c) -{ - /* - * Avoid including <unistd.h>, in case its getopt() declaration - * conflicts. - */ - extern ssize_t write(int, const void *, size_t); - const char *msg = 0; - char *buf, *bp; - - if (pfmt_label__) - s = pfmt_label__; - switch (c) { - case '?': - msg = ": " msgselect("I","i") "llegal option -- "; - break; - case ':': - msg = ": " msgselect("O","o") "ption requires an argument -- "; - break; - } - bp = buf = alloca(strlen(s) + strlen(msg) + 2); - while (*s) - *bp++ = *s++; - while (*msg) - *bp++ = *msg++; - *bp++ = optopt; - *bp++ = '\n'; - write(2, buf, bp - buf); -} - -int -getopt(int argc, char *const argv[], const char *optstring) -{ - int colon; - static const char *lastp; - const char *curp; - - if (optstring[0] == ':') { - colon = 1; - optstring++; - } else - colon = 0; - if (lastp) { - curp = lastp; - lastp = 0; - } else { - if (optind >= argc || argv[optind] == 0 || - argv[optind][0] != '-' || - argv[optind][1] == '\0') - return -1; - if (argv[optind][1] == '-' && argv[optind][2] == '\0') { - optind++; - return -1; - } - curp = &argv[optind][1]; - } - optopt = curp[0] & 0377; - while (optstring[0]) { - if (optstring[0] == ':') { - optstring++; - continue; - } - if ((optstring[0] & 0377) == optopt) { - if (optstring[1] == ':') { - if (curp[1] != '\0') { - optarg = (char *)&curp[1]; - optind++; - } else { - if ((optind += 2) > argc) { - if (!colon && opterr) - error(argv[0], ':'); - return colon ? ':' : '?'; - } - optarg = argv[optind - 1]; - } - } else { - if (curp[1] != '\0') - lastp = &curp[1]; - else - optind++; - optarg = 0; - } - return optopt; - } - optstring++; - } - if (!colon && opterr) - error(argv[0], '?'); - if (curp[1] != '\0') - lastp = &curp[1]; - else - optind++; - optarg = 0; - return '?'; -} - -#ifdef __APPLE__ -/* - * Starting with Mac OS 10.5 Leopard, <unistd.h> turns getopt() - * into getopt$UNIX2003() by default. Consequently, this function - * is called instead of the one defined above. However, optind is - * still taken from this file, so in effect, options are not - * properly handled. Defining an own getopt$UNIX2003() function - * works around this issue. - */ -int -getopt$UNIX2003(int argc, char *const argv[], const char *optstring) -{ - return getopt(argc, argv, optstring); -} -#endif /* __APPLE__ */ diff --git a/tools/cpio/src/gmatch.c b/tools/cpio/src/gmatch.c deleted file mode 100644 index a2c5eb7ba..000000000 --- a/tools/cpio/src/gmatch.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Derived from /usr/src/cmd/sh/expand.c, Unix 7th Edition: - * - * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * Redistributions of source code and documentation must retain the - * above copyright notice, this list of conditions and the following - * disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed or owned by Caldera - * International, Inc. - * Neither the name of Caldera International, Inc. nor the names of - * other contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA - * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE - * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4 -#define USED __attribute__ ((used)) -#elif defined __GNUC__ -#define USED __attribute__ ((unused)) -#else -#define USED -#endif -static const char sccsid[] USED = "@(#)gmatch.sl 1.5 (gritter) 5/29/05"; - -#include <stdlib.h> -#include <wchar.h> -#include <limits.h> - -#include "mbtowi.h" - -#define fetch(wc, s, n) ((mb_cur_max > 1 && *(s) & 0200 ? \ - ((n) = mbtowi(&(wc), (s), mb_cur_max), \ - (n) = ((n) > 0 ? (n) : (n) < 0 ? (wc = WEOF, 1) : 1)) :\ - ((wc) = *(s) & 0377, (n) = 1)), (s) += (n), (wc)) - -int -gmatch(const char *s, const char *p) -{ - const char *bs = s; - int mb_cur_max = MB_CUR_MAX; - wint_t c, scc; - int n; - - if (fetch(scc, s, n) == WEOF) - return (0); - switch (fetch(c, p, n)) { - - case '[': { - int ok = 0, excl; - unsigned long lc = ULONG_MAX; - const char *bp; - - if (*p == '!') { - p++; - excl = 1; - } else - excl = 0; - fetch(c, p, n); - bp = p; - while (c != '\0') { - if (c == ']' && p > bp) - return (ok ^ excl ? gmatch(s, p) : 0); - else if (c == '-' && p > bp && *p != ']') { - if (*p == '\\') - p++; - if (fetch(c, p, n) == '\0') - break; - if (lc <= scc && scc <= c) - ok = 1; - } else { - if (c == '\\') { - if (fetch(c, p, n) == '\0') - break; - } - if (scc == (lc = c)) - ok = 1; - } - fetch(c, p, n); - } - return (0); - } - - case '\\': - fetch(c, p, n); - if (c == '\0') - return (0); - /*FALLTHRU*/ - - default: - if (c != scc) - return (0); - /*FALLTHRU*/ - - case '?': - return (scc ? gmatch(s, p) : 0); - - case '*': - if (*p == '\0') - return (1); - s = bs; - while (*s) { - if (gmatch(s, p)) - return (1); - fetch(scc, s, n); - } - return (0); - - case '\0': - return (scc == '\0'); - - case WEOF: - return (0); - - } -} diff --git a/tools/cpio/src/ib_alloc.c b/tools/cpio/src/ib_alloc.c deleted file mode 100644 index 4020940ce..000000000 --- a/tools/cpio/src/ib_alloc.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)ib_alloc.c 1.5 (gritter) 3/12/05 */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <stdlib.h> - -#include "memalign.h" -#include "iblok.h" - -struct iblok * -ib_alloc(int fd, unsigned blksize) -{ - static long pagesize; - struct iblok *ip; - struct stat st; - - if (pagesize == 0) - if ((pagesize = sysconf(_SC_PAGESIZE)) < 0) - pagesize = 4096; - if (blksize == 0) { - if (fstat(fd, &st) < 0) - return NULL; - blksize = st.st_blksize > 0 ? st.st_blksize : 512; - } - if ((ip = calloc(1, sizeof *ip)) == NULL) - return NULL; - if ((ip->ib_blk = memalign(pagesize, blksize)) == NULL) { - free(ip); - return NULL; - } - ip->ib_blksize = blksize; - ip->ib_fd = fd; - ip->ib_mb_cur_max = MB_CUR_MAX; - return ip; -} diff --git a/tools/cpio/src/ib_close.c b/tools/cpio/src/ib_close.c deleted file mode 100644 index 946bb9ef6..000000000 --- a/tools/cpio/src/ib_close.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)ib_close.c 1.2 (gritter) 4/17/03 */ - -#include <unistd.h> - -#include "iblok.h" - -int -ib_close(struct iblok *ip) -{ - int fd; - - fd = ip->ib_fd; - ib_free(ip); - return close(fd); -} diff --git a/tools/cpio/src/ib_free.c b/tools/cpio/src/ib_free.c deleted file mode 100644 index 72143afef..000000000 --- a/tools/cpio/src/ib_free.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)ib_free.c 1.2 (gritter) 4/17/03 */ - -#include <stdlib.h> - -#include "iblok.h" - -void -ib_free(struct iblok *ip) -{ - free(ip->ib_blk); - free(ip); -} diff --git a/tools/cpio/src/ib_getlin.c b/tools/cpio/src/ib_getlin.c deleted file mode 100644 index ddee226b4..000000000 --- a/tools/cpio/src/ib_getlin.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)ib_getlin.c 1.2 (gritter) 4/17/03 */ - -#include <string.h> -#include <stdlib.h> -#include "iblok.h" - -size_t -ib_getlin(struct iblok *ip, char **line, size_t *alcd, - void *(*reallc)(void *, size_t)) -{ - char *nl; - size_t sz, llen = 0, nllen; - - for (;;) { - if (ip->ib_cur >= ip->ib_end) { - if (ip->ib_incompl) { - ip->ib_incompl = 0; - return 0; - } - if (ib_read(ip) == EOF) { - if (llen) { - ip->ib_incompl++; - (*line)[llen] = '\0'; - return llen; - } else - return 0; - } - /* - * ib_read() advances ib_cur since *ib_cur++ gives - * better performance than *++ib_cur for ib_get(). - * Go back again. - */ - ip->ib_cur--; - } - sz = ip->ib_end - ip->ib_cur; - if ((nl = memchr(ip->ib_cur, '\n', sz)) != NULL) { - sz = nl - ip->ib_cur + 1; - if ((nllen = llen + sz + 1) > *alcd) { - *line = reallc(*line, nllen); - *alcd = nllen; - } - memcpy(&(*line)[llen], ip->ib_cur, sz); - (*line)[llen + sz] = '\0'; - ip->ib_cur = nl + 1; - return llen + sz; - } - if ((nllen = llen + sz + 1) > *alcd) { - *line = reallc(*line, nllen); - *alcd = nllen; - } - memcpy(&(*line)[llen], ip->ib_cur, sz); - llen += sz; - ip->ib_cur = ip->ib_end; - } - /*NOTREACHED*/ - return 0; -} diff --git a/tools/cpio/src/ib_getw.c b/tools/cpio/src/ib_getw.c deleted file mode 100644 index b7f2e6762..000000000 --- a/tools/cpio/src/ib_getw.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)ib_getw.c 1.5 (gritter) 7/16/04 */ - -#include <stdlib.h> -#include <string.h> -#include "iblok.h" -#include "mbtowi.h" - -char * -ib_getw(struct iblok *ip, wint_t *wc, int *len) -{ - size_t rest; - int c, i, n; - - i = 0; - rest = ip->ib_mend - ip->ib_mcur; - if (rest && ip->ib_mcur > ip->ib_mbuf) { - do - ip->ib_mbuf[i] = ip->ib_mcur[i]; - while (i++, --rest); - } else if (ip->ib_incompl) { - ip->ib_incompl = 0; - *wc = WEOF; - ip->ib_mend = ip->ib_mcur = NULL; - return NULL; - } - if (i == 0) { - c = ib_get(ip); - if (c == EOF) { - *wc = WEOF; - ip->ib_mend = ip->ib_mcur = NULL; - return NULL; - } - ip->ib_mbuf[i++] = (char)c; - } - if (ip->ib_mbuf[0] & 0200) { - while (ip->ib_mbuf[i-1] != '\n' && i < ip->ib_mb_cur_max && - ip->ib_incompl == 0) { - c = ib_get(ip); - if (c != EOF) - ip->ib_mbuf[i++] = (char)c; - else - ip->ib_incompl = 1; - } - n = mbtowi(wc, ip->ib_mbuf, i); - if (n < 0) { - *len = 1; - *wc = WEOF; - } else if (n == 0) { - *len = 1; - *wc = '\0'; - } else - *len = n; - } else { - *wc = ip->ib_mbuf[0]; - *len = n = 1; - } - ip->ib_mcur = &ip->ib_mbuf[*len]; - ip->ib_mend = &ip->ib_mcur[i - *len]; - return ip->ib_mbuf; -} diff --git a/tools/cpio/src/ib_open.c b/tools/cpio/src/ib_open.c deleted file mode 100644 index 18e09c776..000000000 --- a/tools/cpio/src/ib_open.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)ib_open.c 1.2 (gritter) 4/17/03 */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <stdlib.h> - -#include "iblok.h" - -struct iblok * -ib_open(const char *name, unsigned blksize) -{ - struct iblok *ip; - int fd, err; - - if ((fd = open(name, O_RDONLY)) < 0) - return NULL; - if ((ip = ib_alloc(fd, blksize)) == NULL) { - err = errno; - close(fd); - errno = err; - } - return ip; -} diff --git a/tools/cpio/src/ib_popen.c b/tools/cpio/src/ib_popen.c deleted file mode 100644 index 9aa873042..000000000 --- a/tools/cpio/src/ib_popen.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)ib_popen.c 1.2 (gritter) 4/17/03 */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <stdlib.h> -#include <signal.h> - -#include "iblok.h" - -struct iblok * -ib_popen(const char *cmd, unsigned blksize) -{ - struct iblok *ip; - int fd[2], err; - pid_t pid; - char *shell; - - if (pipe(fd) < 0) - return NULL; - switch (pid = fork()) { - case -1: - return NULL; - case 0: - close(fd[0]); - dup2(fd[1], 1); - close(fd[1]); - if ((shell = getenv("SHELL")) == NULL) - shell = "/bin/sh"; - execl(shell, shell, "-c", cmd, NULL); - _exit(0177); - /*NOTREACHED*/ - } - close(fd[1]); - if ((ip = ib_alloc(fd[0], blksize)) == NULL) { - err = errno; - close(fd[0]); - errno = err; - } - ip->ib_pid = pid; - return ip; -} - -int -ib_pclose(struct iblok *ip) -{ - struct sigaction oldhup, oldint, oldquit, act; - int status; - - close(ip->ib_fd); - act.sa_handler = SIG_IGN; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; - sigaction(SIGHUP, &act, &oldhup); - sigaction(SIGINT, &act, &oldint); - sigaction(SIGQUIT, &act, &oldquit); - while (waitpid(ip->ib_pid, &status, 0) < 0 && errno == EINTR); - sigaction(SIGHUP, &oldhup, NULL); - sigaction(SIGINT, &oldint, NULL); - sigaction(SIGQUIT, &oldquit, NULL); - return status; -} diff --git a/tools/cpio/src/ib_read.c b/tools/cpio/src/ib_read.c deleted file mode 100644 index 3794f3e95..000000000 --- a/tools/cpio/src/ib_read.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)ib_read.c 1.2 (gritter) 4/17/03 */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <stdlib.h> - -#include "iblok.h" - -int -ib_read(struct iblok *ip) -{ - ssize_t sz; - - do { - if ((sz = read(ip->ib_fd, ip->ib_blk, ip->ib_blksize)) > 0) { - ip->ib_endoff += sz; - ip->ib_cur = ip->ib_blk; - ip->ib_end = &ip->ib_blk[sz]; - return *ip->ib_cur++ & 0377; - } - } while (sz < 0 && errno == EINTR); - if (sz < 0) - ip->ib_errno = errno; - ip->ib_cur = ip->ib_end = NULL; - return EOF; -} diff --git a/tools/cpio/src/ib_seek.c b/tools/cpio/src/ib_seek.c deleted file mode 100644 index 48b2f99bc..000000000 --- a/tools/cpio/src/ib_seek.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)ib_seek.c 1.4 (gritter) 5/8/03 */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <stdlib.h> - -#include "iblok.h" - -off_t -ib_seek(struct iblok *ip, off_t off, int whence) -{ - if (whence == SEEK_CUR) { - off = ip->ib_endoff - (ip->ib_end - ip->ib_cur); - whence = SEEK_SET; - } - if (ip->ib_seekable && whence == SEEK_SET && ip->ib_cur && ip->ib_end && - off < ip->ib_endoff && - off >= ip->ib_endoff - (ip->ib_end - ip->ib_blk)) { - ip->ib_cur = ip->ib_end - (ip->ib_endoff - off); - return off; - } - if ((off = lseek(ip->ib_fd, off, whence)) == (off_t)-1) - return -1; - ip->ib_cur = ip->ib_end = NULL; - ip->ib_endoff = off; - ip->ib_seekable = 1; - return off; -} diff --git a/tools/cpio/src/iblok.h b/tools/cpio/src/iblok.h deleted file mode 100644 index 66964627f..000000000 --- a/tools/cpio/src/iblok.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)iblok.h 1.5 (gritter) 7/16/04 */ - -/* - * Functions to read a file sequentially. - */ - -#include <sys/types.h> /* for off_t, pid_t */ -#include <stdio.h> /* for EOF */ -#include <wchar.h> /* for wchar_t */ -#include <limits.h> /* for MB_LEN_MAX */ - -struct iblok { - long long ib_endoff; /* offset of endc from start of file */ - char ib_mbuf[MB_LEN_MAX+1]; /* multibyte overflow buffer */ - char *ib_mcur; /* next byte to read in ib_mbuf */ - char *ib_mend; /* one beyond last byte in ib_mbuf */ - char *ib_blk; /* buffered data */ - char *ib_cur; /* next character in ib_blk */ - char *ib_end; /* one beyond last byte in ib_blk */ - int ib_fd; /* input file descriptor */ - int ib_errno; /* errno on error, or 0 */ - int ib_incompl; /* had an incomplete last line */ - int ib_mb_cur_max; /* MB_CUR_MAX at time of ib_alloc() */ - int ib_seekable; /* had a successful lseek() */ - pid_t ib_pid; /* child from ib_popen() */ - unsigned ib_blksize; /* buffer size */ -}; - -/* - * Allocate an input buffer with file descriptor fd. blksize may be - * either the size of a buffer to allocate in ib_blk, or 0 if the - * size is determined automatically. On error, NULL is returned and - * errno indicates the offending error. - */ -extern struct iblok *ib_alloc(int fd, unsigned blksize); - -/* - * Deallocate the passed input buffer. The file descriptor is not - * closed. - */ -extern void ib_free(struct iblok *ip); - -/* - * Open file name and do ib_alloc() on the descriptor. - */ -extern struct iblok *ib_open(const char *name, unsigned blksize); - -/* - * Close the file descriptor in ip and do ib_free(). Return value is - * the result of close(). - */ -extern int ib_close(struct iblok *ip); - -/* - * A workalike of popen(cmd, "r") using iblok facilities. - */ -extern struct iblok *ib_popen(const char *cmd, unsigned blksize); - -/* - * Close an iblok opened with ib_popen(). - */ -extern int ib_pclose(struct iblok *ip); - -/* - * Read new input buffer. Returns the next character (or EOF) and advances - * ib_cur by one above the bottom of the buffer. - */ -extern int ib_read(struct iblok *ip); - -/* - * Get next character. Return EOF at end-of-file or read error. - */ -#define ib_get(ip) ((ip)->ib_cur < (ip)->ib_end ? *(ip)->ib_cur++ & 0377 :\ - ib_read(ip)) - -/* - * Unget a character. Note that this implementation alters the read buffer. - * Caution: Calling this macro more than once might underflow ib_blk. - */ -#define ib_unget(c, ip) (*(--(ip)->ib_cur) = (char)(c)) - -/* - * Get file offset of last read character. - */ -#define ib_offs(ip) ((ip)->ib_endoff - ((ip)->ib_end - (ip)->ib_cur - 1)) - -/* - * Read a wide character using ib_get() facilities. *wc is used to store - * the wide character, or WEOF if an invalid byte sequence was found. - * The number of bytes consumed is stored in *len. Return value is the - * corresponding byte sequence, or NULL at end-of-file in input. - * - * Note that it is not possible to mix calls to ib_getw() with calls to - * ib_get(), ib_unget() or ib_seek() unless the last character read by - * ib_getw() was L'\n'. - */ -extern char *ib_getw(struct iblok *ip, wint_t *wc, int *len); - -/* - * Get a line from ip, returning the line length. Further arguments are either - * the pointer to a malloc()ed buffer and a pointer to its size, or (NULL, 0) - * if ib_getlin() shall allocate the buffer itselves. ib_getlin() will use - * the realloc-style function reallc() to increase the buffer if necessary; - * this function is expected never to fail (i. e., it must longjmp() or abort - * if it cannot allocate a buffer of the demanded size). - * On end-of-file or error, 0 is returned. - */ -extern size_t ib_getlin(struct iblok *ip, char **line, size_t *alcd, - void *(*reallc)(void *, size_t)); - -/* - * Like lseek(). - */ -extern off_t ib_seek(struct iblok *ip, off_t off, int whence); diff --git a/tools/cpio/src/inflate.c b/tools/cpio/src/inflate.c deleted file mode 100644 index 2c6d3e59f..000000000 --- a/tools/cpio/src/inflate.c +++ /dev/null @@ -1,991 +0,0 @@ -/* - * Changes by Gunnar Ritter, Freiburg i. Br., Germany, May 2003. - * - * Derived from Info-ZIP 5.50. - * - * Sccsid @(#)inflate.c 1.6 (gritter) 10/13/04 - */ -/* -This is version 2002-Feb-16 of the Info-ZIP copyright and license. -The definitive version of this document should be available at -ftp://ftp.info-zip.org/pub/infozip/license.html indefinitely. - - -Copyright (c) 1990-2002 Info-ZIP. All rights reserved. - -For the purposes of this copyright and license, "Info-ZIP" is defined as -the following set of individuals: - - Mark Adler, John Bush, Karl Davis, Harald Denker, Jean-Michel Dubois, - Jean-loup Gailly, Hunter Goatley, Ian Gorman, Chris Herborth, Dirk Haase, - Greg Hartwig, Robert Heath, Jonathan Hudson, Paul Kienitz, David Kirschbaum, - Johnny Lee, Onno van der Linden, Igor Mandrichenko, Steve P. Miller, - Sergio Monesi, Keith Owens, George Petrov, Greg Roelofs, Kai Uwe Rommel, - Steve Salisbury, Dave Smith, Christian Spieler, Antoine Verheijen, - Paul von Behren, Rich Wales, Mike White - -This software is provided "as is," without warranty of any kind, express -or implied. In no event shall Info-ZIP or its contributors be held liable -for any direct, indirect, incidental, special or consequential damages -arising out of the use of or inability to use this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - - 1. Redistributions of source code must retain the above copyright notice, - definition, disclaimer, and this list of conditions. - - 2. Redistributions in binary form (compiled executables) must reproduce - the above copyright notice, definition, disclaimer, and this list of - conditions in documentation and/or other materials provided with the - distribution. The sole exception to this condition is redistribution - of a standard UnZipSFX binary as part of a self-extracting archive; - that is permitted without inclusion of this license, as long as the - normal UnZipSFX banner has not been removed from the binary or disabled. - - 3. Altered versions--including, but not limited to, ports to new operating - systems, existing ports with new graphical interfaces, and dynamic, - shared, or static library versions--must be plainly marked as such - and must not be misrepresented as being the original source. Such - altered versions also must not be misrepresented as being Info-ZIP - releases--including, but not limited to, labeling of the altered - versions with the names "Info-ZIP" (or any variation thereof, including, - but not limited to, different capitalizations), "Pocket UnZip," "WiZ" - or "MacZip" without the explicit permission of Info-ZIP. Such altered - versions are further prohibited from misrepresentative use of the - Zip-Bugs or Info-ZIP e-mail addresses or of the Info-ZIP URL(s). - - 4. Info-ZIP retains the right to use the names "Info-ZIP," "Zip," "UnZip," - "UnZipSFX," "WiZ," "Pocket UnZip," "Pocket Zip," and "MacZip" for its - own source and binary releases. -*/ -/* - Copyright (c) 1990-2002 Info-ZIP. All rights reserved. - - See the accompanying file LICENSE, version 2000-Apr-09 or later - (the contents of which are also included in unzip.h) for terms of use. - If, for some reason, all these files are missing, the Info-ZIP license - also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html -*/ -/* inflate.c -- by Mark Adler - version c17a, 04 Feb 2001 */ - - -/* Copyright history: - - Starting with UnZip 5.41 of 16-April-2000, this source file - is covered by the Info-Zip LICENSE cited above. - - Prior versions of this source file, found in UnZip source packages - up to UnZip 5.40, were put in the public domain. - The original copyright note by Mark Adler was: - "You can do whatever you like with this source file, - though I would prefer that if you modify it and - redistribute it that you include comments to that effect - with your name and the date. Thank you." - - History: - vers date who what - ---- --------- -------------- ------------------------------------ - a ~~ Feb 92 M. Adler used full (large, one-step) lookup table - b1 21 Mar 92 M. Adler first version with partial lookup tables - b2 21 Mar 92 M. Adler fixed bug in fixed-code blocks - b3 22 Mar 92 M. Adler sped up match copies, cleaned up some - b4 25 Mar 92 M. Adler added prototypes; removed window[] (now - is the responsibility of unzip.h--also - changed name to slide[]), so needs diffs - for unzip.c and unzip.h (this allows - compiling in the small model on MSDOS); - fixed cast of q in huft_build(); - b5 26 Mar 92 M. Adler got rid of unintended macro recursion. - b6 27 Mar 92 M. Adler got rid of nextbyte() routine. fixed - bug in inflate_fixed(). - c1 30 Mar 92 M. Adler removed lbits, dbits environment variables. - changed BMAX to 16 for explode. Removed - OUTB usage, and replaced it with flush()-- - this was a 20% speed improvement! Added - an explode.c (to replace unimplod.c) that - uses the huft routines here. Removed - register union. - c2 4 Apr 92 M. Adler fixed bug for file sizes a multiple of 32k. - c3 10 Apr 92 M. Adler reduced memory of code tables made by - huft_build significantly (factor of two to - three). - c4 15 Apr 92 M. Adler added NOMEMCPY do kill use of memcpy(). - worked around a Turbo C optimization bug. - c5 21 Apr 92 M. Adler added the WSIZE #define to allow reducing - the 32K window size for specialized - applications. - c6 31 May 92 M. Adler added some typecasts to eliminate warnings - c7 27 Jun 92 G. Roelofs added some more typecasts (444: MSC bug). - c8 5 Oct 92 J-l. Gailly added ifdef'd code to deal with PKZIP bug. - c9 9 Oct 92 M. Adler removed a memory error message (~line 416). - c10 17 Oct 92 G. Roelofs changed ULONG/UWORD/byte to ulg/ush/uch, - removed old inflate, renamed inflate_entry - to inflate, added Mark's fix to a comment. - c10.5 14 Dec 92 M. Adler fix up error messages for incomplete trees. - c11 2 Jan 93 M. Adler fixed bug in detection of incomplete - tables, and removed assumption that EOB is - the longest code (bad assumption). - c12 3 Jan 93 M. Adler make tables for fixed blocks only once. - c13 5 Jan 93 M. Adler allow all zero length codes (pkzip 2.04c - outputs one zero length code for an empty - distance tree). - c14 12 Mar 93 M. Adler made inflate.c standalone with the - introduction of inflate.h. - c14b 16 Jul 93 G. Roelofs added (unsigned) typecast to w at 470. - c14c 19 Jul 93 J. Bush changed v[N_MAX], l[288], ll[28x+3x] arrays - to static for Amiga. - c14d 13 Aug 93 J-l. Gailly de-complicatified Mark's c[*p++]++ thing. - c14e 8 Oct 93 G. Roelofs changed memset() to memzero(). - c14f 22 Oct 93 G. Roelofs renamed quietflg to qflag; made Trace() - conditional; added inflate_free(). - c14g 28 Oct 93 G. Roelofs changed l/(lx+1) macro to pointer (Cray bug) - c14h 7 Dec 93 C. Ghisler huft_build() optimizations. - c14i 9 Jan 94 A. Verheijen set fixed_t{d,l} to NULL after freeing; - G. Roelofs check NEXTBYTE macro for EOF. - c14j 23 Jan 94 G. Roelofs removed Ghisler "optimizations"; ifdef'd - EOF check. - c14k 27 Feb 94 G. Roelofs added some typecasts to avoid warnings. - c14l 9 Apr 94 G. Roelofs fixed split comments on preprocessor lines - to avoid bug in Encore compiler. - c14m 7 Jul 94 P. Kienitz modified to allow assembler version of - inflate_codes() (define ASM_INFLATECODES) - c14n 22 Jul 94 G. Roelofs changed fprintf to macro for DLL versions - c14o 23 Aug 94 C. Spieler added a newline to a debug statement; - G. Roelofs added another typecast to avoid MSC warning - c14p 4 Oct 94 G. Roelofs added (voidp *) cast to free() argument - c14q 30 Oct 94 G. Roelofs changed fprintf macro to MESSAGE() - c14r 1 Nov 94 G. Roelofs fixed possible redefinition of CHECK_EOF - c14s 7 May 95 S. Maxwell OS/2 DLL globals stuff incorporated; - P. Kienitz "fixed" ASM_INFLATECODES macro/prototype - c14t 18 Aug 95 G. Roelofs added UZinflate() to use zlib functions; - changed voidp to zvoid; moved huft_build() - and huft_free() to end of file - c14u 1 Oct 95 G. Roelofs moved G into definition of MESSAGE macro - c14v 8 Nov 95 P. Kienitz changed ASM_INFLATECODES to use a regular - call with __G__ instead of a macro - c15 3 Aug 96 M. Adler fixed bomb-bug on random input data (Adobe) - c15b 24 Aug 96 M. Adler more fixes for random input data - c15c 28 Mar 97 G. Roelofs changed USE_ZLIB fatal exit code from - PK_MEM2 to PK_MEM3 - c16 20 Apr 97 J. Altman added memzero(v[]) in huft_build() - c16b 29 Mar 98 C. Spieler modified DLL code for slide redirection - c16c 04 Apr 99 C. Spieler fixed memory leaks when processing gets - stopped because of input data errors - c16d 05 Jul 99 C. Spieler take care of FLUSH() return values and - stop processing in case of errors - c17 31 Dec 00 C. Spieler added preliminary support for Deflate64 - c17a 04 Feb 01 C. Spieler complete integration of Deflate64 support - c17b 16 Feb 02 C. Spieler changed type of "extra bits" arrays and - corresponding huft_buid() parameter e from - ush into uch, to save space - */ - - -/* - Inflate deflated (PKZIP's method 8 compressed) data. The compression - method searches for as much of the current string of bytes (up to a - length of 258) in the previous 32K bytes. If it doesn't find any - matches (of at least length 3), it codes the next byte. Otherwise, it - codes the length of the matched string and its distance backwards from - the current position. There is a single Huffman code that codes both - single bytes (called "literals") and match lengths. A second Huffman - code codes the distance information, which follows a length code. Each - length or distance code actually represents a base value and a number - of "extra" (sometimes zero) bits to get to add to the base value. At - the end of each deflated block is a special end-of-block (EOB) literal/ - length code. The decoding process is basically: get a literal/length - code; if EOB then done; if a literal, emit the decoded byte; if a - length then get the distance and emit the referred-to bytes from the - sliding window of previously emitted data. - - There are (currently) three kinds of inflate blocks: stored, fixed, and - dynamic. The compressor outputs a chunk of data at a time and decides - which method to use on a chunk-by-chunk basis. A chunk might typically - be 32K to 64K, uncompressed. If the chunk is uncompressible, then the - "stored" method is used. In this case, the bytes are simply stored as - is, eight bits per byte, with none of the above coding. The bytes are - preceded by a count, since there is no longer an EOB code. - - If the data are compressible, then either the fixed or dynamic methods - are used. In the dynamic method, the compressed data are preceded by - an encoding of the literal/length and distance Huffman codes that are - to be used to decode this block. The representation is itself Huffman - coded, and so is preceded by a description of that code. These code - descriptions take up a little space, and so for small blocks, there is - a predefined set of codes, called the fixed codes. The fixed method is - used if the block ends up smaller that way (usually for quite small - chunks); otherwise the dynamic method is used. In the latter case, the - codes are customized to the probabilities in the current block and so - can code it much better than the pre-determined fixed codes can. - - The Huffman codes themselves are decoded using a multi-level table - lookup, in order to maximize the speed of decoding plus the speed of - building the decoding tables. See the comments below that precede the - lbits and dbits tuning parameters. - - GRR: return values(?) - 0 OK - 1 incomplete table - 2 bad input - 3 not enough memory - the following return codes are passed through from FLUSH() errors - 50 (PK_DISK) "overflow of output space" - 80 (IZ_CTRLC) "canceled by user's request" - */ - - -/* - Notes beyond the 1.93a appnote.txt: - - 1. Distance pointers never point before the beginning of the output - stream. - 2. Distance pointers can point back across blocks, up to 32k away. - 3. There is an implied maximum of 7 bits for the bit length table and - 15 bits for the actual data. - 4. If only one code exists, then it is encoded using one bit. (Zero - would be more efficient, but perhaps a little confusing.) If two - codes exist, they are coded using one bit each (0 and 1). - 5. There is no way of sending zero distance codes--a dummy must be - sent if there are none. (History: a pre 2.0 version of PKZIP would - store blocks with no distance codes, but this was discovered to be - too harsh a criterion.) Valid only for 1.93a. 2.04c does allow - zero distance codes, which is sent as one code of zero bits in - length. - 6. There are up to 286 literal/length codes. Code 256 represents the - end-of-block. Note however that the static length tree defines - 288 codes just to fill out the Huffman codes. Codes 286 and 287 - cannot be used though, since there is no length base or extra bits - defined for them. Similarily, there are up to 30 distance codes. - However, static trees define 32 codes (all 5 bits) to fill out the - Huffman codes, but the last two had better not show up in the data. - 7. Unzip can check dynamic Huffman blocks for complete code sets. - The exception is that a single code would not be complete (see #4). - 8. The five bits following the block type is really the number of - literal codes sent minus 257. - 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits - (1+6+6). Therefore, to output three times the length, you output - three codes (1+1+1), whereas to output four times the same length, - you only need two codes (1+3). Hmm. - 10. In the tree reconstruction algorithm, Code = Code + Increment - only if BitLength(i) is not zero. (Pretty obvious.) - 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) - 12. Note: length code 284 can represent 227-258, but length code 285 - really is 258. The last length deserves its own, short code - since it gets used a lot in very redundant files. The length - 258 is special since 258 - 3 (the min match length) is 255. - 13. The literal/length and distance code bit lengths are read as a - single stream of lengths. It is possible (and advantageous) for - a repeat code (16, 17, or 18) to go across the boundary between - the two sets of lengths. - 14. The Deflate64 (PKZIP method 9) variant of the compression algorithm - differs from "classic" deflate in the following 3 aspect: - a) The size of the sliding history window is expanded to 64 kByte. - b) The previously unused distance codes #30 and #31 code distances - from 32769 to 49152 and 49153 to 65536. Both codes take 14 bits - of extra data to determine the exact position in their 16 kByte - range. - c) The last lit/length code #285 gets a different meaning. Instead - of coding a fixed maximum match length of 258, it is used as a - "generic" match length code, capable of coding any length from - 3 (min match length + 0) to 65538 (min match length + 65535). - This means that the length code #285 takes 16 bits (!) of uncoded - extra data, added to a fixed min length of 3. - Changes a) and b) would have been transparent for valid deflated - data, but change c) requires to switch decoder configurations between - Deflate and Deflate64 modes. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include "cpio.h" -#include "unzip.h" - -/* - inflate.h must supply the uch slide[WSIZE] array, the zvoid typedef - (void if (void *) is accepted, else char) and the NEXTBYTE, - FLUSH() and memzero macros. If the window size is not 32K, it - should also define WSIZE. If INFMOD is defined, it can include - compiled functions to support the NEXTBYTE and/or FLUSH() macros. - There are defaults for NEXTBYTE and FLUSH() below for use as - examples of what those functions need to do. Normally, you would - also want FLUSH() to compute a crc on the data. inflate.h also - needs to provide these typedefs: - - typedef unsigned char uch; - typedef unsigned short ush; - typedef unsigned long ulg; - - This module uses the external functions malloc() and free() (and - probably memset() or bzero() in the memzero() macro). Their - prototypes are normally found in <string.h> and <stdlib.h>. - */ - -/* marker for "unused" huft code, and corresponding check macro */ -#define INVALID_CODE 99 -#define IS_INVALID_CODE(c) ((c) == INVALID_CODE) - -static int inflate_codes(struct globals *Gp, - struct huft *tl, struct huft *td, - int bl, int bd); -static int inflate_stored(struct globals *Gp); -static int inflate_fixed(struct globals *Gp); -static int inflate_dynamic(struct globals *Gp); -static int inflate_block(struct globals *Gp, int *e); - -#define FLUSH(n) (flush(&G, redirSlide, (n)), 0) - -/* The inflate algorithm uses a sliding 32K byte window on the uncompressed - stream to find repeated byte strings. This is implemented here as a - circular buffer. The index is updated simply by incrementing and then - and'ing with 0x7fff (32K-1). */ -/* It is left to other modules to supply the 32K area. It is assumed - to be usable as if it were declared "uch slide[32768];" or as just - "uch *slide;" and then malloc'ed in the latter case. The definition - must be in unzip.h, included above. */ - - -/* Tables for deflate from PKZIP's appnote.txt. */ -/* - Order of the bit length code lengths */ -static const unsigned border[] = { - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - -/* - Copy lengths for literal codes 257..285 */ -static const uint16_t cplens64[] = { - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 3, 0, 0}; - /* For Deflate64, the code 285 is defined differently. */ -static const uint16_t cplens32[] = { - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - /* note: see note #13 above about the 258 in this list. */ -/* - Extra bits for literal codes 257..285 */ -static const uint8_t cplext64[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 16, INVALID_CODE, INVALID_CODE}; -static const uint8_t cplext32[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, INVALID_CODE, INVALID_CODE}; - -/* - Copy offsets for distance codes 0..29 (0..31 for Deflate64) */ -static const uint16_t cpdist[] = { - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 32769, 49153}; - -/* - Extra bits for distance codes 0..29 (0..31 for Deflate64) */ -static const uint8_t cpdext64[] = { - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, - 12, 12, 13, 13, 14, 14}; -static const uint8_t cpdext32[] = { - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, - 12, 12, 13, 13, INVALID_CODE, INVALID_CODE}; - -# define MAXLITLENS 288 -# define MAXDISTS 32 - -/* Macros for inflate() bit peeking and grabbing. - The usage is: - - NEEDBITS(j) - x = b & mask_bits[j]; - DUMPBITS(j) - - where NEEDBITS makes sure that b has at least j bits in it, and - DUMPBITS removes the bits from b. The macros use the variable k - for the number of bits in b. Normally, b and k are register - variables for speed and are initialized at the begining of a - routine that uses these macros from a global bit buffer and count. - - In order to not ask for more bits than there are in the compressed - stream, the Huffman tables are constructed to only ask for just - enough bits to make up the end-of-block code (value 256). Then no - bytes need to be "returned" to the buffer at the end of the last - block. See the huft_build() routine. - */ - -# define NEEDBITS(n) {while(k<(n)){int c=NEXTBYTE;\ - if(c==EOF){retval=1;goto cleanup_and_exit;}\ - b|=((uint32_t)c)<<k;k+=8;}} - -#define DUMPBITS(n) {b>>=(n);k-=(n);} - -#define Bits 32 -#define Nob 32 -#define Eob 31 - -/* - Huffman code decoding is performed using a multi-level table lookup. - The fastest way to decode is to simply build a lookup table whose - size is determined by the longest code. However, the time it takes - to build this table can also be a factor if the data being decoded - are not very long. The most common codes are necessarily the - shortest codes, so those codes dominate the decoding time, and hence - the speed. The idea is you can have a shorter table that decodes the - shorter, more probable codes, and then point to subsidiary tables for - the longer codes. The time it costs to decode the longer codes is - then traded against the time it takes to make longer tables. - - This results of this trade are in the variables lbits and dbits - below. lbits is the number of bits the first level table for literal/ - length codes can decode in one step, and dbits is the same thing for - the distance codes. Subsequent tables are also less than or equal to - those sizes. These values may be adjusted either when all of the - codes are shorter than that, in which case the longest code length in - bits is used, or when the shortest code is *longer* than the requested - table size, in which case the length of the shortest code in bits is - used. - - There are two different values for the two tables, since they code a - different number of possibilities each. The literal/length table - codes 286 possible values, or in a flat code, a little over eight - bits. The distance table codes 30 possible values, or a little less - than five bits, flat. The optimum values for speed end up being - about one bit more than those, so lbits is 8+1 and dbits is 5+1. - The optimum values may differ though from machine to machine, and - possibly even between compilers. Your mileage may vary. - */ - - -static const int lbits = 9; /* bits in base literal/length lookup table */ -static const int dbits = 6; /* bits in base distance lookup table */ - -#define G (*Gp) - -static int -inflate_codes(struct globals *Gp, - struct huft *tl, struct huft *td, int bl, int bd) -/*struct huft *tl, *td;*/ /* literal/length and distance decoder tables */ -/*int bl, bd;*/ /* number of bits decoded by tl[] and td[] */ -/* inflate (decompress) the codes in a deflated (compressed) block. - Return an error code or zero if it all goes ok. */ -{ - register unsigned e; /* table entry flag/number of extra bits */ - unsigned d; /* index for copy */ - uint32_t n; /* length for copy (deflate64: might be 64k+2) */ - uint32_t w; /* current window position (deflate64: up to 64k) */ - struct huft *t; /* pointer to table entry */ - unsigned ml, md; /* masks for bl and bd bits */ - register uint32_t b; /* bit buffer */ - register unsigned k; /* number of bits in bit buffer */ - int retval = 0; /* error code returned: initialized to "no error" */ - - - /* make local copies of globals */ - b = G.bb; /* initialize bit buffer */ - k = G.bk; - w = G.wp; /* initialize window position */ - - - /* inflate the coded data */ - ml = mask_bits[bl]; /* precompute masks for speed */ - md = mask_bits[bd]; - while (1) /* do until end of block */ - { - NEEDBITS((unsigned)bl) - t = tl + ((unsigned)b & ml); - while (1) { - DUMPBITS(t->b) - - if ((e = t->e) == 32) /* then it's a literal */ - { - redirSlide[w++] = (uint8_t)t->v.n; - if (w == WSIZE) - { - if ((retval = FLUSH(w)) != 0) goto cleanup_and_exit; - w = 0; - } - break; - } - - if (e < 31) /* then it's a length */ - { - /* get length of block to copy */ - NEEDBITS(e) - n = t->v.n + ((unsigned)b & mask_bits[e]); - DUMPBITS(e) - - /* decode distance of block to copy */ - NEEDBITS((unsigned)bd) - t = td + ((unsigned)b & md); - while (1) { - DUMPBITS(t->b) - if ((e = t->e) < 32) - break; - if (IS_INVALID_CODE(e)) - return 1; - e &= 31; - NEEDBITS(e) - t = t->v.t + ((unsigned)b & mask_bits[e]); - } - NEEDBITS(e) - d = (unsigned)w - t->v.n - ((unsigned)b & mask_bits[e]); - DUMPBITS(e) - - /* do the copy */ - do { - e = (unsigned)(WSIZE - - ((d &= (unsigned)(WSIZE-1)) > (unsigned)w ? - (uint32_t)d : w)); - if ((uint32_t)e > n) e = (unsigned)n; - n -= e; -#ifndef NOMEMCPY - if ((unsigned)w - d >= e) - /* (this test assumes unsigned comparison) */ - { - memcpy(redirSlide + (unsigned)w, redirSlide + d, e); - w += e; - d += e; - } - else /* do it slowly to avoid memcpy() overlap */ -#endif /* !NOMEMCPY */ - do { - redirSlide[w++] = redirSlide[d++]; - } while (--e); - if (w == WSIZE) - { - if ((retval = FLUSH(w)) != 0) goto cleanup_and_exit; - w = 0; - } - } while (n); - break; - } - - if (e == 31) /* it's the EOB signal */ - { - /* sorry for this goto, but we have to exit two loops at once */ - goto cleanup_decode; - } - - if (IS_INVALID_CODE(e)) - return 1; - - e &= 31; - NEEDBITS(e) - t = t->v.t + ((unsigned)b & mask_bits[e]); - } - } -cleanup_decode: - - /* restore the globals from the locals */ - G.wp = (unsigned)w; /* restore global window pointer */ - G.bb = b; /* restore global bit buffer */ - G.bk = k; - - -cleanup_and_exit: - /* done */ - return retval; -} - -static int -inflate_stored(struct globals *Gp) -/* "decompress" an inflated type 0 (stored) block. */ -{ - uint32_t w; /* current window position (deflate64: up to 64k!) */ - unsigned n; /* number of bytes in block */ - register uint32_t b; /* bit buffer */ - register unsigned k; /* number of bits in bit buffer */ - int retval = 0; /* error code returned: initialized to "no error" */ - - - /* make local copies of globals */ - Trace((stderr, "\nstored block")); - b = G.bb; /* initialize bit buffer */ - k = G.bk; - w = G.wp; /* initialize window position */ - - - /* go to byte boundary */ - n = k & 7; - DUMPBITS(n); - - - /* get the length and its complement */ - NEEDBITS(16) - n = ((unsigned)b & 0xffff); - DUMPBITS(16) - NEEDBITS(16) - if (n != (unsigned)((~b) & 0xffff)) - return 1; /* error in compressed data */ - DUMPBITS(16) - - - /* read and output the compressed data */ - while (n--) - { - NEEDBITS(8) - redirSlide[w++] = (uint8_t)b; - if (w == WSIZE) - { - if ((retval = FLUSH(w)) != 0) goto cleanup_and_exit; - w = 0; - } - DUMPBITS(8) - } - - - /* restore the globals from the locals */ - G.wp = (unsigned)w; /* restore global window pointer */ - G.bb = b; /* restore global bit buffer */ - G.bk = k; - -cleanup_and_exit: - return retval; -} - - -static int -inflate_fixed(struct globals *Gp) -/* decompress an inflated type 1 (fixed Huffman codes) block. We should - either replace this with a custom decoder, or at least precompute the - Huffman tables. */ -{ - /* if first time, set up tables for fixed blocks */ - Trace((stderr, "\nliteral block")); - if (G.fixed_tl == NULL) - { - int i; /* temporary variable */ - unsigned l[288]; /* length list for huft_build */ - - /* literal table */ - for (i = 0; i < 144; i++) - l[i] = 8; - for (; i < 256; i++) - l[i] = 9; - for (; i < 280; i++) - l[i] = 7; - for (; i < 288; i++) /* make a complete, but wrong code set */ - l[i] = 8; - G.fixed_bl = 7; - if ((i = huft_build(l, 288, 257, G.cplens, G.cplext, - &G.fixed_tl, &G.fixed_bl, - Bits, Nob, Eob)) != 0) - { - G.fixed_tl = NULL; - return i; - } - - /* distance table */ - for (i = 0; i < MAXDISTS; i++) /* make an incomplete code set */ - l[i] = 5; - G.fixed_bd = 5; - if ((i = huft_build(l, MAXDISTS, 0, cpdist, G.cpdext, - &G.fixed_td, &G.fixed_bd, - Bits, Nob, Eob)) > 1) - { - huft_free(G.fixed_tl); - G.fixed_td = G.fixed_tl = NULL; - return i; - } - } - - /* decompress until an end-of-block code */ - return inflate_codes(&G, G.fixed_tl, G.fixed_td, - G.fixed_bl, G.fixed_bd); -} - - - -static int inflate_dynamic(struct globals *Gp) -/* decompress an inflated type 2 (dynamic Huffman codes) block. */ -{ - int i; /* temporary variables */ - unsigned j; - unsigned l; /* last length */ - unsigned m; /* mask for bit lengths table */ - unsigned n; /* number of lengths to get */ - struct huft *tl; /* literal/length code table */ - struct huft *td; /* distance code table */ - int bl; /* lookup bits for tl */ - int bd; /* lookup bits for td */ - unsigned nb; /* number of bit length codes */ - unsigned nl; /* number of literal/length codes */ - unsigned nd; /* number of distance codes */ - unsigned ll[MAXLITLENS+MAXDISTS]; /* lit./length and distance code lengths */ - register uint32_t b; /* bit buffer */ - register unsigned k; /* number of bits in bit buffer */ - int retval = 0; /* error code returned: initialized to "no error" */ - - - /* make local bit buffer */ - Trace((stderr, "\ndynamic block")); - b = G.bb; - k = G.bk; - - - /* read in table lengths */ - NEEDBITS(5) - nl = 257 + ((unsigned)b & 0x1f); /* number of literal/length codes */ - DUMPBITS(5) - NEEDBITS(5) - nd = 1 + ((unsigned)b & 0x1f); /* number of distance codes */ - DUMPBITS(5) - NEEDBITS(4) - nb = 4 + ((unsigned)b & 0xf); /* number of bit length codes */ - DUMPBITS(4) - if (nl > MAXLITLENS || nd > MAXDISTS) - return 1; /* bad lengths */ - - - /* read in bit-length-code lengths */ - for (j = 0; j < nb; j++) - { - NEEDBITS(3) - ll[border[j]] = (unsigned)b & 7; - DUMPBITS(3) - } - for (; j < 19; j++) - ll[border[j]] = 0; - - - /* build decoding table for trees--single level, 7 bit lookup */ - bl = 7; - retval = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl, - Bits, Nob, Eob); - if (bl == 0) /* no bit lengths */ - retval = 1; - if (retval) - { - if (retval == 1) - huft_free(tl); - return retval; /* incomplete code set */ - } - - - /* read in literal and distance code lengths */ - n = nl + nd; - m = mask_bits[bl]; - i = l = 0; - while ((unsigned)i < n) - { - NEEDBITS((unsigned)bl) - j = (td = tl + ((unsigned)b & m))->b; - DUMPBITS(j) - j = td->v.n; - if (j < 16) /* length of code in bits (0..15) */ - ll[i++] = l = j; /* save last length in l */ - else if (j == 16) /* repeat last length 3 to 6 times */ - { - NEEDBITS(2) - j = 3 + ((unsigned)b & 3); - DUMPBITS(2) - if ((unsigned)i + j > n) - return 1; - while (j--) - ll[i++] = l; - } - else if (j == 17) /* 3 to 10 zero length codes */ - { - NEEDBITS(3) - j = 3 + ((unsigned)b & 7); - DUMPBITS(3) - if ((unsigned)i + j > n) - return 1; - while (j--) - ll[i++] = 0; - l = 0; - } - else /* j == 18: 11 to 138 zero length codes */ - { - NEEDBITS(7) - j = 11 + ((unsigned)b & 0x7f); - DUMPBITS(7) - if ((unsigned)i + j > n) - return 1; - while (j--) - ll[i++] = 0; - l = 0; - } - } - - - /* free decoding table for trees */ - huft_free(tl); - - - /* restore the global bit buffer */ - G.bb = b; - G.bk = k; - - - /* build the decoding tables for literal/length and distance codes */ - bl = lbits; - retval = huft_build(ll, nl, 257, G.cplens, G.cplext, &tl, &bl, - Bits, Nob, Eob); - if (bl == 0) /* no literals or lengths */ - retval = 1; - if (retval) - { - if (retval == 1) { - /*if (!uO.qflag) - MESSAGE((uint8_t *)"(incomplete l-tree) ", 21L, 1);*/ - huft_free(tl); - } - return retval; /* incomplete code set */ - } - bd = dbits; - retval = huft_build(ll + nl, nd, 0, cpdist, G.cpdext, &td, &bd, - Bits, Nob, Eob); - if (retval == 1) - retval = 0; - if (bd == 0 && nl > 257) /* lengths but no distances */ - retval = 1; - if (retval) - { - if (retval == 1) { - /*if (!uO.qflag) - MESSAGE((uint8_t *)"(incomplete d-tree) ", 21L, 1);*/ - huft_free(td); - } - huft_free(tl); - return retval; - } - - /* decompress until an end-of-block code */ - retval = inflate_codes(&G, tl, td, bl, bd); - -cleanup_and_exit: - /* free the decoding tables, return */ - huft_free(tl); - huft_free(td); - return retval; -} - - - -static int inflate_block(struct globals *Gp, int *e) -/*int *e;*/ /* last block flag */ -/* decompress an inflated block */ -{ - unsigned t; /* block type */ - register uint32_t b; /* bit buffer */ - register unsigned k; /* number of bits in bit buffer */ - int retval = 0; /* error code returned: initialized to "no error" */ - - - /* make local bit buffer */ - b = G.bb; - k = G.bk; - - - /* read in last block bit */ - NEEDBITS(1) - *e = (int)b & 1; - DUMPBITS(1) - - - /* read in block type */ - NEEDBITS(2) - t = (unsigned)b & 3; - DUMPBITS(2) - - - /* restore the global bit buffer */ - G.bb = b; - G.bk = k; - - - /* inflate that block type */ - if (t == 2) - return inflate_dynamic(&G); - if (t == 0) - return inflate_stored(&G); - if (t == 1) - return inflate_fixed(&G); - - - /* bad block type */ - retval = 2; - -cleanup_and_exit: - return retval; -} - -#undef G - -int -zipinflate(struct file *f, const char *tgt, int tfd, int doswap, uint32_t *crc) -/* decompress an inflated entry */ -{ - struct globals G; - int e = 0; /* last block flag */ - int r; /* result code */ - int is_defl64; -#ifdef DEBUG - unsigned h = 0; /* maximum struct huft's malloc'ed */ -#endif - - is_defl64 = f->f_cmethod == C_ENHDEFLD; - memset(&G, 0, sizeof G); - G.tgt = tgt; - G.tfd = tfd; - G.doswap = doswap; - G.crc = crc; - G.zsize = G.uzsize = f->f_csize; - G.ucsize = f->f_st.st_size; - /* initialize window, bit buffer */ - G.wp = 0; - G.bk = 0; - G.bb = 0; - - if (is_defl64) { - G.cplens = cplens64; - G.cplext = cplext64; - G.cpdext = cpdext64; - G.fixed_tl = G.fixed_tl64; - G.fixed_bl = G.fixed_bl64; - G.fixed_td = G.fixed_td64; - G.fixed_bd = G.fixed_bd64; - } else { - G.cplens = cplens32; - G.cplext = cplext32; - G.cpdext = cpdext32; - G.fixed_tl = G.fixed_tl32; - G.fixed_bl = G.fixed_bl32; - G.fixed_td = G.fixed_td32; - G.fixed_bd = G.fixed_bd32; - } - - /* decompress until the last block */ - do { -#ifdef DEBUG - G.hufts = 0; -#endif - if ((r = inflate_block(&G, &e)) != 0) { - if ((f->f_gflag & FG_DESC) == 0) - while (G.uzsize > 0) - NEXTBYTE; - msg(3, 0, "compression error on \"%s\"\n", f->f_name); - return -1; - } -#ifdef DEBUG - if (G.hufts > h) - h = G.hufts; -#endif - } while (!e); - - Trace((stderr, "\n%u bytes in Huffman tables (%u/entry)\n", - h * (unsigned)sizeof(struct huft), (unsigned)sizeof(struct huft))); - - if (is_defl64) { - G.fixed_tl64 = G.fixed_tl; - G.fixed_bl64 = G.fixed_bl; - G.fixed_td64 = G.fixed_td; - G.fixed_bd64 = G.fixed_bd; - } else { - G.fixed_tl32 = G.fixed_tl; - G.fixed_bl32 = G.fixed_bl; - G.fixed_td32 = G.fixed_td; - G.fixed_bd32 = G.fixed_bd; - } - - /* flush out redirSlide and return (success, unless final FLUSH failed) */ - (FLUSH(G.wp)); - if (f->f_gflag & FG_DESC) - bunread((char *)G.inptr, G.incnt); - return G.status; -} diff --git a/tools/cpio/src/mbtowi.h b/tools/cpio/src/mbtowi.h deleted file mode 100644 index 525ad08d1..000000000 --- a/tools/cpio/src/mbtowi.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Sccsid @(#)mbtowi.h 1.2 (gritter) 7/16/04 */ - -#ifndef LIBCOMMON_MBTOWI_H -#define LIBCOMMON_MBTOWI_H - -static -#if defined (__GNUC__) || defined (__USLC__) || defined (__INTEL_COMPILER) || \ - defined (__IBMC__) || defined (__SUNPRO_C) - inline -#endif - int -mbtowi(wint_t *pwi, const char *s, size_t n) -{ - wchar_t wc; - int i; - - i = mbtowc(&wc, s, n); - *pwi = wc; - return i; -} - -#endif /* !LIBCOMMON_MBTOWI_H */ diff --git a/tools/cpio/src/memalign.c b/tools/cpio/src/memalign.c deleted file mode 100644 index 268949b20..000000000 --- a/tools/cpio/src/memalign.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)memalign.c 1.7 (gritter) 1/22/06 */ - -#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (_AIX) || \ - defined (__NetBSD__) || defined (__OpenBSD__) || \ - defined (__DragonFly__) || defined (__APPLE__) -/* - * FreeBSD malloc(3) promises to page-align the return of malloc() calls - * if size is at least a page. This serves for a poor man's memalign() - * implementation that matches our needs. - */ -#include <unistd.h> -#include <stdlib.h> - -#include "memalign.h" - -void * -memalign(size_t alignment, size_t size) -{ - static long pagesize; - - if (pagesize == 0) - pagesize = sysconf(_SC_PAGESIZE); - if (alignment != pagesize) - return NULL; - if (size < pagesize) - size = pagesize; - return malloc(size); -} -#endif /* __FreeBSD__ || __dietlibc__ || _AIX || __NetBSD__ || __OpenBSD__ || - __DragonFly__ || __APPLE__ */ diff --git a/tools/cpio/src/memalign.h b/tools/cpio/src/memalign.h deleted file mode 100644 index edaef031b..000000000 --- a/tools/cpio/src/memalign.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)memalign.h 1.7 (gritter) 1/22/06 */ - -#ifndef LIBCOMMON_MEMALIGN_H -#define LIBCOMMON_MEMALIGN_H - -#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (_AIX) || \ - defined (__NetBSD__) || defined (__OpenBSD__) || \ - defined (__DragonFly__) || defined (__APPLE__) -#include <stdlib.h> - -extern void *memalign(size_t, size_t); -#endif /* __FreeBSD__ || __dietlibc__ || _AIX || __NetBSD__ || __OpenBSD__ || - __DragonFly__ || __APPLE__ */ -#endif /* !LIBCOMMON_MEMALIGN_H */ diff --git a/tools/cpio/src/msgselect.h b/tools/cpio/src/msgselect.h deleted file mode 100644 index 94a5daa9f..000000000 --- a/tools/cpio/src/msgselect.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)msgselect.h 1.2 (gritter) 9/21/03 */ - -#define MSG_LEVEL 0 - -#if MSG_LEVEL == 1 -#define msgselect(a, b) a -#else -#define msgselect(a, b) b -#endif diff --git a/tools/cpio/src/nonpax.c b/tools/cpio/src/nonpax.c deleted file mode 100644 index d0eb585b7..000000000 --- a/tools/cpio/src/nonpax.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * cpio - copy file archives in and out - * - * Gunnar Ritter, Freiburg i. Br., Germany, April 2003. - */ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ - -/* Sccsid @(#)nonpax.c 1.1 (gritter) 2/24/04 */ - -#include "cpio.h" - -/*ARGSUSED*/ -int -pax_track(const char *name, time_t mtime) -{ - return 1; -} - -/*ARGSUSED*/ -void -pax_prlink(struct file *f) -{ -} - -/*ARGSUSED*/ -int -pax_sname(char **oldp, size_t *olds) -{ - return 1; -} - -void -pax_onexit(void) -{ -} diff --git a/tools/cpio/src/oblok.c b/tools/cpio/src/oblok.c deleted file mode 100644 index 38859ba6d..000000000 --- a/tools/cpio/src/oblok.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)oblok.c 1.7 (gritter) 7/16/04 */ - -#include <sys/types.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <malloc.h> - -#include "memalign.h" -#include "oblok.h" - -struct list { - struct list *l_nxt; - struct oblok *l_op; -}; - -static struct list *bloks; -static int exitset; - -int -ob_clear(void) -{ - struct list *lp; - int val = 0; - - for (lp = bloks; lp; lp = lp->l_nxt) { - if (ob_flush(lp->l_op) < 0) - val = -1; - else if (val >= 0) - val++; - } - return val; -} - -static void -add(struct oblok *op) -{ - struct list *lp, *lq; - - if ((lp = calloc(1, sizeof *lp)) != NULL) { - lp->l_nxt = NULL; - lp->l_op = op; - if (bloks) { - for (lq = bloks; lq->l_nxt; lq = lq->l_nxt); - lq->l_nxt = lp; - } else - bloks = lp; - if (exitset == 0) { - exitset = 1; - atexit((void (*)(void))ob_clear); - } - } -} - -static void -del(struct oblok *op) -{ - struct list *lp, *lq = NULL; - - if (bloks) { - for (lp = bloks; lp && lp->l_op != op; lp = lp->l_nxt) - lq = lp; - if (lp) { - if (lq) - lq->l_nxt = lp->l_nxt; - if (lp == bloks) - bloks = bloks->l_nxt; - free(lp); - } - } -} - -struct oblok * -ob_alloc(int fd, enum ob_mode bf) -{ - static long pagesize; - struct oblok *op; - - if (pagesize == 0) - if ((pagesize = sysconf(_SC_PAGESIZE)) < 0) - pagesize = 4096; - if ((op = memalign(pagesize, sizeof *op)) == NULL) - return NULL; - memset(op, 0, sizeof *op); - op->ob_fd = fd; - switch (bf) { - case OB_EBF: - op->ob_bf = isatty(fd) ? OB_LBF : OB_FBF; - break; - default: - op->ob_bf = bf; - } - add(op); - return op; -} - -ssize_t -ob_free(struct oblok *op) -{ - ssize_t wrt; - - wrt = ob_flush(op); - del(op); - free(op); - return wrt; -} - -static ssize_t -swrite(int fd, const char *data, size_t sz) -{ - ssize_t wo, wt = 0; - - do { - if ((wo = write(fd, data + wt, sz - wt)) < 0) { - if (errno == EINTR) - continue; - else - return wt; - } - wt += wo; - } while (wt < sz); - return sz; -} - -ssize_t -ob_write(struct oblok *op, const char *data, size_t sz) -{ - ssize_t wrt; - size_t di, isz; - - switch (op->ob_bf) { - case OB_NBF: - wrt = swrite(op->ob_fd, data, sz); - op->ob_wrt += wrt; - if (wrt != sz) { - op->ob_bf = OB_EBF; - writerr(op, sz, wrt>0?wrt:0); - return -1; - } - return wrt; - case OB_LBF: - case OB_FBF: - isz = sz; - while (op->ob_pos + sz > (OBLOK)) { - di = (OBLOK) - op->ob_pos; - sz -= di; - if (op->ob_pos > 0) { - memcpy(&op->ob_blk[op->ob_pos], data, di); - wrt = swrite(op->ob_fd, op->ob_blk, (OBLOK)); - } else - wrt = swrite(op->ob_fd, data, (OBLOK)); - op->ob_wrt += wrt; - if (wrt != (OBLOK)) { - op->ob_bf = OB_EBF; - writerr(op, (OBLOK), wrt>0?wrt:0); - return -1; - } - data += di; - op->ob_pos = 0; - } - if (op->ob_bf == OB_LBF) { - const char *cp; - - cp = data; - while (cp < &data[sz]) { - if (*cp == '\n') { - di = cp - data + 1; - sz -= di; - if (op->ob_pos > 0) { - memcpy(&op->ob_blk[op->ob_pos], - data, di); - wrt = swrite(op->ob_fd, - op->ob_blk, - op->ob_pos + di); - } else - wrt = swrite(op->ob_fd, - data, di); - op->ob_wrt += wrt; - if (wrt != op->ob_pos + di) { - op->ob_bf = OB_EBF; - writerr(op, di, wrt>0?wrt:0); - return -1; - } - op->ob_pos = 0; - data += di; - cp = data; - } - cp++; - } - } - if (sz == (OBLOK)) { - wrt = swrite(op->ob_fd, data, sz); - op->ob_wrt += wrt; - if (wrt != sz) { - op->ob_bf = OB_EBF; - writerr(op, sz, wrt>0?wrt:0); - return -1; - } - } else if (sz) { - memcpy(&op->ob_blk[op->ob_pos], data, sz); - op->ob_pos += sz; - } - return isz; - case OB_EBF: - ; - } - return -1; -} - -ssize_t -ob_flush(struct oblok *op) -{ - ssize_t wrt = 0; - - if (op->ob_pos) { - wrt = swrite(op->ob_fd, op->ob_blk, op->ob_pos); - op->ob_wrt += wrt; - if (wrt != op->ob_pos) { - op->ob_bf = OB_EBF; - writerr(op, op->ob_pos, wrt>0?wrt:0); - wrt = -1; - } - op->ob_pos = 0; - } - return wrt; -} - -int -ob_chr(int c, struct oblok *op) -{ - char b; - ssize_t wrt; - - b = (char)c; - wrt = ob_write(op, &b, 1); - return wrt < 0 ? EOF : c; -} diff --git a/tools/cpio/src/oblok.h b/tools/cpio/src/oblok.h deleted file mode 100644 index 1ee91b1c5..000000000 --- a/tools/cpio/src/oblok.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)oblok.h 1.3 (gritter) 4/17/03 */ - -#include <sys/types.h> - -#ifndef OBLOK -enum { - OBLOK = 4096 -}; -#endif /* !OBLOK */ - -enum ob_mode { - OB_EBF = 0, /* error or mode unset */ - OB_NBF = 1, /* not buffered */ - OB_LBF = 2, /* line buffered */ - OB_FBF = 3 /* fully buffered */ -}; - -struct oblok { - char ob_blk[OBLOK]; /* buffered data */ - long long ob_wrt; /* amount of data written */ - int ob_pos; /* position of first empty date byte */ - int ob_fd; /* file descriptor to write to */ - enum ob_mode ob_bf; /* buffering mode */ -}; - -/* - * Allocate an output buffer with file descriptor fd and buffer mode bf. - * If bf is OB_EBF, the choice is made dependant upon the file type. - * NULL is returned if no memory is available. - */ -extern struct oblok *ob_alloc(int fd, enum ob_mode bf); - -/* - * Deallocate the passed output buffer, flushing all data. The file - * descriptor is not closed. Returns -1 if flushing fails. - */ -extern ssize_t ob_free(struct oblok *op); - -/* - * Write data of length sz to the passed output buffer. Returns -1 on - * error or the amount of data written. - */ -extern ssize_t ob_write(struct oblok *op, const char *data, size_t sz); - -/* - * Flush all data in the passed output buffer. Returns -1 on error or - * the amount of data written; 0 is success and means 'nothing to flush'. - * The underlying device is not flushed (i. e. no fsync() is performed). - */ -extern ssize_t ob_flush(struct oblok *op); - -/* - * Flush all output buffers. Called automatically using atexit(). Returns - * -1 on error or the number of buffers flushed; 0 is success. - */ -extern int ob_clear(void); - -/* - * putc() workalike. - */ -#define ob_put(c, op) ((op)->ob_bf != OB_FBF || (op)->ob_pos >= (OBLOK) - 1 ?\ - ob_chr((c), (op)) : \ - (int)((op)->ob_blk[(op)->ob_pos++] = (char)(c))) - - -/* - * fputc() workalike. - */ -extern int ob_chr(int c, struct oblok *op); - -/* - * This function must be supplied by the calling code; it is called on - * write error. - */ -extern void writerr(struct oblok *op, int count, int written); diff --git a/tools/cpio/src/pathconf.c b/tools/cpio/src/pathconf.c deleted file mode 100644 index a6b91ef86..000000000 --- a/tools/cpio/src/pathconf.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2004 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)pathconf.c 1.2 (gritter) 5/1/04 */ - -#ifdef __dietlibc__ -#include <unistd.h> -#include "pathconf.h" - -static long -pc(int name) -{ - switch (name) { - case _PC_PATH_MAX: - return 1024; - case _PC_VDISABLE: - return 0; - default: - return -1; - } -} - -long -fpathconf(int fildes, int name) -{ - return pc(name); -} - -long -pathconf(const char *path, int name) { - return pc(name); -} -#endif /* __dietlibc__ */ diff --git a/tools/cpio/src/pathconf.h b/tools/cpio/src/pathconf.h deleted file mode 100644 index 79696b6da..000000000 --- a/tools/cpio/src/pathconf.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2004 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)pathconf.h 1.2 (gritter) 5/1/04 */ - -#ifdef __dietlibc__ -#include <unistd.h> - -extern long fpathconf(int, int); -extern long pathconf(const char *, int); -#endif /* __dietlibc__ */ diff --git a/tools/cpio/src/pax.1 b/tools/cpio/src/pax.1 deleted file mode 100644 index 4fb9206f9..000000000 --- a/tools/cpio/src/pax.1 +++ /dev/null @@ -1,919 +0,0 @@ -'\" t -.\" Copyright (c) 2004 Gunnar Ritter -.\" -.\" This software is provided 'as-is', without any express or implied -.\" warranty. In no event will the authors be held liable for any damages -.\" arising from the use of this software. -.\" -.\" Permission is granted to anyone to use this software for any purpose, -.\" including commercial applications, and to alter it and redistribute -.\" it freely, subject to the following restrictions: -.\" -.\" 1. The origin of this software must not be misrepresented; you must not -.\" claim that you wrote the original software. If you use this software -.\" in a product, an acknowledgment in the product documentation would be -.\" appreciated but is not required. -.\" -.\" 2. Altered source versions must be plainly marked as such, and must not be -.\" misrepresented as being the original software. -.\" -.\" 3. This notice may not be removed or altered from any source distribution. -.\" Sccsid @(#)pax.1 1.38 (gritter) 8/13/09 -.TH PAX 1 "8/13/09" "Heirloom Toolchest" "User Commands" -.SH NAME -pax \- portable archive interchange -.SH SYNOPSIS -.PD 0 -.HP -.nh -.ad l -\fBpax\fR [\fB\-cdnvK\fR] [\fB\-b\ \fIsize\fR] -[\fB\-f\ \fIfile\fR] [\fB\-s\ \fIreplstr\fR] -[\fB\-x\ \fIhdr\fR] [\fIpatterns\fR] -.HP -.ad l -\fBpax\fR \fB\-r\fR[\fBcdiknuvK\fR] [\fB\-b\ \fIsize\fR] -[\fB\-f\ \fIfile\fR] -[\fB\-o\ \fIoptions\fR] -[\fB\-p\ \fIpriv\fR] [\fB\-s\ \fIreplstr\fR] -[\fB\-x\ \fIhdr\fR] [\fIpatterns\fR] -.HP -.ad l -\fBpax\fR \fB\-w\fR[\fBadiHtuvLX\fR] [\fB\-b\ \fIsize\fR] -[\fB\-f\ \fIfile\fR] -[\fB\-o\ \fIoptions\fR] -[\fB\-s\ \fIreplstr\fR] -[\fB\-x\ \fIhdr\fR] [\fIfiles\fR] -.HP -.ad l -\fBpax\fR \fB\-rw\fR[\fBdiHklntuvLX\fR] -[\fB\-p\ \fIpriv\fR] [\fB\-s\ \fIreplstr\fR] -[\fIfiles\fR] \fIdirectory\fR -.br -.ad b -.hy 1 -.PD -.SH DESCRIPTION -.I Pax -creates and extracts file archives and copies files. -.PP -If neither the -.I \-r -or -.I \-w -options are given, -.I pax -works in -.I list -mode -and prints the contents of the archive. -.PP -With the -.B \-r -option, -.I pax -works in -.RI ` read ' -mode and extracts files from a file archive. -By default, -the archive is read from standard input. -Optional arguments are interpreted as -.I patterns -and restrict the set of extracted files -to those matching any of the -.IR patterns . -The syntax is identical to that described in -.IR glob (7), -except that the slash character -.RB ` / ' -is matched by -meta-character constructs with -.RB ` * ', -.RB ` ? ' -and -.RB ` [ '. -Care must be taken to quote meta-characters appropriately from the shell. -If a pattern matches the prefix name of a directory in the archive, -all files below that directory are also extracted. -File permissions are set to those in the archive; -if the caller is the super-user, -ownerships are restored as well. -options are specified. -Archives compressed with -.IR bzip2 (1), -.IR compress (1), -.IR gzip (1), -or -.IR rpm (1) -are transparently de\%compressed on input. -.PP -With -.BR \-w , -.I pax -works in -.RI ` write ' -mode, -creates archives -and writes them to standard output per default. -A list of filenames to be included in the archive is -read from standard input; -if the name of a directory appears, -all its members and the directory itself are recursively -included in the archive. -The -.IR find (1) -utility is useful to generate a list of files -(see also its -.I \-cpio -and -.I \-ncpio -operators). -When producing a filename list for -.IR pax , -find should always be invoked with -.I \-depth -since this makes it possible to extract write-protected directories -for users other than the super-user. -If -.I files -are given on the command line, -they are included in the archive -in the same manner as described above -and standard input is not read. -.PP -The -.B \-rw -options selects -.RI ` copy ' -mode; -a list of -.I files -is read from standard input -or taken from the command line -as described for -.IR \-w ; -files are copied to the specified -.IR directory , -preserving attributes as described for -.IR \-r . -Special files are re-created in the target hierarchy, -and hard links between copied files are preserved. -.PP -When a premature end-of-file is detected with -.I \-r -and -.I \-w -and the archive is a block or character special file, -the user is prompted for new media. -.PP -The following options alter the behavior of -.IR pax : -.TP -.B \-a -Append files to the archive. -The archive must be seekable, -such as a regular file or a block device, -or a tape device capable of writing between filemarks. -.TP -\fB\-b\fI size\fR[\fBw\fR|\fBb\fR|\fBk\fR|\fBm\fR] -Blocks input and output archives at -.I size -byte records. -The optional suffix multiplies -.I size -by 2 for -.BR w , -512 for -.BR b , -1024 for -.BR k , -and 1048576 for -.BR m . -.TP -.B \-c -Reverses the sense of patterns -such that a file that does not match any of the patterns -is selected. -.TP -.B \-d -Causes -.I pax -to ignore files below directories. -In read mode, -patterns matching directories -cause only the directory itself to extracted, -files below will be ignored -unless another pattern applies to them. -In write mode, -arguments or standard input lines referring to directories -do not cause files below the respective directory -to be archived. -.TP -\fB\-f\fI\ file\fR -Selects a -.I file -that is read with the -.I \-r -option instead of standard input -or written with the -.I \-w -option instead of standard output. -.TP -.B \-H -Follow symbolic links given on the command line when reading files with -.I \-w -or -.IR \-rw , -but do not follow symbolic links encountered during directory traversal. -.TP -.B \-i -Rename files interactively. -Before a file is extracted from the archive, -its file name is printed on standard error -and the user is prompted to specify a substitute file name. -If the line read from the terminal is empty, -the file is skipped; -if the line consists of a single dot, -the name is retained; -otherwise, -the line forms the new file name. -.TP -.B \-k -Causes existing files not to be overwritten. -.TP -.B \-K -Try to continue operation on read errors and invalid headers. -If an archive contains another archive, -files from either archive may be chosen. -.TP -.B \-l -Link files instead of copying them with -.I \-rw -if possible. -.TP -.B \-L -Follow symbolic links when reading files with -.I \-w -or -.IR \-rw . -.B /usr/posix2001/bin/pax -terminates immediately when it -detects a symbolic link loop with this option. -.TP -.B \-n -If any -.I pattern -arguments are present, -each pattern can match exactly one archive member; -further members that could match the particular pattern are ignored. -Without -.I pattern -arguments, -only the first occurence of -a file that occurs more than once in the archive -is selected, the following are ignored. -.TP -\fB\-o\ \fIoption\fB,\fR[\fIoption\fB,\fR\|...] -Specifies options as described for \fI\-x pax\fR. -.TP -\fB\-p\ \fIstring\fR -Specifies which file modes are to be preserved or ignored. -.I string -may contain one or more of -.RS -.TP -.B a -Inhibits preservation of file access times. -.TP -.B e -Causes preservation of every possible mode, ownership and time. -.TP -.B m -Inhibits preservation of file modification times. -.TP -.B o -Causes preservation of owner and group IDs. -.TP -.B p -Causes preservation of file mode bits -regardless of the umask -(see -.IR umask (2)). -.RE -.IP -If file ownership is preserved, -.I pax -tries to set the group ownerships to those specified in the archive -or the original hierarchy, respectively, -regardless of the privilegues of the invoking user. -.BR /usr/5bin/pax , -.BR /usr/5bin/s42/pax , -and -.B /usr/5bin/posix/pax -try to set the user ownerships only if invoked by the super-user; -if invoked by regular users, -.B /usr/5bin/posix2001/pax -will produce an error for any file that is not owned by the invoking user. -.TP -\fB\-s\ /\fIregular expression\fB/\fIreplacement\fB/\fR[\fBgp\fR] -Modifies file names in a manner similar to that described in -.IR ed (1). -The -.I p -flag causes each modified file name to printed. -Any character can be used as delimiter instead of -.RI ` / '. -If a file name is empty after the replacement is done, -the file is ignored. -This option can be specified multiple times -to execute multiple substitutions in the order specified. -.TP -.B \-t -Resets the access times of files -that were included in the archive with -.IR \-r . -.TP -.B \-u -In read mode, -.I pax -will not overwrite existing target files -that were modified more recently than the file in the archive -when this option is given. -In write mode, -.I pax -will read the archive first. -It will then only append those files to the archive -that are not already included -or were more recently modified. -.TP -.B \-v -Prints the file names of archived or extracted files with -.I \-r -and -.I \-w -and a verbose output format -if neither of them is given. -.TP -\fB\-x\fI header\fR -Specifies the archive header format to be one of: -.sp -.in +6 -.TS -lfB l. -\fBnewc\fR SVR4 ASCII cpio format;\ -\fBcrc\fR SVR4 ASCII cpio format with checksum;\ -\fBsco\fR T{ -SCO UnixWare 7.1 ASCII cpio format; -T} -\fBscocrc\fR T{ -SCO UnixWare 7.1 ASCII cpio format with checksum; -T} -\fBodc\fR T{ -traditional ASCII cpio format, as standardized in IEEE Std. 1003.1, 1996; -T} -\fBcpio\fR T{ -same as \fIodc\fR; -T} -\fBbin\fR binary cpio format; -\fBbbs\fR byte-swapped binary cpio format; -\fBsgi\fR T{ -SGI IRIX extended binary cpio format; -T} -\fBcray\fR T{ -Cray UNICOS 9 cpio format; -T} -\fBcray5\fR T{ -Cray UNICOS 5 cpio format; -T} -\fBdec\fR T{ -Digital UNIX extended cpio format; -T} -\fBtar\fR tar format; -\fBotar\fR old tar format; -\fBustar\fR T{ -IEEE Std. 1003.1, 1996 tar format; -T} -.T& -l s. -\fBpax\fR[\fB:\fIoption\fB,\fR[\fIoption\fB,\fR\|...]] -.T& -l l. -\& T{ -IEEE Std. 1003.1, 2001 pax format. -Format-specific \fIoptions\fR are: -.in +2n -.ti 0 -.br -\fBlinkdata\fR -.br -For a regular file which has multiple hard links, -the file data is stored once for each link in the archive, -instead of being stored for the first entry only. -This option must be used with care -since many implementations are unable -to read the resulting archive. -.ti 0 -.br -\fBtimes\fR -.br -Causes the times of last access and last modification -of each archived file -to be stored in an extended \fIpax\fR header. -This in particular allows the time of last access -to be restored when the archive is read. -.br -.in -2n -T} -\fBsun\fR T{ -Sun Solaris 7 extended tar format; -T} -\fBbar\fR T{ -SunOS 4 bar format; -T} -\fBgnu\fR T{ -GNU tar format; -T} -\fBzip\fR[\fB:\fIcc\fR] T{ -zip format with optional compression method. -If \fIcc\fR is one of -\fBen\fR (normal, default), -\fBex\fR (extra), -\fBef\fR (fast), -or -\fBes\fR (super fast), -the standard \fIdeflate\fR compression is used. -\fBe0\fR selects no compression, -and -\fBbz2\fR selects \fIbzip2\fR compression. -T} -.TE -.in -6 -.sp -This option is ignored with -.I \-r -unless the -.I \-K -option is also present. -The default for -.I \-w -is traditional ASCII cpio -.I (odc) -format. -.PP -.ne 38 -Characteristics of archive formats are as follows: -.sp -.TS -allbox; -l r r r l -l1fB r2 n2 r2 c. - T{ -.ad l -maximum user/\%group id -T} T{ -.ad l -maximum file size -T} T{ -.ad l -maximum pathname length -T} T{ -.ad l -bits in dev_t (major/minor) -T} -\-x\ bin 65535 2 GB\ 256 \ 16 -\-x\ sgi 65535 9 EB\ 256 \ 14/18 -T{ -\-x\ odc -T} 262143 8 GB\ 256 \ 18 -\-x\ dec 262143 8 GB\ 256 \ 24/24 -T{ -\-x\ newc, -\-x\ crc -T} 4.3e9 4 GB\ 1024 \ 32/32 -T{ -\-x\ sco, \-x\ scocrc -T} 4.3e9 9 EB\ 1024 \ 32/32 -T{ -\-x\ cray, \-x\ cray5 -T} 1.8e19 9 EB\ 65535 \ 64 -\-x\ otar 2097151 8 GB\ 99 \ n/a -T{ -\-x\ tar, -\-x\ ustar -T} 2097151 8 GB\ 256 (99) \ 21/21 -\-x\ pax 1.8e19 9 EB\ 65535 \ 21/21 -\-x\ sun 1.8e19 9 EB\ 65535 \ 63/63 -\-x\ gnu 1.8e19 9 EB\ 65535 \ 63/63 -\-x\ bar 2097151 8 GB\ 427 \ 21 -\-x\ zip 4.3e9 9 EB\ 60000 \ 32 -.TE -.sp -.PP -The byte order of -.B binary -cpio archives -depends on the machine -on which the archive is created. -Unlike some other implementations, -.I pax -fully supports -archives of either byte order. -.I \-x\ bbs -can be used to create an archive -with the byte order opposed to that of the current machine. -.PP -The -.B sgi -format extends the binary format -to handle larger files and more device bits. -If an archive does not contain any entries -that actually need the extensions, -it is identical to a binary archive. -.I \-x\ sgi -archives are always created in MSB order. -.PP -The -.B odc -format was introduced with System\ III -and standardized with IEEE Std. 1003.1. -All known -.I cpio -and -.I pax -implementations since around 1980 can read this format. -.PP -The -.B dec -format extends the -.I odc -format -to support more device bits. -Archives in this format are generally incompatible with -.I odc -archives -and need special implementation support to be read. -.PP -The -.B \-x\ newc -format was introduced with System\ V Release\ 4. -Except for the file size, -it imposes no practical limitations -on files archived. -The original SVR4 implementation -stores the contents of hard linked files -only once and with the last archived link. -This -.I pax -ensures compatibility with SVR4. -With archives created by implementations that employ other methods -for storing hard linked files, -each file is extracted as a single link, -and some of these files may be empty. -Implementations that expect methods other than the original SVR4 one -may extract no data for hard linked files at all. -.PP -The -.B crc -format is essentially the same as the -.I \-x\ newc -format -but adds a simple checksum (not a CRC, despite its name) -for the data of regular files. -The checksum requires the implementation to read each file twice, -which can considerably increase running time and system overhead. -As not all implementations claiming to support this format -handle the checksum correctly, -it is of limited use. -.PP -The -.B sco -and -.B scocrc -formats are variants of the -.I \-x\ newc -and -.I \-x\ crc -formats, respectively, -with extensions to support larger files. -The extensions result in a different archive format -only if files larger than slightly below 2\ GB occur. -.PP -The -.B cray -format extends all header fields to 64 bits. -It thus imposes no practical limitations of any kind -on archived files, -but requires special implementation support -to be read. -Although it is originally a binary format, -the byte order is always MSB as on Cray machines. -The -.B cray5 -format is an older variant -that was used with UNICOS 5 and earlier. -.PP -The -.B otar -format was introduced with the Unix 7th Edition -.I tar -utility. -Archives in this format -can be read on all Unix systems since about 1980. -It can only hold regular files -(and, on more recent systems, symbolic links). -For file names that contain characters with the most significant bit set -(non-ASCII characters), -implementations differ in the interpretation of the header checksum. -.PP -The -.B ustar -format was introduced with IEEE Std. 1003.1. -It extends the old -.I tar -format -with support for directories, device files, -and longer file names. -Pathnames of single-linked files can consist of up to 256 characters, -dependent on the position of slashes. -Files with multiple links can only be archived -if the first link encountered is no longer than 100 characters. -Due to implementation errors, -file names longer than 99 characters -can not considered to be generally portable. -Another addition of the -.I ustar -format -are fields for the symbolic user and group IDs. -These fields are created by -.IR pax , -but ignored when reading such archives. -.PP -With -.BR "\-x tar" , -a variant of the -.I ustar -format is selected -which stores file type bits in the mode field -to work around common implementation problems. -These bits are ignored by -.I pax -when reading archives. -.PP -The -.B pax -format is an extension to the -.I ustar -format. -If attributes cannot be archived with -.IR ustar , -an extended header is written. -Unless the size of an entry is greater than 8\ GB, -a -.I pax -archive should be readable by any implementation -capable of reading -.I ustar -archives, -although files may be extracted under wrong names -and extended headers may be extracted as separate files. -If a file name contains non-UTF-8 characters, -it may not be archived or extracted correctly -because of a problem of the -.I pax -format specification. -.PP -The -.B sun -format extends the -.I ustar -format similar as the -.I pax -format does. -The extended headers in -.I sun -format archives are not understood -by implementations that support only the -.I pax -format and vice-versa. -The -.I sun -format has also problems with non-UTF-8 characters in file names. -.PP -The -.B GNU -.I tar -format is mostly compatible with the other -.I tar -formats, -unless an archive entry actually uses its extended features. -There are no practical limitations on files archived with this format. -The implementation of -.I pax -is limited to expanded numerical fields -and long file names; -in particular, -there is no support for sparse files or incremental backups. -If -.I pax -creates a multi-volume -.I GNU -archive, -it just splits a single-volume archive in multiple parts, -as with the other formats; -.I GNU -multi-volume archives are not supported. -.PP -The -.B bar -format is similar to the -.I tar -format, but can store longer file names. -It requires special implementation support to be read. -.PP -The -.B zip -format can be read in many non-Unix environments. -There are several restrictions on archives -intended for data exchange: -only regular files should be stored; -file times, permissions and ownerships -might be ignored by other implementations; -there should be no more than 65536 files in the archive; -the total archive size should not exceed 2 GB; -only -.I deflate -compression should be used. -Otherwise, -.I pax -stores all information available with other archive formats -in extended -.I zip -file headers, -so if archive portability is of no concern, -the -.I zip -implementation in -.I pax -can archive complete Unix file hierarchies. -.I Pax -supports the -.I zip64 -format extension for large files; -it automatically writes -.I zip64 -entries if necessary. -.I Pax -can extract all known -.I zip -format compression codes. -It does not support -.I zip -encryption. -Multi-volume -.I zip -archives are created as splitted single-volume archives, -as with the other formats written by -.IR pax ; -generic multi-volume -.I zip -archives are not supported. -.SH EXAMPLES -Extract all files named -.I Makefile -or -.I makefile -from the archive stored on -.IR /dev/rmt/c0s0 , -overwriting recent files: -.RS 2 -.sp -pax \-r \-f /dev/rmt/c0s0 \'[Mm]akefile\' \'*/[Mm]akefile\' -.RE -.PP -List the files contained in a software distribution archive: -.RS 2 -.sp -pax \-v \-f distribution.tar.gz -.RE -.PP -Write a -.IR gzip (1) -compressed -.I ustar -archive containing all files below the directory -.I \%project -to the file -.IR \%project.tar.gz , -excluding all directories named -.I CVS -or -.I SCCS -and their contents: -.RS 2 -.sp -find project \-depth \-print | egrep \-v \'/(CVS|SCCS)(/|$)\' | -.br - pax \-wd \-x ustar | gzip \-c > project.tar.gz -.RE -.PP -Copy the directory -.I work -and its contents -to the directory -.IR \%savedfiles , -preserving all file attributes: -.RS 2 -.sp -pax \-rw \-pe work savedfiles -.RE -.PP -Self-extracting zip archives are not automatically recognized, -but can normally be read using the -.I \-K -option, as with -.RS 2 -.sp -pax \-rK \-x zip \-f archive.exe -.sp -.RE -.SH "ENVIRONMENT VARIABLES" -.TP -.BR LANG ", " LC_ALL -See -.IR locale (7). -.TP -.B LC_CTYPE -Selects the mapping of bytes to characters -used for matching patterns -and regular expressions. -.TP -.B LC_TIME -Sets the month names printed in list mode. -.SH "SEE ALSO" -cpio(1), -find(1), -tar(1) -.SH DIAGNOSTICS -.I Pax -exits with -.sp -.TS -l8fB l. -0 after successful operation; -1 on usage errors; -2 when operation was continued after minor errors; -3 on fatal error conditions. -.TE -.SH NOTES -Device and inode numbers -are used for hard link recognition -with the various cpio formats. -Since the header space cannot hold -large numbers present in current file systems, -devices and inode numbers are set on a per-archive basis. -This enables hard link recognition with all cpio formats, -but the link connection to files appended with -.I \-a -is not preserved. -.PP -If a numeric user or group id does not fit -within the size of the header field in the selected format, -files are stored with the user id (or group id, respectively) -set to 60001. -.PP -Use of the -.I \-a -option with a -.I zip -format archive may cause data loss -if the archive was not previously created by -.I cpio -or -.I pax -itself. -.PP -If the file names passed to -.I "pax -w" -begin with a slash character, -absolute path names are stored in the archive -and will be extracted to these path names later -regardless of the current working directory. -This is normally not advisable, -and relative path names should be passed to -.I pax -only. -The -.I \-s -option can be used to substitute relative for absolute path names -and vice-versa. -.PP -.I Pax -does not currently accept the -\fB\-o delete\fR, -\fB\-o exthdr.name\fR, -\fB\-o globexthdr.name\fR, -\fB\-o invalid\fR, -\fB\-o listopt\fR, -and -\fB\-o keyword\fR -options from POSIX.1-2001. diff --git a/tools/cpio/src/pax.c b/tools/cpio/src/pax.c deleted file mode 100644 index 50632b6b1..000000000 --- a/tools/cpio/src/pax.c +++ /dev/null @@ -1,757 +0,0 @@ -/* - * cpio - copy file archives in and out - * - * Gunnar Ritter, Freiburg i. Br., Germany, April 2003. - */ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ - -#if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4 -#define USED __attribute__ ((used)) -#elif defined __GNUC__ -#define USED __attribute__ ((unused)) -#else -#define USED -#endif -#if defined (SU3) -static const char sccsid[] USED = "@(#)pax_su3.sl 1.26 (gritter) 6/26/05"; -#else -static const char sccsid[] USED = "@(#)pax.sl 1.26 (gritter) 6/26/05"; -#endif -/* Sccsid @(#)pax.c 1.26 (gritter) 6/26/05 */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <stdio.h> -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> -#include <fnmatch.h> -#include <dirent.h> -#include <regex.h> -#include <wchar.h> -#include <time.h> -#include <inttypes.h> - -#include "iblok.h" -#include "cpio.h" - -static char **files; -static int filec; -static struct iblok *filinp; -static char *path; -static size_t pathsz; -static int pax_Hflag; - -static void setpres(const char *); -static size_t ofiles_pax(char **, size_t *); -static void prtime_pax(time_t); -static void parsesub(char *); - -void -flags(int ac, char **av) -{ - const char optstring[] = "rwab:cdf:HikKlLno:p:s:tuvx:X"; - int i; - int illegal = 0; - char *x; - -#if defined (SU3) - pax = PAX_TYPE_PAX2001; -#else - pax = PAX_TYPE_PAX1992; -#endif - dflag = 1; - uflag = 1; - ofiles = ofiles_pax; - prtime = prtime_pax; - while ((i = getopt(ac, av, optstring)) != EOF) { - switch (i) { - case 'r': - if (action && action != 'i') - action = 'p'; - else - action = 'i'; - break; - case 'w': - if (action && action != 'o') - action = 'p'; - else - action = 'o'; - break; - case 'a': - Aflag = 1; - break; - case 'b': - blksiz = strtol(optarg, &x, 10); - switch (*x) { - case 'b': - blksiz *= 512; - break; - case 'k': - blksiz *= 1024; - break; - case 'm': - blksiz *= 1048576; - break; - case 'w': - blksiz *= 2; - break; - } - if (blksiz <= 0) - msg(4, -2, - "Illegal size given for -b option.\n"); - Cflag = 1; - break; - case 'c': - fflag = 1; - break; - case 'd': - pax_dflag = 1; - break; - case 'f': - Oflag = Iflag = optarg; - break; - case 'H': - pax_Hflag = 1; - break; - case 'i': - rflag = 1; - break; - case 'k': - pax_kflag = 1; - break; - case 'K': - kflag = 1; - break; - case 'l': - lflag = 1; - break; - case 'L': - Lflag = 1; - break; - case 'n': - pax_nflag = 1; - break; - case 'o': - pax_options(optarg, 1); - break; - case 'p': - setpres(optarg); - break; - case 's': - pax_sflag = 1; - parsesub(optarg); - break; - case 't': - aflag = 1; - break; - case 'u': - uflag = 0; - pax_uflag = 1; - break; - case 'v': - vflag = 1; - break; - case 'x': - if (strcmp(optarg, "cpio") == 0) - fmttype = FMT_ODC; - else { - if (setfmt(optarg) < 0) - illegal = 1; - } - break; - case 'X': - pax_Xflag = 1; - break; - default: - illegal = 1; - } - } - switch (action) { - case 0: - if (rflag || pax_kflag || pax_uflag || pax_preserve) - illegal = 1; - action = 'i'; - tflag = 1; - setvbuf(stdout, NULL, _IOLBF, 0); - /*FALLTHRU*/ - case 'i': - if (aflag || pax_Xflag || lflag) - illegal = 1; - for (i = optind; i < ac; i++) { - addg(av[i], 0); - if (pax_dflag == 0) { - char *da; - int j; - - da = smalloc(strlen(av[i]) + 2); - for (j = 0; av[i][j]; j++) - da[j] = av[i][j]; - da[j++] = '/'; - da[j++] = '*'; - da[j] = 0; - addg(da, 1); - free(da); - } - } - break; - case 'o': - if (fflag || pax_kflag || pax_nflag || kflag) - illegal = 1; - if (Aflag && Oflag == NULL) { - msg(3, 0, "-a requires the -f option\n"); - illegal = 1; - } - if (optind != ac) { - files = &av[optind]; - filec = ac - optind; - } else - filinp = ib_alloc(0, 0); - if (pax_uflag) - Aflag = 1; - if (Aflag == 0 && fmttype == FMT_NONE) - fmttype = FMT_ODC; - break; - case 'p': - if (fflag || blksiz || Oflag || Iflag || fmttype != FMT_NONE || - kflag) - illegal = 1; - if (optind == ac) - illegal = 1; - else if (optind+1 != ac) { - files = &av[optind]; - filec = ac - optind - 1; - optind = ac - 1; - } else - filinp = ib_alloc(0, 0); - break; - } - if (illegal) - usage(); -} - -void -usage(void) -{ - fprintf(stderr, "USAGE:\n\ -\t%s [-cdnvK] [-b size] [-f file] [-s replstr] [-x hdr] [patterns]\n\ -\t%s -r[cdiknuvK] [-b size] [-f file] [-p priv] [-s replstr] [-x hdr] [patterns]\n\ -\t%s -w[adituvLX] [-b size] [-f file] [-s replstr] [-x hdr] [files]\n\ -\t%s -rw[diklntuvLX] [-p priv] [-s replstr] [files] directory\n", - progname, progname, progname, progname); - exit(1); -} - -static void -setpres(const char *s) -{ - s--; - while (*++s) { - pax_preserve &= ~PAX_P_EVERY; - switch (*s) { - case 'a': - pax_preserve |= PAX_P_ATIME; - break; - case 'e': - pax_preserve |= PAX_P_EVERY; - break; - case 'm': - pax_preserve |= PAX_P_MTIME; - break; - case 'o': - pax_preserve |= PAX_P_OWNER; - break; - case 'p': - pax_preserve |= PAX_P_MODE; - break; - default: - msg(2, 0, "ignoring unknown option \"-p%c\"\n", - *s&0377); - } - } - if (pax_preserve & PAX_P_EVERY) - pax_preserve |= PAX_P_OWNER|PAX_P_MODE; -} - -int -gmatch(const char *s, const char *p) -{ - int val; -#ifdef __GLIBC__ - /* avoid glibc's broken [^...] */ - extern char **environ; - char **savenv = environ; - char *newenv[] = { "POSIXLY_CORRECT=", NULL }; - environ = newenv; -#endif /* __GLIBC__ */ - val = fnmatch(p, s, 0) == 0; -#ifdef __GLIBC__ - environ = savenv; -#endif /* __GLIBC__ */ - return val; -} - -static const char * -nextfile(void) -{ - char *line = NULL; - size_t linsiz = 0, linlen; - - if (filinp) { - pax_Hflag = 0; - if ((linlen=ib_getlin(filinp, &line, &linsiz, srealloc)) == 0) { - filinp = NULL; - return NULL; - } - if (line[linlen-1] == '\n') - line[--linlen] = '\0'; - return line; - } else if (filec > 0) { - filec--; - return *files++; - } else - return NULL; -} - -static size_t -catpath(size_t pend, const char *base) -{ - size_t blen = strlen(base); - - if (pend + blen + 2 >= pathsz) - path = srealloc(path, pathsz = pend + blen + 16); - if (pend == 0 || path[pend-1] != '/') - path[pend++] = '/'; - strcpy(&path[pend], base); - return pend + blen; -} - -/* - * Descend the directory hierarchies given using stdin or arguments - * and return file names one per one. - */ -static size_t -ofiles_pax(char **name, size_t *namsiz) -{ - static DIR **dt; - static int dti, dts; - static int *pend; - static dev_t *curdev; - static ino_t *curino; - struct stat st; - struct dirent *dp; - const char *nf; - int i; - - if (dt == NULL) { - dt = scalloc(dts = 1, sizeof *dt); - pend = scalloc(dts, sizeof *pend); - curdev = scalloc(dts, sizeof *curdev); - curino = scalloc(dts, sizeof *curino); - } - for (;;) { - if (dti >= 0 && dt[dti] != NULL) { - if ((dp = readdir(dt[dti])) != NULL) { - if (dp->d_name[0] == '.' && - (dp->d_name[1] == '\0' || - dp->d_name[1] == '.' && - dp->d_name[2] == '\0')) - continue; - if (dti+1 <= dts) { - dt = srealloc(dt, sizeof *dt * ++dts); - pend = srealloc(pend, sizeof *pend*dts); - curdev = srealloc(curdev, sizeof *curdev - * dts); - curino = srealloc(curino, sizeof *curino - * dts); - } - pend[dti+1] = catpath(pend[dti], dp->d_name); - if (pax_Hflag) - Lflag = dti < 0; - if ((Lflag ? stat : lstat)(path, &st) < 0) { - emsg(2, "Error with %s of \"%s\"", - lflag? "stat" : "lstat", - path); - errcnt++; - } else if ((st.st_mode&S_IFMT) == S_IFDIR && - (pax_Xflag == 0 || - curdev[0] == st.st_dev)) { - if (Lflag) { - for (i = 0; i <= dti; i++) - if (st.st_dev == - curdev[i] && - st.st_ino == - curino[i]) { - if (pax == - PAX_TYPE_PAX2001) - msg(4, 1, - "Symbolic link " - "loop at " - "\"%s\"\n", - path); - break; - } - if (i <= dti) - break; - } - if ((dt[dti+1]=opendir(path)) == NULL) { - emsg(2, "Cannot open directory " - "\"%s\"", path); - errcnt++; - } else { - dti++; - curdev[dti] = st.st_dev; - curino[dti] = st.st_ino; - continue; - } - } else - break; - } else { - path[pend[dti]] = '\0'; - closedir(dt[dti]); - dt[dti--] = NULL; - if (pax_Hflag) - Lflag = dti < 0; - break; - } - } else { - if (pax_Hflag) - Lflag = 1; - while ((nf = nextfile()) != NULL && - (Lflag ? stat : lstat)(nf, &st) < 0) { - emsg(2, "Error with stat of \"%s\"", nf); - errcnt++; - } - if (nf == NULL) - return 0; - dti = 0; - if (path) - free(path); - pend[dti] = strlen(nf); - strcpy(path = smalloc(pathsz = pend[dti]+1), nf); - if (pax_dflag || (st.st_mode&S_IFMT) != S_IFDIR) { - dti = -1; - break; - } - curdev[dti] = st.st_dev; - curino[dti] = st.st_ino; - if ((dt[dti] = opendir(path)) == NULL) { - emsg(2, "Cannot open directory \"%s\"", path); - errcnt++; - } - } - } - if (*name == NULL || *namsiz < pathsz) { - free(*name); - *name = smalloc(*namsiz=pathsz); - } - strcpy(*name, path); - return pend[dti+1]; -} - -struct pax_had { - struct pax_had *p_next; - const char *p_name; - time_t p_mtime; -}; - -static int pprime = 7919; - -static int -phash(const char *s) -{ - uint32_t h = 0, g; - - s--; - while (*++s) { - h = (h << 4) + (*s & 0377); - if (g = h & 0xf0000000) { - h = h ^ (g >> 24); - h = h ^ g; - } - } - return h % pprime; -} - -static int -plook(const char *name, struct pax_had **pp) -{ - static struct pax_had **pt; - uint32_t h, had; - - if (pt == NULL) - pt = scalloc(pprime, sizeof *pt); - (*pp) = pt[h = phash(name)]; - while (*pp != NULL) { - if (strcmp((*pp)->p_name, name) == 0) - break; - *pp = (*pp)->p_next; - } - had = *pp != NULL; - if (*pp == NULL) { - *pp = scalloc(1, sizeof **pp); - (*pp)->p_name = sstrdup(name); - (*pp)->p_next = pt[h]; - pt[h] = *pp; - } - return had; -} - -int -pax_track(const char *name, time_t mtime) -{ - struct pax_had *pp; - struct stat st; - - if (pax_uflag == 0 && (pax_nflag == 0 || patterns)) - return 1; - if (action == 'i' && pax_uflag) { - if (lstat(name, &st) == 0 && mtime < st.st_mtime) - return 0; - } - if (action != 'i' || pax_nflag) { - if (plook(name, &pp) != 0) { - if (action != 'i' && pax_uflag == 0) - return 0; - if (mtime > pp->p_mtime) { - pp->p_mtime = mtime; - return 1; - } - return 0; - } else - pp->p_mtime = mtime; - } - return 1; -} - -static void -prtime_pax(time_t t) -{ - char b[30]; - time_t now; - - time(&now); - if (t > now || t < now - (6*30*86400)) - strftime(b, sizeof b, "%b %e %Y", localtime(&t)); - else - strftime(b, sizeof b, "%b %e %H:%M", localtime(&t)); - printf(" %s ", b); -} - -struct replacement { - regex_t r_re; - const char *r_rhs; - int r_nbra; - enum { - REPL_0 = 0, - REPL_G = 1, - REPL_P = 2 - } r_flags; -} *rep; - -#define NBRA 9 -static int ren, res; -static int mb_cur_max; - -static wchar_t -nextc(char **sc, int *np) -{ - char *p = *sc; - wchar_t wcbuf; - int len; - - if (**sc == '\0') { - *np = 0; - return 0; - } - if (mb_cur_max == 1 || (**sc&0200) == 0) { - *np = 1; - return *(*sc)++ & 0377; - } - if ((len = mbtowc(&wcbuf, p, mb_cur_max)) < 0) - msg(3, -2, "Invalid multibyte character for \"-s\" option\n"); - *np = len; - *sc += len; - return wcbuf; -} - -static void -parsesub(char *s) -{ - int len; - char *ps = NULL; - wchar_t seof = nextc(&s, &len); - wint_t c, d; - int nbra = 0; - int reflags; - - if (seof == 0) - goto unt; - mb_cur_max = MB_CUR_MAX; - ps = s; - do { - if ((c = nextc(&s, &len)) == seof) - break; - if (c == '\\') { - if ((c = nextc(&s, &len)) == '(') - nbra++; - continue; - } else if (c == '[') { - d = WEOF; - do { - if ((c = nextc(&s, &len)) == '\0') - continue; - if (d == '[' && (c == ':' || c == '.' || - c == '=')) { - d = c; - do { - if ((c=nextc(&s, &len)) == '\0') - continue; - } while (c != d || *s != ']'); - nextc(&s, &len); - c = WEOF; /* reset d and continue */ - } - d = c; - } while (c != ']'); - } - } while (*s != '\0'); - if (c != seof) - unt: msg(3, -2, "Unterminated argument for \"-s\" option.\n"); - s[-len] = '\0'; - if (ren <= res) - rep = srealloc(rep, ++res * sizeof *rep); - reflags = REG_ANGLES; - if (pax >= PAX_TYPE_PAX2001) - reflags |= REG_AVOIDNULL; - if (regcomp(&rep[ren].r_re, ps, reflags) != 0) - msg(3, -2, "Regular expression error in \"-s\" option\n"); - rep[ren].r_rhs = s; - rep[ren].r_nbra = nbra; - while ((c = nextc(&s, &len)) != 0) { - if (c == '\\') - c = nextc(&s, &len); - else if (c == seof) - break; - } - rep[ren].r_flags = 0; - if (c == seof) { - s[-len] = '\0'; - while ((c = nextc(&s, &len)) != '\0') { - switch (c) { - case 'g': - rep[ren].r_flags |= REPL_G; - break; - case 'p': - rep[ren].r_flags |= REPL_P; - break; - default: - msg(2, 0, "Ignoring unknown -s flag \"%c\"\n", - c); - } - } - } - ren++; -} - -#define put(c) ((new = innew+1>=newsize ? srealloc(new, newsize+=32) : new), \ - new[innew++] = (c)) - -int -pax_sname(char **oldp, size_t *olds) -{ - char *new = NULL; - size_t newsize = 0; - regmatch_t bralist[NBRA+1]; - int c, i, k, l, y, z; - int innew = 0, ef = 0; - char *inp = *oldp; - - for (z = 0; z < ren; z++) { - in: if (regexec(&rep[z].r_re, inp, NBRA+1, bralist, ef) != 0) { - if (ef == 0) - continue; - goto out; - } - for (i = 0; i < bralist[0].rm_so; i++) - put(inp[i]); - k = 0; - while (c = rep[z].r_rhs[k++] & 0377) { - y = -1; - if (c == '&') - y = 0; - else if (c == '\\') { - c = rep[z].r_rhs[k++] & 0377; - if (c >= '1' && c < rep[z].r_nbra+'1') - y = c - '0'; - } - if (y >= 0) - for (l = bralist[y].rm_so; l < bralist[y].rm_eo; - l++) - put(inp[l]); - else - put(c); - } - k = innew; - for (i = bralist[0].rm_eo; inp[i]; i++) - put(inp[i]); - put('\0'); - if (rep[z].r_flags & REPL_G) { - ef = REG_NOTBOL; - inp = &inp[bralist[0].rm_eo]; - innew = k; - if (bralist[0].rm_so == bralist[0].rm_eo) { - if (inp[0] && (nextc(&inp, &l), inp[0])) - innew++; - else - goto out; - } - goto in; - } - out: if (rep[z].r_flags & REPL_P) - fprintf(stderr, "%s >> %s\n", *oldp, new); - free(*oldp); - *oldp = new; - *olds = newsize; - return *new != '\0'; - } - return 1; -} - -void -pax_onexit(void) -{ - struct glist *gp; - - for (gp = patterns; gp; gp = gp->g_nxt) { - if (gp->g_art) - continue; - if (gp->g_gotcha == 0 && (gp->g_nxt == NULL || - gp->g_nxt->g_art == 0 || - gp->g_gotcha == 0)) { - msg(3, 0, "Pattern not matched: \"%s\"\n", gp->g_pat); - errcnt++; - } - } -} diff --git a/tools/cpio/src/pfmt.c b/tools/cpio/src/pfmt.c deleted file mode 100644 index 8adc22f23..000000000 --- a/tools/cpio/src/pfmt.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)pfmt.c 1.2 (gritter) 9/21/03 */ - -#include <stdio.h> -#include <stdarg.h> - -#include "pfmt.h" - -int -pfmt(FILE *stream, long flags, const char *fmt, ...) -{ - va_list ap; - int i; - - va_start(ap, fmt); - i = vpfmt(stream, flags, fmt, ap); - va_end(ap); - return i; -} diff --git a/tools/cpio/src/pfmt.h b/tools/cpio/src/pfmt.h deleted file mode 100644 index 012667b0b..000000000 --- a/tools/cpio/src/pfmt.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)pfmt.h 1.2 (gritter) 9/21/03 */ - -#include <stdio.h> - -extern int pfmt(FILE *stream, long flags, const char *format, ...); - -#include <stdarg.h> - -extern int vpfmt(FILE *stream, long flags, const char *format, va_list ap); - -#define MM_HALT 0x00000001 -#define MM_ERROR 0x00000000 -#define MM_WARNING 0x00000002 -#define MM_INFO 0x00000004 -#define MM_ACTION 0x00000100 -#define MM_NOSTD 0x00000200 -#define MM_STD 0x00000000 -#define MM_NOGET 0x00000400 -#define MM_GET 0x00000000 - -extern int setlabel(const char *label); -extern int setuxlabel(const char *label); - -#define setcat(s) (s) -#define gettxt(n, s) (s) diff --git a/tools/cpio/src/pfmt_label.c b/tools/cpio/src/pfmt_label.c deleted file mode 100644 index 5b1a53f0a..000000000 --- a/tools/cpio/src/pfmt_label.c +++ /dev/null @@ -1 +0,0 @@ -char *pfmt_label__; diff --git a/tools/cpio/src/regexp.h b/tools/cpio/src/regexp.h deleted file mode 100644 index 5b1fee5e6..000000000 --- a/tools/cpio/src/regexp.h +++ /dev/null @@ -1,1211 +0,0 @@ -/* - * Simple Regular Expression functions. Derived from Unix 7th Edition, - * /usr/src/cmd/expr.y - * - * Modified by Gunnar Ritter, Freiburg i. Br., Germany, February 2002. - * - * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * Redistributions of source code and documentation must retain the - * above copyright notice, this list of conditions and the following - * disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed or owned by Caldera - * International, Inc. - * Neither the name of Caldera International, Inc. nor the names of - * other contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA - * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE - * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4 -#define REGEXP_H_USED __attribute__ ((used)) -#elif defined __GNUC__ -#define REGEXP_H_USED __attribute__ ((unused)) -#else -#define REGEXP_H_USED -#endif -static const char regexp_h_sccsid[] REGEXP_H_USED = - "@(#)regexp.sl 1.56 (gritter) 5/29/05"; - -#if !defined (REGEXP_H_USED_FROM_VI) && !defined (__dietlibc__) -#define REGEXP_H_WCHARS -#endif - -#define CBRA 2 -#define CCHR 4 -#define CDOT 8 -#define CCL 12 -/* CLNUM 14 used in sed */ -/* CEND 16 used in sed */ -#define CDOL 20 -#define CCEOF 22 -#define CKET 24 -#define CBACK 36 -#define CNCL 40 -#define CBRC 44 -#define CLET 48 -#define CCH1 52 -#define CCH2 56 -#define CCH3 60 - -#define STAR 01 -#define RNGE 03 -#define REGEXP_H_LEAST 0100 - -#ifdef REGEXP_H_WCHARS -#define CMB 0200 -#else /* !REGEXP_H_WCHARS */ -#define CMB 0 -#endif /* !REGEXP_H_WCHARS */ - -#define NBRA 9 - -#define PLACE(c) ep[c >> 3] |= bittab[c & 07] -#define ISTHERE(c) (ep[c >> 3] & bittab[c & 07]) - -#ifdef REGEXP_H_WCHARS -#define REGEXP_H_IS_THERE(ep, c) ((ep)[c >> 3] & bittab[c & 07]) -#endif - -#include <ctype.h> -#include <string.h> -#include <limits.h> -#ifdef REGEXP_H_WCHARS -#include <stdlib.h> -#include <wchar.h> -#include <wctype.h> -#endif /* REGEXP_H_WCHARS */ - -#define regexp_h_uletter(c) (isalpha(c) || (c) == '_') -#ifdef REGEXP_H_WCHARS -#define regexp_h_wuletter(c) (iswalpha(c) || (c) == L'_') - -/* - * Used to allocate memory for the multibyte star algorithm. - */ -#ifndef regexp_h_malloc -#define regexp_h_malloc(n) malloc(n) -#endif -#ifndef regexp_h_free -#define regexp_h_free(p) free(p) -#endif - -/* - * Can be predefined to 'inline' to inline some multibyte functions; - * may improve performance for files that contain many multibyte - * sequences. - */ -#ifndef regexp_h_inline -#define regexp_h_inline -#endif - -/* - * Mask to determine whether the first byte of a sequence possibly - * starts a multibyte character. Set to 0377 to force mbtowc() for - * any byte sequence (except 0). - */ -#ifndef REGEXP_H_MASK -#define REGEXP_H_MASK 0200 -#endif -#endif /* REGEXP_H_WCHARS */ - -/* - * For regexpr.h. - */ -#ifndef regexp_h_static -#define regexp_h_static -#endif -#ifndef REGEXP_H_STEP_INIT -#define REGEXP_H_STEP_INIT -#endif -#ifndef REGEXP_H_ADVANCE_INIT -#define REGEXP_H_ADVANCE_INIT -#endif - -char *braslist[NBRA]; -char *braelist[NBRA]; -int nbra; -char *loc1, *loc2, *locs; -int sed; -int nodelim; - -regexp_h_static int circf; -regexp_h_static int low; -regexp_h_static int size; - -regexp_h_static unsigned char bittab[] = { - 1, - 2, - 4, - 8, - 16, - 32, - 64, - 128 -}; -static int regexp_h_advance(register const char *lp, - register const char *ep); -static void regexp_h_getrnge(register const char *str, int least); - -static const char *regexp_h_bol; /* beginning of input line (for \<) */ - -#ifdef REGEXP_H_WCHARS -static int regexp_h_wchars; -static int regexp_h_mbcurmax; - -static const char *regexp_h_firstwc; /* location of first - multibyte character - on input line */ - -#define regexp_h_getwc(c) { \ - if (regexp_h_wchars) { \ - char mbbuf[MB_LEN_MAX + 1], *mbptr; \ - wchar_t wcbuf; \ - int mb, len; \ - mbptr = mbbuf; \ - do { \ - mb = GETC(); \ - *mbptr++ = mb; \ - *mbptr = '\0'; \ - } while ((len = mbtowc(&wcbuf, mbbuf, regexp_h_mbcurmax)) < 0 \ - && mb != eof && mbptr < mbbuf + MB_LEN_MAX); \ - if (len == -1) \ - ERROR(67); \ - c = wcbuf; \ - } else { \ - c = GETC(); \ - } \ -} - -#define regexp_h_store(wc, mb, me) { \ - int len; \ - if (wc == WEOF) \ - ERROR(67); \ - if ((len = me - mb) <= regexp_h_mbcurmax) { \ - char mt[MB_LEN_MAX]; \ - if (wctomb(mt, wc) >= len) \ - ERROR(50); \ - } \ - switch (len = wctomb(mb, wc)) { \ - case -1: \ - ERROR(67); \ - case 0: \ - mb++; \ - break; \ - default: \ - mb += len; \ - } \ -} - -static regexp_h_inline wint_t -regexp_h_fetchwc(const char **mb, int islp) -{ - wchar_t wc; - int len; - - if ((len = mbtowc(&wc, *mb, regexp_h_mbcurmax)) < 0) { - (*mb)++; - return WEOF; - } - if (islp && regexp_h_firstwc == NULL) - regexp_h_firstwc = *mb; - /*if (len == 0) { - (*mb)++; - return L'\0'; - } handled in singlebyte code */ - *mb += len; - return wc; -} - -#define regexp_h_fetch(mb, islp) ((*(mb) & REGEXP_H_MASK) == 0 ? \ - (*(mb)++&0377): \ - regexp_h_fetchwc(&(mb), islp)) - -static regexp_h_inline wint_t -regexp_h_showwc(const char *mb) -{ - wchar_t wc; - - if (mbtowc(&wc, mb, regexp_h_mbcurmax) < 0) - return WEOF; - return wc; -} - -#define regexp_h_show(mb) ((*(mb) & REGEXP_H_MASK) == 0 ? (*(mb)&0377): \ - regexp_h_showwc(mb)) - -/* - * Return the character immediately preceding mb. Since no byte is - * required to be the first byte of a character, the longest multibyte - * character ending at &[mb-1] is searched. - */ -static regexp_h_inline wint_t -regexp_h_previous(const char *mb) -{ - const char *p = mb; - wchar_t wc, lastwc = WEOF; - int len, max = 0; - - if (regexp_h_firstwc == NULL || mb <= regexp_h_firstwc) - return (mb > regexp_h_bol ? (mb[-1] & 0377) : WEOF); - while (p-- > regexp_h_bol) { - mbtowc(NULL, NULL, 0); - if ((len = mbtowc(&wc, p, mb - p)) >= 0) { - if (len < max || len < mb - p) - break; - max = len; - lastwc = wc; - } else if (len < 0 && max > 0) - break; - } - return lastwc; -} - -#define regexp_h_cclass(set, c, af) \ - ((c) == 0 || (c) == WEOF ? 0 : ( \ - ((c) > 0177) ? \ - regexp_h_cclass_wc(set, c, af) : ( \ - REGEXP_H_IS_THERE((set)+1, (c)) ? (af) : !(af) \ - ) \ - ) \ - ) - -static regexp_h_inline int -regexp_h_cclass_wc(const char *set, register wint_t c, int af) -{ - register wint_t wc, wl = WEOF; - const char *end; - - end = &set[18] + set[0] - 1; - set += 17; - while (set < end) { - wc = regexp_h_fetch(set, 0); -#ifdef REGEXP_H_VI_BACKSLASH - if (wc == '\\' && set < end && - (*set == ']' || *set == '-' || - *set == '^' || *set == '\\')) { - wc = regexp_h_fetch(set, 0); - } else -#endif /* REGEXP_H_VI_BACKSLASH */ - if (wc == '-' && wl != WEOF && set < end) { - wc = regexp_h_fetch(set, 0); -#ifdef REGEXP_H_VI_BACKSLASH - if (wc == '\\' && set < end && - (*set == ']' || *set == '-' || - *set == '^' || *set == '\\')) { - wc = regexp_h_fetch(set, 0); - } -#endif /* REGEXP_H_VI_BACKSLASH */ - if (c > wl && c < wc) - return af; - } - if (c == wc) - return af; - wl = wc; - } - return !af; -} -#else /* !REGEXP_H_WCHARS */ -#define regexp_h_wchars 0 -#define regexp_h_getwc(c) { c = GETC(); } -#endif /* !REGEXP_H_WCHARS */ - -regexp_h_static char * -compile(char *instring, char *ep, const char *endbuf, int seof) -{ - INIT /* Dependent declarations and initializations */ - register int c; - register int eof = seof; - char *lastep = instring; - int cclcnt; - char bracket[NBRA], *bracketp; - int closed; - char neg; - int lc; - int i, cflg; - -#ifdef REGEXP_H_WCHARS - char *eq; - regexp_h_mbcurmax = MB_CUR_MAX; - regexp_h_wchars = regexp_h_mbcurmax > 1 ? CMB : 0; -#endif - lastep = 0; - bracketp = bracket; - if((c = GETC()) == eof || c == '\n') { - if (c == '\n') { - UNGETC(c); - nodelim = 1; - } - if(*ep == 0 && !sed) - ERROR(41); - if (bracketp > bracket) - ERROR(42); - RETURN(ep); - } - circf = closed = nbra = 0; - if (c == '^') - circf++; - else - UNGETC(c); - for (;;) { - if (ep >= endbuf) - ERROR(50); - regexp_h_getwc(c); - if(c != '*' && ((c != '\\') || (PEEKC() != '{'))) - lastep = ep; - if (c == eof) { - *ep++ = CCEOF; - if (bracketp > bracket) - ERROR(42); - RETURN(ep); - } - switch (c) { - - case '.': - *ep++ = CDOT|regexp_h_wchars; - continue; - - case '\n': - if (sed == 0) { - UNGETC(c); - *ep++ = CCEOF; - nodelim = 1; - RETURN(ep); - } - ERROR(36); - case '*': - if (lastep==0 || *lastep==CBRA || *lastep==CKET || - *lastep==(CBRC|regexp_h_wchars) || - *lastep==(CLET|regexp_h_wchars)) - goto defchar; - *lastep |= STAR; - continue; - - case '$': - if(PEEKC() != eof) - goto defchar; - *ep++ = CDOL; - continue; - - case '[': -#ifdef REGEXP_H_WCHARS - if (regexp_h_wchars == 0) { -#endif - if(&ep[33] >= endbuf) - ERROR(50); - - *ep++ = CCL; - lc = 0; - for(i = 0; i < 32; i++) - ep[i] = 0; - - neg = 0; - if((c = GETC()) == '^') { - neg = 1; - c = GETC(); - } - - do { - c &= 0377; - if(c == '\0' || c == '\n') - ERROR(49); -#ifdef REGEXP_H_VI_BACKSLASH - if(c == '\\' && ((c = PEEKC()) == ']' || - c == '-' || c == '^' || - c == '\\')) { - c = GETC(); - c &= 0377; - } else -#endif /* REGEXP_H_VI_BACKSLASH */ - if(c == '-' && lc != 0) { - if ((c = GETC()) == ']') { - PLACE('-'); - break; - } -#ifdef REGEXP_H_VI_BACKSLASH - if(c == '\\' && - ((c = PEEKC()) == ']' || - c == '-' || - c == '^' || - c == '\\')) - c = GETC(); -#endif /* REGEXP_H_VI_BACKSLASH */ - c &= 0377; - while(lc < c) { - PLACE(lc); - lc++; - } - } - lc = c; - PLACE(c); - } while((c = GETC()) != ']'); - if(neg) { - for(cclcnt = 0; cclcnt < 32; cclcnt++) - ep[cclcnt] ^= 0377; - ep[0] &= 0376; - } - - ep += 32; -#ifdef REGEXP_H_WCHARS - } else { - if (&ep[18] >= endbuf) - ERROR(50); - *ep++ = CCL|CMB; - *ep++ = 0; - lc = 0; - for (i = 0; i < 16; i++) - ep[i] = 0; - eq = &ep[16]; - regexp_h_getwc(c); - if (c == L'^') { - regexp_h_getwc(c); - ep[-2] = CNCL|CMB; - } - do { - if (c == '\0' || c == '\n') - ERROR(49); -#ifdef REGEXP_H_VI_BACKSLASH - if(c == '\\' && ((c = PEEKC()) == ']' || - c == '-' || c == '^' || - c == '\\')) { - regexp_h_store(c, eq, endbuf); - regexp_h_getwc(c); - } else -#endif /* REGEXP_H_VI_BACKSLASH */ - if (c == '-' && lc != 0 && lc <= 0177) { - regexp_h_store(c, eq, endbuf); - regexp_h_getwc(c); - if (c == ']') { - PLACE('-'); - break; - } -#ifdef REGEXP_H_VI_BACKSLASH - if(c == '\\' && - ((c = PEEKC()) == ']' || - c == '-' || - c == '^' || - c == '\\')) { - regexp_h_store(c, eq, - endbuf); - regexp_h_getwc(c); - } -#endif /* REGEXP_H_VI_BACKSLASH */ - while (lc < (c & 0177)) { - PLACE(lc); - lc++; - } - } - lc = c; - if (c <= 0177) - PLACE(c); - regexp_h_store(c, eq, endbuf); - regexp_h_getwc(c); - } while (c != L']'); - if ((i = eq - &ep[16]) > 255) - ERROR(50); - lastep[1] = i; - ep = eq; - } -#endif /* REGEXP_H_WCHARS */ - - continue; - - case '\\': - regexp_h_getwc(c); - switch(c) { - - case '(': - if(nbra >= NBRA) - ERROR(43); - *bracketp++ = nbra; - *ep++ = CBRA; - *ep++ = nbra++; - continue; - - case ')': - if(bracketp <= bracket) - ERROR(42); - *ep++ = CKET; - *ep++ = *--bracketp; - closed++; - continue; - - case '<': - *ep++ = CBRC|regexp_h_wchars; - continue; - - case '>': - *ep++ = CLET|regexp_h_wchars; - continue; - - case '{': - if(lastep == (char *) (0)) - goto defchar; - *lastep |= RNGE; - cflg = 0; - nlim: - c = GETC(); - i = 0; - do { - if ('0' <= c && c <= '9') - i = 10 * i + c - '0'; - else - ERROR(16); - } while(((c = GETC()) != '\\') && (c != ',')); - if (i > 255) - ERROR(11); - *ep++ = i; - if (c == ',') { - if(cflg++) - ERROR(44); - if((c = GETC()) == '\\') { - *ep++ = (char)255; - *lastep |= REGEXP_H_LEAST; - } else { - UNGETC(c); - goto nlim; /* get 2'nd number */ - } - } - if(GETC() != '}') - ERROR(45); - if(!cflg) /* one number */ - *ep++ = i; - else if((ep[-1] & 0377) < (ep[-2] & 0377)) - ERROR(46); - continue; - - case '\n': - ERROR(36); - - case 'n': - c = '\n'; - goto defchar; - - default: - if(c >= '1' && c <= '9') { - if((c -= '1') >= closed) - ERROR(25); - *ep++ = CBACK; - *ep++ = c; - continue; - } - } - /* Drop through to default to use \ to turn off special chars */ - - defchar: - default: - lastep = ep; -#ifdef REGEXP_H_WCHARS - if (regexp_h_wchars == 0) { -#endif - *ep++ = CCHR; - *ep++ = c; -#ifdef REGEXP_H_WCHARS - } else { - char mbbuf[MB_LEN_MAX]; - - switch (wctomb(mbbuf, c)) { - case 1: *ep++ = CCH1; - break; - case 2: *ep++ = CCH2; - break; - case 3: *ep++ = CCH3; - break; - default: - *ep++ = CCHR|CMB; - } - regexp_h_store(c, ep, endbuf); - } -#endif /* REGEXP_H_WCHARS */ - } - } -} - -int -step(const char *p1, const char *p2) -{ - register int c; -#ifdef REGEXP_H_WCHARS - register int d; -#endif /* REGEXP_H_WCHARS */ - - REGEXP_H_STEP_INIT /* get circf */ - regexp_h_bol = p1; -#ifdef REGEXP_H_WCHARS - regexp_h_firstwc = NULL; -#endif /* REGEXP_H_WCHARS */ - if (circf) { - loc1 = (char *)p1; - return(regexp_h_advance(p1, p2)); - } - /* fast check for first character */ - if (*p2==CCHR) { - c = p2[1] & 0377; - do { - if ((*p1 & 0377) != c) - continue; - if (regexp_h_advance(p1, p2)) { - loc1 = (char *)p1; - return(1); - } - } while (*p1++); - return(0); - } -#ifdef REGEXP_H_WCHARS - else if (*p2==CCH1) { - do { - if (p1[0] == p2[1] && regexp_h_advance(p1, p2)) { - loc1 = (char *)p1; - return(1); - } - c = regexp_h_fetch(p1, 1); - } while (c); - return(0); - } else if (*p2==CCH2) { - do { - if (p1[0] == p2[1] && p1[1] == p2[2] && - regexp_h_advance(p1, p2)) { - loc1 = (char *)p1; - return(1); - } - c = regexp_h_fetch(p1, 1); - } while (c); - return(0); - } else if (*p2==CCH3) { - do { - if (p1[0] == p2[1] && p1[1] == p2[2] && p1[2] == p2[3]&& - regexp_h_advance(p1, p2)) { - loc1 = (char *)p1; - return(1); - } - c = regexp_h_fetch(p1, 1); - } while (c); - return(0); - } else if ((*p2&0377)==(CCHR|CMB)) { - d = regexp_h_fetch(p2, 0); - do { - c = regexp_h_fetch(p1, 1); - if (c == d && regexp_h_advance(p1, p2)) { - loc1 = (char *)p1; - return(1); - } - } while(c); - return(0); - } - /* regular algorithm */ - if (regexp_h_wchars) - do { - if (regexp_h_advance(p1, p2)) { - loc1 = (char *)p1; - return(1); - } - c = regexp_h_fetch(p1, 1); - } while (c); - else -#endif /* REGEXP_H_WCHARS */ - do { - if (regexp_h_advance(p1, p2)) { - loc1 = (char *)p1; - return(1); - } - } while (*p1++); - return(0); -} - -#ifdef REGEXP_H_WCHARS -/* - * It is painfully slow to read character-wise backwards in a - * multibyte string (see regexp_h_previous() above). For the star - * algorithm, we therefore keep track of every character as it is - * read in forward direction. - * - * Don't use alloca() for stack blocks since there is no measurable - * speedup and huge amounts of memory are used up for long input - * lines. - */ -#ifndef REGEXP_H_STAKBLOK -#define REGEXP_H_STAKBLOK 1000 -#endif - -struct regexp_h_stack { - struct regexp_h_stack *s_nxt; - struct regexp_h_stack *s_prv; - const char *s_ptr[REGEXP_H_STAKBLOK]; -}; - -#define regexp_h_push(sb, sp, sc, lp) (regexp_h_wchars ? \ - regexp_h_pushwc(sb, sp, sc, lp) : (void)0) - -static regexp_h_inline void -regexp_h_pushwc(struct regexp_h_stack **sb, - struct regexp_h_stack **sp, - const char ***sc, const char *lp) -{ - if (regexp_h_firstwc == NULL || lp < regexp_h_firstwc) - return; - if (*sb == NULL) { - if ((*sb = regexp_h_malloc(sizeof **sb)) == NULL) - return; - (*sb)->s_nxt = (*sb)->s_prv = NULL; - *sp = *sb; - *sc = &(*sb)->s_ptr[0]; - } else if (*sc >= &(*sp)->s_ptr[REGEXP_H_STAKBLOK]) { - if ((*sp)->s_nxt == NULL) { - struct regexp_h_stack *bq; - - if ((bq = regexp_h_malloc(sizeof *bq)) == NULL) - return; - bq->s_nxt = NULL; - bq->s_prv = *sp; - (*sp)->s_nxt = bq; - *sp = bq; - } else - *sp = (*sp)->s_nxt; - *sc = &(*sp)->s_ptr[0]; - } - *(*sc)++ = lp; -} - -static regexp_h_inline const char * -regexp_h_pop(struct regexp_h_stack **sb, struct regexp_h_stack **sp, - const char ***sc, const char *lp) -{ - if (regexp_h_firstwc == NULL || lp <= regexp_h_firstwc) - return &lp[-1]; - if (*sp == NULL) - return regexp_h_firstwc; - if (*sc == &(*sp)->s_ptr[0]) { - if ((*sp)->s_prv == NULL) { - regexp_h_free(*sp); - *sp = NULL; - *sb = NULL; - return regexp_h_firstwc; - } - *sp = (*sp)->s_prv; - regexp_h_free((*sp)->s_nxt); - (*sp)->s_nxt = NULL ; - *sc = &(*sp)->s_ptr[REGEXP_H_STAKBLOK]; - } - return *(--(*sc)); -} - -static void -regexp_h_zerostak(struct regexp_h_stack **sb, struct regexp_h_stack **sp) -{ - for (*sp = *sb; *sp && (*sp)->s_nxt; *sp = (*sp)->s_nxt) - if ((*sp)->s_prv) - regexp_h_free((*sp)->s_prv); - if (*sp) { - if ((*sp)->s_prv) - regexp_h_free((*sp)->s_prv); - regexp_h_free(*sp); - } - *sp = *sb = NULL; -} -#else /* !REGEXP_H_WCHARS */ -#define regexp_h_push(sb, sp, sc, lp) -#endif /* !REGEXP_H_WCHARS */ - -static int -regexp_h_advance(const char *lp, const char *ep) -{ - register const char *curlp; - int c, least; -#ifdef REGEXP_H_WCHARS - int d; - struct regexp_h_stack *sb = NULL, *sp = NULL; - const char **sc; -#endif /* REGEXP_H_WCHARS */ - char *bbeg; - int ct; - - for (;;) switch (least = *ep++ & 0377, least & ~REGEXP_H_LEAST) { - - case CCHR: -#ifdef REGEXP_H_WCHARS - case CCH1: -#endif - if (*ep++ == *lp++) - continue; - return(0); - -#ifdef REGEXP_H_WCHARS - case CCHR|CMB: - if (regexp_h_fetch(ep, 0) == regexp_h_fetch(lp, 1)) - continue; - return(0); - - case CCH2: - if (ep[0] == lp[0] && ep[1] == lp[1]) { - ep += 2, lp += 2; - continue; - } - return(0); - - case CCH3: - if (ep[0] == lp[0] && ep[1] == lp[1] && ep[2] == lp[2]) { - ep += 3, lp += 3; - continue; - } - return(0); -#endif /* REGEXP_H_WCHARS */ - - case CDOT: - if (*lp++) - continue; - return(0); -#ifdef REGEXP_H_WCHARS - case CDOT|CMB: - if ((c = regexp_h_fetch(lp, 1)) != L'\0' && c != WEOF) - continue; - return(0); -#endif /* REGEXP_H_WCHARS */ - - case CDOL: - if (*lp==0) - continue; - return(0); - - case CCEOF: - loc2 = (char *)lp; - return(1); - - case CCL: - c = *lp++ & 0377; - if(ISTHERE(c)) { - ep += 32; - continue; - } - return(0); - -#ifdef REGEXP_H_WCHARS - case CCL|CMB: - case CNCL|CMB: - c = regexp_h_fetch(lp, 1); - if (regexp_h_cclass(ep, c, (ep[-1] & 0377) == (CCL|CMB))) { - ep += (*ep & 0377) + 17; - continue; - } - return 0; -#endif /* REGEXP_H_WCHARS */ - - case CBRA: - braslist[*ep++ & 0377] = (char *)lp; - continue; - - case CKET: - braelist[*ep++ & 0377] = (char *)lp; - continue; - - case CBRC: - if (lp == regexp_h_bol && locs == NULL) - continue; - if ((isdigit(lp[0] & 0377) || regexp_h_uletter(lp[0] & 0377)) - && !regexp_h_uletter(lp[-1] & 0377) - && !isdigit(lp[-1] & 0377)) - continue; - return(0); - -#ifdef REGEXP_H_WCHARS - case CBRC|CMB: - c = regexp_h_show(lp); - d = regexp_h_previous(lp); - if ((iswdigit(c) || regexp_h_wuletter(c)) - && !regexp_h_wuletter(d) - && !iswdigit(d)) - continue; - return(0); -#endif /* REGEXP_H_WCHARS */ - - case CLET: - if (!regexp_h_uletter(lp[0] & 0377) && !isdigit(lp[0] & 0377)) - continue; - return(0); - -#ifdef REGEXP_H_WCHARS - case CLET|CMB: - c = regexp_h_show(lp); - if (!regexp_h_wuletter(c) && !iswdigit(c)) - continue; - return(0); -#endif /* REGEXP_H_WCHARS */ - - case CCHR|RNGE: - c = *ep++; - regexp_h_getrnge(ep, least); - while(low--) - if(*lp++ != c) - return(0); - curlp = lp; - while(size--) { - regexp_h_push(&sb, &sp, &sc, lp); - if(*lp++ != c) - break; - } - if(size < 0) { - regexp_h_push(&sb, &sp, &sc, lp); - lp++; - } - ep += 2; - goto star; - -#ifdef REGEXP_H_WCHARS - case CCHR|RNGE|CMB: - case CCH1|RNGE: - case CCH2|RNGE: - case CCH3|RNGE: - c = regexp_h_fetch(ep, 0); - regexp_h_getrnge(ep, least); - while (low--) - if (regexp_h_fetch(lp, 1) != c) - return 0; - curlp = lp; - while (size--) { - regexp_h_push(&sb, &sp, &sc, lp); - if (regexp_h_fetch(lp, 1) != c) - break; - } - if(size < 0) { - regexp_h_push(&sb, &sp, &sc, lp); - regexp_h_fetch(lp, 1); - } - ep += 2; - goto star; -#endif /* REGEXP_H_WCHARS */ - - case CDOT|RNGE: - regexp_h_getrnge(ep, least); - while(low--) - if(*lp++ == '\0') - return(0); - curlp = lp; - while(size--) { - regexp_h_push(&sb, &sp, &sc, lp); - if(*lp++ == '\0') - break; - } - if(size < 0) { - regexp_h_push(&sb, &sp, &sc, lp); - lp++; - } - ep += 2; - goto star; - -#ifdef REGEXP_H_WCHARS - case CDOT|RNGE|CMB: - regexp_h_getrnge(ep, least); - while (low--) - if ((c = regexp_h_fetch(lp, 1)) == L'\0' || c == WEOF) - return 0; - curlp = lp; - while (size--) { - regexp_h_push(&sb, &sp, &sc, lp); - if ((c = regexp_h_fetch(lp, 1)) == L'\0' || c == WEOF) - break; - } - if (size < 0) { - regexp_h_push(&sb, &sp, &sc, lp); - regexp_h_fetch(lp, 1); - } - ep += 2; - goto star; -#endif /* REGEXP_H_WCHARS */ - - case CCL|RNGE: - regexp_h_getrnge(ep + 32, least); - while(low--) { - c = *lp++ & 0377; - if(!ISTHERE(c)) - return(0); - } - curlp = lp; - while(size--) { - regexp_h_push(&sb, &sp, &sc, lp); - c = *lp++ & 0377; - if(!ISTHERE(c)) - break; - } - if(size < 0) { - regexp_h_push(&sb, &sp, &sc, lp); - lp++; - } - ep += 34; /* 32 + 2 */ - goto star; - -#ifdef REGEXP_H_WCHARS - case CCL|RNGE|CMB: - case CNCL|RNGE|CMB: - regexp_h_getrnge(ep + (*ep & 0377) + 17, least); - while (low--) { - c = regexp_h_fetch(lp, 1); - if (!regexp_h_cclass(ep, c, - (ep[-1] & 0377 & ~REGEXP_H_LEAST) - == (CCL|RNGE|CMB))) - return 0; - } - curlp = lp; - while (size--) { - regexp_h_push(&sb, &sp, &sc, lp); - c = regexp_h_fetch(lp, 1); - if (!regexp_h_cclass(ep, c, - (ep[-1] & 0377 & ~REGEXP_H_LEAST) - == (CCL|RNGE|CMB))) - break; - } - if (size < 0) { - regexp_h_push(&sb, &sp, &sc, lp); - regexp_h_fetch(lp, 1); - } - ep += (*ep & 0377) + 19; - goto star; -#endif /* REGEXP_H_WCHARS */ - - case CBACK: - bbeg = braslist[*ep & 0377]; - ct = braelist[*ep++ & 0377] - bbeg; - - if(strncmp(bbeg, lp, ct) == 0) { - lp += ct; - continue; - } - return(0); - - case CBACK|STAR: - bbeg = braslist[*ep & 0377]; - ct = braelist[*ep++ & 0377] - bbeg; - curlp = lp; - while(strncmp(bbeg, lp, ct) == 0) - lp += ct; - - while(lp >= curlp) { - if(regexp_h_advance(lp, ep)) return(1); - lp -= ct; - } - return(0); - - - case CDOT|STAR: - curlp = lp; - do - regexp_h_push(&sb, &sp, &sc, lp); - while (*lp++); - goto star; - -#ifdef REGEXP_H_WCHARS - case CDOT|STAR|CMB: - curlp = lp; - do - regexp_h_push(&sb, &sp, &sc, lp); - while ((c = regexp_h_fetch(lp, 1)) != L'\0' && c != WEOF); - goto star; -#endif /* REGEXP_H_WCHARS */ - - case CCHR|STAR: - curlp = lp; - do - regexp_h_push(&sb, &sp, &sc, lp); - while (*lp++ == *ep); - ep++; - goto star; - -#ifdef REGEXP_H_WCHARS - case CCHR|STAR|CMB: - case CCH1|STAR: - case CCH2|STAR: - case CCH3|STAR: - curlp = lp; - d = regexp_h_fetch(ep, 0); - do - regexp_h_push(&sb, &sp, &sc, lp); - while (regexp_h_fetch(lp, 1) == d); - goto star; -#endif /* REGEXP_H_WCHARS */ - - case CCL|STAR: - curlp = lp; - do { - regexp_h_push(&sb, &sp, &sc, lp); - c = *lp++ & 0377; - } while(ISTHERE(c)); - ep += 32; - goto star; - -#ifdef REGEXP_H_WCHARS - case CCL|STAR|CMB: - case CNCL|STAR|CMB: - curlp = lp; - do { - regexp_h_push(&sb, &sp, &sc, lp); - c = regexp_h_fetch(lp, 1); - } while (regexp_h_cclass(ep, c, (ep[-1] & 0377) - == (CCL|STAR|CMB))); - ep += (*ep & 0377) + 17; - goto star; -#endif /* REGEXP_H_WCHARS */ - - star: -#ifdef REGEXP_H_WCHARS - if (regexp_h_wchars == 0) { -#endif - do { - if(--lp == locs) - break; - if (regexp_h_advance(lp, ep)) - return(1); - } while (lp > curlp); -#ifdef REGEXP_H_WCHARS - } else { - do { - lp = regexp_h_pop(&sb, &sp, &sc, lp); - if (lp <= locs) - break; - if (regexp_h_advance(lp, ep)) { - regexp_h_zerostak(&sb, &sp); - return(1); - } - } while (lp > curlp); - regexp_h_zerostak(&sb, &sp); - } -#endif /* REGEXP_H_WCHARS */ - return(0); - - } -} - -static void -regexp_h_getrnge(register const char *str, int least) -{ - low = *str++ & 0377; - size = least & REGEXP_H_LEAST ? /*20000*/INT_MAX : (*str & 0377) - low; -} - -int -advance(const char *lp, const char *ep) -{ - REGEXP_H_ADVANCE_INIT /* skip past circf */ - regexp_h_bol = lp; -#ifdef REGEXP_H_WCHARS - regexp_h_firstwc = NULL; -#endif /* REGEXP_H_WCHARS */ - return regexp_h_advance(lp, ep); -} diff --git a/tools/cpio/src/regexpr.c b/tools/cpio/src/regexpr.c deleted file mode 100644 index 40dceb525..000000000 --- a/tools/cpio/src/regexpr.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Simple Regular Expression functions. Derived from Unix 7th Edition, - * /usr/src/cmd/expr.y - * - * Modified by Gunnar Ritter, Freiburg i. Br., Germany, January 2003. - * - * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * Redistributions of source code and documentation must retain the - * above copyright notice, this list of conditions and the following - * disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed or owned by Caldera - * International, Inc. - * Neither the name of Caldera International, Inc. nor the names of - * other contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA - * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE - * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* Sccsid @(#)regexpr.c 1.8 (gritter) 10/13/04 */ - -#include <stdlib.h> -#include "regexpr.h" - -int regerrno, reglength; -static int circf; - -static char *regexpr_compile(char *, char *, const char *, int); - -char * -compile(const char *instring, char *ep, char *endbuf) -{ - char *cp; - int sz = 0; - - if (ep == 0) { - for (cp = (char *)instring; *cp != '\0'; cp++) - if (*cp == '[') - sz += 32; - sz += 2 * (cp - instring) + 5; - if ((ep = malloc(sz)) == 0) { - regerrno = 11; - return 0; - } - endbuf = &ep[sz]; - ep[1] = '\0'; - } - if ((cp=regexpr_compile((char *)instring, &ep[1], endbuf, '\0')) == 0) { - if (sz) - free(ep); - return 0; - } - ep[0] = circf; - reglength = cp - ep; - return sz ? ep : cp; -} - -#define INIT register char *sp = instring; -#define GETC() (*sp++) -#define PEEKC() (*sp) -#define UNGETC(c) (--sp) -#define RETURN(c) return (c); -#define ERROR(c) { regerrno = c; return 0; } - -#define compile(a, b, c, d) regexpr_compile(a, b, c, d) -#define regexp_h_static static -#define REGEXP_H_STEP_INIT circf = *p2++; -#define REGEXP_H_ADVANCE_INIT circf = *ep++; - -#include "regexp.h" diff --git a/tools/cpio/src/regexpr.h b/tools/cpio/src/regexpr.h deleted file mode 100644 index 74f4a1426..000000000 --- a/tools/cpio/src/regexpr.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Simple Regular Expression functions. Derived from Unix 7th Edition, - * /usr/src/cmd/expr.y - * - * Modified by Gunnar Ritter, Freiburg i. Br., Germany, January 2003. - * - * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * Redistributions of source code and documentation must retain the - * above copyright notice, this list of conditions and the following - * disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed or owned by Caldera - * International, Inc. - * Neither the name of Caldera International, Inc. nor the names of - * other contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA - * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE - * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* Sccsid @(#)regexpr.h 1.2 (gritter) 1/11/03 */ - -#define NBRA 9 - -extern char *braslist[NBRA]; -extern char *braelist[NBRA]; -extern int nbra; -extern int regerrno, reglength; -extern char *loc1, *loc2, *locs; -extern int sed; - -extern char *compile(const char *, char *, char *); -extern int step(const char *, const char *); -extern int advance(const char *, const char *); diff --git a/tools/cpio/src/setlabel.c b/tools/cpio/src/setlabel.c deleted file mode 100644 index a1db0646e..000000000 --- a/tools/cpio/src/setlabel.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)setlabel.c 1.1 (gritter) 9/21/03 */ - -extern char *pfmt_label__; - -int -setlabel(const char *s) -{ - static char lbuf[26]; - char *lp; - - if (s && s[0]) { - for (lp = lbuf; *s && lp < &lbuf[sizeof lbuf-1]; s++, lp++) - *lp = *s; - *lp = '\0'; - pfmt_label__ = lbuf; - } else - pfmt_label__ = 0; - return 0; -} diff --git a/tools/cpio/src/setuxlabel.c b/tools/cpio/src/setuxlabel.c deleted file mode 100644 index 9d304869e..000000000 --- a/tools/cpio/src/setuxlabel.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)setuxlabel.c 1.1 (gritter) 9/21/03 */ - -#include "msgselect.h" - -extern char *pfmt_label__; - -int -setuxlabel(const char *s) -{ - static char lbuf[msgselect(29,26)]; - char *lp, *mp; - - if (s && s[0]) { - lp = lbuf; - mp = msgselect("UX:",""); - while (*mp) - *lp++ = *mp++; - lbuf[0] = 'U', lbuf[1] = 'X', lbuf[2] = ':'; - while (*s && lp < &lbuf[sizeof lbuf-1]) - *lp++ = *s++; - *lp = '\0'; - pfmt_label__ = lbuf; - } else - pfmt_label__ = 0; - return 0; -} diff --git a/tools/cpio/src/sfile.c b/tools/cpio/src/sfile.c deleted file mode 100644 index 089d85fdf..000000000 --- a/tools/cpio/src/sfile.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)sfile.c 1.9 (gritter) 6/7/04 */ - -#ifdef __linux__ -#undef _FILE_OFFSET_BITS - -#include <sys/types.h> -#include <sys/sendfile.h> -#include <sys/stat.h> -#include <unistd.h> -#include <limits.h> -#include <errno.h> -#include "sfile.h" - -long long -sfile(int dfd, int sfd, mode_t mode, long long count) -{ - static int enosys, einval, success; - off_t offset; - ssize_t sent, total; - extern void writerr(void *, int, int); - /* - * A process is not interruptible while executing a sendfile() - * system call. So it is not advisable to to send an entire - * file with one call; it is sent in parts so signals can - * be delivered in between. - */ - const ssize_t chunk = 196608; - - /* - * If a previous call returned ENOSYS, the operating system does - * not support sendfile() at all and it makes no sense to try it - * again. - * - * If a previous call returned EINVAL and there was no successful - * call yet, it is very likely that this is a permanent error - * condition (on Linux 2.6.0-test4, sendfile() may be used for - * socket targets only; older versions don't support tmpfs as - * source file system etc.). - */ - if (enosys || !success && einval || - (mode&S_IFMT) != S_IFREG || count > SSIZE_MAX) - return 0; - offset = lseek(sfd, 0, SEEK_CUR); - sent = 0, total = 0; - while (count > 0 && (sent = sendfile(dfd, sfd, &offset, - count > chunk ? chunk : count)) > 0) { - count -= sent, total += sent; - } - if (total && lseek(sfd, offset, SEEK_SET) == (off_t)-1) - return -1; - if (count == 0 || sent == 0) { - success = 1; - return total; - } - switch (errno) { - case ENOSYS: - enosys = 1; - return 0; - case EINVAL: - einval = 1; - return 0; - case ENOMEM: - return 0; - default: - writerr(NULL, count > chunk ? chunk : count, 0); - return -1; - } -} -#else /* !__linux__ */ -#include <sys/types.h> - -/*ARGSUSED*/ -long long -sfile(int dfd, int sfd, mode_t mode, long long count) -{ - return 0; -} -#endif /* __linux__ */ diff --git a/tools/cpio/src/sfile.h b/tools/cpio/src/sfile.h deleted file mode 100644 index 53d832a6f..000000000 --- a/tools/cpio/src/sfile.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)sfile.h 1.4 (gritter) 4/17/03 */ - -/* - * Return values: - * - * src_size The entire range has been copied. The file offset of both - * dst_fd and src_fd have been set to this position. The - * operation has been completed successfully. - * - * >0 Number of bytes written. The file offset of both dst_fd - * and src_fd have been set to this position. The operation - * may continue using read()/write(). - * - * 0 No data was written; operation may continue. - * - * -1 An error occured; operation may not continue. - */ -extern long long sfile(int dst_fd, int src_fd, mode_t src_mode, - long long src_size); diff --git a/tools/cpio/src/sighold.c b/tools/cpio/src/sighold.c deleted file mode 100644 index bae3bc393..000000000 --- a/tools/cpio/src/sighold.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2004 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)sighold.c 1.7 (gritter) 1/22/06 */ - -#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \ - defined (__OpenBSD__) || defined (__DragonFly__) || defined (__APPLE__) || \ - defined (__UCLIBC__) -#include <signal.h> -#include "sigset.h" - -int -sighold(int sig) -{ - sigset_t set, oset; - - if (sig <= 0) - return -1; - sigemptyset(&set); - sigaddset(&set, sig); - return sigprocmask(SIG_BLOCK, &set, &oset); -} -#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __OpenBSD__ || - __DragonFly__ || __APPLE__ || __UCLIBC__ */ diff --git a/tools/cpio/src/sigignore.c b/tools/cpio/src/sigignore.c deleted file mode 100644 index 6938ef676..000000000 --- a/tools/cpio/src/sigignore.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2004 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)sigignore.c 1.6 (gritter) 1/22/06 */ - -#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \ - defined (__OpenBSD__) || defined (__DragonFly__) || defined (__APPLE__) -#include <signal.h> -#include "sigset.h" - -int -sigignore(int sig) -{ - struct sigaction act; - - if (sig <= 0) - return -1; - act.sa_handler = SIG_IGN; - act.sa_flags = 0; - if (sig == SIGCHLD) - act.sa_flags |= SA_NOCLDSTOP|SA_NOCLDWAIT; - sigemptyset(&act.sa_mask); - sigaddset(&act.sa_mask, sig); - return sigaction(sig, &act, (struct sigaction *)0); -} -#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __OpenBSD__ || - __DragonFly__ || __APPLE__ */ diff --git a/tools/cpio/src/signal.c b/tools/cpio/src/signal.c deleted file mode 100644 index 1f9d51cb7..000000000 --- a/tools/cpio/src/signal.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2004 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)signal.c 1.6 (gritter) 1/22/06 */ - -#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \ - defined (__OpenBSD__) || defined (__DragonFly__) || defined (__APPLE__) || \ - defined (__UCLIBC__) -#include <signal.h> -#include "sigset.h" - -void (*signal(int sig, void (*func)(int)))(int) -{ - struct sigaction nact, oact; - - if (sig <= 0) - return SIG_ERR; - nact.sa_handler = func; - nact.sa_flags = SA_RESETHAND|SA_NODEFER; - if (sig == SIGCHLD && func == SIG_IGN) - nact.sa_flags |= SA_NOCLDSTOP|SA_NOCLDWAIT; - sigemptyset(&nact.sa_mask); - if (sigaction(sig, &nact, &oact) == -1) - return SIG_ERR; - return oact.sa_handler; -} -#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __OpenBSD__ || - __DragonFly__ || __APPLE__ || __UCLIBC__ */ diff --git a/tools/cpio/src/sigpause.c b/tools/cpio/src/sigpause.c deleted file mode 100644 index 504a5ed4d..000000000 --- a/tools/cpio/src/sigpause.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2004 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)sigpause.c 1.6 (gritter) 1/22/06 */ - -#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \ - defined (__OpenBSD__) || defined (__DragonFly__) || defined (__APPLE__) -#include <signal.h> -#include "sigset.h" - -int -sigpause(int sig) -{ - sigset_t nset, oset; - int ret; - - if (sig <= 0) - return -1; - sigemptyset(&nset); - sigaddset(&nset, sig); - if (sigprocmask(SIG_UNBLOCK, &nset, &oset) < 0) - return -1; - sigemptyset(&nset); - ret = sigsuspend(&nset); - if (sigprocmask(SIG_SETMASK, &oset, (sigset_t *)0) < 0) - ret = -1; - return ret; -} -#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __OpenBSD__ || - __DragonFly__ || __APPLE__ */ diff --git a/tools/cpio/src/sigrelse.c b/tools/cpio/src/sigrelse.c deleted file mode 100644 index d74de74bf..000000000 --- a/tools/cpio/src/sigrelse.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2004 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)sigrelse.c 1.8 (gritter) 1/22/06 */ - -#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \ - defined (__OpenBSD__) || defined (__DragonFly__) || defined (__APPLE__) || \ - defined (__UCLIBC__) -#include <signal.h> -#include "sigset.h" - -int -sigrelse(int sig) -{ - sigset_t set, oset; - - if (sig <= 0) - return -1; - sigemptyset(&set); - sigaddset(&set, sig); - return sigprocmask(SIG_UNBLOCK, &set, &oset); -} -#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __OpenBSD__ || - __DragonFly__ || __APPLE__ || __UCLIBC__ */ diff --git a/tools/cpio/src/sigset.c b/tools/cpio/src/sigset.c deleted file mode 100644 index d561d541d..000000000 --- a/tools/cpio/src/sigset.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2004 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)sigset.c 1.7 (gritter) 1/22/06 */ - -#include <sys/param.h> -#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \ - defined (__OpenBSD__) || defined (__DragonFly__) || defined (__APPLE__) || \ - defined (__UCLIBC__) -#include <signal.h> -#include "sigset.h" - -void (*sigset(int sig, void (*func)(int)))(int) -{ - struct sigaction nact, oact; - sigset_t nset, oset; - - if (sig <= 0) - return SIG_ERR; - sigemptyset(&nset); - sigaddset(&nset, sig); - if (sigprocmask(func==SIG_HOLD?SIG_BLOCK:SIG_UNBLOCK, &nset, &oset) < 0) - return SIG_ERR; - nact.sa_handler = func; - nact.sa_flags = 0; - if (sig == SIGCHLD && func == SIG_IGN) - nact.sa_flags |= SA_NOCLDSTOP|SA_NOCLDWAIT; - sigemptyset(&nact.sa_mask); - sigaddset(&nact.sa_mask, sig); - if (sigaction(sig, func==SIG_HOLD?(struct sigaction *)0:&nact, &oact) - == -1) - return SIG_ERR; - if (sigismember(&oset, sig)) - return SIG_HOLD; - else - return (oact.sa_handler); -} -#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __OpenBSD__ || - __DragonFly__ || __APPLE__ || __UCLIBC__ */ diff --git a/tools/cpio/src/sigset.h b/tools/cpio/src/sigset.h deleted file mode 100644 index ada73a884..000000000 --- a/tools/cpio/src/sigset.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2004 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)sigset.h 1.9 (gritter) 1/22/06 */ - -#include <sys/param.h> -#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \ - defined (__OpenBSD__) || defined (__DragonFly__) || defined (__APPLE__) || \ - defined (__UCLIBC__) - -#ifndef SIG_HOLD -#define SIG_HOLD ((void (*)(int))2) -#endif /* !SIG_HOLD */ - -extern int sighold(int); -extern int sigignore(int); -//extern int sigpause(int); -extern int sigrelse(int); -extern void (*sigset(int, void (*)(int)))(int); -extern void (*signal(int, void (*)(int)))(int); -#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __OpenBSD__ || - __DragonFly__ || __APPLE__ || __UCLIBC__ */ diff --git a/tools/cpio/src/strtol.c b/tools/cpio/src/strtol.c deleted file mode 100644 index cd8ecfe7a..000000000 --- a/tools/cpio/src/strtol.c +++ /dev/null @@ -1,117 +0,0 @@ -/* Sccsid @(#)strtol.c 1.6 (gritter) 7/18/04 */ - -#if defined (__hpux) || defined (_AIX) || \ - defined (__FreeBSD__) && (__FreeBSD__) < 5 - -#include <stdlib.h> -#include <ctype.h> -#include <errno.h> - -#include "atoll.h" - -#ifdef __hpux -#ifndef _INCLUDE__STDC_A1_SOURCE -#error You must use cc -D_INCLUDE__STDC_A1_SOURCE on HP-UX -#endif -#endif /* __hpux */ - -static long long -internal(const char *nptr, char **endptr, int base, int flags) -{ - const char *pp = nptr, *bptr; - long long v = 0, ov; - int sign = 1; - int c; - int valid = 1; - - /* XXX - * iswspace() should be used. - */ - for (bptr = nptr; isspace(*bptr&0377); bptr++); - if (*bptr == '-') { - sign = -1; - bptr++; - } else if (*bptr == '+') - bptr++; - if (base == 0) { - if (*bptr >= '1' && *bptr <= '9') - base = 10; - else if (*bptr == '0') { - if (bptr[1] == 'x' || bptr[1] == 'X') - base = 16; - else - base = 8; - } else { - if (flags&1) - errno = EINVAL; - goto out; - } - } - if (base < 2 || base > 36) { - if (flags&1) - errno = EINVAL; - goto out; - } - if (base == 16 && bptr[0] == '0' && - (bptr[1] == 'x' || bptr[1] == 'X')) - bptr += 2; - pp = bptr; - for (;;) { - if (*pp >= '0' && *pp <= '9') - c = *pp - '0'; - else if (*pp >= 'a' && *pp <= 'z') - c = *pp - 'a' + 10; - else if (*pp >= 'A' && *pp <= 'A') - c = *pp - 'A' + 10; - else - break; - if (c >= base) - break; - pp++; - if (valid) { - ov = v; - v = v * base + c; - if (flags&1) { - if (flags&2 && (unsigned long long)v < - (unsigned long long)ov || - v < ov) { - sign = 1; - errno = ERANGE; - v = -1; - if ((flags&2)==0) - v = (unsigned long long)v >> 1; - valid = 0; - } - } - } - } -out: if (pp <= bptr) { - if (flags&1) - errno = EINVAL; - if (endptr) - *endptr = (char *)nptr; - } else { - if (endptr) - *endptr = (char *)pp; - } - return v * sign; -} - -long long -strtoll(const char *nptr, char **endptr, int base) -{ - return internal(nptr, endptr, base, 1); -} - -unsigned long long -strtoull(const char *nptr, char **endptr, int base) -{ - return (unsigned long long)internal(nptr, endptr, base, 3); -} - -long long -atoll(const char *nptr) -{ - return internal(nptr, NULL, 10, 0); -} -#endif /* __hpux || _AIX || __FreeBSD__ < 5 */ diff --git a/tools/cpio/src/unshrink.c b/tools/cpio/src/unshrink.c deleted file mode 100644 index 61f5c507c..000000000 --- a/tools/cpio/src/unshrink.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Changes by Gunnar Ritter, Freiburg i. Br., Germany, May 2003. - * - * Derived from unzip 5.40. - * - * Sccsid @(#)unshrink.c 1.4 (gritter) 6/18/04 - */ -/*--------------------------------------------------------------------------- - - unshrink.c version 1.21 23 Nov 95 - - - NOTE: This code may or may not infringe on the so-called "Welch - patent" owned by Unisys. (From reading the patent, it appears - that a pure LZW decompressor is *not* covered, but this claim has - not been tested in court, and Unisys is reported to believe other- - wise.) It is therefore the responsibility of the user to acquire - whatever license(s) may be required for legal use of this code. - - THE INFO-ZIP GROUP DISCLAIMS ALL LIABILITY FOR USE OF THIS CODE - IN VIOLATION OF APPLICABLE PATENT LAW. - - - Shrinking is basically a dynamic LZW algorithm with allowed code sizes of - up to 13 bits; in addition, there is provision for partial clearing of - leaf nodes. PKWARE uses the special code 256 (decimal) to indicate a - change in code size or a partial clear of the code tree: 256,1 for the - former and 256,2 for the latter. [Note that partial clearing can "orphan" - nodes: the parent-to-be can be cleared before its new child is added, - but the child is added anyway (as an orphan, as though the parent still - existed). When the tree fills up to the point where the parent node is - reused, the orphan is effectively "adopted." Versions prior to 1.05 were - affected more due to greater use of pointers (to children and siblings - as well as parents).] - - This replacement version of unshrink.c was written from scratch. It is - based only on the algorithms described in Mark Nelson's _The Data Compres- - sion Book_ and in Terry Welch's original paper in the June 1984 issue of - IEEE _Computer_; no existing source code, including any in Nelson's book, - was used. - - Memory requirements have been reduced in this version and are now no more - than the original Sam Smith code. This is still larger than any of the - other algorithms: at a minimum, 8K+8K+16K (stack+values+parents) assuming - 16-bit short ints, and this does not even include the output buffer (the - other algorithms leave the uncompressed data in the work area, typically - called slide[]). For machines with a 64KB data space this is a problem, - particularly when text conversion is required and line endings have more - than one character. UnZip's solution is to use two roughly equal halves - of outbuf for the ASCII conversion in such a case; the "unshrink" argument - to flush() signals that this is the case. - - For large-memory machines, a second outbuf is allocated for translations, - but only if unshrinking and only if translations are required. - - | binary mode | text mode - --------------------------------------------------- - big mem | big outbuf | big outbuf + big outbuf2 <- malloc'd here - small mem | small outbuf | half + half small outbuf - - Copyright 1994, 1995 Greg Roelofs. See the accompanying file "COPYING" - in UnZip 5.20 (or later) source or binary distributions. - - From "COPYING": - - The following copyright applies to the new version of unshrink.c, - distributed with UnZip version 5.2 and later: - - * Copyright (c) 1994 Greg Roelofs. - * Permission is granted to any individual/institution/corporate - * entity to use, copy, redistribute or modify this software for - * any purpose whatsoever, subject to the conditions noted in the - * Frequently Asked Questions section below, plus one additional - * condition: namely, that my name not be removed from the source - * code. (Other names may, of course, be added as modifications - * are made.) Corporate legal staff (like at IBM :-) ) who have - * problems understanding this can contact me through Zip-Bugs... - - - Q. Can I use the source code of Zip and UnZip in my commercial - application? - - A. Yes, so long as you include in your product an acknowledgment; a - pointer to the original, free compression sources; and a statement - making it clear that there are no extra or hidden charges resulting - from the use of our compression code in your product (see below for - an example). The acknowledgment should appear in at least one piece - of human-readable documentation (e.g., a README file or man page), - although additionally putting it in the executable(s) is OK, too. - In other words, you are allowed to sell only your own work, not ours, - and we'd like a little credit. (Note the additional restrictions - above on the code in unreduce.c, unshrink.c, vms.c, time_lib.c, and - everything in the wince and windll subdirectories.) Contact us at - Zip-Bugs@lists.wku.edu if you have special requirements. We also - like to hear when our code is being used, but we don't require that. - - <Product> incorporates compression code from the Info-ZIP group. - There are no extra charges or costs due to the use of this code, - and the original compression sources are freely available from - http://www.cdrom.com/pub/infozip/ or ftp://ftp.cdrom.com/pub/infozip/ - on the Internet. - - If you only need compression capability, not full zipfile support, - you might want to look at zlib instead; it has fewer restrictions - on commercial use. See http://www.cdrom.com/pub/infozip/zlib/ . - - ---------------------------------------------------------------------------*/ - -#include <string.h> -#include <stdio.h> - -#include "cpio.h" -#include "unzip.h" - -static void partial_clear(struct globals *); - -#define trace() - -/* HSIZE is defined as 2^13 (8192) in unzip.h */ -#define BOGUSCODE 256 -#define FLAG_BITS parent /* upper bits of parent[] used as flag bits */ -#define CODE_MASK (HSIZE - 1) /* 0x1fff (lower bits are parent's index) */ -#define FREE_CODE HSIZE /* 0x2000 (code is unused or was cleared) */ -#define HAS_CHILD (HSIZE << 1) /* 0x4000 (code has a child--do not clear) */ - -#define parent G.area.shrink.Parent -#define Value G.area.shrink.value /* "value" conflicts with Pyramid ioctl.h */ -#define stack G.area.shrink.Stack - -/***********************/ -/* Function unshrink() */ -/***********************/ - -int -zipunshrink(struct file *f, const char *tgt, int tfd, int doswap, uint32_t *crc) -{ - struct globals G; - int offset = (HSIZE - 1); - uint8_t *stacktop = stack + offset; - register uint8_t *newstr; - int codesize=9, len, KwKwK; - int16_t code, oldcode, freecode, curcode; - int16_t lastfreecode; - unsigned int outbufsiz; - -/*--------------------------------------------------------------------------- - Initialize various variables. - ---------------------------------------------------------------------------*/ - - memset(&G, 0, sizeof G); - G.tgt = tgt; - G.tfd = tfd; - G.doswap = doswap; - G.crc = crc; - G.zsize = G.uzsize = f->f_csize; - lastfreecode = BOGUSCODE; - - for (code = 0; code < BOGUSCODE; ++code) { - Value[code] = (uint8_t)code; - parent[code] = BOGUSCODE; - } - for (code = BOGUSCODE+1; code < HSIZE; ++code) - parent[code] = FREE_CODE; - - outbufsiz = OUTBUFSIZ; - G.outptr = G.outbuf; - G.outcnt = 0L; - -/*--------------------------------------------------------------------------- - Get and output first code, then loop over remaining ones. - ---------------------------------------------------------------------------*/ - - READBITS(codesize, oldcode) - if (!G.zipeof) { - *G.outptr++ = (uint8_t)oldcode; - ++G.outcnt; - } - - do { - READBITS(codesize, code) - if (G.zipeof) - break; - if (code == BOGUSCODE) { /* possible to have consecutive escapes? */ - READBITS(codesize, code) - if (code == 1) { - ++codesize; - Trace((stderr, " (codesize now %d bits)\n", codesize)); - } else if (code == 2) { - Trace((stderr, " (partial clear code)\n")); - partial_clear(&G); /* clear leafs (nodes with no children) */ - Trace((stderr, " (done with partial clear)\n")); - lastfreecode = BOGUSCODE; /* reset start of free-node search */ - } - continue; - } - - /*----------------------------------------------------------------------- - Translate code: traverse tree from leaf back to root. - -----------------------------------------------------------------------*/ - - newstr = stacktop; - curcode = code; - - if (parent[curcode] == FREE_CODE) { - /* or (FLAG_BITS[curcode] & FREE_CODE)? */ - KwKwK = TRUE; - Trace((stderr, " (found a KwKwK code %d; oldcode = %d)\n", code, - oldcode)); - --newstr; /* last character will be same as first character */ - curcode = oldcode; - } else - KwKwK = FALSE; - - do { - *newstr-- = Value[curcode]; - curcode = (int16_t)(parent[curcode] & CODE_MASK); - } while (curcode != BOGUSCODE); - - len = (int)(stacktop - newstr++); - if (KwKwK) - *stacktop = *newstr; - - /*----------------------------------------------------------------------- - Write expanded string in reverse order to output buffer. - -----------------------------------------------------------------------*/ - - Trace((stderr, "code %4d; oldcode %4d; char %3d (%c); string [", code, - oldcode, (int)(*newstr), (*newstr<32 || *newstr>=127)? ' ':*newstr)); - - { - register uint8_t *p; - - for (p = newstr; p < newstr+len; ++p) { - *G.outptr++ = *p; - if (++G.outcnt == outbufsiz) { - flush(&G, G.outbuf, G.outcnt); - G.outptr = G.outbuf; - G.outcnt = 0L; - } - } - } - - /*----------------------------------------------------------------------- - Add new leaf (first character of newstr) to tree as child of oldcode. - -----------------------------------------------------------------------*/ - - /* search for freecode */ - freecode = (int16_t)(lastfreecode + 1); - /* add if-test before loop for speed? */ - while (parent[freecode] != FREE_CODE) - ++freecode; - lastfreecode = freecode; - Trace((stderr, "]; newcode %d\n", freecode)); - - Value[freecode] = *newstr; - parent[freecode] = oldcode; - oldcode = code; - - } while (!G.zipeof); - -/*--------------------------------------------------------------------------- - Flush any remaining data and return to sender... - ---------------------------------------------------------------------------*/ - - if (G.outcnt > 0L) - flush(&G, G.outbuf, G.outcnt); - - return G.status; - -} /* end function unshrink() */ - - - - - -/****************************/ -/* Function partial_clear() */ /* no longer recursive... */ -/****************************/ - -static void -partial_clear(struct globals *Gp) -{ -#define G (*Gp) - register int16_t code; - - /* clear all nodes which have no children (i.e., leaf nodes only) */ - - /* first loop: mark each parent as such */ - for (code = BOGUSCODE+1; code < HSIZE; ++code) { - register int16_t cparent = (int16_t)(parent[code] & CODE_MASK); - - if (cparent > BOGUSCODE && cparent != FREE_CODE) - FLAG_BITS[cparent] |= HAS_CHILD; /* set parent's child-bit */ - } - - /* second loop: clear all nodes *not* marked as parents; reset flag bits */ - for (code = BOGUSCODE+1; code < HSIZE; ++code) { - if (FLAG_BITS[code] & HAS_CHILD) /* just clear child-bit */ - FLAG_BITS[code] &= ~HAS_CHILD; - else { /* leaf: lose it */ - Trace((stderr, "%d\n", code)); - parent[code] = FREE_CODE; - } - } - - return; -} diff --git a/tools/cpio/src/unzip.h b/tools/cpio/src/unzip.h deleted file mode 100644 index d53f81024..000000000 --- a/tools/cpio/src/unzip.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Changes by Gunnar Ritter, Freiburg i. Br., Germany, May 2003. - * - * Derived from unzip 5.40. - * - * Sccsid @(#)unzip.h 1.5 (gritter) 7/16/04 - */ - -#include <inttypes.h> - -#define Trace(a) - -#define MAX_BITS 13 -#define HSIZE (1 << MAX_BITS) -#define WSIZE 65536L /* at least 64K for enhanced deflate */ - -#define redirSlide G.area.Slide - -#define NEXTBYTE (--G.incnt >= 0 ? (int)(*G.inptr++) : readbyte(&G)) - -#define READBITS(nbits, zdest) { \ - if (nbits > G.bits_left) { \ - int temp; \ - G.zipeof = 1; \ - while (G.bits_left <= 8 * (int)(sizeof G.bitbuf - 1) && \ - (temp = NEXTBYTE) != EOF) { \ - G.bitbuf |= (uint32_t)temp << G.bits_left; \ - G.bits_left += 8; \ - G.zipeof = 0; \ - } \ - } \ - zdest = (int16_t)((uint16_t)G.bitbuf & mask_bits[nbits]); \ - G.bitbuf >>= nbits; \ - G.bits_left -= nbits; \ -} - -#undef FALSE -#undef TRUE -enum { - FALSE = 0, - TRUE = 1 -}; - -union work { - struct { - int16_t Parent[HSIZE]; - uint8_t value[HSIZE]; - uint8_t Stack[HSIZE]; - } shrink; - uint8_t Slide[WSIZE]; -}; - -#define OUTBUFSIZ 4096 - -struct globals { - union work area; - uint8_t inbuf[4096]; - long long zsize; - long long uzsize; - uint8_t *inptr; - const char *tgt; - struct huft *fixed_tl; - struct huft *fixed_td; - struct huft *fixed_tl64; - struct huft *fixed_td64; - struct huft *fixed_tl32; - struct huft *fixed_td32; - const uint16_t *cplens; - const uint8_t *cplext; - const uint8_t *cpdext; - long csize; - long ucsize; - uint8_t outbuf[OUTBUFSIZ]; - uint8_t *outptr; - uint32_t *crc; - uint32_t bitbuf; - uint32_t wp; - uint32_t bb; - uint32_t bk; - unsigned outcnt; - int tfd; - int doswap; - int incnt; - int bits_left; - int zipeof; - int fixed_bl; - int fixed_bd; - int fixed_bl64; - int fixed_bd64; - int fixed_bl32; - int fixed_bd32; - int status; -}; - -/* Huffman code lookup table entry--this entry is four bytes for machines - that have 16-bit pointers (e.g. PC's in the small or medium model). - Valid extra bits are 0..13. e == 15 is EOB (end of block), e == 16 - means that v is a literal, 16 < e < 32 means that v is a pointer to - the next table, which codes e - 16 bits, and lastly e == 99 indicates - an unused code. If a code with e == 99 is looked up, this implies an - error in the data. */ - -struct huft { - uint8_t e; /* number of extra bits or operation */ - uint8_t b; /* number of bits in this code or subcode */ - union { - uint16_t n; /* literal, length base, or distance base */ - struct huft *t; /* pointer to next level of table */ - } v; -}; - -extern const uint16_t mask_bits[]; - -extern void flush(struct globals *, const void *, size_t); -extern int readbyte(struct globals *); - -extern int huft_build(const unsigned *b, unsigned n, unsigned s, - const uint16_t *d, const uint8_t *e, - struct huft **t, int *m, - int bits, int nob, int eob); -extern void huft_free(struct huft *); diff --git a/tools/cpio/src/utmpx.c b/tools/cpio/src/utmpx.c deleted file mode 100644 index d88a627a7..000000000 --- a/tools/cpio/src/utmpx.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright (c) 2004 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)utmpx.c 1.13 (gritter) 12/16/07 */ - -#include <stdio.h> - -#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \ - defined (__UCLIBC__) || defined (__OpenBSD__) || \ - defined (__DragonFly__) || \ - defined (__APPLE__) && \ - (__MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_OS_X_VERSION_10_5) -#include <sys/types.h> -#include <sys/time.h> -#include <utmp.h> -#include <string.h> - -#include "utmpx.h" - -static FILE *utfp; -static struct utmpx utx; -static const char *utmpfile = _PATH_UTMP; - -static FILE * -init(void) -{ - if (utfp == NULL && (utfp = fopen(utmpfile, "r+")) == NULL) - if ((utfp = fopen(utmpfile, "r")) == NULL) - return NULL; - return utfp; -} - -static struct utmpx * -utmp2utmpx(struct utmpx *ux, const struct utmp *up) -{ -#ifndef __dietlibc__ - memset(ux, 0, sizeof *ux); - ux->ut_tv.tv_sec = up->ut_time; - memcpy(ux->ut_line, up->ut_line, UT_LINESIZE); - memcpy(ux->ut_user, up->ut_name, UT_NAMESIZE); - memcpy(ux->ut_host, up->ut_host, UT_HOSTSIZE); - if (strcmp(up->ut_line, "~") == 0) - ux->ut_type = BOOT_TIME; - else if (strcmp(up->ut_line, "|") == 0) - ux->ut_type = OLD_TIME; - else if (strcmp(up->ut_line, "}") == 0) - ux->ut_type = NEW_TIME; - else if (*up->ut_name == 0) - ux->ut_type = DEAD_PROCESS; - else - ux->ut_type = USER_PROCESS; -#else /* __dietlibc__ */ - *ux = *up; -#endif /* __dietlibc__ */ - return ux; -} - -static struct utmp * -utmpx2utmp(struct utmp *up, const struct utmpx *ux) -{ -#ifndef __dietlibc__ - memset(up, 0, sizeof *up); - up->ut_time = ux->ut_tv.tv_sec; - switch (ux->ut_type) { - case DEAD_PROCESS: - memcpy(up->ut_line, ux->ut_line, UT_LINESIZE); - break; - default: - case EMPTY: - case INIT_PROCESS: - case LOGIN_PROCESS: - case RUN_LVL: - case ACCOUNTING: - return NULL; - case BOOT_TIME: - strcpy(up->ut_name, "reboot"); - strcpy(up->ut_line, "~"); - break; - case OLD_TIME: - strcpy(up->ut_name, "date"); - strcpy(up->ut_line, "|"); - break; - case NEW_TIME: - strcpy(up->ut_name, "date"); - strcpy(up->ut_line, "{"); - break; - case USER_PROCESS: - memcpy(up->ut_line, ux->ut_line, UT_LINESIZE); - memcpy(up->ut_name, ux->ut_user, UT_NAMESIZE); - memcpy(up->ut_host, ux->ut_host, UT_HOSTSIZE); - } -#else /* __dietlibc__ */ - *up = *ux; -#endif /* __dietlibc__ */ - return up; -} - -struct utmpx * -getutxent(void) -{ - static struct utmp zero; - struct utmp ut; - - if (init() == NULL) - return NULL; - do { - if (fread(&ut, sizeof ut, 1, utfp) != 1) - return NULL; - } while (memcmp(&ut, &zero, sizeof ut) == 0); - return utmp2utmpx(&utx, &ut); -} - -struct utmpx * -getutxline(const struct utmpx *ux) -{ - struct utmp ut; - - if (init() == NULL) - return NULL; - fseek(utfp, 0, SEEK_SET); - while (fread(&ut, sizeof ut, 1, utfp) == 1) { - utmp2utmpx(&utx, &ut); - if ((utx.ut_type == LOGIN_PROCESS || - utx.ut_type == USER_PROCESS) && - strcmp(ut.ut_line, utx.ut_line) == 0) - return &utx; - } - return NULL; -} - -struct utmpx * -getutxid(const struct utmpx *ux) -{ -#ifdef __dietlibc__ - struct utmp ut; -#endif - - if (init() == NULL) - return NULL; -#ifdef __dietlibc__ - fseek(utfp, 0, SEEK_SET); - while (fread(&ut, sizeof ut, 1, utfp) == 1) { - utmp2utmpx(&utx, &ut); - switch (ux->ut_type) { - case BOOT_TIME: - case OLD_TIME: - case NEW_TIME: - if (ux->ut_type == utx.ut_type) - return &utx; - break; - case INIT_PROCESS: - case LOGIN_PROCESS: - case USER_PROCESS: - case DEAD_PROCESS: - if (ux->ut_type == utx.ut_type && - ux->ut_id == utx.ut_id) - return &utx; - break; - } - } -#endif /* __dietlibc__ */ - return NULL; -} - -void -setutxent(void) -{ - if (init() == NULL) - return; - fseek(utfp, 0, SEEK_SET); -} - -void -endutxent(void) -{ - FILE *fp; - - if (init() == NULL) - return; - fp = utfp; - utfp = NULL; - fclose(fp); -} - -int -utmpxname(const char *name) -{ - utmpfile = strdup(name); - return 0; -} - -extern struct utmpx * -pututxline(const struct utmpx *up) -{ - struct utmp ut; - struct utmpx *rp; - - if (init() == NULL) - return NULL; - /* - * Cannot use getutxid() because there is no id field. Use - * the equivalent of getutxline() instead. - */ - while (fread(&ut, sizeof ut, 1, utfp) == 1) { - if (strncmp(ut.ut_line, up->ut_line, UT_LINESIZE) == 0) { - fseek(utfp, -sizeof ut, SEEK_CUR); - break; - } - } - fflush(utfp); - if (utmpx2utmp(&ut, up) == NULL) - rp = NULL; - else if (fwrite(&ut, sizeof ut, 1, utfp) == 1) { - utx = *up; - rp = &utx; - } else - rp = NULL; - fflush(utfp); - return rp; -} - -extern void -updwtmpx(const char *name, const struct utmpx *up) -{ - FILE *fp; - - if ((fp = fopen(name, "a")) == NULL) - return; - fwrite(up, sizeof *up, 1, fp); - fclose(fp); -} - -#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __UCLIBC__ || - __OpenBSD__ || __DragonFly__ || __APPLE__ */ diff --git a/tools/cpio/src/version.c b/tools/cpio/src/version.c deleted file mode 100644 index a9d4a4681..000000000 --- a/tools/cpio/src/version.c +++ /dev/null @@ -1,26 +0,0 @@ -#if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4 -#define USED __attribute__ ((used)) -#elif defined __GNUC__ -#define USED __attribute__ ((unused)) -#else -#define USED -#endif -static const char sccsid[] USED = "@(#)cpio.sl 2.9 (gritter) 8/14/09"; -/* SLIST */ -/* -blast.c: * Sccsid @(#)blast.c 1.2 (gritter) 2/17/04 -blast.h: * Sccsid @(#)blast.h 1.2 (gritter) 2/17/04 -cpio.c: * Sccsid @(#)cpio.c 1.305 (gritter) 8/14/09 -cpio.h: Sccsid @(#)cpio.h 1.29 (gritter) 3/26/07 -crc32.c: * Sccsid @(#)crc32.c 1.2 (gritter) 5/29/03 -expand.c: Sccsid @(#)expand.c 1.6 (gritter) 12/15/03 -explode.c: * Sccsid @(#)explode.c 1.6 (gritter) 9/30/03 -flags.c: Sccsid @(#)flags.c 1.6 (gritter) 3/26/07 -inflate.c: * Sccsid @(#)inflate.c 1.6 (gritter) 10/13/04 -nonpax.c: Sccsid @(#)nonpax.c 1.1 (gritter) 2/24/04 -pax.c:static const char sccsid[] USED = "@(#)pax_su3.sl 1.26 (gritter) 6/26/05"; -pax.c:static const char sccsid[] USED = "@(#)pax.sl 1.26 (gritter) 6/26/05"; -pax.c: Sccsid @(#)pax.c 1.26 (gritter) 6/26/05 -unshrink.c: * Sccsid @(#)unshrink.c 1.4 (gritter) 6/18/04 -unzip.h: * Sccsid @(#)unzip.h 1.5 (gritter) 7/16/04 -*/ diff --git a/tools/cpio/src/vpfmt.c b/tools/cpio/src/vpfmt.c deleted file mode 100644 index fdbb4ccb0..000000000 --- a/tools/cpio/src/vpfmt.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ -/* Sccsid @(#)vpfmt.c 1.2 (gritter) 9/21/03 */ - -#include <stdio.h> -#include <stdarg.h> - -#include "pfmt.h" - -extern char *pfmt_label__; - -/* - * Strip catalog and msgnum from s, but only if they actually appear. - */ -static const char * -begin(const char *s, long flags) -{ - const char *sp; - - if (flags & MM_NOGET) - return s; - sp = s; - if (*sp && *sp != ':') { - sp++; - while (*sp && *sp != '/' && *sp != ':' && sp - s < 14) - sp++; - } - if (*sp++ != ':') - return s; - while (*sp >= '0' && *sp <= '9') - sp++; - if (*sp++ != ':' || *sp == '\0') - return s; - return sp; -} - -int -vpfmt(FILE *stream, long flags, const char *fmt, va_list ap) -{ - int n = 0; - const char *severity = NULL; - char sevbuf[25]; - - if ((flags&MM_NOSTD) == 0) { - if (flags & MM_ACTION) - severity = "TO FIX"; - else switch (flags & 0377) { - case MM_HALT: - severity = "HALT"; - break; - case MM_WARNING: - severity = "WARNING"; - break; - case MM_INFO: - severity = "INFO"; - break; - case MM_ERROR: - severity = "ERROR"; - break; - default: - snprintf(sevbuf, sizeof sevbuf, "SEV=%ld", flags&0377); - severity = sevbuf; - } - if (pfmt_label__) - n = fprintf(stream, "%s: ", pfmt_label__); - if (severity) - n += fprintf(stream, "%s: ", severity); - } - n += vfprintf(stream, begin(fmt, flags), ap); - return n; -} |