xref: /illumos-gate/usr/src/cmd/fs.d/udfs/fstyp/fstyp.c (revision 7c478bd9)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <fcntl.h>
30 #include <stdio.h>
31 #include <errno.h>
32 #include <unistd.h>
33 #include <locale.h>
34 #include <stdlib.h>
35 #include <strings.h>
36 #include <sys/param.h>
37 #include <sys/stat.h>
38 #include <sys/time.h>
39 #include <sys/types.h>
40 #include <sys/file.h>
41 #include <sys/fs/udf_volume.h>
42 #include "ud_lib.h"
43 
44 
45 extern int optind;
46 
47 static int verbose;
48 
49 static int check_if_udfs(int32_t);
50 static int print_vds(struct vds *, int32_t);
51 
52 int
53 main(int argc, char **argv)
54 {
55 	int errflag = 0, c, rval, fd;
56 
57 	(void) setlocale(LC_ALL, "");
58 #if !defined(TEXT_DOMAIN)
59 #define	TEXT_DOMAIN "SYS_TEST"
60 #endif
61 	(void) textdomain(TEXT_DOMAIN);
62 
63 	while ((c = getopt(argc, argv, "v")) != EOF) {
64 		switch (c) {
65 			case 'v':
66 				verbose++;
67 				break;
68 			default:
69 				errflag++;
70 				break;
71 		}
72 	}
73 
74 	if (errflag || (argc <= optind)) {
75 		(void) fprintf(stderr,
76 			gettext("Usage: fstyp -v special\n"));
77 		exit(1);
78 	}
79 
80 	if ((fd = ud_open_dev(argv[optind], O_RDONLY)) < 0) {
81 		(void) fprintf(stderr,
82 			gettext("udfs fstyp: cannot open <%s> errorno <%d>\n"),
83 					argv[optind], errno);
84 		exit(1);
85 	}
86 
87 	/*
88 	 * check the volume
89 	 */
90 	rval = check_if_udfs(fd);
91 
92 	ud_close_dev(fd);
93 
94 	return (rval);
95 }
96 
97 
98 /*
99  * Assumption is that we will confirm to level-1
100  */
101 int
102 check_if_udfs(int32_t fd)
103 {
104 	int32_t ret;
105 
106 	if ((ret = ud_fill_udfs_info(fd)) != 0) {
107 		return (ret);
108 	}
109 
110 	if ((udfs.flags & VALID_UDFS) == 0) {
111 		return (1);
112 	}
113 
114 	(void) fprintf(stdout, "udfs\n");
115 
116 	if (verbose == 0) {
117 		return (0);
118 	}
119 
120 	(void) fprintf(stdout,
121 		"Standard Identifier %5s\n", udfs.ecma_id);
122 
123 	if (udfs.flags & VALID_MVDS) {
124 		ret = print_vds(&udfs.mvds, fd);
125 	} else {
126 		ret = print_vds(&udfs.rvds, fd);
127 	}
128 
129 	return (ret);
130 }
131 
132 int
133 print_vds(struct vds *v, int32_t fd)
134 {
135 	int32_t i;
136 	uint32_t len;
137 	uint64_t off;
138 	uint8_t *buf;
139 
140 	/*
141 	 * All descriptors are 512 bytes
142 	 * except lvd, usd and lvid
143 	 * findout the largest and allocate space
144 	 */
145 	len = udfs.lbsize;
146 	if (v->lvd_len > len) {
147 		len = v->lvd_len;
148 	}
149 	if (v->usd_len > len) {
150 		len = v->usd_len;
151 	}
152 	if (udfs.lvid_len > len) {
153 		len = udfs.lvid_len;
154 	}
155 
156 	if ((buf = (uint8_t *)malloc(len)) == NULL) {
157 		return (1);
158 	}
159 
160 	/*
161 	 * Anchor Volume Descriptor
162 	 */
163 	if (udfs.avdp_len != 0) {
164 		off = udfs.avdp_loc * udfs.lbsize;
165 		if (ud_read_dev(fd, off, buf, udfs.avdp_len) != 0) {
166 			return (2);
167 		}
168 
169 		/* LINTED */
170 		print_avd((struct anch_vol_desc_ptr *)buf);
171 	}
172 
173 	/*
174 	 * Primary Volume Descriptor
175 	 */
176 	if (v->pvd_len != 0) {
177 		off = v->pvd_loc * udfs.lbsize;
178 		if (ud_read_dev(fd, off, buf, v->pvd_len) != 0) {
179 			return (3);
180 		}
181 
182 		/* LINTED */
183 		print_pvd((struct pri_vol_desc *)buf);
184 	}
185 
186 	/*
187 	 * Implementation Use descriptor
188 	 */
189 	if (v->iud_len != 0) {
190 		off = v->iud_loc * udfs.lbsize;
191 		if (ud_read_dev(fd, off, buf, v->iud_len) != 0) {
192 			return (3);
193 		}
194 
195 		/* LINTED */
196 		print_iuvd((struct iuvd_desc *)buf);
197 	}
198 
199 	/*
200 	 * Paritions
201 	 */
202 	for (i = 0; i < n_parts; i++) {
203 		if (v->part_len[i] != 0) {
204 			off = v->part_loc[i] * udfs.lbsize;
205 			if (ud_read_dev(fd, off, buf, v->part_len[i]) != 0) {
206 				return (3);
207 			}
208 
209 			/* LINTED */
210 			print_part((struct part_desc *)buf);
211 		}
212 	}
213 
214 	/*
215 	 * Logical Volume Descriptor
216 	 */
217 	if (v->lvd_len != 0) {
218 		off = v->lvd_loc * udfs.lbsize;
219 		if (ud_read_dev(fd, off, buf, v->lvd_len) != 0) {
220 			return (3);
221 		}
222 
223 		/* LINTED */
224 		print_lvd((struct log_vol_desc *)buf);
225 	}
226 
227 	/*
228 	 * Unallocated Space Descriptor
229 	 */
230 	if (v->usd_len != 0) {
231 		off = v->usd_loc * udfs.lbsize;
232 		if (ud_read_dev(fd, off, buf, v->usd_len) != 0) {
233 			return (3);
234 		}
235 
236 		/* LINTED */
237 		print_usd((struct unall_spc_desc *)buf);
238 	}
239 
240 	/*
241 	 * Logical Volume Integrity Descriptor
242 	 */
243 	if (udfs.lvid_len != 0) {
244 		off = udfs.lvid_loc * udfs.lbsize;
245 		if (ud_read_dev(fd, off, buf, udfs.lvid_len) != 0) {
246 			return (3);
247 		}
248 
249 		/* LINTED */
250 		print_lvid((struct log_vol_int_desc *)buf);
251 	}
252 
253 	/*
254 	 * File Set Descriptor
255 	 */
256 	if (udfs.fsd_len != 0) {
257 		off = udfs.fsd_loc * udfs.lbsize;
258 		if (ud_read_dev(fd, off, buf, udfs.fsd_len) != 0) {
259 			return (3);
260 		}
261 
262 		/* LINTED */
263 		print_fsd((struct file_set_desc *)buf);
264 	}
265 
266 	return (0);
267 }
268