1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 1991-2002 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate /* 30*0Sstevel@tonic-gate * fdformat program - formats floppy disks, and then adds a label to them 31*0Sstevel@tonic-gate * 32*0Sstevel@tonic-gate * ****Warning, Warning, Warning, Warning***** 33*0Sstevel@tonic-gate * This program runs suid root. This change was made to 34*0Sstevel@tonic-gate * allow it to umount a file system if it's mounted. 35*0Sstevel@tonic-gate */ 36*0Sstevel@tonic-gate 37*0Sstevel@tonic-gate #include <stdio.h> 38*0Sstevel@tonic-gate #include <fcntl.h> 39*0Sstevel@tonic-gate #include <stdlib.h> 40*0Sstevel@tonic-gate #include <unistd.h> 41*0Sstevel@tonic-gate #include <string.h> 42*0Sstevel@tonic-gate #include <memory.h> 43*0Sstevel@tonic-gate #include <errno.h> 44*0Sstevel@tonic-gate #include <locale.h> 45*0Sstevel@tonic-gate #include <libintl.h> 46*0Sstevel@tonic-gate #include <volmgt.h> 47*0Sstevel@tonic-gate #include <sys/isa_defs.h> 48*0Sstevel@tonic-gate #include <sys/ioccom.h> 49*0Sstevel@tonic-gate #include <sys/types.h> 50*0Sstevel@tonic-gate #include <sys/time.h> 51*0Sstevel@tonic-gate #include <sys/file.h> 52*0Sstevel@tonic-gate #include <sys/dklabel.h> 53*0Sstevel@tonic-gate #include <sys/ioctl.h> 54*0Sstevel@tonic-gate #include <sys/dkio.h> 55*0Sstevel@tonic-gate #include <sys/fdio.h> 56*0Sstevel@tonic-gate #include <sys/stat.h> 57*0Sstevel@tonic-gate #include <sys/vtoc.h> 58*0Sstevel@tonic-gate #include <sys/mnttab.h> 59*0Sstevel@tonic-gate 60*0Sstevel@tonic-gate /* DEFINES */ 61*0Sstevel@tonic-gate #if defined(_BIG_ENDIAN) 62*0Sstevel@tonic-gate #define getbyte(A, N) (((unsigned char *)(&(A)))[N]) 63*0Sstevel@tonic-gate #define htols(S) ((getbyte(S, 1) <<8) | getbyte(S, 0)) 64*0Sstevel@tonic-gate #elif defined(_LITTLE_ENDIAN) 65*0Sstevel@tonic-gate #define htols(S) (*((ushort_t *)(&(S)))) 66*0Sstevel@tonic-gate #else 67*0Sstevel@tonic-gate #error One of _BIG_ENDIAN or LITTLE_ENDIAN must be defined 68*0Sstevel@tonic-gate #endif 69*0Sstevel@tonic-gate 70*0Sstevel@tonic-gate #define getlobyte(A) (A & 0xFF) 71*0Sstevel@tonic-gate #define gethibyte(A) (A >> 8 & 0xFF) 72*0Sstevel@tonic-gate #define uppercase(c) ((c) >= 'a' && (c) <= 'z' ? (c) - 'a' + 'A' : (c)) 73*0Sstevel@tonic-gate #define min(a, b) ((a) < (b) ? (a) : (b)) 74*0Sstevel@tonic-gate 75*0Sstevel@tonic-gate /* 76*0Sstevel@tonic-gate * These defines are from the PCMCIA memory driver driver 77*0Sstevel@tonic-gate * header files (pcramio.h/pcramvar.h) and they are in 78*0Sstevel@tonic-gate * the Platform Specific (PS) train. 79*0Sstevel@tonic-gate */ 80*0Sstevel@tonic-gate #ifndef PCRAM_PROBESIZE 81*0Sstevel@tonic-gate #define PCRAMIOC ('P' << 8) 82*0Sstevel@tonic-gate #define PCRAM_PROBESIZE (PCRAMIOC|22) /* Probe memory card size */ 83*0Sstevel@tonic-gate #endif 84*0Sstevel@tonic-gate 85*0Sstevel@tonic-gate /* FORMAT PATTERNS */ 86*0Sstevel@tonic-gate #define PATTERN_1 0x55; 87*0Sstevel@tonic-gate #define PATTERN_2 0xaa; 88*0Sstevel@tonic-gate #define PATTERN_3 0xff; 89*0Sstevel@tonic-gate #define PATTERN_4 0x00; 90*0Sstevel@tonic-gate 91*0Sstevel@tonic-gate /* UNINITIALIZED DATA */ 92*0Sstevel@tonic-gate static struct fd_char fdchar; 93*0Sstevel@tonic-gate static struct dk_geom fdgeom; 94*0Sstevel@tonic-gate static struct dk_allmap allmap; 95*0Sstevel@tonic-gate static struct dk_cinfo dkinfo; 96*0Sstevel@tonic-gate static struct dk_geom dkg; 97*0Sstevel@tonic-gate 98*0Sstevel@tonic-gate /* EXTERN */ 99*0Sstevel@tonic-gate extern char *optarg; 100*0Sstevel@tonic-gate extern int optind; 101*0Sstevel@tonic-gate 102*0Sstevel@tonic-gate /* for verify buffers */ 103*0Sstevel@tonic-gate static uchar_t *ibuf1; 104*0Sstevel@tonic-gate static uchar_t *obuf; 105*0Sstevel@tonic-gate 106*0Sstevel@tonic-gate static char *myname; 107*0Sstevel@tonic-gate 108*0Sstevel@tonic-gate static int fd_debug = 1; /* 1 if debug XXX */ 109*0Sstevel@tonic-gate static int b_flag = 0; /* install a volume label to the diskette */ 110*0Sstevel@tonic-gate static int d_flag = 0; /* format the diskette in dos format */ 111*0Sstevel@tonic-gate static int D_flag = 0; /* double (aka low) density flag */ 112*0Sstevel@tonic-gate static int e_flag = 0; /* "eject" diskette when done (if supported) */ 113*0Sstevel@tonic-gate static int E_flag = 0; /* extended density */ 114*0Sstevel@tonic-gate static int f_flag = 0; /* "force" (no confirmation before start) */ 115*0Sstevel@tonic-gate static int H_flag = 0; /* high density */ 116*0Sstevel@tonic-gate static int m_flag = 0; /* medium density */ 117*0Sstevel@tonic-gate static int n_flag = 0; /* format the diskette in NEC-DOS format */ 118*0Sstevel@tonic-gate static int q_flag = 0; /* quiet format flag */ 119*0Sstevel@tonic-gate static int U_flag = 0; /* automatically unmount if it's mounted */ 120*0Sstevel@tonic-gate static int v_flag = 0; /* verify format/diskette flag */ 121*0Sstevel@tonic-gate static int x_flag = 0; /* skip the format, only install SunOS label */ 122*0Sstevel@tonic-gate /* or DOS file system */ 123*0Sstevel@tonic-gate static int z_flag = 0; /* debugging only, setting partial formatting */ 124*0Sstevel@tonic-gate static int interleave = 1; /* interleave factor */ 125*0Sstevel@tonic-gate static int pcmcia = 0; /* 1 if media is a pcmcia card */ 126*0Sstevel@tonic-gate 127*0Sstevel@tonic-gate static uid_t euid = 0; /* stores effective user id */ 128*0Sstevel@tonic-gate 129*0Sstevel@tonic-gate struct bios_param_blk { 130*0Sstevel@tonic-gate uchar_t b_bps[2]; /* bytes per sector */ 131*0Sstevel@tonic-gate uchar_t b_spcl; /* sectors per alloction unit */ 132*0Sstevel@tonic-gate uchar_t b_res_sec[2]; /* reserved sectors, starting at 0 */ 133*0Sstevel@tonic-gate uchar_t b_nfat; /* number of FATs */ 134*0Sstevel@tonic-gate uchar_t b_rdirents[2]; /* number of root directory entries */ 135*0Sstevel@tonic-gate uchar_t b_totalsec[2]; /* total sectors in logical image */ 136*0Sstevel@tonic-gate char b_mediadescriptor; /* media descriptor byte */ 137*0Sstevel@tonic-gate uchar_t b_fatsec[2]; /* number of sectors per FAT */ 138*0Sstevel@tonic-gate uchar_t b_spt[2]; /* sectors per track */ 139*0Sstevel@tonic-gate uchar_t b_nhead[2]; /* number of heads */ 140*0Sstevel@tonic-gate uchar_t b_hiddensec[2]; /* number of hidden sectors */ 141*0Sstevel@tonic-gate }; 142*0Sstevel@tonic-gate 143*0Sstevel@tonic-gate /* 144*0Sstevel@tonic-gate * ON-private functions from libvolmgt 145*0Sstevel@tonic-gate */ 146*0Sstevel@tonic-gate char *_media_oldaliases(char *name); 147*0Sstevel@tonic-gate int _dev_mounted(char *path); 148*0Sstevel@tonic-gate int _dev_unmount(char *path); 149*0Sstevel@tonic-gate 150*0Sstevel@tonic-gate /* 151*0Sstevel@tonic-gate * local functions 152*0Sstevel@tonic-gate */ 153*0Sstevel@tonic-gate static void usage(char *); 154*0Sstevel@tonic-gate static int verify(int, int, int); 155*0Sstevel@tonic-gate static void write_SunOS_label(int, char *, struct vtoc *); 156*0Sstevel@tonic-gate static int valid_DOS_boot(char *, uchar_t **); 157*0Sstevel@tonic-gate static void write_DOS_label(int, uchar_t *, int, char *, char *, 158*0Sstevel@tonic-gate struct bios_param_blk *, int); 159*0Sstevel@tonic-gate static void write_NEC_DOS_label(int, char *); 160*0Sstevel@tonic-gate static int check_mount(); 161*0Sstevel@tonic-gate static void format_diskette(int, char *, struct vtoc *, 162*0Sstevel@tonic-gate struct bios_param_blk *, int *); 163*0Sstevel@tonic-gate static void format_pcmcia_card(int, char *, struct vtoc *, 164*0Sstevel@tonic-gate struct bios_param_blk *, int *); 165*0Sstevel@tonic-gate static void restore_default_chars(int fd, 166*0Sstevel@tonic-gate struct fd_char save_fdchar, 167*0Sstevel@tonic-gate struct dk_allmap save_allmap); 168*0Sstevel@tonic-gate 169*0Sstevel@tonic-gate int 170*0Sstevel@tonic-gate main(int argc, char **argv) 171*0Sstevel@tonic-gate { 172*0Sstevel@tonic-gate int altsize = 0; 173*0Sstevel@tonic-gate int fd; 174*0Sstevel@tonic-gate int i; 175*0Sstevel@tonic-gate uchar_t *altboot = NULL; 176*0Sstevel@tonic-gate char *altbootname = NULL; 177*0Sstevel@tonic-gate char *dev_name = NULL, *real_name, *alias_name; 178*0Sstevel@tonic-gate char *vollabel = ""; 179*0Sstevel@tonic-gate struct vtoc fd_vtoc; 180*0Sstevel@tonic-gate struct bios_param_blk bpb; 181*0Sstevel@tonic-gate int rdirsec; 182*0Sstevel@tonic-gate char *nullstring = ""; 183*0Sstevel@tonic-gate 184*0Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 185*0Sstevel@tonic-gate 186*0Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 187*0Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 188*0Sstevel@tonic-gate #endif 189*0Sstevel@tonic-gate 190*0Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 191*0Sstevel@tonic-gate 192*0Sstevel@tonic-gate myname = argv[0]; 193*0Sstevel@tonic-gate while ((i = getopt(argc, argv, "B:b:dDeEfhHlLmMxqt:UvVZ?")) != -1) { 194*0Sstevel@tonic-gate switch (i) { 195*0Sstevel@tonic-gate 196*0Sstevel@tonic-gate case 'B': 197*0Sstevel@tonic-gate altbootname = strdup(optarg); 198*0Sstevel@tonic-gate d_flag++; 199*0Sstevel@tonic-gate /* check for valid boot file now */ 200*0Sstevel@tonic-gate altsize = valid_DOS_boot(altbootname, &altboot); 201*0Sstevel@tonic-gate if (!altsize) { 202*0Sstevel@tonic-gate (void) fprintf(stderr, gettext( 203*0Sstevel@tonic-gate "%s: invalid boot loader\n"), myname); 204*0Sstevel@tonic-gate exit(1); 205*0Sstevel@tonic-gate } 206*0Sstevel@tonic-gate break; 207*0Sstevel@tonic-gate 208*0Sstevel@tonic-gate case 'b': 209*0Sstevel@tonic-gate b_flag++; 210*0Sstevel@tonic-gate vollabel = strdup(optarg); 211*0Sstevel@tonic-gate break; 212*0Sstevel@tonic-gate 213*0Sstevel@tonic-gate case 'd': 214*0Sstevel@tonic-gate /* format a MS-DOS diskette */ 215*0Sstevel@tonic-gate d_flag++; 216*0Sstevel@tonic-gate break; 217*0Sstevel@tonic-gate 218*0Sstevel@tonic-gate case 'D': 219*0Sstevel@tonic-gate case 'L': 220*0Sstevel@tonic-gate case 'l': 221*0Sstevel@tonic-gate /* format a Double density 720KB (or 360KB) disk */ 222*0Sstevel@tonic-gate D_flag++; 223*0Sstevel@tonic-gate break; 224*0Sstevel@tonic-gate 225*0Sstevel@tonic-gate case 'e': 226*0Sstevel@tonic-gate /* eject diskette when done */ 227*0Sstevel@tonic-gate e_flag++; 228*0Sstevel@tonic-gate break; 229*0Sstevel@tonic-gate 230*0Sstevel@tonic-gate case 'E': 231*0Sstevel@tonic-gate /* format an 2.88MB Extended density disk */ 232*0Sstevel@tonic-gate E_flag++; 233*0Sstevel@tonic-gate break; 234*0Sstevel@tonic-gate 235*0Sstevel@tonic-gate case 'f': 236*0Sstevel@tonic-gate /* don't ask for confirmation */ 237*0Sstevel@tonic-gate f_flag++; 238*0Sstevel@tonic-gate break; 239*0Sstevel@tonic-gate 240*0Sstevel@tonic-gate case 'H': 241*0Sstevel@tonic-gate case 'h': 242*0Sstevel@tonic-gate /* format a High density 1.2MB or 1.44MB disk */ 243*0Sstevel@tonic-gate H_flag++; 244*0Sstevel@tonic-gate break; 245*0Sstevel@tonic-gate 246*0Sstevel@tonic-gate #if 0 247*0Sstevel@tonic-gate case 'i': 248*0Sstevel@tonic-gate /* interleave factor */ 249*0Sstevel@tonic-gate interleave = atol(optarg); 250*0Sstevel@tonic-gate if (interleave <= 0) { 251*0Sstevel@tonic-gate (void) fprintf(stderr, gettext( 252*0Sstevel@tonic-gate "%s: invalid interleave\n"), myname); 253*0Sstevel@tonic-gate exit(1); 254*0Sstevel@tonic-gate } 255*0Sstevel@tonic-gate break; 256*0Sstevel@tonic-gate #endif 257*0Sstevel@tonic-gate 258*0Sstevel@tonic-gate case 'M': 259*0Sstevel@tonic-gate case 'm': 260*0Sstevel@tonic-gate /* format a 3.5" HD disk to 1.2MB */ 261*0Sstevel@tonic-gate m_flag++; 262*0Sstevel@tonic-gate break; 263*0Sstevel@tonic-gate 264*0Sstevel@tonic-gate case 'x': 265*0Sstevel@tonic-gate /* skip format, just write label */ 266*0Sstevel@tonic-gate x_flag++; 267*0Sstevel@tonic-gate break; 268*0Sstevel@tonic-gate 269*0Sstevel@tonic-gate case 'q': 270*0Sstevel@tonic-gate /* quiet format */ 271*0Sstevel@tonic-gate q_flag++; 272*0Sstevel@tonic-gate break; 273*0Sstevel@tonic-gate 274*0Sstevel@tonic-gate case 't': 275*0Sstevel@tonic-gate /* Type of DOS formatting: NEC or MS */ 276*0Sstevel@tonic-gate if (strcmp(optarg, "nec") == 0) { 277*0Sstevel@tonic-gate n_flag++; 278*0Sstevel@tonic-gate } 279*0Sstevel@tonic-gate if (strcmp(optarg, "dos") == 0) { 280*0Sstevel@tonic-gate d_flag++; 281*0Sstevel@tonic-gate } 282*0Sstevel@tonic-gate break; 283*0Sstevel@tonic-gate 284*0Sstevel@tonic-gate case 'U': 285*0Sstevel@tonic-gate /* umount filesystem if mounted */ 286*0Sstevel@tonic-gate U_flag++; 287*0Sstevel@tonic-gate break; 288*0Sstevel@tonic-gate 289*0Sstevel@tonic-gate case 'v': 290*0Sstevel@tonic-gate case 'V': 291*0Sstevel@tonic-gate /* verify the diskette after format */ 292*0Sstevel@tonic-gate v_flag++; 293*0Sstevel@tonic-gate break; 294*0Sstevel@tonic-gate 295*0Sstevel@tonic-gate case 'Z': 296*0Sstevel@tonic-gate /* for debug only, format cyl 0 only */ 297*0Sstevel@tonic-gate if (!fd_debug) { 298*0Sstevel@tonic-gate usage(gettext("unknown argument")); 299*0Sstevel@tonic-gate /* NOTREACHED */ 300*0Sstevel@tonic-gate } 301*0Sstevel@tonic-gate (void) printf(gettext("\nFormat cyl Zero only\n")); 302*0Sstevel@tonic-gate z_flag++; 303*0Sstevel@tonic-gate break; 304*0Sstevel@tonic-gate 305*0Sstevel@tonic-gate default: 306*0Sstevel@tonic-gate usage(" "); 307*0Sstevel@tonic-gate /* NOTREACHED */ 308*0Sstevel@tonic-gate } 309*0Sstevel@tonic-gate } 310*0Sstevel@tonic-gate 311*0Sstevel@tonic-gate if (optind < argc -1) { 312*0Sstevel@tonic-gate usage(gettext("more than one device name argument")); 313*0Sstevel@tonic-gate /* NOTREACHED */ 314*0Sstevel@tonic-gate } 315*0Sstevel@tonic-gate if (optind == argc -1) { 316*0Sstevel@tonic-gate dev_name = argv[optind]; 317*0Sstevel@tonic-gate } 318*0Sstevel@tonic-gate if (D_flag && H_flag) { 319*0Sstevel@tonic-gate usage(gettext("switches -D, -L and -H incompatible")); 320*0Sstevel@tonic-gate /* NOTREACHED */ 321*0Sstevel@tonic-gate } 322*0Sstevel@tonic-gate if (D_flag && E_flag) { 323*0Sstevel@tonic-gate usage(gettext("switches -D, -L and -E incompatible")); 324*0Sstevel@tonic-gate /* NOTREACHED */ 325*0Sstevel@tonic-gate } 326*0Sstevel@tonic-gate if (H_flag && E_flag) { 327*0Sstevel@tonic-gate usage(gettext("switches -H and -E incompatible")); 328*0Sstevel@tonic-gate /* NOTREACHED */ 329*0Sstevel@tonic-gate } 330*0Sstevel@tonic-gate if (n_flag && d_flag) { 331*0Sstevel@tonic-gate usage(gettext("switches nec and dos incompatible")); 332*0Sstevel@tonic-gate /* NOTREACHED */ 333*0Sstevel@tonic-gate } 334*0Sstevel@tonic-gate if (n_flag && !m_flag) { 335*0Sstevel@tonic-gate usage(gettext("switch -M required for NEC-DOS")); 336*0Sstevel@tonic-gate /* NOTREACHED */ 337*0Sstevel@tonic-gate } 338*0Sstevel@tonic-gate if (D_flag && m_flag) { 339*0Sstevel@tonic-gate usage(gettext("switches -D, -L and -M incompatible")); 340*0Sstevel@tonic-gate /* NOTREACHED */ 341*0Sstevel@tonic-gate } 342*0Sstevel@tonic-gate if (d_flag && m_flag) { 343*0Sstevel@tonic-gate usage(gettext("switches -d and -M incompatible")); 344*0Sstevel@tonic-gate /* NOTREACHED */ 345*0Sstevel@tonic-gate } 346*0Sstevel@tonic-gate 347*0Sstevel@tonic-gate if (dev_name == NULL) 348*0Sstevel@tonic-gate dev_name = "floppy"; 349*0Sstevel@tonic-gate 350*0Sstevel@tonic-gate if ((real_name = media_findname(dev_name)) == NULL) { 351*0Sstevel@tonic-gate if ((alias_name = _media_oldaliases(dev_name)) != NULL) 352*0Sstevel@tonic-gate real_name = media_findname(alias_name); 353*0Sstevel@tonic-gate if (real_name == NULL) { 354*0Sstevel@tonic-gate (void) fprintf(stderr, 355*0Sstevel@tonic-gate gettext("No such volume (or no media in specified device): %s\n"), 356*0Sstevel@tonic-gate dev_name); 357*0Sstevel@tonic-gate exit(1); 358*0Sstevel@tonic-gate } 359*0Sstevel@tonic-gate } 360*0Sstevel@tonic-gate 361*0Sstevel@tonic-gate /* 362*0Sstevel@tonic-gate * This check is required because program runs suid root. 363*0Sstevel@tonic-gate */ 364*0Sstevel@tonic-gate if (access(real_name, R_OK|W_OK) < 0) { 365*0Sstevel@tonic-gate perror(real_name); 366*0Sstevel@tonic-gate exit(1); 367*0Sstevel@tonic-gate } 368*0Sstevel@tonic-gate 369*0Sstevel@tonic-gate /* store callers euid */ 370*0Sstevel@tonic-gate 371*0Sstevel@tonic-gate euid = geteuid(); 372*0Sstevel@tonic-gate 373*0Sstevel@tonic-gate /* 374*0Sstevel@tonic-gate * See if the given device name is mounted. If this check isn't done 375*0Sstevel@tonic-gate * before the open, the open will fail. The failed open will not 376*0Sstevel@tonic-gate * indicate that the device is mounted, only that it's busy 377*0Sstevel@tonic-gate */ 378*0Sstevel@tonic-gate if (_dev_mounted(real_name)) { 379*0Sstevel@tonic-gate if (U_flag) { 380*0Sstevel@tonic-gate if (!_dev_unmount(real_name)) { 381*0Sstevel@tonic-gate (void) fprintf(stderr, 382*0Sstevel@tonic-gate gettext("%s: umount of %s failed\n"), 383*0Sstevel@tonic-gate myname, real_name); 384*0Sstevel@tonic-gate exit(1); 385*0Sstevel@tonic-gate } 386*0Sstevel@tonic-gate } else { 387*0Sstevel@tonic-gate (void) fprintf(stderr, 388*0Sstevel@tonic-gate gettext("%s: %s is mounted (use -U flag)\n"), 389*0Sstevel@tonic-gate myname, real_name); 390*0Sstevel@tonic-gate exit(1); 391*0Sstevel@tonic-gate } 392*0Sstevel@tonic-gate } 393*0Sstevel@tonic-gate 394*0Sstevel@tonic-gate /* Set to user access permissions to open file */ 395*0Sstevel@tonic-gate (void) seteuid(getuid()); 396*0Sstevel@tonic-gate 397*0Sstevel@tonic-gate if ((fd = open(real_name, O_NDELAY | O_RDWR | O_EXCL)) == -1) { 398*0Sstevel@tonic-gate if (errno == EROFS) { 399*0Sstevel@tonic-gate (void) fprintf(stderr, 400*0Sstevel@tonic-gate gettext("%s: \"%s\" is write protected\n"), 401*0Sstevel@tonic-gate myname, real_name); 402*0Sstevel@tonic-gate exit(1); 403*0Sstevel@tonic-gate } 404*0Sstevel@tonic-gate /* XXX ought to check for "drive not installed", etc. */ 405*0Sstevel@tonic-gate (void) fprintf(stderr, gettext("%s: could not open \"%s\": "), 406*0Sstevel@tonic-gate myname, real_name); 407*0Sstevel@tonic-gate perror(nullstring); 408*0Sstevel@tonic-gate exit(1); 409*0Sstevel@tonic-gate } 410*0Sstevel@tonic-gate 411*0Sstevel@tonic-gate /* restore effective id */ 412*0Sstevel@tonic-gate (void) seteuid(euid); 413*0Sstevel@tonic-gate 414*0Sstevel@tonic-gate if (ioctl(fd, DKIOCINFO, &dkinfo) < 0) { 415*0Sstevel@tonic-gate (void) fprintf(stderr, 416*0Sstevel@tonic-gate gettext("%s: DKIOCINFO failed, "), myname); 417*0Sstevel@tonic-gate perror(nullstring); 418*0Sstevel@tonic-gate exit(3); 419*0Sstevel@tonic-gate } 420*0Sstevel@tonic-gate 421*0Sstevel@tonic-gate /* See if there are any mounted partitions. */ 422*0Sstevel@tonic-gate if (check_mount() != 0) { 423*0Sstevel@tonic-gate exit(3); 424*0Sstevel@tonic-gate } 425*0Sstevel@tonic-gate 426*0Sstevel@tonic-gate /* See if the device is a PCMCIA card */ 427*0Sstevel@tonic-gate if (dkinfo.dki_ctype == DKC_PCMCIA_MEM) 428*0Sstevel@tonic-gate pcmcia = 1; 429*0Sstevel@tonic-gate 430*0Sstevel@tonic-gate 431*0Sstevel@tonic-gate /* 432*0Sstevel@tonic-gate * The fd_vtoc, bpb, and rdirsec structures will be 433*0Sstevel@tonic-gate * partially filled in by format_pcmcia_card() or 434*0Sstevel@tonic-gate * format_diskette(). This was done so that write_DOS_label(), 435*0Sstevel@tonic-gate * write_SunOS_label(), and write_NEC_DOS_label() could be 436*0Sstevel@tonic-gate * device independent. If a new device needs to be added to 437*0Sstevel@tonic-gate * fdformat, a new format function like format_diskette should 438*0Sstevel@tonic-gate * be added. This function should fill in fd_vtoc, bpb, and 439*0Sstevel@tonic-gate * rdirsec with device dependent information. 440*0Sstevel@tonic-gate */ 441*0Sstevel@tonic-gate (void) memset((void *)&fd_vtoc, (char)0, sizeof (struct vtoc)); 442*0Sstevel@tonic-gate (void) memset((void *)&bpb, (char)0, sizeof (struct bios_param_blk)); 443*0Sstevel@tonic-gate 444*0Sstevel@tonic-gate if (pcmcia) 445*0Sstevel@tonic-gate format_pcmcia_card(fd, real_name, &fd_vtoc, &bpb, &rdirsec); 446*0Sstevel@tonic-gate else 447*0Sstevel@tonic-gate format_diskette(fd, real_name, &fd_vtoc, &bpb, &rdirsec); 448*0Sstevel@tonic-gate 449*0Sstevel@tonic-gate if (d_flag) 450*0Sstevel@tonic-gate write_DOS_label(fd, altboot, altsize, altbootname, 451*0Sstevel@tonic-gate vollabel, &bpb, rdirsec); 452*0Sstevel@tonic-gate else if (n_flag) 453*0Sstevel@tonic-gate write_NEC_DOS_label(fd, vollabel); 454*0Sstevel@tonic-gate else 455*0Sstevel@tonic-gate write_SunOS_label(fd, vollabel, &fd_vtoc); 456*0Sstevel@tonic-gate 457*0Sstevel@tonic-gate if (e_flag) 458*0Sstevel@tonic-gate /* eject media if possible */ 459*0Sstevel@tonic-gate if (ioctl(fd, FDEJECT, 0)) { 460*0Sstevel@tonic-gate (void) fprintf(stderr, 461*0Sstevel@tonic-gate gettext("%s: could not eject diskette, "), myname); 462*0Sstevel@tonic-gate perror(nullstring); 463*0Sstevel@tonic-gate exit(3); 464*0Sstevel@tonic-gate } 465*0Sstevel@tonic-gate 466*0Sstevel@tonic-gate return (0); 467*0Sstevel@tonic-gate } 468*0Sstevel@tonic-gate 469*0Sstevel@tonic-gate /* 470*0Sstevel@tonic-gate * Inputs: file descriptor for the device and the device name. 471*0Sstevel@tonic-gate * Oututs: the fd_vtoc will be partially filled in with the 472*0Sstevel@tonic-gate * device specific information such as partition 473*0Sstevel@tonic-gate * information and ascillabel. bpb and rdirsec will 474*0Sstevel@tonic-gate * also be partially filled in with device specific information 475*0Sstevel@tonic-gate */ 476*0Sstevel@tonic-gate void 477*0Sstevel@tonic-gate format_diskette(int fd, char *real_name, struct vtoc *fd_vtoc, 478*0Sstevel@tonic-gate struct bios_param_blk *bpb, int *rdirsec) 479*0Sstevel@tonic-gate { 480*0Sstevel@tonic-gate int transfer_rate = 1000; /* transfer rate code */ 481*0Sstevel@tonic-gate int sec_size = 512; /* sector size */ 482*0Sstevel@tonic-gate uchar_t gap = 0x54; /* format gap size */ 483*0Sstevel@tonic-gate uchar_t *fbuf, *p; 484*0Sstevel@tonic-gate char *capacity = NULL; 485*0Sstevel@tonic-gate int cyl_size; 486*0Sstevel@tonic-gate int i; 487*0Sstevel@tonic-gate int chgd; /* for testing disk changed/present */ 488*0Sstevel@tonic-gate int cyl, hd; 489*0Sstevel@tonic-gate int size_of_part, size_of_dev; 490*0Sstevel@tonic-gate int spt = 36; /* sectors per track */ 491*0Sstevel@tonic-gate int drive_size; 492*0Sstevel@tonic-gate uchar_t num_cyl = 80; /* max number of cylinders */ 493*0Sstevel@tonic-gate char *nullstring = ""; 494*0Sstevel@tonic-gate struct fd_char save_fdchar; /* original diskette characteristics */ 495*0Sstevel@tonic-gate struct dk_allmap save_allmap; /* original diskette partition info */ 496*0Sstevel@tonic-gate 497*0Sstevel@tonic-gate 498*0Sstevel@tonic-gate /* FDIOCMD ioctl command structure for formatting */ 499*0Sstevel@tonic-gate /* LINTED */ 500*0Sstevel@tonic-gate struct fd_cmd fcmd_fmt = { 501*0Sstevel@tonic-gate FDCMD_FORMAT_TRACK, 502*0Sstevel@tonic-gate 0xA5, 503*0Sstevel@tonic-gate 0, 504*0Sstevel@tonic-gate 1, 505*0Sstevel@tonic-gate 0, 506*0Sstevel@tonic-gate 0 507*0Sstevel@tonic-gate }; 508*0Sstevel@tonic-gate 509*0Sstevel@tonic-gate /* FDRAW ioctl command structures for seeking and formatting */ 510*0Sstevel@tonic-gate struct fd_raw fdr_seek = { 511*0Sstevel@tonic-gate FDRAW_SEEK, 0, 0, 0, 0, 0, 0, 0, 0, 0, 512*0Sstevel@tonic-gate 3, 513*0Sstevel@tonic-gate 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 514*0Sstevel@tonic-gate 0, 515*0Sstevel@tonic-gate 0 516*0Sstevel@tonic-gate }; 517*0Sstevel@tonic-gate 518*0Sstevel@tonic-gate struct fd_raw fdr_form = { 519*0Sstevel@tonic-gate 0x4D, 0, 2, 0, 0x54, (char)0xA5, 0, 0, 0, 0, 520*0Sstevel@tonic-gate 6, 521*0Sstevel@tonic-gate 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 522*0Sstevel@tonic-gate 0, /* nbytes */ 523*0Sstevel@tonic-gate 0 /* addr */ 524*0Sstevel@tonic-gate }; 525*0Sstevel@tonic-gate 526*0Sstevel@tonic-gate 527*0Sstevel@tonic-gate /* 528*0Sstevel@tonic-gate * restore drive to default geometry and characteristics 529*0Sstevel@tonic-gate * (probably not implemented on sparc) 530*0Sstevel@tonic-gate */ 531*0Sstevel@tonic-gate (void) ioctl(fd, FDDEFGEOCHAR, NULL); 532*0Sstevel@tonic-gate 533*0Sstevel@tonic-gate /* get the default partititon maps */ 534*0Sstevel@tonic-gate if (ioctl(fd, DKIOCGAPART, &allmap) == -1) { 535*0Sstevel@tonic-gate (void) fprintf(stderr, 536*0Sstevel@tonic-gate gettext("%s: DKIOCGAPART failed, "), myname); 537*0Sstevel@tonic-gate perror(nullstring); 538*0Sstevel@tonic-gate exit(3); 539*0Sstevel@tonic-gate } 540*0Sstevel@tonic-gate 541*0Sstevel@tonic-gate /* Save the original default partition maps */ 542*0Sstevel@tonic-gate save_allmap = allmap; 543*0Sstevel@tonic-gate 544*0Sstevel@tonic-gate /* find out the characteristics of the default diskette */ 545*0Sstevel@tonic-gate if (ioctl(fd, FDIOGCHAR, &fdchar) == -1) { 546*0Sstevel@tonic-gate (void) fprintf(stderr, 547*0Sstevel@tonic-gate gettext("%s: FDIOGCHAR failed, "), myname); 548*0Sstevel@tonic-gate perror(nullstring); 549*0Sstevel@tonic-gate exit(3); 550*0Sstevel@tonic-gate } 551*0Sstevel@tonic-gate 552*0Sstevel@tonic-gate /* Save the original characteristics of the default diskette */ 553*0Sstevel@tonic-gate save_fdchar = fdchar; 554*0Sstevel@tonic-gate 555*0Sstevel@tonic-gate /* 556*0Sstevel@tonic-gate * The user may only format the entire diskette. 557*0Sstevel@tonic-gate * formatting partion a or b is not allowed 558*0Sstevel@tonic-gate */ 559*0Sstevel@tonic-gate size_of_part = allmap.dka_map[dkinfo.dki_partition].dkl_nblk 560*0Sstevel@tonic-gate * DEV_BSIZE; 561*0Sstevel@tonic-gate size_of_dev = fdchar.fdc_ncyl * fdchar.fdc_nhead 562*0Sstevel@tonic-gate * fdchar.fdc_secptrack * fdchar.fdc_sec_size; 563*0Sstevel@tonic-gate 564*0Sstevel@tonic-gate if (size_of_part != size_of_dev) { 565*0Sstevel@tonic-gate (void) fprintf(stderr, 566*0Sstevel@tonic-gate /*CSTYLED*/ 567*0Sstevel@tonic-gate gettext("%s: The entire diskette must be formatted. Invalid device name.\n"), 568*0Sstevel@tonic-gate myname); 569*0Sstevel@tonic-gate exit(3); 570*0Sstevel@tonic-gate } 571*0Sstevel@tonic-gate 572*0Sstevel@tonic-gate 573*0Sstevel@tonic-gate /* find out the geometry of the drive */ 574*0Sstevel@tonic-gate if (ioctl(fd, DKIOCGGEOM, &fdgeom) == -1) { 575*0Sstevel@tonic-gate (void) fprintf(stderr, 576*0Sstevel@tonic-gate gettext("%s: DKIOCGGEOM failed, "), myname); 577*0Sstevel@tonic-gate perror(nullstring); 578*0Sstevel@tonic-gate exit(3); 579*0Sstevel@tonic-gate } 580*0Sstevel@tonic-gate 581*0Sstevel@tonic-gate #ifdef sparc 582*0Sstevel@tonic-gate fdchar.fdc_medium = 3; 583*0Sstevel@tonic-gate #endif 584*0Sstevel@tonic-gate if (fdchar.fdc_medium == 5) 585*0Sstevel@tonic-gate drive_size = 5; 586*0Sstevel@tonic-gate else 587*0Sstevel@tonic-gate drive_size = 3; 588*0Sstevel@tonic-gate 589*0Sstevel@tonic-gate /* 590*0Sstevel@tonic-gate * set proper density flag in case we're formating to default 591*0Sstevel@tonic-gate * characteristics because no density switch was input 592*0Sstevel@tonic-gate */ 593*0Sstevel@tonic-gate if ((E_flag | H_flag | D_flag | m_flag) == 0) { 594*0Sstevel@tonic-gate switch (fdchar.fdc_transfer_rate) { 595*0Sstevel@tonic-gate case 1000: 596*0Sstevel@tonic-gate /* assumes only ED uses 1.0 MB/sec */ 597*0Sstevel@tonic-gate E_flag++; 598*0Sstevel@tonic-gate break; 599*0Sstevel@tonic-gate case 500: 600*0Sstevel@tonic-gate default: 601*0Sstevel@tonic-gate /* 602*0Sstevel@tonic-gate * default to HD even though High density and 603*0Sstevel@tonic-gate * "medium" density both use 500 KB/sec 604*0Sstevel@tonic-gate */ 605*0Sstevel@tonic-gate H_flag++; 606*0Sstevel@tonic-gate break; 607*0Sstevel@tonic-gate #ifndef sparc 608*0Sstevel@tonic-gate case 250: 609*0Sstevel@tonic-gate /* assumes only DD uses 250 KB/sec */ 610*0Sstevel@tonic-gate D_flag++; 611*0Sstevel@tonic-gate break; 612*0Sstevel@tonic-gate #endif 613*0Sstevel@tonic-gate } 614*0Sstevel@tonic-gate } 615*0Sstevel@tonic-gate 616*0Sstevel@tonic-gate if (H_flag) { 617*0Sstevel@tonic-gate transfer_rate = 500; 618*0Sstevel@tonic-gate num_cyl = 80; 619*0Sstevel@tonic-gate sec_size = 512; 620*0Sstevel@tonic-gate if (drive_size == 5) { 621*0Sstevel@tonic-gate (void) strcpy(fd_vtoc->v_asciilabel, 622*0Sstevel@tonic-gate "5.25\" floppy cyl 80 alt 0 hd 2 sec 15"); 623*0Sstevel@tonic-gate spt = 15; 624*0Sstevel@tonic-gate capacity = "1.2 MB"; 625*0Sstevel@tonic-gate } else { 626*0Sstevel@tonic-gate (void) strcpy(fd_vtoc->v_asciilabel, 627*0Sstevel@tonic-gate "3.5\" floppy cyl 80 alt 0 hd 2 sec 18"); 628*0Sstevel@tonic-gate spt = 18; 629*0Sstevel@tonic-gate capacity = "1.44 MB"; 630*0Sstevel@tonic-gate } 631*0Sstevel@tonic-gate gap = 0x54; 632*0Sstevel@tonic-gate } else if (D_flag) { 633*0Sstevel@tonic-gate transfer_rate = 250; 634*0Sstevel@tonic-gate if (drive_size == 5) { 635*0Sstevel@tonic-gate (void) strcpy(fd_vtoc->v_asciilabel, 636*0Sstevel@tonic-gate "5.25\" floppy cyl 40 alt 0 hd 2 sec 9"); 637*0Sstevel@tonic-gate if (fdchar.fdc_transfer_rate == 500) { 638*0Sstevel@tonic-gate /* 639*0Sstevel@tonic-gate * formatting a 360KB DD diskette in 640*0Sstevel@tonic-gate * a 1.2MB drive is not a good idea 641*0Sstevel@tonic-gate */ 642*0Sstevel@tonic-gate transfer_rate = 300; 643*0Sstevel@tonic-gate fdchar.fdc_steps = 2; 644*0Sstevel@tonic-gate } 645*0Sstevel@tonic-gate num_cyl = 40; 646*0Sstevel@tonic-gate gap = 0x50; 647*0Sstevel@tonic-gate capacity = "360 KB"; 648*0Sstevel@tonic-gate } else { 649*0Sstevel@tonic-gate (void) strcpy(fd_vtoc->v_asciilabel, 650*0Sstevel@tonic-gate "3.5\" floppy cyl 80 alt 0 hd 2 sec 9"); 651*0Sstevel@tonic-gate num_cyl = 80; 652*0Sstevel@tonic-gate gap = 0x54; 653*0Sstevel@tonic-gate capacity = "720 KB"; 654*0Sstevel@tonic-gate } 655*0Sstevel@tonic-gate sec_size = 512; 656*0Sstevel@tonic-gate spt = 9; 657*0Sstevel@tonic-gate } else if (m_flag) { 658*0Sstevel@tonic-gate #ifdef sparc 659*0Sstevel@tonic-gate transfer_rate = 500; 660*0Sstevel@tonic-gate #else 661*0Sstevel@tonic-gate /* 662*0Sstevel@tonic-gate * 416.67 KB/sec is the effective transfer rate of a "medium" 663*0Sstevel@tonic-gate * density diskette spun at 300 rpm instead of 360 rpm 664*0Sstevel@tonic-gate */ 665*0Sstevel@tonic-gate transfer_rate = 417; 666*0Sstevel@tonic-gate #endif 667*0Sstevel@tonic-gate (void) strcpy(fd_vtoc->v_asciilabel, 668*0Sstevel@tonic-gate "3.5\" floppy cyl 77 alt 0 hd 2 sec 8"); 669*0Sstevel@tonic-gate num_cyl = 77; 670*0Sstevel@tonic-gate sec_size = 1024; 671*0Sstevel@tonic-gate spt = 8; 672*0Sstevel@tonic-gate gap = 0x74; 673*0Sstevel@tonic-gate capacity = "1.2 MB"; 674*0Sstevel@tonic-gate } else if (E_flag) { 675*0Sstevel@tonic-gate (void) strcpy(fd_vtoc->v_asciilabel, 676*0Sstevel@tonic-gate "3.5\" floppy cyl 80 alt 0 hd 2 sec 36"); 677*0Sstevel@tonic-gate transfer_rate = 1000; 678*0Sstevel@tonic-gate num_cyl = 80; 679*0Sstevel@tonic-gate sec_size = 512; 680*0Sstevel@tonic-gate spt = 36; 681*0Sstevel@tonic-gate gap = 0x54; 682*0Sstevel@tonic-gate capacity = "2.88 MB"; 683*0Sstevel@tonic-gate } 684*0Sstevel@tonic-gate /* 685*0Sstevel@tonic-gate * Medium density diskettes have 1024 byte blocks. The dk_map 686*0Sstevel@tonic-gate * structure in dklabel.h assumes the blocks size is DEVBSIZE (512) 687*0Sstevel@tonic-gate * bytes. The dkl_nblk field is in terms of DEVBSIZE byte blocks 688*0Sstevel@tonic-gate * while the spt variable is in terms of the true block size on 689*0Sstevel@tonic-gate * the diskette. 690*0Sstevel@tonic-gate */ 691*0Sstevel@tonic-gate if (allmap.dka_map[2].dkl_nblk != 692*0Sstevel@tonic-gate (2 * num_cyl * spt * (m_flag ? 2 : 1))) { 693*0Sstevel@tonic-gate allmap.dka_map[1].dkl_cylno = num_cyl - 1; 694*0Sstevel@tonic-gate allmap.dka_map[0].dkl_nblk = 2 * (num_cyl - 1) * spt * 695*0Sstevel@tonic-gate (m_flag ? 2 : 1); 696*0Sstevel@tonic-gate allmap.dka_map[1].dkl_nblk = 2 * spt * (m_flag ? 2 : 1); 697*0Sstevel@tonic-gate allmap.dka_map[2].dkl_nblk = 2 * num_cyl * spt * 698*0Sstevel@tonic-gate (m_flag ? 2 : 1); 699*0Sstevel@tonic-gate if (allmap.dka_map[3].dkl_nblk) 700*0Sstevel@tonic-gate allmap.dka_map[3].dkl_nblk = 2 * (num_cyl - 1) * spt * 701*0Sstevel@tonic-gate (m_flag ? 2 : 1); 702*0Sstevel@tonic-gate if (allmap.dka_map[4].dkl_nblk) 703*0Sstevel@tonic-gate allmap.dka_map[4].dkl_nblk = 704*0Sstevel@tonic-gate 2 * spt * (m_flag ? 2 : 1); 705*0Sstevel@tonic-gate } 706*0Sstevel@tonic-gate 707*0Sstevel@tonic-gate 708*0Sstevel@tonic-gate /* initialize the vtoc structure */ 709*0Sstevel@tonic-gate fd_vtoc->v_nparts = 3; 710*0Sstevel@tonic-gate 711*0Sstevel@tonic-gate fd_vtoc->v_part[0].p_start = 0; 712*0Sstevel@tonic-gate fd_vtoc->v_part[0].p_size = ((num_cyl - 1) * 2 * spt * 713*0Sstevel@tonic-gate (m_flag ? 2 : 1)); 714*0Sstevel@tonic-gate fd_vtoc->v_part[1].p_start = ((num_cyl - 1) * 2 * spt * 715*0Sstevel@tonic-gate (m_flag ? 2 : 1)); 716*0Sstevel@tonic-gate fd_vtoc->v_part[1].p_size = 2 * spt * (m_flag ? 2 : 1); 717*0Sstevel@tonic-gate 718*0Sstevel@tonic-gate fd_vtoc->v_part[2].p_start = 0; 719*0Sstevel@tonic-gate fd_vtoc->v_part[2].p_size = num_cyl * 2 * spt * (m_flag ? 2 : 1); 720*0Sstevel@tonic-gate 721*0Sstevel@tonic-gate /* initialize the bios parameter blockstructure */ 722*0Sstevel@tonic-gate bpb->b_nfat = 2; 723*0Sstevel@tonic-gate if (E_flag && drive_size == 3) { 724*0Sstevel@tonic-gate bpb->b_spcl = 2; 725*0Sstevel@tonic-gate *rdirsec = (ushort_t)240; 726*0Sstevel@tonic-gate bpb->b_mediadescriptor = (char)0xF0; 727*0Sstevel@tonic-gate bpb->b_fatsec[0] = 9; 728*0Sstevel@tonic-gate bpb->b_fatsec[1] = 0; 729*0Sstevel@tonic-gate } else if (H_flag) { 730*0Sstevel@tonic-gate if (drive_size == 5) { 731*0Sstevel@tonic-gate bpb->b_spcl = 1; 732*0Sstevel@tonic-gate *rdirsec = 224; 733*0Sstevel@tonic-gate bpb->b_mediadescriptor = (char)0xF9; 734*0Sstevel@tonic-gate bpb->b_fatsec[0] = 7; 735*0Sstevel@tonic-gate bpb->b_fatsec[1] = 0; 736*0Sstevel@tonic-gate } else { 737*0Sstevel@tonic-gate bpb->b_spcl = 1; 738*0Sstevel@tonic-gate *rdirsec = 224; 739*0Sstevel@tonic-gate bpb->b_mediadescriptor = (char)0xF0; 740*0Sstevel@tonic-gate bpb->b_fatsec[0] = 9; 741*0Sstevel@tonic-gate bpb->b_fatsec[1] = 0; 742*0Sstevel@tonic-gate } 743*0Sstevel@tonic-gate } else if (drive_size == 5) { 744*0Sstevel@tonic-gate bpb->b_spcl = 2; 745*0Sstevel@tonic-gate *rdirsec = 112; 746*0Sstevel@tonic-gate bpb->b_mediadescriptor = (char)0xFD; 747*0Sstevel@tonic-gate bpb->b_fatsec[0] = 2; 748*0Sstevel@tonic-gate bpb->b_fatsec[1] = 0; 749*0Sstevel@tonic-gate } else if (drive_size == 3) { 750*0Sstevel@tonic-gate bpb->b_spcl = 2; 751*0Sstevel@tonic-gate *rdirsec = 112; 752*0Sstevel@tonic-gate bpb->b_mediadescriptor = (char)0xF9; 753*0Sstevel@tonic-gate bpb->b_fatsec[0] = 3; 754*0Sstevel@tonic-gate bpb->b_fatsec[1] = 0; 755*0Sstevel@tonic-gate } 756*0Sstevel@tonic-gate 757*0Sstevel@tonic-gate 758*0Sstevel@tonic-gate 759*0Sstevel@tonic-gate #ifndef sparc 760*0Sstevel@tonic-gate if (num_cyl > fdchar.fdc_ncyl || spt > fdchar.fdc_secptrack || 761*0Sstevel@tonic-gate transfer_rate > fdchar.fdc_transfer_rate) { 762*0Sstevel@tonic-gate (void) fprintf(stderr, 763*0Sstevel@tonic-gate gettext("%s: drive not capable of requested density, "), 764*0Sstevel@tonic-gate myname); 765*0Sstevel@tonic-gate perror(nullstring); 766*0Sstevel@tonic-gate exit(3); 767*0Sstevel@tonic-gate } 768*0Sstevel@tonic-gate #endif 769*0Sstevel@tonic-gate if (num_cyl != fdchar.fdc_ncyl || spt != fdchar.fdc_secptrack || 770*0Sstevel@tonic-gate transfer_rate != fdchar.fdc_transfer_rate) { 771*0Sstevel@tonic-gate /* 772*0Sstevel@tonic-gate * -- CAUTION -- 773*0Sstevel@tonic-gate * The SPARC fd driver is using a non-zero value in 774*0Sstevel@tonic-gate * fdc_medium to indicate the 360 rpm, 77 track, 775*0Sstevel@tonic-gate * 9 sectors/track, 1024 bytes/sector mode of operation 776*0Sstevel@tonic-gate * (similar to an 8", DS/DD, 1.2 MB floppy). 777*0Sstevel@tonic-gate * 778*0Sstevel@tonic-gate * The x86 fd driver uses fdc_medium as the diameter 779*0Sstevel@tonic-gate * indicator, either 3 or 5. It should not be modified. 780*0Sstevel@tonic-gate */ 781*0Sstevel@tonic-gate #ifdef sparc 782*0Sstevel@tonic-gate fdchar.fdc_medium = m_flag ? 1 : 0; 783*0Sstevel@tonic-gate #endif 784*0Sstevel@tonic-gate fdchar.fdc_transfer_rate = transfer_rate; 785*0Sstevel@tonic-gate fdchar.fdc_ncyl = num_cyl; 786*0Sstevel@tonic-gate fdchar.fdc_sec_size = sec_size; 787*0Sstevel@tonic-gate fdchar.fdc_secptrack = spt; 788*0Sstevel@tonic-gate 789*0Sstevel@tonic-gate if (ioctl(fd, FDIOSCHAR, &fdchar) == -1) { 790*0Sstevel@tonic-gate (void) fprintf(stderr, gettext( 791*0Sstevel@tonic-gate "%s: FDIOSCHAR (density selection) failed, "), 792*0Sstevel@tonic-gate myname); 793*0Sstevel@tonic-gate 794*0Sstevel@tonic-gate /* restore the default characteristics */ 795*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, save_allmap); 796*0Sstevel@tonic-gate perror(nullstring); 797*0Sstevel@tonic-gate exit(3); 798*0Sstevel@tonic-gate } 799*0Sstevel@tonic-gate if (ioctl(fd, DKIOCSAPART, &allmap) == -1) { 800*0Sstevel@tonic-gate (void) fprintf(stderr, 801*0Sstevel@tonic-gate gettext("%s: DKIOCSAPART failed, "), 802*0Sstevel@tonic-gate myname); 803*0Sstevel@tonic-gate 804*0Sstevel@tonic-gate /* restore the default characteristics */ 805*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, save_allmap); 806*0Sstevel@tonic-gate 807*0Sstevel@tonic-gate perror(nullstring); 808*0Sstevel@tonic-gate exit(3); 809*0Sstevel@tonic-gate } 810*0Sstevel@tonic-gate } 811*0Sstevel@tonic-gate 812*0Sstevel@tonic-gate if (interleave != 1 && interleave != fdgeom.dkg_intrlv) { 813*0Sstevel@tonic-gate fdgeom.dkg_intrlv = interleave; 814*0Sstevel@tonic-gate if (ioctl(fd, DKIOCSGEOM, &fdgeom) == -1) { 815*0Sstevel@tonic-gate (void) fprintf(stderr, 816*0Sstevel@tonic-gate gettext("%s: DKIOCSGEOM failed, "), myname); 817*0Sstevel@tonic-gate perror(nullstring); 818*0Sstevel@tonic-gate 819*0Sstevel@tonic-gate /* restore the default characteristics */ 820*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, save_allmap); 821*0Sstevel@tonic-gate 822*0Sstevel@tonic-gate exit(3); 823*0Sstevel@tonic-gate } 824*0Sstevel@tonic-gate } 825*0Sstevel@tonic-gate 826*0Sstevel@tonic-gate cyl_size = 2 * sec_size * spt; 827*0Sstevel@tonic-gate 828*0Sstevel@tonic-gate if ((ibuf1 = (uchar_t *)malloc((size_t)cyl_size)) == 0 || 829*0Sstevel@tonic-gate (obuf = (uchar_t *)malloc((size_t)cyl_size)) == 0) { 830*0Sstevel@tonic-gate (void) fprintf(stderr, 831*0Sstevel@tonic-gate gettext("%s: can't malloc verify buffer, "), 832*0Sstevel@tonic-gate myname); 833*0Sstevel@tonic-gate perror(nullstring); 834*0Sstevel@tonic-gate /* restore the default characteristics */ 835*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, save_allmap); 836*0Sstevel@tonic-gate 837*0Sstevel@tonic-gate exit(4); 838*0Sstevel@tonic-gate } 839*0Sstevel@tonic-gate (void) memset(ibuf1, (uchar_t)0xA5, cyl_size); 840*0Sstevel@tonic-gate 841*0Sstevel@tonic-gate if (x_flag) 842*0Sstevel@tonic-gate goto skipformat; 843*0Sstevel@tonic-gate 844*0Sstevel@tonic-gate if (!(q_flag && f_flag)) 845*0Sstevel@tonic-gate if (interleave != 1) 846*0Sstevel@tonic-gate (void) printf(gettext( 847*0Sstevel@tonic-gate "Formatting %s, %d cylinders, %d sectors per trk, interleave=%d in %s\n"), 848*0Sstevel@tonic-gate capacity, num_cyl, spt, interleave, real_name); 849*0Sstevel@tonic-gate else 850*0Sstevel@tonic-gate (void) printf(gettext("Formatting %s in %s\n"), 851*0Sstevel@tonic-gate capacity, real_name); 852*0Sstevel@tonic-gate 853*0Sstevel@tonic-gate if (!f_flag) { 854*0Sstevel@tonic-gate (void) printf( 855*0Sstevel@tonic-gate gettext("Press return to start formatting floppy.")); 856*0Sstevel@tonic-gate while (getchar() != '\n') 857*0Sstevel@tonic-gate ; 858*0Sstevel@tonic-gate } 859*0Sstevel@tonic-gate /* 860*0Sstevel@tonic-gate * for those systems that support this ioctl, they will 861*0Sstevel@tonic-gate * return whether or not a diskette is in the drive. 862*0Sstevel@tonic-gate */ 863*0Sstevel@tonic-gate if (ioctl(fd, FDGETCHANGE, &chgd) == 0) { 864*0Sstevel@tonic-gate if (chgd & FDGC_CURRENT) { 865*0Sstevel@tonic-gate (void) fprintf(stderr, 866*0Sstevel@tonic-gate gettext("%s: no diskette in drive %s\n"), 867*0Sstevel@tonic-gate myname, real_name); 868*0Sstevel@tonic-gate 869*0Sstevel@tonic-gate /* restore the default characteristics */ 870*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, save_allmap); 871*0Sstevel@tonic-gate 872*0Sstevel@tonic-gate exit(4); 873*0Sstevel@tonic-gate } 874*0Sstevel@tonic-gate if (chgd & FDGC_CURWPROT) { 875*0Sstevel@tonic-gate (void) fprintf(stderr, 876*0Sstevel@tonic-gate gettext("%s: \"%s\" is write protected\n"), 877*0Sstevel@tonic-gate myname, real_name); 878*0Sstevel@tonic-gate 879*0Sstevel@tonic-gate /* restore the default characteristics */ 880*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, save_allmap); 881*0Sstevel@tonic-gate 882*0Sstevel@tonic-gate exit(1); 883*0Sstevel@tonic-gate } 884*0Sstevel@tonic-gate } 885*0Sstevel@tonic-gate 886*0Sstevel@tonic-gate if ((fbuf = (uchar_t *)malloc((unsigned)(4 * spt))) == 0) { 887*0Sstevel@tonic-gate (void) fprintf(stderr, 888*0Sstevel@tonic-gate gettext("%s: can't malloc format header buffer, "), 889*0Sstevel@tonic-gate myname); 890*0Sstevel@tonic-gate perror(nullstring); 891*0Sstevel@tonic-gate 892*0Sstevel@tonic-gate /* restore the default characteristics */ 893*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, save_allmap); 894*0Sstevel@tonic-gate 895*0Sstevel@tonic-gate exit(3); 896*0Sstevel@tonic-gate } 897*0Sstevel@tonic-gate /* 898*0Sstevel@tonic-gate * do the format, a track at a time 899*0Sstevel@tonic-gate */ 900*0Sstevel@tonic-gate fcmd_fmt.fdc_blkno = 0; 901*0Sstevel@tonic-gate for (cyl = 0; cyl < (z_flag ? 1 : (int)num_cyl); cyl++) { 902*0Sstevel@tonic-gate #if 0 903*0Sstevel@tonic-gate /* 904*0Sstevel@tonic-gate * This should be the ioctl used to format the floppy. 905*0Sstevel@tonic-gate * The device driver should do do the work, 906*0Sstevel@tonic-gate * instead of this program mucking with a lot 907*0Sstevel@tonic-gate * of low-level, device-dependent code. 908*0Sstevel@tonic-gate */ 909*0Sstevel@tonic-gate for (hd = 0; hd < fdchar.fdc_nhead; hd++) { 910*0Sstevel@tonic-gate if (ioctl(fd, FDIOCMD, &fcmd_fmt) == -1) { 911*0Sstevel@tonic-gate (void) fprintf(stderr, 912*0Sstevel@tonic-gate gettext("%s: format of cyl %d head %d failed\n"), 913*0Sstevel@tonic-gate myname, cyl, hd); 914*0Sstevel@tonic-gate 915*0Sstevel@tonic-gate /* restore the default characteristics */ 916*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, 917*0Sstevel@tonic-gate save_allmap); 918*0Sstevel@tonic-gate exit(3); 919*0Sstevel@tonic-gate } 920*0Sstevel@tonic-gate fcmd_fmt.fdc_blkno += spt; 921*0Sstevel@tonic-gate } 922*0Sstevel@tonic-gate #else 923*0Sstevel@tonic-gate /* 924*0Sstevel@tonic-gate * This is not the optimal ioctl to format the floppy. 925*0Sstevel@tonic-gate * The device driver should do do the work, 926*0Sstevel@tonic-gate * instead of this program mucking with a lot 927*0Sstevel@tonic-gate * of low-level, device-dependent code. 928*0Sstevel@tonic-gate */ 929*0Sstevel@tonic-gate fdr_seek.fdr_cmd[2] = cyl; 930*0Sstevel@tonic-gate if (ioctl(fd, FDRAW, &fdr_seek) == -1) { 931*0Sstevel@tonic-gate (void) fprintf(stderr, 932*0Sstevel@tonic-gate gettext("%s: seek to cyl %d failed\n"), 933*0Sstevel@tonic-gate myname, cyl); 934*0Sstevel@tonic-gate 935*0Sstevel@tonic-gate /* restore the default characteristics */ 936*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, save_allmap); 937*0Sstevel@tonic-gate 938*0Sstevel@tonic-gate exit(3); 939*0Sstevel@tonic-gate } 940*0Sstevel@tonic-gate /* 941*0Sstevel@tonic-gate * Assume that the fd driver has issued a SENSE_INT 942*0Sstevel@tonic-gate * command to complete the seek operation. 943*0Sstevel@tonic-gate */ 944*0Sstevel@tonic-gate for (hd = 0; hd < fdchar.fdc_nhead; hd++) { 945*0Sstevel@tonic-gate p = (uchar_t *)fbuf; 946*0Sstevel@tonic-gate for (i = 1; i <= spt; i++) { 947*0Sstevel@tonic-gate *p++ = cyl; 948*0Sstevel@tonic-gate *p++ = hd; 949*0Sstevel@tonic-gate *p++ = i; /* sector # */ 950*0Sstevel@tonic-gate *p++ = (sec_size == 1024) ? 3 : 2; 951*0Sstevel@tonic-gate } 952*0Sstevel@tonic-gate /* 953*0Sstevel@tonic-gate * ASSUME the fd driver is going to set drive-select 954*0Sstevel@tonic-gate * bits in the second command byte 955*0Sstevel@tonic-gate */ 956*0Sstevel@tonic-gate fdr_form.fdr_cmd[1] = hd << 2; 957*0Sstevel@tonic-gate fdr_form.fdr_cmd[2] = (sec_size == 1024) ? 3 : 2; 958*0Sstevel@tonic-gate fdr_form.fdr_cmd[3] = spt; 959*0Sstevel@tonic-gate fdr_form.fdr_cmd[4] = gap; 960*0Sstevel@tonic-gate fdr_form.fdr_nbytes = 4 * spt; 961*0Sstevel@tonic-gate fdr_form.fdr_addr = (char *)fbuf; 962*0Sstevel@tonic-gate 963*0Sstevel@tonic-gate if (ioctl(fd, FDRAW, &fdr_form) == -1) { 964*0Sstevel@tonic-gate 965*0Sstevel@tonic-gate 966*0Sstevel@tonic-gate (void) fprintf(stderr, gettext( 967*0Sstevel@tonic-gate "%s: format of cyl %d head %d failed\n"), 968*0Sstevel@tonic-gate myname, cyl, hd); 969*0Sstevel@tonic-gate 970*0Sstevel@tonic-gate /* restore the default characteristics */ 971*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, 972*0Sstevel@tonic-gate save_allmap); 973*0Sstevel@tonic-gate 974*0Sstevel@tonic-gate exit(3); 975*0Sstevel@tonic-gate } 976*0Sstevel@tonic-gate if (fdr_form.fdr_result[0] & 0xC0) { 977*0Sstevel@tonic-gate if (fdr_form.fdr_result[1] & 0x02) { 978*0Sstevel@tonic-gate (void) fprintf(stderr, gettext( 979*0Sstevel@tonic-gate /*CSTYLED*/ 980*0Sstevel@tonic-gate "%s: diskette is write protected\n"), 981*0Sstevel@tonic-gate myname); 982*0Sstevel@tonic-gate 983*0Sstevel@tonic-gate /* 984*0Sstevel@tonic-gate * restore the default 985*0Sstevel@tonic-gate * characteristics 986*0Sstevel@tonic-gate */ 987*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, 988*0Sstevel@tonic-gate save_allmap); 989*0Sstevel@tonic-gate 990*0Sstevel@tonic-gate exit(3); 991*0Sstevel@tonic-gate } 992*0Sstevel@tonic-gate (void) fprintf(stderr, gettext( 993*0Sstevel@tonic-gate "%s: format of cyl %d head %d failed\n"), 994*0Sstevel@tonic-gate myname, cyl, hd); 995*0Sstevel@tonic-gate 996*0Sstevel@tonic-gate /* restore the default characteristics */ 997*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, 998*0Sstevel@tonic-gate save_allmap); 999*0Sstevel@tonic-gate 1000*0Sstevel@tonic-gate exit(3); 1001*0Sstevel@tonic-gate } 1002*0Sstevel@tonic-gate 1003*0Sstevel@tonic-gate } 1004*0Sstevel@tonic-gate #endif 1005*0Sstevel@tonic-gate 1006*0Sstevel@tonic-gate /* 1007*0Sstevel@tonic-gate * do a quick verify 1008*0Sstevel@tonic-gate */ 1009*0Sstevel@tonic-gate if (!v_flag) { 1010*0Sstevel@tonic-gate if (lseek(fd, cyl * cyl_size, 0) != cyl * cyl_size) { 1011*0Sstevel@tonic-gate (void) fprintf(stderr, 1012*0Sstevel@tonic-gate gettext("%s: bad seek to format verify, "), 1013*0Sstevel@tonic-gate myname); 1014*0Sstevel@tonic-gate perror(nullstring); 1015*0Sstevel@tonic-gate /* restore the default characteristics */ 1016*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, 1017*0Sstevel@tonic-gate save_allmap); 1018*0Sstevel@tonic-gate 1019*0Sstevel@tonic-gate exit(3); 1020*0Sstevel@tonic-gate } 1021*0Sstevel@tonic-gate if (read(fd, obuf, cyl_size) == cyl_size) { 1022*0Sstevel@tonic-gate /* write some progress msg */ 1023*0Sstevel@tonic-gate /* when each cylinder is done. */ 1024*0Sstevel@tonic-gate if (!q_flag) 1025*0Sstevel@tonic-gate (void) printf("."); 1026*0Sstevel@tonic-gate } else { 1027*0Sstevel@tonic-gate if (!q_flag) 1028*0Sstevel@tonic-gate (void) printf(gettext("e\n")); 1029*0Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1030*0Sstevel@tonic-gate "%s: can't read format data, "), myname); 1031*0Sstevel@tonic-gate perror(nullstring); 1032*0Sstevel@tonic-gate /* restore the default characteristics */ 1033*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, 1034*0Sstevel@tonic-gate save_allmap); 1035*0Sstevel@tonic-gate 1036*0Sstevel@tonic-gate exit(3); 1037*0Sstevel@tonic-gate } 1038*0Sstevel@tonic-gate } else 1039*0Sstevel@tonic-gate if (!q_flag) 1040*0Sstevel@tonic-gate (void) printf("."); 1041*0Sstevel@tonic-gate if (!q_flag) 1042*0Sstevel@tonic-gate (void) fflush(stdout); 1043*0Sstevel@tonic-gate } 1044*0Sstevel@tonic-gate if (!q_flag) 1045*0Sstevel@tonic-gate (void) printf("\n"); 1046*0Sstevel@tonic-gate skipformat: 1047*0Sstevel@tonic-gate if (v_flag) { 1048*0Sstevel@tonic-gate /* 1049*0Sstevel@tonic-gate * do a write & read verify of the entire diskette 1050*0Sstevel@tonic-gate */ 1051*0Sstevel@tonic-gate if (!q_flag && x_flag) 1052*0Sstevel@tonic-gate (void) printf(gettext("Verifying %s in %s\n"), 1053*0Sstevel@tonic-gate capacity, real_name); 1054*0Sstevel@tonic-gate 1055*0Sstevel@tonic-gate for (cyl = 0; cyl < (int)num_cyl; cyl++) { 1056*0Sstevel@tonic-gate 1057*0Sstevel@tonic-gate int val; 1058*0Sstevel@tonic-gate if ((val = verify(fd, 2 * spt * cyl, cyl_size)) != 0) { 1059*0Sstevel@tonic-gate perror(nullstring); 1060*0Sstevel@tonic-gate 1061*0Sstevel@tonic-gate /* restore the default characteristics */ 1062*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, 1063*0Sstevel@tonic-gate save_allmap); 1064*0Sstevel@tonic-gate 1065*0Sstevel@tonic-gate exit(val); 1066*0Sstevel@tonic-gate 1067*0Sstevel@tonic-gate } 1068*0Sstevel@tonic-gate /* write some progress msg as */ 1069*0Sstevel@tonic-gate /* each cylinder is done. */ 1070*0Sstevel@tonic-gate if (!q_flag) 1071*0Sstevel@tonic-gate (void) printf(gettext("v")); 1072*0Sstevel@tonic-gate (void) fflush(stdout); 1073*0Sstevel@tonic-gate } 1074*0Sstevel@tonic-gate if (!q_flag) 1075*0Sstevel@tonic-gate (void) printf("\n"); 1076*0Sstevel@tonic-gate } 1077*0Sstevel@tonic-gate 1078*0Sstevel@tonic-gate if (lseek(fd, (off_t)0, 0) != 0) { 1079*0Sstevel@tonic-gate (void) fprintf(stderr, gettext("%s: seek to blk 0 failed, "), 1080*0Sstevel@tonic-gate myname); 1081*0Sstevel@tonic-gate perror(nullstring); 1082*0Sstevel@tonic-gate /* restore the default characteristics */ 1083*0Sstevel@tonic-gate restore_default_chars(fd, save_fdchar, save_allmap); 1084*0Sstevel@tonic-gate 1085*0Sstevel@tonic-gate exit(3); 1086*0Sstevel@tonic-gate } 1087*0Sstevel@tonic-gate 1088*0Sstevel@tonic-gate } 1089*0Sstevel@tonic-gate 1090*0Sstevel@tonic-gate 1091*0Sstevel@tonic-gate /* 1092*0Sstevel@tonic-gate * Restore the default characteristics of the floppy diskette. 1093*0Sstevel@tonic-gate * Fdformat changes the characteristics in the process of formatting. 1094*0Sstevel@tonic-gate * If fdformat fails while in the process of doing the format, fdformat 1095*0Sstevel@tonic-gate * should clean up after itself and reset the driver back to the original 1096*0Sstevel@tonic-gate * state. 1097*0Sstevel@tonic-gate */ 1098*0Sstevel@tonic-gate 1099*0Sstevel@tonic-gate static void 1100*0Sstevel@tonic-gate restore_default_chars(int fd, 1101*0Sstevel@tonic-gate struct fd_char save_fdchar, 1102*0Sstevel@tonic-gate struct dk_allmap save_allmap) 1103*0Sstevel@tonic-gate { 1104*0Sstevel@tonic-gate 1105*0Sstevel@tonic-gate 1106*0Sstevel@tonic-gate /* 1107*0Sstevel@tonic-gate * When this function is called, fdformat is failing anyways, 1108*0Sstevel@tonic-gate * so the errors are not processed. 1109*0Sstevel@tonic-gate */ 1110*0Sstevel@tonic-gate 1111*0Sstevel@tonic-gate (void) ioctl(fd, FDIOSCHAR, &save_fdchar); 1112*0Sstevel@tonic-gate 1113*0Sstevel@tonic-gate (void) ioctl(fd, DKIOCSAPART, &save_allmap); 1114*0Sstevel@tonic-gate 1115*0Sstevel@tonic-gate /* 1116*0Sstevel@tonic-gate * Before looking at the diskette's characteristics, format_diskette() 1117*0Sstevel@tonic-gate * sets the x86 floppy driver to the default characteristics. 1118*0Sstevel@tonic-gate * restore drive to default geometry and 1119*0Sstevel@tonic-gate * characteristics. This ioctl isn't implemented on 1120*0Sstevel@tonic-gate * sparc. 1121*0Sstevel@tonic-gate */ 1122*0Sstevel@tonic-gate (void) ioctl(fd, FDDEFGEOCHAR, NULL); 1123*0Sstevel@tonic-gate 1124*0Sstevel@tonic-gate } 1125*0Sstevel@tonic-gate 1126*0Sstevel@tonic-gate /* 1127*0Sstevel@tonic-gate * Inputs: file descriptor for the device and the device name. 1128*0Sstevel@tonic-gate * Oututs: the fd_vtoc will be partially filled in with the 1129*0Sstevel@tonic-gate * device specific information such as partition 1130*0Sstevel@tonic-gate * information and ascillabel. The bpb structure and rdirsec will also be 1131*0Sstevel@tonic-gate * partially filled in with device specific information. 1132*0Sstevel@tonic-gate */ 1133*0Sstevel@tonic-gate void 1134*0Sstevel@tonic-gate format_pcmcia_card(int fd, char *real_name, struct vtoc *fd_vtoc, 1135*0Sstevel@tonic-gate struct bios_param_blk *bpb, int *rdirsec) 1136*0Sstevel@tonic-gate { 1137*0Sstevel@tonic-gate int sec_size; /* sector size */ 1138*0Sstevel@tonic-gate int i, j; 1139*0Sstevel@tonic-gate char wrpat; 1140*0Sstevel@tonic-gate char wrbuf[512]; 1141*0Sstevel@tonic-gate char rdbuf[512]; 1142*0Sstevel@tonic-gate enum dkio_state state = DKIO_NONE; 1143*0Sstevel@tonic-gate int card_size; /* PCMCIA memory card size */ 1144*0Sstevel@tonic-gate ulong_t max_cyl; /* max number of cylinders */ 1145*0Sstevel@tonic-gate int sec_fat; 1146*0Sstevel@tonic-gate 1147*0Sstevel@tonic-gate /* 1148*0Sstevel@tonic-gate * Using DKIOCSTATE ioctl() 1149*0Sstevel@tonic-gate * to replace FDGETCHANGE ioctl() 1150*0Sstevel@tonic-gate * start out with state=DKIO_NONE 1151*0Sstevel@tonic-gate */ 1152*0Sstevel@tonic-gate if (ioctl(fd, DKIOCSTATE, &state) < 0) { 1153*0Sstevel@tonic-gate (void) fprintf(stderr, 1154*0Sstevel@tonic-gate gettext("%s: DKIOCSTATE failed, "), 1155*0Sstevel@tonic-gate myname); 1156*0Sstevel@tonic-gate perror(""); 1157*0Sstevel@tonic-gate exit(3); 1158*0Sstevel@tonic-gate } 1159*0Sstevel@tonic-gate 1160*0Sstevel@tonic-gate if (state != DKIO_INSERTED) { 1161*0Sstevel@tonic-gate (void) fprintf(stderr, 1162*0Sstevel@tonic-gate gettext("%s: no media in %s\n"), 1163*0Sstevel@tonic-gate myname, real_name); 1164*0Sstevel@tonic-gate exit(4); 1165*0Sstevel@tonic-gate } 1166*0Sstevel@tonic-gate 1167*0Sstevel@tonic-gate 1168*0Sstevel@tonic-gate /* initialize the asciilabel */ 1169*0Sstevel@tonic-gate (void) strcpy(fd_vtoc->v_asciilabel, "PCMCIA Memory Card"); 1170*0Sstevel@tonic-gate 1171*0Sstevel@tonic-gate /* Get card cyl/head/secptrack info */ 1172*0Sstevel@tonic-gate if (ioctl(fd, DKIOCGGEOM, &dkg) == -1) { 1173*0Sstevel@tonic-gate /* 1174*0Sstevel@tonic-gate * Card doesn't have a CIS. So, ask driver to probe 1175*0Sstevel@tonic-gate * card size info 1176*0Sstevel@tonic-gate */ 1177*0Sstevel@tonic-gate if (ioctl(fd, PCRAM_PROBESIZE, &dkg) == -1) { 1178*0Sstevel@tonic-gate (void) fprintf(stderr, 1179*0Sstevel@tonic-gate gettext("%s: Unable to get card size information"), 1180*0Sstevel@tonic-gate myname); 1181*0Sstevel@tonic-gate perror(""); 1182*0Sstevel@tonic-gate exit(3); 1183*0Sstevel@tonic-gate } 1184*0Sstevel@tonic-gate } 1185*0Sstevel@tonic-gate 1186*0Sstevel@tonic-gate /* PCMCIA memory default sector size */ 1187*0Sstevel@tonic-gate sec_size = DEV_BSIZE; 1188*0Sstevel@tonic-gate 1189*0Sstevel@tonic-gate fdchar.fdc_sec_size = sec_size; 1190*0Sstevel@tonic-gate fdchar.fdc_ncyl = dkg.dkg_ncyl; 1191*0Sstevel@tonic-gate fdchar.fdc_nhead = dkg.dkg_nhead; 1192*0Sstevel@tonic-gate fdchar.fdc_secptrack = dkg.dkg_nsect; 1193*0Sstevel@tonic-gate 1194*0Sstevel@tonic-gate max_cyl = fdchar.fdc_ncyl; 1195*0Sstevel@tonic-gate 1196*0Sstevel@tonic-gate /* Initialize the vtoc information */ 1197*0Sstevel@tonic-gate fd_vtoc->v_part[2].p_start = 0; 1198*0Sstevel@tonic-gate fd_vtoc->v_part[2].p_size = max_cyl * fdchar.fdc_nhead 1199*0Sstevel@tonic-gate * fdchar.fdc_secptrack; 1200*0Sstevel@tonic-gate fd_vtoc->v_nparts = 1; 1201*0Sstevel@tonic-gate 1202*0Sstevel@tonic-gate card_size = fdchar.fdc_ncyl * fdchar.fdc_nhead * 1203*0Sstevel@tonic-gate fdchar.fdc_secptrack * fdchar.fdc_sec_size; 1204*0Sstevel@tonic-gate 1205*0Sstevel@tonic-gate /* Initialize the bios parameter block information */ 1206*0Sstevel@tonic-gate bpb->b_nfat = 1; 1207*0Sstevel@tonic-gate if (card_size < 1048576) { 1208*0Sstevel@tonic-gate bpb->b_spcl = 2; 1209*0Sstevel@tonic-gate *rdirsec = 112; 1210*0Sstevel@tonic-gate } else { 1211*0Sstevel@tonic-gate bpb->b_spcl = 1; 1212*0Sstevel@tonic-gate *rdirsec = 224; 1213*0Sstevel@tonic-gate } 1214*0Sstevel@tonic-gate bpb->b_mediadescriptor = (char)0xf8; /* fixed disk */ 1215*0Sstevel@tonic-gate 1216*0Sstevel@tonic-gate /* 1217*0Sstevel@tonic-gate * card_size sec_fat 1218*0Sstevel@tonic-gate * 524288 3 1219*0Sstevel@tonic-gate * 1048576 6 1220*0Sstevel@tonic-gate * 2097152 12 1221*0Sstevel@tonic-gate */ 1222*0Sstevel@tonic-gate 1223*0Sstevel@tonic-gate sec_fat = (card_size * 3) / 524288; 1224*0Sstevel@tonic-gate bpb->b_fatsec[0] = sec_fat % 0x100; 1225*0Sstevel@tonic-gate bpb->b_fatsec[1] = sec_fat / 0x100; 1226*0Sstevel@tonic-gate 1227*0Sstevel@tonic-gate 1228*0Sstevel@tonic-gate (void) printf(gettext("Formatting %d bytes in %s\n"), 1229*0Sstevel@tonic-gate card_size, real_name); 1230*0Sstevel@tonic-gate 1231*0Sstevel@tonic-gate if (!f_flag && !x_flag) { 1232*0Sstevel@tonic-gate (void) printf(gettext( 1233*0Sstevel@tonic-gate /*CSTYLED*/ 1234*0Sstevel@tonic-gate "Press return to start formatting PCMCIA memory card.")); 1235*0Sstevel@tonic-gate while (getchar() != '\n') 1236*0Sstevel@tonic-gate ; 1237*0Sstevel@tonic-gate } 1238*0Sstevel@tonic-gate 1239*0Sstevel@tonic-gate 1240*0Sstevel@tonic-gate /* 1241*0Sstevel@tonic-gate * Skip the format, only install SunOS label or DOS file system. 1242*0Sstevel@tonic-gate */ 1243*0Sstevel@tonic-gate if (x_flag) 1244*0Sstevel@tonic-gate goto skipformat; 1245*0Sstevel@tonic-gate 1246*0Sstevel@tonic-gate /* 1247*0Sstevel@tonic-gate * First try to format only 512 bytes with four different 1248*0Sstevel@tonic-gate * patterns. 1249*0Sstevel@tonic-gate */ 1250*0Sstevel@tonic-gate for (i = 0; i < 4; ++i) { 1251*0Sstevel@tonic-gate switch (i) { 1252*0Sstevel@tonic-gate 1253*0Sstevel@tonic-gate case 0: 1254*0Sstevel@tonic-gate wrpat = (uchar_t)PATTERN_1; 1255*0Sstevel@tonic-gate break; 1256*0Sstevel@tonic-gate case 1: 1257*0Sstevel@tonic-gate wrpat = (uchar_t)PATTERN_2; 1258*0Sstevel@tonic-gate break; 1259*0Sstevel@tonic-gate case 2: 1260*0Sstevel@tonic-gate wrpat = (uchar_t)PATTERN_3; 1261*0Sstevel@tonic-gate break; 1262*0Sstevel@tonic-gate case 3: 1263*0Sstevel@tonic-gate wrpat = PATTERN_4; 1264*0Sstevel@tonic-gate break; 1265*0Sstevel@tonic-gate } 1266*0Sstevel@tonic-gate 1267*0Sstevel@tonic-gate if (lseek(fd, (off_t)0, 0) != 0) { 1268*0Sstevel@tonic-gate (void) fprintf(stderr, 1269*0Sstevel@tonic-gate gettext("%s: seek to blk 0 failed, "), 1270*0Sstevel@tonic-gate myname); 1271*0Sstevel@tonic-gate perror(""); 1272*0Sstevel@tonic-gate exit(3); 1273*0Sstevel@tonic-gate } 1274*0Sstevel@tonic-gate 1275*0Sstevel@tonic-gate (void) memset(wrbuf, wrpat, 512); 1276*0Sstevel@tonic-gate 1277*0Sstevel@tonic-gate if (write(fd, &wrbuf[0], 512) != 512) { 1278*0Sstevel@tonic-gate (void) fprintf(stderr, 1279*0Sstevel@tonic-gate /*CSTYLED*/ 1280*0Sstevel@tonic-gate gettext("%s: Format Write failed, "), myname); 1281*0Sstevel@tonic-gate perror(""); 1282*0Sstevel@tonic-gate exit(3); 1283*0Sstevel@tonic-gate } 1284*0Sstevel@tonic-gate 1285*0Sstevel@tonic-gate if (lseek(fd, (off_t)0, 0) != 0) { 1286*0Sstevel@tonic-gate (void) fprintf(stderr, 1287*0Sstevel@tonic-gate gettext("%s: seek to blk 0 failed, "), 1288*0Sstevel@tonic-gate myname); 1289*0Sstevel@tonic-gate perror(""); 1290*0Sstevel@tonic-gate exit(3); 1291*0Sstevel@tonic-gate } 1292*0Sstevel@tonic-gate 1293*0Sstevel@tonic-gate if (read(fd, &rdbuf[0], 512) != 512) { 1294*0Sstevel@tonic-gate (void) fprintf(stderr, 1295*0Sstevel@tonic-gate /*CSTYLED*/ 1296*0Sstevel@tonic-gate gettext("%s: Format Read failed, "), myname); 1297*0Sstevel@tonic-gate perror(""); 1298*0Sstevel@tonic-gate exit(3); 1299*0Sstevel@tonic-gate } 1300*0Sstevel@tonic-gate 1301*0Sstevel@tonic-gate if (memcmp(wrbuf, rdbuf, 512) != 0) { 1302*0Sstevel@tonic-gate (void) fprintf(stderr, 1303*0Sstevel@tonic-gate /*CSTYLED*/ 1304*0Sstevel@tonic-gate gettext("%s: Format Compare Error, "), myname); 1305*0Sstevel@tonic-gate perror(""); 1306*0Sstevel@tonic-gate exit(3); 1307*0Sstevel@tonic-gate } 1308*0Sstevel@tonic-gate } 1309*0Sstevel@tonic-gate /* 1310*0Sstevel@tonic-gate * Then format the whole memory card with patterns 1311*0Sstevel@tonic-gate * 0xff and 0x00 to erase the card. 1312*0Sstevel@tonic-gate */ 1313*0Sstevel@tonic-gate for (i = 0; i < 2; ++i) { 1314*0Sstevel@tonic-gate 1315*0Sstevel@tonic-gate if (i == 0) { 1316*0Sstevel@tonic-gate wrpat = (uchar_t)PATTERN_3; 1317*0Sstevel@tonic-gate } else { 1318*0Sstevel@tonic-gate wrpat = PATTERN_4; 1319*0Sstevel@tonic-gate } 1320*0Sstevel@tonic-gate 1321*0Sstevel@tonic-gate if (lseek(fd, (off_t)0, 0) != 0) { 1322*0Sstevel@tonic-gate (void) fprintf(stderr, 1323*0Sstevel@tonic-gate gettext("%s: seek to blk 0 failed, "), 1324*0Sstevel@tonic-gate myname); 1325*0Sstevel@tonic-gate perror(""); 1326*0Sstevel@tonic-gate exit(3); 1327*0Sstevel@tonic-gate } 1328*0Sstevel@tonic-gate 1329*0Sstevel@tonic-gate (void) memset(wrbuf, wrpat, 512); 1330*0Sstevel@tonic-gate 1331*0Sstevel@tonic-gate for (j = 0; j < (card_size/512); ++j) { 1332*0Sstevel@tonic-gate if (write(fd, &wrbuf[0], 512) != 512) { 1333*0Sstevel@tonic-gate (void) fprintf(stderr, 1334*0Sstevel@tonic-gate /*CSTYLED*/ 1335*0Sstevel@tonic-gate gettext("%s: Format Write failed, "), myname); 1336*0Sstevel@tonic-gate perror(""); 1337*0Sstevel@tonic-gate exit(3); 1338*0Sstevel@tonic-gate } 1339*0Sstevel@tonic-gate /* 1340*0Sstevel@tonic-gate * write some progress msg when each 1341*0Sstevel@tonic-gate * 512KB block is done. 1342*0Sstevel@tonic-gate */ 1343*0Sstevel@tonic-gate if (((j%1024) == 0) && (!q_flag)) { 1344*0Sstevel@tonic-gate (void) printf("."); 1345*0Sstevel@tonic-gate (void) fflush(stdout); 1346*0Sstevel@tonic-gate } 1347*0Sstevel@tonic-gate } 1348*0Sstevel@tonic-gate /* 1349*0Sstevel@tonic-gate * do a verify 1350*0Sstevel@tonic-gate */ 1351*0Sstevel@tonic-gate 1352*0Sstevel@tonic-gate if (lseek(fd, (off_t)0, 0) != 0) { 1353*0Sstevel@tonic-gate (void) fprintf(stderr, 1354*0Sstevel@tonic-gate gettext("%s: seek to blk 0 failed, "), 1355*0Sstevel@tonic-gate myname); 1356*0Sstevel@tonic-gate perror(""); 1357*0Sstevel@tonic-gate exit(3); 1358*0Sstevel@tonic-gate } 1359*0Sstevel@tonic-gate 1360*0Sstevel@tonic-gate for (j = 0; j < (card_size/512); ++j) { 1361*0Sstevel@tonic-gate if (read(fd, &rdbuf[0], 512) != 512) { 1362*0Sstevel@tonic-gate (void) fprintf(stderr, 1363*0Sstevel@tonic-gate /*CSTYLED*/ 1364*0Sstevel@tonic-gate gettext("%s: Format Read failed, "), myname); 1365*0Sstevel@tonic-gate perror(""); 1366*0Sstevel@tonic-gate exit(3); 1367*0Sstevel@tonic-gate } 1368*0Sstevel@tonic-gate if (memcmp(wrbuf, rdbuf, 512) != 0) { 1369*0Sstevel@tonic-gate (void) fprintf(stderr, 1370*0Sstevel@tonic-gate /*CSTYLED*/ 1371*0Sstevel@tonic-gate gettext("%s: Format Compare Error, "), myname); 1372*0Sstevel@tonic-gate perror(""); 1373*0Sstevel@tonic-gate exit(3); 1374*0Sstevel@tonic-gate } 1375*0Sstevel@tonic-gate /*CSTYLED*/ 1376*0Sstevel@tonic-gate /* write some progress msg when each 512KB block is done. */ 1377*0Sstevel@tonic-gate if ((j%1024) == 0) { 1378*0Sstevel@tonic-gate if (!q_flag) { 1379*0Sstevel@tonic-gate (void) printf("."); 1380*0Sstevel@tonic-gate (void) fflush(stdout); 1381*0Sstevel@tonic-gate } 1382*0Sstevel@tonic-gate } 1383*0Sstevel@tonic-gate } 1384*0Sstevel@tonic-gate } 1385*0Sstevel@tonic-gate if (!q_flag) 1386*0Sstevel@tonic-gate (void) printf("\n"); 1387*0Sstevel@tonic-gate 1388*0Sstevel@tonic-gate skipformat: 1389*0Sstevel@tonic-gate if (lseek(fd, (off_t)0, 0) != 0) { 1390*0Sstevel@tonic-gate (void) fprintf(stderr, gettext("%s: seek to blk 0 failed, "), 1391*0Sstevel@tonic-gate myname); 1392*0Sstevel@tonic-gate perror(""); 1393*0Sstevel@tonic-gate exit(3); 1394*0Sstevel@tonic-gate } 1395*0Sstevel@tonic-gate } 1396*0Sstevel@tonic-gate 1397*0Sstevel@tonic-gate 1398*0Sstevel@tonic-gate 1399*0Sstevel@tonic-gate /* 1400*0Sstevel@tonic-gate * See if any partitions on the device are mounted. Return 1 if a partition is 1401*0Sstevel@tonic-gate * mounted. Return 0 otherwise. 1402*0Sstevel@tonic-gate */ 1403*0Sstevel@tonic-gate static int 1404*0Sstevel@tonic-gate check_mount() 1405*0Sstevel@tonic-gate { 1406*0Sstevel@tonic-gate FILE *fp = NULL; 1407*0Sstevel@tonic-gate int mfd; 1408*0Sstevel@tonic-gate struct dk_cinfo dkinfo_tmp; 1409*0Sstevel@tonic-gate struct mnttab mnt_record; 1410*0Sstevel@tonic-gate struct mnttab *mp = &mnt_record; 1411*0Sstevel@tonic-gate struct stat stbuf; 1412*0Sstevel@tonic-gate char raw_device[MAXPATHLEN]; 1413*0Sstevel@tonic-gate int found = 0; 1414*0Sstevel@tonic-gate 1415*0Sstevel@tonic-gate if ((fp = fopen(MNTTAB, "r")) == NULL) { 1416*0Sstevel@tonic-gate perror(MNTTAB); 1417*0Sstevel@tonic-gate exit(3); 1418*0Sstevel@tonic-gate } 1419*0Sstevel@tonic-gate 1420*0Sstevel@tonic-gate while (getmntent(fp, mp) == 0) { 1421*0Sstevel@tonic-gate if (strstr(mp->mnt_special, "/dev/fd") == NULL && 1422*0Sstevel@tonic-gate strstr(mp->mnt_special, "/dev/disket") == NULL && 1423*0Sstevel@tonic-gate strstr(mp->mnt_special, "/dev/c") == NULL) { 1424*0Sstevel@tonic-gate continue; 1425*0Sstevel@tonic-gate } 1426*0Sstevel@tonic-gate 1427*0Sstevel@tonic-gate (void) strcpy(raw_device, "/dev/r"); 1428*0Sstevel@tonic-gate (void) strcat(raw_device, mp->mnt_special + strlen("/dev/")); 1429*0Sstevel@tonic-gate 1430*0Sstevel@tonic-gate /* 1431*0Sstevel@tonic-gate * Attempt to open the device. If it fails, skip it. 1432*0Sstevel@tonic-gate */ 1433*0Sstevel@tonic-gate if ((mfd = open(raw_device, O_RDWR | O_NDELAY)) < 0) { 1434*0Sstevel@tonic-gate continue; 1435*0Sstevel@tonic-gate } 1436*0Sstevel@tonic-gate 1437*0Sstevel@tonic-gate /* 1438*0Sstevel@tonic-gate * Must be a character device 1439*0Sstevel@tonic-gate */ 1440*0Sstevel@tonic-gate if (fstat(mfd, &stbuf) == -1 || !S_ISCHR(stbuf.st_mode)) { 1441*0Sstevel@tonic-gate (void) close(mfd); 1442*0Sstevel@tonic-gate continue; 1443*0Sstevel@tonic-gate } 1444*0Sstevel@tonic-gate /* 1445*0Sstevel@tonic-gate * Attempt to read the configuration info on the disk. 1446*0Sstevel@tonic-gate */ 1447*0Sstevel@tonic-gate if (ioctl(mfd, DKIOCINFO, &dkinfo_tmp) < 0) { 1448*0Sstevel@tonic-gate (void) close(mfd); 1449*0Sstevel@tonic-gate continue; 1450*0Sstevel@tonic-gate } 1451*0Sstevel@tonic-gate /* 1452*0Sstevel@tonic-gate * Finished with the opened device 1453*0Sstevel@tonic-gate */ 1454*0Sstevel@tonic-gate (void) close(mfd); 1455*0Sstevel@tonic-gate 1456*0Sstevel@tonic-gate /* 1457*0Sstevel@tonic-gate * If it's not the disk we're interested in, it doesn't apply. 1458*0Sstevel@tonic-gate */ 1459*0Sstevel@tonic-gate if (dkinfo.dki_ctype != dkinfo_tmp.dki_ctype || 1460*0Sstevel@tonic-gate dkinfo.dki_cnum != dkinfo_tmp.dki_cnum || 1461*0Sstevel@tonic-gate dkinfo.dki_unit != dkinfo_tmp.dki_unit) { 1462*0Sstevel@tonic-gate continue; 1463*0Sstevel@tonic-gate } 1464*0Sstevel@tonic-gate /* 1465*0Sstevel@tonic-gate * It's a mount on the disk we're checking. If we are 1466*0Sstevel@tonic-gate * checking whole disk, then we found trouble. We can 1467*0Sstevel@tonic-gate * quit searching. 1468*0Sstevel@tonic-gate */ 1469*0Sstevel@tonic-gate 1470*0Sstevel@tonic-gate if (U_flag) { 1471*0Sstevel@tonic-gate if (!_dev_unmount(mp->mnt_special)) { 1472*0Sstevel@tonic-gate (void) fprintf(stderr, 1473*0Sstevel@tonic-gate gettext("%s: umount of %s failed\n"), 1474*0Sstevel@tonic-gate myname, mp->mnt_special); 1475*0Sstevel@tonic-gate found = 1; 1476*0Sstevel@tonic-gate } 1477*0Sstevel@tonic-gate } else { 1478*0Sstevel@tonic-gate (void) fprintf(stderr, 1479*0Sstevel@tonic-gate gettext("%s: %s is mounted (use -U flag)\n"), 1480*0Sstevel@tonic-gate myname, mp->mnt_special); 1481*0Sstevel@tonic-gate found = 1; 1482*0Sstevel@tonic-gate } 1483*0Sstevel@tonic-gate } 1484*0Sstevel@tonic-gate return (found); 1485*0Sstevel@tonic-gate } 1486*0Sstevel@tonic-gate 1487*0Sstevel@tonic-gate static void 1488*0Sstevel@tonic-gate usage(char *str) 1489*0Sstevel@tonic-gate { 1490*0Sstevel@tonic-gate char *real_name, *alias_name; 1491*0Sstevel@tonic-gate 1492*0Sstevel@tonic-gate if ((real_name = media_findname("floppy")) == NULL) { 1493*0Sstevel@tonic-gate if ((alias_name = _media_oldaliases("floppy")) != NULL) 1494*0Sstevel@tonic-gate real_name = media_findname(alias_name); 1495*0Sstevel@tonic-gate } 1496*0Sstevel@tonic-gate 1497*0Sstevel@tonic-gate if (str[0] != ' ') 1498*0Sstevel@tonic-gate (void) printf("%s: %s\n", myname, str); 1499*0Sstevel@tonic-gate (void) printf(gettext( 1500*0Sstevel@tonic-gate /*CSTYLED*/ 1501*0Sstevel@tonic-gate "\n usage: %s [-dDeEfHlLmMqUvx] [-b label] [-B file] [-t dostype] [devname]\n"), 1502*0Sstevel@tonic-gate myname); 1503*0Sstevel@tonic-gate 1504*0Sstevel@tonic-gate (void) printf(gettext( 1505*0Sstevel@tonic-gate /*CSTYLED*/ 1506*0Sstevel@tonic-gate " -b label install \"label\" on media\n")); 1507*0Sstevel@tonic-gate (void) printf(gettext( 1508*0Sstevel@tonic-gate " -B file install special boot loader on MS-DOS media\n")); 1509*0Sstevel@tonic-gate (void) printf(gettext( 1510*0Sstevel@tonic-gate /*CSTYLED*/ 1511*0Sstevel@tonic-gate " -d format MS-DOS media\n")); 1512*0Sstevel@tonic-gate (void) printf(gettext( 1513*0Sstevel@tonic-gate /*CSTYLED*/ 1514*0Sstevel@tonic-gate " -D format 720KB (3.5\") or 360KB (5.25\") Double-density diskette\n")); 1515*0Sstevel@tonic-gate (void) printf(gettext( 1516*0Sstevel@tonic-gate " -e eject the media when done\n")); 1517*0Sstevel@tonic-gate /*CSTYLED*/ 1518*0Sstevel@tonic-gate (void) printf(gettext( 1519*0Sstevel@tonic-gate /*CSTYLED*/ 1520*0Sstevel@tonic-gate " -E format 2.88MB (3.5\") Extended-density diskette\n")); 1521*0Sstevel@tonic-gate (void) printf(gettext( 1522*0Sstevel@tonic-gate " -f \"force\" - don't wait for confirmation\n")); 1523*0Sstevel@tonic-gate (void) printf(gettext( 1524*0Sstevel@tonic-gate /*CSTYLED*/ 1525*0Sstevel@tonic-gate " -H format 1.44MB (3.5\") or 1.2MB (5.25\") High-density diskette\n")); 1526*0Sstevel@tonic-gate (void) printf(gettext( 1527*0Sstevel@tonic-gate /*CSTYLED*/ 1528*0Sstevel@tonic-gate " -l format 720KB (3.5\") or 360KB (5.25\") Double-density diskette\n")); 1529*0Sstevel@tonic-gate (void) printf(gettext( 1530*0Sstevel@tonic-gate /*CSTYLED*/ 1531*0Sstevel@tonic-gate " -L format 720KB (3.5\") or 360KB (5.25\") Double-density diskette\n")); 1532*0Sstevel@tonic-gate (void) printf(gettext( 1533*0Sstevel@tonic-gate " -m format 1.2MB (3.5\") Medium-density diskette\n")); 1534*0Sstevel@tonic-gate (void) printf(gettext( 1535*0Sstevel@tonic-gate " -M format 1.2MB (3.5\") Medium-density diskette\n")); 1536*0Sstevel@tonic-gate (void) printf(gettext( 1537*0Sstevel@tonic-gate " -q quiet\n")); 1538*0Sstevel@tonic-gate (void) printf(gettext( 1539*0Sstevel@tonic-gate /*CSTYLED*/ 1540*0Sstevel@tonic-gate " -t dos format MS-DOS media (same as -d)\n")); 1541*0Sstevel@tonic-gate (void) printf(gettext( 1542*0Sstevel@tonic-gate " -t nec format NEC-DOS media (with -M only)\n")); 1543*0Sstevel@tonic-gate (void) printf(gettext( 1544*0Sstevel@tonic-gate /*CSTYLED*/ 1545*0Sstevel@tonic-gate " -U unmount media if it's mounted\n")); 1546*0Sstevel@tonic-gate (void) printf(gettext( 1547*0Sstevel@tonic-gate " -v verify each block of the media\n")); 1548*0Sstevel@tonic-gate (void) printf(gettext( 1549*0Sstevel@tonic-gate " -x skip the format, only install SunOS or DOS label\n")); 1550*0Sstevel@tonic-gate 1551*0Sstevel@tonic-gate (void) printf(gettext( 1552*0Sstevel@tonic-gate " devname defaults to '%s'\n"), 1553*0Sstevel@tonic-gate real_name ? real_name : gettext("no available default device")); 1554*0Sstevel@tonic-gate 1555*0Sstevel@tonic-gate exit(1); 1556*0Sstevel@tonic-gate 1557*0Sstevel@tonic-gate } 1558*0Sstevel@tonic-gate 1559*0Sstevel@tonic-gate 1560*0Sstevel@tonic-gate static int 1561*0Sstevel@tonic-gate verify(int fd, int blk, int len) 1562*0Sstevel@tonic-gate { 1563*0Sstevel@tonic-gate off_t off; 1564*0Sstevel@tonic-gate char *nullstring = ""; 1565*0Sstevel@tonic-gate 1566*0Sstevel@tonic-gate off = (off_t)(blk * (m_flag ? 1024 : 512)); 1567*0Sstevel@tonic-gate 1568*0Sstevel@tonic-gate if (lseek(fd, off, 0) != off) { 1569*0Sstevel@tonic-gate if (!q_flag) 1570*0Sstevel@tonic-gate (void) printf(gettext("e\n")); 1571*0Sstevel@tonic-gate (void) fprintf(stderr, 1572*0Sstevel@tonic-gate gettext("%s: can't seek to write verify, "), myname); 1573*0Sstevel@tonic-gate perror(nullstring); 1574*0Sstevel@tonic-gate return (4); 1575*0Sstevel@tonic-gate } 1576*0Sstevel@tonic-gate if (write(fd, ibuf1, len) != len) { 1577*0Sstevel@tonic-gate if (!q_flag) 1578*0Sstevel@tonic-gate (void) printf(gettext("e\n")); 1579*0Sstevel@tonic-gate if (blk == 0) 1580*0Sstevel@tonic-gate (void) fprintf(stderr, 1581*0Sstevel@tonic-gate gettext("%s: check diskette density, "), 1582*0Sstevel@tonic-gate myname); 1583*0Sstevel@tonic-gate else 1584*0Sstevel@tonic-gate (void) fprintf(stderr, 1585*0Sstevel@tonic-gate gettext("%s: can't write verify data, "), 1586*0Sstevel@tonic-gate myname); 1587*0Sstevel@tonic-gate perror(nullstring); 1588*0Sstevel@tonic-gate return (4); 1589*0Sstevel@tonic-gate } 1590*0Sstevel@tonic-gate 1591*0Sstevel@tonic-gate if (lseek(fd, off, 0) != off) { 1592*0Sstevel@tonic-gate if (!q_flag) 1593*0Sstevel@tonic-gate (void) printf(gettext("e\n")); 1594*0Sstevel@tonic-gate (void) fprintf(stderr, 1595*0Sstevel@tonic-gate gettext("%s: bad seek to read verify, "), 1596*0Sstevel@tonic-gate myname); 1597*0Sstevel@tonic-gate perror(nullstring); 1598*0Sstevel@tonic-gate return (4); 1599*0Sstevel@tonic-gate } 1600*0Sstevel@tonic-gate if (read(fd, obuf, len) != len) { 1601*0Sstevel@tonic-gate if (!q_flag) 1602*0Sstevel@tonic-gate (void) printf(gettext("e\n")); 1603*0Sstevel@tonic-gate (void) fprintf(stderr, 1604*0Sstevel@tonic-gate gettext("%s: can't read verify data, "), myname); 1605*0Sstevel@tonic-gate perror(nullstring); 1606*0Sstevel@tonic-gate return (4); 1607*0Sstevel@tonic-gate } 1608*0Sstevel@tonic-gate if (memcmp(ibuf1, obuf, len)) { 1609*0Sstevel@tonic-gate if (!q_flag) 1610*0Sstevel@tonic-gate (void) printf(gettext("e\n")); 1611*0Sstevel@tonic-gate (void) fprintf(stderr, gettext("%s: verify data failure\n"), 1612*0Sstevel@tonic-gate myname); 1613*0Sstevel@tonic-gate return (4); 1614*0Sstevel@tonic-gate } 1615*0Sstevel@tonic-gate return (0); 1616*0Sstevel@tonic-gate } 1617*0Sstevel@tonic-gate 1618*0Sstevel@tonic-gate /* 1619*0Sstevel@tonic-gate * write a SunOS label 1620*0Sstevel@tonic-gate * NOTE: this function assumes fd_vtoc has been filled in with the 1621*0Sstevel@tonic-gate * device specific information such as partition information 1622*0Sstevel@tonic-gate * and the asciilabel 1623*0Sstevel@tonic-gate */ 1624*0Sstevel@tonic-gate static void 1625*0Sstevel@tonic-gate write_SunOS_label(int fd, char *volname, struct vtoc *fd_vtoc) 1626*0Sstevel@tonic-gate { 1627*0Sstevel@tonic-gate char *nullstring = ""; 1628*0Sstevel@tonic-gate 1629*0Sstevel@tonic-gate fd_vtoc->v_sanity = VTOC_SANE; 1630*0Sstevel@tonic-gate 1631*0Sstevel@tonic-gate /* 1632*0Sstevel@tonic-gate * The label structure is set up for DEV_BSIZE (512 byte) blocks, 1633*0Sstevel@tonic-gate * even though a medium density diskette has 1024 byte blocks 1634*0Sstevel@tonic-gate * See dklabel.h for more details. 1635*0Sstevel@tonic-gate */ 1636*0Sstevel@tonic-gate fd_vtoc->v_sectorsz = DEV_BSIZE; 1637*0Sstevel@tonic-gate 1638*0Sstevel@tonic-gate (void) strncpy(fd_vtoc->v_volume, volname, sizeof (fd_vtoc->v_volume)); 1639*0Sstevel@tonic-gate 1640*0Sstevel@tonic-gate /* let the fd driver finish constructing the label and writing it */ 1641*0Sstevel@tonic-gate if (ioctl(fd, DKIOCSVTOC, fd_vtoc) == -1) { 1642*0Sstevel@tonic-gate (void) fprintf(stderr, 1643*0Sstevel@tonic-gate gettext("%s: write of SunOS label failed, "), myname); 1644*0Sstevel@tonic-gate perror(nullstring); 1645*0Sstevel@tonic-gate exit(3); 1646*0Sstevel@tonic-gate } 1647*0Sstevel@tonic-gate 1648*0Sstevel@tonic-gate } 1649*0Sstevel@tonic-gate 1650*0Sstevel@tonic-gate 1651*0Sstevel@tonic-gate /* 1652*0Sstevel@tonic-gate * MS-DOS Disk layout: 1653*0Sstevel@tonic-gate * 1654*0Sstevel@tonic-gate * --------------------- 1655*0Sstevel@tonic-gate * | Boot sector | 1656*0Sstevel@tonic-gate * |-------------------| 1657*0Sstevel@tonic-gate * | Reserved area | 1658*0Sstevel@tonic-gate * |-------------------| 1659*0Sstevel@tonic-gate * | FAT #1 | 1660*0Sstevel@tonic-gate * |-------------------| 1661*0Sstevel@tonic-gate * | FAT #2 | 1662*0Sstevel@tonic-gate * |-------------------| 1663*0Sstevel@tonic-gate * | Root directory | 1664*0Sstevel@tonic-gate * |-------------------| 1665*0Sstevel@tonic-gate * | | 1666*0Sstevel@tonic-gate * | File area | 1667*0Sstevel@tonic-gate * |___________________| 1668*0Sstevel@tonic-gate */ 1669*0Sstevel@tonic-gate 1670*0Sstevel@tonic-gate /* 1671*0Sstevel@tonic-gate * The following is a copy of MS-DOS 3.3 boot block. 1672*0Sstevel@tonic-gate * It consists of the BIOS parameter block, and a disk 1673*0Sstevel@tonic-gate * bootstrap program. 1674*0Sstevel@tonic-gate * 1675*0Sstevel@tonic-gate * The BIOS parameter block contains the right values 1676*0Sstevel@tonic-gate * for the 3.5" high-density 1.44MB floppy format. 1677*0Sstevel@tonic-gate * 1678*0Sstevel@tonic-gate */ 1679*0Sstevel@tonic-gate static uchar_t bootsec[512] = { 1680*0Sstevel@tonic-gate 0xeb, 0x34, 0x90, /* 8086 short jump + displacement + NOP */ 1681*0Sstevel@tonic-gate 'M', 'S', 'D', 'O', 'S', '3', '.', '3', /* OEM name & version */ 1682*0Sstevel@tonic-gate 0, 2, 1, 1, 0, /* Start of BIOS parameter block */ 1683*0Sstevel@tonic-gate 2, 224, 0, 0x40, 0xb, 0xf0, 9, 0, 1684*0Sstevel@tonic-gate 18, 0, 2, 0, 0, 0, /* End of BIOS parameter block */ 1685*0Sstevel@tonic-gate 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 1686*0Sstevel@tonic-gate 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 1687*0Sstevel@tonic-gate 0x0, 0x0, 0x0, 0x0, 1688*0Sstevel@tonic-gate 0x1, 0x0, 0xfa, 0x33, /* 0x34, start of the bootstrap. */ 1689*0Sstevel@tonic-gate 0xc0, 0x8e, 0xd0, 0xbc, 0x0, 0x7c, 0x16, 0x7, 1690*0Sstevel@tonic-gate 0xbb, 0x78, 0x0, 0x36, 0xc5, 0x37, 0x1e, 0x56, 1691*0Sstevel@tonic-gate 0x16, 0x53, 0xbf, 0x2b, 0x7c, 0xb9, 0xb, 0x0, 1692*0Sstevel@tonic-gate 0xfc, 0xac, 0x26, 0x80, 0x3d, 0x0, 0x74, 0x3, 1693*0Sstevel@tonic-gate 0x26, 0x8a, 0x5, 0xaa, 0x8a, 0xc4, 0xe2, 0xf1, 1694*0Sstevel@tonic-gate 0x6, 0x1f, 0x89, 0x47, 0x2, 0xc7, 0x7, 0x2b, 1695*0Sstevel@tonic-gate 0x7c, 0xfb, 0xcd, 0x13, 0x72, 0x67, 0xa0, 0x10, 1696*0Sstevel@tonic-gate 0x7c, 0x98, 0xf7, 0x26, 0x16, 0x7c, 0x3, 0x6, 1697*0Sstevel@tonic-gate 0x1c, 0x7c, 0x3, 0x6, 0xe, 0x7c, 0xa3, 0x3f, 1698*0Sstevel@tonic-gate 0x7c, 0xa3, 0x37, 0x7c, 0xb8, 0x20, 0x0, 0xf7, 1699*0Sstevel@tonic-gate 0x26, 0x11, 0x7c, 0x8b, 0x1e, 0xb, 0x7c, 0x3, 1700*0Sstevel@tonic-gate 0xc3, 0x48, 0xf7, 0xf3, 0x1, 0x6, 0x37, 0x7c, 1701*0Sstevel@tonic-gate 0xbb, 0x0, 0x5, 0xa1, 0x3f, 0x7c, 0xe8, 0x9f, 1702*0Sstevel@tonic-gate 0x0, 0xb8, 0x1, 0x2, 0xe8, 0xb3, 0x0, 0x72, 1703*0Sstevel@tonic-gate 0x19, 0x8b, 0xfb, 0xb9, 0xb, 0x0, 0xbe, 0xd6, 1704*0Sstevel@tonic-gate 0x7d, 0xf3, 0xa6, 0x75, 0xd, 0x8d, 0x7f, 0x20, 1705*0Sstevel@tonic-gate 0xbe, 0xe1, 0x7d, 0xb9, 0xb, 0x0, 0xf3, 0xa6, 1706*0Sstevel@tonic-gate 0x74, 0x18, 0xbe, 0x77, 0x7d, 0xe8, 0x6a, 0x0, 1707*0Sstevel@tonic-gate 0x32, 0xe4, 0xcd, 0x16, 0x5e, 0x1f, 0x8f, 0x4, 1708*0Sstevel@tonic-gate 0x8f, 0x44, 0x2, 0xcd, 0x19, 0xbe, 0xc0, 0x7d, 1709*0Sstevel@tonic-gate 0xeb, 0xeb, 0xa1, 0x1c, 0x5, 0x33, 0xd2, 0xf7, 1710*0Sstevel@tonic-gate 0x36, 0xb, 0x7c, 0xfe, 0xc0, 0xa2, 0x3c, 0x7c, 1711*0Sstevel@tonic-gate 0xa1, 0x37, 0x7c, 0xa3, 0x3d, 0x7c, 0xbb, 0x0, 1712*0Sstevel@tonic-gate 0x7, 0xa1, 0x37, 0x7c, 0xe8, 0x49, 0x0, 0xa1, 1713*0Sstevel@tonic-gate 0x18, 0x7c, 0x2a, 0x6, 0x3b, 0x7c, 0x40, 0x38, 1714*0Sstevel@tonic-gate 0x6, 0x3c, 0x7c, 0x73, 0x3, 0xa0, 0x3c, 0x7c, 1715*0Sstevel@tonic-gate 0x50, 0xe8, 0x4e, 0x0, 0x58, 0x72, 0xc6, 0x28, 1716*0Sstevel@tonic-gate 0x6, 0x3c, 0x7c, 0x74, 0xc, 0x1, 0x6, 0x37, 1717*0Sstevel@tonic-gate 0x7c, 0xf7, 0x26, 0xb, 0x7c, 0x3, 0xd8, 0xeb, 1718*0Sstevel@tonic-gate 0xd0, 0x8a, 0x2e, 0x15, 0x7c, 0x8a, 0x16, 0xfd, 1719*0Sstevel@tonic-gate 0x7d, 0x8b, 0x1e, 0x3d, 0x7c, 0xea, 0x0, 0x0, 1720*0Sstevel@tonic-gate 0x70, 0x0, 0xac, 0xa, 0xc0, 0x74, 0x22, 0xb4, 1721*0Sstevel@tonic-gate 0xe, 0xbb, 0x7, 0x0, 0xcd, 0x10, 0xeb, 0xf2, 1722*0Sstevel@tonic-gate 0x33, 0xd2, 0xf7, 0x36, 0x18, 0x7c, 0xfe, 0xc2, 1723*0Sstevel@tonic-gate 0x88, 0x16, 0x3b, 0x7c, 0x33, 0xd2, 0xf7, 0x36, 1724*0Sstevel@tonic-gate 0x1a, 0x7c, 0x88, 0x16, 0x2a, 0x7c, 0xa3, 0x39, 1725*0Sstevel@tonic-gate 0x7c, 0xc3, 0xb4, 0x2, 0x8b, 0x16, 0x39, 0x7c, 1726*0Sstevel@tonic-gate 0xb1, 0x6, 0xd2, 0xe6, 0xa, 0x36, 0x3b, 0x7c, 1727*0Sstevel@tonic-gate 0x8b, 0xca, 0x86, 0xe9, 0x8a, 0x16, 0xfd, 0x7d, 1728*0Sstevel@tonic-gate 0x8a, 0x36, 0x2a, 0x7c, 0xcd, 0x13, 0xc3, '\r', 1729*0Sstevel@tonic-gate '\n', 'N', 'o', 'n', '-', 'S', 'y', 's', 1730*0Sstevel@tonic-gate 't', 'e', 'm', ' ', 'd', 'i', 's', 'k', 1731*0Sstevel@tonic-gate ' ', 'o', 'r', ' ', 'd', 'i', 's', 'k', 1732*0Sstevel@tonic-gate ' ', 'e', 'r', 'r', 'o', 'r', '\r', '\n', 1733*0Sstevel@tonic-gate 'R', 'e', 'p', 'l', 'a', 'c', 'e', ' ', 1734*0Sstevel@tonic-gate 'a', 'n', 'd', ' ', 's', 't', 'r', 'i', 1735*0Sstevel@tonic-gate 'k', 'e', ' ', 'a', 'n', 'y', ' ', 'k', 1736*0Sstevel@tonic-gate 'e', 'y', ' ', 'w', 'h', 'e', 'n', ' ', 1737*0Sstevel@tonic-gate 'r', 'e', 'a', 'd', 'y', '\r', '\n', '\0', 1738*0Sstevel@tonic-gate '\r', '\n', 'D', 'i', 's', 'k', ' ', 'B', 1739*0Sstevel@tonic-gate 'o', 'o', 't', ' ', 'f', 'a', 'i', 'l', 1740*0Sstevel@tonic-gate 'u', 'r', 'e', '\r', '\n', '\0', 'I', 'O', 1741*0Sstevel@tonic-gate ' ', ' ', ' ', ' ', ' ', ' ', 'S', 'Y', 1742*0Sstevel@tonic-gate 'S', 'M', 'S', 'D', 'O', 'S', ' ', ' ', 1743*0Sstevel@tonic-gate ' ', 'S', 'Y', 'S', '\0', 0, 0, 0, 1744*0Sstevel@tonic-gate 0, 0, 0, 0, 0, 0, 0, 0, 0, 1745*0Sstevel@tonic-gate 0, 0, 0, 0, 0, 0x55, 0xaa 1746*0Sstevel@tonic-gate }; 1747*0Sstevel@tonic-gate 1748*0Sstevel@tonic-gate static int 1749*0Sstevel@tonic-gate valid_DOS_boot(char *bootfile, uchar_t **bootloadp) 1750*0Sstevel@tonic-gate { 1751*0Sstevel@tonic-gate struct stat status; 1752*0Sstevel@tonic-gate size_t sizebootldr; 1753*0Sstevel@tonic-gate uchar_t *bootloader; 1754*0Sstevel@tonic-gate int bfd; 1755*0Sstevel@tonic-gate int boot_size = 0; 1756*0Sstevel@tonic-gate int err; 1757*0Sstevel@tonic-gate char *nullstring = ""; 1758*0Sstevel@tonic-gate 1759*0Sstevel@tonic-gate if (err = stat(bootfile, &status)) { 1760*0Sstevel@tonic-gate (void) fprintf(stderr, gettext("%s: \"%s\" stat error %d\n"), 1761*0Sstevel@tonic-gate myname, bootfile, err); 1762*0Sstevel@tonic-gate return (0); 1763*0Sstevel@tonic-gate } 1764*0Sstevel@tonic-gate if ((boot_size = status.st_size) < 512) { 1765*0Sstevel@tonic-gate (void) fprintf(stderr, 1766*0Sstevel@tonic-gate gettext("%s: short boot sector"), myname); 1767*0Sstevel@tonic-gate perror(nullstring); 1768*0Sstevel@tonic-gate return (0); 1769*0Sstevel@tonic-gate } 1770*0Sstevel@tonic-gate sizebootldr = (boot_size + 511) / 512 * 512; 1771*0Sstevel@tonic-gate if ((bootloader = (uchar_t *)malloc((size_t)sizebootldr)) == NULL) { 1772*0Sstevel@tonic-gate (void) fprintf(stderr, gettext("%s: malloc error\n"), 1773*0Sstevel@tonic-gate myname); 1774*0Sstevel@tonic-gate return (0); 1775*0Sstevel@tonic-gate } 1776*0Sstevel@tonic-gate 1777*0Sstevel@tonic-gate /* switch to user to access the boot file */ 1778*0Sstevel@tonic-gate (void) seteuid(getuid()); 1779*0Sstevel@tonic-gate 1780*0Sstevel@tonic-gate if ((bfd = open(bootfile, O_RDONLY)) == -1) { 1781*0Sstevel@tonic-gate (void) fprintf(stderr, gettext("%s: could not open \"%s\": "), 1782*0Sstevel@tonic-gate myname, bootfile); 1783*0Sstevel@tonic-gate perror(nullstring); 1784*0Sstevel@tonic-gate return (0); 1785*0Sstevel@tonic-gate } 1786*0Sstevel@tonic-gate 1787*0Sstevel@tonic-gate /* restore effective id */ 1788*0Sstevel@tonic-gate (void) seteuid(euid); 1789*0Sstevel@tonic-gate 1790*0Sstevel@tonic-gate if (read(bfd, bootloader, boot_size) != boot_size) { 1791*0Sstevel@tonic-gate (void) fprintf(stderr, 1792*0Sstevel@tonic-gate gettext("%s: read of MS-DOS boot file failed, "), myname); 1793*0Sstevel@tonic-gate perror(nullstring); 1794*0Sstevel@tonic-gate (void) close(bfd); 1795*0Sstevel@tonic-gate return (0); 1796*0Sstevel@tonic-gate } 1797*0Sstevel@tonic-gate 1798*0Sstevel@tonic-gate if (!((*bootloader == 0xE9 || 1799*0Sstevel@tonic-gate (*bootloader == 0xEB && *(bootloader + 2) == 0x90)) && 1800*0Sstevel@tonic-gate *(bootloader + 510) == 0x55 && 1801*0Sstevel@tonic-gate *(bootloader + 511) == 0xAA)) { 1802*0Sstevel@tonic-gate (void) fprintf(stderr, 1803*0Sstevel@tonic-gate gettext("%s: invalid MS-DOS boot loader image\n"), myname); 1804*0Sstevel@tonic-gate boot_size = 0; 1805*0Sstevel@tonic-gate } 1806*0Sstevel@tonic-gate 1807*0Sstevel@tonic-gate (void) close(bfd); 1808*0Sstevel@tonic-gate *bootloadp = bootloader; 1809*0Sstevel@tonic-gate return (boot_size); 1810*0Sstevel@tonic-gate } 1811*0Sstevel@tonic-gate 1812*0Sstevel@tonic-gate 1813*0Sstevel@tonic-gate static void 1814*0Sstevel@tonic-gate write_DOS_label(int fd, uchar_t *bootloadr, int bootlen, char *altbootname, 1815*0Sstevel@tonic-gate char *doslabel, struct bios_param_blk *bpb, int rdirsec) 1816*0Sstevel@tonic-gate { 1817*0Sstevel@tonic-gate int i, j; 1818*0Sstevel@tonic-gate int bootclen; 1819*0Sstevel@tonic-gate size_t fat_bsize; 1820*0Sstevel@tonic-gate ushort_t totalsec; 1821*0Sstevel@tonic-gate uchar_t *fat_rdir; 1822*0Sstevel@tonic-gate uchar_t *fatptr; 1823*0Sstevel@tonic-gate char *nullstring = ""; 1824*0Sstevel@tonic-gate 1825*0Sstevel@tonic-gate if (bootlen < 512 || !bootloadr) { 1826*0Sstevel@tonic-gate /* use default boot loader routine */ 1827*0Sstevel@tonic-gate bootloadr = bootsec; 1828*0Sstevel@tonic-gate bootlen = 512; 1829*0Sstevel@tonic-gate } else 1830*0Sstevel@tonic-gate (void) printf 1831*0Sstevel@tonic-gate (gettext("%s: using \"%s\" for MS-DOS boot loader\n"), 1832*0Sstevel@tonic-gate myname, altbootname); 1833*0Sstevel@tonic-gate if (bootlen % 512 > 0) 1834*0Sstevel@tonic-gate bootlen = (bootlen + 511) / 512 * 512; 1835*0Sstevel@tonic-gate 1836*0Sstevel@tonic-gate bpb->b_bps[0] = getlobyte(512); 1837*0Sstevel@tonic-gate bpb->b_bps[1] = gethibyte(512); 1838*0Sstevel@tonic-gate /* MS-DOS 5.0 supports only 1 reserved sector :-( */ 1839*0Sstevel@tonic-gate bpb->b_res_sec[0] = 1; 1840*0Sstevel@tonic-gate bpb->b_res_sec[1] = 0; 1841*0Sstevel@tonic-gate 1842*0Sstevel@tonic-gate totalsec = fdchar.fdc_ncyl * fdchar.fdc_nhead * fdchar.fdc_secptrack; 1843*0Sstevel@tonic-gate bpb->b_totalsec[0] = getlobyte(totalsec); 1844*0Sstevel@tonic-gate bpb->b_totalsec[1] = gethibyte(totalsec); 1845*0Sstevel@tonic-gate bpb->b_spt[0] = fdchar.fdc_secptrack; 1846*0Sstevel@tonic-gate bpb->b_spt[1] = 0; 1847*0Sstevel@tonic-gate bpb->b_nhead[0] = fdchar.fdc_nhead; 1848*0Sstevel@tonic-gate bpb->b_nhead[1] = 0; 1849*0Sstevel@tonic-gate bpb->b_hiddensec[0] = 0; 1850*0Sstevel@tonic-gate bpb->b_hiddensec[1] = 0; 1851*0Sstevel@tonic-gate 1852*0Sstevel@tonic-gate bpb->b_rdirents[0] = getlobyte(rdirsec); 1853*0Sstevel@tonic-gate bpb->b_rdirents[1] = gethibyte(rdirsec); 1854*0Sstevel@tonic-gate 1855*0Sstevel@tonic-gate (void) memcpy((char *)(bootloadr + 0x0B), (char *)bpb, 1856*0Sstevel@tonic-gate sizeof (struct bios_param_blk)); 1857*0Sstevel@tonic-gate 1858*0Sstevel@tonic-gate if (write(fd, bootloadr, 512) != 512) { 1859*0Sstevel@tonic-gate (void) fprintf(stderr, 1860*0Sstevel@tonic-gate gettext("%s: write of MS-DOS boot sector failed"), myname); 1861*0Sstevel@tonic-gate perror(nullstring); 1862*0Sstevel@tonic-gate exit(3); 1863*0Sstevel@tonic-gate } 1864*0Sstevel@tonic-gate bootloadr += 512; 1865*0Sstevel@tonic-gate bootlen -= 512; 1866*0Sstevel@tonic-gate 1867*0Sstevel@tonic-gate fat_bsize = 512 * bpb->b_fatsec[0]; 1868*0Sstevel@tonic-gate fat_rdir = (uchar_t *)malloc(fat_bsize); 1869*0Sstevel@tonic-gate (void) memset(fat_rdir, (char)0, fat_bsize); 1870*0Sstevel@tonic-gate 1871*0Sstevel@tonic-gate *fat_rdir = bpb->b_mediadescriptor; 1872*0Sstevel@tonic-gate *(fat_rdir + 1) = 0xFF; 1873*0Sstevel@tonic-gate *(fat_rdir + 2) = 0xFF; 1874*0Sstevel@tonic-gate bootclen = (bootlen + 512 * (int)bpb->b_spcl - 1) / 1875*0Sstevel@tonic-gate (512 * (int)bpb->b_spcl); 1876*0Sstevel@tonic-gate #define BAD_CLUSTER 0xFF7 1877*0Sstevel@tonic-gate for (i = 0, fatptr = fat_rdir+3; i < bootclen; i++) 1878*0Sstevel@tonic-gate /* 1879*0Sstevel@tonic-gate * pre-allocate any clusters used by boot loader if 1880*0Sstevel@tonic-gate * loader will occupy more than 1 sector 1881*0Sstevel@tonic-gate */ 1882*0Sstevel@tonic-gate if (!(i & 01)) { 1883*0Sstevel@tonic-gate *fatptr++ = BAD_CLUSTER & 0xFF; 1884*0Sstevel@tonic-gate *fatptr = (BAD_CLUSTER >> 8) & 0x0F; 1885*0Sstevel@tonic-gate } else { 1886*0Sstevel@tonic-gate *fatptr = (*fatptr & 0x0F) | 1887*0Sstevel@tonic-gate ((BAD_CLUSTER << 4) & 0xF0); 1888*0Sstevel@tonic-gate fatptr++; 1889*0Sstevel@tonic-gate *fatptr++ = (BAD_CLUSTER >> 4) & 0xFF; 1890*0Sstevel@tonic-gate } 1891*0Sstevel@tonic-gate for (i = 0; i < (int)bpb->b_nfat; ++i) 1892*0Sstevel@tonic-gate if (write(fd, fat_rdir, fat_bsize) != fat_bsize) { 1893*0Sstevel@tonic-gate (void) fprintf(stderr, 1894*0Sstevel@tonic-gate gettext("%s: write of MS-DOS File Allocation Table failed, "), 1895*0Sstevel@tonic-gate myname); 1896*0Sstevel@tonic-gate perror(nullstring); 1897*0Sstevel@tonic-gate exit(3); 1898*0Sstevel@tonic-gate } 1899*0Sstevel@tonic-gate rdirsec = bpb->b_rdirents[0]; 1900*0Sstevel@tonic-gate rdirsec = 32 * (int)rdirsec / 512; 1901*0Sstevel@tonic-gate if (b_flag) { 1902*0Sstevel@tonic-gate struct timeval tv; 1903*0Sstevel@tonic-gate struct tm *tp; 1904*0Sstevel@tonic-gate ushort_t dostime; 1905*0Sstevel@tonic-gate ushort_t dosday; 1906*0Sstevel@tonic-gate 1907*0Sstevel@tonic-gate /* the label can be no more than 11 characters */ 1908*0Sstevel@tonic-gate j = min(11, (int)strlen(doslabel)); 1909*0Sstevel@tonic-gate for (i = 0; i < j; i++) { 1910*0Sstevel@tonic-gate fat_rdir[i] = uppercase(doslabel[i]); 1911*0Sstevel@tonic-gate } 1912*0Sstevel@tonic-gate for (; i < 11; i++) { 1913*0Sstevel@tonic-gate fat_rdir[i] = ' '; 1914*0Sstevel@tonic-gate } 1915*0Sstevel@tonic-gate fat_rdir[0x0B] = 0x28; 1916*0Sstevel@tonic-gate (void) gettimeofday(&tv, (struct timezone *)0); 1917*0Sstevel@tonic-gate tp = localtime(&tv.tv_sec); 1918*0Sstevel@tonic-gate /* get the time & day into DOS format */ 1919*0Sstevel@tonic-gate dostime = tp->tm_sec / 2; 1920*0Sstevel@tonic-gate dostime |= tp->tm_min << 5; 1921*0Sstevel@tonic-gate dostime |= tp->tm_hour << 11; 1922*0Sstevel@tonic-gate dosday = tp->tm_mday; 1923*0Sstevel@tonic-gate dosday |= (tp->tm_mon + 1) << 5; 1924*0Sstevel@tonic-gate dosday |= (tp->tm_year - 80) << 9; 1925*0Sstevel@tonic-gate fat_rdir[0x16] = getlobyte(dostime); 1926*0Sstevel@tonic-gate fat_rdir[0x17] = gethibyte(dostime); 1927*0Sstevel@tonic-gate fat_rdir[0x18] = getlobyte(dosday); 1928*0Sstevel@tonic-gate fat_rdir[0x19] = gethibyte(dosday); 1929*0Sstevel@tonic-gate 1930*0Sstevel@tonic-gate if (write(fd, fat_rdir, 512) != 512) { 1931*0Sstevel@tonic-gate (void) fprintf(stderr, 1932*0Sstevel@tonic-gate gettext("%s: write of MS-DOS FAT failed, "), 1933*0Sstevel@tonic-gate myname); 1934*0Sstevel@tonic-gate perror(nullstring); 1935*0Sstevel@tonic-gate exit(3); 1936*0Sstevel@tonic-gate } 1937*0Sstevel@tonic-gate i = 1; 1938*0Sstevel@tonic-gate } else { 1939*0Sstevel@tonic-gate i = 0; 1940*0Sstevel@tonic-gate } 1941*0Sstevel@tonic-gate (void) memset(fat_rdir, (char)0, 512); 1942*0Sstevel@tonic-gate for (; i < (int)rdirsec; ++i) { 1943*0Sstevel@tonic-gate if (write(fd, fat_rdir, 512) != 512) { 1944*0Sstevel@tonic-gate (void) fprintf(stderr, 1945*0Sstevel@tonic-gate gettext("%s: write of MS-DOS root directory failed, "), 1946*0Sstevel@tonic-gate myname); 1947*0Sstevel@tonic-gate perror(nullstring); 1948*0Sstevel@tonic-gate exit(3); 1949*0Sstevel@tonic-gate } 1950*0Sstevel@tonic-gate } 1951*0Sstevel@tonic-gate /* 1952*0Sstevel@tonic-gate * Write the rest of the boot loader if it's longer than one sector. 1953*0Sstevel@tonic-gate * The clusters used are marked Bad in the FAT. 1954*0Sstevel@tonic-gate * No directory entry exists for this file (so that it cannot be 1955*0Sstevel@tonic-gate * deleted). 1956*0Sstevel@tonic-gate */ 1957*0Sstevel@tonic-gate if (bootlen && write(fd, bootloadr, bootlen) != bootlen) { 1958*0Sstevel@tonic-gate (void) fprintf(stderr, 1959*0Sstevel@tonic-gate gettext("%s: write of MS-DOS boot sectors failed"), myname); 1960*0Sstevel@tonic-gate perror(nullstring); 1961*0Sstevel@tonic-gate exit(3); 1962*0Sstevel@tonic-gate } 1963*0Sstevel@tonic-gate } 1964*0Sstevel@tonic-gate 1965*0Sstevel@tonic-gate static void 1966*0Sstevel@tonic-gate write_NEC_DOS_label(int fd, char *doslabel) 1967*0Sstevel@tonic-gate { 1968*0Sstevel@tonic-gate struct bios_param_blk *bpb; 1969*0Sstevel@tonic-gate ushort_t fatsec; 1970*0Sstevel@tonic-gate ushort_t rdirsec; 1971*0Sstevel@tonic-gate char fat_rdir[1024]; 1972*0Sstevel@tonic-gate int i, j, m = 1; 1973*0Sstevel@tonic-gate uchar_t bootsec_NEC[1024]; 1974*0Sstevel@tonic-gate char *nullstring = ""; 1975*0Sstevel@tonic-gate 1976*0Sstevel@tonic-gate uchar_t bios_param_NEC[30] = { 0xeb, 0x1c, 0x90, 0x0, 0x0, 0x0, 0x0, 1977*0Sstevel@tonic-gate 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x1, 0x1, 0x0, 1978*0Sstevel@tonic-gate 0x2, 0xc0, 0x0, 0xd0, 0x4, 0xfe, 0x2, 0x0, 1979*0Sstevel@tonic-gate 0x8, 0x0, 0x2, 0x0, 0x0, 0x0 1980*0Sstevel@tonic-gate }; 1981*0Sstevel@tonic-gate 1982*0Sstevel@tonic-gate uchar_t fatdir[32] = { 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 1983*0Sstevel@tonic-gate 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 1984*0Sstevel@tonic-gate 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 1985*0Sstevel@tonic-gate 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5 1986*0Sstevel@tonic-gate 1987*0Sstevel@tonic-gate }; 1988*0Sstevel@tonic-gate 1989*0Sstevel@tonic-gate 1990*0Sstevel@tonic-gate (void) memset(bootsec_NEC, (char)0, 1024); 1991*0Sstevel@tonic-gate 1992*0Sstevel@tonic-gate (void) memcpy(&bootsec_NEC, &bios_param_NEC, 30); 1993*0Sstevel@tonic-gate 1994*0Sstevel@tonic-gate bpb = (struct bios_param_blk *)&(bootsec_NEC[0xb]); 1995*0Sstevel@tonic-gate if (write(fd, &bootsec_NEC[0], 1024) != 1024) { 1996*0Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1997*0Sstevel@tonic-gate "%s: write of NEC-DOS boot sector failed, "), 1998*0Sstevel@tonic-gate myname); 1999*0Sstevel@tonic-gate perror(nullstring); 2000*0Sstevel@tonic-gate exit(3); 2001*0Sstevel@tonic-gate } 2002*0Sstevel@tonic-gate (void) memset(fat_rdir, (char)0, 1024); 2003*0Sstevel@tonic-gate fatsec = bpb->b_fatsec[0]; 2004*0Sstevel@tonic-gate for (i = 0; i < (int)bpb->b_nfat * (int)fatsec; ++i) { 2005*0Sstevel@tonic-gate if ((i % (int)fatsec) == 0) { 2006*0Sstevel@tonic-gate fat_rdir[0] = bpb->b_mediadescriptor; 2007*0Sstevel@tonic-gate fat_rdir[1] = (char)0xff; 2008*0Sstevel@tonic-gate fat_rdir[2] = (char)0xff; 2009*0Sstevel@tonic-gate fat_rdir[3] = 0; 2010*0Sstevel@tonic-gate fat_rdir[4] = 0; 2011*0Sstevel@tonic-gate fat_rdir[5] = 0; 2012*0Sstevel@tonic-gate } else { 2013*0Sstevel@tonic-gate fat_rdir[0] = 0; 2014*0Sstevel@tonic-gate fat_rdir[1] = 0; 2015*0Sstevel@tonic-gate fat_rdir[2] = 0; 2016*0Sstevel@tonic-gate fat_rdir[3] = 0; 2017*0Sstevel@tonic-gate fat_rdir[4] = 0; 2018*0Sstevel@tonic-gate fat_rdir[5] = 0; 2019*0Sstevel@tonic-gate } 2020*0Sstevel@tonic-gate if (write(fd, &fat_rdir[0], 1024) != 1024) { 2021*0Sstevel@tonic-gate (void) fprintf(stderr, 2022*0Sstevel@tonic-gate /*CSTYLED*/ 2023*0Sstevel@tonic-gate gettext("%s: write of NEC-DOS File Allocation Table failed, "), myname); 2024*0Sstevel@tonic-gate perror(nullstring); 2025*0Sstevel@tonic-gate exit(3); 2026*0Sstevel@tonic-gate } 2027*0Sstevel@tonic-gate } 2028*0Sstevel@tonic-gate #ifndef sparc 2029*0Sstevel@tonic-gate /* LINTED */ 2030*0Sstevel@tonic-gate rdirsec = (int)htols(bpb->b_rdirents[0]) * 32 /1024; 2031*0Sstevel@tonic-gate #else 2032*0Sstevel@tonic-gate rdirsec = (int)htols(bpb->b_rdirents[0]) * 32 /1024; 2033*0Sstevel@tonic-gate #endif 2034*0Sstevel@tonic-gate if (b_flag) { 2035*0Sstevel@tonic-gate struct timeval tv; 2036*0Sstevel@tonic-gate struct tm *tp; 2037*0Sstevel@tonic-gate ushort_t dostime; 2038*0Sstevel@tonic-gate ushort_t dosday; 2039*0Sstevel@tonic-gate 2040*0Sstevel@tonic-gate /* the label can be no more than 11 characters */ 2041*0Sstevel@tonic-gate j = min(11, (int)strlen(doslabel)); 2042*0Sstevel@tonic-gate for (i = 0; i < j; i++) { 2043*0Sstevel@tonic-gate fat_rdir[i] = uppercase(doslabel[i]); 2044*0Sstevel@tonic-gate } 2045*0Sstevel@tonic-gate for (; i < 11; i++) { 2046*0Sstevel@tonic-gate fat_rdir[i] = ' '; 2047*0Sstevel@tonic-gate } 2048*0Sstevel@tonic-gate fat_rdir[0xb] = 0x28; 2049*0Sstevel@tonic-gate (void) gettimeofday(&tv, (struct timezone *)0); 2050*0Sstevel@tonic-gate tp = localtime(&tv.tv_sec); 2051*0Sstevel@tonic-gate /* get the time & day into DOS format */ 2052*0Sstevel@tonic-gate dostime = tp->tm_sec / 2; 2053*0Sstevel@tonic-gate dostime |= tp->tm_min << 5; 2054*0Sstevel@tonic-gate dostime |= tp->tm_hour << 11; 2055*0Sstevel@tonic-gate dosday = tp->tm_mday; 2056*0Sstevel@tonic-gate dosday |= (tp->tm_mon + 1) << 5; 2057*0Sstevel@tonic-gate dosday |= (tp->tm_year - 80) << 9; 2058*0Sstevel@tonic-gate fat_rdir[0x16] = getlobyte(dostime); 2059*0Sstevel@tonic-gate fat_rdir[0x17] = gethibyte(dostime); 2060*0Sstevel@tonic-gate fat_rdir[0x18] = getlobyte(dosday); 2061*0Sstevel@tonic-gate fat_rdir[0x19] = gethibyte(dosday); 2062*0Sstevel@tonic-gate 2063*0Sstevel@tonic-gate if (write(fd, &fat_rdir[0], 1024) != 1024) { 2064*0Sstevel@tonic-gate (void) fprintf(stderr, 2065*0Sstevel@tonic-gate /*CSTYLED*/ 2066*0Sstevel@tonic-gate gettext("%s: write of NEC-DOS root directory failed, "), myname); 2067*0Sstevel@tonic-gate perror(nullstring); 2068*0Sstevel@tonic-gate exit(3); 2069*0Sstevel@tonic-gate } 2070*0Sstevel@tonic-gate (void) memset(fat_rdir, (char)0, 512); 2071*0Sstevel@tonic-gate i = 1; 2072*0Sstevel@tonic-gate } else { 2073*0Sstevel@tonic-gate i = 0; 2074*0Sstevel@tonic-gate 2075*0Sstevel@tonic-gate while (m < 1024) { 2076*0Sstevel@tonic-gate (void) memcpy(&fat_rdir[m], &fatdir, 31); 2077*0Sstevel@tonic-gate m = m + 32; 2078*0Sstevel@tonic-gate } 2079*0Sstevel@tonic-gate } 2080*0Sstevel@tonic-gate for (; i < (int)rdirsec; ++i) { 2081*0Sstevel@tonic-gate 2082*0Sstevel@tonic-gate if (write(fd, &fat_rdir[0], 1024) != 1024) { 2083*0Sstevel@tonic-gate (void) fprintf(stderr, 2084*0Sstevel@tonic-gate /*CSTYLED*/ 2085*0Sstevel@tonic-gate gettext("%s: write of NEC-DOS root directory failed, "), myname); 2086*0Sstevel@tonic-gate perror(nullstring); 2087*0Sstevel@tonic-gate exit(3); 2088*0Sstevel@tonic-gate } 2089*0Sstevel@tonic-gate } 2090*0Sstevel@tonic-gate } 2091