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