xref: /illumos-gate/usr/src/cmd/fs.d/udfs/fstyp/fstyp.c (revision 2a8bcb4e)
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
5*0e42dee6Sartem  * Common Development and Distribution License (the "License").
6*0e42dee6Sartem  * 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 /*
22*0e42dee6Sartem  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
26*0e42dee6Sartem /*
27*0e42dee6Sartem  * libfstyp module for udfs
28*0e42dee6Sartem  */
297c478bd9Sstevel@tonic-gate #include <fcntl.h>
307c478bd9Sstevel@tonic-gate #include <stdio.h>
317c478bd9Sstevel@tonic-gate #include <errno.h>
327c478bd9Sstevel@tonic-gate #include <unistd.h>
337c478bd9Sstevel@tonic-gate #include <locale.h>
347c478bd9Sstevel@tonic-gate #include <stdlib.h>
357c478bd9Sstevel@tonic-gate #include <strings.h>
367c478bd9Sstevel@tonic-gate #include <sys/param.h>
377c478bd9Sstevel@tonic-gate #include <sys/stat.h>
387c478bd9Sstevel@tonic-gate #include <sys/time.h>
397c478bd9Sstevel@tonic-gate #include <sys/types.h>
407c478bd9Sstevel@tonic-gate #include <sys/file.h>
41*0e42dee6Sartem #include <libnvpair.h>
42*0e42dee6Sartem #include <libfstyp_module.h>
437c478bd9Sstevel@tonic-gate #include <sys/fs/udf_volume.h>
447c478bd9Sstevel@tonic-gate #include "ud_lib.h"
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate 
47*0e42dee6Sartem typedef struct fstyp_udfs {
48*0e42dee6Sartem 	int		fd;
49*0e42dee6Sartem 	ud_handle_t	udh;
50*0e42dee6Sartem 	nvlist_t	*attr;
51*0e42dee6Sartem } fstyp_udfs_t;
527c478bd9Sstevel@tonic-gate 
53*0e42dee6Sartem static int	is_udfs(fstyp_udfs_t *h);
54*0e42dee6Sartem static int	print_vds(fstyp_udfs_t *h, struct vds *,
55*0e42dee6Sartem 		FILE *fout, FILE *ferr);
56*0e42dee6Sartem static int	get_attr(fstyp_udfs_t *h);
57*0e42dee6Sartem 
58*0e42dee6Sartem int	fstyp_mod_init(int fd, off_t offset, fstyp_mod_handle_t *handle);
59*0e42dee6Sartem void	fstyp_mod_fini(fstyp_mod_handle_t handle);
60*0e42dee6Sartem int	fstyp_mod_ident(fstyp_mod_handle_t handle);
61*0e42dee6Sartem int	fstyp_mod_get_attr(fstyp_mod_handle_t handle, nvlist_t **attrp);
62*0e42dee6Sartem int	fstyp_mod_dump(fstyp_mod_handle_t handle, FILE *fout, FILE *ferr);
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate int
fstyp_mod_init(int fd,off_t offset,fstyp_mod_handle_t * handle)66*0e42dee6Sartem fstyp_mod_init(int fd, off_t offset, fstyp_mod_handle_t *handle)
677c478bd9Sstevel@tonic-gate {
68*0e42dee6Sartem 	fstyp_udfs_t *h = (fstyp_udfs_t *)handle;
69*0e42dee6Sartem 
70*0e42dee6Sartem 	if (offset != 0) {
71*0e42dee6Sartem 		return (FSTYP_ERR_OFFSET);
727c478bd9Sstevel@tonic-gate 	}
737c478bd9Sstevel@tonic-gate 
74*0e42dee6Sartem 	if ((h = calloc(1, sizeof (fstyp_udfs_t))) == NULL) {
75*0e42dee6Sartem 		return (FSTYP_ERR_NOMEM);
767c478bd9Sstevel@tonic-gate 	}
77*0e42dee6Sartem 	h->fd = fd;
787c478bd9Sstevel@tonic-gate 
79*0e42dee6Sartem 	if (ud_init(h->fd, &h->udh) != 0) {
80*0e42dee6Sartem 		free(h);
81*0e42dee6Sartem 		return (FSTYP_ERR_NOMEM);
827c478bd9Sstevel@tonic-gate 	}
837c478bd9Sstevel@tonic-gate 
84*0e42dee6Sartem 	*handle = (fstyp_mod_handle_t)h;
85*0e42dee6Sartem 	return (0);
86*0e42dee6Sartem }
87*0e42dee6Sartem 
88*0e42dee6Sartem void
fstyp_mod_fini(fstyp_mod_handle_t handle)89*0e42dee6Sartem fstyp_mod_fini(fstyp_mod_handle_t handle)
90*0e42dee6Sartem {
91*0e42dee6Sartem 	fstyp_udfs_t *h = (fstyp_udfs_t *)handle;
92*0e42dee6Sartem 
93*0e42dee6Sartem 	if (h->attr == NULL) {
94*0e42dee6Sartem 		nvlist_free(h->attr);
95*0e42dee6Sartem 		h->attr = NULL;
96*0e42dee6Sartem 	}
97*0e42dee6Sartem 	ud_fini(h->udh);
98*0e42dee6Sartem 	free(h);
99*0e42dee6Sartem }
100*0e42dee6Sartem 
101*0e42dee6Sartem int
fstyp_mod_ident(fstyp_mod_handle_t handle)102*0e42dee6Sartem fstyp_mod_ident(fstyp_mod_handle_t handle)
103*0e42dee6Sartem {
104*0e42dee6Sartem 	fstyp_udfs_t *h = (fstyp_udfs_t *)handle;
105*0e42dee6Sartem 
106*0e42dee6Sartem 	return (is_udfs(h));
107*0e42dee6Sartem }
108*0e42dee6Sartem 
109*0e42dee6Sartem int
fstyp_mod_get_attr(fstyp_mod_handle_t handle,nvlist_t ** attrp)110*0e42dee6Sartem fstyp_mod_get_attr(fstyp_mod_handle_t handle, nvlist_t **attrp)
111*0e42dee6Sartem {
112*0e42dee6Sartem 	fstyp_udfs_t *h = (fstyp_udfs_t *)handle;
113*0e42dee6Sartem 	int error;
114*0e42dee6Sartem 
115*0e42dee6Sartem 	if (h->attr == NULL) {
116*0e42dee6Sartem 		if (nvlist_alloc(&h->attr, NV_UNIQUE_NAME_TYPE, 0)) {
117*0e42dee6Sartem 			return (FSTYP_ERR_NOMEM);
118*0e42dee6Sartem 		}
119*0e42dee6Sartem 		if ((error = get_attr(h)) != 0) {
120*0e42dee6Sartem 			nvlist_free(h->attr);
121*0e42dee6Sartem 			h->attr = NULL;
122*0e42dee6Sartem 			return (error);
123*0e42dee6Sartem 		}
124*0e42dee6Sartem 	}
125*0e42dee6Sartem 
126*0e42dee6Sartem 	*attrp = h->attr;
127*0e42dee6Sartem 	return (0);
128*0e42dee6Sartem }
129*0e42dee6Sartem 
130*0e42dee6Sartem int
fstyp_mod_dump(fstyp_mod_handle_t handle,FILE * fout,FILE * ferr)131*0e42dee6Sartem fstyp_mod_dump(fstyp_mod_handle_t handle, FILE *fout, FILE *ferr)
132*0e42dee6Sartem {
133*0e42dee6Sartem 	fstyp_udfs_t *h = (fstyp_udfs_t *)handle;
134*0e42dee6Sartem 	struct udf *udfs = &h->udh->udfs;
135*0e42dee6Sartem 	int ret;
1367c478bd9Sstevel@tonic-gate 
137*0e42dee6Sartem 	(void) fprintf(fout,
138*0e42dee6Sartem 		"Standard Identifier %5s\n", udfs->ecma_id);
139*0e42dee6Sartem 
140*0e42dee6Sartem 	if (udfs->flags & VALID_MVDS) {
141*0e42dee6Sartem 		ret = print_vds(h, &udfs->mvds, fout, ferr);
142*0e42dee6Sartem 	} else {
143*0e42dee6Sartem 		ret = print_vds(h, &udfs->rvds, fout, ferr);
144*0e42dee6Sartem 	}
1457c478bd9Sstevel@tonic-gate 
146*0e42dee6Sartem 	return (ret);
1477c478bd9Sstevel@tonic-gate }
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate /*
1517c478bd9Sstevel@tonic-gate  * Assumption is that we will confirm to level-1
1527c478bd9Sstevel@tonic-gate  */
1537c478bd9Sstevel@tonic-gate int
is_udfs(fstyp_udfs_t * h)154*0e42dee6Sartem is_udfs(fstyp_udfs_t *h)
1557c478bd9Sstevel@tonic-gate {
156*0e42dee6Sartem 	struct udf *udfs = &h->udh->udfs;
1577c478bd9Sstevel@tonic-gate 	int32_t ret;
1587c478bd9Sstevel@tonic-gate 
159*0e42dee6Sartem 	if ((ret = ud_fill_udfs_info(h->udh)) != 0) {
1607c478bd9Sstevel@tonic-gate 		return (ret);
1617c478bd9Sstevel@tonic-gate 	}
1627c478bd9Sstevel@tonic-gate 
163*0e42dee6Sartem 	if ((udfs->flags & VALID_UDFS) == 0) {
164*0e42dee6Sartem 		return (FSTYP_ERR_NO_MATCH);
1657c478bd9Sstevel@tonic-gate 	}
1667c478bd9Sstevel@tonic-gate 
167*0e42dee6Sartem 	return (0);
168*0e42dee6Sartem }
169*0e42dee6Sartem 
170*0e42dee6Sartem /*
171*0e42dee6Sartem  * For now, only return generic attributes.
172*0e42dee6Sartem  * Will open an RFE to add native attributes.
173*0e42dee6Sartem  */
174*0e42dee6Sartem static int
get_attr(fstyp_udfs_t * h)175*0e42dee6Sartem get_attr(fstyp_udfs_t *h)
176*0e42dee6Sartem {
177*0e42dee6Sartem 	struct udf *udfs = &h->udh->udfs;
178*0e42dee6Sartem 	struct vds *v;
179*0e42dee6Sartem 	struct pri_vol_desc *pvd;
180*0e42dee6Sartem 	uint32_t len;
181*0e42dee6Sartem 	uint64_t off;
182*0e42dee6Sartem 	uint8_t *buf;
183*0e42dee6Sartem 	int8_t str[64];
184*0e42dee6Sartem 	int ret = 0;
185*0e42dee6Sartem 
186*0e42dee6Sartem 	v = (udfs->flags & VALID_MVDS) ? &udfs->mvds : &udfs->rvds;
1877c478bd9Sstevel@tonic-gate 
188*0e42dee6Sartem 	/* allocate buffer */
189*0e42dee6Sartem 	len = udfs->lbsize;
190*0e42dee6Sartem 	if (v->pvd_len > len) {
191*0e42dee6Sartem 		len = v->pvd_len;
192*0e42dee6Sartem 	}
193*0e42dee6Sartem 	if ((buf = (uint8_t *)malloc(len)) == NULL) {
194*0e42dee6Sartem 		return (FSTYP_ERR_NOMEM);
1957c478bd9Sstevel@tonic-gate 	}
1967c478bd9Sstevel@tonic-gate 
197*0e42dee6Sartem 	(void) nvlist_add_boolean_value(h->attr, "gen_clean", B_TRUE);
1987c478bd9Sstevel@tonic-gate 
199*0e42dee6Sartem 	/* Primary Volume Descriptor */
200*0e42dee6Sartem 	if (v->pvd_len != 0) {
201*0e42dee6Sartem 		off = v->pvd_loc * udfs->lbsize;
202*0e42dee6Sartem 		if (ud_read_dev(h->udh, off, buf, v->pvd_len) != 0) {
203*0e42dee6Sartem 			ret = FSTYP_ERR_IO;
204*0e42dee6Sartem 			goto out;
205*0e42dee6Sartem 		}
206*0e42dee6Sartem 		/* LINTED */
207*0e42dee6Sartem 		pvd = (struct pri_vol_desc *)(uint32_t *)buf;
208*0e42dee6Sartem 
209*0e42dee6Sartem 		ud_convert2local(pvd->pvd_vol_id, str, 32);
210*0e42dee6Sartem 		str[32] = '\0';
211*0e42dee6Sartem 		(void) nvlist_add_string(h->attr, "gen_volume_label", str);
2127c478bd9Sstevel@tonic-gate 	}
2137c478bd9Sstevel@tonic-gate 
214*0e42dee6Sartem 	ret = 0;
215*0e42dee6Sartem 
216*0e42dee6Sartem out:
217*0e42dee6Sartem 	free(buf);
2187c478bd9Sstevel@tonic-gate 	return (ret);
2197c478bd9Sstevel@tonic-gate }
2207c478bd9Sstevel@tonic-gate 
221*0e42dee6Sartem /* ARGSUSED */
2227c478bd9Sstevel@tonic-gate int
print_vds(fstyp_udfs_t * h,struct vds * v,FILE * fout,FILE * ferr)223*0e42dee6Sartem print_vds(fstyp_udfs_t *h, struct vds *v, FILE *fout, FILE *ferr)
2247c478bd9Sstevel@tonic-gate {
225*0e42dee6Sartem 	struct udf *udfs = &h->udh->udfs;
2267c478bd9Sstevel@tonic-gate 	int32_t i;
2277c478bd9Sstevel@tonic-gate 	uint32_t len;
2287c478bd9Sstevel@tonic-gate 	uint64_t off;
2297c478bd9Sstevel@tonic-gate 	uint8_t *buf;
230*0e42dee6Sartem 	int	ret = 0;
2317c478bd9Sstevel@tonic-gate 
2327c478bd9Sstevel@tonic-gate 	/*
2337c478bd9Sstevel@tonic-gate 	 * All descriptors are 512 bytes
2347c478bd9Sstevel@tonic-gate 	 * except lvd, usd and lvid
2357c478bd9Sstevel@tonic-gate 	 * findout the largest and allocate space
2367c478bd9Sstevel@tonic-gate 	 */
237*0e42dee6Sartem 	len = udfs->lbsize;
2387c478bd9Sstevel@tonic-gate 	if (v->lvd_len > len) {
2397c478bd9Sstevel@tonic-gate 		len = v->lvd_len;
2407c478bd9Sstevel@tonic-gate 	}
2417c478bd9Sstevel@tonic-gate 	if (v->usd_len > len) {
2427c478bd9Sstevel@tonic-gate 		len = v->usd_len;
2437c478bd9Sstevel@tonic-gate 	}
244*0e42dee6Sartem 	if (udfs->lvid_len > len) {
245*0e42dee6Sartem 		len = udfs->lvid_len;
2467c478bd9Sstevel@tonic-gate 	}
2477c478bd9Sstevel@tonic-gate 
2487c478bd9Sstevel@tonic-gate 	if ((buf = (uint8_t *)malloc(len)) == NULL) {
249*0e42dee6Sartem 		return (FSTYP_ERR_NOMEM);
2507c478bd9Sstevel@tonic-gate 	}
2517c478bd9Sstevel@tonic-gate 
2527c478bd9Sstevel@tonic-gate 	/*
2537c478bd9Sstevel@tonic-gate 	 * Anchor Volume Descriptor
2547c478bd9Sstevel@tonic-gate 	 */
255*0e42dee6Sartem 	if (udfs->avdp_len != 0) {
256*0e42dee6Sartem 		off = udfs->avdp_loc * udfs->lbsize;
257*0e42dee6Sartem 		if (ud_read_dev(h->udh, off, buf, udfs->avdp_len) != 0) {
258*0e42dee6Sartem 			ret = FSTYP_ERR_IO;
259*0e42dee6Sartem 			goto out;
2607c478bd9Sstevel@tonic-gate 		}
2617c478bd9Sstevel@tonic-gate 
2627c478bd9Sstevel@tonic-gate 		/* LINTED */
263*0e42dee6Sartem 		print_avd(fout, (struct anch_vol_desc_ptr *)buf);
2647c478bd9Sstevel@tonic-gate 	}
2657c478bd9Sstevel@tonic-gate 
2667c478bd9Sstevel@tonic-gate 	/*
2677c478bd9Sstevel@tonic-gate 	 * Primary Volume Descriptor
2687c478bd9Sstevel@tonic-gate 	 */
2697c478bd9Sstevel@tonic-gate 	if (v->pvd_len != 0) {
270*0e42dee6Sartem 		off = v->pvd_loc * udfs->lbsize;
271*0e42dee6Sartem 		if (ud_read_dev(h->udh, off, buf, v->pvd_len) != 0) {
272*0e42dee6Sartem 			ret = FSTYP_ERR_IO;
273*0e42dee6Sartem 			goto out;
2747c478bd9Sstevel@tonic-gate 		}
2757c478bd9Sstevel@tonic-gate 
2767c478bd9Sstevel@tonic-gate 		/* LINTED */
277*0e42dee6Sartem 		print_pvd(fout, (struct pri_vol_desc *)buf);
2787c478bd9Sstevel@tonic-gate 	}
2797c478bd9Sstevel@tonic-gate 
2807c478bd9Sstevel@tonic-gate 	/*
2817c478bd9Sstevel@tonic-gate 	 * Implementation Use descriptor
2827c478bd9Sstevel@tonic-gate 	 */
2837c478bd9Sstevel@tonic-gate 	if (v->iud_len != 0) {
284*0e42dee6Sartem 		off = v->iud_loc * udfs->lbsize;
285*0e42dee6Sartem 		if (ud_read_dev(h->udh, off, buf, v->iud_len) != 0) {
286*0e42dee6Sartem 			ret = FSTYP_ERR_IO;
287*0e42dee6Sartem 			goto out;
2887c478bd9Sstevel@tonic-gate 		}
2897c478bd9Sstevel@tonic-gate 
2907c478bd9Sstevel@tonic-gate 		/* LINTED */
291*0e42dee6Sartem 		print_iuvd(fout, (struct iuvd_desc *)buf);
2927c478bd9Sstevel@tonic-gate 	}
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate 	/*
2957c478bd9Sstevel@tonic-gate 	 * Paritions
2967c478bd9Sstevel@tonic-gate 	 */
297*0e42dee6Sartem 	for (i = 0; i < h->udh->n_parts; i++) {
2987c478bd9Sstevel@tonic-gate 		if (v->part_len[i] != 0) {
299*0e42dee6Sartem 			off = v->part_loc[i] * udfs->lbsize;
300*0e42dee6Sartem 			if (ud_read_dev(h->udh, off, buf,
301*0e42dee6Sartem 			    v->part_len[i]) != 0) {
302*0e42dee6Sartem 				ret = FSTYP_ERR_IO;
303*0e42dee6Sartem 				goto out;
3047c478bd9Sstevel@tonic-gate 			}
3057c478bd9Sstevel@tonic-gate 
3067c478bd9Sstevel@tonic-gate 			/* LINTED */
307*0e42dee6Sartem 			print_part(fout, (struct part_desc *)buf);
3087c478bd9Sstevel@tonic-gate 		}
3097c478bd9Sstevel@tonic-gate 	}
3107c478bd9Sstevel@tonic-gate 
3117c478bd9Sstevel@tonic-gate 	/*
3127c478bd9Sstevel@tonic-gate 	 * Logical Volume Descriptor
3137c478bd9Sstevel@tonic-gate 	 */
3147c478bd9Sstevel@tonic-gate 	if (v->lvd_len != 0) {
315*0e42dee6Sartem 		off = v->lvd_loc * udfs->lbsize;
316*0e42dee6Sartem 		if (ud_read_dev(h->udh, off, buf, v->lvd_len) != 0) {
317*0e42dee6Sartem 			ret = FSTYP_ERR_IO;
318*0e42dee6Sartem 			goto out;
3197c478bd9Sstevel@tonic-gate 		}
3207c478bd9Sstevel@tonic-gate 
3217c478bd9Sstevel@tonic-gate 		/* LINTED */
322*0e42dee6Sartem 		print_lvd(fout, (struct log_vol_desc *)buf);
3237c478bd9Sstevel@tonic-gate 	}
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate 	/*
3267c478bd9Sstevel@tonic-gate 	 * Unallocated Space Descriptor
3277c478bd9Sstevel@tonic-gate 	 */
3287c478bd9Sstevel@tonic-gate 	if (v->usd_len != 0) {
329*0e42dee6Sartem 		off = v->usd_loc * udfs->lbsize;
330*0e42dee6Sartem 		if (ud_read_dev(h->udh, off, buf, v->usd_len) != 0) {
331*0e42dee6Sartem 			ret = FSTYP_ERR_IO;
332*0e42dee6Sartem 			goto out;
3337c478bd9Sstevel@tonic-gate 		}
3347c478bd9Sstevel@tonic-gate 
3357c478bd9Sstevel@tonic-gate 		/* LINTED */
336*0e42dee6Sartem 		print_usd(fout, (struct unall_spc_desc *)buf);
3377c478bd9Sstevel@tonic-gate 	}
3387c478bd9Sstevel@tonic-gate 
3397c478bd9Sstevel@tonic-gate 	/*
3407c478bd9Sstevel@tonic-gate 	 * Logical Volume Integrity Descriptor
3417c478bd9Sstevel@tonic-gate 	 */
342*0e42dee6Sartem 	if (udfs->lvid_len != 0) {
343*0e42dee6Sartem 		off = udfs->lvid_loc * udfs->lbsize;
344*0e42dee6Sartem 		if (ud_read_dev(h->udh, off, buf, udfs->lvid_len) != 0) {
345*0e42dee6Sartem 			ret = FSTYP_ERR_IO;
346*0e42dee6Sartem 			goto out;
3477c478bd9Sstevel@tonic-gate 		}
3487c478bd9Sstevel@tonic-gate 
3497c478bd9Sstevel@tonic-gate 		/* LINTED */
350*0e42dee6Sartem 		print_lvid(fout, (struct log_vol_int_desc *)buf);
3517c478bd9Sstevel@tonic-gate 	}
3527c478bd9Sstevel@tonic-gate 
3537c478bd9Sstevel@tonic-gate 	/*
3547c478bd9Sstevel@tonic-gate 	 * File Set Descriptor
3557c478bd9Sstevel@tonic-gate 	 */
356*0e42dee6Sartem 	if (udfs->fsd_len != 0) {
357*0e42dee6Sartem 		off = udfs->fsd_loc * udfs->lbsize;
358*0e42dee6Sartem 		if (ud_read_dev(h->udh, off, buf, udfs->fsd_len) != 0) {
359*0e42dee6Sartem 			ret = FSTYP_ERR_IO;
360*0e42dee6Sartem 			goto out;
3617c478bd9Sstevel@tonic-gate 		}
3627c478bd9Sstevel@tonic-gate 
3637c478bd9Sstevel@tonic-gate 		/* LINTED */
364*0e42dee6Sartem 		print_fsd(fout, h->udh, (struct file_set_desc *)buf);
3657c478bd9Sstevel@tonic-gate 	}
366*0e42dee6Sartem 	ret = 0;
3677c478bd9Sstevel@tonic-gate 
368*0e42dee6Sartem out:
369*0e42dee6Sartem 	free(buf);
370*0e42dee6Sartem 	return (ret);
3717c478bd9Sstevel@tonic-gate }
372