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 569ed0c8eSGarrett D'Amore * Common Development and Distribution License (the "License"). 669ed0c8eSGarrett D'Amore * 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 /* 2269ed0c8eSGarrett D'Amore * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /* 277c478bd9Sstevel@tonic-gate * fdformat program - formats floppy disks, and then adds a label to them 287c478bd9Sstevel@tonic-gate * 297c478bd9Sstevel@tonic-gate * ****Warning, Warning, Warning, Warning***** 307c478bd9Sstevel@tonic-gate * This program runs suid root. This change was made to 317c478bd9Sstevel@tonic-gate * allow it to umount a file system if it's mounted. 327c478bd9Sstevel@tonic-gate */ 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate #include <stdio.h> 357c478bd9Sstevel@tonic-gate #include <fcntl.h> 367c478bd9Sstevel@tonic-gate #include <stdlib.h> 377c478bd9Sstevel@tonic-gate #include <unistd.h> 387c478bd9Sstevel@tonic-gate #include <string.h> 397c478bd9Sstevel@tonic-gate #include <memory.h> 407c478bd9Sstevel@tonic-gate #include <errno.h> 417c478bd9Sstevel@tonic-gate #include <locale.h> 427c478bd9Sstevel@tonic-gate #include <libintl.h> 437c478bd9Sstevel@tonic-gate #include <volmgt.h> 447c478bd9Sstevel@tonic-gate #include <sys/isa_defs.h> 457c478bd9Sstevel@tonic-gate #include <sys/ioccom.h> 467c478bd9Sstevel@tonic-gate #include <sys/types.h> 477c478bd9Sstevel@tonic-gate #include <sys/time.h> 487c478bd9Sstevel@tonic-gate #include <sys/file.h> 497c478bd9Sstevel@tonic-gate #include <sys/dklabel.h> 507c478bd9Sstevel@tonic-gate #include <sys/ioctl.h> 517c478bd9Sstevel@tonic-gate #include <sys/dkio.h> 527c478bd9Sstevel@tonic-gate #include <sys/fdio.h> 537c478bd9Sstevel@tonic-gate #include <sys/stat.h> 547c478bd9Sstevel@tonic-gate #include <sys/vtoc.h> 557c478bd9Sstevel@tonic-gate #include <sys/mnttab.h> 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate /* DEFINES */ 587c478bd9Sstevel@tonic-gate #if defined(_BIG_ENDIAN) 597c478bd9Sstevel@tonic-gate #define getbyte(A, N) (((unsigned char *)(&(A)))[N]) 607c478bd9Sstevel@tonic-gate #define htols(S) ((getbyte(S, 1) <<8) | getbyte(S, 0)) 617c478bd9Sstevel@tonic-gate #elif defined(_LITTLE_ENDIAN) 627c478bd9Sstevel@tonic-gate #define htols(S) (*((ushort_t *)(&(S)))) 637c478bd9Sstevel@tonic-gate #else 647c478bd9Sstevel@tonic-gate #error One of _BIG_ENDIAN or LITTLE_ENDIAN must be defined 657c478bd9Sstevel@tonic-gate #endif 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate #define getlobyte(A) (A & 0xFF) 687c478bd9Sstevel@tonic-gate #define gethibyte(A) (A >> 8 & 0xFF) 697c478bd9Sstevel@tonic-gate #define uppercase(c) ((c) >= 'a' && (c) <= 'z' ? (c) - 'a' + 'A' : (c)) 707c478bd9Sstevel@tonic-gate #define min(a, b) ((a) < (b) ? (a) : (b)) 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate /* FORMAT PATTERNS */ 737c478bd9Sstevel@tonic-gate #define PATTERN_1 0x55; 747c478bd9Sstevel@tonic-gate #define PATTERN_2 0xaa; 757c478bd9Sstevel@tonic-gate #define PATTERN_3 0xff; 767c478bd9Sstevel@tonic-gate #define PATTERN_4 0x00; 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate /* UNINITIALIZED DATA */ 797c478bd9Sstevel@tonic-gate static struct fd_char fdchar; 807c478bd9Sstevel@tonic-gate static struct dk_geom fdgeom; 817c478bd9Sstevel@tonic-gate static struct dk_allmap allmap; 827c478bd9Sstevel@tonic-gate static struct dk_cinfo dkinfo; 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate /* EXTERN */ 857c478bd9Sstevel@tonic-gate extern char *optarg; 867c478bd9Sstevel@tonic-gate extern int optind; 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate /* for verify buffers */ 897c478bd9Sstevel@tonic-gate static uchar_t *ibuf1; 907c478bd9Sstevel@tonic-gate static uchar_t *obuf; 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate static char *myname; 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate static int fd_debug = 1; /* 1 if debug XXX */ 957c478bd9Sstevel@tonic-gate static int b_flag = 0; /* install a volume label to the diskette */ 967c478bd9Sstevel@tonic-gate static int d_flag = 0; /* format the diskette in dos format */ 977c478bd9Sstevel@tonic-gate static int D_flag = 0; /* double (aka low) density flag */ 987c478bd9Sstevel@tonic-gate static int e_flag = 0; /* "eject" diskette when done (if supported) */ 997c478bd9Sstevel@tonic-gate static int E_flag = 0; /* extended density */ 1007c478bd9Sstevel@tonic-gate static int f_flag = 0; /* "force" (no confirmation before start) */ 1017c478bd9Sstevel@tonic-gate static int H_flag = 0; /* high density */ 1027c478bd9Sstevel@tonic-gate static int m_flag = 0; /* medium density */ 1037c478bd9Sstevel@tonic-gate static int n_flag = 0; /* format the diskette in NEC-DOS format */ 1047c478bd9Sstevel@tonic-gate static int q_flag = 0; /* quiet format flag */ 1057c478bd9Sstevel@tonic-gate static int U_flag = 0; /* automatically unmount if it's mounted */ 1067c478bd9Sstevel@tonic-gate static int v_flag = 0; /* verify format/diskette flag */ 1077c478bd9Sstevel@tonic-gate static int x_flag = 0; /* skip the format, only install SunOS label */ 1087c478bd9Sstevel@tonic-gate /* or DOS file system */ 1097c478bd9Sstevel@tonic-gate static int z_flag = 0; /* debugging only, setting partial formatting */ 1107c478bd9Sstevel@tonic-gate static int interleave = 1; /* interleave factor */ 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gate static uid_t euid = 0; /* stores effective user id */ 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate struct bios_param_blk { 1157c478bd9Sstevel@tonic-gate uchar_t b_bps[2]; /* bytes per sector */ 1167c478bd9Sstevel@tonic-gate uchar_t b_spcl; /* sectors per alloction unit */ 1177c478bd9Sstevel@tonic-gate uchar_t b_res_sec[2]; /* reserved sectors, starting at 0 */ 1187c478bd9Sstevel@tonic-gate uchar_t b_nfat; /* number of FATs */ 1197c478bd9Sstevel@tonic-gate uchar_t b_rdirents[2]; /* number of root directory entries */ 1207c478bd9Sstevel@tonic-gate uchar_t b_totalsec[2]; /* total sectors in logical image */ 1217c478bd9Sstevel@tonic-gate char b_mediadescriptor; /* media descriptor byte */ 1227c478bd9Sstevel@tonic-gate uchar_t b_fatsec[2]; /* number of sectors per FAT */ 1237c478bd9Sstevel@tonic-gate uchar_t b_spt[2]; /* sectors per track */ 1247c478bd9Sstevel@tonic-gate uchar_t b_nhead[2]; /* number of heads */ 1257c478bd9Sstevel@tonic-gate uchar_t b_hiddensec[2]; /* number of hidden sectors */ 1267c478bd9Sstevel@tonic-gate }; 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate /* 1297c478bd9Sstevel@tonic-gate * ON-private functions from libvolmgt 1307c478bd9Sstevel@tonic-gate */ 1317c478bd9Sstevel@tonic-gate char *_media_oldaliases(char *name); 1327c478bd9Sstevel@tonic-gate int _dev_mounted(char *path); 1337c478bd9Sstevel@tonic-gate int _dev_unmount(char *path); 1347c478bd9Sstevel@tonic-gate 1357c478bd9Sstevel@tonic-gate /* 1367c478bd9Sstevel@tonic-gate * local functions 1377c478bd9Sstevel@tonic-gate */ 1387c478bd9Sstevel@tonic-gate static void usage(char *); 1397c478bd9Sstevel@tonic-gate static int verify(int, int, int); 1407c478bd9Sstevel@tonic-gate static void write_SunOS_label(int, char *, struct vtoc *); 1417c478bd9Sstevel@tonic-gate static int valid_DOS_boot(char *, uchar_t **); 1427c478bd9Sstevel@tonic-gate static void write_DOS_label(int, uchar_t *, int, char *, char *, 1437c478bd9Sstevel@tonic-gate struct bios_param_blk *, int); 1447c478bd9Sstevel@tonic-gate static void write_NEC_DOS_label(int, char *); 1457c478bd9Sstevel@tonic-gate static int check_mount(); 1467c478bd9Sstevel@tonic-gate static void format_diskette(int, char *, struct vtoc *, 1477c478bd9Sstevel@tonic-gate struct bios_param_blk *, int *); 1487c478bd9Sstevel@tonic-gate static void restore_default_chars(int fd, 1497c478bd9Sstevel@tonic-gate struct fd_char save_fdchar, 1507c478bd9Sstevel@tonic-gate struct dk_allmap save_allmap); 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate int 1537c478bd9Sstevel@tonic-gate main(int argc, char **argv) 1547c478bd9Sstevel@tonic-gate { 1557c478bd9Sstevel@tonic-gate int altsize = 0; 1567c478bd9Sstevel@tonic-gate int fd; 1577c478bd9Sstevel@tonic-gate int i; 1587c478bd9Sstevel@tonic-gate uchar_t *altboot = NULL; 1597c478bd9Sstevel@tonic-gate char *altbootname = NULL; 1607c478bd9Sstevel@tonic-gate char *dev_name = NULL, *real_name, *alias_name; 1617c478bd9Sstevel@tonic-gate char *vollabel = ""; 1627c478bd9Sstevel@tonic-gate struct vtoc fd_vtoc; 1637c478bd9Sstevel@tonic-gate struct bios_param_blk bpb; 1647c478bd9Sstevel@tonic-gate int rdirsec; 1657c478bd9Sstevel@tonic-gate char *nullstring = ""; 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 1707c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 1717c478bd9Sstevel@tonic-gate #endif 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate myname = argv[0]; 1767c478bd9Sstevel@tonic-gate while ((i = getopt(argc, argv, "B:b:dDeEfhHlLmMxqt:UvVZ?")) != -1) { 1777c478bd9Sstevel@tonic-gate switch (i) { 1787c478bd9Sstevel@tonic-gate 1797c478bd9Sstevel@tonic-gate case 'B': 1807c478bd9Sstevel@tonic-gate altbootname = strdup(optarg); 1817c478bd9Sstevel@tonic-gate d_flag++; 1827c478bd9Sstevel@tonic-gate /* check for valid boot file now */ 1837c478bd9Sstevel@tonic-gate altsize = valid_DOS_boot(altbootname, &altboot); 1847c478bd9Sstevel@tonic-gate if (!altsize) { 1857c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1867c478bd9Sstevel@tonic-gate "%s: invalid boot loader\n"), myname); 1877c478bd9Sstevel@tonic-gate exit(1); 1887c478bd9Sstevel@tonic-gate } 1897c478bd9Sstevel@tonic-gate break; 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate case 'b': 1927c478bd9Sstevel@tonic-gate b_flag++; 1937c478bd9Sstevel@tonic-gate vollabel = strdup(optarg); 1947c478bd9Sstevel@tonic-gate break; 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate case 'd': 1977c478bd9Sstevel@tonic-gate /* format a MS-DOS diskette */ 1987c478bd9Sstevel@tonic-gate d_flag++; 1997c478bd9Sstevel@tonic-gate break; 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate case 'D': 2027c478bd9Sstevel@tonic-gate case 'L': 2037c478bd9Sstevel@tonic-gate case 'l': 2047c478bd9Sstevel@tonic-gate /* format a Double density 720KB (or 360KB) disk */ 2057c478bd9Sstevel@tonic-gate D_flag++; 2067c478bd9Sstevel@tonic-gate break; 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate case 'e': 2097c478bd9Sstevel@tonic-gate /* eject diskette when done */ 2107c478bd9Sstevel@tonic-gate e_flag++; 2117c478bd9Sstevel@tonic-gate break; 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate case 'E': 2147c478bd9Sstevel@tonic-gate /* format an 2.88MB Extended density disk */ 2157c478bd9Sstevel@tonic-gate E_flag++; 2167c478bd9Sstevel@tonic-gate break; 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate case 'f': 2197c478bd9Sstevel@tonic-gate /* don't ask for confirmation */ 2207c478bd9Sstevel@tonic-gate f_flag++; 2217c478bd9Sstevel@tonic-gate break; 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate case 'H': 2247c478bd9Sstevel@tonic-gate case 'h': 2257c478bd9Sstevel@tonic-gate /* format a High density 1.2MB or 1.44MB disk */ 2267c478bd9Sstevel@tonic-gate H_flag++; 2277c478bd9Sstevel@tonic-gate break; 2287c478bd9Sstevel@tonic-gate 2297c478bd9Sstevel@tonic-gate #if 0 2307c478bd9Sstevel@tonic-gate case 'i': 2317c478bd9Sstevel@tonic-gate /* interleave factor */ 2327c478bd9Sstevel@tonic-gate interleave = atol(optarg); 2337c478bd9Sstevel@tonic-gate if (interleave <= 0) { 2347c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 2357c478bd9Sstevel@tonic-gate "%s: invalid interleave\n"), myname); 2367c478bd9Sstevel@tonic-gate exit(1); 2377c478bd9Sstevel@tonic-gate } 2387c478bd9Sstevel@tonic-gate break; 2397c478bd9Sstevel@tonic-gate #endif 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate case 'M': 2427c478bd9Sstevel@tonic-gate case 'm': 2437c478bd9Sstevel@tonic-gate /* format a 3.5" HD disk to 1.2MB */ 2447c478bd9Sstevel@tonic-gate m_flag++; 2457c478bd9Sstevel@tonic-gate break; 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate case 'x': 2487c478bd9Sstevel@tonic-gate /* skip format, just write label */ 2497c478bd9Sstevel@tonic-gate x_flag++; 2507c478bd9Sstevel@tonic-gate break; 2517c478bd9Sstevel@tonic-gate 2527c478bd9Sstevel@tonic-gate case 'q': 2537c478bd9Sstevel@tonic-gate /* quiet format */ 2547c478bd9Sstevel@tonic-gate q_flag++; 2557c478bd9Sstevel@tonic-gate break; 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate case 't': 2587c478bd9Sstevel@tonic-gate /* Type of DOS formatting: NEC or MS */ 2597c478bd9Sstevel@tonic-gate if (strcmp(optarg, "nec") == 0) { 2607c478bd9Sstevel@tonic-gate n_flag++; 2617c478bd9Sstevel@tonic-gate } 2627c478bd9Sstevel@tonic-gate if (strcmp(optarg, "dos") == 0) { 2637c478bd9Sstevel@tonic-gate d_flag++; 2647c478bd9Sstevel@tonic-gate } 2657c478bd9Sstevel@tonic-gate break; 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate case 'U': 2687c478bd9Sstevel@tonic-gate /* umount filesystem if mounted */ 2697c478bd9Sstevel@tonic-gate U_flag++; 2707c478bd9Sstevel@tonic-gate break; 2717c478bd9Sstevel@tonic-gate 2727c478bd9Sstevel@tonic-gate case 'v': 2737c478bd9Sstevel@tonic-gate case 'V': 2747c478bd9Sstevel@tonic-gate /* verify the diskette after format */ 2757c478bd9Sstevel@tonic-gate v_flag++; 2767c478bd9Sstevel@tonic-gate break; 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate case 'Z': 2797c478bd9Sstevel@tonic-gate /* for debug only, format cyl 0 only */ 2807c478bd9Sstevel@tonic-gate if (!fd_debug) { 2817c478bd9Sstevel@tonic-gate usage(gettext("unknown argument")); 2827c478bd9Sstevel@tonic-gate /* NOTREACHED */ 2837c478bd9Sstevel@tonic-gate } 2847c478bd9Sstevel@tonic-gate (void) printf(gettext("\nFormat cyl Zero only\n")); 2857c478bd9Sstevel@tonic-gate z_flag++; 2867c478bd9Sstevel@tonic-gate break; 2877c478bd9Sstevel@tonic-gate 2887c478bd9Sstevel@tonic-gate default: 2897c478bd9Sstevel@tonic-gate usage(" "); 2907c478bd9Sstevel@tonic-gate /* NOTREACHED */ 2917c478bd9Sstevel@tonic-gate } 2927c478bd9Sstevel@tonic-gate } 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate if (optind < argc -1) { 2957c478bd9Sstevel@tonic-gate usage(gettext("more than one device name argument")); 2967c478bd9Sstevel@tonic-gate /* NOTREACHED */ 2977c478bd9Sstevel@tonic-gate } 2987c478bd9Sstevel@tonic-gate if (optind == argc -1) { 2997c478bd9Sstevel@tonic-gate dev_name = argv[optind]; 3007c478bd9Sstevel@tonic-gate } 3017c478bd9Sstevel@tonic-gate if (D_flag && H_flag) { 3027c478bd9Sstevel@tonic-gate usage(gettext("switches -D, -L and -H incompatible")); 3037c478bd9Sstevel@tonic-gate /* NOTREACHED */ 3047c478bd9Sstevel@tonic-gate } 3057c478bd9Sstevel@tonic-gate if (D_flag && E_flag) { 3067c478bd9Sstevel@tonic-gate usage(gettext("switches -D, -L and -E incompatible")); 3077c478bd9Sstevel@tonic-gate /* NOTREACHED */ 3087c478bd9Sstevel@tonic-gate } 3097c478bd9Sstevel@tonic-gate if (H_flag && E_flag) { 3107c478bd9Sstevel@tonic-gate usage(gettext("switches -H and -E incompatible")); 3117c478bd9Sstevel@tonic-gate /* NOTREACHED */ 3127c478bd9Sstevel@tonic-gate } 3137c478bd9Sstevel@tonic-gate if (n_flag && d_flag) { 3147c478bd9Sstevel@tonic-gate usage(gettext("switches nec and dos incompatible")); 3157c478bd9Sstevel@tonic-gate /* NOTREACHED */ 3167c478bd9Sstevel@tonic-gate } 3177c478bd9Sstevel@tonic-gate if (n_flag && !m_flag) { 3187c478bd9Sstevel@tonic-gate usage(gettext("switch -M required for NEC-DOS")); 3197c478bd9Sstevel@tonic-gate /* NOTREACHED */ 3207c478bd9Sstevel@tonic-gate } 3217c478bd9Sstevel@tonic-gate if (D_flag && m_flag) { 3227c478bd9Sstevel@tonic-gate usage(gettext("switches -D, -L and -M incompatible")); 3237c478bd9Sstevel@tonic-gate /* NOTREACHED */ 3247c478bd9Sstevel@tonic-gate } 3257c478bd9Sstevel@tonic-gate if (d_flag && m_flag) { 3267c478bd9Sstevel@tonic-gate usage(gettext("switches -d and -M incompatible")); 3277c478bd9Sstevel@tonic-gate /* NOTREACHED */ 3287c478bd9Sstevel@tonic-gate } 3297c478bd9Sstevel@tonic-gate 3307c478bd9Sstevel@tonic-gate if (dev_name == NULL) 3317c478bd9Sstevel@tonic-gate dev_name = "floppy"; 3327c478bd9Sstevel@tonic-gate 3337c478bd9Sstevel@tonic-gate if ((real_name = media_findname(dev_name)) == NULL) { 3347c478bd9Sstevel@tonic-gate if ((alias_name = _media_oldaliases(dev_name)) != NULL) 3357c478bd9Sstevel@tonic-gate real_name = media_findname(alias_name); 3367c478bd9Sstevel@tonic-gate if (real_name == NULL) { 3377c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 3387c478bd9Sstevel@tonic-gate gettext("No such volume (or no media in specified device): %s\n"), 3397c478bd9Sstevel@tonic-gate dev_name); 3407c478bd9Sstevel@tonic-gate exit(1); 3417c478bd9Sstevel@tonic-gate } 3427c478bd9Sstevel@tonic-gate } 3437c478bd9Sstevel@tonic-gate 3447c478bd9Sstevel@tonic-gate /* 3457c478bd9Sstevel@tonic-gate * This check is required because program runs suid root. 3467c478bd9Sstevel@tonic-gate */ 3477c478bd9Sstevel@tonic-gate if (access(real_name, R_OK|W_OK) < 0) { 3487c478bd9Sstevel@tonic-gate perror(real_name); 3497c478bd9Sstevel@tonic-gate exit(1); 3507c478bd9Sstevel@tonic-gate } 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate /* store callers euid */ 3537c478bd9Sstevel@tonic-gate 3547c478bd9Sstevel@tonic-gate euid = geteuid(); 3557c478bd9Sstevel@tonic-gate 3567c478bd9Sstevel@tonic-gate /* 3577c478bd9Sstevel@tonic-gate * See if the given device name is mounted. If this check isn't done 3587c478bd9Sstevel@tonic-gate * before the open, the open will fail. The failed open will not 3597c478bd9Sstevel@tonic-gate * indicate that the device is mounted, only that it's busy 3607c478bd9Sstevel@tonic-gate */ 3617c478bd9Sstevel@tonic-gate if (_dev_mounted(real_name)) { 3627c478bd9Sstevel@tonic-gate if (U_flag) { 3637c478bd9Sstevel@tonic-gate if (!_dev_unmount(real_name)) { 3647c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 3657c478bd9Sstevel@tonic-gate gettext("%s: umount of %s failed\n"), 3667c478bd9Sstevel@tonic-gate myname, real_name); 3677c478bd9Sstevel@tonic-gate exit(1); 3687c478bd9Sstevel@tonic-gate } 3697c478bd9Sstevel@tonic-gate } else { 3707c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 3717c478bd9Sstevel@tonic-gate gettext("%s: %s is mounted (use -U flag)\n"), 3727c478bd9Sstevel@tonic-gate myname, real_name); 3737c478bd9Sstevel@tonic-gate exit(1); 3747c478bd9Sstevel@tonic-gate } 3757c478bd9Sstevel@tonic-gate } 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate /* Set to user access permissions to open file */ 3787c478bd9Sstevel@tonic-gate (void) seteuid(getuid()); 3797c478bd9Sstevel@tonic-gate 3807c478bd9Sstevel@tonic-gate if ((fd = open(real_name, O_NDELAY | O_RDWR | O_EXCL)) == -1) { 3817c478bd9Sstevel@tonic-gate if (errno == EROFS) { 3827c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 3837c478bd9Sstevel@tonic-gate gettext("%s: \"%s\" is write protected\n"), 3847c478bd9Sstevel@tonic-gate myname, real_name); 3857c478bd9Sstevel@tonic-gate exit(1); 3867c478bd9Sstevel@tonic-gate } 3877c478bd9Sstevel@tonic-gate /* XXX ought to check for "drive not installed", etc. */ 3887c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("%s: could not open \"%s\": "), 3897c478bd9Sstevel@tonic-gate myname, real_name); 3907c478bd9Sstevel@tonic-gate perror(nullstring); 3917c478bd9Sstevel@tonic-gate exit(1); 3927c478bd9Sstevel@tonic-gate } 3937c478bd9Sstevel@tonic-gate 3947c478bd9Sstevel@tonic-gate /* restore effective id */ 3957c478bd9Sstevel@tonic-gate (void) seteuid(euid); 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate if (ioctl(fd, DKIOCINFO, &dkinfo) < 0) { 3987c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 3997c478bd9Sstevel@tonic-gate gettext("%s: DKIOCINFO failed, "), myname); 4007c478bd9Sstevel@tonic-gate perror(nullstring); 4017c478bd9Sstevel@tonic-gate exit(3); 4027c478bd9Sstevel@tonic-gate } 4037c478bd9Sstevel@tonic-gate 4047c478bd9Sstevel@tonic-gate /* See if there are any mounted partitions. */ 4057c478bd9Sstevel@tonic-gate if (check_mount() != 0) { 4067c478bd9Sstevel@tonic-gate exit(3); 4077c478bd9Sstevel@tonic-gate } 4087c478bd9Sstevel@tonic-gate 4097c478bd9Sstevel@tonic-gate /* 4107c478bd9Sstevel@tonic-gate * The fd_vtoc, bpb, and rdirsec structures will be 41169ed0c8eSGarrett D'Amore * partially filled in by format_diskette(). 41269ed0c8eSGarrett D'Amore * This was done so that write_DOS_label(), 4137c478bd9Sstevel@tonic-gate * write_SunOS_label(), and write_NEC_DOS_label() could be 4147c478bd9Sstevel@tonic-gate * device independent. If a new device needs to be added to 4157c478bd9Sstevel@tonic-gate * fdformat, a new format function like format_diskette should 4167c478bd9Sstevel@tonic-gate * be added. This function should fill in fd_vtoc, bpb, and 4177c478bd9Sstevel@tonic-gate * rdirsec with device dependent information. 4187c478bd9Sstevel@tonic-gate */ 4197c478bd9Sstevel@tonic-gate (void) memset((void *)&fd_vtoc, (char)0, sizeof (struct vtoc)); 4207c478bd9Sstevel@tonic-gate (void) memset((void *)&bpb, (char)0, sizeof (struct bios_param_blk)); 4217c478bd9Sstevel@tonic-gate 4227c478bd9Sstevel@tonic-gate format_diskette(fd, real_name, &fd_vtoc, &bpb, &rdirsec); 4237c478bd9Sstevel@tonic-gate 4247c478bd9Sstevel@tonic-gate if (d_flag) 4257c478bd9Sstevel@tonic-gate write_DOS_label(fd, altboot, altsize, altbootname, 4267c478bd9Sstevel@tonic-gate vollabel, &bpb, rdirsec); 4277c478bd9Sstevel@tonic-gate else if (n_flag) 4287c478bd9Sstevel@tonic-gate write_NEC_DOS_label(fd, vollabel); 4297c478bd9Sstevel@tonic-gate else 4307c478bd9Sstevel@tonic-gate write_SunOS_label(fd, vollabel, &fd_vtoc); 4317c478bd9Sstevel@tonic-gate 4327c478bd9Sstevel@tonic-gate if (e_flag) 4337c478bd9Sstevel@tonic-gate /* eject media if possible */ 4347c478bd9Sstevel@tonic-gate if (ioctl(fd, FDEJECT, 0)) { 4357c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 4367c478bd9Sstevel@tonic-gate gettext("%s: could not eject diskette, "), myname); 4377c478bd9Sstevel@tonic-gate perror(nullstring); 4387c478bd9Sstevel@tonic-gate exit(3); 4397c478bd9Sstevel@tonic-gate } 4407c478bd9Sstevel@tonic-gate 4417c478bd9Sstevel@tonic-gate return (0); 4427c478bd9Sstevel@tonic-gate } 4437c478bd9Sstevel@tonic-gate 4447c478bd9Sstevel@tonic-gate /* 4457c478bd9Sstevel@tonic-gate * Inputs: file descriptor for the device and the device name. 4467c478bd9Sstevel@tonic-gate * Oututs: the fd_vtoc will be partially filled in with the 4477c478bd9Sstevel@tonic-gate * device specific information such as partition 4487c478bd9Sstevel@tonic-gate * information and ascillabel. bpb and rdirsec will 4497c478bd9Sstevel@tonic-gate * also be partially filled in with device specific information 4507c478bd9Sstevel@tonic-gate */ 4517c478bd9Sstevel@tonic-gate void 4527c478bd9Sstevel@tonic-gate format_diskette(int fd, char *real_name, struct vtoc *fd_vtoc, 4537c478bd9Sstevel@tonic-gate struct bios_param_blk *bpb, int *rdirsec) 4547c478bd9Sstevel@tonic-gate { 4557c478bd9Sstevel@tonic-gate int transfer_rate = 1000; /* transfer rate code */ 4567c478bd9Sstevel@tonic-gate int sec_size = 512; /* sector size */ 4577c478bd9Sstevel@tonic-gate uchar_t gap = 0x54; /* format gap size */ 4587c478bd9Sstevel@tonic-gate uchar_t *fbuf, *p; 4597c478bd9Sstevel@tonic-gate char *capacity = NULL; 4607c478bd9Sstevel@tonic-gate int cyl_size; 4617c478bd9Sstevel@tonic-gate int i; 4627c478bd9Sstevel@tonic-gate int chgd; /* for testing disk changed/present */ 4637c478bd9Sstevel@tonic-gate int cyl, hd; 4647c478bd9Sstevel@tonic-gate int size_of_part, size_of_dev; 4657c478bd9Sstevel@tonic-gate int spt = 36; /* sectors per track */ 4667c478bd9Sstevel@tonic-gate int drive_size; 4677c478bd9Sstevel@tonic-gate uchar_t num_cyl = 80; /* max number of cylinders */ 4687c478bd9Sstevel@tonic-gate char *nullstring = ""; 4697c478bd9Sstevel@tonic-gate struct fd_char save_fdchar; /* original diskette characteristics */ 4707c478bd9Sstevel@tonic-gate struct dk_allmap save_allmap; /* original diskette partition info */ 4717c478bd9Sstevel@tonic-gate 4727c478bd9Sstevel@tonic-gate /* FDRAW ioctl command structures for seeking and formatting */ 4737c478bd9Sstevel@tonic-gate struct fd_raw fdr_seek = { 4747c478bd9Sstevel@tonic-gate FDRAW_SEEK, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4757c478bd9Sstevel@tonic-gate 3, 4767c478bd9Sstevel@tonic-gate 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4777c478bd9Sstevel@tonic-gate 0, 4787c478bd9Sstevel@tonic-gate 0 4797c478bd9Sstevel@tonic-gate }; 4807c478bd9Sstevel@tonic-gate 4817c478bd9Sstevel@tonic-gate struct fd_raw fdr_form = { 4827c478bd9Sstevel@tonic-gate 0x4D, 0, 2, 0, 0x54, (char)0xA5, 0, 0, 0, 0, 4837c478bd9Sstevel@tonic-gate 6, 4847c478bd9Sstevel@tonic-gate 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4857c478bd9Sstevel@tonic-gate 0, /* nbytes */ 4867c478bd9Sstevel@tonic-gate 0 /* addr */ 4877c478bd9Sstevel@tonic-gate }; 4887c478bd9Sstevel@tonic-gate 4897c478bd9Sstevel@tonic-gate 4907c478bd9Sstevel@tonic-gate /* 4917c478bd9Sstevel@tonic-gate * restore drive to default geometry and characteristics 4927c478bd9Sstevel@tonic-gate * (probably not implemented on sparc) 4937c478bd9Sstevel@tonic-gate */ 4947c478bd9Sstevel@tonic-gate (void) ioctl(fd, FDDEFGEOCHAR, NULL); 4957c478bd9Sstevel@tonic-gate 4967c478bd9Sstevel@tonic-gate /* get the default partititon maps */ 4977c478bd9Sstevel@tonic-gate if (ioctl(fd, DKIOCGAPART, &allmap) == -1) { 4987c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 4997c478bd9Sstevel@tonic-gate gettext("%s: DKIOCGAPART failed, "), myname); 5007c478bd9Sstevel@tonic-gate perror(nullstring); 5017c478bd9Sstevel@tonic-gate exit(3); 5027c478bd9Sstevel@tonic-gate } 5037c478bd9Sstevel@tonic-gate 5047c478bd9Sstevel@tonic-gate /* Save the original default partition maps */ 5057c478bd9Sstevel@tonic-gate save_allmap = allmap; 5067c478bd9Sstevel@tonic-gate 5077c478bd9Sstevel@tonic-gate /* find out the characteristics of the default diskette */ 5087c478bd9Sstevel@tonic-gate if (ioctl(fd, FDIOGCHAR, &fdchar) == -1) { 5097c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 5107c478bd9Sstevel@tonic-gate gettext("%s: FDIOGCHAR failed, "), myname); 5117c478bd9Sstevel@tonic-gate perror(nullstring); 5127c478bd9Sstevel@tonic-gate exit(3); 5137c478bd9Sstevel@tonic-gate } 5147c478bd9Sstevel@tonic-gate 5157c478bd9Sstevel@tonic-gate /* Save the original characteristics of the default diskette */ 5167c478bd9Sstevel@tonic-gate save_fdchar = fdchar; 5177c478bd9Sstevel@tonic-gate 5187c478bd9Sstevel@tonic-gate /* 5197c478bd9Sstevel@tonic-gate * The user may only format the entire diskette. 5207c478bd9Sstevel@tonic-gate * formatting partion a or b is not allowed 5217c478bd9Sstevel@tonic-gate */ 5227c478bd9Sstevel@tonic-gate size_of_part = allmap.dka_map[dkinfo.dki_partition].dkl_nblk 5237c478bd9Sstevel@tonic-gate * DEV_BSIZE; 5247c478bd9Sstevel@tonic-gate size_of_dev = fdchar.fdc_ncyl * fdchar.fdc_nhead 5257c478bd9Sstevel@tonic-gate * fdchar.fdc_secptrack * fdchar.fdc_sec_size; 5267c478bd9Sstevel@tonic-gate 5277c478bd9Sstevel@tonic-gate if (size_of_part != size_of_dev) { 5287c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 5297c478bd9Sstevel@tonic-gate /*CSTYLED*/ 5307c478bd9Sstevel@tonic-gate gettext("%s: The entire diskette must be formatted. Invalid device name.\n"), 5317c478bd9Sstevel@tonic-gate myname); 5327c478bd9Sstevel@tonic-gate exit(3); 5337c478bd9Sstevel@tonic-gate } 5347c478bd9Sstevel@tonic-gate 5357c478bd9Sstevel@tonic-gate 5367c478bd9Sstevel@tonic-gate /* find out the geometry of the drive */ 5377c478bd9Sstevel@tonic-gate if (ioctl(fd, DKIOCGGEOM, &fdgeom) == -1) { 5387c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 5397c478bd9Sstevel@tonic-gate gettext("%s: DKIOCGGEOM failed, "), myname); 5407c478bd9Sstevel@tonic-gate perror(nullstring); 5417c478bd9Sstevel@tonic-gate exit(3); 5427c478bd9Sstevel@tonic-gate } 5437c478bd9Sstevel@tonic-gate 5447c478bd9Sstevel@tonic-gate #ifdef sparc 5457c478bd9Sstevel@tonic-gate fdchar.fdc_medium = 3; 5467c478bd9Sstevel@tonic-gate #endif 5477c478bd9Sstevel@tonic-gate if (fdchar.fdc_medium == 5) 5487c478bd9Sstevel@tonic-gate drive_size = 5; 5497c478bd9Sstevel@tonic-gate else 5507c478bd9Sstevel@tonic-gate drive_size = 3; 5517c478bd9Sstevel@tonic-gate 5527c478bd9Sstevel@tonic-gate /* 5537c478bd9Sstevel@tonic-gate * set proper density flag in case we're formating to default 5547c478bd9Sstevel@tonic-gate * characteristics because no density switch was input 5557c478bd9Sstevel@tonic-gate */ 5567c478bd9Sstevel@tonic-gate if ((E_flag | H_flag | D_flag | m_flag) == 0) { 5577c478bd9Sstevel@tonic-gate switch (fdchar.fdc_transfer_rate) { 5587c478bd9Sstevel@tonic-gate case 1000: 5597c478bd9Sstevel@tonic-gate /* assumes only ED uses 1.0 MB/sec */ 5607c478bd9Sstevel@tonic-gate E_flag++; 5617c478bd9Sstevel@tonic-gate break; 5627c478bd9Sstevel@tonic-gate case 500: 5637c478bd9Sstevel@tonic-gate default: 5647c478bd9Sstevel@tonic-gate /* 5657c478bd9Sstevel@tonic-gate * default to HD even though High density and 5667c478bd9Sstevel@tonic-gate * "medium" density both use 500 KB/sec 5677c478bd9Sstevel@tonic-gate */ 5687c478bd9Sstevel@tonic-gate H_flag++; 5697c478bd9Sstevel@tonic-gate break; 5707c478bd9Sstevel@tonic-gate #ifndef sparc 5717c478bd9Sstevel@tonic-gate case 250: 5727c478bd9Sstevel@tonic-gate /* assumes only DD uses 250 KB/sec */ 5737c478bd9Sstevel@tonic-gate D_flag++; 5747c478bd9Sstevel@tonic-gate break; 5757c478bd9Sstevel@tonic-gate #endif 5767c478bd9Sstevel@tonic-gate } 5777c478bd9Sstevel@tonic-gate } 5787c478bd9Sstevel@tonic-gate 5797c478bd9Sstevel@tonic-gate if (H_flag) { 5807c478bd9Sstevel@tonic-gate transfer_rate = 500; 5817c478bd9Sstevel@tonic-gate num_cyl = 80; 5827c478bd9Sstevel@tonic-gate sec_size = 512; 5837c478bd9Sstevel@tonic-gate if (drive_size == 5) { 5847c478bd9Sstevel@tonic-gate (void) strcpy(fd_vtoc->v_asciilabel, 5857c478bd9Sstevel@tonic-gate "5.25\" floppy cyl 80 alt 0 hd 2 sec 15"); 5867c478bd9Sstevel@tonic-gate spt = 15; 5877c478bd9Sstevel@tonic-gate capacity = "1.2 MB"; 5887c478bd9Sstevel@tonic-gate } else { 5897c478bd9Sstevel@tonic-gate (void) strcpy(fd_vtoc->v_asciilabel, 5907c478bd9Sstevel@tonic-gate "3.5\" floppy cyl 80 alt 0 hd 2 sec 18"); 5917c478bd9Sstevel@tonic-gate spt = 18; 5927c478bd9Sstevel@tonic-gate capacity = "1.44 MB"; 5937c478bd9Sstevel@tonic-gate } 5947c478bd9Sstevel@tonic-gate gap = 0x54; 5957c478bd9Sstevel@tonic-gate } else if (D_flag) { 5967c478bd9Sstevel@tonic-gate transfer_rate = 250; 5977c478bd9Sstevel@tonic-gate if (drive_size == 5) { 5987c478bd9Sstevel@tonic-gate (void) strcpy(fd_vtoc->v_asciilabel, 5997c478bd9Sstevel@tonic-gate "5.25\" floppy cyl 40 alt 0 hd 2 sec 9"); 6007c478bd9Sstevel@tonic-gate if (fdchar.fdc_transfer_rate == 500) { 6017c478bd9Sstevel@tonic-gate /* 6027c478bd9Sstevel@tonic-gate * formatting a 360KB DD diskette in 6037c478bd9Sstevel@tonic-gate * a 1.2MB drive is not a good idea 6047c478bd9Sstevel@tonic-gate */ 6057c478bd9Sstevel@tonic-gate transfer_rate = 300; 6067c478bd9Sstevel@tonic-gate fdchar.fdc_steps = 2; 6077c478bd9Sstevel@tonic-gate } 6087c478bd9Sstevel@tonic-gate num_cyl = 40; 6097c478bd9Sstevel@tonic-gate gap = 0x50; 6107c478bd9Sstevel@tonic-gate capacity = "360 KB"; 6117c478bd9Sstevel@tonic-gate } else { 6127c478bd9Sstevel@tonic-gate (void) strcpy(fd_vtoc->v_asciilabel, 6137c478bd9Sstevel@tonic-gate "3.5\" floppy cyl 80 alt 0 hd 2 sec 9"); 6147c478bd9Sstevel@tonic-gate num_cyl = 80; 6157c478bd9Sstevel@tonic-gate gap = 0x54; 6167c478bd9Sstevel@tonic-gate capacity = "720 KB"; 6177c478bd9Sstevel@tonic-gate } 6187c478bd9Sstevel@tonic-gate sec_size = 512; 6197c478bd9Sstevel@tonic-gate spt = 9; 6207c478bd9Sstevel@tonic-gate } else if (m_flag) { 6217c478bd9Sstevel@tonic-gate #ifdef sparc 6227c478bd9Sstevel@tonic-gate transfer_rate = 500; 6237c478bd9Sstevel@tonic-gate #else 6247c478bd9Sstevel@tonic-gate /* 6257c478bd9Sstevel@tonic-gate * 416.67 KB/sec is the effective transfer rate of a "medium" 6267c478bd9Sstevel@tonic-gate * density diskette spun at 300 rpm instead of 360 rpm 6277c478bd9Sstevel@tonic-gate */ 6287c478bd9Sstevel@tonic-gate transfer_rate = 417; 6297c478bd9Sstevel@tonic-gate #endif 6307c478bd9Sstevel@tonic-gate (void) strcpy(fd_vtoc->v_asciilabel, 6317c478bd9Sstevel@tonic-gate "3.5\" floppy cyl 77 alt 0 hd 2 sec 8"); 6327c478bd9Sstevel@tonic-gate num_cyl = 77; 6337c478bd9Sstevel@tonic-gate sec_size = 1024; 6347c478bd9Sstevel@tonic-gate spt = 8; 6357c478bd9Sstevel@tonic-gate gap = 0x74; 6367c478bd9Sstevel@tonic-gate capacity = "1.2 MB"; 6377c478bd9Sstevel@tonic-gate } else if (E_flag) { 6387c478bd9Sstevel@tonic-gate (void) strcpy(fd_vtoc->v_asciilabel, 6397c478bd9Sstevel@tonic-gate "3.5\" floppy cyl 80 alt 0 hd 2 sec 36"); 6407c478bd9Sstevel@tonic-gate transfer_rate = 1000; 6417c478bd9Sstevel@tonic-gate num_cyl = 80; 6427c478bd9Sstevel@tonic-gate sec_size = 512; 6437c478bd9Sstevel@tonic-gate spt = 36; 6447c478bd9Sstevel@tonic-gate gap = 0x54; 6457c478bd9Sstevel@tonic-gate capacity = "2.88 MB"; 6467c478bd9Sstevel@tonic-gate } 6477c478bd9Sstevel@tonic-gate /* 6487c478bd9Sstevel@tonic-gate * Medium density diskettes have 1024 byte blocks. The dk_map 6497c478bd9Sstevel@tonic-gate * structure in dklabel.h assumes the blocks size is DEVBSIZE (512) 6507c478bd9Sstevel@tonic-gate * bytes. The dkl_nblk field is in terms of DEVBSIZE byte blocks 6517c478bd9Sstevel@tonic-gate * while the spt variable is in terms of the true block size on 6527c478bd9Sstevel@tonic-gate * the diskette. 6537c478bd9Sstevel@tonic-gate */ 6547c478bd9Sstevel@tonic-gate if (allmap.dka_map[2].dkl_nblk != 6557c478bd9Sstevel@tonic-gate (2 * num_cyl * spt * (m_flag ? 2 : 1))) { 6567c478bd9Sstevel@tonic-gate allmap.dka_map[1].dkl_cylno = num_cyl - 1; 6577c478bd9Sstevel@tonic-gate allmap.dka_map[0].dkl_nblk = 2 * (num_cyl - 1) * spt * 6587c478bd9Sstevel@tonic-gate (m_flag ? 2 : 1); 6597c478bd9Sstevel@tonic-gate allmap.dka_map[1].dkl_nblk = 2 * spt * (m_flag ? 2 : 1); 6607c478bd9Sstevel@tonic-gate allmap.dka_map[2].dkl_nblk = 2 * num_cyl * spt * 6617c478bd9Sstevel@tonic-gate (m_flag ? 2 : 1); 6627c478bd9Sstevel@tonic-gate if (allmap.dka_map[3].dkl_nblk) 6637c478bd9Sstevel@tonic-gate allmap.dka_map[3].dkl_nblk = 2 * (num_cyl - 1) * spt * 6647c478bd9Sstevel@tonic-gate (m_flag ? 2 : 1); 6657c478bd9Sstevel@tonic-gate if (allmap.dka_map[4].dkl_nblk) 6667c478bd9Sstevel@tonic-gate allmap.dka_map[4].dkl_nblk = 6677c478bd9Sstevel@tonic-gate 2 * spt * (m_flag ? 2 : 1); 6687c478bd9Sstevel@tonic-gate } 6697c478bd9Sstevel@tonic-gate 6707c478bd9Sstevel@tonic-gate 6717c478bd9Sstevel@tonic-gate /* initialize the vtoc structure */ 6727c478bd9Sstevel@tonic-gate fd_vtoc->v_nparts = 3; 6737c478bd9Sstevel@tonic-gate 6747c478bd9Sstevel@tonic-gate fd_vtoc->v_part[0].p_start = 0; 6757c478bd9Sstevel@tonic-gate fd_vtoc->v_part[0].p_size = ((num_cyl - 1) * 2 * spt * 6767c478bd9Sstevel@tonic-gate (m_flag ? 2 : 1)); 6777c478bd9Sstevel@tonic-gate fd_vtoc->v_part[1].p_start = ((num_cyl - 1) * 2 * spt * 6787c478bd9Sstevel@tonic-gate (m_flag ? 2 : 1)); 6797c478bd9Sstevel@tonic-gate fd_vtoc->v_part[1].p_size = 2 * spt * (m_flag ? 2 : 1); 6807c478bd9Sstevel@tonic-gate 6817c478bd9Sstevel@tonic-gate fd_vtoc->v_part[2].p_start = 0; 6827c478bd9Sstevel@tonic-gate fd_vtoc->v_part[2].p_size = num_cyl * 2 * spt * (m_flag ? 2 : 1); 6837c478bd9Sstevel@tonic-gate 6847c478bd9Sstevel@tonic-gate /* initialize the bios parameter blockstructure */ 6857c478bd9Sstevel@tonic-gate bpb->b_nfat = 2; 6867c478bd9Sstevel@tonic-gate if (E_flag && drive_size == 3) { 6877c478bd9Sstevel@tonic-gate bpb->b_spcl = 2; 6887c478bd9Sstevel@tonic-gate *rdirsec = (ushort_t)240; 6897c478bd9Sstevel@tonic-gate bpb->b_mediadescriptor = (char)0xF0; 6907c478bd9Sstevel@tonic-gate bpb->b_fatsec[0] = 9; 6917c478bd9Sstevel@tonic-gate bpb->b_fatsec[1] = 0; 6927c478bd9Sstevel@tonic-gate } else if (H_flag) { 6937c478bd9Sstevel@tonic-gate if (drive_size == 5) { 6947c478bd9Sstevel@tonic-gate bpb->b_spcl = 1; 6957c478bd9Sstevel@tonic-gate *rdirsec = 224; 6967c478bd9Sstevel@tonic-gate bpb->b_mediadescriptor = (char)0xF9; 6977c478bd9Sstevel@tonic-gate bpb->b_fatsec[0] = 7; 6987c478bd9Sstevel@tonic-gate bpb->b_fatsec[1] = 0; 6997c478bd9Sstevel@tonic-gate } else { 7007c478bd9Sstevel@tonic-gate bpb->b_spcl = 1; 7017c478bd9Sstevel@tonic-gate *rdirsec = 224; 7027c478bd9Sstevel@tonic-gate bpb->b_mediadescriptor = (char)0xF0; 7037c478bd9Sstevel@tonic-gate bpb->b_fatsec[0] = 9; 7047c478bd9Sstevel@tonic-gate bpb->b_fatsec[1] = 0; 7057c478bd9Sstevel@tonic-gate } 7067c478bd9Sstevel@tonic-gate } else if (drive_size == 5) { 7077c478bd9Sstevel@tonic-gate bpb->b_spcl = 2; 7087c478bd9Sstevel@tonic-gate *rdirsec = 112; 7097c478bd9Sstevel@tonic-gate bpb->b_mediadescriptor = (char)0xFD; 7107c478bd9Sstevel@tonic-gate bpb->b_fatsec[0] = 2; 7117c478bd9Sstevel@tonic-gate bpb->b_fatsec[1] = 0; 7127c478bd9Sstevel@tonic-gate } else if (drive_size == 3) { 7137c478bd9Sstevel@tonic-gate bpb->b_spcl = 2; 7147c478bd9Sstevel@tonic-gate *rdirsec = 112; 7157c478bd9Sstevel@tonic-gate bpb->b_mediadescriptor = (char)0xF9; 7167c478bd9Sstevel@tonic-gate bpb->b_fatsec[0] = 3; 7177c478bd9Sstevel@tonic-gate bpb->b_fatsec[1] = 0; 7187c478bd9Sstevel@tonic-gate } 7197c478bd9Sstevel@tonic-gate 7207c478bd9Sstevel@tonic-gate 7217c478bd9Sstevel@tonic-gate 7227c478bd9Sstevel@tonic-gate #ifndef sparc 7237c478bd9Sstevel@tonic-gate if (num_cyl > fdchar.fdc_ncyl || spt > fdchar.fdc_secptrack || 7247c478bd9Sstevel@tonic-gate transfer_rate > fdchar.fdc_transfer_rate) { 7257c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 7267c478bd9Sstevel@tonic-gate gettext("%s: drive not capable of requested density, "), 7277c478bd9Sstevel@tonic-gate myname); 7287c478bd9Sstevel@tonic-gate perror(nullstring); 7297c478bd9Sstevel@tonic-gate exit(3); 7307c478bd9Sstevel@tonic-gate } 7317c478bd9Sstevel@tonic-gate #endif 7327c478bd9Sstevel@tonic-gate if (num_cyl != fdchar.fdc_ncyl || spt != fdchar.fdc_secptrack || 7337c478bd9Sstevel@tonic-gate transfer_rate != fdchar.fdc_transfer_rate) { 7347c478bd9Sstevel@tonic-gate /* 7357c478bd9Sstevel@tonic-gate * -- CAUTION -- 7367c478bd9Sstevel@tonic-gate * The SPARC fd driver is using a non-zero value in 7377c478bd9Sstevel@tonic-gate * fdc_medium to indicate the 360 rpm, 77 track, 7387c478bd9Sstevel@tonic-gate * 9 sectors/track, 1024 bytes/sector mode of operation 7397c478bd9Sstevel@tonic-gate * (similar to an 8", DS/DD, 1.2 MB floppy). 7407c478bd9Sstevel@tonic-gate * 7417c478bd9Sstevel@tonic-gate * The x86 fd driver uses fdc_medium as the diameter 7427c478bd9Sstevel@tonic-gate * indicator, either 3 or 5. It should not be modified. 7437c478bd9Sstevel@tonic-gate */ 7447c478bd9Sstevel@tonic-gate #ifdef sparc 7457c478bd9Sstevel@tonic-gate fdchar.fdc_medium = m_flag ? 1 : 0; 7467c478bd9Sstevel@tonic-gate #endif 7477c478bd9Sstevel@tonic-gate fdchar.fdc_transfer_rate = transfer_rate; 7487c478bd9Sstevel@tonic-gate fdchar.fdc_ncyl = num_cyl; 7497c478bd9Sstevel@tonic-gate fdchar.fdc_sec_size = sec_size; 7507c478bd9Sstevel@tonic-gate fdchar.fdc_secptrack = spt; 7517c478bd9Sstevel@tonic-gate 7527c478bd9Sstevel@tonic-gate if (ioctl(fd, FDIOSCHAR, &fdchar) == -1) { 7537c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 7547c478bd9Sstevel@tonic-gate "%s: FDIOSCHAR (density selection) failed, "), 7557c478bd9Sstevel@tonic-gate myname); 7567c478bd9Sstevel@tonic-gate 7577c478bd9Sstevel@tonic-gate /* restore the default characteristics */ 7587c478bd9Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, save_allmap); 7597c478bd9Sstevel@tonic-gate perror(nullstring); 7607c478bd9Sstevel@tonic-gate exit(3); 7617c478bd9Sstevel@tonic-gate } 7627c478bd9Sstevel@tonic-gate if (ioctl(fd, DKIOCSAPART, &allmap) == -1) { 7637c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 7647c478bd9Sstevel@tonic-gate gettext("%s: DKIOCSAPART failed, "), 7657c478bd9Sstevel@tonic-gate myname); 7667c478bd9Sstevel@tonic-gate 7677c478bd9Sstevel@tonic-gate /* restore the default characteristics */ 7687c478bd9Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, save_allmap); 7697c478bd9Sstevel@tonic-gate 7707c478bd9Sstevel@tonic-gate perror(nullstring); 7717c478bd9Sstevel@tonic-gate exit(3); 7727c478bd9Sstevel@tonic-gate } 7737c478bd9Sstevel@tonic-gate } 7747c478bd9Sstevel@tonic-gate 7757c478bd9Sstevel@tonic-gate if (interleave != 1 && interleave != fdgeom.dkg_intrlv) { 7767c478bd9Sstevel@tonic-gate fdgeom.dkg_intrlv = interleave; 7777c478bd9Sstevel@tonic-gate if (ioctl(fd, DKIOCSGEOM, &fdgeom) == -1) { 7787c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 7797c478bd9Sstevel@tonic-gate gettext("%s: DKIOCSGEOM failed, "), myname); 7807c478bd9Sstevel@tonic-gate perror(nullstring); 7817c478bd9Sstevel@tonic-gate 7827c478bd9Sstevel@tonic-gate /* restore the default characteristics */ 7837c478bd9Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, save_allmap); 7847c478bd9Sstevel@tonic-gate 7857c478bd9Sstevel@tonic-gate exit(3); 7867c478bd9Sstevel@tonic-gate } 7877c478bd9Sstevel@tonic-gate } 7887c478bd9Sstevel@tonic-gate 7897c478bd9Sstevel@tonic-gate cyl_size = 2 * sec_size * spt; 7907c478bd9Sstevel@tonic-gate 7917c478bd9Sstevel@tonic-gate if ((ibuf1 = (uchar_t *)malloc((size_t)cyl_size)) == 0 || 7927c478bd9Sstevel@tonic-gate (obuf = (uchar_t *)malloc((size_t)cyl_size)) == 0) { 7937c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 7947c478bd9Sstevel@tonic-gate gettext("%s: can't malloc verify buffer, "), 7957c478bd9Sstevel@tonic-gate myname); 7967c478bd9Sstevel@tonic-gate perror(nullstring); 7977c478bd9Sstevel@tonic-gate /* restore the default characteristics */ 7987c478bd9Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, save_allmap); 7997c478bd9Sstevel@tonic-gate 8007c478bd9Sstevel@tonic-gate exit(4); 8017c478bd9Sstevel@tonic-gate } 8027c478bd9Sstevel@tonic-gate (void) memset(ibuf1, (uchar_t)0xA5, cyl_size); 8037c478bd9Sstevel@tonic-gate 8047c478bd9Sstevel@tonic-gate if (x_flag) 8057c478bd9Sstevel@tonic-gate goto skipformat; 8067c478bd9Sstevel@tonic-gate 807*a388614eSIgor Kozhukhov if (!(q_flag && f_flag)) { 808*a388614eSIgor Kozhukhov if (interleave != 1) { 8097c478bd9Sstevel@tonic-gate (void) printf(gettext( 8107c478bd9Sstevel@tonic-gate "Formatting %s, %d cylinders, %d sectors per trk, interleave=%d in %s\n"), 8117c478bd9Sstevel@tonic-gate capacity, num_cyl, spt, interleave, real_name); 812*a388614eSIgor Kozhukhov } else { 8137c478bd9Sstevel@tonic-gate (void) printf(gettext("Formatting %s in %s\n"), 8147c478bd9Sstevel@tonic-gate capacity, real_name); 815*a388614eSIgor Kozhukhov } 816*a388614eSIgor Kozhukhov } 8177c478bd9Sstevel@tonic-gate if (!f_flag) { 8187c478bd9Sstevel@tonic-gate (void) printf( 8197c478bd9Sstevel@tonic-gate gettext("Press return to start formatting floppy.")); 8207c478bd9Sstevel@tonic-gate while (getchar() != '\n') 8217c478bd9Sstevel@tonic-gate ; 8227c478bd9Sstevel@tonic-gate } 8237c478bd9Sstevel@tonic-gate /* 8247c478bd9Sstevel@tonic-gate * for those systems that support this ioctl, they will 8257c478bd9Sstevel@tonic-gate * return whether or not a diskette is in the drive. 8267c478bd9Sstevel@tonic-gate */ 8277c478bd9Sstevel@tonic-gate if (ioctl(fd, FDGETCHANGE, &chgd) == 0) { 8287c478bd9Sstevel@tonic-gate if (chgd & FDGC_CURRENT) { 8297c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 8307c478bd9Sstevel@tonic-gate gettext("%s: no diskette in drive %s\n"), 8317c478bd9Sstevel@tonic-gate myname, real_name); 8327c478bd9Sstevel@tonic-gate 8337c478bd9Sstevel@tonic-gate /* restore the default characteristics */ 8347c478bd9Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, save_allmap); 8357c478bd9Sstevel@tonic-gate 8367c478bd9Sstevel@tonic-gate exit(4); 8377c478bd9Sstevel@tonic-gate } 8387c478bd9Sstevel@tonic-gate if (chgd & FDGC_CURWPROT) { 8397c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 8407c478bd9Sstevel@tonic-gate gettext("%s: \"%s\" is write protected\n"), 8417c478bd9Sstevel@tonic-gate myname, real_name); 8427c478bd9Sstevel@tonic-gate 8437c478bd9Sstevel@tonic-gate /* restore the default characteristics */ 8447c478bd9Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, save_allmap); 8457c478bd9Sstevel@tonic-gate 8467c478bd9Sstevel@tonic-gate exit(1); 8477c478bd9Sstevel@tonic-gate } 8487c478bd9Sstevel@tonic-gate } 8497c478bd9Sstevel@tonic-gate 8507c478bd9Sstevel@tonic-gate if ((fbuf = (uchar_t *)malloc((unsigned)(4 * spt))) == 0) { 8517c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 8527c478bd9Sstevel@tonic-gate gettext("%s: can't malloc format header buffer, "), 8537c478bd9Sstevel@tonic-gate myname); 8547c478bd9Sstevel@tonic-gate perror(nullstring); 8557c478bd9Sstevel@tonic-gate 8567c478bd9Sstevel@tonic-gate /* restore the default characteristics */ 8577c478bd9Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, save_allmap); 8587c478bd9Sstevel@tonic-gate 8597c478bd9Sstevel@tonic-gate exit(3); 8607c478bd9Sstevel@tonic-gate } 8617c478bd9Sstevel@tonic-gate /* 8627c478bd9Sstevel@tonic-gate * do the format, a track at a time 8637c478bd9Sstevel@tonic-gate */ 8647c478bd9Sstevel@tonic-gate for (cyl = 0; cyl < (z_flag ? 1 : (int)num_cyl); cyl++) { 8657c478bd9Sstevel@tonic-gate /* 8667c478bd9Sstevel@tonic-gate * This is not the optimal ioctl to format the floppy. 8677c478bd9Sstevel@tonic-gate * The device driver should do do the work, 8687c478bd9Sstevel@tonic-gate * instead of this program mucking with a lot 8697c478bd9Sstevel@tonic-gate * of low-level, device-dependent code. 8707c478bd9Sstevel@tonic-gate */ 8717c478bd9Sstevel@tonic-gate fdr_seek.fdr_cmd[2] = cyl; 8727c478bd9Sstevel@tonic-gate if (ioctl(fd, FDRAW, &fdr_seek) == -1) { 8737c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 8747c478bd9Sstevel@tonic-gate gettext("%s: seek to cyl %d failed\n"), 8757c478bd9Sstevel@tonic-gate myname, cyl); 8767c478bd9Sstevel@tonic-gate 8777c478bd9Sstevel@tonic-gate /* restore the default characteristics */ 8787c478bd9Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, save_allmap); 8797c478bd9Sstevel@tonic-gate 8807c478bd9Sstevel@tonic-gate exit(3); 8817c478bd9Sstevel@tonic-gate } 8827c478bd9Sstevel@tonic-gate /* 8837c478bd9Sstevel@tonic-gate * Assume that the fd driver has issued a SENSE_INT 8847c478bd9Sstevel@tonic-gate * command to complete the seek operation. 8857c478bd9Sstevel@tonic-gate */ 8867c478bd9Sstevel@tonic-gate for (hd = 0; hd < fdchar.fdc_nhead; hd++) { 8877c478bd9Sstevel@tonic-gate p = (uchar_t *)fbuf; 8887c478bd9Sstevel@tonic-gate for (i = 1; i <= spt; i++) { 8897c478bd9Sstevel@tonic-gate *p++ = cyl; 8907c478bd9Sstevel@tonic-gate *p++ = hd; 8917c478bd9Sstevel@tonic-gate *p++ = i; /* sector # */ 8927c478bd9Sstevel@tonic-gate *p++ = (sec_size == 1024) ? 3 : 2; 8937c478bd9Sstevel@tonic-gate } 8947c478bd9Sstevel@tonic-gate /* 8957c478bd9Sstevel@tonic-gate * ASSUME the fd driver is going to set drive-select 8967c478bd9Sstevel@tonic-gate * bits in the second command byte 8977c478bd9Sstevel@tonic-gate */ 8987c478bd9Sstevel@tonic-gate fdr_form.fdr_cmd[1] = hd << 2; 8997c478bd9Sstevel@tonic-gate fdr_form.fdr_cmd[2] = (sec_size == 1024) ? 3 : 2; 9007c478bd9Sstevel@tonic-gate fdr_form.fdr_cmd[3] = spt; 9017c478bd9Sstevel@tonic-gate fdr_form.fdr_cmd[4] = gap; 9027c478bd9Sstevel@tonic-gate fdr_form.fdr_nbytes = 4 * spt; 9037c478bd9Sstevel@tonic-gate fdr_form.fdr_addr = (char *)fbuf; 9047c478bd9Sstevel@tonic-gate 9057c478bd9Sstevel@tonic-gate if (ioctl(fd, FDRAW, &fdr_form) == -1) { 9067c478bd9Sstevel@tonic-gate 9077c478bd9Sstevel@tonic-gate 9087c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 9097c478bd9Sstevel@tonic-gate "%s: format of cyl %d head %d failed\n"), 9107c478bd9Sstevel@tonic-gate myname, cyl, hd); 9117c478bd9Sstevel@tonic-gate 9127c478bd9Sstevel@tonic-gate /* restore the default characteristics */ 9137c478bd9Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, 9147c478bd9Sstevel@tonic-gate save_allmap); 9157c478bd9Sstevel@tonic-gate 9167c478bd9Sstevel@tonic-gate exit(3); 9177c478bd9Sstevel@tonic-gate } 9187c478bd9Sstevel@tonic-gate if (fdr_form.fdr_result[0] & 0xC0) { 9197c478bd9Sstevel@tonic-gate if (fdr_form.fdr_result[1] & 0x02) { 9207c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 9217c478bd9Sstevel@tonic-gate /*CSTYLED*/ 9227c478bd9Sstevel@tonic-gate "%s: diskette is write protected\n"), 9237c478bd9Sstevel@tonic-gate myname); 9247c478bd9Sstevel@tonic-gate 9257c478bd9Sstevel@tonic-gate /* 9267c478bd9Sstevel@tonic-gate * restore the default 9277c478bd9Sstevel@tonic-gate * characteristics 9287c478bd9Sstevel@tonic-gate */ 9297c478bd9Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, 9307c478bd9Sstevel@tonic-gate save_allmap); 9317c478bd9Sstevel@tonic-gate 9327c478bd9Sstevel@tonic-gate exit(3); 9337c478bd9Sstevel@tonic-gate } 9347c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 9357c478bd9Sstevel@tonic-gate "%s: format of cyl %d head %d failed\n"), 9367c478bd9Sstevel@tonic-gate myname, cyl, hd); 9377c478bd9Sstevel@tonic-gate 9387c478bd9Sstevel@tonic-gate /* restore the default characteristics */ 9397c478bd9Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, 9407c478bd9Sstevel@tonic-gate save_allmap); 9417c478bd9Sstevel@tonic-gate 9427c478bd9Sstevel@tonic-gate exit(3); 9437c478bd9Sstevel@tonic-gate } 9447c478bd9Sstevel@tonic-gate 9457c478bd9Sstevel@tonic-gate } 9467c478bd9Sstevel@tonic-gate 9477c478bd9Sstevel@tonic-gate /* 9487c478bd9Sstevel@tonic-gate * do a quick verify 9497c478bd9Sstevel@tonic-gate */ 9507c478bd9Sstevel@tonic-gate if (!v_flag) { 9517c478bd9Sstevel@tonic-gate if (lseek(fd, cyl * cyl_size, 0) != cyl * cyl_size) { 9527c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 9537c478bd9Sstevel@tonic-gate gettext("%s: bad seek to format verify, "), 9547c478bd9Sstevel@tonic-gate myname); 9557c478bd9Sstevel@tonic-gate perror(nullstring); 9567c478bd9Sstevel@tonic-gate /* restore the default characteristics */ 9577c478bd9Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, 9587c478bd9Sstevel@tonic-gate save_allmap); 9597c478bd9Sstevel@tonic-gate 9607c478bd9Sstevel@tonic-gate exit(3); 9617c478bd9Sstevel@tonic-gate } 9627c478bd9Sstevel@tonic-gate if (read(fd, obuf, cyl_size) == cyl_size) { 9637c478bd9Sstevel@tonic-gate /* write some progress msg */ 9647c478bd9Sstevel@tonic-gate /* when each cylinder is done. */ 9657c478bd9Sstevel@tonic-gate if (!q_flag) 9667c478bd9Sstevel@tonic-gate (void) printf("."); 9677c478bd9Sstevel@tonic-gate } else { 9687c478bd9Sstevel@tonic-gate if (!q_flag) 9697c478bd9Sstevel@tonic-gate (void) printf(gettext("e\n")); 9707c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 9717c478bd9Sstevel@tonic-gate "%s: can't read format data, "), myname); 9727c478bd9Sstevel@tonic-gate perror(nullstring); 9737c478bd9Sstevel@tonic-gate /* restore the default characteristics */ 9747c478bd9Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, 9757c478bd9Sstevel@tonic-gate save_allmap); 9767c478bd9Sstevel@tonic-gate 9777c478bd9Sstevel@tonic-gate exit(3); 9787c478bd9Sstevel@tonic-gate } 9797c478bd9Sstevel@tonic-gate } else 9807c478bd9Sstevel@tonic-gate if (!q_flag) 9817c478bd9Sstevel@tonic-gate (void) printf("."); 9827c478bd9Sstevel@tonic-gate if (!q_flag) 9837c478bd9Sstevel@tonic-gate (void) fflush(stdout); 9847c478bd9Sstevel@tonic-gate } 9857c478bd9Sstevel@tonic-gate if (!q_flag) 9867c478bd9Sstevel@tonic-gate (void) printf("\n"); 9877c478bd9Sstevel@tonic-gate skipformat: 9887c478bd9Sstevel@tonic-gate if (v_flag) { 9897c478bd9Sstevel@tonic-gate /* 9907c478bd9Sstevel@tonic-gate * do a write & read verify of the entire diskette 9917c478bd9Sstevel@tonic-gate */ 9927c478bd9Sstevel@tonic-gate if (!q_flag && x_flag) 9937c478bd9Sstevel@tonic-gate (void) printf(gettext("Verifying %s in %s\n"), 9947c478bd9Sstevel@tonic-gate capacity, real_name); 9957c478bd9Sstevel@tonic-gate 9967c478bd9Sstevel@tonic-gate for (cyl = 0; cyl < (int)num_cyl; cyl++) { 9977c478bd9Sstevel@tonic-gate 9987c478bd9Sstevel@tonic-gate int val; 9997c478bd9Sstevel@tonic-gate if ((val = verify(fd, 2 * spt * cyl, cyl_size)) != 0) { 10007c478bd9Sstevel@tonic-gate perror(nullstring); 10017c478bd9Sstevel@tonic-gate 10027c478bd9Sstevel@tonic-gate /* restore the default characteristics */ 10037c478bd9Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, 10047c478bd9Sstevel@tonic-gate save_allmap); 10057c478bd9Sstevel@tonic-gate 10067c478bd9Sstevel@tonic-gate exit(val); 10077c478bd9Sstevel@tonic-gate 10087c478bd9Sstevel@tonic-gate } 10097c478bd9Sstevel@tonic-gate /* write some progress msg as */ 10107c478bd9Sstevel@tonic-gate /* each cylinder is done. */ 10117c478bd9Sstevel@tonic-gate if (!q_flag) 10127c478bd9Sstevel@tonic-gate (void) printf(gettext("v")); 10137c478bd9Sstevel@tonic-gate (void) fflush(stdout); 10147c478bd9Sstevel@tonic-gate } 10157c478bd9Sstevel@tonic-gate if (!q_flag) 10167c478bd9Sstevel@tonic-gate (void) printf("\n"); 10177c478bd9Sstevel@tonic-gate } 10187c478bd9Sstevel@tonic-gate 10197c478bd9Sstevel@tonic-gate if (lseek(fd, (off_t)0, 0) != 0) { 10207c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("%s: seek to blk 0 failed, "), 10217c478bd9Sstevel@tonic-gate myname); 10227c478bd9Sstevel@tonic-gate perror(nullstring); 10237c478bd9Sstevel@tonic-gate /* restore the default characteristics */ 10247c478bd9Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, save_allmap); 10257c478bd9Sstevel@tonic-gate 10267c478bd9Sstevel@tonic-gate exit(3); 10277c478bd9Sstevel@tonic-gate } 10287c478bd9Sstevel@tonic-gate 10297c478bd9Sstevel@tonic-gate } 10307c478bd9Sstevel@tonic-gate 10317c478bd9Sstevel@tonic-gate 10327c478bd9Sstevel@tonic-gate /* 10337c478bd9Sstevel@tonic-gate * Restore the default characteristics of the floppy diskette. 10347c478bd9Sstevel@tonic-gate * Fdformat changes the characteristics in the process of formatting. 10357c478bd9Sstevel@tonic-gate * If fdformat fails while in the process of doing the format, fdformat 10367c478bd9Sstevel@tonic-gate * should clean up after itself and reset the driver back to the original 10377c478bd9Sstevel@tonic-gate * state. 10387c478bd9Sstevel@tonic-gate */ 10397c478bd9Sstevel@tonic-gate 10407c478bd9Sstevel@tonic-gate static void 10417c478bd9Sstevel@tonic-gate restore_default_chars(int fd, 10427c478bd9Sstevel@tonic-gate struct fd_char save_fdchar, 10437c478bd9Sstevel@tonic-gate struct dk_allmap save_allmap) 10447c478bd9Sstevel@tonic-gate { 10457c478bd9Sstevel@tonic-gate 10467c478bd9Sstevel@tonic-gate 10477c478bd9Sstevel@tonic-gate /* 10487c478bd9Sstevel@tonic-gate * When this function is called, fdformat is failing anyways, 10497c478bd9Sstevel@tonic-gate * so the errors are not processed. 10507c478bd9Sstevel@tonic-gate */ 10517c478bd9Sstevel@tonic-gate 10527c478bd9Sstevel@tonic-gate (void) ioctl(fd, FDIOSCHAR, &save_fdchar); 10537c478bd9Sstevel@tonic-gate 10547c478bd9Sstevel@tonic-gate (void) ioctl(fd, DKIOCSAPART, &save_allmap); 10557c478bd9Sstevel@tonic-gate 10567c478bd9Sstevel@tonic-gate /* 10577c478bd9Sstevel@tonic-gate * Before looking at the diskette's characteristics, format_diskette() 10587c478bd9Sstevel@tonic-gate * sets the x86 floppy driver to the default characteristics. 10597c478bd9Sstevel@tonic-gate * restore drive to default geometry and 10607c478bd9Sstevel@tonic-gate * characteristics. This ioctl isn't implemented on 10617c478bd9Sstevel@tonic-gate * sparc. 10627c478bd9Sstevel@tonic-gate */ 10637c478bd9Sstevel@tonic-gate (void) ioctl(fd, FDDEFGEOCHAR, NULL); 10647c478bd9Sstevel@tonic-gate 10657c478bd9Sstevel@tonic-gate } 10667c478bd9Sstevel@tonic-gate 10677c478bd9Sstevel@tonic-gate /* 10687c478bd9Sstevel@tonic-gate * See if any partitions on the device are mounted. Return 1 if a partition is 10697c478bd9Sstevel@tonic-gate * mounted. Return 0 otherwise. 10707c478bd9Sstevel@tonic-gate */ 10717c478bd9Sstevel@tonic-gate static int 10727c478bd9Sstevel@tonic-gate check_mount() 10737c478bd9Sstevel@tonic-gate { 10747c478bd9Sstevel@tonic-gate FILE *fp = NULL; 10757c478bd9Sstevel@tonic-gate int mfd; 10767c478bd9Sstevel@tonic-gate struct dk_cinfo dkinfo_tmp; 10777c478bd9Sstevel@tonic-gate struct mnttab mnt_record; 10787c478bd9Sstevel@tonic-gate struct mnttab *mp = &mnt_record; 10797c478bd9Sstevel@tonic-gate struct stat stbuf; 10807c478bd9Sstevel@tonic-gate char raw_device[MAXPATHLEN]; 10817c478bd9Sstevel@tonic-gate int found = 0; 10827c478bd9Sstevel@tonic-gate 10837c478bd9Sstevel@tonic-gate if ((fp = fopen(MNTTAB, "r")) == NULL) { 10847c478bd9Sstevel@tonic-gate perror(MNTTAB); 10857c478bd9Sstevel@tonic-gate exit(3); 10867c478bd9Sstevel@tonic-gate } 10877c478bd9Sstevel@tonic-gate 10887c478bd9Sstevel@tonic-gate while (getmntent(fp, mp) == 0) { 10897c478bd9Sstevel@tonic-gate if (strstr(mp->mnt_special, "/dev/fd") == NULL && 10907c478bd9Sstevel@tonic-gate strstr(mp->mnt_special, "/dev/disket") == NULL && 10917c478bd9Sstevel@tonic-gate strstr(mp->mnt_special, "/dev/c") == NULL) { 10927c478bd9Sstevel@tonic-gate continue; 10937c478bd9Sstevel@tonic-gate } 10947c478bd9Sstevel@tonic-gate 10957c478bd9Sstevel@tonic-gate (void) strcpy(raw_device, "/dev/r"); 10967c478bd9Sstevel@tonic-gate (void) strcat(raw_device, mp->mnt_special + strlen("/dev/")); 10977c478bd9Sstevel@tonic-gate 10987c478bd9Sstevel@tonic-gate /* 10997c478bd9Sstevel@tonic-gate * Attempt to open the device. If it fails, skip it. 11007c478bd9Sstevel@tonic-gate */ 11017c478bd9Sstevel@tonic-gate if ((mfd = open(raw_device, O_RDWR | O_NDELAY)) < 0) { 11027c478bd9Sstevel@tonic-gate continue; 11037c478bd9Sstevel@tonic-gate } 11047c478bd9Sstevel@tonic-gate 11057c478bd9Sstevel@tonic-gate /* 11067c478bd9Sstevel@tonic-gate * Must be a character device 11077c478bd9Sstevel@tonic-gate */ 11087c478bd9Sstevel@tonic-gate if (fstat(mfd, &stbuf) == -1 || !S_ISCHR(stbuf.st_mode)) { 11097c478bd9Sstevel@tonic-gate (void) close(mfd); 11107c478bd9Sstevel@tonic-gate continue; 11117c478bd9Sstevel@tonic-gate } 11127c478bd9Sstevel@tonic-gate /* 11137c478bd9Sstevel@tonic-gate * Attempt to read the configuration info on the disk. 11147c478bd9Sstevel@tonic-gate */ 11157c478bd9Sstevel@tonic-gate if (ioctl(mfd, DKIOCINFO, &dkinfo_tmp) < 0) { 11167c478bd9Sstevel@tonic-gate (void) close(mfd); 11177c478bd9Sstevel@tonic-gate continue; 11187c478bd9Sstevel@tonic-gate } 11197c478bd9Sstevel@tonic-gate /* 11207c478bd9Sstevel@tonic-gate * Finished with the opened device 11217c478bd9Sstevel@tonic-gate */ 11227c478bd9Sstevel@tonic-gate (void) close(mfd); 11237c478bd9Sstevel@tonic-gate 11247c478bd9Sstevel@tonic-gate /* 11257c478bd9Sstevel@tonic-gate * If it's not the disk we're interested in, it doesn't apply. 11267c478bd9Sstevel@tonic-gate */ 11277c478bd9Sstevel@tonic-gate if (dkinfo.dki_ctype != dkinfo_tmp.dki_ctype || 11287c478bd9Sstevel@tonic-gate dkinfo.dki_cnum != dkinfo_tmp.dki_cnum || 11297c478bd9Sstevel@tonic-gate dkinfo.dki_unit != dkinfo_tmp.dki_unit) { 11307c478bd9Sstevel@tonic-gate continue; 11317c478bd9Sstevel@tonic-gate } 11327c478bd9Sstevel@tonic-gate /* 11337c478bd9Sstevel@tonic-gate * It's a mount on the disk we're checking. If we are 11347c478bd9Sstevel@tonic-gate * checking whole disk, then we found trouble. We can 11357c478bd9Sstevel@tonic-gate * quit searching. 11367c478bd9Sstevel@tonic-gate */ 11377c478bd9Sstevel@tonic-gate 11387c478bd9Sstevel@tonic-gate if (U_flag) { 11397c478bd9Sstevel@tonic-gate if (!_dev_unmount(mp->mnt_special)) { 11407c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 11417c478bd9Sstevel@tonic-gate gettext("%s: umount of %s failed\n"), 11427c478bd9Sstevel@tonic-gate myname, mp->mnt_special); 11437c478bd9Sstevel@tonic-gate found = 1; 11447c478bd9Sstevel@tonic-gate } 11457c478bd9Sstevel@tonic-gate } else { 11467c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 11477c478bd9Sstevel@tonic-gate gettext("%s: %s is mounted (use -U flag)\n"), 11487c478bd9Sstevel@tonic-gate myname, mp->mnt_special); 11497c478bd9Sstevel@tonic-gate found = 1; 11507c478bd9Sstevel@tonic-gate } 11517c478bd9Sstevel@tonic-gate } 11527c478bd9Sstevel@tonic-gate return (found); 11537c478bd9Sstevel@tonic-gate } 11547c478bd9Sstevel@tonic-gate 11557c478bd9Sstevel@tonic-gate static void 11567c478bd9Sstevel@tonic-gate usage(char *str) 11577c478bd9Sstevel@tonic-gate { 11587c478bd9Sstevel@tonic-gate char *real_name, *alias_name; 11597c478bd9Sstevel@tonic-gate 11607c478bd9Sstevel@tonic-gate if ((real_name = media_findname("floppy")) == NULL) { 11617c478bd9Sstevel@tonic-gate if ((alias_name = _media_oldaliases("floppy")) != NULL) 11627c478bd9Sstevel@tonic-gate real_name = media_findname(alias_name); 11637c478bd9Sstevel@tonic-gate } 11647c478bd9Sstevel@tonic-gate 11657c478bd9Sstevel@tonic-gate if (str[0] != ' ') 11667c478bd9Sstevel@tonic-gate (void) printf("%s: %s\n", myname, str); 11677c478bd9Sstevel@tonic-gate (void) printf(gettext( 11687c478bd9Sstevel@tonic-gate /*CSTYLED*/ 11697c478bd9Sstevel@tonic-gate "\n usage: %s [-dDeEfHlLmMqUvx] [-b label] [-B file] [-t dostype] [devname]\n"), 11707c478bd9Sstevel@tonic-gate myname); 11717c478bd9Sstevel@tonic-gate 11727c478bd9Sstevel@tonic-gate (void) printf(gettext( 11737c478bd9Sstevel@tonic-gate /*CSTYLED*/ 11747c478bd9Sstevel@tonic-gate " -b label install \"label\" on media\n")); 11757c478bd9Sstevel@tonic-gate (void) printf(gettext( 11767c478bd9Sstevel@tonic-gate " -B file install special boot loader on MS-DOS media\n")); 11777c478bd9Sstevel@tonic-gate (void) printf(gettext( 11787c478bd9Sstevel@tonic-gate /*CSTYLED*/ 11797c478bd9Sstevel@tonic-gate " -d format MS-DOS media\n")); 11807c478bd9Sstevel@tonic-gate (void) printf(gettext( 11817c478bd9Sstevel@tonic-gate /*CSTYLED*/ 11827c478bd9Sstevel@tonic-gate " -D format 720KB (3.5\") or 360KB (5.25\") Double-density diskette\n")); 11837c478bd9Sstevel@tonic-gate (void) printf(gettext( 11847c478bd9Sstevel@tonic-gate " -e eject the media when done\n")); 11857c478bd9Sstevel@tonic-gate /*CSTYLED*/ 11867c478bd9Sstevel@tonic-gate (void) printf(gettext( 11877c478bd9Sstevel@tonic-gate /*CSTYLED*/ 11887c478bd9Sstevel@tonic-gate " -E format 2.88MB (3.5\") Extended-density diskette\n")); 11897c478bd9Sstevel@tonic-gate (void) printf(gettext( 11907c478bd9Sstevel@tonic-gate " -f \"force\" - don't wait for confirmation\n")); 11917c478bd9Sstevel@tonic-gate (void) printf(gettext( 11927c478bd9Sstevel@tonic-gate /*CSTYLED*/ 11937c478bd9Sstevel@tonic-gate " -H format 1.44MB (3.5\") or 1.2MB (5.25\") High-density diskette\n")); 11947c478bd9Sstevel@tonic-gate (void) printf(gettext( 11957c478bd9Sstevel@tonic-gate /*CSTYLED*/ 11967c478bd9Sstevel@tonic-gate " -l format 720KB (3.5\") or 360KB (5.25\") Double-density diskette\n")); 11977c478bd9Sstevel@tonic-gate (void) printf(gettext( 11987c478bd9Sstevel@tonic-gate /*CSTYLED*/ 11997c478bd9Sstevel@tonic-gate " -L format 720KB (3.5\") or 360KB (5.25\") Double-density diskette\n")); 12007c478bd9Sstevel@tonic-gate (void) printf(gettext( 12017c478bd9Sstevel@tonic-gate " -m format 1.2MB (3.5\") Medium-density diskette\n")); 12027c478bd9Sstevel@tonic-gate (void) printf(gettext( 12037c478bd9Sstevel@tonic-gate " -M format 1.2MB (3.5\") Medium-density diskette\n")); 12047c478bd9Sstevel@tonic-gate (void) printf(gettext( 12057c478bd9Sstevel@tonic-gate " -q quiet\n")); 12067c478bd9Sstevel@tonic-gate (void) printf(gettext( 12077c478bd9Sstevel@tonic-gate /*CSTYLED*/ 12087c478bd9Sstevel@tonic-gate " -t dos format MS-DOS media (same as -d)\n")); 12097c478bd9Sstevel@tonic-gate (void) printf(gettext( 12107c478bd9Sstevel@tonic-gate " -t nec format NEC-DOS media (with -M only)\n")); 12117c478bd9Sstevel@tonic-gate (void) printf(gettext( 12127c478bd9Sstevel@tonic-gate /*CSTYLED*/ 12137c478bd9Sstevel@tonic-gate " -U unmount media if it's mounted\n")); 12147c478bd9Sstevel@tonic-gate (void) printf(gettext( 12157c478bd9Sstevel@tonic-gate " -v verify each block of the media\n")); 12167c478bd9Sstevel@tonic-gate (void) printf(gettext( 12177c478bd9Sstevel@tonic-gate " -x skip the format, only install SunOS or DOS label\n")); 12187c478bd9Sstevel@tonic-gate 12197c478bd9Sstevel@tonic-gate (void) printf(gettext( 12207c478bd9Sstevel@tonic-gate " devname defaults to '%s'\n"), 12217c478bd9Sstevel@tonic-gate real_name ? real_name : gettext("no available default device")); 12227c478bd9Sstevel@tonic-gate 12237c478bd9Sstevel@tonic-gate exit(1); 12247c478bd9Sstevel@tonic-gate 12257c478bd9Sstevel@tonic-gate } 12267c478bd9Sstevel@tonic-gate 12277c478bd9Sstevel@tonic-gate 12287c478bd9Sstevel@tonic-gate static int 12297c478bd9Sstevel@tonic-gate verify(int fd, int blk, int len) 12307c478bd9Sstevel@tonic-gate { 12317c478bd9Sstevel@tonic-gate off_t off; 12327c478bd9Sstevel@tonic-gate char *nullstring = ""; 12337c478bd9Sstevel@tonic-gate 12347c478bd9Sstevel@tonic-gate off = (off_t)(blk * (m_flag ? 1024 : 512)); 12357c478bd9Sstevel@tonic-gate 12367c478bd9Sstevel@tonic-gate if (lseek(fd, off, 0) != off) { 12377c478bd9Sstevel@tonic-gate if (!q_flag) 12387c478bd9Sstevel@tonic-gate (void) printf(gettext("e\n")); 12397c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 12407c478bd9Sstevel@tonic-gate gettext("%s: can't seek to write verify, "), myname); 12417c478bd9Sstevel@tonic-gate perror(nullstring); 12427c478bd9Sstevel@tonic-gate return (4); 12437c478bd9Sstevel@tonic-gate } 12447c478bd9Sstevel@tonic-gate if (write(fd, ibuf1, len) != len) { 12457c478bd9Sstevel@tonic-gate if (!q_flag) 12467c478bd9Sstevel@tonic-gate (void) printf(gettext("e\n")); 12477c478bd9Sstevel@tonic-gate if (blk == 0) 12487c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 12497c478bd9Sstevel@tonic-gate gettext("%s: check diskette density, "), 12507c478bd9Sstevel@tonic-gate myname); 12517c478bd9Sstevel@tonic-gate else 12527c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 12537c478bd9Sstevel@tonic-gate gettext("%s: can't write verify data, "), 12547c478bd9Sstevel@tonic-gate myname); 12557c478bd9Sstevel@tonic-gate perror(nullstring); 12567c478bd9Sstevel@tonic-gate return (4); 12577c478bd9Sstevel@tonic-gate } 12587c478bd9Sstevel@tonic-gate 12597c478bd9Sstevel@tonic-gate if (lseek(fd, off, 0) != off) { 12607c478bd9Sstevel@tonic-gate if (!q_flag) 12617c478bd9Sstevel@tonic-gate (void) printf(gettext("e\n")); 12627c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 12637c478bd9Sstevel@tonic-gate gettext("%s: bad seek to read verify, "), 12647c478bd9Sstevel@tonic-gate myname); 12657c478bd9Sstevel@tonic-gate perror(nullstring); 12667c478bd9Sstevel@tonic-gate return (4); 12677c478bd9Sstevel@tonic-gate } 12687c478bd9Sstevel@tonic-gate if (read(fd, obuf, len) != len) { 12697c478bd9Sstevel@tonic-gate if (!q_flag) 12707c478bd9Sstevel@tonic-gate (void) printf(gettext("e\n")); 12717c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 12727c478bd9Sstevel@tonic-gate gettext("%s: can't read verify data, "), myname); 12737c478bd9Sstevel@tonic-gate perror(nullstring); 12747c478bd9Sstevel@tonic-gate return (4); 12757c478bd9Sstevel@tonic-gate } 12767c478bd9Sstevel@tonic-gate if (memcmp(ibuf1, obuf, len)) { 12777c478bd9Sstevel@tonic-gate if (!q_flag) 12787c478bd9Sstevel@tonic-gate (void) printf(gettext("e\n")); 12797c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("%s: verify data failure\n"), 12807c478bd9Sstevel@tonic-gate myname); 12817c478bd9Sstevel@tonic-gate return (4); 12827c478bd9Sstevel@tonic-gate } 12837c478bd9Sstevel@tonic-gate return (0); 12847c478bd9Sstevel@tonic-gate } 12857c478bd9Sstevel@tonic-gate 12867c478bd9Sstevel@tonic-gate /* 12877c478bd9Sstevel@tonic-gate * write a SunOS label 12887c478bd9Sstevel@tonic-gate * NOTE: this function assumes fd_vtoc has been filled in with the 12897c478bd9Sstevel@tonic-gate * device specific information such as partition information 12907c478bd9Sstevel@tonic-gate * and the asciilabel 12917c478bd9Sstevel@tonic-gate */ 12927c478bd9Sstevel@tonic-gate static void 12937c478bd9Sstevel@tonic-gate write_SunOS_label(int fd, char *volname, struct vtoc *fd_vtoc) 12947c478bd9Sstevel@tonic-gate { 12957c478bd9Sstevel@tonic-gate char *nullstring = ""; 12967c478bd9Sstevel@tonic-gate 12977c478bd9Sstevel@tonic-gate fd_vtoc->v_sanity = VTOC_SANE; 12987c478bd9Sstevel@tonic-gate 12997c478bd9Sstevel@tonic-gate /* 13007c478bd9Sstevel@tonic-gate * The label structure is set up for DEV_BSIZE (512 byte) blocks, 13017c478bd9Sstevel@tonic-gate * even though a medium density diskette has 1024 byte blocks 13027c478bd9Sstevel@tonic-gate * See dklabel.h for more details. 13037c478bd9Sstevel@tonic-gate */ 13047c478bd9Sstevel@tonic-gate fd_vtoc->v_sectorsz = DEV_BSIZE; 13057c478bd9Sstevel@tonic-gate 13067c478bd9Sstevel@tonic-gate (void) strncpy(fd_vtoc->v_volume, volname, sizeof (fd_vtoc->v_volume)); 13077c478bd9Sstevel@tonic-gate 13087c478bd9Sstevel@tonic-gate /* let the fd driver finish constructing the label and writing it */ 13097c478bd9Sstevel@tonic-gate if (ioctl(fd, DKIOCSVTOC, fd_vtoc) == -1) { 13107c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 13117c478bd9Sstevel@tonic-gate gettext("%s: write of SunOS label failed, "), myname); 13127c478bd9Sstevel@tonic-gate perror(nullstring); 13137c478bd9Sstevel@tonic-gate exit(3); 13147c478bd9Sstevel@tonic-gate } 13157c478bd9Sstevel@tonic-gate 13167c478bd9Sstevel@tonic-gate } 13177c478bd9Sstevel@tonic-gate 13187c478bd9Sstevel@tonic-gate 13197c478bd9Sstevel@tonic-gate /* 13207c478bd9Sstevel@tonic-gate * MS-DOS Disk layout: 13217c478bd9Sstevel@tonic-gate * 13227c478bd9Sstevel@tonic-gate * --------------------- 13237c478bd9Sstevel@tonic-gate * | Boot sector | 13247c478bd9Sstevel@tonic-gate * |-------------------| 13257c478bd9Sstevel@tonic-gate * | Reserved area | 13267c478bd9Sstevel@tonic-gate * |-------------------| 13277c478bd9Sstevel@tonic-gate * | FAT #1 | 13287c478bd9Sstevel@tonic-gate * |-------------------| 13297c478bd9Sstevel@tonic-gate * | FAT #2 | 13307c478bd9Sstevel@tonic-gate * |-------------------| 13317c478bd9Sstevel@tonic-gate * | Root directory | 13327c478bd9Sstevel@tonic-gate * |-------------------| 13337c478bd9Sstevel@tonic-gate * | | 13347c478bd9Sstevel@tonic-gate * | File area | 13357c478bd9Sstevel@tonic-gate * |___________________| 13367c478bd9Sstevel@tonic-gate */ 13377c478bd9Sstevel@tonic-gate 13387c478bd9Sstevel@tonic-gate /* 13397c478bd9Sstevel@tonic-gate * The following is a copy of MS-DOS 3.3 boot block. 13407c478bd9Sstevel@tonic-gate * It consists of the BIOS parameter block, and a disk 13417c478bd9Sstevel@tonic-gate * bootstrap program. 13427c478bd9Sstevel@tonic-gate * 13437c478bd9Sstevel@tonic-gate * The BIOS parameter block contains the right values 13447c478bd9Sstevel@tonic-gate * for the 3.5" high-density 1.44MB floppy format. 13457c478bd9Sstevel@tonic-gate * 13467c478bd9Sstevel@tonic-gate */ 13477c478bd9Sstevel@tonic-gate static uchar_t bootsec[512] = { 13487c478bd9Sstevel@tonic-gate 0xeb, 0x34, 0x90, /* 8086 short jump + displacement + NOP */ 13497c478bd9Sstevel@tonic-gate 'M', 'S', 'D', 'O', 'S', '3', '.', '3', /* OEM name & version */ 13507c478bd9Sstevel@tonic-gate 0, 2, 1, 1, 0, /* Start of BIOS parameter block */ 13517c478bd9Sstevel@tonic-gate 2, 224, 0, 0x40, 0xb, 0xf0, 9, 0, 13527c478bd9Sstevel@tonic-gate 18, 0, 2, 0, 0, 0, /* End of BIOS parameter block */ 13537c478bd9Sstevel@tonic-gate 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 13547c478bd9Sstevel@tonic-gate 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 13557c478bd9Sstevel@tonic-gate 0x0, 0x0, 0x0, 0x0, 13567c478bd9Sstevel@tonic-gate 0x1, 0x0, 0xfa, 0x33, /* 0x34, start of the bootstrap. */ 13577c478bd9Sstevel@tonic-gate 0xc0, 0x8e, 0xd0, 0xbc, 0x0, 0x7c, 0x16, 0x7, 13587c478bd9Sstevel@tonic-gate 0xbb, 0x78, 0x0, 0x36, 0xc5, 0x37, 0x1e, 0x56, 13597c478bd9Sstevel@tonic-gate 0x16, 0x53, 0xbf, 0x2b, 0x7c, 0xb9, 0xb, 0x0, 13607c478bd9Sstevel@tonic-gate 0xfc, 0xac, 0x26, 0x80, 0x3d, 0x0, 0x74, 0x3, 13617c478bd9Sstevel@tonic-gate 0x26, 0x8a, 0x5, 0xaa, 0x8a, 0xc4, 0xe2, 0xf1, 13627c478bd9Sstevel@tonic-gate 0x6, 0x1f, 0x89, 0x47, 0x2, 0xc7, 0x7, 0x2b, 13637c478bd9Sstevel@tonic-gate 0x7c, 0xfb, 0xcd, 0x13, 0x72, 0x67, 0xa0, 0x10, 13647c478bd9Sstevel@tonic-gate 0x7c, 0x98, 0xf7, 0x26, 0x16, 0x7c, 0x3, 0x6, 13657c478bd9Sstevel@tonic-gate 0x1c, 0x7c, 0x3, 0x6, 0xe, 0x7c, 0xa3, 0x3f, 13667c478bd9Sstevel@tonic-gate 0x7c, 0xa3, 0x37, 0x7c, 0xb8, 0x20, 0x0, 0xf7, 13677c478bd9Sstevel@tonic-gate 0x26, 0x11, 0x7c, 0x8b, 0x1e, 0xb, 0x7c, 0x3, 13687c478bd9Sstevel@tonic-gate 0xc3, 0x48, 0xf7, 0xf3, 0x1, 0x6, 0x37, 0x7c, 13697c478bd9Sstevel@tonic-gate 0xbb, 0x0, 0x5, 0xa1, 0x3f, 0x7c, 0xe8, 0x9f, 13707c478bd9Sstevel@tonic-gate 0x0, 0xb8, 0x1, 0x2, 0xe8, 0xb3, 0x0, 0x72, 13717c478bd9Sstevel@tonic-gate 0x19, 0x8b, 0xfb, 0xb9, 0xb, 0x0, 0xbe, 0xd6, 13727c478bd9Sstevel@tonic-gate 0x7d, 0xf3, 0xa6, 0x75, 0xd, 0x8d, 0x7f, 0x20, 13737c478bd9Sstevel@tonic-gate 0xbe, 0xe1, 0x7d, 0xb9, 0xb, 0x0, 0xf3, 0xa6, 13747c478bd9Sstevel@tonic-gate 0x74, 0x18, 0xbe, 0x77, 0x7d, 0xe8, 0x6a, 0x0, 13757c478bd9Sstevel@tonic-gate 0x32, 0xe4, 0xcd, 0x16, 0x5e, 0x1f, 0x8f, 0x4, 13767c478bd9Sstevel@tonic-gate 0x8f, 0x44, 0x2, 0xcd, 0x19, 0xbe, 0xc0, 0x7d, 13777c478bd9Sstevel@tonic-gate 0xeb, 0xeb, 0xa1, 0x1c, 0x5, 0x33, 0xd2, 0xf7, 13787c478bd9Sstevel@tonic-gate 0x36, 0xb, 0x7c, 0xfe, 0xc0, 0xa2, 0x3c, 0x7c, 13797c478bd9Sstevel@tonic-gate 0xa1, 0x37, 0x7c, 0xa3, 0x3d, 0x7c, 0xbb, 0x0, 13807c478bd9Sstevel@tonic-gate 0x7, 0xa1, 0x37, 0x7c, 0xe8, 0x49, 0x0, 0xa1, 13817c478bd9Sstevel@tonic-gate 0x18, 0x7c, 0x2a, 0x6, 0x3b, 0x7c, 0x40, 0x38, 13827c478bd9Sstevel@tonic-gate 0x6, 0x3c, 0x7c, 0x73, 0x3, 0xa0, 0x3c, 0x7c, 13837c478bd9Sstevel@tonic-gate 0x50, 0xe8, 0x4e, 0x0, 0x58, 0x72, 0xc6, 0x28, 13847c478bd9Sstevel@tonic-gate 0x6, 0x3c, 0x7c, 0x74, 0xc, 0x1, 0x6, 0x37, 13857c478bd9Sstevel@tonic-gate 0x7c, 0xf7, 0x26, 0xb, 0x7c, 0x3, 0xd8, 0xeb, 13867c478bd9Sstevel@tonic-gate 0xd0, 0x8a, 0x2e, 0x15, 0x7c, 0x8a, 0x16, 0xfd, 13877c478bd9Sstevel@tonic-gate 0x7d, 0x8b, 0x1e, 0x3d, 0x7c, 0xea, 0x0, 0x0, 13887c478bd9Sstevel@tonic-gate 0x70, 0x0, 0xac, 0xa, 0xc0, 0x74, 0x22, 0xb4, 13897c478bd9Sstevel@tonic-gate 0xe, 0xbb, 0x7, 0x0, 0xcd, 0x10, 0xeb, 0xf2, 13907c478bd9Sstevel@tonic-gate 0x33, 0xd2, 0xf7, 0x36, 0x18, 0x7c, 0xfe, 0xc2, 13917c478bd9Sstevel@tonic-gate 0x88, 0x16, 0x3b, 0x7c, 0x33, 0xd2, 0xf7, 0x36, 13927c478bd9Sstevel@tonic-gate 0x1a, 0x7c, 0x88, 0x16, 0x2a, 0x7c, 0xa3, 0x39, 13937c478bd9Sstevel@tonic-gate 0x7c, 0xc3, 0xb4, 0x2, 0x8b, 0x16, 0x39, 0x7c, 13947c478bd9Sstevel@tonic-gate 0xb1, 0x6, 0xd2, 0xe6, 0xa, 0x36, 0x3b, 0x7c, 13957c478bd9Sstevel@tonic-gate 0x8b, 0xca, 0x86, 0xe9, 0x8a, 0x16, 0xfd, 0x7d, 13967c478bd9Sstevel@tonic-gate 0x8a, 0x36, 0x2a, 0x7c, 0xcd, 0x13, 0xc3, '\r', 13977c478bd9Sstevel@tonic-gate '\n', 'N', 'o', 'n', '-', 'S', 'y', 's', 13987c478bd9Sstevel@tonic-gate 't', 'e', 'm', ' ', 'd', 'i', 's', 'k', 13997c478bd9Sstevel@tonic-gate ' ', 'o', 'r', ' ', 'd', 'i', 's', 'k', 14007c478bd9Sstevel@tonic-gate ' ', 'e', 'r', 'r', 'o', 'r', '\r', '\n', 14017c478bd9Sstevel@tonic-gate 'R', 'e', 'p', 'l', 'a', 'c', 'e', ' ', 14027c478bd9Sstevel@tonic-gate 'a', 'n', 'd', ' ', 's', 't', 'r', 'i', 14037c478bd9Sstevel@tonic-gate 'k', 'e', ' ', 'a', 'n', 'y', ' ', 'k', 14047c478bd9Sstevel@tonic-gate 'e', 'y', ' ', 'w', 'h', 'e', 'n', ' ', 14057c478bd9Sstevel@tonic-gate 'r', 'e', 'a', 'd', 'y', '\r', '\n', '\0', 14067c478bd9Sstevel@tonic-gate '\r', '\n', 'D', 'i', 's', 'k', ' ', 'B', 14077c478bd9Sstevel@tonic-gate 'o', 'o', 't', ' ', 'f', 'a', 'i', 'l', 14087c478bd9Sstevel@tonic-gate 'u', 'r', 'e', '\r', '\n', '\0', 'I', 'O', 14097c478bd9Sstevel@tonic-gate ' ', ' ', ' ', ' ', ' ', ' ', 'S', 'Y', 14107c478bd9Sstevel@tonic-gate 'S', 'M', 'S', 'D', 'O', 'S', ' ', ' ', 14117c478bd9Sstevel@tonic-gate ' ', 'S', 'Y', 'S', '\0', 0, 0, 0, 14127c478bd9Sstevel@tonic-gate 0, 0, 0, 0, 0, 0, 0, 0, 0, 14137c478bd9Sstevel@tonic-gate 0, 0, 0, 0, 0, 0x55, 0xaa 14147c478bd9Sstevel@tonic-gate }; 14157c478bd9Sstevel@tonic-gate 14167c478bd9Sstevel@tonic-gate static int 14177c478bd9Sstevel@tonic-gate valid_DOS_boot(char *bootfile, uchar_t **bootloadp) 14187c478bd9Sstevel@tonic-gate { 14197c478bd9Sstevel@tonic-gate struct stat status; 14207c478bd9Sstevel@tonic-gate size_t sizebootldr; 14217c478bd9Sstevel@tonic-gate uchar_t *bootloader; 14227c478bd9Sstevel@tonic-gate int bfd; 14237c478bd9Sstevel@tonic-gate int boot_size = 0; 14247c478bd9Sstevel@tonic-gate int err; 14257c478bd9Sstevel@tonic-gate char *nullstring = ""; 14267c478bd9Sstevel@tonic-gate 1427*a388614eSIgor Kozhukhov if ((err = stat(bootfile, &status)) != 0) { 14287c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("%s: \"%s\" stat error %d\n"), 14297c478bd9Sstevel@tonic-gate myname, bootfile, err); 14307c478bd9Sstevel@tonic-gate return (0); 14317c478bd9Sstevel@tonic-gate } 14327c478bd9Sstevel@tonic-gate if ((boot_size = status.st_size) < 512) { 14337c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 14347c478bd9Sstevel@tonic-gate gettext("%s: short boot sector"), myname); 14357c478bd9Sstevel@tonic-gate perror(nullstring); 14367c478bd9Sstevel@tonic-gate return (0); 14377c478bd9Sstevel@tonic-gate } 14387c478bd9Sstevel@tonic-gate sizebootldr = (boot_size + 511) / 512 * 512; 14397c478bd9Sstevel@tonic-gate if ((bootloader = (uchar_t *)malloc((size_t)sizebootldr)) == NULL) { 14407c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("%s: malloc error\n"), 14417c478bd9Sstevel@tonic-gate myname); 14427c478bd9Sstevel@tonic-gate return (0); 14437c478bd9Sstevel@tonic-gate } 14447c478bd9Sstevel@tonic-gate 14457c478bd9Sstevel@tonic-gate /* switch to user to access the boot file */ 14467c478bd9Sstevel@tonic-gate (void) seteuid(getuid()); 14477c478bd9Sstevel@tonic-gate 14487c478bd9Sstevel@tonic-gate if ((bfd = open(bootfile, O_RDONLY)) == -1) { 14497c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("%s: could not open \"%s\": "), 14507c478bd9Sstevel@tonic-gate myname, bootfile); 14517c478bd9Sstevel@tonic-gate perror(nullstring); 14527c478bd9Sstevel@tonic-gate return (0); 14537c478bd9Sstevel@tonic-gate } 14547c478bd9Sstevel@tonic-gate 14557c478bd9Sstevel@tonic-gate /* restore effective id */ 14567c478bd9Sstevel@tonic-gate (void) seteuid(euid); 14577c478bd9Sstevel@tonic-gate 14587c478bd9Sstevel@tonic-gate if (read(bfd, bootloader, boot_size) != boot_size) { 14597c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 14607c478bd9Sstevel@tonic-gate gettext("%s: read of MS-DOS boot file failed, "), myname); 14617c478bd9Sstevel@tonic-gate perror(nullstring); 14627c478bd9Sstevel@tonic-gate (void) close(bfd); 14637c478bd9Sstevel@tonic-gate return (0); 14647c478bd9Sstevel@tonic-gate } 14657c478bd9Sstevel@tonic-gate 14667c478bd9Sstevel@tonic-gate if (!((*bootloader == 0xE9 || 14677c478bd9Sstevel@tonic-gate (*bootloader == 0xEB && *(bootloader + 2) == 0x90)) && 14687c478bd9Sstevel@tonic-gate *(bootloader + 510) == 0x55 && 14697c478bd9Sstevel@tonic-gate *(bootloader + 511) == 0xAA)) { 14707c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 14717c478bd9Sstevel@tonic-gate gettext("%s: invalid MS-DOS boot loader image\n"), myname); 14727c478bd9Sstevel@tonic-gate boot_size = 0; 14737c478bd9Sstevel@tonic-gate } 14747c478bd9Sstevel@tonic-gate 14757c478bd9Sstevel@tonic-gate (void) close(bfd); 14767c478bd9Sstevel@tonic-gate *bootloadp = bootloader; 14777c478bd9Sstevel@tonic-gate return (boot_size); 14787c478bd9Sstevel@tonic-gate } 14797c478bd9Sstevel@tonic-gate 14807c478bd9Sstevel@tonic-gate 14817c478bd9Sstevel@tonic-gate static void 14827c478bd9Sstevel@tonic-gate write_DOS_label(int fd, uchar_t *bootloadr, int bootlen, char *altbootname, 14837c478bd9Sstevel@tonic-gate char *doslabel, struct bios_param_blk *bpb, int rdirsec) 14847c478bd9Sstevel@tonic-gate { 14857c478bd9Sstevel@tonic-gate int i, j; 14867c478bd9Sstevel@tonic-gate int bootclen; 14877c478bd9Sstevel@tonic-gate size_t fat_bsize; 14887c478bd9Sstevel@tonic-gate ushort_t totalsec; 14897c478bd9Sstevel@tonic-gate uchar_t *fat_rdir; 14907c478bd9Sstevel@tonic-gate uchar_t *fatptr; 14917c478bd9Sstevel@tonic-gate char *nullstring = ""; 14927c478bd9Sstevel@tonic-gate 14937c478bd9Sstevel@tonic-gate if (bootlen < 512 || !bootloadr) { 14947c478bd9Sstevel@tonic-gate /* use default boot loader routine */ 14957c478bd9Sstevel@tonic-gate bootloadr = bootsec; 14967c478bd9Sstevel@tonic-gate bootlen = 512; 14977c478bd9Sstevel@tonic-gate } else 14987c478bd9Sstevel@tonic-gate (void) printf 14997c478bd9Sstevel@tonic-gate (gettext("%s: using \"%s\" for MS-DOS boot loader\n"), 15007c478bd9Sstevel@tonic-gate myname, altbootname); 15017c478bd9Sstevel@tonic-gate if (bootlen % 512 > 0) 15027c478bd9Sstevel@tonic-gate bootlen = (bootlen + 511) / 512 * 512; 15037c478bd9Sstevel@tonic-gate 15047c478bd9Sstevel@tonic-gate bpb->b_bps[0] = getlobyte(512); 15057c478bd9Sstevel@tonic-gate bpb->b_bps[1] = gethibyte(512); 15067c478bd9Sstevel@tonic-gate /* MS-DOS 5.0 supports only 1 reserved sector :-( */ 15077c478bd9Sstevel@tonic-gate bpb->b_res_sec[0] = 1; 15087c478bd9Sstevel@tonic-gate bpb->b_res_sec[1] = 0; 15097c478bd9Sstevel@tonic-gate 15107c478bd9Sstevel@tonic-gate totalsec = fdchar.fdc_ncyl * fdchar.fdc_nhead * fdchar.fdc_secptrack; 15117c478bd9Sstevel@tonic-gate bpb->b_totalsec[0] = getlobyte(totalsec); 15127c478bd9Sstevel@tonic-gate bpb->b_totalsec[1] = gethibyte(totalsec); 15137c478bd9Sstevel@tonic-gate bpb->b_spt[0] = fdchar.fdc_secptrack; 15147c478bd9Sstevel@tonic-gate bpb->b_spt[1] = 0; 15157c478bd9Sstevel@tonic-gate bpb->b_nhead[0] = fdchar.fdc_nhead; 15167c478bd9Sstevel@tonic-gate bpb->b_nhead[1] = 0; 15177c478bd9Sstevel@tonic-gate bpb->b_hiddensec[0] = 0; 15187c478bd9Sstevel@tonic-gate bpb->b_hiddensec[1] = 0; 15197c478bd9Sstevel@tonic-gate 15207c478bd9Sstevel@tonic-gate bpb->b_rdirents[0] = getlobyte(rdirsec); 15217c478bd9Sstevel@tonic-gate bpb->b_rdirents[1] = gethibyte(rdirsec); 15227c478bd9Sstevel@tonic-gate 15237c478bd9Sstevel@tonic-gate (void) memcpy((char *)(bootloadr + 0x0B), (char *)bpb, 15247c478bd9Sstevel@tonic-gate sizeof (struct bios_param_blk)); 15257c478bd9Sstevel@tonic-gate 15267c478bd9Sstevel@tonic-gate if (write(fd, bootloadr, 512) != 512) { 15277c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 15287c478bd9Sstevel@tonic-gate gettext("%s: write of MS-DOS boot sector failed"), myname); 15297c478bd9Sstevel@tonic-gate perror(nullstring); 15307c478bd9Sstevel@tonic-gate exit(3); 15317c478bd9Sstevel@tonic-gate } 15327c478bd9Sstevel@tonic-gate bootloadr += 512; 15337c478bd9Sstevel@tonic-gate bootlen -= 512; 15347c478bd9Sstevel@tonic-gate 15357c478bd9Sstevel@tonic-gate fat_bsize = 512 * bpb->b_fatsec[0]; 15367c478bd9Sstevel@tonic-gate fat_rdir = (uchar_t *)malloc(fat_bsize); 15377c478bd9Sstevel@tonic-gate (void) memset(fat_rdir, (char)0, fat_bsize); 15387c478bd9Sstevel@tonic-gate 15397c478bd9Sstevel@tonic-gate *fat_rdir = bpb->b_mediadescriptor; 15407c478bd9Sstevel@tonic-gate *(fat_rdir + 1) = 0xFF; 15417c478bd9Sstevel@tonic-gate *(fat_rdir + 2) = 0xFF; 15427c478bd9Sstevel@tonic-gate bootclen = (bootlen + 512 * (int)bpb->b_spcl - 1) / 15437c478bd9Sstevel@tonic-gate (512 * (int)bpb->b_spcl); 15447c478bd9Sstevel@tonic-gate #define BAD_CLUSTER 0xFF7 15457c478bd9Sstevel@tonic-gate for (i = 0, fatptr = fat_rdir+3; i < bootclen; i++) 15467c478bd9Sstevel@tonic-gate /* 15477c478bd9Sstevel@tonic-gate * pre-allocate any clusters used by boot loader if 15487c478bd9Sstevel@tonic-gate * loader will occupy more than 1 sector 15497c478bd9Sstevel@tonic-gate */ 15507c478bd9Sstevel@tonic-gate if (!(i & 01)) { 15517c478bd9Sstevel@tonic-gate *fatptr++ = BAD_CLUSTER & 0xFF; 15527c478bd9Sstevel@tonic-gate *fatptr = (BAD_CLUSTER >> 8) & 0x0F; 15537c478bd9Sstevel@tonic-gate } else { 15547c478bd9Sstevel@tonic-gate *fatptr = (*fatptr & 0x0F) | 15557c478bd9Sstevel@tonic-gate ((BAD_CLUSTER << 4) & 0xF0); 15567c478bd9Sstevel@tonic-gate fatptr++; 15577c478bd9Sstevel@tonic-gate *fatptr++ = (BAD_CLUSTER >> 4) & 0xFF; 15587c478bd9Sstevel@tonic-gate } 15597c478bd9Sstevel@tonic-gate for (i = 0; i < (int)bpb->b_nfat; ++i) 15607c478bd9Sstevel@tonic-gate if (write(fd, fat_rdir, fat_bsize) != fat_bsize) { 15617c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 15627c478bd9Sstevel@tonic-gate gettext("%s: write of MS-DOS File Allocation Table failed, "), 15637c478bd9Sstevel@tonic-gate myname); 15647c478bd9Sstevel@tonic-gate perror(nullstring); 15657c478bd9Sstevel@tonic-gate exit(3); 15667c478bd9Sstevel@tonic-gate } 15677c478bd9Sstevel@tonic-gate rdirsec = bpb->b_rdirents[0]; 15687c478bd9Sstevel@tonic-gate rdirsec = 32 * (int)rdirsec / 512; 15697c478bd9Sstevel@tonic-gate if (b_flag) { 15707c478bd9Sstevel@tonic-gate struct timeval tv; 15717c478bd9Sstevel@tonic-gate struct tm *tp; 15727c478bd9Sstevel@tonic-gate ushort_t dostime; 15737c478bd9Sstevel@tonic-gate ushort_t dosday; 15747c478bd9Sstevel@tonic-gate 15757c478bd9Sstevel@tonic-gate /* the label can be no more than 11 characters */ 15767c478bd9Sstevel@tonic-gate j = min(11, (int)strlen(doslabel)); 15777c478bd9Sstevel@tonic-gate for (i = 0; i < j; i++) { 15787c478bd9Sstevel@tonic-gate fat_rdir[i] = uppercase(doslabel[i]); 15797c478bd9Sstevel@tonic-gate } 15807c478bd9Sstevel@tonic-gate for (; i < 11; i++) { 15817c478bd9Sstevel@tonic-gate fat_rdir[i] = ' '; 15827c478bd9Sstevel@tonic-gate } 15837c478bd9Sstevel@tonic-gate fat_rdir[0x0B] = 0x28; 15847c478bd9Sstevel@tonic-gate (void) gettimeofday(&tv, (struct timezone *)0); 15857c478bd9Sstevel@tonic-gate tp = localtime(&tv.tv_sec); 15867c478bd9Sstevel@tonic-gate /* get the time & day into DOS format */ 15877c478bd9Sstevel@tonic-gate dostime = tp->tm_sec / 2; 15887c478bd9Sstevel@tonic-gate dostime |= tp->tm_min << 5; 15897c478bd9Sstevel@tonic-gate dostime |= tp->tm_hour << 11; 15907c478bd9Sstevel@tonic-gate dosday = tp->tm_mday; 15917c478bd9Sstevel@tonic-gate dosday |= (tp->tm_mon + 1) << 5; 15927c478bd9Sstevel@tonic-gate dosday |= (tp->tm_year - 80) << 9; 15937c478bd9Sstevel@tonic-gate fat_rdir[0x16] = getlobyte(dostime); 15947c478bd9Sstevel@tonic-gate fat_rdir[0x17] = gethibyte(dostime); 15957c478bd9Sstevel@tonic-gate fat_rdir[0x18] = getlobyte(dosday); 15967c478bd9Sstevel@tonic-gate fat_rdir[0x19] = gethibyte(dosday); 15977c478bd9Sstevel@tonic-gate 15987c478bd9Sstevel@tonic-gate if (write(fd, fat_rdir, 512) != 512) { 15997c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 16007c478bd9Sstevel@tonic-gate gettext("%s: write of MS-DOS FAT failed, "), 16017c478bd9Sstevel@tonic-gate myname); 16027c478bd9Sstevel@tonic-gate perror(nullstring); 16037c478bd9Sstevel@tonic-gate exit(3); 16047c478bd9Sstevel@tonic-gate } 16057c478bd9Sstevel@tonic-gate i = 1; 16067c478bd9Sstevel@tonic-gate } else { 16077c478bd9Sstevel@tonic-gate i = 0; 16087c478bd9Sstevel@tonic-gate } 16097c478bd9Sstevel@tonic-gate (void) memset(fat_rdir, (char)0, 512); 16107c478bd9Sstevel@tonic-gate for (; i < (int)rdirsec; ++i) { 16117c478bd9Sstevel@tonic-gate if (write(fd, fat_rdir, 512) != 512) { 16127c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 16137c478bd9Sstevel@tonic-gate gettext("%s: write of MS-DOS root directory failed, "), 16147c478bd9Sstevel@tonic-gate myname); 16157c478bd9Sstevel@tonic-gate perror(nullstring); 16167c478bd9Sstevel@tonic-gate exit(3); 16177c478bd9Sstevel@tonic-gate } 16187c478bd9Sstevel@tonic-gate } 16197c478bd9Sstevel@tonic-gate /* 16207c478bd9Sstevel@tonic-gate * Write the rest of the boot loader if it's longer than one sector. 16217c478bd9Sstevel@tonic-gate * The clusters used are marked Bad in the FAT. 16227c478bd9Sstevel@tonic-gate * No directory entry exists for this file (so that it cannot be 16237c478bd9Sstevel@tonic-gate * deleted). 16247c478bd9Sstevel@tonic-gate */ 16257c478bd9Sstevel@tonic-gate if (bootlen && write(fd, bootloadr, bootlen) != bootlen) { 16267c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 16277c478bd9Sstevel@tonic-gate gettext("%s: write of MS-DOS boot sectors failed"), myname); 16287c478bd9Sstevel@tonic-gate perror(nullstring); 16297c478bd9Sstevel@tonic-gate exit(3); 16307c478bd9Sstevel@tonic-gate } 16317c478bd9Sstevel@tonic-gate } 16327c478bd9Sstevel@tonic-gate 16337c478bd9Sstevel@tonic-gate static void 16347c478bd9Sstevel@tonic-gate write_NEC_DOS_label(int fd, char *doslabel) 16357c478bd9Sstevel@tonic-gate { 16367c478bd9Sstevel@tonic-gate struct bios_param_blk *bpb; 16377c478bd9Sstevel@tonic-gate ushort_t fatsec; 16387c478bd9Sstevel@tonic-gate ushort_t rdirsec; 16397c478bd9Sstevel@tonic-gate char fat_rdir[1024]; 16407c478bd9Sstevel@tonic-gate int i, j, m = 1; 16417c478bd9Sstevel@tonic-gate uchar_t bootsec_NEC[1024]; 16427c478bd9Sstevel@tonic-gate char *nullstring = ""; 16437c478bd9Sstevel@tonic-gate 16447c478bd9Sstevel@tonic-gate uchar_t bios_param_NEC[30] = { 0xeb, 0x1c, 0x90, 0x0, 0x0, 0x0, 0x0, 16457c478bd9Sstevel@tonic-gate 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x1, 0x1, 0x0, 16467c478bd9Sstevel@tonic-gate 0x2, 0xc0, 0x0, 0xd0, 0x4, 0xfe, 0x2, 0x0, 16477c478bd9Sstevel@tonic-gate 0x8, 0x0, 0x2, 0x0, 0x0, 0x0 16487c478bd9Sstevel@tonic-gate }; 16497c478bd9Sstevel@tonic-gate 16507c478bd9Sstevel@tonic-gate uchar_t fatdir[32] = { 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 16517c478bd9Sstevel@tonic-gate 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 16527c478bd9Sstevel@tonic-gate 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 16537c478bd9Sstevel@tonic-gate 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5 16547c478bd9Sstevel@tonic-gate 16557c478bd9Sstevel@tonic-gate }; 16567c478bd9Sstevel@tonic-gate 16577c478bd9Sstevel@tonic-gate 16587c478bd9Sstevel@tonic-gate (void) memset(bootsec_NEC, (char)0, 1024); 16597c478bd9Sstevel@tonic-gate 16607c478bd9Sstevel@tonic-gate (void) memcpy(&bootsec_NEC, &bios_param_NEC, 30); 16617c478bd9Sstevel@tonic-gate 16627c478bd9Sstevel@tonic-gate bpb = (struct bios_param_blk *)&(bootsec_NEC[0xb]); 16637c478bd9Sstevel@tonic-gate if (write(fd, &bootsec_NEC[0], 1024) != 1024) { 16647c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 16657c478bd9Sstevel@tonic-gate "%s: write of NEC-DOS boot sector failed, "), 16667c478bd9Sstevel@tonic-gate myname); 16677c478bd9Sstevel@tonic-gate perror(nullstring); 16687c478bd9Sstevel@tonic-gate exit(3); 16697c478bd9Sstevel@tonic-gate } 16707c478bd9Sstevel@tonic-gate (void) memset(fat_rdir, (char)0, 1024); 16717c478bd9Sstevel@tonic-gate fatsec = bpb->b_fatsec[0]; 16727c478bd9Sstevel@tonic-gate for (i = 0; i < (int)bpb->b_nfat * (int)fatsec; ++i) { 16737c478bd9Sstevel@tonic-gate if ((i % (int)fatsec) == 0) { 16747c478bd9Sstevel@tonic-gate fat_rdir[0] = bpb->b_mediadescriptor; 16757c478bd9Sstevel@tonic-gate fat_rdir[1] = (char)0xff; 16767c478bd9Sstevel@tonic-gate fat_rdir[2] = (char)0xff; 16777c478bd9Sstevel@tonic-gate fat_rdir[3] = 0; 16787c478bd9Sstevel@tonic-gate fat_rdir[4] = 0; 16797c478bd9Sstevel@tonic-gate fat_rdir[5] = 0; 16807c478bd9Sstevel@tonic-gate } else { 16817c478bd9Sstevel@tonic-gate fat_rdir[0] = 0; 16827c478bd9Sstevel@tonic-gate fat_rdir[1] = 0; 16837c478bd9Sstevel@tonic-gate fat_rdir[2] = 0; 16847c478bd9Sstevel@tonic-gate fat_rdir[3] = 0; 16857c478bd9Sstevel@tonic-gate fat_rdir[4] = 0; 16867c478bd9Sstevel@tonic-gate fat_rdir[5] = 0; 16877c478bd9Sstevel@tonic-gate } 16887c478bd9Sstevel@tonic-gate if (write(fd, &fat_rdir[0], 1024) != 1024) { 16897c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 16907c478bd9Sstevel@tonic-gate /*CSTYLED*/ 16917c478bd9Sstevel@tonic-gate gettext("%s: write of NEC-DOS File Allocation Table failed, "), myname); 16927c478bd9Sstevel@tonic-gate perror(nullstring); 16937c478bd9Sstevel@tonic-gate exit(3); 16947c478bd9Sstevel@tonic-gate } 16957c478bd9Sstevel@tonic-gate } 16967c478bd9Sstevel@tonic-gate #ifndef sparc 16977c478bd9Sstevel@tonic-gate /* LINTED */ 16987c478bd9Sstevel@tonic-gate rdirsec = (int)htols(bpb->b_rdirents[0]) * 32 /1024; 16997c478bd9Sstevel@tonic-gate #else 17007c478bd9Sstevel@tonic-gate rdirsec = (int)htols(bpb->b_rdirents[0]) * 32 /1024; 17017c478bd9Sstevel@tonic-gate #endif 17027c478bd9Sstevel@tonic-gate if (b_flag) { 17037c478bd9Sstevel@tonic-gate struct timeval tv; 17047c478bd9Sstevel@tonic-gate struct tm *tp; 17057c478bd9Sstevel@tonic-gate ushort_t dostime; 17067c478bd9Sstevel@tonic-gate ushort_t dosday; 17077c478bd9Sstevel@tonic-gate 17087c478bd9Sstevel@tonic-gate /* the label can be no more than 11 characters */ 17097c478bd9Sstevel@tonic-gate j = min(11, (int)strlen(doslabel)); 17107c478bd9Sstevel@tonic-gate for (i = 0; i < j; i++) { 17117c478bd9Sstevel@tonic-gate fat_rdir[i] = uppercase(doslabel[i]); 17127c478bd9Sstevel@tonic-gate } 17137c478bd9Sstevel@tonic-gate for (; i < 11; i++) { 17147c478bd9Sstevel@tonic-gate fat_rdir[i] = ' '; 17157c478bd9Sstevel@tonic-gate } 17167c478bd9Sstevel@tonic-gate fat_rdir[0xb] = 0x28; 17177c478bd9Sstevel@tonic-gate (void) gettimeofday(&tv, (struct timezone *)0); 17187c478bd9Sstevel@tonic-gate tp = localtime(&tv.tv_sec); 17197c478bd9Sstevel@tonic-gate /* get the time & day into DOS format */ 17207c478bd9Sstevel@tonic-gate dostime = tp->tm_sec / 2; 17217c478bd9Sstevel@tonic-gate dostime |= tp->tm_min << 5; 17227c478bd9Sstevel@tonic-gate dostime |= tp->tm_hour << 11; 17237c478bd9Sstevel@tonic-gate dosday = tp->tm_mday; 17247c478bd9Sstevel@tonic-gate dosday |= (tp->tm_mon + 1) << 5; 17257c478bd9Sstevel@tonic-gate dosday |= (tp->tm_year - 80) << 9; 17267c478bd9Sstevel@tonic-gate fat_rdir[0x16] = getlobyte(dostime); 17277c478bd9Sstevel@tonic-gate fat_rdir[0x17] = gethibyte(dostime); 17287c478bd9Sstevel@tonic-gate fat_rdir[0x18] = getlobyte(dosday); 17297c478bd9Sstevel@tonic-gate fat_rdir[0x19] = gethibyte(dosday); 17307c478bd9Sstevel@tonic-gate 17317c478bd9Sstevel@tonic-gate if (write(fd, &fat_rdir[0], 1024) != 1024) { 17327c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 17337c478bd9Sstevel@tonic-gate /*CSTYLED*/ 17347c478bd9Sstevel@tonic-gate gettext("%s: write of NEC-DOS root directory failed, "), myname); 17357c478bd9Sstevel@tonic-gate perror(nullstring); 17367c478bd9Sstevel@tonic-gate exit(3); 17377c478bd9Sstevel@tonic-gate } 17387c478bd9Sstevel@tonic-gate (void) memset(fat_rdir, (char)0, 512); 17397c478bd9Sstevel@tonic-gate i = 1; 17407c478bd9Sstevel@tonic-gate } else { 17417c478bd9Sstevel@tonic-gate i = 0; 17427c478bd9Sstevel@tonic-gate 17437c478bd9Sstevel@tonic-gate while (m < 1024) { 17447c478bd9Sstevel@tonic-gate (void) memcpy(&fat_rdir[m], &fatdir, 31); 17457c478bd9Sstevel@tonic-gate m = m + 32; 17467c478bd9Sstevel@tonic-gate } 17477c478bd9Sstevel@tonic-gate } 17487c478bd9Sstevel@tonic-gate for (; i < (int)rdirsec; ++i) { 17497c478bd9Sstevel@tonic-gate 17507c478bd9Sstevel@tonic-gate if (write(fd, &fat_rdir[0], 1024) != 1024) { 17517c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 17527c478bd9Sstevel@tonic-gate /*CSTYLED*/ 17537c478bd9Sstevel@tonic-gate gettext("%s: write of NEC-DOS root directory failed, "), myname); 17547c478bd9Sstevel@tonic-gate perror(nullstring); 17557c478bd9Sstevel@tonic-gate exit(3); 17567c478bd9Sstevel@tonic-gate } 17577c478bd9Sstevel@tonic-gate } 17587c478bd9Sstevel@tonic-gate } 1759