dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / fs.d / udfs / fstyp / fstyp.c
blob64ccb4de902c590ee04b90223f564e89a4ba6641
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
29 * libfstyp module for udfs
31 #include <fcntl.h>
32 #include <stdio.h>
33 #include <errno.h>
34 #include <unistd.h>
35 #include <locale.h>
36 #include <stdlib.h>
37 #include <strings.h>
38 #include <sys/param.h>
39 #include <sys/stat.h>
40 #include <sys/time.h>
41 #include <sys/types.h>
42 #include <sys/file.h>
43 #include <libnvpair.h>
44 #include <libfstyp_module.h>
45 #include <sys/fs/udf_volume.h>
46 #include "ud_lib.h"
49 typedef struct fstyp_udfs {
50 int fd;
51 ud_handle_t udh;
52 nvlist_t *attr;
53 } fstyp_udfs_t;
55 static int is_udfs(fstyp_udfs_t *h);
56 static int print_vds(fstyp_udfs_t *h, struct vds *,
57 FILE *fout, FILE *ferr);
58 static int get_attr(fstyp_udfs_t *h);
60 int fstyp_mod_init(int fd, off_t offset, fstyp_mod_handle_t *handle);
61 void fstyp_mod_fini(fstyp_mod_handle_t handle);
62 int fstyp_mod_ident(fstyp_mod_handle_t handle);
63 int fstyp_mod_get_attr(fstyp_mod_handle_t handle, nvlist_t **attrp);
64 int fstyp_mod_dump(fstyp_mod_handle_t handle, FILE *fout, FILE *ferr);
67 int
68 fstyp_mod_init(int fd, off_t offset, fstyp_mod_handle_t *handle)
70 fstyp_udfs_t *h = (fstyp_udfs_t *)handle;
72 if (offset != 0) {
73 return (FSTYP_ERR_OFFSET);
76 if ((h = calloc(1, sizeof (fstyp_udfs_t))) == NULL) {
77 return (FSTYP_ERR_NOMEM);
79 h->fd = fd;
81 if (ud_init(h->fd, &h->udh) != 0) {
82 free(h);
83 return (FSTYP_ERR_NOMEM);
86 *handle = (fstyp_mod_handle_t)h;
87 return (0);
90 void
91 fstyp_mod_fini(fstyp_mod_handle_t handle)
93 fstyp_udfs_t *h = (fstyp_udfs_t *)handle;
95 if (h->attr == NULL) {
96 nvlist_free(h->attr);
97 h->attr = NULL;
99 ud_fini(h->udh);
100 free(h);
104 fstyp_mod_ident(fstyp_mod_handle_t handle)
106 fstyp_udfs_t *h = (fstyp_udfs_t *)handle;
108 return (is_udfs(h));
112 fstyp_mod_get_attr(fstyp_mod_handle_t handle, nvlist_t **attrp)
114 fstyp_udfs_t *h = (fstyp_udfs_t *)handle;
115 int error;
117 if (h->attr == NULL) {
118 if (nvlist_alloc(&h->attr, NV_UNIQUE_NAME_TYPE, 0)) {
119 return (FSTYP_ERR_NOMEM);
121 if ((error = get_attr(h)) != 0) {
122 nvlist_free(h->attr);
123 h->attr = NULL;
124 return (error);
128 *attrp = h->attr;
129 return (0);
133 fstyp_mod_dump(fstyp_mod_handle_t handle, FILE *fout, FILE *ferr)
135 fstyp_udfs_t *h = (fstyp_udfs_t *)handle;
136 struct udf *udfs = &h->udh->udfs;
137 int ret;
139 (void) fprintf(fout,
140 "Standard Identifier %5s\n", udfs->ecma_id);
142 if (udfs->flags & VALID_MVDS) {
143 ret = print_vds(h, &udfs->mvds, fout, ferr);
144 } else {
145 ret = print_vds(h, &udfs->rvds, fout, ferr);
148 return (ret);
153 * Assumption is that we will confirm to level-1
156 is_udfs(fstyp_udfs_t *h)
158 struct udf *udfs = &h->udh->udfs;
159 int32_t ret;
161 if ((ret = ud_fill_udfs_info(h->udh)) != 0) {
162 return (ret);
165 if ((udfs->flags & VALID_UDFS) == 0) {
166 return (FSTYP_ERR_NO_MATCH);
169 return (0);
173 * For now, only return generic attributes.
174 * Will open an RFE to add native attributes.
176 static int
177 get_attr(fstyp_udfs_t *h)
179 struct udf *udfs = &h->udh->udfs;
180 struct vds *v;
181 struct pri_vol_desc *pvd;
182 uint32_t len;
183 uint64_t off;
184 uint8_t *buf;
185 int8_t str[64];
186 int ret = 0;
188 v = (udfs->flags & VALID_MVDS) ? &udfs->mvds : &udfs->rvds;
190 /* allocate buffer */
191 len = udfs->lbsize;
192 if (v->pvd_len > len) {
193 len = v->pvd_len;
195 if ((buf = (uint8_t *)malloc(len)) == NULL) {
196 return (FSTYP_ERR_NOMEM);
199 (void) nvlist_add_boolean_value(h->attr, "gen_clean", B_TRUE);
201 /* Primary Volume Descriptor */
202 if (v->pvd_len != 0) {
203 off = v->pvd_loc * udfs->lbsize;
204 if (ud_read_dev(h->udh, off, buf, v->pvd_len) != 0) {
205 ret = FSTYP_ERR_IO;
206 goto out;
208 /* LINTED */
209 pvd = (struct pri_vol_desc *)(uint32_t *)buf;
211 ud_convert2local(pvd->pvd_vol_id, str, 32);
212 str[32] = '\0';
213 (void) nvlist_add_string(h->attr, "gen_volume_label", str);
216 ret = 0;
218 out:
219 free(buf);
220 return (ret);
223 /* ARGSUSED */
225 print_vds(fstyp_udfs_t *h, struct vds *v, FILE *fout, FILE *ferr)
227 struct udf *udfs = &h->udh->udfs;
228 int32_t i;
229 uint32_t len;
230 uint64_t off;
231 uint8_t *buf;
232 int ret = 0;
235 * All descriptors are 512 bytes
236 * except lvd, usd and lvid
237 * findout the largest and allocate space
239 len = udfs->lbsize;
240 if (v->lvd_len > len) {
241 len = v->lvd_len;
243 if (v->usd_len > len) {
244 len = v->usd_len;
246 if (udfs->lvid_len > len) {
247 len = udfs->lvid_len;
250 if ((buf = (uint8_t *)malloc(len)) == NULL) {
251 return (FSTYP_ERR_NOMEM);
255 * Anchor Volume Descriptor
257 if (udfs->avdp_len != 0) {
258 off = udfs->avdp_loc * udfs->lbsize;
259 if (ud_read_dev(h->udh, off, buf, udfs->avdp_len) != 0) {
260 ret = FSTYP_ERR_IO;
261 goto out;
264 /* LINTED */
265 print_avd(fout, (struct anch_vol_desc_ptr *)buf);
269 * Primary Volume Descriptor
271 if (v->pvd_len != 0) {
272 off = v->pvd_loc * udfs->lbsize;
273 if (ud_read_dev(h->udh, off, buf, v->pvd_len) != 0) {
274 ret = FSTYP_ERR_IO;
275 goto out;
278 /* LINTED */
279 print_pvd(fout, (struct pri_vol_desc *)buf);
283 * Implementation Use descriptor
285 if (v->iud_len != 0) {
286 off = v->iud_loc * udfs->lbsize;
287 if (ud_read_dev(h->udh, off, buf, v->iud_len) != 0) {
288 ret = FSTYP_ERR_IO;
289 goto out;
292 /* LINTED */
293 print_iuvd(fout, (struct iuvd_desc *)buf);
297 * Paritions
299 for (i = 0; i < h->udh->n_parts; i++) {
300 if (v->part_len[i] != 0) {
301 off = v->part_loc[i] * udfs->lbsize;
302 if (ud_read_dev(h->udh, off, buf,
303 v->part_len[i]) != 0) {
304 ret = FSTYP_ERR_IO;
305 goto out;
308 /* LINTED */
309 print_part(fout, (struct part_desc *)buf);
314 * Logical Volume Descriptor
316 if (v->lvd_len != 0) {
317 off = v->lvd_loc * udfs->lbsize;
318 if (ud_read_dev(h->udh, off, buf, v->lvd_len) != 0) {
319 ret = FSTYP_ERR_IO;
320 goto out;
323 /* LINTED */
324 print_lvd(fout, (struct log_vol_desc *)buf);
328 * Unallocated Space Descriptor
330 if (v->usd_len != 0) {
331 off = v->usd_loc * udfs->lbsize;
332 if (ud_read_dev(h->udh, off, buf, v->usd_len) != 0) {
333 ret = FSTYP_ERR_IO;
334 goto out;
337 /* LINTED */
338 print_usd(fout, (struct unall_spc_desc *)buf);
342 * Logical Volume Integrity Descriptor
344 if (udfs->lvid_len != 0) {
345 off = udfs->lvid_loc * udfs->lbsize;
346 if (ud_read_dev(h->udh, off, buf, udfs->lvid_len) != 0) {
347 ret = FSTYP_ERR_IO;
348 goto out;
351 /* LINTED */
352 print_lvid(fout, (struct log_vol_int_desc *)buf);
356 * File Set Descriptor
358 if (udfs->fsd_len != 0) {
359 off = udfs->fsd_loc * udfs->lbsize;
360 if (ud_read_dev(h->udh, off, buf, udfs->fsd_len) != 0) {
361 ret = FSTYP_ERR_IO;
362 goto out;
365 /* LINTED */
366 print_fsd(fout, h->udh, (struct file_set_desc *)buf);
368 ret = 0;
370 out:
371 free(buf);
372 return (ret);