1 /*        $NetBSD: common.h,v 1.8 2017/07/29 21:04:07 riastradh Exp $ */
2 
3 /*-
4  * Copyright (c) 2013 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Taylor R. Campbell.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #ifndef   VNDCOMPRESS_COMMON_H
33 #define   VNDCOMPRESS_COMMON_H
34 
35 #include <sys/cdefs.h>
36 #include <sys/param.h>
37 
38 #include <limits.h>
39 #include <stdint.h>
40 
41 #ifndef __type_fit
42 
43 /* XXX Cruft from HEAD.  */
44 
45 #define __type_mask(t) (/*LINTED*/sizeof(t) < sizeof(intmax_t) ? \
46     (~((1ULL << (sizeof(t) * NBBY)) - 1)) : 0ULL)
47 
48 #define __zeroll() (0LL)
49 #define __negative_p(x) ((x) < 0)
50 
51 #define __type_min_s(t) ((t)((1ULL << (sizeof(t) * NBBY - 1))))
52 #define __type_max_s(t) ((t)~((1ULL << (sizeof(t) * NBBY - 1))))
53 #define __type_min_u(t) ((t)0ULL)
54 #define __type_max_u(t) ((t)~0ULL)
55 #define __type_is_signed(t) (/*LINTED*/__type_min_s(t) + (t)1 < (t)1)
56 #define __type_min(t) (__type_is_signed(t) ? __type_min_s(t) : __type_min_u(t))
57 #define __type_max(t) (__type_is_signed(t) ? __type_max_s(t) : __type_max_u(t))
58 
59 
60 #define __type_fit_u(t, a) (/*LINTED*/sizeof(t) < sizeof(intmax_t) ? \
61     (((a) & __type_mask(t)) == 0) : !__negative_p(a))
62 
63 #define __type_fit_s(t, a) (/*LINTED*/__negative_p(a) ? \
64     ((intmax_t)((a) + __zeroll()) >= (intmax_t)__type_min_s(t)) : \
65     ((intmax_t)((a) + __zeroll()) <= (intmax_t)__type_max_s(t)))
66 
67 /*
68  * return true if value 'a' fits in type 't'
69  */
70 #define __type_fit(t, a) (__type_is_signed(t) ? \
71     __type_fit_s(t, a) : __type_fit_u(t, a))
72 
73 #endif
74 
75 /* XXX urk */
76 #ifndef OFF_MAX
77 #define   OFF_MAX                       __type_max(off_t)
78 #endif
79 
80 /* XXX Why is this kernel-only?  */
81 #define   SET(t, f) ((t) |= (f))
82 #define   CLR(t, f) ((t) &= ~(f))
83 #define   ISSET(t, f)         ((t) & (f))
84 
85 /*
86  * Bounds checks for arithmetic.
87  */
88 #define   ADD_OK(T, A, B)     ((A) <= __type_max(T) - (B))
89 
90 #define   MUL_OK(T, A, B)     ((A) <= __type_max(T)/(B))
91 
92 #define   HOWMANY(X, N)                 (((X) + ((N) - 1))/(N))
93 #define   TOOMANY(T, X, N, M) (!ADD_OK(T, X, (N) - 1) || HOWMANY(X, N) > (M))
94 
95 /*
96  * We require:
97  *
98  *   0 < blocksize                      (duh)
99  *   blocksize % DEV_BSIZE == 0                   (for kernel use)
100  *
101  *   blocksize <= UINT32_MAX            (per the format)
102  *   blocksize*2 <= SIZE_MAX            (for a compression buffer)
103  *   blocksize*2 <= ULONG_MAX           (for zlib API)
104  */
105 #define   MIN_BLOCKSIZE                 DEV_BSIZE
106 #define   DEF_BLOCKSIZE                 0x10000
107 #define   MAX_BLOCKSIZE                                                                   \
108           rounddown(MIN(UINT32_MAX, (MIN(SIZE_MAX, ULONG_MAX) / 2)),  \
109               MIN_BLOCKSIZE)
110 
111 /*
112  * We require:
113  *
114  *   n_offsets * sizeof(uint64_t) <= SIZE_MAX     (array of 64-bit offsets)
115  *   n_blocks = (n_offsets + 1)                   (extra offset to set last block end)
116  *   n_blocks <= UINT32_MAX             (per the format)
117  *   n_offsets <= UINT32_MAX            (for the sake of simplicity)
118  */
119 #define   MAX_N_BLOCKS                                                                    \
120           (MIN(UINT32_MAX, (SIZE_MAX / sizeof(uint64_t))) - 1)
121 #define   MAX_N_OFFSETS                 (MAX_N_BLOCKS + 1)
122 
123 /*
124  * The window size is at most the number of offsets, or the largest
125  * uint32_t value.  The default window size is chosen so that windows
126  * fit in one 4096-byte page of memory.  We could use 64k bytes, or
127  * st_blksize, to maximize I/O transfer size, but the transfers won't
128  * be aligned without a lot of extra work.
129  */
130 #define   MAX_WINDOW_SIZE               MIN(UINT32_MAX, MAX_N_OFFSETS)
131 #define   DEF_WINDOW_SIZE               512
132 
133 struct cloop2_header {
134           char                cl2h_magic[128];
135           uint32_t  cl2h_blocksize;
136           uint32_t  cl2h_n_blocks;
137 } __packed;
138 
139 #define   CLOOP2_OFFSET_TABLE_OFFSET    136
140 
141 struct options {
142           int                 flags;
143 #define   FLAG_c    0x0001    /* Compress */
144 #define   FLAG_d    0x0002    /* Decompress */
145 #define   FLAG_p    0x0004    /* Partial */
146 #define   FLAG_r    0x0008    /* Restart */
147 #define   FLAG_b    0x0010    /* Block size */
148 #define   FLAG_R    0x0020    /* abort on Restart failure */
149 #define   FLAG_k    0x0040    /* checKpoint blocks */
150 #define   FLAG_l    0x0080    /* Length of input */
151 #define   FLAG_w    0x0100    /* Window size */
152           uint32_t  blocksize;
153           uint32_t  end_block;          /* end for partial transfer */
154           uint32_t  checkpoint_blocks;  /* blocks before checkpoint */
155           uint64_t  length;                       /* length of image in bytes */
156           uint32_t  window_size;        /* size of window into offset table */
157 };
158 
159 int       vndcompress(int, char **, const struct options *);
160 int       vnduncompress(int, char **, const struct options *);
161 void      usage(void) __dead;
162 
163 static const char cloop2_magic[] = "\
164 #!/bin/sh\n\
165 #V2.0 Format\n\
166 insmod cloop.o file=$0 && mount -r -t iso9660 /dev/cloop $1\n\
167 exit $?\n\
168 ";
169 
170 #endif    /* VNDCOMPRESS_COMMON_H */
171