4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * libfstyp module for hsfs
34 #include <sys/param.h>
37 #include <sys/types.h>
41 #include <libnvpair.h>
42 #include <libfstyp_module.h>
44 #include <sys/fs/hsfs_spec.h>
45 #include <sys/fs/hsfs_isospec.h>
47 typedef struct fstyp_hsfs
{
50 char hs_buf
[ISO_SECTOR_SIZE
];
52 char iso_buf
[ISO_SECTOR_SIZE
];
54 char unix_buf
[ISO_SECTOR_SIZE
];
60 #define GETCDSECTOR(h, buf, secno, nosec) (getdisk(h, buf, \
61 ((secno)+(h)->cdroff)*ISO_SECTOR_SIZE, \
62 (nosec)*ISO_SECTOR_SIZE))
64 #define NELEM(a) sizeof (a) / sizeof (*(a))
66 static int ckvoldesc(fstyp_hsfs_t
*h
, int *cd_type
);
67 static int findhsvol(fstyp_hsfs_t
*h
, char *volp
);
68 static int findisovol(fstyp_hsfs_t
*h
, char *volp
);
69 static int findunixvol(fstyp_hsfs_t
*h
, char *volp
);
70 static char *get_old_name(char *new);
71 static int rdev_is_a_cd(int rdevfd
);
72 static int getdisk(fstyp_hsfs_t
*h
, char *buf
, int daddr
, int size
);
73 static void copy_string(char *d
, char *s
, int maxlen
);
74 static int is_hsfs(fstyp_hsfs_t
*h
);
75 static int get_attr(fstyp_hsfs_t
*h
);
77 int fstyp_mod_init(int fd
, off_t offset
, fstyp_mod_handle_t
*handle
);
78 void fstyp_mod_fini(fstyp_mod_handle_t handle
);
79 int fstyp_mod_ident(fstyp_mod_handle_t handle
);
80 int fstyp_mod_get_attr(fstyp_mod_handle_t handle
, nvlist_t
**attrp
);
81 int fstyp_mod_dump(fstyp_mod_handle_t handle
, FILE *fout
, FILE *ferr
);
85 fstyp_mod_init(int fd
, off_t offset
, fstyp_mod_handle_t
*handle
)
87 fstyp_hsfs_t
*h
= (fstyp_hsfs_t
*)handle
;
90 return (FSTYP_ERR_OFFSET
);
93 if ((h
= calloc(1, sizeof (fstyp_hsfs_t
))) == NULL
) {
94 return (FSTYP_ERR_NOMEM
);
98 *handle
= (fstyp_mod_handle_t
)h
;
103 fstyp_mod_fini(fstyp_mod_handle_t handle
)
105 fstyp_hsfs_t
*h
= (fstyp_hsfs_t
*)handle
;
107 if (h
->attr
== NULL
) {
108 nvlist_free(h
->attr
);
115 fstyp_mod_ident(fstyp_mod_handle_t handle
)
117 fstyp_hsfs_t
*h
= (fstyp_hsfs_t
*)handle
;
123 fstyp_mod_get_attr(fstyp_mod_handle_t handle
, nvlist_t
**attrp
)
125 fstyp_hsfs_t
*h
= (fstyp_hsfs_t
*)handle
;
128 if (h
->attr
== NULL
) {
129 if (nvlist_alloc(&h
->attr
, NV_UNIQUE_NAME_TYPE
, 0)) {
130 return (FSTYP_ERR_NOMEM
);
132 if ((error
= get_attr(h
)) != 0) {
133 nvlist_free(h
->attr
);
145 fstyp_mod_dump(fstyp_mod_handle_t handle
, FILE *fout
, FILE *ferr
)
149 nvpair_t
*elem
= NULL
;
151 uint64_t uint64_value
;
154 if ((error
= fstyp_mod_get_attr(handle
, &attr
)) != 0) {
157 while ((elem
= nvlist_next_nvpair(attr
, elem
)) != NULL
) {
158 /* format is special */
159 if (strcmp(nvpair_name(elem
), "format") == 0) {
160 (void) nvpair_value_string(elem
, &str_value
);
161 if (strcmp(str_value
,
162 "ISO 9660 with UNIX extension") == 0) {
164 "CD-ROM is in ISO 9660 format with"
165 " UNIX extension\n");
167 (void) fprintf(fout
, "CD-ROM is in %s"
168 " format\n", str_value
);
172 if ((name
= get_old_name(nvpair_name(elem
))) == NULL
) {
175 if (nvpair_type(elem
) == DATA_TYPE_STRING
) {
176 (void) nvpair_value_string(elem
, &str_value
);
177 (void) fprintf(fout
, "%s: %s\n", name
, str_value
);
178 } else if (nvpair_type(elem
) == DATA_TYPE_UINT64
) {
179 (void) nvpair_value_uint64(elem
, &uint64_value
);
180 (void) fprintf(fout
, "%s %llu\n",
181 name
, (u_longlong_t
)uint64_value
);
189 get_old_name(char *new)
191 static char *map
[] = {
192 "system_id", "System id",
193 "volume_id", "Volume id",
194 "volume_set_id", "Volume set id",
195 "publisher_id", "Publisher id",
196 "data_preparer_id", "Data preparer id",
197 "application_id", "Application id",
198 "copyright_file_id", "Copyright File id",
199 "abstract_file_id", "Abstract File id",
200 "bibliographic_file_id", "Bibliographic File id",
201 "volume_set_size", "Volume set size is",
202 "volume_set_sequence_number", "Volume set sequence number is",
203 "logical_block_size", "Logical block size is",
204 "volume_size", "Volume size is"
209 for (i
= 0; i
< NELEM(map
) / 2; i
++) {
210 if (strcmp(new, map
[i
* 2]) == 0) {
211 old
= map
[i
* 2 + 1];
219 * findhsvol: check if the disk is in high sierra format
220 * return(1) if found, (0) otherwise
221 * if found, volp will point to the descriptor
225 findhsvol(fstyp_hsfs_t
*h
, char *volp
)
231 secno
= HS_VOLDESC_SEC
;
232 if ((err
= GETCDSECTOR(h
, volp
, secno
++, 1)) != 0) {
235 while (HSV_DESC_TYPE(volp
) != VD_EOV
) {
236 for (i
= 0; i
< HSV_ID_STRLEN
; i
++)
237 if (HSV_STD_ID(volp
)[i
] != HSV_ID_STRING
[i
])
239 if (HSV_STD_VER(volp
) != HSV_ID_VER
)
241 switch (HSV_DESC_TYPE(volp
)) {
243 h
->hs_pvd_sec_no
= secno
-1;
248 if ((err
= GETCDSECTOR(h
, volp
, secno
++, 1)) != 0) {
253 return (FSTYP_ERR_NO_MATCH
);
257 * findisovol: check if the disk is in ISO 9660 format
258 * return(1) if found, (0) otherwise
259 * if found, volp will point to the descriptor
263 findisovol(fstyp_hsfs_t
*h
, char *volp
)
269 secno
= ISO_VOLDESC_SEC
;
270 if ((err
= GETCDSECTOR(h
, volp
, secno
++, 1)) != 0) {
273 while (ISO_DESC_TYPE(volp
) != ISO_VD_EOV
) {
274 for (i
= 0; i
< ISO_ID_STRLEN
; i
++)
275 if (ISO_STD_ID(volp
)[i
] != ISO_ID_STRING
[i
])
277 if (ISO_STD_VER(volp
) != ISO_ID_VER
)
279 switch (ISO_DESC_TYPE(volp
)) {
281 h
->iso_pvd_sec_no
= secno
-1;
286 if ((err
= GETCDSECTOR(h
, volp
, secno
++, 1)) != 0) {
291 return (FSTYP_ERR_NO_MATCH
);
295 * findunixvol: check if the disk is in UNIX extension format
296 * return(1) if found, (0) otherwise
297 * if found, volp will point to the descriptor
301 findunixvol(fstyp_hsfs_t
*h
, char *volp
)
307 secno
= ISO_VOLDESC_SEC
;
308 if ((err
= GETCDSECTOR(h
, volp
, secno
++, 1)) != 0) {
311 while (ISO_DESC_TYPE(volp
) != ISO_VD_EOV
) {
312 for (i
= 0; i
< ISO_ID_STRLEN
; i
++)
313 if (ISO_STD_ID(volp
)[i
] != ISO_ID_STRING
[i
])
315 if (ISO_STD_VER(volp
) != ISO_ID_VER
)
317 switch (ISO_DESC_TYPE(volp
)) {
319 h
->unix_pvd_sec_no
= secno
-1;
324 if ((err
= GETCDSECTOR(h
, volp
, secno
++, 1)) != 0) {
329 return (FSTYP_ERR_NO_MATCH
);
333 ckvoldesc(fstyp_hsfs_t
*h
, int *cd_type
)
337 if ((err
= findhsvol(h
, h
->hs_buf
)) == 0) {
339 } else if ((err
= findisovol(h
, h
->iso_buf
)) == 0) {
340 if (findunixvol(h
, h
->unix_buf
) == 0) {
353 is_hsfs(fstyp_hsfs_t
*h
)
355 #ifdef CDROMREADOFFSET
358 if (rdev_is_a_cd(h
->fd
)) {
359 err
= ioctl(h
->fd
, CDROMREADOFFSET
, &h
->cdroff
);
362 * This device doesn't support this ioctl.
368 /* check volume descriptor */
369 return (ckvoldesc(h
, &h
->cd_type
));
372 #define ADD_STRING(h, name, value) \
373 if (nvlist_add_string(h->attr, name, value) != 0) { \
374 return (FSTYP_ERR_NOMEM); \
377 #define ADD_UINT64(h, name, value) \
378 if (nvlist_add_uint64(h->attr, name, value) != 0) { \
379 return (FSTYP_ERR_NOMEM); \
382 #define ADD_BOOL(h, name, value) \
383 if (nvlist_add_boolean_value(h->attr, name, value) != 0) { \
384 return (FSTYP_ERR_NOMEM); \
388 get_attr(fstyp_hsfs_t
*h
)
405 switch (h
->cd_type
) {
407 ADD_STRING(h
, "format", "High Sierra");
408 ADD_STRING(h
, "gen_version", "High Sierra");
409 sysid
= (char *)HSV_sys_id(h
->hs_buf
);
410 volid
= (char *)HSV_vol_id(h
->hs_buf
);
411 volsetid
= (char *)HSV_vol_set_id(h
->hs_buf
);
412 pubid
= (char *)HSV_pub_id(h
->hs_buf
);
413 prepid
= (char *)HSV_prep_id(h
->hs_buf
);
414 applid
= (char *)HSV_appl_id(h
->hs_buf
);
415 copyfile
= (char *)HSV_copyr_id(h
->hs_buf
);
416 absfile
= (char *)HSV_abstr_id(h
->hs_buf
);
418 volsetsize
= HSV_SET_SIZE(h
->hs_buf
);
419 volsetseq
= HSV_SET_SEQ(h
->hs_buf
);
420 blksize
= HSV_BLK_SIZE(h
->hs_buf
);
421 volsize
= HSV_VOL_SIZE(h
->hs_buf
);
424 ADD_STRING(h
, "format", "ISO 9660");
425 ADD_STRING(h
, "gen_version", "ISO 9660");
426 sysid
= (char *)ISO_sys_id(h
->iso_buf
);
427 volid
= (char *)ISO_vol_id(h
->iso_buf
);
428 volsetid
= (char *)ISO_vol_set_id(h
->iso_buf
);
429 pubid
= (char *)ISO_pub_id(h
->iso_buf
);
430 prepid
= (char *)ISO_prep_id(h
->iso_buf
);
431 applid
= (char *)ISO_appl_id(h
->iso_buf
);
432 copyfile
= (char *)ISO_copyr_id(h
->iso_buf
);
433 absfile
= (char *)ISO_abstr_id(h
->iso_buf
);
434 bibfile
= (char *)ISO_bibli_id(h
->iso_buf
);
435 volsetsize
= ISO_SET_SIZE(h
->iso_buf
);
436 volsetseq
= ISO_SET_SEQ(h
->iso_buf
);
437 blksize
= ISO_BLK_SIZE(h
->iso_buf
);
438 volsize
= ISO_VOL_SIZE(h
->iso_buf
);
441 ADD_STRING(h
, "format", "ISO 9660 with UNIX extension");
442 ADD_STRING(h
, "gen_version", "ISO 9660 with UNIX extension");
443 sysid
= (char *)ISO_sys_id(h
->unix_buf
);
444 volid
= (char *)ISO_vol_id(h
->unix_buf
);
445 volsetid
= (char *)ISO_vol_set_id(h
->unix_buf
);
446 pubid
= (char *)ISO_pub_id(h
->unix_buf
);
447 prepid
= (char *)ISO_prep_id(h
->unix_buf
);
448 applid
= (char *)ISO_appl_id(h
->unix_buf
);
449 copyfile
= (char *)ISO_copyr_id(h
->unix_buf
);
450 absfile
= (char *)ISO_abstr_id(h
->unix_buf
);
451 bibfile
= (char *)ISO_bibli_id(h
->unix_buf
);
452 volsetsize
= ISO_SET_SIZE(h
->unix_buf
);
453 volsetseq
= ISO_SET_SEQ(h
->unix_buf
);
454 blksize
= ISO_BLK_SIZE(h
->unix_buf
);
455 volsize
= ISO_VOL_SIZE(h
->unix_buf
);
458 return (FSTYP_ERR_NO_MATCH
);
461 copy_string(s
, sysid
, 32);
462 ADD_STRING(h
, "system_id", s
);
463 copy_string(s
, volid
, 32);
464 ADD_STRING(h
, "volume_id", s
);
465 ADD_STRING(h
, "gen_volume_label", s
);
466 copy_string(s
, volsetid
, 128);
467 ADD_STRING(h
, "volume_set_id", s
);
468 copy_string(s
, pubid
, 128);
469 ADD_STRING(h
, "publisher_id", s
);
470 copy_string(s
, prepid
, 128);
471 ADD_STRING(h
, "data_preparer_id", s
);
472 copy_string(s
, applid
, 128);
473 ADD_STRING(h
, "application_id", s
);
474 copy_string(s
, copyfile
, 37);
475 ADD_STRING(h
, "copyright_file_id", s
);
476 copy_string(s
, absfile
, 37);
477 ADD_STRING(h
, "abstract_file_id", s
);
478 copy_string(s
, bibfile
, 37);
479 ADD_STRING(h
, "bibliographic_file_id", s
);
480 ADD_UINT64(h
, "volume_set_size", volsetsize
);
481 ADD_UINT64(h
, "volume_set_sequence_number", volsetseq
);
482 ADD_UINT64(h
, "logical_block_size", blksize
);
483 ADD_UINT64(h
, "volume_size", volsize
);
484 ADD_BOOL(h
, "gen_clean", B_TRUE
);
490 copy_string(char *d
, char *s
, int maxlen
)
494 /* strip off trailing zeros */
495 for (i
= maxlen
-1; i
>= 0; i
--) {
502 for (i
= 0; i
< maxlen
; i
++) {
508 /* readdisk - read from cdrom image file */
510 getdisk(fstyp_hsfs_t
*h
, char *buf
, int daddr
, int size
)
512 if (lseek(h
->fd
, daddr
, L_SET
) == -1) {
513 return (FSTYP_ERR_IO
);
515 if (read(h
->fd
, buf
, size
) != size
) {
516 return (FSTYP_ERR_IO
);
522 * rdev_is_a_cd - return TRUE if the raw device identified by
523 * a file descriptor is a CDROM device.
525 * return FALSE if the device can't be accessed
529 rdev_is_a_cd(int rdevfd
)
533 if (ioctl(rdevfd
, DKIOCINFO
, &dkc
) < 0)
535 if (dkc
.dki_ctype
== DKC_CDROM
)