1330449Seadler/*- 2330449Seadler * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3330449Seadler * 487992Sjoerg * Copyright (C) 1994, 2001 by Joerg Wunsch, Dresden 54007Sjoerg * All rights reserved. 64007Sjoerg * 74007Sjoerg * Redistribution and use in source and binary forms, with or without 84007Sjoerg * modification, are permitted provided that the following conditions 94007Sjoerg * are met: 104007Sjoerg * 1. Redistributions of source code must retain the above copyright 114007Sjoerg * notice, this list of conditions and the following disclaimer. 124007Sjoerg * 2. Redistributions in binary form must reproduce the above copyright 134007Sjoerg * notice, this list of conditions and the following disclaimer in the 144007Sjoerg * documentation and/or other materials provided with the distribution. 154007Sjoerg * 164007Sjoerg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY 174007Sjoerg * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 184007Sjoerg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 194007Sjoerg * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE 204007Sjoerg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 214007Sjoerg * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 224007Sjoerg * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 234007Sjoerg * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 244007Sjoerg * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 254007Sjoerg * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 264007Sjoerg * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 274007Sjoerg * DAMAGE. 284007Sjoerg */ 294007Sjoerg 30114601Sobrien#include <sys/cdefs.h> 31114601Sobrien__FBSDID("$FreeBSD: stable/11/usr.sbin/fdcontrol/fdcontrol.c 330449 2018-03-05 07:26:05Z eadler $"); 3229530Scharnier 3378855Sdd#include <sys/fdcio.h> 3478855Sdd#include <sys/file.h> 3578855Sdd 3629530Scharnier#include <err.h> 374007Sjoerg#include <stdio.h> 384007Sjoerg#include <stdlib.h> 3987992Sjoerg#include <string.h> 4087992Sjoerg#include <sysexits.h> 4123716Speter#include <unistd.h> 424007Sjoerg 4387992Sjoerg#include "fdutil.h" 4478855Sdd 458857Srgrimes 46134081Sphkstatic int format, verbose, show = 1, showfmt; 4787992Sjoergstatic char *fmtstring; 484007Sjoerg 4987992Sjoergstatic void showdev(enum fd_drivetype, const char *); 5087992Sjoergstatic void usage(void); 514007Sjoerg 5278855Sddstatic void 534007Sjoergusage(void) 544007Sjoerg{ 5587992Sjoerg errx(EX_USAGE, 5687992Sjoerg "usage: fdcontrol [-F] [-d dbg] [-f fmt] [-s fmtstr] [-v] device"); 574007Sjoerg} 584007Sjoerg 5987992Sjoergvoid 6087992Sjoergshowdev(enum fd_drivetype type, const char *fname) 6187992Sjoerg{ 6287992Sjoerg const char *name, *descr; 634007Sjoerg 6487992Sjoerg getname(type, &name, &descr); 6587992Sjoerg if (verbose) 6687992Sjoerg printf("%s: %s drive (%s)\n", fname, name, descr); 6787992Sjoerg else 6887992Sjoerg printf("%s\n", name); 6987992Sjoerg} 704007Sjoerg 714007Sjoergint 724007Sjoergmain(int argc, char **argv) 734007Sjoerg{ 7487992Sjoerg enum fd_drivetype type; 7587992Sjoerg struct fd_type ft, newft, *fdtp; 7687992Sjoerg const char *name, *descr; 77194892Sjoerg int fd, i, autofmt; 784007Sjoerg 79134081Sphk autofmt = 0; 80134081Sphk while((i = getopt(argc, argv, "aFf:s:v")) != -1) 8187992Sjoerg switch(i) { 828857Srgrimes 83134081Sphk case 'a': 84134081Sphk autofmt = 1; 8587992Sjoerg case 'F': 8687992Sjoerg showfmt = 1; 8787992Sjoerg show = 0; 8887992Sjoerg break; 898857Srgrimes 9087992Sjoerg case 'f': 91126231Sphk if (!strcmp(optarg, "auto")) { 92126231Sphk format = -1; 93126231Sphk } else if (getnum(optarg, &format)) { 9487992Sjoerg fprintf(stderr, 9587992Sjoerg "Bad argument %s to -f option; must be numeric\n", 9687992Sjoerg optarg); 9787992Sjoerg usage(); 9887992Sjoerg } 9987992Sjoerg show = 0; 10087992Sjoerg break; 1018857Srgrimes 10287992Sjoerg case 's': 10387992Sjoerg fmtstring = optarg; 10487992Sjoerg show = 0; 10587992Sjoerg break; 1064007Sjoerg 10787992Sjoerg case 'v': 10887992Sjoerg verbose++; 10987992Sjoerg break; 1108857Srgrimes 11187992Sjoerg default: 11287992Sjoerg usage(); 11387992Sjoerg } 1144007Sjoerg 11587992Sjoerg argc -= optind; 11687992Sjoerg argv += optind; 11787992Sjoerg 11887992Sjoerg if(argc != 1) 11987992Sjoerg usage(); 12087992Sjoerg 121194892Sjoerg if((fd = open(argv[0], O_RDONLY | O_NONBLOCK)) < 0) 12287992Sjoerg err(EX_UNAVAILABLE, "open(%s)", argv[0]); 12387992Sjoerg 12487992Sjoerg if (ioctl(fd, FD_GDTYPE, &type) == -1) 12587992Sjoerg err(EX_OSERR, "ioctl(FD_GDTYPE)"); 12687992Sjoerg if (ioctl(fd, FD_GTYPE, &ft) == -1) 12787992Sjoerg err(EX_OSERR, "ioctl(FD_GTYPE)"); 12887992Sjoerg 12987992Sjoerg if (show) { 13087992Sjoerg showdev(type, argv[0]); 13187992Sjoerg return (0); 1324007Sjoerg } 1338857Srgrimes 134134081Sphk if (autofmt) { 135134081Sphk memset(&newft, 0, sizeof newft); 136134081Sphk ft = newft; 137134081Sphk } 138134081Sphk 13987992Sjoerg if (format) { 14087992Sjoerg getname(type, &name, &descr); 14187992Sjoerg fdtp = get_fmt(format, type); 14287992Sjoerg if (fdtp == 0) 14387992Sjoerg errx(EX_USAGE, 14487992Sjoerg "unknown format %d KB for drive type %s", 14587992Sjoerg format, name); 14687992Sjoerg ft = *fdtp; 1474007Sjoerg } 1484007Sjoerg 14987992Sjoerg if (fmtstring) { 15087992Sjoerg parse_fmt(fmtstring, type, ft, &newft); 15187992Sjoerg ft = newft; 15287992Sjoerg } 1534007Sjoerg 15487992Sjoerg if (showfmt) { 155126231Sphk if (verbose) { 156139905Sdelphij const char *s; 157126231Sphk 158126231Sphk printf("%s: %d KB media type\n", argv[0], 159126231Sphk (128 << ft.secsize) * ft.size / 1024); 160126231Sphk printf("\tFormat:\t\t"); 161126231Sphk print_fmt(ft); 162126231Sphk if (ft.datalen != 0xff && 163126231Sphk ft.datalen != (128 << ft.secsize)) 164126231Sphk printf("\tData length:\t%d\n", ft.datalen); 165126231Sphk printf("\tSector size:\t%d\n", 128 << ft.secsize); 166126231Sphk printf("\tSectors/track:\t%d\n", ft.sectrac); 167126231Sphk printf("\tHeads/cylinder:\t%d\n", ft.heads); 168126231Sphk printf("\tCylinders/disk:\t%d\n", ft.tracks); 169126231Sphk switch (ft.trans) { 170126231Sphk case 0: printf("\tTransfer rate:\t500 kbps\n"); break; 171126231Sphk case 1: printf("\tTransfer rate:\t300 kbps\n"); break; 172126231Sphk case 2: printf("\tTransfer rate:\t250 kbps\n"); break; 173126231Sphk case 3: printf("\tTransfer rate:\t1 Mbps\n"); break; 174126231Sphk } 175126231Sphk printf("\tSector gap:\t%d\n", ft.gap); 176126231Sphk printf("\tFormat gap:\t%d\n", ft.f_gap); 177126231Sphk printf("\tInterleave:\t%d\n", ft.f_inter); 178126231Sphk printf("\tSide offset:\t%d\n", ft.offset_side2); 179126231Sphk printf("\tFlags\t\t<"); 180126231Sphk s = ""; 181126231Sphk if (ft.flags & FL_MFM) { 182126231Sphk printf("%sMFM", s); 183126231Sphk s = ","; 184126231Sphk } 185126231Sphk if (ft.flags & FL_2STEP) { 186126231Sphk printf("%s2STEP", s); 187126231Sphk s = ","; 188126231Sphk } 189126231Sphk if (ft.flags & FL_PERPND) { 190126231Sphk printf("%sPERPENDICULAR", s); 191126231Sphk s = ","; 192126231Sphk } 193134081Sphk if (ft.flags & FL_AUTO) { 194134081Sphk printf("%sAUTO", s); 195134081Sphk s = ","; 196134081Sphk } 197126231Sphk printf(">\n"); 198126231Sphk } else { 199126231Sphk print_fmt(ft); 200126231Sphk } 20187992Sjoerg return (0); 2024007Sjoerg } 2038857Srgrimes 20487992Sjoerg if (format || fmtstring) { 20587992Sjoerg if (ioctl(fd, FD_STYPE, &ft) == -1) 20687992Sjoerg err(EX_OSERR, "ioctl(FD_STYPE)"); 20787992Sjoerg return (0); 20887992Sjoerg } 20987992Sjoerg 21087992Sjoerg return 0; 2114007Sjoerg} 212