]>
git.saurik.com Git - apple/hfs.git/blob - fstyp_hfs/fstyp_hfs.c
2 * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
33 #define HFS_VOLHDR_OFFSET 1024 /* technote 1150 */
34 #define HFS_VOLHDR_SIZE 512 /* technote 1150 */
40 char *rawname(char *name
);
41 char *unrawname(char *name
);
42 int checkVolHdr(const unsigned char *volhdr
);
43 char *blockcheck(char *origname
);
48 * perhaps check the alternate volume header as well
50 * prefer to use raw device. TODO: suppose block device is valid but
51 * the corresponding raw device is not valid, then we fail. this is
52 * probably no the desired behavior.
56 main(int argc
, char **argv
)
58 unsigned char volhdr
[HFS_VOLHDR_SIZE
] = {0};
65 if ((progname
= strrchr(*argv
, '/')))
73 devname
= blockcheck(argv
[1]);
75 if (devname
!= NULL
) {
76 if ((fd
= open(devname
, O_RDONLY
, 0)) < 0) {
78 } else if (pread(fd
, volhdr
, HFS_VOLHDR_SIZE
, HFS_VOLHDR_OFFSET
) != HFS_VOLHDR_SIZE
) {
81 retval
= checkVolHdr(volhdr
);
97 fprintf(stdout
, "usage: %s device\n", progname
);
101 /* copied from diskdev_cmds/fsck_hfs/utilities.c */
105 static char rawbuf
[32];
108 (void) memset(rawbuf
, 0, sizeof(rawbuf
));
110 /* find the last "/" in a path, like /dev/disk2 */
111 if ((dp
= strrchr(name
, '/')) == 0)
114 /* temporarily replace the last "/" with a NUL */
117 /* copy name, with the "/" removed into 'rawbuf' */
118 (void) strlcpy(rawbuf
, name
, sizeof(rawbuf
));
120 /* replace the "/" back */
123 /* Now add the "/r" to make it a raw device */
124 (void) strlcat(rawbuf
, "/r", sizeof(rawbuf
));
126 /* then copy the rest of the string (after the /) into place */
127 (void) strlcat(rawbuf
, &dp
[1], sizeof(rawbuf
));
132 /* copied from diskdev_cmds/fsck_hfs/utilities.c */
134 unrawname(char *name
)
139 if ((dp
= strrchr(name
, '/')) == 0)
141 if (stat(name
, &stb
) < 0)
143 if ((stb
.st_mode
& S_IFMT
) != S_IFCHR
)
147 (void) strcpy(&dp
[1], &dp
[2]);
153 * copied from diskdev_cmds/fsck_hfs/utilities.c, and modified:
154 * 1) remove "hotroot"
155 * 2) if error, return NULL
156 * 3) if not a char device, return NULL (effectively, this is treated
157 * as error even if accessing the block device might have been OK)
160 blockcheck(char *origname
)
162 struct stat stblock
, stchar
;
169 if (stat(newname
, &stblock
) < 0) {
171 fprintf(stderr
, "Can't stat %s\n", newname
);
174 if ((stblock
.st_mode
& S_IFMT
) == S_IFBLK
) {
175 raw
= rawname(newname
);
176 if (stat(raw
, &stchar
) < 0) {
178 fprintf(stderr
, "Can't stat %s\n", raw
);
181 if ((stchar
.st_mode
& S_IFMT
) == S_IFCHR
) {
184 fprintf(stderr
, "%s is not a character device\n", raw
);
187 } else if ((stblock
.st_mode
& S_IFMT
) == S_IFCHR
&& !retried
) {
188 newname
= unrawname(newname
);
192 /* not a block or character device */
197 * (sanity) check the volume header in volhdr
199 * return 1 if volhdr is an HFS volhdr, 0 otherwise
202 checkVolHdr(const unsigned char *volhdr
)
208 if (strncmp((const char *)volhdr
, "H+", 2) == 0) {
209 /* technote 1150: H+ is version 4 */
210 retval
= (volhdr
[3] == 4);
211 } else if (strncmp((const char *)volhdr
, "HX", 2) == 0) {
212 /* technote 1150: HX is version 5 */
213 retval
= (volhdr
[3] == 5);