]>
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 if ((dp
= strrchr(name
, '/')) == 0)
111 (void) strcpy(rawbuf
, name
);
113 (void) strcat(rawbuf
, "/r");
114 (void) strcat(rawbuf
, &dp
[1]);
119 /* copied from diskdev_cmds/fsck_hfs/utilities.c */
121 unrawname(char *name
)
126 if ((dp
= strrchr(name
, '/')) == 0)
128 if (stat(name
, &stb
) < 0)
130 if ((stb
.st_mode
& S_IFMT
) != S_IFCHR
)
134 (void) strcpy(&dp
[1], &dp
[2]);
140 * copied from diskdev_cmds/fsck_hfs/utilities.c, and modified:
141 * 1) remove "hotroot"
142 * 2) if error, return NULL
143 * 3) if not a char device, return NULL (effectively, this is treated
144 * as error even if accessing the block device might have been OK)
147 blockcheck(char *origname
)
149 struct stat stblock
, stchar
;
156 if (stat(newname
, &stblock
) < 0) {
158 fprintf(stderr
, "Can't stat %s\n", newname
);
161 if ((stblock
.st_mode
& S_IFMT
) == S_IFBLK
) {
162 raw
= rawname(newname
);
163 if (stat(raw
, &stchar
) < 0) {
165 fprintf(stderr
, "Can't stat %s\n", raw
);
168 if ((stchar
.st_mode
& S_IFMT
) == S_IFCHR
) {
171 fprintf(stderr
, "%s is not a character device\n", raw
);
174 } else if ((stblock
.st_mode
& S_IFMT
) == S_IFCHR
&& !retried
) {
175 newname
= unrawname(newname
);
179 /* not a block or character device */
184 * (sanity) check the volume header in volhdr
186 * return 1 if volhdr is an HFS volhdr, 0 otherwise
189 checkVolHdr(const unsigned char *volhdr
)
195 if (strncmp((const char *)volhdr
, "H+", 2) == 0) {
196 /* technote 1150: H+ is version 4 */
197 retval
= (volhdr
[3] == 4);
198 } else if (strncmp((const char *)volhdr
, "HX", 2) == 0) {
199 /* technote 1150: HX is version 5 */
200 retval
= (volhdr
[3] == 5);