xref: /illumos-gate/usr/src/cmd/fs.d/udfs/mkfs/mkfs.c (revision fe0e7ec4)
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*fe0e7ec4Smaheshvs  * Common Development and Distribution License (the "License").
6*fe0e7ec4Smaheshvs  * 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*fe0e7ec4Smaheshvs  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
277c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate /*
307c478bd9Sstevel@tonic-gate  * Portions of this source code were derived from Berkeley 4.3 BSD
317c478bd9Sstevel@tonic-gate  * under license from the Regents of the University of California.
327c478bd9Sstevel@tonic-gate  */
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate /*
377c478bd9Sstevel@tonic-gate  * make file system for udfs (UDF - ISO13346)
387c478bd9Sstevel@tonic-gate  *
397c478bd9Sstevel@tonic-gate  * usage:
407c478bd9Sstevel@tonic-gate  *
417c478bd9Sstevel@tonic-gate  *    mkfs [-F FSType] [-V] [-m] [options]
427c478bd9Sstevel@tonic-gate  *	[-o specific_options]  special size
437c478bd9Sstevel@tonic-gate  *
447c478bd9Sstevel@tonic-gate  *  where specific_options are:
457c478bd9Sstevel@tonic-gate  *	N - no create
467c478bd9Sstevel@tonic-gate  *	label - volume label
477c478bd9Sstevel@tonic-gate  *	psize - physical block size
487c478bd9Sstevel@tonic-gate  */
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate #include	<stdio.h>
517c478bd9Sstevel@tonic-gate #include	<strings.h>
527c478bd9Sstevel@tonic-gate #include	<string.h>
537c478bd9Sstevel@tonic-gate #include	<stdlib.h>
547c478bd9Sstevel@tonic-gate #include	<unistd.h>
557c478bd9Sstevel@tonic-gate #include	<time.h>
567c478bd9Sstevel@tonic-gate #include	<locale.h>
577c478bd9Sstevel@tonic-gate #include	<fcntl.h>
587c478bd9Sstevel@tonic-gate #include	<errno.h>
597c478bd9Sstevel@tonic-gate #include	<limits.h>
607c478bd9Sstevel@tonic-gate #include	<sys/mnttab.h>
617c478bd9Sstevel@tonic-gate #include	<sys/param.h>
627c478bd9Sstevel@tonic-gate #include	<sys/types.h>
637c478bd9Sstevel@tonic-gate #include	<sys/sysmacros.h>
647c478bd9Sstevel@tonic-gate #include	<sys/vnode.h>
657c478bd9Sstevel@tonic-gate #include	<sys/mntent.h>
667c478bd9Sstevel@tonic-gate #include	<sys/filio.h>
677c478bd9Sstevel@tonic-gate #include	<sys/stat.h>
687c478bd9Sstevel@tonic-gate #include	<ustat.h>
697c478bd9Sstevel@tonic-gate #include 	<sys/isa_defs.h>	/* for ENDIAN defines */
707c478bd9Sstevel@tonic-gate #include	<sys/dkio.h>
717c478bd9Sstevel@tonic-gate #include	<sys/fdio.h>
727c478bd9Sstevel@tonic-gate #include	<sys/vtoc.h>
737c478bd9Sstevel@tonic-gate #include	<sys/fs/udf_volume.h>
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate extern char	*getfullrawname(char *);
767c478bd9Sstevel@tonic-gate extern char	*getfullblkname(char *);
777c478bd9Sstevel@tonic-gate extern struct tm *localtime_r(const time_t *, struct tm *);
787c478bd9Sstevel@tonic-gate extern void	maketag(struct tag *, struct tag *);
797c478bd9Sstevel@tonic-gate extern int	verifytag(struct tag *, uint32_t, struct tag *, int);
807c478bd9Sstevel@tonic-gate extern void	setcharspec(struct charspec *, int32_t, uint8_t *);
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate #define	UMASK		0755
847c478bd9Sstevel@tonic-gate #define	POWEROF2(num)	(((num) & ((num) - 1)) == 0)
857c478bd9Sstevel@tonic-gate #define	MB		(1024*1024)
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate /*
887c478bd9Sstevel@tonic-gate  * Forward declarations
897c478bd9Sstevel@tonic-gate  */
907c478bd9Sstevel@tonic-gate static void rdfs(daddr_t bno, int size, char *bf);
917c478bd9Sstevel@tonic-gate static void wtfs(daddr_t bno, int size, char *bf);
927c478bd9Sstevel@tonic-gate static void dump_fscmd(char *fsys, int fsi);
937c478bd9Sstevel@tonic-gate static int32_t number(long big, char *param);
947c478bd9Sstevel@tonic-gate static void usage();
957c478bd9Sstevel@tonic-gate static int match(char *s);
967c478bd9Sstevel@tonic-gate static int readvolseq();
977c478bd9Sstevel@tonic-gate static uint32_t get_last_block();
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate /*
1007c478bd9Sstevel@tonic-gate  * variables set up by front end.
1017c478bd9Sstevel@tonic-gate  */
1027c478bd9Sstevel@tonic-gate static int	Nflag = 0;		/* run mkfs without writing */
1037c478bd9Sstevel@tonic-gate 					/* file system */
1047c478bd9Sstevel@tonic-gate static int	mflag = 0;		/* return the command line used */
1057c478bd9Sstevel@tonic-gate 					/* to create this FS */
1067c478bd9Sstevel@tonic-gate static int	fssize;			/* file system size */
1077c478bd9Sstevel@tonic-gate static uint32_t	disk_size;		/* partition size from VTOC */
1087c478bd9Sstevel@tonic-gate static uint32_t unused;			/* unused sectors in partition */
1097c478bd9Sstevel@tonic-gate static int	sectorsize = 2048;	/* bytes/sector default */
1107c478bd9Sstevel@tonic-gate 					/* If nothing specified */
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate static char	*fsys;
1137c478bd9Sstevel@tonic-gate static int	fsi;
1147c478bd9Sstevel@tonic-gate static int	fso;
1157c478bd9Sstevel@tonic-gate 
1167c478bd9Sstevel@tonic-gate #define	BIG	LONG_MAX
1177c478bd9Sstevel@tonic-gate static	uint32_t	number_flags = 0;
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate static char	*string;
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate static void	setstamp(tstamp_t *);
1227c478bd9Sstevel@tonic-gate static void	setextad(extent_ad_t *, uint32_t, uint32_t);
1237c478bd9Sstevel@tonic-gate static void	setdstring(dstring_t *, char *, int32_t);
1247c478bd9Sstevel@tonic-gate static void	wtvolseq(tag_t *, daddr_t, daddr_t);
1257c478bd9Sstevel@tonic-gate static void	volseqinit();
1267c478bd9Sstevel@tonic-gate static void	setstamp(tstamp_t *);
1277c478bd9Sstevel@tonic-gate static uint32_t	get_bsize();
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate #define	VOLRECSTART	(32 * 1024)
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate #define	VOLSEQSTART	128
1337c478bd9Sstevel@tonic-gate #define	VOLSEQLEN	16
1347c478bd9Sstevel@tonic-gate #define	INTSEQSTART	192
1357c478bd9Sstevel@tonic-gate #define	INTSEQLEN	8192
1367c478bd9Sstevel@tonic-gate #define	FIRSTAVDP	256
1377c478bd9Sstevel@tonic-gate #define	AVDPLEN		1
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate 
1407c478bd9Sstevel@tonic-gate #define	FILESETLEN	2
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate #define	SPACEMAP_OFF	24
1437c478bd9Sstevel@tonic-gate #define	MAXID		16
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate static time_t mkfstime;
1467c478bd9Sstevel@tonic-gate static struct tm res;
1477c478bd9Sstevel@tonic-gate static long tzone;
1487c478bd9Sstevel@tonic-gate static char vsibuf[128];
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate static regid_t sunmicro = { 0, "*SUN SOLARIS UDF", 4, 2 };
1517c478bd9Sstevel@tonic-gate static regid_t lvinfo = { 0, "*UDF LV Info", 0x50, 0x1, 4, 2 };
1527c478bd9Sstevel@tonic-gate static regid_t partid = { 0, "+NSR02", 0 };
1537c478bd9Sstevel@tonic-gate static regid_t udf_compliant = { 0, "*OSTA UDF Compliant", 0x50, 0x1, 0 };
1547c478bd9Sstevel@tonic-gate static uint8_t osta_unicode[] = "OSTA Compressed Unicode";
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate static int bdevismounted;
1577c478bd9Sstevel@tonic-gate static int ismounted;
1587c478bd9Sstevel@tonic-gate static int directory;
1597c478bd9Sstevel@tonic-gate static char buf[MAXBSIZE];
1607c478bd9Sstevel@tonic-gate static char buf2[MAXBSIZE];
1617c478bd9Sstevel@tonic-gate static char lvid[MAXBSIZE];
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate uint32_t ecma_version = 2;
1647c478bd9Sstevel@tonic-gate 
1657c478bd9Sstevel@tonic-gate static int serialnum = 1;	/* Tag serial number */
1667c478bd9Sstevel@tonic-gate static char udfs_label[128] = "*NoLabel*";
1677c478bd9Sstevel@tonic-gate static int acctype = PART_ACC_OW;
1687c478bd9Sstevel@tonic-gate static uint32_t part_start;
1697c478bd9Sstevel@tonic-gate static uint32_t part_len;
1707c478bd9Sstevel@tonic-gate static uint32_t part_bmp_bytes;
1717c478bd9Sstevel@tonic-gate static uint32_t part_bmp_sectors;
1727c478bd9Sstevel@tonic-gate static int32_t part_unalloc = -1;
1737c478bd9Sstevel@tonic-gate static uint32_t filesetblock;
1747c478bd9Sstevel@tonic-gate 
1757c478bd9Sstevel@tonic-gate /* Set by readvolseq for -m option */
1767c478bd9Sstevel@tonic-gate static uint32_t oldfssize;
1777c478bd9Sstevel@tonic-gate static char *oldlabel;
1787c478bd9Sstevel@tonic-gate 
179*fe0e7ec4Smaheshvs int
1807c478bd9Sstevel@tonic-gate main(int32_t argc, int8_t *argv[])
1817c478bd9Sstevel@tonic-gate {
1827c478bd9Sstevel@tonic-gate 	long i;
1837c478bd9Sstevel@tonic-gate 	FILE *mnttab;
1847c478bd9Sstevel@tonic-gate 	struct mnttab mntp;
1857c478bd9Sstevel@tonic-gate 	char *special, *raw_special;
1867c478bd9Sstevel@tonic-gate 	struct stat statarea;
1877c478bd9Sstevel@tonic-gate 	struct ustat ustatarea;
1887c478bd9Sstevel@tonic-gate 	int32_t	c;
1897c478bd9Sstevel@tonic-gate 	uint32_t temp_secsz;
1907c478bd9Sstevel@tonic-gate 	int isfs;
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
1957c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"
1967c478bd9Sstevel@tonic-gate #endif
1977c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate 	while ((c = getopt(argc, argv, "F:Vmo:")) != EOF) {
2007c478bd9Sstevel@tonic-gate 		switch (c) {
2017c478bd9Sstevel@tonic-gate 
2027c478bd9Sstevel@tonic-gate 			case 'F':
2037c478bd9Sstevel@tonic-gate 				string = optarg;
2047c478bd9Sstevel@tonic-gate 				if (strcmp(string, "udfs") != 0) {
2057c478bd9Sstevel@tonic-gate 					usage();
2067c478bd9Sstevel@tonic-gate 				}
2077c478bd9Sstevel@tonic-gate 				break;
2087c478bd9Sstevel@tonic-gate 
2097c478bd9Sstevel@tonic-gate 			case 'V':
2107c478bd9Sstevel@tonic-gate 				{
2117c478bd9Sstevel@tonic-gate 					char	*opt_text;
2127c478bd9Sstevel@tonic-gate 					int	opt_count;
2137c478bd9Sstevel@tonic-gate 
2147c478bd9Sstevel@tonic-gate 					(void) fprintf(stdout,
2157c478bd9Sstevel@tonic-gate 					gettext("mkfs -F udfs "));
2167c478bd9Sstevel@tonic-gate 					for (opt_count = 1; opt_count < argc;
2177c478bd9Sstevel@tonic-gate 							opt_count++) {
2187c478bd9Sstevel@tonic-gate 						opt_text = argv[opt_count];
2197c478bd9Sstevel@tonic-gate 						if (opt_text) {
2207c478bd9Sstevel@tonic-gate 							(void) fprintf(stdout,
2217c478bd9Sstevel@tonic-gate 							" %s ", opt_text);
2227c478bd9Sstevel@tonic-gate 						}
2237c478bd9Sstevel@tonic-gate 					}
2247c478bd9Sstevel@tonic-gate 					(void) fprintf(stdout, "\n");
2257c478bd9Sstevel@tonic-gate 				}
2267c478bd9Sstevel@tonic-gate 				break;
2277c478bd9Sstevel@tonic-gate 
2287c478bd9Sstevel@tonic-gate 			case 'm':
2297c478bd9Sstevel@tonic-gate 				/*
2307c478bd9Sstevel@tonic-gate 				 * return command line used
2317c478bd9Sstevel@tonic-gate 				 * to create this FS
2327c478bd9Sstevel@tonic-gate 				 */
2337c478bd9Sstevel@tonic-gate 				mflag++;
2347c478bd9Sstevel@tonic-gate 				break;
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate 			case 'o':
2377c478bd9Sstevel@tonic-gate 				/*
2387c478bd9Sstevel@tonic-gate 				 * udfs specific options.
2397c478bd9Sstevel@tonic-gate 				 */
2407c478bd9Sstevel@tonic-gate 				string = optarg;
2417c478bd9Sstevel@tonic-gate 				while (*string != '\0') {
2427c478bd9Sstevel@tonic-gate 					if (match("N")) {
2437c478bd9Sstevel@tonic-gate 						Nflag++;
2447c478bd9Sstevel@tonic-gate 					} else if (match("psize=")) {
2457c478bd9Sstevel@tonic-gate 						number_flags = 0;
2467c478bd9Sstevel@tonic-gate 						sectorsize = number(BIG,
2477c478bd9Sstevel@tonic-gate 							"psize");
2487c478bd9Sstevel@tonic-gate 					} else if (match("label=")) {
2497c478bd9Sstevel@tonic-gate 						for (i = 0; i < 31; i++) {
2507c478bd9Sstevel@tonic-gate 							if (*string == '\0') {
2517c478bd9Sstevel@tonic-gate 								break;
2527c478bd9Sstevel@tonic-gate 							}
2537c478bd9Sstevel@tonic-gate 							udfs_label[i] =
2547c478bd9Sstevel@tonic-gate 								*string++;
2557c478bd9Sstevel@tonic-gate 						}
2567c478bd9Sstevel@tonic-gate 						udfs_label[i] = '\0';
2577c478bd9Sstevel@tonic-gate 					} else if (*string == '\0') {
2587c478bd9Sstevel@tonic-gate 						break;
2597c478bd9Sstevel@tonic-gate 					} else {
2607c478bd9Sstevel@tonic-gate 						(void) fprintf(stdout,
2617c478bd9Sstevel@tonic-gate 							gettext("illegal "
2627c478bd9Sstevel@tonic-gate 							"option: %s\n"),
2637c478bd9Sstevel@tonic-gate 							string);
2647c478bd9Sstevel@tonic-gate 						usage();
2657c478bd9Sstevel@tonic-gate 					}
2667c478bd9Sstevel@tonic-gate 					if (*string == ',') {
2677c478bd9Sstevel@tonic-gate 						string++;
2687c478bd9Sstevel@tonic-gate 					}
2697c478bd9Sstevel@tonic-gate 					if (*string == ' ') {
2707c478bd9Sstevel@tonic-gate 						string++;
2717c478bd9Sstevel@tonic-gate 					}
2727c478bd9Sstevel@tonic-gate 				}
2737c478bd9Sstevel@tonic-gate 				break;
2747c478bd9Sstevel@tonic-gate 
2757c478bd9Sstevel@tonic-gate 			case '?':
2767c478bd9Sstevel@tonic-gate 				usage();
2777c478bd9Sstevel@tonic-gate 				break;
2787c478bd9Sstevel@tonic-gate 		}
2797c478bd9Sstevel@tonic-gate 	}
2807c478bd9Sstevel@tonic-gate 
2817c478bd9Sstevel@tonic-gate 	(void) time(&mkfstime);
2827c478bd9Sstevel@tonic-gate 	if (optind > (argc - 1)) {
2837c478bd9Sstevel@tonic-gate 		usage();
2847c478bd9Sstevel@tonic-gate 	}
2857c478bd9Sstevel@tonic-gate 
2867c478bd9Sstevel@tonic-gate 	argc -= optind;
2877c478bd9Sstevel@tonic-gate 	argv = &argv[optind];
2887c478bd9Sstevel@tonic-gate 	fsys = argv[0];
2897c478bd9Sstevel@tonic-gate 	raw_special = getfullrawname(fsys);
2907c478bd9Sstevel@tonic-gate 	fsi = open(raw_special, 0);
2917c478bd9Sstevel@tonic-gate 	if (fsi < 0) {
2927c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout,
2937c478bd9Sstevel@tonic-gate 			gettext("%s: cannot open\n"), fsys);
2947c478bd9Sstevel@tonic-gate 		exit(32);
2957c478bd9Sstevel@tonic-gate 	}
2967c478bd9Sstevel@tonic-gate 	fso = fsi;
2977c478bd9Sstevel@tonic-gate 
2987c478bd9Sstevel@tonic-gate 	if ((temp_secsz = get_bsize()) != 0) {
2997c478bd9Sstevel@tonic-gate 		sectorsize = temp_secsz;
3007c478bd9Sstevel@tonic-gate 	}
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate 	/* Get old file system information */
3037c478bd9Sstevel@tonic-gate 	isfs = readvolseq();
3047c478bd9Sstevel@tonic-gate 
3057c478bd9Sstevel@tonic-gate 	if (mflag) {
3067c478bd9Sstevel@tonic-gate 		/*
3077c478bd9Sstevel@tonic-gate 		 * Figure out the block size and
3087c478bd9Sstevel@tonic-gate 		 * file system size and print the information
3097c478bd9Sstevel@tonic-gate 		 */
3107c478bd9Sstevel@tonic-gate 		if (isfs)
3117c478bd9Sstevel@tonic-gate 			dump_fscmd(fsys, fsi);
3127c478bd9Sstevel@tonic-gate 		else
3137c478bd9Sstevel@tonic-gate 			(void) printf(gettext(
3147c478bd9Sstevel@tonic-gate 				"[not currently a valid file system]\n"));
3157c478bd9Sstevel@tonic-gate 		exit(0);
3167c478bd9Sstevel@tonic-gate 	}
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate 	/*
3197c478bd9Sstevel@tonic-gate 	 * Get the disk size from the drive or VTOC for the N and N-256
3207c478bd9Sstevel@tonic-gate 	 * AVDPs and to make sure we don't want to create a file system
3217c478bd9Sstevel@tonic-gate 	 * bigger than the partition.
3227c478bd9Sstevel@tonic-gate 	 */
3237c478bd9Sstevel@tonic-gate 	disk_size = get_last_block();
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate 	if (argc < 2 && disk_size == 0 || argc < 1) {
3267c478bd9Sstevel@tonic-gate 		usage();
3277c478bd9Sstevel@tonic-gate 	}
3287c478bd9Sstevel@tonic-gate 
3297c478bd9Sstevel@tonic-gate 	if (argc < 2) {
3307c478bd9Sstevel@tonic-gate 		(void) printf(gettext("No size specified, entire partition "
3317c478bd9Sstevel@tonic-gate 			"of %u sectors used\n"), disk_size);
3327c478bd9Sstevel@tonic-gate 		fssize = disk_size;
3337c478bd9Sstevel@tonic-gate 	} else {
3347c478bd9Sstevel@tonic-gate 		string = argv[1];
3357c478bd9Sstevel@tonic-gate 		number_flags = 0;
3367c478bd9Sstevel@tonic-gate 		fssize = number(BIG, "size");
3377c478bd9Sstevel@tonic-gate 	}
3387c478bd9Sstevel@tonic-gate 
3397c478bd9Sstevel@tonic-gate 	if (fssize < 0) {
3407c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
3417c478bd9Sstevel@tonic-gate 			gettext("Negative number of sectors(%d) not allowed\n"),
3427c478bd9Sstevel@tonic-gate 			fssize);
3437c478bd9Sstevel@tonic-gate 		exit(32);
3447c478bd9Sstevel@tonic-gate 	}
3457c478bd9Sstevel@tonic-gate 
3467c478bd9Sstevel@tonic-gate 	if (fssize < (512 * sectorsize / DEV_BSIZE)) {
3477c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout,
3487c478bd9Sstevel@tonic-gate 			gettext("size should be at least %d sectors\n"),
3497c478bd9Sstevel@tonic-gate 			(512 * sectorsize / DEV_BSIZE));
3507c478bd9Sstevel@tonic-gate 		exit(32);
3517c478bd9Sstevel@tonic-gate 	}
3527c478bd9Sstevel@tonic-gate 
3537c478bd9Sstevel@tonic-gate 	if (disk_size != 0) {
3547c478bd9Sstevel@tonic-gate 		if (fssize > disk_size) {
3557c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("Invalid size: %d "
3567c478bd9Sstevel@tonic-gate 				"larger than the partition size\n"), fssize);
3577c478bd9Sstevel@tonic-gate 			exit(32);
3587c478bd9Sstevel@tonic-gate 		} else if (fssize < disk_size) {
3597c478bd9Sstevel@tonic-gate 			unused = disk_size - fssize;
3607c478bd9Sstevel@tonic-gate 			(void) printf(
3617c478bd9Sstevel@tonic-gate 			    gettext("File system size %d smaller than "
3627c478bd9Sstevel@tonic-gate 				"partition, %u sectors unused\n"),
3637c478bd9Sstevel@tonic-gate 				fssize, unused);
3647c478bd9Sstevel@tonic-gate 		}
3657c478bd9Sstevel@tonic-gate 	} else {
3667c478bd9Sstevel@tonic-gate 		/* Use passed-in size */
3677c478bd9Sstevel@tonic-gate 		disk_size = fssize;
3687c478bd9Sstevel@tonic-gate 	}
3697c478bd9Sstevel@tonic-gate 
3707c478bd9Sstevel@tonic-gate 	if (!Nflag) {
3717c478bd9Sstevel@tonic-gate 		special = getfullblkname(fsys);
3727c478bd9Sstevel@tonic-gate 
3737c478bd9Sstevel@tonic-gate 		/*
3747c478bd9Sstevel@tonic-gate 		 * If we found the block device name,
3757c478bd9Sstevel@tonic-gate 		 * then check the mount table.
3767c478bd9Sstevel@tonic-gate 		 * if mounted, write lock the file system
3777c478bd9Sstevel@tonic-gate 		 *
3787c478bd9Sstevel@tonic-gate 		 */
3797c478bd9Sstevel@tonic-gate 		if ((special != NULL) && (*special != '\0')) {
3807c478bd9Sstevel@tonic-gate 			mnttab = fopen(MNTTAB, "r");
3817c478bd9Sstevel@tonic-gate 			while ((getmntent(mnttab, &mntp)) == NULL) {
3827c478bd9Sstevel@tonic-gate 				if (strcmp(special, mntp.mnt_special) == 0) {
3837c478bd9Sstevel@tonic-gate 					(void) fprintf(stdout,
3847c478bd9Sstevel@tonic-gate 						gettext("%s is mounted,"
3857c478bd9Sstevel@tonic-gate 						" can't mkfs\n"), special);
3867c478bd9Sstevel@tonic-gate 					exit(32);
3877c478bd9Sstevel@tonic-gate 				}
3887c478bd9Sstevel@tonic-gate 			}
3897c478bd9Sstevel@tonic-gate 			(void) fclose(mnttab);
3907c478bd9Sstevel@tonic-gate 		}
3917c478bd9Sstevel@tonic-gate 		if ((bdevismounted) && (ismounted == 0)) {
3927c478bd9Sstevel@tonic-gate 			(void) fprintf(stdout,
3937c478bd9Sstevel@tonic-gate 				gettext("can't check mount point; "));
3947c478bd9Sstevel@tonic-gate 			(void) fprintf(stdout,
3957c478bd9Sstevel@tonic-gate 				gettext("%s is mounted but not in mnttab(4)\n"),
3967c478bd9Sstevel@tonic-gate 				special);
3977c478bd9Sstevel@tonic-gate 			exit(32);
3987c478bd9Sstevel@tonic-gate 		}
3997c478bd9Sstevel@tonic-gate 		if (directory) {
4007c478bd9Sstevel@tonic-gate 			if (ismounted == 0) {
4017c478bd9Sstevel@tonic-gate 				(void) fprintf(stdout,
4027c478bd9Sstevel@tonic-gate 					gettext("%s is not mounted\n"),
4037c478bd9Sstevel@tonic-gate 					special);
4047c478bd9Sstevel@tonic-gate 				exit(32);
4057c478bd9Sstevel@tonic-gate 			}
4067c478bd9Sstevel@tonic-gate 		}
4077c478bd9Sstevel@tonic-gate 		fso = creat(fsys, 0666);
4087c478bd9Sstevel@tonic-gate 		if (fso < 0) {
4097c478bd9Sstevel@tonic-gate 			(void) fprintf(stdout,
4107c478bd9Sstevel@tonic-gate 				gettext("%s: cannot create\n"), fsys);
4117c478bd9Sstevel@tonic-gate 			exit(32);
4127c478bd9Sstevel@tonic-gate 		}
4137c478bd9Sstevel@tonic-gate 		if (stat(fsys, &statarea) < 0) {
4147c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
4157c478bd9Sstevel@tonic-gate 				gettext("%s: %s: cannot stat\n"),
4167c478bd9Sstevel@tonic-gate 				argv[0], fsys);
4177c478bd9Sstevel@tonic-gate 			exit(32);
4187c478bd9Sstevel@tonic-gate 		}
4197c478bd9Sstevel@tonic-gate 		if (ustat(statarea.st_rdev, &ustatarea) >= 0) {
4207c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
4217c478bd9Sstevel@tonic-gate 				gettext("%s is mounted, can't mkfs\n"), fsys);
4227c478bd9Sstevel@tonic-gate 			exit(32);
4237c478bd9Sstevel@tonic-gate 		}
4247c478bd9Sstevel@tonic-gate 	} else {
4257c478bd9Sstevel@tonic-gate 		/*
4267c478bd9Sstevel@tonic-gate 		 * For the -N case, a file descriptor is needed for the llseek()
4277c478bd9Sstevel@tonic-gate 		 * in wtfs(). See the comment in wtfs() for more information.
4287c478bd9Sstevel@tonic-gate 		 *
4297c478bd9Sstevel@tonic-gate 		 * Get a file descriptor that's read-only so that this code
4307c478bd9Sstevel@tonic-gate 		 * doesn't accidentally write to the file.
4317c478bd9Sstevel@tonic-gate 		 */
4327c478bd9Sstevel@tonic-gate 		fso = open(fsys, O_RDONLY);
4337c478bd9Sstevel@tonic-gate 		if (fso < 0) {
4347c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("%s: cannot open\n"),
4357c478bd9Sstevel@tonic-gate 				fsys);
4367c478bd9Sstevel@tonic-gate 			exit(32);
4377c478bd9Sstevel@tonic-gate 		}
4387c478bd9Sstevel@tonic-gate 	}
4397c478bd9Sstevel@tonic-gate 
4407c478bd9Sstevel@tonic-gate 
4417c478bd9Sstevel@tonic-gate 	/*
4427c478bd9Sstevel@tonic-gate 	 * Validate the given file system size.
4437c478bd9Sstevel@tonic-gate 	 * Verify that its last block can actually be accessed.
4447c478bd9Sstevel@tonic-gate 	 */
4457c478bd9Sstevel@tonic-gate 	fssize = fssize / (sectorsize / DEV_BSIZE);
4467c478bd9Sstevel@tonic-gate 	if (fssize <= 0) {
4477c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout,
4487c478bd9Sstevel@tonic-gate 			gettext("preposterous size %d. sectors\n"), fssize);
4497c478bd9Sstevel@tonic-gate 		exit(32);
4507c478bd9Sstevel@tonic-gate 	}
4517c478bd9Sstevel@tonic-gate 	fssize --;
4527c478bd9Sstevel@tonic-gate 
4537c478bd9Sstevel@tonic-gate 	/*
4547c478bd9Sstevel@tonic-gate 	 * verify device size
4557c478bd9Sstevel@tonic-gate 	 */
4567c478bd9Sstevel@tonic-gate 	rdfs(fssize - 1, sectorsize, buf);
4577c478bd9Sstevel@tonic-gate 
4587c478bd9Sstevel@tonic-gate 	if ((sectorsize < DEV_BSIZE) ||
4597c478bd9Sstevel@tonic-gate 		(sectorsize > MAXBSIZE)) {
4607c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout,
4617c478bd9Sstevel@tonic-gate 			gettext("sector size must be"
4627c478bd9Sstevel@tonic-gate 			" between 512, 8192 bytes\n"));
4637c478bd9Sstevel@tonic-gate 	}
4647c478bd9Sstevel@tonic-gate 	if (!POWEROF2(sectorsize)) {
4657c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout,
4667c478bd9Sstevel@tonic-gate 			gettext("sector size must be a power of 2, not %d\n"),
4677c478bd9Sstevel@tonic-gate 			sectorsize);
4687c478bd9Sstevel@tonic-gate 		exit(32);
4697c478bd9Sstevel@tonic-gate 	}
4707c478bd9Sstevel@tonic-gate 	if (Nflag) {
4717c478bd9Sstevel@tonic-gate 		exit(0);
4727c478bd9Sstevel@tonic-gate 	}
4737c478bd9Sstevel@tonic-gate 
4747c478bd9Sstevel@tonic-gate 	(void) printf(gettext("Creating file system with sector size of "
4757c478bd9Sstevel@tonic-gate 		"%d bytes\n"), sectorsize);
4767c478bd9Sstevel@tonic-gate 
4777c478bd9Sstevel@tonic-gate 	/*
4787c478bd9Sstevel@tonic-gate 	 * Set up time stamp values
4797c478bd9Sstevel@tonic-gate 	 */
4807c478bd9Sstevel@tonic-gate 	mkfstime = time(0);
4817c478bd9Sstevel@tonic-gate 	(void) localtime_r(&mkfstime, &res);
4827c478bd9Sstevel@tonic-gate 	if (res.tm_isdst > 0) {
4837c478bd9Sstevel@tonic-gate 		tzone = altzone / 60;
4847c478bd9Sstevel@tonic-gate 	} else if (res.tm_isdst == 0) {
4857c478bd9Sstevel@tonic-gate 		tzone = tzone / 60;
4867c478bd9Sstevel@tonic-gate 	} else {
4877c478bd9Sstevel@tonic-gate 		tzone = 2047;	/* Unknown */
4887c478bd9Sstevel@tonic-gate 	}
4897c478bd9Sstevel@tonic-gate 
4907c478bd9Sstevel@tonic-gate 	/*
4917c478bd9Sstevel@tonic-gate 	 * Initialize the volume recognition sequence, the volume descriptor
4927c478bd9Sstevel@tonic-gate 	 * sequences and the anchor pointer.
4937c478bd9Sstevel@tonic-gate 	 */
4947c478bd9Sstevel@tonic-gate 	volseqinit();
4957c478bd9Sstevel@tonic-gate 
4967c478bd9Sstevel@tonic-gate 	(void) fsync(fso);
4977c478bd9Sstevel@tonic-gate 	(void) close(fsi);
4987c478bd9Sstevel@tonic-gate 	(void) close(fso);
4997c478bd9Sstevel@tonic-gate 
5007c478bd9Sstevel@tonic-gate 	return (0);
5017c478bd9Sstevel@tonic-gate }
5027c478bd9Sstevel@tonic-gate 
5037c478bd9Sstevel@tonic-gate static void
5047c478bd9Sstevel@tonic-gate setstamp(tstamp_t *tp)
5057c478bd9Sstevel@tonic-gate {
5067c478bd9Sstevel@tonic-gate 	tp->ts_usec = 0;
5077c478bd9Sstevel@tonic-gate 	tp->ts_husec = 0;
5087c478bd9Sstevel@tonic-gate 	tp->ts_csec = 0;
5097c478bd9Sstevel@tonic-gate 
5107c478bd9Sstevel@tonic-gate 	tp->ts_sec = res.tm_sec;
5117c478bd9Sstevel@tonic-gate 	tp->ts_min = res.tm_min;
5127c478bd9Sstevel@tonic-gate 	tp->ts_hour = res.tm_hour;
5137c478bd9Sstevel@tonic-gate 	tp->ts_day = res.tm_mday;
5147c478bd9Sstevel@tonic-gate 	tp->ts_month = res.tm_mon + 1;
5157c478bd9Sstevel@tonic-gate 	tp->ts_year = 1900 + res.tm_year;
5167c478bd9Sstevel@tonic-gate 
5177c478bd9Sstevel@tonic-gate 	tp->ts_tzone = 0x1000 + (-tzone & 0xFFF);
5187c478bd9Sstevel@tonic-gate }
5197c478bd9Sstevel@tonic-gate 
5207c478bd9Sstevel@tonic-gate static void
5217c478bd9Sstevel@tonic-gate setextad(extent_ad_t *eap, uint32_t len, uint32_t loc)
5227c478bd9Sstevel@tonic-gate {
5237c478bd9Sstevel@tonic-gate 	eap->ext_len = len;
5247c478bd9Sstevel@tonic-gate 	eap->ext_loc = loc;
5257c478bd9Sstevel@tonic-gate }
5267c478bd9Sstevel@tonic-gate 
5277c478bd9Sstevel@tonic-gate static void
5287c478bd9Sstevel@tonic-gate setdstring(dstring_t *dp, char *cp, int len)
5297c478bd9Sstevel@tonic-gate {
5307c478bd9Sstevel@tonic-gate 	int32_t length;
5317c478bd9Sstevel@tonic-gate 
5327c478bd9Sstevel@tonic-gate 	bzero(dp, len);
5337c478bd9Sstevel@tonic-gate 	length = strlen(cp);
5347c478bd9Sstevel@tonic-gate 	if (length > len - 3) {
5357c478bd9Sstevel@tonic-gate 		length = len - 3;
5367c478bd9Sstevel@tonic-gate 	}
5377c478bd9Sstevel@tonic-gate 	dp[len - 1] = length + 1;
5387c478bd9Sstevel@tonic-gate 	*dp++ = 8;
5397c478bd9Sstevel@tonic-gate 	(void) strncpy(dp, cp, len-2);
5407c478bd9Sstevel@tonic-gate }
5417c478bd9Sstevel@tonic-gate 
5427c478bd9Sstevel@tonic-gate static void
5437c478bd9Sstevel@tonic-gate wtvolseq(tag_t *tp, daddr_t blk1, daddr_t blk2)
5447c478bd9Sstevel@tonic-gate {
5457c478bd9Sstevel@tonic-gate 	static uint32_t vdsn = 0;
5467c478bd9Sstevel@tonic-gate 
5477c478bd9Sstevel@tonic-gate 	tp->tag_loc = blk1;
5487c478bd9Sstevel@tonic-gate 	switch (tp->tag_id) {
5497c478bd9Sstevel@tonic-gate 	case UD_PRI_VOL_DESC :
5507c478bd9Sstevel@tonic-gate 		((struct pri_vol_desc *)tp)->pvd_vdsn = vdsn++;
5517c478bd9Sstevel@tonic-gate 		break;
5527c478bd9Sstevel@tonic-gate 	case UD_VOL_DESC_PTR :
5537c478bd9Sstevel@tonic-gate 		((struct vol_desc_ptr *)tp)->vdp_vdsn = vdsn++;
5547c478bd9Sstevel@tonic-gate 		break;
5557c478bd9Sstevel@tonic-gate 	case UD_IMPL_USE_DESC :
5567c478bd9Sstevel@tonic-gate 		((struct iuvd_desc *)tp)->iuvd_vdsn = vdsn++;
5577c478bd9Sstevel@tonic-gate 		break;
5587c478bd9Sstevel@tonic-gate 	case UD_PART_DESC :
5597c478bd9Sstevel@tonic-gate 		((struct part_desc *)tp)->pd_vdsn = vdsn++;
5607c478bd9Sstevel@tonic-gate 		break;
5617c478bd9Sstevel@tonic-gate 	case UD_LOG_VOL_DESC :
5627c478bd9Sstevel@tonic-gate 		((struct log_vol_desc *)tp)->lvd_vdsn = vdsn++;
5637c478bd9Sstevel@tonic-gate 		break;
5647c478bd9Sstevel@tonic-gate 	case UD_UNALL_SPA_DESC :
5657c478bd9Sstevel@tonic-gate 		((struct unall_spc_desc *)tp)->ua_vdsn = vdsn++;
5667c478bd9Sstevel@tonic-gate 		break;
5677c478bd9Sstevel@tonic-gate 	}
5687c478bd9Sstevel@tonic-gate 
5697c478bd9Sstevel@tonic-gate 	bzero(buf2, sectorsize);
5707c478bd9Sstevel@tonic-gate 	/* LINTED */
5717c478bd9Sstevel@tonic-gate 	maketag(tp, (struct tag *)buf2);
5727c478bd9Sstevel@tonic-gate 
5737c478bd9Sstevel@tonic-gate 	/*
5747c478bd9Sstevel@tonic-gate 	 * Write at Main Volume Descriptor Sequence
5757c478bd9Sstevel@tonic-gate 	 */
5767c478bd9Sstevel@tonic-gate 	wtfs(blk1, sectorsize, buf2);
5777c478bd9Sstevel@tonic-gate 
5787c478bd9Sstevel@tonic-gate 	tp->tag_loc = blk2;
5797c478bd9Sstevel@tonic-gate 	switch (tp->tag_id) {
5807c478bd9Sstevel@tonic-gate 	case UD_PRI_VOL_DESC :
5817c478bd9Sstevel@tonic-gate 		((struct pri_vol_desc *)tp)->pvd_vdsn = vdsn++;
5827c478bd9Sstevel@tonic-gate 		break;
5837c478bd9Sstevel@tonic-gate 	case UD_VOL_DESC_PTR :
5847c478bd9Sstevel@tonic-gate 		((struct vol_desc_ptr *)tp)->vdp_vdsn = vdsn++;
5857c478bd9Sstevel@tonic-gate 		break;
5867c478bd9Sstevel@tonic-gate 	case UD_IMPL_USE_DESC :
5877c478bd9Sstevel@tonic-gate 		((struct iuvd_desc *)tp)->iuvd_vdsn = vdsn++;
5887c478bd9Sstevel@tonic-gate 		break;
5897c478bd9Sstevel@tonic-gate 	case UD_PART_DESC :
5907c478bd9Sstevel@tonic-gate 		((struct part_desc *)tp)->pd_vdsn = vdsn++;
5917c478bd9Sstevel@tonic-gate 		break;
5927c478bd9Sstevel@tonic-gate 	case UD_LOG_VOL_DESC :
5937c478bd9Sstevel@tonic-gate 		((struct log_vol_desc *)tp)->lvd_vdsn = vdsn++;
5947c478bd9Sstevel@tonic-gate 		break;
5957c478bd9Sstevel@tonic-gate 	case UD_UNALL_SPA_DESC :
5967c478bd9Sstevel@tonic-gate 		((struct unall_spc_desc *)tp)->ua_vdsn = vdsn++;
5977c478bd9Sstevel@tonic-gate 		break;
5987c478bd9Sstevel@tonic-gate 	}
5997c478bd9Sstevel@tonic-gate 	maketag(tp, tp);
6007c478bd9Sstevel@tonic-gate 	/*
6017c478bd9Sstevel@tonic-gate 	 * Write at Reserve Volume Descriptor Sequence
6027c478bd9Sstevel@tonic-gate 	 */
6037c478bd9Sstevel@tonic-gate 	wtfs(blk2, sectorsize, buf);
6047c478bd9Sstevel@tonic-gate }
6057c478bd9Sstevel@tonic-gate 
6067c478bd9Sstevel@tonic-gate static void
6077c478bd9Sstevel@tonic-gate volseqinit()
6087c478bd9Sstevel@tonic-gate {
6097c478bd9Sstevel@tonic-gate 	struct tag *tp;
6107c478bd9Sstevel@tonic-gate 	struct nsr_desc *nsp;
6117c478bd9Sstevel@tonic-gate 	struct pri_vol_desc *pvdp;
6127c478bd9Sstevel@tonic-gate 	struct iuvd_desc *iudp;
6137c478bd9Sstevel@tonic-gate 	struct part_desc *pp;
6147c478bd9Sstevel@tonic-gate 	struct phdr_desc *php;
6157c478bd9Sstevel@tonic-gate 	struct log_vol_desc *lvp;
6167c478bd9Sstevel@tonic-gate 	long_ad_t *lap;
6177c478bd9Sstevel@tonic-gate 	struct pmap_typ1 *pmp;
6187c478bd9Sstevel@tonic-gate 	struct unall_spc_desc *uap;
6197c478bd9Sstevel@tonic-gate 	struct log_vol_int_desc *lvip;
6207c478bd9Sstevel@tonic-gate 	struct term_desc *tdp;
6217c478bd9Sstevel@tonic-gate 	struct anch_vol_desc_ptr *avp;
6227c478bd9Sstevel@tonic-gate 	struct lvid_iu *lviup;
6237c478bd9Sstevel@tonic-gate 	struct file_set_desc *fsp;
6247c478bd9Sstevel@tonic-gate 	struct file_entry *fp;
6257c478bd9Sstevel@tonic-gate 	struct icb_tag *icb;
6267c478bd9Sstevel@tonic-gate 	struct short_ad *sap;
6277c478bd9Sstevel@tonic-gate 	struct file_id *fip;
6287c478bd9Sstevel@tonic-gate 	struct space_bmap_desc *sbp;
6297c478bd9Sstevel@tonic-gate 	uint8_t *cp;
6307c478bd9Sstevel@tonic-gate 	daddr_t nextblock, endblock;
6317c478bd9Sstevel@tonic-gate 	int32_t volseq_sectors, nextlogblock, rootfelen, i;
6327c478bd9Sstevel@tonic-gate 	uint32_t mvds_loc, rvds_loc;
6337c478bd9Sstevel@tonic-gate 
6347c478bd9Sstevel@tonic-gate 	bzero(buf, MAXBSIZE);
6357c478bd9Sstevel@tonic-gate 
6367c478bd9Sstevel@tonic-gate 	/*
6377c478bd9Sstevel@tonic-gate 	 * Starting from MAXBSIZE, clear out till 256 sectors.
6387c478bd9Sstevel@tonic-gate 	 */
6397c478bd9Sstevel@tonic-gate 	for (i = MAXBSIZE / sectorsize; i < FIRSTAVDP; i++) {
6407c478bd9Sstevel@tonic-gate 		wtfs(i, sectorsize, buf);
6417c478bd9Sstevel@tonic-gate 	}
6427c478bd9Sstevel@tonic-gate 
6437c478bd9Sstevel@tonic-gate 	/* Zero out the avdp at N - 257 */
6447c478bd9Sstevel@tonic-gate 	wtfs(fssize - 256, sectorsize, buf);
6457c478bd9Sstevel@tonic-gate 
6467c478bd9Sstevel@tonic-gate 	/*
6477c478bd9Sstevel@tonic-gate 	 * Leave 1st 32K for O.S.
6487c478bd9Sstevel@tonic-gate 	 */
6497c478bd9Sstevel@tonic-gate 	nextblock = VOLRECSTART / sectorsize;
6507c478bd9Sstevel@tonic-gate 
6517c478bd9Sstevel@tonic-gate 	/*
6527c478bd9Sstevel@tonic-gate 	 * Write BEA01/NSR02/TEA01 sequence.
6537c478bd9Sstevel@tonic-gate 	 * Each one must be 2K bytes in length.
6547c478bd9Sstevel@tonic-gate 	 */
6557c478bd9Sstevel@tonic-gate 	nsp = (struct nsr_desc *)buf;
6567c478bd9Sstevel@tonic-gate 	nsp->nsr_str_type = 0;
6577c478bd9Sstevel@tonic-gate 	nsp->nsr_ver = 1;
6587c478bd9Sstevel@tonic-gate 	(void) strncpy((int8_t *)nsp->nsr_id, "BEA01", 5);
6597c478bd9Sstevel@tonic-gate 
6607c478bd9Sstevel@tonic-gate 	nsp = (struct nsr_desc *)&buf[2048];
6617c478bd9Sstevel@tonic-gate 	nsp->nsr_str_type = 0;
6627c478bd9Sstevel@tonic-gate 	nsp->nsr_ver = 1;
6637c478bd9Sstevel@tonic-gate 	(void) strncpy((int8_t *)nsp->nsr_id, "NSR02", 5);
6647c478bd9Sstevel@tonic-gate 
6657c478bd9Sstevel@tonic-gate 	nsp = (struct nsr_desc *)&buf[4096];
6667c478bd9Sstevel@tonic-gate 	nsp->nsr_str_type = 0;
6677c478bd9Sstevel@tonic-gate 	nsp->nsr_ver = 1;
6687c478bd9Sstevel@tonic-gate 	(void) strncpy((int8_t *)nsp->nsr_id, "TEA01", 5);
6697c478bd9Sstevel@tonic-gate 
6707c478bd9Sstevel@tonic-gate 	wtfs(nextblock, 8192, buf);
6717c478bd9Sstevel@tonic-gate 	bzero(buf, MAXBSIZE);
6727c478bd9Sstevel@tonic-gate 
6737c478bd9Sstevel@tonic-gate 	/*
6747c478bd9Sstevel@tonic-gate 	 * Minimum length of volume sequences
6757c478bd9Sstevel@tonic-gate 	 */
6767c478bd9Sstevel@tonic-gate 	volseq_sectors = 16;
6777c478bd9Sstevel@tonic-gate 
6787c478bd9Sstevel@tonic-gate 	/*
6797c478bd9Sstevel@tonic-gate 	 * Round up to next 32K boundary for
6807c478bd9Sstevel@tonic-gate 	 * volume descriptor sequences
6817c478bd9Sstevel@tonic-gate 	 */
6827c478bd9Sstevel@tonic-gate 	nextblock = VOLSEQSTART;
6837c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
6847c478bd9Sstevel@tonic-gate 	mvds_loc = VOLSEQSTART;
6857c478bd9Sstevel@tonic-gate 	rvds_loc = mvds_loc + volseq_sectors;
6867c478bd9Sstevel@tonic-gate 
6877c478bd9Sstevel@tonic-gate 	/*
6887c478bd9Sstevel@tonic-gate 	 * Primary Volume Descriptor
6897c478bd9Sstevel@tonic-gate 	 */
6907c478bd9Sstevel@tonic-gate 	/* LINTED */
6917c478bd9Sstevel@tonic-gate 	pvdp = (struct pri_vol_desc *)buf;
6927c478bd9Sstevel@tonic-gate 	tp = &pvdp->pvd_tag;
6937c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_PRI_VOL_DESC;
6947c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
6957c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
6967c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct pri_vol_desc) -
6977c478bd9Sstevel@tonic-gate 			sizeof (struct tag);
6987c478bd9Sstevel@tonic-gate 	pvdp->pvd_vdsn = 0;
6997c478bd9Sstevel@tonic-gate 	pvdp->pvd_pvdn = 0;
7007c478bd9Sstevel@tonic-gate 	setdstring(pvdp->pvd_vol_id, udfs_label, 32);
7017c478bd9Sstevel@tonic-gate 	pvdp->pvd_vsn = 1;
7027c478bd9Sstevel@tonic-gate 	pvdp->pvd_mvsn = 1;
7037c478bd9Sstevel@tonic-gate 	pvdp->pvd_il = 2;		/* Single-volume */
7047c478bd9Sstevel@tonic-gate 	pvdp->pvd_mil = 3;		/* Multi-volume */
7057c478bd9Sstevel@tonic-gate 	pvdp->pvd_csl = 1;		/* CS0 */
7067c478bd9Sstevel@tonic-gate 	pvdp->pvd_mcsl = 1;		/* CS0 */
7077c478bd9Sstevel@tonic-gate 	(void) sprintf(vsibuf, "%08X", SWAP_32((uint32_t)mkfstime));
7087c478bd9Sstevel@tonic-gate 	setdstring(pvdp->pvd_vsi, vsibuf, 128);
7097c478bd9Sstevel@tonic-gate 	(void) strncpy(pvdp->pvd_vsi + 17, udfs_label, 128 - 17);
7107c478bd9Sstevel@tonic-gate 	setcharspec(&pvdp->pvd_desc_cs, 0, osta_unicode);
7117c478bd9Sstevel@tonic-gate 	setcharspec(&pvdp->pvd_exp_cs, 0, osta_unicode);
7127c478bd9Sstevel@tonic-gate 	setextad(&pvdp->pvd_vol_abs, 0, 0);
7137c478bd9Sstevel@tonic-gate 	setextad(&pvdp->pvd_vcn, 0, 0);
7147c478bd9Sstevel@tonic-gate 	bzero(&pvdp->pvd_appl_id, sizeof (regid_t));
7157c478bd9Sstevel@tonic-gate 	setstamp(&pvdp->pvd_time);
7167c478bd9Sstevel@tonic-gate 	bcopy(&sunmicro, &pvdp->pvd_ii, sizeof (regid_t));
7177c478bd9Sstevel@tonic-gate 	pvdp->pvd_flags = 0;
7187c478bd9Sstevel@tonic-gate 	wtvolseq(tp, nextblock, nextblock + volseq_sectors);
7197c478bd9Sstevel@tonic-gate 	nextblock++;
7207c478bd9Sstevel@tonic-gate 
7217c478bd9Sstevel@tonic-gate 	/*
7227c478bd9Sstevel@tonic-gate 	 * Implementation Use Descriptor
7237c478bd9Sstevel@tonic-gate 	 */
7247c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
7257c478bd9Sstevel@tonic-gate 	/* LINTED */
7267c478bd9Sstevel@tonic-gate 	iudp = (struct iuvd_desc *)buf;
7277c478bd9Sstevel@tonic-gate 	tp = &iudp->iuvd_tag;
7287c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_IMPL_USE_DESC;
7297c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
7307c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
7317c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct iuvd_desc) -
7327c478bd9Sstevel@tonic-gate 			sizeof (struct tag);
7337c478bd9Sstevel@tonic-gate 	iudp->iuvd_vdsn = 0;
7347c478bd9Sstevel@tonic-gate 	bcopy(&lvinfo, &iudp->iuvd_ii, sizeof (regid_t));
7357c478bd9Sstevel@tonic-gate 	setcharspec(&iudp->iuvd_cset, 0, osta_unicode);
7367c478bd9Sstevel@tonic-gate 	setdstring(iudp->iuvd_lvi, udfs_label, 128);
7377c478bd9Sstevel@tonic-gate 
7387c478bd9Sstevel@tonic-gate 	setdstring(iudp->iuvd_ifo1, "", 36);
7397c478bd9Sstevel@tonic-gate 	setdstring(iudp->iuvd_ifo2, "", 36);
7407c478bd9Sstevel@tonic-gate 	setdstring(iudp->iuvd_ifo3, "", 36);
7417c478bd9Sstevel@tonic-gate 
7427c478bd9Sstevel@tonic-gate 
7437c478bd9Sstevel@tonic-gate 	/*
7447c478bd9Sstevel@tonic-gate 	 * info1,2,3 = user specified
7457c478bd9Sstevel@tonic-gate 	 */
7467c478bd9Sstevel@tonic-gate 	bcopy(&sunmicro, &iudp->iuvd_iid, sizeof (regid_t));
7477c478bd9Sstevel@tonic-gate 	wtvolseq(tp, nextblock, nextblock + volseq_sectors);
7487c478bd9Sstevel@tonic-gate 	nextblock++;
7497c478bd9Sstevel@tonic-gate 
7507c478bd9Sstevel@tonic-gate 	/*
7517c478bd9Sstevel@tonic-gate 	 * Partition Descriptor
7527c478bd9Sstevel@tonic-gate 	 */
7537c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
7547c478bd9Sstevel@tonic-gate 	/* LINTED */
7557c478bd9Sstevel@tonic-gate 	pp = (struct part_desc *)buf;
7567c478bd9Sstevel@tonic-gate 	tp = &pp->pd_tag;
7577c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_PART_DESC;
7587c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
7597c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
7607c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct part_desc) -
7617c478bd9Sstevel@tonic-gate 			sizeof (struct tag);
7627c478bd9Sstevel@tonic-gate 	pp->pd_vdsn = 0;
7637c478bd9Sstevel@tonic-gate 	pp->pd_pflags = 1;			/* Allocated */
7647c478bd9Sstevel@tonic-gate 	pp->pd_pnum = 0;
7657c478bd9Sstevel@tonic-gate 	bcopy(&partid, &pp->pd_pcontents, sizeof (regid_t));
7667c478bd9Sstevel@tonic-gate 
7677c478bd9Sstevel@tonic-gate 	part_start = FIRSTAVDP + AVDPLEN;
7687c478bd9Sstevel@tonic-gate 	part_len = fssize - part_start;
7697c478bd9Sstevel@tonic-gate 	part_bmp_bytes = (part_len + NBBY - 1) / NBBY;
7707c478bd9Sstevel@tonic-gate 	part_bmp_sectors = (part_bmp_bytes + SPACEMAP_OFF + sectorsize - 1) /
7717c478bd9Sstevel@tonic-gate 		sectorsize;
7727c478bd9Sstevel@tonic-gate 
7737c478bd9Sstevel@tonic-gate 	pp->pd_part_start = part_start;
7747c478bd9Sstevel@tonic-gate 	pp->pd_part_length = part_len;
7757c478bd9Sstevel@tonic-gate 
7767c478bd9Sstevel@tonic-gate 	pp->pd_acc_type = acctype;
7777c478bd9Sstevel@tonic-gate 	nextlogblock = 0;
7787c478bd9Sstevel@tonic-gate 
7797c478bd9Sstevel@tonic-gate 	/*
7807c478bd9Sstevel@tonic-gate 	 * Do the partition header
7817c478bd9Sstevel@tonic-gate 	 */
7827c478bd9Sstevel@tonic-gate 	/* LINTED */
7837c478bd9Sstevel@tonic-gate 	php = (struct phdr_desc *)&pp->pd_pc_use;
7847c478bd9Sstevel@tonic-gate 
7857c478bd9Sstevel@tonic-gate 	/*
7867c478bd9Sstevel@tonic-gate 	 * Set up unallocated space bitmap
7877c478bd9Sstevel@tonic-gate 	 */
7887c478bd9Sstevel@tonic-gate 	if (acctype == PART_ACC_RW || acctype == PART_ACC_OW) {
7897c478bd9Sstevel@tonic-gate 		php->phdr_usb.sad_ext_len =
7907c478bd9Sstevel@tonic-gate 			(part_bmp_bytes + SPACEMAP_OFF + sectorsize - 1) &
7917c478bd9Sstevel@tonic-gate 				(~(sectorsize - 1));
7927c478bd9Sstevel@tonic-gate 		php->phdr_usb.sad_ext_loc = nextlogblock;
7937c478bd9Sstevel@tonic-gate 		part_unalloc = nextlogblock;
7947c478bd9Sstevel@tonic-gate 		nextlogblock += part_bmp_sectors;
7957c478bd9Sstevel@tonic-gate 	}
7967c478bd9Sstevel@tonic-gate 
7977c478bd9Sstevel@tonic-gate 	bcopy(&sunmicro, &pp->pd_ii, sizeof (regid_t));
7987c478bd9Sstevel@tonic-gate 	wtvolseq(tp, nextblock, nextblock + volseq_sectors);
7997c478bd9Sstevel@tonic-gate 	nextblock++;
8007c478bd9Sstevel@tonic-gate 
8017c478bd9Sstevel@tonic-gate 	/*
8027c478bd9Sstevel@tonic-gate 	 * Logical Volume Descriptor
8037c478bd9Sstevel@tonic-gate 	 */
8047c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
8057c478bd9Sstevel@tonic-gate 	/* LINTED */
8067c478bd9Sstevel@tonic-gate 	lvp = (struct log_vol_desc *)buf;
8077c478bd9Sstevel@tonic-gate 	tp = &lvp->lvd_tag;
8087c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_LOG_VOL_DESC;
8097c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
8107c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
8117c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct log_vol_desc) -
8127c478bd9Sstevel@tonic-gate 			sizeof (struct tag);
8137c478bd9Sstevel@tonic-gate 	lvp->lvd_vdsn = 0;
8147c478bd9Sstevel@tonic-gate 	setcharspec(&lvp->lvd_desc_cs, 0, osta_unicode);
8157c478bd9Sstevel@tonic-gate 	setdstring(lvp->lvd_lvid, udfs_label, 128);
8167c478bd9Sstevel@tonic-gate 	lvp->lvd_log_bsize = sectorsize;
8177c478bd9Sstevel@tonic-gate 	bcopy(&udf_compliant, &lvp->lvd_dom_id, sizeof (regid_t));
8187c478bd9Sstevel@tonic-gate 	lap = (long_ad_t *)&lvp->lvd_lvcu;
8197c478bd9Sstevel@tonic-gate 	lap->lad_ext_len = FILESETLEN * sectorsize;
8207c478bd9Sstevel@tonic-gate 	filesetblock = nextlogblock;
8217c478bd9Sstevel@tonic-gate 	lap->lad_ext_loc = nextlogblock;
8227c478bd9Sstevel@tonic-gate 	lap->lad_ext_prn = 0;
8237c478bd9Sstevel@tonic-gate 	lvp->lvd_mtbl_len = 6;
8247c478bd9Sstevel@tonic-gate 	lvp->lvd_num_pmaps = 1;
8257c478bd9Sstevel@tonic-gate 	bcopy(&sunmicro, &lvp->lvd_ii, sizeof (regid_t));
8267c478bd9Sstevel@tonic-gate 	/* LINTED */
8277c478bd9Sstevel@tonic-gate 	pmp = (struct pmap_typ1 *)&lvp->lvd_pmaps;
8287c478bd9Sstevel@tonic-gate 	pmp->map1_type = 1;
8297c478bd9Sstevel@tonic-gate 	pmp->map1_length = 6;
8307c478bd9Sstevel@tonic-gate 	pmp->map1_vsn = SWAP_16(1);
8317c478bd9Sstevel@tonic-gate 	pmp->map1_pn  = 0;
8327c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = (char *)(pmp + 1) - buf - sizeof (struct tag);
8337c478bd9Sstevel@tonic-gate 	setextad(&lvp->lvd_int_seq_ext, INTSEQLEN, INTSEQSTART);
8347c478bd9Sstevel@tonic-gate 	wtvolseq(tp, nextblock, nextblock + volseq_sectors);
8357c478bd9Sstevel@tonic-gate 	nextblock++;
8367c478bd9Sstevel@tonic-gate 
8377c478bd9Sstevel@tonic-gate 	/*
8387c478bd9Sstevel@tonic-gate 	 * Unallocated Space Descriptor
8397c478bd9Sstevel@tonic-gate 	 */
8407c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
8417c478bd9Sstevel@tonic-gate 	/* LINTED */
8427c478bd9Sstevel@tonic-gate 	uap = (struct unall_spc_desc *)buf;
8437c478bd9Sstevel@tonic-gate 	tp = &uap->ua_tag;
8447c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_UNALL_SPA_DESC;
8457c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
8467c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
8477c478bd9Sstevel@tonic-gate 	uap->ua_vdsn = 0;
8487c478bd9Sstevel@tonic-gate 	uap->ua_nad = 0;
8497c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = (char *)uap->ua_al_dsc - buf - sizeof (struct tag);
8507c478bd9Sstevel@tonic-gate 	wtvolseq(tp, nextblock, nextblock + volseq_sectors);
8517c478bd9Sstevel@tonic-gate 	nextblock++;
8527c478bd9Sstevel@tonic-gate 
8537c478bd9Sstevel@tonic-gate 	/*
8547c478bd9Sstevel@tonic-gate 	 * Terminating Descriptor
8557c478bd9Sstevel@tonic-gate 	 */
8567c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
8577c478bd9Sstevel@tonic-gate 	/* LINTED */
8587c478bd9Sstevel@tonic-gate 	tdp = (struct term_desc *)buf;
8597c478bd9Sstevel@tonic-gate 	tp = &tdp->td_tag;
8607c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_TERM_DESC;
8617c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
8627c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
8637c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct term_desc) -
8647c478bd9Sstevel@tonic-gate 			sizeof (struct tag);
8657c478bd9Sstevel@tonic-gate 	tp->tag_loc = nextblock;
8667c478bd9Sstevel@tonic-gate 	wtvolseq(tp, nextblock, nextblock + volseq_sectors);
8677c478bd9Sstevel@tonic-gate 	nextblock++;
8687c478bd9Sstevel@tonic-gate 
8697c478bd9Sstevel@tonic-gate 	/*
8707c478bd9Sstevel@tonic-gate 	 * Do the anchor volume descriptor
8717c478bd9Sstevel@tonic-gate 	 */
8727c478bd9Sstevel@tonic-gate 	if (nextblock > FIRSTAVDP) {
8737c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout,
8747c478bd9Sstevel@tonic-gate 			gettext("Volume integrity sequence"
8757c478bd9Sstevel@tonic-gate 			" descriptors too long\n"));
8767c478bd9Sstevel@tonic-gate 		exit(32);
8777c478bd9Sstevel@tonic-gate 	}
8787c478bd9Sstevel@tonic-gate 
8797c478bd9Sstevel@tonic-gate 	nextblock = FIRSTAVDP;
8807c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
8817c478bd9Sstevel@tonic-gate 	/* LINTED */
8827c478bd9Sstevel@tonic-gate 	avp = (struct anch_vol_desc_ptr *)buf;
8837c478bd9Sstevel@tonic-gate 	tp = &avp->avd_tag;
8847c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_ANCH_VOL_DESC;
8857c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
8867c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
8877c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct anch_vol_desc_ptr) -
8887c478bd9Sstevel@tonic-gate 			sizeof (struct tag);
8897c478bd9Sstevel@tonic-gate 	tp->tag_loc = nextblock;
8907c478bd9Sstevel@tonic-gate 	setextad(&avp->avd_main_vdse,
8917c478bd9Sstevel@tonic-gate 			volseq_sectors * sectorsize, mvds_loc);
8927c478bd9Sstevel@tonic-gate 	setextad(&avp->avd_res_vdse,
8937c478bd9Sstevel@tonic-gate 			volseq_sectors * sectorsize, rvds_loc);
8947c478bd9Sstevel@tonic-gate 	bzero(buf2, sectorsize);
8957c478bd9Sstevel@tonic-gate 	/* LINTED */
8967c478bd9Sstevel@tonic-gate 	maketag(tp, (struct tag *)buf2);
8977c478bd9Sstevel@tonic-gate 	wtfs(nextblock, sectorsize, buf2);
8987c478bd9Sstevel@tonic-gate 	nextblock++;
8997c478bd9Sstevel@tonic-gate 
9007c478bd9Sstevel@tonic-gate 	tp->tag_loc = fssize;
9017c478bd9Sstevel@tonic-gate 	/* LINTED */
9027c478bd9Sstevel@tonic-gate 	maketag(tp, (struct tag *)buf2);
9037c478bd9Sstevel@tonic-gate 	wtfs(fssize, sectorsize, buf2);
9047c478bd9Sstevel@tonic-gate 
9057c478bd9Sstevel@tonic-gate 	/*
9067c478bd9Sstevel@tonic-gate 	 * File Set Descriptor
9077c478bd9Sstevel@tonic-gate 	 */
9087c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
9097c478bd9Sstevel@tonic-gate 	/* LINTED */
9107c478bd9Sstevel@tonic-gate 	fsp = (struct file_set_desc *)&buf;
9117c478bd9Sstevel@tonic-gate 	tp = &fsp->fsd_tag;
9127c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_FILE_SET_DESC;
9137c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
9147c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
9157c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct file_set_desc) -
9167c478bd9Sstevel@tonic-gate 			sizeof (struct tag);
9177c478bd9Sstevel@tonic-gate 	tp->tag_loc = nextlogblock;
9187c478bd9Sstevel@tonic-gate 	setstamp(&fsp->fsd_time);
9197c478bd9Sstevel@tonic-gate 	fsp->fsd_ilevel = 3;
9207c478bd9Sstevel@tonic-gate 	fsp->fsd_mi_level = 3;
9217c478bd9Sstevel@tonic-gate 	fsp->fsd_cs_list = 1;
9227c478bd9Sstevel@tonic-gate 	fsp->fsd_mcs_list = 1;
9237c478bd9Sstevel@tonic-gate 	fsp->fsd_fs_no = 0;
9247c478bd9Sstevel@tonic-gate 	fsp->fsd_fsd_no = 0;
9257c478bd9Sstevel@tonic-gate 	setcharspec(&fsp->fsd_lvidcs, 0, osta_unicode);
9267c478bd9Sstevel@tonic-gate 	setdstring(fsp->fsd_lvid, udfs_label, 128);
9277c478bd9Sstevel@tonic-gate 	setcharspec(&fsp->fsd_fscs, 0, osta_unicode);
9287c478bd9Sstevel@tonic-gate 	setdstring(fsp->fsd_fsi, udfs_label, 32);
9297c478bd9Sstevel@tonic-gate 	setdstring(fsp->fsd_cfi, "", 32);
9307c478bd9Sstevel@tonic-gate 	setdstring(fsp->fsd_afi, "", 32);
9317c478bd9Sstevel@tonic-gate 	lap = (long_ad_t *)&fsp->fsd_root_icb;
9327c478bd9Sstevel@tonic-gate 	lap->lad_ext_len = sectorsize;
9337c478bd9Sstevel@tonic-gate 	lap->lad_ext_loc = filesetblock + FILESETLEN;
9347c478bd9Sstevel@tonic-gate 	lap->lad_ext_prn = 0;
9357c478bd9Sstevel@tonic-gate 	bcopy(&udf_compliant, &fsp->fsd_did, sizeof (regid_t));
9367c478bd9Sstevel@tonic-gate 	maketag(tp, tp);
9377c478bd9Sstevel@tonic-gate 	wtfs(nextlogblock + part_start, sectorsize, (char *)tp);
9387c478bd9Sstevel@tonic-gate 	nextlogblock++;
9397c478bd9Sstevel@tonic-gate 
9407c478bd9Sstevel@tonic-gate 	/*
9417c478bd9Sstevel@tonic-gate 	 * Terminating Descriptor
9427c478bd9Sstevel@tonic-gate 	 */
9437c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
9447c478bd9Sstevel@tonic-gate 	/* LINTED */
9457c478bd9Sstevel@tonic-gate 	tdp = (struct term_desc *)buf;
9467c478bd9Sstevel@tonic-gate 	tp = &tdp->td_tag;
9477c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_TERM_DESC;
9487c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
9497c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
9507c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct term_desc) -
9517c478bd9Sstevel@tonic-gate 			sizeof (struct tag);
9527c478bd9Sstevel@tonic-gate 	tp->tag_loc = nextlogblock;
9537c478bd9Sstevel@tonic-gate 	maketag(tp, tp);
9547c478bd9Sstevel@tonic-gate 	wtfs(nextlogblock + part_start, sectorsize, (char *)tp);
9557c478bd9Sstevel@tonic-gate 	nextlogblock++;
9567c478bd9Sstevel@tonic-gate 
9577c478bd9Sstevel@tonic-gate 	if (nextlogblock > filesetblock + FILESETLEN) {
9587c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout,
9597c478bd9Sstevel@tonic-gate 			gettext("File set descriptor too long\n"));
9607c478bd9Sstevel@tonic-gate 		exit(32);
9617c478bd9Sstevel@tonic-gate 	}
9627c478bd9Sstevel@tonic-gate 	nextlogblock = filesetblock + FILESETLEN;
9637c478bd9Sstevel@tonic-gate 
9647c478bd9Sstevel@tonic-gate 	/*
9657c478bd9Sstevel@tonic-gate 	 * Root File Entry
9667c478bd9Sstevel@tonic-gate 	 */
9677c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
9687c478bd9Sstevel@tonic-gate 	/* LINTED */
9697c478bd9Sstevel@tonic-gate 	fp = (struct file_entry *)&buf;
9707c478bd9Sstevel@tonic-gate 	tp = &fp->fe_tag;
9717c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_FILE_ENTRY;
9727c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
9737c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
9747c478bd9Sstevel@tonic-gate 	tp->tag_loc = nextlogblock;
9757c478bd9Sstevel@tonic-gate 	icb = &fp->fe_icb_tag;
9767c478bd9Sstevel@tonic-gate 	icb->itag_prnde = 0;
9777c478bd9Sstevel@tonic-gate 	icb->itag_strategy = STRAT_TYPE4;
9787c478bd9Sstevel@tonic-gate 	icb->itag_param = 0; /* what does this mean? */
9797c478bd9Sstevel@tonic-gate 	icb->itag_max_ent = 1;
9807c478bd9Sstevel@tonic-gate 	icb->itag_ftype = FTYPE_DIRECTORY;
9817c478bd9Sstevel@tonic-gate 	icb->itag_lb_loc = 0;
9827c478bd9Sstevel@tonic-gate 	icb->itag_lb_prn = 0;
9837c478bd9Sstevel@tonic-gate 	icb->itag_flags = ICB_FLAG_ARCHIVE;
9847c478bd9Sstevel@tonic-gate 	fp->fe_uid = getuid();
9857c478bd9Sstevel@tonic-gate 	fp->fe_gid = getgid();
9867c478bd9Sstevel@tonic-gate 	fp->fe_perms = (0x1f << 10) | (0x5 << 5) | 0x5;
9877c478bd9Sstevel@tonic-gate 	fp->fe_lcount = 1;
9887c478bd9Sstevel@tonic-gate 	fp->fe_rec_for = 0;
9897c478bd9Sstevel@tonic-gate 	fp->fe_rec_dis = 0;
9907c478bd9Sstevel@tonic-gate 	fp->fe_rec_len = 0;
9917c478bd9Sstevel@tonic-gate 	fp->fe_info_len = sizeof (struct file_id);
9927c478bd9Sstevel@tonic-gate 	fp->fe_lbr = 1;
9937c478bd9Sstevel@tonic-gate 	setstamp(&fp->fe_acc_time);
9947c478bd9Sstevel@tonic-gate 	setstamp(&fp->fe_mod_time);
9957c478bd9Sstevel@tonic-gate 	setstamp(&fp->fe_attr_time);
9967c478bd9Sstevel@tonic-gate 	fp->fe_ckpoint = 1;
9977c478bd9Sstevel@tonic-gate 	bcopy(&sunmicro, &fp->fe_impl_id, sizeof (regid_t));
9987c478bd9Sstevel@tonic-gate 	fp->fe_uniq_id = 0;
9997c478bd9Sstevel@tonic-gate 	fp->fe_len_ear = 0;
10007c478bd9Sstevel@tonic-gate 	fp->fe_len_adesc = sizeof (short_ad_t);
10017c478bd9Sstevel@tonic-gate 
10027c478bd9Sstevel@tonic-gate 	/* LINTED */
10037c478bd9Sstevel@tonic-gate 	sap = (short_ad_t *)(fp->fe_spec + fp->fe_len_ear);
10047c478bd9Sstevel@tonic-gate 	sap->sad_ext_len = sizeof (struct file_id);
10057c478bd9Sstevel@tonic-gate 	sap->sad_ext_loc = nextlogblock + 1;
10067c478bd9Sstevel@tonic-gate 	rootfelen = (char *)(sap + 1) - buf;
10077c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = rootfelen - sizeof (struct tag);
10087c478bd9Sstevel@tonic-gate 	maketag(tp, tp);
10097c478bd9Sstevel@tonic-gate 	wtfs(nextlogblock + part_start, sectorsize, (char *)tp);
10107c478bd9Sstevel@tonic-gate 	nextlogblock++;
10117c478bd9Sstevel@tonic-gate 
10127c478bd9Sstevel@tonic-gate 	/*
10137c478bd9Sstevel@tonic-gate 	 * Root Directory
10147c478bd9Sstevel@tonic-gate 	 */
10157c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
10167c478bd9Sstevel@tonic-gate 	/* LINTED */
10177c478bd9Sstevel@tonic-gate 	fip = (struct file_id *)&buf;
10187c478bd9Sstevel@tonic-gate 	tp = &fip->fid_tag;
10197c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_FILE_ID_DESC;
10207c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
10217c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
10227c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct file_id) -
10237c478bd9Sstevel@tonic-gate 			sizeof (struct tag);
10247c478bd9Sstevel@tonic-gate 	tp->tag_loc = nextlogblock;
10257c478bd9Sstevel@tonic-gate 	fip->fid_ver = 1;
10267c478bd9Sstevel@tonic-gate 	fip->fid_flags = FID_DIR | FID_PARENT;
10277c478bd9Sstevel@tonic-gate 	fip->fid_idlen = 0;
10287c478bd9Sstevel@tonic-gate 	fip->fid_iulen = 0;
10297c478bd9Sstevel@tonic-gate 	fip->fid_icb.lad_ext_len = sectorsize; /* rootfelen; */
10307c478bd9Sstevel@tonic-gate 	fip->fid_icb.lad_ext_loc = nextlogblock - 1;
10317c478bd9Sstevel@tonic-gate 	fip->fid_icb.lad_ext_prn = 0;
10327c478bd9Sstevel@tonic-gate 	maketag(tp, tp);
10337c478bd9Sstevel@tonic-gate 	wtfs(nextlogblock + part_start, sectorsize, (char *)tp);
10347c478bd9Sstevel@tonic-gate 	nextlogblock++;
10357c478bd9Sstevel@tonic-gate 
10367c478bd9Sstevel@tonic-gate 	/*
10377c478bd9Sstevel@tonic-gate 	 * Now do the space bitmaps
10387c478bd9Sstevel@tonic-gate 	 */
10397c478bd9Sstevel@tonic-gate 	if (part_unalloc >= 0) {
10407c478bd9Sstevel@tonic-gate 		int size = sectorsize * part_bmp_sectors;
10417c478bd9Sstevel@tonic-gate 
10427c478bd9Sstevel@tonic-gate 		sbp = (struct space_bmap_desc *)malloc(size);
10437c478bd9Sstevel@tonic-gate 		if (!sbp) {
10447c478bd9Sstevel@tonic-gate 			(void) fprintf(stdout,
10457c478bd9Sstevel@tonic-gate 				gettext("Can't allocate bitmap space\n"));
10467c478bd9Sstevel@tonic-gate 			exit(32);
10477c478bd9Sstevel@tonic-gate 		}
10487c478bd9Sstevel@tonic-gate 		bzero((char *)sbp, sectorsize * part_bmp_sectors);
10497c478bd9Sstevel@tonic-gate 		tp = &sbp->sbd_tag;
10507c478bd9Sstevel@tonic-gate 		tp->tag_id =  UD_SPA_BMAP_DESC;
10517c478bd9Sstevel@tonic-gate 		tp->tag_desc_ver = ecma_version;
10527c478bd9Sstevel@tonic-gate 		tp->tag_sno = serialnum;
10537c478bd9Sstevel@tonic-gate 		tp->tag_crc_len = 0;	/* Don't do CRCs on bitmaps */
10547c478bd9Sstevel@tonic-gate 		tp->tag_loc = part_unalloc;
10557c478bd9Sstevel@tonic-gate 		sbp->sbd_nbits = part_len;
10567c478bd9Sstevel@tonic-gate 		sbp->sbd_nbytes = part_bmp_bytes;
10577c478bd9Sstevel@tonic-gate 		maketag(tp, tp);
10587c478bd9Sstevel@tonic-gate 		if (part_unalloc >= 0) {
10597c478bd9Sstevel@tonic-gate 			int32_t i;
10607c478bd9Sstevel@tonic-gate 
10617c478bd9Sstevel@tonic-gate 			cp = (uint8_t *)sbp + SPACEMAP_OFF;
10627c478bd9Sstevel@tonic-gate 			i = nextlogblock / NBBY;
10637c478bd9Sstevel@tonic-gate 			cp[i++] = (0xff << (nextlogblock % NBBY)) & 0xff;
10647c478bd9Sstevel@tonic-gate 			while (i < part_bmp_bytes)
10657c478bd9Sstevel@tonic-gate 				cp[i++] = 0xff;
10667c478bd9Sstevel@tonic-gate 			if (part_len % NBBY)
10677c478bd9Sstevel@tonic-gate 				cp[--i] = (unsigned)0xff >>
10687c478bd9Sstevel@tonic-gate 					(NBBY - part_len % NBBY);
10697c478bd9Sstevel@tonic-gate 
10707c478bd9Sstevel@tonic-gate 			wtfs(part_unalloc + part_start, size, (char *)tp);
10717c478bd9Sstevel@tonic-gate 		}
10727c478bd9Sstevel@tonic-gate 		free((char *)sbp);
10737c478bd9Sstevel@tonic-gate 	}
10747c478bd9Sstevel@tonic-gate 
10757c478bd9Sstevel@tonic-gate 	/*
10767c478bd9Sstevel@tonic-gate 	 * Volume Integrity Descriptor
10777c478bd9Sstevel@tonic-gate 	 */
10787c478bd9Sstevel@tonic-gate 	nextblock = INTSEQSTART;
10797c478bd9Sstevel@tonic-gate 	endblock = nextblock + INTSEQLEN / sectorsize;
10807c478bd9Sstevel@tonic-gate 	/* LINTED */
10817c478bd9Sstevel@tonic-gate 	lvip = (struct log_vol_int_desc *)&lvid;
10827c478bd9Sstevel@tonic-gate 	tp = &lvip->lvid_tag;
10837c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_LOG_VOL_INT;
10847c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
10857c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
10867c478bd9Sstevel@tonic-gate 	tp->tag_loc = nextblock;
10877c478bd9Sstevel@tonic-gate 	setstamp(&lvip->lvid_tstamp);
10887c478bd9Sstevel@tonic-gate 	lvip->lvid_int_type = LOG_VOL_CLOSE_INT;
10897c478bd9Sstevel@tonic-gate 	setextad(&lvip->lvid_nie, 0, 0);
10907c478bd9Sstevel@tonic-gate 	lvip->lvid_npart = 1;
10917c478bd9Sstevel@tonic-gate 	lvip->lvid_liu = 0x2e;
10927c478bd9Sstevel@tonic-gate 	lvip->lvid_uniqid = MAXID + 1;
10937c478bd9Sstevel@tonic-gate 	lvip->lvid_fst[0] = part_len - nextlogblock;	/* Free space */
10947c478bd9Sstevel@tonic-gate 	lvip->lvid_fst[1] = part_len;			/* Size */
10957c478bd9Sstevel@tonic-gate 	lviup = (struct lvid_iu *)&lvip->lvid_fst[2];
10967c478bd9Sstevel@tonic-gate 	bcopy(&sunmicro, &lviup->lvidiu_regid, sizeof (regid_t));
10977c478bd9Sstevel@tonic-gate 	lviup->lvidiu_nfiles = 0;
10987c478bd9Sstevel@tonic-gate 	lviup->lvidiu_ndirs = 1;
10997c478bd9Sstevel@tonic-gate 	lviup->lvidiu_mread = 0x102;
11007c478bd9Sstevel@tonic-gate 	lviup->lvidiu_mwrite = 0x102;
11017c478bd9Sstevel@tonic-gate 	lviup->lvidiu_maxwr = 0x150;
11027c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct log_vol_int_desc) + lvip->lvid_liu -
11037c478bd9Sstevel@tonic-gate 		sizeof (struct tag);
11047c478bd9Sstevel@tonic-gate 	maketag(tp, tp);
11057c478bd9Sstevel@tonic-gate 	wtfs(nextblock, sectorsize, (char *)tp);
11067c478bd9Sstevel@tonic-gate 	nextblock++;
11077c478bd9Sstevel@tonic-gate 
11087c478bd9Sstevel@tonic-gate 	/*
11097c478bd9Sstevel@tonic-gate 	 * Terminating Descriptor
11107c478bd9Sstevel@tonic-gate 	 */
11117c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
11127c478bd9Sstevel@tonic-gate 	/* LINTED */
11137c478bd9Sstevel@tonic-gate 	tdp = (struct term_desc *)buf;
11147c478bd9Sstevel@tonic-gate 	tp = &tdp->td_tag;
11157c478bd9Sstevel@tonic-gate 	tp->tag_id =  UD_TERM_DESC;
11167c478bd9Sstevel@tonic-gate 	tp->tag_desc_ver = ecma_version;
11177c478bd9Sstevel@tonic-gate 	tp->tag_sno = serialnum;
11187c478bd9Sstevel@tonic-gate 	tp->tag_crc_len = sizeof (struct term_desc) - sizeof (struct tag);
11197c478bd9Sstevel@tonic-gate 	tp->tag_loc = nextblock;
11207c478bd9Sstevel@tonic-gate 	maketag(tp, tp);
11217c478bd9Sstevel@tonic-gate 	wtfs(nextblock, sectorsize, (char *)tp);
11227c478bd9Sstevel@tonic-gate 	nextblock++;
11237c478bd9Sstevel@tonic-gate 
11247c478bd9Sstevel@tonic-gate 	/* Zero out the rest of the LVI extent */
11257c478bd9Sstevel@tonic-gate 	bzero(buf, sectorsize);
11267c478bd9Sstevel@tonic-gate 	while (nextblock < endblock)
11277c478bd9Sstevel@tonic-gate 		wtfs(nextblock++, sectorsize, buf);
11287c478bd9Sstevel@tonic-gate }
11297c478bd9Sstevel@tonic-gate 
11307c478bd9Sstevel@tonic-gate /*
11317c478bd9Sstevel@tonic-gate  * read a block from the file system
11327c478bd9Sstevel@tonic-gate  */
11337c478bd9Sstevel@tonic-gate static void
11347c478bd9Sstevel@tonic-gate rdfs(daddr_t bno, int size, char *bf)
11357c478bd9Sstevel@tonic-gate {
11367c478bd9Sstevel@tonic-gate 	int n, saverr;
11377c478bd9Sstevel@tonic-gate 
11387c478bd9Sstevel@tonic-gate 	if (llseek(fsi, (offset_t)bno * sectorsize, 0) < 0) {
11397c478bd9Sstevel@tonic-gate 		saverr = errno;
11407c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
11417c478bd9Sstevel@tonic-gate 			gettext("seek error on sector %ld: %s\n"),
11427c478bd9Sstevel@tonic-gate 			bno, strerror(saverr));
11437c478bd9Sstevel@tonic-gate 		exit(32);
11447c478bd9Sstevel@tonic-gate 	}
11457c478bd9Sstevel@tonic-gate 	n = read(fsi, bf, size);
11467c478bd9Sstevel@tonic-gate 	if (n != size) {
11477c478bd9Sstevel@tonic-gate 		saverr = errno;
11487c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
11497c478bd9Sstevel@tonic-gate 			gettext("read error on sector %ld: %s\n"),
11507c478bd9Sstevel@tonic-gate 			bno, strerror(saverr));
11517c478bd9Sstevel@tonic-gate 		exit(32);
11527c478bd9Sstevel@tonic-gate 	}
11537c478bd9Sstevel@tonic-gate }
11547c478bd9Sstevel@tonic-gate 
11557c478bd9Sstevel@tonic-gate /*
11567c478bd9Sstevel@tonic-gate  * write a block to the file system
11577c478bd9Sstevel@tonic-gate  */
11587c478bd9Sstevel@tonic-gate static void
11597c478bd9Sstevel@tonic-gate wtfs(daddr_t bno, int size, char *bf)
11607c478bd9Sstevel@tonic-gate {
11617c478bd9Sstevel@tonic-gate 	int n, saverr;
11627c478bd9Sstevel@tonic-gate 
11637c478bd9Sstevel@tonic-gate 	if (fso == -1)
11647c478bd9Sstevel@tonic-gate 		return;
11657c478bd9Sstevel@tonic-gate 
11667c478bd9Sstevel@tonic-gate 	if (llseek(fso, (offset_t)bno * sectorsize, 0) < 0) {
11677c478bd9Sstevel@tonic-gate 		saverr = errno;
11687c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
11697c478bd9Sstevel@tonic-gate 			gettext("seek error on sector %ld: %s\n"),
11707c478bd9Sstevel@tonic-gate 			bno, strerror(saverr));
11717c478bd9Sstevel@tonic-gate 		exit(32);
11727c478bd9Sstevel@tonic-gate 	}
11737c478bd9Sstevel@tonic-gate 	if (Nflag)
11747c478bd9Sstevel@tonic-gate 		return;
11757c478bd9Sstevel@tonic-gate 	n = write(fso, bf, size);
11767c478bd9Sstevel@tonic-gate 	if (n != size) {
11777c478bd9Sstevel@tonic-gate 		saverr = errno;
11787c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
11797c478bd9Sstevel@tonic-gate 			gettext("write error on sector %ld: %s\n"),
11807c478bd9Sstevel@tonic-gate 			bno, strerror(saverr));
11817c478bd9Sstevel@tonic-gate 		exit(32);
11827c478bd9Sstevel@tonic-gate 	}
11837c478bd9Sstevel@tonic-gate }
11847c478bd9Sstevel@tonic-gate 
11857c478bd9Sstevel@tonic-gate static void
11867c478bd9Sstevel@tonic-gate usage()
11877c478bd9Sstevel@tonic-gate {
11887c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
11897c478bd9Sstevel@tonic-gate 		gettext("udfs usage: mkfs [-F FSType] [-V]"
11907c478bd9Sstevel@tonic-gate 		" [-m] [-o options] special size(sectors)\n"));
11917c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
11927c478bd9Sstevel@tonic-gate 		gettext(" -m : dump fs cmd line used to make"
11937c478bd9Sstevel@tonic-gate 		" this partition\n"));
11947c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
11957c478bd9Sstevel@tonic-gate 		gettext(" -V : print this command line and return\n"));
11967c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
11977c478bd9Sstevel@tonic-gate 		gettext(" -o : udfs options: :psize=%d:label=%s\n"),
11987c478bd9Sstevel@tonic-gate 		sectorsize, udfs_label);
11997c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
12007c478bd9Sstevel@tonic-gate 		gettext("NOTE that all -o suboptions: must"
12017c478bd9Sstevel@tonic-gate 		" be separated only by commas so as to\n"));
12027c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
12037c478bd9Sstevel@tonic-gate 		gettext("be parsed as a single argument\n"));
12047c478bd9Sstevel@tonic-gate 	exit(32);
12057c478bd9Sstevel@tonic-gate }
12067c478bd9Sstevel@tonic-gate 
12077c478bd9Sstevel@tonic-gate /*ARGSUSED*/
12087c478bd9Sstevel@tonic-gate static void
12097c478bd9Sstevel@tonic-gate dump_fscmd(char *fsys, int fsi)
12107c478bd9Sstevel@tonic-gate {
12117c478bd9Sstevel@tonic-gate 	(void) printf(gettext("mkfs -F udfs -o "));
12127c478bd9Sstevel@tonic-gate 	(void) printf("psize=%d,label=\"%s\" %s %d\n",
12137c478bd9Sstevel@tonic-gate 		sectorsize, oldlabel, fsys, oldfssize);
12147c478bd9Sstevel@tonic-gate }
12157c478bd9Sstevel@tonic-gate 
12167c478bd9Sstevel@tonic-gate /* number ************************************************************* */
12177c478bd9Sstevel@tonic-gate /*									*/
12187c478bd9Sstevel@tonic-gate /* Convert a numeric arg to binary					*/
12197c478bd9Sstevel@tonic-gate /*									*/
12207c478bd9Sstevel@tonic-gate /* Arg:	 big - maximum valid input number				*/
12217c478bd9Sstevel@tonic-gate /* Global arg:  string - pointer to command arg				*/
12227c478bd9Sstevel@tonic-gate /*									*/
12237c478bd9Sstevel@tonic-gate /* Valid forms: 123 | 123k | 123*123 | 123x123				*/
12247c478bd9Sstevel@tonic-gate /*									*/
12257c478bd9Sstevel@tonic-gate /* Return:	converted number					*/
12267c478bd9Sstevel@tonic-gate /*									*/
12277c478bd9Sstevel@tonic-gate /* ******************************************************************** */
12287c478bd9Sstevel@tonic-gate 
12297c478bd9Sstevel@tonic-gate static int32_t
12307c478bd9Sstevel@tonic-gate number(long big, char *param)
12317c478bd9Sstevel@tonic-gate {
12327c478bd9Sstevel@tonic-gate 	char		*cs;
12337c478bd9Sstevel@tonic-gate 	int64_t		n = 0;
12347c478bd9Sstevel@tonic-gate 	int64_t		cut = BIG;
12357c478bd9Sstevel@tonic-gate 	int32_t		minus = 0;
12367c478bd9Sstevel@tonic-gate 
12377c478bd9Sstevel@tonic-gate #define	FOUND_MULT	0x1
12387c478bd9Sstevel@tonic-gate #define	FOUND_K		0x2
12397c478bd9Sstevel@tonic-gate 
12407c478bd9Sstevel@tonic-gate 	cs = string;
12417c478bd9Sstevel@tonic-gate 	if (*cs == '-') {
12427c478bd9Sstevel@tonic-gate 		minus = 1;
12437c478bd9Sstevel@tonic-gate 		cs++;
12447c478bd9Sstevel@tonic-gate 	}
12457c478bd9Sstevel@tonic-gate 	n = 0;
12467c478bd9Sstevel@tonic-gate 	while ((*cs != ' ') && (*cs != '\0') && (*cs != ',')) {
12477c478bd9Sstevel@tonic-gate 		if ((*cs >= '0') && (*cs <= '9')) {
12487c478bd9Sstevel@tonic-gate 			n = n * 10 + *cs - '0';
12497c478bd9Sstevel@tonic-gate 			cs++;
12507c478bd9Sstevel@tonic-gate 		} else if ((*cs == '*') || (*cs == 'x')) {
12517c478bd9Sstevel@tonic-gate 			if (number_flags & FOUND_MULT) {
12527c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
12537c478bd9Sstevel@tonic-gate 				gettext("mkfs: only one \"*\" "
12547c478bd9Sstevel@tonic-gate 				"or \"x\" allowed\n"));
12557c478bd9Sstevel@tonic-gate 				exit(2);
12567c478bd9Sstevel@tonic-gate 			}
12577c478bd9Sstevel@tonic-gate 			number_flags |= FOUND_MULT;
12587c478bd9Sstevel@tonic-gate 			cs++;
12597c478bd9Sstevel@tonic-gate 			string = cs;
12607c478bd9Sstevel@tonic-gate 			n = n * number(big, param);
12617c478bd9Sstevel@tonic-gate 			cs = string;
12627c478bd9Sstevel@tonic-gate 			continue;
12637c478bd9Sstevel@tonic-gate 		} else if (*cs == 'k') {
12647c478bd9Sstevel@tonic-gate 			if (number_flags & FOUND_K) {
12657c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
12667c478bd9Sstevel@tonic-gate 				gettext("mkfs: only one \"k\" allowed\n"));
12677c478bd9Sstevel@tonic-gate 				exit(2);
12687c478bd9Sstevel@tonic-gate 			}
12697c478bd9Sstevel@tonic-gate 			number_flags |= FOUND_K;
12707c478bd9Sstevel@tonic-gate 			n = n * 1024;
12717c478bd9Sstevel@tonic-gate 			cs++;
12727c478bd9Sstevel@tonic-gate 			continue;
12737c478bd9Sstevel@tonic-gate 		} else {
12747c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
12757c478bd9Sstevel@tonic-gate 				gettext("mkfs: bad numeric arg: \"%s\"\n"),
12767c478bd9Sstevel@tonic-gate 				string);
12777c478bd9Sstevel@tonic-gate 			exit(2);
12787c478bd9Sstevel@tonic-gate 		}
12797c478bd9Sstevel@tonic-gate 	}
12807c478bd9Sstevel@tonic-gate 
12817c478bd9Sstevel@tonic-gate 	if (n > cut) {
12827c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
12837c478bd9Sstevel@tonic-gate 			gettext("mkfs: value for %s overflowed\n"), param);
12847c478bd9Sstevel@tonic-gate 		exit(2);
12857c478bd9Sstevel@tonic-gate 	}
12867c478bd9Sstevel@tonic-gate 
12877c478bd9Sstevel@tonic-gate 	if (minus) {
12887c478bd9Sstevel@tonic-gate 		n = -n;
12897c478bd9Sstevel@tonic-gate 	}
12907c478bd9Sstevel@tonic-gate 
12917c478bd9Sstevel@tonic-gate 	if ((n > big) || (n < 0)) {
12927c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
12937c478bd9Sstevel@tonic-gate 			gettext("mkfs: argument %s out of range\n"), param);
12947c478bd9Sstevel@tonic-gate 		exit(2);
12957c478bd9Sstevel@tonic-gate 	}
12967c478bd9Sstevel@tonic-gate 
12977c478bd9Sstevel@tonic-gate 	string = cs;
12987c478bd9Sstevel@tonic-gate 	return ((int32_t)n);
12997c478bd9Sstevel@tonic-gate }
13007c478bd9Sstevel@tonic-gate 
13017c478bd9Sstevel@tonic-gate /* match ************************************************************** */
13027c478bd9Sstevel@tonic-gate /*									*/
13037c478bd9Sstevel@tonic-gate /* Compare two text strings for equality				*/
13047c478bd9Sstevel@tonic-gate /*									*/
13057c478bd9Sstevel@tonic-gate /* Arg:	 s - pointer to string to match with a command arg		*/
13067c478bd9Sstevel@tonic-gate /* Global arg:  string - pointer to command arg				*/
13077c478bd9Sstevel@tonic-gate /*									*/
13087c478bd9Sstevel@tonic-gate /* Return:	1 if match, 0 if no match				*/
13097c478bd9Sstevel@tonic-gate /*		If match, also reset `string' to point to the text	*/
13107c478bd9Sstevel@tonic-gate /*		that follows the matching text.				*/
13117c478bd9Sstevel@tonic-gate /*									*/
13127c478bd9Sstevel@tonic-gate /* ******************************************************************** */
13137c478bd9Sstevel@tonic-gate 
13147c478bd9Sstevel@tonic-gate static int
13157c478bd9Sstevel@tonic-gate match(char *s)
13167c478bd9Sstevel@tonic-gate {
13177c478bd9Sstevel@tonic-gate 	char *cs;
13187c478bd9Sstevel@tonic-gate 
13197c478bd9Sstevel@tonic-gate 	cs = string;
13207c478bd9Sstevel@tonic-gate 	while (*cs++ == *s) {
13217c478bd9Sstevel@tonic-gate 		if (*s++ == '\0') {
13227c478bd9Sstevel@tonic-gate 			goto true;
13237c478bd9Sstevel@tonic-gate 		}
13247c478bd9Sstevel@tonic-gate 	}
13257c478bd9Sstevel@tonic-gate 	if (*s != '\0') {
13267c478bd9Sstevel@tonic-gate 		return (0);
13277c478bd9Sstevel@tonic-gate 	}
13287c478bd9Sstevel@tonic-gate 
13297c478bd9Sstevel@tonic-gate true:
13307c478bd9Sstevel@tonic-gate 	cs--;
13317c478bd9Sstevel@tonic-gate 	string = cs;
13327c478bd9Sstevel@tonic-gate 	return (1);
13337c478bd9Sstevel@tonic-gate }
13347c478bd9Sstevel@tonic-gate 
13357c478bd9Sstevel@tonic-gate static uint32_t
13367c478bd9Sstevel@tonic-gate get_bsize()
13377c478bd9Sstevel@tonic-gate {
13387c478bd9Sstevel@tonic-gate 	struct dk_cinfo info;
13397c478bd9Sstevel@tonic-gate 	struct fd_char fd_char;
13407c478bd9Sstevel@tonic-gate 
13417c478bd9Sstevel@tonic-gate 	if (ioctl(fso, DKIOCINFO, &info) < 0) {
13427c478bd9Sstevel@tonic-gate 		perror("mkfs DKIOCINFO ");
13437c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout,
13447c478bd9Sstevel@tonic-gate 			gettext("DKIOCINFO failed using psize = 2048"
13457c478bd9Sstevel@tonic-gate 			" for creating file-system\n"));
13467c478bd9Sstevel@tonic-gate 		return (0);
13477c478bd9Sstevel@tonic-gate 	}
13487c478bd9Sstevel@tonic-gate 
13497c478bd9Sstevel@tonic-gate 	switch (info.dki_ctype) {
13507c478bd9Sstevel@tonic-gate 		case DKC_CDROM :
13517c478bd9Sstevel@tonic-gate 			return (2048);
13527c478bd9Sstevel@tonic-gate 		case DKC_SCSI_CCS :
13537c478bd9Sstevel@tonic-gate 			/* FALLTHROUGH */
13547c478bd9Sstevel@tonic-gate 		case DKC_INTEL82072 :
13557c478bd9Sstevel@tonic-gate 			/* FALLTHROUGH */
13567c478bd9Sstevel@tonic-gate 		case DKC_INTEL82077 :
13577c478bd9Sstevel@tonic-gate 			/* FALLTHROUGH */
13587c478bd9Sstevel@tonic-gate 		case DKC_DIRECT :
13597c478bd9Sstevel@tonic-gate 			if (ioctl(fso, FDIOGCHAR, &fd_char) >= 0) {
13607c478bd9Sstevel@tonic-gate 				return (fd_char.fdc_sec_size);
13617c478bd9Sstevel@tonic-gate 			}
13627c478bd9Sstevel@tonic-gate 			/* FALLTHROUGH */
13637c478bd9Sstevel@tonic-gate 		case DKC_PCMCIA_ATA :
13647c478bd9Sstevel@tonic-gate 			return (512);
13657c478bd9Sstevel@tonic-gate 		default :
13667c478bd9Sstevel@tonic-gate 			return (0);
13677c478bd9Sstevel@tonic-gate 	}
13687c478bd9Sstevel@tonic-gate }
13697c478bd9Sstevel@tonic-gate 
13707c478bd9Sstevel@tonic-gate /*
13717c478bd9Sstevel@tonic-gate  * Read in the volume sequences descriptors.
13727c478bd9Sstevel@tonic-gate  */
13737c478bd9Sstevel@tonic-gate static int
13747c478bd9Sstevel@tonic-gate readvolseq()
13757c478bd9Sstevel@tonic-gate {
13767c478bd9Sstevel@tonic-gate 	struct tag *tp;
13777c478bd9Sstevel@tonic-gate 	uint8_t *cp, *end;
13787c478bd9Sstevel@tonic-gate 	int err;
13797c478bd9Sstevel@tonic-gate 	struct pri_vol_desc *pvolp;
13807c478bd9Sstevel@tonic-gate 	struct part_desc *partp;
13817c478bd9Sstevel@tonic-gate 	struct log_vol_desc *logvp;
13827c478bd9Sstevel@tonic-gate 	struct anch_vol_desc_ptr *avp;
13837c478bd9Sstevel@tonic-gate 	char *main_vdbuf;
13847c478bd9Sstevel@tonic-gate 	uint32_t nextblock;
13857c478bd9Sstevel@tonic-gate 
13867c478bd9Sstevel@tonic-gate 	avp = (struct anch_vol_desc_ptr *)malloc(sectorsize);
13877c478bd9Sstevel@tonic-gate 	rdfs(FIRSTAVDP, sectorsize, (char *)avp);
13887c478bd9Sstevel@tonic-gate 	tp = (struct tag *)avp;
13897c478bd9Sstevel@tonic-gate 	err = verifytag(tp, FIRSTAVDP, tp, UD_ANCH_VOL_DESC);
13907c478bd9Sstevel@tonic-gate 	if (err)
13917c478bd9Sstevel@tonic-gate 		return (0);
13927c478bd9Sstevel@tonic-gate 	main_vdbuf = malloc(avp->avd_main_vdse.ext_len);
13937c478bd9Sstevel@tonic-gate 	if (main_vdbuf == NULL) {
13947c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("Cannot allocate space for "
13957c478bd9Sstevel@tonic-gate 			"volume sequences\n"));
13967c478bd9Sstevel@tonic-gate 		exit(32);
13977c478bd9Sstevel@tonic-gate 	}
13987c478bd9Sstevel@tonic-gate 	rdfs(avp->avd_main_vdse.ext_loc, avp->avd_main_vdse.ext_len,
13997c478bd9Sstevel@tonic-gate 		main_vdbuf);
14007c478bd9Sstevel@tonic-gate 	end = (uint8_t *)main_vdbuf + avp->avd_main_vdse.ext_len;
14017c478bd9Sstevel@tonic-gate 
14027c478bd9Sstevel@tonic-gate 	nextblock = avp->avd_main_vdse.ext_loc;
14037c478bd9Sstevel@tonic-gate 	for (cp = (uint8_t *)main_vdbuf; cp < end; cp += sectorsize,
14047c478bd9Sstevel@tonic-gate 		nextblock++) {
14057c478bd9Sstevel@tonic-gate 		/* LINTED */
14067c478bd9Sstevel@tonic-gate 		tp = (struct tag *)cp;
14077c478bd9Sstevel@tonic-gate 		err = verifytag(tp, nextblock, tp, 0);
14087c478bd9Sstevel@tonic-gate 		if (err)
14097c478bd9Sstevel@tonic-gate 			continue;
14107c478bd9Sstevel@tonic-gate 
14117c478bd9Sstevel@tonic-gate 		switch (tp->tag_id) {
14127c478bd9Sstevel@tonic-gate 		case UD_PRI_VOL_DESC:
14137c478bd9Sstevel@tonic-gate 			/* Bump serial number, according to spec. */
14147c478bd9Sstevel@tonic-gate 			serialnum = tp->tag_sno + 1;
14157c478bd9Sstevel@tonic-gate 			pvolp = (struct pri_vol_desc *)tp;
14167c478bd9Sstevel@tonic-gate 			oldlabel = pvolp->pvd_vol_id + 1;
14177c478bd9Sstevel@tonic-gate 			break;
14187c478bd9Sstevel@tonic-gate 		case UD_ANCH_VOL_DESC:
14197c478bd9Sstevel@tonic-gate 			avp = (struct anch_vol_desc_ptr *)tp;
14207c478bd9Sstevel@tonic-gate 			break;
14217c478bd9Sstevel@tonic-gate 		case UD_VOL_DESC_PTR:
14227c478bd9Sstevel@tonic-gate 			break;
14237c478bd9Sstevel@tonic-gate 		case UD_IMPL_USE_DESC:
14247c478bd9Sstevel@tonic-gate 			break;
14257c478bd9Sstevel@tonic-gate 		case UD_PART_DESC:
14267c478bd9Sstevel@tonic-gate 			partp = (struct part_desc *)tp;
14277c478bd9Sstevel@tonic-gate 			part_start = partp->pd_part_start;
14287c478bd9Sstevel@tonic-gate 			part_len = partp->pd_part_length;
14297c478bd9Sstevel@tonic-gate 			oldfssize = part_start + part_len;
14307c478bd9Sstevel@tonic-gate 			break;
14317c478bd9Sstevel@tonic-gate 		case UD_LOG_VOL_DESC:
14327c478bd9Sstevel@tonic-gate 			logvp = (struct log_vol_desc *)tp;
14337c478bd9Sstevel@tonic-gate 			break;
14347c478bd9Sstevel@tonic-gate 		case UD_UNALL_SPA_DESC:
14357c478bd9Sstevel@tonic-gate 			break;
14367c478bd9Sstevel@tonic-gate 		case UD_TERM_DESC:
14377c478bd9Sstevel@tonic-gate 			goto done;
14387c478bd9Sstevel@tonic-gate 			break;
14397c478bd9Sstevel@tonic-gate 		case UD_LOG_VOL_INT:
14407c478bd9Sstevel@tonic-gate 			break;
14417c478bd9Sstevel@tonic-gate 		default:
14427c478bd9Sstevel@tonic-gate 			break;
14437c478bd9Sstevel@tonic-gate 		}
14447c478bd9Sstevel@tonic-gate 	}
14457c478bd9Sstevel@tonic-gate done:
14467c478bd9Sstevel@tonic-gate 	if (!partp || !logvp) {
14477c478bd9Sstevel@tonic-gate 		return (0);
14487c478bd9Sstevel@tonic-gate 	}
14497c478bd9Sstevel@tonic-gate 	return (1);
14507c478bd9Sstevel@tonic-gate }
14517c478bd9Sstevel@tonic-gate 
14527c478bd9Sstevel@tonic-gate uint32_t
14537c478bd9Sstevel@tonic-gate get_last_block()
14547c478bd9Sstevel@tonic-gate {
14557c478bd9Sstevel@tonic-gate 	struct vtoc vtoc;
14567c478bd9Sstevel@tonic-gate 	struct dk_cinfo dki_info;
14577c478bd9Sstevel@tonic-gate 
14587c478bd9Sstevel@tonic-gate 	if (ioctl(fsi, DKIOCGVTOC, (intptr_t)&vtoc) != 0) {
14597c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("Unable to read VTOC\n"));
14607c478bd9Sstevel@tonic-gate 		return (0);
14617c478bd9Sstevel@tonic-gate 	}
14627c478bd9Sstevel@tonic-gate 
14637c478bd9Sstevel@tonic-gate 	if (vtoc.v_sanity != VTOC_SANE) {
14647c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("Vtoc.v_sanity != VTOC_SANE\n"));
14657c478bd9Sstevel@tonic-gate 		return (0);
14667c478bd9Sstevel@tonic-gate 	}
14677c478bd9Sstevel@tonic-gate 
14687c478bd9Sstevel@tonic-gate 	if (ioctl(fsi, DKIOCINFO, (intptr_t)&dki_info) != 0) {
14697c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
14707c478bd9Sstevel@tonic-gate 		    gettext("Could not get the slice information\n"));
14717c478bd9Sstevel@tonic-gate 		return (0);
14727c478bd9Sstevel@tonic-gate 	}
14737c478bd9Sstevel@tonic-gate 
14747c478bd9Sstevel@tonic-gate 	if (dki_info.dki_partition > V_NUMPAR) {
14757c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
14767c478bd9Sstevel@tonic-gate 		    gettext("dki_info.dki_partition > V_NUMPAR\n"));
14777c478bd9Sstevel@tonic-gate 		return (0);
14787c478bd9Sstevel@tonic-gate 	}
14797c478bd9Sstevel@tonic-gate 
14807c478bd9Sstevel@tonic-gate 	return ((uint32_t)vtoc.v_part[dki_info.dki_partition].p_size);
14817c478bd9Sstevel@tonic-gate }
1482