/src/CMake/Utilities/cmlibarchive/libarchive/archive_pack_dev.c
Line | Count | Source |
1 | | /* $NetBSD: pack_dev.c,v 1.12 2013/06/14 16:28:20 tsutsui Exp $ */ |
2 | | |
3 | | /*- |
4 | | * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc. |
5 | | * All rights reserved. |
6 | | * |
7 | | * This code is derived from software contributed to The NetBSD Foundation |
8 | | * by Charles M. Hannum. |
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 | | /* Originally from NetBSD's mknod(8) source. */ |
33 | | |
34 | | #include "archive_platform.h" |
35 | | |
36 | | #ifdef HAVE_LIMITS_H |
37 | | #include <limits.h> |
38 | | #endif |
39 | | |
40 | | #include <stdio.h> |
41 | | #ifdef HAVE_STDLIB_H |
42 | | #include <stdlib.h> |
43 | | #endif |
44 | | #ifdef HAVE_STRING_H |
45 | | #include <string.h> |
46 | | #endif |
47 | | #ifdef HAVE_SYS_TYPES_H |
48 | | #include <sys/types.h> |
49 | | #endif |
50 | | #ifdef HAVE_SYS_STAT_H |
51 | | #include <sys/stat.h> |
52 | | #endif |
53 | | #if MAJOR_IN_MKDEV |
54 | | #include <sys/mkdev.h> |
55 | | #define HAVE_MAJOR |
56 | | #elif MAJOR_IN_SYSMACROS |
57 | | #include <sys/sysmacros.h> |
58 | | #define HAVE_MAJOR |
59 | | #endif |
60 | | #ifdef HAVE_UNISTD_H |
61 | | #include <unistd.h> |
62 | | #endif |
63 | | |
64 | | #include "archive_pack_dev.h" |
65 | | |
66 | | static pack_t pack_netbsd; |
67 | | static pack_t pack_freebsd; |
68 | | static pack_t pack_8_8; |
69 | | static pack_t pack_12_20; |
70 | | static pack_t pack_14_18; |
71 | | static pack_t pack_8_24; |
72 | | static pack_t pack_bsdos; |
73 | | static int __LA_LIBC_CC compare_format(const void *, const void *); |
74 | | |
75 | | static const char iMajorError[] = "invalid major number"; |
76 | | static const char iMinorError[] = "invalid minor number"; |
77 | | static const char tooManyFields[] = "too many fields for format"; |
78 | | |
79 | | /* This is blatantly stolen from libarchive/archive_entry.c, |
80 | | * in an attempt to get this to play nice on MinGW... */ |
81 | | #if !defined(HAVE_MAJOR) && !defined(major) |
82 | | /* Replacement for major/minor/makedev. */ |
83 | | #define major(x) ((int)(0x00ff & ((x) >> 8))) |
84 | | #define minor(x) ((int)(0xffff00ff & (x))) |
85 | | #define makedev(maj,min) ((0xff00 & ((maj)<<8)) | (0xffff00ff & (min))) |
86 | | #endif |
87 | | |
88 | | /* Play games to come up with a suitable makedev() definition. */ |
89 | | #ifdef __QNXNTO__ |
90 | | /* QNX. <sigh> */ |
91 | | #include <sys/netmgr.h> |
92 | | #define apd_makedev(maj, min) makedev(ND_LOCAL_NODE, (maj), (min)) |
93 | | #elif defined makedev |
94 | | /* There's a "makedev" macro. */ |
95 | 0 | #define apd_makedev(maj, min) makedev((maj), (min)) |
96 | | #elif defined mkdev || ((defined _WIN32 || defined __WIN32__) && !defined(__CYGWIN__)) |
97 | | /* Windows. <sigh> */ |
98 | | #define apd_makedev(maj, min) mkdev((maj), (min)) |
99 | | #else |
100 | | /* There's a "makedev" function. */ |
101 | | #define apd_makedev(maj, min) makedev((maj), (min)) |
102 | | #endif |
103 | | |
104 | | /* exported */ |
105 | | dev_t |
106 | | pack_native(int n, unsigned long numbers[], const char **error) |
107 | 0 | { |
108 | 0 | dev_t dev = 0; |
109 | |
|
110 | 0 | if (n == 2) { |
111 | 0 | dev = apd_makedev(numbers[0], numbers[1]); |
112 | 0 | if ((unsigned long)major(dev) != numbers[0]) |
113 | 0 | *error = iMajorError; |
114 | 0 | else if ((unsigned long)minor(dev) != numbers[1]) |
115 | 0 | *error = iMinorError; |
116 | 0 | } else |
117 | 0 | *error = tooManyFields; |
118 | 0 | return (dev); |
119 | 0 | } |
120 | | |
121 | | |
122 | | static dev_t |
123 | | pack_netbsd(int n, unsigned long numbers[], const char **error) |
124 | 0 | { |
125 | 0 | dev_t dev = 0; |
126 | |
|
127 | 0 | if (n == 2) { |
128 | 0 | dev = makedev_netbsd(numbers[0], numbers[1]); |
129 | 0 | if ((unsigned long)major_netbsd(dev) != numbers[0]) |
130 | 0 | *error = iMajorError; |
131 | 0 | else if ((unsigned long)minor_netbsd(dev) != numbers[1]) |
132 | 0 | *error = iMinorError; |
133 | 0 | } else |
134 | 0 | *error = tooManyFields; |
135 | 0 | return (dev); |
136 | 0 | } |
137 | | |
138 | | |
139 | 0 | #define major_freebsd(x) ((int32_t)(((x) & 0x0000ff00) >> 8)) |
140 | 0 | #define minor_freebsd(x) ((int32_t)(((x) & 0xffff00ff) >> 0)) |
141 | 0 | #define makedev_freebsd(x,y) ((dev_t)((((x) << 8) & 0x0000ff00) | \ |
142 | 0 | (((y) << 0) & 0xffff00ff))) |
143 | | |
144 | | static dev_t |
145 | | pack_freebsd(int n, unsigned long numbers[], const char **error) |
146 | 0 | { |
147 | 0 | dev_t dev = 0; |
148 | |
|
149 | 0 | if (n == 2) { |
150 | 0 | dev = makedev_freebsd(numbers[0], numbers[1]); |
151 | 0 | if ((unsigned long)major_freebsd(dev) != numbers[0]) |
152 | 0 | *error = iMajorError; |
153 | 0 | if ((unsigned long)minor_freebsd(dev) != numbers[1]) |
154 | 0 | *error = iMinorError; |
155 | 0 | } else |
156 | 0 | *error = tooManyFields; |
157 | 0 | return (dev); |
158 | 0 | } |
159 | | |
160 | | |
161 | 0 | #define major_8_8(x) ((int32_t)(((x) & 0x0000ff00) >> 8)) |
162 | 0 | #define minor_8_8(x) ((int32_t)(((x) & 0x000000ff) >> 0)) |
163 | 0 | #define makedev_8_8(x,y) ((dev_t)((((x) << 8) & 0x0000ff00) | \ |
164 | 0 | (((y) << 0) & 0x000000ff))) |
165 | | |
166 | | static dev_t |
167 | | pack_8_8(int n, unsigned long numbers[], const char **error) |
168 | 0 | { |
169 | 0 | dev_t dev = 0; |
170 | |
|
171 | 0 | if (n == 2) { |
172 | 0 | dev = makedev_8_8(numbers[0], numbers[1]); |
173 | 0 | if ((unsigned long)major_8_8(dev) != numbers[0]) |
174 | 0 | *error = iMajorError; |
175 | 0 | if ((unsigned long)minor_8_8(dev) != numbers[1]) |
176 | 0 | *error = iMinorError; |
177 | 0 | } else |
178 | 0 | *error = tooManyFields; |
179 | 0 | return (dev); |
180 | 0 | } |
181 | | |
182 | | |
183 | 0 | #define major_12_20(x) ((int32_t)(((x) & 0xfff00000) >> 20)) |
184 | 0 | #define minor_12_20(x) ((int32_t)(((x) & 0x000fffff) >> 0)) |
185 | 0 | #define makedev_12_20(x,y) ((dev_t)((((x) << 20) & 0xfff00000) | \ |
186 | 0 | (((y) << 0) & 0x000fffff))) |
187 | | |
188 | | static dev_t |
189 | | pack_12_20(int n, unsigned long numbers[], const char **error) |
190 | 0 | { |
191 | 0 | dev_t dev = 0; |
192 | |
|
193 | 0 | if (n == 2) { |
194 | 0 | dev = makedev_12_20(numbers[0], numbers[1]); |
195 | 0 | if ((unsigned long)major_12_20(dev) != numbers[0]) |
196 | 0 | *error = iMajorError; |
197 | 0 | if ((unsigned long)minor_12_20(dev) != numbers[1]) |
198 | 0 | *error = iMinorError; |
199 | 0 | } else |
200 | 0 | *error = tooManyFields; |
201 | 0 | return (dev); |
202 | 0 | } |
203 | | |
204 | | |
205 | 0 | #define major_14_18(x) ((int32_t)(((x) & 0xfffc0000) >> 18)) |
206 | 0 | #define minor_14_18(x) ((int32_t)(((x) & 0x0003ffff) >> 0)) |
207 | 0 | #define makedev_14_18(x,y) ((dev_t)((((x) << 18) & 0xfffc0000) | \ |
208 | 0 | (((y) << 0) & 0x0003ffff))) |
209 | | |
210 | | static dev_t |
211 | | pack_14_18(int n, unsigned long numbers[], const char **error) |
212 | 0 | { |
213 | 0 | dev_t dev = 0; |
214 | |
|
215 | 0 | if (n == 2) { |
216 | 0 | dev = makedev_14_18(numbers[0], numbers[1]); |
217 | 0 | if ((unsigned long)major_14_18(dev) != numbers[0]) |
218 | 0 | *error = iMajorError; |
219 | 0 | if ((unsigned long)minor_14_18(dev) != numbers[1]) |
220 | 0 | *error = iMinorError; |
221 | 0 | } else |
222 | 0 | *error = tooManyFields; |
223 | 0 | return (dev); |
224 | 0 | } |
225 | | |
226 | | |
227 | 0 | #define major_8_24(x) ((int32_t)(((x) & 0xff000000) >> 24)) |
228 | 0 | #define minor_8_24(x) ((int32_t)(((x) & 0x00ffffff) >> 0)) |
229 | 0 | #define makedev_8_24(x,y) ((dev_t)((((x) << 24) & 0xff000000) | \ |
230 | 0 | (((y) << 0) & 0x00ffffff))) |
231 | | |
232 | | static dev_t |
233 | | pack_8_24(int n, unsigned long numbers[], const char **error) |
234 | 0 | { |
235 | 0 | dev_t dev = 0; |
236 | |
|
237 | 0 | if (n == 2) { |
238 | 0 | dev = makedev_8_24(numbers[0], numbers[1]); |
239 | 0 | if ((unsigned long)major_8_24(dev) != numbers[0]) |
240 | 0 | *error = iMajorError; |
241 | 0 | if ((unsigned long)minor_8_24(dev) != numbers[1]) |
242 | 0 | *error = iMinorError; |
243 | 0 | } else |
244 | 0 | *error = tooManyFields; |
245 | 0 | return (dev); |
246 | 0 | } |
247 | | |
248 | | |
249 | 0 | #define major_12_12_8(x) ((int32_t)(((x) & 0xfff00000) >> 20)) |
250 | 0 | #define unit_12_12_8(x) ((int32_t)(((x) & 0x000fff00) >> 8)) |
251 | 0 | #define subunit_12_12_8(x) ((int32_t)(((x) & 0x000000ff) >> 0)) |
252 | 0 | #define makedev_12_12_8(x,y,z) ((dev_t)((((x) << 20) & 0xfff00000) | \ |
253 | 0 | (((y) << 8) & 0x000fff00) | \ |
254 | 0 | (((z) << 0) & 0x000000ff))) |
255 | | |
256 | | static dev_t |
257 | | pack_bsdos(int n, unsigned long numbers[], const char **error) |
258 | 0 | { |
259 | 0 | dev_t dev = 0; |
260 | |
|
261 | 0 | if (n == 2) { |
262 | 0 | dev = makedev_12_20(numbers[0], numbers[1]); |
263 | 0 | if ((unsigned long)major_12_20(dev) != numbers[0]) |
264 | 0 | *error = iMajorError; |
265 | 0 | if ((unsigned long)minor_12_20(dev) != numbers[1]) |
266 | 0 | *error = iMinorError; |
267 | 0 | } else if (n == 3) { |
268 | 0 | dev = makedev_12_12_8(numbers[0], numbers[1], numbers[2]); |
269 | 0 | if ((unsigned long)major_12_12_8(dev) != numbers[0]) |
270 | 0 | *error = iMajorError; |
271 | 0 | if ((unsigned long)unit_12_12_8(dev) != numbers[1]) |
272 | 0 | *error = "invalid unit number"; |
273 | 0 | if ((unsigned long)subunit_12_12_8(dev) != numbers[2]) |
274 | 0 | *error = "invalid subunit number"; |
275 | 0 | } else |
276 | 0 | *error = tooManyFields; |
277 | 0 | return (dev); |
278 | 0 | } |
279 | | |
280 | | |
281 | | /* list of formats and pack functions */ |
282 | | /* this list must be sorted lexically */ |
283 | | static const struct format { |
284 | | const char *name; |
285 | | pack_t *pack; |
286 | | } formats[] = { |
287 | | {"386bsd", pack_8_8}, |
288 | | {"4bsd", pack_8_8}, |
289 | | {"bsdos", pack_bsdos}, |
290 | | {"freebsd", pack_freebsd}, |
291 | | {"hpux", pack_8_24}, |
292 | | {"isc", pack_8_8}, |
293 | | {"linux", pack_8_8}, |
294 | | {"native", pack_native}, |
295 | | {"netbsd", pack_netbsd}, |
296 | | {"osf1", pack_12_20}, |
297 | | {"sco", pack_8_8}, |
298 | | {"solaris", pack_14_18}, |
299 | | {"sunos", pack_8_8}, |
300 | | {"svr3", pack_8_8}, |
301 | | {"svr4", pack_14_18}, |
302 | | {"ultrix", pack_8_8}, |
303 | | }; |
304 | | |
305 | | static int |
306 | | __LA_LIBC_CC |
307 | | compare_format(const void *key, const void *element) |
308 | 0 | { |
309 | 0 | const char *name; |
310 | 0 | const struct format *format; |
311 | |
|
312 | 0 | name = key; |
313 | 0 | format = element; |
314 | |
|
315 | 0 | return (strcmp(name, format->name)); |
316 | 0 | } |
317 | | |
318 | | |
319 | | pack_t * |
320 | | pack_find(const char *name) |
321 | 0 | { |
322 | 0 | struct format *format; |
323 | |
|
324 | 0 | format = bsearch(name, formats, |
325 | 0 | sizeof(formats)/sizeof(formats[0]), |
326 | 0 | sizeof(formats[0]), compare_format); |
327 | 0 | if (format == 0) |
328 | 0 | return (NULL); |
329 | 0 | return (format->pack); |
330 | 0 | } |