xref: /illumos-gate/usr/src/cmd/fs.d/hsfs/fstyp/fstyp.c (revision 54719d5edb7521bb3a321ad8bd9ebc251d61a1a0)
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 2005 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 <sys/param.h>
32 #include <sys/stat.h>
33 #include <sys/time.h>
34 #include <sys/types.h>
35 #include <sys/file.h>
36 #include <sys/cdio.h>
37 #include <sys/dkio.h>
38 #include "hsfs_spec.h"
39 #include "iso_spec.h"
40 #include "iso_impl.h"
41 
42 #define	GETCDSECTOR(buf, secno, nosec) (getdisk(buf, \
43 	((secno)+cdroff)*ISO_SECTOR_SIZE, \
44 	(nosec)*ISO_SECTOR_SIZE))
45 char hs_buf[ISO_SECTOR_SIZE];
46 int  hs_pvd_sec_no;
47 char iso_buf[ISO_SECTOR_SIZE];
48 int  iso_pvd_sec_no;
49 char unix_buf[ISO_SECTOR_SIZE];
50 int  unix_pvd_sec_no;
51 
52 int vflag;
53 int  cdfd;
54 
55 int cdroff = 0;
56 
57 static int rdev_is_a_cd(int rdevfd);
58 static void getdisk(char *buf, int daddr, int size);
59 static void prntstring(char *heading, char *s, int maxlen);
60 static void prntlabel(int cd_type);
61 static void dumpfs(char *special);
62 static void usage(void);
63 
64 int
65 main(int argc, char **argv)
66 {
67 	int c;
68 	char *special;
69 	int errflag = 0;
70 
71 	while ((c = getopt(argc, argv, "v")) != EOF) {
72 		switch (c) {
73 			case 'v':
74 				vflag++;
75 				break;
76 			default:
77 				errflag++;
78 				break;
79 		}
80 	}
81 
82 	if (errflag || (argc <= optind)) {
83 		usage();
84 		exit(1);
85 	}
86 
87 	special = argv[optind];
88 
89 	dumpfs(special);
90 
91 	return (0);
92 }
93 
94 static void
95 usage(void)
96 {
97 	fprintf(stderr, "Usage: fstyp -v special\n");
98 }
99 
100 /*
101  * findhsvol: check if the disk is in high sierra format
102  *            return(1) if found, (0) otherwise
103  *	      if found, volp will point to the descriptor
104  *
105  */
106 int
107 findhsvol(volp)
108 char *volp;
109 {
110 int secno;
111 int i;
112 
113 	secno = HS_VOLDESC_SEC;
114 	GETCDSECTOR(volp, secno++, 1);
115 	while (HSV_DESC_TYPE(volp) != VD_EOV) {
116 		for (i = 0; i < HSV_ID_STRLEN; i++)
117 			if (HSV_STD_ID(volp)[i] != HSV_ID_STRING[i])
118 				goto cantfind;
119 		if (HSV_STD_VER(volp) != HSV_ID_VER)
120 			goto cantfind;
121 		switch (HSV_DESC_TYPE(volp)) {
122 		case VD_SFS:
123 			hs_pvd_sec_no = secno-1;
124 			return (1);
125 		case VD_EOV:
126 			goto cantfind;
127 		}
128 		GETCDSECTOR(volp, secno++, 1);
129 	}
130 cantfind:
131 	return (0);
132 }
133 
134 /*
135  * findisovol: check if the disk is in ISO 9660 format
136  *            return(1) if found, (0) otherwise
137  *	      if found, volp will point to the descriptor
138  *
139  */
140 int
141 findisovol(volp)
142 char *volp;
143 {
144 int secno;
145 int i;
146 
147 	secno = ISO_VOLDESC_SEC;
148 	GETCDSECTOR(volp, secno++, 1);
149 	while (ISO_DESC_TYPE(volp) != ISO_VD_EOV) {
150 		for (i = 0; i < ISO_ID_STRLEN; i++)
151 			if (ISO_STD_ID(volp)[i] != ISO_ID_STRING[i])
152 				goto cantfind;
153 		if (ISO_STD_VER(volp) != ISO_ID_VER)
154 			goto cantfind;
155 		switch (ISO_DESC_TYPE(volp)) {
156 		case ISO_VD_PVD:
157 			iso_pvd_sec_no = secno-1;
158 			return (1);
159 		case ISO_VD_EOV:
160 			goto cantfind;
161 		}
162 		GETCDSECTOR(volp, secno++, 1);
163 	}
164 cantfind:
165 	return (0);
166 }
167 
168 /*
169  * findunixvol: check if the disk is in UNIX extension format
170  *            return(1) if found, (0) otherwise
171  *	      if found, volp will point to the descriptor
172  *
173  */
174 int
175 findunixvol(char *volp)
176 {
177 int secno;
178 int i;
179 
180 	secno = ISO_VOLDESC_SEC;
181 	GETCDSECTOR(volp, secno++, 1);
182 	while (ISO_DESC_TYPE(volp) != ISO_VD_EOV) {
183 		for (i = 0; i < ISO_ID_STRLEN; i++)
184 			if (ISO_STD_ID(volp)[i] != ISO_ID_STRING[i])
185 				goto cantfind;
186 		if (ISO_STD_VER(volp) != ISO_ID_VER)
187 			goto cantfind;
188 		switch (ISO_DESC_TYPE(volp)) {
189 		case ISO_VD_UNIX:
190 			unix_pvd_sec_no = secno-1;
191 			return (1);
192 		case ISO_VD_EOV:
193 			goto cantfind;
194 		}
195 		GETCDSECTOR(volp, secno++, 1);
196 	}
197 cantfind:
198 	return (0);
199 }
200 
201 int
202 ckvoldesc(void)
203 {
204 	int cd_type;
205 
206 	if (findhsvol(hs_buf))
207 		cd_type = 0;
208 	else if (findisovol(iso_buf)) {
209 		if (findunixvol(unix_buf))
210 			cd_type = 2;
211 		else cd_type = 1;
212 	} else {
213 		cd_type = -1;
214 	}
215 
216 	return (cd_type);
217 
218 }
219 
220 static void
221 dumpfs(char *special)
222 {
223 	int err;
224 	int cd_type;
225 
226 	if ((cdfd = open(special, O_RDONLY)) < 0) {
227 		fprintf(stderr, "hsfs fstyp: cannot open <%s>\n", special);
228 		exit(1);
229 	}
230 
231 #ifdef CDROMREADOFFSET
232 	if (rdev_is_a_cd(cdfd)) {
233 		err = ioctl(cdfd, CDROMREADOFFSET, &cdroff);
234 		if (err == -1)
235 			/*
236 			 *  This device doesn't support this ioctl.
237 			 *  That's OK.
238 			 */
239 			cdroff = 0;
240 	}
241 #endif
242 	/* check volume descriptor */
243 	cd_type = ckvoldesc();
244 
245 	if (cd_type < 0)
246 		exit(1);
247 	else
248 		fprintf(stdout, "hsfs\n");
249 
250 	if (vflag)
251 		prntlabel(cd_type);
252 
253 	exit(0);
254 }
255 
256 static void
257 prntlabel(int cd_type)
258 {
259 	char *vdp;
260 	char *sysid;
261 	char *volid;
262 	char *volsetid;
263 	char *pubid;
264 	char *prepid;
265 	char *applid;
266 	char *copyfile;
267 	char *absfile;
268 	char *bibfile;
269 	int volsetsize;
270 	int volsetseq;
271 	int blksize;
272 	int volsize;
273 	int i;
274 
275 	switch (cd_type) {
276 	case 0:
277 		fprintf(stdout, "CD-ROM is in High Sierra format\n");
278 		sysid = (char *)HSV_sys_id(hs_buf);
279 		volid = (char *)HSV_vol_id(hs_buf);
280 		volsetid = (char *)HSV_vol_set_id(hs_buf);
281 		pubid = (char *)HSV_pub_id(hs_buf);
282 		prepid = (char *)HSV_prep_id(hs_buf);
283 		applid = (char *)HSV_appl_id(hs_buf);
284 		copyfile = (char *)HSV_copyr_id(hs_buf);
285 		absfile = (char *)HSV_abstr_id(hs_buf);
286 		bibfile = NULL;
287 		volsetsize = HSV_SET_SIZE(hs_buf);
288 		volsetseq = HSV_SET_SEQ(hs_buf);
289 		blksize = HSV_BLK_SIZE(hs_buf);
290 		volsize = HSV_VOL_SIZE(hs_buf);
291 		break;
292 	case 1:
293 		fprintf(stdout, "CD-ROM is in ISO 9660 format\n");
294 		sysid = (char *)ISO_sys_id(iso_buf);
295 		volid = (char *)ISO_vol_id(iso_buf);
296 		volsetid = (char *)ISO_vol_set_id(iso_buf);
297 		pubid = (char *)ISO_pub_id(iso_buf);
298 		prepid = (char *)ISO_prep_id(iso_buf);
299 		applid = (char *)ISO_appl_id(iso_buf);
300 		copyfile = (char *)ISO_copyr_id(iso_buf);
301 		absfile = (char *)ISO_abstr_id(iso_buf);
302 		bibfile = (char *)ISO_bibli_id(iso_buf);
303 		volsetsize = ISO_SET_SIZE(iso_buf);
304 		volsetseq = ISO_SET_SEQ(iso_buf);
305 		blksize = ISO_BLK_SIZE(iso_buf);
306 		volsize = ISO_VOL_SIZE(iso_buf);
307 		break;
308 	case 2:
309 		fprintf(stdout, "CD-ROM is in ISO 9660 format with"
310 		    " UNIX extension\n");
311 		sysid = (char *)ISO_sys_id(unix_buf);
312 		volid = (char *)ISO_vol_id(unix_buf);
313 		volsetid = (char *)ISO_vol_set_id(unix_buf);
314 		pubid = (char *)ISO_pub_id(unix_buf);
315 		prepid = (char *)ISO_prep_id(unix_buf);
316 		applid = (char *)ISO_appl_id(unix_buf);
317 		copyfile = (char *)ISO_copyr_id(unix_buf);
318 		absfile = (char *)ISO_abstr_id(unix_buf);
319 		bibfile = (char *)ISO_bibli_id(unix_buf);
320 		volsetsize = ISO_SET_SIZE(unix_buf);
321 		volsetseq = ISO_SET_SEQ(unix_buf);
322 		blksize = ISO_BLK_SIZE(unix_buf);
323 		volsize = ISO_VOL_SIZE(unix_buf);
324 		break;
325 	default:
326 		return;
327 	}
328 	/* system id */
329 	prntstring("System id", sysid, 32);
330 	/* read volume id */
331 	prntstring("Volume id", volid, 32);
332 	/* read volume set id */
333 	prntstring("Volume set id", volsetid, 128);
334 	/* publisher id */
335 	prntstring("Publisher id", pubid, 128);
336 	/* data preparer id */
337 	prntstring("Data preparer id", prepid, 128);
338 	/* application id */
339 	prntstring("Application id", applid, 128);
340 	/* copyright file identifier */
341 	prntstring("Copyright File id", copyfile, 37);
342 	/* Abstract file identifier */
343 	prntstring("Abstract File id", absfile, 37);
344 	/* Bibliographic file identifier */
345 	prntstring("Bibliographic File id", bibfile, 37);
346 	/* print volume set size */
347 	fprintf(stdout, "Volume set size is %d\n", volsetsize);
348 	/* print volume set sequnce number */
349 	fprintf(stdout, "Volume set sequence number is %d\n", volsetseq);
350 	/* print logical block size */
351 	fprintf(stdout, "Logical block size is %d\n", blksize);
352 	/* print volume size */
353 	fprintf(stdout, "Volume size is %d\n", volsize);
354 }
355 
356 static void
357 prntstring(char *heading, char *s, int maxlen)
358 {
359 	int i;
360 	if (maxlen < 1)
361 		return;
362 	if (heading == NULL || s == NULL)
363 		return;
364 	/* print heading */
365 	fprintf(stdout, "%s: ", heading);
366 
367 	/* strip off trailing zeros */
368 	for (i = maxlen-1; i >= 0; i--)
369 		if (s[i] != ' ') break;
370 
371 	maxlen = i+1;
372 	for (i = 0; i < maxlen; i++)
373 		fprintf(stdout, "%c", s[i]);
374 	fprintf(stdout, "\n");
375 }
376 
377 /* readdisk - read from cdrom image file */
378 static void
379 getdisk(char *buf, int daddr, int size)
380 {
381 	if (lseek(cdfd, daddr, L_SET) == -1) {
382 		perror("getdisk/lseek");
383 		exit(1);
384 	}
385 	if (read(cdfd, buf, size) != size) {
386 		perror("getdisk/read");
387 		exit(1);
388 	}
389 }
390 
391 /*
392  * rdev_is_a_cd  - return TRUE if the raw device identified by
393  *		      a file descriptor is a CDROM device.
394  *
395  *		      return FALSE if the device can't be accessed
396  *		      or is not a CDROM.
397  */
398 static int
399 rdev_is_a_cd(int rdevfd)
400 {
401 	struct dk_cinfo dkc;
402 
403 	if (ioctl(rdevfd, DKIOCINFO, &dkc) < 0)
404 		return (0);
405 	if (dkc.dki_ctype == DKC_CDROM)
406 		return (1);
407 	else
408 		return (0);
409 }
410