1 |
174 |
hellwig |
/* $NetBSD: pack_dev.c,v 1.11 2011/08/27 18:37:41 joerg 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 |
|
|
#if HAVE_NBTOOL_CONFIG_H
|
33 |
|
|
#include "nbtool_config.h"
|
34 |
|
|
#endif
|
35 |
|
|
|
36 |
|
|
#include <sys/cdefs.h>
|
37 |
|
|
|
38 |
|
|
#include <sys/types.h>
|
39 |
|
|
#include <sys/stat.h>
|
40 |
|
|
|
41 |
|
|
#include <limits.h>
|
42 |
|
|
#include <stdio.h>
|
43 |
|
|
#include <stdlib.h>
|
44 |
|
|
#include <string.h>
|
45 |
|
|
#include <unistd.h>
|
46 |
|
|
|
47 |
|
|
#include "pack_dev.h"
|
48 |
|
|
|
49 |
|
|
static pack_t pack_netbsd;
|
50 |
|
|
static pack_t pack_freebsd;
|
51 |
|
|
static pack_t pack_8_8;
|
52 |
|
|
static pack_t pack_12_20;
|
53 |
|
|
static pack_t pack_14_18;
|
54 |
|
|
static pack_t pack_8_24;
|
55 |
|
|
static pack_t pack_bsdos;
|
56 |
|
|
static int compare_format(const void *, const void *);
|
57 |
|
|
|
58 |
|
|
static const char iMajorError[] = "invalid major number";
|
59 |
|
|
static const char iMinorError[] = "invalid minor number";
|
60 |
|
|
static const char tooManyFields[] = "too many fields for format";
|
61 |
|
|
|
62 |
|
|
/* exported */
|
63 |
|
|
portdev_t
|
64 |
|
|
pack_native(int n, u_long numbers[], const char **error)
|
65 |
|
|
{
|
66 |
|
|
portdev_t dev = 0;
|
67 |
|
|
|
68 |
|
|
if (n == 2) {
|
69 |
|
|
dev = makedev(numbers[0], numbers[1]);
|
70 |
|
|
if ((u_long)major(dev) != numbers[0])
|
71 |
|
|
*error = iMajorError;
|
72 |
|
|
else if ((u_long)minor(dev) != numbers[1])
|
73 |
|
|
*error = iMinorError;
|
74 |
|
|
} else
|
75 |
|
|
*error = tooManyFields;
|
76 |
|
|
return (dev);
|
77 |
|
|
}
|
78 |
|
|
|
79 |
|
|
|
80 |
|
|
static portdev_t
|
81 |
|
|
pack_netbsd(int n, u_long numbers[], const char **error)
|
82 |
|
|
{
|
83 |
|
|
portdev_t dev = 0;
|
84 |
|
|
|
85 |
|
|
if (n == 2) {
|
86 |
|
|
dev = makedev_netbsd(numbers[0], numbers[1]);
|
87 |
|
|
if ((u_long)major_netbsd(dev) != numbers[0])
|
88 |
|
|
*error = iMajorError;
|
89 |
|
|
else if ((u_long)minor_netbsd(dev) != numbers[1])
|
90 |
|
|
*error = iMinorError;
|
91 |
|
|
} else
|
92 |
|
|
*error = tooManyFields;
|
93 |
|
|
return (dev);
|
94 |
|
|
}
|
95 |
|
|
|
96 |
|
|
|
97 |
|
|
#define major_freebsd(x) ((int32_t)(((x) & 0x0000ff00) >> 8))
|
98 |
|
|
#define minor_freebsd(x) ((int32_t)(((x) & 0xffff00ff) >> 0))
|
99 |
|
|
#define makedev_freebsd(x,y) ((portdev_t)((((x) << 8) & 0x0000ff00) | \
|
100 |
|
|
(((y) << 0) & 0xffff00ff)))
|
101 |
|
|
|
102 |
|
|
static portdev_t
|
103 |
|
|
pack_freebsd(int n, u_long numbers[], const char **error)
|
104 |
|
|
{
|
105 |
|
|
portdev_t dev = 0;
|
106 |
|
|
|
107 |
|
|
if (n == 2) {
|
108 |
|
|
dev = makedev_freebsd(numbers[0], numbers[1]);
|
109 |
|
|
if ((u_long)major_freebsd(dev) != numbers[0])
|
110 |
|
|
*error = iMajorError;
|
111 |
|
|
if ((u_long)minor_freebsd(dev) != numbers[1])
|
112 |
|
|
*error = iMinorError;
|
113 |
|
|
} else
|
114 |
|
|
*error = tooManyFields;
|
115 |
|
|
return (dev);
|
116 |
|
|
}
|
117 |
|
|
|
118 |
|
|
|
119 |
|
|
#define major_8_8(x) ((int32_t)(((x) & 0x0000ff00) >> 8))
|
120 |
|
|
#define minor_8_8(x) ((int32_t)(((x) & 0x000000ff) >> 0))
|
121 |
|
|
#define makedev_8_8(x,y) ((portdev_t)((((x) << 8) & 0x0000ff00) | \
|
122 |
|
|
(((y) << 0) & 0x000000ff)))
|
123 |
|
|
|
124 |
|
|
static portdev_t
|
125 |
|
|
pack_8_8(int n, u_long numbers[], const char **error)
|
126 |
|
|
{
|
127 |
|
|
portdev_t dev = 0;
|
128 |
|
|
|
129 |
|
|
if (n == 2) {
|
130 |
|
|
dev = makedev_8_8(numbers[0], numbers[1]);
|
131 |
|
|
if ((u_long)major_8_8(dev) != numbers[0])
|
132 |
|
|
*error = iMajorError;
|
133 |
|
|
if ((u_long)minor_8_8(dev) != numbers[1])
|
134 |
|
|
*error = iMinorError;
|
135 |
|
|
} else
|
136 |
|
|
*error = tooManyFields;
|
137 |
|
|
return (dev);
|
138 |
|
|
}
|
139 |
|
|
|
140 |
|
|
|
141 |
|
|
#define major_12_20(x) ((int32_t)(((x) & 0xfff00000) >> 20))
|
142 |
|
|
#define minor_12_20(x) ((int32_t)(((x) & 0x000fffff) >> 0))
|
143 |
|
|
#define makedev_12_20(x,y) ((portdev_t)((((x) << 20) & 0xfff00000) | \
|
144 |
|
|
(((y) << 0) & 0x000fffff)))
|
145 |
|
|
|
146 |
|
|
static portdev_t
|
147 |
|
|
pack_12_20(int n, u_long numbers[], const char **error)
|
148 |
|
|
{
|
149 |
|
|
portdev_t dev = 0;
|
150 |
|
|
|
151 |
|
|
if (n == 2) {
|
152 |
|
|
dev = makedev_12_20(numbers[0], numbers[1]);
|
153 |
|
|
if ((u_long)major_12_20(dev) != numbers[0])
|
154 |
|
|
*error = iMajorError;
|
155 |
|
|
if ((u_long)minor_12_20(dev) != numbers[1])
|
156 |
|
|
*error = iMinorError;
|
157 |
|
|
} else
|
158 |
|
|
*error = tooManyFields;
|
159 |
|
|
return (dev);
|
160 |
|
|
}
|
161 |
|
|
|
162 |
|
|
|
163 |
|
|
#define major_14_18(x) ((int32_t)(((x) & 0xfffc0000) >> 18))
|
164 |
|
|
#define minor_14_18(x) ((int32_t)(((x) & 0x0003ffff) >> 0))
|
165 |
|
|
#define makedev_14_18(x,y) ((portdev_t)((((x) << 18) & 0xfffc0000) | \
|
166 |
|
|
(((y) << 0) & 0x0003ffff)))
|
167 |
|
|
|
168 |
|
|
static portdev_t
|
169 |
|
|
pack_14_18(int n, u_long numbers[], const char **error)
|
170 |
|
|
{
|
171 |
|
|
portdev_t dev = 0;
|
172 |
|
|
|
173 |
|
|
if (n == 2) {
|
174 |
|
|
dev = makedev_14_18(numbers[0], numbers[1]);
|
175 |
|
|
if ((u_long)major_14_18(dev) != numbers[0])
|
176 |
|
|
*error = iMajorError;
|
177 |
|
|
if ((u_long)minor_14_18(dev) != numbers[1])
|
178 |
|
|
*error = iMinorError;
|
179 |
|
|
} else
|
180 |
|
|
*error = tooManyFields;
|
181 |
|
|
return (dev);
|
182 |
|
|
}
|
183 |
|
|
|
184 |
|
|
|
185 |
|
|
#define major_8_24(x) ((int32_t)(((x) & 0xff000000) >> 24))
|
186 |
|
|
#define minor_8_24(x) ((int32_t)(((x) & 0x00ffffff) >> 0))
|
187 |
|
|
#define makedev_8_24(x,y) ((portdev_t)((((x) << 24) & 0xff000000) | \
|
188 |
|
|
(((y) << 0) & 0x00ffffff)))
|
189 |
|
|
|
190 |
|
|
static portdev_t
|
191 |
|
|
pack_8_24(int n, u_long numbers[], const char **error)
|
192 |
|
|
{
|
193 |
|
|
portdev_t dev = 0;
|
194 |
|
|
|
195 |
|
|
if (n == 2) {
|
196 |
|
|
dev = makedev_8_24(numbers[0], numbers[1]);
|
197 |
|
|
if ((u_long)major_8_24(dev) != numbers[0])
|
198 |
|
|
*error = iMajorError;
|
199 |
|
|
if ((u_long)minor_8_24(dev) != numbers[1])
|
200 |
|
|
*error = iMinorError;
|
201 |
|
|
} else
|
202 |
|
|
*error = tooManyFields;
|
203 |
|
|
return (dev);
|
204 |
|
|
}
|
205 |
|
|
|
206 |
|
|
|
207 |
|
|
#define major_12_12_8(x) ((int32_t)(((x) & 0xfff00000) >> 20))
|
208 |
|
|
#define unit_12_12_8(x) ((int32_t)(((x) & 0x000fff00) >> 8))
|
209 |
|
|
#define subunit_12_12_8(x) ((int32_t)(((x) & 0x000000ff) >> 0))
|
210 |
|
|
#define makedev_12_12_8(x,y,z) ((portdev_t)((((x) << 20) & 0xfff00000) | \
|
211 |
|
|
(((y) << 8) & 0x000fff00) | \
|
212 |
|
|
(((z) << 0) & 0x000000ff)))
|
213 |
|
|
|
214 |
|
|
static portdev_t
|
215 |
|
|
pack_bsdos(int n, u_long numbers[], const char **error)
|
216 |
|
|
{
|
217 |
|
|
portdev_t dev = 0;
|
218 |
|
|
|
219 |
|
|
if (n == 2) {
|
220 |
|
|
dev = makedev_12_20(numbers[0], numbers[1]);
|
221 |
|
|
if ((u_long)major_12_20(dev) != numbers[0])
|
222 |
|
|
*error = iMajorError;
|
223 |
|
|
if ((u_long)minor_12_20(dev) != numbers[1])
|
224 |
|
|
*error = iMinorError;
|
225 |
|
|
} else if (n == 3) {
|
226 |
|
|
dev = makedev_12_12_8(numbers[0], numbers[1], numbers[2]);
|
227 |
|
|
if ((u_long)major_12_12_8(dev) != numbers[0])
|
228 |
|
|
*error = iMajorError;
|
229 |
|
|
if ((u_long)unit_12_12_8(dev) != numbers[1])
|
230 |
|
|
*error = "invalid unit number";
|
231 |
|
|
if ((u_long)subunit_12_12_8(dev) != numbers[2])
|
232 |
|
|
*error = "invalid subunit number";
|
233 |
|
|
} else
|
234 |
|
|
*error = tooManyFields;
|
235 |
|
|
return (dev);
|
236 |
|
|
}
|
237 |
|
|
|
238 |
|
|
|
239 |
|
|
/* list of formats and pack functions */
|
240 |
|
|
/* this list must be sorted lexically */
|
241 |
|
|
static struct format {
|
242 |
|
|
const char *name;
|
243 |
|
|
pack_t *pack;
|
244 |
|
|
} formats[] = {
|
245 |
|
|
{"386bsd", pack_8_8},
|
246 |
|
|
{"4bsd", pack_8_8},
|
247 |
|
|
{"bsdos", pack_bsdos},
|
248 |
|
|
{"freebsd", pack_freebsd},
|
249 |
|
|
{"hpux", pack_8_24},
|
250 |
|
|
{"isc", pack_8_8},
|
251 |
|
|
{"linux", pack_8_8},
|
252 |
|
|
{"native", pack_native},
|
253 |
|
|
{"netbsd", pack_netbsd},
|
254 |
|
|
{"osf1", pack_12_20},
|
255 |
|
|
{"sco", pack_8_8},
|
256 |
|
|
{"solaris", pack_14_18},
|
257 |
|
|
{"sunos", pack_8_8},
|
258 |
|
|
{"svr3", pack_8_8},
|
259 |
|
|
{"svr4", pack_14_18},
|
260 |
|
|
{"ultrix", pack_8_8},
|
261 |
|
|
};
|
262 |
|
|
|
263 |
|
|
static int
|
264 |
|
|
compare_format(const void *key, const void *element)
|
265 |
|
|
{
|
266 |
|
|
const char *name;
|
267 |
|
|
const struct format *format;
|
268 |
|
|
|
269 |
|
|
name = key;
|
270 |
|
|
format = element;
|
271 |
|
|
|
272 |
|
|
return (strcmp(name, format->name));
|
273 |
|
|
}
|
274 |
|
|
|
275 |
|
|
|
276 |
|
|
pack_t *
|
277 |
|
|
pack_find(const char *name)
|
278 |
|
|
{
|
279 |
|
|
struct format *format;
|
280 |
|
|
|
281 |
|
|
format = bsearch(name, formats,
|
282 |
|
|
sizeof(formats)/sizeof(formats[0]),
|
283 |
|
|
sizeof(formats[0]), compare_format);
|
284 |
|
|
if (format == 0)
|
285 |
|
|
return (NULL);
|
286 |
|
|
return (format->pack);
|
287 |
|
|
}
|