xref: /illumos-gate/usr/src/cmd/fs.d/hsfs/fstyp/fstyp.c (revision 0c79d02b)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50e42dee6Sartem  * Common Development and Distribution License (the "License").
60e42dee6Sartem  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
220e42dee6Sartem  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23c719c59aSjkennedy  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
25c719c59aSjkennedy 
260e42dee6Sartem /*
270e42dee6Sartem  * libfstyp module for hsfs
280e42dee6Sartem  */
290e42dee6Sartem #include <unistd.h>
300e42dee6Sartem #include <stropts.h>
317c478bd9Sstevel@tonic-gate #include <fcntl.h>
327c478bd9Sstevel@tonic-gate #include <stdio.h>
330e42dee6Sartem #include <strings.h>
347c478bd9Sstevel@tonic-gate #include <sys/param.h>
357c478bd9Sstevel@tonic-gate #include <sys/stat.h>
367c478bd9Sstevel@tonic-gate #include <sys/time.h>
377c478bd9Sstevel@tonic-gate #include <sys/types.h>
387c478bd9Sstevel@tonic-gate #include <sys/file.h>
397c478bd9Sstevel@tonic-gate #include <sys/cdio.h>
407c478bd9Sstevel@tonic-gate #include <sys/dkio.h>
410e42dee6Sartem #include <libnvpair.h>
420e42dee6Sartem #include <libfstyp_module.h>
43*0c79d02bSRichard Lowe 
44*0c79d02bSRichard Lowe #include <sys/fs/hsfs_spec.h>
45*0c79d02bSRichard Lowe #include <sys/fs/hsfs_isospec.h>
467c478bd9Sstevel@tonic-gate 
470e42dee6Sartem typedef struct fstyp_hsfs {
480e42dee6Sartem 	int		fd;
490e42dee6Sartem 	nvlist_t	*attr;
500e42dee6Sartem 	char		hs_buf[ISO_SECTOR_SIZE];
510e42dee6Sartem 	int		hs_pvd_sec_no;
520e42dee6Sartem 	char		iso_buf[ISO_SECTOR_SIZE];
530e42dee6Sartem 	int		iso_pvd_sec_no;
540e42dee6Sartem 	char		unix_buf[ISO_SECTOR_SIZE];
550e42dee6Sartem 	int		unix_pvd_sec_no;
560e42dee6Sartem 	int		cdroff;
570e42dee6Sartem 	int		cd_type;
580e42dee6Sartem } fstyp_hsfs_t;
590e42dee6Sartem 
600e42dee6Sartem #define	GETCDSECTOR(h, buf, secno, nosec) (getdisk(h, buf, \
610e42dee6Sartem 	((secno)+(h)->cdroff)*ISO_SECTOR_SIZE, \
627c478bd9Sstevel@tonic-gate 	(nosec)*ISO_SECTOR_SIZE))
637c478bd9Sstevel@tonic-gate 
640e42dee6Sartem #define	NELEM(a)	sizeof (a) / sizeof (*(a))
650e42dee6Sartem 
660e42dee6Sartem static int	ckvoldesc(fstyp_hsfs_t *h, int *cd_type);
670e42dee6Sartem static int	findhsvol(fstyp_hsfs_t *h, char *volp);
680e42dee6Sartem static int	findisovol(fstyp_hsfs_t *h, char *volp);
690e42dee6Sartem static int	findunixvol(fstyp_hsfs_t *h, char *volp);
700e42dee6Sartem static char	*get_old_name(char *new);
710e42dee6Sartem static int	rdev_is_a_cd(int rdevfd);
720e42dee6Sartem static int	getdisk(fstyp_hsfs_t *h, char *buf, int daddr, int size);
730e42dee6Sartem static void	copy_string(char *d, char *s, int maxlen);
740e42dee6Sartem static int	is_hsfs(fstyp_hsfs_t *h);
750e42dee6Sartem static int	get_attr(fstyp_hsfs_t *h);
767c478bd9Sstevel@tonic-gate 
770e42dee6Sartem int	fstyp_mod_init(int fd, off_t offset, fstyp_mod_handle_t *handle);
780e42dee6Sartem void	fstyp_mod_fini(fstyp_mod_handle_t handle);
790e42dee6Sartem int	fstyp_mod_ident(fstyp_mod_handle_t handle);
800e42dee6Sartem int	fstyp_mod_get_attr(fstyp_mod_handle_t handle, nvlist_t **attrp);
810e42dee6Sartem int	fstyp_mod_dump(fstyp_mod_handle_t handle, FILE *fout, FILE *ferr);
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate 
84c719c59aSjkennedy int
fstyp_mod_init(int fd,off_t offset,fstyp_mod_handle_t * handle)850e42dee6Sartem fstyp_mod_init(int fd, off_t offset, fstyp_mod_handle_t *handle)
867c478bd9Sstevel@tonic-gate {
870e42dee6Sartem 	fstyp_hsfs_t	*h = (fstyp_hsfs_t *)handle;
880e42dee6Sartem 
890e42dee6Sartem 	if (offset != 0) {
900e42dee6Sartem 		return (FSTYP_ERR_OFFSET);
917c478bd9Sstevel@tonic-gate 	}
927c478bd9Sstevel@tonic-gate 
930e42dee6Sartem 	if ((h = calloc(1, sizeof (fstyp_hsfs_t))) == NULL) {
940e42dee6Sartem 		return (FSTYP_ERR_NOMEM);
950e42dee6Sartem 	}
960e42dee6Sartem 	h->fd = fd;
970e42dee6Sartem 
980e42dee6Sartem 	*handle = (fstyp_mod_handle_t)h;
990e42dee6Sartem 	return (0);
1000e42dee6Sartem }
1010e42dee6Sartem 
1020e42dee6Sartem void
fstyp_mod_fini(fstyp_mod_handle_t handle)1030e42dee6Sartem fstyp_mod_fini(fstyp_mod_handle_t handle)
1040e42dee6Sartem {
1050e42dee6Sartem 	fstyp_hsfs_t	*h = (fstyp_hsfs_t *)handle;
1060e42dee6Sartem 
1070e42dee6Sartem 	if (h->attr == NULL) {
1080e42dee6Sartem 		nvlist_free(h->attr);
1090e42dee6Sartem 		h->attr = NULL;
1107c478bd9Sstevel@tonic-gate 	}
1110e42dee6Sartem 	free(h);
1120e42dee6Sartem }
1137c478bd9Sstevel@tonic-gate 
1140e42dee6Sartem int
fstyp_mod_ident(fstyp_mod_handle_t handle)1150e42dee6Sartem fstyp_mod_ident(fstyp_mod_handle_t handle)
1160e42dee6Sartem {
1170e42dee6Sartem 	fstyp_hsfs_t *h = (fstyp_hsfs_t *)handle;
1187c478bd9Sstevel@tonic-gate 
1190e42dee6Sartem 	return (is_hsfs(h));
1200e42dee6Sartem }
1217c478bd9Sstevel@tonic-gate 
1220e42dee6Sartem int
fstyp_mod_get_attr(fstyp_mod_handle_t handle,nvlist_t ** attrp)1230e42dee6Sartem fstyp_mod_get_attr(fstyp_mod_handle_t handle, nvlist_t **attrp)
1240e42dee6Sartem {
1250e42dee6Sartem 	fstyp_hsfs_t	*h = (fstyp_hsfs_t *)handle;
1260e42dee6Sartem 	int error;
1270e42dee6Sartem 
1280e42dee6Sartem 	if (h->attr == NULL) {
1290e42dee6Sartem 		if (nvlist_alloc(&h->attr, NV_UNIQUE_NAME_TYPE, 0)) {
1300e42dee6Sartem 			return (FSTYP_ERR_NOMEM);
1310e42dee6Sartem 		}
1320e42dee6Sartem 		if ((error = get_attr(h)) != 0) {
1330e42dee6Sartem 			nvlist_free(h->attr);
1340e42dee6Sartem 			h->attr = NULL;
1350e42dee6Sartem 			return (error);
1360e42dee6Sartem 		}
1370e42dee6Sartem 	}
1380e42dee6Sartem 
1390e42dee6Sartem 	*attrp = h->attr;
140c719c59aSjkennedy 	return (0);
1417c478bd9Sstevel@tonic-gate }
1427c478bd9Sstevel@tonic-gate 
1430e42dee6Sartem /* ARGSUSED */
1440e42dee6Sartem int
fstyp_mod_dump(fstyp_mod_handle_t handle,FILE * fout,FILE * ferr)1450e42dee6Sartem fstyp_mod_dump(fstyp_mod_handle_t handle, FILE *fout, FILE *ferr)
1467c478bd9Sstevel@tonic-gate {
1470e42dee6Sartem 	int		error;
1480e42dee6Sartem 	nvlist_t	*attr;
1490e42dee6Sartem 	nvpair_t	*elem = NULL;
1500e42dee6Sartem 	char		*str_value;
1510e42dee6Sartem 	uint64_t	uint64_value;
1520e42dee6Sartem 	char		*name;
1530e42dee6Sartem 
1540e42dee6Sartem 	if ((error = fstyp_mod_get_attr(handle, &attr)) != 0) {
1550e42dee6Sartem 		return (error);
1560e42dee6Sartem 	}
1570e42dee6Sartem 	while ((elem = nvlist_next_nvpair(attr, elem)) != NULL) {
1580e42dee6Sartem 		/* format is special */
1590e42dee6Sartem 		if (strcmp(nvpair_name(elem), "format") == 0) {
1600e42dee6Sartem 			(void) nvpair_value_string(elem, &str_value);
1610e42dee6Sartem 			if (strcmp(str_value,
1620e42dee6Sartem 			    "ISO 9660 with UNIX extension") == 0) {
1630e42dee6Sartem 				(void) fprintf(fout,
1640e42dee6Sartem 				    "CD-ROM is in ISO 9660 format with"
1650e42dee6Sartem 				    " UNIX extension\n");
1660e42dee6Sartem 			} else {
1670e42dee6Sartem 				(void) fprintf(fout, "CD-ROM is in %s"
1680e42dee6Sartem 				    " format\n", str_value);
1690e42dee6Sartem 			}
1700e42dee6Sartem 			continue;
1710e42dee6Sartem 		}
1720e42dee6Sartem 		if ((name = get_old_name(nvpair_name(elem))) == NULL) {
1730e42dee6Sartem 			continue;
1740e42dee6Sartem 		}
1750e42dee6Sartem 		if (nvpair_type(elem) == DATA_TYPE_STRING) {
1760e42dee6Sartem 			(void) nvpair_value_string(elem, &str_value);
1770e42dee6Sartem 			(void) fprintf(fout, "%s: %s\n", name, str_value);
1780e42dee6Sartem 		} else if (nvpair_type(elem) == DATA_TYPE_UINT64) {
1790e42dee6Sartem 			(void) nvpair_value_uint64(elem, &uint64_value);
1800e42dee6Sartem 			(void) fprintf(fout, "%s %llu\n",
1810e42dee6Sartem 			    name, (u_longlong_t)uint64_value);
1820e42dee6Sartem 		}
1830e42dee6Sartem 	}
1840e42dee6Sartem 
1850e42dee6Sartem 	return (0);
1860e42dee6Sartem }
1870e42dee6Sartem 
1880e42dee6Sartem static char *
get_old_name(char * new)1890e42dee6Sartem get_old_name(char *new)
1900e42dee6Sartem {
1910e42dee6Sartem 	static char	*map[] = {
1920e42dee6Sartem 		"system_id",		"System id",
1930e42dee6Sartem 		"volume_id",		"Volume id",
1940e42dee6Sartem 		"volume_set_id",	"Volume set id",
1950e42dee6Sartem 		"publisher_id",		"Publisher id",
1960e42dee6Sartem 		"data_preparer_id",	"Data preparer id",
1970e42dee6Sartem 		"application_id",	"Application id",
1980e42dee6Sartem 		"copyright_file_id",	"Copyright File id",
1990e42dee6Sartem 		"abstract_file_id",	"Abstract File id",
2000e42dee6Sartem 		"bibliographic_file_id", "Bibliographic File id",
2010e42dee6Sartem 		"volume_set_size",	"Volume set size is",
2020e42dee6Sartem 		"volume_set_sequence_number", "Volume set sequence number is",
2030e42dee6Sartem 		"logical_block_size",	"Logical block size is",
2040e42dee6Sartem 		"volume_size",		"Volume size is"
2050e42dee6Sartem 	};
2060e42dee6Sartem 	int	i;
2070e42dee6Sartem 	char	*old = NULL;
2080e42dee6Sartem 
2090e42dee6Sartem 	for (i = 0; i < NELEM(map) / 2; i++) {
2100e42dee6Sartem 		if (strcmp(new, map[i * 2]) == 0) {
2110e42dee6Sartem 			old = map[i * 2 + 1];
2120e42dee6Sartem 			break;
2130e42dee6Sartem 		}
2140e42dee6Sartem 	}
2150e42dee6Sartem 	return (old);
2167c478bd9Sstevel@tonic-gate }
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate /*
2197c478bd9Sstevel@tonic-gate  * findhsvol: check if the disk is in high sierra format
2207c478bd9Sstevel@tonic-gate  *            return(1) if found, (0) otherwise
2217c478bd9Sstevel@tonic-gate  *	      if found, volp will point to the descriptor
2227c478bd9Sstevel@tonic-gate  *
2237c478bd9Sstevel@tonic-gate  */
2240e42dee6Sartem static int
findhsvol(fstyp_hsfs_t * h,char * volp)2250e42dee6Sartem findhsvol(fstyp_hsfs_t *h, char *volp)
2267c478bd9Sstevel@tonic-gate {
2270e42dee6Sartem 	int secno;
2280e42dee6Sartem 	int i;
2290e42dee6Sartem 	int err;
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate 	secno = HS_VOLDESC_SEC;
2320e42dee6Sartem 	if ((err = GETCDSECTOR(h, volp, secno++, 1)) != 0) {
2330e42dee6Sartem 		return (err);
2340e42dee6Sartem 	}
2357c478bd9Sstevel@tonic-gate 	while (HSV_DESC_TYPE(volp) != VD_EOV) {
2367c478bd9Sstevel@tonic-gate 		for (i = 0; i < HSV_ID_STRLEN; i++)
2377c478bd9Sstevel@tonic-gate 			if (HSV_STD_ID(volp)[i] != HSV_ID_STRING[i])
2387c478bd9Sstevel@tonic-gate 				goto cantfind;
2397c478bd9Sstevel@tonic-gate 		if (HSV_STD_VER(volp) != HSV_ID_VER)
2407c478bd9Sstevel@tonic-gate 			goto cantfind;
2417c478bd9Sstevel@tonic-gate 		switch (HSV_DESC_TYPE(volp)) {
2427c478bd9Sstevel@tonic-gate 		case VD_SFS:
2430e42dee6Sartem 			h->hs_pvd_sec_no = secno-1;
2440e42dee6Sartem 			return (0);
2457c478bd9Sstevel@tonic-gate 		case VD_EOV:
2467c478bd9Sstevel@tonic-gate 			goto cantfind;
2477c478bd9Sstevel@tonic-gate 		}
2480e42dee6Sartem 		if ((err = GETCDSECTOR(h, volp, secno++, 1)) != 0) {
2490e42dee6Sartem 			return (err);
2500e42dee6Sartem 		}
2517c478bd9Sstevel@tonic-gate 	}
2527c478bd9Sstevel@tonic-gate cantfind:
2530e42dee6Sartem 	return (FSTYP_ERR_NO_MATCH);
2547c478bd9Sstevel@tonic-gate }
2557c478bd9Sstevel@tonic-gate 
2567c478bd9Sstevel@tonic-gate /*
2577c478bd9Sstevel@tonic-gate  * findisovol: check if the disk is in ISO 9660 format
2587c478bd9Sstevel@tonic-gate  *            return(1) if found, (0) otherwise
2597c478bd9Sstevel@tonic-gate  *	      if found, volp will point to the descriptor
2607c478bd9Sstevel@tonic-gate  *
2617c478bd9Sstevel@tonic-gate  */
2620e42dee6Sartem static int
findisovol(fstyp_hsfs_t * h,char * volp)2630e42dee6Sartem findisovol(fstyp_hsfs_t *h, char *volp)
2647c478bd9Sstevel@tonic-gate {
2650e42dee6Sartem 	int secno;
2660e42dee6Sartem 	int i;
2670e42dee6Sartem 	int err;
2687c478bd9Sstevel@tonic-gate 
2697c478bd9Sstevel@tonic-gate 	secno = ISO_VOLDESC_SEC;
2700e42dee6Sartem 	if ((err = GETCDSECTOR(h, volp, secno++, 1)) != 0) {
2710e42dee6Sartem 		return (err);
2720e42dee6Sartem 	}
2737c478bd9Sstevel@tonic-gate 	while (ISO_DESC_TYPE(volp) != ISO_VD_EOV) {
2747c478bd9Sstevel@tonic-gate 		for (i = 0; i < ISO_ID_STRLEN; i++)
2757c478bd9Sstevel@tonic-gate 			if (ISO_STD_ID(volp)[i] != ISO_ID_STRING[i])
2767c478bd9Sstevel@tonic-gate 				goto cantfind;
2777c478bd9Sstevel@tonic-gate 		if (ISO_STD_VER(volp) != ISO_ID_VER)
2787c478bd9Sstevel@tonic-gate 			goto cantfind;
2797c478bd9Sstevel@tonic-gate 		switch (ISO_DESC_TYPE(volp)) {
2807c478bd9Sstevel@tonic-gate 		case ISO_VD_PVD:
2810e42dee6Sartem 			h->iso_pvd_sec_no = secno-1;
2820e42dee6Sartem 			return (0);
2837c478bd9Sstevel@tonic-gate 		case ISO_VD_EOV:
2847c478bd9Sstevel@tonic-gate 			goto cantfind;
2857c478bd9Sstevel@tonic-gate 		}
2860e42dee6Sartem 		if ((err = GETCDSECTOR(h, volp, secno++, 1)) != 0) {
2870e42dee6Sartem 			return (err);
2880e42dee6Sartem 		}
2897c478bd9Sstevel@tonic-gate 	}
2907c478bd9Sstevel@tonic-gate cantfind:
2910e42dee6Sartem 	return (FSTYP_ERR_NO_MATCH);
2927c478bd9Sstevel@tonic-gate }
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate /*
2957c478bd9Sstevel@tonic-gate  * findunixvol: check if the disk is in UNIX extension format
2967c478bd9Sstevel@tonic-gate  *            return(1) if found, (0) otherwise
2977c478bd9Sstevel@tonic-gate  *	      if found, volp will point to the descriptor
2987c478bd9Sstevel@tonic-gate  *
2997c478bd9Sstevel@tonic-gate  */
3000e42dee6Sartem static int
findunixvol(fstyp_hsfs_t * h,char * volp)3010e42dee6Sartem findunixvol(fstyp_hsfs_t *h, char *volp)
3027c478bd9Sstevel@tonic-gate {
3030e42dee6Sartem 	int secno;
3040e42dee6Sartem 	int i;
3050e42dee6Sartem 	int err;
3067c478bd9Sstevel@tonic-gate 
3077c478bd9Sstevel@tonic-gate 	secno = ISO_VOLDESC_SEC;
3080e42dee6Sartem 	if ((err = GETCDSECTOR(h, volp, secno++, 1)) != 0) {
3090e42dee6Sartem 		return (err);
3100e42dee6Sartem 	}
3117c478bd9Sstevel@tonic-gate 	while (ISO_DESC_TYPE(volp) != ISO_VD_EOV) {
3127c478bd9Sstevel@tonic-gate 		for (i = 0; i < ISO_ID_STRLEN; i++)
3137c478bd9Sstevel@tonic-gate 			if (ISO_STD_ID(volp)[i] != ISO_ID_STRING[i])
3147c478bd9Sstevel@tonic-gate 				goto cantfind;
3157c478bd9Sstevel@tonic-gate 		if (ISO_STD_VER(volp) != ISO_ID_VER)
3167c478bd9Sstevel@tonic-gate 			goto cantfind;
3177c478bd9Sstevel@tonic-gate 		switch (ISO_DESC_TYPE(volp)) {
3187c478bd9Sstevel@tonic-gate 		case ISO_VD_UNIX:
3190e42dee6Sartem 			h->unix_pvd_sec_no = secno-1;
3200e42dee6Sartem 			return (0);
3217c478bd9Sstevel@tonic-gate 		case ISO_VD_EOV:
3227c478bd9Sstevel@tonic-gate 			goto cantfind;
3237c478bd9Sstevel@tonic-gate 		}
3240e42dee6Sartem 		if ((err = GETCDSECTOR(h, volp, secno++, 1)) != 0) {
3250e42dee6Sartem 			return (err);
3260e42dee6Sartem 		}
3277c478bd9Sstevel@tonic-gate 	}
3287c478bd9Sstevel@tonic-gate cantfind:
3290e42dee6Sartem 	return (FSTYP_ERR_NO_MATCH);
3307c478bd9Sstevel@tonic-gate }
3317c478bd9Sstevel@tonic-gate 
3320e42dee6Sartem static int
ckvoldesc(fstyp_hsfs_t * h,int * cd_type)3330e42dee6Sartem ckvoldesc(fstyp_hsfs_t *h, int *cd_type)
3347c478bd9Sstevel@tonic-gate {
3350e42dee6Sartem 	int	err;
3360e42dee6Sartem 
3370e42dee6Sartem 	if ((err = findhsvol(h, h->hs_buf)) == 0) {
3380e42dee6Sartem 		*cd_type = 0;
3390e42dee6Sartem 	} else if ((err = findisovol(h, h->iso_buf)) == 0) {
3400e42dee6Sartem 		if (findunixvol(h, h->unix_buf) == 0) {
3410e42dee6Sartem 			*cd_type = 2;
3420e42dee6Sartem 		} else {
3430e42dee6Sartem 			*cd_type = 1;
3440e42dee6Sartem 		}
345c719c59aSjkennedy 	} else {
3460e42dee6Sartem 		*cd_type = -1;
3477c478bd9Sstevel@tonic-gate 	}
3487c478bd9Sstevel@tonic-gate 
3490e42dee6Sartem 	return (err);
3507c478bd9Sstevel@tonic-gate }
3517c478bd9Sstevel@tonic-gate 
3520e42dee6Sartem static int
is_hsfs(fstyp_hsfs_t * h)3530e42dee6Sartem is_hsfs(fstyp_hsfs_t *h)
3547c478bd9Sstevel@tonic-gate {
3550e42dee6Sartem #ifdef CDROMREADOFFSET
3567c478bd9Sstevel@tonic-gate 	int err;
3577c478bd9Sstevel@tonic-gate 
3580e42dee6Sartem 	if (rdev_is_a_cd(h->fd)) {
3590e42dee6Sartem 		err = ioctl(h->fd, CDROMREADOFFSET, &h->cdroff);
3607c478bd9Sstevel@tonic-gate 		if (err == -1)
3617c478bd9Sstevel@tonic-gate 			/*
3627c478bd9Sstevel@tonic-gate 			 *  This device doesn't support this ioctl.
3637c478bd9Sstevel@tonic-gate 			 *  That's OK.
3647c478bd9Sstevel@tonic-gate 			 */
3650e42dee6Sartem 			h->cdroff = 0;
3667c478bd9Sstevel@tonic-gate 	}
3677c478bd9Sstevel@tonic-gate #endif
3687c478bd9Sstevel@tonic-gate 	/* check volume descriptor */
3690e42dee6Sartem 	return (ckvoldesc(h, &h->cd_type));
3700e42dee6Sartem }
3717c478bd9Sstevel@tonic-gate 
3720e42dee6Sartem #define	ADD_STRING(h, name, value) \
3730e42dee6Sartem 	if (nvlist_add_string(h->attr, name, value) != 0) { \
3740e42dee6Sartem 		return (FSTYP_ERR_NOMEM); \
3750e42dee6Sartem 	}
3767c478bd9Sstevel@tonic-gate 
3770e42dee6Sartem #define	ADD_UINT64(h, name, value) \
3780e42dee6Sartem 	if (nvlist_add_uint64(h->attr, name, value) != 0) { \
3790e42dee6Sartem 		return (FSTYP_ERR_NOMEM); \
3800e42dee6Sartem 	}
3817c478bd9Sstevel@tonic-gate 
3820e42dee6Sartem #define	ADD_BOOL(h, name, value) \
3830e42dee6Sartem 	if (nvlist_add_boolean_value(h->attr, name, value) != 0) { \
3840e42dee6Sartem 		return (FSTYP_ERR_NOMEM); \
3850e42dee6Sartem 	}
3867c478bd9Sstevel@tonic-gate 
3870e42dee6Sartem static int
get_attr(fstyp_hsfs_t * h)3880e42dee6Sartem get_attr(fstyp_hsfs_t *h)
3897c478bd9Sstevel@tonic-gate {
3907c478bd9Sstevel@tonic-gate 	char *sysid;
3917c478bd9Sstevel@tonic-gate 	char *volid;
3927c478bd9Sstevel@tonic-gate 	char *volsetid;
3937c478bd9Sstevel@tonic-gate 	char *pubid;
3947c478bd9Sstevel@tonic-gate 	char *prepid;
3957c478bd9Sstevel@tonic-gate 	char *applid;
3967c478bd9Sstevel@tonic-gate 	char *copyfile;
3977c478bd9Sstevel@tonic-gate 	char *absfile;
3987c478bd9Sstevel@tonic-gate 	char *bibfile;
3997c478bd9Sstevel@tonic-gate 	int volsetsize;
4007c478bd9Sstevel@tonic-gate 	int volsetseq;
4017c478bd9Sstevel@tonic-gate 	int blksize;
4027c478bd9Sstevel@tonic-gate 	int volsize;
4030e42dee6Sartem 	char s[256];
4047c478bd9Sstevel@tonic-gate 
4050e42dee6Sartem 	switch (h->cd_type) {
4067c478bd9Sstevel@tonic-gate 	case 0:
4070e42dee6Sartem 		ADD_STRING(h, "format", "High Sierra");
4080e42dee6Sartem 		ADD_STRING(h, "gen_version", "High Sierra");
4090e42dee6Sartem 		sysid = (char *)HSV_sys_id(h->hs_buf);
4100e42dee6Sartem 		volid = (char *)HSV_vol_id(h->hs_buf);
4110e42dee6Sartem 		volsetid = (char *)HSV_vol_set_id(h->hs_buf);
4120e42dee6Sartem 		pubid = (char *)HSV_pub_id(h->hs_buf);
4130e42dee6Sartem 		prepid = (char *)HSV_prep_id(h->hs_buf);
4140e42dee6Sartem 		applid = (char *)HSV_appl_id(h->hs_buf);
4150e42dee6Sartem 		copyfile = (char *)HSV_copyr_id(h->hs_buf);
4160e42dee6Sartem 		absfile = (char *)HSV_abstr_id(h->hs_buf);
417c719c59aSjkennedy 		bibfile = NULL;
4180e42dee6Sartem 		volsetsize = HSV_SET_SIZE(h->hs_buf);
4190e42dee6Sartem 		volsetseq = HSV_SET_SEQ(h->hs_buf);
4200e42dee6Sartem 		blksize = HSV_BLK_SIZE(h->hs_buf);
4210e42dee6Sartem 		volsize = HSV_VOL_SIZE(h->hs_buf);
4227c478bd9Sstevel@tonic-gate 		break;
4237c478bd9Sstevel@tonic-gate 	case 1:
4240e42dee6Sartem 		ADD_STRING(h, "format", "ISO 9660");
4250e42dee6Sartem 		ADD_STRING(h, "gen_version", "ISO 9660");
4260e42dee6Sartem 		sysid = (char *)ISO_sys_id(h->iso_buf);
4270e42dee6Sartem 		volid = (char *)ISO_vol_id(h->iso_buf);
4280e42dee6Sartem 		volsetid = (char *)ISO_vol_set_id(h->iso_buf);
4290e42dee6Sartem 		pubid = (char *)ISO_pub_id(h->iso_buf);
4300e42dee6Sartem 		prepid = (char *)ISO_prep_id(h->iso_buf);
4310e42dee6Sartem 		applid = (char *)ISO_appl_id(h->iso_buf);
4320e42dee6Sartem 		copyfile = (char *)ISO_copyr_id(h->iso_buf);
4330e42dee6Sartem 		absfile = (char *)ISO_abstr_id(h->iso_buf);
4340e42dee6Sartem 		bibfile = (char *)ISO_bibli_id(h->iso_buf);
4350e42dee6Sartem 		volsetsize = ISO_SET_SIZE(h->iso_buf);
4360e42dee6Sartem 		volsetseq = ISO_SET_SEQ(h->iso_buf);
4370e42dee6Sartem 		blksize = ISO_BLK_SIZE(h->iso_buf);
4380e42dee6Sartem 		volsize = ISO_VOL_SIZE(h->iso_buf);
4397c478bd9Sstevel@tonic-gate 		break;
4407c478bd9Sstevel@tonic-gate 	case 2:
4410e42dee6Sartem 		ADD_STRING(h, "format", "ISO 9660 with UNIX extension");
4420e42dee6Sartem 		ADD_STRING(h, "gen_version", "ISO 9660 with UNIX extension");
4430e42dee6Sartem 		sysid = (char *)ISO_sys_id(h->unix_buf);
4440e42dee6Sartem 		volid = (char *)ISO_vol_id(h->unix_buf);
4450e42dee6Sartem 		volsetid = (char *)ISO_vol_set_id(h->unix_buf);
4460e42dee6Sartem 		pubid = (char *)ISO_pub_id(h->unix_buf);
4470e42dee6Sartem 		prepid = (char *)ISO_prep_id(h->unix_buf);
4480e42dee6Sartem 		applid = (char *)ISO_appl_id(h->unix_buf);
4490e42dee6Sartem 		copyfile = (char *)ISO_copyr_id(h->unix_buf);
4500e42dee6Sartem 		absfile = (char *)ISO_abstr_id(h->unix_buf);
4510e42dee6Sartem 		bibfile = (char *)ISO_bibli_id(h->unix_buf);
4520e42dee6Sartem 		volsetsize = ISO_SET_SIZE(h->unix_buf);
4530e42dee6Sartem 		volsetseq = ISO_SET_SEQ(h->unix_buf);
4540e42dee6Sartem 		blksize = ISO_BLK_SIZE(h->unix_buf);
4550e42dee6Sartem 		volsize = ISO_VOL_SIZE(h->unix_buf);
4567c478bd9Sstevel@tonic-gate 		break;
4577c478bd9Sstevel@tonic-gate 	default:
4580e42dee6Sartem 		return (FSTYP_ERR_NO_MATCH);
4597c478bd9Sstevel@tonic-gate 	}
4600e42dee6Sartem 
4610e42dee6Sartem 	copy_string(s, sysid, 32);
4620e42dee6Sartem 	ADD_STRING(h, "system_id", s);
4630e42dee6Sartem 	copy_string(s, volid, 32);
4640e42dee6Sartem 	ADD_STRING(h, "volume_id", s);
4650e42dee6Sartem 	ADD_STRING(h, "gen_volume_label", s);
4660e42dee6Sartem 	copy_string(s, volsetid, 128);
4670e42dee6Sartem 	ADD_STRING(h, "volume_set_id", s);
4680e42dee6Sartem 	copy_string(s, pubid, 128);
4690e42dee6Sartem 	ADD_STRING(h, "publisher_id", s);
4700e42dee6Sartem 	copy_string(s, prepid, 128);
4710e42dee6Sartem 	ADD_STRING(h, "data_preparer_id", s);
4720e42dee6Sartem 	copy_string(s, applid, 128);
4730e42dee6Sartem 	ADD_STRING(h, "application_id", s);
4740e42dee6Sartem 	copy_string(s, copyfile, 37);
4750e42dee6Sartem 	ADD_STRING(h, "copyright_file_id", s);
4760e42dee6Sartem 	copy_string(s, absfile, 37);
4770e42dee6Sartem 	ADD_STRING(h, "abstract_file_id", s);
4780e42dee6Sartem 	copy_string(s, bibfile, 37);
4790e42dee6Sartem 	ADD_STRING(h, "bibliographic_file_id", s);
4800e42dee6Sartem 	ADD_UINT64(h, "volume_set_size", volsetsize);
4810e42dee6Sartem 	ADD_UINT64(h, "volume_set_sequence_number", volsetseq);
4820e42dee6Sartem 	ADD_UINT64(h, "logical_block_size", blksize);
4830e42dee6Sartem 	ADD_UINT64(h, "volume_size", volsize);
4840e42dee6Sartem 	ADD_BOOL(h, "gen_clean", B_TRUE);
4850e42dee6Sartem 
4860e42dee6Sartem 	return (0);
4877c478bd9Sstevel@tonic-gate }
4887c478bd9Sstevel@tonic-gate 
489c719c59aSjkennedy static void
copy_string(char * d,char * s,int maxlen)4900e42dee6Sartem copy_string(char *d, char *s, int maxlen)
4917c478bd9Sstevel@tonic-gate {
492c719c59aSjkennedy 	int i;
4937c478bd9Sstevel@tonic-gate 
4947c478bd9Sstevel@tonic-gate 	/* strip off trailing zeros */
4950e42dee6Sartem 	for (i = maxlen-1; i >= 0; i--) {
4960e42dee6Sartem 		if (s[i] != ' ') {
4970e42dee6Sartem 			break;
4980e42dee6Sartem 		}
4990e42dee6Sartem 	}
5007c478bd9Sstevel@tonic-gate 
5017c478bd9Sstevel@tonic-gate 	maxlen = i+1;
5020e42dee6Sartem 	for (i = 0; i < maxlen; i++) {
5030e42dee6Sartem 		*d++ = s[i];
5040e42dee6Sartem 	}
5050e42dee6Sartem 	*d++ = '\0';
5067c478bd9Sstevel@tonic-gate }
5077c478bd9Sstevel@tonic-gate 
508c719c59aSjkennedy /* readdisk - read from cdrom image file */
5090e42dee6Sartem static int
getdisk(fstyp_hsfs_t * h,char * buf,int daddr,int size)5100e42dee6Sartem getdisk(fstyp_hsfs_t *h, char *buf, int daddr, int size)
5117c478bd9Sstevel@tonic-gate {
5120e42dee6Sartem 	if (lseek(h->fd, daddr, L_SET) == -1) {
5130e42dee6Sartem 		return (FSTYP_ERR_IO);
514c719c59aSjkennedy 	}
5150e42dee6Sartem 	if (read(h->fd, buf, size) != size) {
5160e42dee6Sartem 		return (FSTYP_ERR_IO);
517c719c59aSjkennedy 	}
5180e42dee6Sartem 	return (0);
5197c478bd9Sstevel@tonic-gate }
5207c478bd9Sstevel@tonic-gate 
5217c478bd9Sstevel@tonic-gate /*
5227c478bd9Sstevel@tonic-gate  * rdev_is_a_cd  - return TRUE if the raw device identified by
523c719c59aSjkennedy  *		      a file descriptor is a CDROM device.
5247c478bd9Sstevel@tonic-gate  *
5257c478bd9Sstevel@tonic-gate  *		      return FALSE if the device can't be accessed
5267c478bd9Sstevel@tonic-gate  *		      or is not a CDROM.
5277c478bd9Sstevel@tonic-gate  */
5287c478bd9Sstevel@tonic-gate static int
rdev_is_a_cd(int rdevfd)5297c478bd9Sstevel@tonic-gate rdev_is_a_cd(int rdevfd)
5307c478bd9Sstevel@tonic-gate {
5317c478bd9Sstevel@tonic-gate 	struct dk_cinfo dkc;
5327c478bd9Sstevel@tonic-gate 
533c719c59aSjkennedy 	if (ioctl(rdevfd, DKIOCINFO, &dkc) < 0)
534c719c59aSjkennedy 		return (0);
535c719c59aSjkennedy 	if (dkc.dki_ctype == DKC_CDROM)
536c719c59aSjkennedy 		return (1);
5377c478bd9Sstevel@tonic-gate 	else
5387c478bd9Sstevel@tonic-gate 		return (0);
5397c478bd9Sstevel@tonic-gate }
540