1 /* $NetBSD: ffs_appleufs.c,v 1.2 2002/11/02 19:31:09 dbj Exp $ */ 2 /* 3 * Copyright (c) 2002 Darrin B. Jewell 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Darrin B. Jewell 17 * 4. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 33 #include <sys/cdefs.h> 34 __KERNEL_RCSID(0, "$NetBSD: ffs_appleufs.c,v 1.2 2002/11/02 19:31:09 dbj Exp $"); 35 36 #include <sys/param.h> 37 #include <sys/time.h> 38 #if defined(_KERNEL) 39 #include <sys/kernel.h> 40 #include <sys/systm.h> 41 #endif 42 43 #include <ufs/ufs/dinode.h> 44 #include <ufs/ufs/ufs_bswap.h> 45 #include <ufs/ffs/fs.h> 46 #include <ufs/ffs/ffs_extern.h> 47 48 #if !defined(_KERNEL) && !defined(STANDALONE) 49 #include <stddef.h> 50 #include <stdio.h> 51 #include <stdlib.h> 52 #include <string.h> 53 #include <errno.h> 54 #include <assert.h> 55 #define KASSERT(x) assert(x) 56 #endif 57 58 /* 59 * this is the same calculation as in_cksum 60 */ 61 u_int16_t 62 ffs_appleufs_cksum(appleufs) 63 const struct appleufslabel *appleufs; 64 { 65 const u_int16_t *p = (const u_int16_t *)appleufs; 66 int len = sizeof(struct appleufslabel); 67 long res = 0; 68 while (len > 1) { 69 res += *p++; 70 len -= 2; 71 } 72 #if 0 /* sizeof(struct appleufslabel) is guaranteed to be even */ 73 if (len == 1) 74 res += htobe16(*(u_char *)p<<8); 75 #endif 76 res = (res >> 16) + (res & 0xffff); 77 res += (res >> 16); 78 return (~res); 79 } 80 81 /* copies o to n, validating and byteswapping along the way 82 * returns 0 if ok, EINVAL if not valid 83 */ 84 int 85 ffs_appleufs_validate(name,o,n) 86 const char *name; 87 const struct appleufslabel *o; 88 struct appleufslabel *n; 89 { 90 struct appleufslabel tmp; 91 if (!n) n = &tmp; 92 93 if (o->ul_magic != be32toh(APPLEUFS_LABEL_MAGIC)) { 94 return EINVAL; 95 } 96 *n = *o; 97 n->ul_checksum = 0; 98 n->ul_checksum = ffs_appleufs_cksum(n); 99 if (n->ul_checksum != o->ul_checksum) { 100 #if defined(DIAGNOSTIC) || !defined(_KERNEL) 101 printf("%s: invalid APPLE UFS checksum. found 0x%x, expecting 0x%x", 102 name,o->ul_checksum,n->ul_checksum); 103 #endif 104 return EINVAL; 105 } 106 n->ul_magic = be32toh(o->ul_magic); 107 n->ul_version = be32toh(o->ul_version); 108 n->ul_time = be32toh(o->ul_time); 109 n->ul_namelen = be16toh(o->ul_namelen); 110 111 if (n->ul_namelen > APPLEUFS_MAX_LABEL_NAME) { 112 #if defined(DIAGNOSTIC) || !defined(_KERNEL) 113 printf("%s: APPLE UFS label name too long, truncated.\n", 114 name); 115 #endif 116 n->ul_namelen = APPLEUFS_MAX_LABEL_NAME; 117 } 118 /* if len is max, will set ul_reserved[0] */ 119 n->ul_name[n->ul_namelen] = '\0'; 120 #ifdef DEBUG 121 printf("%s: found APPLE UFS label v%d: \"%s\"\n", 122 name,n->ul_version,n->ul_name); 123 #endif 124 125 return 0; 126 } 127 128 void 129 ffs_appleufs_set(appleufs,name,t) 130 struct appleufslabel *appleufs; 131 const char *name; 132 time_t t; 133 { 134 size_t namelen; 135 if (!name) name = "untitled"; 136 if (t == ((time_t)-1)) { 137 #if defined(_KERNEL) 138 t = time.tv_sec; 139 #elif defined(STANDALONE) 140 t = 0; 141 #else 142 (void)time(&t); 143 #endif 144 } 145 namelen = strlen(name); 146 if (namelen > APPLEUFS_MAX_LABEL_NAME) 147 namelen = APPLEUFS_MAX_LABEL_NAME; 148 memset(appleufs, 0, sizeof(*appleufs)); 149 appleufs->ul_magic = htobe32(APPLEUFS_LABEL_MAGIC); 150 appleufs->ul_version = htobe32(APPLEUFS_LABEL_VERSION); 151 appleufs->ul_time = htobe32((u_int32_t)t); 152 appleufs->ul_namelen = htobe16(namelen); 153 strncpy(appleufs->ul_name,name,namelen); 154 appleufs->ul_checksum = ffs_appleufs_cksum(appleufs); 155 } 156