1a43287ccSSascha Wildner /* $NetBSD: pack_dev.c,v 1.12 2013/06/14 16:28:20 tsutsui Exp $ */ 2a43287ccSSascha Wildner 3a43287ccSSascha Wildner /*- 4a43287ccSSascha Wildner * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc. 5a43287ccSSascha Wildner * All rights reserved. 6a43287ccSSascha Wildner * 7a43287ccSSascha Wildner * This code is derived from software contributed to The NetBSD Foundation 8a43287ccSSascha Wildner * by Charles M. Hannum. 9a43287ccSSascha Wildner * 10a43287ccSSascha Wildner * Redistribution and use in source and binary forms, with or without 11a43287ccSSascha Wildner * modification, are permitted provided that the following conditions 12a43287ccSSascha Wildner * are met: 13a43287ccSSascha Wildner * 1. Redistributions of source code must retain the above copyright 14a43287ccSSascha Wildner * notice, this list of conditions and the following disclaimer. 15a43287ccSSascha Wildner * 2. Redistributions in binary form must reproduce the above copyright 16a43287ccSSascha Wildner * notice, this list of conditions and the following disclaimer in the 17a43287ccSSascha Wildner * documentation and/or other materials provided with the distribution. 18a43287ccSSascha Wildner * 19a43287ccSSascha Wildner * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20a43287ccSSascha Wildner * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21a43287ccSSascha Wildner * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22a43287ccSSascha Wildner * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23a43287ccSSascha Wildner * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24a43287ccSSascha Wildner * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25a43287ccSSascha Wildner * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26a43287ccSSascha Wildner * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27a43287ccSSascha Wildner * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28a43287ccSSascha Wildner * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29a43287ccSSascha Wildner * POSSIBILITY OF SUCH DAMAGE. 30a43287ccSSascha Wildner */ 31a43287ccSSascha Wildner 32a43287ccSSascha Wildner #if HAVE_NBTOOL_CONFIG_H 33a43287ccSSascha Wildner #include "nbtool_config.h" 34a43287ccSSascha Wildner #endif 35a43287ccSSascha Wildner 36a43287ccSSascha Wildner #include <sys/types.h> 37a43287ccSSascha Wildner #include <sys/stat.h> 38a43287ccSSascha Wildner 39a43287ccSSascha Wildner #include <limits.h> 40a43287ccSSascha Wildner #include <stdio.h> 41a43287ccSSascha Wildner #include <stdlib.h> 42a43287ccSSascha Wildner #include <string.h> 43a43287ccSSascha Wildner #include <unistd.h> 44a43287ccSSascha Wildner 45a43287ccSSascha Wildner #include "pack_dev.h" 46a43287ccSSascha Wildner 47a43287ccSSascha Wildner static pack_t pack_netbsd; 48a43287ccSSascha Wildner static pack_t pack_freebsd; 49a43287ccSSascha Wildner static pack_t pack_8_8; 50a43287ccSSascha Wildner static pack_t pack_12_20; 51a43287ccSSascha Wildner static pack_t pack_14_18; 52a43287ccSSascha Wildner static pack_t pack_8_24; 53a43287ccSSascha Wildner static pack_t pack_bsdos; 54a43287ccSSascha Wildner static int compare_format(const void *, const void *); 55a43287ccSSascha Wildner 56a43287ccSSascha Wildner static const char iMajorError[] = "invalid major number"; 57a43287ccSSascha Wildner static const char iMinorError[] = "invalid minor number"; 58a43287ccSSascha Wildner static const char tooManyFields[] = "too many fields for format"; 59a43287ccSSascha Wildner 60a43287ccSSascha Wildner /* exported */ 61a43287ccSSascha Wildner dev_t 62a43287ccSSascha Wildner pack_native(int n, u_long numbers[], const char **error) 63a43287ccSSascha Wildner { 64a43287ccSSascha Wildner dev_t dev = 0; 65a43287ccSSascha Wildner 66a43287ccSSascha Wildner if (n == 2) { 67a43287ccSSascha Wildner dev = makedev(numbers[0], numbers[1]); 68a43287ccSSascha Wildner if ((u_long)major(dev) != numbers[0]) 69a43287ccSSascha Wildner *error = iMajorError; 70a43287ccSSascha Wildner else if ((u_long)minor(dev) != numbers[1]) 71a43287ccSSascha Wildner *error = iMinorError; 72a43287ccSSascha Wildner } else 73a43287ccSSascha Wildner *error = tooManyFields; 74a43287ccSSascha Wildner return (dev); 75a43287ccSSascha Wildner } 76a43287ccSSascha Wildner 77a43287ccSSascha Wildner 78a43287ccSSascha Wildner static dev_t 79a43287ccSSascha Wildner pack_netbsd(int n, u_long numbers[], const char **error) 80a43287ccSSascha Wildner { 81a43287ccSSascha Wildner dev_t dev = 0; 82a43287ccSSascha Wildner 83a43287ccSSascha Wildner if (n == 2) { 84a43287ccSSascha Wildner dev = makedev_netbsd(numbers[0], numbers[1]); 85a43287ccSSascha Wildner if ((u_long)major_netbsd(dev) != numbers[0]) 86a43287ccSSascha Wildner *error = iMajorError; 87a43287ccSSascha Wildner else if ((u_long)minor_netbsd(dev) != numbers[1]) 88a43287ccSSascha Wildner *error = iMinorError; 89a43287ccSSascha Wildner } else 90a43287ccSSascha Wildner *error = tooManyFields; 91a43287ccSSascha Wildner return (dev); 92a43287ccSSascha Wildner } 93a43287ccSSascha Wildner 94a43287ccSSascha Wildner 95a43287ccSSascha Wildner #define major_freebsd(x) ((int32_t)(((x) & 0x0000ff00) >> 8)) 96a43287ccSSascha Wildner #define minor_freebsd(x) ((int32_t)(((x) & 0xffff00ff) >> 0)) 97a43287ccSSascha Wildner #define makedev_freebsd(x,y) ((dev_t)((((x) << 8) & 0x0000ff00) | \ 98a43287ccSSascha Wildner (((y) << 0) & 0xffff00ff))) 99a43287ccSSascha Wildner 100a43287ccSSascha Wildner static dev_t 101a43287ccSSascha Wildner pack_freebsd(int n, u_long numbers[], const char **error) 102a43287ccSSascha Wildner { 103a43287ccSSascha Wildner dev_t dev = 0; 104a43287ccSSascha Wildner 105a43287ccSSascha Wildner if (n == 2) { 106a43287ccSSascha Wildner dev = makedev_freebsd(numbers[0], numbers[1]); 107a43287ccSSascha Wildner if ((u_long)major_freebsd(dev) != numbers[0]) 108a43287ccSSascha Wildner *error = iMajorError; 109a43287ccSSascha Wildner if ((u_long)minor_freebsd(dev) != numbers[1]) 110a43287ccSSascha Wildner *error = iMinorError; 111a43287ccSSascha Wildner } else 112a43287ccSSascha Wildner *error = tooManyFields; 113a43287ccSSascha Wildner return (dev); 114a43287ccSSascha Wildner } 115a43287ccSSascha Wildner 116a43287ccSSascha Wildner 117a43287ccSSascha Wildner #define major_8_8(x) ((int32_t)(((x) & 0x0000ff00) >> 8)) 118a43287ccSSascha Wildner #define minor_8_8(x) ((int32_t)(((x) & 0x000000ff) >> 0)) 119a43287ccSSascha Wildner #define makedev_8_8(x,y) ((dev_t)((((x) << 8) & 0x0000ff00) | \ 120a43287ccSSascha Wildner (((y) << 0) & 0x000000ff))) 121a43287ccSSascha Wildner 122a43287ccSSascha Wildner static dev_t 123a43287ccSSascha Wildner pack_8_8(int n, u_long numbers[], const char **error) 124a43287ccSSascha Wildner { 125a43287ccSSascha Wildner dev_t dev = 0; 126a43287ccSSascha Wildner 127a43287ccSSascha Wildner if (n == 2) { 128a43287ccSSascha Wildner dev = makedev_8_8(numbers[0], numbers[1]); 129a43287ccSSascha Wildner if ((u_long)major_8_8(dev) != numbers[0]) 130a43287ccSSascha Wildner *error = iMajorError; 131a43287ccSSascha Wildner if ((u_long)minor_8_8(dev) != numbers[1]) 132a43287ccSSascha Wildner *error = iMinorError; 133a43287ccSSascha Wildner } else 134a43287ccSSascha Wildner *error = tooManyFields; 135a43287ccSSascha Wildner return (dev); 136a43287ccSSascha Wildner } 137a43287ccSSascha Wildner 138a43287ccSSascha Wildner 139a43287ccSSascha Wildner #define major_12_20(x) ((int32_t)(((x) & 0xfff00000) >> 20)) 140a43287ccSSascha Wildner #define minor_12_20(x) ((int32_t)(((x) & 0x000fffff) >> 0)) 141a43287ccSSascha Wildner #define makedev_12_20(x,y) ((dev_t)((((x) << 20) & 0xfff00000) | \ 142a43287ccSSascha Wildner (((y) << 0) & 0x000fffff))) 143a43287ccSSascha Wildner 144a43287ccSSascha Wildner static dev_t 145a43287ccSSascha Wildner pack_12_20(int n, u_long numbers[], const char **error) 146a43287ccSSascha Wildner { 147a43287ccSSascha Wildner dev_t dev = 0; 148a43287ccSSascha Wildner 149a43287ccSSascha Wildner if (n == 2) { 150a43287ccSSascha Wildner dev = makedev_12_20(numbers[0], numbers[1]); 151a43287ccSSascha Wildner if ((u_long)major_12_20(dev) != numbers[0]) 152a43287ccSSascha Wildner *error = iMajorError; 153a43287ccSSascha Wildner if ((u_long)minor_12_20(dev) != numbers[1]) 154a43287ccSSascha Wildner *error = iMinorError; 155a43287ccSSascha Wildner } else 156a43287ccSSascha Wildner *error = tooManyFields; 157a43287ccSSascha Wildner return (dev); 158a43287ccSSascha Wildner } 159a43287ccSSascha Wildner 160a43287ccSSascha Wildner 161a43287ccSSascha Wildner #define major_14_18(x) ((int32_t)(((x) & 0xfffc0000) >> 18)) 162a43287ccSSascha Wildner #define minor_14_18(x) ((int32_t)(((x) & 0x0003ffff) >> 0)) 163a43287ccSSascha Wildner #define makedev_14_18(x,y) ((dev_t)((((x) << 18) & 0xfffc0000) | \ 164a43287ccSSascha Wildner (((y) << 0) & 0x0003ffff))) 165a43287ccSSascha Wildner 166a43287ccSSascha Wildner static dev_t 167a43287ccSSascha Wildner pack_14_18(int n, u_long numbers[], const char **error) 168a43287ccSSascha Wildner { 169a43287ccSSascha Wildner dev_t dev = 0; 170a43287ccSSascha Wildner 171a43287ccSSascha Wildner if (n == 2) { 172a43287ccSSascha Wildner dev = makedev_14_18(numbers[0], numbers[1]); 173a43287ccSSascha Wildner if ((u_long)major_14_18(dev) != numbers[0]) 174a43287ccSSascha Wildner *error = iMajorError; 175a43287ccSSascha Wildner if ((u_long)minor_14_18(dev) != numbers[1]) 176a43287ccSSascha Wildner *error = iMinorError; 177a43287ccSSascha Wildner } else 178a43287ccSSascha Wildner *error = tooManyFields; 179a43287ccSSascha Wildner return (dev); 180a43287ccSSascha Wildner } 181a43287ccSSascha Wildner 182a43287ccSSascha Wildner 183a43287ccSSascha Wildner #define major_8_24(x) ((int32_t)(((x) & 0xff000000) >> 24)) 184a43287ccSSascha Wildner #define minor_8_24(x) ((int32_t)(((x) & 0x00ffffff) >> 0)) 185a43287ccSSascha Wildner #define makedev_8_24(x,y) ((dev_t)((((x) << 24) & 0xff000000) | \ 186a43287ccSSascha Wildner (((y) << 0) & 0x00ffffff))) 187a43287ccSSascha Wildner 188a43287ccSSascha Wildner static dev_t 189a43287ccSSascha Wildner pack_8_24(int n, u_long numbers[], const char **error) 190a43287ccSSascha Wildner { 191a43287ccSSascha Wildner dev_t dev = 0; 192a43287ccSSascha Wildner 193a43287ccSSascha Wildner if (n == 2) { 194a43287ccSSascha Wildner dev = makedev_8_24(numbers[0], numbers[1]); 195a43287ccSSascha Wildner if ((u_long)major_8_24(dev) != numbers[0]) 196a43287ccSSascha Wildner *error = iMajorError; 197a43287ccSSascha Wildner if ((u_long)minor_8_24(dev) != numbers[1]) 198a43287ccSSascha Wildner *error = iMinorError; 199a43287ccSSascha Wildner } else 200a43287ccSSascha Wildner *error = tooManyFields; 201a43287ccSSascha Wildner return (dev); 202a43287ccSSascha Wildner } 203a43287ccSSascha Wildner 204a43287ccSSascha Wildner 205a43287ccSSascha Wildner #define major_12_12_8(x) ((int32_t)(((x) & 0xfff00000) >> 20)) 206a43287ccSSascha Wildner #define unit_12_12_8(x) ((int32_t)(((x) & 0x000fff00) >> 8)) 207a43287ccSSascha Wildner #define subunit_12_12_8(x) ((int32_t)(((x) & 0x000000ff) >> 0)) 208a43287ccSSascha Wildner #define makedev_12_12_8(x,y,z) ((dev_t)((((x) << 20) & 0xfff00000) | \ 209a43287ccSSascha Wildner (((y) << 8) & 0x000fff00) | \ 210a43287ccSSascha Wildner (((z) << 0) & 0x000000ff))) 211a43287ccSSascha Wildner 212a43287ccSSascha Wildner static dev_t 213a43287ccSSascha Wildner pack_bsdos(int n, u_long numbers[], const char **error) 214a43287ccSSascha Wildner { 215a43287ccSSascha Wildner dev_t dev = 0; 216a43287ccSSascha Wildner 217a43287ccSSascha Wildner if (n == 2) { 218a43287ccSSascha Wildner dev = makedev_12_20(numbers[0], numbers[1]); 219a43287ccSSascha Wildner if ((u_long)major_12_20(dev) != numbers[0]) 220a43287ccSSascha Wildner *error = iMajorError; 221a43287ccSSascha Wildner if ((u_long)minor_12_20(dev) != numbers[1]) 222a43287ccSSascha Wildner *error = iMinorError; 223a43287ccSSascha Wildner } else if (n == 3) { 224a43287ccSSascha Wildner dev = makedev_12_12_8(numbers[0], numbers[1], numbers[2]); 225a43287ccSSascha Wildner if ((u_long)major_12_12_8(dev) != numbers[0]) 226a43287ccSSascha Wildner *error = iMajorError; 227a43287ccSSascha Wildner if ((u_long)unit_12_12_8(dev) != numbers[1]) 228a43287ccSSascha Wildner *error = "invalid unit number"; 229a43287ccSSascha Wildner if ((u_long)subunit_12_12_8(dev) != numbers[2]) 230a43287ccSSascha Wildner *error = "invalid subunit number"; 231a43287ccSSascha Wildner } else 232a43287ccSSascha Wildner *error = tooManyFields; 233a43287ccSSascha Wildner return (dev); 234a43287ccSSascha Wildner } 235a43287ccSSascha Wildner 236a43287ccSSascha Wildner 237a43287ccSSascha Wildner /* list of formats and pack functions */ 238a43287ccSSascha Wildner /* this list must be sorted lexically */ 239a43287ccSSascha Wildner static struct format { 240a43287ccSSascha Wildner const char *name; 241a43287ccSSascha Wildner pack_t *pack; 242a43287ccSSascha Wildner } formats[] = { 243a43287ccSSascha Wildner {"386bsd", pack_8_8}, 244a43287ccSSascha Wildner {"4bsd", pack_8_8}, 245a43287ccSSascha Wildner {"bsdos", pack_bsdos}, 246a43287ccSSascha Wildner {"freebsd", pack_freebsd}, 247a43287ccSSascha Wildner {"hpux", pack_8_24}, 248a43287ccSSascha Wildner {"isc", pack_8_8}, 249a43287ccSSascha Wildner {"linux", pack_8_8}, 250a43287ccSSascha Wildner {"native", pack_native}, 251a43287ccSSascha Wildner {"netbsd", pack_netbsd}, 252a43287ccSSascha Wildner {"osf1", pack_12_20}, 253a43287ccSSascha Wildner {"sco", pack_8_8}, 254a43287ccSSascha Wildner {"solaris", pack_14_18}, 255a43287ccSSascha Wildner {"sunos", pack_8_8}, 256a43287ccSSascha Wildner {"svr3", pack_8_8}, 257a43287ccSSascha Wildner {"svr4", pack_14_18}, 258a43287ccSSascha Wildner {"ultrix", pack_8_8}, 259a43287ccSSascha Wildner }; 260a43287ccSSascha Wildner 261a43287ccSSascha Wildner static int 262a43287ccSSascha Wildner compare_format(const void *key, const void *element) 263a43287ccSSascha Wildner { 264a43287ccSSascha Wildner const char *name; 265a43287ccSSascha Wildner const struct format *format; 266a43287ccSSascha Wildner 267a43287ccSSascha Wildner name = key; 268a43287ccSSascha Wildner format = element; 269a43287ccSSascha Wildner 270a43287ccSSascha Wildner return (strcmp(name, format->name)); 271a43287ccSSascha Wildner } 272a43287ccSSascha Wildner 273a43287ccSSascha Wildner 274a43287ccSSascha Wildner pack_t * 275a43287ccSSascha Wildner pack_find(const char *name) 276a43287ccSSascha Wildner { 277a43287ccSSascha Wildner struct format *format; 278a43287ccSSascha Wildner 279a43287ccSSascha Wildner format = bsearch(name, formats, 280a43287ccSSascha Wildner sizeof(formats)/sizeof(formats[0]), 281a43287ccSSascha Wildner sizeof(formats[0]), compare_format); 282*5e83d98bSSascha Wildner if (format == NULL) 283a43287ccSSascha Wildner return (NULL); 284a43287ccSSascha Wildner return (format->pack); 285a43287ccSSascha Wildner } 286