diff options
Diffstat (limited to 'dosfstools')
49 files changed, 13016 insertions, 0 deletions
diff --git a/dosfstools/Android.mk b/dosfstools/Android.mk new file mode 100644 index 000000000..7b6d62349 --- /dev/null +++ b/dosfstools/Android.mk @@ -0,0 +1,58 @@ +ifneq ($(TARGET_SIMULATOR),true) +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_SRC_FILES := \ + src/boot.c \ + src/check.c \ + src/common.c \ + src/fat.c \ + src/file.c \ + src/io.c \ + src/lfn.c \ + src/fsck.fat.c + +LOCAL_SHARED_LIBRARIES := libc +LOCAL_CFLAGS += -D_USING_BIONIC_ +LOCAL_CFLAGS += -DUSE_ANDROID_RETVALS +LOCAL_CFLAGS += -Wno-sign-compare +LOCAL_MODULE = fsck.fat +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES +LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin +include $(BUILD_EXECUTABLE) + +include $(CLEAR_VARS) +LOCAL_SRC_FILES := \ + src/boot.c \ + src/check.c \ + src/common.c \ + src/fat.c \ + src/file.c \ + src/io.c \ + src/lfn.c \ + src/fatlabel.c + +LOCAL_C_INCLUDES += bionic/libc/kernel/common +LOCAL_SHARED_LIBRARIES := libc +LOCAL_CFLAGS += -D_USING_BIONIC_ +LOCAL_CFLAGS += -Wno-sign-compare +LOCAL_MODULE = fatlabel +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES +LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin +include $(BUILD_EXECUTABLE) + +include $(CLEAR_VARS) +LOCAL_SRC_FILES := src/mkfs.fat.c + +LOCAL_SHARED_LIBRARIES := libc +LOCAL_CFLAGS += -D_USING_BIONIC_ +LOCAL_CFLAGS += -Wno-sign-compare +LOCAL_MODULE = mkfs.fat +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES +LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin +include $(BUILD_EXECUTABLE) + +endif diff --git a/dosfstools/COPYING b/dosfstools/COPYING new file mode 100644 index 000000000..94a9ed024 --- /dev/null +++ b/dosfstools/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/dosfstools/ChangeLog b/dosfstools/ChangeLog new file mode 100644 index 000000000..f6a1e3da9 --- /dev/null +++ b/dosfstools/ChangeLog @@ -0,0 +1,2096 @@ +commit ad1342e +Author: Andreas Bombe <aeb@debian.org> +Date: Sat May 16 02:10:18 2015 +0200 + + manpages: Mark MT and ME tags as untranslated for po4a + + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit 3ed9ec2 +Author: Andreas Bombe <aeb@debian.org> +Date: Sun May 10 19:59:02 2015 +0200 + + mkfs: Small changes to FAT32 cluster size selection + + Put the cluster size selection back in line with the table used in + Microsoft's fatgen103.pdf and fix the comment. This only involved + changing some comparison operators, all values stayed the same. + + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit 9984552 +Author: Andreas Bombe <aeb@debian.org> +Date: Mon Apr 20 23:41:34 2015 +0200 + + fsck: Mention -r is default in usage message + + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit 3eaca68 +Author: Andreas Bombe <aeb@debian.org> +Date: Mon Apr 20 23:30:56 2015 +0200 + + manpages: Remove obsolete information about Linux FAT support + + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit a5e34de +Author: Andreas Bombe <aeb@debian.org> +Date: Thu Apr 16 23:16:08 2015 +0200 + + manpages: Convert the rest of argument placeholders to upper case + + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit 2303765 +Author: Andreas Bombe <aeb@debian.org> +Date: Thu Apr 16 22:51:20 2015 +0200 + + manpages: Fix formatting + + Make the manpages conform to the rules for groff sources. First, + eliminate empty lines because these create vertical spaces where it + isn't desired. Man page sources should not contain empty lines. Second, + put a line break between sentences in a paragraph. A period is + recognized and formatted as a full stop period only when a line break + comes right after it. + + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit d3969b8 +Author: Andreas Bombe <aeb@debian.org> +Date: Fri Apr 10 20:32:50 2015 +0200 + + fsck: Verify first cluster of a file is not 1 + + Previously the FAT was checked for any out of bounds entries which were + cleared. However the first cluster of a file, as specified in its + directory entry, was not verified to not be 1. + + In addition to missing this filesystem error, code that correctly + assumes the FAT contained no bad entries anymore could still look up + invalid table indices depending on the value stored in entry 1. With + the right values and FAT size this can lead to a segfault by accessing + unallocated memory. + + Now test_file() will ignore files where the first cluster equals 1 and + an additional check in check_file() will truncate them. + + This bug was reported in http://bugs.debian.org/773885 by Jakub Wilk. + + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit 2a56575 +Author: Andreas Bombe <aeb@debian.org> +Date: Thu Apr 2 23:35:00 2015 +0200 + + Simplify synopses of man pages + + Since there is only one mode of invocation for the tools, it is + somewhat pointless to list every possible option in the synopsis. + + Fix a few style inconsistencies in addition, specifically that + placeholders for option arguments are in capital letters and should be + shown where the option is described. + + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit 40f1436 +Author: Andreas Bombe <aeb@debian.org> +Date: Wed Apr 1 20:55:58 2015 +0200 + + Update homepage and maintainer sections of man pages + + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit 0169db8 +Author: Andreas Bombe <aeb@debian.org> +Date: Wed Apr 1 20:05:01 2015 +0200 + + mkfs: Show a clearer message that file already exists with -C + + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit 2967e27 +Author: Andreas Bombe <aeb@debian.org> +Date: Mon Mar 30 21:12:51 2015 +0200 + + mkfs: Remove O_TRUNC from file creation call + + open() is called with O_EXCL | O_CREAT, so it will definitely create a + new, empty file or error out. O_TRUNC is superfluous and may be harmless + in practice but its effect under these circumstances is unspecified. + + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit 90612df +Author: Andreas Bombe <aeb@debian.org> +Date: Mon Mar 30 21:09:51 2015 +0200 + + mkfs: Use ftruncate() for expanding created file + + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit 58e8e09 +Author: Andreas Bombe <aeb@debian.org> +Date: Tue Mar 24 21:32:40 2015 +0100 + + mkfs: Add --invariant option + + The --invariant option is designed to prevent random or time based + differences to end up in generated filesystems so that multiple runs + generate on the same file or device create completely identical results. + + This is intended for debugging or regression testing of mkfs.fat. + + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit 354feaf +Author: Andreas Bombe <aeb@debian.org> +Date: Thu Mar 19 21:35:21 2015 +0100 + + mkfs: Add long option parsing + + Add long option parsing with getopt_long() to mkfs and define --help as + the first long option. The usage() function now takes an exit code + parameter so that the --help option handling can exit the program with + a success exit code. + + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit b611549 +Author: Andreas Bombe <aeb@debian.org> +Date: Mon Mar 16 21:08:35 2015 +0100 + + Do not expect EOF as return value of getopt() + + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit a41fc32 +Author: Andreas Bombe <aeb@debian.org> +Date: Wed Mar 11 21:45:04 2015 +0100 + + fsck.fat: Fix read beyond end of array on FAT12 + + When a FAT12 filesystem contains an odd number of clusters, setting the + last cluster with set_fat() will trigger a read of the next entry, + which does not exist in the fat array allocated for this. + + Round up the allocation to an even number of FAT entries for FAT12 so + that this is fixed without introducing special casing in get_fat(). + + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit e18d72f +Author: Álvaro Fernández Rojas <noltari@gmail.com> +Date: Sat Mar 7 13:23:23 2015 +0100 + + Remove linux/msdos_fs.h includes + + Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com> + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit 245d0cc +Author: Álvaro Fernández Rojas <noltari@gmail.com> +Date: Thu Feb 26 19:22:54 2015 +0100 + + Remove non standard int types + + Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com> + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit 628b3ec +Author: Álvaro Fernández Rojas <noltari@gmail.com> +Date: Thu Feb 26 19:41:19 2015 +0100 + + Improve .gitignore + + Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com> + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit 02b5a6d +Author: Álvaro Fernández Rojas <noltari@gmail.com> +Date: Thu Feb 26 12:51:23 2015 +0100 + + Makefile: avoid using install -D + + OS X and FreeBSD are not compatible with this option + + Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com> + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit fb6aea6 +Author: Álvaro Fernández Rojas <noltari@gmail.com> +Date: Thu Feb 26 12:50:57 2015 +0100 + + Makefile: fix typo in uninstall-man + + Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com> + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit 357ab07 +Author: Andreas Bombe <aeb@debian.org> +Date: Thu Feb 19 21:22:54 2015 +0100 + + fsck.fat: Make -r option default + + Default mode is now to interactively repair with the option to write + the changes back at the end (like the -r option) instead of the previous + default mode of interactively correcting but never writing back the + changes. + + The -r option continues to be recognized by fsck.fat. + + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit 266a5fc +Author: Andreas Bombe <aeb@debian.org> +Date: Fri Feb 20 03:19:28 2015 +0100 + + mkfs.fat: Allow 0xF0 to be specified as media byte + + Let the -M option accept 0xF0, which should be the proper descriptor + byte for 3.5" 1.44 MB and 2.88 MB floppies. + + Also split the error reporting for -M between badly formatted and + invalid numbers. + + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit 16e97e9 +Author: Andreas Bombe <aeb@debian.org> +Date: Wed Jan 28 15:07:18 2015 +0100 + + Make all char* that may take literals const + + Every char* variable or function argument that may be given a literal + string is now made const. Additionally add -Wwrite-strings to CFLAGS to + enable a warning where const would be missing. + + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit 8b8948c +Author: Andreas Bombe <aeb@debian.org> +Date: Mon Dec 29 18:24:54 2014 +0100 + + mkfs.fat.c: Use unsigned char for binary data + + Simple char technically works for the dummy_boot_jump variables, but + some compiler warning settings would give a warning over a signed char + overflowing with the values given as initializers. + + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit 45aeed0 +Author: Andreas Bombe <aeb@debian.org> +Date: Sun Nov 16 19:49:22 2014 +0100 + + Fix indentation of "fix power loss damage" commit + + I fixed the (sometimes misleading) indentation of the code introduced in + commit 6893c45 to be in line with the reset of the code and also removed + the /* PATCH ED+DL */ comments which are quite meaningless to the wider + world. + + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit 75c5446 +Author: Andreas Bombe <aeb@debian.org> +Date: Sat Nov 15 16:48:48 2014 +0100 + + Add tags and editor backup files to .gitignore + + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit cb98ae2 (tag: v3.0.27) +Author: Andreas Bombe <aeb@debian.org> +Date: Wed Nov 12 01:10:23 2014 +0100 + + Releasing version 3.0.27. + + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit e2c8f06 +Author: Andreas Bombe <aeb@debian.org> +Date: Wed Nov 12 00:22:17 2014 +0100 + + fsck.fat: Don't print version string every time -v is encountered + + Remove the printing of the version string every time -v is seen during + command line parsing in fsck.fat. The version string is printed anyway + before opening the filesystem device/image. + + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit 82076b6 +Author: Andreas Bombe <aeb@debian.org> +Date: Tue Nov 11 23:25:30 2014 +0100 + + Fix attempt to rename root dir in fsck due to uninitialized fields + + When add_file() is called with offset 0, it will construct a DIR_ENT for + the root directory instead of reading the contents from the filesystem. + It did not initialize the whole DIR_ENT on the stack, just select + values. + + In particular, the lcase field was left with an undefined value. If + that value happened to include the FAT_NO_83NAME bit, the "neither long + nor short file name" check in bad_name() added in 3.0.26 would trigger + and cause an attempt to rename the entry (which is not possible). + Example run: + + $ /sbin/fsck.fat -y bad.img + fsck.fat 3.0.26 (2014-03-07) + / + Bad short file name (). + Auto-renaming it. + Renamed to + bad.img: 14 files, 19388/403266 clusters + + This commit changes the initialization zeroize the whole struct before + setting individual fields. Thanks to AlexisM, who found the cause and + posted a patch on the Debian bug http://bugs.debian.org/764992 . + + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit c24ecb6 +Author: Andreas Bombe <aeb@debian.org> +Date: Tue Nov 11 22:49:50 2014 +0100 + + Support long file names in volume labeling code + + The code to find the volume label directory entry in find_volume_de() + did not consider long file names so far. Directory entries that make up + long file names have four attribute bits set, including the "volume" + bit. + + This caused the code to mistake a directory entry that is part of a + long file name as the volume name entry. If such an entry is found + first, fatlabel would print garbage when asked to display the label and + mangle the long file name when asked to set it. The latter would lead + to the loss of the long file name and require a fsck to clean up. + + Change so that the set of attributes equal that of LFN entries will no + langer match as a volume label. + + Signed-off-by: Andreas Bombe <aeb@debian.org> + +commit 1646f6e (tag: v3.0.26) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Mar 7 18:40:13 2014 +0100 + + Releasing version 3.0.26. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 6893c45 +Author: Dir Lotter <dirk.lotter@siemens.com> +Date: Fri Mar 7 18:25:39 2014 +0100 + + Fix "odd" files created by frequent power-loss. + + After running many power losses the filesystem can degrate, containing "odd" + files making the filesystem corrupt that could not be solved by fsck: + + * file was not visible in a ls -l + * ls -i reported a "invalid file name" on the console + * a test program with diropen/dirread showed the file, a stat on this file + failed + * file was not accessible and could not be deleted + + After digging into the code we found why fsck didn't repair the file system: + One thing was we don't have short filenames. Another issue was that the LFN + pointer was set to NULL and so it looked like we didn't have short and long + filenames. + + Our patch of check.c includes: + + * returns 1 from function bad_name() in case no short and no long filename + exist + * auto_rename() and rename_file() got a special handling for the case no short + file name exist: + - it enables the short file name (we think here was a weakness of the old + code: it changed the short filename but didn't enabled it in the + file->dir_ent.lcase entry) + - it reset all attributes except ATTR_DIR and ATTR_VOLUME + + This solved our problem pretty well. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 621e11f +Author: Natanael Copa <ncopa@alpinelinux.org> +Date: Sat Feb 8 18:53:30 2014 +0100 + + Build fixes for musl libc. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 52588b7 (tag: v3.0.25) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Jan 17 07:11:11 2014 +0100 + + Releasing version 3.0.25. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit acf64ae +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Jan 17 07:09:54 2014 +0100 + + Updating copyright headers for 2014. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 21fe921 +Author: Andrew Tridgell <tridge@samba.org> +Date: Tue Jan 14 09:37:51 2014 +1100 + + Fixed remaining 64 bit build warnings. + + Some of these may be real bugs. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 9e3a2b1 +Author: Andrew Tridgell <tridge@samba.org> +Date: Tue Jan 14 09:25:28 2014 +1100 + + Prevent corruption of FAT during fsck on 64 bit platforms. + + unsigned long is 64 bit on x86-64, which means set_fat was writing two + entries, which corrupts the next entry. This can cause loss of data in + another file. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 0d2c9bc (tag: v3.0.24) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Sat Nov 23 10:36:55 2013 +0100 + + Releasing version 3.0.24. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 55bd7b7 +Author: Jaroslav Skarvada <jskarvad@redhat.com> +Date: Sat Nov 23 10:34:48 2013 +0100 + + Fixed dosfsck on big endian platforms (Resolves: rhbz#1029695). + + It seems there is problem in the double conversion on big endians. + The first conversion is done by the explicit conversion to __u16 + in the GET_UNALIGNED_W macro, so the secondary conversion by le16toh + seems to be redundant (and wrong). + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 6debb4a (tag: v3.0.23) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Tue Oct 15 08:05:46 2013 +0200 + + Releasing version 3.0.23. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 07d85ff +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Tue Oct 15 08:04:11 2013 +0200 + + Reformating mkfs.fat manpage. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 137552f +Author: Michael Shigorin <mike@altlinux.org> +Date: Tue Oct 15 01:29:33 2013 +0400 + + Fixing "Fixing default sectors per cluster for FAT32" for UEFI. + + FAT32 "EFI System Partition" is basically required for UEFI boot; + commit ge048a8d broke that for me with both virtualbox-4.2 and + real hardware (ASUS C60M1-I to be exact) given ~250Mb filesystem. + + This commit amends that one by reverting its effects for these + small sizes by restoring 512b cluster size for <= 260Mb FAT32. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 2000696 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Aug 9 09:38:13 2013 +0200 + + Also allowing lowercase labels in mkfs (with warning message) consistent with the recent fsck change, thanks to Michael Baum <mbaum@devonit.com>. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 9b04807 +Author: Tim Harder <radhermit@gentoo.org> +Date: Fri Jul 19 18:15:21 2013 +0200 + + Add install-man dependency to install-symlinks Makefile target. + + This fixes a race condition during parallel installs where man page + symlinks won't be installed because install-man hasn't been run yet. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 651f91c (tag: v3.0.22) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Jul 19 07:01:19 2013 +0200 + + Releasing version 3.0.22. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 3dc5560 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Jul 19 06:55:24 2013 +0200 + + Addding install-symlinks target to phony targets in Makefile. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit c6c0581 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Jul 19 06:55:00 2013 +0200 + + Adding uninstall-symlinks target in Makefile. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 465dd8c +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Jul 19 06:45:40 2013 +0200 + + Allowing fatlabel to write labels in all lowercase but give a warning about DOS/Windows (Closes: #714971). + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 3621b30 +Author: John S Gruber <JohnSGruber@gmail.com> +Date: Fri Jul 19 06:40:21 2013 +0200 + + Add options and make dos boot sector more compatible with reference system (Closes: #552673). + + Unless overridden by the user sets the DOS boot sector's + hidden-sectors field to match the start of a hard disk's + partition. + + Initialize DOS boot sector drive_number according to FAT media type + Addresses LP: #398241 and Debian #552673 + + Adds options to override the DOS boot sector device_number and + the FAT media type. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit be1eed5 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Wed Jul 17 12:52:20 2013 +0200 + + Correcting wrong check preventing installation of fatlabel legacy manpage symlink. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit d0065d3 (tag: v3.0.21) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Tue Jul 16 08:34:28 2013 +0200 + + Releasing version 3.0.21. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit a74c12c +Author: Jaroslav Skarvada <jskarvad@redhat.com> +Date: Tue Jun 25 14:53:14 2013 +0200 + + Adding the missing -p option to the fsck manpage (to be consistent with the output of the tool). + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 25e03c9 +Author: Patrick J. Volkerding <volkerdi@slackware.com> +Date: Mon Jun 24 14:23:00 2013 +0200 + + Using $MANDIR instead of hardcoded ${PREFIX}/share/man in the Makefile. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 7fd9cf7 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Jun 14 18:50:31 2013 +0200 + + Making install-symlinks Makefile target depend on install-bin to not break when using make in parallel, thanks to David Walser <luigiwalser@yahoo.com>. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit a76bbcd +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Wed Jun 12 13:00:10 2013 +0200 + + Using US digit date format in version date, rather than name abbrev. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit a64195f (tag: v3.0.20) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Wed Jun 12 12:25:32 2013 +0200 + + Releasing version 3.0.20. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 1a5d99f +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Wed Jun 12 12:07:58 2013 +0200 + + Softening message about different boot sectors a bit (Closes: #704198). + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 4727286 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Wed Jun 12 11:42:52 2013 +0200 + + Harmonizing program name output. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 17c956c +Author: Martin Wilck <mwilck@arcor.de> +Date: Wed Jun 12 11:38:00 2013 +0200 + + Don't align FAT to cluster size. + + See previous patch for explanation. + + With this patch and the previous two, the + mkdosfs generated FAT32 file systems work well in my extremely + picky TechniSat device. Of course, they're also detected cleanly + by Linux and Windows. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit d63e0d6 +Author: Martin Wilck <mwilck@arcor.de> +Date: Wed Jun 12 11:36:08 2013 +0200 + + Don't align FAT32 reserved sectors to cluster size. + + For certain file system sizes (in particular, exact GB sizes - + don't ask me why) a Technisat HD S2 Plus DVB receiver will still + choke on mkdosfs generated file systems, even if the sectors per + cluster problem is fixed. + + By comparing the properties of generated FAT32 FS with results + of the Windows tool "h2format" (www.heise.de/download/h2format.html), + I found that the remaining problems were caused by rounding of the + reserved sectors and FAT space to cluster size (the h2format tool + doesn't do this). + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit e048a8d +Author: Martin Wilck <mwilck@arcor.de> +Date: Wed Jun 12 11:33:33 2013 +0200 + + Fixing default sectors per cluster for FAT32 (Closes: #690062). + + The default sectors per cluster calculated by mkdosfs are outdated, + see http://technet.microsoft.com/en-us/library/cc938438.aspx. + + The deviations may cause some 3rd party devices (e.g. TechniSat DVB + receivers) to hang when reading mkdosfs generated file systems. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 86509aa +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Tue Jun 11 20:19:09 2013 +0200 + + Splitting out legacy symlink creation in toplevel Makefile to own target. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit da37dd1 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Wed Jun 12 11:29:12 2013 +0200 + + Correcting wrong toolname in fsck.fat. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit b29a722 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Tue Jun 11 19:51:47 2013 +0200 + + Consistently spelling filesystem as filesystem, and not file system. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 977d7aa +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Tue Jun 11 19:30:19 2013 +0200 + + Removing Debian reference in GPL license headers. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 5505cc2 (tag: v3.0.19) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Tue Jun 11 18:46:03 2013 +0200 + + Releasing version 3.0.19. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 2c88f35 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Tue Jun 11 18:44:50 2013 +0200 + + Running indent on source files. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit d495d43 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Tue Jun 11 18:41:41 2013 +0200 + + Using memcpy instead of strcpy to fix segfault with fortify, thanks to Dave Reisner <falconindy@jabber.org>. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 9fb4ffc +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Sun Jun 9 13:17:16 2013 +0200 + + Correcting fsck.fat spelling error in manpages, thanks to E.J.M. Hartman <E.J.M.Hartman@tudelft.nl>. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 2d8ef9b (tag: v3.0.18) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Thu Jun 6 09:49:00 2013 +0200 + + Releasing version 3.0.18. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit d4e1180 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Thu Jun 6 09:38:45 2013 +0200 + + Adding initial i18n support for manpages with po4a. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit ea8f712 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Thu Jun 6 09:17:13 2013 +0200 + + Renaming tools to sane namespace and keeping legacy symlinks in place. + + dosfslabel becomes fatlabel, + dosfsck becomes fsck.fat, + and mkdosfs becomes mkfs.fat. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit a42b127 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Wed Jun 5 07:12:03 2013 +0200 + + Correcting wrong spelling of Debian in mkdosfs manpage. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 2749084 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Wed Jun 5 07:10:50 2013 +0200 + + Correcting spelling typo in boot.c. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 6461c83 +Author: Martin Pitt <martinpitt@gnome.org> +Date: Fri May 24 09:35:44 2013 +0200 + + dosfslabel: Do not read beyond string length (Closes: #709587). + + When checking whether the label contains any lower-case characters, do not read + beyond the end of the string. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 4203a90 (tag: v3.0.17) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Wed May 29 10:14:09 2013 +0200 + + Releasing version 3.0.17. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 3aa88ed +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Wed May 29 09:48:24 2013 +0200 + + Updating maximal lenght of a label in manpage to talk about bytes instead of characters, thanks to Francois Wendling <frwendling@gmail.com> (Closes: #655953). + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 0916f8a +Author: Jaroslav Skarvada <jskarvad@redhat.com> +Date: Wed May 29 09:56:08 2013 +0200 + + Fixing segfault in dosfslabel. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 4a265c6 +Author: James Byrne <jbyrne@aminocom.com> +Date: Mon Apr 22 12:29:51 2013 +0100 + + Allow operation on SH4 CPUs and remove compiler warnings. + + Simplify the GET_UNALIGNED_W macro and use it in all cases instead of making it + conditional on CPU types. This missed some CPUs that needed it (e.g. SH4), and + in any case the implementation caused "dereferencing type-punned pointer will + break strict-aliasing rules" warnings. + + Enable extra warnings, but disable signed comparison and missing field + initializer warnings as these are not helpful. + + Update write_boot_label() so that the boot_sector_16 and boot_sector cases are + handled separately instead of using an aliased pointer, as that causes + "dereferencing type-punned pointer will break strict-aliasing rules" warnings. + + Make date_dos2unix(), usage() and cdiv() static functions as they are only used + in the files in which they are declared. + + Update bad_name() and lfn_get() so that the extension is processed separately + instead of by indexing past the end of the name field as that causes "array + subscript is above array bounds" warnings. + + Update the dosfsck() main function to avoid a warning that free_clusters may + be used uninitialized. Do not print the final count of files and clusters when + dosfsck is run with the "-b" option because the used files and clusters have + not been counted in this case. + + Alter the setup_tables() function so that it does not cause an "array subscript + is below array bounds" warning. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit eb68a14 +Author: James Byrne <jbyrne@aminocom.com> +Date: Mon Apr 22 13:32:01 2013 +0100 + + Add a .gitignore file. + + Add a .gitignore file so that the results of compilation do not appear as + changes. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 336e8f1 +Author: James Byrne <jbyrne@aminocom.com> +Date: Mon Apr 22 12:38:52 2013 +0100 + + Finish cleanup of byteswap code. + + Commit 9ba8992 left three references to the old CT_LE_W macro. + Remove these since no conversion was needed as the value being + converted was zero. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 64b6227 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Thu Apr 4 08:08:00 2013 +0200 + + Shortening links to upstream homepage. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 76304be +Author: Cristian Rodríguez <crrodriguez@opensuse.org> +Date: Fri Mar 1 08:23:34 2013 +0100 + + Fix offsetof definition. + + * include stddef.h to get the correct offsetof definition. + * remove local offsetof definition, systems not having it on stddef.h + are in violation of C89, C99, POSIX.1-2001. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 9ba8992 +Author: Cristian Rodríguez <crrodriguez@opensuse.org> +Date: Fri Mar 1 08:58:36 2013 +0100 + + Cleanup byteswap code. + + Remove all duplicate macro definitions for byteswapping routines + and replace them for proper usage of userspace endian(3). + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 8733e12 (tag: v3.0.16) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Wed May 29 10:06:01 2013 +0200 + + Releasing version 3.0.16. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit a9fa87e +Author: Petr Gajdos <pgajdos@suse.cz> +Date: Fri Mar 1 08:34:12 2013 +0100 + + Create rootdir entry volume label with mkdosfs, create it when + it doesn't exist with dosfslabel. + + See https://bugzilla.novell.com/show_bug.cgi?id=657011#c4 + for more information. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 92057f1 +Author: Petr Gajdos <pgajdos@suse.cz> +Date: Fri Mar 1 08:33:18 2013 +0100 + + Forbid lowercase letters in label. + + See https://bugzilla.novell.com/show_bug.cgi?id=657011#c4 and + http://support.microsoft.com/kb/71715/en-us for more information. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 5e265c4 +Author: Petr Gajdos <pgajdos@suse.cz> +Date: Fri Mar 1 08:32:02 2013 +0100 + + Read label also from rootdir entry. + + See https://bugzilla.novell.com/show_bug.cgi?id=657011#c4 + for more information. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 5cec53c +Author: Petr Gajdos <pgajdos@suse.cz> +Date: Fri Mar 1 08:30:21 2013 +0100 + + alloc_rootdir_entry() is intended to be called with pattern == "FSCK%04dREC", + the old code (probably c&p from auto_rename()) doesn't reflect this. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 63938f0 +Author: Petr Gajdos <pgajdos@suse.cz> +Date: Fri Mar 1 08:29:00 2013 +0100 + + Instead of eleven blanks, fill in "NO NAME " as specification tells. + + See https://bugzilla.novell.com/show_bug.cgi?id=657011#c4 and + http://www.win.tue.nl/~aeb/linux/fs/fat/fat-1.html for more information. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 10c1c41 +Author: Petr Gajdos <pgajdos@suse.cz> +Date: Fri Mar 1 08:58:15 2013 +0100 + + Write uppercase letters in label. + + See https://bugzilla.novell.com/show_bug.cgi?id=657011#c4 and + http://support.microsoft.com/kb/71715/en-us for more information. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit a75fb1c (tag: v3.0.15) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Thu Feb 21 15:06:52 2013 +0100 + + Releasing version 3.0.15. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit c8f84fd +Author: Alexander Korolkov <alexander.korolkov@gmail.com> +Date: Mon Feb 4 00:22:34 2013 +0400 + + Using wcstombs() to convert LFN unicode characters to printable text. + + This closes Debian bug #596336. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 1546545 +Author: Alexander Korolkov <alexander.korolkov@gmail.com> +Date: Sun Sep 5 18:59:47 2010 +0400 + + Recode short filenames from DOS codepage (default 437). + + Recode short filenames from DOS codepage (default 437) to the current + character encoding. This makes messages of dosfsck more readable. + Partially closes Debian bug #596336. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit ad76cae +Author: Jaroslav Skarvada <jskarvad@redhat.com> +Date: Thu Feb 21 14:40:52 2013 +0100 + + Fixing root directory allocation. + + See https://bugzilla.redhat.com/show_bug.cgi?id=674095 for more information. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit b8201b3 +Author: Jaroslav Skarvada <jskarvad@redhat.com> +Date: Thu Feb 21 14:40:25 2013 +0100 + + Fixing device detection. + + See https://bugzilla.redhat.com/show_bug.cgi?id=710480 for more information. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 7a75638 (tag: v3.0.14) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Wed Jan 23 13:22:01 2013 +0100 + + Releasing version 3.0.14. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 5bdd7ef +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Wed Jan 23 13:16:20 2013 +0100 + + Documenting dosfsck -b in its manpage. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit a307be2 +Author: Oleksij Rempel <bug-track@fisher-privat.net> +Date: Wed Jan 23 12:36:56 2013 +0100 + + Adding option for bootsector read-only check. + + Most boot sectors may contains marker for filesystem state. We can this + bit on every mount and warn user if some thing wrong, without checking + complete filesystem. + + Signed-off-by: Oleksij Rempel <bug-track@fisher-privat.net> + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit ce2f8dc +Author: Oleksij Rempel <bug-track@fisher-privat.net> +Date: Wed Jan 23 12:35:13 2013 +0100 + + Checking boot sector for dirty bit. + + Some OSos use reseved byte of boot sector to set state of the file + system. If first bit set, then filesystem is proably damaged - write + operation was not finished/cache not snycted/... + + Signed-off-by: Oleksij Rempel <bug-track@fisher-privat.net> + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit f33ee8c +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Wed Jan 23 12:25:59 2013 +0100 + + Completing and updating all copyright headers for 2013. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit bfe6d25 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Wed Jan 23 12:17:20 2013 +0100 + + Updating my email address. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 13cdb4d (tag: v3.0.13) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Sat Jun 30 19:10:44 2012 +0200 + + Releasing version 3.0.13. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit d039482 +Author: Jaroslav Škarvada <jskarvad@redhat.com> +Date: Sat Jun 30 19:09:11 2012 +0200 + + Fix 'dosfslabel throws "Seek to 114116076544:Invalid argument" error when labeling'. + + See https://bugzilla.redhat.com/show_bug.cgi?id=693662 for more information. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit e243612 (tag: v3.0.12) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Sat Oct 29 08:40:53 2011 +0200 + + Releasing version 3.0.12. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 025b4f0 +Author: Michael Casadevall <mcasadevall@ubuntu.com> +Date: Tue Jun 7 19:19:30 2011 +0200 + + Correcting miscalculation of sector number in some cases. + + mkdosfs will incorrectly calculate the number of sectors of a + given FAT partition if the number sectors are odd due to + count_blocks incorrectly handling the remainder of a division + operation. This miscalculation causes the OMAP4 bootloader to + fail to boot. + + This bug can be observed by comparing the total sector size in + fdisk expert more to fsck.msdos; this discrepancy only shows up + when the number of sectors are odd. + + See https://bugs.launchpad.net/ubuntu/+source/dosfstools/+bug/794043 + for more information. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 91a1fb9 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Sat Jan 8 23:38:59 2011 +0100 + + Re-running Nindent. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 0390c4c +Author: Sergey Gusarov <laborer2008@gmail.com> +Date: Sat Jan 8 23:36:11 2011 +0100 + + Fixing compiler warnings related to the mismatch of types "char *" / "unsigned + char *". + + These warnings appear when you compile the project with the option "-Wall", what + is done with the current default Makefile. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 4a8f8a6 +Author: Jaroslav Skarvada <jskarvad@redhat.com> +Date: Thu Jan 6 22:35:00 2011 +0100 + + Fixing overflow bug in reclaim_file function, see + https://bugzilla.redhat.com/show_bug.cgi?id=660154 for more information. + + The problem is that alloc_rootdir_entry counts with 10000 files at max, but the + filename buffer is only 8 chars long. Due to pattern mask used it results to + only 10 files at max (FSCK0-9REC). If there is more than 10 files, it overflows + and hangs. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit e0366da +Author: Sergey Gusarov <laborer2008@gmail.com> +Date: Thu Jan 6 22:31:39 2011 +0100 + + Fixing conversion specifiers in accordance with the type of expressions. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 2d8be9c +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Sun Jan 2 15:41:44 2011 +0100 + + Indenting source files. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 697af85 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Sun Jan 2 15:39:03 2011 +0100 + + Adding Nindent script from syslinux. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 66d55cd (tag: v3.0.11) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Dec 24 17:58:29 2010 +0100 + + Releasing version 3.0.11. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit d579802 +Author: Michael Stapelberg <michael@stapelberg.de> +Date: Fri Nov 19 14:09:36 2010 +0100 + + Add better error message when the device cannot be opened. + + This is helpful for SD cards or other removable media which have an enabled + write lock -- without the "Permission denied" message, the user has to strace + mkdosfs to find out what's going on. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit bb6000f +Author: Jaroslav Skarvada <jskarvad@redhat.com> +Date: Fri Oct 8 13:38:16 2010 +0200 + + Unalign on s390x, see http://bugzilla.redhat.com/show_bug.cgi?id=624596 for + more information. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 5ef7f1f (tag: v3.0.10) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Sun Sep 12 09:35:47 2010 +0200 + + Releasing version 3.0.10. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit ea41797 +Author: Alexander Korolkov <alexander.korolkov@gmail.com> +Date: Sun Sep 12 09:29:12 2010 +0200 + + Modify LFN direntries when file is renamed or deleted, see + Debian bug #596329. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit e56ff72 +Author: Alexander Korolkov <alexander.korolkov@gmail.com> +Date: Sun Sep 12 09:27:07 2010 +0200 + + If the test of short filename fails, dosfsck could complain about + bad long filename, see Debian bug #596327. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit f0a42d0 +Author: Alexander Korolkov <alexander.korolkov@gmail.com> +Date: Sun Sep 12 09:24:47 2010 +0200 + + dosfsck: don't complain about bad filenames when short filename + contains 7 or more characters with codes 128-255, see Debian + bug #596327. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 0113c5b +Author: Mitch Rybczynski <mrybczynski@miovision.com> +Date: Mon Jul 5 14:45:54 2010 +0200 + + Adding __arm__ define check for some crosscompile toolchains. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 88cb84f +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Sun Mar 14 16:42:32 2010 +0100 + + Modernizing dosfslabel manpage. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 5aa7ec4 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Sun Mar 14 16:33:47 2010 +0100 + + Modernizing dosfsck manpage. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 807ed80 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Sun Mar 14 16:05:32 2010 +0100 + + Fixing spelling error in boot.c. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 5b6849d (tag: v3.0.9) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Sun Jan 31 08:31:32 2010 +0100 + + Releasing version 3.0.9. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 33bca7d +Author: Daniel Kahn Gillmor <dkg@fifthhorseman.net> +Date: Sun Jan 31 00:11:41 2010 -0500 + + Be sure to store the updated reserved_sector count in the boot sector, + see Debian bug #567337. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 2a3bef8 (tag: v3.0.8) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Sat Jan 23 10:16:18 2010 +0100 + + Releasing version 3.0.8. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 726c02d +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Sat Jan 23 10:15:01 2010 +0100 + + Removing some cruft in end-comments. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit a5961d7 +Author: Steven J. Magnani <steve@digidescorp.com> +Date: Thu Jan 21 16:58:11 2010 +0100 + + When compiling a 32-bit version of dosfstools on an x86_64 machine, + the resulting applications report strange errors on "large" (> 2 GiB) + partitions: + + Seek to -2118967808:Invalid argument + + Warning: Filesystem is FAT32 according to fat_length and fat32_length fields, + but has only 8613 clusters, less than the required minimum of 65525. + This may lead to problems on some systems. + + This appears to be due to compilation with a 32-bit off_t and lseek() library + function. + + Use lseek64 for positioning, and change some suspect uses of off_t to loff_t. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit bbb25bf +Author: Steven J. Magnani <steve@digidescorp.com> +Date: Thu Jan 21 16:56:26 2010 +0100 + + If dosfsck is run in read-only mode (-n), exit with code 0 + if the only issue found is an uninitialized free cluster summary. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 1cae726 +Author: Steven J. Magnani <steve@digidescorp.com> +Date: Thu Jan 21 16:55:30 2010 +0100 + + On x86_64, dosfsck incorrectly claims that a free_cluster summary of + 0xFFFFFFFF, defined by Microsoft to be "uninitialized," is wrong. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 62f806a +Author: H. Peter Anvin <hpa@zytor.com> +Date: Fri Jan 8 09:16:38 2010 +0100 + + mkdosfs: correct alignment of the root directory. + + Correct the code to align the root directory; it was broken before + since bs.dir_entries had already been set at the point of alignment. + This patch removes the dual use of bs.dir_entries and root_dir_entries + to carry the same information: the information is carried in + root_dir_entires exclusively, and then bs.dir_entries is set inside + setup_tables() at a late point. + + The code to align the root directory is also wrapped in + if (align_structures); this avoids rounding the number of root + directory entries up to a whole sector when used with -a + (i.e. preserves the previous behavior.) + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 8825bda +Author: H. Peter Anvin <hpa@zytor.com> +Date: Wed Jan 6 20:55:36 2010 +0100 + + mkdosfs: improve wording in the man page for the -a option. + + Improve the English language used in the man page for the -a (no + align) option to mkdosfs. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 21d3f81 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Wed Jan 6 11:27:25 2010 +0100 + + Adding reference to dosfslable in mkdosfs manpage. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 247ba06 +Author: H. Peter Anvin <hpa@zytor.com> +Date: Wed Jan 6 11:18:55 2010 +0100 + + mkdosfs: by default align all structures to cluster boundaries + + Align all data structures (reserved sectors, FATs, root directory for + FAT12/16) to an even multiple of the cluster size. This means that if + the partition is aligned, so will all clusters be. This adds + significant performance for anything where the physical sector size is + larger than the logical sector size, e.g. flash media or large-sector + hard disks. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 171bc07 (tag: v3.0.7) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Thu Dec 24 10:53:36 2009 +0100 + + Releasing version 3.0.7. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 28708fc +Author: Ben Hutchings <ben@decadent.org.uk> +Date: Thu Dec 24 09:55:52 2009 +0100 + + Fixing dosfslabel to set volume label in the right place, + see Debian bug #559985. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 2c405dd +Author: Lubomir Rintel <lkundrak@v3.sk> +Date: Thu Dec 24 09:39:39 2009 +0100 + + Fixing out-of bound writes. + + Firstly, packed attribute is added to the structure so that extension + is guarranteed to immediately follow name for the cross-name-extension + reads to succeed. + + Secondly, writes into dir_entry->name that span through the extension as + well are split into two, so that FORTIFY_SOURCE's bound checking does + not abort dosfsck. There also was an off-by-one error in auto_rename()'s + sprintf(). + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit b8f3efe +Author: San Mehat <san@google.com> +Date: Thu Dec 24 09:31:41 2009 +0100 + + Adding custom exit code in dosfsck for the case where the FS is read only. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 0657e01 (tag: v3.0.6) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Sun Oct 4 10:59:33 2009 +0200 + + Releasing version 3.0.6. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit bc84254 +Author: Steven J. Magnani <steve@digidescorp.com> +Date: Sun Oct 4 10:58:43 2009 +0200 + + Attempt to improve clarity of the orphan cluster reclaim code. + Minor optimization - remove some unnecessary checking. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 8054b4a +Author: Steven J. Magnani <steve@digidescorp.com> +Date: Sun Oct 4 08:37:19 2009 +0200 + + Close hole that permitted clusters to link to (invalid) cluster 1. + + If an orphan chain that linked to cluster 1 was reclaimed to a file, + deletion of the file would result in a filesystem panic. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit e51af88 +Author: Steven J. Magnani <steve@digidescorp.com> +Date: Sun Oct 4 08:32:30 2009 +0200 + + Fix erroneous report of huge number of clusters in use on big-endian + systems when the FSINFO free cluster count is reset. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 16ba63f (tag: v3.0.5) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Mon Jul 27 14:26:11 2009 +0200 + + Releasing version 3.0.5. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 28ff9d9 +Author: Piotr Kaczuba <pepe@attika.ath.cx> +Date: Sun Jul 26 22:21:25 2009 +0200 + + Signed/unsigned char mismatch in check.c causes false positives + in bad_name() and can result in data loss, see Debian bug #538758. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit d42a273 +Author: Andrew Tridgell <tridge@samba.org> +Date: Sun Jul 26 22:12:06 2009 +0200 + + Update to new kernel patches that add FAT_NO_83NAME flag. + + See http://lkml.org/lkml/2009/7/20/425 and + http://lkml.org/lkml/2009/7/20/424 for more information. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit dd0f0b5 (tag: v3.0.4) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Tue Jul 21 08:10:52 2009 +0200 + + Releasing version 3.0.4. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit b9f37a6 +Author: Andrew Tridgell <tridge@samba.org> +Date: Tue Jul 21 07:59:22 2009 +0200 + + Modify dosfstools to support the dummy 8.3 short filename values + used by Linux systems with the VFAT_FS_DUALNAMES option disabled. + + See http://lkml.org/lkml/2009/6/26/313 and + http://lkml.org/lkml/2009/6/26/314 for more information. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit ecd15e8 +Author: Paul Rupe <prupe@nc.rr.com> +Date: Tue May 19 10:37:52 2009 +0200 + + Fixing "Too many files need repair" error during fsck. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 7c16098 (tag: v3.0.3) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Mon May 18 15:12:04 2009 +0200 + + Releasing version 3.0.3. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit b396dcf +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Mon May 18 15:10:55 2009 +0200 + + Also declaring arm as an unaligned architecture, see Debian bug #502961. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit ff1b24e +Author: Steven J. Magnani <steve@digidescorp.com> +Date: Mon May 18 15:01:49 2009 +0200 + + Adding support for limited-memory embedded systems. + + This patch reorganizes heap memory usage by dosfsck and mkdosfs + to support limited-memory embedded systems - in particular, those + based on Xilinx's Microblaze processor. It also adds a few comments. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 89f0b72 +Author: Mike Frysinger <vapier@gentoo.org> +Date: Thu Mar 5 07:03:36 2009 +0100 + + Declaring Blackfin as an unaligned architecture. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit b54a8a4 (tag: v3.0.2) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Sat Feb 28 09:48:04 2009 +0100 + + Releasing version 3.0.2. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 9500529 +Author: Hiroaki Ishizawa <hiroaki.ishizawa@gmail.com> +Date: Fri Feb 13 10:00:46 2009 +0100 + + dosfsck corrupts root directory when fs->nfats is 1. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 043f8a8 +Author: Stepan Kasal <skasal@redhat.com> +Date: Fri Jan 30 14:56:33 2009 +0100 + + src/dosfslabel.c (main): After writing the label, exit code should be 0. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 017da27 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Jan 30 14:06:01 2009 +0100 + + Also installing ChangeLog in install-doc target of Makefile. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 1c76f0f +Author: Stepan Kasal <skasal@redhat.com> +Date: Fri Jan 30 14:05:12 2009 +0100 + + Makefile: Do not clobber time stamps of doc files. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit df2d2f1 (tag: v3.0.1) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Sun Nov 23 22:45:45 2008 +0100 + + Releasing version 3.0.1. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 17b269b +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Sun Nov 23 18:41:01 2008 +0100 + + Applying Fedoras dosfstools-vfat-timingfix.diff from Bill Nottingham + <notting@redhat.com> to fix vfat timing issue. See + https://bugzilla.redhat.com/show_bug.cgi?id=448247 for more information. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit e597caf +Author: Ulrich Mueller <ulm@gentoo.org> +Date: Tue Oct 7 07:55:37 2008 +0200 + + Patch to check for bad number of clusters in dosfsck: + + * FAT16 filesystems with 65525 clusters or more will be rejected + (Before, this was not tested for. Up to 65535 clusters were accepted + as good). + + * For FAT32 filesystems with less than 65525 a warning message will be + output. + + Macro MSDOS_FAT12 is now replaced by FAT12_THRESHOLD to make it + consistent with the definition in mkdosfs and to remove the dependency + on the kernel version. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 90102bc +Author: Dann Frazier <dannf@hp.com> +Date: Tue Sep 30 07:25:19 2008 +0200 + + Changing some wording to make the indended meaning of "full-disk device" + more obvious. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 21e9ba0 (tag: v3.0.0) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Sun Sep 28 11:43:19 2008 +0200 + + Releasing version 3.0.0. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit eaf145d +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Sun Sep 28 11:29:01 2008 +0200 + + Adding GPL headers to all files. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 0826117 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Sun Sep 28 10:51:55 2008 +0200 + + Adding new GPL license file. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit f8d6127 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 23:31:12 2008 +0200 + + Redoing Makefile from scratch. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit b4feb73 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Sat Sep 27 00:17:38 2008 +0200 + + Removing whitespaces in all files at EOL and EOF. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 1410138 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 23:48:56 2008 +0200 + + Adding Debians dosfslabel.8 manpage from Francois Wendling + <frwendling@free.fr>. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit f62e7f2 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 18:36:04 2008 +0200 + + Updating version.h includes to new location of version.h file. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 32e5952 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 18:19:36 2008 +0200 + + Removing old lsm file. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 25a433b +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 18:07:47 2008 +0200 + + Removing old cvsignore files. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit acac13f +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 18:18:39 2008 +0200 + + Removing old build file. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 3ecdd21 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 18:19:16 2008 +0200 + + Removing old GPL license files. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit f183d0e +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 18:21:57 2008 +0200 + + Unifying dosfsck and mkdosfs Makefiles in common src/Makefile. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 61e7466 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 18:04:02 2008 +0200 + + Unifying dosfsck and mkdosfs sources in common src directory. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 7552d57 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 18:05:27 2008 +0200 + + Unifying dosfsck and mkdosfs manpages in common man directory. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 124598b +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 18:12:29 2008 +0200 + + Unifying dosfsck and mkdosfs documents in common doc directory. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit fb9c46b +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 15:39:51 2008 +0200 + + Applying Gentoos dosfstools-2.11-preen.patch from Roy Marples + <uberlord@gentoo.org> to alias dosfsck -p to -a: + + * Map -p to -a for baselayout-2, #177514. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit aaa40a9 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 15:49:43 2008 +0200 + + Applying Gentoos dosfstools-2.11-build.patch from Mike Frysinger + <vapier@gentoo.org> to improve Makefile: + + * Respect user settings #157785/#157786 by Diego Petteno. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 251626d +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 15:37:34 2008 +0200 + + Applying Gentoos dosfstools-2.11-verify-double-count-fix.patch from + Robin H. Johnson <robbat2@gentoo.org> to fix double count of files + during verification: + + * Don't double-count n_files during a verification pass. + Bugzilla: http://bugs.gentoo.org/show_bug.cgi?id=99845 + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit e670ea8 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 15:33:36 2008 +0200 + + Applying Gentoos dosfstools-2.11-fat32size.patch from Mike Frysinger + <vapier@gentoo.org> to fix generation of filesystems on 256meg devices: + + * Fix generation of FAT filesystems on devices that are 256meg in size + Patch by Ulrich Mueller and accepted upstream + http://bugs.gentoo.org/112504 + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit a6dc6a4 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 15:22:06 2008 +0200 + + Applying Suses dosfstools-2.11-unsupported-sector-size.patch from Petr + Gajdos <pgajdos@suse.cz> to add sector size warning: + + * added warning for creation msdos on filesystem with sector size + greater than 4096 [fate#303325] + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit f746956 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 15:18:35 2008 +0200 + + Applying Suses dosfstools-2.11-mkdosfs-geo0.diff from Ludwig Nussel + <lnussel@suse.de> to fix handling of zero heads and sectors: + + * the HDIO_GETGEO ioctl works on device mapper devices but returns + zero heads and sectors. Therefore let's a) assume dummy values in + that case in mkdosfs and b) don't consider such fat file systems as + invalid in dosfsck. The Linux kernel accepts them anyways. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit cf243e4 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 15:15:40 2008 +0200 + + Applying Suses dosfstools-2.11-linuxfs.patch from Ruediger Oertel + <ro@suse.de> to not include linux/fs.h. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 2d4f184 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 15:11:50 2008 +0200 + + Applying Fedoras dosfstools-2.11-assumeKernel26.patch from Peter Vrabec + <pvrabec@redhat.com> to remove linux 2.6 conditionals: + + * LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) does not work with + glibc-kernheaders-2.4-9.1.94 + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 739a6fb +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 15:05:00 2008 +0200 + + Applying Debians 99-conglomeration.dpatch (no other information + available). + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 3b5ed8a +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 14:26:41 2008 +0200 + + Applying Debians 15-manpage-files.dpatch from Daniel Baumann + <daniel@debian.org> to improve dosfsck manpage: + + * Lists fsckNNNN.rec files in FILES section (Closes: #444596). + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 3b6a863 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 14:34:42 2008 +0200 + + Applying Debians 13-getopt.dpatch from Adonikam Virgo + <adonikam@virgonet.org> to fix mkdosfs getopt: + + * Fixes backup sector getopt (Closes: #232387, #479794). + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 1b2c8ca +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 14:34:17 2008 +0200 + + Applying Debians 12-zero-slot.dpatch by Karl Tomlinson + <karlt@karlt.net> to fix dosfsck zero slot crashes: + + * Fixes crashes due to zero slot numbers causing a negative offset in + the call to copy_lfn_part in lfn_add_slot. On amd64 this results in + a SIGSEGV in copy_lfn_part. On x86 the result is heap corruption and + thus sometimes a SIGSEGV or double free abort later. (Closes: + #152550, #353198, #356377, #401798). + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit eec8585 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 14:33:54 2008 +0200 + + Applying Debians 11-memory-efficiency.dpatch from Eero Tamminen + <eero.tamminen@nokia.com> to improve dosfsck memory efficiency: + + * Improves memory efficiency when checking filesystems. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 06bd669 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 14:33:28 2008 +0200 + + Applying Debians 10-manpage-synopsis.dpatch from Daniel Baumann + <daniel@debian.org> to fix manpage synopsis: + + * List alternative binary names in manpage synopsis (Closes: #284983). + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 42d340d +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 14:32:46 2008 +0200 + + Applying Debians 09-manpage-fat32.dpatch from Daniel Baumann + <daniel@debian.org> to improve mkdosfs manpage: + + * Don't claim that FAT32 is not choosed automatically (Closes: + #414183). + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 0f5ce0d +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 14:32:23 2008 +0200 + + Applying Debians 08-manpage-drop.dpatch from Daniel Baumann + <daniel@debian.org> to improve dosfsck manpage: + + * Don't use confusing word 'drop' when 'delete' is meant (Closes: + #134100). + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 8ec54dd +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 14:31:50 2008 +0200 + + Applying Debians 07-manpage-spelling.dpatch from Justin Pryzby + <justinpryzby@users.sourceforge.net> to fix mkdosfs manpage typos. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 4371588 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 14:30:31 2008 +0200 + + Applying Suses dosfstools-2.11_determine-sector-size.patch from Petr + Gajdos <pgajdos@suse.cz> to determine mkdosfs sector size automatically: + + * determine sector size of device automatically or if -S parameter + present, verify, that it's not under physical sector size + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit fc92e19 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 14:30:03 2008 +0200 + + Applying Suses dosfstools-2.11-o_excl.patch from Pavol Rusnak + <prusnak@suse.cz> to use O_EXCL in mkdosfs: + + * mkdosfs now opens device with O_EXCL [#238687] + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 3084697 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 14:29:36 2008 +0200 + + Applying Debians 04-unaligned-memory.dpatch from Khalid Aziz + <khalid_aziz@hp.com> to fix dosfsck unaligned memory accesses: + + * Fix unaligned memory accesses which cause warnings to appear + everytime the elilo bootloader script runs. This has led a number of + users to believe their install has failed (Closes: #258839). + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 6d5c091 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 13:47:40 2008 +0200 + + Applying Fedoras dosfstools-2.11-label.patch from Jeremy Katz + <katzj@redhat.com> to add dosfslabel (originally by Peter Jones). + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 07ef487 +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 13:41:14 2008 +0200 + + Applying Fedoras dosfstools-2.11-fortify.patch from Jakub Jelinek + <jakub@redhat.com> to make it build with -D_FORTIFY_SOURCE=2: + + * This violates -D_FORTIFY_SOURCE=2 (which is stricter than C + standard), but isn't actually any buffer overflow. But using memcpy + is more efficient anyway. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit 78f9dca +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Fri Sep 26 13:40:47 2008 +0200 + + Applying Fedoras dosfstools-2.7-argfix.patch (no other information + available). + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> + +commit ba6774a (tag: v2.11) +Author: Daniel Baumann <mail@daniel-baumann.ch> +Date: Thu Jun 26 12:45:36 2008 +0200 + + Adding version 2.11. + + Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch> diff --git a/dosfstools/Makefile b/dosfstools/Makefile new file mode 100644 index 000000000..fa993559c --- /dev/null +++ b/dosfstools/Makefile @@ -0,0 +1,170 @@ +# Makefile +# +# Copyright (C) 2008-2014 Daniel Baumann <mail@daniel-baumann.ch> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# The complete text of the GNU General Public License +# can be found in /usr/share/common-licenses/GPL-3 file. + +SHELL := sh -e +LANGUAGES = $(shell cd manpages/po && ls) + +DESTDIR = +PREFIX = /usr/local +SBINDIR = $(PREFIX)/sbin +DOCDIR = $(PREFIX)/share/doc +MANDIR = $(PREFIX)/share/man + +#OPTFLAGS = -O2 -fomit-frame-pointer -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 +OPTFLAGS = -O2 -fomit-frame-pointer -D_GNU_SOURCE $(shell getconf LFS_CFLAGS) +#WARNFLAGS = -Wall -pedantic -std=c99 +WARNFLAGS = -Wall -Wextra -Wno-sign-compare -Wno-missing-field-initializers -Wmissing-prototypes -Wstrict-prototypes -Wwrite-strings +DEBUGFLAGS = -g +CFLAGS += $(OPTFLAGS) $(WARNFLAGS) $(DEBUGFLAGS) + +VPATH = src + +all: build + +build: fatlabel fsck.fat mkfs.fat + +fatlabel: boot.o check.o common.o fat.o file.o io.o lfn.o fatlabel.o + +fsck.fat: boot.o check.o common.o fat.o file.o io.o lfn.o fsck.fat.o + +mkfs.fat: mkfs.fat.o + +rebuild: distclean build + +install: install-bin install-doc install-man install-symlinks + +install-bin: build + install -d -m 0755 $(DESTDIR)/$(SBINDIR) + install -m 0755 fatlabel fsck.fat mkfs.fat $(DESTDIR)/$(SBINDIR) + +install-doc: + install -d -m 0755 $(DESTDIR)/$(DOCDIR)/dosfstools + install -p -m 0644 ChangeLog doc/* $(DESTDIR)/$(DOCDIR)/dosfstools + +install-man: + for MANPAGE in manpages/en/*; \ + do \ + SECTION="8"; \ + mkdir -p $(DESTDIR)/$(MANDIR)/man$${SECTION}/; \ + install -m 0644 $${MANPAGE} $(DESTDIR)/$(MANDIR)/man$${SECTION}/$$(basename $${MANPAGE}); \ + done + + for LANGUAGE in $(LANGUAGES); \ + do \ + for MANPAGE in manpages/$${LANGUAGE}/*; \ + do \ + SECTION="8"; \ + mkdir -p $(DESTDIR)/$(MANDIR)/$${LANGUAGE}/man$${SECTION}/; \ + install -m 0644 $${MANPAGE} $(DESTDIR)/$(MANDIR)/$${LANGUAGE}/man$${SECTION}/$$(basename $${MANPAGE} .$${LANGUAGE}.$${SECTION}).$${SECTION}; \ + done; \ + done +install-symlinks: install-bin install-man + if [ -e $(DESTDIR)/$(SBINDIR)/fatlabel ]; \ + then \ + ln -sf fatlabel $(DESTDIR)/$(SBINDIR)/dosfslabel; \ + if [ -e $(DESTDIR)/$(MANDIR)/man8/fatlabel.8 ]; \ + then \ + ln -sf fatlabel.8 $(DESTDIR)/$(MANDIR)/man8/dosfslabel.8; \ + fi; \ + fi + + if [ -e $(DESTDIR)/$(SBINDIR)/fsck.fat ]; \ + then \ + ln -sf fsck.fat $(DESTDIR)/$(SBINDIR)/dosfsck; \ + ln -sf fsck.fat $(DESTDIR)/$(SBINDIR)/fsck.msdos; \ + ln -sf fsck.fat $(DESTDIR)/$(SBINDIR)/fsck.vfat; \ + if [ -e $(DESTDIR)/$(MANDIR)/man8/fsck.fat.8 ]; \ + then \ + ln -sf fsck.fat.8 $(DESTDIR)/$(MANDIR)/man8/dosfsck.8; \ + ln -sf fsck.fat.8 $(DESTDIR)/$(MANDIR)/man8/fsck.msdos.8; \ + ln -sf fsck.fat.8 $(DESTDIR)/$(MANDIR)/man8/fsck.vfat.8; \ + fi; \ + fi + + if [ -e $(DESTDIR)/$(SBINDIR)/mkfs.fat ]; \ + then \ + ln -sf mkfs.fat $(DESTDIR)/$(SBINDIR)/mkdosfs; \ + ln -sf mkfs.fat $(DESTDIR)/$(SBINDIR)/mkfs.msdos; \ + ln -sf mkfs.fat $(DESTDIR)/$(SBINDIR)/mkfs.vfat; \ + if [ -e $(DESTDIR)/$(MANDIR)/man8/mkfs.fat.8 ]; \ + then \ + ln -sf mkfs.fat.8 $(DESTDIR)/$(MANDIR)/man8/mkdosfs.8; \ + ln -sf mkfs.fat.8 $(DESTDIR)/$(MANDIR)/man8/mkfs.msdos.8; \ + ln -sf mkfs.fat.8 $(DESTDIR)/$(MANDIR)/man8/mkfs.vfat.8; \ + fi; \ + fi + +uninstall: uninstall-symlinks uninstall-man uninstall-doc uninstall-bin + +uninstall-bin: + rm -f $(DESTDIR)/$(SBINDIR)/fatlabel + rm -f $(DESTDIR)/$(SBINDIR)/fsck.fat + rm -f $(DESTDIR)/$(SBINDIR)/mkfs.fat + + rmdir --ignore-fail-on-non-empty $(DESTDIR)/$(SBINDIR) + +uninstall-doc: + rm -rf $(DESTDIR)/$(DOCDIR)/dosfstools + + rmdir --ignore-fail-on-non-empty $(DESTDIR)/$(DOCDIR) + +uninstall-man: + for MANPAGE in manpages/en/*; \ + do \ + SECTION="8"; \ + rm -f $(DESTDIR)/$(MANDIR)/man$${SECTION}/$$(basename $${MANPAGE} .en.$${SECTION}).$${SECTION}; \ + done + + for LANGUAGE in $(LANGUAGES); \ + do \ + for MANPAGE in manpages/$${LANGUAGE}/*; \ + do \ + SECTION="8"; \ + rm -f $(DESTDIR)/$(MANDIR)/$${LANGUAGE}/man$${SECTION}/$$(basename $${MANPAGE} .$${LANGUAGE}.$${SECTION}).$${SECTION}; \ + done; \ + done + +uninstall-symlinks: + rm -f $(DESTDIR)/$(SBINDIR)/dosfslabel + rm -f $(DESTDIR)/$(MANDIR)/man8/dosfslabel.8 + + rm -f $(DESTDIR)/$(SBINDIR)/dosfsck + rm -f $(DESTDIR)/$(MANDIR)/man8/dosfsck.8 + rm -f $(DESTDIR)/$(SBINDIR)/fsck.msdos + rm -f $(DESTDIR)/$(MANDIR)/man8/fsck.msdos.8 + rm -f $(DESTDIR)/$(SBINDIR)/fsck.vfat + rm -f $(DESTDIR)/$(MANDIR)/man8/fsck.vfat.8 + + rm -f $(DESTDIR)/$(SBINDIR)/mkdosfs + rm -f $(DESTDIR)/$(MANDIR)/man8/mkdosfs.8 + rm -f $(DESTDIR)/$(SBINDIR)/mkfs.msdos + rm -f $(DESTDIR)/$(MANDIR)/man8/mkfs.msdos.8 + rm -f $(DESTDIR)/$(SBINDIR)/mkfs.vfat + rm -f $(DESTDIR)/$(MANDIR)/man8/mkfs.vfat.8 + +reinstall: distclean install + +clean: + rm -f *.o + +distclean: clean + rm -f fatlabel fsck.fat mkfs.fat + +.PHONY: build rebuild install install-bin install-doc install-man install-symlinks uninstall uninstall-bin uninstall-doc uninstall-man uninstall-symlinks reinstall clean distclean diff --git a/dosfstools/VERSION b/dosfstools/VERSION new file mode 100644 index 000000000..0baec4d10 --- /dev/null +++ b/dosfstools/VERSION @@ -0,0 +1 @@ +3.0.28 diff --git a/dosfstools/bin/Nindent b/dosfstools/bin/Nindent new file mode 100755 index 000000000..cf8ecfd50 --- /dev/null +++ b/dosfstools/bin/Nindent @@ -0,0 +1,18 @@ +#!/bin/sh +PARAM="-npro -kr -i4 -ts8 -sob -l80 -ss -ncs -cp1" +RES=`indent --version` +V1=`echo $RES | cut -d' ' -f3 | cut -d'.' -f1` +V2=`echo $RES | cut -d' ' -f3 | cut -d'.' -f2` +V3=`echo $RES | cut -d' ' -f3 | cut -d'.' -f3` +if [ $V1 -gt 2 ]; then + PARAM="$PARAM -il0" +elif [ $V1 -eq 2 ]; then + if [ $V2 -gt 2 ]; then + PARAM="$PARAM -il0"; + elif [ $V2 -eq 2 ]; then + if [ $V3 -ge 10 ]; then + PARAM="$PARAM -il0" + fi + fi +fi +exec indent $PARAM "$@" diff --git a/dosfstools/doc/ANNOUNCE.mkdosfs b/dosfstools/doc/ANNOUNCE.mkdosfs new file mode 100644 index 000000000..2e01716b4 --- /dev/null +++ b/dosfstools/doc/ANNOUNCE.mkdosfs @@ -0,0 +1,41 @@ +Announcing the release of mkdosfs version 0.3b (Yggdrasil) + +It seems I didn't get the bug completely fixed in 0.3a. Some +borderline cases would still allocate too many sectors for the FAT. +Again, nothing to worry about, just a nitpick -- this one would only +in certain cases add one sector per FAT. + +Announcing the release of mkdosfs version 0.3a (Yggdrasil) + +Fixed a bug which would cause too many sectors to be reserved for the +FAT (filesystem will still work fine, but have slightly less space +available). + +Announcing the release of mkdosfs version 0.3 (Yggdrasil) + +This version correctly handles even very large filesystems, and +properly supports the modern (3.3+) DOS bootsector format, including a +message printed on boot attempts. + +Peter Anvin +Yggdrasil Computing, Inc. +hpa@yggdrasil.com + + -------------- + +Announcing the release of mkdosfs version 0.2 + + +I've just uploaded mkdosfs to sunsite.unc.edu. It works in a similar way +to Remy Card's mke2fs, but creates an MS-DOS filesystem. + +The filename is mkdosfs-0.2.tar.gz. + +This second release should fix a small bug that could lead to FAT sizes that +Linux's dosfs would accept but MS-DOS wouldn't. + +The archive contains a manual page, binary and source versions. + + +Dave Hudson +dave@humbug.demon.co.uk diff --git a/dosfstools/doc/ChangeLog.dosfsck b/dosfstools/doc/ChangeLog.dosfsck new file mode 100644 index 000000000..f628ac289 --- /dev/null +++ b/dosfstools/doc/ChangeLog.dosfsck @@ -0,0 +1,10 @@ +Changes from version 0 to 1 +=========================== + + - fixed an off-by-two error in check.c:check_file + - fixed marking clusters bad in fat.c:set_fat + - fat.c:reclaim_free was also reclaiming bad clusters. + - fixed many incorrect byte sex conversions in check.c and fat.c + - -t and -w now require -a or -r + - added option -d to drop files. + - added option -u to try to "undelete" non-directory files. diff --git a/dosfstools/doc/ChangeLog.dosfstools-2.x b/dosfstools/doc/ChangeLog.dosfstools-2.x new file mode 100644 index 000000000..7ed9efe94 --- /dev/null +++ b/dosfstools/doc/ChangeLog.dosfstools-2.x @@ -0,0 +1,161 @@ +version 2.11 +============ + + - all: don't use own llseek() anymore, glibc lseek() does everything we need + - dosfsck: lfn.c: avoid segfault + - dosfsck: check.c, lfn.c: check for orphaned LFN slots + - dosfsck: check.c alloc_rootdir_entry(): set owner of newly alloced clusters + - dosfsck: dosfsck.h: better use <byteswap.h> for byte swapping + - dosfsck: io.c: added code for real DOS + - mkdosfs: raised FAT12_THRESHOLD from 4078 to 4085, introduced MIN_CLUST_32 + - mkdosfs: fix loop device size + - mkdosfs: by default, use FAT32 on devices >= 512MB + - mkdosfs: fix a memory leak (blank_sector) + - mkdosfs: fix parsing of number of blocks on command line, so that numbers + >2G can be used + - mkdosfs: add 'b' to getopt() string so this option can be used :) + - mkdosfs: fix parsing of -i arg (should be unsigned) + - mkdosfs: change default permissions of created images (-C) to 0666 & ~umask + - mkdosfs: relax geometry check: if HDIO_GETGEO fails, print a warning and + default to H=255,S=63 + - dosfsck: new option -n (no-op): just check non-interactively, but + don't write anything to filesystem + - A few #include changes to support compilation with linux 2.6 + headers (thanks to Jim Gifford <jim@jg555.com>) + - dosfsck: remove directory entries pointing to start cluster 0, if they're + not "." or ".." entries that should actually point to the root dir + (pointed out by Thomas Winkler <twinkler@sysgo.de>) + - mkdosfs: new option -h to set number of hidden sectors + (thanks to Godwin Stewart <gstewart@spamcop.net>) + - all: updated my mail address everywhere... + +version 2.10 +============ + + - dosfsck: various 64-bit fixes and removed some warnings by Michal + Cihar <mcihar@suse.cz> + - mkdosfs: better error message if called without parameters (also + suggested by Michal) + +version 2.9 +=========== + + - dosfsck: if EOF from stdin, exit with error code + - dosfsck: Fix potential for "Internal error: next_cluster on bad cluster". + - dosfsck: When clearing long file names, don't overwrite the dir + entries with all zeros, but put 0xe5 into the first byte. + Otherwise, some OSes stop reading the directory at that point... + - dosfsck: in statistics printed by -v, fix 32bit overflow in number + of data bytes. + - dosfsck: fix an potential overflow in "too many clusters" check + - dosfsck: fix 64bit problem in fat.c (Debian bug #152769) + - dosfsck: allow FAT size > 32MB. + - dosfsck: allow for only one FAT + - dosfsck: with -v, also check that last sector of the filesystem can + be read (in case a partition is smaller than the fs thinks) + - mkdosfs: add note in manpage that creating bootable filesystems is + not supported. + - mkdosfs: better error message with pointer to -I if target is a + full-disk device. + +version 2.8 +=========== + + - dosfsck: Fixed endless loop whenever a volume label was present. + +version 2.7 +=========== + + - dosfsck: Don't check volume label for bad characters, everything + seems to be allowed there... Also ignore duplicate names where one of + them is a volume label. + +version 2.6 +=========== + + - mkdosfs: Added correct heads definition for 2.88M floppies if not + created via loopback. + - dosfsck: If boot sector and its backup are different (FAT32), offer + to write the backup to sector 0. (tnx to Pavel Roskin for this) + - For 64 bit alpha, struct bootsector in dosfsck.h must be defined + with __attribute__((packed)). + - mkdosfs now actually accepts -R option. (tnx to David Kerrawn) + - Fixed typo in dosfsck boot.c (recognition of boot signature in FSINFO) + - Various compilation fixes for 2.4 kernel headers and for ia64. + +version 2.5 +=========== + + - The llseek() implementation for alpha didn't really work; fixed it. + +version 2.4 +=========== + + - Fix compiling problem on alpha (made a silly typo...) + +version 2.3 +=========== + + - mkdosfs: Fixed usage message (printed only "bad address"). + - both: made man pages and usage statements more consistent. + - both: fix llseek function for alpha. + - dosfsck: fix reading of unaligned fields in boot sector for alpha. + - dosfsck: fixed renaming of files (extension wasn't really written). + +version 2.2 +=========== + + - Added dosfsck/COPYING, putting dosfsck officially under GPL (Werner + and I agree that it should be GPL). + - mkdosfs: Allow creation of a 16 bit FAT on filesystems that are too + small for it if the user explicitly selected FAT16 (but a warning + is printed). Formerly, you got the misleading error message "make + the fs a bit smaller". + - dosfsck: new option -y as synonym for -y; for compability with + other fs checkers, which also accept this option. + - dosfsck: Now prints messages similar to e2fsck: at start version + and feature list; at end number of files (and directories) and + number of used/total clusters. This makes the printouts of *fsck at + boot time nicer. + - dosfsck: -a (auto repair) now turns on -f (salvage files), too. -a + should act as non-destructive as possible, so lost clusters should + be assigned to files. Otherwise the data in them might be + overwritten later. + - dosfsck: Don't drop a directory with lots of bad entries in + auto-repair mode for the same reason as above. + - dosfsck: avoid deleting the whole FAT32 root dir if something is + wrong with it (bad start cluster or the like). + - general: also create symlinks {mkfs,fsck}.vfat.8 to the respective + real man pages. + +version 2.1 +=========== + + - Fix some forgotten loff_t's for filesystems > 4GB. (Thanks to + <ki@kretz.co.at>). + - Fix typo in mkdosfs manpage. + - Removed inclusion of <linux/loop.h> from mkdosfs.c; it's unnecessary and + caused problems in some environments. + - Fix condition when to expect . and .. entries in a directory. (Was + wrong for non-FAT32 if first entry in root dir was a directory also.) + - Also create mkfs.vfat and fsck.vfat symlinks, so that also + filesystems listed with type "vfat" in /etc/fstab can be + automatically checked. + +version 2.0 +=========== + + - merge of mkdosfs and dosfstools in one package + - new maintainer: Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> + - FAT32 support in both mkdosfs and dosfsck + - VFAT (long filename) support in dosfsck + - Support for Atari variant of MS-DOS filesystem in both tools + - Working support for big-endian systems in both tools + - Better support for loop devices in mkdosfs: usual floppy sizes are + detected and media byte etc. set accordingly; if loop fs has no + standard floppy size, use hd params + (mainly by Giuliano Procida <gpp10@cus.cam.ac.uk>) + - Removed lots of gcc warnings + - Fixed some minor calculation bugs in mkdosfs. + +For change logs previous to 2.0, see the CHANGES files in the subdirectories. diff --git a/dosfstools/doc/ChangeLog.mkdosfs b/dosfstools/doc/ChangeLog.mkdosfs new file mode 100644 index 000000000..e39d9d6a4 --- /dev/null +++ b/dosfstools/doc/ChangeLog.mkdosfs @@ -0,0 +1,18 @@ +28th January 1995 H. Peter Anvin (hpa@yggdrasil.com) + + Better algorithm to select cluster sizes on large filesystems. + Added bogus boot sector code that on attempts to boot prints a + message (which can be chosen at mkdosfs time) and lets the user + press any key and try again. Corrected support for 1.2 Mb + floppies. mkdosfs now generates the extended bootsector + (superblock) format of DOS 3.3+, with support for volume ID's and + volume labels (volume labels are also written to the root + directory, as they should). + +18th February 1994 Dave Hudson (dave@humbug.demon.co.uk) + + Released version 0.2 - clears a bug in the FAT sizing code. + +1st September 1993 Dave Hudson (dave@humbug.demon.co.uk) + + Released version 0.1 - ALPHA release of mkdosfs diff --git a/dosfstools/doc/README.dosfsck b/dosfstools/doc/README.dosfsck new file mode 100644 index 000000000..3038f363b --- /dev/null +++ b/dosfstools/doc/README.dosfsck @@ -0,0 +1,60 @@ +dosfsck, version 1 +================== + +WARNING: This is ALPHA test software. Use at your own risk. + +dosfsck is the Linux equivalent of PC/MS-DOS' CHKDSK. It checks the +consistency of PC/MS-DOS filesystems and optionally tries to repair +them. The tests dosfsck performs are described in the man page. + +dosfsck needs header files from dosfs.9 (or later) to compile. + +Before using dosfsck to repair a filesystem that contains data of any +value, you should verify that dosfsck is able to correct all reported +errors. (Except fatal errors and those reported as unfixable, of +course.) In order to do this, run it with the -V option, e.g. + + dosfsck -V /dev/sda1 (automatic check) +or dosfsck -V -r /dev/sda1 (interactive check and repair) + +dosfsck will perform two passes: in the first pass, inconsistencies are +detected and a list of changes to correct the problems is generated. In +the second pass, those changes are applied whenever dosfsck reads data +from disk. Hence no fixable errors should be reported in the second +pass if the first pass was successful. + +Please notify the author if fixable errors are reported in the second +pass. + +After verifying that dosfsck appears to be able to perform the desired +operations, either confirm that you want the changes to be performed +(if dosfsck was started with -r) or re-run dosfsck with the -a option +(if it was started without -r). + +Please send bug reports, comments, flames, etc. to +almesber@nessie.cs.id.ethz.ch or almesber@bernina.ethz.ch + +- Werner + +FAT32 and LFN support +===================== + +I've finally implemented some of the new features of MS-DOS +filesystems: FAT32 and long filenames. + +FAT32 is automatically detected and of course the different FAT +structure is handled. (Internally many changes were needed, so 32 bit +variables for all cluster numbers and 64 bit vars for offsets inside +the filesystem.) New checks for FAT32 are most notably on the backup +boot sector and the new info sector. Also the possibility that the +root directory resides in a cluster chain (instead of in a static +area) on FAT32 is handled. + +dosfscheck also knows about VFAT long filenames now. It parses those +names and uses them in listings etc. when available. There are also +some checks on the (cruel) structure of how LFNs are stored and some +attempts to fix problems. + +- Roman <roman@hodek.net> + +BTW, version 2 isn't ALPHA anymore :-) diff --git a/dosfstools/doc/README.dosfstools-2.x b/dosfstools/doc/README.dosfstools-2.x new file mode 100644 index 000000000..5fb00ed07 --- /dev/null +++ b/dosfstools/doc/README.dosfstools-2.x @@ -0,0 +1,60 @@ + +Atari format support +==================== + +Both mkdosfs and dosfsck now can also handle the Atari variation of +the MS-DOS filesystem format. The Atari format has some minor +differences, some caused by the different machine architecture (m68k), +some being "historic" (Atari didn't change some things that M$ +changed). + +Both tools automatically select Atari format if they run on an Atari. +Additionally the -A switch toggles between Atari and MS-DOS format. +I.e., on an Atari it selects plain DOS format, on any other machine it +switches to Atari format. + +The differences are in detail: + + - Atari TOS doesn't like cluster sizes != 2, so the usual solution + for bigger partitions was to increase the logical sector size. So + mkdosfs can handle sector sizes != 512 now, you can also manually + select it with the -S option. On filesystems larger than approx. 32 + MB, the sector size is automatically increased (stead of the + cluster size) to make the filesystem fit. mkdosfs will always use 2 + sectors per cluster (also with the floppy standard configurations), + except when directed otherwise on the command line. + + - From the docs, all values between 0xfff8 and 0xffff in the FAT mark + an end-of-file. However, DOS usually uses 0xfff8 and Atari 0xffff. + This seems to be only an consmetic difference. At least TOS doesn't + complain about 0xffff EOF marks. Don't know what DOS thinks of + 0xfff8 :-) Anyway, both tools use the EOF mark common to the + system (DOS/Atari). + + - Something similar of the bad cluster marks: On Atari the FAT values + 0xfff0 to 0xfff7 are used for this, under DOS only 0xfff7 (the + others can be normal cluster numbers, allowing 7 more clusters :-) + However, both systems usually mark with 0xfff7. Just dosfsck has to + interpret 0xfff0...0xfff7 differently. + + - Some fields in the boot sector are interpreted differently. For + example, Atari has a disk serial number (used to aid disk change + detection) where DOS stores the system name; the 'hidden' field is + 32 bit for DOS, but 16 bit for Atari, and there's no 'total_sect' + field; the 12/16 bit FAT decision is different: it's not based on + the number of clusters, but always FAT12 on floppies and FAT16 on + hard disks. mkdosfs nows about these differences and constructs the + boot sector accordingly. + + - In dosfsck, the boot sector differences also have to known, to not + warn about things that are no error on Atari. In addition, most + Atari formatting tools fill the 'tracks' and 'heads' fields with 0 + for hard disks, because they're meaningless on SCSI disks (Atari + has/had no IDE). Due to this, the check that they should be + non-zero is switched off. + + - Under Atari TOS, some other characters are illegal in filenames: + '<', '>', '|', '"', and ':' are allowed, but all non-ASCII chars + (codes >= 128) are forbidden. + +- Roman <Roman.Hodek@informatik.uni-erlangen.de> diff --git a/dosfstools/doc/README.mkdosfs b/dosfstools/doc/README.mkdosfs new file mode 100644 index 000000000..5bd9b21b3 --- /dev/null +++ b/dosfstools/doc/README.mkdosfs @@ -0,0 +1,50 @@ +mkdosfs - Make DOS filesystem utilty. + + +I wrote this, partially to complement the dosfsck utility written by Werner +Almesberger (who graciously gave me some pointers when I asked for some +advice about writing this code), and also to avoid me having to boot DOS +just to create data partitions (I use Linux to back up DOS :-) ). + +The code is really derived from Remy Card's mke2fs utility - I used this as a +framework, although all of the filesystem specific stuff was removed and the +DOS stuff inserted. I believe originally mke2fs was based on Linus' mkfs +code, hence the acknowledgements in the source code. + +Neither Remy nor Linus have had any involvement with mkdosfs, so if there are +any bugs they're almost certainly "all my own work". + +The code has been available for ftp since 1st September 1993, and I have yet +to receive any bug reports from users. I don't know of any bugs, but if you +do find a bug or have any constructive comments, please mail me! + +The only bug I found with version 0.1 was an obscure fault that could lead +to an invalid (for MS-DOS, not Linux's dos fs) number of sectors used in the +file allocation table(s). + + +Dave Hudson +dave@humbug.demon.co.uk + + +FAT32 support +============= + +mkdosfs now can also create filesystems in the new FAT32 format. To do +this, give mkdosfs a "-F 32" option. FAT32 isn't selected +automatically (yet), even if very large clusters are needed with +FAT16. With FAT32 you have two additional options, -R to select the +number of reserved sectors (usually 32), and -b to select the location +of the backup boot sector (default 6). Of course such a backup is +created, as well as the new info sector. On FAT32, the root directory +is always created as a cluster chain. Sorry, there's no switch to +generate an old static root dir. + +One bigger bug fix besides FAT32 was to reject filesystems that need a +16 bit FAT to fit all possible clusters, but the bigger FAT needs some +more sectors, so the total number of clusters drop below the border +where MS-DOS expects a 12 bit FAT. So such filesystems would be FAT16, +but interpreted as FAT32 by DOS. The fix is to reduce filesystem size +a bit. + +- Roman <roman@hodek.net> diff --git a/dosfstools/doc/TODO.dosfstools-2.x b/dosfstools/doc/TODO.dosfstools-2.x new file mode 100644 index 000000000..dbc2de074 --- /dev/null +++ b/dosfstools/doc/TODO.dosfstools-2.x @@ -0,0 +1,14 @@ + -*- mode: indented-text -*- + + - dosfsck: Better checking of file times: ctime <= mtime <= atime + + - mkdosfs: If /etc/bootsect.dos (or similar) exists, use it as a + template for generating boot sectors. This way, you can, e.g., make + bootable DOS disks. + + Addendum: Don't know if that's so wise... There are really many + variants of DOS/Windows bootcode out in the wild, and the code is + proprietary, too. + + - dosfsck: read-only sector test (-t without -a or -r); just print + out errors. diff --git a/dosfstools/manpages/Makefile b/dosfstools/manpages/Makefile new file mode 100644 index 000000000..ee8a47829 --- /dev/null +++ b/dosfstools/manpages/Makefile @@ -0,0 +1,50 @@ +# Makefile + +## dosfstools(7) +## Copyright (C) 2006-2014 Daniel Baumann <mail@daniel-baumann.ch> +## +## This program comes with ABSOLUTELY NO WARRANTY; for details see COPYING. +## This is free software, and you are welcome to redistribute it +## under certain conditions; see COPYING for details. + + +SHELL := sh -e + +LANGUAGES = $(shell cd po && ls) + +all: build + +po4a.cfg: + echo "[po4a_langs] $(LANGUAGES)" > po4a.cfg + echo "[po4a_paths] pot/\$$master.pot \$$lang:po/\$$lang/\$$master.po" >> po4a.cfg + + for MANPAGE in en/*; \ + do \ + SECTION="$$(basename $${MANPAGE} | sed -e 's|\.|\n|g' | tail -n1)"; \ + echo "[type: man] $${MANPAGE} \$$lang:\$$lang/$$(basename $${MANPAGE} .$${SECTION}).\$$lang.$${SECTION}" >> po4a.cfg; \ + done + +update: + ./bin/update-version.sh + +build: po4a.cfg + @if [ ! -x "$$(which po4a 2>/dev/null)" ]; \ + then \ + echo "E: po4a - command not found"; \ + echo "I: po4a can be obtained from:"; \ + echo "I: http://po4a.alioth.debian.org/"; \ + echo "I: On Debian based systems, po4a can be installed with:"; \ + echo "I: apt-get install po4a"; \ + exit 1; \ + fi + + po4a --keep 0 --no-backups -o untranslated=MT,ME \ + --package-name dosfstools po4a.cfg + +clean: + rm -rf $(LANGUAGES) + +distclean: clean + rm -f po4a.cfg + +rebuild: distclean update build diff --git a/dosfstools/manpages/bin/update-version.sh b/dosfstools/manpages/bin/update-version.sh new file mode 100755 index 000000000..48e9c08c0 --- /dev/null +++ b/dosfstools/manpages/bin/update-version.sh @@ -0,0 +1,55 @@ +#!/bin/sh + +## dosfstools(7) +## Copyright (C) 2006-2014 Daniel Baumann <mail@daniel-baumann.ch> +## +## This program comes with ABSOLUTELY NO WARRANTY; for details see COPYING. +## This is free software, and you are welcome to redistribute it +## under certain conditions; see COPYING for details. + + +set -e + +PROJECT="dosfstools" +VERSION="$(cat ../VERSION)" + +DATE="$(LC_ALL=C date +%Y\\\\-%m\\\\-%d)" + +DAY="$(LC_ALL=C date +%d)" +MONTH="$(LC_ALL=C date +%m)" +YEAR="$(LC_ALL=C date +%Y)" + +echo "Updating version headers..." + +for MANPAGE in en/* +do + PROGRAM="$(basename ${MANPAGE} | sed -e 's|\(.*\).[0-9]$|\1|' | tr [a-z] [A-Z])" + SECTION="$(basename ${MANPAGE} | sed -e 's|.*.\([0-9]\)$|\1|')" + + sed -i -e "s|^.TH.*$|.TH ${PROGRAM} ${SECTION} ${DATE} ${VERSION} \"${PROJECT}\"|" ${MANPAGE} +done + +# European date format +for _LANGUAGE in de es fr it +do + if ls po/${_LANGUAGE}/*.po > /dev/null 2>&1 + then + for _FILE in po/${_LANGUAGE}/*.po + do + sed -i -e "s|^msgstr .*.2014-.*$|msgstr \"${DAY}.${MONTH}.${YEAR}\"|g" \ + -e "s|^msgstr .*.2014\"$|msgstr \"${DAY}.${MONTH}.${YEAR}\"|g" \ + "${_FILE}" + done + fi +done + +# Brazilian date format +if ls po/pt_BR/*.po > /dev/null 2>&1 +then + for _FILE in po/pt_BR/*.po + do + sed -i -e "s|^msgstr .*.2014-.*$|msgstr \"${DAY}-${MONTH}-${YEAR}\"|g" \ + -e "s|^msgstr .*-2014\"$|msgstr \"${DAY}-${MONTH}-${YEAR}\"|g" \ + "${_FILE}" + done +fi diff --git a/dosfstools/manpages/de/fatlabel.de.8 b/dosfstools/manpages/de/fatlabel.de.8 new file mode 100644 index 000000000..53f5515ed --- /dev/null +++ b/dosfstools/manpages/de/fatlabel.de.8 @@ -0,0 +1,68 @@ +.\" fatlabel.8 - manpage for fatlabel +.\" +.\" Copyright (C) 2006-2014 Daniel Baumann <daniel@debian.org> +.\" +.\" This program is free software: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 3 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see <http://www.gnu.org/licenses/>. +.\" +.\" The complete text of the GNU General Public License +.\" can be found in /usr/share/common-licenses/GPL-3 file. +.\" +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH FATLABEL 8 2015\-05\-16 3.0.28 dosfstools +.SH NAME +.\" ---------------------------------------------------------------------------- +\fBfatlabel\fP \- set or get MS\-DOS filesystem label +.SH SYNOPSIS +.\" ---------------------------------------------------------------------------- +\fBfatlabel\fP \fIDEVICE\fP [\fILABEL\fP] +.SH DESCRIPTION +\fBfatlabel\fP set or gets a MS\-DOS filesystem label from a given device. +.PP +.\" ---------------------------------------------------------------------------- +If \fILABEL\fP is omitted, then the label name of the specified device is +written on the standard output. A label can't be longer than 11 bytes. +.SH OPTIONS +.IP "\fB\-h\fP, \fB\-\-help\fP" 4 +Displays a help message. +.IP "\fB\-V\fP, \fB\-\-version\fP" 4 +.\" ---------------------------------------------------------------------------- +Shows version. +.SH "SEE ALSO" +\fBfsck.fat\fP(8) +.br +.\" ---------------------------------------------------------------------------- +\fBmkfs.fat\fP(8) +.SH HOMEPAGE +.\" ---------------------------------------------------------------------------- +The home for the \fBdosfstools\fP project is its +.UR https://github.com/dosfstools/dosfstools +GitHub project page +.UE . +.SH AUTHORS +\fBdosfstools\fP were written by +.MT werner.almesberger@\:lrc.di.epfl.ch +Werner Almesberger +.ME , +.MT Roman.Hodek@\:informatik.\:uni-erlangen.de +Roman Hodek +.ME , +and others. The current maintainer is +.MT aeb@\:debian.org +Andreas Bombe +.ME . diff --git a/dosfstools/manpages/de/fsck.fat.de.8 b/dosfstools/manpages/de/fsck.fat.de.8 new file mode 100644 index 000000000..869b806a8 --- /dev/null +++ b/dosfstools/manpages/de/fsck.fat.de.8 @@ -0,0 +1,189 @@ +.\" fsck.fat.8 - manpage for fsck.fat +.\" +.\" Copyright (C) 2006-2014 Daniel Baumann <daniel@debian.org> +.\" +.\" This program is free software: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 3 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see <http://www.gnu.org/licenses/>. +.\" +.\" The complete text of the GNU General Public License +.\" can be found in /usr/share/common-licenses/GPL-3 file. +.\" +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH FSCK.FAT 8 2015\-05\-16 3.0.28 dosfstools +.SH NAME +.\" ---------------------------------------------------------------------------- +\fBfsck.fat\fP \- check and repair MS\-DOS filesystems +.SH SYNOPSIS +.\" ---------------------------------------------------------------------------- +\fBfsck.fat\fP [\fIOPTIONS\fP] \fIDEVICE\fP +.SH DESCRIPTION +\fBfsck.fat\fP verifies the consistency of MS\-DOS filesystems and optionally +tries to repair them. +.PP +The following filesystem problems can be corrected (in this order): +.IP * 4 +FAT contains invalid cluster numbers. Cluster is changed to EOF. +.IP * 4 +File's cluster chain contains a loop. The loop is broken. +.IP * 4 +Bad clusters (read errors). The clusters are marked bad and they are +removed from files owning them. This check is optional. +.IP * 4 +Directories with a large number of bad entries (probably corrupt). The +directory can be deleted. +.IP * 4 +Files . and .. are non\-directories. They can be deleted or renamed. +.IP * 4 +Directories . and .. in root directory. They are deleted. +.IP * 4 +Bad filenames. They can be renamed. +.IP * 4 +Duplicate directory entries. They can be deleted or renamed. +.IP * 4 +Directories with non\-zero size field. Size is set to zero. +.IP * 4 +Directory . does not point to parent directory. The start pointer is +adjusted. +.IP * 4 +Directory .. does not point to parent of parent directory. The start +pointer is adjusted. +.IP * 4 +Start cluster number of a file is invalid. The file is truncated. +.IP * 4 +File contains bad or free clusters. The file is truncated. +.IP * 4 +File's cluster chain is longer than indicated by the size fields. The file +is truncated. +.IP * 4 +Two or more files share the same cluster(s). All but one of the files are +truncated. If the file being truncated is a directory file that has already +been read, the filesystem check is restarted after truncation. +.IP * 4 +File's cluster chain is shorter than indicated by the size fields. The file +is truncated. +.IP * 4 +Clusters are marked as used but are not owned by a file. They are marked as +free. +.PP +Additionally, the following problems are detected, but not repaired: +.IP * 4 +Invalid parameters in boot sector +.IP * 4 +Absence of . and .. entries in non\-root directories +.PP +.\" ---------------------------------------------------------------------------- +When \fBfsck.fat\fP checks a filesystem, it accumulates all changes in memory +and performs them only after all checks are complete. This can be disabled +with the \fB\-w\fP option. +.SH OPTIONS +.IP \fB\-a\fP 4 +Automatically repair the filesystem. No user intervention is necessary. +Whenever there is more than one method to solve a problem, the least +destructive approach is used. +.IP \fB\-A\fP 4 +Use Atari variation of the MS\-DOS filesystem. This is default if +\fBfsck.fat\fP is run on an Atari, then this option turns off Atari format. +There are some minor differences in Atari format: Some boot sector fields +are interpreted slightly different, and the special FAT entries for +end\-of\-file and bad cluster can be different. Under MS\-DOS 0xfff8 is used +for EOF and Atari employs 0xffff by default, but both systems recognize all +values from 0xfff8...0xffff as end\-of\-file. MS\-DOS uses only 0xfff7 for bad +clusters, where on Atari values 0xfff0...0xfff7 are for this purpose (but +the standard value is still 0xfff7). +.IP \fB\-b\fP 4 +Make read\-only boot sector check. +.IP "\fB\-d\fP \fIPATH\fP" 4 +Delete the specified file. If more than one file with that name exist, the +first one is deleted. This option can be given more than once. +.IP \fB\-f\fP 4 +Salvage unused cluster chains to files. By default, unused clusters are +added to the free disk space except in auto mode (\fB\-a\fP). +.IP \fB\-l\fP 4 +List path names of files being processed. +.IP \fB\-n\fP 4 +No\-operation mode: non\-interactively check for errors, but don't write +anything to the filesystem. +.IP \fB\-p\fP 4 +Same as \fB\-a\fP, for compatibility with other *fsck. +.IP \fB\-r\fP 4 +Interactively repair the filesystem. The user is asked for advice whenever +there is more than one approach to fix an inconsistency. This is the +default mode and the option is only retained for backwards compatibility. +.IP \fB\-t\fP 4 +Mark unreadable clusters as bad. +.IP "\fB\-u\fP \fIPATH\fP" 4 +Try to undelete the specified file. \fBfsck.fat\fP tries to allocate a chain +of contiguous unallocated clusters beginning with the start cluster of the +undeleted file. This option can be given more than once. +.IP \fB\-v\fP 4 +Verbose mode. Generates slightly more output. +.IP \fB\-V\fP 4 +Perform a verification pass. The filesystem check is repeated after the +first run. The second pass should never report any fixable errors. It may +take considerably longer than the first pass, because the first pass may +have generated long list of modifications that have to be scanned for each +disk read. +.IP \fB\-w\fP 4 +Write changes to disk immediately. +.IP \fB\-y\fP 4 +.\" ---------------------------------------------------------------------------- +Same as \fB\-a\fP (automatically repair filesystem) for compatibility with other +fsck tools. +.SH "EXIT STATUS" +.IP 0 4 +No recoverable errors have been detected. +.IP 1 4 +Recoverable errors have been detected or \fBfsck.fat\fP has discovered an +internal inconsistency. +.IP 2 4 +.\" ---------------------------------------------------------------------------- +Usage error. \fBfsck.fat\fP did not access the filesystem. +.SH FILES +.IP "fsck0000.rec, fsck0001.rec, ..." 4 +.\" ---------------------------------------------------------------------------- +When recovering from a corrupted filesystem, \fBfsck.fat\fP dumps recovered +data into files named 'fsckNNNN.rec' in the top level directory of the +filesystem. +.SH BUGS +.\" ---------------------------------------------------------------------------- +Does not create . and .. files where necessary. Does not remove entirely +empty directories. Should give more diagnostic messages. Undeleting files +should use a more sophisticated algorithm. +.SH "SEE ALSO" +\fBfatlabel\fP(8) +.br +.\" ---------------------------------------------------------------------------- +\fBmkfs.fat\fP(8) +.SH HOMEPAGE +.\" ---------------------------------------------------------------------------- +The home for the \fBdosfstools\fP project is its +.UR https://github.com/dosfstools/dosfstools +GitHub project page +.UE . +.SH AUTHORS +\fBdosfstools\fP were written by +.MT werner.almesberger@\:lrc.di.epfl.ch +Werner Almesberger +.ME , +.MT Roman.Hodek@\:informatik.\:uni-erlangen.de +Roman Hodek +.ME , +and others. The current maintainer is +.MT aeb@\:debian.org +Andreas Bombe +.ME . diff --git a/dosfstools/manpages/de/mkfs.fat.de.8 b/dosfstools/manpages/de/mkfs.fat.de.8 new file mode 100644 index 000000000..a1b51d45b --- /dev/null +++ b/dosfstools/manpages/de/mkfs.fat.de.8 @@ -0,0 +1,172 @@ +.\" mkfs.fat.8 - manpage for fs.fatck +.\" +.\" Copyright (C) 2006-2014 Daniel Baumann <daniel@debian.org> +.\" +.\" This program is free software: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 3 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see <http://www.gnu.org/licenses/>. +.\" +.\" The complete text of the GNU General Public License +.\" can be found in /usr/share/common-licenses/GPL-3 file. +.\" +.\" +.\"******************************************************************* +.\" +.\" This file was generated with po4a. Translate the source file. +.\" +.\"******************************************************************* +.TH MKFS.FAT 8 2015\-05\-16 3.0.28 dosfstools +.SH NAME +.\" ---------------------------------------------------------------------------- +\fBmkfs.fat\fP \- create an MS\-DOS filesystem under Linux +.SH SYNOPSIS +.\" ---------------------------------------------------------------------------- +\fBmkfs.fat\fP [\fIOPTIONS\fP] \fIDEVICE\fP [\fIBLOCK\-COUNT\fP] +.SH DESCRIPTION +.\" ---------------------------------------------------------------------------- +\fBmkfs.fat\fP is used to create an MS\-DOS filesystem under Linux on a device +(usually a disk partition). \fIDEVICE\fP is the special file corresponding to +the device (e.g. /dev/sdXX). \fIBLOCK\-COUNT\fP is the number of blocks on the +device. If omitted, \fBmkfs.fat\fP automatically determines the filesystem +size. +.SH OPTIONS +.IP \fB\-a\fP 4 +Normally, for any filesystem except very small ones, \fBmkfs.fat\fP will align +all the data structures to cluster size, to make sure that as long as the +partition is properly aligned, so will all the data structures in the +filesystem. This option disables alignment; this may provide a handful of +additional clusters of storage at the expense of a significant performance +degradation on RAIDs, flash media or large\-sector hard disks. +.IP "\fB \-A\fP" 4 +Use Atari variation of the MS\-DOS filesystem. This is default if +\fBmkfs.fat\fP is run on an Atari, then this option turns off Atari format. +There are some differences when using Atari format: If not directed +otherwise by the user, \fBmkfs.fat\fP will always use 2 sectors per cluster, +since GEMDOS doesn't like other values very much. It will also obey the +maximum number of sectors GEMDOS can handle. Larger filesystems are managed +by raising the logical sector size. Under Atari format, an Atari\-compatible +serial number for the filesystem is generated, and a 12 bit FAT is used only +for filesystems that have one of the usual floppy sizes (720k, 1.2M, 1.44M, +2.88M), a 16 bit FAT otherwise. This can be overridden with the \fB\-F\fP +option. Some PC\-specific boot sector fields aren't written, and a boot +message (option \fB\-m\fP) is ignored. +.IP "\fB\-b\fP \fISECTOR\-OF\-BACKUP\fP" 4 +Selects the location of the backup boot sector for FAT32. Default depends +on number of reserved sectors, but usually is sector 6. The backup must be +within the range of reserved sectors. +.IP \fB\-c\fP 4 +Check the device for bad blocks before creating the filesystem. +.IP \fB\-C\fP 4 +Create the file given as \fIDEVICE\fP on the command line, and write the +to\-be\-created filesystem to it. This can be used to create the new +filesystem in a file instead of on a real device, and to avoid using \fBdd\fP +in advance to create a file of appropriate size. With this option, the +\fIBLOCK\-COUNT\fP must be given, because otherwise the intended size of the +filesystem wouldn't be known. The file created is a sparse file, which +actually only contains the meta\-data areas (boot sector, FATs, and root +directory). The data portions won't be stored on the disk, but the file +nevertheless will have the correct size. The resulting file can be copied +later to a floppy disk or other device, or mounted through a loop device. +.IP "\fB\-D\fP \fIDRIVE\-NUMBER\fP" 4 +Specify the BIOS drive number to be stored in the FAT boot sector. This +value is usually 0x80 for hard disks and 0x00 for floppy devices or +partitions to be used for floppy emulation. +.IP "\fB\-f\fP \fINUMBER\-OF\-FATS\fP" 4 +Specify the number of file allocation tables in the filesystem. The default +is 2. +.IP "\fB\-F\fP \fIFAT\-SIZE\fP" 4 +Specifies the type of file allocation tables used (12, 16 or 32 bit). If +nothing is specified, \fBmkfs.fat\fP will automatically select between 12, 16 +and 32 bit, whatever fits better for the filesystem size. +.IP "\fB\-h\fP \fINUMBER\-OF\-HIDDEN\-SECTORS\fP" 4 +Select the number of hidden sectors in the volume. Apparently some digital +cameras get indigestion if you feed them a CF card without such hidden +sectors, this option allows you to satisfy them. +.IP "\fB\-i\fP \fIVOLUME\-ID\fP" 4 +Sets the volume ID of the newly created filesystem; \fIVOLUME\-ID\fP is a 32\-bit +hexadecimal number (for example, 2e24ec82). The default is a number which +depends on the filesystem creation time. +.IP \fB\-I\fP 4 +It is typical for fixed disk devices to be partitioned so, by default, you +are not permitted to create a filesystem across the entire device. +\fBmkfs.fat\fP will complain and tell you that it refuses to work. This is +different when using MO disks. One doesn't always need partitions on MO +disks. The filesystem can go directly to the whole disk. Under other OSes +this is known as the 'superfloppy' format. This switch will force +\fBmkfs.fat\fP to work properly. +.IP "\fB\-l\fP \fIFILENAME\fP" 4 +Read the bad blocks list from \fIFILENAME\fP. +.IP "\fB\-m\fP \fIMESSAGE\-FILE\fP" 4 +Sets the message the user receives on attempts to boot this filesystem +without having properly installed an operating system. The message file +must not exceed 418 bytes once line feeds have been converted to carriage +return\-line feed combinations, and tabs have been expanded. If the filename +is a hyphen (\-), the text is taken from standard input. +.IP "\fB\-M\fP \fIFAT\-MEDIA\-TYPE\fP" 4 +Specify the media type to be stored in the FAT boot sector. This value is +usually 0xF8 for hard disks and is 0xF0 or a value from 0xF9 to 0xFF for +floppies or partitions to be used for floppy emulation. +.IP "\fB\-n\fP \fIVOLUME\-NAME\fP" 4 +Sets the volume name (label) of the filesystem. The volume name can be up +to 11 characters long. The default is no label. +.IP "\fB\-r\fP \fIROOT\-DIR\-ENTRIES\fP" 4 +Select the number of entries available in the root directory. The default +is 112 or 224 for floppies and 512 for hard disks. +.IP "\fB\-R\fP \fINUMBER\-OF\-RESERVED\-SECTORS\fP" 4 +Select the number of reserved sectors. With FAT32 format at least 2 +reserved sectors are needed, the default is 32. Otherwise the default is 1 +(only the boot sector). +.IP "\fB\-s\fP \fISECTORS\-PER\-CLUSTER\fP" 4 +Specify the number of disk sectors per cluster. Must be a power of 2, +i.e. 1, 2, 4, 8, ... 128. +.IP "\fB\-S\fP \fILOGICAL\-SECTOR\-SIZE\fP" 4 +Specify the number of bytes per logical sector. Must be a power of 2 and +greater than or equal to 512, i.e. 512, 1024, 2048, 4096, 8192, 16384, or +32768. +.IP \fB\-v\fP 4 +Verbose execution. +.IP \fB\-\-invariant\fP 4 +Use constants for normally randomly generated or time based data such as +volume ID and creation time. Multiple runs of \fBmkfs.fat\fP on the same +device create identical results with this option. Its main purpose is +testing \fBmkfs.fat\fP. +.IP \fB\-\-help\fP 4 +.\" ---------------------------------------------------------------------------- +Display option summary and exit. +.SH BUGS +.\" ---------------------------------------------------------------------------- +\fBmkfs.fat\fP can not create boot\-able filesystems. This isn't as easy as you +might think at first glance for various reasons and has been discussed a lot +already. \fBmkfs.fat\fP simply will not support it ;) +.SH "SEE ALSO" +\fBfatlabel\fP(8) +.br +.\" ---------------------------------------------------------------------------- +\fBfsck.fat\fP(8) +.SH HOMEPAGE +.\" ---------------------------------------------------------------------------- +The home for the \fBdosfstools\fP project is its +.UR https://github.com/dosfstools/dosfstools +GitHub project page +.UE . +.SH AUTHORS +\fBdosfstools\fP were written by +.MT werner.almesberger@\:lrc.di.epfl.ch +Werner Almesberger +.ME , +.MT Roman.Hodek@\:informatik.\:uni-erlangen.de +Roman Hodek +.ME , +and others. The current maintainer is +.MT aeb@\:debian.org +Andreas Bombe +.ME . diff --git a/dosfstools/manpages/en/fatlabel.8 b/dosfstools/manpages/en/fatlabel.8 new file mode 100644 index 000000000..c00a79517 --- /dev/null +++ b/dosfstools/manpages/en/fatlabel.8 @@ -0,0 +1,65 @@ +.\" fatlabel.8 - manpage for fatlabel +.\" +.\" Copyright (C) 2006-2014 Daniel Baumann <daniel@debian.org> +.\" +.\" This program is free software: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 3 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see <http://www.gnu.org/licenses/>. +.\" +.\" The complete text of the GNU General Public License +.\" can be found in /usr/share/common-licenses/GPL-3 file. +.\" +.\" +.TH FATLABEL 8 2015\-05\-16 3.0.28 "dosfstools" +.SH NAME +\fBfatlabel\fR \- set or get MS\-DOS filesystem label +.\" ---------------------------------------------------------------------------- +.SH SYNOPSIS +\fBfatlabel\fR \fIDEVICE\fR [\fILABEL\fR] +.\" ---------------------------------------------------------------------------- +.SH DESCRIPTION +\fBfatlabel\fR set or gets a MS\-DOS filesystem label from a given device. +.PP +If \fILABEL\fR is omitted, then the label name of the specified device is +written on the standard output. +A label can't be longer than 11 bytes. +.\" ---------------------------------------------------------------------------- +.SH OPTIONS +.IP "\fB\-h\fR, \fB\-\-help\fR" 4 +Displays a help message. +.IP "\fB\-V\fR, \fB\-\-version\fR" 4 +Shows version. +.\" ---------------------------------------------------------------------------- +.SH SEE ALSO +\fBfsck.fat\fR(8) +.br +\fBmkfs.fat\fR(8) +.\" ---------------------------------------------------------------------------- +.SH HOMEPAGE +The home for the \fBdosfstools\fR project is its +.UR https://github.com/dosfstools/dosfstools +GitHub project page +.UE . +.\" ---------------------------------------------------------------------------- +.SH AUTHORS +\fBdosfstools\fR were written by +.MT werner.almesberger@\:lrc.di.epfl.ch +Werner Almesberger +.ME , +.MT Roman.Hodek@\:informatik.\:uni-erlangen.de +Roman Hodek +.ME , +and others. +The current maintainer is +.MT aeb@\:debian.org +Andreas Bombe +.ME . diff --git a/dosfstools/manpages/en/fsck.fat.8 b/dosfstools/manpages/en/fsck.fat.8 new file mode 100644 index 000000000..f2d44d080 --- /dev/null +++ b/dosfstools/manpages/en/fsck.fat.8 @@ -0,0 +1,206 @@ +.\" fsck.fat.8 - manpage for fsck.fat +.\" +.\" Copyright (C) 2006-2014 Daniel Baumann <daniel@debian.org> +.\" +.\" This program is free software: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 3 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see <http://www.gnu.org/licenses/>. +.\" +.\" The complete text of the GNU General Public License +.\" can be found in /usr/share/common-licenses/GPL-3 file. +.\" +.\" +.TH FSCK.FAT 8 2015\-05\-16 3.0.28 "dosfstools" +.SH NAME +\fBfsck.fat\fR \- check and repair MS\-DOS filesystems +.\" ---------------------------------------------------------------------------- +.SH SYNOPSIS +\fBfsck.fat\fR [\fIOPTIONS\fR] \fIDEVICE\fR +.\" ---------------------------------------------------------------------------- +.SH DESCRIPTION +\fBfsck.fat\fR verifies the consistency of MS\-DOS filesystems and optionally +tries to repair them. +.PP +The following filesystem problems can be corrected (in this order): +.IP "*" 4 +FAT contains invalid cluster numbers. +Cluster is changed to EOF. +.IP "*" 4 +File's cluster chain contains a loop. +The loop is broken. +.IP "*" 4 +Bad clusters (read errors). +The clusters are marked bad and they are removed from files owning them. +This check is optional. +.IP "*" 4 +Directories with a large number of bad entries (probably corrupt). +The directory can be deleted. +.IP "*" 4 +Files . and .. are non\-directories. +They can be deleted or renamed. +.IP "*" 4 +Directories . and .. in root directory. +They are deleted. +.IP "*" 4 +Bad filenames. +They can be renamed. +.IP "*" 4 +Duplicate directory entries. +They can be deleted or renamed. +.IP "*" 4 +Directories with non\-zero size field. +Size is set to zero. +.IP "*" 4 +Directory . does not point to parent directory. +The start pointer is adjusted. +.IP "*" 4 +Directory .. does not point to parent of parent directory. +The start pointer is adjusted. +.IP "*" 4 +Start cluster number of a file is invalid. +The file is truncated. +.IP "*" 4 +File contains bad or free clusters. +The file is truncated. +.IP "*" 4 +File's cluster chain is longer than indicated by the size fields. +The file is truncated. +.IP "*" 4 +Two or more files share the same cluster(s). +All but one of the files are truncated. +If the file being truncated is a directory file that has already been read, the +filesystem check is restarted after truncation. +.IP "*" 4 +File's cluster chain is shorter than indicated by the size fields. +The file is truncated. +.IP "*" 4 +Clusters are marked as used but are not owned by a file. +They are marked as free. +.PP +Additionally, the following problems are detected, but not repaired: +.IP "*" 4 +Invalid parameters in boot sector +.IP "*" 4 +Absence of . and .. entries in non\-root directories +.PP +When \fBfsck.fat\fR checks a filesystem, it accumulates all changes in memory +and performs them only after all checks are complete. +This can be disabled with the \fB\-w\fR option. +.\" ---------------------------------------------------------------------------- +.SH OPTIONS +.IP "\fB\-a\fR" 4 +Automatically repair the filesystem. +No user intervention is necessary. +Whenever there is more than one method to solve a problem, the least +destructive approach is used. +.IP "\fB\-A\fR" 4 +Use Atari variation of the MS\-DOS filesystem. +This is default if \fBfsck.fat\fR is run on an Atari, then this option turns +off Atari format. +There are some minor differences in Atari format: +Some boot sector fields are interpreted slightly different, and the special FAT +entries for end\-of\-file and bad cluster can be different. +Under MS\-DOS 0xfff8 is used for EOF and Atari employs 0xffff by default, but +both systems recognize all values from 0xfff8...0xffff as end\-of\-file. +MS\-DOS uses only 0xfff7 for bad clusters, where on Atari values 0xfff0...0xfff7 +are for this purpose (but the standard value is still 0xfff7). +.IP "\fB-b\fR" 4 +Make read-only boot sector check. +.IP "\fB\-d\fR \fIPATH\fR" 4 +Delete the specified file. +If more than one file with that name exist, the first one is deleted. +This option can be given more than once. +.IP "\fB\-f\fR" 4 +Salvage unused cluster chains to files. +By default, unused clusters are added to the free disk space except in auto mode +(\fB\-a\fR). +.IP "\fB\-l\fR" 4 +List path names of files being processed. +.IP "\fB\-n\fR" 4 +No\-operation mode: non\-interactively check for errors, but don't write +anything to the filesystem. +.IP "\fB\-p\fR" 4 +Same as \fB\-a\fR, for compatibility with other *fsck. +.IP "\fB\-r\fR" 4 +Interactively repair the filesystem. +The user is asked for advice whenever there is more than one approach to fix an +inconsistency. +This is the default mode and the option is only retained for backwards +compatibility. +.IP "\fB\-t\fR" 4 +Mark unreadable clusters as bad. +.IP "\fB\-u\fR \fIPATH\fR" 4 +Try to undelete the specified file. +\fBfsck.fat\fR tries to allocate a chain of contiguous unallocated clusters +beginning with the start cluster of the undeleted file. +This option can be given more than once. +.IP "\fB\-v\fR" 4 +Verbose mode. +Generates slightly more output. +.IP "\fB\-V\fR" 4 +Perform a verification pass. +The filesystem check is repeated after the first run. +The second pass should never report any fixable errors. +It may take considerably longer than the first pass, because the first pass may +have generated long list of modifications that have to be scanned for each disk +read. +.IP "\fB\-w\fR" 4 +Write changes to disk immediately. +.IP "\fB\-y\fR" 4 +Same as \fB\-a\fR (automatically repair filesystem) for compatibility with other +fsck tools. +.\" ---------------------------------------------------------------------------- +.SH "EXIT STATUS" +.IP "0" 4 +No recoverable errors have been detected. +.IP "1" 4 +Recoverable errors have been detected or \fBfsck.fat\fR has discovered an +internal inconsistency. +.IP "2" 4 +Usage error. +\fBfsck.fat\fR did not access the filesystem. +.\" ---------------------------------------------------------------------------- +.SH FILES +.IP "fsck0000.rec, fsck0001.rec, ..." 4 +When recovering from a corrupted filesystem, \fBfsck.fat\fR dumps recovered data +into files named 'fsckNNNN.rec' in the top level directory of the filesystem. +.\" ---------------------------------------------------------------------------- +.SH BUGS +Does not create . and .. files where necessary. +Does not remove entirely empty directories. +Should give more diagnostic messages. +Undeleting files should use a more sophisticated algorithm. +.\" ---------------------------------------------------------------------------- +.SH SEE ALSO +\fBfatlabel\fR(8) +.br +\fBmkfs.fat\fR(8) +.\" ---------------------------------------------------------------------------- +.SH HOMEPAGE +The home for the \fBdosfstools\fR project is its +.UR https://github.com/dosfstools/dosfstools +GitHub project page +.UE . +.\" ---------------------------------------------------------------------------- +.SH AUTHORS +\fBdosfstools\fR were written by +.MT werner.almesberger@\:lrc.di.epfl.ch +Werner Almesberger +.ME , +.MT Roman.Hodek@\:informatik.\:uni-erlangen.de +Roman Hodek +.ME , +and others. +The current maintainer is +.MT aeb@\:debian.org +Andreas Bombe +.ME . diff --git a/dosfstools/manpages/en/mkfs.fat.8 b/dosfstools/manpages/en/mkfs.fat.8 new file mode 100644 index 000000000..5a5086efc --- /dev/null +++ b/dosfstools/manpages/en/mkfs.fat.8 @@ -0,0 +1,178 @@ +.\" mkfs.fat.8 - manpage for fs.fatck +.\" +.\" Copyright (C) 2006-2014 Daniel Baumann <daniel@debian.org> +.\" +.\" This program is free software: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 3 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see <http://www.gnu.org/licenses/>. +.\" +.\" The complete text of the GNU General Public License +.\" can be found in /usr/share/common-licenses/GPL-3 file. +.\" +.\" +.TH MKFS.FAT 8 2015\-05\-16 3.0.28 "dosfstools" +.SH NAME +\fBmkfs.fat\fR \- create an MS-DOS filesystem under Linux +.\" ---------------------------------------------------------------------------- +.SH SYNOPSIS +\fBmkfs.fat\fR [\fIOPTIONS\fR] \fIDEVICE\fR [\fIBLOCK-COUNT\fR] +.\" ---------------------------------------------------------------------------- +.SH DESCRIPTION +\fBmkfs.fat\fR is used to create an MS-DOS filesystem under Linux on a device +(usually a disk partition). +\fIDEVICE\fR is the special file corresponding to the device (e.g. /dev/sdXX). +\fIBLOCK-COUNT\fR is the number of blocks on the device. +If omitted, \fBmkfs.fat\fR automatically determines the filesystem size. +.\" ---------------------------------------------------------------------------- +.SH OPTIONS +.IP "\fB\-a\fR" 4 +Normally, for any filesystem except very small ones, \fBmkfs.fat\fR will align +all the data structures to cluster size, to make sure that as long as the +partition is properly aligned, so will all the data structures in the +filesystem. +This option disables alignment; this may provide a handful of additional +clusters of storage at the expense of a significant performance degradation on +RAIDs, flash media or large-sector hard disks. +.IP "\fB \-A\fR" 4 +Use Atari variation of the MS-DOS filesystem. +This is default if \fBmkfs.fat\fR is run on an Atari, then this option turns off +Atari format. +There are some differences when using Atari format: +If not directed otherwise by the user, \fBmkfs.fat\fR will always use 2 sectors +per cluster, since GEMDOS doesn't like other values very much. +It will also obey the maximum number of sectors GEMDOS can handle. +Larger filesystems are managed by raising the logical sector size. +Under Atari format, an Atari-compatible serial number for the filesystem is +generated, and a 12 bit FAT is used only for filesystems that have one of the +usual floppy sizes (720k, 1.2M, 1.44M, 2.88M), a 16 bit FAT otherwise. +This can be overridden with the \fB\-F\fR option. +Some PC-specific boot sector fields aren't written, and a boot message (option +\fB\-m\fR) is ignored. +.IP "\fB\-b\fR \fISECTOR-OF-BACKUP\fR" 4 +Selects the location of the backup boot sector for FAT32. +Default depends on number of reserved sectors, but usually is sector 6. +The backup must be within the range of reserved sectors. +.IP "\fB\-c" 4 +Check the device for bad blocks before creating the filesystem. +.IP "\fB\-C\fR" 4 +Create the file given as \fIDEVICE\fR on the command line, and write the +to-be-created filesystem to it. +This can be used to create the new filesystem in a file instead of on a real +device, and to avoid using \fBdd\fR in advance to create a file of appropriate +size. +With this option, the \fIBLOCK-COUNT\fR must be given, because otherwise the +intended size of the filesystem wouldn't be known. +The file created is a sparse file, which actually only contains the meta-data +areas (boot sector, FATs, and root directory). +The data portions won't be stored on the disk, but the file nevertheless will +have the correct size. +The resulting file can be copied later to a floppy disk or other device, or +mounted through a loop device. +.IP "\fB\-D\fR \fIDRIVE-NUMBER\fR" 4 +Specify the BIOS drive number to be stored in the FAT boot sector. +This value is usually 0x80 for hard disks and 0x00 for floppy devices or +partitions to be used for floppy emulation. +.IP "\fB\-f\fR \fINUMBER-OF-FATS\fR" 4 +Specify the number of file allocation tables in the filesystem. +The default is 2. +.IP "\fB\-F\fR \fIFAT-SIZE\fR" 4 +Specifies the type of file allocation tables used (12, 16 or 32 bit). +If nothing is specified, \fBmkfs.fat\fR will automatically select between 12, 16 +and 32 bit, whatever fits better for the filesystem size. +.IP "\fB\-h\fR \fINUMBER-OF-HIDDEN-SECTORS\fR" 4 +Select the number of hidden sectors in the volume. +Apparently some digital cameras get indigestion if you feed them a CF card +without such hidden sectors, this option allows you to satisfy them. +.IP "\fB\-i\fR \fIVOLUME-ID\fR" 4 +Sets the volume ID of the newly created filesystem; \fIVOLUME-ID\fR is a 32-bit +hexadecimal number (for example, 2e24ec82). +The default is a number which depends on the filesystem creation time. +.IP "\fB\-I\fR" 4 +It is typical for fixed disk devices to be partitioned so, by default, you are +not permitted to create a filesystem across the entire device. +\fBmkfs.fat\fR will complain and tell you that it refuses to work. +This is different when using MO disks. +One doesn't always need partitions on MO disks. +The filesystem can go directly to the whole disk. +Under other OSes this is known as the 'superfloppy' format. +This switch will force \fBmkfs.fat\fR to work properly. +.IP "\fB\-l\fR \fIFILENAME\fR" 4 +Read the bad blocks list from \fIFILENAME\fR. +.IP "\fB\-m\fR \fIMESSAGE-FILE\fR" 4 +Sets the message the user receives on attempts to boot this filesystem without +having properly installed an operating system. +The message file must not exceed 418 bytes once line feeds have been converted +to carriage return-line feed combinations, and tabs have been expanded. +If the filename is a hyphen (-), the text is taken from standard input. +.IP "\fB\-M\fR \fIFAT-MEDIA-TYPE\fR" 4 +Specify the media type to be stored in the FAT boot sector. +This value is usually 0xF8 for hard disks and is 0xF0 or a value from 0xF9 to +0xFF for floppies or partitions to be used for floppy emulation. +.IP "\fB\-n\fR \fIVOLUME-NAME\fR" 4 +Sets the volume name (label) of the filesystem. +The volume name can be up to 11 characters long. +The default is no label. +.IP "\fB\-r\fR \fIROOT-DIR-ENTRIES\fR" 4 +Select the number of entries available in the root directory. +The default is 112 or 224 for floppies and 512 for hard disks. +.IP "\fB\-R\fR \fINUMBER-OF-RESERVED-SECTORS\fR" 4 +Select the number of reserved sectors. +With FAT32 format at least 2 reserved sectors are needed, the default is 32. +Otherwise the default is 1 (only the boot sector). +.IP "\fB\-s\fR \fISECTORS-PER-CLUSTER\fR" 4 +Specify the number of disk sectors per cluster. +Must be a power of 2, i.e. 1, 2, 4, 8, ... 128. +.IP "\fB\-S\fR \fILOGICAL-SECTOR-SIZE\fR" 4 +Specify the number of bytes per logical sector. +Must be a power of 2 and greater than or equal to 512, i.e. 512, 1024, 2048, +4096, 8192, 16384, or 32768. +.IP "\fB\-v\fR" 4 +Verbose execution. +.IP "\fB\-\-invariant\fR" 4 +Use constants for normally randomly generated or time based data such as +volume ID and creation time. +Multiple runs of \fBmkfs.fat\fR on the same device create identical results +with this option. +Its main purpose is testing \fBmkfs.fat\fR. +.IP "\fB\-\-help\fR" 4 +Display option summary and exit. +.\" ---------------------------------------------------------------------------- +.SH BUGS +\fBmkfs.fat\fR can not create boot-able filesystems. +This isn't as easy as you might think at first glance for various reasons and +has been discussed a lot already. +\fBmkfs.fat\fR simply will not support it ;) +.\" ---------------------------------------------------------------------------- +.SH SEE ALSO +\fBfatlabel\fR(8) +.br +\fBfsck.fat\fR(8) +.\" ---------------------------------------------------------------------------- +.SH HOMEPAGE +The home for the \fBdosfstools\fR project is its +.UR https://github.com/dosfstools/dosfstools +GitHub project page +.UE . +.\" ---------------------------------------------------------------------------- +.SH AUTHORS +\fBdosfstools\fR were written by +.MT werner.almesberger@\:lrc.di.epfl.ch +Werner Almesberger +.ME , +.MT Roman.Hodek@\:informatik.\:uni-erlangen.de +Roman Hodek +.ME , +and others. +The current maintainer is +.MT aeb@\:debian.org +Andreas Bombe +.ME . diff --git a/dosfstools/manpages/po/de/fatlabel.8.po b/dosfstools/manpages/po/de/fatlabel.8.po new file mode 100644 index 000000000..a2b6da2e8 --- /dev/null +++ b/dosfstools/manpages/po/de/fatlabel.8.po @@ -0,0 +1,173 @@ +# German translations for dosfstools package +# +msgid "" +msgstr "" +"Project-Id-Version: dosfstools VERSION\n" +"POT-Creation-Date: 2015-05-16 00:40+0200\n" +"PO-Revision-Date: 2013-06-06 09:34+0300\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ASCII\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: TH +#: en/fatlabel.8:22 +#, no-wrap +msgid "FATLABEL" +msgstr "" + +#. type: TH +#: en/fatlabel.8:22 en/fsck.fat.8:22 en/mkfs.fat.8:22 +#, no-wrap +msgid "2015-05-16" +msgstr "" + +#. type: TH +#: en/fatlabel.8:22 en/fsck.fat.8:22 en/mkfs.fat.8:22 +#, no-wrap +msgid "3.0.28" +msgstr "" + +#. type: TH +#: en/fatlabel.8:22 en/fsck.fat.8:22 en/mkfs.fat.8:22 +#, no-wrap +msgid "dosfstools" +msgstr "" + +#. type: SH +#: en/fatlabel.8:23 en/fsck.fat.8:23 en/mkfs.fat.8:23 +#, no-wrap +msgid "NAME" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fatlabel.8:26 +msgid "B<fatlabel> - set or get MS-DOS filesystem label" +msgstr "" + +#. type: SH +#: en/fatlabel.8:26 en/fsck.fat.8:26 en/mkfs.fat.8:26 +#, no-wrap +msgid "SYNOPSIS" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fatlabel.8:29 +msgid "B<fatlabel> I<DEVICE> [I<LABEL>]" +msgstr "" + +#. type: SH +#: en/fatlabel.8:29 en/fsck.fat.8:29 en/mkfs.fat.8:29 +#, no-wrap +msgid "DESCRIPTION" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:31 +msgid "B<fatlabel> set or gets a MS-DOS filesystem label from a given device." +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fatlabel.8:36 +msgid "" +"If I<LABEL> is omitted, then the label name of the specified device is " +"written on the standard output. A label can't be longer than 11 bytes." +msgstr "" + +#. type: SH +#: en/fatlabel.8:36 en/fsck.fat.8:99 en/mkfs.fat.8:36 +#, no-wrap +msgid "OPTIONS" +msgstr "" + +#. type: IP +#: en/fatlabel.8:37 +#, no-wrap +msgid "B<-h>, B<--help>" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:39 +msgid "Displays a help message." +msgstr "" + +#. type: IP +#: en/fatlabel.8:39 +#, no-wrap +msgid "B<-V>, B<--version>" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fatlabel.8:42 +msgid "Shows version." +msgstr "" + +#. type: SH +#: en/fatlabel.8:42 en/fsck.fat.8:183 en/mkfs.fat.8:155 +#, no-wrap +msgid "SEE ALSO" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fatlabel.8:44 en/mkfs.fat.8:160 +msgid "B<fsck.fat>(8)" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fatlabel.8:47 en/fsck.fat.8:188 +msgid "B<mkfs.fat>(8)" +msgstr "" + +#. type: SH +#: en/fatlabel.8:47 en/fsck.fat.8:188 en/mkfs.fat.8:160 +#, no-wrap +msgid "HOMEPAGE" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fatlabel.8:53 en/fsck.fat.8:194 en/mkfs.fat.8:166 +msgid "" +"The home for the B<dosfstools> project is its E<.UR https://github.com/" +"dosfstools/dosfstools> GitHub project page E<.UE .>" +msgstr "" + +#. type: SH +#: en/fatlabel.8:53 en/fsck.fat.8:194 en/mkfs.fat.8:166 +#, no-wrap +msgid "AUTHORS" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:55 en/fsck.fat.8:196 en/mkfs.fat.8:168 +msgid "B<dosfstools> were written by" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:57 en/fsck.fat.8:198 en/mkfs.fat.8:170 +msgid "Werner Almesberger" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:60 en/fsck.fat.8:201 en/mkfs.fat.8:173 +msgid "Roman Hodek" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:63 en/fsck.fat.8:204 en/mkfs.fat.8:176 +msgid "and others. The current maintainer is" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:65 en/fsck.fat.8:206 en/mkfs.fat.8:178 +msgid "Andreas Bombe" +msgstr "" diff --git a/dosfstools/manpages/po/de/fsck.fat.8.po b/dosfstools/manpages/po/de/fsck.fat.8.po new file mode 100644 index 000000000..1487e9ff2 --- /dev/null +++ b/dosfstools/manpages/po/de/fsck.fat.8.po @@ -0,0 +1,559 @@ +# German translations for dosfstools package +# +msgid "" +msgstr "" +"Project-Id-Version: dosfstools VERSION\n" +"POT-Creation-Date: 2015-05-16 00:40+0200\n" +"PO-Revision-Date: 2013-06-06 09:34+0300\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ASCII\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: TH +#: en/fatlabel.8:22 en/fsck.fat.8:22 en/mkfs.fat.8:22 +#, no-wrap +msgid "2015-05-16" +msgstr "" + +#. type: TH +#: en/fatlabel.8:22 en/fsck.fat.8:22 en/mkfs.fat.8:22 +#, no-wrap +msgid "3.0.28" +msgstr "" + +#. type: TH +#: en/fatlabel.8:22 en/fsck.fat.8:22 en/mkfs.fat.8:22 +#, no-wrap +msgid "dosfstools" +msgstr "" + +#. type: SH +#: en/fatlabel.8:23 en/fsck.fat.8:23 en/mkfs.fat.8:23 +#, no-wrap +msgid "NAME" +msgstr "" + +#. type: SH +#: en/fatlabel.8:26 en/fsck.fat.8:26 en/mkfs.fat.8:26 +#, no-wrap +msgid "SYNOPSIS" +msgstr "" + +#. type: SH +#: en/fatlabel.8:29 en/fsck.fat.8:29 en/mkfs.fat.8:29 +#, no-wrap +msgid "DESCRIPTION" +msgstr "" + +#. type: SH +#: en/fatlabel.8:36 en/fsck.fat.8:99 en/mkfs.fat.8:36 +#, no-wrap +msgid "OPTIONS" +msgstr "" + +#. type: SH +#: en/fatlabel.8:42 en/fsck.fat.8:183 en/mkfs.fat.8:155 +#, no-wrap +msgid "SEE ALSO" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fatlabel.8:47 en/fsck.fat.8:188 +msgid "B<mkfs.fat>(8)" +msgstr "" + +#. type: SH +#: en/fatlabel.8:47 en/fsck.fat.8:188 en/mkfs.fat.8:160 +#, no-wrap +msgid "HOMEPAGE" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fatlabel.8:53 en/fsck.fat.8:194 en/mkfs.fat.8:166 +msgid "" +"The home for the B<dosfstools> project is its E<.UR https://github.com/" +"dosfstools/dosfstools> GitHub project page E<.UE .>" +msgstr "" + +#. type: SH +#: en/fatlabel.8:53 en/fsck.fat.8:194 en/mkfs.fat.8:166 +#, no-wrap +msgid "AUTHORS" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:55 en/fsck.fat.8:196 en/mkfs.fat.8:168 +msgid "B<dosfstools> were written by" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:57 en/fsck.fat.8:198 en/mkfs.fat.8:170 +msgid "Werner Almesberger" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:60 en/fsck.fat.8:201 en/mkfs.fat.8:173 +msgid "Roman Hodek" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:63 en/fsck.fat.8:204 en/mkfs.fat.8:176 +msgid "and others. The current maintainer is" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:65 en/fsck.fat.8:206 en/mkfs.fat.8:178 +msgid "Andreas Bombe" +msgstr "" + +#. type: TH +#: en/fsck.fat.8:22 +#, no-wrap +msgid "FSCK.FAT" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fsck.fat.8:26 +msgid "B<fsck.fat> - check and repair MS-DOS filesystems" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fsck.fat.8:29 +msgid "B<fsck.fat> [I<OPTIONS>] I<DEVICE>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:32 +msgid "" +"B<fsck.fat> verifies the consistency of MS-DOS filesystems and optionally " +"tries to repair them." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:34 +msgid "The following filesystem problems can be corrected (in this order):" +msgstr "" + +#. type: IP +#: en/fsck.fat.8:34 en/fsck.fat.8:37 en/fsck.fat.8:40 en/fsck.fat.8:44 +#: en/fsck.fat.8:47 en/fsck.fat.8:50 en/fsck.fat.8:53 en/fsck.fat.8:56 +#: en/fsck.fat.8:59 en/fsck.fat.8:62 en/fsck.fat.8:65 en/fsck.fat.8:68 +#: en/fsck.fat.8:71 en/fsck.fat.8:74 en/fsck.fat.8:77 en/fsck.fat.8:82 +#: en/fsck.fat.8:85 en/fsck.fat.8:90 en/fsck.fat.8:92 +#, no-wrap +msgid "*" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:37 +msgid "FAT contains invalid cluster numbers. Cluster is changed to EOF." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:40 +msgid "File's cluster chain contains a loop. The loop is broken." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:44 +msgid "" +"Bad clusters (read errors). The clusters are marked bad and they are " +"removed from files owning them. This check is optional." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:47 +msgid "" +"Directories with a large number of bad entries (probably corrupt). The " +"directory can be deleted." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:50 +msgid "Files . and .. are non-directories. They can be deleted or renamed." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:53 +msgid "Directories . and .. in root directory. They are deleted." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:56 +msgid "Bad filenames. They can be renamed." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:59 +msgid "Duplicate directory entries. They can be deleted or renamed." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:62 +msgid "Directories with non-zero size field. Size is set to zero." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:65 +msgid "" +"Directory . does not point to parent directory. The start pointer is " +"adjusted." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:68 +msgid "" +"Directory .. does not point to parent of parent directory. The start " +"pointer is adjusted." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:71 +msgid "Start cluster number of a file is invalid. The file is truncated." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:74 +msgid "File contains bad or free clusters. The file is truncated." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:77 +msgid "" +"File's cluster chain is longer than indicated by the size fields. The file " +"is truncated." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:82 +msgid "" +"Two or more files share the same cluster(s). All but one of the files are " +"truncated. If the file being truncated is a directory file that has already " +"been read, the filesystem check is restarted after truncation." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:85 +msgid "" +"File's cluster chain is shorter than indicated by the size fields. The file " +"is truncated." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:88 +msgid "" +"Clusters are marked as used but are not owned by a file. They are marked as " +"free." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:90 +msgid "Additionally, the following problems are detected, but not repaired:" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:92 +msgid "Invalid parameters in boot sector" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:94 +msgid "Absence of . and .. entries in non-root directories" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fsck.fat.8:99 +msgid "" +"When B<fsck.fat> checks a filesystem, it accumulates all changes in memory " +"and performs them only after all checks are complete. This can be disabled " +"with the B<-w> option." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:100 en/mkfs.fat.8:37 +#, no-wrap +msgid "B<-a>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:105 +msgid "" +"Automatically repair the filesystem. No user intervention is necessary. " +"Whenever there is more than one method to solve a problem, the least " +"destructive approach is used." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:105 +#, no-wrap +msgid "B<-A>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:116 +msgid "" +"Use Atari variation of the MS-DOS filesystem. This is default if B<fsck." +"fat> is run on an Atari, then this option turns off Atari format. There are " +"some minor differences in Atari format: Some boot sector fields are " +"interpreted slightly different, and the special FAT entries for end-of-file " +"and bad cluster can be different. Under MS-DOS 0xfff8 is used for EOF and " +"Atari employs 0xffff by default, but both systems recognize all values from " +"0xfff8...0xffff as end-of-file. MS-DOS uses only 0xfff7 for bad clusters, " +"where on Atari values 0xfff0...0xfff7 are for this purpose (but the standard " +"value is still 0xfff7)." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:116 +#, no-wrap +msgid "B<-b>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:118 +msgid "Make read-only boot sector check." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:118 +#, no-wrap +msgid "B<-d> I<PATH>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:122 +msgid "" +"Delete the specified file. If more than one file with that name exist, the " +"first one is deleted. This option can be given more than once." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:122 +#, no-wrap +msgid "B<-f>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:126 +msgid "" +"Salvage unused cluster chains to files. By default, unused clusters are " +"added to the free disk space except in auto mode (B<-a>)." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:126 +#, no-wrap +msgid "B<-l>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:128 +msgid "List path names of files being processed." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:128 +#, no-wrap +msgid "B<-n>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:131 +msgid "" +"No-operation mode: non-interactively check for errors, but don't write " +"anything to the filesystem." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:131 +#, no-wrap +msgid "B<-p>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:133 +msgid "Same as B<-a>, for compatibility with other *fsck." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:133 +#, no-wrap +msgid "B<-r>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:139 +msgid "" +"Interactively repair the filesystem. The user is asked for advice whenever " +"there is more than one approach to fix an inconsistency. This is the " +"default mode and the option is only retained for backwards compatibility." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:139 +#, no-wrap +msgid "B<-t>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:141 +msgid "Mark unreadable clusters as bad." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:141 +#, no-wrap +msgid "B<-u> I<PATH>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:146 +msgid "" +"Try to undelete the specified file. B<fsck.fat> tries to allocate a chain " +"of contiguous unallocated clusters beginning with the start cluster of the " +"undeleted file. This option can be given more than once." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:146 en/mkfs.fat.8:138 +#, no-wrap +msgid "B<-v>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:149 +msgid "Verbose mode. Generates slightly more output." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:149 +#, no-wrap +msgid "B<-V>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:156 +msgid "" +"Perform a verification pass. The filesystem check is repeated after the " +"first run. The second pass should never report any fixable errors. It may " +"take considerably longer than the first pass, because the first pass may " +"have generated long list of modifications that have to be scanned for each " +"disk read." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:156 +#, no-wrap +msgid "B<-w>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:158 +msgid "Write changes to disk immediately." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:158 +#, no-wrap +msgid "B<-y>" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fsck.fat.8:162 +msgid "" +"Same as B<-a> (automatically repair filesystem) for compatibility with other " +"fsck tools." +msgstr "" + +#. type: SH +#: en/fsck.fat.8:162 +#, no-wrap +msgid "EXIT STATUS" +msgstr "" + +#. type: IP +#: en/fsck.fat.8:163 +#, no-wrap +msgid "0" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:165 +msgid "No recoverable errors have been detected." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:165 +#, no-wrap +msgid "1" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:168 +msgid "" +"Recoverable errors have been detected or B<fsck.fat> has discovered an " +"internal inconsistency." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:168 +#, no-wrap +msgid "2" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fsck.fat.8:172 +msgid "Usage error. B<fsck.fat> did not access the filesystem." +msgstr "" + +#. type: SH +#: en/fsck.fat.8:172 +#, no-wrap +msgid "FILES" +msgstr "" + +#. type: IP +#: en/fsck.fat.8:173 +#, no-wrap +msgid "fsck0000.rec, fsck0001.rec, ..." +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fsck.fat.8:177 +msgid "" +"When recovering from a corrupted filesystem, B<fsck.fat> dumps recovered " +"data into files named 'fsckNNNN.rec' in the top level directory of the " +"filesystem." +msgstr "" + +#. type: SH +#: en/fsck.fat.8:177 en/mkfs.fat.8:149 +#, no-wrap +msgid "BUGS" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fsck.fat.8:183 +msgid "" +"Does not create . and .. files where necessary. Does not remove entirely " +"empty directories. Should give more diagnostic messages. Undeleting files " +"should use a more sophisticated algorithm." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:185 en/mkfs.fat.8:157 +msgid "B<fatlabel>(8)" +msgstr "" diff --git a/dosfstools/manpages/po/de/mkfs.fat.8.po b/dosfstools/manpages/po/de/mkfs.fat.8.po new file mode 100644 index 000000000..3344f71a1 --- /dev/null +++ b/dosfstools/manpages/po/de/mkfs.fat.8.po @@ -0,0 +1,481 @@ +# German translations for dosfstools package +# +msgid "" +msgstr "" +"Project-Id-Version: dosfstools VERSION\n" +"POT-Creation-Date: 2015-05-16 00:40+0200\n" +"PO-Revision-Date: 2013-06-06 09:34+0300\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ASCII\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. type: TH +#: en/fatlabel.8:22 en/fsck.fat.8:22 en/mkfs.fat.8:22 +#, no-wrap +msgid "2015-05-16" +msgstr "" + +#. type: TH +#: en/fatlabel.8:22 en/fsck.fat.8:22 en/mkfs.fat.8:22 +#, no-wrap +msgid "3.0.28" +msgstr "" + +#. type: TH +#: en/fatlabel.8:22 en/fsck.fat.8:22 en/mkfs.fat.8:22 +#, no-wrap +msgid "dosfstools" +msgstr "" + +#. type: SH +#: en/fatlabel.8:23 en/fsck.fat.8:23 en/mkfs.fat.8:23 +#, no-wrap +msgid "NAME" +msgstr "" + +#. type: SH +#: en/fatlabel.8:26 en/fsck.fat.8:26 en/mkfs.fat.8:26 +#, no-wrap +msgid "SYNOPSIS" +msgstr "" + +#. type: SH +#: en/fatlabel.8:29 en/fsck.fat.8:29 en/mkfs.fat.8:29 +#, no-wrap +msgid "DESCRIPTION" +msgstr "" + +#. type: SH +#: en/fatlabel.8:36 en/fsck.fat.8:99 en/mkfs.fat.8:36 +#, no-wrap +msgid "OPTIONS" +msgstr "" + +#. type: SH +#: en/fatlabel.8:42 en/fsck.fat.8:183 en/mkfs.fat.8:155 +#, no-wrap +msgid "SEE ALSO" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fatlabel.8:44 en/mkfs.fat.8:160 +msgid "B<fsck.fat>(8)" +msgstr "" + +#. type: SH +#: en/fatlabel.8:47 en/fsck.fat.8:188 en/mkfs.fat.8:160 +#, no-wrap +msgid "HOMEPAGE" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fatlabel.8:53 en/fsck.fat.8:194 en/mkfs.fat.8:166 +msgid "" +"The home for the B<dosfstools> project is its E<.UR https://github.com/" +"dosfstools/dosfstools> GitHub project page E<.UE .>" +msgstr "" + +#. type: SH +#: en/fatlabel.8:53 en/fsck.fat.8:194 en/mkfs.fat.8:166 +#, no-wrap +msgid "AUTHORS" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:55 en/fsck.fat.8:196 en/mkfs.fat.8:168 +msgid "B<dosfstools> were written by" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:57 en/fsck.fat.8:198 en/mkfs.fat.8:170 +msgid "Werner Almesberger" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:60 en/fsck.fat.8:201 en/mkfs.fat.8:173 +msgid "Roman Hodek" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:63 en/fsck.fat.8:204 en/mkfs.fat.8:176 +msgid "and others. The current maintainer is" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:65 en/fsck.fat.8:206 en/mkfs.fat.8:178 +msgid "Andreas Bombe" +msgstr "" + +#. type: IP +#: en/fsck.fat.8:100 en/mkfs.fat.8:37 +#, no-wrap +msgid "B<-a>" +msgstr "" + +#. type: IP +#: en/fsck.fat.8:146 en/mkfs.fat.8:138 +#, no-wrap +msgid "B<-v>" +msgstr "" + +#. type: SH +#: en/fsck.fat.8:177 en/mkfs.fat.8:149 +#, no-wrap +msgid "BUGS" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:185 en/mkfs.fat.8:157 +msgid "B<fatlabel>(8)" +msgstr "" + +#. type: TH +#: en/mkfs.fat.8:22 +#, no-wrap +msgid "MKFS.FAT" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/mkfs.fat.8:26 +msgid "B<mkfs.fat> - create an MS-DOS filesystem under Linux" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/mkfs.fat.8:29 +msgid "B<mkfs.fat> [I<OPTIONS>] I<DEVICE> [I<BLOCK-COUNT>]" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/mkfs.fat.8:36 +msgid "" +"B<mkfs.fat> is used to create an MS-DOS filesystem under Linux on a device " +"(usually a disk partition). I<DEVICE> is the special file corresponding to " +"the device (e.g. /dev/sdXX). I<BLOCK-COUNT> is the number of blocks on the " +"device. If omitted, B<mkfs.fat> automatically determines the filesystem " +"size." +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:45 +msgid "" +"Normally, for any filesystem except very small ones, B<mkfs.fat> will align " +"all the data structures to cluster size, to make sure that as long as the " +"partition is properly aligned, so will all the data structures in the " +"filesystem. This option disables alignment; this may provide a handful of " +"additional clusters of storage at the expense of a significant performance " +"degradation on RAIDs, flash media or large-sector hard disks." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:45 +#, no-wrap +msgid "B< -A>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:60 +msgid "" +"Use Atari variation of the MS-DOS filesystem. This is default if B<mkfs." +"fat> is run on an Atari, then this option turns off Atari format. There are " +"some differences when using Atari format: If not directed otherwise by the " +"user, B<mkfs.fat> will always use 2 sectors per cluster, since GEMDOS " +"doesn't like other values very much. It will also obey the maximum number " +"of sectors GEMDOS can handle. Larger filesystems are managed by raising the " +"logical sector size. Under Atari format, an Atari-compatible serial number " +"for the filesystem is generated, and a 12 bit FAT is used only for " +"filesystems that have one of the usual floppy sizes (720k, 1.2M, 1.44M, " +"2.88M), a 16 bit FAT otherwise. This can be overridden with the B<-F> " +"option. Some PC-specific boot sector fields aren't written, and a boot " +"message (option B<-m>) is ignored." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:60 +#, no-wrap +msgid "B<-b> I<SECTOR-OF-BACKUP>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:64 +msgid "" +"Selects the location of the backup boot sector for FAT32. Default depends " +"on number of reserved sectors, but usually is sector 6. The backup must be " +"within the range of reserved sectors." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:64 +#, no-wrap +msgid "B<-c>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:66 +msgid "Check the device for bad blocks before creating the filesystem." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:66 +#, no-wrap +msgid "B<-C>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:80 +msgid "" +"Create the file given as I<DEVICE> on the command line, and write the to-be-" +"created filesystem to it. This can be used to create the new filesystem in " +"a file instead of on a real device, and to avoid using B<dd> in advance to " +"create a file of appropriate size. With this option, the I<BLOCK-COUNT> " +"must be given, because otherwise the intended size of the filesystem " +"wouldn't be known. The file created is a sparse file, which actually only " +"contains the meta-data areas (boot sector, FATs, and root directory). The " +"data portions won't be stored on the disk, but the file nevertheless will " +"have the correct size. The resulting file can be copied later to a floppy " +"disk or other device, or mounted through a loop device." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:80 +#, no-wrap +msgid "B<-D> I<DRIVE-NUMBER>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:84 +msgid "" +"Specify the BIOS drive number to be stored in the FAT boot sector. This " +"value is usually 0x80 for hard disks and 0x00 for floppy devices or " +"partitions to be used for floppy emulation." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:84 +#, no-wrap +msgid "B<-f> I<NUMBER-OF-FATS>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:87 +msgid "" +"Specify the number of file allocation tables in the filesystem. The default " +"is 2." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:87 +#, no-wrap +msgid "B<-F> I<FAT-SIZE>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:91 +msgid "" +"Specifies the type of file allocation tables used (12, 16 or 32 bit). If " +"nothing is specified, B<mkfs.fat> will automatically select between 12, 16 " +"and 32 bit, whatever fits better for the filesystem size." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:91 +#, no-wrap +msgid "B<-h> I<NUMBER-OF-HIDDEN-SECTORS>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:95 +msgid "" +"Select the number of hidden sectors in the volume. Apparently some digital " +"cameras get indigestion if you feed them a CF card without such hidden " +"sectors, this option allows you to satisfy them." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:95 +#, no-wrap +msgid "B<-i> I<VOLUME-ID>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:99 +msgid "" +"Sets the volume ID of the newly created filesystem; I<VOLUME-ID> is a 32-bit " +"hexadecimal number (for example, 2e24ec82). The default is a number which " +"depends on the filesystem creation time." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:99 +#, no-wrap +msgid "B<-I>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:108 +msgid "" +"It is typical for fixed disk devices to be partitioned so, by default, you " +"are not permitted to create a filesystem across the entire device. B<mkfs." +"fat> will complain and tell you that it refuses to work. This is different " +"when using MO disks. One doesn't always need partitions on MO disks. The " +"filesystem can go directly to the whole disk. Under other OSes this is " +"known as the 'superfloppy' format. This switch will force B<mkfs.fat> to " +"work properly." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:108 +#, no-wrap +msgid "B<-l> I<FILENAME>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:110 +msgid "Read the bad blocks list from I<FILENAME>." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:110 +#, no-wrap +msgid "B<-m> I<MESSAGE-FILE>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:116 +msgid "" +"Sets the message the user receives on attempts to boot this filesystem " +"without having properly installed an operating system. The message file " +"must not exceed 418 bytes once line feeds have been converted to carriage " +"return-line feed combinations, and tabs have been expanded. If the filename " +"is a hyphen (-), the text is taken from standard input." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:116 +#, no-wrap +msgid "B<-M> I<FAT-MEDIA-TYPE>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:120 +msgid "" +"Specify the media type to be stored in the FAT boot sector. This value is " +"usually 0xF8 for hard disks and is 0xF0 or a value from 0xF9 to 0xFF for " +"floppies or partitions to be used for floppy emulation." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:120 +#, no-wrap +msgid "B<-n> I<VOLUME-NAME>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:124 +msgid "" +"Sets the volume name (label) of the filesystem. The volume name can be up " +"to 11 characters long. The default is no label." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:124 +#, no-wrap +msgid "B<-r> I<ROOT-DIR-ENTRIES>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:127 +msgid "" +"Select the number of entries available in the root directory. The default " +"is 112 or 224 for floppies and 512 for hard disks." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:127 +#, no-wrap +msgid "B<-R> I<NUMBER-OF-RESERVED-SECTORS>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:131 +msgid "" +"Select the number of reserved sectors. With FAT32 format at least 2 " +"reserved sectors are needed, the default is 32. Otherwise the default is 1 " +"(only the boot sector)." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:131 +#, no-wrap +msgid "B<-s> I<SECTORS-PER-CLUSTER>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:134 +msgid "" +"Specify the number of disk sectors per cluster. Must be a power of 2, i.e. " +"1, 2, 4, 8, ... 128." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:134 +#, no-wrap +msgid "B<-S> I<LOGICAL-SECTOR-SIZE>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:138 +msgid "" +"Specify the number of bytes per logical sector. Must be a power of 2 and " +"greater than or equal to 512, i.e. 512, 1024, 2048, 4096, 8192, 16384, or " +"32768." +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:140 +msgid "Verbose execution." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:140 +#, no-wrap +msgid "B<--invariant>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:146 +msgid "" +"Use constants for normally randomly generated or time based data such as " +"volume ID and creation time. Multiple runs of B<mkfs.fat> on the same " +"device create identical results with this option. Its main purpose is " +"testing B<mkfs.fat>." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:146 +#, no-wrap +msgid "B<--help>" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/mkfs.fat.8:149 +msgid "Display option summary and exit." +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/mkfs.fat.8:155 +msgid "" +"B<mkfs.fat> can not create boot-able filesystems. This isn't as easy as you " +"might think at first glance for various reasons and has been discussed a lot " +"already. B<mkfs.fat> simply will not support it ;)" +msgstr "" diff --git a/dosfstools/manpages/po4a.cfg b/dosfstools/manpages/po4a.cfg new file mode 100644 index 000000000..5d16f636c --- /dev/null +++ b/dosfstools/manpages/po4a.cfg @@ -0,0 +1,5 @@ +[po4a_langs] de +[po4a_paths] pot/$master.pot $lang:po/$lang/$master.po +[type: man] en/fatlabel.8 $lang:$lang/fatlabel.$lang.8 +[type: man] en/fsck.fat.8 $lang:$lang/fsck.fat.$lang.8 +[type: man] en/mkfs.fat.8 $lang:$lang/mkfs.fat.$lang.8 diff --git a/dosfstools/manpages/pot/fatlabel.8.pot b/dosfstools/manpages/pot/fatlabel.8.pot new file mode 100644 index 000000000..2eafa05eb --- /dev/null +++ b/dosfstools/manpages/pot/fatlabel.8.pot @@ -0,0 +1,176 @@ +# SOME DESCRIPTIVE TITLE +# Copyright (C) YEAR Free Software Foundation, Inc. +# This file is distributed under the same license as the dosfstools package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: dosfstools VERSION\n" +"POT-Creation-Date: 2015-05-16 00:40+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: TH +#: en/fatlabel.8:22 +#, no-wrap +msgid "FATLABEL" +msgstr "" + +#. type: TH +#: en/fatlabel.8:22 en/fsck.fat.8:22 en/mkfs.fat.8:22 +#, no-wrap +msgid "2015-05-16" +msgstr "" + +#. type: TH +#: en/fatlabel.8:22 en/fsck.fat.8:22 en/mkfs.fat.8:22 +#, no-wrap +msgid "3.0.28" +msgstr "" + +#. type: TH +#: en/fatlabel.8:22 en/fsck.fat.8:22 en/mkfs.fat.8:22 +#, no-wrap +msgid "dosfstools" +msgstr "" + +#. type: SH +#: en/fatlabel.8:23 en/fsck.fat.8:23 en/mkfs.fat.8:23 +#, no-wrap +msgid "NAME" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fatlabel.8:26 +msgid "B<fatlabel> - set or get MS-DOS filesystem label" +msgstr "" + +#. type: SH +#: en/fatlabel.8:26 en/fsck.fat.8:26 en/mkfs.fat.8:26 +#, no-wrap +msgid "SYNOPSIS" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fatlabel.8:29 +msgid "B<fatlabel> I<DEVICE> [I<LABEL>]" +msgstr "" + +#. type: SH +#: en/fatlabel.8:29 en/fsck.fat.8:29 en/mkfs.fat.8:29 +#, no-wrap +msgid "DESCRIPTION" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:31 +msgid "B<fatlabel> set or gets a MS-DOS filesystem label from a given device." +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fatlabel.8:36 +msgid "" +"If I<LABEL> is omitted, then the label name of the specified device is " +"written on the standard output. A label can't be longer than 11 bytes." +msgstr "" + +#. type: SH +#: en/fatlabel.8:36 en/fsck.fat.8:99 en/mkfs.fat.8:36 +#, no-wrap +msgid "OPTIONS" +msgstr "" + +#. type: IP +#: en/fatlabel.8:37 +#, no-wrap +msgid "B<-h>, B<--help>" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:39 +msgid "Displays a help message." +msgstr "" + +#. type: IP +#: en/fatlabel.8:39 +#, no-wrap +msgid "B<-V>, B<--version>" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fatlabel.8:42 +msgid "Shows version." +msgstr "" + +#. type: SH +#: en/fatlabel.8:42 en/fsck.fat.8:183 en/mkfs.fat.8:155 +#, no-wrap +msgid "SEE ALSO" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fatlabel.8:44 en/mkfs.fat.8:160 +msgid "B<fsck.fat>(8)" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fatlabel.8:47 en/fsck.fat.8:188 +msgid "B<mkfs.fat>(8)" +msgstr "" + +#. type: SH +#: en/fatlabel.8:47 en/fsck.fat.8:188 en/mkfs.fat.8:160 +#, no-wrap +msgid "HOMEPAGE" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fatlabel.8:53 en/fsck.fat.8:194 en/mkfs.fat.8:166 +msgid "" +"The home for the B<dosfstools> project is its E<.UR https://github.com/" +"dosfstools/dosfstools> GitHub project page E<.UE .>" +msgstr "" + +#. type: SH +#: en/fatlabel.8:53 en/fsck.fat.8:194 en/mkfs.fat.8:166 +#, no-wrap +msgid "AUTHORS" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:55 en/fsck.fat.8:196 en/mkfs.fat.8:168 +msgid "B<dosfstools> were written by" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:57 en/fsck.fat.8:198 en/mkfs.fat.8:170 +msgid "Werner Almesberger" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:60 en/fsck.fat.8:201 en/mkfs.fat.8:173 +msgid "Roman Hodek" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:63 en/fsck.fat.8:204 en/mkfs.fat.8:176 +msgid "and others. The current maintainer is" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:65 en/fsck.fat.8:206 en/mkfs.fat.8:178 +msgid "Andreas Bombe" +msgstr "" diff --git a/dosfstools/manpages/pot/fsck.fat.8.pot b/dosfstools/manpages/pot/fsck.fat.8.pot new file mode 100644 index 000000000..65ef52a66 --- /dev/null +++ b/dosfstools/manpages/pot/fsck.fat.8.pot @@ -0,0 +1,562 @@ +# SOME DESCRIPTIVE TITLE +# Copyright (C) YEAR Free Software Foundation, Inc. +# This file is distributed under the same license as the dosfstools package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: dosfstools VERSION\n" +"POT-Creation-Date: 2015-05-16 00:40+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: TH +#: en/fatlabel.8:22 en/fsck.fat.8:22 en/mkfs.fat.8:22 +#, no-wrap +msgid "2015-05-16" +msgstr "" + +#. type: TH +#: en/fatlabel.8:22 en/fsck.fat.8:22 en/mkfs.fat.8:22 +#, no-wrap +msgid "3.0.28" +msgstr "" + +#. type: TH +#: en/fatlabel.8:22 en/fsck.fat.8:22 en/mkfs.fat.8:22 +#, no-wrap +msgid "dosfstools" +msgstr "" + +#. type: SH +#: en/fatlabel.8:23 en/fsck.fat.8:23 en/mkfs.fat.8:23 +#, no-wrap +msgid "NAME" +msgstr "" + +#. type: SH +#: en/fatlabel.8:26 en/fsck.fat.8:26 en/mkfs.fat.8:26 +#, no-wrap +msgid "SYNOPSIS" +msgstr "" + +#. type: SH +#: en/fatlabel.8:29 en/fsck.fat.8:29 en/mkfs.fat.8:29 +#, no-wrap +msgid "DESCRIPTION" +msgstr "" + +#. type: SH +#: en/fatlabel.8:36 en/fsck.fat.8:99 en/mkfs.fat.8:36 +#, no-wrap +msgid "OPTIONS" +msgstr "" + +#. type: SH +#: en/fatlabel.8:42 en/fsck.fat.8:183 en/mkfs.fat.8:155 +#, no-wrap +msgid "SEE ALSO" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fatlabel.8:47 en/fsck.fat.8:188 +msgid "B<mkfs.fat>(8)" +msgstr "" + +#. type: SH +#: en/fatlabel.8:47 en/fsck.fat.8:188 en/mkfs.fat.8:160 +#, no-wrap +msgid "HOMEPAGE" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fatlabel.8:53 en/fsck.fat.8:194 en/mkfs.fat.8:166 +msgid "" +"The home for the B<dosfstools> project is its E<.UR https://github.com/" +"dosfstools/dosfstools> GitHub project page E<.UE .>" +msgstr "" + +#. type: SH +#: en/fatlabel.8:53 en/fsck.fat.8:194 en/mkfs.fat.8:166 +#, no-wrap +msgid "AUTHORS" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:55 en/fsck.fat.8:196 en/mkfs.fat.8:168 +msgid "B<dosfstools> were written by" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:57 en/fsck.fat.8:198 en/mkfs.fat.8:170 +msgid "Werner Almesberger" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:60 en/fsck.fat.8:201 en/mkfs.fat.8:173 +msgid "Roman Hodek" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:63 en/fsck.fat.8:204 en/mkfs.fat.8:176 +msgid "and others. The current maintainer is" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:65 en/fsck.fat.8:206 en/mkfs.fat.8:178 +msgid "Andreas Bombe" +msgstr "" + +#. type: TH +#: en/fsck.fat.8:22 +#, no-wrap +msgid "FSCK.FAT" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fsck.fat.8:26 +msgid "B<fsck.fat> - check and repair MS-DOS filesystems" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fsck.fat.8:29 +msgid "B<fsck.fat> [I<OPTIONS>] I<DEVICE>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:32 +msgid "" +"B<fsck.fat> verifies the consistency of MS-DOS filesystems and optionally " +"tries to repair them." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:34 +msgid "The following filesystem problems can be corrected (in this order):" +msgstr "" + +#. type: IP +#: en/fsck.fat.8:34 en/fsck.fat.8:37 en/fsck.fat.8:40 en/fsck.fat.8:44 +#: en/fsck.fat.8:47 en/fsck.fat.8:50 en/fsck.fat.8:53 en/fsck.fat.8:56 +#: en/fsck.fat.8:59 en/fsck.fat.8:62 en/fsck.fat.8:65 en/fsck.fat.8:68 +#: en/fsck.fat.8:71 en/fsck.fat.8:74 en/fsck.fat.8:77 en/fsck.fat.8:82 +#: en/fsck.fat.8:85 en/fsck.fat.8:90 en/fsck.fat.8:92 +#, no-wrap +msgid "*" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:37 +msgid "FAT contains invalid cluster numbers. Cluster is changed to EOF." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:40 +msgid "File's cluster chain contains a loop. The loop is broken." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:44 +msgid "" +"Bad clusters (read errors). The clusters are marked bad and they are " +"removed from files owning them. This check is optional." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:47 +msgid "" +"Directories with a large number of bad entries (probably corrupt). The " +"directory can be deleted." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:50 +msgid "Files . and .. are non-directories. They can be deleted or renamed." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:53 +msgid "Directories . and .. in root directory. They are deleted." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:56 +msgid "Bad filenames. They can be renamed." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:59 +msgid "Duplicate directory entries. They can be deleted or renamed." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:62 +msgid "Directories with non-zero size field. Size is set to zero." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:65 +msgid "" +"Directory . does not point to parent directory. The start pointer is " +"adjusted." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:68 +msgid "" +"Directory .. does not point to parent of parent directory. The start " +"pointer is adjusted." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:71 +msgid "Start cluster number of a file is invalid. The file is truncated." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:74 +msgid "File contains bad or free clusters. The file is truncated." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:77 +msgid "" +"File's cluster chain is longer than indicated by the size fields. The file " +"is truncated." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:82 +msgid "" +"Two or more files share the same cluster(s). All but one of the files are " +"truncated. If the file being truncated is a directory file that has already " +"been read, the filesystem check is restarted after truncation." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:85 +msgid "" +"File's cluster chain is shorter than indicated by the size fields. The file " +"is truncated." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:88 +msgid "" +"Clusters are marked as used but are not owned by a file. They are marked as " +"free." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:90 +msgid "Additionally, the following problems are detected, but not repaired:" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:92 +msgid "Invalid parameters in boot sector" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:94 +msgid "Absence of . and .. entries in non-root directories" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fsck.fat.8:99 +msgid "" +"When B<fsck.fat> checks a filesystem, it accumulates all changes in memory " +"and performs them only after all checks are complete. This can be disabled " +"with the B<-w> option." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:100 en/mkfs.fat.8:37 +#, no-wrap +msgid "B<-a>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:105 +msgid "" +"Automatically repair the filesystem. No user intervention is necessary. " +"Whenever there is more than one method to solve a problem, the least " +"destructive approach is used." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:105 +#, no-wrap +msgid "B<-A>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:116 +msgid "" +"Use Atari variation of the MS-DOS filesystem. This is default if B<fsck." +"fat> is run on an Atari, then this option turns off Atari format. There are " +"some minor differences in Atari format: Some boot sector fields are " +"interpreted slightly different, and the special FAT entries for end-of-file " +"and bad cluster can be different. Under MS-DOS 0xfff8 is used for EOF and " +"Atari employs 0xffff by default, but both systems recognize all values from " +"0xfff8...0xffff as end-of-file. MS-DOS uses only 0xfff7 for bad clusters, " +"where on Atari values 0xfff0...0xfff7 are for this purpose (but the standard " +"value is still 0xfff7)." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:116 +#, no-wrap +msgid "B<-b>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:118 +msgid "Make read-only boot sector check." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:118 +#, no-wrap +msgid "B<-d> I<PATH>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:122 +msgid "" +"Delete the specified file. If more than one file with that name exist, the " +"first one is deleted. This option can be given more than once." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:122 +#, no-wrap +msgid "B<-f>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:126 +msgid "" +"Salvage unused cluster chains to files. By default, unused clusters are " +"added to the free disk space except in auto mode (B<-a>)." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:126 +#, no-wrap +msgid "B<-l>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:128 +msgid "List path names of files being processed." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:128 +#, no-wrap +msgid "B<-n>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:131 +msgid "" +"No-operation mode: non-interactively check for errors, but don't write " +"anything to the filesystem." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:131 +#, no-wrap +msgid "B<-p>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:133 +msgid "Same as B<-a>, for compatibility with other *fsck." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:133 +#, no-wrap +msgid "B<-r>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:139 +msgid "" +"Interactively repair the filesystem. The user is asked for advice whenever " +"there is more than one approach to fix an inconsistency. This is the " +"default mode and the option is only retained for backwards compatibility." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:139 +#, no-wrap +msgid "B<-t>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:141 +msgid "Mark unreadable clusters as bad." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:141 +#, no-wrap +msgid "B<-u> I<PATH>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:146 +msgid "" +"Try to undelete the specified file. B<fsck.fat> tries to allocate a chain " +"of contiguous unallocated clusters beginning with the start cluster of the " +"undeleted file. This option can be given more than once." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:146 en/mkfs.fat.8:138 +#, no-wrap +msgid "B<-v>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:149 +msgid "Verbose mode. Generates slightly more output." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:149 +#, no-wrap +msgid "B<-V>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:156 +msgid "" +"Perform a verification pass. The filesystem check is repeated after the " +"first run. The second pass should never report any fixable errors. It may " +"take considerably longer than the first pass, because the first pass may " +"have generated long list of modifications that have to be scanned for each " +"disk read." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:156 +#, no-wrap +msgid "B<-w>" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:158 +msgid "Write changes to disk immediately." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:158 +#, no-wrap +msgid "B<-y>" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fsck.fat.8:162 +msgid "" +"Same as B<-a> (automatically repair filesystem) for compatibility with other " +"fsck tools." +msgstr "" + +#. type: SH +#: en/fsck.fat.8:162 +#, no-wrap +msgid "EXIT STATUS" +msgstr "" + +#. type: IP +#: en/fsck.fat.8:163 +#, no-wrap +msgid "0" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:165 +msgid "No recoverable errors have been detected." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:165 +#, no-wrap +msgid "1" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:168 +msgid "" +"Recoverable errors have been detected or B<fsck.fat> has discovered an " +"internal inconsistency." +msgstr "" + +#. type: IP +#: en/fsck.fat.8:168 +#, no-wrap +msgid "2" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fsck.fat.8:172 +msgid "Usage error. B<fsck.fat> did not access the filesystem." +msgstr "" + +#. type: SH +#: en/fsck.fat.8:172 +#, no-wrap +msgid "FILES" +msgstr "" + +#. type: IP +#: en/fsck.fat.8:173 +#, no-wrap +msgid "fsck0000.rec, fsck0001.rec, ..." +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fsck.fat.8:177 +msgid "" +"When recovering from a corrupted filesystem, B<fsck.fat> dumps recovered " +"data into files named 'fsckNNNN.rec' in the top level directory of the " +"filesystem." +msgstr "" + +#. type: SH +#: en/fsck.fat.8:177 en/mkfs.fat.8:149 +#, no-wrap +msgid "BUGS" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fsck.fat.8:183 +msgid "" +"Does not create . and .. files where necessary. Does not remove entirely " +"empty directories. Should give more diagnostic messages. Undeleting files " +"should use a more sophisticated algorithm." +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:185 en/mkfs.fat.8:157 +msgid "B<fatlabel>(8)" +msgstr "" diff --git a/dosfstools/manpages/pot/mkfs.fat.8.pot b/dosfstools/manpages/pot/mkfs.fat.8.pot new file mode 100644 index 000000000..c9d5bba96 --- /dev/null +++ b/dosfstools/manpages/pot/mkfs.fat.8.pot @@ -0,0 +1,484 @@ +# SOME DESCRIPTIVE TITLE +# Copyright (C) YEAR Free Software Foundation, Inc. +# This file is distributed under the same license as the dosfstools package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: dosfstools VERSION\n" +"POT-Creation-Date: 2015-05-16 00:40+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#. type: TH +#: en/fatlabel.8:22 en/fsck.fat.8:22 en/mkfs.fat.8:22 +#, no-wrap +msgid "2015-05-16" +msgstr "" + +#. type: TH +#: en/fatlabel.8:22 en/fsck.fat.8:22 en/mkfs.fat.8:22 +#, no-wrap +msgid "3.0.28" +msgstr "" + +#. type: TH +#: en/fatlabel.8:22 en/fsck.fat.8:22 en/mkfs.fat.8:22 +#, no-wrap +msgid "dosfstools" +msgstr "" + +#. type: SH +#: en/fatlabel.8:23 en/fsck.fat.8:23 en/mkfs.fat.8:23 +#, no-wrap +msgid "NAME" +msgstr "" + +#. type: SH +#: en/fatlabel.8:26 en/fsck.fat.8:26 en/mkfs.fat.8:26 +#, no-wrap +msgid "SYNOPSIS" +msgstr "" + +#. type: SH +#: en/fatlabel.8:29 en/fsck.fat.8:29 en/mkfs.fat.8:29 +#, no-wrap +msgid "DESCRIPTION" +msgstr "" + +#. type: SH +#: en/fatlabel.8:36 en/fsck.fat.8:99 en/mkfs.fat.8:36 +#, no-wrap +msgid "OPTIONS" +msgstr "" + +#. type: SH +#: en/fatlabel.8:42 en/fsck.fat.8:183 en/mkfs.fat.8:155 +#, no-wrap +msgid "SEE ALSO" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fatlabel.8:44 en/mkfs.fat.8:160 +msgid "B<fsck.fat>(8)" +msgstr "" + +#. type: SH +#: en/fatlabel.8:47 en/fsck.fat.8:188 en/mkfs.fat.8:160 +#, no-wrap +msgid "HOMEPAGE" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/fatlabel.8:53 en/fsck.fat.8:194 en/mkfs.fat.8:166 +msgid "" +"The home for the B<dosfstools> project is its E<.UR https://github.com/" +"dosfstools/dosfstools> GitHub project page E<.UE .>" +msgstr "" + +#. type: SH +#: en/fatlabel.8:53 en/fsck.fat.8:194 en/mkfs.fat.8:166 +#, no-wrap +msgid "AUTHORS" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:55 en/fsck.fat.8:196 en/mkfs.fat.8:168 +msgid "B<dosfstools> were written by" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:57 en/fsck.fat.8:198 en/mkfs.fat.8:170 +msgid "Werner Almesberger" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:60 en/fsck.fat.8:201 en/mkfs.fat.8:173 +msgid "Roman Hodek" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:63 en/fsck.fat.8:204 en/mkfs.fat.8:176 +msgid "and others. The current maintainer is" +msgstr "" + +#. type: Plain text +#: en/fatlabel.8:65 en/fsck.fat.8:206 en/mkfs.fat.8:178 +msgid "Andreas Bombe" +msgstr "" + +#. type: IP +#: en/fsck.fat.8:100 en/mkfs.fat.8:37 +#, no-wrap +msgid "B<-a>" +msgstr "" + +#. type: IP +#: en/fsck.fat.8:146 en/mkfs.fat.8:138 +#, no-wrap +msgid "B<-v>" +msgstr "" + +#. type: SH +#: en/fsck.fat.8:177 en/mkfs.fat.8:149 +#, no-wrap +msgid "BUGS" +msgstr "" + +#. type: Plain text +#: en/fsck.fat.8:185 en/mkfs.fat.8:157 +msgid "B<fatlabel>(8)" +msgstr "" + +#. type: TH +#: en/mkfs.fat.8:22 +#, no-wrap +msgid "MKFS.FAT" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/mkfs.fat.8:26 +msgid "B<mkfs.fat> - create an MS-DOS filesystem under Linux" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/mkfs.fat.8:29 +msgid "B<mkfs.fat> [I<OPTIONS>] I<DEVICE> [I<BLOCK-COUNT>]" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/mkfs.fat.8:36 +msgid "" +"B<mkfs.fat> is used to create an MS-DOS filesystem under Linux on a device " +"(usually a disk partition). I<DEVICE> is the special file corresponding to " +"the device (e.g. /dev/sdXX). I<BLOCK-COUNT> is the number of blocks on the " +"device. If omitted, B<mkfs.fat> automatically determines the filesystem " +"size." +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:45 +msgid "" +"Normally, for any filesystem except very small ones, B<mkfs.fat> will align " +"all the data structures to cluster size, to make sure that as long as the " +"partition is properly aligned, so will all the data structures in the " +"filesystem. This option disables alignment; this may provide a handful of " +"additional clusters of storage at the expense of a significant performance " +"degradation on RAIDs, flash media or large-sector hard disks." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:45 +#, no-wrap +msgid "B< -A>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:60 +msgid "" +"Use Atari variation of the MS-DOS filesystem. This is default if B<mkfs." +"fat> is run on an Atari, then this option turns off Atari format. There are " +"some differences when using Atari format: If not directed otherwise by the " +"user, B<mkfs.fat> will always use 2 sectors per cluster, since GEMDOS " +"doesn't like other values very much. It will also obey the maximum number " +"of sectors GEMDOS can handle. Larger filesystems are managed by raising the " +"logical sector size. Under Atari format, an Atari-compatible serial number " +"for the filesystem is generated, and a 12 bit FAT is used only for " +"filesystems that have one of the usual floppy sizes (720k, 1.2M, 1.44M, " +"2.88M), a 16 bit FAT otherwise. This can be overridden with the B<-F> " +"option. Some PC-specific boot sector fields aren't written, and a boot " +"message (option B<-m>) is ignored." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:60 +#, no-wrap +msgid "B<-b> I<SECTOR-OF-BACKUP>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:64 +msgid "" +"Selects the location of the backup boot sector for FAT32. Default depends " +"on number of reserved sectors, but usually is sector 6. The backup must be " +"within the range of reserved sectors." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:64 +#, no-wrap +msgid "B<-c>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:66 +msgid "Check the device for bad blocks before creating the filesystem." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:66 +#, no-wrap +msgid "B<-C>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:80 +msgid "" +"Create the file given as I<DEVICE> on the command line, and write the to-be-" +"created filesystem to it. This can be used to create the new filesystem in " +"a file instead of on a real device, and to avoid using B<dd> in advance to " +"create a file of appropriate size. With this option, the I<BLOCK-COUNT> " +"must be given, because otherwise the intended size of the filesystem " +"wouldn't be known. The file created is a sparse file, which actually only " +"contains the meta-data areas (boot sector, FATs, and root directory). The " +"data portions won't be stored on the disk, but the file nevertheless will " +"have the correct size. The resulting file can be copied later to a floppy " +"disk or other device, or mounted through a loop device." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:80 +#, no-wrap +msgid "B<-D> I<DRIVE-NUMBER>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:84 +msgid "" +"Specify the BIOS drive number to be stored in the FAT boot sector. This " +"value is usually 0x80 for hard disks and 0x00 for floppy devices or " +"partitions to be used for floppy emulation." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:84 +#, no-wrap +msgid "B<-f> I<NUMBER-OF-FATS>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:87 +msgid "" +"Specify the number of file allocation tables in the filesystem. The default " +"is 2." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:87 +#, no-wrap +msgid "B<-F> I<FAT-SIZE>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:91 +msgid "" +"Specifies the type of file allocation tables used (12, 16 or 32 bit). If " +"nothing is specified, B<mkfs.fat> will automatically select between 12, 16 " +"and 32 bit, whatever fits better for the filesystem size." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:91 +#, no-wrap +msgid "B<-h> I<NUMBER-OF-HIDDEN-SECTORS>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:95 +msgid "" +"Select the number of hidden sectors in the volume. Apparently some digital " +"cameras get indigestion if you feed them a CF card without such hidden " +"sectors, this option allows you to satisfy them." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:95 +#, no-wrap +msgid "B<-i> I<VOLUME-ID>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:99 +msgid "" +"Sets the volume ID of the newly created filesystem; I<VOLUME-ID> is a 32-bit " +"hexadecimal number (for example, 2e24ec82). The default is a number which " +"depends on the filesystem creation time." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:99 +#, no-wrap +msgid "B<-I>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:108 +msgid "" +"It is typical for fixed disk devices to be partitioned so, by default, you " +"are not permitted to create a filesystem across the entire device. B<mkfs." +"fat> will complain and tell you that it refuses to work. This is different " +"when using MO disks. One doesn't always need partitions on MO disks. The " +"filesystem can go directly to the whole disk. Under other OSes this is " +"known as the 'superfloppy' format. This switch will force B<mkfs.fat> to " +"work properly." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:108 +#, no-wrap +msgid "B<-l> I<FILENAME>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:110 +msgid "Read the bad blocks list from I<FILENAME>." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:110 +#, no-wrap +msgid "B<-m> I<MESSAGE-FILE>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:116 +msgid "" +"Sets the message the user receives on attempts to boot this filesystem " +"without having properly installed an operating system. The message file " +"must not exceed 418 bytes once line feeds have been converted to carriage " +"return-line feed combinations, and tabs have been expanded. If the filename " +"is a hyphen (-), the text is taken from standard input." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:116 +#, no-wrap +msgid "B<-M> I<FAT-MEDIA-TYPE>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:120 +msgid "" +"Specify the media type to be stored in the FAT boot sector. This value is " +"usually 0xF8 for hard disks and is 0xF0 or a value from 0xF9 to 0xFF for " +"floppies or partitions to be used for floppy emulation." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:120 +#, no-wrap +msgid "B<-n> I<VOLUME-NAME>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:124 +msgid "" +"Sets the volume name (label) of the filesystem. The volume name can be up " +"to 11 characters long. The default is no label." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:124 +#, no-wrap +msgid "B<-r> I<ROOT-DIR-ENTRIES>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:127 +msgid "" +"Select the number of entries available in the root directory. The default " +"is 112 or 224 for floppies and 512 for hard disks." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:127 +#, no-wrap +msgid "B<-R> I<NUMBER-OF-RESERVED-SECTORS>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:131 +msgid "" +"Select the number of reserved sectors. With FAT32 format at least 2 " +"reserved sectors are needed, the default is 32. Otherwise the default is 1 " +"(only the boot sector)." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:131 +#, no-wrap +msgid "B<-s> I<SECTORS-PER-CLUSTER>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:134 +msgid "" +"Specify the number of disk sectors per cluster. Must be a power of 2, i.e. " +"1, 2, 4, 8, ... 128." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:134 +#, no-wrap +msgid "B<-S> I<LOGICAL-SECTOR-SIZE>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:138 +msgid "" +"Specify the number of bytes per logical sector. Must be a power of 2 and " +"greater than or equal to 512, i.e. 512, 1024, 2048, 4096, 8192, 16384, or " +"32768." +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:140 +msgid "Verbose execution." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:140 +#, no-wrap +msgid "B<--invariant>" +msgstr "" + +#. type: Plain text +#: en/mkfs.fat.8:146 +msgid "" +"Use constants for normally randomly generated or time based data such as " +"volume ID and creation time. Multiple runs of B<mkfs.fat> on the same " +"device create identical results with this option. Its main purpose is " +"testing B<mkfs.fat>." +msgstr "" + +#. type: IP +#: en/mkfs.fat.8:146 +#, no-wrap +msgid "B<--help>" +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/mkfs.fat.8:149 +msgid "Display option summary and exit." +msgstr "" + +#. ---------------------------------------------------------------------------- +#. type: Plain text +#: en/mkfs.fat.8:155 +msgid "" +"B<mkfs.fat> can not create boot-able filesystems. This isn't as easy as you " +"might think at first glance for various reasons and has been discussed a lot " +"already. B<mkfs.fat> simply will not support it ;)" +msgstr "" diff --git a/dosfstools/src/boot.c b/dosfstools/src/boot.c new file mode 100644 index 000000000..0c0918f8b --- /dev/null +++ b/dosfstools/src/boot.c @@ -0,0 +1,568 @@ +/* boot.c - Read and analyze ia PC/MS-DOS boot sector + + Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch> + Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> + Copyright (C) 2008-2014 Daniel Baumann <mail@daniel-baumann.ch> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + The complete text of the GNU General Public License + can be found in /usr/share/common-licenses/GPL-3 file. +*/ + +/* FAT32, VFAT, Atari format support, and various fixes additions May 1998 + * by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */ + +#include <stdio.h> +#include <stdint.h> +#include <string.h> +#include <stdlib.h> +#include <time.h> + +#include "common.h" +#include "fsck.fat.h" +#include "fat.h" +#include "io.h" +#include "boot.h" +#include "check.h" + +#define ROUND_TO_MULTIPLE(n,m) ((n) && (m) ? (n)+(m)-1-((n)-1)%(m) : 0) + /* don't divide by zero */ + +/* cut-over cluster counts for FAT12 and FAT16 */ +#define FAT12_THRESHOLD 4085 +#define FAT16_THRESHOLD 65525 + +static struct { + uint8_t media; + const char *descr; +} mediabytes[] = { + { + 0xf0, "5.25\" or 3.5\" HD floppy"}, { + 0xf8, "hard disk"}, { + 0xf9, "3,5\" 720k floppy 2s/80tr/9sec or " + "5.25\" 1.2M floppy 2s/80tr/15sec"}, { + 0xfa, "5.25\" 320k floppy 1s/80tr/8sec"}, { + 0xfb, "3.5\" 640k floppy 2s/80tr/8sec"}, { + 0xfc, "5.25\" 180k floppy 1s/40tr/9sec"}, { + 0xfd, "5.25\" 360k floppy 2s/40tr/9sec"}, { + 0xfe, "5.25\" 160k floppy 1s/40tr/8sec"}, { +0xff, "5.25\" 320k floppy 2s/40tr/8sec"},}; + +/* Unaligned fields must first be accessed byte-wise */ +#define GET_UNALIGNED_W(f) \ + ( (uint16_t)f[0] | ((uint16_t)f[1]<<8) ) + +static const char *get_media_descr(unsigned char media) +{ + int i; + + for (i = 0; i < sizeof(mediabytes) / sizeof(*mediabytes); ++i) { + if (mediabytes[i].media == media) + return (mediabytes[i].descr); + } + return ("undefined"); +} + +static void dump_boot(DOS_FS * fs, struct boot_sector *b, unsigned lss) +{ + unsigned short sectors; + + printf("Boot sector contents:\n"); + if (!atari_format) { + char id[9]; + strncpy(id, (const char *)b->system_id, 8); + id[8] = 0; + printf("System ID \"%s\"\n", id); + } else { + /* On Atari, a 24 bit serial number is stored at offset 8 of the boot + * sector */ + printf("Serial number 0x%x\n", + b->system_id[5] | (b->system_id[6] << 8) | (b-> + system_id[7] << 16)); + } + printf("Media byte 0x%02x (%s)\n", b->media, get_media_descr(b->media)); + printf("%10d bytes per logical sector\n", GET_UNALIGNED_W(b->sector_size)); + printf("%10d bytes per cluster\n", fs->cluster_size); + printf("%10d reserved sector%s\n", le16toh(b->reserved), + le16toh(b->reserved) == 1 ? "" : "s"); + printf("First FAT starts at byte %llu (sector %llu)\n", + (unsigned long long)fs->fat_start, + (unsigned long long)fs->fat_start / lss); + printf("%10d FATs, %d bit entries\n", b->fats, fs->fat_bits); + printf("%10d bytes per FAT (= %u sectors)\n", fs->fat_size, + fs->fat_size / lss); + if (!fs->root_cluster) { + printf("Root directory starts at byte %llu (sector %llu)\n", + (unsigned long long)fs->root_start, + (unsigned long long)fs->root_start / lss); + printf("%10d root directory entries\n", fs->root_entries); + } else { + printf("Root directory start at cluster %lu (arbitrary size)\n", + (unsigned long)fs->root_cluster); + } + printf("Data area starts at byte %llu (sector %llu)\n", + (unsigned long long)fs->data_start, + (unsigned long long)fs->data_start / lss); + printf("%10lu data clusters (%llu bytes)\n", (unsigned long)fs->clusters, + (unsigned long long)fs->clusters * fs->cluster_size); + printf("%u sectors/track, %u heads\n", le16toh(b->secs_track), + le16toh(b->heads)); + printf("%10u hidden sectors\n", atari_format ? + /* On Atari, the hidden field is only 16 bit wide and unused */ + (((unsigned char *)&b->hidden)[0] | + ((unsigned char *)&b->hidden)[1] << 8) : le32toh(b->hidden)); + sectors = GET_UNALIGNED_W(b->sectors); + printf("%10u sectors total\n", sectors ? sectors : le32toh(b->total_sect)); +} + +static void check_backup_boot(DOS_FS * fs, struct boot_sector *b, int lss) +{ + struct boot_sector b2; + + if (!fs->backupboot_start) { + printf("There is no backup boot sector.\n"); + if (le16toh(b->reserved) < 3) { + printf("And there is no space for creating one!\n"); + return; + } + if (interactive) + printf("1) Create one\n2) Do without a backup\n"); + else + printf(" Auto-creating backup boot block.\n"); + if (!interactive || get_key("12", "?") == '1') { + int bbs; + /* The usual place for the backup boot sector is sector 6. Choose + * that or the last reserved sector. */ + if (le16toh(b->reserved) >= 7 && le16toh(b->info_sector) != 6) + bbs = 6; + else { + bbs = le16toh(b->reserved) - 1; + if (bbs == le16toh(b->info_sector)) + --bbs; /* this is never 0, as we checked reserved >= 3! */ + } + fs->backupboot_start = bbs * lss; + b->backup_boot = htole16(bbs); + fs_write(fs->backupboot_start, sizeof(*b), b); + fs_write((loff_t) offsetof(struct boot_sector, backup_boot), + sizeof(b->backup_boot), &b->backup_boot); + printf("Created backup of boot sector in sector %d\n", bbs); + return; + } else + return; + } + + fs_read(fs->backupboot_start, sizeof(b2), &b2); + if (memcmp(b, &b2, sizeof(b2)) != 0) { + /* there are any differences */ + uint8_t *p, *q; + int i, pos, first = 1; + char buf[20]; + + printf("There are differences between boot sector and its backup.\n"); + printf("This is mostly harmless. Differences: (offset:original/backup)\n "); + pos = 2; + for (p = (uint8_t *) b, q = (uint8_t *) & b2, i = 0; i < sizeof(b2); + ++p, ++q, ++i) { + if (*p != *q) { + sprintf(buf, "%s%u:%02x/%02x", first ? "" : ", ", + (unsigned)(p - (uint8_t *) b), *p, *q); + if (pos + strlen(buf) > 78) + printf("\n "), pos = 2; + printf("%s", buf); + pos += strlen(buf); + first = 0; + } + } + printf("\n"); + + if (interactive) + printf("1) Copy original to backup\n" + "2) Copy backup to original\n" "3) No action\n"); + else + printf(" Not automatically fixing this.\n"); + switch (interactive ? get_key("123", "?") : '3') { + case '1': + fs_write(fs->backupboot_start, sizeof(*b), b); + break; + case '2': + fs_write(0, sizeof(b2), &b2); + break; + default: + break; + } + } +} + +static void init_fsinfo(struct info_sector *i) +{ + i->magic = htole32(0x41615252); + i->signature = htole32(0x61417272); + i->free_clusters = htole32(-1); + i->next_cluster = htole32(2); + i->boot_sign = htole16(0xaa55); +} + +static void read_fsinfo(DOS_FS * fs, struct boot_sector *b, int lss) +{ + struct info_sector i; + + if (!b->info_sector) { + printf("No FSINFO sector\n"); + if (interactive) + printf("1) Create one\n2) Do without FSINFO\n"); + else + printf(" Not automatically creating it.\n"); + if (interactive && get_key("12", "?") == '1') { + /* search for a free reserved sector (not boot sector and not + * backup boot sector) */ + uint32_t s; + for (s = 1; s < le16toh(b->reserved); ++s) + if (s != le16toh(b->backup_boot)) + break; + if (s > 0 && s < le16toh(b->reserved)) { + init_fsinfo(&i); + fs_write((loff_t) s * lss, sizeof(i), &i); + b->info_sector = htole16(s); + fs_write((loff_t) offsetof(struct boot_sector, info_sector), + sizeof(b->info_sector), &b->info_sector); + if (fs->backupboot_start) + fs_write(fs->backupboot_start + + offsetof(struct boot_sector, info_sector), + sizeof(b->info_sector), &b->info_sector); + } else { + printf("No free reserved sector found -- " + "no space for FSINFO sector!\n"); + return; + } + } else + return; + } + + fs->fsinfo_start = le16toh(b->info_sector) * lss; + fs_read(fs->fsinfo_start, sizeof(i), &i); + + if (i.magic != htole32(0x41615252) || + i.signature != htole32(0x61417272) || i.boot_sign != htole16(0xaa55)) { + printf("FSINFO sector has bad magic number(s):\n"); + if (i.magic != htole32(0x41615252)) + printf(" Offset %llu: 0x%08x != expected 0x%08x\n", + (unsigned long long)offsetof(struct info_sector, magic), + le32toh(i.magic), 0x41615252); + if (i.signature != htole32(0x61417272)) + printf(" Offset %llu: 0x%08x != expected 0x%08x\n", + (unsigned long long)offsetof(struct info_sector, signature), + le32toh(i.signature), 0x61417272); + if (i.boot_sign != htole16(0xaa55)) + printf(" Offset %llu: 0x%04x != expected 0x%04x\n", + (unsigned long long)offsetof(struct info_sector, boot_sign), + le16toh(i.boot_sign), 0xaa55); + if (interactive) + printf("1) Correct\n2) Don't correct (FSINFO invalid then)\n"); + else + printf(" Auto-correcting it.\n"); + if (!interactive || get_key("12", "?") == '1') { + init_fsinfo(&i); + fs_write(fs->fsinfo_start, sizeof(i), &i); + } else + fs->fsinfo_start = 0; + } + + if (fs->fsinfo_start) + fs->free_clusters = le32toh(i.free_clusters); +} + +static char print_fat_dirty_state(void) +{ + printf("Dirty bit is set. Fs was not properly unmounted and" + " some data may be corrupt.\n"); + + if (interactive) { + printf("1) Remove dirty bit\n" "2) No action\n"); + return get_key("12", "?"); + } else + printf(" Automatically removing dirty bit.\n"); + return '1'; +} + +static void check_fat_state_bit(DOS_FS * fs, void *b) +{ + if (fs->fat_bits == 32) { + struct boot_sector *b32 = b; + + if (b32->reserved3 & FAT_STATE_DIRTY) { + printf("0x41: "); + if (print_fat_dirty_state() == '1') { + b32->reserved3 &= ~FAT_STATE_DIRTY; + fs_write(0, sizeof(*b32), b32); + } + } + } else { + struct boot_sector_16 *b16 = b; + + if (b16->reserved2 & FAT_STATE_DIRTY) { + printf("0x25: "); + if (print_fat_dirty_state() == '1') { + b16->reserved2 &= ~FAT_STATE_DIRTY; + fs_write(0, sizeof(*b16), b16); + } + } + } +} + +void read_boot(DOS_FS * fs) +{ + struct boot_sector b; + unsigned total_sectors; + unsigned short logical_sector_size, sectors; + unsigned fat_length; + loff_t data_size; + + fs_read(0, sizeof(b), &b); + logical_sector_size = GET_UNALIGNED_W(b.sector_size); + if (!logical_sector_size) + die("Logical sector size is zero."); + + /* This was moved up because it's the first thing that will fail */ + /* if the platform needs special handling of unaligned multibyte accesses */ + /* but such handling isn't being provided. See GET_UNALIGNED_W() above. */ + if (logical_sector_size & (SECTOR_SIZE - 1)) + die("Logical sector size (%d bytes) is not a multiple of the physical " + "sector size.", logical_sector_size); + + fs->cluster_size = b.cluster_size * logical_sector_size; + if (!fs->cluster_size) + die("Cluster size is zero."); + if (b.fats != 2 && b.fats != 1) + die("Currently, only 1 or 2 FATs are supported, not %d.\n", b.fats); + fs->nfats = b.fats; + sectors = GET_UNALIGNED_W(b.sectors); + total_sectors = sectors ? sectors : le32toh(b.total_sect); + if (verbose) + printf("Checking we can access the last sector of the filesystem\n"); + /* Can't access last odd sector anyway, so round down */ + fs_test((loff_t) ((total_sectors & ~1) - 1) * (loff_t) logical_sector_size, + logical_sector_size); + fat_length = le16toh(b.fat_length) ? + le16toh(b.fat_length) : le32toh(b.fat32_length); + fs->fat_start = (loff_t) le16toh(b.reserved) * logical_sector_size; + fs->root_start = ((loff_t) le16toh(b.reserved) + b.fats * fat_length) * + logical_sector_size; + fs->root_entries = GET_UNALIGNED_W(b.dir_entries); + fs->data_start = fs->root_start + ROUND_TO_MULTIPLE(fs->root_entries << + MSDOS_DIR_BITS, + logical_sector_size); + data_size = (loff_t) total_sectors *logical_sector_size - fs->data_start; + fs->clusters = data_size / fs->cluster_size; + fs->root_cluster = 0; /* indicates standard, pre-FAT32 root dir */ + fs->fsinfo_start = 0; /* no FSINFO structure */ + fs->free_clusters = -1; /* unknown */ + if (!b.fat_length && b.fat32_length) { + fs->fat_bits = 32; + fs->root_cluster = le32toh(b.root_cluster); + if (!fs->root_cluster && fs->root_entries) + /* M$ hasn't specified this, but it looks reasonable: If + * root_cluster is 0 but there is a separate root dir + * (root_entries != 0), we handle the root dir the old way. Give a + * warning, but convertig to a root dir in a cluster chain seems + * to complex for now... */ + printf("Warning: FAT32 root dir not in cluster chain! " + "Compatibility mode...\n"); + else if (!fs->root_cluster && !fs->root_entries) + die("No root directory!"); + else if (fs->root_cluster && fs->root_entries) + printf("Warning: FAT32 root dir is in a cluster chain, but " + "a separate root dir\n" + " area is defined. Cannot fix this easily.\n"); + if (fs->clusters < FAT16_THRESHOLD) + printf("Warning: Filesystem is FAT32 according to fat_length " + "and fat32_length fields,\n" + " but has only %lu clusters, less than the required " + "minimum of %d.\n" + " This may lead to problems on some systems.\n", + (unsigned long)fs->clusters, FAT16_THRESHOLD); + + check_fat_state_bit(fs, &b); + fs->backupboot_start = le16toh(b.backup_boot) * logical_sector_size; + check_backup_boot(fs, &b, logical_sector_size); + + read_fsinfo(fs, &b, logical_sector_size); + } else if (!atari_format) { + /* On real MS-DOS, a 16 bit FAT is used whenever there would be too + * much clusers otherwise. */ + fs->fat_bits = (fs->clusters >= FAT12_THRESHOLD) ? 16 : 12; + if (fs->clusters >= FAT16_THRESHOLD) + die("Too many clusters (%lu) for FAT16 filesystem.", fs->clusters); + check_fat_state_bit(fs, &b); + } else { + /* On Atari, things are more difficult: GEMDOS always uses 12bit FATs + * on floppies, and always 16 bit on harddisks. */ + fs->fat_bits = 16; /* assume 16 bit FAT for now */ + /* If more clusters than fat entries in 16-bit fat, we assume + * it's a real MSDOS FS with 12-bit fat. */ + if (fs->clusters + 2 > fat_length * logical_sector_size * 8 / 16 || + /* if it's a floppy disk --> 12bit fat */ + device_no == 2 || + /* if it's a ramdisk or loopback device and has one of the usual + * floppy sizes -> 12bit FAT */ + ((device_no == 1 || device_no == 7) && + (total_sectors == 720 || total_sectors == 1440 || + total_sectors == 2880))) + fs->fat_bits = 12; + } + /* On FAT32, the high 4 bits of a FAT entry are reserved */ + fs->eff_fat_bits = (fs->fat_bits == 32) ? 28 : fs->fat_bits; + fs->fat_size = fat_length * logical_sector_size; + + fs->label = calloc(12, sizeof(uint8_t)); + if (fs->fat_bits == 12 || fs->fat_bits == 16) { + struct boot_sector_16 *b16 = (struct boot_sector_16 *)&b; + if (b16->extended_sig == 0x29) + memmove(fs->label, b16->label, 11); + else + fs->label = NULL; + } else if (fs->fat_bits == 32) { + if (b.extended_sig == 0x29) + memmove(fs->label, &b.label, 11); + else + fs->label = NULL; + } + + if (fs->clusters > + ((uint64_t)fs->fat_size * 8 / fs->fat_bits) - 2) + die("Filesystem has %d clusters but only space for %d FAT entries.", + fs->clusters, + ((unsigned long long)fs->fat_size * 8 / fs->fat_bits) - 2); + if (!fs->root_entries && !fs->root_cluster) + die("Root directory has zero size."); + if (fs->root_entries & (MSDOS_DPS - 1)) + die("Root directory (%d entries) doesn't span an integral number of " + "sectors.", fs->root_entries); + if (logical_sector_size & (SECTOR_SIZE - 1)) + die("Logical sector size (%d bytes) is not a multiple of the physical " + "sector size.", logical_sector_size); +#if 0 /* linux kernel doesn't check that either */ + /* ++roman: On Atari, these two fields are often left uninitialized */ + if (!atari_format && (!b.secs_track || !b.heads)) + die("Invalid disk format in boot sector."); +#endif + if (verbose) + dump_boot(fs, &b, logical_sector_size); +} + +static void write_boot_label(DOS_FS * fs, char *label) +{ + if (fs->fat_bits == 12 || fs->fat_bits == 16) { + struct boot_sector_16 b16; + + fs_read(0, sizeof(b16), &b16); + if (b16.extended_sig != 0x29) { + b16.extended_sig = 0x29; + b16.serial = 0; + memmove(b16.fs_type, fs->fat_bits == 12 ? "FAT12 " : "FAT16 ", + 8); + } + memmove(b16.label, label, 11); + fs_write(0, sizeof(b16), &b16); + } else if (fs->fat_bits == 32) { + struct boot_sector b; + + fs_read(0, sizeof(b), &b); + if (b.extended_sig != 0x29) { + b.extended_sig = 0x29; + b.serial = 0; + memmove(b.fs_type, "FAT32 ", 8); + } + memmove(b.label, label, 11); + fs_write(0, sizeof(b), &b); + if (fs->backupboot_start) + fs_write(fs->backupboot_start, sizeof(b), &b); + } +} + +loff_t find_volume_de(DOS_FS * fs, DIR_ENT * de) +{ + uint32_t cluster; + loff_t offset; + int i; + + if (fs->root_cluster) { + for (cluster = fs->root_cluster; + cluster != 0 && cluster != -1; + cluster = next_cluster(fs, cluster)) { + offset = cluster_start(fs, cluster); + for (i = 0; i * sizeof(DIR_ENT) < fs->cluster_size; i++) { + fs_read(offset, sizeof(DIR_ENT), de); + if (de->attr != VFAT_LN_ATTR && de->attr & ATTR_VOLUME) + return offset; + offset += sizeof(DIR_ENT); + } + } + } else { + for (i = 0; i < fs->root_entries; i++) { + offset = fs->root_start + i * sizeof(DIR_ENT); + fs_read(offset, sizeof(DIR_ENT), de); + if (de->attr != VFAT_LN_ATTR && de->attr & ATTR_VOLUME) + return offset; + } + } + + return 0; +} + +static void write_volume_label(DOS_FS * fs, char *label) +{ + time_t now = time(NULL); + struct tm *mtime = localtime(&now); + loff_t offset; + int created; + DIR_ENT de; + + created = 0; + offset = find_volume_de(fs, &de); + if (offset == 0) { + created = 1; + offset = alloc_rootdir_entry(fs, &de, label); + } + memcpy(de.name, label, 11); + de.time = htole16((unsigned short)((mtime->tm_sec >> 1) + + (mtime->tm_min << 5) + + (mtime->tm_hour << 11))); + de.date = htole16((unsigned short)(mtime->tm_mday + + ((mtime->tm_mon + 1) << 5) + + ((mtime->tm_year - 80) << 9))); + if (created) { + de.attr = ATTR_VOLUME; + de.ctime_ms = 0; + de.ctime = de.time; + de.cdate = de.date; + de.adate = de.date; + de.starthi = 0; + de.start = 0; + de.size = 0; + } + + fs_write(offset, sizeof(DIR_ENT), &de); +} + +void write_label(DOS_FS * fs, char *label) +{ + int l = strlen(label); + + while (l < 11) + label[l++] = ' '; + + write_boot_label(fs, label); + write_volume_label(fs, label); +} diff --git a/dosfstools/src/boot.h b/dosfstools/src/boot.h new file mode 100644 index 000000000..d52e62476 --- /dev/null +++ b/dosfstools/src/boot.h @@ -0,0 +1,32 @@ +/* boot.h - Read and analyze ia PC/MS-DOS boot sector + + Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch> + Copyright (C) 2008-2014 Daniel Baumann <mail@daniel-baumann.ch> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + The complete text of the GNU General Public License + can be found in /usr/share/common-licenses/GPL-3 file. +*/ + +#ifndef _BOOT_H +#define _BOOT_H + +void read_boot(DOS_FS * fs); +void write_label(DOS_FS * fs, char *label); +loff_t find_volume_de(DOS_FS * fs, DIR_ENT * de); + +/* Reads the boot sector from the currently open device and initializes *FS */ + +#endif diff --git a/dosfstools/src/check.c b/dosfstools/src/check.c new file mode 100644 index 000000000..bbb97e4f3 --- /dev/null +++ b/dosfstools/src/check.c @@ -0,0 +1,1089 @@ +/* check.c - Check and repair a PC/MS-DOS filesystem + + Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch> + Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> + Copyright (C) 2008-2014 Daniel Baumann <mail@daniel-baumann.ch> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + The complete text of the GNU General Public License + can be found in /usr/share/common-licenses/GPL-3 file. +*/ + +/* FAT32, VFAT, Atari format support, and various fixes additions May 1998 + * by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <limits.h> +#include <time.h> + +#include "common.h" +#include "fsck.fat.h" +#include "io.h" +#include "fat.h" +#include "file.h" +#include "lfn.h" +#include "check.h" + +static DOS_FILE *root; + +/* get start field of a dir entry */ +#define FSTART(p,fs) \ + ((uint32_t)le16toh(p->dir_ent.start) | \ + (fs->fat_bits == 32 ? le16toh(p->dir_ent.starthi) << 16 : 0)) + +#define MODIFY(p,i,v) \ + do { \ + if (p->offset) { \ + p->dir_ent.i = v; \ + fs_write(p->offset+offsetof(DIR_ENT,i), \ + sizeof(p->dir_ent.i),&p->dir_ent.i); \ + } \ + } while(0) + +#define MODIFY_START(p,v,fs) \ + do { \ + uint32_t __v = (v); \ + if (!p->offset) { \ + /* writing to fake entry for FAT32 root dir */ \ + if (!__v) die("Oops, deleting FAT32 root dir!"); \ + fs->root_cluster = __v; \ + p->dir_ent.start = htole16(__v&0xffff); \ + p->dir_ent.starthi = htole16(__v>>16); \ + __v = htole32(__v); \ + fs_write((loff_t)offsetof(struct boot_sector,root_cluster), \ + sizeof(((struct boot_sector *)0)->root_cluster), \ + &__v); \ + } \ + else { \ + MODIFY(p,start,htole16((__v)&0xffff)); \ + if (fs->fat_bits == 32) \ + MODIFY(p,starthi,htole16((__v)>>16)); \ + } \ + } while(0) + +loff_t alloc_rootdir_entry(DOS_FS * fs, DIR_ENT * de, const char *pattern) +{ + static int curr_num = 0; + loff_t offset; + + if (fs->root_cluster) { + DIR_ENT d2; + int i = 0, got = 0; + uint32_t clu_num, prev = 0; + loff_t offset2; + + clu_num = fs->root_cluster; + offset = cluster_start(fs, clu_num); + while (clu_num > 0 && clu_num != -1) { + fs_read(offset, sizeof(DIR_ENT), &d2); + if (IS_FREE(d2.name) && d2.attr != VFAT_LN_ATTR) { + got = 1; + break; + } + i += sizeof(DIR_ENT); + offset += sizeof(DIR_ENT); + if ((i % fs->cluster_size) == 0) { + prev = clu_num; + if ((clu_num = next_cluster(fs, clu_num)) == 0 || clu_num == -1) + break; + offset = cluster_start(fs, clu_num); + } + } + if (!got) { + /* no free slot, need to extend root dir: alloc next free cluster + * after previous one */ + if (!prev) + die("Root directory has no cluster allocated!"); + for (clu_num = prev + 1; clu_num != prev; clu_num++) { + FAT_ENTRY entry; + + if (clu_num >= fs->clusters + 2) + clu_num = 2; + get_fat(&entry, fs->fat, clu_num, fs); + if (!entry.value) + break; + } + if (clu_num == prev) + die("Root directory full and no free cluster"); + set_fat(fs, prev, clu_num); + set_fat(fs, clu_num, -1); + set_owner(fs, clu_num, get_owner(fs, fs->root_cluster)); + /* clear new cluster */ + memset(&d2, 0, sizeof(d2)); + offset = cluster_start(fs, clu_num); + for (i = 0; i < fs->cluster_size; i += sizeof(DIR_ENT)) + fs_write(offset + i, sizeof(d2), &d2); + } + memset(de, 0, sizeof(DIR_ENT)); + while (1) { + char expanded[12]; + sprintf(expanded, pattern, curr_num); + memcpy(de->name, expanded, 8); + memcpy(de->ext, expanded + 8, 3); + clu_num = fs->root_cluster; + i = 0; + offset2 = cluster_start(fs, clu_num); + while (clu_num > 0 && clu_num != -1) { + fs_read(offset2, sizeof(DIR_ENT), &d2); + if (offset2 != offset && + !strncmp((const char *)d2.name, (const char *)de->name, + MSDOS_NAME)) + break; + i += sizeof(DIR_ENT); + offset2 += sizeof(DIR_ENT); + if ((i % fs->cluster_size) == 0) { + if ((clu_num = next_cluster(fs, clu_num)) == 0 || + clu_num == -1) + break; + offset2 = cluster_start(fs, clu_num); + } + } + if (clu_num == 0 || clu_num == -1) + break; + if (++curr_num >= 10000) + die("Unable to create unique name"); + } + } else { + DIR_ENT *root; + int next_free = 0, scan; + + root = alloc(fs->root_entries * sizeof(DIR_ENT)); + fs_read(fs->root_start, fs->root_entries * sizeof(DIR_ENT), root); + + while (next_free < fs->root_entries) + if (IS_FREE(root[next_free].name) && + root[next_free].attr != VFAT_LN_ATTR) + break; + else + next_free++; + if (next_free == fs->root_entries) + die("Root directory is full."); + offset = fs->root_start + next_free * sizeof(DIR_ENT); + memset(de, 0, sizeof(DIR_ENT)); + while (1) { + char expanded[12]; + sprintf(expanded, pattern, curr_num); + memcpy(de->name, expanded, 8); + memcpy(de->ext, expanded + 8, 3); + for (scan = 0; scan < fs->root_entries; scan++) + if (scan != next_free && + !strncmp((const char *)root[scan].name, + (const char *)de->name, MSDOS_NAME)) + break; + if (scan == fs->root_entries) + break; + if (++curr_num >= 10000) + die("Unable to create unique name"); + } + free(root); + } + ++n_files; + return offset; +} + +/** + * Construct a full path (starting with '/') for the specified dentry, + * relative to the partition. All components are "long" names where possible. + * + * @param[in] file Information about dentry (file or directory) of interest + * + * return Pointer to static string containing file's full path + */ +static char *path_name(DOS_FILE * file) +{ + static char path[PATH_MAX * 2]; + + if (!file) + *path = 0; /* Reached the root directory */ + else { + if (strlen(path_name(file->parent)) > PATH_MAX) + die("Path name too long."); + if (strcmp(path, "/") != 0) + strcat(path, "/"); + + /* Append the long name to the path, + * or the short name if there isn't a long one + */ + strcpy(strrchr(path, 0), + file->lfn ? file->lfn : file_name(file->dir_ent.name)); + } + return path; +} + +static const int day_n[] = + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0 }; +/* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec */ + +/* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */ + +static time_t date_dos2unix(unsigned short time, unsigned short date) +{ + int month, year; + time_t secs; + + month = ((date >> 5) & 15) - 1; + if (month < 0) { + /* make sure that nothing bad happens if the month bits were zero */ + month = 0; + } + year = date >> 9; + secs = + (time & 31) * 2 + 60 * ((time >> 5) & 63) + (time >> 11) * 3600 + + 86400 * ((date & 31) - 1 + day_n[month] + (year / 4) + year * 365 - + ((year & 3) == 0 && month < 2 ? 1 : 0) + 3653); + /* days since 1.1.70 plus 80's leap day */ + return secs; +} + +static char *file_stat(DOS_FILE * file) +{ + static char temp[100]; + struct tm *tm; + char tmp[100]; + time_t date; + + date = + date_dos2unix(le16toh(file->dir_ent.time), le16toh(file->dir_ent.date)); + tm = localtime(&date); + strftime(tmp, 99, "%H:%M:%S %b %d %Y", tm); + sprintf(temp, " Size %u bytes, date %s", le32toh(file->dir_ent.size), tmp); + return temp; +} + +static int bad_name(DOS_FILE * file) +{ + int i, spc, suspicious = 0; + const char *bad_chars = atari_format ? "*?\\/:" : "*?<>|\"\\/:"; + const unsigned char *name = file->dir_ent.name; + const unsigned char *ext = file->dir_ent.ext; + + /* Do not complain about (and auto-correct) the extended attribute files + * of OS/2. */ + if (strncmp((const char *)name, "EA DATA SF", 11) == 0 || + strncmp((const char *)name, "WP ROOT SF", 11) == 0) + return 0; + + /* check if we have neither a long filename nor a short name */ + if ((file->lfn == NULL) && (file->dir_ent.lcase & FAT_NO_83NAME)) { + return 1; + } + + /* don't complain about the dummy 11 bytes used by patched Linux + kernels */ + if (file->dir_ent.lcase & FAT_NO_83NAME) + return 0; + + for (i = 0; i < 8; i++) { + if (name[i] < ' ' || name[i] == 0x7f) + return 1; + if (name[i] > 0x7f) + ++suspicious; + if (strchr(bad_chars, name[i])) + return 1; + } + + for (i = 0; i < 3; i++) { + if (ext[i] < ' ' || ext[i] == 0x7f) + return 1; + if (ext[i] > 0x7f) + ++suspicious; + if (strchr(bad_chars, ext[i])) + return 1; + } + + spc = 0; + for (i = 0; i < 8; i++) { + if (name[i] == ' ') + spc = 1; + else if (spc) + /* non-space after a space not allowed, space terminates the name + * part */ + return 1; + } + + spc = 0; + for (i = 0; i < 3; i++) { + if (ext[i] == ' ') + spc = 1; + else if (spc) + /* non-space after a space not allowed, space terminates the ext + * part */ + return 1; + } + + /* Under GEMDOS, chars >= 128 are never allowed. */ + if (atari_format && suspicious) + return 1; + + /* Under MS-DOS and Windows, chars >= 128 in short names are valid + * (but these characters can be visualised differently depending on + * local codepage: CP437, CP866, etc). The chars are all basically ok, + * so we shouldn't auto-correct such names. */ + return 0; +} + +static void lfn_remove(loff_t from, loff_t to) +{ + DIR_ENT empty; + + /* New dir entry is zeroed except first byte, which is set to 0xe5. + * This is to avoid that some FAT-reading OSes (not Linux! ;) stop reading + * a directory at the first zero entry... + */ + memset(&empty, 0, sizeof(empty)); + empty.name[0] = DELETED_FLAG; + + for (; from < to; from += sizeof(empty)) { + fs_write(from, sizeof(DIR_ENT), &empty); + } +} + +static void drop_file(DOS_FS * fs, DOS_FILE * file) +{ + uint32_t cluster; + + MODIFY(file, name[0], DELETED_FLAG); + if (file->lfn) + lfn_remove(file->lfn_offset, file->offset); + for (cluster = FSTART(file, fs); cluster > 0 && cluster < + fs->clusters + 2; cluster = next_cluster(fs, cluster)) + set_owner(fs, cluster, NULL); + --n_files; +} + +static void truncate_file(DOS_FS * fs, DOS_FILE * file, uint32_t clusters) +{ + int deleting; + uint32_t walk, next; + + walk = FSTART(file, fs); + if ((deleting = !clusters)) + MODIFY_START(file, 0, fs); + while (walk > 0 && walk != -1) { + next = next_cluster(fs, walk); + if (deleting) + set_fat(fs, walk, 0); + else if ((deleting = !--clusters)) + set_fat(fs, walk, -1); + walk = next; + } +} + +static void auto_rename(DOS_FILE * file) +{ + DOS_FILE *first, *walk; + uint32_t number; + + if (!file->offset) + return; /* cannot rename FAT32 root dir */ + first = file->parent ? file->parent->first : root; + number = 0; + while (1) { + char num[8]; + sprintf(num, "%07lu", (unsigned long)number); + memcpy(file->dir_ent.name, "FSCK", 4); + memcpy(file->dir_ent.name + 4, num, 4); + memcpy(file->dir_ent.ext, num + 4, 3); + for (walk = first; walk; walk = walk->next) + if (walk != file + && !strncmp((const char *)walk->dir_ent.name, + (const char *)file->dir_ent.name, MSDOS_NAME)) + break; + if (!walk) { + if (file->dir_ent.lcase & FAT_NO_83NAME) { + /* as we only assign a new 8.3 filename, reset flag that 8.3 name is not + present */ + file->dir_ent.lcase &= ~FAT_NO_83NAME; + /* reset the attributes, only keep DIR and VOLUME */ + file->dir_ent.attr &= ~(ATTR_DIR | ATTR_VOLUME); + fs_write(file->offset, MSDOS_NAME + 2, file->dir_ent.name); + } else { + fs_write(file->offset, MSDOS_NAME, file->dir_ent.name); + } + if (file->lfn) + lfn_fix_checksum(file->lfn_offset, file->offset, + (const char *)file->dir_ent.name); + return; + } + number++; + if (number > 9999999) { + die("Too many files need repair."); + } + } + die("Can't generate a unique name."); +} + +static void rename_file(DOS_FILE * file) +{ + unsigned char name[46]; + unsigned char *walk, *here; + + if (!file->offset) { + printf("Cannot rename FAT32 root dir\n"); + return; /* cannot rename FAT32 root dir */ + } + while (1) { + printf("New name: "); + fflush(stdout); + if (fgets((char *)name, 45, stdin)) { + if ((here = (unsigned char *)strchr((const char *)name, '\n'))) + *here = 0; + for (walk = (unsigned char *)strrchr((const char *)name, 0); + walk >= name && (*walk == ' ' || *walk == '\t'); walk--) ; + walk[1] = 0; + for (walk = name; *walk == ' ' || *walk == '\t'; walk++) ; + if (file_cvt(walk, file->dir_ent.name)) { + if (file->dir_ent.lcase & FAT_NO_83NAME) { + /* as we only assign a new 8.3 filename, reset flag that 8.3 name is not + present */ + file->dir_ent.lcase &= ~FAT_NO_83NAME; + /* reset the attributes, only keep DIR and VOLUME */ + file->dir_ent.attr &= ~(ATTR_DIR | ATTR_VOLUME); + fs_write(file->offset, MSDOS_NAME + 2, file->dir_ent.name); + } else { + fs_write(file->offset, MSDOS_NAME, file->dir_ent.name); + } + if (file->lfn) + lfn_fix_checksum(file->lfn_offset, file->offset, + (const char *)file->dir_ent.name); + return; + } + } + } +} + +static int handle_dot(DOS_FS * fs, DOS_FILE * file, int dots) +{ + const char *name; + + name = + strncmp((const char *)file->dir_ent.name, MSDOS_DOT, + MSDOS_NAME) ? ".." : "."; + if (!(file->dir_ent.attr & ATTR_DIR)) { + printf("%s\n Is a non-directory.\n", path_name(file)); + if (interactive) + printf("1) Drop it\n2) Auto-rename\n3) Rename\n" + "4) Convert to directory\n"); + else + printf(" Auto-renaming it.\n"); + switch (interactive ? get_key("1234", "?") : '2') { + case '1': + drop_file(fs, file); + return 1; + case '2': + auto_rename(file); + printf(" Renamed to %s\n", file_name(file->dir_ent.name)); + return 0; + case '3': + rename_file(file); + return 0; + case '4': + MODIFY(file, size, htole32(0)); + MODIFY(file, attr, file->dir_ent.attr | ATTR_DIR); + break; + } + } + if (!dots) { + printf("Root contains directory \"%s\". Dropping it.\n", name); + drop_file(fs, file); + return 1; + } + return 0; +} + +static int check_file(DOS_FS * fs, DOS_FILE * file) +{ + DOS_FILE *owner; + int restart; + uint32_t expect, curr, this, clusters, prev, walk, clusters2; + + if (file->dir_ent.attr & ATTR_DIR) { + if (le32toh(file->dir_ent.size)) { + printf("%s\n Directory has non-zero size. Fixing it.\n", + path_name(file)); + MODIFY(file, size, htole32(0)); + } + if (file->parent + && !strncmp((const char *)file->dir_ent.name, MSDOS_DOT, + MSDOS_NAME)) { + expect = FSTART(file->parent, fs); + if (FSTART(file, fs) != expect) { + printf("%s\n Start (%lu) does not point to parent (%lu)\n", + path_name(file), (unsigned long)FSTART(file, fs), (long)expect); + MODIFY_START(file, expect, fs); + } + return 0; + } + if (file->parent + && !strncmp((const char *)file->dir_ent.name, MSDOS_DOTDOT, + MSDOS_NAME)) { + expect = + file->parent->parent ? FSTART(file->parent->parent, fs) : 0; + if (fs->root_cluster && expect == fs->root_cluster) + expect = 0; + if (FSTART(file, fs) != expect) { + printf("%s\n Start (%lu) does not point to .. (%lu)\n", + path_name(file), (unsigned long)FSTART(file, fs), (unsigned long)expect); + MODIFY_START(file, expect, fs); + } + return 0; + } + if (FSTART(file, fs) == 0) { + printf("%s\n Start does point to root directory. Deleting dir. \n", + path_name(file)); + MODIFY(file, name[0], DELETED_FLAG); + return 0; + } + } + if (FSTART(file, fs) == 1) { + printf("%s\n Bad start cluster 1. Truncating file.\n", + path_name(file)); + if (!file->offset) + die("Bad FAT32 root directory! (bad start cluster 1)\n"); + MODIFY_START(file, 0, fs); + } + if (FSTART(file, fs) >= fs->clusters + 2) { + printf + ("%s\n Start cluster beyond limit (%lu > %lu). Truncating file.\n", + path_name(file), (unsigned long)FSTART(file, fs), (unsigned long)(fs->clusters + 1)); + if (!file->offset) + die("Bad FAT32 root directory! (start cluster beyond limit: %lu > %lu)\n", + (unsigned long)FSTART(file, fs), (unsigned long)(fs->clusters + 1)); + MODIFY_START(file, 0, fs); + } + clusters = prev = 0; + for (curr = FSTART(file, fs) ? FSTART(file, fs) : + -1; curr != -1; curr = next_cluster(fs, curr)) { + FAT_ENTRY curEntry; + get_fat(&curEntry, fs->fat, curr, fs); + + if (!curEntry.value || bad_cluster(fs, curr)) { + printf("%s\n Contains a %s cluster (%lu). Assuming EOF.\n", + path_name(file), curEntry.value ? "bad" : "free", (unsigned long)curr); + if (prev) + set_fat(fs, prev, -1); + else if (!file->offset) + die("FAT32 root dir starts with a bad cluster!"); + else + MODIFY_START(file, 0, fs); + break; + } + if (!(file->dir_ent.attr & ATTR_DIR) && le32toh(file->dir_ent.size) <= + (uint64_t)clusters * fs->cluster_size) { + printf + ("%s\n File size is %u bytes, cluster chain length is > %lu " + "bytes.\n Truncating file to %u bytes.\n", path_name(file), + le32toh(file->dir_ent.size), + (uint64_t)clusters * fs->cluster_size, + le32toh(file->dir_ent.size)); + truncate_file(fs, file, clusters); + break; + } + if ((owner = get_owner(fs, curr))) { + int do_trunc = 0; + printf("%s and\n", path_name(owner)); + printf("%s\n share clusters.\n", path_name(file)); + clusters2 = 0; + for (walk = FSTART(owner, fs); walk > 0 && walk != -1; walk = + next_cluster(fs, walk)) + if (walk == curr) + break; + else + clusters2++; + restart = file->dir_ent.attr & ATTR_DIR; + if (!owner->offset) { + printf(" Truncating second to %llu bytes because first " + "is FAT32 root dir.\n", + (unsigned long long)clusters2 * fs->cluster_size); + do_trunc = 2; + } else if (!file->offset) { + printf(" Truncating first to %llu bytes because second " + "is FAT32 root dir.\n", + (unsigned long long)clusters * fs->cluster_size); + do_trunc = 1; + } else if (interactive) + printf("1) Truncate first to %llu bytes%s\n" + "2) Truncate second to %llu bytes\n", + (unsigned long long)clusters * fs->cluster_size, + restart ? " and restart" : "", + (unsigned long long)clusters2 * fs->cluster_size); + else + printf(" Truncating second to %llu bytes.\n", + (unsigned long long)clusters2 * fs->cluster_size); + if (do_trunc != 2 + && (do_trunc == 1 + || (interactive && get_key("12", "?") == '1'))) { + prev = 0; + clusters = 0; + for (this = FSTART(owner, fs); this > 0 && this != -1; this = + next_cluster(fs, this)) { + if (this == curr) { + if (prev) + set_fat(fs, prev, -1); + else + MODIFY_START(owner, 0, fs); + MODIFY(owner, size, + htole32((uint64_t)clusters * + fs->cluster_size)); + if (restart) + return 1; + while (this > 0 && this != -1) { + set_owner(fs, this, NULL); + this = next_cluster(fs, this); + } + this = curr; + break; + } + clusters++; + prev = this; + } + if (this != curr) + die("Internal error: didn't find cluster %d in chain" + " starting at %d", curr, FSTART(owner, fs)); + } else { + if (prev) + set_fat(fs, prev, -1); + else + MODIFY_START(file, 0, fs); + break; + } + } + set_owner(fs, curr, file); + clusters++; + prev = curr; + } + if (!(file->dir_ent.attr & ATTR_DIR) && le32toh(file->dir_ent.size) > + (uint64_t)clusters * fs->cluster_size) { + printf + ("%s\n File size is %u bytes, cluster chain length is %llu bytes." + "\n Truncating file to %llu bytes.\n", path_name(file), + le32toh(file->dir_ent.size), + (unsigned long long)clusters * fs->cluster_size, + (unsigned long long)clusters * fs->cluster_size); + MODIFY(file, size, + htole32((uint64_t)clusters * fs->cluster_size)); + } + return 0; +} + +static int check_files(DOS_FS * fs, DOS_FILE * start) +{ + while (start) { + if (check_file(fs, start)) + return 1; + start = start->next; + } + return 0; +} + +static int check_dir(DOS_FS * fs, DOS_FILE ** root, int dots) +{ + DOS_FILE *parent, **walk, **scan; + int dot, dotdot, skip, redo; + int good, bad; + + if (!*root) + return 0; + parent = (*root)->parent; + good = bad = 0; + for (walk = root; *walk; walk = &(*walk)->next) + if (bad_name(*walk)) + bad++; + else + good++; + if (*root && parent && good + bad > 4 && bad > good / 2) { + printf("%s\n Has a large number of bad entries. (%d/%d)\n", + path_name(parent), bad, good + bad); + if (!dots) + printf(" Not dropping root directory.\n"); + else if (!interactive) + printf(" Not dropping it in auto-mode.\n"); + else if (get_key("yn", "Drop directory ? (y/n)") == 'y') { + truncate_file(fs, parent, 0); + MODIFY(parent, name[0], DELETED_FLAG); + /* buglet: deleted directory stays in the list. */ + return 1; + } + } + dot = dotdot = redo = 0; + walk = root; + while (*walk) { + if (!strncmp + ((const char *)((*walk)->dir_ent.name), MSDOS_DOT, MSDOS_NAME) + || !strncmp((const char *)((*walk)->dir_ent.name), MSDOS_DOTDOT, + MSDOS_NAME)) { + if (handle_dot(fs, *walk, dots)) { + *walk = (*walk)->next; + continue; + } + if (!strncmp + ((const char *)((*walk)->dir_ent.name), MSDOS_DOT, MSDOS_NAME)) + dot++; + else + dotdot++; + } + if (!((*walk)->dir_ent.attr & ATTR_VOLUME) && bad_name(*walk)) { + puts(path_name(*walk)); + printf(" Bad short file name (%s).\n", + file_name((*walk)->dir_ent.name)); + if (interactive) + printf("1) Drop file\n2) Rename file\n3) Auto-rename\n" + "4) Keep it\n"); + else + printf(" Auto-renaming it.\n"); + switch (interactive ? get_key("1234", "?") : '3') { + case '1': + drop_file(fs, *walk); + walk = &(*walk)->next; + continue; + case '2': + rename_file(*walk); + redo = 1; + break; + case '3': + auto_rename(*walk); + printf(" Renamed to %s\n", file_name((*walk)->dir_ent.name)); + break; + case '4': + break; + } + } + /* don't check for duplicates of the volume label */ + if (!((*walk)->dir_ent.attr & ATTR_VOLUME)) { + scan = &(*walk)->next; + skip = 0; + while (*scan && !skip) { + if (!((*scan)->dir_ent.attr & ATTR_VOLUME) && + !memcmp((*walk)->dir_ent.name, (*scan)->dir_ent.name, + MSDOS_NAME)) { + printf("%s\n Duplicate directory entry.\n First %s\n", + path_name(*walk), file_stat(*walk)); + printf(" Second %s\n", file_stat(*scan)); + if (interactive) + printf + ("1) Drop first\n2) Drop second\n3) Rename first\n" + "4) Rename second\n5) Auto-rename first\n" + "6) Auto-rename second\n"); + else + printf(" Auto-renaming second.\n"); + switch (interactive ? get_key("123456", "?") : '6') { + case '1': + drop_file(fs, *walk); + *walk = (*walk)->next; + skip = 1; + break; + case '2': + drop_file(fs, *scan); + *scan = (*scan)->next; + continue; + case '3': + rename_file(*walk); + printf(" Renamed to %s\n", path_name(*walk)); + redo = 1; + break; + case '4': + rename_file(*scan); + printf(" Renamed to %s\n", path_name(*walk)); + redo = 1; + break; + case '5': + auto_rename(*walk); + printf(" Renamed to %s\n", + file_name((*walk)->dir_ent.name)); + break; + case '6': + auto_rename(*scan); + printf(" Renamed to %s\n", + file_name((*scan)->dir_ent.name)); + break; + } + } + scan = &(*scan)->next; + } + if (skip) + continue; + } + if (!redo) + walk = &(*walk)->next; + else { + walk = root; + dot = dotdot = redo = 0; + } + } + if (dots && !dot) + printf("%s\n \".\" is missing. Can't fix this yet.\n", + path_name(parent)); + if (dots && !dotdot) + printf("%s\n \"..\" is missing. Can't fix this yet.\n", + path_name(parent)); + return 0; +} + +/** + * Check a dentry's cluster chain for bad clusters. + * If requested, we verify readability and mark unreadable clusters as bad. + * + * @param[inout] fs Information about the filesystem + * @param[in] file dentry to check + * @param[in] read_test Nonzero == verify that dentry's clusters can + * be read + */ +static void test_file(DOS_FS * fs, DOS_FILE * file, int read_test) +{ + DOS_FILE *owner; + uint32_t walk, prev, clusters, next_clu; + + prev = clusters = 0; + for (walk = FSTART(file, fs); walk > 1 && walk < fs->clusters + 2; + walk = next_clu) { + next_clu = next_cluster(fs, walk); + + /* In this stage we are checking only for a loop within our own + * cluster chain. + * Cross-linking of clusters is handled in check_file() + */ + if ((owner = get_owner(fs, walk))) { + if (owner == file) { + printf("%s\n Circular cluster chain. Truncating to %lu " + "cluster%s.\n", path_name(file), (unsigned long)clusters, + clusters == 1 ? "" : "s"); + if (prev) + set_fat(fs, prev, -1); + else if (!file->offset) + die("Bad FAT32 root directory! (bad start cluster)\n"); + else + MODIFY_START(file, 0, fs); + } + break; + } + if (bad_cluster(fs, walk)) + break; + if (read_test) { + if (fs_test(cluster_start(fs, walk), fs->cluster_size)) { + prev = walk; + clusters++; + } else { + printf("%s\n Cluster %lu (%lu) is unreadable. Skipping it.\n", + path_name(file), (unsigned long)clusters, (unsigned long)walk); + if (prev) + set_fat(fs, prev, next_cluster(fs, walk)); + else + MODIFY_START(file, next_cluster(fs, walk), fs); + set_fat(fs, walk, -2); + } + } + set_owner(fs, walk, file); + } + /* Revert ownership (for now) */ + for (walk = FSTART(file, fs); walk > 1 && walk < fs->clusters + 2; + walk = next_cluster(fs, walk)) + if (bad_cluster(fs, walk)) + break; + else if (get_owner(fs, walk) == file) + set_owner(fs, walk, NULL); + else + break; +} + +static void undelete(DOS_FS * fs, DOS_FILE * file) +{ + uint32_t clusters, left, prev, walk; + + clusters = left = (le32toh(file->dir_ent.size) + fs->cluster_size - 1) / + fs->cluster_size; + prev = 0; + + walk = FSTART(file, fs); + + while (left && (walk >= 2) && (walk < fs->clusters + 2)) { + + FAT_ENTRY curEntry; + get_fat(&curEntry, fs->fat, walk, fs); + + if (!curEntry.value) + break; + + left--; + if (prev) + set_fat(fs, prev, walk); + prev = walk; + walk++; + } + if (prev) + set_fat(fs, prev, -1); + else + MODIFY_START(file, 0, fs); + if (left) + printf("Warning: Did only undelete %lu of %lu cluster%s.\n", + (unsigned long)clusters - left, (unsigned long)clusters, clusters == 1 ? "" : "s"); + +} + +static void new_dir(void) +{ + lfn_reset(); +} + +/** + * Create a description for a referenced dentry and insert it in our dentry + * tree. Then, go check the dentry's cluster chain for bad clusters and + * cluster loops. + * + * @param[inout] fs Information about the filesystem + * @param[out] chain + * @param[in] parent Information about parent directory of this file + * NULL == no parent ('file' is root directory) + * @param[in] offset Partition-relative byte offset of directory entry of interest + * 0 == Root directory + * @param cp + */ +static void add_file(DOS_FS * fs, DOS_FILE *** chain, DOS_FILE * parent, + loff_t offset, FDSC ** cp) +{ + DOS_FILE *new; + DIR_ENT de; + FD_TYPE type; + + if (offset) + fs_read(offset, sizeof(DIR_ENT), &de); + else { + /* Construct a DIR_ENT for the root directory */ + memset(&de, 0, sizeof de); + memcpy(de.name, " ", MSDOS_NAME); + de.attr = ATTR_DIR; + de.start = htole16(fs->root_cluster & 0xffff); + de.starthi = htole16((fs->root_cluster >> 16) & 0xffff); + } + if ((type = file_type(cp, (char *)de.name)) != fdt_none) { + if (type == fdt_undelete && (de.attr & ATTR_DIR)) + die("Can't undelete directories."); + file_modify(cp, (char *)de.name); + fs_write(offset, 1, &de); + } + if (IS_FREE(de.name)) { + lfn_check_orphaned(); + return; + } + if (de.attr == VFAT_LN_ATTR) { + lfn_add_slot(&de, offset); + return; + } + new = qalloc(&mem_queue, sizeof(DOS_FILE)); + new->lfn = lfn_get(&de, &new->lfn_offset); + new->offset = offset; + memcpy(&new->dir_ent, &de, sizeof(de)); + new->next = new->first = NULL; + new->parent = parent; + if (type == fdt_undelete) + undelete(fs, new); + **chain = new; + *chain = &new->next; + if (list) { + printf("Checking file %s", path_name(new)); + if (new->lfn) + printf(" (%s)", file_name(new->dir_ent.name)); /* (8.3) */ + printf("\n"); + } + /* Don't include root directory, '.', or '..' in the total file count */ + if (offset && + strncmp((const char *)de.name, MSDOS_DOT, MSDOS_NAME) != 0 && + strncmp((const char *)de.name, MSDOS_DOTDOT, MSDOS_NAME) != 0) + ++n_files; + test_file(fs, new, test); /* Bad cluster check */ +} + +static int subdirs(DOS_FS * fs, DOS_FILE * parent, FDSC ** cp); + +static int scan_dir(DOS_FS * fs, DOS_FILE * this, FDSC ** cp) +{ + DOS_FILE **chain; + int i; + uint32_t clu_num; + + chain = &this->first; + i = 0; + clu_num = FSTART(this, fs); + new_dir(); + while (clu_num > 0 && clu_num != -1) { + add_file(fs, &chain, this, + cluster_start(fs, clu_num) + (i % fs->cluster_size), cp); + i += sizeof(DIR_ENT); + if (!(i % fs->cluster_size)) + if ((clu_num = next_cluster(fs, clu_num)) == 0 || clu_num == -1) + break; + } + lfn_check_orphaned(); + if (check_dir(fs, &this->first, this->offset)) + return 0; + if (check_files(fs, this->first)) + return 1; + return subdirs(fs, this, cp); +} + +/** + * Recursively scan subdirectories of the specified parent directory. + * + * @param[inout] fs Information about the filesystem + * @param[in] parent Identifies the directory to scan + * @param[in] cp + * + * @return 0 Success + * @return 1 Error + */ +static int subdirs(DOS_FS * fs, DOS_FILE * parent, FDSC ** cp) +{ + DOS_FILE *walk; + + for (walk = parent ? parent->first : root; walk; walk = walk->next) + if (walk->dir_ent.attr & ATTR_DIR) + if (strncmp((const char *)walk->dir_ent.name, MSDOS_DOT, MSDOS_NAME) + && strncmp((const char *)walk->dir_ent.name, MSDOS_DOTDOT, + MSDOS_NAME)) + if (scan_dir(fs, walk, file_cd(cp, (char *)walk->dir_ent.name))) + return 1; + return 0; +} + +/** + * Scan all directory and file information for errors. + * + * @param[inout] fs Information about the filesystem + * + * @return 0 Success + * @return 1 Error + */ +int scan_root(DOS_FS * fs) +{ + DOS_FILE **chain; + int i; + + root = NULL; + chain = &root; + new_dir(); + if (fs->root_cluster) { + add_file(fs, &chain, NULL, 0, &fp_root); + } else { + for (i = 0; i < fs->root_entries; i++) + add_file(fs, &chain, NULL, fs->root_start + i * sizeof(DIR_ENT), + &fp_root); + } + lfn_check_orphaned(); + (void)check_dir(fs, &root, 0); + if (check_files(fs, root)) + return 1; + return subdirs(fs, NULL, &fp_root); +} diff --git a/dosfstools/src/check.h b/dosfstools/src/check.h new file mode 100644 index 000000000..fcb6bea39 --- /dev/null +++ b/dosfstools/src/check.h @@ -0,0 +1,40 @@ +/* check.h - Check and repair a PC/MS-DOS filesystem + + Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch> + Copyright (C) 2008-2014 Daniel Baumann <mail@daniel-baumann.ch> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + The complete text of the GNU General Public License + can be found in /usr/share/common-licenses/GPL-3 file. +*/ + +#ifndef _CHECK_H +#define _CHECK_H + +loff_t alloc_rootdir_entry(DOS_FS * fs, DIR_ENT * de, const char *pattern); + +/* Allocate a free slot in the root directory for a new file. The file name is + constructed after 'pattern', which must include a %d type format for printf + and expand to exactly 11 characters. The name actually used is written into + the 'de' structure, the rest of *de is cleared. The offset returned is to + where in the filesystem the entry belongs. */ + +int scan_root(DOS_FS * fs); + +/* Scans the root directory and recurses into all subdirectories. See check.c + for all the details. Returns a non-zero integer if the filesystem has to + be checked again. */ + +#endif diff --git a/dosfstools/src/common.c b/dosfstools/src/common.c new file mode 100644 index 000000000..9d1119322 --- /dev/null +++ b/dosfstools/src/common.c @@ -0,0 +1,119 @@ +/* common.c - Common functions + + Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch> + Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> + Copyright (C) 2008-2014 Daniel Baumann <mail@daniel-baumann.ch> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + The complete text of the GNU General Public License + can be found in /usr/share/common-licenses/GPL-3 file. +*/ + +/* FAT32, VFAT, Atari format support, and various fixes additions May 1998 + * by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdarg.h> +#include <errno.h> + +#include "common.h" + +typedef struct _link { + void *data; + struct _link *next; +} LINK; + +void die(const char *msg, ...) +{ + va_list args; + + va_start(args, msg); + vfprintf(stderr, msg, args); + va_end(args); + fprintf(stderr, "\n"); + exit(1); +} + +void pdie(const char *msg, ...) +{ + va_list args; + + va_start(args, msg); + vfprintf(stderr, msg, args); + va_end(args); + fprintf(stderr, ":%s\n", strerror(errno)); + exit(1); +} + +void *alloc(int size) +{ + void *this; + + if ((this = malloc(size))) + return this; + pdie("malloc"); + return NULL; /* for GCC */ +} + +void *qalloc(void **root, int size) +{ + LINK *link; + + link = alloc(sizeof(LINK)); + link->next = *root; + *root = link; + return link->data = alloc(size); +} + +void qfree(void **root) +{ + LINK *this; + + while (*root) { + this = (LINK *) * root; + *root = this->next; + free(this->data); + free(this); + } +} + +int min(int a, int b) +{ + return a < b ? a : b; +} + +char get_key(const char *valid, const char *prompt) +{ + int ch, okay; + + while (1) { + if (prompt) + printf("%s ", prompt); + fflush(stdout); + while (ch = getchar(), ch == ' ' || ch == '\t') ; + if (ch == EOF) + exit(1); + if (!strchr(valid, okay = ch)) + okay = 0; + while (ch = getchar(), ch != '\n' && ch != EOF) ; + if (ch == EOF) + exit(1); + if (okay) + return okay; + printf("Invalid input.\n"); + } +} diff --git a/dosfstools/src/common.h b/dosfstools/src/common.h new file mode 100644 index 000000000..c15efb538 --- /dev/null +++ b/dosfstools/src/common.h @@ -0,0 +1,56 @@ +/* common.h - Common functions + + Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch> + Copyright (C) 2008-2014 Daniel Baumann <mail@daniel-baumann.ch> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + The complete text of the GNU General Public License + can be found in /usr/share/common-licenses/GPL-3 file. +*/ + +#ifndef _COMMON_H +#define _COMMON_H + +void die(const char *msg, ...) __attribute((noreturn)); + +/* Displays a prinf-style message and terminates the program. */ + +void pdie(const char *msg, ...) __attribute((noreturn)); + +/* Like die, but appends an error message according to the state of errno. */ + +void *alloc(int size); + +/* mallocs SIZE bytes and returns a pointer to the data. Terminates the program + if malloc fails. */ + +void *qalloc(void **root, int size); + +/* Like alloc, but registers the data area in a list described by ROOT. */ + +void qfree(void **root); + +/* Deallocates all qalloc'ed data areas described by ROOT. */ + +int min(int a, int b); + +/* Returns the smaller integer value of a and b. */ + +char get_key(const char *valid, const char *prompt); + +/* Displays PROMPT and waits for user input. Only characters in VALID are + accepted. Terminates the program on EOF. Returns the character. */ + +#endif diff --git a/dosfstools/src/fat.c b/dosfstools/src/fat.c new file mode 100644 index 000000000..5a92f5684 --- /dev/null +++ b/dosfstools/src/fat.c @@ -0,0 +1,558 @@ +/* fat.c - Read/write access to the FAT + + Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch> + Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> + Copyright (C) 2008-2014 Daniel Baumann <mail@daniel-baumann.ch> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + The complete text of the GNU General Public License + can be found in /usr/share/common-licenses/GPL-3 file. +*/ + +/* FAT32, VFAT, Atari format support, and various fixes additions May 1998 + * by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "common.h" +#include "fsck.fat.h" +#include "io.h" +#include "check.h" +#include "fat.h" + +/** + * Fetch the FAT entry for a specified cluster. + * + * @param[out] entry Cluster to which cluster of interest is linked + * @param[in] fat FAT table for the partition + * @param[in] cluster Cluster of interest + * @param[in] fs Information from the FAT boot sectors (bits per FAT entry) + */ +void get_fat(FAT_ENTRY * entry, void *fat, uint32_t cluster, DOS_FS * fs) +{ + unsigned char *ptr; + + switch (fs->fat_bits) { + case 12: + ptr = &((unsigned char *)fat)[cluster * 3 / 2]; + entry->value = 0xfff & (cluster & 1 ? (ptr[0] >> 4) | (ptr[1] << 4) : + (ptr[0] | ptr[1] << 8)); + break; + case 16: + entry->value = le16toh(((unsigned short *)fat)[cluster]); + break; + case 32: + /* According to M$, the high 4 bits of a FAT32 entry are reserved and + * are not part of the cluster number. So we cut them off. */ + { + uint32_t e = le32toh(((unsigned int *)fat)[cluster]); + entry->value = e & 0xfffffff; + entry->reserved = e >> 28; + } + break; + default: + die("Bad FAT entry size: %d bits.", fs->fat_bits); + } +} + +/** + * Build a bookkeeping structure from the partition's FAT table. + * If the partition has multiple FATs and they don't agree, try to pick a winner, + * and queue a command to overwrite the loser. + * One error that is fixed here is a cluster that links to something out of range. + * + * @param[inout] fs Information about the filesystem + */ +void read_fat(DOS_FS * fs) +{ + int eff_size, alloc_size; + uint32_t i; + void *first, *second = NULL; + int first_ok, second_ok; + uint32_t total_num_clusters; + + /* Clean up from previous pass */ + if (fs->fat) + free(fs->fat); + if (fs->cluster_owner) + free(fs->cluster_owner); + fs->fat = NULL; + fs->cluster_owner = NULL; + + total_num_clusters = fs->clusters + 2UL; + eff_size = (total_num_clusters * fs->fat_bits + 7) / 8ULL; + + if (fs->fat_bits != 12) + alloc_size = eff_size; + else + /* round up to an even number of FAT entries to avoid special + * casing the last entry in get_fat() */ + alloc_size = (total_num_clusters * 12 + 23) / 24 * 3; + + first = alloc(alloc_size); + fs_read(fs->fat_start, eff_size, first); + if (fs->nfats > 1) { + second = alloc(alloc_size); + fs_read(fs->fat_start + fs->fat_size, eff_size, second); + } + if (second && memcmp(first, second, eff_size) != 0) { + FAT_ENTRY first_media, second_media; + get_fat(&first_media, first, 0, fs); + get_fat(&second_media, second, 0, fs); + first_ok = (first_media.value & FAT_EXTD(fs)) == FAT_EXTD(fs); + second_ok = (second_media.value & FAT_EXTD(fs)) == FAT_EXTD(fs); + if (first_ok && !second_ok) { + printf("FATs differ - using first FAT.\n"); + fs_write(fs->fat_start + fs->fat_size, eff_size, first); + } + if (!first_ok && second_ok) { + printf("FATs differ - using second FAT.\n"); + fs_write(fs->fat_start, eff_size, second); + memcpy(first, second, eff_size); + } + if (first_ok && second_ok) { + if (interactive) { + printf("FATs differ but appear to be intact. Use which FAT ?\n" + "1) Use first FAT\n2) Use second FAT\n"); + if (get_key("12", "?") == '1') { + fs_write(fs->fat_start + fs->fat_size, eff_size, first); + } else { + fs_write(fs->fat_start, eff_size, second); + memcpy(first, second, eff_size); + } + } else { + printf("FATs differ but appear to be intact. Using first " + "FAT.\n"); + fs_write(fs->fat_start + fs->fat_size, eff_size, first); + } + } + if (!first_ok && !second_ok) { + printf("Both FATs appear to be corrupt. Giving up.\n"); + exit(1); + } + } + if (second) { + free(second); + } + fs->fat = (unsigned char *)first; + + fs->cluster_owner = alloc(total_num_clusters * sizeof(DOS_FILE *)); + memset(fs->cluster_owner, 0, (total_num_clusters * sizeof(DOS_FILE *))); + + /* Truncate any cluster chains that link to something out of range */ + for (i = 2; i < fs->clusters + 2; i++) { + FAT_ENTRY curEntry; + get_fat(&curEntry, fs->fat, i, fs); + if (curEntry.value == 1) { + printf("Cluster %ld out of range (1). Setting to EOF.\n", (long)(i - 2)); + set_fat(fs, i, -1); + } + if (curEntry.value >= fs->clusters + 2 && + (curEntry.value < FAT_MIN_BAD(fs))) { + printf("Cluster %ld out of range (%ld > %ld). Setting to EOF.\n", + (long)(i - 2), (long)curEntry.value, (long)(fs->clusters + 2 - 1)); + set_fat(fs, i, -1); + } + } +} + +/** + * Update the FAT entry for a specified cluster + * (i.e., change the cluster it links to). + * Queue a command to write out this change. + * + * @param[in,out] fs Information about the filesystem + * @param[in] cluster Cluster to change + * @param[in] new Cluster to link to + * Special values: + * 0 == free cluster + * -1 == end-of-chain + * -2 == bad cluster + */ +void set_fat(DOS_FS * fs, uint32_t cluster, int32_t new) +{ + unsigned char *data = NULL; + int size; + loff_t offs; + + if (new == -1) + new = FAT_EOF(fs); + else if ((long)new == -2) + new = FAT_BAD(fs); + switch (fs->fat_bits) { + case 12: + data = fs->fat + cluster * 3 / 2; + offs = fs->fat_start + cluster * 3 / 2; + if (cluster & 1) { + FAT_ENTRY prevEntry; + get_fat(&prevEntry, fs->fat, cluster - 1, fs); + data[0] = ((new & 0xf) << 4) | (prevEntry.value >> 8); + data[1] = new >> 4; + } else { + FAT_ENTRY subseqEntry; + get_fat(&subseqEntry, fs->fat, cluster + 1, fs); + data[0] = new & 0xff; + data[1] = (new >> 8) | (cluster == fs->clusters - 1 ? 0 : + (0xff & subseqEntry.value) << 4); + } + size = 2; + break; + case 16: + data = fs->fat + cluster * 2; + offs = fs->fat_start + cluster * 2; + *(unsigned short *)data = htole16(new); + size = 2; + break; + case 32: + { + FAT_ENTRY curEntry; + get_fat(&curEntry, fs->fat, cluster, fs); + + data = fs->fat + cluster * 4; + offs = fs->fat_start + cluster * 4; + /* According to M$, the high 4 bits of a FAT32 entry are reserved and + * are not part of the cluster number. So we never touch them. */ + *(uint32_t *)data = htole32((new & 0xfffffff) | + (curEntry.reserved << 28)); + size = 4; + } + break; + default: + die("Bad FAT entry size: %d bits.", fs->fat_bits); + } + fs_write(offs, size, data); + if (fs->nfats > 1) { + fs_write(offs + fs->fat_size, size, data); + } +} + +int bad_cluster(DOS_FS * fs, uint32_t cluster) +{ + FAT_ENTRY curEntry; + get_fat(&curEntry, fs->fat, cluster, fs); + + return FAT_IS_BAD(fs, curEntry.value); +} + +/** + * Get the cluster to which the specified cluster is linked. + * If the linked cluster is marked bad, abort. + * + * @param[in] fs Information about the filesystem + * @param[in] cluster Cluster to follow + * + * @return -1 'cluster' is at the end of the chain + * @return Other values Next cluster in this chain + */ +uint32_t next_cluster(DOS_FS * fs, uint32_t cluster) +{ + uint32_t value; + FAT_ENTRY curEntry; + + get_fat(&curEntry, fs->fat, cluster, fs); + + value = curEntry.value; + if (FAT_IS_BAD(fs, value)) + die("Internal error: next_cluster on bad cluster"); + return FAT_IS_EOF(fs, value) ? -1 : value; +} + +loff_t cluster_start(DOS_FS * fs, uint32_t cluster) +{ + return fs->data_start + ((loff_t) cluster - + 2) * (uint64_t)fs->cluster_size; +} + +/** + * Update internal bookkeeping to show that the specified cluster belongs + * to the specified dentry. + * + * @param[in,out] fs Information about the filesystem + * @param[in] cluster Cluster being assigned + * @param[in] owner Information on dentry that owns this cluster + * (may be NULL) + */ +void set_owner(DOS_FS * fs, uint32_t cluster, DOS_FILE * owner) +{ + if (fs->cluster_owner == NULL) + die("Internal error: attempt to set owner in non-existent table"); + + if (owner && fs->cluster_owner[cluster] + && (fs->cluster_owner[cluster] != owner)) + die("Internal error: attempt to change file owner"); + fs->cluster_owner[cluster] = owner; +} + +DOS_FILE *get_owner(DOS_FS * fs, uint32_t cluster) +{ + if (fs->cluster_owner == NULL) + return NULL; + else + return fs->cluster_owner[cluster]; +} + +void fix_bad(DOS_FS * fs) +{ + uint32_t i; + + if (verbose) + printf("Checking for bad clusters.\n"); + for (i = 2; i < fs->clusters + 2; i++) { + FAT_ENTRY curEntry; + get_fat(&curEntry, fs->fat, i, fs); + + if (!get_owner(fs, i) && !FAT_IS_BAD(fs, curEntry.value)) + if (!fs_test(cluster_start(fs, i), fs->cluster_size)) { + printf("Cluster %lu is unreadable.\n", (unsigned long)i); + set_fat(fs, i, -2); + } + } +} + +void reclaim_free(DOS_FS * fs) +{ + int reclaimed; + uint32_t i; + + if (verbose) + printf("Checking for unused clusters.\n"); + reclaimed = 0; + for (i = 2; i < fs->clusters + 2; i++) { + FAT_ENTRY curEntry; + get_fat(&curEntry, fs->fat, i, fs); + + if (!get_owner(fs, i) && curEntry.value && + !FAT_IS_BAD(fs, curEntry.value)) { + set_fat(fs, i, 0); + reclaimed++; + } + } + if (reclaimed) + printf("Reclaimed %d unused cluster%s (%llu bytes).\n", (int)reclaimed, + reclaimed == 1 ? "" : "s", + (unsigned long long)reclaimed * fs->cluster_size); +} + +/** + * Assign the specified owner to all orphan chains (except cycles). + * Break cross-links between orphan chains. + * + * @param[in,out] fs Information about the filesystem + * @param[in] owner dentry to be assigned ownership of orphans + * @param[in,out] num_refs For each orphan cluster [index], how many + * clusters link to it. + * @param[in] start_cluster Where to start scanning for orphans + */ +static void tag_free(DOS_FS * fs, DOS_FILE * owner, uint32_t *num_refs, + uint32_t start_cluster) +{ + int prev; + uint32_t i, walk; + + if (start_cluster == 0) + start_cluster = 2; + + for (i = start_cluster; i < fs->clusters + 2; i++) { + FAT_ENTRY curEntry; + get_fat(&curEntry, fs->fat, i, fs); + + /* If the current entry is the head of an un-owned chain... */ + if (curEntry.value && !FAT_IS_BAD(fs, curEntry.value) && + !get_owner(fs, i) && !num_refs[i]) { + prev = 0; + /* Walk the chain, claiming ownership as we go */ + for (walk = i; walk != -1; walk = next_cluster(fs, walk)) { + if (!get_owner(fs, walk)) { + set_owner(fs, walk, owner); + } else { + /* We've run into cross-links between orphaned chains, + * or a cycle with a tail. + * Terminate this orphan chain (break the link) + */ + set_fat(fs, prev, -1); + + /* This is not necessary because 'walk' is owned and thus + * will never become the head of a chain (the only case + * that would matter during reclaim to files). + * It's easier to decrement than to prove that it's + * unnecessary. + */ + num_refs[walk]--; + break; + } + prev = walk; + } + } + } +} + +/** + * Recover orphan chains to files, handling any cycles or cross-links. + * + * @param[in,out] fs Information about the filesystem + */ +void reclaim_file(DOS_FS * fs) +{ + DOS_FILE orphan; + int reclaimed, files; + int changed = 0; + uint32_t i, next, walk; + uint32_t *num_refs = NULL; /* Only for orphaned clusters */ + uint32_t total_num_clusters; + + if (verbose) + printf("Reclaiming unconnected clusters.\n"); + + total_num_clusters = fs->clusters + 2UL; + num_refs = alloc(total_num_clusters * sizeof(uint32_t)); + memset(num_refs, 0, (total_num_clusters * sizeof(uint32_t))); + + /* Guarantee that all orphan chains (except cycles) end cleanly + * with an end-of-chain mark. + */ + + for (i = 2; i < total_num_clusters; i++) { + FAT_ENTRY curEntry; + get_fat(&curEntry, fs->fat, i, fs); + + next = curEntry.value; + if (!get_owner(fs, i) && next && next < fs->clusters + 2) { + /* Cluster is linked, but not owned (orphan) */ + FAT_ENTRY nextEntry; + get_fat(&nextEntry, fs->fat, next, fs); + + /* Mark it end-of-chain if it links into an owned cluster, + * a free cluster, or a bad cluster. + */ + if (get_owner(fs, next) || !nextEntry.value || + FAT_IS_BAD(fs, nextEntry.value)) + set_fat(fs, i, -1); + else + num_refs[next]++; + } + } + + /* Scan until all the orphans are accounted for, + * and all cycles and cross-links are broken + */ + do { + tag_free(fs, &orphan, num_refs, changed); + changed = 0; + + /* Any unaccounted-for orphans must be part of a cycle */ + for (i = 2; i < total_num_clusters; i++) { + FAT_ENTRY curEntry; + get_fat(&curEntry, fs->fat, i, fs); + + if (curEntry.value && !FAT_IS_BAD(fs, curEntry.value) && + !get_owner(fs, i)) { + if (!num_refs[curEntry.value]--) + die("Internal error: num_refs going below zero"); + set_fat(fs, i, -1); + changed = curEntry.value; + printf("Broke cycle at cluster %lu in free chain.\n", (unsigned long)i); + + /* If we've created a new chain head, + * tag_free() can claim it + */ + if (num_refs[curEntry.value] == 0) + break; + } + } + } + while (changed); + + /* Now we can start recovery */ + files = reclaimed = 0; + for (i = 2; i < total_num_clusters; i++) + /* If this cluster is the head of an orphan chain... */ + if (get_owner(fs, i) == &orphan && !num_refs[i]) { + DIR_ENT de; + loff_t offset; + files++; + offset = alloc_rootdir_entry(fs, &de, "FSCK%04dREC"); + de.start = htole16(i & 0xffff); + if (fs->fat_bits == 32) + de.starthi = htole16(i >> 16); + for (walk = i; walk > 0 && walk != -1; + walk = next_cluster(fs, walk)) { + de.size = htole32(le32toh(de.size) + fs->cluster_size); + reclaimed++; + } + fs_write(offset, sizeof(DIR_ENT), &de); + } + if (reclaimed) + printf("Reclaimed %d unused cluster%s (%llu bytes) in %d chain%s.\n", + reclaimed, reclaimed == 1 ? "" : "s", + (unsigned long long)reclaimed * fs->cluster_size, files, + files == 1 ? "" : "s"); + + free(num_refs); +} + +uint32_t update_free(DOS_FS * fs) +{ + uint32_t i; + uint32_t free = 0; + int do_set = 0; + + for (i = 2; i < fs->clusters + 2; i++) { + FAT_ENTRY curEntry; + get_fat(&curEntry, fs->fat, i, fs); + + if (!get_owner(fs, i) && !FAT_IS_BAD(fs, curEntry.value)) + ++free; + } + + if (!fs->fsinfo_start) + return free; + + if (verbose) + printf("Checking free cluster summary.\n"); + if (fs->free_clusters != 0xFFFFFFFF) { + if (free != fs->free_clusters) { + printf("Free cluster summary wrong (%ld vs. really %ld)\n", + (long)fs->free_clusters, (long)free); + if (interactive) + printf("1) Correct\n2) Don't correct\n"); + else + printf(" Auto-correcting.\n"); + if (!interactive || get_key("12", "?") == '1') + do_set = 1; + } + } else { + printf("Free cluster summary uninitialized (should be %ld)\n", (long)free); + if (rw) { + if (interactive) + printf("1) Set it\n2) Leave it uninitialized\n"); + else + printf(" Auto-setting.\n"); + if (!interactive || get_key("12", "?") == '1') + do_set = 1; + } + } + + if (do_set) { + uint32_t le_free = htole32(free); + fs->free_clusters = free; + fs_write(fs->fsinfo_start + offsetof(struct info_sector, free_clusters), + sizeof(le_free), &le_free); + } + + return free; +} diff --git a/dosfstools/src/fat.h b/dosfstools/src/fat.h new file mode 100644 index 000000000..b50ed4a96 --- /dev/null +++ b/dosfstools/src/fat.h @@ -0,0 +1,85 @@ +/* fat.h - Read/write access to the FAT + + Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch> + Copyright (C) 2008-2014 Daniel Baumann <mail@daniel-baumann.ch> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + THe complete text of the GNU General Public License + can be found in /usr/share/common-licenses/GPL-3 file. +*/ + +#ifndef _FAT_H +#define _FAT_H + +void read_fat(DOS_FS * fs); + +/* Loads the FAT of the filesystem described by FS. Initializes the FAT, + replaces broken FATs and rejects invalid cluster entries. */ + +void get_fat(FAT_ENTRY * entry, void *fat, uint32_t cluster, DOS_FS * fs); + +/* Retrieve the FAT entry (next chained cluster) for CLUSTER. */ + +void set_fat(DOS_FS * fs, uint32_t cluster, int32_t new); + +/* Changes the value of the CLUSTERth cluster of the FAT of FS to NEW. Special + values of NEW are -1 (EOF, 0xff8 or 0xfff8) and -2 (bad sector, 0xff7 or + 0xfff7) */ + +int bad_cluster(DOS_FS * fs, uint32_t cluster); + +/* Returns a non-zero integer if the CLUSTERth cluster is marked as bad or zero + otherwise. */ + +uint32_t next_cluster(DOS_FS * fs, uint32_t cluster); + +/* Returns the number of the cluster following CLUSTER, or -1 if this is the + last cluster of the respective cluster chain. CLUSTER must not be a bad + cluster. */ + +loff_t cluster_start(DOS_FS * fs, uint32_t cluster); + +/* Returns the byte offset of CLUSTER, relative to the respective device. */ + +void set_owner(DOS_FS * fs, uint32_t cluster, DOS_FILE * owner); + +/* Sets the owner pointer of the respective cluster to OWNER. If OWNER was NULL + before, it can be set to NULL or any non-NULL value. Otherwise, only NULL is + accepted as the new value. */ + +DOS_FILE *get_owner(DOS_FS * fs, uint32_t cluster); + +/* Returns the owner of the repective cluster or NULL if the cluster has no + owner. */ + +void fix_bad(DOS_FS * fs); + +/* Scans the disk for currently unused bad clusters and marks them as bad. */ + +void reclaim_free(DOS_FS * fs); + +/* Marks all allocated, but unused clusters as free. */ + +void reclaim_file(DOS_FS * fs); + +/* Scans the FAT for chains of allocated, but unused clusters and creates files + for them in the root directory. Also tries to fix all inconsistencies (e.g. + loops, shared clusters, etc.) in the process. */ + +uint32_t update_free(DOS_FS * fs); + +/* Updates free cluster count in FSINFO sector. */ + +#endif diff --git a/dosfstools/src/fatlabel.c b/dosfstools/src/fatlabel.c new file mode 100644 index 000000000..1484ba527 --- /dev/null +++ b/dosfstools/src/fatlabel.c @@ -0,0 +1,144 @@ +/* fatlabel.c - User interface + + Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch> + Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> + Copyright (C) 2007 Red Hat, Inc. + Copyright (C) 2008-2014 Daniel Baumann <mail@daniel-baumann.ch> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + The complete text of the GNU General Public License + can be found in /usr/share/common-licenses/GPL-3 file. +*/ + +#include "version.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <getopt.h> +#include <ctype.h> + +#include "common.h" +#include "fsck.fat.h" +#include "io.h" +#include "boot.h" +#include "fat.h" +#include "file.h" +#include "check.h" + +int interactive = 0, rw = 0, list = 0, test = 0, verbose = 0, write_immed = 0; +int atari_format = 0; +unsigned n_files = 0; +void *mem_queue = NULL; + +static void usage(int error) +{ + FILE *f = error ? stderr : stdout; + int status = error ? 1 : 0; + + fprintf(f, "usage: fatlabel device [label]\n"); + exit(status); +} + +/* + * ++roman: On m68k, check if this is an Atari; if yes, turn on Atari variant + * of MS-DOS filesystem by default. + */ +static void check_atari(void) +{ +#ifdef __mc68000__ + FILE *f; + char line[128], *p; + + if (!(f = fopen("/proc/hardware", "r"))) { + perror("/proc/hardware"); + return; + } + + while (fgets(line, sizeof(line), f)) { + if (strncmp(line, "Model:", 6) == 0) { + p = line + 6; + p += strspn(p, " \t"); + if (strncmp(p, "Atari ", 6) == 0) + atari_format = 1; + break; + } + } + fclose(f); +#endif +} + +int main(int argc, char *argv[]) +{ + DOS_FS fs = { 0 }; + rw = 0; + + int i; + + char *device = NULL; + char label[12] = { 0 }; + + loff_t offset; + DIR_ENT de; + + check_atari(); + + if (argc < 2 || argc > 3) + usage(1); + + if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) + usage(0); + else if (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version")) { + printf("fatlabel " VERSION " (" VERSION_DATE ")\n"); + exit(0); + } + + device = argv[1]; + if (argc == 3) { + strncpy(label, argv[2], 11); + if (strlen(argv[2]) > 11) { + fprintf(stderr, + "fatlabel: labels can be no longer than 11 characters\n"); + exit(1); + } + for (i = 0; label[i] && i < 11; i++) + /* don't know if here should be more strict !uppercase(label[i]) */ + if (islower(label[i])) { + fprintf(stderr, + "fatlabel: warning - lowercase labels might not work properly with DOS or Windows\n"); + break; + } + rw = 1; + } + + fs_open(device, rw); + read_boot(&fs); + if (fs.fat_bits == 32) + read_fat(&fs); + if (!rw) { + offset = find_volume_de(&fs, &de); + if (offset == 0) + fprintf(stdout, "%s\n", fs.label); + else + fprintf(stdout, "%.8s%.3s\n", de.name, de.ext); + exit(0); + } + + write_label(&fs, label); + fs_close(rw); + return 0; +} diff --git a/dosfstools/src/file.c b/dosfstools/src/file.c new file mode 100644 index 000000000..dffcec1cd --- /dev/null +++ b/dosfstools/src/file.c @@ -0,0 +1,276 @@ +/* file.c - Additional file attributes + + Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch> + Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> + Copyright (C) 2008-2014 Daniel Baumann <mail@daniel-baumann.ch> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + The complete text of the GNU General Public License + can be found in /usr/share/common-licenses/GPL-3 file. +*/ + +/* FAT32, VFAT, Atari format support, and various fixes additions May 1998 + * by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <unistd.h> + +#include "common.h" +#include "file.h" +#include "msdos_fs.h" + +FDSC *fp_root = NULL; + +static void put_char(char **p, unsigned char c) +{ + if ((c >= ' ' && c < 0x7f) || c >= 0xa0) + *(*p)++ = c; + else { + *(*p)++ = '\\'; + *(*p)++ = '0' + (c >> 6); + *(*p)++ = '0' + ((c >> 3) & 7); + *(*p)++ = '0' + (c & 7); + } +} + +/** + * Construct the "pretty-printed" representation of the name in a short directory entry. + * + * @param[in] fixed Pointer to name[0] of a DIR_ENT + * + * @return Pointer to static string containing pretty "8.3" equivalent of the + * name in the directory entry. + */ +char *file_name(unsigned char *fixed) +{ + static char path[MSDOS_NAME * 4 + 2]; + char *p; + int i, j; + + p = path; + for (i = j = 0; i < 8; i++) + if (fixed[i] != ' ') { + while (j++ < i) + *p++ = ' '; + put_char(&p, fixed[i]); + } + if (strncmp((const char *)(fixed + 8), " ", 3)) { + *p++ = '.'; + for (i = j = 0; i < 3; i++) + if (fixed[i + 8] != ' ') { + while (j++ < i) + *p++ = ' '; + put_char(&p, fixed[i + 8]); + } + } + *p = 0; + return path; +} + +int file_cvt(unsigned char *name, unsigned char *fixed) +{ + unsigned char c; + int size, ext, cnt; + + size = 8; + ext = 0; + while (*name) { + c = *name; + if (c < ' ' || c > 0x7e || strchr("*?<>|\"/", c)) { + printf("Invalid character in name. Use \\ooo for special " + "characters.\n"); + return 0; + } + if (c == '.') { + if (ext) { + printf("Duplicate dots in name.\n"); + return 0; + } + while (size--) + *fixed++ = ' '; + size = 3; + ext = 1; + name++; + continue; + } + if (c == '\\') { + c = 0; + for (cnt = 3; cnt; cnt--) { + if (*name < '0' || *name > '7') { + printf("Invalid octal character.\n"); + return 0; + } + c = c * 8 + *name++ - '0'; + } + if (cnt < 4) { + printf("Expected three octal digits.\n"); + return 0; + } + name += 3; + } + if (islower(c)) + c = toupper(c); + if (size) { + *fixed++ = c; + size--; + } + name++; + } + if (*name || size == 8) + return 0; + if (!ext) { + while (size--) + *fixed++ = ' '; + size = 3; + } + while (size--) + *fixed++ = ' '; + return 1; +} + +void file_add(char *path, FD_TYPE type) +{ + FDSC **current, *walk; + char name[MSDOS_NAME]; + char *here; + + current = &fp_root; + if (*path != '/') + die("%s: Absolute path required.", path); + path++; + while (1) { + if ((here = strchr(path, '/'))) + *here = 0; + if (!file_cvt((unsigned char *)path, (unsigned char *)name)) + exit(2); + for (walk = *current; walk; walk = walk->next) + if (!here && (!strncmp(name, walk->name, MSDOS_NAME) || (type == + fdt_undelete + && + !strncmp + (name + 1, + walk->name + + 1, + MSDOS_NAME + - 1)))) + die("Ambiguous name: \"%s\"", path); + else if (here && !strncmp(name, walk->name, MSDOS_NAME)) + break; + if (!walk) { + walk = alloc(sizeof(FDSC)); + strncpy(walk->name, name, MSDOS_NAME); + walk->type = here ? fdt_none : type; + walk->first = NULL; + walk->next = *current; + *current = walk; + } + current = &walk->first; + if (!here) + break; + *here = '/'; + path = here + 1; + } +} + +FDSC **file_cd(FDSC ** curr, char *fixed) +{ + FDSC **walk; + + if (!curr || !*curr) + return NULL; + for (walk = curr; *walk; walk = &(*walk)->next) + if (!strncmp((*walk)->name, fixed, MSDOS_NAME) && (*walk)->first) + return &(*walk)->first; + return NULL; +} + +static FDSC **file_find(FDSC ** dir, char *fixed) +{ + if (!dir || !*dir) + return NULL; + if (*(unsigned char *)fixed == DELETED_FLAG) { + while (*dir) { + if (!strncmp((*dir)->name + 1, fixed + 1, MSDOS_NAME - 1) + && !(*dir)->first) + return dir; + dir = &(*dir)->next; + } + return NULL; + } + while (*dir) { + if (!strncmp((*dir)->name, fixed, MSDOS_NAME) && !(*dir)->first) + return dir; + dir = &(*dir)->next; + } + return NULL; +} + +/* Returns the attribute of the file FIXED in directory CURR or FDT_NONE if no + such file exists or if CURR is NULL. */ +FD_TYPE file_type(FDSC ** curr, char *fixed) +{ + FDSC **this; + + if ((this = file_find(curr, fixed))) + return (*this)->type; + return fdt_none; +} + +void file_modify(FDSC ** curr, char *fixed) +{ + FDSC **this, *next; + + if (!(this = file_find(curr, fixed))) + die("Internal error: file_find failed"); + switch ((*this)->type) { + case fdt_drop: + printf("Dropping %s\n", file_name((unsigned char *)fixed)); + *(unsigned char *)fixed = DELETED_FLAG; + break; + case fdt_undelete: + *fixed = *(*this)->name; + printf("Undeleting %s\n", file_name((unsigned char *)fixed)); + break; + default: + die("Internal error: file_modify"); + } + next = (*this)->next; + free(*this); + *this = next; +} + +static void report_unused(FDSC * this) +{ + FDSC *next; + + while (this) { + next = this->next; + if (this->first) + report_unused(this->first); + else if (this->type != fdt_none) + printf("Warning: did not %s file %s\n", this->type == fdt_drop ? + "drop" : "undelete", file_name((unsigned char *)this->name)); + free(this); + this = next; + } +} + +void file_unused(void) +{ + report_unused(fp_root); +} diff --git a/dosfstools/src/file.h b/dosfstools/src/file.h new file mode 100644 index 000000000..eaaf356be --- /dev/null +++ b/dosfstools/src/file.h @@ -0,0 +1,72 @@ +/* file.h - Additional file attributes + + Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch> + Copyright (C) 2008-2014 Daniel Baumann <mail@daniel-baumann.ch> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + The complete text of the GNU General Public License + can be found in /usr/share/common-licenses/GPL-3 file. +*/ + +#ifndef _FILE_H +#define _FILE_H + +#include "msdos_fs.h" + +typedef enum { fdt_none, fdt_drop, fdt_undelete } FD_TYPE; + +typedef struct _fptr { + char name[MSDOS_NAME]; + FD_TYPE type; + struct _fptr *first; /* first entry */ + struct _fptr *next; /* next file in directory */ +} FDSC; + +extern FDSC *fp_root; + +char *file_name(unsigned char *fixed); + +/* Returns a pointer to a pretty-printed representation of a fixed MS-DOS file + name. */ + +int file_cvt(unsigned char *name, unsigned char *fixed); + +/* Converts a pretty-printed file name to the fixed MS-DOS format. Returns a + non-zero integer on success, zero on failure. */ + +void file_add(char *path, FD_TYPE type); + +/* Define special attributes for a path. TYPE can be either FDT_DROP or + FDT_UNDELETE. */ + +FDSC **file_cd(FDSC ** curr, char *fixed); + +/* Returns a pointer to the directory descriptor of the subdirectory FIXED of + CURR, or NULL if no such subdirectory exists. */ + +FD_TYPE file_type(FDSC ** curr, char *fixed); + +/* Returns the attribute of the file FIXED in directory CURR or FDT_NONE if no + such file exists or if CURR is NULL. */ + +void file_modify(FDSC ** curr, char *fixed); + +/* Performs the necessary operation on the entry of CURR that is named FIXED. */ + +void file_unused(void); + +/* Displays warnings for all unused file attributes. */ + +#endif diff --git a/dosfstools/src/fsck.fat.c b/dosfstools/src/fsck.fat.c new file mode 100644 index 000000000..2bc3dc216 --- /dev/null +++ b/dosfstools/src/fsck.fat.c @@ -0,0 +1,215 @@ +/* fsck.fat.c - User interface + + Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch> + Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> + Copyright (C) 2008-2014 Daniel Baumann <mail@daniel-baumann.ch> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + The complete text of the GNU General Public License + can be found in /usr/share/common-licenses/GPL-3 file. +*/ + +/* FAT32, VFAT, Atari format support, and various fixes additions May 1998 + * by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */ + +#include "version.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <getopt.h> + +#include "common.h" +#include "fsck.fat.h" +#include "io.h" +#include "boot.h" +#include "fat.h" +#include "file.h" +#include "check.h" + +int interactive = 0, rw = 0, list = 0, test = 0, verbose = 0, write_immed = 0; +int atari_format = 0, boot_only = 0; +unsigned n_files = 0; +void *mem_queue = NULL; + +static void usage(char *name) +{ + fprintf(stderr, "usage: %s [-aAbflrtvVwy] [-d path -d ...] " + "[-u path -u ...]\n%15sdevice\n", name, ""); + fprintf(stderr, " -a automatically repair the filesystem\n"); + fprintf(stderr, " -A toggle Atari filesystem format\n"); + fprintf(stderr, " -b make read-only boot sector check\n"); + fprintf(stderr, " -d path drop that file\n"); + fprintf(stderr, " -f salvage unused chains to files\n"); + fprintf(stderr, " -l list path names\n"); + fprintf(stderr, + " -n no-op, check non-interactively without changing\n"); + fprintf(stderr, " -p same as -a, for compat with other *fsck\n"); + fprintf(stderr, " -r interactively repair the filesystem (default)\n"); + fprintf(stderr, " -t test for bad clusters\n"); + fprintf(stderr, " -u path try to undelete that (non-directory) file\n"); + fprintf(stderr, " -v verbose mode\n"); + fprintf(stderr, " -V perform a verification pass\n"); + fprintf(stderr, " -w write changes to disk immediately\n"); + fprintf(stderr, " -y same as -a, for compat with other *fsck\n"); + exit(2); +} + +/* + * ++roman: On m68k, check if this is an Atari; if yes, turn on Atari variant + * of MS-DOS filesystem by default. + */ +static void check_atari(void) +{ +#ifdef __mc68000__ + FILE *f; + char line[128], *p; + + if (!(f = fopen("/proc/hardware", "r"))) { + perror("/proc/hardware"); + return; + } + + while (fgets(line, sizeof(line), f)) { + if (strncmp(line, "Model:", 6) == 0) { + p = line + 6; + p += strspn(p, " \t"); + if (strncmp(p, "Atari ", 6) == 0) + atari_format = 1; + break; + } + } + fclose(f); +#endif +} + +int main(int argc, char **argv) +{ + DOS_FS fs; + int salvage_files, verify, c; + uint32_t free_clusters = 0; + + memset(&fs, 0, sizeof(fs)); + salvage_files = verify = 0; + rw = interactive = 1; + check_atari(); + + while ((c = getopt(argc, argv, "Aad:bflnprtu:vVwy")) != -1) + switch (c) { + case 'A': /* toggle Atari format */ + atari_format = !atari_format; + break; + case 'a': + case 'p': + case 'y': + rw = 1; + interactive = 0; + salvage_files = 1; + break; + case 'b': + rw = 0; + interactive = 0; + boot_only = 1; + break; + case 'd': + file_add(optarg, fdt_drop); + break; + case 'f': + salvage_files = 1; + break; + case 'l': + list = 1; + break; + case 'n': + rw = 0; + interactive = 0; + break; + case 'r': + rw = 1; + interactive = 1; + break; + case 't': + test = 1; + break; + case 'u': + file_add(optarg, fdt_undelete); + break; + case 'v': + verbose = 1; + break; + case 'V': + verify = 1; + break; + case 'w': + write_immed = 1; + break; + default: + usage(argv[0]); + } + if ((test || write_immed) && !rw) { + fprintf(stderr, "-t and -w can not be used in read only mode\n"); + exit(2); + } + if (optind != argc - 1) + usage(argv[0]); + + printf("fsck.fat " VERSION " (" VERSION_DATE ")\n"); + fs_open(argv[optind], rw); + + read_boot(&fs); + if (boot_only) + goto exit; + + if (verify) + printf("Starting check/repair pass.\n"); + while (read_fat(&fs), scan_root(&fs)) + qfree(&mem_queue); + if (test) + fix_bad(&fs); + if (salvage_files) + reclaim_file(&fs); + else + reclaim_free(&fs); + free_clusters = update_free(&fs); + file_unused(); + qfree(&mem_queue); + if (verify) { + n_files = 0; + printf("Starting verification pass.\n"); + read_fat(&fs); + scan_root(&fs); + reclaim_free(&fs); + qfree(&mem_queue); + } + +exit: + if (fs_changed()) { + if (rw) { + if (interactive) + rw = get_key("yn", "Perform changes ? (y/n)") == 'y'; + else + printf("Performing changes.\n"); + } else + printf("Leaving filesystem unchanged.\n"); + } + + if (!boot_only) + printf("%s: %u files, %lu/%lu clusters\n", argv[optind], + n_files, (unsigned long)fs.clusters - free_clusters, (unsigned long)fs.clusters); + + return fs_close(rw) ? 1 : 0; +} diff --git a/dosfstools/src/fsck.fat.h b/dosfstools/src/fsck.fat.h new file mode 100644 index 000000000..e5f617871 --- /dev/null +++ b/dosfstools/src/fsck.fat.h @@ -0,0 +1,191 @@ +/* fsck.fat.h - Common data structures and global variables + + Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch> + Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> + Copyright (C) 2008-2014 Daniel Baumann <mail@daniel-baumann.ch> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + The complete text of the GNU General Public License + can be found in /usr/share/common-licenses/GPL-3 file. +*/ + +/* FAT32, VFAT, Atari format support, and various fixes additions May 1998 + * by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */ + +#ifndef _DOSFSCK_H +#define _DOSFSCK_H + +#include <fcntl.h> +#include <stddef.h> +#include <stdint.h> +#include <endian.h> + +#include "msdos_fs.h" + +#define VFAT_LN_ATTR (ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME) + +#define FAT_STATE_DIRTY 0x01 + +/* ++roman: Use own definition of boot sector structure -- the kernel headers' + * name for it is msdos_boot_sector in 2.0 and fat_boot_sector in 2.1 ... */ +struct boot_sector { + uint8_t ignored[3]; /* Boot strap short or near jump */ + uint8_t system_id[8]; /* Name - can be used to special case + partition manager volumes */ + uint8_t sector_size[2]; /* bytes per logical sector */ + uint8_t cluster_size; /* sectors/cluster */ + uint16_t reserved; /* reserved sectors */ + uint8_t fats; /* number of FATs */ + uint8_t dir_entries[2]; /* root directory entries */ + uint8_t sectors[2]; /* number of sectors */ + uint8_t media; /* media code (unused) */ + uint16_t fat_length; /* sectors/FAT */ + uint16_t secs_track; /* sectors per track */ + uint16_t heads; /* number of heads */ + uint32_t hidden; /* hidden sectors (unused) */ + uint32_t total_sect; /* number of sectors (if sectors == 0) */ + + /* The following fields are only used by FAT32 */ + uint32_t fat32_length; /* sectors/FAT */ + uint16_t flags; /* bit 8: fat mirroring, low 4: active fat */ + uint8_t version[2]; /* major, minor filesystem version */ + uint32_t root_cluster; /* first cluster in root directory */ + uint16_t info_sector; /* filesystem info sector */ + uint16_t backup_boot; /* backup boot sector */ + uint8_t reserved2[12]; /* Unused */ + + uint8_t drive_number; /* Logical Drive Number */ + uint8_t reserved3; /* Unused */ + + uint8_t extended_sig; /* Extended Signature (0x29) */ + uint32_t serial; /* Serial number */ + uint8_t label[11]; /* FS label */ + uint8_t fs_type[8]; /* FS Type */ + + /* fill up to 512 bytes */ + uint8_t junk[422]; +} __attribute__ ((packed)); + +struct boot_sector_16 { + uint8_t ignored[3]; /* Boot strap short or near jump */ + uint8_t system_id[8]; /* Name - can be used to special case + partition manager volumes */ + uint8_t sector_size[2]; /* bytes per logical sector */ + uint8_t cluster_size; /* sectors/cluster */ + uint16_t reserved; /* reserved sectors */ + uint8_t fats; /* number of FATs */ + uint8_t dir_entries[2]; /* root directory entries */ + uint8_t sectors[2]; /* number of sectors */ + uint8_t media; /* media code (unused) */ + uint16_t fat_length; /* sectors/FAT */ + uint16_t secs_track; /* sectors per track */ + uint16_t heads; /* number of heads */ + uint32_t hidden; /* hidden sectors (unused) */ + uint32_t total_sect; /* number of sectors (if sectors == 0) */ + + uint8_t drive_number; /* Logical Drive Number */ + uint8_t reserved2; /* Unused */ + + uint8_t extended_sig; /* Extended Signature (0x29) */ + uint32_t serial; /* Serial number */ + uint8_t label[11]; /* FS label */ + uint8_t fs_type[8]; /* FS Type */ + + /* fill up to 512 bytes */ + uint8_t junk[450]; +} __attribute__ ((packed)); + +struct info_sector { + uint32_t magic; /* Magic for info sector ('RRaA') */ + uint8_t junk[0x1dc]; + uint32_t reserved1; /* Nothing as far as I can tell */ + uint32_t signature; /* 0x61417272 ('rrAa') */ + uint32_t free_clusters; /* Free cluster count. -1 if unknown */ + uint32_t next_cluster; /* Most recently allocated cluster. */ + uint32_t reserved2[3]; + uint16_t reserved3; + uint16_t boot_sign; +}; + +typedef struct { + uint8_t name[8], ext[3]; /* name and extension */ + uint8_t attr; /* attribute bits */ + uint8_t lcase; /* Case for base and extension */ + uint8_t ctime_ms; /* Creation time, milliseconds */ + uint16_t ctime; /* Creation time */ + uint16_t cdate; /* Creation date */ + uint16_t adate; /* Last access date */ + uint16_t starthi; /* High 16 bits of cluster in FAT32 */ + uint16_t time, date, start; /* time, date and first cluster */ + uint32_t size; /* file size (in bytes) */ +} __attribute__ ((packed)) DIR_ENT; + +typedef struct _dos_file { + DIR_ENT dir_ent; + char *lfn; + loff_t offset; + loff_t lfn_offset; + struct _dos_file *parent; /* parent directory */ + struct _dos_file *next; /* next entry */ + struct _dos_file *first; /* first entry (directory only) */ +} DOS_FILE; + +typedef struct { + uint32_t value; + uint32_t reserved; +} FAT_ENTRY; + +typedef struct { + int nfats; + loff_t fat_start; + unsigned int fat_size; /* unit is bytes */ + unsigned int fat_bits; /* size of a FAT entry */ + unsigned int eff_fat_bits; /* # of used bits in a FAT entry */ + uint32_t root_cluster; /* 0 for old-style root dir */ + loff_t root_start; + unsigned int root_entries; + loff_t data_start; + unsigned int cluster_size; + uint32_t clusters; + loff_t fsinfo_start; /* 0 if not present */ + long free_clusters; + loff_t backupboot_start; /* 0 if not present */ + unsigned char *fat; + DOS_FILE **cluster_owner; + char *label; +} DOS_FS; + +extern int interactive, rw, list, verbose, test, write_immed; +extern int atari_format; +extern unsigned n_files; +extern void *mem_queue; + +/* value to use as end-of-file marker */ +#define FAT_EOF(fs) ((atari_format ? 0xfff : 0xff8) | FAT_EXTD(fs)) +#define FAT_IS_EOF(fs,v) ((uint32_t)(v) >= (0xff8|FAT_EXTD(fs))) +/* value to mark bad clusters */ +#define FAT_BAD(fs) (0xff7 | FAT_EXTD(fs)) +/* range of values used for bad clusters */ +#define FAT_MIN_BAD(fs) ((atari_format ? 0xff0 : 0xff7) | FAT_EXTD(fs)) +#define FAT_MAX_BAD(fs) ((atari_format ? 0xff7 : 0xff7) | FAT_EXTD(fs)) +#define FAT_IS_BAD(fs,v) ((v) >= FAT_MIN_BAD(fs) && (v) <= FAT_MAX_BAD(fs)) + +/* return -16 as a number with fs->fat_bits bits */ +#define FAT_EXTD(fs) (((1 << fs->eff_fat_bits)-1) & ~0xf) + +/* marker for files with no 8.3 name */ +#define FAT_NO_83NAME 32 + +#endif diff --git a/dosfstools/src/io.c b/dosfstools/src/io.c new file mode 100644 index 000000000..450432c8e --- /dev/null +++ b/dosfstools/src/io.c @@ -0,0 +1,232 @@ +/* io.c - Virtual disk input/output + + Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch> + Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> + Copyright (C) 2008-2014 Daniel Baumann <mail@daniel-baumann.ch> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + The complete text of the GNU General Public License + can be found in /usr/share/common-licenses/GPL-3 file. +*/ + +/* + * Thu Feb 26 01:15:36 CET 1998: Martin Schulze <joey@infodrom.north.de> + * Fixed nasty bug that caused every file with a name like + * xxxxxxxx.xxx to be treated as bad name that needed to be fixed. + */ + +/* FAT32, VFAT, Atari format support, and various fixes additions May 1998 + * by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */ + +#define _LARGEFILE64_SOURCE +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <errno.h> +#include <fcntl.h> +#include <linux/fd.h> + +#include "fsck.fat.h" +#include "common.h" +#include "io.h" + +typedef struct _change { + void *data; + loff_t pos; + int size; + struct _change *next; +} CHANGE; + +static CHANGE *changes, *last; +static int fd, did_change = 0; + +unsigned device_no; + +#ifdef __DJGPP__ +#include "volume.h" /* DOS lowlevel disk access functions */ +loff_t llseek(int fd, loff_t offset, int whence) +{ + if ((whence != SEEK_SET) || (fd == 4711)) + return -1; /* only those supported */ + return VolumeSeek(offset); +} + +#define open OpenVolume +#define close CloseVolume +#define read(a,b,c) ReadVolume(b,c) +#define write(a,b,c) WriteVolume(b,c) +#else +loff_t llseek(int fd, loff_t offset, int whence) +{ + return (loff_t) lseek64(fd, (off64_t) offset, whence); +} +#endif + +void fs_open(char *path, int rw) +{ + struct stat stbuf; + + if ((fd = open(path, rw ? O_RDWR : O_RDONLY)) < 0) { + perror("open"); + exit(6); + } + changes = last = NULL; + did_change = 0; + +#ifndef _DJGPP_ + if (fstat(fd, &stbuf) < 0) + pdie("fstat %s", path); + device_no = S_ISBLK(stbuf.st_mode) ? (stbuf.st_rdev >> 8) & 0xff : 0; +#else + if (IsWorkingOnImageFile()) { + if (fstat(GetVolumeHandle(), &stbuf) < 0) + pdie("fstat image %s", path); + device_no = 0; + } else { + /* return 2 for floppy, 1 for ramdisk, 7 for loopback */ + /* used by boot.c in Atari mode: floppy always FAT12, */ + /* loopback / ramdisk only FAT12 if usual floppy size, */ + /* harddisk always FAT16 on Atari... */ + device_no = (GetVolumeHandle() < 2) ? 2 : 1; + /* telling "floppy" for A:/B:, "ramdisk" for the rest */ + } +#endif +} + +/** + * Read data from the partition, accounting for any pending updates that are + * queued for writing. + * + * @param[in] pos Byte offset, relative to the beginning of the partition, + * at which to read + * @param[in] size Number of bytes to read + * @param[out] data Where to put the data read + */ +void fs_read(loff_t pos, int size, void *data) +{ + CHANGE *walk; + int got; + + if (llseek(fd, pos, 0) != pos) + pdie("Seek to %lld", pos); + if ((got = read(fd, data, size)) < 0) + pdie("Read %d bytes at %lld", size, pos); + if (got != size) + die("Got %d bytes instead of %d at %lld", got, size, pos); + for (walk = changes; walk; walk = walk->next) { + if (walk->pos < pos + size && walk->pos + walk->size > pos) { + if (walk->pos < pos) + memcpy(data, (char *)walk->data + pos - walk->pos, min(size, + walk-> + size - + pos + + walk-> + pos)); + else + memcpy((char *)data + walk->pos - pos, walk->data, + min(walk->size, size + pos - walk->pos)); + } + } +} + +int fs_test(loff_t pos, int size) +{ + void *scratch; + int okay; + + if (llseek(fd, pos, 0) != pos) + pdie("Seek to %lld", pos); + scratch = alloc(size); + okay = read(fd, scratch, size) == size; + free(scratch); + return okay; +} + +void fs_write(loff_t pos, int size, void *data) +{ + CHANGE *new; + int did; + + if (write_immed) { + did_change = 1; + if (llseek(fd, pos, 0) != pos) + pdie("Seek to %lld", pos); + if ((did = write(fd, data, size)) == size) + return; + if (did < 0) + pdie("Write %d bytes at %lld", size, pos); + die("Wrote %d bytes instead of %d at %lld", did, size, pos); + } + new = alloc(sizeof(CHANGE)); + new->pos = pos; + memcpy(new->data = alloc(new->size = size), data, size); + new->next = NULL; + if (last) + last->next = new; + else + changes = new; + last = new; +} + +static void fs_flush(void) +{ + CHANGE *this; + int size; + + while (changes) { + this = changes; + changes = changes->next; + if (llseek(fd, this->pos, 0) != this->pos) + fprintf(stderr, + "Seek to %lld failed: %s\n Did not write %d bytes.\n", + (long long)this->pos, strerror(errno), this->size); + else if ((size = write(fd, this->data, this->size)) < 0) + fprintf(stderr, "Writing %d bytes at %lld failed: %s\n", this->size, + (long long)this->pos, strerror(errno)); + else if (size != this->size) + fprintf(stderr, "Wrote %d bytes instead of %d bytes at %lld." + "\n", size, this->size, (long long)this->pos); + free(this->data); + free(this); + } +} + +int fs_close(int write) +{ + CHANGE *next; + int changed; + + changed = ! !changes; + if (write) + fs_flush(); + else + while (changes) { + next = changes->next; + free(changes->data); + free(changes); + changes = next; + } + if (close(fd) < 0) + pdie("closing filesystem"); + return changed || did_change; +} + +int fs_changed(void) +{ + return ! !changes || did_change; +} diff --git a/dosfstools/src/io.h b/dosfstools/src/io.h new file mode 100644 index 000000000..d23d07ee3 --- /dev/null +++ b/dosfstools/src/io.h @@ -0,0 +1,71 @@ +/* io.h - Virtual disk input/output + + Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch> + Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> + Copyright (C) 2008-2014 Daniel Baumann <mail@daniel-baumann.ch> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + The complete text of the GNU General Public License + can be found in /usr/share/common-licenses/GPL-3 file. +*/ + +/* FAT32, VFAT, Atari format support, and various fixes additions May 1998 + * by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */ + +#ifndef _IO_H +#define _IO_H + +#include <fcntl.h> /* for loff_t */ + +loff_t llseek(int fd, loff_t offset, int whence); + +/* lseek() analogue for large offsets. */ + +void fs_open(char *path, int rw); + +/* Opens the filesystem PATH. If RW is zero, the filesystem is opened + read-only, otherwise, it is opened read-write. */ + +void fs_read(loff_t pos, int size, void *data); + +/* Reads SIZE bytes starting at POS into DATA. Performs all applicable + changes. */ + +int fs_test(loff_t pos, int size); + +/* Returns a non-zero integer if SIZE bytes starting at POS can be read without + errors. Otherwise, it returns zero. */ + +void fs_write(loff_t pos, int size, void *data); + +/* If write_immed is non-zero, SIZE bytes are written from DATA to the disk, + starting at POS. If write_immed is zero, the change is added to a list in + memory. */ + +int fs_close(int write); + +/* Closes the filesystem, performs all pending changes if WRITE is non-zero + and removes the list of changes. Returns a non-zero integer if the file + system has been changed since the last fs_open, zero otherwise. */ + +int fs_changed(void); + +/* Determines whether the filesystem has changed. See fs_close. */ + +extern unsigned device_no; + +/* Major number of device (0 if file) and size (in 512 byte sectors) */ + +#endif diff --git a/dosfstools/src/lfn.c b/dosfstools/src/lfn.c new file mode 100644 index 000000000..2601172ee --- /dev/null +++ b/dosfstools/src/lfn.c @@ -0,0 +1,528 @@ +/* lfn.c - Functions for handling VFAT long filenames + + Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> + Copyright (C) 2008-2014 Daniel Baumann <mail@daniel-baumann.ch> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + The complete text of the GNU General Public License + can be found in /usr/share/common-licenses/GPL-3 file. +*/ + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <limits.h> +#include <time.h> + +#include "common.h" +#include "io.h" +#include "fsck.fat.h" +#include "lfn.h" +#include "file.h" + +typedef struct { + uint8_t id; /* sequence number for slot */ + uint8_t name0_4[10]; /* first 5 characters in name */ + uint8_t attr; /* attribute byte */ + uint8_t reserved; /* always 0 */ + uint8_t alias_checksum; /* checksum for 8.3 alias */ + uint8_t name5_10[12]; /* 6 more characters in name */ + uint16_t start; /* starting cluster number, 0 in long slots */ + uint8_t name11_12[4]; /* last 2 characters in name */ +} LFN_ENT; + +#define LFN_ID_START 0x40 +#define LFN_ID_SLOTMASK 0x1f + +#define CHARS_PER_LFN 13 + +/* These modul-global vars represent the state of the LFN parser */ +unsigned char *lfn_unicode = NULL; +unsigned char lfn_checksum; +int lfn_slot = -1; +loff_t *lfn_offsets = NULL; +int lfn_parts = 0; + +static unsigned char fat_uni2esc[64] = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', + 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', + 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', + 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', + 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', + 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', + 'u', 'v', 'w', 'x', 'y', 'z', '+', '-' +}; + +/* This defines which unicode chars are directly convertable to ISO-8859-1 */ +#define UNICODE_CONVERTABLE(cl,ch) (ch == 0 && (cl < 0x80 || cl >= 0xa0)) + +/* for maxlen param */ +#define UNTIL_0 INT_MAX + +/* Convert name part in 'lfn' from unicode to ASCII */ +#define CNV_THIS_PART(lfn) \ + ({ \ + unsigned char __part_uni[CHARS_PER_LFN*2]; \ + copy_lfn_part( __part_uni, lfn ); \ + cnv_unicode( __part_uni, CHARS_PER_LFN, 0 ); \ + }) + +/* Convert name parts collected so far (from previous slots) from unicode to + * ASCII */ +#define CNV_PARTS_SO_FAR() \ + (cnv_unicode( lfn_unicode+(lfn_slot*CHARS_PER_LFN*2), \ + lfn_parts*CHARS_PER_LFN, 0 )) + +#define BYTES_TO_WCHAR(cl,ch) ((wchar_t)((unsigned)(cl) + ((unsigned)(ch) << 8))) +static size_t mbslen(wchar_t x) +{ + wchar_t wstr[] = { x, 0 }; + return wcstombs(NULL, wstr, 0); +} + +static size_t wctombs(char *dest, wchar_t x) +{ + wchar_t wstr[] = { x, 0 }; + size_t size = wcstombs(NULL, wstr, 0); + if (size != (size_t) - 1) + size = wcstombs(dest, wstr, size + 1); + return size; +} + +/* This function converts an unicode string to a normal ASCII string, assuming + * ISO-8859-1 charset. Characters not in 8859-1 are converted to the same + * escape notation as used by the kernel, i.e. the uuencode-like ":xxx" */ +static char *cnv_unicode(const unsigned char *uni, int maxlen, int use_q) +{ + const unsigned char *up; + unsigned char *out, *cp; + int len, val; + size_t x; + + for (len = 0, up = uni; (up - uni) / 2 < maxlen && (up[0] || up[1]); + up += 2) { + if ((x = mbslen(BYTES_TO_WCHAR(up[0], up[1]))) != (size_t) - 1) + len += x; + else if (UNICODE_CONVERTABLE(up[0], up[1])) + ++len; + else + len += 4; + } + cp = out = use_q ? qalloc(&mem_queue, len + 1) : alloc(len + 1); + + for (up = uni; (up - uni) / 2 < maxlen && (up[0] || up[1]); up += 2) { + if ((x = + wctombs((char *)cp, BYTES_TO_WCHAR(up[0], up[1]))) != (size_t) - 1) + cp += x; + else if (UNICODE_CONVERTABLE(up[0], up[1])) + *cp++ = up[0]; + else { + /* here the same escape notation is used as in the Linux kernel */ + *cp++ = ':'; + val = (up[1] << 8) + up[0]; + cp[2] = fat_uni2esc[val & 0x3f]; + val >>= 6; + cp[1] = fat_uni2esc[val & 0x3f]; + val >>= 6; + cp[0] = fat_uni2esc[val & 0x3f]; + cp += 3; + } + } + *cp = 0; + + return (char *)out; +} + +static void copy_lfn_part(unsigned char *dst, LFN_ENT * lfn) +{ + memcpy(dst, lfn->name0_4, 10); + memcpy(dst + 10, lfn->name5_10, 12); + memcpy(dst + 22, lfn->name11_12, 4); +} + +static void clear_lfn_slots(int start, int end) +{ + int i; + LFN_ENT empty; + + /* New dir entry is zeroed except first byte, which is set to 0xe5. + * This is to avoid that some FAT-reading OSes (not Linux! ;) stop reading + * a directory at the first zero entry... + */ + memset(&empty, 0, sizeof(empty)); + empty.id = DELETED_FLAG; + + for (i = start; i <= end; ++i) { + fs_write(lfn_offsets[i], sizeof(LFN_ENT), &empty); + } +} + +void lfn_fix_checksum(loff_t from, loff_t to, const char *short_name) +{ + int i; + uint8_t sum; + for (sum = 0, i = 0; i < 11; i++) + sum = (((sum & 1) << 7) | ((sum & 0xfe) >> 1)) + short_name[i]; + + for (; from < to; from += sizeof(LFN_ENT)) { + fs_write(from + offsetof(LFN_ENT, alias_checksum), sizeof(sum), &sum); + } +} + +void lfn_reset(void) +{ + if (lfn_unicode) + free(lfn_unicode); + lfn_unicode = NULL; + if (lfn_offsets) + free(lfn_offsets); + lfn_offsets = NULL; + lfn_slot = -1; +} + +/* This function is only called with de->attr == VFAT_LN_ATTR. It stores part + * of the long name. */ +void lfn_add_slot(DIR_ENT * de, loff_t dir_offset) +{ + LFN_ENT *lfn = (LFN_ENT *) de; + int slot = lfn->id & LFN_ID_SLOTMASK; + unsigned offset; + + if (lfn_slot == 0) + lfn_check_orphaned(); + + if (de->attr != VFAT_LN_ATTR) + die("lfn_add_slot called with non-LFN directory entry"); + + if (lfn->id & LFN_ID_START && slot != 0) { + if (lfn_slot != -1) { + int can_clear = 0; + /* There is already a LFN "in progess", so it is an error that a + * new start entry is here. */ + /* Causes: 1) if slot# == expected: start bit set mysteriously, 2) + * old LFN overwritten by new one */ + /* Fixes: 1) delete previous LFN 2) if slot# == expected and + * checksum ok: clear start bit */ + /* XXX: Should delay that until next LFN known (then can better + * display the name) */ + printf("A new long file name starts within an old one.\n"); + if (slot == lfn_slot && lfn->alias_checksum == lfn_checksum) { + char *part1 = CNV_THIS_PART(lfn); + char *part2 = CNV_PARTS_SO_FAR(); + printf(" It could be that the LFN start bit is wrong here\n" + " if \"%s\" seems to match \"%s\".\n", part1, part2); + free(part1); + free(part2); + can_clear = 1; + } + if (interactive) { + printf("1: Delete previous LFN\n2: Leave it as it is.\n"); + if (can_clear) + printf("3: Clear start bit and concatenate LFNs\n"); + } else + printf(" Not auto-correcting this.\n"); + if (interactive) { + switch (get_key(can_clear ? "123" : "12", "?")) { + case '1': + clear_lfn_slots(0, lfn_parts - 1); + lfn_reset(); + break; + case '2': + break; + case '3': + lfn->id &= ~LFN_ID_START; + fs_write(dir_offset + offsetof(LFN_ENT, id), + sizeof(lfn->id), &lfn->id); + break; + } + } + } + lfn_slot = slot; + lfn_checksum = lfn->alias_checksum; + lfn_unicode = alloc((lfn_slot * CHARS_PER_LFN + 1) * 2); + lfn_offsets = alloc(lfn_slot * sizeof(loff_t)); + lfn_parts = 0; + } else if (lfn_slot == -1 && slot != 0) { + /* No LFN in progress, but slot found; start bit missing */ + /* Causes: 1) start bit got lost, 2) Previous slot with start bit got + * lost */ + /* Fixes: 1) delete LFN, 2) set start bit */ + char *part = CNV_THIS_PART(lfn); + printf("Long filename fragment \"%s\" found outside a LFN " + "sequence.\n (Maybe the start bit is missing on the " + "last fragment)\n", part); + if (interactive) { + printf("1: Delete fragment\n2: Leave it as it is.\n" + "3: Set start bit\n"); + } else + printf(" Not auto-correcting this.\n"); + switch (interactive ? get_key("123", "?") : '2') { + case '1': + if (!lfn_offsets) + lfn_offsets = alloc(sizeof(loff_t)); + lfn_offsets[0] = dir_offset; + clear_lfn_slots(0, 0); + lfn_reset(); + return; + case '2': + lfn_reset(); + return; + case '3': + lfn->id |= LFN_ID_START; + fs_write(dir_offset + offsetof(LFN_ENT, id), + sizeof(lfn->id), &lfn->id); + lfn_slot = slot; + lfn_checksum = lfn->alias_checksum; + lfn_unicode = alloc((lfn_slot * CHARS_PER_LFN + 1) * 2); + lfn_offsets = alloc(lfn_slot * sizeof(loff_t)); + lfn_parts = 0; + break; + } + } else if (slot != lfn_slot) { + /* wrong sequence number */ + /* Causes: 1) seq-no destroyed */ + /* Fixes: 1) delete LFN, 2) fix number (maybe only if following parts + * are ok?, maybe only if checksum is ok?) (Attention: space + * for name was allocated before!) */ + int can_fix = 0; + printf("Unexpected long filename sequence number " + "(%d vs. expected %d).\n", slot, lfn_slot); + if (lfn->alias_checksum == lfn_checksum && lfn_slot > 0) { + char *part1 = CNV_THIS_PART(lfn); + char *part2 = CNV_PARTS_SO_FAR(); + printf(" It could be that just the number is wrong\n" + " if \"%s\" seems to match \"%s\".\n", part1, part2); + free(part1); + free(part2); + can_fix = 1; + } + if (interactive) { + printf + ("1: Delete LFN\n2: Leave it as it is (and ignore LFN so far)\n"); + if (can_fix) + printf("3: Correct sequence number\n"); + } else + printf(" Not auto-correcting this.\n"); + switch (interactive ? get_key(can_fix ? "123" : "12", "?") : '2') { + case '1': + if (!lfn_offsets) { + lfn_offsets = alloc(sizeof(loff_t)); + lfn_parts = 0; + } + lfn_offsets[lfn_parts++] = dir_offset; + clear_lfn_slots(0, lfn_parts - 1); + lfn_reset(); + return; + case '2': + lfn_reset(); + return; + case '3': + lfn->id = (lfn->id & ~LFN_ID_SLOTMASK) | lfn_slot; + fs_write(dir_offset + offsetof(LFN_ENT, id), + sizeof(lfn->id), &lfn->id); + break; + } + } + + if (lfn->alias_checksum != lfn_checksum) { + /* checksum mismatch */ + /* Causes: 1) checksum field here destroyed */ + /* Fixes: 1) delete LFN, 2) fix checksum */ + printf("Checksum in long filename part wrong " + "(%02x vs. expected %02x).\n", + lfn->alias_checksum, lfn_checksum); + if (interactive) { + printf("1: Delete LFN\n2: Leave it as it is.\n" + "3: Correct checksum\n"); + } else + printf(" Not auto-correcting this.\n"); + if (interactive) { + switch (get_key("123", "?")) { + case '1': + lfn_offsets[lfn_parts++] = dir_offset; + clear_lfn_slots(0, lfn_parts - 1); + lfn_reset(); + return; + case '2': + break; + case '3': + lfn->alias_checksum = lfn_checksum; + fs_write(dir_offset + offsetof(LFN_ENT, alias_checksum), + sizeof(lfn->alias_checksum), &lfn->alias_checksum); + break; + } + } + } + + if (lfn_slot != -1) { + lfn_slot--; + offset = lfn_slot * CHARS_PER_LFN * 2; + copy_lfn_part(lfn_unicode + offset, lfn); + if (lfn->id & LFN_ID_START) + lfn_unicode[offset + 26] = lfn_unicode[offset + 27] = 0; + lfn_offsets[lfn_parts++] = dir_offset; + } + + if (lfn->reserved != 0) { + printf("Reserved field in VFAT long filename slot is not 0 " + "(but 0x%02x).\n", lfn->reserved); + if (interactive) + printf("1: Fix.\n2: Leave it.\n"); + else + printf("Auto-setting to 0.\n"); + if (!interactive || get_key("12", "?") == '1') { + lfn->reserved = 0; + fs_write(dir_offset + offsetof(LFN_ENT, reserved), + sizeof(lfn->reserved), &lfn->reserved); + } + } + if (lfn->start != htole16(0)) { + printf("Start cluster field in VFAT long filename slot is not 0 " + "(but 0x%04x).\n", lfn->start); + if (interactive) + printf("1: Fix.\n2: Leave it.\n"); + else + printf("Auto-setting to 0.\n"); + if (!interactive || get_key("12", "?") == '1') { + lfn->start = htole16(0); + fs_write(dir_offset + offsetof(LFN_ENT, start), + sizeof(lfn->start), &lfn->start); + } + } +} + +/* This function is always called when de->attr != VFAT_LN_ATTR is found, to + * retrieve the previously constructed LFN. */ +char *lfn_get(DIR_ENT * de, loff_t * lfn_offset) +{ + char *lfn; + uint8_t sum; + int i; + + *lfn_offset = 0; + if (de->attr == VFAT_LN_ATTR) + die("lfn_get called with LFN directory entry"); + +#if 0 + if (de->lcase) + printf("lcase=%02x\n", de->lcase); +#endif + + if (lfn_slot == -1) + /* no long name for this file */ + return NULL; + + if (lfn_slot != 0) { + /* The long name isn't finished yet. */ + /* Causes: 1) LFN slot overwritten by non-VFAT aware tool */ + /* Fixes: 1) delete LFN 2) move overwriting entry to somewhere else + * and let user enter missing part of LFN (hard to do :-() + * 3) renumber entries and truncate name */ + char *long_name = CNV_PARTS_SO_FAR(); + char *short_name = file_name(de->name); + printf("Unfinished long file name \"%s\".\n" + " (Start may have been overwritten by %s)\n", + long_name, short_name); + free(long_name); + if (interactive) { + printf("1: Delete LFN\n2: Leave it as it is.\n" + "3: Fix numbering (truncates long name and attaches " + "it to short name %s)\n", short_name); + } else + printf(" Not auto-correcting this.\n"); + switch (interactive ? get_key("123", "?") : '2') { + case '1': + clear_lfn_slots(0, lfn_parts - 1); + lfn_reset(); + return NULL; + case '2': + lfn_reset(); + return NULL; + case '3': + for (i = 0; i < lfn_parts; ++i) { + uint8_t id = (lfn_parts - i) | (i == 0 ? LFN_ID_START : 0); + fs_write(lfn_offsets[i] + offsetof(LFN_ENT, id), + sizeof(id), &id); + } + memmove(lfn_unicode, lfn_unicode + lfn_slot * CHARS_PER_LFN * 2, + lfn_parts * CHARS_PER_LFN * 2); + break; + } + } + + for (sum = 0, i = 0; i < 8; i++) + sum = (((sum & 1) << 7) | ((sum & 0xfe) >> 1)) + de->name[i]; + for (i = 0; i < 3; i++) + sum = (((sum & 1) << 7) | ((sum & 0xfe) >> 1)) + de->ext[i]; + if (sum != lfn_checksum) { + /* checksum doesn't match, long name doesn't apply to this alias */ + /* Causes: 1) alias renamed */ + /* Fixes: 1) Fix checksum in LFN entries */ + char *long_name = CNV_PARTS_SO_FAR(); + char *short_name = file_name(de->name); + printf("Wrong checksum for long file name \"%s\".\n" + " (Short name %s may have changed without updating the long name)\n", + long_name, short_name); + free(long_name); + if (interactive) { + printf("1: Delete LFN\n2: Leave it as it is.\n" + "3: Fix checksum (attaches to short name %s)\n", short_name); + } else + printf(" Not auto-correcting this.\n"); + if (interactive) { + switch (get_key("123", "?")) { + case '1': + clear_lfn_slots(0, lfn_parts - 1); + lfn_reset(); + return NULL; + case '2': + lfn_reset(); + return NULL; + case '3': + for (i = 0; i < lfn_parts; ++i) { + fs_write(lfn_offsets[i] + offsetof(LFN_ENT, alias_checksum), + sizeof(sum), &sum); + } + break; + } + } + } + + *lfn_offset = lfn_offsets[0]; + lfn = cnv_unicode(lfn_unicode, UNTIL_0, 1); + lfn_reset(); + return (lfn); +} + +void lfn_check_orphaned(void) +{ + char *long_name; + + if (lfn_slot == -1) + return; + + long_name = CNV_PARTS_SO_FAR(); + printf("Orphaned long file name part \"%s\"\n", long_name); + if (interactive) + printf("1: Delete.\n2: Leave it.\n"); + else + printf(" Auto-deleting.\n"); + if (!interactive || get_key("12", "?") == '1') { + clear_lfn_slots(0, lfn_parts - 1); + } + lfn_reset(); +} diff --git a/dosfstools/src/lfn.h b/dosfstools/src/lfn.h new file mode 100644 index 000000000..e5c3991ff --- /dev/null +++ b/dosfstools/src/lfn.h @@ -0,0 +1,39 @@ +/* lfn.h - Functions for handling VFAT long filenames + + Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> + Copyright (C) 2008-2014 Daniel Baumann <mail@daniel-baumann.ch> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + The complete text of the GNU General Public License + can be found in /usr/share/common-licenses/GPL-3 file. +*/ + +#ifndef _LFN_H +#define _LFN_H + +void lfn_reset(void); +/* Reset the state of the LFN parser. */ + +void lfn_add_slot(DIR_ENT * de, loff_t dir_offset); +/* Process a dir slot that is a VFAT LFN entry. */ + +char *lfn_get(DIR_ENT * de, loff_t * lfn_offset); +/* Retrieve the long name for the proper dir entry. */ + +void lfn_check_orphaned(void); + +void lfn_fix_checksum(loff_t from, loff_t to, const char *short_name); + +#endif diff --git a/dosfstools/src/mkfs.fat.c b/dosfstools/src/mkfs.fat.c new file mode 100644 index 000000000..2dad23630 --- /dev/null +++ b/dosfstools/src/mkfs.fat.c @@ -0,0 +1,1757 @@ +/* mkfs.fat.c - utility to create FAT/MS-DOS filesystems + + Copyright (C) 1991 Linus Torvalds <torvalds@klaava.helsinki.fi> + Copyright (C) 1992-1993 Remy Card <card@masi.ibp.fr> + Copyright (C) 1993-1994 David Hudson <dave@humbug.demon.co.uk> + Copyright (C) 1998 H. Peter Anvin <hpa@zytor.com> + Copyright (C) 1998-2005 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> + Copyright (C) 2008-2014 Daniel Baumann <mail@daniel-baumann.ch> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + The complete text of the GNU General Public License + can be found in /usr/share/common-licenses/GPL-3 file. +*/ + +/* Description: Utility to allow an MS-DOS filesystem to be created + under Linux. A lot of the basic structure of this program has been + borrowed from Remy Card's "mke2fs" code. + + As far as possible the aim here is to make the "mkfs.fat" command + look almost identical to the other Linux filesystem make utilties, + eg bad blocks are still specified as blocks, not sectors, but when + it comes down to it, DOS is tied to the idea of a sector (512 bytes + as a rule), and not the block. For example the boot block does not + occupy a full cluster. + + Fixes/additions May 1998 by Roman Hodek + <Roman.Hodek@informatik.uni-erlangen.de>: + - Atari format support + - New options -A, -S, -C + - Support for filesystems > 2GB + - FAT32 support */ + +/* Include the header files */ + +#include "version.h" + +#include <fcntl.h> +#include <linux/hdreg.h> +#include <sys/mount.h> +#include <linux/fs.h> +#include <linux/fd.h> +#include <endian.h> +#include <mntent.h> +#include <signal.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <unistd.h> +#include <time.h> +#include <errno.h> +#include <ctype.h> +#include <stdint.h> +#include <endian.h> +#include <getopt.h> + +#include "msdos_fs.h" + +/* In earlier versions, an own llseek() was used, but glibc lseek() is + * sufficient (or even better :) for 64 bit offsets in the meantime */ +#define llseek lseek64 + +/* Constant definitions */ + +#define TRUE 1 /* Boolean constants */ +#define FALSE 0 + +#define TEST_BUFFER_BLOCKS 16 +#define HARD_SECTOR_SIZE 512 +#define SECTORS_PER_BLOCK ( BLOCK_SIZE / HARD_SECTOR_SIZE ) + +#define NO_NAME "NO NAME " + +/* Macro definitions */ + +/* Report a failure message and return a failure error code */ + +#define die( str ) fatal_error( "%s: " str "\n" ) + +/* Mark a cluster in the FAT as bad */ + +#define mark_sector_bad( sector ) mark_FAT_sector( sector, FAT_BAD ) + +/* Compute ceil(a/b) */ + +static inline int cdiv(int a, int b) +{ + return (a + b - 1) / b; +} + +/* FAT values */ +#define FAT_EOF (atari_format ? 0x0fffffff : 0x0ffffff8) +#define FAT_BAD 0x0ffffff7 + +#define MSDOS_EXT_SIGN 0x29 /* extended boot sector signature */ +#define MSDOS_FAT12_SIGN "FAT12 " /* FAT12 filesystem signature */ +#define MSDOS_FAT16_SIGN "FAT16 " /* FAT16 filesystem signature */ +#define MSDOS_FAT32_SIGN "FAT32 " /* FAT32 filesystem signature */ + +#define BOOT_SIGN 0xAA55 /* Boot sector magic number */ + +#define MAX_CLUST_12 ((1 << 12) - 16) +#define MAX_CLUST_16 ((1 << 16) - 16) +#define MIN_CLUST_32 65529 +/* M$ says the high 4 bits of a FAT32 FAT entry are reserved and don't belong + * to the cluster number. So the max. cluster# is based on 2^28 */ +#define MAX_CLUST_32 ((1 << 28) - 16) + +#define FAT12_THRESHOLD 4085 + +#define OLDGEMDOS_MAX_SECTORS 32765 +#define GEMDOS_MAX_SECTORS 65531 +#define GEMDOS_MAX_SECTOR_SIZE (16*1024) + +#define BOOTCODE_SIZE 448 +#define BOOTCODE_FAT32_SIZE 420 + +/* __attribute__ ((packed)) is used on all structures to make gcc ignore any + * alignments */ + +struct msdos_volume_info { + uint8_t drive_number; /* BIOS drive number */ + uint8_t RESERVED; /* Unused */ + uint8_t ext_boot_sign; /* 0x29 if fields below exist (DOS 3.3+) */ + uint8_t volume_id[4]; /* Volume ID number */ + uint8_t volume_label[11]; /* Volume label */ + uint8_t fs_type[8]; /* Typically FAT12 or FAT16 */ +} __attribute__ ((packed)); + +struct msdos_boot_sector { + uint8_t boot_jump[3]; /* Boot strap short or near jump */ + uint8_t system_id[8]; /* Name - can be used to special case + partition manager volumes */ + uint8_t sector_size[2]; /* bytes per logical sector */ + uint8_t cluster_size; /* sectors/cluster */ + uint16_t reserved; /* reserved sectors */ + uint8_t fats; /* number of FATs */ + uint8_t dir_entries[2]; /* root directory entries */ + uint8_t sectors[2]; /* number of sectors */ + uint8_t media; /* media code (unused) */ + uint16_t fat_length; /* sectors/FAT */ + uint16_t secs_track; /* sectors per track */ + uint16_t heads; /* number of heads */ + uint32_t hidden; /* hidden sectors (unused) */ + uint32_t total_sect; /* number of sectors (if sectors == 0) */ + union { + struct { + struct msdos_volume_info vi; + uint8_t boot_code[BOOTCODE_SIZE]; + } __attribute__ ((packed)) _oldfat; + struct { + uint32_t fat32_length; /* sectors/FAT */ + uint16_t flags; /* bit 8: fat mirroring, low 4: active fat */ + uint8_t version[2]; /* major, minor filesystem version */ + uint32_t root_cluster; /* first cluster in root directory */ + uint16_t info_sector; /* filesystem info sector */ + uint16_t backup_boot; /* backup boot sector */ + uint16_t reserved2[6]; /* Unused */ + struct msdos_volume_info vi; + uint8_t boot_code[BOOTCODE_FAT32_SIZE]; + } __attribute__ ((packed)) _fat32; + } __attribute__ ((packed)) fstype; + uint16_t boot_sign; +} __attribute__ ((packed)); +#define fat32 fstype._fat32 +#define oldfat fstype._oldfat + +struct fat32_fsinfo { + uint32_t reserved1; /* Nothing as far as I can tell */ + uint32_t signature; /* 0x61417272L */ + uint32_t free_clusters; /* Free cluster count. -1 if unknown */ + uint32_t next_cluster; /* Most recently allocated cluster. + * Unused under Linux. */ + uint32_t reserved2[4]; +}; + +/* The "boot code" we put into the filesystem... it writes a message and + tells the user to try again */ + +unsigned char dummy_boot_jump[3] = { 0xeb, 0x3c, 0x90 }; + +unsigned char dummy_boot_jump_m68k[2] = { 0x60, 0x1c }; + +#define MSG_OFFSET_OFFSET 3 +char dummy_boot_code[BOOTCODE_SIZE] = "\x0e" /* push cs */ + "\x1f" /* pop ds */ + "\xbe\x5b\x7c" /* mov si, offset message_txt */ + /* write_msg: */ + "\xac" /* lodsb */ + "\x22\xc0" /* and al, al */ + "\x74\x0b" /* jz key_press */ + "\x56" /* push si */ + "\xb4\x0e" /* mov ah, 0eh */ + "\xbb\x07\x00" /* mov bx, 0007h */ + "\xcd\x10" /* int 10h */ + "\x5e" /* pop si */ + "\xeb\xf0" /* jmp write_msg */ + /* key_press: */ + "\x32\xe4" /* xor ah, ah */ + "\xcd\x16" /* int 16h */ + "\xcd\x19" /* int 19h */ + "\xeb\xfe" /* foo: jmp foo */ + /* message_txt: */ + "This is not a bootable disk. Please insert a bootable floppy and\r\n" + "press any key to try again ... \r\n"; + +#define MESSAGE_OFFSET 29 /* Offset of message in above code */ + +/* Global variables - the root of all evil :-) - see these and weep! */ + +static const char *program_name = "mkfs.fat"; /* Name of the program */ +static char *device_name = NULL; /* Name of the device on which to create the filesystem */ +static int atari_format = 0; /* Use Atari variation of MS-DOS FS format */ +static int check = FALSE; /* Default to no readablity checking */ +static int verbose = 0; /* Default to verbose mode off */ +static long volume_id; /* Volume ID number */ +static time_t create_time; /* Creation time */ +static char volume_name[] = NO_NAME; /* Volume name */ +static uint64_t blocks; /* Number of blocks in filesystem */ +static int sector_size = 512; /* Size of a logical sector */ +static int sector_size_set = 0; /* User selected sector size */ +static int backup_boot = 0; /* Sector# of backup boot sector */ +static int reserved_sectors = 0; /* Number of reserved sectors */ +static int badblocks = 0; /* Number of bad blocks in the filesystem */ +static int nr_fats = 2; /* Default number of FATs to produce */ +static int size_fat = 0; /* Size in bits of FAT entries */ +static int size_fat_by_user = 0; /* 1 if FAT size user selected */ +static int dev = -1; /* FS block device file handle */ +static int ignore_full_disk = 0; /* Ignore warning about 'full' disk devices */ +static off_t currently_testing = 0; /* Block currently being tested (if autodetect bad blocks) */ +static struct msdos_boot_sector bs; /* Boot sector data */ +static int start_data_sector; /* Sector number for the start of the data area */ +static int start_data_block; /* Block number for the start of the data area */ +static unsigned char *fat; /* File allocation table */ +static unsigned alloced_fat_length; /* # of FAT sectors we can keep in memory */ +static unsigned char *info_sector; /* FAT32 info sector */ +static struct msdos_dir_entry *root_dir; /* Root directory */ +static int size_root_dir; /* Size of the root directory in bytes */ +static int sectors_per_cluster = 0; /* Number of sectors per disk cluster */ +static int root_dir_entries = 0; /* Number of root directory entries */ +static char *blank_sector; /* Blank sector - all zeros */ +static int hidden_sectors = 0; /* Number of hidden sectors */ +static int hidden_sectors_by_user = 0; /* -h option invoked */ +static int drive_number_option = 0; /* drive number */ +static int drive_number_by_user = 0; /* drive number option invoked */ +static int fat_media_byte = 0; /* media byte in header and starting FAT */ +static int malloc_entire_fat = FALSE; /* Whether we should malloc() the entire FAT or not */ +static int align_structures = TRUE; /* Whether to enforce alignment */ +static int orphaned_sectors = 0; /* Sectors that exist in the last block of filesystem */ +static int invariant = 0; /* Whether to set normally randomized or + current time based values to + constants */ + +/* Function prototype definitions */ + +static void fatal_error(const char *fmt_string) __attribute__ ((noreturn)); +static void mark_FAT_cluster(int cluster, unsigned int value); +static void mark_FAT_sector(int sector, unsigned int value); +static long do_check(char *buffer, int try, off_t current_block); +static void alarm_intr(int alnum); +static void check_blocks(void); +static void get_list_blocks(char *filename); +static int valid_offset(int fd, loff_t offset); +static uint64_t count_blocks(char *filename, int *remainder); +static void check_mount(char *device_name); +static void establish_params(int device_num, int size); +static void setup_tables(void); +static void write_tables(void); + +/* The function implementations */ + +/* Handle the reporting of fatal errors. Volatile to let gcc know that this doesn't return */ + +static void fatal_error(const char *fmt_string) +{ + fprintf(stderr, fmt_string, program_name, device_name); + exit(1); /* The error exit code is 1! */ +} + +/* Mark the specified cluster as having a particular value */ + +static void mark_FAT_cluster(int cluster, unsigned int value) +{ + switch (size_fat) { + case 12: + value &= 0x0fff; + if (((cluster * 3) & 0x1) == 0) { + fat[3 * cluster / 2] = (unsigned char)(value & 0x00ff); + fat[(3 * cluster / 2) + 1] = + (unsigned char)((fat[(3 * cluster / 2) + 1] & 0x00f0) + | ((value & 0x0f00) >> 8)); + } else { + fat[3 * cluster / 2] = + (unsigned char)((fat[3 * cluster / 2] & 0x000f) | + ((value & 0x000f) << 4)); + fat[(3 * cluster / 2) + 1] = (unsigned char)((value & 0x0ff0) >> 4); + } + break; + + case 16: + value &= 0xffff; + fat[2 * cluster] = (unsigned char)(value & 0x00ff); + fat[(2 * cluster) + 1] = (unsigned char)(value >> 8); + break; + + case 32: + value &= 0xfffffff; + fat[4 * cluster] = (unsigned char)(value & 0x000000ff); + fat[(4 * cluster) + 1] = (unsigned char)((value & 0x0000ff00) >> 8); + fat[(4 * cluster) + 2] = (unsigned char)((value & 0x00ff0000) >> 16); + fat[(4 * cluster) + 3] = (unsigned char)((value & 0xff000000) >> 24); + break; + + default: + die("Bad FAT size (not 12, 16, or 32)"); + } +} + +/* Mark a specified sector as having a particular value in it's FAT entry */ + +static void mark_FAT_sector(int sector, unsigned int value) +{ + int cluster; + + cluster = (sector - start_data_sector) / (int)(bs.cluster_size) / + (sector_size / HARD_SECTOR_SIZE); + if (cluster < 0) + die("Invalid cluster number in mark_FAT_sector: probably bug!"); + + mark_FAT_cluster(cluster, value); +} + +/* Perform a test on a block. Return the number of blocks that could be read successfully */ + +static long do_check(char *buffer, int try, off_t current_block) +{ + long got; + + if (llseek(dev, current_block * BLOCK_SIZE, SEEK_SET) /* Seek to the correct location */ + !=current_block * BLOCK_SIZE) + die("seek failed during testing for blocks"); + + got = read(dev, buffer, try * BLOCK_SIZE); /* Try reading! */ + if (got < 0) + got = 0; + + if (got & (BLOCK_SIZE - 1)) + printf("Unexpected values in do_check: probably bugs\n"); + got /= BLOCK_SIZE; + + return got; +} + +/* Alarm clock handler - display the status of the quest for bad blocks! Then retrigger the alarm for five senconds + later (so we can come here again) */ + +static void alarm_intr(int alnum) +{ + (void)alnum; + + if (currently_testing >= blocks) + return; + + signal(SIGALRM, alarm_intr); + alarm(5); + if (!currently_testing) + return; + + printf("%lld... ", (unsigned long long)currently_testing); + fflush(stdout); +} + +static void check_blocks(void) +{ + int try, got; + int i; + static char blkbuf[BLOCK_SIZE * TEST_BUFFER_BLOCKS]; + + if (verbose) { + printf("Searching for bad blocks "); + fflush(stdout); + } + currently_testing = 0; + if (verbose) { + signal(SIGALRM, alarm_intr); + alarm(5); + } + try = TEST_BUFFER_BLOCKS; + while (currently_testing < blocks) { + if (currently_testing + try > blocks) + try = blocks - currently_testing; + got = do_check(blkbuf, try, currently_testing); + currently_testing += got; + if (got == try) { + try = TEST_BUFFER_BLOCKS; + continue; + } else + try = 1; + if (currently_testing < start_data_block) + die("bad blocks before data-area: cannot make fs"); + + for (i = 0; i < SECTORS_PER_BLOCK; i++) /* Mark all of the sectors in the block as bad */ + mark_sector_bad(currently_testing * SECTORS_PER_BLOCK + i); + badblocks++; + currently_testing++; + } + + if (verbose) + printf("\n"); + + if (badblocks) + printf("%d bad block%s\n", badblocks, (badblocks > 1) ? "s" : ""); +} + +static void get_list_blocks(char *filename) +{ + int i; + FILE *listfile; + long blockno; + + listfile = fopen(filename, "r"); + if (listfile == (FILE *) NULL) + die("Can't open file of bad blocks"); + + while (!feof(listfile)) { + fscanf(listfile, "%ld\n", &blockno); + for (i = 0; i < SECTORS_PER_BLOCK; i++) /* Mark all of the sectors in the block as bad */ + mark_sector_bad(blockno * SECTORS_PER_BLOCK + i); + badblocks++; + } + fclose(listfile); + + if (badblocks) + printf("%d bad block%s\n", badblocks, (badblocks > 1) ? "s" : ""); +} + +/* Given a file descriptor and an offset, check whether the offset is a valid offset for the file - return FALSE if it + isn't valid or TRUE if it is */ + +static int valid_offset(int fd, loff_t offset) +{ + char ch; + + if (llseek(fd, offset, SEEK_SET) < 0) + return FALSE; + if (read(fd, &ch, 1) < 1) + return FALSE; + return TRUE; +} + +/* Given a filename, look to see how many blocks of BLOCK_SIZE are present, returning the answer */ + +static uint64_t count_blocks(char *filename, int *remainder) +{ + loff_t high, low; + int fd; + + if ((fd = open(filename, O_RDONLY)) < 0) { + perror(filename); + exit(1); + } + + /* first try SEEK_END, which should work on most devices nowadays */ + if ((low = llseek(fd, 0, SEEK_END)) <= 0) { + low = 0; + for (high = 1; valid_offset(fd, high); high *= 2) + low = high; + while (low < high - 1) { + const loff_t mid = (low + high) / 2; + if (valid_offset(fd, mid)) + low = mid; + else + high = mid; + } + ++low; + } + + close(fd); + *remainder = (low % BLOCK_SIZE) / sector_size; + return (low / BLOCK_SIZE); +} + +/* Check to see if the specified device is currently mounted - abort if it is */ + +static void check_mount(char *device_name) +{ +/* older versions of Bionic don't have setmntent (4.x) or an incomplete impl (5.x) */ +#ifdef MOUNTED + FILE *f; + struct mntent *mnt; + + if ((f = setmntent(MOUNTED, "r")) == NULL) + return; + while ((mnt = getmntent(f)) != NULL) + if (strcmp(device_name, mnt->mnt_fsname) == 0) + die("%s contains a mounted filesystem."); + endmntent(f); +#endif +} + +/* Establish the geometry and media parameters for the device */ + +static void establish_params(int device_num, int size) +{ + long loop_size; + struct hd_geometry geometry; + struct floppy_struct param; + int def_root_dir_entries = 512; + + if ((0 == device_num) || ((device_num & 0xff00) == 0x0200)) + /* file image or floppy disk */ + { + if (0 == device_num) { + param.size = size / 512; + switch (param.size) { + case 720: + param.sect = 9; + param.head = 2; + break; + case 1440: + param.sect = 9; + param.head = 2; + break; + case 2400: + param.sect = 15; + param.head = 2; + break; + case 2880: + param.sect = 18; + param.head = 2; + break; + case 5760: + param.sect = 36; + param.head = 2; + break; + default: + /* fake values */ + param.sect = 32; + param.head = 64; + break; + } + + } else { /* is a floppy diskette */ + + if (ioctl(dev, FDGETPRM, ¶m)) /* Can we get the diskette geometry? */ + die("unable to get diskette geometry for '%s'"); + } + bs.secs_track = htole16(param.sect); /* Set up the geometry information */ + bs.heads = htole16(param.head); + switch (param.size) { /* Set up the media descriptor byte */ + case 720: /* 5.25", 2, 9, 40 - 360K */ + bs.media = (char)0xfd; + bs.cluster_size = (char)2; + def_root_dir_entries = 112; + break; + + case 1440: /* 3.5", 2, 9, 80 - 720K */ + bs.media = (char)0xf9; + bs.cluster_size = (char)2; + def_root_dir_entries = 112; + break; + + case 2400: /* 5.25", 2, 15, 80 - 1200K */ + bs.media = (char)0xf9; + bs.cluster_size = (char)(atari_format ? 2 : 1); + def_root_dir_entries = 224; + break; + + case 5760: /* 3.5", 2, 36, 80 - 2880K */ + bs.media = (char)0xf0; + bs.cluster_size = (char)2; + def_root_dir_entries = 224; + break; + + case 2880: /* 3.5", 2, 18, 80 - 1440K */ +floppy_default: + bs.media = (char)0xf0; + bs.cluster_size = (char)(atari_format ? 2 : 1); + def_root_dir_entries = 224; + break; + + default: /* Anything else */ + if (0 == device_num) + goto def_hd_params; + else + goto floppy_default; + } + } else if ((device_num & 0xff00) == 0x0700) { /* This is a loop device */ + if (ioctl(dev, BLKGETSIZE, &loop_size)) + die("unable to get loop device size"); + + switch (loop_size) { /* Assuming the loop device -> floppy later */ + case 720: /* 5.25", 2, 9, 40 - 360K */ + bs.secs_track = le16toh(9); + bs.heads = le16toh(2); + bs.media = (char)0xfd; + bs.cluster_size = (char)2; + def_root_dir_entries = 112; + break; + + case 1440: /* 3.5", 2, 9, 80 - 720K */ + bs.secs_track = le16toh(9); + bs.heads = le16toh(2); + bs.media = (char)0xf9; + bs.cluster_size = (char)2; + def_root_dir_entries = 112; + break; + + case 2400: /* 5.25", 2, 15, 80 - 1200K */ + bs.secs_track = le16toh(15); + bs.heads = le16toh(2); + bs.media = (char)0xf9; + bs.cluster_size = (char)(atari_format ? 2 : 1); + def_root_dir_entries = 224; + break; + + case 5760: /* 3.5", 2, 36, 80 - 2880K */ + bs.secs_track = le16toh(36); + bs.heads = le16toh(2); + bs.media = (char)0xf0; + bs.cluster_size = (char)2; + bs.dir_entries[0] = (char)224; + bs.dir_entries[1] = (char)0; + break; + + case 2880: /* 3.5", 2, 18, 80 - 1440K */ + bs.secs_track = le16toh(18); + bs.heads = le16toh(2); + bs.media = (char)0xf0; + bs.cluster_size = (char)(atari_format ? 2 : 1); + def_root_dir_entries = 224; + break; + + default: /* Anything else: default hd setup */ + printf("Loop device does not match a floppy size, using " + "default hd params\n"); + bs.secs_track = htole16(32); /* these are fake values... */ + bs.heads = htole16(64); + goto def_hd_params; + } + } else + /* Must be a hard disk then! */ + { + /* Can we get the drive geometry? (Note I'm not too sure about */ + /* whether to use HDIO_GETGEO or HDIO_REQ) */ + if (ioctl(dev, HDIO_GETGEO, &geometry) || geometry.sectors == 0 + || geometry.heads == 0) { + printf("unable to get drive geometry, using default 255/63\n"); + bs.secs_track = htole16(63); + bs.heads = htole16(255); + } else { + bs.secs_track = htole16(geometry.sectors); /* Set up the geometry information */ + bs.heads = htole16(geometry.heads); + if (!hidden_sectors_by_user) + hidden_sectors = htole32(geometry.start); + } +def_hd_params: + bs.media = (char)0xf8; /* Set up the media descriptor for a hard drive */ + if (!size_fat && blocks * SECTORS_PER_BLOCK > 1064960) { + if (verbose) + printf("Auto-selecting FAT32 for large filesystem\n"); + size_fat = 32; + } + if (size_fat == 32) { + /* For FAT32, try to do the same as M$'s format command + * (see http://www.win.tue.nl/~aeb/linux/fs/fat/fatgen103.pdf p. 20): + * fs size <= 260M: 0.5k clusters + * fs size <= 8G: 4k clusters + * fs size <= 16G: 8k clusters + * fs size <= 32G: 16k clusters + * fs size > 32G: 32k clusters + */ + uint32_t sz_mb = + (blocks + (1 << (20 - BLOCK_SIZE_BITS)) - 1) >> (20 - + BLOCK_SIZE_BITS); + bs.cluster_size = + sz_mb > 32 * 1024 ? 64 : sz_mb > 16 * 1024 ? 32 : sz_mb > + 8 * 1024 ? 16 : sz_mb > 260 ? 8 : 1; + } else { + /* FAT12 and FAT16: start at 4 sectors per cluster */ + bs.cluster_size = (char)4; + } + } + + if (!root_dir_entries) + root_dir_entries = def_root_dir_entries; +} + +/* + * If alignment is enabled, round the first argument up to the second; the + * latter must be a power of two. + */ +static unsigned int align_object(unsigned int sectors, unsigned int clustsize) +{ + if (align_structures) + return (sectors + clustsize - 1) & ~(clustsize - 1); + else + return sectors; +} + +/* Create the filesystem data tables */ + +static void setup_tables(void) +{ + unsigned num_sectors; + unsigned cluster_count = 0, fat_length; + struct tm *ctime; + struct msdos_volume_info *vi = + (size_fat == 32 ? &bs.fat32.vi : &bs.oldfat.vi); + + if (atari_format) { + /* On Atari, the first few bytes of the boot sector are assigned + * differently: The jump code is only 2 bytes (and m68k machine code + * :-), then 6 bytes filler (ignored), then 3 byte serial number. */ + bs.boot_jump[2] = 'm'; + memcpy((char *)bs.system_id, "kdosf", strlen("kdosf")); + } else + memcpy((char *)bs.system_id, "mkfs.fat", strlen("mkfs.fat")); + if (sectors_per_cluster) + bs.cluster_size = (char)sectors_per_cluster; + + if (fat_media_byte) + bs.media = (char) fat_media_byte; + + if (bs.media == 0xf8) + vi->drive_number=0x80; + else + vi->drive_number=0x00; + + if (drive_number_by_user) + vi->drive_number= (char) drive_number_option; + + if (size_fat == 32) { + /* Under FAT32, the root dir is in a cluster chain, and this is + * signalled by bs.dir_entries being 0. */ + root_dir_entries = 0; + } + + if (atari_format) { + bs.system_id[5] = (unsigned char)(volume_id & 0x000000ff); + bs.system_id[6] = (unsigned char)((volume_id & 0x0000ff00) >> 8); + bs.system_id[7] = (unsigned char)((volume_id & 0x00ff0000) >> 16); + } else { + vi->volume_id[0] = (unsigned char)(volume_id & 0x000000ff); + vi->volume_id[1] = (unsigned char)((volume_id & 0x0000ff00) >> 8); + vi->volume_id[2] = (unsigned char)((volume_id & 0x00ff0000) >> 16); + vi->volume_id[3] = (unsigned char)(volume_id >> 24); + } + + if (!atari_format) { + memcpy(vi->volume_label, volume_name, 11); + + memcpy(bs.boot_jump, dummy_boot_jump, 3); + /* Patch in the correct offset to the boot code */ + bs.boot_jump[1] = ((size_fat == 32 ? + (char *)&bs.fat32.boot_code : + (char *)&bs.oldfat.boot_code) - (char *)&bs) - 2; + + if (size_fat == 32) { + int offset = (char *)&bs.fat32.boot_code - + (char *)&bs + MESSAGE_OFFSET + 0x7c00; + if (dummy_boot_code[BOOTCODE_FAT32_SIZE - 1]) + printf("Warning: message too long; truncated\n"); + dummy_boot_code[BOOTCODE_FAT32_SIZE - 1] = 0; + memcpy(bs.fat32.boot_code, dummy_boot_code, BOOTCODE_FAT32_SIZE); + bs.fat32.boot_code[MSG_OFFSET_OFFSET] = offset & 0xff; + bs.fat32.boot_code[MSG_OFFSET_OFFSET + 1] = offset >> 8; + } else { + memcpy(bs.oldfat.boot_code, dummy_boot_code, BOOTCODE_SIZE); + } + bs.boot_sign = htole16(BOOT_SIGN); + } else { + memcpy(bs.boot_jump, dummy_boot_jump_m68k, 2); + } + if (verbose >= 2) + printf("Boot jump code is %02x %02x\n", + bs.boot_jump[0], bs.boot_jump[1]); + + if (!reserved_sectors) + reserved_sectors = (size_fat == 32) ? 32 : 1; + else { + if (size_fat == 32 && reserved_sectors < 2) + die("On FAT32 at least 2 reserved sectors are needed."); + } + bs.reserved = htole16(reserved_sectors); + if (verbose >= 2) + printf("Using %d reserved sectors\n", reserved_sectors); + bs.fats = (char)nr_fats; + if (!atari_format || size_fat == 32) + bs.hidden = htole32(hidden_sectors); + else { + /* In Atari format, hidden is a 16 bit field */ + uint16_t hidden = htole16(hidden_sectors); + if (hidden_sectors & ~0xffff) + die("#hidden doesn't fit in 16bit field of Atari format\n"); + memcpy(&bs.hidden, &hidden, 2); + } + + num_sectors = + (long long)(blocks * BLOCK_SIZE / sector_size) + orphaned_sectors; + + if (!atari_format) { + unsigned fatdata1216; /* Sectors for FATs + data area (FAT12/16) */ + unsigned fatdata32; /* Sectors for FATs + data area (FAT32) */ + unsigned fatlength12, fatlength16, fatlength32; + unsigned maxclust12, maxclust16, maxclust32; + unsigned clust12, clust16, clust32; + int maxclustsize; + unsigned root_dir_sectors = cdiv(root_dir_entries * 32, sector_size); + + /* + * If the filesystem is 8192 sectors or less (4 MB with 512-byte + * sectors, i.e. floppy size), don't align the data structures. + */ + if (num_sectors <= 8192) { + if (align_structures && verbose >= 2) + printf("Disabling alignment due to tiny filesystem\n"); + + align_structures = FALSE; + } + + if (sectors_per_cluster) + bs.cluster_size = maxclustsize = sectors_per_cluster; + else + /* An initial guess for bs.cluster_size should already be set */ + maxclustsize = 128; + + do { + fatdata32 = num_sectors - reserved_sectors; + fatdata1216 = fatdata32 + - align_object(root_dir_sectors, bs.cluster_size); + + if (verbose >= 2) + printf("Trying with %d sectors/cluster:\n", bs.cluster_size); + + /* The factor 2 below avoids cut-off errors for nr_fats == 1. + * The "nr_fats*3" is for the reserved first two FAT entries */ + clust12 = 2 * ((long long)fatdata1216 * sector_size + nr_fats * 3) / + (2 * (int)bs.cluster_size * sector_size + nr_fats * 3); + fatlength12 = cdiv(((clust12 + 2) * 3 + 1) >> 1, sector_size); + fatlength12 = align_object(fatlength12, bs.cluster_size); + /* Need to recalculate number of clusters, since the unused parts of the + * FATS and data area together could make up space for an additional, + * not really present cluster. */ + clust12 = (fatdata1216 - nr_fats * fatlength12) / bs.cluster_size; + maxclust12 = (fatlength12 * 2 * sector_size) / 3; + if (maxclust12 > MAX_CLUST_12) + maxclust12 = MAX_CLUST_12; + if (verbose >= 2) + printf("FAT12: #clu=%u, fatlen=%u, maxclu=%u, limit=%u\n", + clust12, fatlength12, maxclust12, MAX_CLUST_12); + if (clust12 > maxclust12 - 2) { + clust12 = 0; + if (verbose >= 2) + printf("FAT12: too much clusters\n"); + } + + clust16 = ((long long)fatdata1216 * sector_size + nr_fats * 4) / + ((int)bs.cluster_size * sector_size + nr_fats * 2); + fatlength16 = cdiv((clust16 + 2) * 2, sector_size); + fatlength16 = align_object(fatlength16, bs.cluster_size); + /* Need to recalculate number of clusters, since the unused parts of the + * FATS and data area together could make up space for an additional, + * not really present cluster. */ + clust16 = (fatdata1216 - nr_fats * fatlength16) / bs.cluster_size; + maxclust16 = (fatlength16 * sector_size) / 2; + if (maxclust16 > MAX_CLUST_16) + maxclust16 = MAX_CLUST_16; + if (verbose >= 2) + printf("FAT16: #clu=%u, fatlen=%u, maxclu=%u, limit=%u\n", + clust16, fatlength16, maxclust16, MAX_CLUST_16); + if (clust16 > maxclust16 - 2) { + if (verbose >= 2) + printf("FAT16: too much clusters\n"); + clust16 = 0; + } + /* The < 4078 avoids that the filesystem will be misdetected as having a + * 12 bit FAT. */ + if (clust16 < FAT12_THRESHOLD + && !(size_fat_by_user && size_fat == 16)) { + if (verbose >= 2) + printf(clust16 < FAT12_THRESHOLD ? + "FAT16: would be misdetected as FAT12\n" : + "FAT16: too much clusters\n"); + clust16 = 0; + } + + clust32 = ((long long)fatdata32 * sector_size + nr_fats * 8) / + ((int)bs.cluster_size * sector_size + nr_fats * 4); + fatlength32 = cdiv((clust32 + 2) * 4, sector_size); + /* Need to recalculate number of clusters, since the unused parts of the + * FATS and data area together could make up space for an additional, + * not really present cluster. */ + clust32 = (fatdata32 - nr_fats * fatlength32) / bs.cluster_size; + maxclust32 = (fatlength32 * sector_size) / 4; + if (maxclust32 > MAX_CLUST_32) + maxclust32 = MAX_CLUST_32; + if (clust32 && clust32 < MIN_CLUST_32 + && !(size_fat_by_user && size_fat == 32)) { + clust32 = 0; + if (verbose >= 2) + printf("FAT32: not enough clusters (%d)\n", MIN_CLUST_32); + } + if (verbose >= 2) + printf("FAT32: #clu=%u, fatlen=%u, maxclu=%u, limit=%u\n", + clust32, fatlength32, maxclust32, MAX_CLUST_32); + if (clust32 > maxclust32) { + clust32 = 0; + if (verbose >= 2) + printf("FAT32: too much clusters\n"); + } + + if ((clust12 && (size_fat == 0 || size_fat == 12)) || + (clust16 && (size_fat == 0 || size_fat == 16)) || + (clust32 && size_fat == 32)) + break; + + bs.cluster_size <<= 1; + } while (bs.cluster_size && bs.cluster_size <= maxclustsize); + + /* Use the optimal FAT size if not specified; + * FAT32 is (not yet) choosen automatically */ + if (!size_fat) { + size_fat = (clust16 > clust12) ? 16 : 12; + if (verbose >= 2) + printf("Choosing %d bits for FAT\n", size_fat); + } + + switch (size_fat) { + case 12: + cluster_count = clust12; + fat_length = fatlength12; + bs.fat_length = htole16(fatlength12); + memcpy(vi->fs_type, MSDOS_FAT12_SIGN, 8); + break; + + case 16: + if (clust16 < FAT12_THRESHOLD) { + if (size_fat_by_user) { + fprintf(stderr, "WARNING: Not enough clusters for a " + "16 bit FAT! The filesystem will be\n" + "misinterpreted as having a 12 bit FAT without " + "mount option \"fat=16\".\n"); + } else { + fprintf(stderr, "This filesystem has an unfortunate size. " + "A 12 bit FAT cannot provide\n" + "enough clusters, but a 16 bit FAT takes up a little " + "bit more space so that\n" + "the total number of clusters becomes less than the " + "threshold value for\n" + "distinction between 12 and 16 bit FATs.\n"); + die("Make the filesystem a bit smaller manually."); + } + } + cluster_count = clust16; + fat_length = fatlength16; + bs.fat_length = htole16(fatlength16); + memcpy(vi->fs_type, MSDOS_FAT16_SIGN, 8); + break; + + case 32: + if (clust32 < MIN_CLUST_32) + fprintf(stderr, + "WARNING: Not enough clusters for a 32 bit FAT!\n"); + cluster_count = clust32; + fat_length = fatlength32; + bs.fat_length = htole16(0); + bs.fat32.fat32_length = htole32(fatlength32); + memcpy(vi->fs_type, MSDOS_FAT32_SIGN, 8); + root_dir_entries = 0; + break; + + default: + die("FAT not 12, 16 or 32 bits"); + } + + /* Adjust the number of root directory entries to help enforce alignment */ + if (align_structures) { + root_dir_entries = align_object(root_dir_sectors, bs.cluster_size) + * (sector_size >> 5); + } + } else { + unsigned clusters, maxclust, fatdata; + + /* GEMDOS always uses a 12 bit FAT on floppies, and always a 16 bit FAT on + * hard disks. So use 12 bit if the size of the filesystem suggests that + * this fs is for a floppy disk, if the user hasn't explicitly requested a + * size. + */ + if (!size_fat) + size_fat = (num_sectors == 1440 || num_sectors == 2400 || + num_sectors == 2880 || num_sectors == 5760) ? 12 : 16; + if (verbose >= 2) + printf("Choosing %d bits for FAT\n", size_fat); + + /* Atari format: cluster size should be 2, except explicitly requested by + * the user, since GEMDOS doesn't like other cluster sizes very much. + * Instead, tune the sector size for the FS to fit. + */ + bs.cluster_size = sectors_per_cluster ? sectors_per_cluster : 2; + if (!sector_size_set) { + while (num_sectors > GEMDOS_MAX_SECTORS) { + num_sectors >>= 1; + sector_size <<= 1; + } + } + if (verbose >= 2) + printf("Sector size must be %d to have less than %d log. sectors\n", + sector_size, GEMDOS_MAX_SECTORS); + + /* Check if there are enough FAT indices for how much clusters we have */ + do { + fatdata = num_sectors - cdiv(root_dir_entries * 32, sector_size) - + reserved_sectors; + /* The factor 2 below avoids cut-off errors for nr_fats == 1 and + * size_fat == 12 + * The "2*nr_fats*size_fat/8" is for the reserved first two FAT entries + */ + clusters = + (2 * + ((long long)fatdata * sector_size - + 2 * nr_fats * size_fat / 8)) / (2 * ((int)bs.cluster_size * + sector_size + + nr_fats * size_fat / 8)); + fat_length = cdiv((clusters + 2) * size_fat / 8, sector_size); + /* Need to recalculate number of clusters, since the unused parts of the + * FATS and data area together could make up space for an additional, + * not really present cluster. */ + clusters = (fatdata - nr_fats * fat_length) / bs.cluster_size; + maxclust = (fat_length * sector_size * 8) / size_fat; + if (verbose >= 2) + printf("ss=%d: #clu=%d, fat_len=%d, maxclu=%d\n", + sector_size, clusters, fat_length, maxclust); + + /* last 10 cluster numbers are special (except FAT32: 4 high bits rsvd); + * first two numbers are reserved */ + if (maxclust <= + (size_fat == 32 ? MAX_CLUST_32 : (1 << size_fat) - 0x10) + && clusters <= maxclust - 2) + break; + if (verbose >= 2) + printf(clusters > maxclust - 2 ? + "Too many clusters\n" : "FAT too big\n"); + + /* need to increment sector_size once more to */ + if (sector_size_set) + die("With this sector size, the maximum number of FAT entries " + "would be exceeded."); + num_sectors >>= 1; + sector_size <<= 1; + } while (sector_size <= GEMDOS_MAX_SECTOR_SIZE); + + if (sector_size > GEMDOS_MAX_SECTOR_SIZE) + die("Would need a sector size > 16k, which GEMDOS can't work with"); + + cluster_count = clusters; + if (size_fat != 32) + bs.fat_length = htole16(fat_length); + else { + bs.fat_length = 0; + bs.fat32.fat32_length = htole32(fat_length); + } + } + + bs.sector_size[0] = (char)(sector_size & 0x00ff); + bs.sector_size[1] = (char)((sector_size & 0xff00) >> 8); + + bs.dir_entries[0] = (char)(root_dir_entries & 0x00ff); + bs.dir_entries[1] = (char)((root_dir_entries & 0xff00) >> 8); + + if (size_fat == 32) { + /* set up additional FAT32 fields */ + bs.fat32.flags = htole16(0); + bs.fat32.version[0] = 0; + bs.fat32.version[1] = 0; + bs.fat32.root_cluster = htole32(2); + bs.fat32.info_sector = htole16(1); + if (!backup_boot) + backup_boot = (reserved_sectors >= 7) ? 6 : + (reserved_sectors >= 2) ? reserved_sectors - 1 : 0; + else { + if (backup_boot == 1) + die("Backup boot sector must be after sector 1"); + else if (backup_boot >= reserved_sectors) + die("Backup boot sector must be a reserved sector"); + } + if (verbose >= 2) + printf("Using sector %d as backup boot sector (0 = none)\n", + backup_boot); + bs.fat32.backup_boot = htole16(backup_boot); + memset(&bs.fat32.reserved2, 0, sizeof(bs.fat32.reserved2)); + } + + if (atari_format) { + /* Just some consistency checks */ + if (num_sectors >= GEMDOS_MAX_SECTORS) + die("GEMDOS can't handle more than 65531 sectors"); + else if (num_sectors >= OLDGEMDOS_MAX_SECTORS) + printf("Warning: More than 32765 sector need TOS 1.04 " + "or higher.\n"); + } + if (num_sectors >= 65536) { + bs.sectors[0] = (char)0; + bs.sectors[1] = (char)0; + bs.total_sect = htole32(num_sectors); + } else { + bs.sectors[0] = (char)(num_sectors & 0x00ff); + bs.sectors[1] = (char)((num_sectors & 0xff00) >> 8); + if (!atari_format) + bs.total_sect = htole32(0); + } + + if (!atari_format) + vi->ext_boot_sign = MSDOS_EXT_SIGN; + + if (!cluster_count) { + if (sectors_per_cluster) /* If yes, die if we'd spec'd sectors per cluster */ + die("Too many clusters for filesystem - try more sectors per cluster"); + else + die("Attempting to create a too large filesystem"); + } + + /* The two following vars are in hard sectors, i.e. 512 byte sectors! */ + start_data_sector = (reserved_sectors + nr_fats * fat_length) * + (sector_size / HARD_SECTOR_SIZE); + start_data_block = (start_data_sector + SECTORS_PER_BLOCK - 1) / + SECTORS_PER_BLOCK; + + if (blocks < start_data_block + 32) /* Arbitrary undersize filesystem! */ + die("Too few blocks for viable filesystem"); + + if (verbose) { + printf("%s has %d head%s and %d sector%s per track,\n", + device_name, le16toh(bs.heads), + (le16toh(bs.heads) != 1) ? "s" : "", le16toh(bs.secs_track), + (le16toh(bs.secs_track) != 1) ? "s" : ""); + printf("hidden sectors 0x%04x;\n", hidden_sectors); + printf("logical sector size is %d,\n", sector_size); + printf("using 0x%02x media descriptor, with %d sectors;\n", + (int)(bs.media), num_sectors); + printf("drive number 0x%02x;\n", (int) (vi->drive_number)); + printf("filesystem has %d %d-bit FAT%s and %d sector%s per cluster.\n", + (int)(bs.fats), size_fat, (bs.fats != 1) ? "s" : "", + (int)(bs.cluster_size), (bs.cluster_size != 1) ? "s" : ""); + printf("FAT size is %d sector%s, and provides %d cluster%s.\n", + fat_length, (fat_length != 1) ? "s" : "", + cluster_count, (cluster_count != 1) ? "s" : ""); + printf("There %s %u reserved sector%s.\n", + (reserved_sectors != 1) ? "are" : "is", + reserved_sectors, (reserved_sectors != 1) ? "s" : ""); + + if (size_fat != 32) { + unsigned root_dir_entries = + bs.dir_entries[0] + ((bs.dir_entries[1]) * 256); + unsigned root_dir_sectors = + cdiv(root_dir_entries * 32, sector_size); + printf("Root directory contains %u slots and uses %u sectors.\n", + root_dir_entries, root_dir_sectors); + } + printf("Volume ID is %08lx, ", volume_id & + (atari_format ? 0x00ffffff : 0xffffffff)); + if (strcmp(volume_name, NO_NAME)) + printf("volume label %s.\n", volume_name); + else + printf("no volume label.\n"); + } + + /* Make the file allocation tables! */ + + if (malloc_entire_fat) + alloced_fat_length = fat_length; + else + alloced_fat_length = 1; + + if ((fat = + (unsigned char *)malloc(alloced_fat_length * sector_size)) == NULL) + die("unable to allocate space for FAT image in memory"); + + memset(fat, 0, alloced_fat_length * sector_size); + + mark_FAT_cluster(0, 0xffffffff); /* Initial fat entries */ + mark_FAT_cluster(1, 0xffffffff); + fat[0] = (unsigned char)bs.media; /* Put media type in first byte! */ + if (size_fat == 32) { + /* Mark cluster 2 as EOF (used for root dir) */ + mark_FAT_cluster(2, FAT_EOF); + } + + /* Make the root directory entries */ + + size_root_dir = (size_fat == 32) ? + bs.cluster_size * sector_size : + (((int)bs.dir_entries[1] * 256 + (int)bs.dir_entries[0]) * + sizeof(struct msdos_dir_entry)); + if ((root_dir = (struct msdos_dir_entry *)malloc(size_root_dir)) == NULL) { + free(fat); /* Tidy up before we die! */ + die("unable to allocate space for root directory in memory"); + } + + memset(root_dir, 0, size_root_dir); + if (memcmp(volume_name, NO_NAME, 11)) { + struct msdos_dir_entry *de = &root_dir[0]; + memcpy(de->name, volume_name, 8); + memcpy(de->ext, volume_name + 8, 3); + de->attr = ATTR_VOLUME; + if (!invariant) + ctime = localtime(&create_time); + else + ctime = gmtime(&create_time); + de->time = htole16((unsigned short)((ctime->tm_sec >> 1) + + (ctime->tm_min << 5) + + (ctime->tm_hour << 11))); + de->date = + htole16((unsigned short)(ctime->tm_mday + + ((ctime->tm_mon + 1) << 5) + + ((ctime->tm_year - 80) << 9))); + de->ctime_cs = 0; + de->ctime = de->time; + de->cdate = de->date; + de->adate = de->date; + de->starthi = htole16(0); + de->start = htole16(0); + de->size = htole32(0); + } + + if (size_fat == 32) { + /* For FAT32, create an info sector */ + struct fat32_fsinfo *info; + + if (!(info_sector = malloc(sector_size))) + die("Out of memory"); + memset(info_sector, 0, sector_size); + /* fsinfo structure is at offset 0x1e0 in info sector by observation */ + info = (struct fat32_fsinfo *)(info_sector + 0x1e0); + + /* Info sector magic */ + info_sector[0] = 'R'; + info_sector[1] = 'R'; + info_sector[2] = 'a'; + info_sector[3] = 'A'; + + /* Magic for fsinfo structure */ + info->signature = htole32(0x61417272); + /* We've allocated cluster 2 for the root dir. */ + info->free_clusters = htole32(cluster_count - 1); + info->next_cluster = htole32(2); + + /* Info sector also must have boot sign */ + *(uint16_t *) (info_sector + 0x1fe) = htole16(BOOT_SIGN); + } + + if (!(blank_sector = malloc(sector_size))) + die("Out of memory"); + memset(blank_sector, 0, sector_size); +} + +/* Write the new filesystem's data tables to wherever they're going to end up! */ + +#define error(str) \ + do { \ + free (fat); \ + if (info_sector) free (info_sector); \ + free (root_dir); \ + die (str); \ + } while(0) + +#define seekto(pos,errstr) \ + do { \ + loff_t __pos = (pos); \ + if (llseek (dev, __pos, SEEK_SET) != __pos) \ + error ("seek to " errstr " failed whilst writing tables"); \ + } while(0) + +#define writebuf(buf,size,errstr) \ + do { \ + int __size = (size); \ + if (write (dev, buf, __size) != __size) \ + error ("failed whilst writing " errstr); \ + } while(0) + +static void write_tables(void) +{ + int x; + int fat_length; + + fat_length = (size_fat == 32) ? + le32toh(bs.fat32.fat32_length) : le16toh(bs.fat_length); + + seekto(0, "start of device"); + /* clear all reserved sectors */ + for (x = 0; x < reserved_sectors; ++x) + writebuf(blank_sector, sector_size, "reserved sector"); + /* seek back to sector 0 and write the boot sector */ + seekto(0, "boot sector"); + writebuf((char *)&bs, sizeof(struct msdos_boot_sector), "boot sector"); + /* on FAT32, write the info sector and backup boot sector */ + if (size_fat == 32) { + seekto(le16toh(bs.fat32.info_sector) * sector_size, "info sector"); + writebuf(info_sector, 512, "info sector"); + if (backup_boot != 0) { + seekto(backup_boot * sector_size, "backup boot sector"); + writebuf((char *)&bs, sizeof(struct msdos_boot_sector), + "backup boot sector"); + } + } + /* seek to start of FATS and write them all */ + seekto(reserved_sectors * sector_size, "first FAT"); + for (x = 1; x <= nr_fats; x++) { + int y; + int blank_fat_length = fat_length - alloced_fat_length; + writebuf(fat, alloced_fat_length * sector_size, "FAT"); + for (y = 0; y < blank_fat_length; y++) + writebuf(blank_sector, sector_size, "FAT"); + } + /* Write the root directory directly after the last FAT. This is the root + * dir area on FAT12/16, and the first cluster on FAT32. */ + writebuf((char *)root_dir, size_root_dir, "root directory"); + + if (blank_sector) + free(blank_sector); + if (info_sector) + free(info_sector); + free(root_dir); /* Free up the root directory space from setup_tables */ + free(fat); /* Free up the fat table space reserved during setup_tables */ +} + +/* Report the command usage and exit with the given error code */ + +static void usage(int exitval) +{ + fprintf(stderr, "\ +Usage: mkfs.fat [-a][-A][-c][-C][-v][-I][-l bad-block-file][-b backup-boot-sector]\n\ + [-m boot-msg-file][-n volume-name][-i volume-id]\n\ + [-s sectors-per-cluster][-S logical-sector-size][-f number-of-FATs]\n\ + [-h hidden-sectors][-F fat-size][-r root-dir-entries][-R reserved-sectors]\n\ + [-M FAT-media-byte][-D drive_number]\n\ + [--invariant]\n\ + [--help]\n\ + /dev/name [blocks]\n"); + exit(exitval); +} + +/* + * ++roman: On m68k, check if this is an Atari; if yes, turn on Atari variant + * of MS-DOS filesystem by default. + */ +static void check_atari(void) +{ +#ifdef __mc68000__ + FILE *f; + char line[128], *p; + + if (!(f = fopen("/proc/hardware", "r"))) { + perror("/proc/hardware"); + return; + } + + while (fgets(line, sizeof(line), f)) { + if (strncmp(line, "Model:", 6) == 0) { + p = line + 6; + p += strspn(p, " \t"); + if (strncmp(p, "Atari ", 6) == 0) + atari_format = 1; + break; + } + } + fclose(f); +#endif +} + +/* The "main" entry point into the utility - we pick up the options and attempt to process them in some sort of sensible + way. In the event that some/all of the options are invalid we need to tell the user so that something can be done! */ + +int main(int argc, char **argv) +{ + int c; + char *tmp; + char *listfile = NULL; + FILE *msgfile; + struct stat statbuf; + int i = 0, pos, ch; + int create = 0; + uint64_t cblocks = 0; + int min_sector_size; + int bad_block_count = 0; + struct timeval create_timeval; + + enum {OPT_HELP=1000, OPT_INVARIANT,}; + const struct option long_options[] = { + {"help", no_argument, NULL, OPT_HELP}, + {"invariant", no_argument, NULL, OPT_INVARIANT}, + {0,} + }; + + if (argc && *argv) { /* What's the program name? */ + char *p; + program_name = *argv; + if ((p = strrchr(program_name, '/'))) + program_name = p + 1; + } + + gettimeofday(&create_timeval, NULL); + create_time = create_timeval.tv_sec; + volume_id = (uint32_t) ((create_timeval.tv_sec << 20) | create_timeval.tv_usec); /* Default volume ID = creation time, fudged for more uniqueness */ + check_atari(); + + printf("mkfs.fat " VERSION " (" VERSION_DATE ")\n"); + + while ((c = getopt_long(argc, argv, "aAb:cCf:D:F:Ii:l:m:M:n:r:R:s:S:h:v", + long_options, NULL)) != -1) + /* Scan the command line for options */ + switch (c) { + case 'A': /* toggle Atari format */ + atari_format = !atari_format; + break; + + case 'a': /* a : skip alignment */ + align_structures = FALSE; + break; + + case 'b': /* b : location of backup boot sector */ + backup_boot = (int)strtol(optarg, &tmp, 0); + if (*tmp || backup_boot < 2 || backup_boot > 0xffff) { + printf("Bad location for backup boot sector : %s\n", optarg); + usage(1); + } + break; + + case 'c': /* c : Check FS as we build it */ + check = TRUE; + malloc_entire_fat = TRUE; /* Need to be able to mark clusters bad */ + break; + + case 'C': /* C : Create a new file */ + create = TRUE; + break; + + case 'D': /* D : Choose Drive Number */ + drive_number_option = (int) strtol (optarg, &tmp, 0); + if (*tmp || (drive_number_option != 0 && drive_number_option != 0x80)) { + printf ("Drive number must be 0 or 0x80: %s\n", optarg); + usage(1); + } + drive_number_by_user=1; + break; + + case 'f': /* f : Choose number of FATs */ + nr_fats = (int)strtol(optarg, &tmp, 0); + if (*tmp || nr_fats < 1 || nr_fats > 4) { + printf("Bad number of FATs : %s\n", optarg); + usage(1); + } + break; + + case 'F': /* F : Choose FAT size */ + size_fat = (int)strtol(optarg, &tmp, 0); + if (*tmp || (size_fat != 12 && size_fat != 16 && size_fat != 32)) { + printf("Bad FAT type : %s\n", optarg); + usage(1); + } + size_fat_by_user = 1; + break; + + case 'h': /* h : number of hidden sectors */ + hidden_sectors = (int)strtol(optarg, &tmp, 0); + if (*tmp || hidden_sectors < 0) { + printf("Bad number of hidden sectors : %s\n", optarg); + usage(1); + } + hidden_sectors_by_user = 1; + break; + + case 'I': + ignore_full_disk = 1; + break; + + case 'i': /* i : specify volume ID */ + volume_id = strtoul(optarg, &tmp, 16); + if (*tmp) { + printf("Volume ID must be a hexadecimal number\n"); + usage(1); + } + break; + + case 'l': /* l : Bad block filename */ + listfile = optarg; + malloc_entire_fat = TRUE; /* Need to be able to mark clusters bad */ + break; + + case 'm': /* m : Set boot message */ + if (strcmp(optarg, "-")) { + msgfile = fopen(optarg, "r"); + if (!msgfile) + perror(optarg); + } else + msgfile = stdin; + + if (msgfile) { + /* The boot code ends at offset 448 and needs a null terminator */ + i = MESSAGE_OFFSET; + pos = 0; /* We are at beginning of line */ + do { + ch = getc(msgfile); + switch (ch) { + case '\r': /* Ignore CRs */ + case '\0': /* and nulls */ + break; + + case '\n': /* LF -> CR+LF if necessary */ + if (pos) { /* If not at beginning of line */ + dummy_boot_code[i++] = '\r'; + pos = 0; + } + dummy_boot_code[i++] = '\n'; + break; + + case '\t': /* Expand tabs */ + do { + dummy_boot_code[i++] = ' '; + pos++; + } + while (pos % 8 && i < BOOTCODE_SIZE - 1); + break; + + case EOF: + dummy_boot_code[i++] = '\0'; /* Null terminator */ + break; + + default: + dummy_boot_code[i++] = ch; /* Store character */ + pos++; /* Advance position */ + break; + } + } + while (ch != EOF && i < BOOTCODE_SIZE - 1); + + /* Fill up with zeros */ + while (i < BOOTCODE_SIZE - 1) + dummy_boot_code[i++] = '\0'; + dummy_boot_code[BOOTCODE_SIZE - 1] = '\0'; /* Just in case */ + + if (ch != EOF) + printf("Warning: message too long; truncated\n"); + + if (msgfile != stdin) + fclose(msgfile); + } + break; + + case 'M': /* M : FAT Media byte */ + fat_media_byte = (int)strtol(optarg, &tmp, 0); + if (*tmp) { + printf("Bad number for media descriptor : %s\n", optarg); + usage(1); + } + if (fat_media_byte != 0xf0 && (fat_media_byte < 0xf8 || fat_media_byte > 0xff)) { + printf("FAT Media byte must either be between 0xF8 and 0xFF or be 0xF0 : %s\n", optarg); + usage(1); + } + break; + + case 'n': /* n : Volume name */ + sprintf(volume_name, "%-11.11s", optarg); + for (i = 0; volume_name[i] && i < 11; i++) + /* don't know if here should be more strict !uppercase(label[i]) */ + if (islower(volume_name[i])) { + fprintf(stderr, + "mkfs.fat: warning - lowercase labels might not work properly with DOS or Windows\n"); + break; + } + + break; + + case 'r': /* r : Root directory entries */ + root_dir_entries = (int)strtol(optarg, &tmp, 0); + if (*tmp || root_dir_entries < 16 || root_dir_entries > 32768) { + printf("Bad number of root directory entries : %s\n", optarg); + usage(1); + } + break; + + case 'R': /* R : number of reserved sectors */ + reserved_sectors = (int)strtol(optarg, &tmp, 0); + if (*tmp || reserved_sectors < 1 || reserved_sectors > 0xffff) { + printf("Bad number of reserved sectors : %s\n", optarg); + usage(1); + } + break; + + case 's': /* s : Sectors per cluster */ + sectors_per_cluster = (int)strtol(optarg, &tmp, 0); + if (*tmp || (sectors_per_cluster != 1 && sectors_per_cluster != 2 + && sectors_per_cluster != 4 && sectors_per_cluster != 8 + && sectors_per_cluster != 16 + && sectors_per_cluster != 32 + && sectors_per_cluster != 64 + && sectors_per_cluster != 128)) { + printf("Bad number of sectors per cluster : %s\n", optarg); + usage(1); + } + break; + + case 'S': /* S : Sector size */ + sector_size = (int)strtol(optarg, &tmp, 0); + if (*tmp || (sector_size != 512 && sector_size != 1024 && + sector_size != 2048 && sector_size != 4096 && + sector_size != 8192 && sector_size != 16384 && + sector_size != 32768)) { + printf("Bad logical sector size : %s\n", optarg); + usage(1); + } + sector_size_set = 1; + break; + + case 'v': /* v : Verbose execution */ + ++verbose; + break; + + case OPT_HELP: + usage(0); + break; + + case OPT_INVARIANT: + invariant = 1; + volume_id = 0x1234abcd; + create_time = 1426325213; + break; + + default: + printf("Unknown option: %c\n", c); + usage(1); + } + if (optind < argc) { + device_name = argv[optind]; /* Determine the number of blocks in the FS */ + + if (!device_name) { + printf("No device specified.\n"); + usage(1); + } + + if (!create) + cblocks = count_blocks(device_name, &orphaned_sectors); /* Have a look and see! */ + } + if (optind == argc - 2) { /* Either check the user specified number */ + blocks = strtoull(argv[optind + 1], &tmp, 0); + if (!create && blocks != cblocks) { + fprintf(stderr, "Warning: block count mismatch: "); + fprintf(stderr, "found %llu but assuming %llu.\n", (unsigned long long)cblocks, (unsigned long long)blocks); + } + if (*tmp) + bad_block_count = 1; + } else if (optind == argc - 1) { /* Or use value found */ + if (create) + die("Need intended size with -C."); + blocks = cblocks; + } else { + fprintf(stderr, "No device specified!\n"); + usage(1); + } + if (bad_block_count) { + printf("Bad block count : %s\n", argv[optind + 1]); + usage(1); + } + + if (check && listfile) /* Auto and specified bad block handling are mutually */ + die("-c and -l are incompatible"); /* exclusive of each other! */ + + if (!create) { + check_mount(device_name); /* Is the device already mounted? */ + dev = open(device_name, O_EXCL | O_RDWR); /* Is it a suitable device to build the FS on? */ + if (dev < 0) { + fprintf(stderr, "%s: unable to open %s: %s\n", program_name, + device_name, strerror(errno)); + exit(1); /* The error exit code is 1! */ + } + } else { + /* create the file */ + dev = open(device_name, O_EXCL | O_RDWR | O_CREAT, 0666); + if (dev < 0) { + if (errno == EEXIST) + die("file %s already exists"); + else + die("unable to create %s"); + } + /* expand to desired size */ + if (ftruncate(dev, blocks * BLOCK_SIZE)) + die("unable to resize %s"); + } + + if (fstat(dev, &statbuf) < 0) + die("unable to stat %s"); + if (!S_ISBLK(statbuf.st_mode)) { + statbuf.st_rdev = 0; + check = 0; + } else + /* + * Ignore any 'full' fixed disk devices, if -I is not given. + * On a MO-disk one doesn't need partitions. The filesytem can go + * directly to the whole disk. Under other OSes this is known as + * the 'superfloppy' format. As I don't know how to find out if + * this is a MO disk I introduce a -I (ignore) switch. -Joey + */ + if (!ignore_full_disk && ((statbuf.st_rdev & 0xffffff3f) == 0x0300 || /* hda, hdb */ + (statbuf.st_rdev & 0xffffff0f) == 0x0800 || /* sd */ + (statbuf.st_rdev & 0xffffff3f) == 0x0d00 || /* xd */ + (statbuf.st_rdev & 0xffffff3f) == 0x1600) /* hdc, hdd */ + ) + die("Device partition expected, not making filesystem on entire device '%s' (use -I to override)"); + + if (sector_size_set) { + if (ioctl(dev, BLKSSZGET, &min_sector_size) >= 0) + if (sector_size < min_sector_size) { + sector_size = min_sector_size; + fprintf(stderr, + "Warning: sector size was set to %d (minimal for this device)\n", + sector_size); + } + } else { + if (ioctl(dev, BLKSSZGET, &min_sector_size) >= 0) { + sector_size = min_sector_size; + sector_size_set = 1; + } + } + + if (sector_size > 4096) + fprintf(stderr, + "Warning: sector size is set to %d > 4096, such filesystem will not propably mount\n", + sector_size); + + establish_params(statbuf.st_rdev, statbuf.st_size); + /* Establish the media parameters */ + + setup_tables(); /* Establish the filesystem tables */ + + if (check) /* Determine any bad block locations and mark them */ + check_blocks(); + else if (listfile) + get_list_blocks(listfile); + + write_tables(); /* Write the filesystem tables away! */ + + exit(0); /* Terminate with no errors! */ +} diff --git a/dosfstools/src/msdos_fs.h b/dosfstools/src/msdos_fs.h new file mode 100644 index 000000000..54b2a3446 --- /dev/null +++ b/dosfstools/src/msdos_fs.h @@ -0,0 +1,61 @@ +/* msdos_fs.h - MS-DOS filesystem constants/structures + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + The complete text of the GNU General Public License + can be found in /usr/share/common-licenses/GPL-3 file. +*/ + +#ifndef _MSDOS_FS_H +#define _MSDOS_FS_H + +#include <stdint.h> + +#define SECTOR_SIZE 512 /* sector size (bytes) */ +#define MSDOS_DPS (SECTOR_SIZE / sizeof(struct msdos_dir_entry)) +#define MSDOS_DPS_BITS 4 /* log2(MSDOS_DPS) */ +#define MSDOS_DIR_BITS 5 /* log2(sizeof(struct msdos_dir_entry)) */ + +#define ATTR_NONE 0 /* no attribute bits */ +#define ATTR_RO 1 /* read-only */ +#define ATTR_HIDDEN 2 /* hidden */ +#define ATTR_SYS 4 /* system */ +#define ATTR_VOLUME 8 /* volume label */ +#define ATTR_DIR 16 /* directory */ +#define ATTR_ARCH 32 /* archived */ + +/* attribute bits that are copied "as is" */ +#define ATTR_UNUSED (ATTR_VOLUME | ATTR_ARCH | ATTR_SYS | ATTR_HIDDEN) + +#define DELETED_FLAG 0xe5 /* marks file as deleted when in name[0] */ +#define IS_FREE(n) (!*(n) || *(n) == DELETED_FLAG) + +#define MSDOS_NAME 11 /* maximum name length */ +#define MSDOS_DOT ". " /* ".", padded to MSDOS_NAME chars */ +#define MSDOS_DOTDOT ".. " /* "..", padded to MSDOS_NAME chars */ + +struct msdos_dir_entry { + uint8_t name[8], ext[3]; /* name and extension */ + uint8_t attr; /* attribute bits */ + uint8_t lcase; /* Case for base and extension */ + uint8_t ctime_cs; /* Creation time, centiseconds (0-199) */ + uint16_t ctime; /* Creation time */ + uint16_t cdate; /* Creation date */ + uint16_t adate; /* Last access date */ + uint16_t starthi; /* High 16 bits of cluster in FAT32 */ + uint16_t time, date, start; /* time, date and first cluster */ + uint32_t size; /* file size (in bytes) */ +} __attribute__ ((packed)); + +#endif /* _MSDOS_FS_H */ diff --git a/dosfstools/src/version.h b/dosfstools/src/version.h new file mode 100644 index 000000000..f0716d346 --- /dev/null +++ b/dosfstools/src/version.h @@ -0,0 +1,29 @@ +/* version.h + + Copyright (C) 1998-2005 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> + Copyright (C) 2008-2014 Daniel Baumann <mail@daniel-baumann.ch> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + The complete text of the GNU General Public License + can be found in /usr/share/common-licenses/GPL-3 file. +*/ + +#ifndef _version_h +#define _version_h + +#define VERSION "3.0.28" +#define VERSION_DATE "2015-05-16" + +#endif |