xref: /onnv-gate/usr/src/cmd/fs.d/udfs/fstyp/fstyp.c (revision 2212:4d4fd25d9b6e)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*2212Sartem  * Common Development and Distribution License (the "License").
6*2212Sartem  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*2212Sartem  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
28*2212Sartem /*
29*2212Sartem  * libfstyp module for udfs
30*2212Sartem  */
310Sstevel@tonic-gate #include <fcntl.h>
320Sstevel@tonic-gate #include <stdio.h>
330Sstevel@tonic-gate #include <errno.h>
340Sstevel@tonic-gate #include <unistd.h>
350Sstevel@tonic-gate #include <locale.h>
360Sstevel@tonic-gate #include <stdlib.h>
370Sstevel@tonic-gate #include <strings.h>
380Sstevel@tonic-gate #include <sys/param.h>
390Sstevel@tonic-gate #include <sys/stat.h>
400Sstevel@tonic-gate #include <sys/time.h>
410Sstevel@tonic-gate #include <sys/types.h>
420Sstevel@tonic-gate #include <sys/file.h>
43*2212Sartem #include <libnvpair.h>
44*2212Sartem #include <libfstyp_module.h>
450Sstevel@tonic-gate #include <sys/fs/udf_volume.h>
460Sstevel@tonic-gate #include "ud_lib.h"
470Sstevel@tonic-gate 
480Sstevel@tonic-gate 
49*2212Sartem typedef struct fstyp_udfs {
50*2212Sartem 	int		fd;
51*2212Sartem 	ud_handle_t	udh;
52*2212Sartem 	nvlist_t	*attr;
53*2212Sartem } fstyp_udfs_t;
540Sstevel@tonic-gate 
55*2212Sartem static int	is_udfs(fstyp_udfs_t *h);
56*2212Sartem static int	print_vds(fstyp_udfs_t *h, struct vds *,
57*2212Sartem 		FILE *fout, FILE *ferr);
58*2212Sartem static int	get_attr(fstyp_udfs_t *h);
590Sstevel@tonic-gate 
60*2212Sartem int	fstyp_mod_init(int fd, off_t offset, fstyp_mod_handle_t *handle);
61*2212Sartem void	fstyp_mod_fini(fstyp_mod_handle_t handle);
62*2212Sartem int	fstyp_mod_ident(fstyp_mod_handle_t handle);
63*2212Sartem int	fstyp_mod_get_attr(fstyp_mod_handle_t handle, nvlist_t **attrp);
64*2212Sartem int	fstyp_mod_dump(fstyp_mod_handle_t handle, FILE *fout, FILE *ferr);
65*2212Sartem 
660Sstevel@tonic-gate 
670Sstevel@tonic-gate int
fstyp_mod_init(int fd,off_t offset,fstyp_mod_handle_t * handle)68*2212Sartem fstyp_mod_init(int fd, off_t offset, fstyp_mod_handle_t *handle)
690Sstevel@tonic-gate {
70*2212Sartem 	fstyp_udfs_t *h = (fstyp_udfs_t *)handle;
71*2212Sartem 
72*2212Sartem 	if (offset != 0) {
73*2212Sartem 		return (FSTYP_ERR_OFFSET);
74*2212Sartem 	}
75*2212Sartem 
76*2212Sartem 	if ((h = calloc(1, sizeof (fstyp_udfs_t))) == NULL) {
77*2212Sartem 		return (FSTYP_ERR_NOMEM);
78*2212Sartem 	}
79*2212Sartem 	h->fd = fd;
80*2212Sartem 
81*2212Sartem 	if (ud_init(h->fd, &h->udh) != 0) {
82*2212Sartem 		free(h);
83*2212Sartem 		return (FSTYP_ERR_NOMEM);
84*2212Sartem 	}
85*2212Sartem 
86*2212Sartem 	*handle = (fstyp_mod_handle_t)h;
87*2212Sartem 	return (0);
88*2212Sartem }
89*2212Sartem 
90*2212Sartem void
fstyp_mod_fini(fstyp_mod_handle_t handle)91*2212Sartem fstyp_mod_fini(fstyp_mod_handle_t handle)
92*2212Sartem {
93*2212Sartem 	fstyp_udfs_t *h = (fstyp_udfs_t *)handle;
940Sstevel@tonic-gate 
95*2212Sartem 	if (h->attr == NULL) {
96*2212Sartem 		nvlist_free(h->attr);
97*2212Sartem 		h->attr = NULL;
98*2212Sartem 	}
99*2212Sartem 	ud_fini(h->udh);
100*2212Sartem 	free(h);
101*2212Sartem }
102*2212Sartem 
103*2212Sartem int
fstyp_mod_ident(fstyp_mod_handle_t handle)104*2212Sartem fstyp_mod_ident(fstyp_mod_handle_t handle)
105*2212Sartem {
106*2212Sartem 	fstyp_udfs_t *h = (fstyp_udfs_t *)handle;
1070Sstevel@tonic-gate 
108*2212Sartem 	return (is_udfs(h));
109*2212Sartem }
110*2212Sartem 
111*2212Sartem int
fstyp_mod_get_attr(fstyp_mod_handle_t handle,nvlist_t ** attrp)112*2212Sartem fstyp_mod_get_attr(fstyp_mod_handle_t handle, nvlist_t **attrp)
113*2212Sartem {
114*2212Sartem 	fstyp_udfs_t *h = (fstyp_udfs_t *)handle;
115*2212Sartem 	int error;
116*2212Sartem 
117*2212Sartem 	if (h->attr == NULL) {
118*2212Sartem 		if (nvlist_alloc(&h->attr, NV_UNIQUE_NAME_TYPE, 0)) {
119*2212Sartem 			return (FSTYP_ERR_NOMEM);
120*2212Sartem 		}
121*2212Sartem 		if ((error = get_attr(h)) != 0) {
122*2212Sartem 			nvlist_free(h->attr);
123*2212Sartem 			h->attr = NULL;
124*2212Sartem 			return (error);
1250Sstevel@tonic-gate 		}
1260Sstevel@tonic-gate 	}
1270Sstevel@tonic-gate 
128*2212Sartem 	*attrp = h->attr;
129*2212Sartem 	return (0);
130*2212Sartem }
131*2212Sartem 
132*2212Sartem int
fstyp_mod_dump(fstyp_mod_handle_t handle,FILE * fout,FILE * ferr)133*2212Sartem fstyp_mod_dump(fstyp_mod_handle_t handle, FILE *fout, FILE *ferr)
134*2212Sartem {
135*2212Sartem 	fstyp_udfs_t *h = (fstyp_udfs_t *)handle;
136*2212Sartem 	struct udf *udfs = &h->udh->udfs;
137*2212Sartem 	int ret;
138*2212Sartem 
139*2212Sartem 	(void) fprintf(fout,
140*2212Sartem 		"Standard Identifier %5s\n", udfs->ecma_id);
141*2212Sartem 
142*2212Sartem 	if (udfs->flags & VALID_MVDS) {
143*2212Sartem 		ret = print_vds(h, &udfs->mvds, fout, ferr);
144*2212Sartem 	} else {
145*2212Sartem 		ret = print_vds(h, &udfs->rvds, fout, ferr);
1460Sstevel@tonic-gate 	}
1470Sstevel@tonic-gate 
148*2212Sartem 	return (ret);
1490Sstevel@tonic-gate }
1500Sstevel@tonic-gate 
1510Sstevel@tonic-gate 
1520Sstevel@tonic-gate /*
1530Sstevel@tonic-gate  * Assumption is that we will confirm to level-1
1540Sstevel@tonic-gate  */
1550Sstevel@tonic-gate int
is_udfs(fstyp_udfs_t * h)156*2212Sartem is_udfs(fstyp_udfs_t *h)
1570Sstevel@tonic-gate {
158*2212Sartem 	struct udf *udfs = &h->udh->udfs;
1590Sstevel@tonic-gate 	int32_t ret;
1600Sstevel@tonic-gate 
161*2212Sartem 	if ((ret = ud_fill_udfs_info(h->udh)) != 0) {
1620Sstevel@tonic-gate 		return (ret);
1630Sstevel@tonic-gate 	}
1640Sstevel@tonic-gate 
165*2212Sartem 	if ((udfs->flags & VALID_UDFS) == 0) {
166*2212Sartem 		return (FSTYP_ERR_NO_MATCH);
1670Sstevel@tonic-gate 	}
1680Sstevel@tonic-gate 
169*2212Sartem 	return (0);
170*2212Sartem }
1710Sstevel@tonic-gate 
172*2212Sartem /*
173*2212Sartem  * For now, only return generic attributes.
174*2212Sartem  * Will open an RFE to add native attributes.
175*2212Sartem  */
176*2212Sartem static int
get_attr(fstyp_udfs_t * h)177*2212Sartem get_attr(fstyp_udfs_t *h)
178*2212Sartem {
179*2212Sartem 	struct udf *udfs = &h->udh->udfs;
180*2212Sartem 	struct vds *v;
181*2212Sartem 	struct pri_vol_desc *pvd;
182*2212Sartem 	uint32_t len;
183*2212Sartem 	uint64_t off;
184*2212Sartem 	uint8_t *buf;
185*2212Sartem 	int8_t str[64];
186*2212Sartem 	int ret = 0;
187*2212Sartem 
188*2212Sartem 	v = (udfs->flags & VALID_MVDS) ? &udfs->mvds : &udfs->rvds;
189*2212Sartem 
190*2212Sartem 	/* allocate buffer */
191*2212Sartem 	len = udfs->lbsize;
192*2212Sartem 	if (v->pvd_len > len) {
193*2212Sartem 		len = v->pvd_len;
194*2212Sartem 	}
195*2212Sartem 	if ((buf = (uint8_t *)malloc(len)) == NULL) {
196*2212Sartem 		return (FSTYP_ERR_NOMEM);
1970Sstevel@tonic-gate 	}
1980Sstevel@tonic-gate 
199*2212Sartem 	(void) nvlist_add_boolean_value(h->attr, "gen_clean", B_TRUE);
200*2212Sartem 
201*2212Sartem 	/* Primary Volume Descriptor */
202*2212Sartem 	if (v->pvd_len != 0) {
203*2212Sartem 		off = v->pvd_loc * udfs->lbsize;
204*2212Sartem 		if (ud_read_dev(h->udh, off, buf, v->pvd_len) != 0) {
205*2212Sartem 			ret = FSTYP_ERR_IO;
206*2212Sartem 			goto out;
207*2212Sartem 		}
208*2212Sartem 		/* LINTED */
209*2212Sartem 		pvd = (struct pri_vol_desc *)(uint32_t *)buf;
210*2212Sartem 
211*2212Sartem 		ud_convert2local(pvd->pvd_vol_id, str, 32);
212*2212Sartem 		str[32] = '\0';
213*2212Sartem 		(void) nvlist_add_string(h->attr, "gen_volume_label", str);
214*2212Sartem 	}
215*2212Sartem 
216*2212Sartem 	ret = 0;
217*2212Sartem 
218*2212Sartem out:
219*2212Sartem 	free(buf);
2200Sstevel@tonic-gate 	return (ret);
2210Sstevel@tonic-gate }
2220Sstevel@tonic-gate 
223*2212Sartem /* ARGSUSED */
2240Sstevel@tonic-gate int
print_vds(fstyp_udfs_t * h,struct vds * v,FILE * fout,FILE * ferr)225*2212Sartem print_vds(fstyp_udfs_t *h, struct vds *v, FILE *fout, FILE *ferr)
2260Sstevel@tonic-gate {
227*2212Sartem 	struct udf *udfs = &h->udh->udfs;
2280Sstevel@tonic-gate 	int32_t i;
2290Sstevel@tonic-gate 	uint32_t len;
2300Sstevel@tonic-gate 	uint64_t off;
2310Sstevel@tonic-gate 	uint8_t *buf;
232*2212Sartem 	int	ret = 0;
2330Sstevel@tonic-gate 
2340Sstevel@tonic-gate 	/*
2350Sstevel@tonic-gate 	 * All descriptors are 512 bytes
2360Sstevel@tonic-gate 	 * except lvd, usd and lvid
2370Sstevel@tonic-gate 	 * findout the largest and allocate space
2380Sstevel@tonic-gate 	 */
239*2212Sartem 	len = udfs->lbsize;
2400Sstevel@tonic-gate 	if (v->lvd_len > len) {
2410Sstevel@tonic-gate 		len = v->lvd_len;
2420Sstevel@tonic-gate 	}
2430Sstevel@tonic-gate 	if (v->usd_len > len) {
2440Sstevel@tonic-gate 		len = v->usd_len;
2450Sstevel@tonic-gate 	}
246*2212Sartem 	if (udfs->lvid_len > len) {
247*2212Sartem 		len = udfs->lvid_len;
2480Sstevel@tonic-gate 	}
2490Sstevel@tonic-gate 
2500Sstevel@tonic-gate 	if ((buf = (uint8_t *)malloc(len)) == NULL) {
251*2212Sartem 		return (FSTYP_ERR_NOMEM);
2520Sstevel@tonic-gate 	}
2530Sstevel@tonic-gate 
2540Sstevel@tonic-gate 	/*
2550Sstevel@tonic-gate 	 * Anchor Volume Descriptor
2560Sstevel@tonic-gate 	 */
257*2212Sartem 	if (udfs->avdp_len != 0) {
258*2212Sartem 		off = udfs->avdp_loc * udfs->lbsize;
259*2212Sartem 		if (ud_read_dev(h->udh, off, buf, udfs->avdp_len) != 0) {
260*2212Sartem 			ret = FSTYP_ERR_IO;
261*2212Sartem 			goto out;
2620Sstevel@tonic-gate 		}
2630Sstevel@tonic-gate 
2640Sstevel@tonic-gate 		/* LINTED */
265*2212Sartem 		print_avd(fout, (struct anch_vol_desc_ptr *)buf);
2660Sstevel@tonic-gate 	}
2670Sstevel@tonic-gate 
2680Sstevel@tonic-gate 	/*
2690Sstevel@tonic-gate 	 * Primary Volume Descriptor
2700Sstevel@tonic-gate 	 */
2710Sstevel@tonic-gate 	if (v->pvd_len != 0) {
272*2212Sartem 		off = v->pvd_loc * udfs->lbsize;
273*2212Sartem 		if (ud_read_dev(h->udh, off, buf, v->pvd_len) != 0) {
274*2212Sartem 			ret = FSTYP_ERR_IO;
275*2212Sartem 			goto out;
2760Sstevel@tonic-gate 		}
2770Sstevel@tonic-gate 
2780Sstevel@tonic-gate 		/* LINTED */
279*2212Sartem 		print_pvd(fout, (struct pri_vol_desc *)buf);
2800Sstevel@tonic-gate 	}
2810Sstevel@tonic-gate 
2820Sstevel@tonic-gate 	/*
2830Sstevel@tonic-gate 	 * Implementation Use descriptor
2840Sstevel@tonic-gate 	 */
2850Sstevel@tonic-gate 	if (v->iud_len != 0) {
286*2212Sartem 		off = v->iud_loc * udfs->lbsize;
287*2212Sartem 		if (ud_read_dev(h->udh, off, buf, v->iud_len) != 0) {
288*2212Sartem 			ret = FSTYP_ERR_IO;
289*2212Sartem 			goto out;
2900Sstevel@tonic-gate 		}
2910Sstevel@tonic-gate 
2920Sstevel@tonic-gate 		/* LINTED */
293*2212Sartem 		print_iuvd(fout, (struct iuvd_desc *)buf);
2940Sstevel@tonic-gate 	}
2950Sstevel@tonic-gate 
2960Sstevel@tonic-gate 	/*
2970Sstevel@tonic-gate 	 * Paritions
2980Sstevel@tonic-gate 	 */
299*2212Sartem 	for (i = 0; i < h->udh->n_parts; i++) {
3000Sstevel@tonic-gate 		if (v->part_len[i] != 0) {
301*2212Sartem 			off = v->part_loc[i] * udfs->lbsize;
302*2212Sartem 			if (ud_read_dev(h->udh, off, buf,
303*2212Sartem 			    v->part_len[i]) != 0) {
304*2212Sartem 				ret = FSTYP_ERR_IO;
305*2212Sartem 				goto out;
3060Sstevel@tonic-gate 			}
3070Sstevel@tonic-gate 
3080Sstevel@tonic-gate 			/* LINTED */
309*2212Sartem 			print_part(fout, (struct part_desc *)buf);
3100Sstevel@tonic-gate 		}
3110Sstevel@tonic-gate 	}
3120Sstevel@tonic-gate 
3130Sstevel@tonic-gate 	/*
3140Sstevel@tonic-gate 	 * Logical Volume Descriptor
3150Sstevel@tonic-gate 	 */
3160Sstevel@tonic-gate 	if (v->lvd_len != 0) {
317*2212Sartem 		off = v->lvd_loc * udfs->lbsize;
318*2212Sartem 		if (ud_read_dev(h->udh, off, buf, v->lvd_len) != 0) {
319*2212Sartem 			ret = FSTYP_ERR_IO;
320*2212Sartem 			goto out;
3210Sstevel@tonic-gate 		}
3220Sstevel@tonic-gate 
3230Sstevel@tonic-gate 		/* LINTED */
324*2212Sartem 		print_lvd(fout, (struct log_vol_desc *)buf);
3250Sstevel@tonic-gate 	}
3260Sstevel@tonic-gate 
3270Sstevel@tonic-gate 	/*
3280Sstevel@tonic-gate 	 * Unallocated Space Descriptor
3290Sstevel@tonic-gate 	 */
3300Sstevel@tonic-gate 	if (v->usd_len != 0) {
331*2212Sartem 		off = v->usd_loc * udfs->lbsize;
332*2212Sartem 		if (ud_read_dev(h->udh, off, buf, v->usd_len) != 0) {
333*2212Sartem 			ret = FSTYP_ERR_IO;
334*2212Sartem 			goto out;
3350Sstevel@tonic-gate 		}
3360Sstevel@tonic-gate 
3370Sstevel@tonic-gate 		/* LINTED */
338*2212Sartem 		print_usd(fout, (struct unall_spc_desc *)buf);
3390Sstevel@tonic-gate 	}
3400Sstevel@tonic-gate 
3410Sstevel@tonic-gate 	/*
3420Sstevel@tonic-gate 	 * Logical Volume Integrity Descriptor
3430Sstevel@tonic-gate 	 */
344*2212Sartem 	if (udfs->lvid_len != 0) {
345*2212Sartem 		off = udfs->lvid_loc * udfs->lbsize;
346*2212Sartem 		if (ud_read_dev(h->udh, off, buf, udfs->lvid_len) != 0) {
347*2212Sartem 			ret = FSTYP_ERR_IO;
348*2212Sartem 			goto out;
3490Sstevel@tonic-gate 		}
3500Sstevel@tonic-gate 
3510Sstevel@tonic-gate 		/* LINTED */
352*2212Sartem 		print_lvid(fout, (struct log_vol_int_desc *)buf);
3530Sstevel@tonic-gate 	}
3540Sstevel@tonic-gate 
3550Sstevel@tonic-gate 	/*
3560Sstevel@tonic-gate 	 * File Set Descriptor
3570Sstevel@tonic-gate 	 */
358*2212Sartem 	if (udfs->fsd_len != 0) {
359*2212Sartem 		off = udfs->fsd_loc * udfs->lbsize;
360*2212Sartem 		if (ud_read_dev(h->udh, off, buf, udfs->fsd_len) != 0) {
361*2212Sartem 			ret = FSTYP_ERR_IO;
362*2212Sartem 			goto out;
3630Sstevel@tonic-gate 		}
3640Sstevel@tonic-gate 
3650Sstevel@tonic-gate 		/* LINTED */
366*2212Sartem 		print_fsd(fout, h->udh, (struct file_set_desc *)buf);
3670Sstevel@tonic-gate 	}
368*2212Sartem 	ret = 0;
3690Sstevel@tonic-gate 
370*2212Sartem out:
371*2212Sartem 	free(buf);
372*2212Sartem 	return (ret);
3730Sstevel@tonic-gate }
374