diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6875430..541b673 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -32,10 +32,10 @@ set(BLKID_MIN_VERSION "2.33.2")
# Qca plugin (botan or ossl)
set(VERSION_MAJOR "4")
-set(VERSION_MINOR "0")
-set(VERSION_RELEASE "1")
+set(VERSION_MINOR "1")
+set(VERSION_RELEASE "0")
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_RELEASE})
-set(SOVERSION "8")
+set(SOVERSION "10")
add_definitions(-D'VERSION="${VERSION}"') #"
set(CMAKE_CXX_STANDARD 14)
@@ -82,8 +82,8 @@ add_definitions(
-DQT_NO_URL_CAST_FROM_STRING
-DQT_NO_CAST_FROM_BYTEARRAY
-DQT_NO_CAST_TO_BYTEARRAY
- -DQT_NO_SIGNALS_SLOTS_KEYWORDS
-DQT_USE_FAST_OPERATOR_PLUS
+ -DQT_NO_KEYWORDS
)
kde_enable_exceptions()
diff --git a/COPYING.md b/COPYING.md
deleted file mode 100644
index 2fb2e74..0000000
--- a/COPYING.md
+++ /dev/null
@@ -1,675 +0,0 @@
-### GNU GENERAL PUBLIC LICENSE
-
-Version 3, 29 June 2007
-
-Copyright (C) 2007 Free Software Foundation, Inc.
-
-
-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.
-
-
- Copyright (C)
-
- 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 .
-
-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:
-
- Copyright (C)
- 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 .
-
-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 .
diff --git a/LICENSES/GPL-3.0-or-later.txt b/LICENSES/GPL-3.0-or-later.txt
new file mode 100644
index 0000000..e69de29
diff --git a/README.md b/README.md
index bf21350..394d214 100644
--- a/README.md
+++ b/README.md
@@ -55,7 +55,7 @@ class `KPMCoreInitializer` from `test/helpers.h`):
QByteArray env = qgetenv( "KPMCORE_BACKEND" );
auto backendName = env.isEmpty() ? CoreBackendManager::defaultBackendName() : env;
- if ( !CoreBackendManager::self()->load( backendName )
+ if ( !CoreBackendManager::self()->load( backendName ) )
{
qWarning() << "Failed to load backend plugin" << backendName;
return false;
diff --git a/src/backend/corebackend.cpp b/src/backend/corebackend.cpp
index fbd3410..e6ab9ee 100644
--- a/src/backend/corebackend.cpp
+++ b/src/backend/corebackend.cpp
@@ -40,12 +40,12 @@ CoreBackend::~CoreBackend()
void CoreBackend::emitProgress(int i)
{
- emit progress(i);
+ Q_EMIT progress(i);
}
void CoreBackend::emitScanProgress(const QString& deviceNode, int i)
{
- emit scanProgress(deviceNode, i);
+ Q_EMIT scanProgress(deviceNode, i);
}
void CoreBackend::setPartitionTableForDevice(Device& d, PartitionTable* p)
diff --git a/src/backend/corebackenddevice.h b/src/backend/corebackenddevice.h
index 0629f33..79c0f85 100644
--- a/src/backend/corebackenddevice.h
+++ b/src/backend/corebackenddevice.h
@@ -39,7 +39,7 @@ class Report;
class CoreBackendDevice
{
public:
- CoreBackendDevice(const QString& deviceNode);
+ explicit CoreBackendDevice(const QString& deviceNode);
virtual ~CoreBackendDevice() {}
public:
diff --git a/src/backend/corebackendpartitiontable.h b/src/backend/corebackendpartitiontable.h
index aae5fca..292523e 100644
--- a/src/backend/corebackendpartitiontable.h
+++ b/src/backend/corebackendpartitiontable.h
@@ -103,6 +103,47 @@ public:
*/
virtual bool updateGeometry(Report& report, const Partition& partition, qint64 sector_start, qint64 sector_end) = 0;
+ /**
+ * Get the UUID of a partition in the partition table (GPT only).
+ * The partition UUID is known as PARTUUID by several utilities. The device-manager links
+ * the device under /dev/disk/by-partuuid/.
+ * @param report the report to write information to
+ * @param partition the partition to get the UUID for
+ * @return the partition UUID
+ */
+ virtual QString getPartitionUUID(Report& report, const Partition& partition) = 0;
+
+ /**
+ * Set the label of a partition in the partition table (GPT only).
+ * The label is set in the GPT partition name entry. The partition name is known as PARTLABEL by
+ * several utilities. The device-manager links the device under /dev/disk/by-partlabel/.
+ * @param report the report to write information to
+ * @param partition the partition to set the label for
+ * @param label the new label for the partition
+ * @return true on success
+ */
+ virtual bool setPartitionLabel(Report& report, const Partition& partition, const QString& label) = 0;
+
+ /**
+ * Set the UUID of a partition in the partition table (GPT only).
+ * The partition UUID is known as PARTUUID by several utilities. The device-manager links
+ * the device under /dev/disk/by-partuuid/.
+ * @param report the report to write information to
+ * @param partition the partition to set the UUID for
+ * @param uuid the new UUID for the partition
+ * @return true on success
+ */
+ virtual bool setPartitionUUID(Report& report, const Partition& partition, const QString& uuid) = 0;
+
+ /**
+ * Set the attributes of a partition in the partition table (GPT only).
+ * @param report the report to write information to
+ * @param partition the partition to set the attributes for
+ * @param attrs the new attributes for the partition
+ * @return true on success
+ */
+ virtual bool setPartitionAttributes(Report& report, const Partition& partition, quint64 attrs) = 0;
+
/**
* Set the system type (e.g. 83 for Linux) of a partition. The type to set is taken from
* the partition's file system.
diff --git a/src/core/copysourcefile.h b/src/core/copysourcefile.h
index 3a5cebd..458b161 100644
--- a/src/core/copysourcefile.h
+++ b/src/core/copysourcefile.h
@@ -36,7 +36,7 @@ class CopyTarget;
class CopySourceFile : public CopySource
{
public:
- CopySourceFile(const QString& filename);
+ explicit CopySourceFile(const QString& filename);
public:
bool open() override;
diff --git a/src/core/copytargetbytearray.h b/src/core/copytargetbytearray.h
index 709fa9a..4c4a38a 100644
--- a/src/core/copytargetbytearray.h
+++ b/src/core/copytargetbytearray.h
@@ -34,7 +34,7 @@
class CopyTargetByteArray : public CopyTarget
{
public:
- CopyTargetByteArray(QByteArray& array);
+ explicit CopyTargetByteArray(QByteArray& array);
public:
bool open() override {
diff --git a/src/core/copytargetfile.h b/src/core/copytargetfile.h
index 258a403..53c32d7 100644
--- a/src/core/copytargetfile.h
+++ b/src/core/copytargetfile.h
@@ -36,7 +36,7 @@ class QString;
class CopyTargetFile : public CopyTarget
{
public:
- CopyTargetFile(const QString& filename);
+ explicit CopyTargetFile(const QString& filename);
public:
bool open() override;
diff --git a/src/core/devicescanner.cpp b/src/core/devicescanner.cpp
index bff979b..d3944de 100644
--- a/src/core/devicescanner.cpp
+++ b/src/core/devicescanner.cpp
@@ -59,7 +59,7 @@ void DeviceScanner::run()
void DeviceScanner::scan()
{
- emit progress(QString(), 0);
+ Q_EMIT progress(QString(), 0);
clear();
diff --git a/src/core/fstab.cpp b/src/core/fstab.cpp
index 650c96f..e2bcbbd 100644
--- a/src/core/fstab.cpp
+++ b/src/core/fstab.cpp
@@ -21,6 +21,8 @@
#include "util/externalcommand.h"
#include "util/report.h"
+#include
+
#if defined(Q_OS_LINUX)
#include
#endif
@@ -34,6 +36,8 @@
static void parseFsSpec(const QString& m_fsSpec, FstabEntry::Type& m_entryType, QString& m_deviceNode);
static QString findBlkIdDevice(const char *token, const QString& value);
+static void writeEntry(QTextStream& s, const FstabEntry& entry, std::array columnWidth);
+std::array fstabColumnWidth(const FstabEntryList& fstabEntries);
struct FstabEntryPrivate
{
@@ -59,6 +63,7 @@ FstabEntry::FstabEntry(const QString& fsSpec, const QString& mountPoint, const Q
d->m_comment = comment;
d->m_options = options.split(QLatin1Char(','));
+ d->m_options.removeAll(QStringLiteral("defaults"));
parseFsSpec(d->m_fsSpec, d->m_entryType, d->m_deviceNode);
}
@@ -88,15 +93,20 @@ FstabEntryList readFstabEntries( const QString& fstabPath )
// (4) dump frequency (optional, defaults to 0), no comment is allowed if omitted,
// (5) pass number (optional, defaults to 0), no comment is allowed if omitted,
// (#) comment (optional).
+ auto fsSpec = splitLine.at(0);
+ auto mountPoint = splitLine.at(1);
+ auto fsType = splitLine.at(2);
+ auto options = splitLine.at(3);
+
switch (splitLine.length()) {
case 4:
- fstabEntries.push_back( {splitLine.at(0), splitLine.at(1), splitLine.at(2), splitLine.at(3) } );
+ fstabEntries.push_back( {fsSpec, mountPoint, fsType, options } );
break;
case 5:
- fstabEntries.push_back( {splitLine.at(0), splitLine.at(1), splitLine.at(2), splitLine.at(3), splitLine.at(4).toInt() } );
+ fstabEntries.push_back( {fsSpec, mountPoint, fsType, options, splitLine.at(4).toInt() } );
break;
case 6:
- fstabEntries.push_back( {splitLine.at(0), splitLine.at(1), splitLine.at(2), splitLine.at(3), splitLine.at(4).toInt(), splitLine.at(5).toInt(), comment.isEmpty() ? QString() : QLatin1Char('#') + comment } );
+ fstabEntries.push_back( {fsSpec, mountPoint, fsType, options, splitLine.at(4).toInt(), splitLine.at(5).toInt(), comment.isEmpty() ? QString() : QLatin1Char('#') + comment } );
break;
default:
fstabEntries.push_back( { {}, {}, {}, {}, {}, {}, QLatin1Char('#') + line } );
@@ -142,6 +152,11 @@ const QStringList& FstabEntry::options() const
return d->m_options;
}
+const QString FstabEntry::optionsString() const
+{
+ return options().size() > 0 ? options().join(QLatin1Char(',')) : QStringLiteral("defaults");
+}
+
int FstabEntry::dumpFreq() const
{
return d->m_dumpFreq;
@@ -203,6 +218,9 @@ static QString findBlkIdDevice(const char *token, const QString& value)
rval = QString::fromLocal8Bit(c);
free(c);
}
+#else
+ Q_UNUSED(token);
+ Q_UNUSED(value);
#endif
return rval;
@@ -229,40 +247,50 @@ static void parseFsSpec(const QString& m_fsSpec, FstabEntry::Type& m_entryType,
}
}
-static void writeEntry(QTextStream& s, const FstabEntry& entry)
+
+// Used to nicely format fstab file
+std::array fstabColumnWidth(const FstabEntryList& fstabEntries)
+{
+ std::array columnWidth;
+
+#define FIELD_WIDTH(x) 3 + std::max_element(fstabEntries.begin(), fstabEntries.end(), [](const FstabEntry& a, const FstabEntry& b) {return a.x().length() < b.x().length(); })->x().length();
+
+ columnWidth[0] = FIELD_WIDTH(fsSpec);
+ columnWidth[1] = FIELD_WIDTH(mountPoint);
+ columnWidth[2] = FIELD_WIDTH(type);
+ columnWidth[3] = FIELD_WIDTH(optionsString);
+
+ return columnWidth;
+}
+
+static void writeEntry(QTextStream& s, const FstabEntry& entry, std::array columnWidth)
{
if (entry.entryType() == FstabEntry::Type::comment) {
s << entry.comment() << "\n";
return;
}
- QString options;
- if (entry.options().size() > 0) {
- options = entry.options().join(QLatin1Char(','));
- if (options.isEmpty())
- options = QStringLiteral("defaults");
- }
- else
- options = QStringLiteral("defaults");
-
- s << entry.fsSpec() << "\t"
- << (entry.mountPoint().isEmpty() ? QStringLiteral("none") : entry.mountPoint()) << "\t"
- << entry.type() << "\t"
- << options << "\t"
- << entry.dumpFreq() << "\t"
- << entry.passNumber() << "\t"
+ s.setFieldAlignment(QTextStream::AlignLeft);
+ s.setFieldWidth(columnWidth[0]);
+ s << entry.fsSpec()
+ << qSetFieldWidth(columnWidth[1]) << (entry.mountPoint().isEmpty() ? QStringLiteral("none") : entry.mountPoint())
+ << qSetFieldWidth(columnWidth[2]) << entry.type()
+ << qSetFieldWidth(columnWidth[3]) << entry.optionsString() << qSetFieldWidth(0)
+ << entry.dumpFreq() << " "
+ << entry.passNumber() << " "
<< entry.comment() << "\n";
}
bool writeMountpoints(const FstabEntryList& fstabEntries, const QString& filename)
{
- Report report(nullptr);
- QByteArray fstabContents;
+ QString fstabContents;
QTextStream out(&fstabContents);
+ std::array columnWidth = fstabColumnWidth(fstabEntries);
+
for (const auto &e : fstabEntries)
- writeEntry(out, e);
+ writeEntry(out, e, columnWidth);
ExternalCommand cmd;
- return cmd.writeData(report, fstabContents, filename, 0);
+ return cmd.createFile(fstabContents.toLocal8Bit(), filename);
}
diff --git a/src/core/fstab.h b/src/core/fstab.h
index d158813..cdc7e47 100644
--- a/src/core/fstab.h
+++ b/src/core/fstab.h
@@ -66,6 +66,11 @@ public:
*/
const QStringList& options() const;
+ /**
+ * @return the mount options associated with the file system
+ */
+ const QString optionsString() const;
+
/**
* @return the fs_freq field of fstab entry
*/
diff --git a/src/core/lvmdevice.cpp b/src/core/lvmdevice.cpp
index 64ff0f3..746fc0f 100644
--- a/src/core/lvmdevice.cpp
+++ b/src/core/lvmdevice.cpp
@@ -170,7 +170,7 @@ Partition* LvmDevice::scanPartition(const QString& lvPath, PartitionTable* pTabl
mountPoint = FileSystem::detectMountPoint(fs, lvPath);
mounted = FileSystem::detectMountStatus(fs, lvPath);
- if (mountPoint != QString() && fs->type() != FileSystem::Type::LinuxSwap) {
+ if (!mountPoint.isEmpty() && fs->type() != FileSystem::Type::LinuxSwap) {
const QStorageInfo storage = QStorageInfo(mountPoint);
if (logicalSize() > 0 && fs->type() != FileSystem::Type::Luks && mounted && storage.isValid())
fs->setSectorsUsed( (storage.bytesTotal() - storage.bytesFree()) / logicalSize() );
diff --git a/src/core/lvmdevice.h b/src/core/lvmdevice.h
index 86cea4e..588a2b2 100644
--- a/src/core/lvmdevice.h
+++ b/src/core/lvmdevice.h
@@ -48,7 +48,7 @@ class LIBKPMCORE_EXPORT LvmDevice : public VolumeManagerDevice
friend class VolumeManagerDevice;
public:
- LvmDevice(const QString& name, const QString& iconName = QString());
+ explicit LvmDevice(const QString& name, const QString& iconName = QString());
~LvmDevice();
public:
diff --git a/src/core/operationrunner.cpp b/src/core/operationrunner.cpp
index 1880bf6..55a9d14 100644
--- a/src/core/operationrunner.cpp
+++ b/src/core/operationrunner.cpp
@@ -69,7 +69,7 @@ void OperationRunner::run()
Operation* op = operationStack().operations()[i];
op->setStatus(Operation::StatusRunning);
- emit opStarted(i + 1, op);
+ Q_EMIT opStarted(i + 1, op);
connect(op, &Operation::progress, this, &OperationRunner::progressSub);
@@ -78,18 +78,18 @@ void OperationRunner::run()
disconnect(op, &Operation::progress, this, &OperationRunner::progressSub);
- emit opFinished(i + 1, op);
+ Q_EMIT opFinished(i + 1, op);
}
if (automounter)
kdedInterface.call( QStringLiteral("loadModule"), automounterService );
if (!status)
- emit error();
+ Q_EMIT error();
else if (isCancelling())
- emit cancelled();
+ Q_EMIT cancelled();
else
- emit finished();
+ Q_EMIT finished();
}
/** @return the number of Operations to run */
diff --git a/src/core/operationstack.cpp b/src/core/operationstack.cpp
index 0a9b9f5..2ccdc08 100644
--- a/src/core/operationstack.cpp
+++ b/src/core/operationstack.cpp
@@ -452,9 +452,9 @@ void OperationStack::push(Operation* o)
o->setStatus(Operation::StatusPending);
}
- // emit operationsChanged even if o is nullptr because it has been merged: merging might
+ // Q_EMIT operationsChanged even if o is nullptr because it has been merged: merging might
// have led to an existing operation changing.
- emit operationsChanged();
+ Q_EMIT operationsChanged();
}
/** Removes the topmost Operation from the OperationStack, calls Operation::undo() on it and deletes it. */
@@ -463,7 +463,7 @@ void OperationStack::pop()
Operation* o = operations().takeLast();
o->undo();
delete o;
- emit operationsChanged();
+ Q_EMIT operationsChanged();
}
/** Check whether previous operations involve given partition.
@@ -499,7 +499,7 @@ void OperationStack::clearOperations()
delete o;
}
- emit operationsChanged();
+ Q_EMIT operationsChanged();
}
/** Clears the list of Devices. */
@@ -509,7 +509,7 @@ void OperationStack::clearDevices()
qDeleteAll(previewDevices());
previewDevices().clear();
- emit devicesChanged();
+ Q_EMIT devicesChanged();
}
/** Finds a Device a Partition is on.
@@ -549,7 +549,7 @@ void OperationStack::addDevice(Device* d)
QWriteLocker lockDevices(&lock());
previewDevices().append(d);
- emit devicesChanged();
+ Q_EMIT devicesChanged();
}
static bool deviceLessThan(const Device* d1, const Device* d2)
@@ -567,5 +567,5 @@ void OperationStack::sortDevices()
std::sort(previewDevices().begin(), previewDevices().end(), deviceLessThan);
- emit devicesChanged();
+ Q_EMIT devicesChanged();
}
diff --git a/src/core/operationstack.h b/src/core/operationstack.h
index ccf2897..7276dd4 100644
--- a/src/core/operationstack.h
+++ b/src/core/operationstack.h
@@ -51,7 +51,7 @@ public:
typedef QList Operations;
public:
- OperationStack(QObject* parent = nullptr);
+ explicit OperationStack(QObject* parent = nullptr);
~OperationStack();
Q_SIGNALS:
diff --git a/src/core/partition.h b/src/core/partition.h
index 7b6c0f8..dd30ef3 100644
--- a/src/core/partition.h
+++ b/src/core/partition.h
@@ -24,7 +24,6 @@
#include "util/libpartitionmanagerexport.h"
-#include
#include
#include
@@ -125,9 +124,15 @@ public:
const QString& label() const {
return m_Label; /**< @return the GPT Partition label */
}
+ const QString& type() const {
+ return m_Type; /**< @return the GPT Partition type */
+ }
const QString& uuid() const {
return m_UUID; /**< @return the GPT Partition UUID */
}
+ quint64 attributes() const {
+ return m_Attributes; /**< @return the GPT Partition attributes */
+ }
qint64 firstSector() const {
return m_FirstSector; /**< @return the Partition's first sector on the Device */
}
@@ -210,9 +215,15 @@ public:
void setLabel(const QString& s) {
m_Label = s; /**< @param s the new label */
}
+ void setType(const QString& s) {
+ m_Type = s; /**< @param s the new type */
+ }
void setUUID(const QString& s) {
m_UUID = s; /**< @param s the new UUID */
}
+ void setAttributes(quint64 f) {
+ m_Attributes = f; /**< @param f the new attributes */
+ }
void append(Partition* p) override {
m_Children.append(p);
@@ -266,7 +277,9 @@ private:
qint64 m_LastSector;
QString m_DevicePath;
QString m_Label;
+ QString m_Type;
QString m_UUID;
+ quint64 m_Attributes;
QString m_PartitionPath;
QString m_MountPoint;
PartitionTable::Flags m_AvailableFlags;
diff --git a/src/core/partitionalignment.cpp b/src/core/partitionalignment.cpp
index d32da6d..b0ff0e1 100644
--- a/src/core/partitionalignment.cpp
+++ b/src/core/partitionalignment.cpp
@@ -75,7 +75,7 @@ bool PartitionAlignment::isLengthAligned(const Device& d, const Partition& p)
@param d device the partition is on
@param p the partition to check
@param quiet if true, will not print warning
- @return true if propertly aligned
+ @return true if properly aligned
*/
bool PartitionAlignment::isAligned(const Device& d, const Partition& p, bool quiet)
{
diff --git a/src/core/raid/softwareraid.h b/src/core/raid/softwareraid.h
index dceb395..f3e5f3c 100644
--- a/src/core/raid/softwareraid.h
+++ b/src/core/raid/softwareraid.h
@@ -36,7 +36,7 @@ public:
Recovery,
};
- SoftwareRAID(const QString& name,
+ explicit SoftwareRAID(const QString& name,
SoftwareRAID::Status status = SoftwareRAID::Status::Active,
const QString& iconName = QString());
diff --git a/src/core/smartattribute.h b/src/core/smartattribute.h
index 2df9ae9..7df36a4 100644
--- a/src/core/smartattribute.h
+++ b/src/core/smartattribute.h
@@ -46,7 +46,7 @@ public:
};
public:
- SmartAttribute(const SmartAttributeParsedData& a);
+ explicit SmartAttribute(const SmartAttributeParsedData& a);
public:
qint32 id() const {
diff --git a/src/core/smartparser.cpp b/src/core/smartparser.cpp
index f7a7377..a3023ee 100644
--- a/src/core/smartparser.cpp
+++ b/src/core/smartparser.cpp
@@ -31,7 +31,7 @@
#include
/** Creates a new SmartParser object
- @param device_path device path that indicates the device that SMART must analyse
+ @param device_path device path that indicates the device that SMART must analyze
*/
SmartParser::SmartParser(const QString &device_path) :
m_DevicePath(device_path),
diff --git a/src/core/smartparser.h b/src/core/smartparser.h
index 417bd90..115fbd5 100644
--- a/src/core/smartparser.h
+++ b/src/core/smartparser.h
@@ -32,7 +32,7 @@ class SmartDiskInformation;
class SmartParser
{
public:
- SmartParser(const QString &device_path);
+ explicit SmartParser(const QString &device_path);
~SmartParser();
public:
@@ -41,7 +41,7 @@ public:
public:
const QString &devicePath() const
{
- return m_DevicePath; /**< @return the device path that SMART must analyse */
+ return m_DevicePath; /**< @return the device path that SMART must analyze */
}
SmartDiskInformation *diskInformation() const
diff --git a/src/core/smartstatus.h b/src/core/smartstatus.h
index 06defe8..d480cd2 100644
--- a/src/core/smartstatus.h
+++ b/src/core/smartstatus.h
@@ -57,7 +57,7 @@ public:
typedef QList Attributes;
public:
- SmartStatus(const QString &device_path);
+ explicit SmartStatus(const QString &device_path);
public:
void update();
diff --git a/src/core/volumemanagerdevice.cpp b/src/core/volumemanagerdevice.cpp
index 185c18f..0ce656a 100644
--- a/src/core/volumemanagerdevice.cpp
+++ b/src/core/volumemanagerdevice.cpp
@@ -16,10 +16,10 @@
* along with this program. If not, see .*
*************************************************************************/
-#include "core/device_p.h"
-#include "core/partition.h"
#include "core/volumemanagerdevice.h"
#include "core/volumemanagerdevice_p.h"
+#include "core/device_p.h"
+#include "core/partition.h"
#include "core/lvmdevice.h"
#include "core/raid/softwareraid.h"
diff --git a/src/fs/apfs.cpp b/src/fs/apfs.cpp
index 984cef2..52f126a 100644
--- a/src/fs/apfs.cpp
+++ b/src/fs/apfs.cpp
@@ -23,8 +23,8 @@ FileSystem::CommandSupportType apfs::m_Move = FileSystem::cmdSupportCore;
FileSystem::CommandSupportType apfs::m_Copy = FileSystem::cmdSupportCore;
FileSystem::CommandSupportType apfs::m_Backup = FileSystem::cmdSupportCore;
-apfs::apfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Apfs)
+apfs::apfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::Apfs)
{
}
}
diff --git a/src/fs/apfs.h b/src/fs/apfs.h
index 2af3a40..3d080b5 100644
--- a/src/fs/apfs.h
+++ b/src/fs/apfs.h
@@ -34,7 +34,7 @@ namespace FS
class LIBKPMCORE_EXPORT apfs : public FileSystem
{
public:
- apfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ apfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
public:
CommandSupportType supportMove() const override {
diff --git a/src/fs/bitlocker.cpp b/src/fs/bitlocker.cpp
index 15280cf..8f131b4 100644
--- a/src/fs/bitlocker.cpp
+++ b/src/fs/bitlocker.cpp
@@ -23,8 +23,8 @@ FileSystem::CommandSupportType bitlocker::m_Move = FileSystem::cmdSupportCore;
FileSystem::CommandSupportType bitlocker::m_Copy = FileSystem::cmdSupportCore;
FileSystem::CommandSupportType bitlocker::m_Backup = FileSystem::cmdSupportCore;
-bitlocker::bitlocker(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::BitLocker)
+bitlocker::bitlocker(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::BitLocker)
{
}
}
diff --git a/src/fs/bitlocker.h b/src/fs/bitlocker.h
index 493eb4d..e602d79 100644
--- a/src/fs/bitlocker.h
+++ b/src/fs/bitlocker.h
@@ -34,7 +34,7 @@ namespace FS
class LIBKPMCORE_EXPORT bitlocker : public FileSystem
{
public:
- bitlocker(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ bitlocker(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
public:
CommandSupportType supportMove() const override {
diff --git a/src/fs/btrfs.cpp b/src/fs/btrfs.cpp
index c7c1edb..f27ad2b 100644
--- a/src/fs/btrfs.cpp
+++ b/src/fs/btrfs.cpp
@@ -43,8 +43,8 @@ FileSystem::CommandSupportType btrfs::m_SetLabel = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType btrfs::m_UpdateUUID = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType btrfs::m_GetUUID = FileSystem::cmdSupportNone;
-btrfs::btrfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Btrfs)
+btrfs::btrfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::Btrfs)
{
}
@@ -65,6 +65,22 @@ void btrfs::init()
m_GetLabel = cmdSupportCore;
m_Backup = cmdSupportCore;
m_GetUUID = cmdSupportCore;
+
+ if (m_Create == cmdSupportFileSystem) {
+ ExternalCommand cmd(QStringLiteral("mkfs.btrfs"), QStringList() << QStringLiteral("-O") << QStringLiteral("list-all"));
+ if (cmd.run(-1) && cmd.exitCode() == 0) {
+ QStringList lines = cmd.output().split(QStringLiteral("\n"));
+
+ // First line is introductory text, we don't need it
+ lines.removeFirst();
+
+ for (const auto& l: lines) {
+ if (!l.isEmpty())
+ addAvailableFeature(l.split(QStringLiteral(" ")).first());
+ }
+ }
+ }
+
}
bool btrfs::supportToolFound() const
@@ -86,7 +102,7 @@ bool btrfs::supportToolFound() const
FileSystem::SupportTool btrfs::supportToolName() const
{
- return SupportTool(QStringLiteral("btrfs-tools"), QUrl(QStringLiteral("http://btrfs.wiki.kernel.org/")));
+ return SupportTool(QStringLiteral("btrfs-tools"), QUrl(QStringLiteral("https://btrfs.wiki.kernel.org/")));
}
qint64 btrfs::minCapacity() const
@@ -128,7 +144,26 @@ bool btrfs::check(Report& report, const QString& deviceNode) const
bool btrfs::create(Report& report, const QString& deviceNode)
{
- ExternalCommand cmd(report, QStringLiteral("mkfs.btrfs"), { QStringLiteral("--force"), deviceNode });
+ QStringList args = QStringList();
+
+ if (!this->features().isEmpty()) {
+ QStringList feature_list = QStringList();
+ for (const auto& k : this->features().keys()) {
+ const auto& v = this->features().value(k);
+ if (v.type() == QVariant::Type::Bool) {
+ if (v.toBool())
+ feature_list << k;
+ else
+ feature_list << (QStringLiteral("^") + k);
+ } else {
+ qWarning() << "Ignoring feature" << k << "of type" << v.type() << "; requires type QVariant::bool.";
+ }
+ }
+ args << QStringLiteral("--features") << feature_list.join(QStringLiteral(","));
+ }
+ args << QStringLiteral("--force") << deviceNode;
+
+ ExternalCommand cmd(report, QStringLiteral("mkfs.btrfs"), args);
return cmd.run(-1) && cmd.exitCode() == 0;
}
diff --git a/src/fs/btrfs.h b/src/fs/btrfs.h
index 694f8c8..9277cb4 100644
--- a/src/fs/btrfs.h
+++ b/src/fs/btrfs.h
@@ -38,7 +38,7 @@ namespace FS
class LIBKPMCORE_EXPORT btrfs : public FileSystem
{
public:
- btrfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ btrfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
public:
void init() override;
@@ -61,6 +61,9 @@ public:
CommandSupportType supportCreate() const override {
return m_Create;
}
+ CommandSupportType supportCreateWithFeatures() const override {
+ return m_Create;
+ }
CommandSupportType supportGrow() const override {
return m_Grow;
}
diff --git a/src/fs/exfat.cpp b/src/fs/exfat.cpp
index 3173450..7c7c962 100644
--- a/src/fs/exfat.cpp
+++ b/src/fs/exfat.cpp
@@ -38,8 +38,8 @@ FileSystem::CommandSupportType exfat::m_SetLabel = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType exfat::m_UpdateUUID = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType exfat::m_GetUUID = FileSystem::cmdSupportNone;
-exfat::exfat(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Exfat)
+exfat::exfat(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::Exfat)
{
}
@@ -79,7 +79,7 @@ bool exfat::supportToolFound() const
FileSystem::SupportTool exfat::supportToolName() const
{
- return SupportTool(QStringLiteral("exfat-utils"), QUrl(QStringLiteral("http://code.google.com/p/exfat/")));
+ return SupportTool(QStringLiteral("exfat-utils"), QUrl(QStringLiteral("https://github.com/relan/exfat")));
}
qint64 exfat::maxCapacity() const
diff --git a/src/fs/exfat.h b/src/fs/exfat.h
index 55940b0..43b5de9 100644
--- a/src/fs/exfat.h
+++ b/src/fs/exfat.h
@@ -37,7 +37,7 @@ namespace FS
class LIBKPMCORE_EXPORT exfat : public FileSystem
{
public:
- exfat(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ exfat(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
public:
void init() override;
diff --git a/src/fs/ext2.cpp b/src/fs/ext2.cpp
index fce9274..688e135 100644
--- a/src/fs/ext2.cpp
+++ b/src/fs/ext2.cpp
@@ -39,8 +39,8 @@ FileSystem::CommandSupportType ext2::m_SetLabel = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType ext2::m_UpdateUUID = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType ext2::m_GetUUID = FileSystem::cmdSupportNone;
-ext2::ext2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type t) :
- FileSystem(firstsector, lastsector, sectorsused, label, t)
+ext2::ext2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features, FileSystem::Type t) :
+ FileSystem(firstsector, lastsector, sectorsused, label, features, t)
{
}
@@ -58,6 +58,37 @@ void ext2::init()
m_Move = (m_Check != cmdSupportNone) ? cmdSupportCore : cmdSupportNone;
m_Backup = cmdSupportCore;
m_GetUUID = cmdSupportCore;
+
+ if (m_Create == cmdSupportFileSystem) {
+ addAvailableFeature(QStringLiteral("64bit"));
+ addAvailableFeature(QStringLiteral("bigalloc"));
+ addAvailableFeature(QStringLiteral("casefold"));
+ addAvailableFeature(QStringLiteral("dir_index"));
+ addAvailableFeature(QStringLiteral("dir_nlink"));
+ addAvailableFeature(QStringLiteral("ea_inode"));
+ addAvailableFeature(QStringLiteral("encrypt"));
+ addAvailableFeature(QStringLiteral("ext_attr"));
+ addAvailableFeature(QStringLiteral("extent"));
+ addAvailableFeature(QStringLiteral("extra_isize"));
+ addAvailableFeature(QStringLiteral("filetype"));
+ addAvailableFeature(QStringLiteral("flex_bg"));
+ addAvailableFeature(QStringLiteral("has_journal"));
+ addAvailableFeature(QStringLiteral("huge_file"));
+ addAvailableFeature(QStringLiteral("inline_data"));
+ addAvailableFeature(QStringLiteral("journal_dev"));
+ addAvailableFeature(QStringLiteral("large_dir"));
+ addAvailableFeature(QStringLiteral("large_file"));
+ addAvailableFeature(QStringLiteral("metadata_csum"));
+ addAvailableFeature(QStringLiteral("metadata_csum_seed"));
+ addAvailableFeature(QStringLiteral("meta_bg"));
+ addAvailableFeature(QStringLiteral("mmp"));
+ addAvailableFeature(QStringLiteral("project"));
+ addAvailableFeature(QStringLiteral("quota"));
+ addAvailableFeature(QStringLiteral("resize_inode"));
+ addAvailableFeature(QStringLiteral("sparse_super"));
+ addAvailableFeature(QStringLiteral("sparse_super2"));
+ addAvailableFeature(QStringLiteral("uninit_bg"));
+ }
}
bool ext2::supportToolFound() const
@@ -133,7 +164,26 @@ bool ext2::check(Report& report, const QString& deviceNode) const
bool ext2::create(Report& report, const QString& deviceNode)
{
- ExternalCommand cmd(report, QStringLiteral("mkfs.ext2"), { QStringLiteral("-qF"), deviceNode });
+ QStringList args = QStringList();
+
+ if (!this->features().isEmpty()) {
+ QStringList feature_list = QStringList();
+ for (const auto& k : this->features().keys()) {
+ const auto& v = this->features().value(k);
+ if (v.type() == QVariant::Type::Bool) {
+ if (v.toBool())
+ feature_list << k;
+ else
+ feature_list << (QStringLiteral("^") + k);
+ } else {
+ qWarning() << "Ignoring feature" << k << "of type" << v.type() << "; requires type QVariant::bool.";
+ }
+ }
+ args << QStringLiteral("-O") << feature_list.join(QStringLiteral(","));
+ }
+ args << QStringLiteral("-qF") << deviceNode;
+
+ ExternalCommand cmd(report, QStringLiteral("mkfs.ext2"), args);
return cmd.run(-1) && cmd.exitCode() == 0;
}
diff --git a/src/fs/ext2.h b/src/fs/ext2.h
index ec2ca59..32b0eac 100644
--- a/src/fs/ext2.h
+++ b/src/fs/ext2.h
@@ -37,7 +37,7 @@ namespace FS
class LIBKPMCORE_EXPORT ext2 : public FileSystem
{
public:
- ext2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type t = FileSystem::Type::Ext2);
+ ext2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {}, FileSystem::Type t = FileSystem::Type::Ext2);
public:
void init() override;
@@ -59,6 +59,9 @@ public:
CommandSupportType supportCreate() const override {
return m_Create;
}
+ CommandSupportType supportCreateWithFeatures() const override {
+ return m_Create;
+ }
CommandSupportType supportGrow() const override {
return m_Grow;
}
diff --git a/src/fs/ext3.cpp b/src/fs/ext3.cpp
index 7fa67c9..af81047 100644
--- a/src/fs/ext3.cpp
+++ b/src/fs/ext3.cpp
@@ -24,8 +24,8 @@
namespace FS
{
-ext3::ext3(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- ext2(firstsector, lastsector, sectorsused, label, FileSystem::Type::Ext3)
+ext3::ext3(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ ext2(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::Ext3)
{
}
@@ -36,7 +36,26 @@ qint64 ext3::maxCapacity() const
bool ext3::create(Report& report, const QString& deviceNode)
{
- ExternalCommand cmd(report, QStringLiteral("mkfs.ext3"), QStringList() << QStringLiteral("-qF") << deviceNode);
+ QStringList args = QStringList();
+
+ if (!this->features().isEmpty()) {
+ QStringList feature_list = QStringList();
+ for (const auto& k : this->features().keys()) {
+ const auto& v = this->features().value(k);
+ if (v.type() == QVariant::Type::Bool) {
+ if (v.toBool())
+ feature_list << k;
+ else
+ feature_list << (QStringLiteral("^") + k);
+ } else {
+ qWarning() << "Ignoring feature" << k << "of type" << v.type() << "; requires type QVariant::bool.";
+ }
+ }
+ args << QStringLiteral("-O") << feature_list.join(QStringLiteral(","));
+ }
+ args << QStringLiteral("-qF") << deviceNode;
+
+ ExternalCommand cmd(report, QStringLiteral("mkfs.ext3"), args);
return cmd.run(-1) && cmd.exitCode() == 0;
}
diff --git a/src/fs/ext3.h b/src/fs/ext3.h
index 23ac4df..c21da82 100644
--- a/src/fs/ext3.h
+++ b/src/fs/ext3.h
@@ -40,7 +40,7 @@ namespace FS
class LIBKPMCORE_EXPORT ext3 : public ext2
{
public:
- ext3(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ ext3(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
public:
bool create(Report& report, const QString& deviceNode) override;
diff --git a/src/fs/ext4.cpp b/src/fs/ext4.cpp
index 0fa3811..3692eb5 100644
--- a/src/fs/ext4.cpp
+++ b/src/fs/ext4.cpp
@@ -24,8 +24,8 @@
namespace FS
{
-ext4::ext4(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- ext2(firstsector, lastsector, sectorsused, label, FileSystem::Type::Ext4)
+ext4::ext4(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ ext2(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::Ext4)
{
}
@@ -36,7 +36,26 @@ qint64 ext4::maxCapacity() const
bool ext4::create(Report& report, const QString& deviceNode)
{
- ExternalCommand cmd(report, QStringLiteral("mkfs.ext4"), QStringList() << QStringLiteral("-qF") << deviceNode);
+ QStringList args = QStringList();
+
+ if (!this->features().isEmpty()) {
+ QStringList feature_list = QStringList();
+ for (const auto& k : this->features().keys()) {
+ const auto& v = this->features().value(k);
+ if (v.type() == QVariant::Type::Bool) {
+ if (v.toBool())
+ feature_list << k;
+ else
+ feature_list << (QStringLiteral("^") + k);
+ } else {
+ qWarning() << "Ignoring feature" << k << "of type" << v.type() << "; requires type QVariant::bool.";
+ }
+ }
+ args << QStringLiteral("-O") << feature_list.join(QStringLiteral(","));
+ }
+ args << QStringLiteral("-qF") << deviceNode;
+
+ ExternalCommand cmd(report, QStringLiteral("mkfs.ext4"), args);
return cmd.run(-1) && cmd.exitCode() == 0;
}
diff --git a/src/fs/ext4.h b/src/fs/ext4.h
index 8050413..64562da 100644
--- a/src/fs/ext4.h
+++ b/src/fs/ext4.h
@@ -40,7 +40,7 @@ namespace FS
class LIBKPMCORE_EXPORT ext4 : public ext2
{
public:
- ext4(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ ext4(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
public:
bool create(Report& report, const QString& deviceNode) override;
diff --git a/src/fs/extended.cpp b/src/fs/extended.cpp
index 49ab801..bf1d859 100644
--- a/src/fs/extended.cpp
+++ b/src/fs/extended.cpp
@@ -24,8 +24,8 @@ FileSystem::CommandSupportType extended::m_Grow = FileSystem::cmdSupportCore;
FileSystem::CommandSupportType extended::m_Shrink = FileSystem::cmdSupportCore;
FileSystem::CommandSupportType extended::m_Move = FileSystem::cmdSupportCore;
-extended::extended(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Extended)
+extended::extended(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::Extended)
{
}
diff --git a/src/fs/extended.h b/src/fs/extended.h
index ef00a7c..73e1949 100644
--- a/src/fs/extended.h
+++ b/src/fs/extended.h
@@ -40,7 +40,7 @@ namespace FS
class LIBKPMCORE_EXPORT extended : public FileSystem
{
public:
- extended(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ extended(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
public:
diff --git a/src/fs/f2fs.cpp b/src/fs/f2fs.cpp
index f8c62cb..8ef1242 100644
--- a/src/fs/f2fs.cpp
+++ b/src/fs/f2fs.cpp
@@ -45,8 +45,8 @@ FileSystem::CommandSupportType f2fs::m_UpdateUUID = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType f2fs::m_GetUUID = FileSystem::cmdSupportNone;
bool f2fs::oldVersion = false; // 1.8.x or older
-f2fs::f2fs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::F2fs)
+f2fs::f2fs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::F2fs)
{
}
diff --git a/src/fs/f2fs.h b/src/fs/f2fs.h
index 4d2d92b..f3c8a56 100644
--- a/src/fs/f2fs.h
+++ b/src/fs/f2fs.h
@@ -36,7 +36,7 @@ namespace FS
class LIBKPMCORE_EXPORT f2fs : public FileSystem
{
public:
- f2fs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ f2fs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
public:
void init() override;
diff --git a/src/fs/fat12.cpp b/src/fs/fat12.cpp
index b4917fe..a098dbe 100644
--- a/src/fs/fat12.cpp
+++ b/src/fs/fat12.cpp
@@ -29,6 +29,9 @@
#include
#include
+#include
+#include
+
#include
namespace FS
@@ -46,8 +49,8 @@ FileSystem::CommandSupportType fat12::m_Backup = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType fat12::m_UpdateUUID = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType fat12::m_GetUUID = FileSystem::cmdSupportNone;
-fat12::fat12(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type t) :
- FileSystem(firstsector, lastsector, sectorsused, label, t)
+fat12::fat12(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features, FileSystem::Type t) :
+ FileSystem(firstsector, lastsector, sectorsused, label, features, t)
{
}
@@ -61,6 +64,11 @@ void fat12::init()
m_Backup = cmdSupportCore;
m_UpdateUUID = cmdSupportCore;
m_GetUUID = cmdSupportCore;
+
+ if (m_Create == cmdSupportFileSystem) {
+ addAvailableFeature(QStringLiteral("sector-size"));
+ addAvailableFeature(QStringLiteral("sectors-per-cluster"));
+ }
}
bool fat12::supportToolFound() const
@@ -151,7 +159,39 @@ bool fat12::check(Report& report, const QString& deviceNode) const
bool fat12::create(Report& report, const QString& deviceNode)
{
- ExternalCommand cmd(report, QStringLiteral("mkfs.fat"), { QStringLiteral("-F12"), QStringLiteral("-I"), QStringLiteral("-v"), deviceNode });
+ return createWithFatSize(report, deviceNode, 12);
+}
+
+bool fat12::createWithFatSize(Report &report, const QString& deviceNode, int fatSize)
+{
+ QStringList args = QStringList();
+
+ if (fatSize != 12 && fatSize != 16 && fatSize != 32)
+ return false;
+
+ for (const auto& k : this->features().keys()) {
+ const auto& v = this->features().value(k);
+ if (k == QStringLiteral("sector-size")) {
+ quint32 sectorSize = v.toInt();
+
+ /* sectorSize has to be a power of 2 between 512 and 32768 */
+ if (sectorSize >= 512 && sectorSize <= 32768 && sectorSize == qNextPowerOfTwo(sectorSize - 1))
+ args << QStringLiteral("-S%1").arg(sectorSize);
+ else
+ qWarning() << QStringLiteral("FAT sector size %1 is invalid, using default").arg(sectorSize);
+ } else if (k == QStringLiteral("sectors-per-cluster")) {
+ quint32 sectorsPerCluster = v.toInt();
+
+ /* sectorsPerCluster has to be a power of 2 between 2 and 128 */
+ if (sectorsPerCluster <= 128 && sectorsPerCluster == qNextPowerOfTwo(sectorsPerCluster - 1))
+ args << QStringLiteral("-s%1").arg(sectorsPerCluster);
+ else
+ qWarning() << QStringLiteral("FAT sector size %1 is invalid, using default").arg(sectorsPerCluster);
+ }
+ }
+ args << QStringLiteral("-F%1").arg(fatSize) << QStringLiteral("-I") << QStringLiteral("-v") << deviceNode;
+
+ ExternalCommand cmd(report, QStringLiteral("mkfs.fat"), args);
return cmd.run(-1) && cmd.exitCode() == 0;
}
diff --git a/src/fs/fat12.h b/src/fs/fat12.h
index 5a02895..4c08aac 100644
--- a/src/fs/fat12.h
+++ b/src/fs/fat12.h
@@ -37,7 +37,7 @@ namespace FS
class LIBKPMCORE_EXPORT fat12 : public FileSystem
{
public:
- fat12(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type t = FileSystem::Type::Fat12);
+ fat12(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {}, FileSystem::Type t = FileSystem::Type::Fat12);
public:
void init() override;
@@ -92,6 +92,9 @@ public:
SupportTool supportToolName() const override;
bool supportToolFound() const override;
+protected:
+ bool createWithFatSize(Report &report, const QString& deviceNode, int fatSize);
+
public:
static CommandSupportType m_GetUsed;
static CommandSupportType m_GetLabel;
diff --git a/src/fs/fat16.cpp b/src/fs/fat16.cpp
index 69962de..fb0e6e3 100644
--- a/src/fs/fat16.cpp
+++ b/src/fs/fat16.cpp
@@ -31,13 +31,8 @@
namespace FS
{
-fat16::fat16(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- fat12(firstsector, lastsector, sectorsused, label, FileSystem::Type::Fat16)
-{
-}
-
-fat16::fat16(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type type) :
- fat12(firstsector, lastsector, sectorsused, label, type)
+fat16::fat16(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features, FileSystem::Type type) :
+ fat12(firstsector, lastsector, sectorsused, label, features, type)
{
}
@@ -53,6 +48,11 @@ void fat16::init()
m_Grow = findExternal(QStringLiteral("fatresize")) ? cmdSupportFileSystem : cmdSupportNone;
m_Shrink = findExternal(QStringLiteral("fatresize")) ? cmdSupportFileSystem : cmdSupportNone;
m_GetUUID = cmdSupportCore;
+
+ if (m_Create == cmdSupportFileSystem) {
+ addAvailableFeature(QStringLiteral("sector-size"));
+ addAvailableFeature(QStringLiteral("sectors-per-cluster"));
+ }
}
bool fat16::supportToolFound() const
@@ -84,8 +84,7 @@ qint64 fat16::maxCapacity() const
bool fat16::create(Report& report, const QString& deviceNode)
{
- ExternalCommand cmd(report, QStringLiteral("mkfs.fat"), { QStringLiteral("-F16"), QStringLiteral("-I"), QStringLiteral("-v"), deviceNode });
- return cmd.run(-1) && cmd.exitCode() == 0;
+ return createWithFatSize(report, deviceNode, 16);
}
bool fat16::resize(Report& report, const QString& deviceNode, qint64 length) const
diff --git a/src/fs/fat16.h b/src/fs/fat16.h
index ea988a5..edceb58 100644
--- a/src/fs/fat16.h
+++ b/src/fs/fat16.h
@@ -33,8 +33,7 @@ namespace FS
class LIBKPMCORE_EXPORT fat16 : public fat12
{
public:
- fat16(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
- fat16(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type type);
+ fat16(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {}, FileSystem::Type type = FileSystem::Type::Fat16);
public:
void init() override;
diff --git a/src/fs/fat32.cpp b/src/fs/fat32.cpp
index 2bb6b34..8e5b709 100644
--- a/src/fs/fat32.cpp
+++ b/src/fs/fat32.cpp
@@ -26,8 +26,8 @@
namespace FS
{
-fat32::fat32(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- fat16(firstsector, lastsector, sectorsused, label, FileSystem::Type::Fat32)
+fat32::fat32(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ fat16(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::Fat32)
{
}
@@ -43,8 +43,7 @@ qint64 fat32::maxCapacity() const
bool fat32::create(Report& report, const QString& deviceNode)
{
- ExternalCommand cmd(report, QStringLiteral("mkfs.fat"), { QStringLiteral("-F32"), QStringLiteral("-I"), QStringLiteral("-v"), deviceNode });
- return cmd.run(-1) && cmd.exitCode() == 0;
+ return createWithFatSize(report, deviceNode, 32);
}
bool fat32::updateUUID(Report& report, const QString& deviceNode) const
diff --git a/src/fs/fat32.h b/src/fs/fat32.h
index a356bf7..4bbdc93 100644
--- a/src/fs/fat32.h
+++ b/src/fs/fat32.h
@@ -40,7 +40,7 @@ namespace FS
class LIBKPMCORE_EXPORT fat32 : public fat16
{
public:
- fat32(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ fat32(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
public:
bool create(Report& report, const QString& deviceNode) override;
diff --git a/src/fs/filesystem.cpp b/src/fs/filesystem.cpp
index 4c9d25e..7423923 100644
--- a/src/fs/filesystem.cpp
+++ b/src/fs/filesystem.cpp
@@ -17,10 +17,10 @@
* along with this program. If not, see .*
*************************************************************************/
+#include "fs/filesystem.h"
#include "core/fstab.h"
#include "core/raid/softwareraid.h"
-#include "fs/filesystem.h"
#include "fs/lvm2_pv.h"
#include "backend/corebackend.h"
@@ -85,6 +85,8 @@ struct FileSystemPrivate {
qint64 m_SectorsUsed;
QString m_Label;
QString m_UUID;
+ QStringList m_AvailableFeatures;
+ QVariantMap m_Features;
};
/** Creates a new FileSystem object
@@ -105,6 +107,26 @@ FileSystem::FileSystem(qint64 firstsector, qint64 lastsector, qint64 sectorsused
d->m_UUID = QString();
}
+/** Creates a new FileSystem object
+ @param firstsector the first sector used by this FileSystem on the Device
+ @param lastsector the last sector used by this FileSystem on the Device
+ @param sectorsused the number of sectors in use on the FileSystem
+ @param label the FileSystem label
+ @param features the FileSystem features
+ @param type the FileSystem type
+*/
+FileSystem::FileSystem(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features, FileSystem::Type type) :
+ d(std::make_unique())
+{
+ d->m_Type = type;
+ d->m_FirstSector = firstsector;
+ d->m_LastSector = lastsector;
+ d->m_SectorsUsed = sectorsused;
+ d->m_Label = label;
+ d->m_Features = features;
+ d->m_UUID = QString();
+}
+
FileSystem::~FileSystem()
{
}
@@ -155,7 +177,7 @@ bool FileSystem::detectMountStatus(FileSystem* fs, const QString& partitionPath)
bool mounted = false;
if (fs->type() == FileSystem::Type::Lvm2_PV) {
- mounted = FS::lvm2_pv::getVGName(partitionPath) != QString();
+ mounted = !FS::lvm2_pv::getVGName(partitionPath).isEmpty();
} else {
mounted = isMounted(partitionPath);
}
@@ -585,6 +607,23 @@ bool FileSystem::findExternal(const QString& cmdName, const QStringList& args, i
return cmd.exitCode() == 0 || cmd.exitCode() == expectedCode;
}
+void FileSystem::addAvailableFeature(const QString& name)
+{
+ d->m_AvailableFeatures.append(name);
+}
+
+void FileSystem::addFeature(const QString& name, const QVariant& value)
+{
+ d->m_Features.insert(name, value);
+}
+
+void FileSystem::addFeatures(const QVariantMap& features)
+{
+ for (const auto& k : features.keys()) {
+ d->m_Features.insert(k, features.value(k));
+ }
+}
+
bool FileSystem::supportToolFound() const
{
return false;
@@ -610,6 +649,16 @@ const QString& FileSystem::label() const
return d->m_Label;
}
+const QStringList& FileSystem::availableFeatures() const
+{
+ return d->m_AvailableFeatures;
+}
+
+const QVariantMap& FileSystem::features() const
+{
+ return d->m_Features;
+}
+
qint64 FileSystem::sectorSize() const
{
return d->m_SectorSize;
diff --git a/src/fs/filesystem.h b/src/fs/filesystem.h
index 052a391..39bc46e 100644
--- a/src/fs/filesystem.h
+++ b/src/fs/filesystem.h
@@ -20,8 +20,10 @@
#ifndef KPMCORE_FILESYSTEM_H
#define KPMCORE_FILESYSTEM_H
+
#include "util/libpartitionmanagerexport.h"
+#include
#include
#include
#include
@@ -113,6 +115,7 @@ public:
protected:
FileSystem(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type type);
+ FileSystem(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features, FileSystem::Type type);
public:
virtual ~FileSystem();
@@ -149,6 +152,9 @@ public:
virtual CommandSupportType supportCreateWithLabel() const {
return cmdSupportNone; /**< @return CommandSupportType for creating */
}
+ virtual CommandSupportType supportCreateWithFeatures() const {
+ return cmdSupportNone; /**< @return CommandSupportType for creating */
+ }
virtual CommandSupportType supportGrow() const {
return cmdSupportNone; /**< @return CommandSupportType for growing */
}
@@ -263,6 +269,19 @@ public:
/**< @return the FileSystem's label */
const QString& label() const;
+ /**< @return the FileSystem's available features */
+ const QStringList& availableFeatures() const;
+
+ /**< @return the FileSystem's features */
+ const QVariantMap& features() const;
+
+ /**< @param the feature's name to add to the FileSystem */
+ /**< @param the feature's value to add to the FileSystem */
+ void addFeature(const QString& name, const QVariant& value);
+
+ /**< @param features the list of features to add to the FileSystem */
+ void addFeatures(const QVariantMap& features);
+
/**< @return the sector size in the underlying Device */
qint64 sectorSize() const;
@@ -286,6 +305,7 @@ public:
protected:
static bool findExternal(const QString& cmdName, const QStringList& args = QStringList(), int exptectedCode = 1);
+ void addAvailableFeature(const QString& name);
std::unique_ptr d;
};
diff --git a/src/fs/filesystemfactory.cpp b/src/fs/filesystemfactory.cpp
index 0be1542..0141eba 100644
--- a/src/fs/filesystemfactory.cpp
+++ b/src/fs/filesystemfactory.cpp
@@ -62,46 +62,48 @@ FileSystemFactory::FileSystems FileSystemFactory::m_FileSystems;
/** Initializes the instance. */
void FileSystemFactory::init()
{
+ FileSystems fileSystems;
+ fileSystems.insert(FileSystem::Type::Apfs, new FS::apfs(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::BitLocker, new FS::bitlocker(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::Btrfs, new FS::btrfs(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::Exfat, new FS::exfat(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::Ext2, new FS::ext2(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::Ext3, new FS::ext3(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::Ext4, new FS::ext4(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::Extended, new FS::extended(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::F2fs, new FS::f2fs(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::Fat12, new FS::fat12(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::Fat16, new FS::fat16(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::Fat32, new FS::fat32(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::Hfs, new FS::hfs(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::HfsPlus, new FS::hfsplus(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::Hpfs, new FS::hpfs(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::Iso9660, new FS::iso9660(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::Jfs, new FS::jfs(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::LinuxRaidMember, new FS::linuxraidmember(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::LinuxSwap, new FS::linuxswap(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::Luks, new FS::luks(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::Luks2, new FS::luks2(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::Lvm2_PV, new FS::lvm2_pv(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::Minix, new FS::minix(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::Nilfs2, new FS::nilfs2(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::Ntfs, new FS::ntfs(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::Ocfs2, new FS::ocfs2(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::ReiserFS, new FS::reiserfs(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::Reiser4, new FS::reiser4(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::Udf, new FS::udf(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::Ufs, new FS::ufs(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::Unformatted, new FS::unformatted(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::Unknown, new FS::unknown(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::Xfs, new FS::xfs(-1, -1, -1, QString()));
+ fileSystems.insert(FileSystem::Type::Zfs, new FS::zfs(-1, -1, -1, QString()));
+
+ for (const auto &fs : qAsConst(fileSystems))
+ fs->init();
+
qDeleteAll(m_FileSystems);
m_FileSystems.clear();
-
- m_FileSystems.insert(FileSystem::Type::Apfs, new FS::apfs(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::BitLocker, new FS::bitlocker(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::Btrfs, new FS::btrfs(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::Exfat, new FS::exfat(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::Ext2, new FS::ext2(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::Ext3, new FS::ext3(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::Ext4, new FS::ext4(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::Extended, new FS::extended(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::F2fs, new FS::f2fs(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::Fat12, new FS::fat12(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::Fat16, new FS::fat16(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::Fat32, new FS::fat32(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::Hfs, new FS::hfs(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::HfsPlus, new FS::hfsplus(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::Hpfs, new FS::hpfs(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::Iso9660, new FS::iso9660(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::Jfs, new FS::jfs(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::LinuxRaidMember, new FS::linuxraidmember(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::LinuxSwap, new FS::linuxswap(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::Luks, new FS::luks(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::Luks2, new FS::luks2(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::Lvm2_PV, new FS::lvm2_pv(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::Minix, new FS::minix(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::Nilfs2, new FS::nilfs2(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::Ntfs, new FS::ntfs(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::Ocfs2, new FS::ocfs2(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::ReiserFS, new FS::reiserfs(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::Reiser4, new FS::reiser4(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::Udf, new FS::udf(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::Ufs, new FS::ufs(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::Unformatted, new FS::unformatted(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::Unknown, new FS::unknown(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::Xfs, new FS::xfs(-1, -1, -1, QString()));
- m_FileSystems.insert(FileSystem::Type::Zfs, new FS::zfs(-1, -1, -1, QString()));
-
- for (const auto &fs : FileSystemFactory::map())
- fs->init();
+ m_FileSystems = fileSystems;
CoreBackendManager::self()->backend()->initFSSupport();
}
@@ -114,45 +116,45 @@ void FileSystemFactory::init()
@param label the FileSystem's label
@return pointer to the newly created FileSystem object or nullptr if FileSystem could not be created
*/
-FileSystem* FileSystemFactory::create(FileSystem::Type t, qint64 firstsector, qint64 lastsector, qint64 sectorSize, qint64 sectorsused, const QString& label, const QString& uuid)
+FileSystem* FileSystemFactory::create(FileSystem::Type t, qint64 firstsector, qint64 lastsector, qint64 sectorSize, qint64 sectorsused, const QString& label, const QVariantMap& features, const QString& uuid)
{
FileSystem* fs = nullptr;
switch (t) {
- case FileSystem::Type::Apfs: fs = new FS::apfs (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::BitLocker: fs = new FS::bitlocker (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::Btrfs: fs = new FS::btrfs (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::Exfat: fs = new FS::exfat (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::Ext2: fs = new FS::ext2 (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::Ext3: fs = new FS::ext3 (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::Ext4: fs = new FS::ext4 (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::Extended: fs = new FS::extended (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::F2fs: fs = new FS::f2fs (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::Fat12: fs = new FS::fat12 (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::Fat16: fs = new FS::fat16 (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::Fat32: fs = new FS::fat32 (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::Hfs: fs = new FS::hfs (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::HfsPlus: fs = new FS::hfsplus (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::Hpfs: fs = new FS::hpfs (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::Iso9660: fs = new FS::iso9660 (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::Jfs: fs = new FS::jfs (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::LinuxRaidMember: fs = new FS::linuxraidmember(firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::LinuxSwap: fs = new FS::linuxswap (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::Luks: fs = new FS::luks (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::Luks2: fs = new FS::luks2 (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::Lvm2_PV: fs = new FS::lvm2_pv (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::Minix: fs = new FS::minix (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::Nilfs2: fs = new FS::nilfs2 (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::Ntfs: fs = new FS::ntfs (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::Ocfs2: fs = new FS::ocfs2 (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::ReiserFS: fs = new FS::reiserfs (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::Reiser4: fs = new FS::reiser4 (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::Udf: fs = new FS::udf (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::Ufs: fs = new FS::ufs (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::Unformatted: fs = new FS::unformatted (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::Unknown: fs = new FS::unknown (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::Xfs: fs = new FS::xfs (firstsector, lastsector, sectorsused, label); break;
- case FileSystem::Type::Zfs: fs = new FS::zfs (firstsector, lastsector, sectorsused, label); break;
+ case FileSystem::Type::Apfs: fs = new FS::apfs (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::BitLocker: fs = new FS::bitlocker (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::Btrfs: fs = new FS::btrfs (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::Exfat: fs = new FS::exfat (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::Ext2: fs = new FS::ext2 (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::Ext3: fs = new FS::ext3 (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::Ext4: fs = new FS::ext4 (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::Extended: fs = new FS::extended (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::F2fs: fs = new FS::f2fs (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::Fat12: fs = new FS::fat12 (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::Fat16: fs = new FS::fat16 (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::Fat32: fs = new FS::fat32 (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::Hfs: fs = new FS::hfs (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::HfsPlus: fs = new FS::hfsplus (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::Hpfs: fs = new FS::hpfs (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::Iso9660: fs = new FS::iso9660 (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::Jfs: fs = new FS::jfs (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::LinuxRaidMember: fs = new FS::linuxraidmember(firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::LinuxSwap: fs = new FS::linuxswap (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::Luks: fs = new FS::luks (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::Luks2: fs = new FS::luks2 (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::Lvm2_PV: fs = new FS::lvm2_pv (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::Minix: fs = new FS::minix (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::Nilfs2: fs = new FS::nilfs2 (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::Ntfs: fs = new FS::ntfs (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::Ocfs2: fs = new FS::ocfs2 (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::ReiserFS: fs = new FS::reiserfs (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::Reiser4: fs = new FS::reiser4 (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::Udf: fs = new FS::udf (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::Ufs: fs = new FS::ufs (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::Unformatted: fs = new FS::unformatted (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::Unknown: fs = new FS::unknown (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::Xfs: fs = new FS::xfs (firstsector, lastsector, sectorsused, label, features); break;
+ case FileSystem::Type::Zfs: fs = new FS::zfs (firstsector, lastsector, sectorsused, label, features); break;
default: break;
}
@@ -169,7 +171,7 @@ FileSystem* FileSystemFactory::create(FileSystem::Type t, qint64 firstsector, qi
*/
FileSystem* FileSystemFactory::create(const FileSystem& other)
{
- return create(other.type(), other.firstSector(), other.lastSector(), other.sectorSize(), other.sectorsUsed(), other.label(), other.uuid());
+ return create(other.type(), other.firstSector(), other.lastSector(), other.sectorSize(), other.sectorsUsed(), other.label(), other.features(), other.uuid());
}
/** @return the map of FileSystems */
@@ -185,5 +187,5 @@ const FileSystemFactory::FileSystems& FileSystemFactory::map()
*/
FileSystem* FileSystemFactory::cloneWithNewType(FileSystem::Type newType, const FileSystem& other)
{
- return create(newType, other.firstSector(), other.lastSector(), other.sectorSize(), other.sectorsUsed(), other.label());
+ return create(newType, other.firstSector(), other.lastSector(), other.sectorSize(), other.sectorsUsed(), other.label(), other.features());
}
diff --git a/src/fs/filesystemfactory.h b/src/fs/filesystemfactory.h
index 6679bbc..464c9a6 100644
--- a/src/fs/filesystemfactory.h
+++ b/src/fs/filesystemfactory.h
@@ -41,7 +41,7 @@ private:
public:
static void init();
- static FileSystem* create(FileSystem::Type t, qint64 firstsector, qint64 lastsector, qint64 sectorSize, qint64 sectorsused = -1, const QString& label = QString(), const QString& uuid = QString());
+ static FileSystem* create(FileSystem::Type t, qint64 firstsector, qint64 lastsector, qint64 sectorSize, qint64 sectorsused = -1, const QString& label = QString(), const QVariantMap& features = {}, const QString& uuid = QString());
static FileSystem* create(const FileSystem& other);
static FileSystem* cloneWithNewType(FileSystem::Type newType, const FileSystem& other);
static const FileSystems& map();
diff --git a/src/fs/hfs.cpp b/src/fs/hfs.cpp
index 15677fc..5facd82 100644
--- a/src/fs/hfs.cpp
+++ b/src/fs/hfs.cpp
@@ -34,8 +34,8 @@ FileSystem::CommandSupportType hfs::m_Check = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType hfs::m_Copy = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType hfs::m_Backup = FileSystem::cmdSupportNone;
-hfs::hfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Hfs)
+hfs::hfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::Hfs)
{
}
@@ -67,7 +67,7 @@ bool hfs::supportToolFound() const
FileSystem::SupportTool hfs::supportToolName() const
{
- return SupportTool(QStringLiteral("hfsutils"), QUrl(QStringLiteral("http://www.mars.org/home/rob/proj/hfs/")));
+ return SupportTool(QStringLiteral("hfsutils"), QUrl(QStringLiteral("https://www.mars.org/home/rob/proj/hfs/")));
}
diff --git a/src/fs/hfs.h b/src/fs/hfs.h
index 780dc72..71e9813 100644
--- a/src/fs/hfs.h
+++ b/src/fs/hfs.h
@@ -37,7 +37,7 @@ namespace FS
class LIBKPMCORE_EXPORT hfs : public FileSystem
{
public:
- hfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ hfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
public:
void init() override;
diff --git a/src/fs/hfsplus.cpp b/src/fs/hfsplus.cpp
index 81341ff..aa32f95 100644
--- a/src/fs/hfsplus.cpp
+++ b/src/fs/hfsplus.cpp
@@ -34,8 +34,8 @@ FileSystem::CommandSupportType hfsplus::m_Create = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType hfsplus::m_Copy = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType hfsplus::m_Backup = FileSystem::cmdSupportNone;
-hfsplus::hfsplus(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::HfsPlus)
+hfsplus::hfsplus(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::HfsPlus)
{
}
@@ -68,7 +68,7 @@ bool hfsplus::supportToolFound() const
FileSystem::SupportTool hfsplus::supportToolName() const
{
- return SupportTool(QStringLiteral("diskdev_cmds"), QUrl(QStringLiteral("http://opendarwin.org")));
+ return SupportTool(QStringLiteral("diskdev_cmds"), QUrl(QStringLiteral("https://opensource.apple.com/tarballs/diskdev_cmds/")));
}
qint64 hfsplus::maxCapacity() const
diff --git a/src/fs/hfsplus.h b/src/fs/hfsplus.h
index 8f3e2d4..076810d 100644
--- a/src/fs/hfsplus.h
+++ b/src/fs/hfsplus.h
@@ -37,7 +37,7 @@ namespace FS
class LIBKPMCORE_EXPORT hfsplus : public FileSystem
{
public:
- hfsplus(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ hfsplus(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
public:
void init() override;
diff --git a/src/fs/hpfs.cpp b/src/fs/hpfs.cpp
index 55c41a1..0674c3c 100644
--- a/src/fs/hpfs.cpp
+++ b/src/fs/hpfs.cpp
@@ -36,8 +36,8 @@ FileSystem::CommandSupportType hpfs::m_SetLabel = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType hpfs::m_UpdateUUID = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType hpfs::m_GetUUID = FileSystem::cmdSupportNone;
-hpfs::hpfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Hpfs)
+hpfs::hpfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::Hpfs)
{
}
diff --git a/src/fs/hpfs.h b/src/fs/hpfs.h
index 7bbb9ba..b1b4b55 100644
--- a/src/fs/hpfs.h
+++ b/src/fs/hpfs.h
@@ -37,7 +37,7 @@ namespace FS
class LIBKPMCORE_EXPORT hpfs : public FileSystem
{
public:
- hpfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ hpfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
public:
CommandSupportType supportGetUsed() const override {
diff --git a/src/fs/iso9660.cpp b/src/fs/iso9660.cpp
index d7939a9..91e63e7 100644
--- a/src/fs/iso9660.cpp
+++ b/src/fs/iso9660.cpp
@@ -20,8 +20,8 @@
namespace FS
{
-iso9660::iso9660(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Iso9660)
+iso9660::iso9660(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::Iso9660)
{
}
diff --git a/src/fs/iso9660.h b/src/fs/iso9660.h
index f6b2192..4190019 100644
--- a/src/fs/iso9660.h
+++ b/src/fs/iso9660.h
@@ -35,7 +35,7 @@ namespace FS
class LIBKPMCORE_EXPORT iso9660 : public FileSystem
{
public:
- iso9660(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ iso9660(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
};
diff --git a/src/fs/jfs.cpp b/src/fs/jfs.cpp
index dfb90a0..f488a1e 100644
--- a/src/fs/jfs.cpp
+++ b/src/fs/jfs.cpp
@@ -39,8 +39,8 @@ FileSystem::CommandSupportType jfs::m_Copy = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType jfs::m_Backup = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType jfs::m_SetLabel = FileSystem::cmdSupportNone;
-jfs::jfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Jfs)
+jfs::jfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::Jfs)
{
}
diff --git a/src/fs/jfs.h b/src/fs/jfs.h
index c67ab27..54f1774 100644
--- a/src/fs/jfs.h
+++ b/src/fs/jfs.h
@@ -37,7 +37,7 @@ namespace FS
class LIBKPMCORE_EXPORT jfs : public FileSystem
{
public:
- jfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ jfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
public:
void init() override;
diff --git a/src/fs/linuxraidmember.cpp b/src/fs/linuxraidmember.cpp
index 19b4825..482787e 100644
--- a/src/fs/linuxraidmember.cpp
+++ b/src/fs/linuxraidmember.cpp
@@ -20,8 +20,8 @@
namespace FS
{
-linuxraidmember::linuxraidmember(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::LinuxRaidMember)
+linuxraidmember::linuxraidmember(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::LinuxRaidMember)
{
}
diff --git a/src/fs/linuxraidmember.h b/src/fs/linuxraidmember.h
index aa71cdd..39a0896 100644
--- a/src/fs/linuxraidmember.h
+++ b/src/fs/linuxraidmember.h
@@ -34,7 +34,7 @@ namespace FS
class LIBKPMCORE_EXPORT linuxraidmember : public FileSystem
{
public:
- linuxraidmember(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ linuxraidmember(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
};
}
diff --git a/src/fs/linuxswap.cpp b/src/fs/linuxswap.cpp
index e535d67..56606ba 100644
--- a/src/fs/linuxswap.cpp
+++ b/src/fs/linuxswap.cpp
@@ -39,8 +39,8 @@ FileSystem::CommandSupportType linuxswap::m_SetLabel = FileSystem::cmdSupportNon
FileSystem::CommandSupportType linuxswap::m_GetUUID = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType linuxswap::m_UpdateUUID = FileSystem::cmdSupportNone;
-linuxswap::linuxswap(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::LinuxSwap)
+linuxswap::linuxswap(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::LinuxSwap)
{
}
@@ -73,7 +73,7 @@ bool linuxswap::supportToolFound() const
FileSystem::SupportTool linuxswap::supportToolName() const
{
- return SupportTool(QStringLiteral("util-linux"), QUrl(QStringLiteral("http://www.kernel.org/pub/linux/utils/util-linux-ng/")));
+ return SupportTool(QStringLiteral("util-linux"), QUrl(QStringLiteral("https://github.com/karelzak/util-linux")));
}
int linuxswap::maxLabelLength() const
diff --git a/src/fs/linuxswap.h b/src/fs/linuxswap.h
index d36392b..fbf9d88 100644
--- a/src/fs/linuxswap.h
+++ b/src/fs/linuxswap.h
@@ -37,7 +37,7 @@ namespace FS
class LIBKPMCORE_EXPORT linuxswap : public FileSystem
{
public:
- linuxswap(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ linuxswap(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
public:
void init() override;
diff --git a/src/fs/luks.cpp b/src/fs/luks.cpp
index 6215554..7f71d85 100644
--- a/src/fs/luks.cpp
+++ b/src/fs/luks.cpp
@@ -63,8 +63,9 @@ luks::luks(qint64 firstsector,
qint64 lastsector,
qint64 sectorsused,
const QString& label,
+ const QVariantMap& features,
FileSystem::Type t)
- : FileSystem(firstsector, lastsector, sectorsused, label, t)
+ : FileSystem(firstsector, lastsector, sectorsused, label, features, t)
, m_innerFs(nullptr)
, m_isCryptOpen(false)
, m_cryptsetupFound(m_Create != cmdSupportNone)
@@ -492,18 +493,20 @@ bool luks::resize(Report& report, const QString& deviceNode, qint64 newLength) c
if (mapperName().isEmpty())
return false;
- if ( newLength - length() * sectorSize() > 0 )
+ const qint64 sizeDiff = newLength - length() * sectorSize();
+ const qint64 newPayloadSize = m_PayloadSize + sizeDiff;
+ if ( sizeDiff > 0 ) // grow
{
ExternalCommand cryptResizeCmd(report, QStringLiteral("cryptsetup"), { QStringLiteral("resize"), mapperName() });
report.line() << xi18nc("@info:progress", "Resizing LUKS crypt on partition %1 .", deviceNode);
if (cryptResizeCmd.run(-1) && cryptResizeCmd.exitCode() == 0)
- return m_innerFs->resize(report, mapperName(), m_PayloadSize);
+ return m_innerFs->resize(report, mapperName(), newPayloadSize);
}
- else if (m_innerFs->resize(report, mapperName(), m_PayloadSize))
+ else if (m_innerFs->resize(report, mapperName(), newPayloadSize)) // shrink
{
ExternalCommand cryptResizeCmd(report, QStringLiteral("cryptsetup"),
- { QStringLiteral("--size"), QString::number(m_PayloadSize / 512), // LUKS1 payload length is specified in multiples of 512 bytes
+ { QStringLiteral("--size"), QString::number(newPayloadSize / 512), // LUKS1 payload length is specified in multiples of 512 bytes
QStringLiteral("resize"), mapperName() });
report.line() << xi18nc("@info:progress", "Resizing LUKS crypt on partition %1 .", deviceNode);
if (cryptResizeCmd.run(-1) && cryptResizeCmd.exitCode() == 0)
diff --git a/src/fs/luks.h b/src/fs/luks.h
index 7dddba1..49f31ed 100644
--- a/src/fs/luks.h
+++ b/src/fs/luks.h
@@ -39,7 +39,7 @@ namespace FS
class LIBKPMCORE_EXPORT luks : public FileSystem
{
public:
- luks(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, FileSystem::Type t = FileSystem::Type::Luks);
+ luks(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {}, FileSystem::Type t = FileSystem::Type::Luks);
~luks() override;
enum class KeyLocation {
diff --git a/src/fs/luks2.cpp b/src/fs/luks2.cpp
index dfc9db0..4cd9576 100644
--- a/src/fs/luks2.cpp
+++ b/src/fs/luks2.cpp
@@ -27,8 +27,8 @@
namespace FS
{
-luks2::luks2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label)
- : luks(firstsector, lastsector, sectorsused, label, FileSystem::Type::Luks2)
+luks2::luks2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features)
+ : luks(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::Luks2)
{
}
@@ -89,7 +89,9 @@ bool luks2::resize(Report& report, const QString& deviceNode, qint64 newLength)
if (mapperName().isEmpty())
return false;
- if ( newLength - length() * sectorSize() > 0 )
+ const qint64 sizeDiff = newLength - length() * sectorSize();
+ const qint64 newPayloadSize = m_PayloadSize + sizeDiff;
+ if ( sizeDiff > 0 ) // grow
{
ExternalCommand cryptResizeCmd(report, QStringLiteral("cryptsetup"), { QStringLiteral("resize"), mapperName() });
report.line() << xi18nc("@info:progress", "Resizing LUKS crypt on partition %1 .", deviceNode);
@@ -102,12 +104,12 @@ bool luks2::resize(Report& report, const QString& deviceNode, qint64 newLength)
if (!cryptResizeCmd.start(-1))
return false;
if ( cryptResizeCmd.exitCode() == 0 )
- return m_innerFs->resize(report, mapperName(), m_PayloadSize);
+ return m_innerFs->resize(report, mapperName(), newPayloadSize);
}
- else if (m_innerFs->resize(report, mapperName(), m_PayloadSize))
+ else if (m_innerFs->resize(report, mapperName(), newPayloadSize))
{
ExternalCommand cryptResizeCmd(report, QStringLiteral("cryptsetup"),
- { QStringLiteral("--size"), QString::number(m_PayloadSize / 512), // FIXME, LUKS2 can have different sector sizes
+ { QStringLiteral("--size"), QString::number(newPayloadSize / 512), // FIXME, LUKS2 can have different sector sizes
QStringLiteral("resize"), mapperName() });
report.line() << xi18nc("@info:progress", "Resizing LUKS crypt on partition %1 .", deviceNode);
if (m_KeyLocation == KeyLocation::keyring) {
diff --git a/src/fs/luks2.h b/src/fs/luks2.h
index cb014f8..826b523 100644
--- a/src/fs/luks2.h
+++ b/src/fs/luks2.h
@@ -35,7 +35,7 @@ namespace FS
class LIBKPMCORE_EXPORT luks2 : public luks
{
public:
- luks2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ luks2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
~luks2() override;
bool create(Report& report, const QString& deviceNode) override;
diff --git a/src/fs/lvm2_pv.cpp b/src/fs/lvm2_pv.cpp
index 6a3a4c7..029c4a9 100644
--- a/src/fs/lvm2_pv.cpp
+++ b/src/fs/lvm2_pv.cpp
@@ -42,8 +42,8 @@ FileSystem::CommandSupportType lvm2_pv::m_UpdateUUID = FileSystem::cmdSupportNon
FileSystem::CommandSupportType lvm2_pv::m_GetUUID = FileSystem::cmdSupportNone;
lvm2_pv::lvm2_pv(qint64 firstsector, qint64 lastsector,
- qint64 sectorsused, const QString& label)
- : FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Lvm2_PV)
+ qint64 sectorsused, const QString& label, const QVariantMap& features)
+ : FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::Lvm2_PV)
, m_PESize(0)
, m_TotalPE(0)
, m_AllocatedPE(0)
@@ -94,7 +94,7 @@ bool lvm2_pv::supportToolFound() const
FileSystem::SupportTool lvm2_pv::supportToolName() const
{
- return SupportTool(QStringLiteral("lvm2"), QUrl(QStringLiteral("http://sourceware.org/lvm2/")));
+ return SupportTool(QStringLiteral("lvm2"), QUrl(QStringLiteral("https://sourceware.org/lvm2/")));
}
qint64 lvm2_pv::maxCapacity() const
diff --git a/src/fs/lvm2_pv.h b/src/fs/lvm2_pv.h
index 15bbd92..21eb7cb 100644
--- a/src/fs/lvm2_pv.h
+++ b/src/fs/lvm2_pv.h
@@ -89,7 +89,7 @@ class LIBKPMCORE_EXPORT lvm2_pv : public FileSystem
{
public:
- lvm2_pv(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ lvm2_pv(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
public:
void init() override;
diff --git a/src/fs/minix.cpp b/src/fs/minix.cpp
index cbd4038..feadb67 100644
--- a/src/fs/minix.cpp
+++ b/src/fs/minix.cpp
@@ -33,8 +33,8 @@ FileSystem::CommandSupportType minix::m_Create = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType minix::m_Copy = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType minix::m_Backup = FileSystem::cmdSupportNone;
-minix::minix(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Minix)
+minix::minix(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::Minix)
{
}
diff --git a/src/fs/minix.h b/src/fs/minix.h
index 2d7b6ee..6b78fb2 100644
--- a/src/fs/minix.h
+++ b/src/fs/minix.h
@@ -34,8 +34,8 @@ namespace FS
class LIBKPMCORE_EXPORT minix : public FileSystem
{
public:
- minix(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
-
+ minix(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
+
void init() override;
bool check(Report& report, const QString&deviceNode) const override;
diff --git a/src/fs/nilfs2.cpp b/src/fs/nilfs2.cpp
index 5fd15a1..47c9798 100644
--- a/src/fs/nilfs2.cpp
+++ b/src/fs/nilfs2.cpp
@@ -46,8 +46,8 @@ FileSystem::CommandSupportType nilfs2::m_SetLabel = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType nilfs2::m_UpdateUUID = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType nilfs2::m_GetUUID = FileSystem::cmdSupportNone;
-nilfs2::nilfs2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Nilfs2)
+nilfs2::nilfs2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::Nilfs2)
{
}
@@ -91,7 +91,7 @@ bool nilfs2::supportToolFound() const
FileSystem::SupportTool nilfs2::supportToolName() const
{
- return SupportTool(QStringLiteral("nilfs2-utils"), QUrl(QStringLiteral("http://code.google.com/p/nilfs2/")));
+ return SupportTool(QStringLiteral("nilfs2-utils"), QUrl(QStringLiteral("https://github.com/nilfs-dev/nilfs-utils")));
}
qint64 nilfs2::minCapacity() const
diff --git a/src/fs/nilfs2.h b/src/fs/nilfs2.h
index 9432208..bb6f407 100644
--- a/src/fs/nilfs2.h
+++ b/src/fs/nilfs2.h
@@ -38,7 +38,7 @@ namespace FS
class LIBKPMCORE_EXPORT nilfs2 : public FileSystem
{
public:
- nilfs2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ nilfs2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
public:
void init() override;
diff --git a/src/fs/ntfs.cpp b/src/fs/ntfs.cpp
index 8639383..a954140 100644
--- a/src/fs/ntfs.cpp
+++ b/src/fs/ntfs.cpp
@@ -48,8 +48,8 @@ FileSystem::CommandSupportType ntfs::m_SetLabel = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType ntfs::m_UpdateUUID = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType ntfs::m_GetUUID = FileSystem::cmdSupportNone;
-ntfs::ntfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Ntfs)
+ntfs::ntfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::Ntfs)
{
}
@@ -85,7 +85,7 @@ bool ntfs::supportToolFound() const
FileSystem::SupportTool ntfs::supportToolName() const
{
- return SupportTool(QStringLiteral("ntfs-3g"), QUrl(QStringLiteral("http://www.tuxera.com/community/ntfs-3g-download/")));
+ return SupportTool(QStringLiteral("ntfs-3g"), QUrl(QStringLiteral("https://www.tuxera.com/community/open-source-ntfs-3g/")));
}
qint64 ntfs::minCapacity() const
diff --git a/src/fs/ntfs.h b/src/fs/ntfs.h
index c1d409e..1c02f35 100644
--- a/src/fs/ntfs.h
+++ b/src/fs/ntfs.h
@@ -37,7 +37,7 @@ namespace FS
class LIBKPMCORE_EXPORT ntfs : public FileSystem
{
public:
- ntfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ ntfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
public:
void init() override;
diff --git a/src/fs/ocfs2.cpp b/src/fs/ocfs2.cpp
index af8eaaa..3d5a4ec 100644
--- a/src/fs/ocfs2.cpp
+++ b/src/fs/ocfs2.cpp
@@ -39,8 +39,8 @@ FileSystem::CommandSupportType ocfs2::m_SetLabel = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType ocfs2::m_UpdateUUID = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType ocfs2::m_GetUUID = FileSystem::cmdSupportNone;
-ocfs2::ocfs2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Ocfs2)
+ocfs2::ocfs2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::Ocfs2)
{
}
@@ -84,7 +84,7 @@ bool ocfs2::supportToolFound() const
FileSystem::SupportTool ocfs2::supportToolName() const
{
- return SupportTool(QStringLiteral("ocfs2-tools"), QUrl(QStringLiteral("http://oss.oracle.com/projects/ocfs2-tools/")));
+ return SupportTool(QStringLiteral("ocfs2-tools"), QUrl(QStringLiteral("https://oss.oracle.com/projects/ocfs2-tools/")));
}
qint64 ocfs2::minCapacity() const
diff --git a/src/fs/ocfs2.h b/src/fs/ocfs2.h
index 1a86172..39d881a 100644
--- a/src/fs/ocfs2.h
+++ b/src/fs/ocfs2.h
@@ -37,7 +37,7 @@ namespace FS
class LIBKPMCORE_EXPORT ocfs2 : public FileSystem
{
public:
- ocfs2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ ocfs2(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
public:
void init() override;
diff --git a/src/fs/reiser4.cpp b/src/fs/reiser4.cpp
index 38e1d1e..31b4654 100644
--- a/src/fs/reiser4.cpp
+++ b/src/fs/reiser4.cpp
@@ -34,8 +34,8 @@ FileSystem::CommandSupportType reiser4::m_Check = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType reiser4::m_Copy = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType reiser4::m_Backup = FileSystem::cmdSupportNone;
-reiser4::reiser4(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Reiser4)
+reiser4::reiser4(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::Reiser4)
{
}
@@ -68,13 +68,13 @@ bool reiser4::supportToolFound() const
FileSystem::SupportTool reiser4::supportToolName() const
{
- return SupportTool(QStringLiteral("reiser4progs"), QUrl(QStringLiteral("http://www.kernel.org/pub/linux/utils/fs/reiser4/reiser4progs/")));
+ return SupportTool(QStringLiteral("reiser4progs"), QUrl(QStringLiteral("https://github.com/edward6/reiser4progs")));
}
qint64 reiser4::maxCapacity() const
{
// looks like it's actually unknown. see
- // http://en.wikipedia.org/wiki/Comparison_of_file_systems
+ // https://en.wikipedia.org/wiki/Comparison_of_file_systems
return Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::EiB);
}
diff --git a/src/fs/reiser4.h b/src/fs/reiser4.h
index 34f4a13..7438b69 100644
--- a/src/fs/reiser4.h
+++ b/src/fs/reiser4.h
@@ -37,7 +37,7 @@ namespace FS
class LIBKPMCORE_EXPORT reiser4 : public FileSystem
{
public:
- reiser4(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ reiser4(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
public:
void init() override;
diff --git a/src/fs/reiserfs.cpp b/src/fs/reiserfs.cpp
index 5bfeb06..6032350 100644
--- a/src/fs/reiserfs.cpp
+++ b/src/fs/reiserfs.cpp
@@ -41,8 +41,8 @@ FileSystem::CommandSupportType reiserfs::m_SetLabel = FileSystem::cmdSupportNone
FileSystem::CommandSupportType reiserfs::m_UpdateUUID = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType reiserfs::m_GetUUID = FileSystem::cmdSupportNone;
-reiserfs::reiserfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::ReiserFS)
+reiserfs::reiserfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::ReiserFS)
{
}
@@ -80,7 +80,7 @@ bool reiserfs::supportToolFound() const
FileSystem::SupportTool reiserfs::supportToolName() const
{
- return SupportTool(QStringLiteral("reiserfsprogs"), QUrl(QStringLiteral("http://www.kernel.org/pub/linux/utils/fs/reiserfs/")));
+ return SupportTool(QStringLiteral("reiserfsprogs"), QUrl(QStringLiteral("https://reiser4.wiki.kernel.org/index.php/Reiserfsprogs")));
}
qint64 reiserfs::minCapacity() const
diff --git a/src/fs/reiserfs.h b/src/fs/reiserfs.h
index 598c4d2..505c2eb 100644
--- a/src/fs/reiserfs.h
+++ b/src/fs/reiserfs.h
@@ -39,7 +39,7 @@ namespace FS
class LIBKPMCORE_EXPORT reiserfs : public FileSystem
{
public:
- reiserfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ reiserfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
public:
void init() override;
diff --git a/src/fs/udf.cpp b/src/fs/udf.cpp
index b0d28a9..ae55754 100644
--- a/src/fs/udf.cpp
+++ b/src/fs/udf.cpp
@@ -39,8 +39,8 @@ FileSystem::CommandSupportType udf::m_UpdateUUID = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType udf::m_Create = FileSystem::cmdSupportNone;
bool udf::oldMkudffsVersion = false;
-udf::udf(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Udf)
+udf::udf(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::Udf)
{
}
diff --git a/src/fs/udf.h b/src/fs/udf.h
index f49df36..7599c9d 100644
--- a/src/fs/udf.h
+++ b/src/fs/udf.h
@@ -37,7 +37,7 @@ namespace FS
class LIBKPMCORE_EXPORT udf : public FileSystem
{
public:
- udf(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ udf(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
public:
void init() override;
diff --git a/src/fs/ufs.cpp b/src/fs/ufs.cpp
index 71f5e51..6d40e61 100644
--- a/src/fs/ufs.cpp
+++ b/src/fs/ufs.cpp
@@ -23,8 +23,8 @@ FileSystem::CommandSupportType ufs::m_Move = FileSystem::cmdSupportCore;
FileSystem::CommandSupportType ufs::m_Copy = FileSystem::cmdSupportCore;
FileSystem::CommandSupportType ufs::m_Backup = FileSystem::cmdSupportCore;
-ufs::ufs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Ufs)
+ufs::ufs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::Ufs)
{
}
}
diff --git a/src/fs/ufs.h b/src/fs/ufs.h
index 2c67f92..4c072d7 100644
--- a/src/fs/ufs.h
+++ b/src/fs/ufs.h
@@ -35,7 +35,7 @@ namespace FS
class LIBKPMCORE_EXPORT ufs : public FileSystem
{
public:
- ufs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ ufs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
public:
CommandSupportType supportMove() const override {
diff --git a/src/fs/unformatted.cpp b/src/fs/unformatted.cpp
index e1813de..353f10c 100644
--- a/src/fs/unformatted.cpp
+++ b/src/fs/unformatted.cpp
@@ -21,8 +21,8 @@ namespace FS
{
FileSystem::CommandSupportType unformatted::m_Create = FileSystem::cmdSupportFileSystem;
-unformatted::unformatted(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Unformatted)
+unformatted::unformatted(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::Unformatted)
{
}
diff --git a/src/fs/unformatted.h b/src/fs/unformatted.h
index 8c66407..e05c6c5 100644
--- a/src/fs/unformatted.h
+++ b/src/fs/unformatted.h
@@ -37,7 +37,7 @@ namespace FS
class LIBKPMCORE_EXPORT unformatted : public FileSystem
{
public:
- unformatted(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ unformatted(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
public:
bool create(Report&, const QString&) override;
diff --git a/src/fs/unknown.cpp b/src/fs/unknown.cpp
index 173d596..e5e34ca 100644
--- a/src/fs/unknown.cpp
+++ b/src/fs/unknown.cpp
@@ -22,8 +22,8 @@ namespace FS
FileSystem::CommandSupportType unknown::m_Move = FileSystem::cmdSupportNone;
-unknown::unknown(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Unknown)
+unknown::unknown(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::Unknown)
{
}
diff --git a/src/fs/unknown.h b/src/fs/unknown.h
index cf87ca4..88cada4 100644
--- a/src/fs/unknown.h
+++ b/src/fs/unknown.h
@@ -32,7 +32,7 @@ namespace FS
class LIBKPMCORE_EXPORT unknown : public FileSystem
{
public:
- unknown(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ unknown(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
public:
bool supportToolFound() const override {
diff --git a/src/fs/xfs.cpp b/src/fs/xfs.cpp
index 25d2ef3..7a8cea5 100644
--- a/src/fs/xfs.cpp
+++ b/src/fs/xfs.cpp
@@ -41,8 +41,8 @@ FileSystem::CommandSupportType xfs::m_Copy = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType xfs::m_Backup = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType xfs::m_SetLabel = FileSystem::cmdSupportNone;
-xfs::xfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Xfs)
+xfs::xfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::Xfs)
{
}
@@ -78,7 +78,7 @@ bool xfs::supportToolFound() const
FileSystem::SupportTool xfs::supportToolName() const
{
- return SupportTool(QStringLiteral("xfsprogs"), QUrl(QStringLiteral("http://oss.sgi.com/projects/xfs/")));
+ return SupportTool(QStringLiteral("xfsprogs"), QUrl(QStringLiteral("https://xfs.org/index.php/Getting_the_latest_source_code")));
}
qint64 xfs::minCapacity() const
@@ -153,7 +153,7 @@ bool xfs::copy(Report& report, const QString& targetDeviceNode, const QString& s
// xfs_copy behaves a little strangely. It apparently kills itself at the end of main, causing QProcess
// to report that it crashed.
- // See http://oss.sgi.com/archives/xfs/2004-11/msg00169.html
+ // See https://marc.info/?l=linux-xfs&m=110178337825926&w=2
// So we cannot rely on QProcess::exitStatus() and thus not on ExternalCommand::run() returning true.
cmd.run(-1);
diff --git a/src/fs/xfs.h b/src/fs/xfs.h
index 3199c93..1e80d4b 100644
--- a/src/fs/xfs.h
+++ b/src/fs/xfs.h
@@ -37,7 +37,7 @@ namespace FS
class LIBKPMCORE_EXPORT xfs : public FileSystem
{
public:
- xfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ xfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
public:
void init() override;
diff --git a/src/fs/zfs.cpp b/src/fs/zfs.cpp
index a3cb201..d442ed7 100644
--- a/src/fs/zfs.cpp
+++ b/src/fs/zfs.cpp
@@ -39,8 +39,8 @@ FileSystem::CommandSupportType zfs::m_SetLabel = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType zfs::m_UpdateUUID = FileSystem::cmdSupportNone;
FileSystem::CommandSupportType zfs::m_GetUUID = FileSystem::cmdSupportNone;
-zfs::zfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label) :
- FileSystem(firstsector, lastsector, sectorsused, label, FileSystem::Type::Zfs)
+zfs::zfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features) :
+ FileSystem(firstsector, lastsector, sectorsused, label, features, FileSystem::Type::Zfs)
{
}
@@ -72,7 +72,7 @@ bool zfs::supportToolFound() const
FileSystem::SupportTool zfs::supportToolName() const
{
- return SupportTool(QStringLiteral("zfs"), QUrl(QStringLiteral("http://zfsonlinux.org/")));
+ return SupportTool(QStringLiteral("zfs"), QUrl(QStringLiteral("https://zfsonlinux.org/")));
}
qint64 zfs::minCapacity() const
diff --git a/src/fs/zfs.h b/src/fs/zfs.h
index c87f971..b727e25 100644
--- a/src/fs/zfs.h
+++ b/src/fs/zfs.h
@@ -38,7 +38,7 @@ namespace FS
class LIBKPMCORE_EXPORT zfs : public FileSystem
{
public:
- zfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label);
+ zfs(qint64 firstsector, qint64 lastsector, qint64 sectorsused, const QString& label, const QVariantMap& features = {});
public:
void init() override;
diff --git a/src/gui/partresizerwidget.cpp b/src/gui/partresizerwidget.cpp
index 662b0b5..2f17d2f 100644
--- a/src/gui/partresizerwidget.cpp
+++ b/src/gui/partresizerwidget.cpp
@@ -278,8 +278,8 @@ bool PartResizerWidget::movePartition(qint64 newFirstSector)
updatePositions();
- emit firstSectorChanged(partition().firstSector());
- emit lastSectorChanged(partition().lastSector());
+ Q_EMIT firstSectorChanged(partition().firstSector());
+ Q_EMIT lastSectorChanged(partition().lastSector());
return true;
}
@@ -335,7 +335,7 @@ bool PartResizerWidget::updateFirstSector(qint64 newFirstSector)
updatePositions();
- emit firstSectorChanged(partition().firstSector());
+ Q_EMIT firstSectorChanged(partition().firstSector());
return true;
}
@@ -416,7 +416,7 @@ bool PartResizerWidget::updateLastSector(qint64 newLastSector)
resizeLogicals(0, deltaLast);
updatePositions();
- emit lastSectorChanged(partition().lastSector());
+ Q_EMIT lastSectorChanged(partition().lastSector());
return true;
}
diff --git a/src/gui/partresizerwidget.h b/src/gui/partresizerwidget.h
index dbbd57d..41d8e4a 100644
--- a/src/gui/partresizerwidget.h
+++ b/src/gui/partresizerwidget.h
@@ -45,7 +45,7 @@ class LIBKPMCORE_EXPORT PartResizerWidget : public QWidget
Q_DISABLE_COPY(PartResizerWidget)
public:
- PartResizerWidget(QWidget* parent);
+ explicit PartResizerWidget(QWidget* parent);
public:
void init(Device& d, Partition& p, qint64 minFirst, qint64 maxLast, bool read_only = false, bool move_allowed = true);
diff --git a/src/gui/partwidget.cpp b/src/gui/partwidget.cpp
index 57ebf23..59dd7d4 100644
--- a/src/gui/partwidget.cpp
+++ b/src/gui/partwidget.cpp
@@ -93,21 +93,22 @@ void PartWidget::paintEvent(QPaintEvent*)
if (partition() == nullptr)
return;
- const int usedPercentage = static_cast(partition()->used() * 100 / partition()->capacity());
+ auto partitionCapacity = partition()->capacity();
+ if (partitionCapacity <= 0)
+ return;
+
+ const int usedPercentage = static_cast(partition()->used() * 100 / partitionCapacity);
const int w = width() * usedPercentage / 100;
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing);
+ const QColor base = activeColor(m_fileSystemColorCode[ static_cast(partition()->fileSystem().type()) ]);
if (partition()->roles().has(PartitionRole::Extended)) {
- drawGradient(&painter, activeColor(
- m_fileSystemColorCode[ static_cast(partition()->fileSystem().type()) ]),
- QRect(0, 0, width(), height()));
+ drawGradient(&painter, base, QRect(0, 0, width(), height()));
return;
}
- const QColor base = activeColor(m_fileSystemColorCode[ static_cast(partition()->fileSystem().type()) ]);
-
if (!partition()->roles().has(PartitionRole::Unallocated)) {
const QColor dark = base.darker(105);
const QColor light = base.lighter(120);
@@ -124,11 +125,11 @@ void PartWidget::paintEvent(QPaintEvent*)
QString text = partition()->deviceNode().remove(QStringLiteral("/dev/")) + QStringLiteral("\n") + QString(Capacity::formatByteSize(partition()->capacity()));
const QRect textRect(0, 0, width() - 1, height() - 1);
- const QRect boundingRect = painter.boundingRect(textRect, Qt::AlignVCenter | Qt::AlignHCenter, text);
+ const QRect boundingRect = painter.boundingRect(textRect, Qt::AlignCenter, text);
if (boundingRect.x() > PartWidgetBase::borderWidth() && boundingRect.y() > PartWidgetBase::borderHeight()) {
if (isActive())
- painter.setPen(QColor(255, 255, 255));
- painter.drawText(textRect, Qt::AlignVCenter | Qt::AlignHCenter, text);
+ painter.setPen(Qt::white);
+ painter.drawText(textRect, Qt::AlignCenter, text);
}
}
diff --git a/src/jobs/CMakeLists.txt b/src/jobs/CMakeLists.txt
index f055853..84571ce 100644
--- a/src/jobs/CMakeLists.txt
+++ b/src/jobs/CMakeLists.txt
@@ -6,6 +6,9 @@ set(JOBS_SRC
jobs/shredfilesystemjob.cpp
jobs/createpartitionjob.cpp
jobs/createpartitiontablejob.cpp
+ jobs/setpartitionlabeljob.cpp
+ jobs/setpartitionuuidjob.cpp
+ jobs/setpartitionattributesjob.cpp
jobs/createvolumegroupjob.cpp
jobs/removevolumegroupjob.cpp
jobs/deactivatevolumegroupjob.cpp
diff --git a/src/jobs/checkfilesystemjob.h b/src/jobs/checkfilesystemjob.h
index 815d88d..e79e7f7 100644
--- a/src/jobs/checkfilesystemjob.h
+++ b/src/jobs/checkfilesystemjob.h
@@ -32,7 +32,7 @@ class QString;
class CheckFileSystemJob : public Job
{
public:
- CheckFileSystemJob(Partition& p);
+ explicit CheckFileSystemJob(Partition& p);
public:
bool run(Report& parent) override;
diff --git a/src/jobs/createfilesystemjob.cpp b/src/jobs/createfilesystemjob.cpp
index 6a285d2..2ce2eee 100644
--- a/src/jobs/createfilesystemjob.cpp
+++ b/src/jobs/createfilesystemjob.cpp
@@ -54,10 +54,11 @@ bool CreateFileSystemJob::run(Report& parent)
bool createResult;
if (partition().fileSystem().supportCreate() == FileSystem::cmdSupportFileSystem) {
- if (partition().fileSystem().supportCreateWithLabel() == FileSystem::cmdSupportFileSystem)
+ if (partition().fileSystem().supportCreateWithLabel() == FileSystem::cmdSupportFileSystem) {
createResult = partition().fileSystem().createWithLabel(*report, partition().deviceNode(), m_Label);
- else
+ } else {
createResult = partition().fileSystem().create(*report, partition().deviceNode());
+ }
if (createResult) {
if (device().type() == Device::Type::Disk_Device || device().type() == Device::Type::SoftwareRAID_Device) {
std::unique_ptr backendDevice = CoreBackendManager::self()->backend()->openDevice(device());
diff --git a/src/jobs/createpartitionjob.cpp b/src/jobs/createpartitionjob.cpp
index e6fb374..96b1eb3 100644
--- a/src/jobs/createpartitionjob.cpp
+++ b/src/jobs/createpartitionjob.cpp
@@ -59,11 +59,15 @@ bool CreatePartitionJob::run(Report& parent)
if (backendPartitionTable) {
QString partitionPath = backendPartitionTable->createPartition(*report, partition());
- if (partitionPath != QString()) {
+ if (!partitionPath.isEmpty()) {
rval = true;
partition().setPartitionPath(partitionPath);
partition().setState(Partition::State::None);
backendPartitionTable->commit();
+ // The UUID is supported by GPT only; it is generated automatically once the creation of a partition.
+ // Store the generated UUID to the partition object if no UUID is set.
+ if (m_Device.partitionTable()->type() == PartitionTable::gpt && partition().uuid().isEmpty())
+ partition().setUUID(backendPartitionTable->getPartitionUUID(*report, partition()));
} else
report->line() << xi18nc("@info/plain", "Failed to add partition %1 to device %2 .", partition().deviceNode(), device().deviceNode());
} else
diff --git a/src/jobs/createpartitiontablejob.h b/src/jobs/createpartitiontablejob.h
index 0888b1a..de34ee5 100644
--- a/src/jobs/createpartitiontablejob.h
+++ b/src/jobs/createpartitiontablejob.h
@@ -32,7 +32,7 @@ class QString;
class CreatePartitionTableJob : public Job
{
public:
- CreatePartitionTableJob(Device& d);
+ explicit CreatePartitionTableJob(Device& d);
public:
bool run(Report& parent) override;
diff --git a/src/jobs/deactivatelogicalvolumejob.h b/src/jobs/deactivatelogicalvolumejob.h
index 8437977..e5d8da6 100644
--- a/src/jobs/deactivatelogicalvolumejob.h
+++ b/src/jobs/deactivatelogicalvolumejob.h
@@ -30,7 +30,7 @@ class QString;
class DeactivateLogicalVolumeJob : public Job
{
public:
- DeactivateLogicalVolumeJob(const VolumeManagerDevice& dev, const QStringList lvPaths = {});
+ explicit DeactivateLogicalVolumeJob(const VolumeManagerDevice& dev, const QStringList lvPaths = {});
public:
bool run(Report& parent) override;
diff --git a/src/jobs/deactivatevolumegroupjob.h b/src/jobs/deactivatevolumegroupjob.h
index a7886b9..308df1b 100644
--- a/src/jobs/deactivatevolumegroupjob.h
+++ b/src/jobs/deactivatevolumegroupjob.h
@@ -30,7 +30,7 @@ class QString;
class DeactivateVolumeGroupJob : public Job
{
public:
- DeactivateVolumeGroupJob(VolumeManagerDevice& dev);
+ explicit DeactivateVolumeGroupJob(VolumeManagerDevice& dev);
public:
bool run(Report& parent) override;
diff --git a/src/jobs/job.cpp b/src/jobs/job.cpp
index c6708be..fc2d3a8 100644
--- a/src/jobs/job.cpp
+++ b/src/jobs/job.cpp
@@ -100,7 +100,7 @@ bool Job::rollbackCopyBlocks(Report& report, CopyTarget& origTarget, CopySource&
void Job::emitProgress(int i)
{
- emit progress(i);
+ Q_EMIT progress(i);
}
void Job::updateReport(const QVariantMap& reportString)
@@ -110,7 +110,7 @@ void Job::updateReport(const QVariantMap& reportString)
Report* Job::jobStarted(Report& parent)
{
- emit started();
+ Q_EMIT started();
return parent.newChild(xi18nc("@info:progress", "Job: %1", description()));
}
@@ -118,8 +118,8 @@ Report* Job::jobStarted(Report& parent)
void Job::jobFinished(Report& report, bool b)
{
setStatus(b ? Status::Success : Status::Error);
- emit progress(numSteps());
- emit finished();
+ Q_EMIT progress(numSteps());
+ Q_EMIT finished();
report.setStatus(xi18nc("@info:progress job status (error, warning, ...)", "%1: %2", description(), statusText()));
}
diff --git a/src/jobs/setpartflagsjob.cpp b/src/jobs/setpartflagsjob.cpp
index fceb583..47075d6 100644
--- a/src/jobs/setpartflagsjob.cpp
+++ b/src/jobs/setpartflagsjob.cpp
@@ -65,7 +65,7 @@ bool SetPartFlagsJob::run(Report& parent)
int count = 0;
for (const auto &f : PartitionTable::flagList()) {
- emit progress(++count);
+ Q_EMIT progress(++count);
const bool oldState = (partition().activeFlags() & f) ? true : false;
const bool state = (flags() & f) ? true : false;
diff --git a/src/jobs/setpartitionattributesjob.cpp b/src/jobs/setpartitionattributesjob.cpp
new file mode 100644
index 0000000..b37c176
--- /dev/null
+++ b/src/jobs/setpartitionattributesjob.cpp
@@ -0,0 +1,86 @@
+/*************************************************************************
+ * Copyright (C) 2020 by Gaël PORTAY *
+ * *
+ * 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 .*
+ *************************************************************************/
+
+#include "jobs/setpartitionattributesjob.h"
+
+#include "backend/corebackend.h"
+#include "backend/corebackendmanager.h"
+#include "backend/corebackenddevice.h"
+#include "backend/corebackendpartitiontable.h"
+
+#include "core/partition.h"
+#include "core/device.h"
+
+#include "util/report.h"
+
+#include
+#include
+
+/** Creates a new SetPartitionAttributesJob (GPT only)
+ @param d the Device the Partition to be created will be on
+ @param p the Partition whose attributes is to be set is on
+ @param newAttrs the new attributes
+*/
+SetPartitionAttributesJob::SetPartitionAttributesJob(Device& d, Partition& p, quint64 newAttrs) :
+ Job(),
+ m_Device(d),
+ m_Partition(p),
+ m_Attributes(newAttrs)
+{
+}
+
+bool SetPartitionAttributesJob::run(Report& parent)
+{
+ Q_ASSERT(partition().devicePath() == device().deviceNode());
+
+ bool rval = true;
+
+ Report* report = jobStarted(parent);
+
+ // The attributes are supported by GPT only, if the partition table is not GPT, just ignore the
+ // request and say all is well. This helps in operations because we don't have to check for
+ // support to avoid having a failed job.
+ if (m_Device.partitionTable()->type() != PartitionTable::gpt)
+ report->line() << xi18nc("@info:progress", "Partition table of partition %1 does not support setting attributes. Job ignored.", partition().deviceNode());
+ else {
+ std::unique_ptr backendDevice = CoreBackendManager::self()->backend()->openDevice(m_Device);
+ if (backendDevice) {
+ std::unique_ptr backendPartitionTable = backendDevice->openPartitionTable();
+
+ if (backendPartitionTable) {
+ if (backendPartitionTable->setPartitionAttributes(*report, partition(), m_Attributes)) {
+ rval = true;
+ partition().setAttributes(m_Attributes);
+ backendPartitionTable->commit();
+ } else
+ report->line() << xi18nc("@info:progress", "Failed to set the attributes for the partition %1 .", partition().deviceNode());
+ } else
+ report->line() << xi18nc("@info:progress", "Could not open partition table on device %1 to set the attributes for the partition %2 .", device().deviceNode(), partition().deviceNode());
+ } else
+ report->line() << xi18nc("@info:progress", "Could not open device %1 to set the attributes for partition %2 .", device().deviceNode(), partition().deviceNode());
+
+ }
+
+ jobFinished(*report, rval);
+
+ return rval;
+}
+
+QString SetPartitionAttributesJob::description() const
+{
+ return xi18nc("@info:progress", "Set the attributes on partition %1 to \"%2\"", partition().deviceNode(), QString::number(attributes(), 0x10));
+}
diff --git a/src/jobs/setpartitionattributesjob.h b/src/jobs/setpartitionattributesjob.h
new file mode 100644
index 0000000..6ad7607
--- /dev/null
+++ b/src/jobs/setpartitionattributesjob.h
@@ -0,0 +1,68 @@
+/*************************************************************************
+ * Copyright (C) 2020 by Gaël PORTAY *
+ * *
+ * 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 .*
+ *************************************************************************/
+
+#if !defined(KPMCORE_SETPARTITIONATTRIBUTESJOB_H)
+
+#define KPMCORE_SETPARTITIONATTRIBUTESJOB_H
+
+#include "jobs/job.h"
+
+class Partition;
+class Device;
+class Report;
+
+/** Set a Partition attributes (GPT only).
+ @author Gaël PORTAY
+*/
+class SetPartitionAttributesJob : public Job
+{
+public:
+ SetPartitionAttributesJob(Device& d, Partition& p, quint64 newAttrs);
+
+public:
+ bool run(Report& parent) override;
+ QString description() const override;
+
+protected:
+ Partition& partition() {
+ return m_Partition;
+ }
+ const Partition& partition() const {
+ return m_Partition;
+ }
+
+ Device& device() {
+ return m_Device;
+ }
+ const Device& device() const {
+ return m_Device;
+ }
+
+ quint64 attributes() const {
+ return m_Attributes;
+ }
+ void setAttributes(quint64 f) {
+ m_Attributes = f;
+ }
+
+private:
+ Device& m_Device;
+ Partition& m_Partition;
+ quint64 m_Attributes;
+};
+
+#endif
diff --git a/src/jobs/setpartitionlabeljob.cpp b/src/jobs/setpartitionlabeljob.cpp
new file mode 100644
index 0000000..03539c6
--- /dev/null
+++ b/src/jobs/setpartitionlabeljob.cpp
@@ -0,0 +1,86 @@
+/*************************************************************************
+ * Copyright (C) 2020 by Gaël PORTAY *
+ * *
+ * 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 .*
+ *************************************************************************/
+
+#include "jobs/setpartitionlabeljob.h"
+
+#include "backend/corebackend.h"
+#include "backend/corebackendmanager.h"
+#include "backend/corebackenddevice.h"
+#include "backend/corebackendpartitiontable.h"
+
+#include "core/partition.h"
+#include "core/device.h"
+
+#include "util/report.h"
+
+#include
+#include
+
+/** Creates a new SetPartitionLabelJob (GPT only)
+ @param d the Device the Partition to be created will be on
+ @param p the Partition whose label is to be set is on
+ @param newLabel the new label
+*/
+SetPartitionLabelJob::SetPartitionLabelJob(Device& d, Partition& p, const QString& newLabel) :
+ Job(),
+ m_Device(d),
+ m_Partition(p),
+ m_Label(newLabel)
+{
+}
+
+bool SetPartitionLabelJob::run(Report& parent)
+{
+ Q_ASSERT(partition().devicePath() == device().deviceNode());
+
+ bool rval = true;
+
+ Report* report = jobStarted(parent);
+
+ // The label is supported by GPT only (as partition name), if the partition table is not GPT,
+ // just ignore the request and say all is well. This helps in operations because
+ // we don't have to check for support to avoid having a failed job.
+ if (m_Device.partitionTable()->type() != PartitionTable::gpt)
+ report->line() << xi18nc("@info:progress", "Partition table of partition %1 does not support setting names. Job ignored.", partition().deviceNode());
+ else {
+ std::unique_ptr backendDevice = CoreBackendManager::self()->backend()->openDevice(m_Device);
+ if (backendDevice) {
+ std::unique_ptr backendPartitionTable = backendDevice->openPartitionTable();
+
+ if (backendPartitionTable) {
+ if (backendPartitionTable->setPartitionLabel(*report, partition(), m_Label)) {
+ rval = true;
+ partition().setLabel(m_Label);
+ backendPartitionTable->commit();
+ } else
+ report->line() << xi18nc("@info:progress", "Failed to set the name for the partition %1 .", partition().deviceNode());
+ } else
+ report->line() << xi18nc("@info:progress", "Could not open partition table on device %1 to set the name for the partition %2 .", device().deviceNode(), partition().deviceNode());
+ } else
+ report->line() << xi18nc("@info:progress", "Could not open device %1 to set the name for partition %2 .", device().deviceNode(), partition().deviceNode());
+
+ }
+
+ jobFinished(*report, rval);
+
+ return rval;
+}
+
+QString SetPartitionLabelJob::description() const
+{
+ return xi18nc("@info:progress", "Set the label on partition %1 to \"%2\"", partition().deviceNode(), label());
+}
diff --git a/src/jobs/setpartitionlabeljob.h b/src/jobs/setpartitionlabeljob.h
new file mode 100644
index 0000000..7c146da
--- /dev/null
+++ b/src/jobs/setpartitionlabeljob.h
@@ -0,0 +1,70 @@
+/*************************************************************************
+ * Copyright (C) 2020 by Gaël PORTAY *
+ * *
+ * 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 .*
+ *************************************************************************/
+
+#if !defined(KPMCORE_SETPARTITIONNAMEJOB_H)
+
+#define KPMCORE_SETPARTITIONNAMEJOB_H
+
+#include "jobs/job.h"
+
+class Partition;
+class Device;
+class Report;
+
+class QString;
+
+/** Set a Partition label (GPT only).
+ @author Gaël PORTAY
+*/
+class SetPartitionLabelJob : public Job
+{
+public:
+ SetPartitionLabelJob(Device& d, Partition& p, const QString& newLabel);
+
+public:
+ bool run(Report& parent) override;
+ QString description() const override;
+
+protected:
+ Partition& partition() {
+ return m_Partition;
+ }
+ const Partition& partition() const {
+ return m_Partition;
+ }
+
+ Device& device() {
+ return m_Device;
+ }
+ const Device& device() const {
+ return m_Device;
+ }
+
+ const QString& label() const {
+ return m_Label;
+ }
+ void setLabel(const QString& l) {
+ m_Label = l;
+ }
+
+private:
+ Device& m_Device;
+ Partition& m_Partition;
+ QString m_Label;
+};
+
+#endif
diff --git a/src/jobs/setpartitionuuidjob.cpp b/src/jobs/setpartitionuuidjob.cpp
new file mode 100644
index 0000000..11c5ee6
--- /dev/null
+++ b/src/jobs/setpartitionuuidjob.cpp
@@ -0,0 +1,86 @@
+/*************************************************************************
+ * Copyright (C) 2020 by Gaël PORTAY *
+ * *
+ * 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 .*
+ *************************************************************************/
+
+#include "jobs/setpartitionuuidjob.h"
+
+#include "backend/corebackend.h"
+#include "backend/corebackendmanager.h"
+#include "backend/corebackenddevice.h"
+#include "backend/corebackendpartitiontable.h"
+
+#include "core/partition.h"
+#include "core/device.h"
+
+#include "util/report.h"
+
+#include
+#include
+
+/** Creates a new SetPartitionUUIDJob (GPT only)
+ @param d the Device the Partition to be created will be on
+ @param p the Partition whose UUID is to be set is on
+ @param newUUID the new UUID
+*/
+SetPartitionUUIDJob::SetPartitionUUIDJob(Device& d, Partition& p, const QString& newUUID) :
+ Job(),
+ m_Device(d),
+ m_Partition(p),
+ m_UUID(newUUID)
+{
+}
+
+bool SetPartitionUUIDJob::run(Report& parent)
+{
+ Q_ASSERT(partition().devicePath() == device().deviceNode());
+
+ bool rval = true;
+
+ Report* report = jobStarted(parent);
+
+ // The UUID is supported by GPT only, if the partition table is not GPT, just ignore the
+ // request and say all is well. This helps in operations because we don't have to check for
+ // support to avoid having a failed job.
+ if (m_Device.partitionTable()->type() != PartitionTable::gpt)
+ report->line() << xi18nc("@info:progress", "Partition table of partition %1 does not support setting UUIDs. Job ignored.", partition().deviceNode());
+ else {
+ std::unique_ptr backendDevice = CoreBackendManager::self()->backend()->openDevice(m_Device);
+ if (backendDevice) {
+ std::unique_ptr backendPartitionTable = backendDevice->openPartitionTable();
+
+ if (backendPartitionTable) {
+ if (backendPartitionTable->setPartitionUUID(*report, partition(), m_UUID)) {
+ rval = true;
+ partition().setUUID(m_UUID);
+ backendPartitionTable->commit();
+ } else
+ report->line() << xi18nc("@info:progress", "Failed to set the UUID for the partition %1 .", partition().deviceNode());
+ } else
+ report->line() << xi18nc("@info:progress", "Could not open partition table on device %1 to set the UUID for the partition %2 .", device().deviceNode(), partition().deviceNode());
+ } else
+ report->line() << xi18nc("@info:progress", "Could not open device %1 to set the UUID for partition %2 .", device().deviceNode(), partition().deviceNode());
+
+ }
+
+ jobFinished(*report, rval);
+
+ return rval;
+}
+
+QString SetPartitionUUIDJob::description() const
+{
+ return xi18nc("@info:progress", "Set the UUID on partition %1 to \"%2\"", partition().deviceNode(), uuid());
+}
diff --git a/src/jobs/setpartitionuuidjob.h b/src/jobs/setpartitionuuidjob.h
new file mode 100644
index 0000000..d0e8ba1
--- /dev/null
+++ b/src/jobs/setpartitionuuidjob.h
@@ -0,0 +1,70 @@
+/*************************************************************************
+ * Copyright (C) 2020 by Gaël PORTAY *
+ * *
+ * 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 .*
+ *************************************************************************/
+
+#if !defined(KPMCORE_SETPARTITIONUUIDJOB_H)
+
+#define KPMCORE_SETPARTITIONUUIDJOB_H
+
+#include "jobs/job.h"
+
+class Partition;
+class Device;
+class Report;
+
+class QString;
+
+/** Set a Partition UUID (GPT only).
+ @author Gaël PORTAY
+*/
+class SetPartitionUUIDJob : public Job
+{
+public:
+ SetPartitionUUIDJob(Device& d, Partition& p, const QString& newUUID);
+
+public:
+ bool run(Report& parent) override;
+ QString description() const override;
+
+protected:
+ Partition& partition() {
+ return m_Partition;
+ }
+ const Partition& partition() const {
+ return m_Partition;
+ }
+
+ Device& device() {
+ return m_Device;
+ }
+ const Device& device() const {
+ return m_Device;
+ }
+
+ const QString& uuid() const {
+ return m_UUID;
+ }
+ void setUUID(const QString& u) {
+ m_UUID = u;
+ }
+
+private:
+ Device& m_Device;
+ Partition& m_Partition;
+ QString m_UUID;
+};
+
+#endif
diff --git a/src/ops/deactivatevolumegroupoperation.h b/src/ops/deactivatevolumegroupoperation.h
index e0b2b00..bb4d722 100644
--- a/src/ops/deactivatevolumegroupoperation.h
+++ b/src/ops/deactivatevolumegroupoperation.h
@@ -39,7 +39,7 @@ class LIBKPMCORE_EXPORT DeactivateVolumeGroupOperation : public Operation
friend class OperationStack;
public:
- DeactivateVolumeGroupOperation(VolumeManagerDevice& d);
+ explicit DeactivateVolumeGroupOperation(VolumeManagerDevice& d);
public:
QString iconName() const override {
diff --git a/src/ops/newoperation.cpp b/src/ops/newoperation.cpp
index 40bdc62..8e4f454 100644
--- a/src/ops/newoperation.cpp
+++ b/src/ops/newoperation.cpp
@@ -24,6 +24,9 @@
#include "jobs/createpartitionjob.h"
#include "jobs/createfilesystemjob.h"
+#include "jobs/setpartitionlabeljob.h"
+#include "jobs/setpartitionuuidjob.h"
+#include "jobs/setpartitionattributesjob.h"
#include "jobs/setfilesystemlabeljob.h"
#include "jobs/setpartflagsjob.h"
#include "jobs/checkfilesystemjob.h"
@@ -46,6 +49,9 @@ NewOperation::NewOperation(Device& d, Partition* p) :
m_TargetDevice(d),
m_NewPartition(p),
m_CreatePartitionJob(new CreatePartitionJob(targetDevice(), newPartition())),
+ m_SetPartitionLabelJob(nullptr),
+ m_SetPartitionUUIDJob(nullptr),
+ m_SetPartitionAttributesJob(nullptr),
m_CreateFileSystemJob(nullptr),
m_SetPartFlagsJob(nullptr),
m_SetFileSystemLabelJob(nullptr),
@@ -53,6 +59,21 @@ NewOperation::NewOperation(Device& d, Partition* p) :
{
addJob(createPartitionJob());
+ if (!p->label().isEmpty()) {
+ m_SetPartitionLabelJob = new SetPartitionLabelJob(targetDevice(), newPartition(), p->label());
+ addJob(setPartitionLabelJob());
+ }
+
+ if (!p->uuid().isEmpty()) {
+ m_SetPartitionUUIDJob = new SetPartitionUUIDJob(targetDevice(), newPartition(), p->uuid());
+ addJob(setPartitionUUIDJob());
+ }
+
+ if (p->attributes()) {
+ m_SetPartitionAttributesJob = new SetPartitionAttributesJob(targetDevice(), newPartition(), p->attributes());
+ addJob(setPartitionAttributesJob());
+ }
+
const FileSystem& fs = newPartition().fileSystem();
if (fs.type() != FileSystem::Type::Extended) {
diff --git a/src/ops/newoperation.h b/src/ops/newoperation.h
index 36e9d2b..e596535 100644
--- a/src/ops/newoperation.h
+++ b/src/ops/newoperation.h
@@ -30,6 +30,9 @@ class Device;
class OperationStack;
class CreatePartitionJob;
+class SetPartitionLabelJob;
+class SetPartitionUUIDJob;
+class SetPartitionAttributesJob;
class CreateFileSystemJob;
class SetFileSystemLabelJob;
class SetPartFlagsJob;
@@ -83,6 +86,15 @@ protected:
CreatePartitionJob* createPartitionJob() {
return m_CreatePartitionJob;
}
+ SetPartitionLabelJob* setPartitionLabelJob() {
+ return m_SetPartitionLabelJob;
+ }
+ SetPartitionUUIDJob* setPartitionUUIDJob() {
+ return m_SetPartitionUUIDJob;
+ }
+ SetPartitionAttributesJob* setPartitionAttributesJob() {
+ return m_SetPartitionAttributesJob;
+ }
CreateFileSystemJob* createFileSystemJob() {
return m_CreateFileSystemJob;
}
@@ -100,6 +112,9 @@ private:
Device& m_TargetDevice;
Partition* m_NewPartition;
CreatePartitionJob* m_CreatePartitionJob;
+ SetPartitionLabelJob* m_SetPartitionLabelJob;
+ SetPartitionUUIDJob* m_SetPartitionUUIDJob;
+ SetPartitionAttributesJob* m_SetPartitionAttributesJob;
CreateFileSystemJob* m_CreateFileSystemJob;
SetPartFlagsJob* m_SetPartFlagsJob;
SetFileSystemLabelJob* m_SetFileSystemLabelJob;
diff --git a/src/ops/operation.cpp b/src/ops/operation.cpp
index 485b58b..eb73161 100644
--- a/src/ops/operation.cpp
+++ b/src/ops/operation.cpp
@@ -141,7 +141,7 @@ void Operation::onJobStarted()
Job* job = qobject_cast(sender());
if (job)
- emit jobStarted(job, this);
+ Q_EMIT jobStarted(job, this);
}
void Operation::onJobFinished()
@@ -150,7 +150,7 @@ void Operation::onJobFinished()
if (job) {
setProgressBase(progressBase() + job->numSteps());
- emit jobFinished(job, this);
+ Q_EMIT jobFinished(job, this);
}
}
diff --git a/src/ops/removevolumegroupoperation.h b/src/ops/removevolumegroupoperation.h
index c20fb5d..cd1cc7d 100644
--- a/src/ops/removevolumegroupoperation.h
+++ b/src/ops/removevolumegroupoperation.h
@@ -37,7 +37,7 @@ class LIBKPMCORE_EXPORT RemoveVolumeGroupOperation : public Operation
friend class OperationStack;
public:
- RemoveVolumeGroupOperation(VolumeManagerDevice& d);
+ explicit RemoveVolumeGroupOperation(VolumeManagerDevice& d);
public:
QString iconName() const override {
diff --git a/src/plugins/dummy/dummydevice.h b/src/plugins/dummy/dummydevice.h
index 746c346..322a227 100644
--- a/src/plugins/dummy/dummydevice.h
+++ b/src/plugins/dummy/dummydevice.h
@@ -33,7 +33,7 @@ class DummyDevice : public CoreBackendDevice
Q_DISABLE_COPY(DummyDevice)
public:
- DummyDevice(const QString& deviceNode);
+ explicit DummyDevice(const QString& deviceNode);
~DummyDevice();
public:
diff --git a/src/plugins/dummy/dummypartitiontable.cpp b/src/plugins/dummy/dummypartitiontable.cpp
index 90dd93f..046a968 100644
--- a/src/plugins/dummy/dummypartitiontable.cpp
+++ b/src/plugins/dummy/dummypartitiontable.cpp
@@ -108,6 +108,41 @@ bool DummyPartitionTable::setPartitionSystemType(Report& report, const Partition
return true;
}
+bool DummyPartitionTable::setPartitionLabel(Report& report, const Partition& partition, const QString& label)
+{
+ Q_UNUSED(report)
+ Q_UNUSED(partition)
+ Q_UNUSED(label)
+
+ return true;
+}
+
+QString DummyPartitionTable::getPartitionUUID(Report& report, const Partition& partition)
+{
+ Q_UNUSED(report)
+ Q_UNUSED(partition)
+
+ return QString();
+}
+
+bool DummyPartitionTable::setPartitionUUID(Report& report, const Partition& partition, const QString& uuid)
+{
+ Q_UNUSED(report)
+ Q_UNUSED(partition)
+ Q_UNUSED(uuid)
+
+ return true;
+}
+
+bool DummyPartitionTable::setPartitionAttributes(Report& report, const Partition& partition, quint64 attrs)
+{
+ Q_UNUSED(report)
+ Q_UNUSED(partition)
+ Q_UNUSED(attrs)
+
+ return true;
+}
+
bool DummyPartitionTable::setFlag(Report& report, const Partition& partition, PartitionTable::Flag partitionManagerFlag, bool state)
{
Q_UNUSED(report)
diff --git a/src/plugins/dummy/dummypartitiontable.h b/src/plugins/dummy/dummypartitiontable.h
index 3d1da5b..bce15b4 100644
--- a/src/plugins/dummy/dummypartitiontable.h
+++ b/src/plugins/dummy/dummypartitiontable.h
@@ -46,6 +46,10 @@ public:
bool clobberFileSystem(Report& report, const Partition& partition) override;
bool resizeFileSystem(Report& report, const Partition& partition, qint64 newLength) override;
FileSystem::Type detectFileSystemBySector(Report& report, const Device& device, qint64 sector) override;
+ bool setPartitionLabel(Report& report, const Partition& partition, const QString& label) override;
+ QString getPartitionUUID(Report& report, const Partition& partition) override;
+ bool setPartitionUUID(Report& report, const Partition& partition, const QString& uuid) override;
+ bool setPartitionAttributes(Report& report, const Partition& partition, quint64 attrs) override;
bool setPartitionSystemType(Report& report, const Partition& partition) override;
bool setFlag(Report& report, const Partition& partition, PartitionTable::Flag partitionManagerFlag, bool state) override;
};
diff --git a/src/plugins/dummy/pmdummybackendplugin.json b/src/plugins/dummy/pmdummybackendplugin.json
index b894a13..652ad7a 100644
--- a/src/plugins/dummy/pmdummybackendplugin.json
+++ b/src/plugins/dummy/pmdummybackendplugin.json
@@ -13,6 +13,8 @@
"Name[el]": "Volker Lanz",
"Name[en_GB]": "Volker Lanz",
"Name[es]": "Volker Lanz",
+ "Name[et]": "Volker Lanz",
+ "Name[eu]": "Volker Lanz",
"Name[fi]": "Volker Lanz",
"Name[fr]": "Volker Lanz",
"Name[gl]": "Volker Lanz",
@@ -27,6 +29,7 @@
"Name[pt_BR]": "Volker Lanz",
"Name[ru]": "Volker Lanz",
"Name[sk]": "Volker Lanz",
+ "Name[sl]": "Volker Lanz",
"Name[sv]": "Volker Lanz",
"Name[uk]": "Volker Lanz",
"Name[x-test]": "xxVolker Lanzxx",
@@ -36,26 +39,30 @@
],
"Category": "BackendPlugin",
"Description": "A KDE Partition Manager dummy backend for testing purposes.",
- "Description[ca@valencia]": "Un dorsal fals del gestor de particions del KDE amb la finalitat de fer proves.",
- "Description[ca]": "Un dorsal fals del gestor de particions del KDE amb la finalitat de fer proves.",
+ "Description[ca@valencia]": "Un dorsal fals per al gestor de particions del KDE amb la finalitat de fer proves.",
+ "Description[ca]": "Un dorsal fals per al gestor de particions del KDE amb la finalitat de fer proves.",
"Description[cs]": "Falešná podpůrná vrstva pro správce diskových oddílů KDE pro testovací účely.",
"Description[da]": "En KDE-partitionshåndtering med attrap-backend til testformål.",
"Description[de]": "Ein Dummy-Backend für die KDE-Partitionsverwaltung zu Testzwecken.",
"Description[el]": "Ένα εικονικό σύστημα υποστήριξης διαχειριστή κατατμήσεων του KDE για δοκιμές.",
"Description[en_GB]": "A KDE Partition Manager dummy backend for testing purposes.",
"Description[es]": "Un motor de simulación para el gestor de particiones de KDE para hacer pruebas.",
+ "Description[et]": "KDE partitsioonihalduri fiktiivne taustaprogramm testimiseks.",
+ "Description[eu]": "KDE partizio kudeatzailearen probatarako gezurrezko bizkarraldeko bat.",
"Description[fi]": "KDE:n osionhallinnan valetaustaosa testaustarkoituksiin.",
"Description[fr]": "Un moteur de test pour le gestionnaire de partitions de KDE pour faire des essais.",
"Description[gl]": "Unha infraestrutura de probas para o xestor de particións de KDE.",
"Description[id]": "Sebuah backend dumi Pengelola Partisi KDE untuk tujuan pengujian.",
"Description[it]": "Un motore fittizio del gestore delle partizioni di KDE per scopi di prova.",
- "Description[ko]": "테스트를 위한 KDE 파티션 관리자 더미 백엔드입니다.",
+ "Description[ko]": "테스트용 KDE 파티션 관리자 더미 백엔드입니다.",
"Description[lt]": "KDE skaidinių tvarkyklės netikra galinė sąsaja skirta testavimui.",
"Description[nl]": "Dummy backend van KDE-partitiebeheerder voor testdoeleinden",
"Description[nn]": "Ein eksempelbakgrunnsmotor for KDE-partisjonshandtering, for testformål.",
"Description[pl]": "Fikcyjny silnik zarządzania partycjami do prób.",
"Description[pt]": "Uma infra-estrutura de testes para o Gestor de Partições do KDE.",
+ "Description[pt_BR]": "Um simulador de back-end do Gerenciado de Partição do KDE para fins de teste.",
"Description[sk]": "Testovací program v pozadí KDE Správcu partícií",
+ "Description[sl]": "KDE Partition Manager prazen zaledni program za testne namene.",
"Description[sv]": "Ett bakgrundsprogram till KDE:s partitionshanterare i testsyfte.",
"Description[uk]": "Тестовий додаток сервера Керування розділами KDE.",
"Description[x-test]": "xxA KDE Partition Manager dummy backend for testing purposes.xx",
@@ -66,14 +73,16 @@
"Id": "pmdummybackendplugin",
"License": "GPL",
"Name": "KDE Partition Manager Dummy Backend",
- "Name[ca@valencia]": "Dorsal fals del gestor de particions del KDE",
- "Name[ca]": "Dorsal fals del gestor de particions del KDE",
+ "Name[ca@valencia]": "Dorsal fals per al gestor de particions del KDE",
+ "Name[ca]": "Dorsal fals per al gestor de particions del KDE",
"Name[cs]": "Podpůrná vrstva pro správce diskových oddílů pro KDE",
"Name[da]": "KDE-partitionshåndtering med attrap-backend",
"Name[de]": "KDE-Partitionsverwaltung Dummy-Backend",
"Name[el]": "KDE Εικονικό σύστημα υποστήριξης διαχειριστή κατατμήσεων",
"Name[en_GB]": "KDE Partition Manager Dummy Backend",
"Name[es]": "Motor de simulación para el gestor de particiones de KDE",
+ "Name[et]": "KDE partitsioonihalduri fiktiivne taustaprogramm",
+ "Name[eu]": "KDE partizio kudeatzailearen gezurrezko bizkarraldekoa",
"Name[fi]": "KDE:n osionhallinnan valetaustaosa",
"Name[fr]": "Moteur de test pour le gestionnaire de partitions de KDE",
"Name[gl]": "Infraestrutura de probas para o xestor de particións de KDE",
@@ -86,7 +95,9 @@
"Name[nn]": "KDE-partisjonshandtering eksempelbakgrunnsmotor",
"Name[pl]": "Fikcyjny silnik zarządzania partycjami",
"Name[pt]": "Infra-Estrutura de Testes para o Gestor de Partições do KDE",
+ "Name[pt_BR]": "Gerenciador de Partição do KDE Simulado Back-end",
"Name[sk]": "Testovací program v pozadí KDE Správcu partícií",
+ "Name[sl]": "KDE Partition Manager prazen zaledni program",
"Name[sv]": "KDE:s partitionshanterare bakgrundsprogram för test",
"Name[uk]": "Тестовий додаток сервера Керування розділами KDE",
"Name[x-test]": "xxKDE Partition Manager Dummy Backendxx",
diff --git a/src/plugins/sfdisk/CMakeLists.txt b/src/plugins/sfdisk/CMakeLists.txt
index c7b137d..ad51de5 100644
--- a/src/plugins/sfdisk/CMakeLists.txt
+++ b/src/plugins/sfdisk/CMakeLists.txt
@@ -16,6 +16,7 @@
set (pmsfdiskbackendplugin_SRCS
sfdiskbackend.cpp
sfdiskdevice.cpp
+ sfdiskgptattributes.cpp
sfdiskpartitiontable.cpp
${CMAKE_SOURCE_DIR}/src/backend/corebackenddevice.cpp
${CMAKE_SOURCE_DIR}/src/core/copysourcedevice.cpp
diff --git a/src/plugins/sfdisk/pmsfdiskbackendplugin.json b/src/plugins/sfdisk/pmsfdiskbackendplugin.json
index 47f82fb..f8bed3b 100644
--- a/src/plugins/sfdisk/pmsfdiskbackendplugin.json
+++ b/src/plugins/sfdisk/pmsfdiskbackendplugin.json
@@ -13,6 +13,8 @@
"Name[el]": "Andrius Štikonas",
"Name[en_GB]": "Andrius Štikonas",
"Name[es]": "Andrius Štikonas",
+ "Name[et]": "Andrius Štikonas",
+ "Name[eu]": "Andrius Štikonas",
"Name[fi]": "Andrius Štikonas",
"Name[fr]": "Andrius Štikonas",
"Name[gl]": "Andrius Štikonas",
@@ -27,6 +29,7 @@
"Name[pt_BR]": "Andrius Štikonas",
"Name[ru]": "Andrius Štikonas",
"Name[sk]": "Andrius Štikonas",
+ "Name[sl]": "Andrius Štikonas",
"Name[sv]": "Andrius Štikonas",
"Name[uk]": "Andrius Štikonas",
"Name[x-test]": "xxAndrius Štikonasxx",
@@ -44,6 +47,8 @@
"Description[el]": "Σύστημα υποστήριξης sfdisk διαχειριστή κατατμήσεων του KDE.",
"Description[en_GB]": "A KDE Partition Manager sfdisk backend.",
"Description[es]": "Motor sfdisk para el gestor de particiones de KDE.",
+ "Description[et]": "KDE partitsioonihalduri sfdisk'i taustaprogramm.",
+ "Description[eu]": "KDE partizio kudeatzailearen «sfdisk» bizkarraldeko bat.",
"Description[fi]": "KDE:n osionhallinnan sfdisk-taustaosa",
"Description[fr]": "Moteur sfdisk pour le gestionnaire de partitions de KDE.",
"Description[gl]": "Unha infraestrutura de sfdisk para o xestor de particións de KDE.",
@@ -55,7 +60,9 @@
"Description[nn]": "Ein sfdisk-bakgrunnsmotor for KDE-partisjonshandtering.",
"Description[pl]": "Silnik sfdisk zarządzania partycjami.",
"Description[pt]": "A infra-estrutura do 'sfdisk' para o Gestor de Partições do KDE.",
+ "Description[pt_BR]": "Um gerenciado de partição do KDE simulando sfdisk back-end.",
"Description[sk]": "Backend KDE správcu partícií sfdisk.",
+ "Description[sl]": "KDE Partition Manager zaledni program sfdisk.",
"Description[sv]": "Ett sfdisk bakgrundsprogram till KDE:s partitionshanterare",
"Description[uk]": "Додаток sfdisk сервера Керування розділами KDE.",
"Description[x-test]": "xxA KDE Partition Manager sfdisk backend.xx",
@@ -73,6 +80,8 @@
"Name[el]": "KDE Σύστημα υποστήριξης sfdisk διαχειριστή κατατμήσεων",
"Name[en_GB]": "KDE Partition Manager sfdisk Backend",
"Name[es]": "Motor sfdisk para el gestor de particiones de KDE",
+ "Name[et]": "KDE partitsioonihalduri sfdisk'i taustaprogramm",
+ "Name[eu]": "KDE partizio kudeatzailearen «sfdisk» bizkarraldekoa",
"Name[fi]": "KDE:n osionhallinnan sfdisk-taustaosa",
"Name[fr]": "Moteur sfdisk pour le gestionnaire de partitions de KDE",
"Name[gl]": "Infraestrutura de sfdisk para o xestor de particións de KDE",
@@ -84,7 +93,9 @@
"Name[nn]": "sfdisk-bakgrunnsmotor for KDE-partisjonshandtering",
"Name[pl]": "Silnik sfdisk zarządzania partycjami",
"Name[pt]": "Infra-Estrutura do Sfdisk para o Gestor de Partições do KDE",
+ "Name[pt_BR]": "Gerenciador de Partição do KDE simulando sfdisk Back-end.",
"Name[sk]": "Backend KDE správcu partícií sfdisk",
+ "Name[sl]": "KDE Partition Manager zaledni program sfdisk",
"Name[sv]": "KDE:s partitionshanterare sfdisk bakgrundsprogram",
"Name[uk]": "Додаток sfdisk сервера Керування розділами KDE",
"Name[x-test]": "xxKDE Partition Manager sfdisk Backendxx",
diff --git a/src/plugins/sfdisk/sfdiskbackend.cpp b/src/plugins/sfdisk/sfdiskbackend.cpp
index 108bee7..433f1c0 100644
--- a/src/plugins/sfdisk/sfdiskbackend.cpp
+++ b/src/plugins/sfdisk/sfdiskbackend.cpp
@@ -20,6 +20,7 @@
#include "plugins/sfdisk/sfdiskbackend.h"
#include "plugins/sfdisk/sfdiskdevice.h"
+#include "plugins/sfdisk/sfdiskgptattributes.h"
#include "core/copysourcedevice.h"
#include "core/copytargetbytearray.h"
@@ -125,6 +126,60 @@ QList SfdiskBackend::scanDevices(const ScanFlags scanFlags)
return result;
}
+/*** @brief Fix up bogus JSON from `sfdisk --json /dev/sdb`
+ *
+ * The command `sfdisk --json /dev/sdb` outputs a JSON representation
+ * of the partition table, with general device characteristics and
+ * the list of partitions, **but**..
+ *
+ * This isn't necessarily valid JSON: in particular, when there are
+ * no partitions on the disk because it is empty / was recently zeroed /
+ * is a USB stick for testing purposes, the output is changed **only**
+ * by there being no partitions in the partition table. However,
+ * the comma (",") after sectorsize is still printed. Bogus output looks
+ * like this:
+ *
+ * {
+ * "partitiontable": {
+ * "label":"gpt",
+ * "id":"1F9E80D9-DD78-024F-94A3-B61EC82B18C8",
+ * "device":"/dev/sdb",
+ * "unit":"sectors",
+ * "firstlba":2048,
+ * "lastlba":30949342,
+ * "sectorsize":512,
+ * }
+ * }
+ *
+ * That's not valid JSON because of the "," followed by nothing until
+ * the brace, and yields an empty object is passed to fromJson().
+ *
+ * We'll go through and check if there's a "," followed by whitespace
+ * and then a }. If there is, replace the ,.
+ *
+ * This is also fixed in util-linux 2.37.
+ */
+static void
+fixInvalidJsonFromSFDisk( QByteArray& s )
+{
+ // -1 if there is no comma (but then there's no useful JSON either),
+ // not is 0 a valid place (the start) for a , in a JSON document.
+ int lastComma = s.lastIndexOf(',');
+ if ( lastComma > 0 )
+ {
+ for ( int charIndex = lastComma + 1; charIndex < s.length(); ++charIndex )
+ {
+ if ( s[charIndex] == '}' )
+ {
+ s[lastComma] = ' '; // Erase that comma
+ }
+ if ( !isspace( s[charIndex] ) )
+ {
+ break;
+ }
+ }
+ }
+}
/** Create a Device for the given device_node and scan it for partitions.
@param deviceNode the device node (e.g. "/dev/sda")
@@ -206,7 +261,10 @@ Device* SfdiskBackend::scanDevice(const QString& deviceNode)
if (jsonCommand.exitCode() != 0)
return d;
- const QJsonObject jsonObject = QJsonDocument::fromJson(jsonCommand.rawOutput()).object();
+ auto s = jsonCommand.rawOutput();
+ fixInvalidJsonFromSFDisk(s);
+
+ const QJsonObject jsonObject = QJsonDocument::fromJson(s).object();
const QJsonObject partitionTable = jsonObject[QLatin1String("partitiontable")].toObject();
if (!updateDevicePartitionTable(*d, partitionTable))
@@ -275,7 +333,8 @@ void SfdiskBackend::scanDevicePartitions(Device& d, const QJsonArray& jsonPartit
else
r = PartitionRole::Logical;
- FileSystem* fs = FileSystemFactory::create(type, start, start + size - 1, d.logicalSize());
+ auto lastSector = start + size - 1;
+ FileSystem* fs = FileSystemFactory::create(type, start, lastSector, d.logicalSize());
fs->scan(partitionNode);
QString mountPoint;
@@ -293,19 +352,13 @@ void SfdiskBackend::scanDevicePartitions(Device& d, const QJsonArray& jsonPartit
mounted = FileSystem::detectMountStatus(fs, partitionNode);
}
- Partition* part = new Partition(parent, d, PartitionRole(r), fs, start, start + size - 1, partitionNode, availableFlags(d.partitionTable()->type()), mountPoint, mounted, activeFlags);
+ Partition* part = new Partition(parent, d, PartitionRole(r), fs, start, lastSector, partitionNode, availableFlags(d.partitionTable()->type()), mountPoint, mounted, activeFlags);
- if (!part->roles().has(PartitionRole::Luks))
- readSectorsUsed(d, *part, mountPoint);
+ setupPartitionInfo(d, part, partitionObject, mountPoint);
if (fs->supportGetLabel() != FileSystem::cmdSupportNone)
fs->setLabel(fs->readLabel(part->deviceNode()));
- if (d.partitionTable()->type() == PartitionTable::TableType::gpt) {
- part->setLabel(partitionObject[QLatin1String("name")].toString());
- part->setUUID(partitionObject[QLatin1String("uuid")].toString());
- }
-
if (fs->supportGetUUID() != FileSystem::cmdSupportNone)
fs->setUUID(fs->readUUID(part->deviceNode()));
@@ -322,6 +375,20 @@ void SfdiskBackend::scanDevicePartitions(Device& d, const QJsonArray& jsonPartit
PartitionAlignment::isAligned(d, *part);
}
+void SfdiskBackend::setupPartitionInfo(const Device &d, Partition *partition, const QJsonObject& partitionObject, const QString mountPoint)
+{
+ if (!partition->roles().has(PartitionRole::Luks))
+ readSectorsUsed(d, *partition, mountPoint);
+
+ if (d.partitionTable()->type() == PartitionTable::TableType::gpt) {
+ partition->setLabel(partitionObject[QLatin1String("name")].toString());
+ partition->setUUID(partitionObject[QLatin1String("uuid")].toString());
+ partition->setType(partitionObject[QLatin1String("type")].toString());
+ QString attrs = partitionObject[QLatin1String("attrs")].toString();
+ partition->setAttributes(SfdiskGptAttributes::toULongLong(attrs.split(QLatin1Char(' '))));
+ }
+}
+
bool SfdiskBackend::updateDevicePartitionTable(Device &d, const QJsonObject &jsonPartitionTable)
{
QString tableType = jsonPartitionTable[QLatin1String("label")].toString();
diff --git a/src/plugins/sfdisk/sfdiskbackend.h b/src/plugins/sfdisk/sfdiskbackend.h
index 9a659c8..9286f2a 100644
--- a/src/plugins/sfdisk/sfdiskbackend.h
+++ b/src/plugins/sfdisk/sfdiskbackend.h
@@ -27,6 +27,7 @@
#include
class Device;
+class Partition;
class KPluginFactory;
class QString;
@@ -59,6 +60,7 @@ public:
private:
static void readSectorsUsed(const Device& d, Partition& p, const QString& mountPoint);
void scanDevicePartitions(Device& d, const QJsonArray& jsonPartitions);
+ void setupPartitionInfo(const Device& d, Partition* partition, const QJsonObject& partitionObject, const QString mountPoint);
bool updateDevicePartitionTable(Device& d, const QJsonObject& jsonPartitionTable);
static PartitionTable::Flags availableFlags(PartitionTable::TableType type);
};
diff --git a/src/plugins/sfdisk/sfdiskdevice.h b/src/plugins/sfdisk/sfdiskdevice.h
index eab4a12..ad83625 100644
--- a/src/plugins/sfdisk/sfdiskdevice.h
+++ b/src/plugins/sfdisk/sfdiskdevice.h
@@ -34,7 +34,7 @@ class SfdiskDevice : public CoreBackendDevice
Q_DISABLE_COPY(SfdiskDevice);
public:
- SfdiskDevice(const Device& d);
+ explicit SfdiskDevice(const Device& d);
~SfdiskDevice();
public:
diff --git a/src/plugins/sfdisk/sfdiskgptattributes.cpp b/src/plugins/sfdisk/sfdiskgptattributes.cpp
new file mode 100644
index 0000000..0541f48
--- /dev/null
+++ b/src/plugins/sfdisk/sfdiskgptattributes.cpp
@@ -0,0 +1,58 @@
+/*************************************************************************
+ * Copyright (C) 2020 by Gaël PORTAY *
+ * *
+ * 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 .*
+ *************************************************************************/
+
+#include "plugins/sfdisk/sfdiskgptattributes.h"
+
+#include
+#include
+
+const static QString requiredPartition = QStringLiteral("RequiredPartition");
+const static QString noBlockIoProtocol = QStringLiteral("NoBlockIOProtocol");
+const static QString legacyBiosBootable = QStringLiteral("LegacyBIOSBootable");
+const static QString guid = QStringLiteral("GUID:");
+
+quint64 SfdiskGptAttributes::toULongLong(const QStringList& attrs)
+{
+ quint64 attributes = 0;
+ for (auto& attr: attrs)
+ if (attr.compare(requiredPartition) == 0)
+ attributes |= 0x1ULL;
+ else if (attr.compare(noBlockIoProtocol) == 0)
+ attributes |= 0x2ULL;
+ else if (attr.compare(legacyBiosBootable) == 0)
+ attributes |= 0x4ULL;
+ else if (attr.startsWith(guid))
+ attributes |= 1ULL << QStringRef(&attr, guid.length(), attr.length() - guid.length()).toULongLong();
+
+ return attributes;
+}
+
+QStringList SfdiskGptAttributes::toStringList(quint64 attrs)
+{
+ QStringList list;
+ if (attrs & 0x1)
+ list += requiredPartition;
+ if (attrs & 0x2)
+ list += noBlockIoProtocol;
+ if (attrs & 0x4)
+ list += legacyBiosBootable;
+ for (int bit = 48; bit < 64; bit++)
+ if (attrs & (1 << bit))
+ list += guid + QString::number(bit);
+
+ return list;
+}
diff --git a/src/plugins/sfdisk/sfdiskgptattributes.h b/src/plugins/sfdisk/sfdiskgptattributes.h
new file mode 100644
index 0000000..19db26e
--- /dev/null
+++ b/src/plugins/sfdisk/sfdiskgptattributes.h
@@ -0,0 +1,36 @@
+/*************************************************************************
+ * Copyright (C) 2020 by Gaël PORTAY *
+ * *
+ * 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 .*
+ *************************************************************************/
+
+#if !defined(SFDISKGPTATTRIBUTES__H)
+
+#define SFDISKGPTATTRIBUTES__H
+
+#include
+
+class QStringList;
+
+/** Sfdisk GPT Attributes helpers.
+ @author Gaël PORTAY
+*/
+class SfdiskGptAttributes
+{
+public:
+ static quint64 toULongLong(const QStringList& attrs);
+ static QStringList toStringList(quint64 attrs);
+};
+
+#endif
diff --git a/src/plugins/sfdisk/sfdiskpartitiontable.cpp b/src/plugins/sfdisk/sfdiskpartitiontable.cpp
index f200577..5d27b35 100644
--- a/src/plugins/sfdisk/sfdiskpartitiontable.cpp
+++ b/src/plugins/sfdisk/sfdiskpartitiontable.cpp
@@ -16,6 +16,7 @@
*************************************************************************/
#include "plugins/sfdisk/sfdiskpartitiontable.h"
+#include "plugins/sfdisk/sfdiskgptattributes.h"
#include "backend/corebackend.h"
#include "backend/corebackendmanager.h"
@@ -57,11 +58,8 @@ bool SfdiskPartitionTable::commit(quint32 timeout)
ExternalCommand(QStringLiteral("udevadm"), { QStringLiteral("control"), QStringLiteral("--stop-exec-queue") }).run();
ExternalCommand(QStringLiteral("udevadm"), { QStringLiteral("settle"), QStringLiteral("--timeout=") + QString::number(timeout) }).run();
- ExternalCommand(QStringLiteral("blockdev"), { QStringLiteral("--rereadpt"), m_device->deviceNode() }).run();
-
- QThread::msleep(1000);
-
- ExternalCommand(QStringLiteral("udevadm"), { QStringLiteral("trigger") }).run();
+ ExternalCommand(QStringLiteral("partx"), { QStringLiteral("--update"), m_device->deviceNode() }).run();
+ ExternalCommand(QStringLiteral("udevadm"), { QStringLiteral("trigger"), QStringLiteral("--subsystem-match=block") }).run();
if (m_device->type() == Device::Type::SoftwareRAID_Device)
ExternalCommand(QStringLiteral("udevadm"), { QStringLiteral("control"), QStringLiteral("--start-exec-queue") }).run();
@@ -181,7 +179,7 @@ static struct {
{ FileSystem::Type::LinuxSwap, { QLatin1String("0657FD6D-A4AB-43C4-84E5-0933C84B4F4F"), QLatin1String("82") } },
{ FileSystem::Type::Fat12, { QLatin1String("EBD0A0A2-B9E5-4433-87C0-68B6B72699C7"), QLatin1String("6") } },
{ FileSystem::Type::Fat16, { QLatin1String("EBD0A0A2-B9E5-4433-87C0-68B6B72699C7"), QLatin1String("6") } },
- { FileSystem::Type::Fat32, { QLatin1String("EBD0A0A2-B9E5-4433-87C0-68B6B72699C7"), QLatin1String("7") } },
+ { FileSystem::Type::Fat32, { QLatin1String("EBD0A0A2-B9E5-4433-87C0-68B6B72699C7"), QLatin1String("c") } },
{ FileSystem::Type::Nilfs2, { QLatin1String("0FC63DAF-8483-4772-8E79-3D69D8477DE4"), QLatin1String("83") } },
{ FileSystem::Type::Ntfs, { QLatin1String("EBD0A0A2-B9E5-4433-87C0-68B6B72699C7"), QLatin1String("7") } },
{ FileSystem::Type::Exfat, { QLatin1String("EBD0A0A2-B9E5-4433-87C0-68B6B72699C7"), QLatin1String("7") } },
@@ -216,9 +214,54 @@ static QLatin1String getPartitionType(FileSystem::Type t, PartitionTable::TableT
return QLatin1String();
}
+bool SfdiskPartitionTable::setPartitionLabel(Report& report, const Partition& partition, const QString& label)
+{
+ if (label.isEmpty())
+ return true;
+ ExternalCommand sfdiskCommand(report, QStringLiteral("sfdisk"), { QStringLiteral("--part-label"), m_device->deviceNode(), QString::number(partition.number()),
+ label } );
+ return sfdiskCommand.run(-1) && sfdiskCommand.exitCode() == 0;
+}
+
+QString SfdiskPartitionTable::getPartitionUUID(Report& report, const Partition& partition)
+{
+ ExternalCommand sfdiskCommand(report, QStringLiteral("sfdisk"), { QStringLiteral("--list"), QStringLiteral("--output"), QStringLiteral("Device,UUID"),
+ m_device->deviceNode() });
+ if (sfdiskCommand.run(-1) && sfdiskCommand.exitCode() == 0) {
+ QRegularExpression re(m_device->deviceNode() + QString::number(partition.number()) + QStringLiteral(" +(.+)"));
+ QRegularExpressionMatch rem = re.match(sfdiskCommand.output());
+
+ if (rem.hasMatch())
+ return rem.captured(1);
+ }
+
+ return QString();
+}
+
+bool SfdiskPartitionTable::setPartitionUUID(Report& report, const Partition& partition, const QString& uuid)
+{
+ if (uuid.isEmpty())
+ return true;
+ ExternalCommand sfdiskCommand(report, QStringLiteral("sfdisk"), { QStringLiteral("--part-uuid"), m_device->deviceNode(), QString::number(partition.number()),
+ uuid } );
+ return sfdiskCommand.run(-1) && sfdiskCommand.exitCode() == 0;
+}
+
+bool SfdiskPartitionTable::setPartitionAttributes(Report& report, const Partition& partition, quint64 attrs)
+{
+ QStringList attributes = SfdiskGptAttributes::toStringList(attrs);
+ if (attributes.isEmpty())
+ return true;
+ ExternalCommand sfdiskCommand(report, QStringLiteral("sfdisk"), { QStringLiteral("--part-attrs"), m_device->deviceNode(), QString::number(partition.number()),
+ attributes.join(QStringLiteral(",")) } );
+ return sfdiskCommand.run(-1) && sfdiskCommand.exitCode() == 0;
+}
+
bool SfdiskPartitionTable::setPartitionSystemType(Report& report, const Partition& partition)
{
- QString partitionType = getPartitionType(partition.fileSystem().type(), m_device->partitionTable()->type());
+ QString partitionType = partition.type();
+ if (partitionType.isEmpty())
+ partitionType = getPartitionType(partition.fileSystem().type(), m_device->partitionTable()->type());
if (partitionType.isEmpty())
return true;
ExternalCommand sfdiskCommand(report, QStringLiteral("sfdisk"), { QStringLiteral("--part-type"), m_device->deviceNode(), QString::number(partition.number()),
diff --git a/src/plugins/sfdisk/sfdiskpartitiontable.h b/src/plugins/sfdisk/sfdiskpartitiontable.h
index 9d0de1e..e682760 100644
--- a/src/plugins/sfdisk/sfdiskpartitiontable.h
+++ b/src/plugins/sfdisk/sfdiskpartitiontable.h
@@ -32,7 +32,7 @@ class Partition;
class SfdiskPartitionTable : public CoreBackendPartitionTable
{
public:
- SfdiskPartitionTable(const Device *d);
+ explicit SfdiskPartitionTable(const Device *d);
~SfdiskPartitionTable();
public:
@@ -46,6 +46,10 @@ public:
bool clobberFileSystem(Report& report, const Partition& partition) override;
bool resizeFileSystem(Report& report, const Partition& partition, qint64 newLength) override;
FileSystem::Type detectFileSystemBySector(Report& report, const Device& device, qint64 sector) override;
+ bool setPartitionLabel(Report& report, const Partition& partition, const QString& label) override;
+ QString getPartitionUUID(Report& report, const Partition& partition) override;
+ bool setPartitionUUID(Report& report, const Partition& partition, const QString& uuid) override;
+ bool setPartitionAttributes(Report& report, const Partition& partition, quint64 attrs) override;
bool setPartitionSystemType(Report& report, const Partition& partition) override;
bool setFlag(Report& report, const Partition& partition, PartitionTable::Flag flag, bool state) override;
diff --git a/src/util/externalcommand.cpp b/src/util/externalcommand.cpp
index 0568bb6..972be75 100644
--- a/src/util/externalcommand.cpp
+++ b/src/util/externalcommand.cpp
@@ -16,6 +16,7 @@
* along with this program. If not, see .*
*************************************************************************/
+#include "util/externalcommand.h"
#include "backend/corebackendmanager.h"
#include "core/device.h"
#include "core/copysource.h"
@@ -24,7 +25,6 @@
#include "core/copysourcedevice.h"
#include "core/copytargetdevice.h"
#include "util/globallog.h"
-#include "util/externalcommand.h"
#include "util/report.h"
#include "externalcommandhelper_interface.h"
@@ -124,11 +124,6 @@ bool ExternalCommand::start(int timeout)
if (command().isEmpty())
return false;
- if (!QDBusConnection::systemBus().isConnected()) {
- qWarning() << QDBusConnection::systemBus().lastError().message();
- return false;
- }
-
if (report())
report()->setCommand(xi18nc("@info:status", "Command: %1 %2", command(), args().join(QStringLiteral(" "))));
@@ -139,10 +134,9 @@ bool ExternalCommand::start(int timeout)
if (cmd.isEmpty())
cmd = QStandardPaths::findExecutable(command(), { QStringLiteral("/sbin/"), QStringLiteral("/usr/sbin/"), QStringLiteral("/usr/local/sbin/") });
- auto *interface = new org::kde::kpmcore::externalcommand(QStringLiteral("org.kde.kpmcore.externalcommand"),
- QStringLiteral("/Helper"), QDBusConnection::systemBus(), this);
-
- interface->setTimeout(10 * 24 * 3600 * 1000); // 10 days
+ auto interface = helperInterface();
+ if (!interface)
+ return false;
bool rval = false;
@@ -176,18 +170,13 @@ bool ExternalCommand::copyBlocks(const CopySource& source, CopyTarget& target)
bool rval = true;
const qint64 blockSize = 10 * 1024 * 1024; // number of bytes per block to copy
- if (!QDBusConnection::systemBus().isConnected()) {
- qWarning() << QDBusConnection::systemBus().lastError().message();
- return false;
- }
-
// TODO KF6:Use new signal-slot syntax
connect(m_job, SIGNAL(percent(KJob*, unsigned long)), this, SLOT(emitProgress(KJob*, unsigned long)));
connect(m_job, &KAuth::ExecuteJob::newData, this, &ExternalCommand::emitReport);
- auto *interface = new org::kde::kpmcore::externalcommand(QStringLiteral("org.kde.kpmcore.externalcommand"),
- QStringLiteral("/Helper"), QDBusConnection::systemBus(), this);
- interface->setTimeout(10 * 24 * 3600 * 1000); // 10 days
+ auto interface = helperInterface();
+ if (!interface)
+ return false;
QDBusPendingCall pcall = interface->copyblocks(source.path(), source.firstByte(), source.length(),
target.path(), target.firstByte(), blockSize);
@@ -222,19 +211,40 @@ bool ExternalCommand::writeData(Report& commandReport, const QByteArray& buffer,
if (report())
report()->setCommand(xi18nc("@info:status", "Command: %1 %2", command(), args().join(QStringLiteral(" "))));
- bool rval = true;
+ auto interface = helperInterface();
+ if (!interface)
+ return false;
+ QDBusPendingCall pcall = interface->writeData(buffer, deviceNode, firstByte);
+ return waitForDbusReply(pcall);
+}
+
+bool ExternalCommand::createFile(const QByteArray& buffer, const QString& deviceNode)
+{
+ auto interface = helperInterface();
+ if (!interface)
+ return false;
+
+ QDBusPendingCall pcall = interface->createFile(buffer, deviceNode);
+ return waitForDbusReply(pcall);
+}
+
+OrgKdeKpmcoreExternalcommandInterface* ExternalCommand::helperInterface()
+{
if (!QDBusConnection::systemBus().isConnected()) {
qWarning() << QDBusConnection::systemBus().lastError().message();
- return false;
+ return nullptr;
}
auto *interface = new org::kde::kpmcore::externalcommand(QStringLiteral("org.kde.kpmcore.externalcommand"),
QStringLiteral("/Helper"), QDBusConnection::systemBus(), this);
interface->setTimeout(10 * 24 * 3600 * 1000); // 10 days
-
- QDBusPendingCall pcall = interface->writeData(buffer, deviceNode, firstByte);
+ return interface;
+}
+bool ExternalCommand::waitForDbusReply(QDBusPendingCall &pcall)
+{
+ bool rval = true;
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this);
QEventLoop loop;
@@ -255,7 +265,6 @@ bool ExternalCommand::writeData(Report& commandReport, const QByteArray& buffer,
return rval;
}
-
bool ExternalCommand::write(const QByteArray& input)
{
if ( qEnvironmentVariableIsSet( "KPMCORE_DEBUG" ))
diff --git a/src/util/externalcommand.h b/src/util/externalcommand.h
index be56818..9db9d7c 100644
--- a/src/util/externalcommand.h
+++ b/src/util/externalcommand.h
@@ -38,6 +38,8 @@ class Report;
class CopySource;
class CopyTarget;
class QDBusInterface;
+class QDBusPendingCall;
+class OrgKdeKpmcoreExternalcommandInterface;
struct ExternalCommandPrivate;
@@ -71,6 +73,7 @@ public:
public:
bool copyBlocks(const CopySource& source, CopyTarget& target);
bool writeData(Report& commandReport, const QByteArray& buffer, const QString& deviceNode, const quint64 firstByte); // same as copyBlocks but from QByteArray
+ bool createFile(const QByteArray& buffer, const QString& deviceNode); // similar to writeData but creates a new file
/**< @param cmd the command to run */
void setCommand(const QString& cmd);
@@ -102,7 +105,7 @@ public:
/**< @return pointer to the Report or nullptr */
Report* report();
- void emitReport(const QVariantMap& report) { emit reportSignal(report); }
+ void emitReport(const QVariantMap& report) { Q_EMIT reportSignal(report); }
// KAuth
/**< start ExternalCommand Helper */
@@ -123,11 +126,13 @@ Q_SIGNALS:
void reportSignal(const QVariantMap&);
public Q_SLOTS:
- void emitProgress(KJob*, unsigned long percent) { emit progress(percent); }
+ void emitProgress(KJob*, unsigned long percent) { Q_EMIT progress(percent); }
private:
void setExitCode(int i);
void onReadOutput();
+ bool waitForDbusReply(QDBusPendingCall &pcall);
+ OrgKdeKpmcoreExternalcommandInterface* helperInterface();
private:
std::unique_ptr d;
diff --git a/src/util/externalcommand_whitelist.h b/src/util/externalcommand_whitelist.h
index 3b888d4..4fba6cf 100644
--- a/src/util/externalcommand_whitelist.h
+++ b/src/util/externalcommand_whitelist.h
@@ -25,6 +25,7 @@ QStringLiteral("udevadm"),
//Core programs
QStringLiteral("blockdev"),
+QStringLiteral("partx"),
QStringLiteral("sfdisk"),
QStringLiteral("wipefs"),
QStringLiteral("lvm"),
diff --git a/src/util/externalcommandhelper.cpp b/src/util/externalcommandhelper.cpp
index 9e96966..2cb9233 100644
--- a/src/util/externalcommandhelper.cpp
+++ b/src/util/externalcommandhelper.cpp
@@ -21,9 +21,9 @@
#include
#include
#include
+#include
#include
#include
-#include
#include
#include
@@ -118,7 +118,7 @@ bool ExternalCommandHelper::readData(const QString& sourceDevice, QByteArray& bu
return true;
}
-/** Writes the data from buffer to a given device or file.
+/** Writes the data from buffer to a given device.
@param targetDevice device or file to write to
@param buffer the data that we write
@param offset offset where to begin writing
@@ -128,7 +128,8 @@ bool ExternalCommandHelper::writeData(const QString &targetDevice, const QByteAr
{
QFile device(targetDevice);
- if (!device.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Unbuffered)) {
+ auto flags = QIODevice::WriteOnly | QIODevice::Unbuffered | QIODevice::Append;
+ if (!device.open(flags)) {
qCritical() << xi18n("Could not open device %1 for writing.", targetDevice);
return false;
}
@@ -146,6 +147,29 @@ bool ExternalCommandHelper::writeData(const QString &targetDevice, const QByteAr
return true;
}
+/** Creates a new file with given contents.
+ @param filePath file to write to
+ @param fileContents the data that we write
+ @return true on success
+*/
+bool ExternalCommandHelper::createFile(const QString &filePath, const QByteArray& fileContents)
+{
+ QFile device(filePath);
+
+ auto flags = QIODevice::WriteOnly | QIODevice::Unbuffered;
+ if (!device.open(flags)) {
+ qCritical() << xi18n("Could not open file %1 for writing.", filePath);
+ return false;
+ }
+
+ if (device.write(fileContents) != fileContents.size()) {
+ qCritical() << xi18n("Could not write to file %1 .", filePath);
+ return false;
+ }
+
+ return true;
+}
+
// If targetDevice is empty then return QByteArray with data that was read from disk.
QVariantMap ExternalCommandHelper::copyblocks(const QString& sourceDevice, const qint64 sourceFirstByte, const qint64 sourceLength, const QString& targetDevice, const qint64 targetFirstByte, const qint64 blockSize)
{
@@ -170,9 +194,9 @@ QVariantMap ExternalCommandHelper::copyblocks(const QString& sourceDevice, const
QByteArray buffer;
int percent = 0;
- QTime t;
+ QElapsedTimer timer;
- t.start();
+ timer.start();
QVariantMap report;
@@ -196,9 +220,9 @@ QVariantMap ExternalCommandHelper::copyblocks(const QString& sourceDevice, const
if (++blocksCopied * 100 / blocksToCopy != percent) {
percent = blocksCopied * 100 / blocksToCopy;
- if (percent % 5 == 0 && t.elapsed() > 1000) {
- const qint64 mibsPerSec = (blocksCopied * blockSize / 1024 / 1024) / (t.elapsed() / 1000);
- const qint64 estSecsLeft = (100 - percent) * t.elapsed() / percent / 1000;
+ if (percent % 5 == 0 && timer.elapsed() > 1000) {
+ const qint64 mibsPerSec = (blocksCopied * blockSize / 1024 / 1024) / (timer.elapsed() / 1000);
+ const qint64 estSecsLeft = (100 - percent) * timer.elapsed() / percent / 1000;
report[QStringLiteral("report")]= xi18nc("@info:progress", "Copying %1 MiB/second, estimated time left: %2", mibsPerSec, QTime(0, 0).addSecs(estSecsLeft).toString());
HelperSupport::progressStep(report);
}
@@ -239,12 +263,20 @@ QVariantMap ExternalCommandHelper::copyblocks(const QString& sourceDevice, const
bool ExternalCommandHelper::writeData(const QByteArray& buffer, const QString& targetDevice, const qint64 targetFirstByte)
{
// Do not allow using this helper for writing to arbitrary location
- if ( targetDevice.left(5) != QStringLiteral("/dev/") && !targetDevice.contains(QStringLiteral("/etc/fstab")))
+ if ( targetDevice.left(5) != QStringLiteral("/dev/") )
return false;
return writeData(targetDevice, buffer, targetFirstByte);
}
+bool ExternalCommandHelper::createFile(const QByteArray& fileContents, const QString& filePath)
+{
+ // Do not allow using this helper for writing to arbitrary location
+ if ( !filePath.contains(QStringLiteral("/etc/fstab")) )
+ return false;
+
+ return createFile(filePath, fileContents);
+}
QVariantMap ExternalCommandHelper::start(const QString& command, const QStringList& arguments, const QByteArray& input, const int processChannelMode)
{
diff --git a/src/util/externalcommandhelper.h b/src/util/externalcommandhelper.h
index 6d7029b..8c1e6e0 100644
--- a/src/util/externalcommandhelper.h
+++ b/src/util/externalcommandhelper.h
@@ -41,12 +41,14 @@ Q_SIGNALS:
public:
bool readData(const QString& sourceDevice, QByteArray& buffer, const qint64 offset, const qint64 size);
bool writeData(const QString& targetDevice, const QByteArray& buffer, const qint64 offset);
+ bool createFile(const QString& filePath, const QByteArray& fileContents);
public Q_SLOTS:
ActionReply init(const QVariantMap& args);
Q_SCRIPTABLE QVariantMap start(const QString& command, const QStringList& arguments, const QByteArray& input, const int processChannelMode);
Q_SCRIPTABLE QVariantMap copyblocks(const QString& sourceDevice, const qint64 sourceFirstByte, const qint64 sourceLength, const QString& targetDevice, const qint64 targetFirstByte, const qint64 blockSize);
Q_SCRIPTABLE bool writeData(const QByteArray& buffer, const QString& targetDevice, const qint64 targetFirstByte);
+ Q_SCRIPTABLE bool createFile(const QByteArray& fileContents, const QString& filePath);
Q_SCRIPTABLE void exit();
private:
diff --git a/src/util/globallog.cpp b/src/util/globallog.cpp
index 73ac63f..40c21e2 100644
--- a/src/util/globallog.cpp
+++ b/src/util/globallog.cpp
@@ -29,7 +29,7 @@ GlobalLog* GlobalLog::instance()
void GlobalLog::flush(Log::Level lev)
{
- emit newMessage(lev, msg);
+ Q_EMIT newMessage(lev, msg);
msg.clear();
}
diff --git a/src/util/org.kde.kpmcore.externalcommand.actions b/src/util/org.kde.kpmcore.externalcommand.actions
index 84ad970..827a56b 100644
--- a/src/util/org.kde.kpmcore.externalcommand.actions
+++ b/src/util/org.kde.kpmcore.externalcommand.actions
@@ -12,6 +12,8 @@ Name[de]=Externen Befehlsdienst starten
Name[el]=Εκκίνηση διεργασίας με εξωτερική εντολή
Name[en_GB]=Start external command daemon
Name[es]=Iniciar el demonio de órdenes externas
+Name[et]=Välise käsu deemoni käivitamine
+Name[eu]=Abiarazi kanpoko komandoen daimona
Name[fi]=Käynnistä ulkoinen komentopalvelu
Name[fr]=Lancer le démon de la commande externe
Name[gl]=Iniciar o servizo de orde externa
@@ -23,34 +25,41 @@ Name[pl]=Rozpocznij usługę zewnętrznego polecenia
Name[pt]=Iniciar o servidor de comandos externos
Name[pt_BR]=Iniciar comando externo do daemon
Name[sk]=Spustiť externé démony príkazov
+Name[sl]=Zaženite demon za zunanje ukaze
Name[sv]=Starta extern kommandodemon
Name[uk]=Запуск фонової служби зовнішньої команди
Name[x-test]=xxStart external command daemonxx
Name[zh_TW]=啟動外部指令守護程式
Description=Administrative privileges are required to manage disks
Description[ast]=Ríquense los privilexos alministrativos pa xestionar discos
-Description[ca]=Es requereixen privilegis d'administrador per gestionar discs
-Description[ca@valencia]=Es requereixen privilegis d'administrador per gestionar discs
+Description[ca]=Es requereixen privilegis d'administrador per a gestionar els discs
+Description[ca@valencia]=Es requereixen privilegis d'administrador per a gestionar els discs
Description[cs]=Pro správu disků jsou potřeba práva administrátora
Description[da]=Der kræves administrative rettigheder for at håndtere diske
Description[de]=Systemverwalterrechte sind zur Verwaltung von Festplatten erforderlich
Description[el]=Απαιτούνται δικαιώματα διαχειριστή για τη διαχείριση δίσκων
Description[en_GB]=Administrative privileges are required to manage disks
Description[es]=Se necesitan permisos de administrador para gestionar discos
+Description[et]=Ketaste haldamiseks on tarvis administraatori õigusi
+Description[eu]=Administrazio pribilegioak behar dira diskoak kudeatzeko
Description[fi]=Levyjen hallinta vaatii pääkäyttäjäoikeuksia
Description[fr]=Vous devez disposer des privilèges d'administrateur pour gérer les disques
Description[gl]=Requírense privilexios de administración para xestionar discos.
Description[it]=Per gestire il disco sono richiesti privilegi di amministratore
+Description[ja]=ディスクを管理するには管理者権限が必要です
Description[ko]=디스크를 관리하려면 권한이 필요함
Description[lt]=Diskų tvarkymui reikalingos administratoriaus teisės
Description[nl]=Er zijn administratieve rechten vereist om schijven te beheren
Description[pl]=Do zarządzania dyskami wymagane są uprawnienia administratora
Description[pt]=São necessários privilégios de administrador para gerir os discos
Description[pt_BR]=São necessários privilégios administrativos para gerenciar discos
-Description[sk]=Práva správcu sú potrebné na správu diskov
+Description[ru]=Для управления дисками требуются права администратора
+Description[sk]=Na správu diskov sa vyžadujú práva správcu
+Description[sl]=Za upravljanje diskov so potrebne pravice upravljavca računalnika
Description[sv]=Administratörsprivilegier krävs för att hantera diskar
Description[uk]=Для керування дисками потрібні права доступу адміністратора (root)
Description[x-test]=xxAdministrative privileges are required to manage disksxx
+Description[zh_CN]=管理磁盘需要管理权限
Description[zh_TW]=管理硬碟需要管理員權限
Policy=auth_admin
Persistence=session
diff --git a/src/util/report.cpp b/src/util/report.cpp
index 1449333..9469839 100644
--- a/src/util/report.cpp
+++ b/src/util/report.cpp
@@ -130,7 +130,7 @@ void Report::addOutput(const QString& s)
void Report::emitOutputChanged()
{
- emit outputChanged();
+ Q_EMIT outputChanged();
}
/** @return the root Report */
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 6d8f0a5..68824f4 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -54,14 +54,6 @@ find_package (Threads)
kpm_test(testexternalcommand testexternalcommand.cpp)
add_test(NAME testexternalcommand COMMAND testexternalcommand ${BACKEND})
-# Including SMART files reference
-set(SMARTPARSER ${CMAKE_SOURCE_DIR}/src/core/smartdiskinformation.cpp
- ${CMAKE_SOURCE_DIR}/src/core/smartattributeparseddata.cpp
- ${CMAKE_SOURCE_DIR}/src/core/smartparser.cpp)
-
-# Test SMART support
-kpm_test(testsmart testsmart.cpp ${SMARTPARSER})
-add_test(NAME testsmart COMMAND testsmart ${BACKEND})
# Test Device
kpm_test(testdevice testdevice.cpp)
diff --git a/test/testdevice.cpp b/test/testdevice.cpp
index 1bfb29f..d74e1c3 100644
--- a/test/testdevice.cpp
+++ b/test/testdevice.cpp
@@ -17,8 +17,8 @@
// SPDX-License-Identifier: GPL-3.0+
-#include "helpers.h"
#include "testdevice.h"
+#include "helpers.h"
#include "backend/corebackend.h"
#include "backend/corebackendmanager.h"
@@ -36,19 +36,21 @@ int main(int argc, char **argv)
if (argc == 2)
init = KPMCoreInitializer(argv[1]);
- return init.isValid() ? true : false;
+ return init.isValid() ? EXIT_SUCCESS : EXIT_FAILURE;
CoreBackend *backend = CoreBackendManager::self()->backend();
if (!backend) {
qWarning() << "Failed to load backend plugin";
- return false;
+ return EXIT_FAILURE;
}
TestDevice device;
- if (!device.testDeviceName() || !device.testDeviceNode() || !device.testDeviceSize() || !device.testDeviceTotalSectors())
- return false;
+ device.testDeviceName();
+ device.testDeviceNode();
+ device.testDeviceSize();
+ device.testDeviceTotalSectors();
return app.exec();
}
@@ -73,58 +75,50 @@ TestDevice::~TestDevice()
devices.clear();
}
-bool TestDevice::testDeviceName()
+void TestDevice::testDeviceName()
{
if (devices.isEmpty()) {
- return false;
+ exit(EXIT_FAILURE);
} else {
for (const auto &device : devices) {
- if (device->name() == QString())
- return false;
+ if (device->name().isEmpty())
+ exit(EXIT_FAILURE);
}
}
-
- return true;
}
-bool TestDevice::testDeviceNode()
+void TestDevice::testDeviceNode()
{
if (devices.isEmpty()) {
- return false;
+ exit(EXIT_FAILURE);
} else {
for (const auto &device : devices) {
if (device->deviceNode() == QString())
- return false;
+ exit(EXIT_FAILURE);
}
}
-
- return true;
}
-bool TestDevice::testDeviceSize()
+void TestDevice::testDeviceSize()
{
if (devices.isEmpty()) {
- return false;
+ exit(EXIT_FAILURE);
} else {
for (const auto &device : devices) {
if (device->logicalSize() < 0)
- return false;
+ exit(EXIT_FAILURE);
}
}
-
- return true;
}
-bool TestDevice::testDeviceTotalSectors()
+void TestDevice::testDeviceTotalSectors()
{
if (devices.isEmpty()) {
- return false;
+ exit(EXIT_FAILURE);
} else {
for (const auto &device : devices) {
if (device->totalLogical() < 0)
- return false;
+ exit(EXIT_FAILURE);
}
}
-
- return true;
}
diff --git a/test/testdevice.h b/test/testdevice.h
index 07b9d65..0256792 100644
--- a/test/testdevice.h
+++ b/test/testdevice.h
@@ -32,10 +32,10 @@ public:
TestDevice();
~TestDevice();
- bool testDeviceName();
- bool testDeviceNode();
- bool testDeviceSize();
- bool testDeviceTotalSectors();
+ void testDeviceName();
+ void testDeviceNode();
+ void testDeviceSize();
+ void testDeviceTotalSectors();
private:
OperationStack *operationStack;
diff --git a/test/testsmart.cpp b/test/testsmart.cpp
deleted file mode 100644
index eab0936..0000000
--- a/test/testsmart.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-#include "helpers.h"
-
-#include "util/externalcommand.h"
-#include "backend/corebackend.h"
-#include "backend/corebackendmanager.h"
-#include "core/smartstatus.h"
-#include "core/smartparser.h"
-
-#include
-#include
-
-static QString getDefaultDevicePath();
-static bool testSmartStatus();
-static bool testSmartParser();
-
-int main(int argc, char **argv)
-{
- QCoreApplication app(argc, argv);
-
- KPMCoreInitializer i;
-
- if (argc == 2)
- i = KPMCoreInitializer(argv[1]);
-
- if (!i.isValid())
- return 1;
-
- CoreBackend *backend = CoreBackendManager::self()->backend();
-
- if (!backend)
- {
- qWarning() << "Couldn't get backend.";
- return 1;
- }
-
- if (!testSmartStatus() || !testSmartParser())
- return 1;
-
- return app.exec();
-}
-
-static QString getDefaultDevicePath()
-{
- // Getting default home partition using 'df -P /home | awk 'END{print $1}'' command
- ExternalCommand command(QStringLiteral("df"), { QStringLiteral("-P"), QStringLiteral("/home"), QStringLiteral("|"),
- QStringLiteral("awk"), QStringLiteral("\'END{print $1}\'") });
-
- if (command.run() && command.exitCode() == 0) {
- QString output = command.output();
- return output;
- }
-
- return QString();
-}
-
-static bool testSmartStatus()
-{
- const QString devicePath = getDefaultDevicePath();
-
- SmartStatus smart(devicePath);
-
- if (smart.devicePath() != devicePath)
- return false;
-
- if (!smart.status())
- return false;
-
- if (smart.modelName() == QString())
- return false;
-
- if (smart.firmware() == QString())
- return false;
-
- if (smart.serial() == QString())
- return false;
-
- if (smart.selfTestStatus() != SmartStatus::SelfTestStatus::Success)
- return false;
-
- if (!smart.isValid())
- return false;
-
- return true;
-}
-
-static bool testSmartParser()
-{
- const QString devicePath = getDefaultDevicePath();
-
- SmartParser parser(devicePath);
-
- if (!parser.init())
- return false;
-
- if (parser.devicePath() != devicePath)
- return false;
-
- if (!parser.diskInformation())
- return false;
-
- return true;
-}