diff --git a/BUILD.gn b/BUILD.gn deleted file mode 100644 index f0780fc..0000000 --- a/BUILD.gn +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright (c) 2021 Huawei Device Co., Ltd. -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS -# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY -# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER -# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -import("//build/ohos.gni") -config("vfat-defaults") { - cflags = [ - "-Wall", - "-Werror", - "-Wno-unused-function", - "-Wno-unused-parameter", - "-Wno-unused-variable", - "-D_FILE_OFFSET_BITS=64", - "-D_GNU_SOURCE", - "-DSIGINFO=SIGUSR2", - "-Dnitems(x)=(sizeof((x))/sizeof((x)[0]))", - "-Wno-implicit-function-declaration", - "-DMAKEFS", - "-D_MACHINE_IOCTL_FD_H_", - ] - include_dirs = [ "//third_party/FreeBSD/sys" ] -} - -################################################### -##Build newfs_msdos -ohos_executable("newfs_msdos") { - configs = [ ":vfat-defaults" ] - sources = [ - "mkfs_msdos.c", - "newfs_msdos.c", - ] - - include_dirs = [] - install_enable = true - deps = [] - subsystem_name = "filemanagement" - part_name = "storage_service" - install_images = [ "system" ] -} diff --git a/COPYRIGHT b/COPYRIGHT deleted file mode 100644 index 4a40a9f..0000000 --- a/COPYRIGHT +++ /dev/null @@ -1,126 +0,0 @@ -# $FreeBSD$ -# @(#)COPYRIGHT 8.2 (Berkeley) 3/21/94 - -The compilation of software known as FreeBSD is distributed under the -following terms: - -Copyright (c) 1992-2020 The FreeBSD Project. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -SUCH DAMAGE. - -The 4.4BSD and 4.4BSD-Lite software is distributed under the following -terms: - -All of the documentation and software included in the 4.4BSD and 4.4BSD-Lite -Releases is copyrighted by The Regents of the University of California. - -Copyright 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 - The Regents of the University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. All advertising materials mentioning features or use of this software - must display the following acknowledgement: -This product includes software developed by the University of -California, Berkeley and its contributors. -4. Neither the name of the University nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -SUCH DAMAGE. - -The Institute of Electrical and Electronics Engineers and the American -National Standards Committee X3, on Information Processing Systems have -given us permission to reprint portions of their documentation. - -In the following statement, the phrase ``this text'' refers to portions -of the system documentation. - -Portions of this text are reprinted and reproduced in electronic form in -the second BSD Networking Software Release, from IEEE Std 1003.1-1988, IEEE -Standard Portable Operating System Interface for Computer Environments -(POSIX), copyright C 1988 by the Institute of Electrical and Electronics -Engineers, Inc. In the event of any discrepancy between these versions -and the original IEEE Standard, the original IEEE Standard is the referee -document. - -In the following statement, the phrase ``This material'' refers to portions -of the system documentation. - -This material is reproduced with permission from American National -Standards Committee X3, on Information Processing Systems. Computer and -Business Equipment Manufacturers Association (CBEMA), 311 First St., NW, -Suite 500, Washington, DC 20001-2178. The developmental work of -Programming Language C was completed by the X3J11 Technical Committee. - -The views and conclusions contained in the software and documentation are -those of the authors and should not be interpreted as representing official -policies, either expressed or implied, of the Regents of the University -of California. - - -NOTE: The copyright of UC Berkeley's Berkeley Software Distribution ("BSD") -source has been updated. The copyright addendum may be found at -ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change and is -included below. - -July 22, 1999 - -To All Licensees, Distributors of Any Version of BSD: - -As you know, certain of the Berkeley Software Distribution ("BSD") source -code files require that further distributions of products containing all or -portions of the software, acknowledge within their advertising materials -that such products contain software developed by UC Berkeley and its -contributors. - -Specifically, the provision reads: - -" * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors." - -Effective immediately, licensees and distributors are no longer required to -include the acknowledgement within advertising materials. Accordingly, the -foregoing paragraph of those BSD Unix files containing it is hereby deleted -in its entirety. - -William Hoskins -Director, Office of Technology Licensing -University of California, Berkeley diff --git a/Makefile b/Makefile deleted file mode 100644 index d12cf02..0000000 --- a/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# $FreeBSD$ - -PACKAGE=runtime -PROG= newfs_msdos -MAN= newfs_msdos.8 -SRCS= newfs_msdos.c mkfs_msdos.c - -# XXX - this is verboten -.if ${MACHINE_CPUARCH} == "arm" -WARNS?= 3 -.endif -CSTD= c11 - -.include diff --git a/Makefile.depend b/Makefile.depend deleted file mode 100644 index 6cfaab1..0000000 --- a/Makefile.depend +++ /dev/null @@ -1,17 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/OAT.xml b/OAT.xml deleted file mode 100644 index 3c4f1a0..0000000 --- a/OAT.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - COPYRIGHT - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/README.OpenSource b/README.OpenSource deleted file mode 100644 index ed7c72a..0000000 --- a/README.OpenSource +++ /dev/null @@ -1,11 +0,0 @@ -[ - { - "Name" : "newfs_msdos", - "License" : "BSD-4-Clause", - "License File" : "COPYRIGHT", - "Version Number" : "freebsd-src 12.2.0", - "Owner" : "Berkeley", - "Upstream URL" : "https://github.com/freebsd/freebsd-src/tree/master/sbin/newfs_msdos", - "Description" : "The newfs_msdos utility creates a FAT12, FAT16, or FAT32 file system on device or file named special, using disktab(5) entry disktype to determine geometry, if required." - } -] diff --git a/README_ZH.md b/README_ZH.md deleted file mode 100644 index 5219e93..0000000 --- a/README_ZH.md +++ /dev/null @@ -1,51 +0,0 @@ -# third_party_newfs_msdos - -#### 介绍 -newfs_msdos是Fat32格式化工具。实现在设备上构建一个FAT12、FAT16或FAT32的文件OS(FAT)文件系统。 - -命令格式: - - newfs_msdos [-N] [-@ offset] [-A] [-B boot] [-C create-size] - [-F FAT-type] [-I VolumeID] [-L label] [-O OEM] - [-S sector-size] [-T timestamp] [-a FAT-size] [-b block-size] - [-c cluster-size] [-e DirEnts] [-f format] [-h heads] - [-i info] [-k backup] [-m media] [-n FATs] [-o hidden] - [-r reserved] [-s total] [-u track-size] special [disktype] -如果 special 不包含 / 并且未使用 -C,则假定它是设备名称,并且 /dev/ 被添加到名称以构造实际设备名称。 要处理当前目录中的文件,请使用 ./filename。 - -参数选项如下: -- N :不要创建文件系统:只需打印参数。 -- -@ offset :在设备或文件中以字节为单位的指定偏移量处构建文件系统。 附加到偏移量的后缀 s、k、m、g(小写或大写)分别指定该数字以扇区、千字节、兆字节或千兆字节为单位。 -- -A :尝试群集对齐根目录,对 SD 卡有用。 -- -B boot :从文件中获取引导程序。 -- -C create-size :创建具有指定大小的图像文件。 附加到大小的后缀字符被解释为 -@ 选项。该文件是通过截断具有相同名称的任何现有文件并将其调整为请求的大小来创建的。 如果文件系统支持稀疏文件,则占用的磁盘空间可能小于参数指定的大小。 -- -F FAT-type :FAT类型(12/16/32) -- -I VolumeID :卷 ID,十进制或十六进制 (0x...) 格式的 32 位数字。 -- -L label :卷标(最多 11 个字符)。 标签应仅包含在常规 DOS (8+3) 文件名中允许的那些字符。 -- -O OEM :OEM 字符串(最多 8 个字符)。 默认为“BSD 4.4”。、 -- -S sector-size :每个扇区的字节数。 可接受的值为 512 到 32768 范围内的 2 的幂。 -- -T timestamp :创建文件系统,就好像当前时间是时间戳一样。 默认文件系统卷 ID 来自时间。timestamp 可以是路径名(其中时间戳来自该文件)或解释为自纪元以来的秒数的整数值。 -- -a FAT-size :每个 FAT 的扇区数。 -- -b block-size :文件系统块大小(每个簇的字节数) -- -c cluster-size :每个集群的扇区。 可接受的值为 1 到 128 范围内的 2 的幂。 -- -e dirents :根目录的条目数(仅限 FAT12 和 FAT16) -- -f format :指定标准(软盘)格式。 八种标准格式是(以千字节为单位的容量):160、180、320、360、720、1200、1440、2880。 -- -h heads :驱动头数 -- -i info :文件系统信息扇区的位置(仅限 FAT32)。 0xffff 值表示没有信息扇区。 -- -k backup :备份引导扇区的位置(仅限 FAT32)。 0xffff 值表示没有备份扇区。 -- -m media :媒体描述符(可接受的范围 0xf0 到 0xff)。 -- -n FATs :FAT 的数量。 可接受的值为 1 到 16(含)。 默认值为 2。 -- -o hidden :隐藏扇区数 -- -r reserved :保留扇区数。 -- -s total :文件系统大小。 -- -u track-size :每个磁道的扇区数。 - -#### 来源 -1. newfs_msdos是[freebsd/freebsd-src](https://github.com/freebsd/freebsd-src/tree/master/sbin/newfs_msdos)下的一个功能。 -2. BSD提供的[使用手册](https://www.freebsd.org/cgi/man.cgi?query=newfs_msdos)。 -3. 可以到[freebsd-src](https://github.com/freebsd/freebsd-src.git)了解源代码。 - - - - - diff --git a/mkfs_define.h b/mkfs_define.h deleted file mode 100644 index 0b9f303..0000000 --- a/mkfs_define.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef MKFS_DEFINE_H -#define MKFS_DEFINE_H -#include - -/* - * BSD_NPARTS_MIN,BSD_NDRIVEDATA,BSD_NSPARE - * Link: https://github.com/freebsd/freebsd-src/ - * Path: freebsd-src/sys/sys/disk/bsd.h - */ -#define BSD_NPARTS_MIN 8 - -/* Drive-type specific data size (in number of 32-bit inegrals) */ -#define BSD_NDRIVEDATA 5 - -/* Number of spare 32-bit integrals following drive-type data */ -#define BSD_NSPARE 5 - -/* - * MAXPHYS - * Link: https://github.com/freebsd/freebsd-src/ - * Path: freebsd-src/sys/sys/param.h - */ -#ifdef __ILP32__ -#define MAXPHYS (128 * 1024) -#else -#define MAXPHYS (1024 * 1024) -#endif - -/* - * DIOCGMEDIASIZE,DIOCGFWSECTORS,DIOCGSECTORSIZE,DIOCGFWHEADS - * Link: https://github.com/freebsd/freebsd-src/ - * Path: freebsd-src/sys/sys/disk.h - */ -#define DIOCGMEDIASIZE _IOR('d', 129, off_t) /* Get media size in bytes */ - /* - * Get the size of the entire device in bytes. This should be a - * multiple of the sector size. - */ - -#define DIOCGFWSECTORS _IOR('d', 130, u_int) /* Get firmware's sectorcount */ - /* - * Get the firmware's notion of number of sectors per track. This - * value is mostly used for compatibility with various ill designed - * disk label formats. Don't use it unless you have to. - */ - -#define DIOCGSECTORSIZE _IOR('d', 128, u_int) - /* - * Get the sector size of the device in bytes. The sector size is the - * smallest unit of data which can be transferred from this device. - * Usually this is a power of 2 but it might not be (i.e. CDROM audio). - */ - -#define DIOCGFWHEADS _IOR('d', 131, u_int) /* Get firmware's headcount */ - /* - * Get the firmwares notion of number of heads per cylinder. This - * value is mostly used for compatibility with various ill designed - * disk label formats. Don't use it unless you have to. - */ - -/* - * FD_GTYPE - * Link: https://github.com/freebsd/freebsd-src/ - * Path: freebsd-src/sys/sys/fdcio.h - */ -#ifndef _MACHINE_IOCTL_FD_H_ -#define FD_GTYPE _IOR('F', 62, struct fd_type) /* get drive type */ -#endif - -/* - * disklabel - * Link: https://github.com/freebsd/freebsd-src/ - * Path: freebsd-src/sys/sys/disk/bsd.h - */ -struct disklabel { - uint32_t d_magic; /* the magic number */ - uint16_t d_type; /* drive type */ - uint16_t d_subtype; /* controller/d_type specific */ - char d_typename[16]; /* type name, e.g. "eagle" */ - - char d_packname[16]; /* pack identifier */ - - /* disk geometry: */ - uint32_t d_secsize; /* # of bytes per sector */ - uint32_t d_nsectors; /* # of data sectors per track */ - uint32_t d_ntracks; /* # of tracks per cylinder */ - uint32_t d_ncylinders; /* # of data cylinders per unit */ - uint32_t d_secpercyl; /* # of data sectors per cylinder */ - uint32_t d_secperunit; /* # of data sectors per unit */ - - /* - * Spares (bad sector replacements) below are not counted in - * d_nsectors or d_secpercyl. Spare sectors are assumed to - * be physical sectors which occupy space at the end of each - * track and/or cylinder. - */ - uint16_t d_sparespertrack; /* # of spare sectors per track */ - uint16_t d_sparespercyl; /* # of spare sectors per cylinder */ - /* - * Alternate cylinders include maintenance, replacement, configuration - * description areas, etc. - */ - uint32_t d_acylinders; /* # of alt. cylinders per unit */ - - /* hardware characteristics: */ - /* - * d_interleave, d_trackskew and d_cylskew describe perturbations - * in the media format used to compensate for a slow controller. - * Interleave is physical sector interleave, set up by the - * formatter or controller when formatting. When interleaving is - * in use, logically adjacent sectors are not physically - * contiguous, but instead are separated by some number of - * sectors. It is specified as the ratio of physical sectors - * traversed per logical sector. Thus an interleave of 1:1 - * implies contiguous layout, while 2:1 implies that logical - * sector 0 is separated by one sector from logical sector 1. - * d_trackskew is the offset of sector 0 on track N relative to - * sector 0 on track N-1 on the same cylinder. Finally, d_cylskew - * is the offset of sector 0 on cylinder N relative to sector 0 - * on cylinder N-1. - */ - uint16_t d_rpm; /* rotational speed */ - uint16_t d_interleave; /* hardware sector interleave */ - uint16_t d_trackskew; /* sector 0 skew, per track */ - uint16_t d_cylskew; /* sector 0 skew, per cylinder */ - uint32_t d_headswitch; /* head switch time, usec */ - uint32_t d_trkseek; /* track-to-track seek, usec */ - uint32_t d_flags; /* generic flags */ - uint32_t d_drivedata[BSD_NDRIVEDATA]; /* drive-type specific data */ - uint32_t d_spare[BSD_NSPARE]; /* reserved for future use */ - uint32_t d_magic2; /* the magic number (again) */ - uint16_t d_checksum; /* xor of data incl. partitions */ - - /* filesystem and partition information: */ - uint16_t d_npartitions; /* number of partitions in following */ - uint32_t d_bbsize; /* size of boot area at sn0, bytes */ - uint32_t d_sbsize; /* max size of fs superblock, bytes */ - struct partition { /* the partition table */ - uint32_t p_size; /* number of sectors in partition */ - uint32_t p_offset; /* starting sector */ - uint32_t p_fsize; /* filesystem basic fragment size */ - uint8_t p_fstype; /* filesystem type, see below */ - uint8_t p_frag; /* filesystem fragments per block */ - uint16_t p_cpg; /* filesystem cylinders per group */ - } d_partitions[BSD_NPARTS_MIN]; /* actually may be more */ -}; - -/* - * fd_type - * Link: https://github.com/freebsd/freebsd-src/ - * Path: freebsd-src/sys/sys/fdcio.h - */ -struct fd_type { - int sectrac; /* sectors per track */ - int secsize; /* size code for sectors */ - int datalen; /* data len when secsize = 0 */ - int gap; /* gap len between sectors */ - int tracks; /* total number of cylinders */ - int size; /* size of disk in sectors */ - int trans; /* transfer speed code */ - int heads; /* number of heads */ - int f_gap; /* format gap len */ - int f_inter; /* format interleave factor */ - int offset_side2; /* offset of sectors on side2 */ - int flags; /* misc. features */ -#define FL_MFM 0x0001 /* MFM recording */ -#define FL_2STEP 0x0002 /* 2 steps between cylinders */ -#define FL_PERPND 0x0004 /* perpendicular recording */ -#define FL_AUTO 0x0008 /* autodetect format */ -}; -#endif //MKFS_DEFINE_H \ No newline at end of file diff --git a/mkfs_msdos.c b/mkfs_msdos.c deleted file mode 100644 index b18a392..0000000 --- a/mkfs_msdos.c +++ /dev/null @@ -1,1100 +0,0 @@ -/* - * Copyright (c) 1998 Robert Nordier - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -#include -#ifdef MAKEFS -/* In the makefs case we only want struct disklabel */ -// #include -#else -// #include -// #include -// #include -// #include -#endif -#include -// #include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "mkfs_msdos.h" - -#define MAXU16 0xffff /* maximum unsigned 16-bit quantity */ -#define BPN 4 /* bits per nibble */ -#define NPB 2 /* nibbles per byte */ - -#define DOSMAGIC 0xaa55 /* DOS magic number */ -#define MINBPS 512 /* minimum bytes per sector */ -#define MAXBPS 4096 /* maximum bytes per sector */ -#define MAXSPC 128 /* maximum sectors per cluster */ -#define MAXNFT 16 /* maximum number of FATs */ -#define DEFBLK 4096 /* default block size */ -#define DEFBLK16 2048 /* default block size FAT16 */ -#define DEFRDE 512 /* default root directory entries */ -#define RESFTE 2 /* reserved FAT entries */ -#define MINCLS12 1U /* minimum FAT12 clusters */ -#define MINCLS16 0xff5U /* minimum FAT16 clusters */ -#define MINCLS32 0xfff5U /* minimum FAT32 clusters */ -#define MAXCLS12 0xff4U /* maximum FAT12 clusters */ -#define MAXCLS16 0xfff4U /* maximum FAT16 clusters */ -#define MAXCLS32 0xffffff4U /* maximum FAT32 clusters */ - -#define mincls(fat) ((fat) == 12 ? MINCLS12 : \ - (fat) == 16 ? MINCLS16 : \ - MINCLS32) - -#define maxcls(fat) ((fat) == 12 ? MAXCLS12 : \ - (fat) == 16 ? MAXCLS16 : \ - MAXCLS32) - -#define mk1(p, x) \ - (p) = (u_int8_t)(x) - -#define mk2(p, x) \ - (p)[0] = (u_int8_t)(x), \ - (p)[1] = (u_int8_t)((x) >> 010) - -#define mk4(p, x) \ - (p)[0] = (u_int8_t)(x), \ - (p)[1] = (u_int8_t)((x) >> 010), \ - (p)[2] = (u_int8_t)((x) >> 020), \ - (p)[3] = (u_int8_t)((x) >> 030) - -struct bs { - u_int8_t bsJump[3]; /* bootstrap entry point */ - u_int8_t bsOemName[8]; /* OEM name and version */ -}/* __packed */; - -struct bsbpb { - u_int8_t bpbBytesPerSec[2]; /* bytes per sector */ - u_int8_t bpbSecPerClust; /* sectors per cluster */ - u_int8_t bpbResSectors[2]; /* reserved sectors */ - u_int8_t bpbFATs; /* number of FATs */ - u_int8_t bpbRootDirEnts[2]; /* root directory entries */ - u_int8_t bpbSectors[2]; /* total sectors */ - u_int8_t bpbMedia; /* media descriptor */ - u_int8_t bpbFATsecs[2]; /* sectors per FAT */ - u_int8_t bpbSecPerTrack[2]; /* sectors per track */ - u_int8_t bpbHeads[2]; /* drive heads */ - u_int8_t bpbHiddenSecs[4]; /* hidden sectors */ - u_int8_t bpbHugeSectors[4]; /* big total sectors */ -}/* __packed */; - -struct bsxbpb { - u_int8_t bpbBigFATsecs[4]; /* big sectors per FAT */ - u_int8_t bpbExtFlags[2]; /* FAT control flags */ - u_int8_t bpbFSVers[2]; /* file system version */ - u_int8_t bpbRootClust[4]; /* root directory start cluster */ - u_int8_t bpbFSInfo[2]; /* file system info sector */ - u_int8_t bpbBackup[2]; /* backup boot sector */ - u_int8_t bpbReserved[12]; /* reserved */ -}/* __packed */; - -struct bsx { - u_int8_t exDriveNumber; /* drive number */ - u_int8_t exReserved1; /* reserved */ - u_int8_t exBootSignature; /* extended boot signature */ - u_int8_t exVolumeID[4]; /* volume ID number */ - u_int8_t exVolumeLabel[11]; /* volume label */ - u_int8_t exFileSysType[8]; /* file system type */ -}/* __packed */; - -struct de { - u_int8_t deName[11]; /* name and extension */ - u_int8_t deAttributes; /* attributes */ - u_int8_t rsvd[10]; /* reserved */ - u_int8_t deMTime[2]; /* last-modified time */ - u_int8_t deMDate[2]; /* last-modified date */ - u_int8_t deStartCluster[2]; /* starting cluster */ - u_int8_t deFileSize[4]; /* size */ -}/* __packed */; - -struct bpb { - u_int bpbBytesPerSec; /* bytes per sector */ - u_int bpbSecPerClust; /* sectors per cluster */ - u_int bpbResSectors; /* reserved sectors */ - u_int bpbFATs; /* number of FATs */ - u_int bpbRootDirEnts; /* root directory entries */ - u_int bpbSectors; /* total sectors */ - u_int bpbMedia; /* media descriptor */ - u_int bpbFATsecs; /* sectors per FAT */ - u_int bpbSecPerTrack; /* sectors per track */ - u_int bpbHeads; /* drive heads */ - u_int bpbHiddenSecs; /* hidden sectors */ - u_int bpbHugeSectors; /* big total sectors */ - u_int bpbBigFATsecs; /* big sectors per FAT */ - u_int bpbRootClust; /* root directory start cluster */ - u_int bpbFSInfo; /* file system info sector */ - u_int bpbBackup; /* backup boot sector */ -}; - -#define BPBGAP 0, 0, 0, 0, 0, 0 - -static struct { - const char *name; - struct bpb bpb; -} const stdfmt[] = { - {"160", {512, 1, 1, 2, 64, 320, 0xfe, 1, 8, 1, BPBGAP}}, - {"180", {512, 1, 1, 2, 64, 360, 0xfc, 2, 9, 1, BPBGAP}}, - {"320", {512, 2, 1, 2, 112, 640, 0xff, 1, 8, 2, BPBGAP}}, - {"360", {512, 2, 1, 2, 112, 720, 0xfd, 2, 9, 2, BPBGAP}}, - {"640", {512, 2, 1, 2, 112, 1280, 0xfb, 2, 8, 2, BPBGAP}}, - {"720", {512, 2, 1, 2, 112, 1440, 0xf9, 3, 9, 2, BPBGAP}}, - {"1200", {512, 1, 1, 2, 224, 2400, 0xf9, 7, 15, 2, BPBGAP}}, - {"1232", {1024,1, 1, 2, 192, 1232, 0xfe, 2, 8, 2, BPBGAP}}, - {"1440", {512, 1, 1, 2, 224, 2880, 0xf0, 9, 18, 2, BPBGAP}}, - {"2880", {512, 2, 1, 2, 240, 5760, 0xf0, 9, 36, 2, BPBGAP}} -}; - -static const u_int8_t bootcode[] = { - 0xfa, /* cli */ - 0x31, 0xc0, /* xor ax,ax */ - 0x8e, 0xd0, /* mov ss,ax */ - 0xbc, 0x00, 0x7c, /* mov sp,7c00h */ - 0xfb, /* sti */ - 0x8e, 0xd8, /* mov ds,ax */ - 0xe8, 0x00, 0x00, /* call $ + 3 */ - 0x5e, /* pop si */ - 0x83, 0xc6, 0x19, /* add si,+19h */ - 0xbb, 0x07, 0x00, /* mov bx,0007h */ - 0xfc, /* cld */ - 0xac, /* lodsb */ - 0x84, 0xc0, /* test al,al */ - 0x74, 0x06, /* jz $ + 8 */ - 0xb4, 0x0e, /* mov ah,0eh */ - 0xcd, 0x10, /* int 10h */ - 0xeb, 0xf5, /* jmp $ - 9 */ - 0x30, 0xe4, /* xor ah,ah */ - 0xcd, 0x16, /* int 16h */ - 0xcd, 0x19, /* int 19h */ - 0x0d, 0x0a, - 'N', 'o', 'n', '-', 's', 'y', 's', 't', - 'e', 'm', ' ', 'd', 'i', 's', 'k', - 0x0d, 0x0a, - 'P', 'r', 'e', 's', 's', ' ', 'a', 'n', - 'y', ' ', 'k', 'e', 'y', ' ', 't', 'o', - ' ', 'r', 'e', 'b', 'o', 'o', 't', - 0x0d, 0x0a, - 0 -}; - -static volatile sig_atomic_t got_siginfo; -static void infohandler(int); - -static int check_mounted(const char *, mode_t); -static ssize_t getchunksize(void); -static int getstdfmt(const char *, struct bpb *); -static int getdiskinfo(int, const char *, const char *, int, struct bpb *); -static void print_bpb(struct bpb *); -static int ckgeom(const char *, u_int, const char *); -static void mklabel(u_int8_t *, const char *); -static int oklabel(const char *); -static void setstr(u_int8_t *, const char *, size_t); - -int -mkfs_msdos(const char *fname, const char *dtype, const struct msdos_options *op) -{ - char buf[MAXPATHLEN]; - struct sigaction si_sa; - struct stat sb; - struct timeval tv; - struct bpb bpb; - struct tm *tm; - struct bs *bs; - struct bsbpb *bsbpb; - struct bsxbpb *bsxbpb; - struct bsx *bsx; - struct de *de; - u_int8_t *img; - u_int8_t *physbuf, *physbuf_end; - const char *bname; - ssize_t n; - time_t now; - u_int fat, bss, rds, cls, dir, lsn, x, x1, x2; - u_int extra_res, alignment, saved_x, attempts=0; - bool set_res, set_spf, set_spc; - int fd, fd1, rv; - struct msdos_options o = *op; - ssize_t chunksize; - - physbuf = NULL; - rv = -1; - fd = fd1 = -1; - - if (o.block_size && o.sectors_per_cluster) { - warnx("Cannot specify both block size and sectors per cluster"); - goto done; - } - if (o.OEM_string && strlen(o.OEM_string) > 8) { - warnx("%s: bad OEM string", o.OEM_string); - goto done; - } - if (o.create_size) { - if (o.no_create) { - warnx("create (-C) is incompatible with -N"); - goto done; - } - fd = open(fname, O_RDWR | O_CREAT | O_TRUNC, 0644); - if (fd == -1) { - warnx("failed to create %s", fname); - goto done; - } - if (ftruncate(fd, o.create_size)) { - warnx("failed to initialize %jd bytes", (intmax_t)o.create_size); - goto done; - } - } else if ((fd = open(fname, o.no_create ? O_RDONLY : O_RDWR)) == -1) { - warn("%s", fname); - goto done; - } - if (fstat(fd, &sb)) { - warn("%s", fname); - goto done; - } - if (o.create_size) { - if (!S_ISREG(sb.st_mode)) - warnx("warning, %s is not a regular file", fname); - } else { -#ifdef MAKEFS - errx(1, "o.create_size must be set!"); -#else - if (!S_ISCHR(sb.st_mode)) - warnx("warning, %s is not a character device", fname); -#endif - } -#ifndef MAKEFS - if (!o.no_create) - if (check_mounted(fname, sb.st_mode) == -1) - goto done; -#endif - if (o.offset && o.offset != lseek(fd, o.offset, SEEK_SET)) { - warnx("cannot seek to %jd", (intmax_t)o.offset); - goto done; - } - memset(&bpb, 0, sizeof(bpb)); - if (o.floppy) { - if (getstdfmt(o.floppy, &bpb) == -1) - goto done; - bpb.bpbHugeSectors = bpb.bpbSectors; - bpb.bpbSectors = 0; - bpb.bpbBigFATsecs = bpb.bpbFATsecs; - bpb.bpbFATsecs = 0; - } - if (o.drive_heads) - bpb.bpbHeads = o.drive_heads; - if (o.sectors_per_track) - bpb.bpbSecPerTrack = o.sectors_per_track; - if (o.bytes_per_sector) - bpb.bpbBytesPerSec = o.bytes_per_sector; - if (o.size) - bpb.bpbHugeSectors = o.size; - if (o.hidden_sectors_set) - bpb.bpbHiddenSecs = o.hidden_sectors; - if (!(o.floppy || (o.drive_heads && o.sectors_per_track && - o.bytes_per_sector && o.size && o.hidden_sectors_set))) { - if (getdiskinfo(fd, fname, dtype, o.hidden_sectors_set, &bpb) == -1) - goto done; - bpb.bpbHugeSectors -= (o.offset / bpb.bpbBytesPerSec); - if (bpb.bpbSecPerClust == 0) { /* set defaults */ - if (bpb.bpbHugeSectors <= 6000) /* about 3MB -> 512 bytes */ - bpb.bpbSecPerClust = 1; - else if (bpb.bpbHugeSectors <= (1<<17)) /* 64M -> 4k */ - bpb.bpbSecPerClust = 8; - else if (bpb.bpbHugeSectors <= (1<<19)) /* 256M -> 8k */ - bpb.bpbSecPerClust = 16; - else if (bpb.bpbHugeSectors <= (1<<21)) /* 1G -> 16k */ - bpb.bpbSecPerClust = 32; - else - bpb.bpbSecPerClust = 64; /* otherwise 32k */ - } - } - if (bpb.bpbBytesPerSec < MINBPS || - bpb.bpbBytesPerSec > MAXBPS || - !powerof2(bpb.bpbBytesPerSec)) { - warnx("Invalid bytes/sector (%u): must be 512, 1024, 2048 or 4096", - bpb.bpbBytesPerSec); - goto done; - } - - if (o.volume_label && !oklabel(o.volume_label)) { - warnx("%s: bad volume label", o.volume_label); - goto done; - } - if (!(fat = o.fat_type)) { - if (o.floppy) - fat = 12; - else if (!o.directory_entries && (o.info_sector || o.backup_sector)) - fat = 32; - } - if ((fat == 32 && o.directory_entries) || (fat != 32 && (o.info_sector || o.backup_sector))) { - warnx("-%c is not a legal FAT%s option", - fat == 32 ? 'e' : o.info_sector ? 'i' : 'k', - fat == 32 ? "32" : "12/16"); - goto done; - } - if (o.floppy && fat == 32) - bpb.bpbRootDirEnts = 0; - if (fat != 0 && fat != 12 && fat != 16 && fat != 32) { - warnx("%d: bad FAT type", fat); - goto done; - } - - if (o.block_size) { - if (!powerof2(o.block_size)) { - warnx("block size (%u) is not a power of 2", o.block_size); - goto done; - } - if (o.block_size < bpb.bpbBytesPerSec) { - warnx("block size (%u) is too small; minimum is %u", - o.block_size, bpb.bpbBytesPerSec); - goto done; - } - if (o.block_size > bpb.bpbBytesPerSec * MAXSPC) { - warnx("block size (%u) is too large; maximum is %u", - o.block_size, bpb.bpbBytesPerSec * MAXSPC); - goto done; - } - bpb.bpbSecPerClust = o.block_size / bpb.bpbBytesPerSec; - } - if (o.sectors_per_cluster) { - if (!powerof2(o.sectors_per_cluster)) { - warnx("sectors/cluster (%u) is not a power of 2", - o.sectors_per_cluster); - goto done; - } - bpb.bpbSecPerClust = o.sectors_per_cluster; - } - if (o.reserved_sectors) - bpb.bpbResSectors = o.reserved_sectors; - if (o.num_FAT) { - if (o.num_FAT > MAXNFT) { - warnx("number of FATs (%u) is too large; maximum is %u", - o.num_FAT, MAXNFT); - goto done; - } - bpb.bpbFATs = o.num_FAT; - } - if (o.directory_entries) - bpb.bpbRootDirEnts = o.directory_entries; - if (o.media_descriptor_set) { - if (o.media_descriptor < 0xf0) { - warnx("illegal media descriptor (%#x)", o.media_descriptor); - goto done; - } - bpb.bpbMedia = o.media_descriptor; - } - if (o.sectors_per_fat) - bpb.bpbBigFATsecs = o.sectors_per_fat; - if (o.info_sector) - bpb.bpbFSInfo = o.info_sector; - if (o.backup_sector) - bpb.bpbBackup = o.backup_sector; - bss = 1; - bname = NULL; - fd1 = -1; - if (o.bootstrap) { - bname = o.bootstrap; - if (!strchr(bname, '/')) { - snprintf(buf, sizeof(buf), "/boot/%s", bname); - bname = buf; - } - if ((fd1 = open(bname, O_RDONLY)) == -1 || fstat(fd1, &sb)) { - warn("%s", bname); - goto done; - } - if (!S_ISREG(sb.st_mode) || sb.st_size % bpb.bpbBytesPerSec || - sb.st_size < bpb.bpbBytesPerSec || - sb.st_size > bpb.bpbBytesPerSec * MAXU16) { - warnx("%s: inappropriate file type or format", bname); - goto done; - } - bss = sb.st_size / bpb.bpbBytesPerSec; - } - if (!bpb.bpbFATs) - bpb.bpbFATs = 2; - if (!fat) { - if (bpb.bpbHugeSectors < (bpb.bpbResSectors ? bpb.bpbResSectors : bss) + - howmany((RESFTE + (bpb.bpbSecPerClust ? MINCLS16 : MAXCLS12 + 1)) * - (bpb.bpbSecPerClust ? 16 : 12) / BPN, - bpb.bpbBytesPerSec * NPB) * - bpb.bpbFATs + - howmany(bpb.bpbRootDirEnts ? bpb.bpbRootDirEnts : DEFRDE, - bpb.bpbBytesPerSec / sizeof(struct de)) + - (bpb.bpbSecPerClust ? MINCLS16 : MAXCLS12 + 1) * - (bpb.bpbSecPerClust ? bpb.bpbSecPerClust : - howmany(DEFBLK, bpb.bpbBytesPerSec))) - fat = 12; - else if (bpb.bpbRootDirEnts || bpb.bpbHugeSectors < - (bpb.bpbResSectors ? bpb.bpbResSectors : bss) + - howmany((RESFTE + MAXCLS16) * 2, bpb.bpbBytesPerSec) * - bpb.bpbFATs + - howmany(DEFRDE, bpb.bpbBytesPerSec / sizeof(struct de)) + - (MAXCLS16 + 1) * - (bpb.bpbSecPerClust ? bpb.bpbSecPerClust : - howmany(8192, bpb.bpbBytesPerSec))) - fat = 16; - else - fat = 32; - } - x = bss; - if (fat == 32) { - if (!bpb.bpbFSInfo) { - if (x == MAXU16 || x == bpb.bpbBackup) { - warnx("no room for info sector"); - goto done; - } - bpb.bpbFSInfo = x; - } - if (bpb.bpbFSInfo != MAXU16 && x <= bpb.bpbFSInfo) - x = bpb.bpbFSInfo + 1; - if (!bpb.bpbBackup) { - if (x == MAXU16) { - warnx("no room for backup sector"); - goto done; - } - bpb.bpbBackup = x; - } else if (bpb.bpbBackup != MAXU16 && bpb.bpbBackup == bpb.bpbFSInfo) { - warnx("backup sector would overwrite info sector"); - goto done; - } - if (bpb.bpbBackup != MAXU16 && x <= bpb.bpbBackup) - x = bpb.bpbBackup + 1; - } - - extra_res = 0; - alignment = 0; - set_res = (bpb.bpbResSectors == 0); - set_spf = (bpb.bpbBigFATsecs == 0); - set_spc = (bpb.bpbSecPerClust == 0); - saved_x = x; - - /* - * Attempt to align the root directory to cluster if o.align is set. - * This is done by padding with reserved blocks. Note that this can - * cause other factors to change, which can in turn change the alignment. - * This should take at most 2 iterations, as increasing the reserved - * amount may cause the FAT size to decrease by 1, requiring another - * bpbFATs reserved blocks. If bpbSecPerClust changes, it will - * be half of its previous size, and thus will not throw off alignment. - */ - do { - x = saved_x; - if (set_res) - bpb.bpbResSectors = ((fat == 32) ? - MAX(x, MAX(16384 / bpb.bpbBytesPerSec, 4)) : x) + extra_res; - else if (bpb.bpbResSectors < x) { - warnx("too few reserved sectors (need %d have %d)", x, - bpb.bpbResSectors); - goto done; - } - if (fat != 32 && !bpb.bpbRootDirEnts) - bpb.bpbRootDirEnts = DEFRDE; - rds = howmany(bpb.bpbRootDirEnts, - bpb.bpbBytesPerSec / sizeof(struct de)); - if (set_spc) { - for (bpb.bpbSecPerClust = howmany(fat == 16 ? DEFBLK16 : - DEFBLK, bpb.bpbBytesPerSec); - bpb.bpbSecPerClust < MAXSPC && (bpb.bpbResSectors + - howmany((RESFTE + maxcls(fat)) * (fat / BPN), - bpb.bpbBytesPerSec * NPB) * bpb.bpbFATs + - rds + - (u_int64_t) (maxcls(fat) + 1) * bpb.bpbSecPerClust) <= - bpb.bpbHugeSectors; - bpb.bpbSecPerClust <<= 1) - continue; - - } - if (fat != 32 && bpb.bpbBigFATsecs > MAXU16) { - warnx("too many sectors/FAT for FAT12/16"); - goto done; - } - x1 = bpb.bpbResSectors + rds; - x = bpb.bpbBigFATsecs ? bpb.bpbBigFATsecs : 1; - if (x1 + (u_int64_t)x * bpb.bpbFATs > bpb.bpbHugeSectors) { - warnx("meta data exceeds file system size"); - goto done; - } - x1 += x * bpb.bpbFATs; - x = (u_int64_t)(bpb.bpbHugeSectors - x1) * bpb.bpbBytesPerSec * NPB / - (bpb.bpbSecPerClust * bpb.bpbBytesPerSec * NPB + - fat / BPN * bpb.bpbFATs); - x2 = howmany((RESFTE + MIN(x, maxcls(fat))) * (fat / BPN), - bpb.bpbBytesPerSec * NPB); - if (set_spf) { - if (bpb.bpbBigFATsecs == 0) - bpb.bpbBigFATsecs = x2; - x1 += (bpb.bpbBigFATsecs - 1) * bpb.bpbFATs; - } - if (set_res) { - /* attempt to align root directory */ - alignment = (bpb.bpbResSectors + bpb.bpbBigFATsecs * bpb.bpbFATs) % - bpb.bpbSecPerClust; - if (o.align) - extra_res += bpb.bpbSecPerClust - alignment; - } - attempts++; - } while (o.align && alignment != 0 && attempts < 2); - if (o.align && alignment != 0) - warnx("warning: Alignment failed."); - - cls = (bpb.bpbHugeSectors - x1) / bpb.bpbSecPerClust; - x = (u_int64_t)bpb.bpbBigFATsecs * bpb.bpbBytesPerSec * NPB / (fat / BPN) - - RESFTE; - if (cls > x) - cls = x; - if (bpb.bpbBigFATsecs < x2) - warnx("warning: sectors/FAT limits file system to %u clusters", - cls); - if (cls < mincls(fat)) { - warnx("%u clusters too few clusters for FAT%u, need %u", cls, fat, - mincls(fat)); - goto done; - } - if (cls > maxcls(fat)) { - cls = maxcls(fat); - bpb.bpbHugeSectors = x1 + (cls + 1) * bpb.bpbSecPerClust - 1; - warnx("warning: FAT type limits file system to %u sectors", - bpb.bpbHugeSectors); - } - printf("%s: %u sector%s in %u FAT%u cluster%s " - "(%u bytes/cluster)\n", fname, cls * bpb.bpbSecPerClust, - cls * bpb.bpbSecPerClust == 1 ? "" : "s", cls, fat, - cls == 1 ? "" : "s", bpb.bpbBytesPerSec * bpb.bpbSecPerClust); - if (!bpb.bpbMedia) - bpb.bpbMedia = !bpb.bpbHiddenSecs ? 0xf0 : 0xf8; - if (fat == 32) - bpb.bpbRootClust = RESFTE; - if (bpb.bpbHugeSectors <= MAXU16) { - bpb.bpbSectors = bpb.bpbHugeSectors; - bpb.bpbHugeSectors = 0; - } - if (fat != 32) { - bpb.bpbFATsecs = bpb.bpbBigFATsecs; - bpb.bpbBigFATsecs = 0; - } - print_bpb(&bpb); - if (!o.no_create) { - if (o.timestamp_set) { - tv.tv_sec = now = o.timestamp; - tv.tv_usec = 0; - tm = gmtime(&now); - } else { - gettimeofday(&tv, NULL); - now = tv.tv_sec; - tm = localtime(&now); - } - - chunksize = getchunksize(); - physbuf = malloc(chunksize); - if (physbuf == NULL) { - warn(NULL); - goto done; - } - physbuf_end = physbuf + chunksize; - img = physbuf; - - dir = bpb.bpbResSectors + (bpb.bpbFATsecs ? bpb.bpbFATsecs : - bpb.bpbBigFATsecs) * bpb.bpbFATs; - memset(&si_sa, 0, sizeof(si_sa)); - si_sa.sa_handler = infohandler; -#ifdef SIGINFO - if (sigaction(SIGINFO, &si_sa, NULL) == -1) { - warn("sigaction SIGINFO"); - goto done; - } -#endif - for (lsn = 0; lsn < dir + (fat == 32 ? bpb.bpbSecPerClust : rds); lsn++) { - if (got_siginfo) { - fprintf(stderr,"%s: writing sector %u of %u (%u%%)\n", - fname, lsn, - (dir + (fat == 32 ? bpb.bpbSecPerClust: rds)), - (lsn * 100) / (dir + - (fat == 32 ? bpb.bpbSecPerClust: rds))); - got_siginfo = 0; - } - x = lsn; - if (o.bootstrap && - fat == 32 && bpb.bpbBackup != MAXU16 && - bss <= bpb.bpbBackup && x >= bpb.bpbBackup) { - x -= bpb.bpbBackup; - if (!x && lseek(fd1, o.offset, SEEK_SET)) { - warn("%s", bname); - goto done; - } - } - if (o.bootstrap && x < bss) { - if ((n = read(fd1, img, bpb.bpbBytesPerSec)) == -1) { - warn("%s", bname); - goto done; - } - if ((unsigned)n != bpb.bpbBytesPerSec) { - warnx("%s: can't read sector %u", bname, x); - goto done; - } - } else - memset(img, 0, bpb.bpbBytesPerSec); - if (!lsn || - (fat == 32 && bpb.bpbBackup != MAXU16 && - lsn == bpb.bpbBackup)) { - x1 = sizeof(struct bs); - bsbpb = (struct bsbpb *)(img + x1); - mk2(bsbpb->bpbBytesPerSec, bpb.bpbBytesPerSec); - mk1(bsbpb->bpbSecPerClust, bpb.bpbSecPerClust); - mk2(bsbpb->bpbResSectors, bpb.bpbResSectors); - mk1(bsbpb->bpbFATs, bpb.bpbFATs); - mk2(bsbpb->bpbRootDirEnts, bpb.bpbRootDirEnts); - mk2(bsbpb->bpbSectors, bpb.bpbSectors); - mk1(bsbpb->bpbMedia, bpb.bpbMedia); - mk2(bsbpb->bpbFATsecs, bpb.bpbFATsecs); - mk2(bsbpb->bpbSecPerTrack, bpb.bpbSecPerTrack); - mk2(bsbpb->bpbHeads, bpb.bpbHeads); - mk4(bsbpb->bpbHiddenSecs, bpb.bpbHiddenSecs); - mk4(bsbpb->bpbHugeSectors, bpb.bpbHugeSectors); - x1 += sizeof(struct bsbpb); - if (fat == 32) { - bsxbpb = (struct bsxbpb *)(img + x1); - mk4(bsxbpb->bpbBigFATsecs, bpb.bpbBigFATsecs); - mk2(bsxbpb->bpbExtFlags, 0); - mk2(bsxbpb->bpbFSVers, 0); - mk4(bsxbpb->bpbRootClust, bpb.bpbRootClust); - mk2(bsxbpb->bpbFSInfo, bpb.bpbFSInfo); - mk2(bsxbpb->bpbBackup, bpb.bpbBackup); - x1 += sizeof(struct bsxbpb); - } - bsx = (struct bsx *)(img + x1); - mk1(bsx->exBootSignature, 0x29); - if (o.volume_id_set) - x = o.volume_id; - else - x = (((u_int)(1 + tm->tm_mon) << 8 | - (u_int)tm->tm_mday) + - ((u_int)tm->tm_sec << 8 | - (u_int)(tv.tv_usec / 10))) << 16 | - ((u_int)(1900 + tm->tm_year) + - ((u_int)tm->tm_hour << 8 | - (u_int)tm->tm_min)); - mk4(bsx->exVolumeID, x); - mklabel(bsx->exVolumeLabel, o.volume_label ? o.volume_label : "NO NAME"); - snprintf(buf, sizeof(buf), "FAT%u", fat); - setstr(bsx->exFileSysType, buf, sizeof(bsx->exFileSysType)); - if (!o.bootstrap) { - x1 += sizeof(struct bsx); - bs = (struct bs *)img; - mk1(bs->bsJump[0], 0xeb); - mk1(bs->bsJump[1], x1 - 2); - mk1(bs->bsJump[2], 0x90); - setstr(bs->bsOemName, o.OEM_string ? o.OEM_string : "BSD4.4 ", - sizeof(bs->bsOemName)); - memcpy(img + x1, bootcode, sizeof(bootcode)); - mk2(img + MINBPS - 2, DOSMAGIC); - } - } else if (fat == 32 && bpb.bpbFSInfo != MAXU16 && - (lsn == bpb.bpbFSInfo || - (bpb.bpbBackup != MAXU16 && - lsn == bpb.bpbBackup + bpb.bpbFSInfo))) { - mk4(img, 0x41615252); - mk4(img + MINBPS - 28, 0x61417272); - mk4(img + MINBPS - 24, 0xffffffff); - mk4(img + MINBPS - 20, 0xffffffff); - mk2(img + MINBPS - 2, DOSMAGIC); - } else if (lsn >= bpb.bpbResSectors && lsn < dir && - !((lsn - bpb.bpbResSectors) % - (bpb.bpbFATsecs ? bpb.bpbFATsecs : - bpb.bpbBigFATsecs))) { - mk1(img[0], bpb.bpbMedia); - for (x = 1; x < fat * (fat == 32 ? 3 : 2) / 8; x++) - mk1(img[x], fat == 32 && x % 4 == 3 ? 0x0f : 0xff); - } else if (lsn == dir && o.volume_label) { - de = (struct de *)img; - mklabel(de->deName, o.volume_label); - mk1(de->deAttributes, 050); - x = (u_int)tm->tm_hour << 11 | - (u_int)tm->tm_min << 5 | - (u_int)tm->tm_sec >> 1; - mk2(de->deMTime, x); - x = (u_int)(tm->tm_year - 80) << 9 | - (u_int)(tm->tm_mon + 1) << 5 | - (u_int)tm->tm_mday; - mk2(de->deMDate, x); - } - /* - * Issue a write of chunksize once we have collected - * enough sectors. - */ - img += bpb.bpbBytesPerSec; - if (img >= physbuf_end) { - n = write(fd, physbuf, chunksize); - if (n != chunksize) { - warnx("%s: can't write sector %u", fname, lsn); - goto done; - } - img = physbuf; - } - } - /* - * Write remaining sectors, if the last write didn't end - * up filling a whole chunk. - */ - if (img != physbuf) { - ssize_t tailsize = img - physbuf; - - n = write(fd, physbuf, tailsize); - if (n != tailsize) { - warnx("%s: can't write sector %u", fname, lsn); - goto done; - } - } - } - rv = 0; -done: - free(physbuf); - if (fd != -1) - close(fd); - if (fd1 != -1) - close(fd1); - - return rv; -} - -/* - * return -1 with error if file system is mounted. - */ -static int -check_mounted(const char *fname, mode_t mode) -{ -/* - * If getmntinfo() is not available (e.g. Linux) don't check. This should - * not be a problem since we will only be using makefs to create images. - */ -#if !defined(MAKEFS) - struct statfs *mp; - const char *s1, *s2; - size_t len; - int n, r; - - if (!(n = getmntinfo(&mp, MNT_NOWAIT))) { - warn("getmntinfo"); - return -1; - } - len = strlen(_PATH_DEV); - s1 = fname; - if (!strncmp(s1, _PATH_DEV, len)) - s1 += len; - r = S_ISCHR(mode) && s1 != fname && *s1 == 'r'; - for (; n--; mp++) { - s2 = mp->f_mntfromname; - if (!strncmp(s2, _PATH_DEV, len)) - s2 += len; - if ((r && s2 != mp->f_mntfromname && !strcmp(s1 + 1, s2)) || - !strcmp(s1, s2)) { - warnx("%s is mounted on %s", fname, mp->f_mntonname); - return -1; - } - } -#endif - return 0; -} - -/* - * Get optimal I/O size - */ -static ssize_t -getchunksize(void) -{ - static int chunksize; - - if (chunksize != 0) - return ((ssize_t)chunksize); - -#ifdef KERN_MAXPHYS - int mib[2]; - size_t len; - - mib[0] = CTL_KERN; - mib[1] = KERN_MAXPHYS; - len = sizeof(chunksize); - - if (sysctl(mib, 2, &chunksize, &len, NULL, 0) == -1) { - warn("sysctl: KERN_MAXPHYS, using %zu", (size_t)MAXPHYS); - chunksize = 0; - } -#endif - if (chunksize == 0) - chunksize = MAXPHYS; - - /* - * For better performance, we want to write larger chunks instead of - * individual sectors (the size can only be 512, 1024, 2048 or 4096 - * bytes). Assert that chunksize can always hold an integer number of - * sectors by asserting that both are power of two numbers and the - * chunksize is greater than MAXBPS. - */ - static_assert(powerof2(MAXBPS), "MAXBPS is not power of 2"); - assert(powerof2(chunksize)); - assert(chunksize > MAXBPS); - - return ((ssize_t)chunksize); -} - -/* - * Get a standard format. - */ -static int -getstdfmt(const char *fmt, struct bpb *bpb) -{ - u_int x, i; - - x = nitems(stdfmt); - for (i = 0; i < x && strcmp(fmt, stdfmt[i].name); i++); - if (i == x) { - warnx("%s: unknown standard format", fmt); - return -1; - } - *bpb = stdfmt[i].bpb; - return 0; -} - -static void -compute_geometry_from_file(int fd, const char *fname, struct disklabel *lp) -{ - struct stat st; - off_t ms; - - if (fstat(fd, &st)) - err(1, "cannot get disk size"); - if (!S_ISREG(st.st_mode)) - errx(1, "%s is not a regular file", fname); - ms = st.st_size; - lp->d_secsize = 512; - lp->d_nsectors = 63; - lp->d_ntracks = 255; - lp->d_secperunit = ms / lp->d_secsize; -} - -/* - * Get disk slice, partition, and geometry information. - */ -static int -getdiskinfo(int fd, const char *fname, const char *dtype, /* __unused */ int oflag, - struct bpb *bpb) -{ - struct disklabel *lp, dlp; - off_t hs = 0; -#ifndef MAKEFS - off_t ms; - struct fd_type type; - - lp = NULL; - - /* If the user specified a disk type, try to use that */ - if (dtype != NULL) { - lp = getdiskbyname(dtype); - } - - /* Maybe it's a floppy drive */ - if (lp == NULL) { - if (ioctl(fd, DIOCGMEDIASIZE, &ms) == -1) { - /* create a fake geometry for a file image */ - compute_geometry_from_file(fd, fname, &dlp); - lp = &dlp; - } else if (ioctl(fd, FD_GTYPE, &type) != -1) { - dlp.d_secsize = 128 << type.secsize; - dlp.d_nsectors = type.sectrac; - dlp.d_ntracks = type.heads; - dlp.d_secperunit = ms / dlp.d_secsize; - lp = &dlp; - } - } - - /* Maybe it's a fixed drive */ - if (lp == NULL) { - if (bpb->bpbBytesPerSec) - dlp.d_secsize = bpb->bpbBytesPerSec; - if (bpb->bpbBytesPerSec == 0 && ioctl(fd, DIOCGSECTORSIZE, - &dlp.d_secsize) == -1) - err(1, "cannot get sector size"); - - dlp.d_secperunit = ms / dlp.d_secsize; - - if (bpb->bpbSecPerTrack == 0 && ioctl(fd, DIOCGFWSECTORS, - &dlp.d_nsectors) == -1) { - warn("cannot get number of sectors per track"); - dlp.d_nsectors = 63; - } - if (bpb->bpbHeads == 0 && - ioctl(fd, DIOCGFWHEADS, &dlp.d_ntracks) == -1) { - warn("cannot get number of heads"); - if (dlp.d_secperunit <= 63*1*1024) - dlp.d_ntracks = 1; - else if (dlp.d_secperunit <= 63*16*1024) - dlp.d_ntracks = 16; - else - dlp.d_ntracks = 255; - } - - hs = (ms / dlp.d_secsize) - dlp.d_secperunit; - lp = &dlp; - } -#else - /* In the makefs case we only support image files: */ - compute_geometry_from_file(fd, fname, &dlp); - lp = &dlp; -#endif - - if (bpb->bpbBytesPerSec == 0) { - if (ckgeom(fname, lp->d_secsize, "bytes/sector") == -1) - return -1; - bpb->bpbBytesPerSec = lp->d_secsize; - } - if (bpb->bpbSecPerTrack == 0) { - if (ckgeom(fname, lp->d_nsectors, "sectors/track") == -1) - return -1; - bpb->bpbSecPerTrack = lp->d_nsectors; - } - if (bpb->bpbHeads == 0) { - if (ckgeom(fname, lp->d_ntracks, "drive heads") == -1) - return -1; - bpb->bpbHeads = lp->d_ntracks; - } - if (bpb->bpbHugeSectors == 0) - bpb->bpbHugeSectors = lp->d_secperunit; - if (bpb->bpbHiddenSecs == 0) - bpb->bpbHiddenSecs = hs; - return 0; -} - -/* - * Print out BPB values. - */ -static void -print_bpb(struct bpb *bpb) -{ - printf("BytesPerSec=%u SecPerClust=%u ResSectors=%u FATs=%u", - bpb->bpbBytesPerSec, bpb->bpbSecPerClust, bpb->bpbResSectors, - bpb->bpbFATs); - if (bpb->bpbRootDirEnts) - printf(" RootDirEnts=%u", bpb->bpbRootDirEnts); - if (bpb->bpbSectors) - printf(" Sectors=%u", bpb->bpbSectors); - printf(" Media=%#x", bpb->bpbMedia); - if (bpb->bpbFATsecs) - printf(" FATsecs=%u", bpb->bpbFATsecs); - printf(" SecPerTrack=%u Heads=%u HiddenSecs=%u", bpb->bpbSecPerTrack, - bpb->bpbHeads, bpb->bpbHiddenSecs); - if (bpb->bpbHugeSectors) - printf(" HugeSectors=%u", bpb->bpbHugeSectors); - if (!bpb->bpbFATsecs) { - printf(" FATsecs=%u RootCluster=%u", bpb->bpbBigFATsecs, - bpb->bpbRootClust); - printf(" FSInfo="); - printf(bpb->bpbFSInfo == MAXU16 ? "%#x" : "%u", bpb->bpbFSInfo); - printf(" Backup="); - printf(bpb->bpbBackup == MAXU16 ? "%#x" : "%u", bpb->bpbBackup); - } - printf("\n"); -} - -/* - * Check a disk geometry value. - */ -static int -ckgeom(const char *fname, u_int val, const char *msg) -{ - if (!val) { - warnx("%s: no default %s", fname, msg); - return -1; - } - if (val > MAXU16) { - warnx("%s: illegal %s %d", fname, msg, val); - return -1; - } - return 0; -} - -/* - * Check a volume label. - */ -static int -oklabel(const char *src) -{ - int c, i; - - for (i = 0; i <= 11; i++) { - c = (u_char)*src++; - if (c < ' ' + !i || strchr("\"*+,./:;<=>?[\\]|", c)) - break; - } - return i && !c; -} - -/* - * Make a volume label. - */ -static void -mklabel(u_int8_t *dest, const char *src) -{ - int c, i; - - for (i = 0; i < 11; i++) { - c = *src ? toupper(*src++) : ' '; - *dest++ = !i && c == '\xe5' ? 5 : c; - } -} - -/* - * Copy string, padding with spaces. - */ -static void -setstr(u_int8_t *dest, const char *src, size_t len) -{ - while (len--) - *dest++ = *src ? *src++ : ' '; -} - -static void -infohandler(int sig /* __unused */) -{ - - got_siginfo = 1; -} diff --git a/mkfs_msdos.h b/mkfs_msdos.h deleted file mode 100644 index b5e1a19..0000000 --- a/mkfs_msdos.h +++ /dev/null @@ -1,75 +0,0 @@ -/* $FreeBSD$ */ -/* $NetBSD: mkfs_msdos.h,v 1.3 2015/10/16 17:38:17 christos Exp $ */ - -/*- - * Copyright (c) 2013 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Christos Zoulas. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include "mkfs_define.h" - -#define ALLOPTS \ -AOPT('@', off_t, offset, 0, "Offset in device") \ -AOPT('A', bool, align, -2, "Attempt to cluster align root directory") \ -AOPT('B', const char *, bootstrap, -1, "Bootstrap file") \ -AOPT('C', off_t, create_size, 0, "Create file") \ -AOPT('F', uint8_t, fat_type, 12, "FAT type (12, 16, or 32)") \ -AOPT('I', uint32_t, volume_id, 0, "Volume ID") \ -AOPT('L', const char *, volume_label, -1, "Volume Label") \ -AOPT('N', bool, no_create, -2, "Don't create filesystem, print params only") \ -AOPT('O', const char *, OEM_string, -1, "OEM string") \ -AOPT('S', uint16_t, bytes_per_sector, 1, "Bytes per sector") \ -AOPT('T', time_t, timestamp, 0, "Timestamp") \ -AOPT('a', uint32_t, sectors_per_fat, 1, "Sectors per FAT") \ -AOPT('b', uint32_t, block_size, 1, "Block size") \ -AOPT('c', uint8_t, sectors_per_cluster, 1, "Sectors per cluster") \ -AOPT('e', uint16_t, directory_entries, 1, "Directory entries") \ -AOPT('f', const char *, floppy, -1, "Standard format floppies (160,180,320,360,640,720,1200,1232,1440,2880)") \ -AOPT('h', uint16_t, drive_heads, 1, "Drive heads") \ -AOPT('i', uint16_t, info_sector, 1, "Info sector") \ -AOPT('k', uint16_t, backup_sector, 1, "Backup sector") \ -AOPT('m', uint8_t, media_descriptor, 0, "Media descriptor") \ -AOPT('n', uint8_t, num_FAT, 1, "Number of FATs") \ -AOPT('o', uint32_t, hidden_sectors, 0, "Hidden sectors") \ -AOPT('r', uint16_t, reserved_sectors, 1, "Reserved sectors") \ -AOPT('s', uint32_t, size, 1, "File System size") \ -AOPT('u', uint16_t, sectors_per_track, 1, "Sectors per track") - -struct msdos_options { -#define AOPT(_opt, _type, _name, _min, _desc) _type _name; -ALLOPTS -#undef AOPT - uint32_t timestamp_set:1; - uint32_t volume_id_set:1; - uint32_t media_descriptor_set:1; - uint32_t hidden_sectors_set:1; -}; - -int mkfs_msdos(const char *, const char *, const struct msdos_options *); diff --git a/newfs_msdos.8 b/newfs_msdos.8 deleted file mode 100644 index 0cdd384..0000000 --- a/newfs_msdos.8 +++ /dev/null @@ -1,251 +0,0 @@ -.\" Copyright (c) 1998 Robert Nordier -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in -.\" the documentation and/or other materials provided with the -.\" distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS -.\" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY -.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -.\" GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER -.\" IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd June 14, 2018 -.Dt NEWFS_MSDOS 8 -.Os -.Sh NAME -.Nm newfs_msdos -.Nd construct a new MS-DOS (FAT) file system -.Sh SYNOPSIS -.Nm -.Op Fl N -.Op Fl @ Ar offset -.Op Fl A -.Op Fl B Ar boot -.Op Fl C Ar create-size -.Op Fl F Ar FAT-type -.Op Fl I Ar VolumeID -.Op Fl L Ar label -.Op Fl O Ar OEM -.Op Fl S Ar sector-size -.Op Fl T Ar timestamp -.Op Fl a Ar FAT-size -.Op Fl b Ar block-size -.Op Fl c Ar cluster-size -.Op Fl e Ar DirEnts -.Op Fl f Ar format -.Op Fl h Ar heads -.Op Fl i Ar info -.Op Fl k Ar backup -.Op Fl m Ar media -.Op Fl n Ar FATs -.Op Fl o Ar hidden -.Op Fl r Ar reserved -.Op Fl s Ar total -.Op Fl u Ar track-size -.Ar special -.Op Ar disktype -.Sh DESCRIPTION -The -.Nm -utility creates a FAT12, FAT16, or FAT32 file system on device or file named -.Ar special , -using -.Xr disktab 5 -entry -.Ar disktype -to determine geometry, if required. -.Pp -If -.Ar special -does not contain a -.Ar / -and -.Fl C -is not used, it is assumed to be a device name and -.Ar /dev/ -is prepended to the name to construct the actual device name. -To work a file in the current directory use -.Ar ./filename -.Pp -The options are as follow: -.Bl -tag -width indent -.It Fl N -Do not create a file system: just print out parameters. -.It Fl @ Ar offset -Build the filesystem at the specified offset in bytes in the device or file. -A suffix s, k, m, g (lower or upper case) -appended to the offset specifies that the -number is in sectors, kilobytes, megabytes or gigabytes, respectively. -.It Fl A -Attempt to cluster align root directory, useful for SD card. -.It Fl B Ar boot -Get bootstrap from file. -.It Fl C Ar create-size -Create the image file with the specified size. -A suffix character appended to the size is interpreted as for the -.Fl @ -option. -The file is created by truncating any existing file with the same name and -resizing it to the requested size. -If the file system supports sparse files, the space occupied on disk may be -smaller than the size specified as parameter. -.It Fl F Ar FAT-type -FAT type (one of 12, 16, or 32). -.It Fl I Ar VolumeID -Volume ID, a 32 bit number in decimal or hexadecimal (0x...) format. -.It Fl L Ar label -Volume label (up to 11 characters). -The label should consist of -only those characters permitted in regular DOS (8+3) filenames. -.It Fl O Ar OEM -OEM string (up to 8 characters). -The default is -.Qq Li "BSD4.4 " . -.It Fl S Ar sector-size -Number of bytes per sector. -Acceptable values are powers of 2 -in the range 512 through 32768, inclusive. -.It Fl T Ar timestamp -Create the filesystem as though the current time is -.Ar timestamp . -The default filesystem volume ID is derived from the time. -.Ar timestamp -can be a pathname (where the timestamp is derived from -that file) or an integer value interpreted -as the number of seconds since the Epoch. -.It Fl a Ar FAT-size -Number of sectors per FAT. -.It Fl b Ar block-size -File system block size (bytes per cluster). -This should resolve to an -acceptable number of sectors per cluster (see below). -.It Fl c Ar cluster-size -Sectors per cluster. -Acceptable values are powers of 2 in the range -1 through 128. -If the block or cluster size are not specified, the code -uses a cluster between 512 bytes and 32K depending on -the filesystem size. -.It Fl e Ar DirEnts -Number of root directory entries (FAT12 and FAT16 only). -.It Fl f Ar format -Specify a standard (floppy disk) format. -The standard formats -are (capacities in kilobytes): 160, 180, 320, 360, 640, 720, 1200, -1232, 1440, 2880. -.It Fl h Ar heads -Number of drive heads. -.It Fl i Ar info -Location of the file system info sector (FAT32 only). -A value of 0xffff signifies no info sector. -.It Fl k Ar backup -Location of the backup boot sector (FAT32 only). -A value -of 0xffff signifies no backup sector. -.It Fl m Ar media -Media descriptor (acceptable range 0xf0 to 0xff). -.It Fl n Ar FATs -Number of FATs. -Acceptable values are 1 to 16 inclusive. -The default -is 2. -.It Fl o Ar hidden -Number of hidden sectors. -.It Fl r Ar reserved -Number of reserved sectors. -.It Fl s Ar total -File system size. -.It Fl u Ar track-size -Number of sectors per track. -.El -.Sh NOTES -If some parameters (e.g., size, number of sectors, etc.) are not specified -through options or disktype, the program tries to generate them automatically. -In particular, the size is determined as the device or file size minus the -offset specified with the -.Fl @ -option. -When the geometry is not available, it is assumed to be 63 sectors, 255 heads. -The size is then rounded to become a multiple of the track size and avoid -complaints by some filesystem code. -.Pp -FAT file system parameters occupy a "Boot Sector BPB (BIOS Parameter -Block)" in the first of the "reserved" sectors which precede the actual -file system. -For reference purposes, this structure is presented -below. -.Bd -literal -struct bsbpb { - uint16_t bpbBytesPerSec; /* [-S] bytes per sector */ - uint8_t bpbSecPerClust; /* [-c] sectors per cluster */ - uint16_t bpbResSectors; /* [-r] reserved sectors */ - uint8_t bpbFATs; /* [-n] number of FATs */ - uint16_t bpbRootDirEnts; /* [-e] root directory entries */ - uint16_t bpbSectors; /* [-s] total sectors */ - uint8_t bpbMedia; /* [-m] media descriptor */ - uint16_t bpbFATsecs; /* [-a] sectors per FAT */ - uint16_t bpbSecPerTrack; /* [-u] sectors per track */ - uint16_t bpbHeads; /* [-h] drive heads */ - uint32_t bpbHiddenSecs; /* [-o] hidden sectors */ - uint32_t bpbHugeSectors; /* [-s] big total sectors */ -}; -/* FAT32 extensions */ -struct bsxbpb { - uint32_t bpbBigFATsecs; /* [-a] big sectors per FAT */ - uint16_t bpbExtFlags; /* control flags */ - uint16_t bpbFSVers; /* file system version */ - uint32_t bpbRootClust; /* root directory start cluster */ - uint16_t bpbFSInfo; /* [-i] file system info sector */ - uint16_t bpbBackup; /* [-k] backup boot sector */ -}; -.Ed -.Sh LIMITATION -The maximum file size is 4GB, even if the file system itself is bigger. -.Sh EXIT STATUS -Exit status is 0 on success and 1 on error. -.Sh EXAMPLES -Create a file system, using default parameters, on -.Pa /dev/ada0s1 : -.Bd -literal -offset indent -newfs_msdos /dev/ada0s1 -.Ed -.Pp -Create a standard 1.44M file system, with volume label -.Ar foo , -on -.Pa /dev/fd0 : -.Bd -literal -offset indent -newfs_msdos -f 1440 -L foo fd0 -.Ed -.Pp -Create a 30MB image file, with the FAT partition starting -63 sectors within the image file: -.Bd -literal -offset indent -newfs_msdos -C 30M -@63s ./somefile -.Ed -.Sh SEE ALSO -.Xr gpart 8 , -.Xr newfs 8 -.Sh HISTORY -The -.Nm -utility first appeared in -.Fx 3.0 . -.Sh AUTHORS -.An Robert Nordier Aq Mt rnordier@FreeBSD.org diff --git a/newfs_msdos.c b/newfs_msdos.c deleted file mode 100644 index 731bffd..0000000 --- a/newfs_msdos.c +++ /dev/null @@ -1,281 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 1998 Robert Nordier - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "mkfs_msdos.h" - -#define argto1(arg, lo, msg) argtou(arg, lo, 0xff, msg) -#define argto2(arg, lo, msg) argtou(arg, lo, 0xffff, msg) -#define argto4(arg, lo, msg) argtou(arg, lo, 0xffffffff, msg) -#define argtox(arg, lo, msg) argtou(arg, lo, UINT_MAX, msg) - -static u_int argtou(const char *, u_int, u_int, const char *); -static off_t argtooff(const char *, const char *); -static void usage(void); - -static time_t -get_tstamp(const char *b) -{ - struct stat st; - char *eb; - long long l; - - if (stat(b, &st) != -1) - return (time_t)st.st_mtime; - - errno = 0; - l = strtoll(b, &eb, 0); - if (b == eb || *eb || errno) - errx(EXIT_FAILURE, "Can't parse timestamp '%s'", b); - return (time_t)l; -} - -/* - * Construct a FAT12, FAT16, or FAT32 file system. - */ -int -main(int argc, char *argv[]) -{ - static const char opts[] = "@:NAB:C:F:I:L:O:S:a:b:c:e:f:h:i:k:m:n:o:r:s:T:u:"; - struct msdos_options o; - const char *fname, *dtype; - char buf[MAXPATHLEN]; - int ch; - - memset(&o, 0, sizeof(o)); - - while ((ch = getopt(argc, argv, opts)) != -1) - switch (ch) { - case '@': - o.offset = argtooff(optarg, "offset"); - break; - case 'N': - o.no_create = 1; - break; - case 'A': - o.align = true; - break; - case 'B': - o.bootstrap = optarg; - break; - case 'C': - o.create_size = argtooff(optarg, "create size"); - break; - case 'F': - if (strcmp(optarg, "12") && - strcmp(optarg, "16") && - strcmp(optarg, "32")) - errx(1, "%s: bad FAT type", optarg); - o.fat_type = atoi(optarg); - break; - case 'I': - o.volume_id = argto4(optarg, 0, "volume ID"); - o.volume_id_set = 1; - break; - case 'L': - o.volume_label = optarg; - break; - case 'O': - o.OEM_string = optarg; - break; - case 'S': - o.bytes_per_sector = argto2(optarg, 1, "bytes/sector"); - break; - case 'a': - o.sectors_per_fat = argto4(optarg, 1, "sectors/FAT"); - break; - case 'b': - o.block_size = argtox(optarg, 1, "block size"); - o.sectors_per_cluster = 0; - break; - case 'c': - o.sectors_per_cluster = argto1(optarg, 1, "sectors/cluster"); - o.block_size = 0; - break; - case 'e': - o.directory_entries = argto2(optarg, 1, "directory entries"); - break; - case 'f': - o.floppy = optarg; - break; - case 'h': - o.drive_heads = argto2(optarg, 1, "drive heads"); - break; - case 'i': - o.info_sector = argto2(optarg, 1, "info sector"); - break; - case 'k': - o.backup_sector = argto2(optarg, 1, "backup sector"); - break; - case 'm': - o.media_descriptor = argto1(optarg, 0, "media descriptor"); - o.media_descriptor_set = 1; - break; - case 'n': - o.num_FAT = argto1(optarg, 1, "number of FATs"); - break; - case 'o': - o.hidden_sectors = argto4(optarg, 0, "hidden sectors"); - o.hidden_sectors_set = 1; - break; - case 'r': - o.reserved_sectors = argto2(optarg, 1, "reserved sectors"); - break; - case 's': - o.size = argto4(optarg, 1, "file system size"); - break; - case 'T': - o.timestamp_set = 1; - o.timestamp = get_tstamp(optarg); - break; - case 'u': - o.sectors_per_track = argto2(optarg, 1, "sectors/track"); - break; - default: - usage(); - } - argc -= optind; - argv += optind; - if (argc < 1 || argc > 2) - usage(); - if (o.align) { - if (o.reserved_sectors) - errx(1, "align (-A) is incompatible with -r"); - } - fname = *argv++; - if (!o.create_size && !strchr(fname, '/')) { - snprintf(buf, sizeof(buf), "%s%s", _PATH_DEV, fname); - fname = buf; - } - dtype = *argv; - exit(!!mkfs_msdos(fname, dtype, &o)); -} - -/* - * Convert and check a numeric option argument. - */ -static u_int -argtou(const char *arg, u_int lo, u_int hi, const char *msg) -{ - char *s; - u_long x; - - errno = 0; - x = strtoul(arg, &s, 0); - if (errno || !*arg || *s || x < lo || x > hi) - errx(1, "%s: bad %s", arg, msg); - return x; -} - -/* - * Same for off_t, with optional skmgpP suffix - */ -static off_t -argtooff(const char *arg, const char *msg) -{ - char *s; - off_t x; - - errno = 0; - x = strtoll(arg, &s, 0); - /* allow at most one extra char */ - if (errno || x < 0 || (s[0] && s[1]) ) - errx(1, "%s: bad %s", arg, msg); - if (*s) { /* the extra char is the multiplier */ - switch (*s) { - default: - errx(1, "%s: bad %s", arg, msg); - /* notreached */ - - case 's': /* sector */ - case 'S': - x <<= 9; /* times 512 */ - break; - - case 'k': /* kilobyte */ - case 'K': - x <<= 10; /* times 1024 */ - break; - - case 'm': /* megabyte */ - case 'M': - x <<= 20; /* times 1024*1024 */ - break; - - case 'g': /* gigabyte */ - case 'G': - x <<= 30; /* times 1024*1024*1024 */ - break; - - case 'p': /* partition start */ - case 'P': - case 'l': /* partition length */ - case 'L': - errx(1, "%s: not supported yet %s", arg, msg); - /* notreached */ - } - } - return x; -} - -/* - * Print usage message. - */ -static void -usage(void) -{ - fprintf(stderr, - "usage: [ -options ] special [disktype]\n"); - fprintf(stderr, "where the options are:\n"); -static struct { - char o; - const char *h; -} opts[] = { -#define AOPT(_opt, _type, _name, _min, _desc) { _opt, _desc }, -ALLOPTS -#undef AOPT - }; - for (size_t i = 0; i < nitems(opts); i++) - fprintf(stderr, "\t-%c %s\n", opts[i].o, opts[i].h); - exit(1); -}